// 16 Kanal Schalter für Lichtsteuerung
// Fernsteuerung: Flysky i6X
// CPU: Arduino Nano
// https://forum.arduino.cc/t/neues-rc-projekt-16-kanal-schalter-fur-lichtsteuerung/1143800/23
enum State {IDLE, PULSE, MEMA, MEMB}; // Leerlauf, Impulse,
class Kanal {
protected:
const byte channel;
const byte pin;
const byte mem;
State state;
uint32_t previousMillis = 0; // Zeitmanagement
public:
Kanal(const byte channel, const byte pin, const byte mem) : channel(channel), pin(pin), mem(mem) {}
void fire() {
if (state == IDLE) {
if (mem == 0) {
previousMillis = millis();
digitalWrite(pin, HIGH);
state = PULSE;
}
else {
state = MEMA;
previousMillis = millis();
digitalWrite(pin, HIGH);
}
}
else if (state == MEMB && mem == 1) {
digitalWrite(pin, LOW);
state = IDLE;
}
}
void begin() {
pinMode(pin, OUTPUT);
}
void update(uint32_t currentMillis = millis()) {
switch (state) {
case PULSE :
if (currentMillis - previousMillis > 1000) { // nach n millisekunden abschalten
digitalWrite(pin, LOW);
state = IDLE;
}
break;
case MEMA :
if (currentMillis - previousMillis > 1000) { // nach n millisekunden in den nächsten Status
state = MEMB;
}
break;
}
}
};
const byte PWMPin1 {2};
const byte PWMPin2 {3};
uint16_t PWMEingang1;
uint16_t PWMEingang2;
Kanal kanal [] = {
// channel, Pin, mem, befehl auf serieller
/* Daten Kanal01 = */{1, 4, 1 }, // a
/* Daten Kanal02 = */{2, 5, 0 }, // b
/* Daten Kanal03 = */{3, 6, 1 }, // c
/* Daten Kanal04 = */{4, 7, 1 }, // d
/* Daten Kanal05 = */{5, 8, 0 }, // e
/* Daten Kanal06 = */{6, 9, 0 }, // f
/* Daten Kanal07 = */{7, 10, 0 }, // g
/* Daten Kanal08 = */{8, 11, 0 }, // h
/* Daten Kanal09 = */{9, 12, 0 }, // i
/* Daten Kanal10 = */{10, 13, 0 }, // j
/* Daten Kanal11 = */{11, A0, 0 }, // k
/* Daten Kanal12 = */{12, A1, 0 }, // l
/* Daten Kanal13 = */{13, A2, 0 }, // m
/* Daten Kanal14 = */{14, A3, 0 }, // n
/* Daten Kanal15 = */{15, A4, 0 }, // o
/* Daten Kanal16 = */{16, A5, 0 } // p
};
void setup() {
pinMode (PWMPin1, INPUT);
pinMode (PWMPin2, INPUT);
Serial.begin(115200);
for (auto &i : kanal) {
i.begin();
}
Serial.println("und go");
}
void loop() {
readRCinput();
checkRCSwitch1();
Serial.print(F("PWM CH1: "));
Serial.print(PWMEingang1);
Serial.print(F(" PWM CH2: "));
Serial.println(PWMEingang2);
handleSerial();
uint32_t currentMillis = millis();
for (auto &i : kanal) {
i.update(currentMillis);
}
}
// nur testweise um Befehle einzugeben
void handleSerial() {
int c = Serial.read();
if (c >= 'a' && c <= 'p') {
kanal[c - 'a'].fire(); // a = 0 ... p = 15
} else if (c >= '0' && c <= '9') {
kanal[c - '0'].fire(); // ok, die ersten 10 Ziffern gehen auch ;-)
}
}
void readRCinput()
{
int PWM1IN = pulseIn(PWMPin1, HIGH ); //Read PWM Pulse
if (PWM1IN > 900 && PWM1IN < 2100)
{
PWMEingang1 = PWM1IN;
}
int PWM2IN = pulseIn(PWMPin2, HIGH ); //Read PWM Pulse
if (PWM2IN > 900 && PWM2IN < 2100)
{
PWMEingang2 = PWM2IN;
}
}
void checkRCSwitch1()
{
switch (PWMEingang1)
{
case 950 ... 1050:
kanal[0].fire();
break;
case 1950 ... 2050:
kanal[1].fire();
break;
case 1100 ... 1200:
kanal[2].fire();
break;
case 1800 ... 1900:
kanal[3].fire();
break;
case 1240 ... 1340:
kanal[4].fire();
break;
case 1350 ... 1450:
kanal[5].fire();
break;
case 1530 ... 1630:
kanal[6].fire();
break;
case 1660 ... 1760:
kanal[7].fire();
break;
default:
break;
}
}
Das ist der Code mit der wiederhergestellten handleSerial und der von mir eingefügten noch eingefügten checkRCswitch und dem switch/case.
Den neuen Code aus dem Simulator habe ich auch getestet. Auch dort schaltet sich der Kanal nicht wieder aus ![]()