Files
NmraDcc/examples/NmraDccAccessoryDecoder_1/NmraDccAccessoryDecoder_1.ino
Alex Shepherd c3dc28479a corrected Fwd/Rev LED logic in NmraDccMultiFunctionMotorDecoder example
added conditional compilation to use the newer Dcc.pin() method that used digitalPinToInterrupt() to determine the Ext Interrupt Number based on Arduino Pin to reduce confusion
2021-08-30 14:11:54 +12:00

130 lines
3.9 KiB
C++

#include <NmraDcc.h>
// This Example shows how to use the library as a DCC Accessory Decoder or a DCC Signalling Decoder
// It responds to both the normal DCC Turnout Control packets and the newer DCC Signal Aspect packets
// You can also print every DCC packet by uncommenting the "#define NOTIFY_DCC_MSG" line below
NmraDcc Dcc ;
DCC_MSG Packet ;
// Define the Arduino input Pin number for the DCC Signal
#define DCC_PIN 2
struct CVPair
{
uint16_t CV;
uint8_t Value;
};
CVPair FactoryDefaultCVs [] =
{
{CV_ACCESSORY_DECODER_ADDRESS_LSB, DEFAULT_ACCESSORY_DECODER_ADDRESS & 0xFF},
{CV_ACCESSORY_DECODER_ADDRESS_MSB, DEFAULT_ACCESSORY_DECODER_ADDRESS >> 8},
};
uint8_t FactoryDefaultCVIndex = 0;
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);
};
const int DccAckPin = 3 ;
// 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
void notifyCVAck(void)
{
Serial.println("notifyCVAck") ;
digitalWrite( DccAckPin, HIGH );
delay( 6 );
digitalWrite( DccAckPin, LOW );
}
// Uncomment 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 whenever a normal DCC Turnout Packet is received and we're in Board Addressing Mode
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 and we're in Output Addressing Mode
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 notifyDccSigOutputState( uint16_t Addr, uint8_t State)
{
Serial.print("notifyDccSigOutputState: ") ;
Serial.print(Addr,DEC) ;
Serial.print(',');
Serial.println(State, HEX) ;
}
void setup()
{
Serial.begin(115200);
// Configure the DCC CV Programing ACK pin for an output
pinMode( DccAckPin, OUTPUT );
Serial.println("NMRA DCC Example 1");
// Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up
// Many Arduino Cores now support the digitalPinToInterrupt() function that makes it easier to figure out the
// Interrupt Number for the Arduino Pin number, which reduces confusion.
#ifdef digitalPinToInterrupt
Dcc.pin(DCC_PIN, 0);
#else
Dcc.pin(0, DCC_PIN, 1);
#endif
// 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 );
Serial.println("Init Done");
}
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);
}
}