4 Commits

Author SHA1 Message Date
Geoff Bunza
80cffbd19e Add files via upload 2020-11-16 20:51:02 -08:00
Geoff Bunza
a1cb1d55ee Add files via upload 2020-11-16 20:22:53 -08:00
Geoff Bunza
b5d18356c5 Delete IDEC 2020-11-16 20:13:22 -08:00
Geoff Bunza
f2c42ec6d6 Create IDEC 2020-11-16 20:12:44 -08:00
18 changed files with 2507 additions and 3568 deletions

View File

@@ -1,55 +0,0 @@
# http://astyle.sourceforge.net/astyle.html#_style=allman
# use the allman style for braces
--style=allman
# http://astyle.sourceforge.net/astyle.html#_lineend
# newlines for all line endings
--lineend=linux
# http://astyle.sourceforge.net/astyle.html#_indent=spaces
# 4 space indents
--indent=spaces=4
# http://astyle.sourceforge.net/astyle.html#_add-braces
# don't leave any unbraced one-line blocks by changing:
# if (thing)
# statement;
#
# to
# if (thing)
# {
# statement;
# }
#
# --add-braces
# http://astyle.sourceforge.net/astyle.html#_indent-preproc-cond
# line up #if/#endif with the code
#
# statement;
# #if SOMETHING
# statement;
# #endif
#
--indent-preproc-cond
# http://astyle.sourceforge.net/astyle.html#_indent-preproc-block
# indent top level preprocessor block contents
#
# #ifdef __ARDUINO__
# #include "Arduino.h"
# #endif
#
--indent-preproc-block
# normalize spacing around parenthese
# http://astyle.sourceforge.net/astyle.html#_unpad-paren
# first, remove all whitespace on either side of a paren
--unpad-paren
# http://astyle.sourceforge.net/astyle.html#_pad-paren-out
# then add a space on the "outer" side of a paren
--pad-paren-out
# http://astyle.sourceforge.net/astyle.html#_max-code-length
# we've got big monitors these days....
--max-code-length=180

2
.gitignore vendored
View File

@@ -1,4 +1,2 @@
.development
*.zip
*.orig
*~

File diff suppressed because it is too large Load Diff

1507
NmraDcc.h

File diff suppressed because it is too large Load Diff

View File

@@ -10,14 +10,3 @@ The library currently supports the AVR ATTiny84/85 & ATMega88/168/328/32u4 and T
extern void notifyDccAccState( uint16_t Addr, uint16_t BoardAddr, uint8_t OutputAddr, uint8_t State )
extern void notifyDccSigState( uint16_t Addr, uint8_t OutputIndex, uint8_t State)
Developers:
Use of the supplied git pre-commit hook is encouraged. This will require installation of the 'astyle' package for formatting source file.
See http://astyle.sourceforge.net for details on this package.
On Linux or Mac development machines, run the following command after you clone the repository:
ln -s support/pre-commit .git/hooks/pre-commit
Reformatting the source code to the preferred style is easy using astyle. Just run 'astyle --options=.astylerc NmraDcc.h NmraDcc.cpp'

View File

