Merge branch 'master' into MicroBahner-Without-use-of-HW-timers

This commit is contained in:
Alex Shepherd
2016-03-24 18:51:12 +13:00
20 changed files with 626 additions and 64 deletions

View File

@@ -888,8 +888,17 @@ void execDccProcessor( DCC_MSG * pDccMsg )
if(pDccMsg->Data[1] & 0b10000000)
{
uint8_t direction = OutputAddress & 0x01;
uint8_t outputPower = (pDccMsg->Data[1] & 0b00001000) >> 3;
if( notifyDccAccState )
notifyDccAccState( Address, BoardAddress, OutputAddress, pDccMsg->Data[1] & 0b00001000 ) ;
if( notifyDccAccTurnoutBoard )
notifyDccAccTurnoutBoard( BoardAddress, OutputIndex, direction, outputPower );
if( notifyDccAccTurnoutOutput )
notifyDccAccTurnoutOutput( Address, direction, outputPower );
}
else

View File

@@ -223,6 +223,8 @@ extern void notifyDccSpeedRaw( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Ra
extern void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) __attribute__ ((weak));
extern void notifyDccAccState( uint16_t Addr, uint16_t BoardAddr, uint8_t OutputAddr, uint8_t State ) __attribute__ ((weak));
extern void notifyDccAccTurnoutBoard( uint16_t BoardAddr, uint8_t OutputPair, uint8_t Direction, uint8_t OutputPower ) __attribute__ ((weak));
extern void notifyDccAccTurnoutOutput( uint16_t Addr, uint8_t Direction, uint8_t OutputPower ) __attribute__ ((weak));
extern void notifyDccSigState( uint16_t Addr, uint8_t OutputIndex, uint8_t State) __attribute__ ((weak));

View File

