Arduino E-Bike speedometer and voltage display

Hi! I am about to start building an electric bike. It will use a 6-cell LiPo for power. I want to use an Arduino Nano, hall-effect sensor or reed switch, and a Nokia 5110 screen to read speed, display, and also show voltage. I have the voltage all worked out. My problem is the speed reading. I have thought about using millis() and averaging the counts per second, but I am still not quite sure. I want to display MPH, and have no interest in stuff like an odometer. Please contribute. And I know Google. He was in my class at school. :wink:
Thanks!

Isaac96:
I have thought about using millis() and averaging the counts per second, but I am still not quite sure. I want to display MPH,...

Or you could time the hall sensor, the slower the speed the longer the period (both the active pulse and the time between pulses.)

Hi,
In the "Search Arduino Forum" window in top right hand corner of this page, search, speed, bike

Tom.... :slight_smile:

OK. I saw the Playground page, and so far I have an RPM and Hertz reading. Now I need to convert that to MPH.
MPH = RPM * 0.07651
Or something like that.
26" tire = ~82" circumference
RPM * 60 = RPH (rotations per hour
RPH * 82 = IPH (inches per hour)
Convert to miles = 0.07651
Done!

// read RPM
int half_revolutions = 0;
int rpm = 0;
unsigned long lastmillis = 0;
int mph = 0;
void setup() {
  pinMode(2, INPUT_PULLUP);
  Serial.begin(9600);
  attachInterrupt(0, rpm_fan, FALLING);
}
void loop() {
  if (millis() - lastmillis == 1000) { //Uptade every one second, this will be equal to reading frecuency (Hz).
    detachInterrupt(0);//Disable interrupt when calculating
    rpm = half_revolutions * 60; // Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use half_revolutions * 30.
    Serial.print("RPM =\t"); //print the word "RPM" and tab.
    Serial.print(rpm); // print the rpm value.
    Serial.print("\t Hz=\t"); //print the word "Hz".
    Serial.print(half_revolutions); //print revolutions per second or Hz. And print new line or enter.
    mph = rpm * 0.07651;
    Serial.print("\t  MPH=\t");
    Serial.println(mph);
    half_revolutions = 0; // Restart the RPM counter
    lastmillis = millis(); // Uptade lasmillis
    attachInterrupt(0, rpm_fan, FALLING); //enable interrupt
  }
}
// this code will be executed every time the interrupt 0 (pin2) gets low.
void rpm_fan() {
  half_revolutions++;
}

And my code.

Does anyone know of a good Nokia 5110 library that is easy to use? I just want to output the MPH and battery voltage. Thanks!

Isaac96:
Does anyone know of a good Nokia 5110 library that is easy to use?

Better and/or easier than Adafruit's?

OK, thanks! Got the Adafruit PCD8544 library and Adafruit GFX.
Not done very cleanly. Uses the hardware SPI pins. But it should work when my screen gets here.

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
// SCK is LCD serial clock (SCLK) - this is pin 13 on Arduino Uno
// MOSI is LCD DIN - this is pin 11 on an Arduino Uno
// pin 5 - Data/Command select (D/C)
// pin 4 - LCD chip select (CS)
// pin 3 - LCD reset (RST)
Adafruit_PCD8544 display = Adafruit_PCD8544(5, 4, 3);

// read RPM
int half_revolutions = 0;
int rpm = 0;
unsigned long lastmillis = 0;
int mph = 0;
int batteryPin = A0;//analog input for battery-cell 1 of 6
void setup() {
  pinMode(2, INPUT_PULLUP);
  pinMode(batteryPin, INPUT);
  display.begin();
  display.setContrast(50);
  Serial.begin(9600);
  attachInterrupt(0, rpm_fan, FALLING);
}
void loop() {
  if (millis() - lastmillis == 1000) { //Uptade every one second, this will be equal to reading frecuency (Hz).
    detachInterrupt(0);//Disable interrupt when calculating
    int raw = analogRead(batteryPin);
    float voltage = (raw * (5.0 / 1024)) * 6;
    rpm = half_revolutions * 60; // Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use half_revolutions * 30.
    mph = rpm * 0.07651;
    Serial.print("RPM =\t"); //print the word "RPM" and tab.
    Serial.print(rpm); // print the rpm value.
    Serial.print("\t Hz=\t"); //print the word "Hz".
    Serial.print(half_revolutions); //print revolutions per second or Hz.
    Serial.print("\t  MPH=\t");
    Serial.print(mph);
    Serial.print("\t VOLTS=\t");
    Serial.println(voltage);
    display.setTextSize(1);
    display.setTextColor(BLACK);
    display.setCursor(0,0);
    display.print("MPH: ");
    display.println(mph);
    display.print("Battery level:");
    display.println(voltage);

    half_revolutions = 0; // Restart the RPM counter
    lastmillis = millis(); // Uptade lasmillis
    attachInterrupt(0, rpm_fan, FALLING); //enable interrupt
  }
}
// this code will be executed every time the interrupt 0 (pin2) gets low.
void rpm_fan() {
  half_revolutions++;
}