// WORKING ON DEBOUNCING
int opto = 3; // opto-interrupter
int rpm = 0; // rev per min
float speed, dia = 0.021; // speed and diameter in meters
unsigned long dtime; // previous "start time"
volatile int rotation; // counter
// for ISR
unsigned long timer, timeout = 100;
void setup() {
Serial.begin(115200);
// pinMode(opto, INPUT_PULLUP); // xfpd using button tied high
pinMode(opto, INPUT);
// attachInterrupt(digitalPinToInterrupt (opto), ISR1, FALLING); // xfpd using button tied high
attachInterrupt(digitalPinToInterrupt (opto), ISR1, RISING);
}
void loop() {
if (millis() - dtime >= 1000) { // timeout
dtime = millis(); // reset timer
// calculate outside the ISR because calculating is not fast
rpm = rotation * 60; // rotations per second x 60 seconds per minute
speed = (PI * dia) * (rpm); // "linear circumferences" per "time measured"
// print outside the ISR because printing is very slow
Serial.print("Bogie Speed is ");
printout(speed, 2); // speed with two decimal places
Serial.print(" m/s at ");
printout(rpm, 0); // rpm with no decimal places
Serial.print(" RPM over ");
printout(rotation, 0);
Serial.print(" rotation");
if (rotation != 1) Serial.print("s");
Serial.println(".");
rpm = speed = rotation = 0; // reset counters
}
}
void ISR1() {
if (millis() - timer >= timeout) {
timer = millis();
rotation++; // count a rotation only, then calculate outside the ISR
}
}
void printout(float value, byte decimals) { // format the printout
if (value < 100) Serial.print(" ");
if (value < 10) Serial.print(" ");
Serial.print(value, decimals);
}