@@ -69,6 +69,30 @@ void notifyDccAccState( uint16_t Addr, uint16_t BoardAddr, uint8_t OutputAddr, u
Serial.println(State, HEX) ;
}
// This function is called whenever a normal DCC Turnout Packet is received
void notifyDccAccTurnoutBoard( uint16_t BoardAddr, uint8_t OutputPair, uint8_t Direction, uint8_t OutputPower )
{
Serial.print("notifyDccAccTurnoutBoard: ") ;
Serial.print(BoardAddr,DEC) ;
Serial.print(',');
Serial.print(OutputPair,DEC) ;
Serial.print(',');
Serial.print(Direction,DEC) ;
Serial.print(',');
Serial.println(OutputPower, HEX) ;
}
// This function is called whenever a normal DCC Turnout Packet is received
void notifyDccAccTurnoutOutput( uint16_t Addr, uint8_t Direction, uint8_t OutputPower )
{
Serial.print("notifyDccAccTurnoutOutput: ") ;
Serial.print(Addr,DEC) ;
Serial.print(',');
Serial.print(Direction,DEC) ;
Serial.print(',');
Serial.println(OutputPower, HEX) ;
}
// This function is called whenever a DCC Signal Aspect Packet is received
void notifyDccSigState( uint16_t Addr, uint8_t OutputIndex, uint8_t State)
{

View File

@@ -0,0 +1,214 @@
#include <NmraDcc.h>
#include "PinPulser.h"
// This Example shows how to use the library as a DCC Accessory Decoder to drive 8 Pulsed Turnouts
// You can print every DCC packet by un-commenting the line below
//#define NOTIFY_DCC_MSG
// You can print every notifyDccAccTurnoutOutput call-back by un-commenting the line below
#define NOTIFY_TURNOUT_MSG
// You can also print other Debug Messages uncommenting the line below
#define DEBUG_MSG
// Un-Comment the line below to force CVs to be written to the Factory Default values
// defined in the FactoryDefaultCVs below on Start-Up
#define FORCE_RESET_FACTORY_DEFAULT_CV
// Un-Comment the line below to Enable DCC ACK for Service Mode Programming Read CV Capablilty
//#define ENABLE_DCC_ACK 15 // This is A1 on the Iowa Scaled Engineering ARD-DCCSHIELD DCC Shield
#define NUM_TURNOUTS 8 // Set Number of Turnouts (Pairs of Pins)
#define ACTIVE_OUTPUT_STATE LOW // Set the ACTIVE State of the output to Drive the Turnout motor electronics HIGH or LOW
#define DCC_DECODER_VERSION_NUM 11 // Set the Decoder Version - Used by JMRI to Identify the decoder
struct CVPair
{
uint16_t CV;
uint8_t Value;
};
#define CV_ACCESSORY_DECODER_OUTPUT_PULSE_TIME 2 // CV for the Output Pulse ON ms
#define CV_ACCESSORY_DECODER_CDU_RECHARGE_TIME 3 // CV for the delay in ms to allow a CDU to recharge
#define CV_ACCESSORY_DECODER_ACTIVE_STATE 4 // CV to define the ON Output State
// To set the Turnout Addresses for this board you need to change the CV values for CV1 (CV_ACCESSORY_DECODER_ADDRESS_LSB) and
// CV9 (CV_ACCESSORY_DECODER_ADDRESS_MSB) in the FactoryDefaultCVs structure below. The Turnout Addresses are defined as:
// Base Turnout Address is: ((((CV9 * 64) + CV1) - 1) * 4) + 1
// With NUM_TURNOUTS 8 (above) a CV1 = 1 and CV9 = 0, the Turnout Addresses will be 1..8, for CV1 = 2 the Turnout Address is 5..12
CVPair FactoryDefaultCVs [] =
{
{CV_ACCESSORY_DECODER_ADDRESS_LSB, 1}, // CV 1 Board Address (lower 6 bits)
{CV_ACCESSORY_DECODER_ADDRESS_MSB, 0}, // CV 9 Board Address (Upper 3 bits)
{CV_ACCESSORY_DECODER_OUTPUT_PULSE_TIME, 50}, // x 10mS for the output pulse duration
{CV_ACCESSORY_DECODER_CDU_RECHARGE_TIME, 30}, // x 10mS for the CDU recharge delay time
{CV_ACCESSORY_DECODER_ACTIVE_STATE, ACTIVE_OUTPUT_STATE},
};
uint8_t FactoryDefaultCVIndex = 0;
// This is the Arduino Pin Mapping to Turnout Addresses with 2 pins per turnout
// A1 is missing in the sequence as it is used for the DCC ACK
// The Pins are defined in Pairs T=Thrown, C=Closed (Digitrax Notation)
// base address 1T 1C 2T 2C 3T 3C 4T 4C 5T 5C 6T 6C 7T 7C 8T 8C
byte outputs[] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19};
// pins D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 A0 A2 A3 A4 A5
NmraDcc Dcc ;
DCC_MSG Packet ;
PinPulser pinPulser;
uint16_t BaseTurnoutAddress;
// This function is called whenever a normal DCC Turnout Packet is received
void notifyDccAccTurnoutOutput( uint16_t Addr, uint8_t Direction, uint8_t OutputPower )
{
#ifdef NOTIFY_TURNOUT_MSG
Serial.print("notifyDccAccTurnoutOutput: Turnout: ") ;
Serial.print(Addr,DEC) ;
Serial.print(" Direction: ");
Serial.print(Direction ? "Closed" : "Thrown") ;
Serial.print(" Output: ");
Serial.print(OutputPower ? "On" : "Off") ;
#endif
if(( Addr >= BaseTurnoutAddress ) && ( Addr < (BaseTurnoutAddress + NUM_TURNOUTS )) && OutputPower )
{
uint16_t pinIndex = ( (Addr - BaseTurnoutAddress) << 1 ) + Direction ;
pinPulser.addPin(outputs[pinIndex]);
#ifdef NOTIFY_TURNOUT_MSG
Serial.print(" Pin Index: ");
Serial.print(pinIndex,DEC);
Serial.print(" Pin: ");
Serial.print(outputs[pinIndex],DEC);
#endif
}
#ifdef NOTIFY_TURNOUT_MSG
Serial.println();
#endif
}
void initPinPulser(void)
{
BaseTurnoutAddress = (((Dcc.getCV(CV_ACCESSORY_DECODER_ADDRESS_MSB) * 64) + Dcc.getCV(CV_ACCESSORY_DECODER_ADDRESS_LSB) - 1) * 4) + 1 ;
uint16_t onMs = Dcc.getCV(CV_ACCESSORY_DECODER_OUTPUT_PULSE_TIME) * 10;
uint16_t cduRechargeMs = Dcc.getCV(CV_ACCESSORY_DECODER_CDU_RECHARGE_TIME) * 10;
uint8_t activeOutputState = Dcc.getCV(CV_ACCESSORY_DECODER_ACTIVE_STATE);
#ifdef DEBUG_MSG
Serial.print("initPinPulser: DCC Turnout Base Address: "); Serial.print(BaseTurnoutAddress, DEC);
Serial.print(" Active Pulse: "); Serial.print(onMs);
Serial.print("ms CDU Recharge: "); Serial.print(cduRechargeMs);
Serial.print("ms Active Output State: "); Serial.println(activeOutputState ? "HIGH" : "LOW" );
#endif
// Step through all the Turnout Driver pins setting them to OUTPUT and NOT Active State
for(uint8_t i = 0; i < (NUM_TURNOUTS * 2); i++)
{
digitalWrite(outputs[i], !activeOutputState); // Set the Output Inactive before the direction so the
pinMode( outputs[i], OUTPUT ); // Pin doesn't momentarily pulse the wrong state
}
// Init the PinPulser with the new settings
pinPulser.init(onMs, cduRechargeMs, activeOutputState);
}
void setup()
{
Serial.begin(115200);
// Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up
Dcc.pin(0, 2, 1);
// Call the main DCC Init function to enable the DCC Receiver
Dcc.init( MAN_ID_DIY, DCC_DECODER_VERSION_NUM, CV29_ACCESSORY_DECODER, 0 );
#ifdef DEBUG_MSG
Serial.print("\nNMRA DCC 8-Turnout Accessory Decoder. Ver: "); Serial.println(DCC_DECODER_VERSION_NUM,DEC);
#endif
#ifdef FORCE_RESET_FACTORY_DEFAULT_CV
Serial.println("Resetting CVs to Factory Defaults");
notifyCVResetFactoryDefault();
#endif
if( FactoryDefaultCVIndex == 0) // Not forcing a reset CV Reset to Factory Defaults so initPinPulser
initPinPulser();
}
void loop()
{
// You MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation
Dcc.process();
pinPulser.process();
if( FactoryDefaultCVIndex && Dcc.isSetCVReady())
{
FactoryDefaultCVIndex--; // Decrement first as initially it is the size of the array
uint16_t cv = FactoryDefaultCVs[FactoryDefaultCVIndex].CV;
uint8_t val = FactoryDefaultCVs[FactoryDefaultCVIndex].Value;
#ifdef DEBUG_MSG
Serial.print("loop: Write Default CV: "); Serial.print(cv,DEC); Serial.print(" Value: "); Serial.println(val,DEC);
#endif
Dcc.setCV( cv, val );
if( FactoryDefaultCVIndex == 0) // Is this the last Default CV to set? if so re-initPinPulser
initPinPulser();
}
}
void notifyCVChange(uint16_t CV, uint8_t Value)
{
#ifdef DEBUG_MSG
Serial.print("notifyCVChange: CV: ") ;
Serial.print(CV,DEC) ;
Serial.print(" Value: ") ;
Serial.println(Value, DEC) ;
#endif
Value = Value; // Silence Compiler Warnings...
if((CV == CV_ACCESSORY_DECODER_ADDRESS_MSB) || (CV == CV_ACCESSORY_DECODER_ADDRESS_LSB) ||
(CV == CV_ACCESSORY_DECODER_OUTPUT_PULSE_TIME) || (CV == CV_ACCESSORY_DECODER_CDU_RECHARGE_TIME) || (CV == CV_ACCESSORY_DECODER_ACTIVE_STATE))
initPinPulser(); // Some CV we care about changed so re-init the PinPulser with the new CV settings
}
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 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
#ifdef ENABLE_DCC_ACK
void notifyCVAck(void)
{
#ifdef DEBUG_MSG
Serial.println("notifyCVAck") ;
#endif
// Configure the DCC CV Programing ACK pin for an output
pinMode( ENABLE_DCC_ACK, OUTPUT );
// Generate the DCC ACK 60mA pulse
digitalWrite( ENABLE_DCC_ACK, HIGH );
delay( 10 ); // The DCC Spec says 6ms but 10 makes sure... ;)
digitalWrite( ENABLE_DCC_ACK, LOW );
}
#endif
#ifdef NOTIFY_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

