Compare commits
14 Commits
GB_SMAV6.0
...
ESP8266-IC
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a7e206032 | ||
|
|
6d12e6cd3f | ||
|
|
b249762550 | ||
|
|
5cee0d28ed | ||
|
|
5ba1ee3e8e | ||
|
|
bb2a659ebe | ||
|
|
865d919802 | ||
|
|
ff3e24dff4 | ||
|
|
6dca23bc27 | ||
|
|
15da83c411 | ||
|
|
7a3845cbdf | ||
|
|
1717a2efb0 | ||
|
|
32c5597870 | ||
|
|
2de91bd4fd |
223
NmraDcc.cpp
223
NmraDcc.cpp
@@ -25,6 +25,8 @@
|
||||
// 2017-01-19 added STM32F1 support by Franz-Peter
|
||||
// 2017-11-29 Ken West (kgw4449@gmail.com):
|
||||
// Minor fixes to pass NMRA Baseline Conformance Tests.
|
||||
// 2018-12-17 added ESP32 support by Trusty (thierry@lapajaparis.net)
|
||||
// 2019-02-17 added ESP32 specific changes by Hans Tanner
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
@@ -39,7 +41,7 @@
|
||||
#endif
|
||||
|
||||
// Uncomment to print DEBUG messages
|
||||
// #define DEBUG_PRINT
|
||||
//#define DEBUG_PRINT
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// DCC Receive Routine
|
||||
@@ -174,9 +176,22 @@
|
||||
#define MODE_TP3 pinMode( D7,OUTPUT ) ; // GPIO 13
|
||||
#define SET_TP3 GPOS = (1 << D7);
|
||||
#define CLR_TP3 GPOC = (1 << D7);
|
||||
#define MODE_TP4 pinMode( D7,OUTPUT ); // GPIO 15
|
||||
#define MODE_TP4 pinMode( D8,OUTPUT ) ; // GPIO 15
|
||||
#define SET_TP4 GPOC = (1 << D8);
|
||||
#define CLR_TP4 GPOC = (1 << D8);
|
||||
#elif defined(ESP32)
|
||||
#define MODE_TP1 pinMode( 33,OUTPUT ) ; // GPIO 33
|
||||
#define SET_TP1 GPOS = (1 << 33);
|
||||
#define CLR_TP1 GPOC = (1 << 33);
|
||||
#define MODE_TP2 pinMode( 25,OUTPUT ) ; // GPIO 25
|
||||
#define SET_TP2 GPOS = (1 << 25);
|
||||
#define CLR_TP2 GPOC = (1 << 25);
|
||||
#define MODE_TP3 pinMode( 26,OUTPUT ) ; // GPIO 26
|
||||
#define SET_TP3 GPOS = (1 << 26);
|
||||
#define CLR_TP3 GPOC = (1 << 26);
|
||||
#define MODE_TP4 pinMode( 27,OUTPUT ) ; // GPIO 27
|
||||
#define SET_TP4 GPOC = (1 << 27);
|
||||
#define CLR_TP4 GPOC = (1 << 27);
|
||||
|
||||
|
||||
//#elif defined(__AVR_ATmega128__) ||defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__)
|
||||
@@ -230,8 +245,12 @@ struct countOf_t countOf;
|
||||
|
||||
#if defined ( __STM32F1__ )
|
||||
static ExtIntTriggerMode ISREdge;
|
||||
#elif defined ( ESP32 )
|
||||
static byte ISREdge; // Holder of the Next Edge we're looking for: RISING or FALLING
|
||||
static byte ISRWatch; // Interrupt Handler Edge Filter
|
||||
#else
|
||||
static byte ISREdge; // RISING or FALLING
|
||||
static byte ISREdge; // Holder of the Next Edge we're looking for: RISING or FALLING
|
||||
static byte ISRWatch; // Interrupt Handler Edge Filter
|
||||
#endif
|
||||
static word bitMax, bitMin;
|
||||
|
||||
@@ -287,12 +306,43 @@ DCC_PROCESSOR_STATE ;
|
||||
|
||||
DCC_PROCESSOR_STATE DccProcState ;
|
||||
|
||||
#ifdef ESP32
|
||||
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
void IRAM_ATTR ExternalInterruptHandler(void)
|
||||
#elif defined(ESP8266)
|
||||
void ICACHE_RAM_ATTR ExternalInterruptHandler(void)
|
||||
#else
|
||||
void ExternalInterruptHandler(void)
|
||||
#endif
|
||||
{
|
||||
#ifdef ESP32
|
||||
// switch (ISRWatch)
|
||||
// {
|
||||
// case RISING: if (digitalRead(DccProcState.ExtIntPinNum)) break;
|
||||
// case FALLING: if (digitalRead(DccProcState.ExtIntPinNum)) return; break;
|
||||
// }
|
||||
// First compare the edge we're looking for to the pin state
|
||||
switch (ISRWatch)
|
||||
{
|
||||
case CHANGE:
|
||||
break;
|
||||
|
||||
case RISING:
|
||||
if (digitalRead(DccProcState.ExtIntPinNum) != HIGH)
|
||||
return;
|
||||
break;
|
||||
|
||||
case FALLING:
|
||||
if (digitalRead(DccProcState.ExtIntPinNum) != LOW)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
// Bit evaluation without Timer 0 ------------------------------
|
||||
uint8_t DccBitVal;
|
||||
static int8_t bit1, bit2 ;
|
||||
static word lastMicros;
|
||||
static word lastMicros = 0;
|
||||
static byte halfBit, DCC_IrqRunning;
|
||||
unsigned int actMicros, bitMicros;
|
||||
if ( DCC_IrqRunning ) {
|
||||
@@ -336,10 +386,15 @@ void ExternalInterruptHandler(void)
|
||||
DccRx.State = WAIT_START_BIT ;
|
||||
// While waiting for the start bit, detect halfbit lengths. We will detect the correct
|
||||
// sync and detect whether we see a false (e.g. motorola) protocol
|
||||
|
||||
#if defined ( __STM32F1__ )
|
||||
detachInterrupt( DccProcState.ExtIntNum );
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
ISRWatch = CHANGE;
|
||||
#else
|
||||
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, CHANGE);
|
||||
#endif
|
||||
halfBit = 0;
|
||||
bitMax = MAX_ONEBITHALF;
|
||||
bitMin = MIN_ONEBITHALF;
|
||||
@@ -383,10 +438,15 @@ void ExternalInterruptHandler(void)
|
||||
bitMin = MIN_ONEBITFULL;
|
||||
DccRx.BitCount = 0;
|
||||
SET_TP4;
|
||||
|
||||
#if defined ( __STM32F1__ )
|
||||
detachInterrupt( DccProcState.ExtIntNum );
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
ISRWatch = ISREdge;
|
||||
#else
|
||||
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge );
|
||||
#endif
|
||||
SET_TP3;
|
||||
CLR_TP4;
|
||||
}
|
||||
@@ -422,10 +482,15 @@ void ExternalInterruptHandler(void)
|
||||
DccRx.TempByte = 0 ;
|
||||
}
|
||||
SET_TP4;
|
||||
|
||||
#if defined ( __STM32F1__ )
|
||||
detachInterrupt( DccProcState.ExtIntNum );
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
ISRWatch = ISREdge;
|
||||
#else
|
||||
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge );
|
||||
#endif
|
||||
CLR_TP1;
|
||||
CLR_TP4;
|
||||
break;
|
||||
@@ -454,10 +519,16 @@ void ExternalInterruptHandler(void)
|
||||
|
||||
CLR_TP1;
|
||||
SET_TP4;
|
||||
|
||||
#if defined ( __STM32F1__ )
|
||||
detachInterrupt( DccProcState.ExtIntNum );
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
ISRWatch = ISREdge;
|
||||
#else
|
||||
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge );
|
||||
#endif
|
||||
|
||||
CLR_TP4;
|
||||
break;
|
||||
|
||||
@@ -495,8 +566,14 @@ void ExternalInterruptHandler(void)
|
||||
DccRx.State = WAIT_PREAMBLE ;
|
||||
bitMax = MAX_PRAEAMBEL;
|
||||
bitMin = MIN_ONEBITFULL;
|
||||
#ifdef ESP32
|
||||
portENTER_CRITICAL_ISR(&mux);
|
||||
#endif
|
||||
DccRx.PacketCopy = DccRx.PacketBuf ;
|
||||
DccRx.DataReady = 1 ;
|
||||
#ifdef ESP32
|
||||
portEXIT_CRITICAL_ISR(&mux);
|
||||
#endif
|
||||
SET_TP3;
|
||||
}
|
||||
else // Get next Byte
|
||||
@@ -536,6 +613,9 @@ void writeEEPROM( unsigned int CV, uint8_t Value ) {
|
||||
#if defined(ESP8266)
|
||||
EEPROM.commit();
|
||||
#endif
|
||||
#if defined(ESP32)
|
||||
EEPROM.commit();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool readyEEPROM() {
|
||||
@@ -581,11 +661,14 @@ uint8_t writeCV( unsigned int CV, uint8_t Value)
|
||||
{
|
||||
switch( CV )
|
||||
{
|
||||
case CV_29_CONFIG:
|
||||
// copy addressmode Bit to Flags
|
||||
DccProcState.Flags = ( DccProcState.Flags & ~FLAGS_CV29_BITS) | (Value & FLAGS_CV29_BITS);
|
||||
// no break, because myDccAdress must also be reset
|
||||
case CV_ACCESSORY_DECODER_ADDRESS_LSB: // Also same CV for CV_MULTIFUNCTION_PRIMARY_ADDRESS
|
||||
case CV_ACCESSORY_DECODER_ADDRESS_MSB:
|
||||
case CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB:
|
||||
case CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB:
|
||||
case CV_29_CONFIG:
|
||||
DccProcState.myDccAddress = -1; // Assume any CV Write Operation might change the Address
|
||||
}
|
||||
|
||||
@@ -598,7 +681,11 @@ uint8_t writeCV( unsigned int CV, uint8_t Value)
|
||||
|
||||
if( notifyCVChange )
|
||||
notifyCVChange( CV, Value) ;
|
||||
|
||||
if( notifyDccCVChange && !(DccProcState.Flags & FLAGS_SETCV_CALLED) )
|
||||
notifyDccCVChange( CV, Value );
|
||||
}
|
||||
|
||||
return readEEPROM( CV ) ;
|
||||
}
|
||||
|
||||
@@ -882,11 +969,10 @@ void processServiceModeOperation( DCC_MSG * pDccMsg )
|
||||
{
|
||||
uint16_t CVAddr ;
|
||||
uint8_t Value ;
|
||||
|
||||
if( pDccMsg->Size == 3) // 3 Byte Packets are for Address Only, Register and Paged Mode
|
||||
{
|
||||
uint8_t RegisterAddr ;
|
||||
|
||||
DB_PRINT("3-BytePkt");
|
||||
RegisterAddr = pDccMsg->Data[0] & 0x07 ;
|
||||
Value = pDccMsg->Data[1] ;
|
||||
|
||||
@@ -929,6 +1015,7 @@ void processServiceModeOperation( DCC_MSG * pDccMsg )
|
||||
|
||||
else if( pDccMsg->Size == 4) // 4 Byte Packets are for Direct Byte & Bit Mode
|
||||
{
|
||||
DB_PRINT("BB-Mode");
|
||||
CVAddr = ( ( ( pDccMsg->Data[0] & 0x03 ) << 8 ) | pDccMsg->Data[1] ) + 1 ;
|
||||
Value = pDccMsg->Data[2] ;
|
||||
|
||||
@@ -1048,46 +1135,48 @@ void execDccProcessor( DCC_MSG * pDccMsg )
|
||||
{
|
||||
if( DccProcState.Flags & FLAGS_DCC_ACCESSORY_DECODER )
|
||||
{
|
||||
uint16_t BoardAddress ;
|
||||
uint16_t OutputAddress ;
|
||||
int16_t BoardAddress ;
|
||||
int16_t OutputAddress ;
|
||||
uint8_t TurnoutPairIndex ;
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
SerialPrintPacketHex(F( "execDccProcessor: Accessory Decoder Command: "), pDccMsg);
|
||||
SerialPrintPacketHex(F( "eDP: AccCmd: "), pDccMsg);
|
||||
#endif
|
||||
|
||||
BoardAddress = ( ( (~pDccMsg->Data[1]) & 0b01110000 ) << 2 ) | ( pDccMsg->Data[0] & 0b00111111 ) ;
|
||||
DB_PRINT("execDccProcessor: Board Addr: %d", BoardAddress);
|
||||
TurnoutPairIndex = (pDccMsg->Data[1] & 0b00000110) >> 1;
|
||||
DB_PRINT("eDP: BAddr:%d, Index:%d", BoardAddress, TurnoutPairIndex);
|
||||
|
||||
// First check for Legacy Accessory Decoder Configuration Variable Access Instruction
|
||||
// as it's got a different format to the others
|
||||
if((pDccMsg->Size == 5) && ((pDccMsg->Data[1] & 0b10001100) == 0b00001100))
|
||||
{
|
||||
DB_PRINT( "execDccProcessor: Legacy Accessory Decoder CV Access Command");
|
||||
DB_PRINT( "eDP: Legacy Accessory Decoder CV Access Command");
|
||||
// Check if this command is for our address or the broadcast address
|
||||
if((BoardAddress != getMyAddr()) && ( BoardAddress < 511 ))
|
||||
{
|
||||
DB_PRINT("execDccProcessor: Board Address Not Matched");
|
||||
DB_PRINT("eDP: Board Address Not Matched");
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t cvAddress = ((pDccMsg->Data[1] & 0b00000011) << 8) + pDccMsg->Data[2] + 1;
|
||||
uint8_t cvValue = pDccMsg->Data[3];
|
||||
DB_PRINT("execDccProcessor: CV: %d Value: %d", cvAddress, cvValue );
|
||||
DB_PRINT("eDP: CV:%d Value:%d", cvAddress, cvValue );
|
||||
if(validCV( cvAddress, 1 ))
|
||||
writeCV(cvAddress, cvValue);
|
||||
return;
|
||||
}
|
||||
|
||||
TurnoutPairIndex = (pDccMsg->Data[1] & 0b00000110) >> 1;
|
||||
|
||||
OutputAddress = (((BoardAddress - 1) << 2 ) | TurnoutPairIndex) + 1 ; //decoder output addresses start with 1, packet address range starts with 0
|
||||
// ( according to NMRA 9.2.2 )
|
||||
DB_PRINT("eDP: OAddr:%d", OutputAddress);
|
||||
|
||||
if( DccProcState.inAccDecDCCAddrNextReceivedMode)
|
||||
{
|
||||
if( DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE )
|
||||
{
|
||||
DB_PRINT("execDccProcessor: Set Output Addr: %d", OutputAddress);
|
||||
DB_PRINT("eDP: Set OAddr:%d", OutputAddress);
|
||||
//uint16_t storedOutputAddress = OutputAddress + 1; // The value stored in CV1 & 9 for Output Addressing Mode is + 1
|
||||
writeCV(CV_ACCESSORY_DECODER_ADDRESS_LSB, (uint8_t)(OutputAddress % 256));
|
||||
writeCV(CV_ACCESSORY_DECODER_ADDRESS_MSB, (uint8_t)(OutputAddress / 256));
|
||||
@@ -1097,7 +1186,7 @@ void execDccProcessor( DCC_MSG * pDccMsg )
|
||||
}
|
||||
else
|
||||
{
|
||||
DB_PRINT("execDccProcessor: Set Board Addr: %d", BoardAddress);
|
||||
DB_PRINT("eDP: Set BAddr:%d", BoardAddress);
|
||||
writeCV(CV_ACCESSORY_DECODER_ADDRESS_LSB, (uint8_t)(BoardAddress % 64));
|
||||
writeCV(CV_ACCESSORY_DECODER_ADDRESS_MSB, (uint8_t)(BoardAddress / 64));
|
||||
|
||||
@@ -1111,21 +1200,34 @@ void execDccProcessor( DCC_MSG * pDccMsg )
|
||||
// If we're filtering addresses, does the address match our address or is it a broadcast address? If NOT then return
|
||||
if( DccProcState.Flags & FLAGS_MY_ADDRESS_ONLY )
|
||||
{
|
||||
if( ( DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE ) && ( OutputAddress != getMyAddr() ) && ( OutputAddress < 2045 ) )
|
||||
if( DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE ) {
|
||||
DB_PRINT(" AddrChk: OAddr:%d, BAddr:%d, myAddr:%d Chk=%d", OutputAddress, BoardAddress, getMyAddr(), OutputAddress != getMyAddr() );
|
||||
if ( OutputAddress != getMyAddr() && OutputAddress < 2045 ) {
|
||||
DB_PRINT(" eDP: OAddr:%d, myAddr:%d - no match", OutputAddress, getMyAddr() );
|
||||
return;
|
||||
|
||||
else if( ( BoardAddress != getMyAddr() ) && ( BoardAddress < 511 ) )
|
||||
return;
|
||||
|
||||
DB_PRINT("execDccProcessor: Address Matched");
|
||||
}
|
||||
} else {
|
||||
if( ( BoardAddress != getMyAddr() ) && ( BoardAddress < 511 ) ) {
|
||||
DB_PRINT(" eDP: BAddr:%d, myAddr:%d - no match", BoardAddress, getMyAddr() );
|
||||
return;
|
||||
}
|
||||
}
|
||||
DB_PRINT("eDP: Address Matched");
|
||||
}
|
||||
|
||||
|
||||
if((pDccMsg->Size == 4) && ((pDccMsg->Data[1] & 0b10001001) == 1)) // Extended Accessory Decoder Control Packet Format
|
||||
{
|
||||
uint8_t state = pDccMsg->Data[2] ;// & 0b00011111;
|
||||
DB_PRINT("execDccProcessor: Output Addr: %d Extended State: %0X", OutputAddress, state);
|
||||
// According to the NMRA Dcc Spec the Signal State should only use the lower 5 Bits,
|
||||
// however some manufacturers seem to allow/use all 8 bits, so we'll relax that constraint for now
|
||||
uint8_t state = pDccMsg->Data[2] ;
|
||||
DB_PRINT("eDP: OAddr:%d Extended State:%0X", OutputAddress, state);
|
||||
if( notifyDccSigOutputState )
|
||||
notifyDccSigOutputState(OutputAddress, state);
|
||||
|
||||
// old callback ( for compatibility with 1.4.2, not to be used in new designs )
|
||||
if( notifyDccSigState )
|
||||
notifyDccSigState( OutputAddress, TurnoutPairIndex, pDccMsg->Data[2] ) ;
|
||||
}
|
||||
|
||||
else if(pDccMsg->Size == 3) // Basic Accessory Decoder Packet Format
|
||||
@@ -1133,49 +1235,49 @@ void execDccProcessor( DCC_MSG * pDccMsg )
|
||||
uint8_t direction = pDccMsg->Data[1] & 0b00000001;
|
||||
uint8_t outputPower = (pDccMsg->Data[1] & 0b00001000) >> 3;
|
||||
|
||||
// for compatibility with 1.4.2
|
||||
// old callback ( for compatibility with 1.4.2, not to be used in new designs )
|
||||
if ( notifyDccAccState )
|
||||
notifyDccAccState( OutputAddress, BoardAddress, pDccMsg->Data[1] & 0b00000111, outputPower );
|
||||
|
||||
if( DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE )
|
||||
{
|
||||
DB_PRINT("execDccProcessor: Output Addr: %d Turnout Dir: %d Output Power: %d", OutputAddress, direction, outputPower);
|
||||
DB_PRINT("eDP: OAddr:%d Turnout Dir:%d Output Power:%d", OutputAddress, direction, outputPower);
|
||||
if( notifyDccAccTurnoutOutput )
|
||||
notifyDccAccTurnoutOutput( OutputAddress, direction, outputPower );
|
||||
}
|
||||
else
|
||||
{
|
||||
DB_PRINT("execDccProcessor: Turnout Pair Index: %d Dir: %d Output Power: ", TurnoutPairIndex, direction, outputPower);
|
||||
DB_PRINT("eDP: Turnout Pair Index:%d Dir:%d Output Power: ", TurnoutPairIndex, direction, outputPower);
|
||||
if( notifyDccAccTurnoutBoard )
|
||||
notifyDccAccTurnoutBoard( BoardAddress, TurnoutPairIndex, direction, outputPower );
|
||||
}
|
||||
}
|
||||
else if(pDccMsg->Size == 6) // Accessory Decoder OPS Mode Programming
|
||||
{
|
||||
DB_PRINT("execDccProcessor: OPS Mode CV Programming Command");
|
||||
DB_PRINT("eDP: OPS Mode CV Programming Command");
|
||||
// Check for unsupported OPS Mode Addressing mode
|
||||
if(((pDccMsg->Data[1] & 0b10001001) != 1) && ((pDccMsg->Data[1] & 0b10001111) != 0x80))
|
||||
{
|
||||
DB_PRINT("execDccProcessor: Unsupported OPS Mode CV Addressing Mode");
|
||||
DB_PRINT("eDP: Unsupported OPS Mode CV Addressing Mode");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if this command is for our address or the broadcast address
|
||||
if(DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE)
|
||||
{
|
||||
DB_PRINT("execDccProcessor: Check Output Address: %d", OutputAddress);
|
||||
DB_PRINT("eDP: Check Output Address:%d", OutputAddress);
|
||||
if((OutputAddress != getMyAddr()) && ( OutputAddress < 2045 ))
|
||||
{
|
||||
DB_PRINT("execDccProcessor: Output Address Not Matched");
|
||||
DB_PRINT("eDP: Output Address Not Matched");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DB_PRINT("execDccProcessor: Check Board Address: %d", BoardAddress);
|
||||
DB_PRINT("eDP: Check Board Address:%d", BoardAddress);
|
||||
if((BoardAddress != getMyAddr()) && ( BoardAddress < 511 ))
|
||||
{
|
||||
DB_PRINT("execDccProcessor: Board Address Not Matched");
|
||||
DB_PRINT("eDP: Board Address Not Matched");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1185,16 +1287,16 @@ void execDccProcessor( DCC_MSG * pDccMsg )
|
||||
|
||||
OpsInstructionType insType = (OpsInstructionType)((pDccMsg->Data[2] & 0b00001100) >> 2) ;
|
||||
|
||||
DB_PRINT("execDccProcessor: OPS Mode Instruction: %d", insType);
|
||||
DB_PRINT("eDP: OPS Mode Instruction:%d", insType);
|
||||
switch(insType)
|
||||
{
|
||||
case OPS_INS_RESERVED:
|
||||
case OPS_INS_VERIFY_BYTE:
|
||||
DB_PRINT("execDccProcessor: Unsupported OPS Mode Instruction: %d", insType);
|
||||
DB_PRINT("eDP: Unsupported OPS Mode Instruction:%d", insType);
|
||||
break; // We only support Write Byte or Bit Manipulation
|
||||
|
||||
case OPS_INS_WRITE_BYTE:
|
||||
DB_PRINT("execDccProcessor: CV: %d Value: %d", cvAddress, cvValue);
|
||||
DB_PRINT("eDP: CV:%d Value:%d", cvAddress, cvValue);
|
||||
if(validCV( cvAddress, 1 ))
|
||||
writeCV(cvAddress, cvValue);
|
||||
break;
|
||||
@@ -1212,9 +1314,9 @@ void execDccProcessor( DCC_MSG * pDccMsg )
|
||||
uint8_t currentValue = readCV(cvAddress);
|
||||
uint8_t newValueMask = 1 << (cvValue & 0b00000111);
|
||||
if(cvValue & 0b00001000)
|
||||
writeCV(cvAddress, cvValue | newValueMask);
|
||||
writeCV(cvAddress, currentValue | newValueMask);
|
||||
else
|
||||
writeCV(cvAddress, cvValue & ~newValueMask);
|
||||
writeCV(cvAddress, currentValue & ~newValueMask);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1243,6 +1345,13 @@ NmraDcc::NmraDcc()
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef digitalPinToInterrupt
|
||||
void NmraDcc::pin( uint8_t ExtIntPinNum, uint8_t EnablePullup)
|
||||
{
|
||||
pin(digitalPinToInterrupt(ExtIntPinNum), ExtIntPinNum, EnablePullup);
|
||||
}
|
||||
#endif
|
||||
|
||||
void NmraDcc::pin( uint8_t ExtIntNum, uint8_t ExtIntPinNum, uint8_t EnablePullup)
|
||||
{
|
||||
#if defined ( __STM32F1__ )
|
||||
@@ -1270,6 +1379,9 @@ void NmraDcc::init( uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, ui
|
||||
#if defined(ESP8266)
|
||||
EEPROM.begin(MAXCV);
|
||||
#endif
|
||||
#if defined(ESP32)
|
||||
EEPROM.begin(MAXCV);
|
||||
#endif
|
||||
// Clear all the static member variables
|
||||
memset( &DccRx, 0, sizeof( DccRx) );
|
||||
|
||||
@@ -1277,20 +1389,27 @@ void NmraDcc::init( uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, ui
|
||||
MODE_TP2;
|
||||
MODE_TP3;
|
||||
MODE_TP4;
|
||||
ISREdge = RISING;
|
||||
bitMax = MAX_ONEBITFULL;
|
||||
bitMin = MIN_ONEBITFULL;
|
||||
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, RISING);
|
||||
|
||||
DccProcState.Flags = Flags ;
|
||||
DccProcState.OpsModeAddressBaseCV = OpsModeAddressBaseCV ;
|
||||
DccProcState.myDccAddress = -1;
|
||||
DccProcState.inAccDecDCCAddrNextReceivedMode = 0;
|
||||
|
||||
ISREdge = RISING;
|
||||
|
||||
#ifdef ESP32
|
||||
ISRWatch = ISREdge;
|
||||
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, CHANGE);
|
||||
#else
|
||||
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, RISING);
|
||||
#endif
|
||||
|
||||
// Set the Bits that control Multifunction or Accessory behaviour
|
||||
// and if the Accessory decoder optionally handles Output Addressing
|
||||
uint8_t cv29Mask = CV29_ACCESSORY_DECODER | CV29_OUTPUT_ADDRESS_MODE ; // peal off the top two bits
|
||||
writeCV( CV_29_CONFIG, ( readCV( CV_29_CONFIG ) & ~cv29Mask ) | (Flags & cv29Mask) ) ;
|
||||
// we need to peal off the top two bits
|
||||
writeCV( CV_29_CONFIG, ( readCV( CV_29_CONFIG ) & ~FLAGS_CV29_BITS ) | (Flags & FLAGS_CV29_BITS) ) ;
|
||||
|
||||
uint8_t doAutoFactoryDefault = 0;
|
||||
if((Flags & FLAGS_AUTO_FACTORY_DEFAULT) && (readCV(CV_VERSION_ID) == 255) && (readCV(CV_MANUFACTURER_ID) == 255))
|
||||
@@ -1314,7 +1433,13 @@ uint8_t NmraDcc::getCV( uint16_t CV )
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
uint8_t NmraDcc::setCV( uint16_t CV, uint8_t Value)
|
||||
{
|
||||
return writeCV(CV,Value);
|
||||
DccProcState.Flags |= FLAGS_SETCV_CALLED;
|
||||
|
||||
uint8_t returnValue = writeCV(CV,Value);
|
||||
|
||||
DccProcState.Flags &= ~FLAGS_SETCV_CALLED;
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -1384,10 +1509,19 @@ uint8_t NmraDcc::process()
|
||||
{
|
||||
// We need to do this check with interrupts disabled
|
||||
//SET_TP4;
|
||||
#ifdef ESP32
|
||||
portENTER_CRITICAL(&mux);
|
||||
#else
|
||||
noInterrupts();
|
||||
#endif
|
||||
Msg = DccRx.PacketCopy ;
|
||||
DccRx.DataReady = 0 ;
|
||||
|
||||
#ifdef ESP32
|
||||
portEXIT_CRITICAL(&mux);
|
||||
#else
|
||||
interrupts();
|
||||
#endif
|
||||
#ifdef DCC_DBGVAR
|
||||
countOf.Tel++;
|
||||
#endif
|
||||
@@ -1398,6 +1532,7 @@ uint8_t NmraDcc::process()
|
||||
xorValue ^= DccRx.PacketCopy.Data[i];
|
||||
if(xorValue) {
|
||||
#ifdef DCC_DBGVAR
|
||||
DB_PRINT("Cerr");
|
||||
countOf.Err++;
|
||||
#endif
|
||||
return 0 ;
|
||||
|
||||
53
NmraDcc.h
53
NmraDcc.h
@@ -32,7 +32,7 @@
|
||||
// Uncomment the following Line to Enable Service Mode CV Programming
|
||||
#define NMRA_DCC_PROCESS_SERVICEMODE
|
||||
|
||||
// Uncomment the following line to Enable MutliFunction Decoder Operations
|
||||
// Uncomment the following line to Enable MultiFunction Decoder Operations
|
||||
#define NMRA_DCC_PROCESS_MULTIFUNCTION
|
||||
|
||||
// Uncomment the following line to Enable 14 Speed Step Support
|
||||
@@ -49,7 +49,7 @@
|
||||
#ifndef NMRADCC_IS_IN
|
||||
#define NMRADCC_IS_IN
|
||||
|
||||
#define NMRADCC_VERSION 200 // Version 2.0.0
|
||||
#define NMRADCC_VERSION 201 // Version 2.0.1
|
||||
|
||||
#define MAX_DCC_MESSAGE_LEN 6 // including XOR-Byte
|
||||
|
||||
@@ -96,14 +96,17 @@ typedef struct
|
||||
#define CV_MANUFACTURER_ID 8
|
||||
#define CV_29_CONFIG 29
|
||||
|
||||
#if defined(ESP8266)
|
||||
#include <spi_flash.h>
|
||||
#define MAXCV SPI_FLASH_SEC_SIZE
|
||||
#if defined(ESP32)
|
||||
#include <esp_log.h>
|
||||
#define MAXCV SPI_FLASH_SEC_SIZE
|
||||
#elif defined(ESP8266)
|
||||
#include <spi_flash.h>
|
||||
#define MAXCV SPI_FLASH_SEC_SIZE
|
||||
#elif defined( __STM32F1__)
|
||||
#define MAXCV (EEPROM_PAGE_SIZE/4 - 1) // number of storage places (CV address could be larger
|
||||
#define MAXCV (EEPROM_PAGE_SIZE/4 - 1) // number of storage places (CV address could be larger
|
||||
// because STM32 uses virtual adresses)
|
||||
#else
|
||||
#define MAXCV E2END // the upper limit of the CV value currently defined to max memory.
|
||||
#define MAXCV E2END // the upper limit of the CV value currently defined to max memory.
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
@@ -202,9 +205,14 @@ class NmraDcc
|
||||
// Flag values to be logically ORed together and passed into the init() method
|
||||
#define FLAGS_MY_ADDRESS_ONLY 0x01 // Only process DCC Packets with My Address
|
||||
#define FLAGS_AUTO_FACTORY_DEFAULT 0x02 // Call notifyCVResetFactoryDefault() if CV 7 & 8 == 255
|
||||
#define FLAGS_SETCV_CALLED 0x10 // only used internally !!
|
||||
#define FLAGS_OUTPUT_ADDRESS_MODE 0x40 // CV 29/541 bit 6
|
||||
#define FLAGS_DCC_ACCESSORY_DECODER 0x80 // CV 29/541 bit 7
|
||||
|
||||
// Flag Bits that are cloned from CV29 relating the DCC Accessory Decoder
|
||||
#define FLAGS_CV29_BITS (FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER)
|
||||
|
||||
|
||||
/*+
|
||||
* pin() is called from setup() and sets up the pin used to receive DCC packets.
|
||||
*
|
||||
@@ -218,6 +226,21 @@ class NmraDcc
|
||||
*/
|
||||
void pin( uint8_t ExtIntNum, uint8_t ExtIntPinNum, uint8_t EnablePullup);
|
||||
|
||||
/*+
|
||||
* pin() is called from setup() and sets up the pin used to receive DCC packets.
|
||||
* This relies on the internal function: digitalPinToInterrupt() to map the input pin number to the right interrupt
|
||||
*
|
||||
* Inputs:
|
||||
* ExtIntPinNum - Input pin number.
|
||||
* EnablePullup - Set true to enable the pins pullup resistor.
|
||||
*
|
||||
* Returns:
|
||||
* None.
|
||||
*/
|
||||
#ifdef digitalPinToInterrupt
|
||||
void pin( uint8_t ExtIntPinNum, uint8_t EnablePullup);
|
||||
#endif
|
||||
|
||||
/*+
|
||||
* init() is called from setup() after the pin() command is called.
|
||||
* It initializes the NmDcc object and makes it ready to process packets.
|
||||
@@ -630,6 +653,8 @@ extern uint8_t notifyIsSetCVReady(void) __attribute__ ((weak));
|
||||
/*+
|
||||
* notifyCVChange() Called when a CV value is changed.
|
||||
* This is called whenever a CV's value is changed.
|
||||
* notifyDccCVChange() Called only when a CV value is changed by a Dcc packet or a internal lib function.
|
||||
* it is NOT called if the CV is changed by means of the setCV() method.
|
||||
* Note: It is not called if notifyCVWrite() is defined
|
||||
* or if the value in the EEPROM is the same as the value
|
||||
* in the write command.
|
||||
@@ -642,6 +667,7 @@ extern uint8_t notifyIsSetCVReady(void) __attribute__ ((weak));
|
||||
* None
|
||||
*/
|
||||
extern void notifyCVChange( uint16_t CV, uint8_t Value) __attribute__ ((weak));
|
||||
extern void notifyDccCVChange( uint16_t CV, uint8_t Value) __attribute__ ((weak));
|
||||
|
||||
/*+
|
||||
* notifyCVResetFactoryDefault() Called when CVs must be reset.
|
||||
@@ -672,10 +698,21 @@ extern void notifyCVResetFactoryDefault(void) __attribute__ ((weak));
|
||||
* None
|
||||
*/
|
||||
extern void notifyCVAck(void) __attribute__ ((weak));
|
||||
/*+
|
||||
* notifyServiceMode(bool) Called when state of 'inServiceMode' changes
|
||||
*
|
||||
* Inputs:
|
||||
* bool state of inServiceMode
|
||||
* *
|
||||
* Returns:
|
||||
* None
|
||||
*/
|
||||
extern void notifyServiceMode(bool) __attribute__ ((weak));
|
||||
|
||||
// Deprecated, only for backward compatibility with version 1.4.2. Don't use in new designs
|
||||
// Deprecated, only for backward compatibility with version 1.4.2.
|
||||
// Don't use in new designs. These functions may be dropped in future versions
|
||||
extern void notifyDccAccState( uint16_t Addr, uint16_t BoardAddr, uint8_t OutputAddr, uint8_t State ) __attribute__ ((weak));
|
||||
extern void notifyDccSigState( uint16_t Addr, uint8_t OutputIndex, uint8_t State) __attribute__ ((weak));
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,314 @@
|
||||
// NMRA Dcc Multifunction Motor Decoder Demo
|
||||
//
|
||||
// Author: Alex Shepherd 2019-03-30
|
||||
//
|
||||
// This example requires these Arduino Libraries:
|
||||
//
|
||||
// 1) The NmraDcc Library from: http://mrrwa.org/download/
|
||||
//
|
||||
// These libraries can be found and installed via the Arduino IDE Library Manager
|
||||
//
|
||||
// This is a simple demo of how to drive and motor speed and direction using PWM and a motor H-Bridge
|
||||
// It uses vStart and vHigh CV values to customise the PWM values to the motor response
|
||||
// It also uses the Headling Function to drive 2 LEDs for Directional Headlights
|
||||
// Apart from that there's nothing fancy like Lighting Effects or a function matrix or Speed Tables - its just the basics...
|
||||
//
|
||||
|
||||
#include <NmraDcc.h>
|
||||
// Uncomment any of the lines below to enable debug messages for different parts of the code
|
||||
//#define DEBUG_FUNCTIONS
|
||||
//#define DEBUG_SPEED
|
||||
//#define DEBUG_PWM
|
||||
//#define DEBUG_DCC_ACK
|
||||
//#define DEBUG_DCC_MSG
|
||||
|
||||
#if defined(DEBUG_FUNCTIONS) or defined(DEBUG_SPEED) or defined(DEBUG_PWM) or defined(DEBUG_DCC_ACK) or defined(DEBUG_DCC_MSG)
|
||||
#define DEBUG_PRINT
|
||||
#endif
|
||||
|
||||
// This is the default DCC Address
|
||||
#define DEFAULT_DECODER_ADDRESS 3
|
||||
|
||||
// This section defines the Arduino UNO Pins to use
|
||||
#ifdef __AVR_ATmega328P__
|
||||
|
||||
#define DCC_PIN 2
|
||||
|
||||
#define LED_PIN_FWD 5
|
||||
#define LED_PIN_REV 6
|
||||
#define MOTOR_DIR_PIN 12
|
||||
#define MOTOR_PWM_PIN 3
|
||||
|
||||
// This section defines the Arduino ATTiny85 Pins to use
|
||||
#elif ARDUINO_AVR_ATTINYX5
|
||||
|
||||
#define DCC_PIN 2
|
||||
|
||||
#define LED_PIN_FWD 0
|
||||
#define LED_PIN_REV 1
|
||||
#define MOTOR_DIR_PIN 3
|
||||
#define MOTOR_PWM_PIN 4
|
||||
|
||||
#else
|
||||
#error "Unsupported CPU, you need to add another configuration section for your CPU"
|
||||
#endif
|
||||
|
||||
// Some global state variables
|
||||
uint8_t newLedState = 0;
|
||||
uint8_t lastLedState = 0;
|
||||
|
||||
uint8_t newDirection = 0;
|
||||
uint8_t lastDirection = 0;
|
||||
|
||||
uint8_t newSpeed = 0;
|
||||
uint8_t lastSpeed = 0;
|
||||
uint8_t numSpeedSteps = SPEED_STEP_128;
|
||||
|
||||
uint8_t vStart;
|
||||
uint8_t vHigh;
|
||||
|
||||
// Structure for CV Values Table
|
||||
struct CVPair
|
||||
{
|
||||
uint16_t CV;
|
||||
uint8_t Value;
|
||||
};
|
||||
|
||||
// CV Addresses we will be using
|
||||
#define CV_VSTART 2
|
||||
#define CV_VHIGH 5
|
||||
|
||||
// Default CV Values Table
|
||||
CVPair FactoryDefaultCVs [] =
|
||||
{
|
||||
// The CV Below defines the Short DCC Address
|
||||
{CV_MULTIFUNCTION_PRIMARY_ADDRESS, DEFAULT_DECODER_ADDRESS},
|
||||
|
||||
// Three Step Speed Table
|
||||
{CV_VSTART, 120},
|
||||
{CV_VHIGH, 255},
|
||||
|
||||
// These two CVs define the Long DCC Address
|
||||
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0},
|
||||
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, DEFAULT_DECODER_ADDRESS},
|
||||
|
||||
// ONLY uncomment 1 CV_29_CONFIG line below as approprate
|
||||
// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps
|
||||
{CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps
|
||||
};
|
||||
|
||||
NmraDcc Dcc ;
|
||||
|
||||
uint8_t FactoryDefaultCVIndex = 0;
|
||||
|
||||
// This call-back function is called when a CV Value changes so we can update CVs we're using
|
||||
void notifyCVChange( uint16_t CV, uint8_t Value)
|
||||
{
|
||||
switch(CV)
|
||||
{
|
||||
case CV_VSTART:
|
||||
vStart = Value;
|
||||
break;
|
||||
|
||||
case CV_VHIGH:
|
||||
vHigh = Value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void notifyCVResetFactoryDefault()
|
||||
{
|
||||
// Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset
|
||||
// to flag to the loop() function that a reset to Factory Defaults needs to be done
|
||||
FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair);
|
||||
};
|
||||
|
||||
// This call-back function is called whenever we receive a DCC Speed packet for our address
|
||||
void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_DIRECTION Dir, DCC_SPEED_STEPS SpeedSteps )
|
||||
{
|
||||
#ifdef DEBUG_SPEED
|
||||
Serial.print("notifyDccSpeed: Addr: ");
|
||||
Serial.print(Addr,DEC);
|
||||
Serial.print( (AddrType == DCC_ADDR_SHORT) ? "-S" : "-L" );
|
||||
Serial.print(" Speed: ");
|
||||
Serial.print(Speed,DEC);
|
||||
Serial.print(" Steps: ");
|
||||
Serial.print(SpeedSteps,DEC);
|
||||
Serial.print(" Dir: ");
|
||||
Serial.println( (Dir == DCC_DIR_FWD) ? "Forward" : "Reverse" );
|
||||
#endif
|
||||
|
||||
newDirection = Dir;
|
||||
newSpeed = Speed;
|
||||
numSpeedSteps = SpeedSteps;
|
||||
};
|
||||
|
||||
// This call-back function is called whenever we receive a DCC Function packet for our address
|
||||
void notifyDccFunc(uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState)
|
||||
{
|
||||
#ifdef DEBUG_FUNCTIONS
|
||||
Serial.print("notifyDccFunc: Addr: ");
|
||||
Serial.print(Addr,DEC);
|
||||
Serial.print( (AddrType == DCC_ADDR_SHORT) ? 'S' : 'L' );
|
||||
Serial.print(" Function Group: ");
|
||||
Serial.print(FuncGrp,DEC);
|
||||
#endif
|
||||
|
||||
if(FuncGrp == FN_0_4)
|
||||
{
|
||||
newLedState = (FuncState & FN_BIT_00) ? 1 : 0;
|
||||
#ifdef DEBUG_FUNCTIONS
|
||||
Serial.print(" FN 0: ");
|
||||
Serial.print(newLedState);
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG_FUNCTIONS
|
||||
Serial.println();
|
||||
#endif
|
||||
}
|
||||
|
||||
// This call-back function is called whenever we receive a DCC Packet
|
||||
#ifdef DEBUG_DCC_MSG
|
||||
void notifyDccMsg( DCC_MSG * Msg)
|
||||
{
|
||||
Serial.print("notifyDccMsg: ") ;
|
||||
for(uint8_t i = 0; i < Msg->Size; i++)
|
||||
{
|
||||
Serial.print(Msg->Data[i], HEX);
|
||||
Serial.write(' ');
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
#endif
|
||||
|
||||
// This call-back function is called by the NmraDcc library when a DCC ACK needs to be sent
|
||||
// Calling this function should cause an increased 60ma current drain on the power supply for 6ms to ACK a CV Read
|
||||
// So we will just turn the motor on for 8ms and then turn it off again.
|
||||
|
||||
void notifyCVAck(void)
|
||||
{
|
||||
#ifdef DEBUG_DCC_ACK
|
||||
Serial.println("notifyCVAck") ;
|
||||
#endif
|
||||
|
||||
digitalWrite(MOTOR_DIR_PIN, HIGH);
|
||||
digitalWrite(MOTOR_PWM_PIN, HIGH);
|
||||
|
||||
delay( 8 );
|
||||
|
||||
digitalWrite(MOTOR_DIR_PIN, LOW);
|
||||
digitalWrite(MOTOR_PWM_PIN, LOW);
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
#ifdef DEBUG_PRINT
|
||||
Serial.begin(115200);
|
||||
Serial.println("NMRA Dcc Multifunction Motor Decoder Demo");
|
||||
#endif
|
||||
|
||||
// Setup the Pins for the Fwd/Rev LED for Function 0 Headlight
|
||||
pinMode(LED_PIN_FWD, OUTPUT);
|
||||
pinMode(LED_PIN_REV, OUTPUT);
|
||||
|
||||
// Setup the Pins for the Motor H-Bridge Driver
|
||||
pinMode(MOTOR_DIR_PIN, OUTPUT);
|
||||
pinMode(MOTOR_PWM_PIN, OUTPUT);
|
||||
|
||||
|
||||
// Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up
|
||||
Dcc.pin(DCC_PIN, 0);
|
||||
|
||||
Dcc.init( MAN_ID_DIY, 10, FLAGS_MY_ADDRESS_ONLY | FLAGS_AUTO_FACTORY_DEFAULT, 0 );
|
||||
|
||||
// Uncomment to force CV Reset to Factory Defaults
|
||||
// notifyCVResetFactoryDefault();
|
||||
|
||||
// Read the current CV values for vStart and vHigh
|
||||
vStart = Dcc.getCV(CV_VSTART);
|
||||
vHigh = Dcc.getCV(CV_VHIGH);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// You MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation
|
||||
Dcc.process();
|
||||
|
||||
// Handle Speed changes
|
||||
if(lastSpeed != newSpeed)
|
||||
{
|
||||
lastSpeed = newSpeed;
|
||||
|
||||
// Stop if speed = 0 or 1
|
||||
|
||||
if(newSpeed <= 1)
|
||||
digitalWrite(MOTOR_PWM_PIN, LOW);
|
||||
|
||||
// Calculate PWM value in the range 1..255
|
||||
else
|
||||
{
|
||||
uint8_t vScaleFactor;
|
||||
|
||||
if((vHigh > 1) && (vHigh > vStart))
|
||||
vScaleFactor = vHigh - vStart;
|
||||
else
|
||||
vScaleFactor = 255 - vStart;
|
||||
|
||||
uint8_t modSpeed = newSpeed - 1;
|
||||
uint8_t modSteps = numSpeedSteps - 1;
|
||||
|
||||
uint8_t newPwm = (uint8_t) vStart + modSpeed * vScaleFactor / modSteps;
|
||||
|
||||
#ifdef DEBUG_PWM
|
||||
Serial.print("New Speed: vStart: ");
|
||||
Serial.print(vStart);
|
||||
Serial.print(" vHigh: ");
|
||||
Serial.print(vHigh);
|
||||
Serial.print(" modSpeed: ");
|
||||
Serial.print(modSpeed);
|
||||
Serial.print(" vScaleFactor: ");
|
||||
Serial.print(vScaleFactor);
|
||||
Serial.print(" modSteps: ");
|
||||
Serial.print(modSteps);
|
||||
Serial.print(" newPwm: ");
|
||||
Serial.println(newPwm);
|
||||
#endif
|
||||
|
||||
analogWrite(MOTOR_PWM_PIN, newPwm);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle Direction and Headlight changes
|
||||
if((lastDirection != newDirection) || (lastLedState != newLedState))
|
||||
{
|
||||
lastDirection = newDirection;
|
||||
lastLedState = newLedState;
|
||||
|
||||
digitalWrite(MOTOR_DIR_PIN, newDirection);
|
||||
|
||||
if(newLedState)
|
||||
{
|
||||
#ifdef DEBUG_FUNCTIONS
|
||||
Serial.println("LED On");
|
||||
#endif
|
||||
digitalWrite(LED_PIN_FWD, newDirection ? LOW : HIGH);
|
||||
digitalWrite(LED_PIN_REV, newDirection ? HIGH : LOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG_FUNCTIONS
|
||||
Serial.println("LED Off");
|
||||
#endif
|
||||
digitalWrite(LED_PIN_FWD, LOW);
|
||||
digitalWrite(LED_PIN_REV, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle resetting CVs back to Factory Defaults
|
||||
if( FactoryDefaultCVIndex && Dcc.isSetCVReady())
|
||||
{
|
||||
FactoryDefaultCVIndex--; // Decrement first as initially it is the size of the array
|
||||
Dcc.setCV( FactoryDefaultCVs[FactoryDefaultCVIndex].CV, FactoryDefaultCVs[FactoryDefaultCVIndex].Value);
|
||||
}
|
||||
}
|
||||
13
examples/SMA/AccDec_10Servos_7LED_6Ftn/AccDec_10Servos_7LED_6Ftn.ino
Executable file → Normal file
13
examples/SMA/AccDec_10Servos_7LED_6Ftn/AccDec_10Servos_7LED_6Ftn.ino
Executable file → Normal file
@@ -1,5 +1,5 @@
|
||||
// Production 17 Switch Acessory DCC Decoder AccDec_10Servos_7LED_6Ftn.ino
|
||||
// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Version 6.01 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Now works with both short and long DCC Addesses for CV Control Default 24 (LSB CV 121 ; MSB CV 122)
|
||||
// ACCESSORY DECODER DEFAULT ADDRESS IS 40 (MAX 40-56 SWITCHES)
|
||||
// ACCESSRY DECODER ADDRESS CAN NOW BE SET ABOVE 255
|
||||
@@ -82,11 +82,14 @@ CVPair FactoryDefaultCVs [] =
|
||||
|
||||
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0},
|
||||
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0},
|
||||
|
||||
// Speed Steps don't matter for this decoder
|
||||
// ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS
|
||||
// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps
|
||||
{CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps
|
||||
{CV_29_CONFIG,CV29_ACCESSORY_DECODER|CV29_OUTPUT_ADDRESS_MODE|CV29_F0_LOCATION}, // Accesory Decoder Short Address
|
||||
// {CV_29_CONFIG, CV29_ACCESSORY_DECODER|CV29_OUTPUT_ADDRESS_MODE|CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Accesory Decoder Long Address
|
||||
|
||||
{CV_DECODER_MASTER_RESET, 0},
|
||||
{CV_To_Store_SET_CV_Address, SET_CV_Address&0xFF }, // LSB Set CV Address
|
||||
@@ -216,7 +219,7 @@ void setup() //******************************************************
|
||||
// Setup which External Interrupt, the Pin it's associated with that we're using
|
||||
Dcc.pin(0, 2, 0);
|
||||
// Call the main DCC Init function to enable the DCC Receiver
|
||||
Dcc.init( MAN_ID_DIY, 100, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address);
|
||||
Dcc.init( MAN_ID_DIY, 601, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address);
|
||||
delay(800);
|
||||
|
||||
#if defined(DECODER_LOADED)
|
||||
|
||||
13
examples/SMA/AccDec_13Servos_4LED_6Ftn/AccDec_13Servos_4LED_6Ftn.ino
Executable file → Normal file
13
examples/SMA/AccDec_13Servos_4LED_6Ftn/AccDec_13Servos_4LED_6Ftn.ino
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
// Production 17 Function DCC Decoder
|
||||
// Production 17 Switch Acessory DCC Decoder AccDec_13Servos_4LED_6Ftn.ino
|
||||
// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Version 6.01 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Now works with both short and long DCC Addesses for CV Control Default 24 (LSB CV 121 ; MSB CV 122)
|
||||
// ACCESSORY DECODER DEFAULT ADDRESS IS 40 (MAX 40-56 SWITCHES)
|
||||
// ACCESSRY DECODER ADDRESS CAN NOW BE SET ABOVE 255
|
||||
@@ -82,11 +82,14 @@ CVPair FactoryDefaultCVs [] =
|
||||
|
||||
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0},
|
||||
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0},
|
||||
|
||||
// Speed Steps don't matter for this decoder
|
||||
// ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS
|
||||
// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps
|
||||
{CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps
|
||||
{CV_29_CONFIG,CV29_ACCESSORY_DECODER|CV29_OUTPUT_ADDRESS_MODE|CV29_F0_LOCATION}, // Accesory Decoder Short Address
|
||||
// {CV_29_CONFIG, CV29_ACCESSORY_DECODER|CV29_OUTPUT_ADDRESS_MODE|CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Accesory Decoder Long Address
|
||||
|
||||
{CV_DECODER_MASTER_RESET, 0},
|
||||
{CV_To_Store_SET_CV_Address, SET_CV_Address&0xFF }, // LSB Set CV Address
|
||||
@@ -217,7 +220,7 @@ void setup() //******************************************************
|
||||
// Setup which External Interrupt, the Pin it's associated with that we're using
|
||||
Dcc.pin(0, 2, 0);
|
||||
// Call the main DCC Init function to enable the DCC Receiver
|
||||
Dcc.init( MAN_ID_DIY, 600, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address);
|
||||
Dcc.init( MAN_ID_DIY, 601, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address);
|
||||
delay(800);
|
||||
|
||||
#if defined(DECODER_LOADED)
|
||||
|
||||
13
examples/SMA/AccDec_15Servos_2LED_6Ftn/AccDec_15Servos_2LED_6Ftn.ino
Executable file → Normal file
13
examples/SMA/AccDec_15Servos_2LED_6Ftn/AccDec_15Servos_2LED_6Ftn.ino
Executable file → Normal file
@@ -1,5 +1,5 @@
|
||||
// Production 17 Switch Acessory DCC Decoder AccDec_15Servos_2LED_6Ftn.ino
|
||||
// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Version 6.01 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Now works with both short and long DCC Addesses for CV Control Default 24 (LSB CV 121 ; MSB CV 122)
|
||||
// ACCESSORY DECODER DEFAULT ADDRESS IS 40 (MAX 40-56 SWITCHES)
|
||||
// ACCESSRY DECODER ADDRESS CAN NOW BE SET ABOVE 255
|
||||
@@ -81,11 +81,14 @@ CVPair FactoryDefaultCVs [] =
|
||||
|
||||
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0},
|
||||
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0},
|
||||
|
||||
// Speed Steps don't matter for this decoder
|
||||
// ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS
|
||||
// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps
|
||||
{CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps
|
||||
{CV_29_CONFIG,CV29_ACCESSORY_DECODER|CV29_OUTPUT_ADDRESS_MODE|CV29_F0_LOCATION}, // Accesory Decoder Short Address
|
||||
// {CV_29_CONFIG, CV29_ACCESSORY_DECODER|CV29_OUTPUT_ADDRESS_MODE|CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Accesory Decoder Long Address
|
||||
|
||||
{CV_DECODER_MASTER_RESET, 0},
|
||||
{CV_To_Store_SET_CV_Address, SET_CV_Address&0xFF }, // LSB Set CV Address
|
||||
@@ -216,7 +219,7 @@ void setup() //******************************************************
|
||||
// Setup which External Interrupt, the Pin it's associated with that we're using
|
||||
Dcc.pin(0, 2, 0);
|
||||
// Call the main DCC Init function to enable the DCC Receiver
|
||||
Dcc.init( MAN_ID_DIY, 600, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address);
|
||||
Dcc.init( MAN_ID_DIY, 601, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address);
|
||||
delay(800);
|
||||
|
||||
#if defined(DECODER_LOADED)
|
||||
|
||||
13
examples/SMA/AccDec_17LED_1Ftn/AccDec_17LED_1Ftn.ino
Executable file → Normal file
13
examples/SMA/AccDec_17LED_1Ftn/AccDec_17LED_1Ftn.ino
Executable file → Normal file
@@ -1,5 +1,5 @@
|
||||
// Production 17 Switch Acessory DCC Decoder AccDec_17LED_1Ftn.ino
|
||||
// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Version 6.01 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Now works with both short and long DCC Addesses for CV Control Default 24 (LSB CV 121 ; MSB CV 122)
|
||||
// ACCESSORY DECODER DEFAULT ADDRESS IS 40 (MAX 40-56 SWITCHES)
|
||||
// ACCESSRY DECODER ADDRESS CAN NOW BE SET ABOVE 255
|
||||
@@ -56,11 +56,14 @@ CVPair FactoryDefaultCVs [] =
|
||||
|
||||
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0},
|
||||
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0},
|
||||
|
||||
// Speed Steps don't matter for this decoder
|
||||
// ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS
|
||||
// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps
|
||||
{CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps
|
||||
{CV_29_CONFIG,CV29_ACCESSORY_DECODER|CV29_OUTPUT_ADDRESS_MODE|CV29_F0_LOCATION}, // Accesory Decoder Short Address
|
||||
// {CV_29_CONFIG, CV29_ACCESSORY_DECODER|CV29_OUTPUT_ADDRESS_MODE|CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Accesory Decoder Long Address
|
||||
|
||||
{CV_DECODER_MASTER_RESET, 0},
|
||||
{CV_To_Store_SET_CV_Address, SET_CV_Address&0xFF }, // LSB Set CV Address
|
||||
@@ -105,7 +108,7 @@ void setup()
|
||||
// Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up
|
||||
Dcc.pin(0, 2, 0);
|
||||
// Call the main DCC Init function to enable the DCC Receiver
|
||||
Dcc.init( MAN_ID_DIY, 600, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address);
|
||||
Dcc.init( MAN_ID_DIY, 601, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address);
|
||||
}
|
||||
void loop()
|
||||
{
|
||||
|
||||
13
examples/SMA/AccDec_17LED_6Ftn/AccDec_17LED_6Ftn.ino
Executable file → Normal file
13
examples/SMA/AccDec_17LED_6Ftn/AccDec_17LED_6Ftn.ino
Executable file → Normal file
@@ -1,5 +1,5 @@
|
||||
// Production 17 Switch Acessory DCC Decoder AccDec_17LED_6Ftn.ino
|
||||
// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Version 6.01 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Now works with both short and long DCC Addesses for CV Control Default 24 (LSB CV 121 ; MSB CV 122)
|
||||
// ACCESSORY DECODER DEFAULT ADDRESS IS 40 (MAX 40-56 SWITCHES)
|
||||
// ACCESSRY DECODER ADDRESS CAN NOW BE SET ABOVE 255
|
||||
@@ -81,11 +81,14 @@ CVPair FactoryDefaultCVs [] =
|
||||
|
||||
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0},
|
||||
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0},
|
||||
|
||||
// Speed Steps don't matter for this decoder
|
||||
// ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS
|
||||
// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps
|
||||
{CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps
|
||||
{CV_29_CONFIG,CV29_ACCESSORY_DECODER|CV29_OUTPUT_ADDRESS_MODE|CV29_F0_LOCATION}, // Accesory Decoder Short Address
|
||||
// {CV_29_CONFIG, CV29_ACCESSORY_DECODER|CV29_OUTPUT_ADDRESS_MODE|CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Accesory Decoder Long Address
|
||||
|
||||
{CV_DECODER_MASTER_RESET, 0},
|
||||
{CV_To_Store_SET_CV_Address, SET_CV_Address&0xFF }, // LSB Set CV Address
|
||||
@@ -219,7 +222,7 @@ void setup() //******************************************************
|
||||
// Setup which External Interrupt, the Pin it's associated with that we're using
|
||||
Dcc.pin(0, 2, 0);
|
||||
// Call the main DCC Init function to enable the DCC Receiver
|
||||
Dcc.init( MAN_ID_DIY, 600, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address);
|
||||
Dcc.init( MAN_ID_DIY, 601, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address);
|
||||
delay(800);
|
||||
|
||||
#if defined(DECODER_LOADED)
|
||||
|
||||
13
examples/SMA/AccDec_7ServoBackandForth6Ftn/AccDec_7ServoBackandForth6Ftn.ino
Executable file → Normal file
13
examples/SMA/AccDec_7ServoBackandForth6Ftn/AccDec_7ServoBackandForth6Ftn.ino
Executable file → Normal file
@@ -1,5 +1,5 @@
|
||||
// Production 17 Switch Acessory DCC Decoder AccDec_7ServoBackandForth6Ftn.ino
|
||||
// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Version 6.01 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Now works with both short and long DCC Addesses for CV Control Default 24 (LSB CV 121 ; MSB CV 122)
|
||||
// ACCESSORY DECODER DEFAULT ADDRESS IS 40 (MAX 40-56 SWITCHES)
|
||||
// ACCESSRY DECODER ADDRESS CAN NOW BE SET ABOVE 255
|
||||
@@ -85,11 +85,14 @@ CVPair FactoryDefaultCVs [] =
|
||||
|
||||
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0},
|
||||
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0},
|
||||
|
||||
// Speed Steps don't matter for this decoder
|
||||
// ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS
|
||||
// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps
|
||||
{CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps
|
||||
{CV_29_CONFIG,CV29_ACCESSORY_DECODER|CV29_OUTPUT_ADDRESS_MODE|CV29_F0_LOCATION}, // Accesory Decoder Short Address
|
||||
// {CV_29_CONFIG, CV29_ACCESSORY_DECODER|CV29_OUTPUT_ADDRESS_MODE|CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Accesory Decoder Long Address
|
||||
|
||||
{CV_DECODER_MASTER_RESET, 0},
|
||||
{CV_To_Store_SET_CV_Address, SET_CV_Address&0xFF }, // LSB Set CV Address
|
||||
@@ -223,7 +226,7 @@ void setup() //******************************************************
|
||||
// Setup which External Interrupt, the Pin it's associated with that we're using
|
||||
Dcc.pin(0, 2, 0);
|
||||
// Call the main DCC Init function to enable the DCC Receiver
|
||||
Dcc.init( MAN_ID_DIY, 600, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address);
|
||||
Dcc.init( MAN_ID_DIY, 601, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address);
|
||||
delay(800);
|
||||
|
||||
#if defined(DECODER_LOADED)
|
||||
|
||||
13
examples/SMA/AccDec_7Servos_10LED_6Ftn/AccDec_7Servos_10LED_6Ftn.ino
Executable file → Normal file
13
examples/SMA/AccDec_7Servos_10LED_6Ftn/AccDec_7Servos_10LED_6Ftn.ino
Executable file → Normal file
@@ -1,5 +1,5 @@
|
||||
// Production 17 Switch Acessory DCC Decoder AccDec_7Servos_10LED_6Ftn.ino
|
||||
// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Version 6.01 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Now works with both short and long DCC Addesses for CV Control Default 24 (LSB CV 121 ; MSB CV 122)
|
||||
// ACCESSORY DECODER DEFAULT ADDRESS IS 40 (MAX 40-56 SWITCHES)
|
||||
// ACCESSRY DECODER ADDRESS CAN NOW BE SET ABOVE 255
|
||||
@@ -81,11 +81,14 @@ CVPair FactoryDefaultCVs [] =
|
||||
|
||||
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0},
|
||||
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0},
|
||||
|
||||
// Speed Steps don't matter for this decoder
|
||||
// ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS
|
||||
// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps
|
||||
{CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps
|
||||
{CV_29_CONFIG,CV29_ACCESSORY_DECODER|CV29_OUTPUT_ADDRESS_MODE|CV29_F0_LOCATION}, // Accesory Decoder Short Address
|
||||
// {CV_29_CONFIG, CV29_ACCESSORY_DECODER|CV29_OUTPUT_ADDRESS_MODE|CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Accesory Decoder Long Address
|
||||
|
||||
{CV_DECODER_MASTER_RESET, 0},
|
||||
{CV_To_Store_SET_CV_Address, SET_CV_Address&0xFF }, // LSB Set CV Address
|
||||
@@ -219,7 +222,7 @@ void setup() //******************************************************
|
||||
// Setup which External Interrupt, the Pin it's associated with that we're using
|
||||
Dcc.pin(0, 2, 0);
|
||||
// Call the main DCC Init function to enable the DCC Receiver
|
||||
Dcc.init( MAN_ID_DIY, 600, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address);
|
||||
Dcc.init( MAN_ID_DIY, 601, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, CV_To_Store_SET_CV_Address);
|
||||
delay(800);
|
||||
|
||||
#if defined(DECODER_LOADED)
|
||||
|
||||
4
examples/SMA/Dec_10Serv_7LED_6Ftn/Dec_10Serv_7LED_6Ftn.ino
Executable file → Normal file
4
examples/SMA/Dec_10Serv_7LED_6Ftn/Dec_10Serv_7LED_6Ftn.ino
Executable file → Normal file
@@ -1,5 +1,5 @@
|
||||
// Production 17 Function DCC Decoder
|
||||
// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Version 6.01 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Now works with both short and long DCC Addesses
|
||||
// NO LONGER REQUIRES modified software servo Lib
|
||||
// Software restructuring mods added from Alex Shepherd and Franz-Peter
|
||||
@@ -211,7 +211,7 @@ void setup() //******************************************************
|
||||
// Setup which External Interrupt, the Pin it's associated with that we're using
|
||||
Dcc.pin(0, 2, 0);
|
||||
// Call the main DCC Init function to enable the DCC Receiver
|
||||
Dcc.init( MAN_ID_DIY, 600, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
Dcc.init( MAN_ID_DIY, 601, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
delay(800);
|
||||
|
||||
#if defined(DECODER_LOADED)
|
||||
|
||||
5
examples/SMA/Dec_13Serv_4LED_6Ftn/Dec_13Serv_4LED_6Ftn.ino
Executable file → Normal file
5
examples/SMA/Dec_13Serv_4LED_6Ftn/Dec_13Serv_4LED_6Ftn.ino
Executable file → Normal file
@@ -1,5 +1,5 @@
|
||||
// Production 17 Function DCC Decoder Dec_13Serv_4LED_6Ftn.ino
|
||||
// Version 5.4 Geoff Bunza 2014,2015,2016
|
||||
// Version 6.01 Geoff Bunza 2014,2015,2016
|
||||
// NO LONGER REQUIRES modified software servo Lib
|
||||
// Software restructuring mods added from Alex Shepherd and Franz-Peter
|
||||
// With sincere thanks
|
||||
@@ -12,7 +12,6 @@
|
||||
// ******** INFO TO THE SERIAL MONITOR
|
||||
//#define DEBUG
|
||||
|
||||
|
||||
#include <NmraDcc.h>
|
||||
#include <SoftwareServo.h>
|
||||
|
||||
@@ -208,7 +207,7 @@ void setup() //******************************************************
|
||||
// Setup which External Interrupt, the Pin it's associated with that we're using
|
||||
Dcc.pin(0, 2, 0);
|
||||
// Call the main DCC Init function to enable the DCC Receiver
|
||||
Dcc.init( MAN_ID_DIY, 100, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
Dcc.init( MAN_ID_DIY, 601, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
delay(800);
|
||||
|
||||
#if defined(DECODER_LOADED)
|
||||
|
||||
19
examples/SMA/Dec_15Serv_2LED_6Ftn/Dec_15Serv_2LED_6Ftn.ino
Executable file → Normal file
19
examples/SMA/Dec_15Serv_2LED_6Ftn/Dec_15Serv_2LED_6Ftn.ino
Executable file → Normal file
@@ -1,5 +1,5 @@
|
||||
// Production 17 Function DCC Decoder Dec_15Serv_2LED_6Ftn.ino
|
||||
// Version 5.4 Geoff Bunza 2014,2015,2016
|
||||
// Version 6.01 Geoff Bunza 2014,2015,2016
|
||||
// NO LONGER REQUIRES modified software servo Lib
|
||||
// Software restructuring mods added from Alex Shepherd and Franz-Peter
|
||||
// With sincere thanks
|
||||
@@ -68,10 +68,17 @@ struct CVPair
|
||||
|
||||
CVPair FactoryDefaultCVs [] =
|
||||
{
|
||||
{CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address},
|
||||
{CV_ACCESSORY_DECODER_ADDRESS_MSB, 0},
|
||||
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0},
|
||||
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0},
|
||||
{CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F },
|
||||
|
||||
// These two CVs define the Long DCC Address
|
||||
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 },
|
||||
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF },
|
||||
|
||||
// ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS
|
||||
// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps
|
||||
{CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps
|
||||
|
||||
{CV_DECODER_MASTER_RESET, 0},
|
||||
{30, 2}, //F0 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade
|
||||
{31, 1}, //F0 Rate Blink=Eate,PWM=Rate,Servo=Rate
|
||||
@@ -200,7 +207,7 @@ void setup() //******************************************************
|
||||
// Setup which External Interrupt, the Pin it's associated with that we're using
|
||||
Dcc.pin(0, 2, 0);
|
||||
// Call the main DCC Init function to enable the DCC Receiver
|
||||
Dcc.init( MAN_ID_DIY, 100, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
Dcc.init( MAN_ID_DIY, 601, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
delay(800);
|
||||
|
||||
#if defined(DECODER_LOADED)
|
||||
|
||||
4
examples/SMA/Dec_17LED_1Ftn/Dec_17LED_1Ftn.ino
Executable file → Normal file
4
examples/SMA/Dec_17LED_1Ftn/Dec_17LED_1Ftn.ino
Executable file → Normal file
@@ -1,5 +1,5 @@
|
||||
// Production 17 Function DCC Decoder Dec_17LED_1Ftn.ino
|
||||
// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Version 6.01 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Now works with both short and long DCC Addesses
|
||||
|
||||
// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP
|
||||
@@ -87,7 +87,7 @@ void setup()
|
||||
// Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up
|
||||
Dcc.pin(0, 2, 0);
|
||||
// Call the main DCC Init function to enable the DCC Receiver
|
||||
Dcc.init( MAN_ID_DIY, 600, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
Dcc.init( MAN_ID_DIY, 601, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
delay(800);
|
||||
#if defined(DECODER_LOADED)
|
||||
if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET )
|
||||
|
||||
4
examples/SMA/Dec_17LED_6Ftn/Dec_17LED_6Ftn.ino
Executable file → Normal file
4
examples/SMA/Dec_17LED_6Ftn/Dec_17LED_6Ftn.ino
Executable file → Normal file
@@ -1,5 +1,5 @@
|
||||
// Production 17 Function DCC Decoder Dec_17LED_6Ftn.ino
|
||||
// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Version 6.01 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Now works with both short and long DCC Addesses
|
||||
// NO LONGER REQUIRES modified software servo Lib
|
||||
// Software restructuring mods added from Alex Shepherd and Franz-Peter
|
||||
@@ -211,7 +211,7 @@ void setup() //******************************************************
|
||||
// Setup which External Interrupt, the Pin it's associated with that we're using
|
||||
Dcc.pin(0, 2, 0);
|
||||
// Call the main DCC Init function to enable the DCC Receiver
|
||||
Dcc.init( MAN_ID_DIY, 600, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
Dcc.init( MAN_ID_DIY, 601, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
delay(800);
|
||||
|
||||
#if defined(DECODER_LOADED)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Production 2 Motor 13 Function DCC Decoder Dec_2MotDrive_12LED_1Srv_6Ftn.ino
|
||||
// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Version 6.01a Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Now works with both short and long DCC Addesses
|
||||
|
||||
// Better motor control added
|
||||
// NO LONGER REQUIRES modified software servo Lib
|
||||
// Software restructuring mods added from Alex Shepherd and Franz-Peter
|
||||
// With sincere thanks
|
||||
@@ -35,12 +35,10 @@ SoftwareServo servo[13];
|
||||
#define servo_slowdown 12 //servo loop counter limit
|
||||
int servo_slow_counter = 0; //servo loop counter to slowdown servo transit
|
||||
|
||||
uint8_t Motor1Speed = 0;
|
||||
int Motor1Speed = 0;
|
||||
uint8_t Motor1ForwardDir = 1;
|
||||
uint8_t Motor1MaxSpeed = 127;
|
||||
uint8_t Motor2Speed = 0;
|
||||
int Motor2Speed = 0;
|
||||
uint8_t Motor2ForwardDir = 1;
|
||||
uint8_t Motor2MaxSpeed = 127;
|
||||
int kickstarton = 1400; //kick start cycle on time
|
||||
int kickstarttime = 5; //kick start duration on time
|
||||
int fwdon = 0;
|
||||
@@ -49,6 +47,7 @@ int bwdon = 0;
|
||||
int bwdtime = 1;
|
||||
int bwdshift = 0;
|
||||
int cyclewidth = 2047;
|
||||
int loopdelay =14;
|
||||
int m2h = 3; //R H Bridge //Motor1
|
||||
int m2l = 4; //B H Bridge //Motor1
|
||||
int m0h = 9; //R H Bridge //Motor2
|
||||
@@ -56,7 +55,7 @@ int m0l = 10; //B H Bridge //Motor2
|
||||
|
||||
int speedup = 112; //Right track time differntial
|
||||
int deltime = 1500;
|
||||
int tim_delay = 80;
|
||||
int tim_delay = 30;
|
||||
int numfpins = 17;
|
||||
int num_active_fpins = 13;
|
||||
byte fpins [] = {3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
|
||||
@@ -71,7 +70,6 @@ const int FunctionPin6 = 13;
|
||||
const int FunctionPin7 = 14; //A0
|
||||
const int FunctionPin8 = 15; //A1
|
||||
|
||||
|
||||
const int FunctionPin9 = 16; //A2
|
||||
const int FunctionPin10 = 17; //A3
|
||||
const int FunctionPin11 = 18; //A4
|
||||
@@ -111,9 +109,9 @@ CVPair FactoryDefaultCVs [] =
|
||||
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF },
|
||||
|
||||
// ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS
|
||||
// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps
|
||||
// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps
|
||||
{CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps
|
||||
// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps
|
||||
|
||||
{CV_DECODER_MASTER_RESET, 0},
|
||||
{30, 0}, //F0 Config 0=On/Off,1=Blink,2=Servo,3=DBL LED Blink,4=Pulsed,5=fade
|
||||
@@ -244,7 +242,7 @@ void setup() //******************************************************
|
||||
// Setup which External Interrupt, the Pin it's associated with that we're using
|
||||
Dcc.pin(0, 2, 0);
|
||||
// Call the main DCC Init function to enable the DCC Receiver
|
||||
Dcc.init( MAN_ID_DIY, 600, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
Dcc.init( MAN_ID_DIY, 601, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
delay(800);
|
||||
|
||||
#if defined(DECODER_LOADED)
|
||||
@@ -340,13 +338,27 @@ void loop() //****************************************************************
|
||||
Dcc.process();
|
||||
SoftwareServo::refresh();
|
||||
delay(2);
|
||||
#ifdef DEBUG
|
||||
Serial.print("Motor1Speed= ");
|
||||
Serial.println(Motor1Speed, DEC) ;
|
||||
Serial.print("Motor2Speed= ");
|
||||
Serial.println(Motor2Speed, DEC) ;
|
||||
#endif
|
||||
if (Motor1Speed != 0) {
|
||||
if (Motor1ForwardDir == 0) gofwd1 (fwdtime, int((Motor1Speed&0x7f)*21));
|
||||
else gobwd1 (bwdtime, int((Motor1Speed&0x7f)*21));
|
||||
if (Motor1ForwardDir == 0) gofwd1 (fwdtime, Motor1Speed<<4);
|
||||
else gobwd1 (bwdtime, Motor1Speed<<4);
|
||||
}
|
||||
else {
|
||||
digitalWrite(m2h, LOW); //Motor1 OFF
|
||||
digitalWrite(m2l, LOW); //Motor1 OFF
|
||||
}
|
||||
if (Motor2Speed != 0) {
|
||||
if (Motor2ForwardDir == 0) gofwd2 (fwdtime, int((Motor2Speed&0x7f)*21));
|
||||
else gobwd2 (bwdtime, int((Motor2Speed&0x7f)*21));
|
||||
if (Motor2ForwardDir == 0) gofwd2 (fwdtime, Motor2Speed<<4);
|
||||
else gobwd2 (bwdtime, Motor2Speed<<4);
|
||||
}
|
||||
else {
|
||||
digitalWrite(m0h, LOW); //Motor1 OFF
|
||||
digitalWrite(m0l, LOW); //Motor1 OFF
|
||||
}
|
||||
//
|
||||
for (int i=0; i < num_active_fpins; i++) {
|
||||
@@ -420,61 +432,73 @@ void loop() //****************************************************************
|
||||
}
|
||||
void gofwd1(int fcnt,int fcycle) {
|
||||
int icnt;
|
||||
int totcycle;
|
||||
int delta_tp,delta_tm;
|
||||
delta_tp = fcycle+loopdelay<<2;
|
||||
delta_tm = cyclewidth-fcycle-loopdelay;
|
||||
icnt = 0;
|
||||
while (icnt < fcnt)
|
||||
{
|
||||
digitalWrite(m2h, HIGH); //Motor1
|
||||
delayMicroseconds(fcycle);
|
||||
delayMicroseconds(delta_tp);
|
||||
digitalWrite(m2h, LOW); //Motor1
|
||||
delayMicroseconds(cyclewidth - fcycle);
|
||||
delayMicroseconds(delta_tm);
|
||||
icnt++;
|
||||
}
|
||||
}
|
||||
void gobwd1(int bcnt,int bcycle) {
|
||||
int icnt;
|
||||
int delta_tp,delta_tm;
|
||||
delta_tp = bcycle+loopdelay<<2;
|
||||
delta_tm = cyclewidth-bcycle-loopdelay;
|
||||
icnt=0;
|
||||
while (icnt < bcnt)
|
||||
{
|
||||
digitalWrite(m2l, HIGH); //Motor1
|
||||
delayMicroseconds(bcycle);
|
||||
delayMicroseconds(delta_tp);
|
||||
digitalWrite(m2l, LOW); //Motor1
|
||||
delayMicroseconds(cyclewidth - bcycle);
|
||||
delayMicroseconds(delta_tm);
|
||||
icnt++;
|
||||
}
|
||||
}
|
||||
void gofwd2(int fcnt,int fcycle) {
|
||||
int icnt;
|
||||
int totcycle;
|
||||
int delta_tp,delta_tm;
|
||||
delta_tp = fcycle+loopdelay<<2;
|
||||
delta_tm = cyclewidth-fcycle-loopdelay;
|
||||
icnt = 0;
|
||||
while (icnt < fcnt)
|
||||
{
|
||||
digitalWrite(m0h, HIGH); //Motor2
|
||||
delayMicroseconds(fcycle);
|
||||
delayMicroseconds(delta_tp);
|
||||
digitalWrite(m0h, LOW); //Motor2
|
||||
delayMicroseconds(cyclewidth - fcycle);
|
||||
delayMicroseconds(delta_tm);
|
||||
icnt++;
|
||||
}
|
||||
}
|
||||
void gobwd2(int bcnt,int bcycle) {
|
||||
int icnt;
|
||||
int delta_tp,delta_tm;
|
||||
delta_tp = bcycle+loopdelay<<2;
|
||||
delta_tm = cyclewidth-bcycle-loopdelay;
|
||||
icnt=0;
|
||||
while (icnt < bcnt)
|
||||
{
|
||||
digitalWrite(m0l, HIGH); //Motor2
|
||||
delayMicroseconds(bcycle);
|
||||
delayMicroseconds(delta_tp);
|
||||
digitalWrite(m0l, LOW); //Motor2
|
||||
delayMicroseconds(cyclewidth - bcycle);
|
||||
delayMicroseconds(delta_tm);
|
||||
icnt++;
|
||||
}
|
||||
}
|
||||
void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_DIRECTION ForwardDir, DCC_SPEED_STEPS SpeedSteps ) {
|
||||
if (Function13_value==1) {
|
||||
Motor1Speed = Speed;
|
||||
Motor1Speed = (Speed & 0x7f );
|
||||
if (Motor1Speed == 1) Motor1Speed=0;
|
||||
Motor1ForwardDir = ForwardDir;
|
||||
}
|
||||
if (Function14_value==1) {
|
||||
Motor2Speed = Speed;
|
||||
Motor2Speed = (Speed & 0x7f );
|
||||
if (Motor2Speed == 1) Motor2Speed=0;
|
||||
Motor2ForwardDir = ForwardDir;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Production 2 Motor w/Triggered Audio Multi Function DCC Decoder Dec_2Mot_3LED_TrigAudio.ino
|
||||
// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Version 6.01a Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Now works with both short and long DCC Addesses
|
||||
|
||||
// Improved motor control added
|
||||
// This decoder will control 2 motors and play audio clips by function:
|
||||
// F0=LED on pin 8, F1-F4 Controls playing specific audio tracks in the 3rd CV (start) at the volume in the 2nd CV (rate)
|
||||
// F5 Controls playing audio track in CV57 at the volume in CV56 ONLY when F5 is ON and Pin17/A3 is held low,
|
||||
@@ -21,7 +21,7 @@
|
||||
* Motor speed for each can only be changed if the corresponding Function is on
|
||||
* (F13 and/or F14). Motor speed is maintained if the corresponding Motor select function
|
||||
* is off. Thus, each motor can be controlled independently and run at different speeds.
|
||||
* F0 LED Pin 8
|
||||
* F0 LED Pin 13
|
||||
* F1-F6 6 Functions Configures As Audio Play
|
||||
* F7-F8 2 Functions Configures As LEDs by default PINS 18 and 19
|
||||
* F13 Motor1 Control Enable
|
||||
@@ -68,12 +68,10 @@ SoftwareServo servo[10];
|
||||
#define servo_slowdown 4 //servo loop counter limit
|
||||
int servo_slow_counter = 0; //servo loop counter to slowdown servo transit
|
||||
|
||||
uint8_t Motor1Speed = 0;
|
||||
int Motor1Speed = 0;
|
||||
uint8_t Motor1ForwardDir = 1;
|
||||
uint8_t Motor1MaxSpeed = 127;
|
||||
uint8_t Motor2Speed = 0;
|
||||
int Motor2Speed = 0;
|
||||
uint8_t Motor2ForwardDir = 1;
|
||||
uint8_t Motor2MaxSpeed = 127;
|
||||
int kickstarton = 1400; //kick start cycle on time
|
||||
int kickstarttime = 5; //kick start duration on time
|
||||
int fwdon = 0;
|
||||
@@ -82,6 +80,7 @@ int bwdon = 0;
|
||||
int bwdtime = 1;
|
||||
int bwdshift = 0;
|
||||
int cyclewidth = 2047;
|
||||
int loopdelay =14;
|
||||
int m2h = 3; //R H Bridge //Motor1
|
||||
int m2l = 4; //B H Bridge //Motor1
|
||||
int m0h = 9; //R H Bridge //Motor2
|
||||
@@ -89,31 +88,31 @@ int m0l = 10; //B H Bridge //Motor2
|
||||
|
||||
int speedup = 112; //Right track time differntial
|
||||
int deltime = 1500;
|
||||
int tim_delay = 100;
|
||||
int tim_delay = 30;
|
||||
int numfpins = 13;
|
||||
int num_active_fpins = 9;
|
||||
byte fpins [] = {3,4,8,9,10,11,12,13,14,15,16,18};
|
||||
const int FunctionPin0 = 8;
|
||||
const int FunctionPin1 = 11;
|
||||
const int FunctionPin2 = 12;
|
||||
const int FunctionPin3 = 13;
|
||||
const int FunctionPin4 = 14; //A0
|
||||
const int FunctionPin0 = 13;
|
||||
const int FunctionPin1 = 20; // Place holders ONLY
|
||||
const int FunctionPin2 = 20; // Place holders ONLY
|
||||
const int FunctionPin3 = 20; // Place holders ONLY
|
||||
const int FunctionPin4 = 20; //A0 Place holders ONLY
|
||||
|
||||
const int FunctionPin5 = 15; //A1
|
||||
const int FunctionPin6 = 16; //A2
|
||||
const int FunctionPin7 = 18; //A5
|
||||
const int FunctionPin8 = 19; //A4
|
||||
const int FunctionPin5 = 20; //A1 Place holders ONLY
|
||||
const int FunctionPin6 = 20; //A2 Place holders ONLY
|
||||
const int FunctionPin7 = 18; //A5 Place holders ONLY
|
||||
const int FunctionPin8 = 19; //A4 Place holders ONLY
|
||||
|
||||
const int AudioTriggerPin = 17; //A3 NOW USED AS Audio Trigger Pin INPUT_PULLUP
|
||||
|
||||
const int FunctionPin9 = 20; // Place holders ONLY
|
||||
const int FunctionPin10 = 20; // Place holders ONLY
|
||||
const int FunctionPin11 = 20;
|
||||
const int FunctionPin12 = 20;
|
||||
const int FunctionPin13 = 20;
|
||||
const int FunctionPin14 = 20;
|
||||
const int FunctionPin15 = 20;
|
||||
const int FunctionPin16 = 20;
|
||||
const int FunctionPin11 = 20; // Place holders ONLY
|
||||
const int FunctionPin12 = 20; // Place holders ONLY
|
||||
const int FunctionPin13 = 20; // Place holders ONLY
|
||||
const int FunctionPin14 = 20; // Place holders ONLY
|
||||
const int FunctionPin15 = 20; // Place holders ONLY
|
||||
const int FunctionPin16 = 20; // Place holders ONLY
|
||||
|
||||
int Function13_value = 0;
|
||||
int Function14_value = 0;
|
||||
@@ -122,7 +121,6 @@ NmraDcc Dcc ;
|
||||
DCC_MSG Packet ;
|
||||
uint8_t CV_DECODER_MASTER_RESET = 120;
|
||||
int t; // temp
|
||||
|
||||
struct QUEUE
|
||||
{
|
||||
int inuse;
|
||||
@@ -242,7 +240,7 @@ void setup() //******************************************************
|
||||
// Setup which External Interrupt, the Pin it's associated with that we're using
|
||||
Dcc.pin(0, 2, 0);
|
||||
// Call the main DCC Init function to enable the DCC Receiver
|
||||
Dcc.init( MAN_ID_DIY, 600, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
Dcc.init( MAN_ID_DIY, 601, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
delay(800);
|
||||
|
||||
#if defined(DECODER_LOADED)
|
||||
@@ -354,13 +352,27 @@ void loop() //****************************************************************
|
||||
Dcc.process();
|
||||
SoftwareServo::refresh();
|
||||
delay(2);
|
||||
#ifdef DEBUG
|
||||
Serial.print("Motor1Speed= ");
|
||||
Serial.println(Motor1Speed, DEC) ;
|
||||
Serial.print("Motor2Speed= ");
|
||||
Serial.println(Motor2Speed, DEC) ;
|
||||
#endif
|
||||
if (Motor1Speed != 0) {
|
||||
if (Motor1ForwardDir == 0) gofwd1 (fwdtime, int((Motor1Speed&0x7f)*21));
|
||||
else gobwd1 (bwdtime, int((Motor1Speed&0x7f)*21));
|
||||
if (Motor1ForwardDir == 0) gofwd1 (fwdtime, Motor1Speed<<4);
|
||||
else gobwd1 (bwdtime, Motor1Speed<<4);
|
||||
}
|
||||
else {
|
||||
digitalWrite(m2h, LOW); //Motor1 OFF
|
||||
digitalWrite(m2l, LOW); //Motor1 OFF
|
||||
}
|
||||
if (Motor2Speed != 0) {
|
||||
if (Motor2ForwardDir == 0) gofwd2 (fwdtime, int((Motor2Speed&0x7f)*21));
|
||||
else gobwd2 (bwdtime, int((Motor2Speed&0x7f)*21));
|
||||
if (Motor2ForwardDir == 0) gofwd2 (fwdtime, Motor2Speed<<4);
|
||||
else gobwd2 (bwdtime, Motor2Speed<<4);
|
||||
}
|
||||
else {
|
||||
digitalWrite(m0h, LOW); //Motor1 OFF
|
||||
digitalWrite(m0l, LOW); //Motor1 OFF
|
||||
}
|
||||
//
|
||||
for (int i=0; i < num_active_fpins; i++) {
|
||||
@@ -460,61 +472,73 @@ void loop() //****************************************************************
|
||||
}
|
||||
void gofwd1(int fcnt,int fcycle) {
|
||||
int icnt;
|
||||
int totcycle;
|
||||
int delta_tp,delta_tm;
|
||||
delta_tp = fcycle+loopdelay<<2;
|
||||
delta_tm = cyclewidth-fcycle-loopdelay;
|
||||
icnt = 0;
|
||||
while (icnt < fcnt)
|
||||
{
|
||||
digitalWrite(m2h, HIGH); //Motor1
|
||||
delayMicroseconds(fcycle);
|
||||
delayMicroseconds(delta_tp);
|
||||
digitalWrite(m2h, LOW); //Motor1
|
||||
delayMicroseconds(cyclewidth - fcycle);
|
||||
delayMicroseconds(delta_tm);
|
||||
icnt++;
|
||||
}
|
||||
}
|
||||
void gobwd1(int bcnt,int bcycle) {
|
||||
int icnt;
|
||||
int delta_tp,delta_tm;
|
||||
delta_tp = bcycle+loopdelay<<2;
|
||||
delta_tm = cyclewidth-bcycle-loopdelay;
|
||||
icnt=0;
|
||||
while (icnt < bcnt)
|
||||
{
|
||||
digitalWrite(m2l, HIGH); //Motor1
|
||||
delayMicroseconds(bcycle);
|
||||
delayMicroseconds(delta_tp);
|
||||
digitalWrite(m2l, LOW); //Motor1
|
||||
delayMicroseconds(cyclewidth - bcycle);
|
||||
delayMicroseconds(delta_tm);
|
||||
icnt++;
|
||||
}
|
||||
}
|
||||
void gofwd2(int fcnt,int fcycle) {
|
||||
int icnt;
|
||||
int totcycle;
|
||||
int delta_tp,delta_tm;
|
||||
delta_tp = fcycle+loopdelay<<2;
|
||||
delta_tm = cyclewidth-fcycle-loopdelay;
|
||||
icnt = 0;
|
||||
while (icnt < fcnt)
|
||||
{
|
||||
digitalWrite(m0h, HIGH); //Motor2
|
||||
delayMicroseconds(fcycle);
|
||||
delayMicroseconds(delta_tp);
|
||||
digitalWrite(m0h, LOW); //Motor2
|
||||
delayMicroseconds(cyclewidth - fcycle);
|
||||
delayMicroseconds(delta_tm);
|
||||
icnt++;
|
||||
}
|
||||
}
|
||||
void gobwd2(int bcnt,int bcycle) {
|
||||
int icnt;
|
||||
int delta_tp,delta_tm;
|
||||
delta_tp = bcycle+loopdelay<<2;
|
||||
delta_tm = cyclewidth-bcycle-loopdelay;
|
||||
icnt=0;
|
||||
while (icnt < bcnt)
|
||||
{
|
||||
digitalWrite(m0l, HIGH); //Motor2
|
||||
delayMicroseconds(bcycle);
|
||||
delayMicroseconds(delta_tp);
|
||||
digitalWrite(m0l, LOW); //Motor2
|
||||
delayMicroseconds(cyclewidth - bcycle);
|
||||
delayMicroseconds(delta_tm);
|
||||
icnt++;
|
||||
}
|
||||
}
|
||||
void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_DIRECTION ForwardDir, DCC_SPEED_STEPS SpeedSteps ) {
|
||||
if (Function13_value==1) {
|
||||
Motor1Speed = Speed;
|
||||
Motor1Speed = (Speed & 0x7f );
|
||||
if (Motor1Speed == 1) Motor1Speed=0;
|
||||
Motor1ForwardDir = ForwardDir;
|
||||
}
|
||||
if (Function14_value==1) {
|
||||
Motor2Speed = Speed;
|
||||
Motor2Speed = (Speed & 0x7f );
|
||||
if (Motor2Speed == 1) Motor2Speed=0;
|
||||
Motor2ForwardDir = ForwardDir;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
// Production 2 Motor w/Audio 13 Function DCC Decoder Dec_2Mot_10LED_Audio_8Ftn.ino
|
||||
// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Version 6.01a Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Now works with both short and long DCC Addesses
|
||||
// Improved motor control added
|
||||
// This decoder will control 2 motors and play audio clips by function:
|
||||
// F0=LED on pin 13, F1-F4 Controls playing specific audio tracks in the 3rd CV (start) at the volume in the 2nd CV (rate)
|
||||
// F5 Controls playing audio track in CV57 at the volume in CV56 ONLY when F5 is ON and Pin17/A3 is held low,
|
||||
// and plays continuously until F5 turns off or Pin17 trigger goes HIGH or open
|
||||
// F6 plays one track selected randomly off the memory card
|
||||
// F13 and F14 select each separate motor which will respond to speed and direction controls
|
||||
// F7-F8 control LEDs by default PINS 18 and 19
|
||||
|
||||
// NO LONGER REQUIRES modified software servo Lib
|
||||
// Software restructuring mods added from Alex Shepherd and Franz-Peter
|
||||
@@ -10,7 +18,7 @@
|
||||
* Motor speed for each can only be changed if the corresponding Function is on
|
||||
* (F13 and/or F14). Motor speed is maintained if the corresponding Motor select function
|
||||
* is off. Thus, each motor can be controlled independently and run at different speeds.
|
||||
* F0 LED Pin 8
|
||||
* F0 LED Pin 13
|
||||
* F1-F6 6 Functions Configures As Audio Play
|
||||
* F7-F9 3 Functions Configures As LEDs
|
||||
* F13 Motor1 Control Enable
|
||||
@@ -57,12 +65,10 @@ SoftwareServo servo[10];
|
||||
#define servo_slowdown 4 //servo loop counter limit
|
||||
int servo_slow_counter = 0; //servo loop counter to slowdown servo transit
|
||||
|
||||
uint8_t Motor1Speed = 0;
|
||||
int Motor1Speed = 0;
|
||||
uint8_t Motor1ForwardDir = 1;
|
||||
uint8_t Motor1MaxSpeed = 127;
|
||||
uint8_t Motor2Speed = 0;
|
||||
int Motor2Speed = 0;
|
||||
uint8_t Motor2ForwardDir = 1;
|
||||
uint8_t Motor2MaxSpeed = 127;
|
||||
int kickstarton = 1400; //kick start cycle on time
|
||||
int kickstarttime = 5; //kick start duration on time
|
||||
int fwdon = 0;
|
||||
@@ -71,6 +77,7 @@ int bwdon = 0;
|
||||
int bwdtime = 1;
|
||||
int bwdshift = 0;
|
||||
int cyclewidth = 2047;
|
||||
int loopdelay =14;
|
||||
int m2h = 3; //R H Bridge //Motor1
|
||||
int m2l = 4; //B H Bridge //Motor1
|
||||
int m0h = 9; //R H Bridge //Motor2
|
||||
@@ -78,29 +85,31 @@ int m0l = 10; //B H Bridge //Motor2
|
||||
|
||||
int speedup = 112; //Right track time differntial
|
||||
int deltime = 1500;
|
||||
int tim_delay = 100;
|
||||
int tim_delay = 30;
|
||||
int numfpins = 14;
|
||||
int num_active_fpins = 10;
|
||||
byte fpins [] = {3,4,8,9,10,11,12,13,14,15,16,17,18,19};
|
||||
const int FunctionPin0 = 8;
|
||||
const int FunctionPin1 = 11;
|
||||
const int FunctionPin2 = 12;
|
||||
const int FunctionPin3 = 13;
|
||||
const int FunctionPin4 = 14; //A0
|
||||
const int FunctionPin0 = 13;
|
||||
const int FunctionPin1 = 20; // Place holders ONLY
|
||||
const int FunctionPin2 = 20; // Place holders ONLY
|
||||
const int FunctionPin3 = 20; // Place holders ONLY
|
||||
const int FunctionPin4 = 20; //A0 Place holders ONLY
|
||||
|
||||
const int FunctionPin5 = 15; //A1
|
||||
const int FunctionPin6 = 16; //A2
|
||||
const int FunctionPin7 = 17; //A3
|
||||
const int FunctionPin8 = 18; //A4
|
||||
const int FunctionPin9 = 19; //A5
|
||||
const int FunctionPin5 = 20; //A1 Place holders ONLY
|
||||
const int FunctionPin6 = 20; //A2 Place holders ONLY
|
||||
const int FunctionPin7 = 18; //A5 Place holders ONLY
|
||||
const int FunctionPin8 = 19; //A4 Place holders ONLY
|
||||
|
||||
const int AudioTriggerPin = 17; //A3 NOW USED AS Audio Trigger Pin INPUT_PULLUP
|
||||
|
||||
const int FunctionPin9 = 20; // Place holders ONLY
|
||||
const int FunctionPin10 = 20; // Place holders ONLY
|
||||
const int FunctionPin11 = 20;
|
||||
const int FunctionPin12 = 20;
|
||||
const int FunctionPin13 = 20;
|
||||
const int FunctionPin14 = 20;
|
||||
const int FunctionPin15 = 20;
|
||||
const int FunctionPin16 = 20;
|
||||
const int FunctionPin11 = 20; // Place holders ONLY
|
||||
const int FunctionPin12 = 20; // Place holders ONLY
|
||||
const int FunctionPin13 = 20; // Place holders ONLY
|
||||
const int FunctionPin14 = 20; // Place holders ONLY
|
||||
const int FunctionPin15 = 20; // Place holders ONLY
|
||||
const int FunctionPin16 = 20; // Place holders ONLY
|
||||
|
||||
int Function13_value = 0;
|
||||
int Function14_value = 0;
|
||||
@@ -227,7 +236,7 @@ void setup() //******************************************************
|
||||
// Setup which External Interrupt, the Pin it's associated with that we're using
|
||||
Dcc.pin(0, 2, 0);
|
||||
// Call the main DCC Init function to enable the DCC Receiver
|
||||
Dcc.init( MAN_ID_DIY, 600, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
Dcc.init( MAN_ID_DIY, 601, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
delay(800);
|
||||
|
||||
#if defined(DECODER_LOADED)
|
||||
@@ -336,13 +345,27 @@ void loop() //****************************************************************
|
||||
Dcc.process();
|
||||
SoftwareServo::refresh();
|
||||
delay(2);
|
||||
#ifdef DEBUG
|
||||
Serial.print("Motor1Speed= ");
|
||||
Serial.println(Motor1Speed, DEC) ;
|
||||
Serial.print("Motor2Speed= ");
|
||||
Serial.println(Motor2Speed, DEC) ;
|
||||
#endif
|
||||
if (Motor1Speed != 0) {
|
||||
if (Motor1ForwardDir == 0) gofwd1 (fwdtime, int((Motor1Speed&0x7f)*21));
|
||||
else gobwd1 (bwdtime, int((Motor1Speed&0x7f)*21));
|
||||
if (Motor1ForwardDir == 0) gofwd1 (fwdtime, Motor1Speed<<4);
|
||||
else gobwd1 (bwdtime, Motor1Speed<<4);
|
||||
}
|
||||
else {
|
||||
digitalWrite(m2h, LOW); //Motor1 OFF
|
||||
digitalWrite(m2l, LOW); //Motor1 OFF
|
||||
}
|
||||
if (Motor2Speed != 0) {
|
||||
if (Motor2ForwardDir == 0) gofwd2 (fwdtime, int((Motor2Speed&0x7f)*21));
|
||||
else gobwd2 (bwdtime, int((Motor2Speed&0x7f)*21));
|
||||
if (Motor2ForwardDir == 0) gofwd2 (fwdtime, Motor2Speed<<4);
|
||||
else gobwd2 (bwdtime, Motor2Speed<<4);
|
||||
}
|
||||
else {
|
||||
digitalWrite(m0h, LOW); //Motor1 OFF
|
||||
digitalWrite(m0l, LOW); //Motor1 OFF
|
||||
}
|
||||
//
|
||||
for (int i=0; i < num_active_fpins; i++) {
|
||||
@@ -432,65 +455,78 @@ void loop() //****************************************************************
|
||||
}
|
||||
void gofwd1(int fcnt,int fcycle) {
|
||||
int icnt;
|
||||
int totcycle;
|
||||
int delta_tp,delta_tm;
|
||||
delta_tp = fcycle+loopdelay<<2;
|
||||
delta_tm = cyclewidth-fcycle-loopdelay;
|
||||
icnt = 0;
|
||||
while (icnt < fcnt)
|
||||
{
|
||||
digitalWrite(m2h, HIGH); //Motor1
|
||||
delayMicroseconds(fcycle);
|
||||
delayMicroseconds(delta_tp);
|
||||
digitalWrite(m2h, LOW); //Motor1
|
||||
delayMicroseconds(cyclewidth - fcycle);
|
||||
delayMicroseconds(delta_tm);
|
||||
icnt++;
|
||||
}
|
||||
}
|
||||
void gobwd1(int bcnt,int bcycle) {
|
||||
int icnt;
|
||||
int delta_tp,delta_tm;
|
||||
delta_tp = bcycle+loopdelay<<2;
|
||||
delta_tm = cyclewidth-bcycle-loopdelay;
|
||||
icnt=0;
|
||||
while (icnt < bcnt)
|
||||
{
|
||||
digitalWrite(m2l, HIGH); //Motor1
|
||||
delayMicroseconds(bcycle);
|
||||
delayMicroseconds(delta_tp);
|
||||
digitalWrite(m2l, LOW); //Motor1
|
||||
delayMicroseconds(cyclewidth - bcycle);
|
||||
delayMicroseconds(delta_tm);
|
||||
icnt++;
|
||||
}
|
||||
}
|
||||
void gofwd2(int fcnt,int fcycle) {
|
||||
int icnt;
|
||||
int totcycle;
|
||||
int delta_tp,delta_tm;
|
||||
delta_tp = fcycle+loopdelay<<2;
|
||||
delta_tm = cyclewidth-fcycle-loopdelay;
|
||||
icnt = 0;
|
||||
while (icnt < fcnt)
|
||||
{
|
||||
digitalWrite(m0h, HIGH); //Motor2
|
||||
delayMicroseconds(fcycle);
|
||||
delayMicroseconds(delta_tp);
|
||||
digitalWrite(m0h, LOW); //Motor2
|
||||
delayMicroseconds(cyclewidth - fcycle);
|
||||
delayMicroseconds(delta_tm);
|
||||
icnt++;
|
||||
}
|
||||
}
|
||||
void gobwd2(int bcnt,int bcycle) {
|
||||
int icnt;
|
||||
int delta_tp,delta_tm;
|
||||
delta_tp = bcycle+loopdelay<<2;
|
||||
delta_tm = cyclewidth-bcycle-loopdelay;
|
||||
icnt=0;
|
||||
while (icnt < bcnt)
|
||||
{
|
||||
digitalWrite(m0l, HIGH); //Motor2
|
||||
delayMicroseconds(bcycle);
|
||||
delayMicroseconds(delta_tp);
|
||||
digitalWrite(m0l, LOW); //Motor2
|
||||
delayMicroseconds(cyclewidth - bcycle);
|
||||
delayMicroseconds(delta_tm);
|
||||
icnt++;
|
||||
}
|
||||
}
|
||||
void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_DIRECTION ForwardDir, DCC_SPEED_STEPS SpeedSteps ) {
|
||||
if (Function13_value==1) {
|
||||
Motor1Speed = Speed;
|
||||
Motor1Speed = (Speed & 0x7f );
|
||||
if (Motor1Speed == 1) Motor1Speed=0;
|
||||
Motor1ForwardDir = ForwardDir;
|
||||
}
|
||||
if (Function14_value==1) {
|
||||
Motor2Speed = Speed;
|
||||
Motor2Speed = (Speed & 0x7f );
|
||||
if (Motor2Speed == 1) Motor2Speed=0;
|
||||
Motor2ForwardDir = ForwardDir;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) {
|
||||
#ifdef DEBUG
|
||||
Serial.print("Addr= ");
|
||||
|
||||
4
examples/SMA/Dec_7Serv_10LED_6Ftn/Dec_7Serv_10LED_6Ftn.ino
Executable file → Normal file
4
examples/SMA/Dec_7Serv_10LED_6Ftn/Dec_7Serv_10LED_6Ftn.ino
Executable file → Normal file
@@ -1,5 +1,5 @@
|
||||
// Production 17 Function DCC Decoder Dec_7Serv_10LED_6Ftn.ino
|
||||
// Version 5.4 Geoff Bunza 2014,2015,2016
|
||||
// Version 6.01 Geoff Bunza 2014,2015,2016
|
||||
// NO LONGER REQUIRES modified software servo Lib
|
||||
// Software restructuring mods added from Alex Shepherd and Franz-Peter
|
||||
// With sincere thanks
|
||||
@@ -207,7 +207,7 @@ void setup() //******************************************************
|
||||
// Setup which External Interrupt, the Pin it's associated with that we're using
|
||||
Dcc.pin(0, 2, 0);
|
||||
// Call the main DCC Init function to enable the DCC Receiver
|
||||
Dcc.init( MAN_ID_DIY, 100, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
Dcc.init( MAN_ID_DIY, 601, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
delay(800);
|
||||
|
||||
#if defined(DECODER_LOADED)
|
||||
|
||||
4
examples/SMA/Dec_Dir_and_Fade/Dec_Dir_and_Fade.ino
Executable file → Normal file
4
examples/SMA/Dec_Dir_and_Fade/Dec_Dir_and_Fade.ino
Executable file → Normal file
@@ -1,5 +1,5 @@
|
||||
// Production 17 Function DCC Decoder Dec_Dir_and_Fade.ino
|
||||
// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Version 6.01 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Now works with both short and long DCC Addesses
|
||||
// LED control is dependent on direction of travel and Fade can be added
|
||||
|
||||
@@ -110,7 +110,7 @@ void setup()
|
||||
// Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up
|
||||
Dcc.pin(0, 2, 0);
|
||||
// Call the main DCC Init function to enable the DCC Receiver
|
||||
Dcc.init( MAN_ID_DIY, 600, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
Dcc.init( MAN_ID_DIY, 601, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
}
|
||||
void loop()
|
||||
{
|
||||
|
||||
4
examples/SMA/Dec_SMA12_LED_Groups/Dec_SMA12_LED_Groups.ino
Executable file → Normal file
4
examples/SMA/Dec_SMA12_LED_Groups/Dec_SMA12_LED_Groups.ino
Executable file → Normal file
@@ -1,5 +1,5 @@
|
||||
// Production 17 Function DCC Decoder Dec_SMA12_LED_Groups.ino
|
||||
// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Version 6.01 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Now works with both short and long DCC Addesses
|
||||
|
||||
// NO LONGER REQUIRES modified software servo Lib
|
||||
@@ -127,7 +127,7 @@ void setup()
|
||||
// Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up
|
||||
Dcc.pin(0, 2, 0);
|
||||
// Call the main DCC Init function to enable the DCC Receiver
|
||||
Dcc.init( MAN_ID_DIY, 600, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
Dcc.init( MAN_ID_DIY, 601, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
delay(800);
|
||||
#if defined(DECODER_LOADED)
|
||||
if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET )
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Production Stepper Drive DCC Decoder Dec_Stepper_6Ftn.ino
|
||||
// Version 6.0 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Version 6.01 Geoff Bunza 2014,2015,2016,2017,2018
|
||||
// Now works with both short and long DCC Addesses
|
||||
|
||||
// NO LONGER REQUIRES modified software servo Lib
|
||||
@@ -236,7 +236,7 @@ void setup() //******************************************************
|
||||
// Setup which External Interrupt, the Pin it's associated with that we're using
|
||||
Dcc.pin(0, 2, 0);
|
||||
// Call the main DCC Init function to enable the DCC Receiver
|
||||
Dcc.init( MAN_ID_DIY, 600, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
Dcc.init( MAN_ID_DIY, 601, FLAGS_MY_ADDRESS_ONLY, 0 );
|
||||
delay(800);
|
||||
|
||||
#if defined(DECODER_LOADED)
|
||||
|
||||
Binary file not shown.
@@ -1,9 +1,9 @@
|
||||
name=NmraDcc
|
||||
version=2.0.0
|
||||
author=Alex Shepherd, Wolfgang Kuffer, Geoff Bunza, Martin Pischky, Franz-Peter Müller, Sven (littleyoda)
|
||||
version=2.0.1
|
||||
author=Alex Shepherd, Wolfgang Kuffer, Geoff Bunza, Martin Pischky, Franz-Peter Müller, Sven (littleyoda), Hans Tanner
|
||||
maintainer=Alex Shepherd <kiwi64ajs@gmail.com>
|
||||
sentence=Enables NMRA DCC Communication
|
||||
paragraph=This library allows you to interface to a NMRA DCC track signal and receive DCC commands. The library currently supports the AVR ATTiny84/85 & ATMega88/168/328/32u4 and Teensy 3.x using the INT0/1 Hardware Interrupt and micros() ONLY and no longer uses Timer0 Compare Match B, which makes it much more portable to other platforms. WARNING as of version 1.4.4 support for the call-back functions notifyDccAccState() and notifyDccSigState() has been removed, please check and update your sketches, as they will silently fail.
|
||||
paragraph=This library allows you to interface to a NMRA DCC track signal and receive DCC commands. The library has been tested on AVR ATTiny84/85 & ATMega88/168/328/32u4, ESP8266 and Teensy 3.x using the INT0/1 Hardware Interrupt and micros() ONLY and no longer uses Timer0 Compare Match B, which makes it much more portable to other platforms.
|
||||
category=Communication
|
||||
url=https://github.com/mrrwa/NmraDcc
|
||||
architectures=avr,esp8266,STM32F1
|
||||
architectures=*
|
||||
|
||||
Reference in New Issue
Block a user