I am trying to make speedometer for my bike. I've got a reed sensor and a hc05 bluetooth module.
I want to calculate the speed im going.
The problem i'm having is that 'timer' stays 0 at all times. It's the first time im working with these interrupts so i might be doing something wrong.
Can anyone help? I have added prints for all variables and commented their output next to it
int reedSwitch =7;
int circumference;
int totaltime;
int Speed;
int timer;
int radius = 311; // radius in mm
int reed_status;
void isr()
{
timer++;
delayMicroseconds(9600);
}
void setup(){
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(reedSwitch), isr, RISING);
pinMode(reedSwitch, INPUT_PULLUP);
timer = 0;
Speed= 0;
totaltime = 0;
circumference = 6.28 * radius;
}
void loop() {
//reed_status = digitalRead(reedSwitch); // this code prints 0 when magnet is close and 1 when no magnet is close so the reed sensor is working
//Serial.println(reed_status);
delay(5);
if (millis() - totaltime >= 1000) {
detachInterrupt(digitalPinToInterrupt(reedSwitch));
Speed= ((0.0036*circumference)/(millis() - totaltime)*timer); // Calculates the speed of the bike. mm/s -> km/u
Serial.print("Speed ");
Serial.println(Speed); //prints 0
Serial.print("circum ");
Serial.println(circumference); // prints 1953
Serial.print("totaltime ");
Serial.println(totaltime); // this prints 1000 + 1000 every loop until about 32000. Then it prints -32000 and the prints start coming way faster
Serial.print("timer ");
Serial.println(timer); //prints 0
timer = 0;
totaltime = millis();
attachInterrupt(digitalPinToInterrupt(reedSwitch), isr, RISING);
}
}
I changed Speed to float but it did not change anything. Just to be sure i also changed totaltime to float, timer to volatile float timer and circumference to float as a second test.
This also did not change anything.
I think the main problem is that timer is always 0 (that causes the equation to always be 0)
I have changed my code to millis() - totaltime is in milliseconds, my formula was for seconds.
I have divided millis() - totaltime by 1000. I think this should work now. I havent testen on a wheel but by playing with a magnet, the values are kinda believable.
int reedSwitch =2;
float circumference;
float totaltime;
float speedt;
volatile float timer;
int radius = 311; // radius in mm
int reed_status;
void isr()
{
timer++; // Begin the timer and start counting
}
void setup(){
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(reedSwitch), isr, RISING);
pinMode(reedSwitch, INPUT_PULLUP);
timer = 0;
speedt = 0;
totaltime = 0;
circumference = 6.28 * radius;
}
void loop() {
if (millis() - totaltime >= 1000) {
detachInterrupt(digitalPinToInterrupt(reedSwitch));
speedt = ((0.0036*circumference)/((millis() - totaltime) / 1000 )*timer); // Calculates the speed of the bike. mm/ms -> km/u
timer = 0;
totaltime = millis();
attachInterrupt(digitalPinToInterrupt(reedSwitch), isr, RISING);
}
}
Perhaps the major problem is you are using a module with an active IC device that just happens to have a reed switch. But your program is written as if it is actually directly connected to a real reed switch. Nothing in the link you gave for the module has any information about the module or how to use it. I see a pot on the board, so that is likely a sensitivity control, but perhaps some other use. Who knows. But until you get that actually defined, there is no hope for you program.
Assuming 0 or LOW means magnet detected, here is what I have done.
void loop() {
while (digitalRead(sensor) == HIGH) ; //wait until magnet detected.
while (digitalRead(sensor) == LOW); //wait until it passes
unsigned long start = millis();
while (digitalRead(sensor) == HIGH); //wait until detected again
while (digitalRead(sensor) == LOW); //wait until it passes again
unsigned long total_time = millis() - start;
report_speed(total_time);
}
NOTE: This skips one revolution of the wheel and starts over, which with a little more work, can be fixed. And, of course, the code is blocking. The Arduino can't do anything else.