Merge branch 'master' into MicroBahner-Without-use-of-HW-timers
This commit is contained in:
@@ -888,8 +888,17 @@ void execDccProcessor( DCC_MSG * pDccMsg )
|
|||||||
|
|
||||||
if(pDccMsg->Data[1] & 0b10000000)
|
if(pDccMsg->Data[1] & 0b10000000)
|
||||||
{
|
{
|
||||||
|
uint8_t direction = OutputAddress & 0x01;
|
||||||
|
uint8_t outputPower = (pDccMsg->Data[1] & 0b00001000) >> 3;
|
||||||
|
|
||||||
if( notifyDccAccState )
|
if( notifyDccAccState )
|
||||||
notifyDccAccState( Address, BoardAddress, OutputAddress, pDccMsg->Data[1] & 0b00001000 ) ;
|
notifyDccAccState( Address, BoardAddress, OutputAddress, pDccMsg->Data[1] & 0b00001000 ) ;
|
||||||
|
|
||||||
|
if( notifyDccAccTurnoutBoard )
|
||||||
|
notifyDccAccTurnoutBoard( BoardAddress, OutputIndex, direction, outputPower );
|
||||||
|
|
||||||
|
if( notifyDccAccTurnoutOutput )
|
||||||
|
notifyDccAccTurnoutOutput( Address, direction, outputPower );
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@@ -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 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 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));
|
extern void notifyDccSigState( uint16_t Addr, uint8_t OutputIndex, uint8_t State) __attribute__ ((weak));
|
||||||
|
|
||||||
|
@@ -69,6 +69,30 @@ void notifyDccAccState( uint16_t Addr, uint16_t BoardAddr, uint8_t OutputAddr, u
|
|||||||
Serial.println(State, HEX) ;
|
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
|
// This function is called whenever a DCC Signal Aspect Packet is received
|
||||||
void notifyDccSigState( uint16_t Addr, uint8_t OutputIndex, uint8_t State)
|
void notifyDccSigState( uint16_t Addr, uint8_t OutputIndex, uint8_t State)
|
||||||
{
|
{
|
@@ -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
|
92
examples/NmraDccAccessoryDecoder_Pulsed_8/PinPulser.cpp
Normal file
92
examples/NmraDccAccessoryDecoder_Pulsed_8/PinPulser.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
|
27
examples/NmraDccAccessoryDecoder_Pulsed_8/PinPulser.h
Normal file
27
examples/NmraDccAccessoryDecoder_Pulsed_8/PinPulser.h
Normal 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);
|
||||||
|
};
|
||||||
|
|
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -68,7 +68,6 @@ struct QUEUE
|
|||||||
};
|
};
|
||||||
QUEUE *ftn_queue = new QUEUE[16];
|
QUEUE *ftn_queue = new QUEUE[16];
|
||||||
|
|
||||||
extern uint8_t Decoder_Address = This_Decoder_Address;
|
|
||||||
struct CVPair
|
struct CVPair
|
||||||
{
|
{
|
||||||
uint16_t CV;
|
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)
|
switch(FuncGrp)
|
||||||
{
|
{
|
||||||
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
|
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
|
||||||
|
@@ -68,7 +68,6 @@ struct QUEUE
|
|||||||
};
|
};
|
||||||
QUEUE *ftn_queue = new QUEUE[16];
|
QUEUE *ftn_queue = new QUEUE[16];
|
||||||
|
|
||||||
extern uint8_t Decoder_Address = This_Decoder_Address;
|
|
||||||
struct CVPair
|
struct CVPair
|
||||||
{
|
{
|
||||||
uint16_t CV;
|
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)
|
switch(FuncGrp)
|
||||||
{
|
{
|
||||||
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
|
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
|
||||||
|
@@ -68,7 +68,6 @@ struct QUEUE
|
|||||||
};
|
};
|
||||||
QUEUE *ftn_queue = new QUEUE[16];
|
QUEUE *ftn_queue = new QUEUE[16];
|
||||||
|
|
||||||
extern uint8_t Decoder_Address = This_Decoder_Address;
|
|
||||||
struct CVPair
|
struct CVPair
|
||||||
{
|
{
|
||||||
uint16_t CV;
|
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)
|
switch(FuncGrp)
|
||||||
{
|
{
|
||||||
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
|
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
|
||||||
|
@@ -33,7 +33,6 @@ DCC_MSG Packet ;
|
|||||||
|
|
||||||
#define This_Decoder_Address 17
|
#define This_Decoder_Address 17
|
||||||
|
|
||||||
extern uint8_t Decoder_Address = This_Decoder_Address;
|
|
||||||
struct CVPair
|
struct CVPair
|
||||||
{
|
{
|
||||||
uint16_t CV;
|
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)
|
switch(FuncGrp)
|
||||||
{
|
{
|
||||||
|
@@ -68,7 +68,6 @@ struct QUEUE
|
|||||||
};
|
};
|
||||||
QUEUE *ftn_queue = new QUEUE[16];
|
QUEUE *ftn_queue = new QUEUE[16];
|
||||||
|
|
||||||
extern uint8_t Decoder_Address = This_Decoder_Address;
|
|
||||||
struct CVPair
|
struct CVPair
|
||||||
{
|
{
|
||||||
uint16_t CV;
|
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)
|
switch(FuncGrp)
|
||||||
{
|
{
|
||||||
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
|
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
|
||||||
|
@@ -67,7 +67,6 @@ struct QUEUE
|
|||||||
};
|
};
|
||||||
QUEUE *ftn_queue = new QUEUE[16];
|
QUEUE *ftn_queue = new QUEUE[16];
|
||||||
|
|
||||||
extern uint8_t Decoder_Address = This_Decoder_Address;
|
|
||||||
struct CVPair
|
struct CVPair
|
||||||
{
|
{
|
||||||
uint16_t CV;
|
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
|
if (FuncNum==1) { //Function Group 1 F0 F4 F3 F2 F1
|
||||||
exec_function( 0, FunctionPin0, (FuncState&0x10)>>4 );
|
exec_function( 0, FunctionPin0, (FuncState&0x10)>>4 );
|
||||||
exec_function( 1, FunctionPin1, (FuncState&0x01 ));
|
exec_function( 1, FunctionPin1, (FuncState&0x01 ));
|
||||||
|
@@ -71,7 +71,6 @@ struct QUEUE
|
|||||||
};
|
};
|
||||||
QUEUE *ftn_queue = new QUEUE[16];
|
QUEUE *ftn_queue = new QUEUE[16];
|
||||||
|
|
||||||
extern uint8_t Decoder_Address = This_Decoder_Address;
|
|
||||||
struct CVPair
|
struct CVPair
|
||||||
{
|
{
|
||||||
uint16_t CV;
|
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)
|
switch(FuncGrp)
|
||||||
{
|
{
|
||||||
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
|
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
|
||||||
|
@@ -85,7 +85,6 @@ struct QUEUE
|
|||||||
};
|
};
|
||||||
QUEUE *ftn_queue = new QUEUE[16];
|
QUEUE *ftn_queue = new QUEUE[16];
|
||||||
|
|
||||||
extern uint8_t Decoder_Address = This_Decoder_Address;
|
|
||||||
struct CVPair
|
struct CVPair
|
||||||
{
|
{
|
||||||
uint16_t CV;
|
uint16_t CV;
|
||||||
@@ -470,7 +469,7 @@ void gobwd2(int bcnt,int bcycle) {
|
|||||||
icnt++;
|
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) {
|
if (Function13_value==1) {
|
||||||
Motor1Speed = Speed;
|
Motor1Speed = Speed;
|
||||||
Motor1ForwardDir = ForwardDir;
|
Motor1ForwardDir = ForwardDir;
|
||||||
@@ -482,7 +481,7 @@ extern void notifyDccSpeed( uint16_t Addr, uint8_t Speed, uint8_t ForwardDir, ui
|
|||||||
Motor2MaxSpeed = MaxSpeed;
|
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)
|
switch(FuncGrp)
|
||||||
{
|
{
|
||||||
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
|
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
|
||||||
@@ -669,4 +668,5 @@ void detach_servo (int servo_num) {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -68,7 +68,6 @@ struct QUEUE
|
|||||||
};
|
};
|
||||||
QUEUE *ftn_queue = new QUEUE[16];
|
QUEUE *ftn_queue = new QUEUE[16];
|
||||||
|
|
||||||
extern uint8_t Decoder_Address = This_Decoder_Address;
|
|
||||||
struct CVPair
|
struct CVPair
|
||||||
{
|
{
|
||||||
uint16_t CV;
|
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)
|
switch(FuncGrp)
|
||||||
{
|
{
|
||||||
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
|
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
|
||||||
|
@@ -101,7 +101,8 @@ void loop()
|
|||||||
// You MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation
|
// You MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation
|
||||||
Dcc.process();
|
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;
|
int f_index;
|
||||||
switch (FuncGrp) {
|
switch (FuncGrp) {
|
||||||
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
|
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);
|
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;
|
Last_Decoder_direction = Decoder_direction;
|
||||||
Decoder_direction = ForwardDir;
|
Decoder_direction = ForwardDir;
|
||||||
if ( Decoder_direction==Last_Decoder_direction) return;
|
if ( Decoder_direction==Last_Decoder_direction) return;
|
||||||
@@ -196,4 +198,5 @@ void Switch_LED (int Function) {
|
|||||||
delayMicroseconds (1000.*time_fraction);
|
delayMicroseconds (1000.*time_fraction);
|
||||||
}
|
}
|
||||||
led_last_state[Function] = end_state;
|
led_last_state[Function] = end_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -123,7 +123,7 @@ void loop()
|
|||||||
Dcc.process();
|
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;
|
int f_index;
|
||||||
switch (FuncGrp) {
|
switch (FuncGrp) {
|
||||||
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
|
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
|
||||||
@@ -172,4 +172,5 @@ void exec_function (int f_index, int FuncState) {
|
|||||||
Last_Function_State[f_index] = false;
|
Last_Function_State[f_index] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
79
keywords.txt
79
keywords.txt
@@ -6,54 +6,57 @@
|
|||||||
# Datatypes (KEYWORD1)
|
# Datatypes (KEYWORD1)
|
||||||
#######################################
|
#######################################
|
||||||
|
|
||||||
DCC_MSG KEYWORD1
|
DCC_MSG KEYWORD1
|
||||||
NmraDcc KEYWORD1
|
NmraDcc KEYWORD1
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
# Methods and Functions (KEYWORD2)
|
# Methods and Functions (KEYWORD2)
|
||||||
#######################################
|
#######################################
|
||||||
NmraDcc KEYWORD2
|
NmraDcc KEYWORD2
|
||||||
pin KEYWORD2
|
pin KEYWORD2
|
||||||
init KEYWORD2
|
init KEYWORD2
|
||||||
process KEYWORD2
|
process KEYWORD2
|
||||||
getCV KEYWORD2
|
getCV KEYWORD2
|
||||||
setCV KEYWORD2
|
setCV KEYWORD2
|
||||||
isSetCVReady KEYWORD2
|
isSetCVReady KEYWORD2
|
||||||
notifyDccReset KEYWORD2
|
notifyDccReset KEYWORD2
|
||||||
notifyDccIdle KEYWORD2
|
notifyDccIdle KEYWORD2
|
||||||
notifyDccSpeed KEYWORD2
|
notifyDccSpeed KEYWORD2
|
||||||
notifyDccFunc KEYWORD2
|
notifyDccSpeedRaw
|
||||||
notifyDccAccState KEYWORD2
|
notifyDccFunc KEYWORD2
|
||||||
notifyDccSigState KEYWORD2
|
notifyDccAccState KEYWORD2
|
||||||
notifyDccMsg KEYWORD2
|
notifyDccAccTurnoutBoard
|
||||||
notifyCVValid KEYWORD2
|
notifyDccAccTurnoutOutput
|
||||||
notifyCVRead KEYWORD2
|
notifyDccSigState KEYWORD2
|
||||||
notifyCVWrite KEYWORD2
|
notifyDccMsg KEYWORD2
|
||||||
notifyIsSetCVReady KEYWORD2
|
notifyCVValid KEYWORD2
|
||||||
notifyCVChange KEYWORD2
|
notifyCVRead KEYWORD2
|
||||||
notifyCVAck KEYWORD2
|
notifyCVWrite KEYWORD2
|
||||||
notifyCVResetFactoryDefault KEYWORD2
|
notifyIsSetCVReady KEYWORD2
|
||||||
|
notifyCVChange KEYWORD2
|
||||||
|
notifyCVAck KEYWORD2
|
||||||
|
notifyCVResetFactoryDefault KEYWORD2
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
# Constants (LITERAL1)
|
# Constants (LITERAL1)
|
||||||
|
|
||||||
MAN_ID_JMRI LITERAL1
|
MAN_ID_JMRI LITERAL1
|
||||||
MAN_ID_DIY LITERAL1
|
MAN_ID_DIY LITERAL1
|
||||||
MAN_ID_SILICON_RAILWAY LITERAL1
|
MAN_ID_SILICON_RAILWAY LITERAL1
|
||||||
FLAGS_MY_ADDRESS_ONLY LITERAL1
|
FLAGS_MY_ADDRESS_ONLY LITERAL1
|
||||||
FLAGS_OUTPUT_ADDRESS_MODE LITERAL1
|
FLAGS_OUTPUT_ADDRESS_MODE LITERAL1
|
||||||
FLAGS_DCC_ACCESSORY_DECODER LITERAL1
|
FLAGS_DCC_ACCESSORY_DECODER LITERAL1
|
||||||
|
|
||||||
CV_ACCESSORY_DECODER_ADDRESS_LSB LITERAL1
|
CV_ACCESSORY_DECODER_ADDRESS_LSB LITERAL1
|
||||||
CV_ACCESSORY_DECODER_ADDRESS_MSB LITERAL1
|
CV_ACCESSORY_DECODER_ADDRESS_MSB LITERAL1
|
||||||
|
|
||||||
CV_MULTIFUNCTION_PRIMARY_ADDRESS LITERAL1
|
CV_MULTIFUNCTION_PRIMARY_ADDRESS LITERAL1
|
||||||
CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB LITERAL1
|
CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB LITERAL1
|
||||||
CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB LITERAL1
|
CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB LITERAL1
|
||||||
|
|
||||||
CV_VERSION_ID LITERAL1
|
CV_VERSION_ID LITERAL1
|
||||||
CV_MANUFACTURER_ID LITERAL1
|
CV_MANUFACTURER_ID LITERAL1
|
||||||
CV_29_CONFIG LITERAL1
|
CV_29_CONFIG LITERAL1
|
||||||
CV_OPS_MODE_ADDRESS_LSB LITERAL1
|
CV_OPS_MODE_ADDRESS_LSB LITERAL1
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
name=NmraDcc
|
name=NmraDcc
|
||||||
version=1.1.0
|
version=1.2.0
|
||||||
author=Alex Shepherd, Wolfgang Kuffer, Geoff Bunza, Martin Pischky
|
author=Alex Shepherd, Wolfgang Kuffer, Geoff Bunza, Martin Pischky
|
||||||
maintainer=Alex Shepherd <kiwi64ajs@gmail.com>
|
maintainer=Alex Shepherd <kiwi64ajs@gmail.com>
|
||||||
sentence=Enables NMRA DCC Communication
|
sentence=Enables NMRA DCC Communication
|
||||||
|
Reference in New Issue
Block a user