View File

@@ -0,0 +1,92 @@
#include "PinPulser.h"
#define PIN_PULSER_SLOT_EMPTY 255
void PinPulser::init(uint16_t onMs, uint16_t cduRechargeMs, uint8_t activeOutputState)
{
this->onMs = onMs;
this->cduRechargeMs = cduRechargeMs;
this->activeOutputState = activeOutputState;
state = PP_IDLE;
targetMs = 0;
memset(pinQueue, PIN_PULSER_SLOT_EMPTY, PIN_PULSER_MAX_PINS + 1);
}
uint8_t PinPulser::addPin(uint8_t Pin)
{
// Serial.print(" PinPulser::addPin: "); Serial.print(Pin,DEC);
for(uint8_t i = 0; i < PIN_PULSER_MAX_PINS; i++)
{
if(pinQueue[i] == Pin)
{
// Serial.print(" Already in Index: "); Serial.println(i,DEC);
return i;
}
else if(pinQueue[i] == PIN_PULSER_SLOT_EMPTY)
{
// Serial.print(" pinQueue Index: "); Serial.println(i,DEC);
pinQueue[i] = Pin;
process();
return i;
}
}
// Serial.println();
return PIN_PULSER_SLOT_EMPTY;
}
PP_State PinPulser::process(void)
{
unsigned long now;
switch(state)
{
case PP_IDLE:
if(pinQueue[0] != PIN_PULSER_SLOT_EMPTY)
{
// Serial.print(" PinPulser::process: PP_IDLE: Pin: "); Serial.println(pinQueue[0],DEC);
digitalWrite(pinQueue[0], activeOutputState);
targetMs = millis() + onMs;
state = PP_OUTPUT_ON_DELAY;
}
break;
case PP_OUTPUT_ON_DELAY:
now = millis();
if(now >= targetMs)
{
// Serial.print(" PinPulser::process: PP_OUTPUT_ON_DELAY: Done Deactivate Pin: "); Serial.println(pinQueue[0],DEC);
digitalWrite(pinQueue[0], !activeOutputState);
targetMs = now + cduRechargeMs;
memmove(pinQueue, pinQueue + 1, PIN_PULSER_MAX_PINS);
state = PP_CDU_RECHARGE_DELAY;
}
break;
case PP_CDU_RECHARGE_DELAY:
now = millis();
if(now >= targetMs)
{
if(pinQueue[0] != PIN_PULSER_SLOT_EMPTY)
{
// Serial.print(" PinPulser::process: PIN_PULSER_SLOT_EMPTY: Done Deactivate Pin: "); Serial.println(pinQueue[0],DEC);
digitalWrite(pinQueue[0], activeOutputState);
targetMs = now + onMs;
state = PP_OUTPUT_ON_DELAY;
}
else
{
// Serial.println(" PinPulser::process: PP_CDU_RECHARGE_DELAY - Now PP_IDLE");
state = PP_IDLE;
}
}
break;
}
return state;
}