@@ -19,9 +19,6 @@
#include <AccelStepper.h>
#include <NmraDcc.h>
// Define the Arduino input Pin number for the DCC Signal
#define DCC_PIN 2
// The lines below define the pins used to connect to the A4988 driver module
#define A4988_STEP_PIN 4
#define A4988_DIRECTION_PIN 5
@@ -32,9 +29,6 @@
#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
@@ -125,11 +119,16 @@ uint16_t lastAddr = 0xFFFF ;
uint8_t lastDirection = 0xFF;
int lastStep = 0;
void processTurnoutCommand(uint16_t Addr, uint8_t Direction, uint8_t OutputPower)
// 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("processTurnoutCommand: "));
Serial.print(F("notifyDccAccTurnoutOutput: "));
Serial.print(Addr,DEC) ;
Serial.print(',');
Serial.print(Direction,DEC) ;
Serial.print(',');
Serial.println(OutputPower, HEX) ;
for (int i = 0; i < MAX_TURNOUT_POSITIONS ; i++)
{
if ((Addr == turnoutPositions[i].dccAddress) && ((Addr != lastAddr) || (Direction != lastDirection)) && OutputPower)
@@ -187,22 +186,6 @@ void processTurnoutCommand(uint16_t Addr, uint8_t Direction, uint8_t OutputPower
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
@@ -260,26 +243,18 @@ void setupDCCDecoder()
{
Serial.println(F("Setting up DCC Decorder..."));
// 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
// 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, 10, CV29_ACCESSORY_DECODER, 0 );
Dcc.init( MAN_ID_DIY, 10, CV29_ACCESSORY_DECODER | CV29_OUTPUT_ADDRESS_MODE, 0 );
}
void setup()
{
Serial.begin(115200);
uint8_t maxWaitLoops = 255;
while(!Serial && maxWaitLoops--) // Wait for the USB Device to Enumerate
delay(20);
while(!Serial); // Wait for the USB Device to Enumerate
Serial.println(F("\nExample Stepper Motor Driver for DCC Turntable Control"));
Serial.print(F("Full Rotation Steps: "));
@@ -312,7 +287,7 @@ void setup()
setupDCCDecoder();
// Fake a DCC Packet to cause the Turntable to move to Position 1
processTurnoutCommand(POSITION_01_DCC_ADDRESS, 1, 1);
notifyDccAccTurnoutOutput(POSITION_01_DCC_ADDRESS, 1, 1);
}
}
@@ -336,16 +311,3 @@ 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

@@ -1,487 +0,0 @@
#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>
#include <NmraDcc.h>
// You can print every DCC packet by un-commenting the line below
//#define NOTIFY_DCC_MSG
// Define the Arduino Pin to connect to the DCC input signal
#define DCC_PIN 2
// Define the DCC Turnout Address to select the first level = 1
#define DCC_ACCESSORY_DECODER_BASE_ADDRESS 200
// Define the manimus numbr of Levels
#define NUM_LIFT_LEVELS 8
#define PROGRAM_NAME "Fahrstuhl"
#define PROGRAM_VERSION "1.1"
// Locate the Persistant State storage EEPROM space well above the DCC Accessory Decoder CV Storage
#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
// Uncomment ONE of the next 2 lines to enable AJS or UWE Board Settings
//#define AJS_BOARD_SETTINGS
#define UWE_BOARD_SETTINGS
#if defined(AJS_BOARD_SETTINGS) // 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 300000U // 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 STEPPER_INC_SPEED (STEPPER_MAX_SPEED / 10)
#define OLED_DISPLAY_I2C_ADDRESS 0x3C
#elif defined (UWE_BOARD_SETTINGS) // 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 1970000U // 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] = {0, 161064, 32500, 483284, 645326, 808041, 1967457, 1130774}; // Default positions
#define STEPPER_INC_SPEED (STEPPER_MAX_SPEED / 2)
#define OLED_DISPLAY_I2C_ADDRESS 0x3C
#else
#error No Board Settings Defined
#endif
SSD1306AsciiWire oled;
#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);
// NMRA DCC Accessory Decoder object
NmraDcc Dcc;
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);
// Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up
Dcc.pin(DCC_PIN, 1);
// 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);
}
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;
// This function is called whenever a normal DCC Turnout Packet is received
// The DCC Turnout Address is checked to see if it is within the range used to Select Elevator levels and starts a Move if a new level is selected
void notifyDccAccTurnoutOutput(uint16_t receivedAddress, uint8_t direction, uint8_t outputPower)
{
if((receivedAddress >= DCC_ACCESSORY_DECODER_BASE_ADDRESS) && (receivedAddress < (DCC_ACCESSORY_DECODER_BASE_ADDRESS + NUM_LIFT_LEVELS)))
{
uint8_t newLevel = receivedAddress - DCC_ACCESSORY_DECODER_BASE_ADDRESS;
if(persistentValues.lastLiftLevel != newLevel)
{
persistentValues.lastLiftLevel = newLevel;
long newPos = persistentValues.levelPositions[persistentValues.lastLiftLevel];
stepperMoveTo(newPos);
Serial.print("notifyDccAccTurnoutOutput: Move to Level: "); Serial.print(persistentValues.lastLiftLevel); Serial.print(" Pos: "); Serial.println(newPos);
displayMessageNumber("Mv To: ", persistentValues.lastLiftLevel + 1);
}
}
}
void loop()
{
Dcc.process();
//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();
}
#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

