Arduino
Main Project
Oscar
Macdonald
The Project: Speedometer, or the
Arduinospeedo
A magnet is attached to a wheel on the
outermost edge or as close as possible. It does not matter if the south or
north side of the magnet is showing. A linear hall sensor is placed just above
the surface of the wheel, allowing no more than 2cm of space between the sensor
and the magnet while still allowing the wheel to spin freely.
As the wheel spins, the Arduino detects
when the magnet passes the sensor and stores the number of revolutions in an
array of ten separate counts. Every second, the Arduino calculates the average revolutions
per minute (rpm), and when the readings are stable (roughly once every 11
seconds) it converts the rpm to kilometres per hour (km/h) by multiplying the
rpm by the circumference of the wheel, which is hard coded into the Arduino.
The km/h is presented on a liquid crystal display (LCD) in a comfortable,
easy-to-read style.
Fritzing Diagram:
C Code:
/* Linear Hall Sensor and Speedometer
*
Takes the circumference of a wheel and revolutions per minute
*
using a magnet and a linear hall sensor to calculate the speed
* of
the wheel in kilometers per hour and output result to an LCD.
*
*
Assistance from Elimelec Lopez: http://playground.arduino.cc/Main/ReadingRPM
*
and
http://elimelecsarduinoprojects.blogspot.co.nz/2013/06/measure-rpms-arduino.html
*
*
http://www.ehow.com/how_7448165_calculate-wheel-speed.html
*
*
Oscar Macdonald
*
11/06/16
*/
#include <LiquidCrystal.h> //library to use LCD
LiquidCrystal lcd(12,11,5,4,3,2); //pins
attached to LCD
const int LHSP = 0; //Linear Hall Sensor
Pin
const int PP = 1; //Potentiometer Pin
const int MP = 10; //Motor Pin
const double circumference = 1.41; //circumference of the wheel in meters (2πr)
double rpm = 0; //revolutions per minute
int revCount = 0; //count of revolutions
int index = 0; //
const int numreadings = 10; //size of
readings array
int readings[numreadings]; //array of revCounts, used to find average
unsigned long lastmillis = 0; //used to
calculate the frequency of readings
unsigned long total;
double kmh = 0; //Kilometers per hour
bool pass;
void setup() {
lcd.begin(16, 2);
lcd.clear();
lcd.print("Km/h"); //Kilometers per hour
}
void loop() {
if(millis() - lastmillis >= 1000)//Update every one second, this will
be equal to reading frequency (Hz).
{
total = 0;
readings[index] = revCount * 60; // Convert frecuency to RPM (the 60
converts the readings from seconds to minutes)
for(int i = 0; i < readings.length; i++)
{
total = total + readings[i];
}
rpm = total / numreadings; //this
calculates the average rpm every second
revCount = 0; // Restart the RPM counter
index++;
if(index >= numreadings)
{
index=0;
}
if (millis() > 11000) // wait
for RPMs average to get stable
{
kmh = (circumference * rpm) / 60; //calculate the speed in kilometers
per hour
lcd.clear();
lcd.print("Km/h"); //Kilometers per hour
lcd.setCursor(0,1);
lcd.print(kmh);
}
lastmillis = millis(); // Update lasmillis
}
else
{
int magnet = analogRead(LHSP); //reads the hall sensor
/*
* This segment of code detects when the magnet is in range aka 1
rotation.
* When the magnet is in range, a "flag" is raised and the
revCount increases.
* While the flag is up and the magnet is in range, the revCount can't
increase
* When the magnet passes out of range, the flag is lowered.
* This allows for the revCount to increase only once every rotation.
*/
if (!pass && (magnet <= 400 || magnet >= 650))
{
pass = true;
revCount++;
}
if(pass && (magnet >= 500 && magnet <= 570))
{
pass = false;
}
}
}
Reflection:
My first project was originally going to be
a Levitron: a magnet which is suspended using an electromagnet and a linear
hall sensor to detect and adjust the magnetic field. However this project was
too complex to achieve on time, and after several setbacks I decided to change
to the speedometer. For example, I couldn’t get the electromagnet to work at
all, and there was almost no reliable material about Arduino Levitrons online. I
had the linear hall sensor and magnet from the Levitron project already,
setting up the circuitry was easy (especially compared to the Levitron
circuitry) and all that was required to create the speedometer was the code.
In
the LED project I used the serial output and the LEDs themselves to display the
output, but this time I thought it would be more appropriate to use the LCD.
LCDs are often used today to display speedometers in cars.
Lots of other people have made speedometers
from Arduinos, including Elimelec Lopez (1) who used a state hall sensor
instead of a linear hall sensor. This allowed him to use interrupts whenever
the hall sensor went from HIGH output to LOW output. In my code I had to design
a “flag” method that detected whenever the magnet came in range, raise the flag
to prevent multiple readings of the same revolution, increment the revolution
count, and then lower the flag once the magnet had passed out of range.
In some
ways I prefer my method, because it does not require the sensor or the magnet
to face a certain direction: with some state hall sensors, they might only
trigger when the north or south side of the magnet comes in range, but not
either. It was difficult adjusting the threshold levels correctly, and getting
the logic of the IF statements correct took several attempts. At one point,
before the second video, I was using the radius of the wheel in my calculation
instead of the circumference! But after I fixed the problem then the
speedometer began working correctly. In one of my previous attempts I tried to
include a DC motor that spun a wheel, so I could measure its speed. If I wanted
to show the speed of the motor changing, I could attach a potentiometer to the
Arduino and use it to control the motors speed. The Arduino isn’t capable of
supporting both the LCD, the potentiometer, the motor and the sensor
simultaneously however, so I decided that any manual wheel would do.
Speedometers are used all the time in
vehicles. The advantage of this project is that it can be applied to anything
that travels on wheels, including bicycles, remote-controlled cars and power
chairs. It can be used in other aspects of engineering such as production
lines, proximity sensors, magnetic card readers and many more. In future
applications I might include this in a powered longboard design, so that I can
monitor how fast the longboard is travelling via mobile phone.
References:

No comments:
Post a Comment