Introduction: How to Make a Wheel Speed Detector by Using a Light Sensor.

About: Makeblock was founded in 2012 as the world's first open-source robot and programing platform. With more than 400 mechanical components, electronic modules, and software tools, we are determined to bring meanin…

How this work?

As we know the light reflection effects are different in objects. Some bright stuff (white paper, foil, and aluminum stuff) have much better reflection rate than a dark black rubber tire. Therefore, in same condition, if we use a light sensor to test the light reflection value on a foil and a rubber tire, the output value should be obviously different.

So, if we put a piece of foil on a running rubber tier and put the light sensor on top of it, whenever the foil pass the light sensor the light value should be higher than the value was on the rubber tier. We can tell the speed of the running wheel if we know the time between the foil passing through the light sensor.

Sincere there are a lot of light distraction in a public environment, we might need an LED light to increase the light reflection difference and use algorithm to filter out the distraction. The MakeblockMe-LightSensor is a perfect electronic module for this project. It has both LED light and light sensor on board. The following video shows you my final result which is very great!

If you have any suggestion about this project, please visit forum and discuss with us.


You may apply this speed detector to your car! You should try it!

This small project is very straight forward. If you already have somewhere to place the Me-Lightsensor around your wheel and a Me-Baseboard, you can get this Wheel speed detector done immediately!

Step 1: All the Parts I Was Using in This Project.

I was using these parts to build my wheel. Makeblock provide a lot of mechanical and electrical parts that I need for projects stuff.

Step 2: Makeblock Me-LightSensor Testing.

This is the Me-LightSensor.

First I used the Makeblock Me-LightSensor example code to test the difference between tire and the foil.
The light value on a tire is shown on the second picture. I found that the value is varying from 70 to 160.
The light value on the foil is shown on the third picture and I found the value is varying from 200 to 400.

This is hard to tell the different by just looking at the number on the serial monitor.

Next step I will show you how to get a graphic report when reading these light value.

Step 3: Graphic Result of These Light Values.

As you can see in the picture, this window is "Serial Charts".The link to Serial Charts is:
https://code.google.com/p/serialchart/downloads/detail?name=SerialChartInstall.exe

Remember, upload your code first before start reading the data in Serial Charts.

Processes:
First, I uploaded my code to the Me-Baseboard and I used the software "Serial Charts" to read the light sensor value. Since there are a lot of noise and the raw data is not very stable, I used Laplace of Gaussian array [-1,4,-1] to do the second derivative of the light data. As you can see on the second picture the spike is much better than the raw light data. It is very sharp and big value. The light value on foil is easy to distinguish from the light value on the tire. Then, I used a filter to get rid of the unstable value below certain reference. All these algorithms are shown in my code.

In here, I am assuming that you understand how to upload code to Me-Baseboard and install libraries stuff. If you don't, no worry. This is the link that will get you there: http://wiki.makeblock.cc/index.php/Makeblock_Robot_Starter_Kit#Programming

Step 4: Uploading Your Code and Get It Work!

General Idea of Speed detection:
The spike on the second picture illustrated the reflection on the shiny paper in each rotation period. I counted the time between these spikes and get the rotation speed of the wheel.

On the third picture, you can see the speed of your wheel in serial monitor in Arduino software.

If you got a Digital Tube, go to the next page and copy that one.

/*************************************************************************
* File Name : Speed Detector.
* Author : Yuwei
* Updated : Yuwei
* Date : 3/13/2014
* Description : I am using a Makeblock Me-LightSensor to make a wheel speed detector.
You can connect this Me-LightSensor to the PORT_3,PORT_6,PORT_7,PORT_8 of Me-BaseBoard.
* Copyright (C) 2013 Maker Works Technology Co., Ltd. All right reserved.
* http://www.makeblock.cc/
**************************************************************************/

#include
#include
#include
#include

MeLightSensor lightSensor(PORT_6);
MeDCMotor motor1(M1);

uint8_t motorSpeed = 100;

int value = 0; // a variable for the lightSensor's value
int count = 0;
int buff[3];
int sum = 0;
int omega;
static int matrix[3] = {-1,4,-1};