@@ -7,9 +7,6 @@
NmraDcc Dcc ;
DCC_MSG Packet ;
// Define the Arduino input Pin number for the DCC Signal
#define DCC_PIN 2
struct CVPair
{
uint16_t CV;
@@ -18,8 +15,8 @@ struct CVPair
CVPair FactoryDefaultCVs [] =
{
{CV_ACCESSORY_DECODER_ADDRESS_LSB, DEFAULT_ACCESSORY_DECODER_ADDRESS & 0xFF},
{CV_ACCESSORY_DECODER_ADDRESS_MSB, DEFAULT_ACCESSORY_DECODER_ADDRESS >> 8},
{CV_ACCESSORY_DECODER_ADDRESS_LSB, 1},
{CV_ACCESSORY_DECODER_ADDRESS_MSB, 0},
};
uint8_t FactoryDefaultCVIndex = 0;
@@ -95,23 +92,14 @@ 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 );
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
// 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, 10, CV29_ACCESSORY_DECODER | CV29_OUTPUT_ADDRESS_MODE, 0 );

View File

@@ -9,7 +9,7 @@
#define NOTIFY_TURNOUT_MSG
// You can also print other Debug Messages uncommenting the line below
//#define DEBUG_MSG
#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
@@ -18,9 +18,6 @@
// 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 the Arduino input Pin number for the DCC Signal
#define DCC_PIN 2
#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
@@ -43,8 +40,8 @@ struct CVPair
CVPair FactoryDefaultCVs [] =
{
{CV_ACCESSORY_DECODER_ADDRESS_LSB, DEFAULT_ACCESSORY_DECODER_ADDRESS & 0xFF},
{CV_ACCESSORY_DECODER_ADDRESS_MSB, DEFAULT_ACCESSORY_DECODER_ADDRESS >> 8},
{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},
@@ -120,21 +117,12 @@ 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.
#ifdef digitalPinToInterrupt
Dcc.pin(DCC_PIN, 0);
#else
Dcc.pin(0, DCC_PIN, 1);
#endif
// 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, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, 0 );
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);

View File

@@ -1,7 +1,6 @@
#include <NmraDcc.h>
// Define the Arduino input Pin number for the DCC Signal
#define DCC_PIN 2
#define This_Decoder_Address 3
struct CVPair
{
@@ -12,11 +11,11 @@ struct CVPair
CVPair FactoryDefaultCVs [] =
{
// The CV Below defines the Short DCC Address
{CV_MULTIFUNCTION_PRIMARY_ADDRESS, DEFAULT_MULTIFUNCTION_DECODER_ADDRESS},
{CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address},
// These two CVs define the Long DCC Address
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, CALC_MULTIFUNCTION_EXTENDED_ADDRESS_MSB(DEFAULT_MULTIFUNCTION_DECODER_ADDRESS)},
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, CALC_MULTIFUNCTION_EXTENDED_ADDRESS_LSB(DEFAULT_MULTIFUNCTION_DECODER_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
@@ -164,24 +163,14 @@ 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
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
// 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
// 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 );
@@ -203,3 +192,4 @@ void loop()
Dcc.setCV( FactoryDefaultCVs[FactoryDefaultCVIndex].CV, FactoryDefaultCVs[FactoryDefaultCVIndex].Value);
}
}

View File

