6 Commits

Author SHA1 Message Date
Alex Shepherd
5b681f49de oops missed the use of #ifdef ARDUINO_SAMD_ZERO 2023-02-08 00:12:21 +13:00
Alex Shepherd
02be948ed2 added support for the SAMD_21 chip with no EEPROM using the FlashStorage_SAMD emulated EEPROM library
added disable interrupts on the ESP8266 and ESP32 to avoid a crash during FLASH Write of emulated EEPROM
bumped version to 2.0.14
2023-02-07 23:58:45 +13:00
Alex Shepherd
24d6689b24 added DCC Message Debug code to Fahrstuhl example to assist with debugging initial setup
bumped to version 2.0.13
2022-07-30 15:39:39 +12:00
Alex Shepherd
f1f214af3a Added FLAGS_OUTPUT_ADDRESS_MODE to Dcc.init() to make it work again after the DCC Addressing changes 2022-07-30 14:54:12 +12:00
Alex Shepherd
e1080f28fd change default board settings to Uwe 2022-07-24 22:54:46 +12:00
Alex Shepherd
54c56b7cda Added DCC Decoder logic to move levels 2022-07-24 22:52:45 +12:00
5 changed files with 135 additions and 55 deletions

View File

@@ -47,7 +47,11 @@
//------------------------------------------------------------------------
#include "NmraDcc.h"
#ifdef ARDUINO_SAMD_ZERO
#include <FlashStorage_SAMD.h>
#else
#include "EEPROM.h"
#endif
// Uncomment to print DEBUG messages
// #define DEBUG_PRINT
@@ -804,9 +808,18 @@ uint8_t readEEPROM (unsigned int CV)
void writeEEPROM (unsigned int CV, uint8_t Value)
{
EEPROM.write (CV, Value) ;
#if defined(ESP8266) || defined(ESP32)
noInterrupts();
#endif
#if defined(ESP8266) || defined(ESP32) || defined(ARDUINO_ARCH_RP2040)
EEPROM.commit();
#endif
#if defined(ESP8266) || defined(ESP32)
interrupts();
#endif
}
bool readyEEPROM()

View File

@@ -128,7 +128,8 @@ typedef struct
#define PRIO_SYSTIC 8 // MUST be higher priority than DCC Irq
#elif defined(ARDUINO_ARCH_RP2040)
#define MAXCV 256 // todo: maybe somebody knows a good define for it
#elif defined(ARDUINO_SAMD_ZERO)
#define MAXCV EEPROM_EMULATION_SIZE
#else
#define MAXCV E2END // the upper limit of the CV value currently defined to max memory.
#endif

View File

@@ -8,12 +8,24 @@
#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.0"
#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
@@ -21,34 +33,13 @@
#define BUTTON_LONG_PRESS_DELAY 2000
#if defined (ARDUINO_AVR_NANO) // Setting for Uwe's Fahrstuhl System
// Uncomment ONE of the next 2 lines to enable AJS or UWE Board Settings
//#define AJS_BOARD_SETTINGS
#define UWE_BOARD_SETTINGS
// Uncomment the next line to reverse the direction of the stepper movement
//#define REVERSE_STEPPER_DIRECTION
#define HOME_SENSOR_PIN 7
#if defined(AJS_BOARD_SETTINGS) // Setting for AJS Dev System
#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
// Uncomment the next line to reverse the direction of the stepper movement
#define REVERSE_STEPPER_DIRECTION
#define HOME_SENSOR_PIN 10
@@ -59,7 +50,7 @@ long defaultPositions[NUM_LIFT_LEVELS] = {1000, 4000, 7000, 10000, 13000, 16000,
#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 STEPPER_MAX_POSITION 300000U // Maximum Steps to allow the stepper to drive Up Saftey mechanism
#define BUTTON_MANUAL A3
#define BUTTON_DOWN A2
@@ -68,13 +59,42 @@ long defaultPositions[NUM_LIFT_LEVELS] = {1000, 4000, 7000, 10000, 13000, 16000,
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_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
@@ -100,6 +120,9 @@ 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);
@@ -137,15 +160,15 @@ void displayPosition(long newPosition)
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;
@@ -192,38 +215,44 @@ void setup()
stepper.setCurrentPosition(persistentValues.lastStepperPosition);
stepper.setEnablePin(STEPPER_ENABLE_PIN);
#ifdef REVERSE_STEPPER_DIRECTION
#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);
stepper.moveTo(newPosition);
}
void stepperMove(long newRelPosition)
{
stepper.enableOutputs();
stepper.setAcceleration(STEPPER_NORMAL_ACCELERATION);
stepper.move(newRelPosition);
stepper.move(newRelPosition);
}
void stopStepper(void)
{
stepper.setAcceleration(STEPPER_EMERGENCY_STOP_ACCELERATION);
stepper.move(0);
stepper.move(0);
stepper.stop();
while(stepper.run());
stepper.disableOutputs();
stepper.disableOutputs();
}
int lastSpeed = 0;
@@ -233,8 +262,32 @@ 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())
@@ -254,9 +307,9 @@ void loop()
persistentValues.lastLiftLevel = 0;
persistentValues.lastStepperPosition = 0;
stepper.setCurrentPosition(persistentValues.lastStepperPosition);
EEPROM.put(EEPROM_BASE_ADDR, persistentValues);
if(homing)
{
long newPos = persistentValues.levelPositions[persistentValues.lastLiftLevel];
@@ -273,19 +326,19 @@ void loop()
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())
{
@@ -305,7 +358,7 @@ void loop()
homing = true;
newSpeed = -STEPPER_MAX_SPEED;
}
btnManual.tick();
if(btnManual.press())
{
@@ -331,11 +384,11 @@ void loop()
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);
@@ -346,7 +399,7 @@ void loop()
displayMessageNumber("Dn To: ", persistentValues.lastLiftLevel + 1);
}
btnUp.tick();
if(configMode)
{
@@ -355,7 +408,7 @@ void loop()
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");
}
}
@@ -371,12 +424,12 @@ void loop()
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;
@@ -419,3 +472,16 @@ void loop()
}
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

@@ -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
@@ -134,7 +134,7 @@ void setup()
#endif
// Call the main DCC Init function to enable the DCC Receiver
Dcc.init( MAN_ID_DIY, DCC_DECODER_VERSION_NUM, CV29_ACCESSORY_DECODER, 0 );
Dcc.init( MAN_ID_DIY, DCC_DECODER_VERSION_NUM, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_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,5 +1,5 @@
name=NmraDcc
version=2.0.12
version=2.0.14
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