void setup()
{
// initialize serial communications at 9600 bps
Serial.begin(9600);
lightSensor.lightOn();
}
long time0=0;
void loop()
{
value = lightSensor.read();
motor1.run(motorSpeed);
// read the lightSensor value:
buff[0] = buff[1];
buff[1] = buff[2];
buff[2] = value;
sum = matrix[0]*buff[0] +matrix[1]*buff[1]+matrix[2]*buff[2];
// Serial.println(sum); //uncomment this line and comment the next 15 lines if you want to see the data in Serial Charts
if(sum >750)
{
//count++;
long t=millis();
long deltaT=t-time0;
if(deltaT>100)
{
omega = 360000/deltaT;
//You can use Printf fuction if you add the "printf" library to Print Class.
//more details on http://playground.arduino.cc/Main/Printf#.UyE3NxS...
Serial.print(omega);
Serial.println("rad/s");
}
time0=t;
}
delay(2);

}

more

Step 5: Me-Nixie Tube Display.

/*************************************************************************
* File Name : Speed Detector.
* Author : Yuwei
* Updated : Yuwei
* Date : 3/13/2014
* Description : I am using a Makeblock Me-LightSensor to make a wheel speed detector.
You can connect this Me-LightSensor to the PORT_3,PORT_6,PORT_7,PORT_8 of Me-BaseBoard.
* Copyright (C) 2013 Maker Works Technology Co., Ltd. All right reserved.
* http://www.makeblock.cc/
**************************************************************************/

#include

#include

#include

#include

#include

#include

#include

#include "TM1637.h"
#define ON 1
#define OFF 0

int8_t TimeDisp[] = {0x00,0x00,0x00,0x00};
unsigned char ClockPoint = 1;
unsigned char Update;
unsigned char microsecond_10 = 0;
unsigned char second;
unsigned char _microsecond_10 = 0;
unsigned char _second;
unsigned int eepromaddr;
boolean Flag_ReadTime;

#define CLK A3//pins definitions for TM1637 and can be changed to other ports
#define DIO A2 //Digital tude is connected to port 7.
TM1637 tm1637(CLK,DIO);
MeLightSensor lightSensor(PORT_6);
MeDCMotor motor1(M1);

uint8_t motorSpeed = 100;

int value = 0; // a variable for the lightSensor's value
int count = 0;
int buff[3];
int sum = 0;
int omega;
static int matrix[3] = {-1,4,-1};

void setup()
{
// initialize serial communications at 9600 bps
Serial.begin(9600);
tm1637.set(5);//BRIGHT_TYPICAL = 2,BRIGHT_DARKEST = 0,BRIGHTEST = 7;
tm1637.init();
Timer1.initialize(10000);//timing for 10ms
Timer1.attachInterrupt(TimingISR);//declare the interrupt serve routine:TimingISR
lightSensor.lightOn();
}
long time0=0;
void loop()
{
value = lightSensor.read();
motor1.run(motorSpeed);
// read the lightSensor value:
buff[0] = buff[1];
buff[1] = buff[2];
buff[2] = value;
sum = matrix[0]*buff[0] +matrix[1]*buff[1]+matrix[2]*buff[2];
// Serial.println(sum); //uncomment this line and comment the next 15 lines if you want to see the data in Serial Charts
if(sum >750)
{
//count++;
long t=millis();
long deltaT=t-time0;
if(deltaT>100)
{
omega = 360000/deltaT;
//You can use Printf fuction if you add the "printf" library to Print Class.
//more details on http://playground.arduino.cc/Main/Printf#.UyE3NxS...
if(Update == ON)
{
TimeUpdate(omega);
tm1637.display(TimeDisp);
}
Serial.print(omega);
Serial.println("rad/s");
}
time0=t;
}
delay(2);
}

//************************************************
void TimingISR()
{
microsecond_10 ++;
Update = ON;
if(microsecond_10 == 100){
second ++;
if(second == 60)
{
second = 0;
}
microsecond_10 = 0;
}
ClockPoint = (~ClockPoint) & 0x01;
if(Flag_ReadTime == 0)
{
_microsecond_10 = microsecond_10;
_second = second;
}
}
void TimeUpdate(int value)
{
if(ClockPoint)tm1637.point(POINT_ON);//POINT_ON = 1,POINT_OFF = 0;
else tm1637.point(POINT_ON);

TimeDisp[0] = value/1000;
TimeDisp[1] = value/100;
TimeDisp[2] = value/10 - TimeDisp[1]*10;
TimeDisp[3] = value % 10;
Update = OFF;
}


That's all. Start build your own one. If you have any opinion about it, you can just post it here or visit our forum to discuss with us.

more...