View File

@@ -0,0 +1,27 @@
#include <Arduino.h>
#define PIN_PULSER_MAX_PINS 16
enum PP_State
{
PP_IDLE = 0,
PP_OUTPUT_ON_DELAY,
PP_CDU_RECHARGE_DELAY,
};
class PinPulser
{
private:
uint16_t onMs;
uint16_t cduRechargeMs;
PP_State state = PP_IDLE;
unsigned long targetMs = 0;
uint8_t activeOutputState = HIGH;
uint8_t pinQueue[PIN_PULSER_MAX_PINS + 1];
public:
void init(uint16_t onMs, uint16_t cduRechargeMs, uint8_t activeOutputState);
uint8_t addPin(uint8_t pin);
PP_State process(void);
};

View File

@@ -0,0 +1,195 @@
#include <NmraDcc.h>
#define This_Decoder_Address 3
struct CVPair
{
uint16_t CV;
uint8_t Value;
};
CVPair FactoryDefaultCVs [] =
{
// The CV Below defines the Short DCC Address
{CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address},
// These two CVs define the Long DCC Address
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0},
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_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;
// Uncomment this line below to force resetting the CVs back to Factory Defaults
// FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair);
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);
};
// Uncomment the #define below to print all Speed Packets
#define NOTIFY_DCC_SPEED
#ifdef NOTIFY_DCC_SPEED
void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_DIRECTION Dir, DCC_SPEED_STEPS SpeedSteps )
{
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
// Uncomment the #define below to print all Function Packets
#define NOTIFY_DCC_FUNC
#ifdef NOTIFY_DCC_FUNC
void notifyDccFunc(uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState)
{
Serial.print("notifyDccFunc: Addr: ");
Serial.print(Addr,DEC);
Serial.print( (AddrType == DCC_ADDR_SHORT) ? 'S' : 'L' );
Serial.print(" Function Group: ");
Serial.print(FuncGrp,DEC);
switch( FuncGrp )
{
#ifdef NMRA_DCC_ENABLE_14_SPEED_STEP_MODE
case FN_0:
Serial.print(" FN0: ");
Serial.println((FuncState & FN_BIT_00) ? "1 " : "0 ");
break;
#endif
case FN_0_4:
if(Dcc.getCV(CV_29_CONFIG) & CV29_F0_LOCATION) // Only process Function 0 in this packet if we're not in Speed Step 14 Mode
{
Serial.print(" FN 0: ");
Serial.print((FuncState & FN_BIT_00) ? "1 ": "0 ");
}
Serial.print(" FN 1-4: ");
Serial.print((FuncState & FN_BIT_01) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_02) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_03) ? "1 ": "0 ");
Serial.println((FuncState & FN_BIT_04) ? "1 ": "0 ");
break;
case FN_5_8:
Serial.print(" FN 5-8: ");
Serial.print((FuncState & FN_BIT_05) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_06) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_07) ? "1 ": "0 ");
Serial.println((FuncState & FN_BIT_08) ? "1 ": "0 ");
break;
case FN_9_12:
Serial.print(" FN 9-12: ");
Serial.print((FuncState & FN_BIT_09) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_10) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_11) ? "1 ": "0 ");
Serial.println((FuncState & FN_BIT_12) ? "1 ": "0 ");
break;
case FN_13_20:
Serial.print(" FN 13-20: ");
Serial.print((FuncState & FN_BIT_13) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_14) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_15) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_16) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_17) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_18) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_19) ? "1 ": "0 ");
Serial.println((FuncState & FN_BIT_20) ? "1 ": "0 ");
break;
case FN_21_28:
Serial.print(" FN 21-28: ");
Serial.print((FuncState & FN_BIT_21) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_22) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_23) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_24) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_25) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_26) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_27) ? "1 ": "0 ");
Serial.println((FuncState & FN_BIT_28) ? "1 ": "0 ");
break;
}
}
#endif
// Uncomment the #define below to print all DCC Packets
#define NOTIFY_DCC_MSG
#ifdef NOTIFY_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 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
const int DccAckPin = 15 ;
void notifyCVAck(void)
{
Serial.println("notifyCVAck") ;
digitalWrite( DccAckPin, HIGH );
delay( 8 );
digitalWrite( DccAckPin, LOW );
}
void setup()
{
Serial.begin(115200);
Serial.println("NMRA Dcc Multifunction Decoder Demo 1");
// Configure the DCC CV Programing ACK pin for an output
pinMode( DccAckPin, OUTPUT );
digitalWrite( DccAckPin, LOW );
// 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, 10, CV29_ACCESSORY_DECODER | CV29_OUTPUT_ADDRESS_MODE, 0 );
Dcc.init( MAN_ID_DIY, 10, FLAGS_MY_ADDRESS_ONLY, 0 );
// Uncomment to force CV Reset to Factory Defaults
notifyCVResetFactoryDefault();
}
void loop()
{
// You MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation
Dcc.process();
if( FactoryDefaultCVIndex && Dcc.isSetCVReady())
{
FactoryDefaultCVIndex--; // Decrement first as initially it is the size of the array
Dcc.setCV( FactoryDefaultCVs[FactoryDefaultCVIndex].CV, FactoryDefaultCVs[FactoryDefaultCVIndex].Value);
}
}