@@ -1,311 +0,0 @@
// NMRA Dcc Multifunction Motor Decoder Demo using the Seeed XIAO Expansion board
// See: https://wiki.seeedstudio.com/Seeeduino-XIAO-Expansion-Board/
//
// Author: Alex Shepherd 2023-02-15
//
// 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 simple demo displays the Multifunction Decoder actions on the builtin OLED Display
//
#include <NmraDcc.h>
#include <U8x8lib.h>
#include <Wire.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_DCC_MSG
#if defined(DEBUG_FUNCTIONS) or defined(DEBUG_SPEED) or defined(DEBUG_PWM) or defined(DEBUG_DCC_MSG)
#define DEBUG_PRINT
#endif
// This is the default DCC Address
#define DEFAULT_DECODER_ADDRESS 3
#ifndef ARDUINO_SEEED_XIAO_M0
#error "Unsupported CPU, you need to add another configuration section for your CPU"
#endif
// I used a IoTT DCC Interface connected to Grove Analog Input which has A0 or 0 Pin
#define DCC_PIN 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 lastFuncStateList[FN_LAST+1];
// Structure for CV Values Table
struct CVPair
{
uint16_t CV;
uint8_t Value;
};
// Default CV Values Table
CVPair FactoryDefaultCVs [] =
{
// The CV Below defines the Short DCC Address
{CV_MULTIFUNCTION_PRIMARY_ADDRESS, DEFAULT_DECODER_ADDRESS},
// These two CVs define the Long DCC Address
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, CALC_MULTIFUNCTION_EXTENDED_ADDRESS_MSB(DEFAULT_DECODER_ADDRESS)},
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, CALC_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 ;
U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(PIN_WIRE_SCL, PIN_WIRE_SDA, U8X8_PIN_NONE); // OLEDs without Reset of the Display
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);
};
// 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);
Serial.println();
#endif
if(lastFuncStateList[FuncGrp] != FuncState)
{
lastFuncStateList[FuncGrp] = FuncState;
switch(FuncGrp)
{
#ifdef NMRA_DCC_ENABLE_14_SPEED_STEP_MODE
case FN_0:
Serial.print(" FN0: ");
Serial.println((FuncState & FN_BIT_00) ? "1 " : "0 ");
u8x8.setCursor(0, 2);
u8x8.print("FN0 : ");
u8x8.println((FuncState & FN_BIT_00) ? "1" : "0");
break;
#endif
case FN_0_4:
u8x8.setCursor(0, 2);
u8x8.print("FN0 : ");
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 ");
u8x8.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 ");
u8x8.print((FuncState & FN_BIT_01) ? "1": "0");
u8x8.print((FuncState & FN_BIT_02) ? "1": "0");
u8x8.print((FuncState & FN_BIT_03) ? "1": "0");
u8x8.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 ");
u8x8.setCursor(0, 3);
u8x8.print("FN5 : ");
u8x8.print((FuncState & FN_BIT_05) ? "1": "0");
u8x8.print((FuncState & FN_BIT_06) ? "1": "0");
u8x8.print((FuncState & FN_BIT_07) ? "1": "0");
u8x8.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 ");
u8x8.setCursor(0, 4);
u8x8.print("FN9 : ");
u8x8.print((FuncState & FN_BIT_09) ? "1": "0");
u8x8.print((FuncState & FN_BIT_10) ? "1": "0");
u8x8.print((FuncState & FN_BIT_11) ? "1": "0");
u8x8.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 ");
u8x8.setCursor(0, 5);
u8x8.print("FN13: ");
u8x8.print((FuncState & FN_BIT_13) ? "1": "0");
u8x8.print((FuncState & FN_BIT_14) ? "1": "0");
u8x8.print((FuncState & FN_BIT_15) ? "1": "0");
u8x8.print((FuncState & FN_BIT_16) ? "1": "0");
u8x8.print((FuncState & FN_BIT_17) ? "1": "0");
u8x8.print((FuncState & FN_BIT_18) ? "1": "0");
u8x8.print((FuncState & FN_BIT_19) ? "1": "0");
u8x8.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 ");
u8x8.setCursor(0, 6);
u8x8.print("FN21: ");
u8x8.print((FuncState & FN_BIT_21) ? "1": "0");
u8x8.print((FuncState & FN_BIT_22) ? "1": "0");
u8x8.print((FuncState & FN_BIT_23) ? "1": "0");
u8x8.print((FuncState & FN_BIT_24) ? "1": "0");
u8x8.print((FuncState & FN_BIT_25) ? "1": "0");
u8x8.print((FuncState & FN_BIT_26) ? "1": "0");
u8x8.print((FuncState & FN_BIT_27) ? "1": "0");
u8x8.println((FuncState & FN_BIT_28) ? "1": "0");
break;
}
}
}
// 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
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
u8x8.begin();
u8x8.setFlipMode(1);
u8x8.setFont(u8x8_font_chroma48medium8_r);
u8x8.setCursor(0, 0);
u8x8.println("NMRA DCC");
u8x8.println("MultiFunction");
u8x8.println("Decoder Demo");
delay(2000);
u8x8.clearDisplay();
u8x8.setCursor(0, 0);
u8x8.println("Speed:");
// 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
Dcc.init( MAN_ID_DIY, 10, FLAGS_MY_ADDRESS_ONLY | FLAGS_AUTO_FACTORY_DEFAULT, 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();
// Handle Speed changes
if((lastSpeed != newSpeed) || (lastDirection != newDirection))
{
lastSpeed = newSpeed;
lastDirection = newDirection;
u8x8.setCursor(0, 0);
u8x8.print("Speed: ");
u8x8.print(newSpeed);
u8x8.print(":");
u8x8.println( newDirection ? "Fwd" : "Rev");
}
// Handle resetting CVs back to Factory Defaults
if( FactoryDefaultCVIndex )
{
FactoryDefaultCVIndex--; // Decrement first as initially it is the size of the array
Dcc.setCV( FactoryDefaultCVs[FactoryDefaultCVIndex].CV, FactoryDefaultCVs[FactoryDefaultCVIndex].Value);
}
}

