#include <digitalWriteFast.h>
#include <Streaming.h>
Print &cout {Serial};
constexpr uint8_t MEASURE_PIN {4};
//
// Class for measuring the time interval between two edge changes
// Initialized with HIGH -> from low to high - measurement - high to low).
// Initialized with LOW -> from HIGH to Low - measurement - Low to HIGH).
// HIGH is default.
//
class SptMeasurement { // spt -> signal propagation time
public:
SptMeasurement(uint8_t pin_, uint8_t activeState_ = HIGH) : pin {pin_}, activeState {activeState_} {}
void begin() {
pinMode(pin, INPUT);
lastPinState = actPinState = !activeState;
}
uint32_t doTheMeasurment();
void setDebounceTime(uint16_t dbt) { debounceTime = dbt; }
void clearResult() { duration = 0; }
private:
bool checkSignalChange();
private:
uint8_t pin;
uint8_t activeState;
uint32_t timeStampDebounce {0};
uint16_t debounceTime {5};
uint8_t actPinState;
uint8_t lastPinState;
uint32_t timeStampStart {0};
uint32_t duration {0};
};
bool SptMeasurement::checkSignalChange() {
bool signalHasChanged = false;
uint8_t pinState = digitalReadFast(pin);
if (pinState != lastPinState) { // Restart the debounce timer with every edge change
lastPinState = pinState;
timeStampDebounce = millis();
} else if (pinState != actPinState && (millis() - timeStampDebounce >= debounceTime)) {
// No more edge changes within the debounce time but the pinState is permanently unequal to the
// previous one before the test.
actPinState = pinState;
signalHasChanged = true;
}
return signalHasChanged;
}
uint32_t SptMeasurement::doTheMeasurment() {
if (checkSignalChange() == true) { // Signal has been changed from low to high or vice versa
if (actPinState == activeState) {
timeStampStart = millis();
duration = 0;
cout << F("Start\n");
} else {
duration = millis() - timeStampStart;
}
}
return duration;
}
// Class definition end //////////////////////////////////////////////////////////////
SptMeasurement spt {MEASURE_PIN}; // Create new Object
void setup() {
Serial.begin(115200);
spt.begin(); // init Object
}
void loop() {
uint32_t duration = spt.doTheMeasurment();
if (duration != 0) {
cout << F("Stop: ") << duration << " ms: ";
switch (duration) {
case 0 ... 1100: cout << F("Error 1\n"); break;
case 1101 ... 2100: cout << F("Error 2\n"); break;
case 2101 ... 3100: cout << F("Error 3\n"); break;
case 3101 ... 4100: cout << F("Error 4\n"); break;
case 4101 ... 5100: cout << F("Error 5\n"); break;
case 5101 ... 6100: cout << F("Error 6\n"); break;
default: cout << F("Zeitspanne > 6,1 Sekunden!"); break;
}
spt.clearResult();
}
}