View File

@@ -68,7 +68,6 @@ struct QUEUE
};
QUEUE *ftn_queue = new QUEUE[16];
extern uint8_t Decoder_Address = This_Decoder_Address;
struct CVPair
{
uint16_t CV;
@@ -407,7 +406,7 @@ void loop() //****************************************************************
}
}
extern void notifyDccFunc( uint16_t Addr, FN_GROUP FuncGrp, uint8_t FuncState) {
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) {
switch(FuncGrp)
{
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1

View File

@@ -68,7 +68,6 @@ struct QUEUE
};
QUEUE *ftn_queue = new QUEUE[16];
extern uint8_t Decoder_Address = This_Decoder_Address;
struct CVPair
{
uint16_t CV;
@@ -407,7 +406,7 @@ void loop() //****************************************************************
}
}
extern void notifyDccFunc( uint16_t Addr, FN_GROUP FuncGrp, uint8_t FuncState) {
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) {
switch(FuncGrp)
{
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1

View File

@@ -68,7 +68,6 @@ struct QUEUE
};
QUEUE *ftn_queue = new QUEUE[16];
extern uint8_t Decoder_Address = This_Decoder_Address;
struct CVPair
{
uint16_t CV;
@@ -407,7 +406,7 @@ void loop() //****************************************************************
}
}
extern void notifyDccFunc( uint16_t Addr, FN_GROUP FuncGrp, uint8_t FuncState) {
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) {
switch(FuncGrp)
{
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1

View File

@@ -33,7 +33,6 @@ DCC_MSG Packet ;
#define This_Decoder_Address 17
extern uint8_t Decoder_Address = This_Decoder_Address;
struct CVPair
{
uint16_t CV;
@@ -89,7 +88,7 @@ void loop()
}
}
extern void notifyDccFunc( uint16_t Addr, FN_GROUP FuncGrp, uint8_t FuncState)
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState)
{
switch(FuncGrp)
{

View File

@@ -68,7 +68,6 @@ struct QUEUE
};
QUEUE *ftn_queue = new QUEUE[16];
extern uint8_t Decoder_Address = This_Decoder_Address;
struct CVPair
{
uint16_t CV;
@@ -407,7 +406,7 @@ void loop() //****************************************************************
}
}
extern void notifyDccFunc( uint16_t Addr, FN_GROUP FuncGrp, uint8_t FuncState) {
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) {
switch(FuncGrp)
{
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1

View File

@@ -67,7 +67,6 @@ struct QUEUE
};
QUEUE *ftn_queue = new QUEUE[16];
extern uint8_t Decoder_Address = This_Decoder_Address;
struct CVPair
{
uint16_t CV;
@@ -416,7 +415,7 @@ void loop() //****************************************************************
}
}
extern void notifyDccFunc( uint16_t Addr, uint8_t FuncNum, uint8_t FuncState) {
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) {
if (FuncNum==1) { //Function Group 1 F0 F4 F3 F2 F1
exec_function( 0, FunctionPin0, (FuncState&0x10)>>4 );
exec_function( 1, FunctionPin1, (FuncState&0x01 ));

View File

@@ -71,7 +71,6 @@ struct QUEUE
};
QUEUE *ftn_queue = new QUEUE[16];
extern uint8_t Decoder_Address = This_Decoder_Address;
struct CVPair
{
uint16_t CV;
@@ -420,7 +419,7 @@ void loop() //****************************************************************
}
}
extern void notifyDccFunc( uint16_t Addr, FN_GROUP FuncGrp, uint8_t FuncState) {
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) {
switch(FuncGrp)
{
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1

View File

@@ -85,7 +85,6 @@ struct QUEUE
};
QUEUE *ftn_queue = new QUEUE[16];
extern uint8_t Decoder_Address = This_Decoder_Address;
struct CVPair
{
uint16_t CV;
@@ -470,7 +469,7 @@ void gobwd2(int bcnt,int bcycle) {
icnt++;
}
}
extern void notifyDccSpeed( uint16_t Addr, uint8_t Speed, uint8_t ForwardDir, uint8_t MaxSpeed ) {
void notifyDccSpeed( uint16_t Addr, uint8_t Speed, uint8_t ForwardDir, uint8_t MaxSpeed ) {
if (Function13_value==1) {
Motor1Speed = Speed;
Motor1ForwardDir = ForwardDir;
@@ -482,7 +481,7 @@ extern void notifyDccSpeed( uint16_t Addr, uint8_t Speed, uint8_t ForwardDir, ui
Motor2MaxSpeed = MaxSpeed;
}
}
extern void notifyDccFunc( uint16_t Addr, FN_GROUP FuncGrp, uint8_t FuncState) {
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) {
switch(FuncGrp)
{
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
@@ -670,3 +669,4 @@ void detach_servo (int servo_num) {
break;
}
}

View File

@@ -68,7 +68,6 @@ struct QUEUE
};
QUEUE *ftn_queue = new QUEUE[16];
extern uint8_t Decoder_Address = This_Decoder_Address;
struct CVPair
{
uint16_t CV;
@@ -407,7 +406,7 @@ void loop() //****************************************************************
}
}
extern void notifyDccFunc( uint16_t Addr, FN_GROUP FuncGrp, uint8_t FuncState) {
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) {
switch(FuncGrp)
{
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1

View File

@@ -101,7 +101,8 @@ void loop()
// You MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation
Dcc.process();
}
extern void notifyDccFunc( uint16_t Addr, FN_GROUP FuncGrp, uint8_t FuncState) {
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) {
int f_index;
switch (FuncGrp) {
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
@@ -145,7 +146,8 @@ void exec_function (int f_index, int FuncState) {
Set_LED (f_index,false);
}
}
extern void notifyDccSpeed( uint16_t Addr, uint8_t Speed, uint8_t ForwardDir, uint8_t MaxSpeed ) {
void notifyDccSpeed( uint16_t Addr, uint8_t Speed, uint8_t ForwardDir, uint8_t MaxSpeed ) {
Last_Decoder_direction = Decoder_direction;
Decoder_direction = ForwardDir;
if ( Decoder_direction==Last_Decoder_direction) return;
@@ -197,3 +199,4 @@ void Switch_LED (int Function) {
}
led_last_state[Function] = end_state;
}

View File

@@ -123,7 +123,7 @@ void loop()
Dcc.process();
}
extern void notifyDccFunc( uint16_t Addr, FN_GROUP FuncGrp, uint8_t FuncState) {
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) {
int f_index;
switch (FuncGrp) {
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
@@ -173,3 +173,4 @@ void exec_function (int f_index, int FuncState) {
}
}

View File

@@ -22,8 +22,11 @@ isSetCVReady KEYWORD2
notifyDccReset KEYWORD2
notifyDccIdle KEYWORD2
notifyDccSpeed KEYWORD2
notifyDccSpeedRaw
notifyDccFunc KEYWORD2
notifyDccAccState KEYWORD2
notifyDccAccTurnoutBoard
notifyDccAccTurnoutOutput
notifyDccSigState KEYWORD2
notifyDccMsg KEYWORD2
notifyCVValid KEYWORD2

View File

@@ -1,5 +1,5 @@
name=NmraDcc
version=1.1.0
version=1.2.0
author=Alex Shepherd, Wolfgang Kuffer, Geoff Bunza, Martin Pischky
maintainer=Alex Shepherd <kiwi64ajs@gmail.com>
sentence=Enables NMRA DCC Communication