5 Commits

Author SHA1 Message Date
Alex Shepherd
2e1f9098ad Changed Interrupt handling for RP2040 architectures to be similar to ESP32
Added check for proper USB Serial initialisation to examples
2022-07-23 20:26:32 +12:00
Alex Shepherd
37b66af743 Got Manual Operation and Home Sensor working 2022-07-02 23:49:44 +12:00
Alex Shepherd
4cf529e8c5 bump version to 2.0.11 2022-03-12 21:34:39 +13:00
Alex Shepherd
cea2913e8a Fix example DCCInterface_TurntableControl.ino sketch to work with library changes 2022-03-12 21:30:12 +13:00
Alex Shepherd
ae9afe9c24 added CV_MANUFACTURER_START 2022-02-27 18:35:58 +13:00
10 changed files with 497 additions and 27 deletions

View File

@@ -258,8 +258,11 @@
#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
#elif defined ( ARDUINO_AVR_NANO_EVERY ) || defined(ARDUINO_ARCH_RP2040)
static PinStatus ISREdge;
#elif defined ( ARDUINO_AVR_NANO_EVERY )
static PinStatus ISREdge; // Holder of the Next Edge we're looking for: RISING or FALLING
#elif defined ( ARDUINO_ARCH_RP2040)
static PinStatus ISREdge; // Holder of the Next Edge we're looking for: RISING or FALLING
static byte ISRWatch; // Interrupt Handler Edge Filter
#else
static byte ISREdge; // Holder of the Next Edge we're looking for: RISING or FALLING
static byte ISRWatch; // Interrupt Handler Edge Filter
@@ -339,7 +342,7 @@ DCC_PROCESSOR_STATE DccProcState ;
{
SET_TP3;
#ifdef ESP32
#if defined(ESP32) || defined ( ARDUINO_ARCH_RP2040)
// switch (ISRWatch)
// {
// case RISING: if (digitalRead(DccProcState.ExtIntPinNum)) break;
@@ -416,7 +419,7 @@ DCC_PROCESSOR_STATE DccProcState ;
#if defined ( __STM32F1__ )
detachInterrupt (DccProcState.ExtIntNum);
#endif
#ifdef ESP32
#if defined(ESP32) || defined ( ARDUINO_ARCH_RP2040)
ISRWatch = ISREdge;
#else
attachInterrupt (DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge);
@@ -507,7 +510,7 @@ DCC_PROCESSOR_STATE DccProcState ;
#if defined ( __STM32F1__ )
detachInterrupt (DccProcState.ExtIntNum);
#endif
#if defined(ESP32)
#if defined(ESP32) || defined ( ARDUINO_ARCH_RP2040)
ISRWatch = ISREdge;
#else
attachInterrupt (DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge);
@@ -564,7 +567,7 @@ DCC_PROCESSOR_STATE DccProcState ;
#if defined ( __STM32F1__ )
detachInterrupt (DccProcState.ExtIntNum);
#endif
#if defined(ESP32)
#if defined(ESP32) || defined ( ARDUINO_ARCH_RP2040)
ISRWatch = ISREdge;
#else
attachInterrupt (DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge);
@@ -613,7 +616,7 @@ DCC_PROCESSOR_STATE DccProcState ;
detachInterrupt (DccProcState.ExtIntNum);
#endif
#if defined(ESP32)
#if defined(ESP32) || defined ( ARDUINO_ARCH_RP2040)
ISRWatch = ISREdge;
#else
attachInterrupt (DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge);
@@ -743,7 +746,7 @@ DCC_PROCESSOR_STATE DccProcState ;
#if defined ( __STM32F1__ )
detachInterrupt (DccProcState.ExtIntNum);
#endif
#ifdef ESP32
#if defined(ESP32) || defined ( ARDUINO_ARCH_RP2040)
ISRWatch = CHANGE;
#else
attachInterrupt (DccProcState.ExtIntNum, ExternalInterruptHandler, CHANGE);
@@ -1614,7 +1617,7 @@ void NmraDcc::init (uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, ui
ISRLevel = DccProcState.ExtIntMask;
ISRChkMask = DccProcState.ExtIntMask;
#ifdef ESP32
#if defined(ESP32)|| defined ( ARDUINO_ARCH_RP2040)
ISRWatch = ISREdge;
attachInterrupt (DccProcState.ExtIntNum, ExternalInterruptHandler, CHANGE);
#else

View File

@@ -112,6 +112,7 @@ typedef struct
#define CV_VERSION_ID 7
#define CV_MANUFACTURER_ID 8
#define CV_29_CONFIG 29
#define CV_MANUFACTURER_START 33
#if defined(ESP32)
#include <esp_spi_flash.h>

View File

@@ -32,6 +32,9 @@
#define DISABLE_OUTPUTS_IDLE
#endif
// Uncomment the following line to enable Debug Print of DCC Messages
//#define NOTIFY_DCC_MSG
// By default the stepper motor will move the shortest distance to the desired position.
// If you need the turntable to only move in the Positive/Increasing or Negative/Decreasing step numbers to better handle backlash in the mechanism
// Then uncomment the appropriate line below
@@ -122,16 +125,11 @@ uint16_t lastAddr = 0xFFFF ;
uint8_t lastDirection = 0xFF;
int lastStep = 0;
// 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(F("notifyDccAccTurnoutOutput: "));
Serial.print(Addr,DEC) ;
Serial.print(',');
Serial.print(Direction,DEC) ;
Serial.print(',');
Serial.println(OutputPower, HEX) ;
void processTurnoutCommand(uint16_t Addr, uint8_t Direction, uint8_t OutputPower)
{
Serial.print(F("processTurnoutCommand: "));
for (int i = 0; i < MAX_TURNOUT_POSITIONS ; i++)
{
if ((Addr == turnoutPositions[i].dccAddress) && ((Addr != lastAddr) || (Direction != lastDirection)) && OutputPower)
@@ -189,6 +187,22 @@ void notifyDccAccTurnoutOutput( uint16_t Addr, uint8_t Direction, uint8_t Output
break;
}
}
}
// This function is called from the Library whenever a normal DCC Turnout Packet is received
void notifyDccAccTurnoutBoard (uint16_t BoardAddr, uint8_t OutputPair, uint8_t Direction, uint8_t OutputPower)
{
uint16_t Addr = ((BoardAddr - 1) * 4) + OutputPair + 1;
Serial.print(F("notifyDccAccTurnoutBoard: "));
Serial.print(Addr,DEC) ;
Serial.print(',');
Serial.print(Direction,DEC) ;
Serial.print(',');
Serial.println(OutputPower, HEX) ;
processTurnoutCommand(Addr, Direction, OutputPower);
};
#ifdef DISABLE_OUTPUTS_IDLE
@@ -256,14 +270,16 @@ void setupDCCDecoder()
#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 );
Dcc.init( MAN_ID_DIY, 10, CV29_ACCESSORY_DECODER, 0 );
}
void setup()
{
Serial.begin(115200);
while(!Serial); // Wait for the USB Device to Enumerate
uint8_t maxWaitLoops = 255;
while(!Serial && maxWaitLoops--) // Wait for the USB Device to Enumerate
delay(20);
Serial.println(F("\nExample Stepper Motor Driver for DCC Turntable Control"));
Serial.print(F("Full Rotation Steps: "));
@@ -296,7 +312,7 @@ void setup()
setupDCCDecoder();
// Fake a DCC Packet to cause the Turntable to move to Position 1
notifyDccAccTurnoutOutput(POSITION_01_DCC_ADDRESS, 1, 1);
processTurnoutCommand(POSITION_01_DCC_ADDRESS, 1, 1);
}
}
@@ -320,3 +336,16 @@ void loop()
}
#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,421 @@
#include <AccelStepper.h> // Requires AccelStepper Library - http://www.airspayce.com/mikem/arduino/AccelStepper/
#include <EncButton2.h> // Requires EncButton library - https://github.com/GyverLibs/EncButton
#include <elapsedMillis.h> // Requires elapsedMillis library - https://github.com/pfeerick/elapsedMillis
#define OPTIMIZE_I2C 1
#include <Wire.h>
#include <SSD1306Ascii.h>
#include <SSD1306AsciiWire.h>
#include <EEPROM.h>
#define NUM_LIFT_LEVELS 8
#define PROGRAM_NAME "Fahrstuhl"
#define PROGRAM_VERSION "1.0"
#define EEPROM_BASE_ADDR 100
#define EEPROM_VALID_DATA_SIGNATURE 0xA5A5
// Uncomment the line below to force the EEPROM values to be reset to defaults
//#define EEPROM_FORCE_RELOAD_DEFAULT_VALUES
#define BUTTON_LONG_PRESS_DELAY 2000
#if defined (ARDUINO_AVR_NANO) // Setting for Uwe's Fahrstuhl System
// Uncomment the next line to reverse the direction of the stepper movement
//#define REVERSE_STEPPER_DIRECTION
#define HOME_SENSOR_PIN 7
#define STEPPER_PULSE_PIN 4
#define STEPPER_ENABLE_PIN 5
#define STEPPER_DIR_PIN 6
#define STEPPER_MAX_SPEED 2100
#define STEPPER_NORMAL_ACCELERATION 5000
#define STEPPER_MAX_POSITION 30000U // Maximum Steps to allow the stepper to drive Up Saftey mechanism
#define BUTTON_MANUAL 8
#define BUTTON_DOWN 9
#define BUTTON_UP 10
#define BUTTON_STOP_HOME 11
long defaultPositions[NUM_LIFT_LEVELS] = {1000, 4000, 7000, 10000, 13000, 16000, 19000, 22000}; // Default positions
#define OLED_DISPLAY_I2C_ADDRESS 0x3C
#else
//#if defined(ARDUINO_AVR_UNO) // Setting for AJS Dev System
// Uncomment the next line to reverse the direction of the stepper movement
#define REVERSE_STEPPER_DIRECTION
#define HOME_SENSOR_PIN 10
#define STEPPER_PULSE_PIN 11
#define STEPPER_ENABLE_PIN 12
#define STEPPER_DIR_PIN 13
#define STEPPER_MAX_SPEED 2100
#define STEPPER_NORMAL_ACCELERATION 5000
#define STEPPER_MAX_POSITION 30000U // Maximum Steps to allow the stepper to drive Up Saftey mechanism
#define BUTTON_MANUAL A3
#define BUTTON_DOWN A2
#define BUTTON_UP A1
#define BUTTON_STOP_HOME A0
long defaultPositions[NUM_LIFT_LEVELS] = {1000, 4000, 7000, 10000, 13000, 16000, 19000, 22000}; // Default positions
#define OLED_DISPLAY_I2C_ADDRESS 0x3C
#endif
SSD1306AsciiWire oled;
#define STEPPER_INC_SPEED (STEPPER_MAX_SPEED / 10)
#define STEPPER_MAN_SPEED_CHANGE_MILLIS 5
#define STEPPER_EMERGENCY_STOP_ACCELERATION 100000
#define LIFT_LEVEL_NOT_SET -1
typedef struct
{
uint8_t numLiftLevels;
uint8_t lastLiftLevel;
long lastStepperPosition;
long levelPositions[NUM_LIFT_LEVELS];
uint16_t objectSignature;
} PERSISTENT_VALUES;
PERSISTENT_VALUES persistentValues;
// Define a stepper and the pins it will use
AccelStepper stepper(AccelStepper::DRIVER, STEPPER_PULSE_PIN, STEPPER_DIR_PIN, -1, -1, false);
EncButton2<EB_BTN> homeSensor(INPUT_PULLUP, HOME_SENSOR_PIN);
EncButton2<EB_BTN> btnManual(INPUT, BUTTON_MANUAL);
EncButton2<EB_BTN> btnDown(INPUT, BUTTON_DOWN);
EncButton2<EB_BTN> btnUp(INPUT, BUTTON_UP);
EncButton2<EB_BTN> btnStopHome(INPUT, BUTTON_STOP_HOME);
void displayLevel(int newLevel)
{
oled.setCursor(0,0);
oled.set2X();
oled.print("Level: ");
oled.print(newLevel);
oled.clearToEOL();
}
void displayMessage(const char* Msg)
{
oled.setCursor(0,4);
oled.set2X();
oled.print(Msg); oled.clearToEOL();
}
void displayMessageNumber(const char* Msg, int Number)
{
oled.setCursor(0,4);
oled.set2X();
oled.print(Msg);
oled.print(Number);
oled.clearToEOL();
}
void displayPosition(long newPosition)
{
oled.setCursor(0,7);
oled.set1X();
oled.print("Pos: ");
oled.print(newPosition);
oled.clearToEOL();
}
void initPersistentValues()
{
EEPROM.get(EEPROM_BASE_ADDR, persistentValues);
#ifdef EEPROM_FORCE_RELOAD_DEFAULT_VALUES
persistentValues.objectSignature = 0;
#endif
if(persistentValues.objectSignature != EEPROM_VALID_DATA_SIGNATURE)
{
Serial.println("initPersistentValues: set detault values");
persistentValues.numLiftLevels = NUM_LIFT_LEVELS;
persistentValues.lastLiftLevel = 0;
persistentValues.lastStepperPosition = 0;
persistentValues.objectSignature = EEPROM_VALID_DATA_SIGNATURE;
for(uint8_t i = 0; i < NUM_LIFT_LEVELS; i++)
persistentValues.levelPositions[i] = defaultPositions[i];
EEPROM.put(EEPROM_BASE_ADDR, persistentValues);
}
else
Serial.println("initPersistentValues: restored values from EEPROM");
}
void setup()
{
Serial.begin(115200);
uint8_t maxWaitLoops = 255;
while(!Serial && maxWaitLoops--)
delay(20);
Serial.println(); Serial.print(PROGRAM_NAME); Serial.print(" Version: "); Serial.println(PROGRAM_VERSION);
initPersistentValues();
Wire.begin();
Wire.setClock(400000L);
oled.setFont(cp437font8x8);
oled.begin(&Adafruit128x64, OLED_DISPLAY_I2C_ADDRESS);
oled.clear();
oled.println(PROGRAM_NAME);
oled.println();
oled.print("Ver: "); oled.println(PROGRAM_VERSION);
oled.println();
oled.print("Max Levels: "); oled.println(NUM_LIFT_LEVELS);
oled.println();
oled.print("Used Levels: "); oled.println(persistentValues.numLiftLevels);
delay(2000);
oled.clear();
displayLevel(persistentValues.lastLiftLevel + 1);
displayPosition(persistentValues.lastStepperPosition);
stepper.setCurrentPosition(persistentValues.lastStepperPosition);
stepper.setEnablePin(STEPPER_ENABLE_PIN);
#ifdef REVERSE_STEPPER_DIRECTION
stepper.setPinsInverted(true, false, true);
#else
stepper.setPinsInverted(false, false, true);
#endif
stepper.setMaxSpeed(STEPPER_MAX_SPEED);
btnStopHome.setHoldTimeout(BUTTON_LONG_PRESS_DELAY);
btnManual.setHoldTimeout(BUTTON_LONG_PRESS_DELAY);
}
void stepperMoveTo(long newPosition)
{
stepper.enableOutputs();
stepper.setAcceleration(STEPPER_NORMAL_ACCELERATION);
stepper.moveTo(newPosition);
}
void stepperMove(long newRelPosition)
{
stepper.enableOutputs();
stepper.setAcceleration(STEPPER_NORMAL_ACCELERATION);
stepper.move(newRelPosition);
}
void stopStepper(void)
{
stepper.setAcceleration(STEPPER_EMERGENCY_STOP_ACCELERATION);
stepper.move(0);
stepper.stop();
while(stepper.run());
stepper.disableOutputs();
}
int lastSpeed = 0;
int newSpeed = 0;
bool wasRunning = false;
bool configMode = false;
bool homing = false;
elapsedMillis lastSpeedChange = 0;
void loop()
{
//First check the Home Sensor and stop the motor if going in the down direction
homeSensor.tick();
if(homeSensor.state())
{
if((configMode || homing) && stepper.isRunning() && (lastSpeed <= 0))
{
stopStepper();
Serial.print("Home Sensor Hit - LastSpeed: ");
Serial.print(lastSpeed);
Serial.print(" Last Position: ");
Serial.println(stepper.currentPosition());
newSpeed = 0;
lastSpeed = newSpeed;
persistentValues.lastLiftLevel = 0;
persistentValues.lastStepperPosition = 0;
stepper.setCurrentPosition(persistentValues.lastStepperPosition);
EEPROM.put(EEPROM_BASE_ADDR, persistentValues);
if(homing)
{
long newPos = persistentValues.levelPositions[persistentValues.lastLiftLevel];
stepperMoveTo(newPos);
Serial.print("Home Sensor Hit: Move To: "); Serial.print(persistentValues.lastLiftLevel); Serial.print(" Pos: "); Serial.println(newPos);
homing = false;
}
}
}
// Make sure we haven't gone beyond the end point of the traverser.
if(stepper.currentPosition() >= STEPPER_MAX_POSITION)
{
if(configMode && stepper.isRunning() && (lastSpeed >= 0))
{
stopStepper();
Serial.print("Maximum Position Hit - LastSpeed: ");
Serial.print(lastSpeed);
Serial.print(" Last Position: ");
Serial.println(stepper.currentPosition());
newSpeed = 0;
lastSpeed = newSpeed;
displayMessage("At Max");
}
}
btnStopHome.tick();
if(btnStopHome.press())
{
Serial.print("StopHome Click - Current Pos: "); Serial.println(stepper.currentPosition());
displayMessage("Stop");
if(stepper.isRunning())
{
newSpeed = 0;
stopStepper();
}
}
if(btnStopHome.held())
{
Serial.println("StopHome Held: Moving to Home Position");
displayMessage("Homing");
homing = true;
newSpeed = -STEPPER_MAX_SPEED;
}
btnManual.tick();
if(btnManual.press())
{
Serial.print("Manual Press - Current Pos: "); Serial.println(stepper.currentPosition());
if(configMode)
{
configMode = false;
Serial.println("Home Click - Exit Manual Mode");
}
}
if(btnManual.held())
{
Serial.print("Manual Held - Enter Manual Mode Pos: "); Serial.println(stepper.currentPosition());
configMode = true;
}
btnDown.tick();
if(configMode)
{
if((btnDown.press() || btnDown.step()) && (stepper.currentPosition() < STEPPER_MAX_POSITION) && (lastSpeed <= (STEPPER_MAX_SPEED - STEPPER_INC_SPEED)))
{
newSpeed = lastSpeed + STEPPER_INC_SPEED;
lastSpeedChange = STEPPER_MAN_SPEED_CHANGE_MILLIS;
Serial.print("Down Press - Current Pos: "); Serial.print(stepper.currentPosition()); Serial.print(" New Speed: "); Serial.println(newSpeed);
displayMessage("Down");
}
}
else if((btnDown.press() || btnDown.step()) && persistentValues.lastLiftLevel > 0)
{
Serial.print("Down Press - Current Level: "); Serial.print(persistentValues.lastLiftLevel);
persistentValues.lastLiftLevel--;
long newPos = persistentValues.levelPositions[persistentValues.lastLiftLevel];
stepperMoveTo(newPos);
Serial.print(" Move To: "); Serial.print(persistentValues.lastLiftLevel); Serial.print(" Pos: "); Serial.println(newPos);
displayMessageNumber("Dn To: ", persistentValues.lastLiftLevel + 1);
}
btnUp.tick();
if(configMode)
{
if((btnUp.press() || btnDown.step()) && (homeSensor.state() == 0) && (lastSpeed >= -(STEPPER_MAX_SPEED - STEPPER_INC_SPEED)))
{
newSpeed = lastSpeed - STEPPER_INC_SPEED;
lastSpeedChange = STEPPER_MAN_SPEED_CHANGE_MILLIS;
Serial.print("Up Press - Current Pos: "); Serial.print(stepper.currentPosition()); Serial.print(" New Speed: "); Serial.println(newSpeed);
displayMessage("Up");
}
}
else if((btnUp.press() || btnDown.step()) && (persistentValues.lastLiftLevel < (persistentValues.numLiftLevels - 1)))
{
Serial.print("Up Press - Current Level: "); Serial.print(persistentValues.lastLiftLevel);
persistentValues.lastLiftLevel++;
long newPos = persistentValues.levelPositions[persistentValues.lastLiftLevel];
stepperMoveTo(newPos);
Serial.print(" Move To: "); Serial.print(persistentValues.lastLiftLevel); Serial.print(" Pos: "); Serial.println(newPos);
displayMessageNumber("Up To: ", persistentValues.lastLiftLevel + 1);
}
if(lastSpeed != newSpeed)
{
// Serial.print("Speed Change: Last: "); Serial.print(lastSpeed); Serial.print(" New: "); Serial.print(newSpeed);
// Serial.print(" - Current Pos: "); Serial.print(stepper.currentPosition());
if( newSpeed == 0)
{
lastSpeed = newSpeed;
stopStepper();
Serial.print("Speed Change: Stopped Last: "); Serial.print(lastSpeed); Serial.print(" New: "); Serial.println(newSpeed);
}
else if(lastSpeedChange >= STEPPER_MAN_SPEED_CHANGE_MILLIS)
{
lastSpeedChange = 0;
if(newSpeed > lastSpeed)
lastSpeed++;
else
lastSpeed--;
stepper.setSpeed(lastSpeed);
stepper.enableOutputs();
// Serial.print(" Set New Speed: "); Serial.println(newSpeed);
}
}
if(lastSpeed)
stepper.runSpeed();
else
stepper.run();
if(!stepper.isRunning() && wasRunning)
{
Serial.println("Disable Outputs");
stepper.disableOutputs();
displayLevel(persistentValues.lastLiftLevel + 1);
displayMessage("");
persistentValues.lastStepperPosition = stepper.currentPosition();
displayPosition(persistentValues.lastStepperPosition);
EEPROM.put(EEPROM_BASE_ADDR, persistentValues);
}
wasRunning = stepper.isRunning();
}

