Потихоньку, начал писать программу для управления головным устройством.
Наметал черновой вариант обработки КЗ+автореверс, опрос датчиков, контроль наличия DCC, стек LN команд(чтобы гарантировано доставлял сообщения).
Например, самый простой код у обработчика наличия сигнала DCC
Код:
#include <dccctrl.h>
void CDccCtrl::Run(){
uint8_t Test = (analogRead(TestPin) > DCC_IS_ON_LEVEL);
if (Test != IsOn) {
IsOn = Test;
digitalWrite(DccEnablePin, IsOn);
digitalWrite(DccEnableLedPin, IsOn);
LastChange = millis();
if (notifyDccState) notifyDccState(IsOn);
}
}
void CDccCtrl::Init(uint8_t inTestPin, uint8_t outDccEnablePin, uint8_t outDccEnableLedPin){
IsOn = 0;
LastChange = 0;
TestPin = inTestPin;
DccEnablePin = outDccEnablePin;
DccEnableLedPin = outDccEnableLedPin;
pinMode(TestPin, INPUT);
pinMode(DccEnablePin, OUTPUT);
digitalWrite(DccEnablePin, LOW);
pinMode(DccEnableLedPin, OUTPUT);
digitalWrite(DccEnableLedPin, LOW);
};
CDccCtrl DccCtrl = CDccCtrl();
Скорее всего архитектура такая и будет: один объект-обработчик на одну функциональность:
Один из плюсов такого подхода - лишнее несложно выпилить.
Код:
void setup() {
Serial.begin(250000);
Serial.print("LNBBOD v0.");
Serial.println(EEPROM_VERSION);
LocoNet.init(LOCONET_TX_PIN);
ShortCtrl.Init(A7, SHORT_AUTOREVERSE, A0, A2, A3, 12);
DccCtrl.Init(A6, A0, A1);
SensorsCtrl.Init(3, 6, 4, 9, 5, 10, 11);
}
void loop() {
m = millis();
DccCtrl.Run();
ShortCtrl.Run();
LNRun();
CmdQueue.Run();
SensorsCtrl.Run();
m = millis()-m;
Serial.print("c:");
Serial.println(m);
}
Собственно как выглядит обработка в теле "главной" программы:
Код:
...
void notifyShort(){
Serial.println("SHORT!");
}
void notifyPolarity(uint8_t Polarity){
Serial.print("Upd PLR:");
Serial.println(Polarity);
}
void notifyDccState(uint8_t State){
Serial.print("Upd DCC:");
Serial.println(State);
}
void notifyFBSensor(uint8_t index, uint8_t State){
CmdQueue.PushCmd(CMD_FEEDBACK, index, State, 0);
}
//Loconet message
void notifyPower(uint8_t State){
Serial.print("Upd PWR:");
Serial.println(State);
if (State) ShortCtrl.Reset();
}
...
Еще нашел, что можно высвободить 2 вывода у ардуины, сэкономить на CH_LOAD.