#include <Arduino.h>
//////////////////////////////////////////////////
// Object definitions
//////////////////////////////////////////////////
class Timer {
public:
void start() { timeStamp = millis(); }
bool operator()(const unsigned long duration) const { return (millis() - timeStamp >= duration) ? true : false; }
private:
unsigned long timeStamp {0};
};
class SignalCounter {
public:
template <size_t MAX>
SignalCounter(const unsigned long (&stArray)[MAX]) : switchingTimes {stArray}, maxIndex {MAX - 1} {}
byte next() {
index = (index < maxIndex) ? index + 1 : 0;
return index;
}
unsigned long signalDuration() const { return switchingTimes[index]; }
private:
const unsigned long *switchingTimes;
byte maxIndex;
byte index {0};
};
enum class TransistorSwitchState : uint8_t { off = 0, on, locked };
//////////////////////////////////////////////////
// Global constants
//////////////////////////////////////////////////
constexpr byte ANALOGREAD_PIN {A0};
constexpr byte TRANSISTOR_SWITCH {4};
constexpr int LIGHT_THRESHOLD {500};
//////////////////////////////////////////////////
// Global variables and instances
//////////////////////////////////////////////////
const unsigned long msTimes[] {10000, 5000, 2500, 1250};
//const unsigned long msTimes[] {10000, 5000};
SignalCounter scTransistor(msTimes);
Timer timer;
//////////////////////////////////////////////////
// Main Program
//////////////////////////////////////////////////
bool showMessage(SignalCounter &sct) {
Serial.print(F("Nächstes "));
Serial.print(sct.signalDuration());
Serial.println(F(" ms Schaltsignal geblockt weil: "));
Serial.print(F("Lichtwert ist nach Schaltsignal"));
Serial.println(F(" immer noch kleiner als der Grenzwert.\n"));
return false;
}
void setup() {
Serial.begin(115200);
pinMode(TRANSISTOR_SWITCH, OUTPUT);
Serial.println(F("Schieber nach links -> \"LDR\" Werte werden kleiner"));
Serial.println(F("Schieber nach rechts -> \"LDR\" Werte werden größer\n"));
}
void loop() {
static unsigned int light {0};
static TransistorSwitchState tss {TransistorSwitchState::off};
if (tss == TransistorSwitchState::off) { light = analogRead(ANALOGREAD_PIN); }
if (light < LIGHT_THRESHOLD) {
switch (tss) {
case TransistorSwitchState::off:
timer.start();
tss = TransistorSwitchState::on;
digitalWrite(TRANSISTOR_SWITCH, HIGH);
break;
case TransistorSwitchState::on:
if (timer(scTransistor.signalDuration())) {
scTransistor.next();
digitalWrite(TRANSISTOR_SWITCH, LOW);
tss = TransistorSwitchState::locked;
}
break;
case TransistorSwitchState::locked:
static bool message {true};
if (analogRead(ANALOGREAD_PIN) >= LIGHT_THRESHOLD) {
tss = TransistorSwitchState::off;
message = true;
break;
}
message && (message = showMessage(scTransistor));
break;
default: break;
}
}
}