View File

@@ -32,7 +32,6 @@
// This section defines the Arduino UNO Pins to use
#ifdef __AVR_ATmega328P__
// Define the Arduino input Pin number for the DCC Signal
#define DCC_PIN 2
#define LED_PIN_FWD 5
@@ -43,7 +42,6 @@
// This section defines the Arduino ATTiny85 Pins to use
#elif ARDUINO_AVR_ATTINYX5
// Define the Arduino input Pin number for the DCC Signal
#define DCC_PIN 2
#define LED_PIN_FWD 0
@@ -91,8 +89,8 @@ CVPair FactoryDefaultCVs [] =
{CV_VHIGH, 255},
// These two CVs define the Long DCC Address
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, CALC_MULTIFUNCTION_EXTENDED_ADDRESS_MSB(DEFAULT_DECODER_ADDRESS)},
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, CALC_MULTIFUNCTION_EXTENDED_ADDRESS_LSB(DEFAULT_DECODER_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
@@ -207,10 +205,6 @@ 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
@@ -223,14 +217,8 @@ void setup()
pinMode(MOTOR_PWM_PIN, OUTPUT);
// 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
// Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up
Dcc.pin(DCC_PIN, 0);
#else
Dcc.pin(0, DCC_PIN, 1);
#endif
Dcc.init( MAN_ID_DIY, 10, FLAGS_MY_ADDRESS_ONLY | FLAGS_AUTO_FACTORY_DEFAULT, 0 );
@@ -304,8 +292,8 @@ void loop()
#ifdef DEBUG_FUNCTIONS
Serial.println("LED On");
#endif
digitalWrite(LED_PIN_FWD, newDirection ? HIGH : LOW);
digitalWrite(LED_PIN_REV, newDirection ? LOW : HIGH);
digitalWrite(LED_PIN_FWD, newDirection ? LOW : HIGH);
digitalWrite(LED_PIN_REV, newDirection ? HIGH : LOW);
}
else
{

View File

@@ -26,9 +26,6 @@
// 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 the Arduino input Pin number for the DCC Signal
#define DCC_PIN 2
NmraDcc Dcc ;
struct CVPair
@@ -39,8 +36,8 @@ struct CVPair
CVPair FactoryDefaultCVs [] =
{
{CV_ACCESSORY_DECODER_ADDRESS_LSB, DEFAULT_ACCESSORY_DECODER_ADDRESS & 0xFF},
{CV_ACCESSORY_DECODER_ADDRESS_MSB, DEFAULT_ACCESSORY_DECODER_ADDRESS >> 8},
{CV_ACCESSORY_DECODER_ADDRESS_LSB, 1},
{CV_ACCESSORY_DECODER_ADDRESS_MSB, 0},
};
uint8_t FactoryDefaultCVIndex = 0;
@@ -101,20 +98,11 @@ 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");
// 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, 1);
#else
Dcc.pin(0, DCC_PIN, 1);
#endif
// 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, 10, CV29_ACCESSORY_DECODER, 0 );

View File

@@ -106,9 +106,9 @@ CVPair FactoryDefaultCVs [] =
{CV_MANUF, MANUF_ID }, // Manufacturer ID.
// These two CVs define the Long DCC Address
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, CALC_MULTIFUNCTION_EXTENDED_ADDRESS_MSB(DECODER_ADDR)},
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, CALC_MULTIFUNCTION_EXTENDED_ADDRESS_LSB(DECODER_ADDR)},
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0}, // Extended address MSB.
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, DECODER_ADDR}, // Extended address LSB.
{CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps
{CV_MANUF_01, VER_MINOR}, // Minor decoder version.
};

View File

@@ -1,9 +1,9 @@
name=NmraDcc
version=2.0.15
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
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=*
name=NmraDcc
version=2.0.6
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 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=*

View File

@@ -1,20 +0,0 @@
#!/bin/sh
FORMAT_SOURCES="NmraDcc.h NmraDcc.cpp"
error=0
for file in ${FORMAT_SOURCES}
do
output=$(mktemp -t stylecheckXXXXXXX)
astyle --options=.astylerc < $file > $output
if ! cmp -s $file $output
then
echo "Formatting on $file doesn't match expectations"
diff -u $file $output
error=1
fi
[ -f $output ] && rm $output
done
exit $error