hello, how are you doing?, I have a question, I want to build a cadence sensor with the magnetic sensor and an oled screen by I2C, I have a code made, which was with the help of a friend and the internet but it measures the RPM incorrectly, someone could you help me with the code? (the project is for a racing bike)
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSerif9pt7b.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
const int REED_PIN = 0; // Pin connected to reed switch
const int LED_PIN = 13; // LED pin - active-high
const int REVS_PER_PEDAL = 4; // Flywheel revolves 4x per pedal revolution
const int DISPLAY_REFRESH = 1000; // Refresh speed in milliseconds of OLED Display
float rev = 0;
float rpm[2];
int period_start = 0;
int period_duration;
void isr()
{
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();
// If interrupts come faster than 30 ms, assume it's a bounce and ignore
// 31ms is the time of a Reed spike at 30 RPM (assuming the magnet triggers on approxiamtively 1/16 of the wheel)
// It's also >2x faster than the frequency of 200 RPM (pedals) - Shannon resolution
// RPM values beween 30 and 200 should be reasonably good
if (interrupt_time - last_interrupt_time > 30)
{
rev++;
}
last_interrupt_time = interrupt_time;
}
void setup() {
pinMode(REED_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("SSD1306 allocation failed");
for(;;);
}
delay(2000);
display.setFont(&FreeSerif9pt7b);
display.clearDisplay();
display.setTextSize(3);
display.setTextColor(WHITE);
attachInterrupt(digitalPinToInterrupt (REED_PIN), isr, RISING); //interrupt pin
}
void loop() {
delay(DISPLAY_REFRESH);
detachInterrupt(digitalPinToInterrupt(REED_PIN));
display.clearDisplay();
period_duration = millis() - period_start; //duration since we started last IRQ
rpm[1] = (rev / period_duration) * 60000 / REVS_PER_PEDAL; //average RPM in current period
rpm[0] = (2 * rpm[1] + rpm[0]) / 3; //weighted smoothing with previous measure
rev = 0;
display.setCursor(25,50);
display.println((int)rpm[0]);
display.display();
period_start = millis(); //start a new period
attachInterrupt(digitalPinToInterrupt (REED_PIN), isr, RISING);
}
I did the code with my friend (I don't know much about programming, I'm learning), he told me part of the code is from a cadence sensor project but for a stationary bike.
I would really appreciate a help