bicycle speedometer code problem.

I have set up some code to read information from the cadence and wheelspeed of a bicycle.

The cadence part is working fine, but the wheelspeed is unresponsive.

I am using a reed switch to capture wheelspeed, and when the reed switch is triggered the speed reads as -0.00

Can anyone advise where I have made a mistake? In lay terms, I am not very advanced in programming.

Thanks!

//////////////////CADENCE VARIABLES/////////////////

int RPM;
long newCtime = 0;
long newLastCt = 0;
long Ctime = 1000; // give this an initial value so that you can calculate debounceDelay
long lastCt = 0;
int HE01 = A0; // this is the analog pin
int HE02 = A1; // this is the analog pin
const int trigNum=840;
const int trigNum2=520;
boolean HE01trig = false;

//////////////////SPEED VARIABLES/////////////////

#define reed A2//pin connected to read switch
int reedVal;
long timer;// time between one full rotation (in ms)
float kph;
float radius = 13.15;// tire radius (in inches)
float circumference;
int maxReedCounter = 100;//min time (in ms) of one rotation (for debouncing)
int reedCounter;

void setup(){

  reedCounter = maxReedCounter;
  circumference = 2*3.14*radius;
  pinMode(reed, INPUT);

  Serial.begin(57600);
}


void loop() {

  //////////////////CADENCE/////////////////

  // collect sensor data
  int HE01val = analogRead(HE01); 
  int HE02val = analogRead(HE02); 

  // model data

  if(HE01val > trigNum && HE01trig == false) {
    newCtime = millis() - lastCt;
    newLastCt = millis();
    HE01trig = true;
  }

  if(HE02val > trigNum2 && HE01trig == true){
    Ctime = newCtime;
    lastCt = newLastCt;
    RPM = 60000/Ctime;
    HE01trig = false;
  }

  int timeCheck = millis() - lastCt;
  if(timeCheck > Ctime){
    Ctime = timeCheck;
    RPM = 60000/Ctime;
  }

  //////////////////SPEED/////////////////
  
  long startTimer;

  reedVal = digitalRead(reed);//get val of A2
  if (reedVal){//if reed switch is closed
    if (reedCounter == 0){//min time between pulses has passed
      kph = (36*float(circumference))/float(timer);//calculate km per hour
      startTimer = millis();
      reedCounter = maxReedCounter;//reset reedCounter
    }
    else{
      if (reedCounter > 0){//don't let reedCounter go negative
        reedCounter -= 1;//decrement reedCounter
      }
    }
  }
  else{//if reed switch is open
    if (reedCounter > 0){//don't let reedCounter go negative
      reedCounter -= 1;//decrement reedCounter
    }
  }

  timer = millis() - startTimer;

  if (timer > 2000){
    kph = 0;//if no new pulses from reed switch- tire is still, set kp to 0
  }

  //Update display

  Serial.print("Cadence = "); 
  Serial.print(RPM);  
  Serial.print("   ");
  Serial.print("Speed = "); 
  Serial.println(kph);

}

Im still not very good at parsing other's code, but I am working on a very similar project, using a reed switch on my bike to make a simple bicycle computer. While my code has more stuff, you should be able to get some usefull stuff from it.

I have an LCD coded in, and a couple buttons for input, but the relevant code happens at line 111 of that pastebin link. Hope this helps at all :slight_smile:

As a little additional note, to prevent "bounce" in the reed switch, I originally used a delay like you are doing but found it to be an issue at higher speeds. Instead, inside my if block that checks for the switch, I included a boolean, that basically just denotes that it has gone through the logic once. I use that as a condition to the if, so if its true, meaning its already done the logic, it doesn't do it again. This accounts for the time the reed switch is closed, which could end up being 5-10 loop()'s. Once the reed opens, I reset the boolean to false. This has been an extremely effective solution to that part of my project.

Your technique for timing the reed open time eludes me a bit.

Why not take the time when it closes, the time when it opens, and subtract one from the other? Possibly inside an interrupt.

Also:

 //Update display

  Serial.print("Cadence = "); 
  Serial.print(RPM);  
  Serial.print("   ");
  Serial.print("Speed = "); 
  Serial.println(kph);

This will "block" when the buffer fills up, throwing out all your timings. I suggest you only print once a second or so.

Thanks,

I have a boolean on the cadence section, I will do the same for speed, and let you know how it goes.

Also added a delay for the serial read as well.

Cheers.

I wasn't thinking of a delay (function call), more like if a second has elapsed, based on reading the millis() timer.