From e7e4d4fbd90b9be676d381ffcf58e1596d83c533 Mon Sep 17 00:00:00 2001 From: Asbelos Date: Tue, 23 Jun 2020 17:43:50 +0100 Subject: [PATCH] Drop railcom and prepare for servo turnouts --- CVReader.ino | 19 ++++++++++++++++-- DCCWaveform.cpp | 12 ++--------- DCCWaveform.h | 5 ----- Hardware.cpp | 5 +++++ Hardware.h | 1 + Railcom.cpp | 25 ----------------------- Railcom.h | 16 --------------- Turnouts.cpp | 53 ++++++++++++++++++++++++++----------------------- Turnouts.h | 19 +++++++++++------- freeMemory.h | 22 ++++++++++++++++++++ 10 files changed, 87 insertions(+), 90 deletions(-) delete mode 100644 Railcom.cpp delete mode 100644 Railcom.h create mode 100644 freeMemory.h diff --git a/CVReader.ino b/CVReader.ino index 84646ad..e42d284 100644 --- a/CVReader.ino +++ b/CVReader.ino @@ -44,10 +44,15 @@ void myCallback(int result) { } -// Create a serkial command parser... This is OPTIONAL if you don't need to handle JMRI type commands +// Create a serial command parser... This is OPTIONAL if you don't need to handle JMRI type commands // from the Serial port. DCCEXParser serialParser; + +// Try monitoring the memory +#include "freeMemory.h" +int minMemory; + void setup() { Serial.begin(SERIAL_BAUD_RATE); DCC::begin(); @@ -59,8 +64,11 @@ void setup() { // Optionally tell parser to use my example filter DCCEXParser::setFilter(myFilter); + malloc(1); + minMemory=freeMemory(); + DIAG(F("\nFree memory=%d"),minMemory); DIAG(F("\nReady for JMRI commands\n")); - + } void loop() { @@ -71,4 +79,11 @@ void loop() { // This line passes input on Wifi to another DCCEXParser if (WIFI_PORT>0) WifiInterface::loop(); + + // Report any decrease in memory + int freeNow=freeMemory(); + if (freeNow -class Railcom { - public: - static void startCutout(); - static void interrupt(); - private: - static byte interruptState; - static byte bitsReceived; - static const byte MAX_BUFFER=20; - static byte buffer[MAX_BUFFER]; -}; - -#endif diff --git a/Turnouts.cpp b/Turnouts.cpp index 7754a21..47ca972 100644 --- a/Turnouts.cpp +++ b/Turnouts.cpp @@ -1,7 +1,7 @@ #include "Turnouts.h" #include "EEStore.h" #include "StringFormatter.h" - +#include "Hardware.h" bool Turnout::activate(int n,bool state){ Turnout * tt=get(n); if (tt==NULL) return false; @@ -12,8 +12,10 @@ // activate is virtual here so that it can be overridden by a non-DCC turnout mechanism void Turnout::activate(bool state) { - data.tStatus=state; - DCC::setAccessory(data.address,data.subAddress, data.tStatus); + if (state) data.tStatus|=STATUS_ACTIVE; + else data.tStatus &= ~STATUS_ACTIVE; + if (data.tStatus & STATUS_PWM) Hardware::setServo(data.tStatus & STATUS_PWMPIN, (data.inactiveAngle+state?data.moveAngle:0)); + else DCC::setAccessory(data.address,data.subAddress, state); } /////////////////////////////////////////////////////////////////////////////// @@ -46,7 +48,7 @@ bool Turnout::remove(int n){ void Turnout::show(Print & stream, int n){ for(Turnout *tt=firstTurnout;tt!=NULL;tt=tt->nextTurnout){ if (tt->data.id==n) { - StringFormatter::send(stream,F(""), tt->data.id, tt->data.tStatus); + StringFormatter::send(stream,F(""), tt->data.id, tt->data.tStatus & STATUS_ACTIVE); return; } } @@ -70,9 +72,9 @@ void Turnout::load(){ for(int i=0;idata.nTurnouts;i++){ EEPROM.get(EEStore::pointer(),data); - tt=create(data.id,data.address,data.subAddress); + if (data.tStatus & STATUS_PWM) tt=create(data.id,data.tStatus & STATUS_PWMPIN, data.inactiveAngle,data.moveAngle); + else tt=create(data.id,data.address,data.subAddress); tt->data.tStatus=data.tStatus; - tt->num=EEStore::pointer(); EEStore::advance(sizeof(tt->data)); } } @@ -86,7 +88,6 @@ void Turnout::store(){ EEStore::eeStore->data.nTurnouts=0; while(tt!=NULL){ - tt->num=EEStore::pointer(); EEPROM.put(EEStore::pointer(),tt->data); EEStore::advance(sizeof(tt->data)); tt=tt->nextTurnout; @@ -97,29 +98,31 @@ void Turnout::store(){ /////////////////////////////////////////////////////////////////////////////// Turnout *Turnout::create(int id, int add, int subAdd){ - Turnout *tt; - - if(firstTurnout==NULL){ - firstTurnout=(Turnout *)calloc(1,sizeof(Turnout)); - tt=firstTurnout; - } else if((tt=get(id))==NULL){ - tt=firstTurnout; - while(tt->nextTurnout!=NULL) - tt=tt->nextTurnout; - tt->nextTurnout=(Turnout *)calloc(1,sizeof(Turnout)); - tt=tt->nextTurnout; - } - - if (tt==NULL) return(tt); - - tt->data.id=id; + Turnout *tt=create(id); tt->data.address=add; tt->data.subAddress=subAdd; tt->data.tStatus=0; return(tt); - } -/////////////////////////////////////////////////////////////////////////////// +Turnout *Turnout::create(int id, byte pin, int activeAngle, int inactiveAngle){ + Turnout *tt=create(id); + tt->data.tStatus= STATUS_PWM | (pin & STATUS_PWMPIN); + tt->data.inactiveAngle=inactiveAngle; + tt->data.moveAngle=activeAngle-inactiveAngle; + return(tt); +} + +Turnout *Turnout::create(int id){ + Turnout *tt=get(id); + if (tt==NULL) { + tt=(Turnout *)calloc(1,sizeof(Turnout)); + tt->nextTurnout=firstTurnout; + firstTurnout=tt; + tt->data.id=id; + } + return tt; + } + /////////////////////////////////////////////////////////////////////////////// Turnout *Turnout::firstTurnout=NULL; diff --git a/Turnouts.h b/Turnouts.h index 8152c36..28fd528 100644 --- a/Turnouts.h +++ b/Turnouts.h @@ -4,24 +4,29 @@ #include #include "DCC.h" +const byte STATUS_ACTIVE=0x80; // Flag as activated +const byte STATUS_PWM=0x40; // Flag as a PWM turnout +const byte STATUS_PWMPIN=0x3F; // PWM pin 0-63 + struct TurnoutData { - uint8_t tStatus; - uint8_t subAddress; - int id; - int address; + int id; + uint8_t tStatus; // has STATUS_ACTIVE, STATUS_PWM, STATUS_PWMPIN + union {uint8_t subAddress; char moveAngle;}; //DCC sub addrerss or PWM difference from inactiveAngle + union {int address; int inactiveAngle;}; // DCC address or PWM servo angle }; struct Turnout{ static Turnout *firstTurnout; - int num; - struct TurnoutData data; + TurnoutData data; Turnout *nextTurnout; static bool activate(int n, bool state); static Turnout* get(int); static bool remove(int); static void load(); static void store(); - static Turnout *create(int, int, int); + static Turnout *create(int id , int address , int subAddress); + static Turnout *create(int id , byte pin , int activeAngle, int inactiveAngle); + static Turnout *create(int id); static void show(Print & stream, int n); static bool showAll(Print & stream); virtual void activate(bool state); diff --git a/freeMemory.h b/freeMemory.h new file mode 100644 index 0000000..5bc1ad5 --- /dev/null +++ b/freeMemory.h @@ -0,0 +1,22 @@ +#ifndef freeMemory_h +#define freeMemory_h + +// thanks go to https://github.com/mpflaga/Arduino-MemoryFree +#ifdef __arm__ +// should use uinstd.h to define sbrk but Due causes a conflict +extern "C" char* sbrk(int incr); +#else // __ARM__ +extern char *__brkval; +#endif // __arm__ + +int freeMemory() { + char top; +#ifdef __arm__ + return &top - reinterpret_cast(sbrk(0)); +#elif defined(CORE_TEENSY) || (ARDUINO > 103 && ARDUINO != 151) + return &top - __brkval; +#else // __arm__ + return __brkval ? &top - __brkval : &top - __malloc_heap_start; +#endif // __arm__ +} +#endif