View File

@@ -95,7 +95,10 @@ void notifyDccSigOutputState( uint16_t Addr, uint8_t State)
void setup()
{
Serial.begin(115200);
uint8_t maxWaitLoops = 255;
while(!Serial && maxWaitLoops--)
delay(20);
// Configure the DCC CV Programing ACK pin for an output
pinMode( DccAckPin, OUTPUT );

View File

@@ -120,7 +120,10 @@ void initPinPulser(void)
void setup()
{
Serial.begin(115200);
uint8_t maxWaitLoops = 255;
while(!Serial && maxWaitLoops--)
delay(20);
// 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.

View File

@@ -164,6 +164,10 @@ void notifyCVAck(void)
void setup()
{
Serial.begin(115200);
uint8_t maxWaitLoops = 255;
while(!Serial && maxWaitLoops--)
delay(20);
Serial.println("NMRA Dcc Multifunction Decoder Demo 1");
// Configure the DCC CV Programing ACK pin for an output
@@ -199,4 +203,3 @@ void loop()
Dcc.setCV( FactoryDefaultCVs[FactoryDefaultCVIndex].CV, FactoryDefaultCVs[FactoryDefaultCVIndex].Value);
}
}

View File

@@ -207,6 +207,10 @@ void setup()
{
#ifdef DEBUG_PRINT
Serial.begin(115200);
uint8_t maxWaitLoops = 255;
while(!Serial && maxWaitLoops--)
delay(20);
Serial.println("NMRA Dcc Multifunction Motor Decoder Demo");
#endif

View File

@@ -101,6 +101,9 @@ void notifyCVChange(uint16_t CV, uint8_t Value)
void setup()
{
Serial.begin(115200);
uint8_t maxWaitLoops = 255;
while(!Serial && maxWaitLoops--)
delay(20);
Serial.println("NMRA DCC Iowa Scaled Engineering ARD-DCCSHIELD Example");
@@ -108,7 +111,7 @@ void setup()
// 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);
Dcc.pin(DCC_PIN, 1);
#else
Dcc.pin(0, DCC_PIN, 1);
#endif

View File

@@ -1,5 +1,5 @@
name=NmraDcc
version=2.0.10
version=2.0.12
author=Alex Shepherd, Wolfgang Kuffer, Geoff Bunza, Martin Pischky, Franz-Peter Müller, Sven (littleyoda), Hans Tanner, bugfixes by Jueff
maintainer=Alex Shepherd <kiwi64ajs@gmail.com>
sentence=Enables NMRA DCC Communication