1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2025-07-28 18:03:45 +02:00

Low ram sensor groups

This commit is contained in:
Asbelos
2025-07-24 15:49:20 +01:00
parent 8b7d87d6bd
commit 940d7d70e2
4 changed files with 107 additions and 7 deletions

View File

@@ -113,11 +113,29 @@ bool exrailHalSetup1() {
// the first pass from the opcode table.
#include "EXRAIL2MacroReset.h"
#undef JMRI_SENSOR
#define JMRI_SENSOR(vpin,count...) Sensor::createMultiple(vpin,##count);
#define JMRI_SENSOR(vpin,count...) \
{ \
const int npins=#count[0]? count+0:1; \
static byte state_map[(npins+7)/8]; \
SensorGroup::doSensorGroup(vpin,npins,state_map,action,&USB_SERIAL); \
}
void SensorGroup::doExrailSensorGroup(GroupProcess action, Print * stream) {
(void) action; // suppress unused warning
(void) stream; // suppress unused warning
#include "myAutomation.h"
}
// Pass 1s Implements servos by creating exrailHalSetup2
// TODO Turnout and turntable creation should be moved to here instead of
// the first pass from the opcode table.
#include "EXRAIL2MacroReset.h"
#undef CONFIGURE_SERVO
#define CONFIGURE_SERVO(vpin,pos1,pos2,profile) IODevice::configureServo(vpin,pos1,pos2,PCA9685::profile);
void exrailHalSetup2() {
#include "myAutomation.h"
// pullup any group sensors
SensorGroup::pullupAll();
}
// Pass 1c detect compile time featurtes

54
SensorGroup.cpp Normal file
View File

@@ -0,0 +1,54 @@
#include "SensorGroup.h"
// called in loop to check sensors
void SensorGroup::checkAll() {
#ifdef EXRAIL_ACTIVE
doExrailSensorGroup(GroupProcess::CHECK, & USB_SERIAL);
#endif
}
// called by command to get sensor list
void SensorGroup::printAll(Print * serial) {
#ifdef EXRAIL_ACTIVE
doExrailSensorGroup(GroupProcess::PRINT,serial);
#endif
}
void SensorGroup::pullupAll() {
#ifdef EXRAIL_ACTIVE
doExrailSensorGroup(GroupProcess::PULLUP, & USB_SERIAL);
#endif
}
// called by EXRAIL constructed doExrailSensorGroup for each group
void SensorGroup::doSensorGroup(VPIN firstVpin, int nPins, byte* statebits,
GroupProcess action, Print * serial) {
// Loop through the pins in the group
for (auto i=0;i<nPins;i++) {
// locate position of state bit
byte stateByte=i/8;
byte stateMask=1<<(i%8);
VPIN vpin= firstVpin+i;
switch(action) {
case GroupProcess::PULLUP:
IODevice::configureInput(vpin, true);
__attribute__ ((fallthrough)); // to check the current state
case GroupProcess::CHECK:
// check for state change
if ((bool)(statebits[stateByte]&stateMask) ==IODevice::read(vpin)) break; // no change
// flip state bit
statebits[stateByte]^=stateMask;
if (action==GroupProcess::PULLUP) break;
// fall through to print the changed value
__attribute__ ((fallthrough));
case GroupProcess::PRINT:
StringFormatter::send(serial, F("<%c %d>\n"),
(statebits[stateByte]&stateMask)?'Q':'q', firstVpin+i);
break;
}
}
}

24
SensorGroup.h Normal file
View File

@@ -0,0 +1,24 @@
#ifndef SensorGroup_h
#define SensorGroup_h
#include <Arduino.h>
#include "defines.h"
#include "IODevice.h"
#include "StringFormatter.h"
// reference to the optional exrail built function which contains the
// calls to SensorGroup::doSensorGroup
enum GroupProcess:byte {PULLUP,PRINT,CHECK};
class SensorGroup {
public:
static void checkAll();
static void printAll(Print * serial);
static void pullupAll();
static void doSensorGroup(VPIN vpin, int nPins, byte* statebits,
GroupProcess action, Print * serial);
private:
static void doExrailSensorGroup(GroupProcess action, Print * stream);
};
#endif // SensorGroup_h

View File

@@ -91,6 +91,9 @@ decide to ignore the <q ID> return and only react to <Q ID> triggers.
///////////////////////////////////////////////////////////////////////////////
void Sensor::checkAll(){
SensorGroup::checkAll();
uint16_t sensorCount = 0;
#ifdef USE_NOTIFY
@@ -181,12 +184,13 @@ void Sensor::inputChangeCallback(VPIN vpin, int state) {
///////////////////////////////////////////////////////////////////////////////
void Sensor::printAll(Print *stream){
if (stream != NULL) {
for(Sensor * tt=firstSensor;tt!=NULL;tt=tt->nextSensor){
StringFormatter::send(stream, F("<%c %d>\n"), tt->active ? 'Q' : 'q', tt->data.snum);
}
} // loop over all sensors
if (stream == NULL) return; // Nothing to do
SensorGroup::printAll(stream);
for(Sensor * tt=firstSensor;tt!=NULL;tt=tt->nextSensor){
StringFormatter::send(stream, F("<%c %d>\n"), tt->active ? 'Q' : 'q', tt->data.snum);
}
} // Sensor::printAll
///////////////////////////////////////////////////////////////////////////////