/*
Forum: https://forum.arduino.cc/t/convert-led-into-a-digital-signal/1380846
Wokwi: https://wokwi.com/projects/430758590508506113
Example how to measure a blink rate non-blocking
ec2021
2025/05/12
*/
constexpr byte blinkOut {17};
constexpr byte switchPin {12};
unsigned long blinkRate;
constexpr byte blinkIn {5};
constexpr unsigned long connectRate {500};
constexpr unsigned long disConnectRate {250};
constexpr long tolerance {25};
class InputDevice {
private:
unsigned long lastChange = 0;
unsigned long lastDelta = 0;
byte lastState = HIGH;
byte state = LOW;
byte pin;
public:
void init(byte aPin) {
pin = aPin;
pinMode(pin, INPUT_PULLUP);
state = !digitalRead(pin);
}
boolean changedState() {
byte actState = digitalRead(pin);
if (actState != lastState) {
lastDelta = millis() - lastChange;
lastChange = millis();
lastState = actState;
}
if (lastState != state && millis() - lastChange > 100) {
state = lastState;
return true;
}
return false;
}
boolean getState() {
return state;
}
unsigned long getlastDelta() {
return lastDelta;
}
};
InputDevice button;
InputDevice signalIn;
void setup() {
Serial.begin(115200);
Serial.println("Start");
blinkRate = disConnectRate;
pinMode(blinkOut, OUTPUT);
button.init(switchPin);
signalIn.init(blinkIn);
}
void loop() {
controlBlinkRate();
blink();
measureBlinkRate();
}
void measureBlinkRate() {
static boolean errorPrinted = false;
static unsigned long lastChange = 0;
unsigned long delta = signalIn.getlastDelta();
if (signalIn.changedState()) {
errorPrinted = false;
Serial.print("Last Delta: ");
Serial.print(delta);
if (insideTolerance(delta, connectRate)) {
Serial.println("\tConnected");
lastChange = millis();
} else if (insideTolerance(delta, disConnectRate)) {
Serial.println("\tDisconnected");
lastChange = millis();
} else {
Serial.println("\tOut of tolerance!");
}
}
if (millis() - lastChange > 4 * connectRate && !errorPrinted) {
Serial.println("No changes detected!");
errorPrinted = true;
}
}
boolean insideTolerance(unsigned long value, unsigned long rate) {
return (value <= rate + tolerance) && (value >= rate - tolerance);
}
void controlBlinkRate() {
if (button.changedState()) {
if (button.getState()) {
blinkRate = disConnectRate;
} else {
blinkRate = connectRate;
}
}
}
void blink() {
static unsigned long lastBlink = 0;
static byte state = LOW;
static long diff = 0;
if (millis() - lastBlink >= blinkRate + diff) {
diff = random(-tolerance / 2, tolerance / 2);
lastBlink = millis();
state = !state;
digitalWrite(blinkOut, state);
}
}
Left: Connected
Right: Disconnected
Left: Signal enabled
Right: Signal disabled