89 lines
2.6 KiB
Arduino
89 lines
2.6 KiB
Arduino
// Board: Adafruit Feather M0
|
|
|
|
#include <Arduino.h>
|
|
|
|
#include <Adafruit_GFX.h>
|
|
#include "Adafruit_LEDBackpack.h" // "Adafruit LED Backpack Library" v1.5.0
|
|
|
|
#define MEASUREMENT_PERIOD_MS 100
|
|
#define PULSES_PER_REVOLUTION 8
|
|
|
|
Adafruit_7segment matrix = Adafruit_7segment();
|
|
|
|
// --- Tachometer variables ---
|
|
const int TACH_INTERRUPT_PIN = A0; // Or any other digital pin capable of interrupts
|
|
volatile unsigned long g_isr_pulse_count_total = 0; // ISR increments this continuously
|
|
unsigned long g_main_last_pulse_count_snapshot = 0; // Main loop stores previous snapshot here
|
|
unsigned long last_measurement_time = 0;
|
|
|
|
// --- Interrupt Service Routine (ISR) ---
|
|
void count_pulse() {
|
|
g_isr_pulse_count_total++;
|
|
}
|
|
|
|
void show(int num) {
|
|
matrix.print(num, DEC);
|
|
matrix.writeDisplay();
|
|
}
|
|
|
|
void setup() {
|
|
matrix.begin(0x70);
|
|
|
|
Serial.begin(115200);
|
|
// Serial.setDebugOutput(true);
|
|
|
|
// --- Setup Tachometer Interrupt ---
|
|
pinMode(TACH_INTERRUPT_PIN, INPUT_PULLUP); // Set pin as input with internal pull-up resistor
|
|
attachInterrupt(digitalPinToInterrupt(TACH_INTERRUPT_PIN), count_pulse, RISING);
|
|
|
|
delay(1000);
|
|
|
|
Serial.println();
|
|
Serial.println();
|
|
Serial.println("================");
|
|
Serial.println("BOOT UP");
|
|
|
|
show(99999);
|
|
|
|
}
|
|
|
|
void loop() {
|
|
unsigned long current_time = millis();
|
|
|
|
if (current_time - last_measurement_time >= MEASUREMENT_PERIOD_MS) {
|
|
unsigned long current_total_snapshot;
|
|
|
|
// Atomically read the total pulse count
|
|
noInterrupts();
|
|
current_total_snapshot = g_isr_pulse_count_total;
|
|
interrupts();
|
|
|
|
// Calculate pulses collected during this interval
|
|
unsigned long collected_pulses = current_total_snapshot - g_main_last_pulse_count_snapshot;
|
|
|
|
// Store the current total snapshot for the next interval's calculation
|
|
g_main_last_pulse_count_snapshot = current_total_snapshot;
|
|
|
|
unsigned long actual_elapsed_time = current_time - last_measurement_time;
|
|
|
|
// Calculate RPM
|
|
// RPM = (pulses / pulses_per_revolution) / (actual_elapsed_time_ms / 1000 / 60)
|
|
// RPM = (pulses / pulses_per_revolution) * (60000 / actual_elapsed_time_ms)
|
|
// Ensure floating point division for accuracy before converting to int for display
|
|
float rpm_float = 0.0;
|
|
if (actual_elapsed_time > 0) { // Avoid division by zero
|
|
rpm_float = ( (float)collected_pulses / PULSES_PER_REVOLUTION ) * (60000.0 / actual_elapsed_time);
|
|
}
|
|
int rpm = (int)rpm_float;
|
|
|
|
show(rpm);
|
|
|
|
// Debugging output
|
|
Serial.print("Pulses: "); Serial.print(collected_pulses);
|
|
Serial.print("\tElapsed ms: "); Serial.print(actual_elapsed_time);
|
|
Serial.print("\tRPM: "); Serial.println(rpm);
|
|
|
|
last_measurement_time = current_time;
|
|
}
|
|
}
|