/*
TODO:
https://www.youtube.com/watch?v=qsflCf6ahXU
deal with max or min rpm limits
detect when there's no interrupts happening (0 rpm)
use float rpm for improved resolution?
*/
TaskHandle_t Task1;
const byte pulsesPerRevolution = 1;
const unsigned long usPerRevolution = 60000000 / pulsesPerRevolution;
const unsigned int printMs = 250;
volatile unsigned long us, prevPulseUs, pulseUs;
unsigned long prevPulseUsCopy, pulseUsCopy, prevMs, now, pulsePeriod, rpm;
void IRAM_ATTR isr() {
us = micros();
if ((us - pulseUs) > 100) { // debounce interval, also determines max rpm
prevPulseUs = pulseUs;
pulseUs = us;
}
}
void setup() {
Serial.begin(115200);
pinMode(5, OUTPUT);
attachInterrupt(digitalPinToInterrupt(19), isr, RISING);
xTaskCreatePinnedToCore(
Task1code, /* Task function. */
"Task1", /* name of task. */
10000, /* Stack size of task */
NULL, /* parameter of the task */
1, /* priority of the task */
&Task1, /* Task handle to keep track of created task */
0); /* pin task to core 0 */
delay(500);
}
void loop() {
delay(5);
}
//Task1code: pwmOut follows pwmIn
void Task1code( void * pvParameters ) {
for (;;) {
bool timeOut;
now = millis();
if ((now - prevMs) >= printMs) {
prevMs = now;
timeOut = true;
}
else timeOut = false;
if (timeOut) { // 4 Hz update frequency
noInterrupts();
prevPulseUsCopy = prevPulseUs;
pulseUsCopy = pulseUs;
interrupts();
pulsePeriod = pulseUsCopy - prevPulseUsCopy;
if (pulsePeriod > 1000000) rpm = 0; // Show 0 rpm when input < 1 Hz (60 rpm)
else if (pulsePeriod < 1000) rpm = 60000; // show 60000 rpm max when input > 1kHz
else rpm = usPerRevolution / pulsePeriod;
Serial.println(rpm);
}
}
}