Reading ABS Wheel Speed Sensors with Arduino
I am frequently asked how I got an Arduino to read Nissan ABS wheel speed sensors on a Youtube video I posted long ago. The code that was running in that video is thousands of lines long and has a lot going on so I have cut it to just include what I have running the wheel speed sensors.
The basics of reading the wheel speed sensors is using the interrupt ability to read each peak as the sensor passes by the reluctor wheel on the axle or differential. The interrupt is always on waiting for a signal, when it sees a rising signal this code adds to the count. Increase the count as it reads each rise and then divide by the time while accounting for the number of teeth per revolution.
Nissan wheel speed sensors are variable reluctance sensors that output an alternating current signal, the Arduino cannot accept that signal. In order for the Arduino to read this signal you must put the signal through a conditioner that converts the signal to square wave 5V DC. This was done using a MAX9926 chip set that is used in automotive applications for wheel speed as well as cam and crank sensors.
In the video this is running on an Arduino Mega 2560 clone, it has enough interrupt pins available to read all 4 wheel speed sensors. A single MAX9926 chip can condition two sensor signals.
The following code probably isn’t working since I cut it from thousands of lines of other code but should give anyone the idea of what is needed to read variable reluctance ABS speed sensors. I’m not a programmer by trade so I’m sure this looks messy.
//digital pin 2 – right rear wheel speed sensor input, this is interrupt number 0
//digital pin 3 – left rear wheel speed sensor input, this is interrupt number 1
//digital pin 18 – front left wheel speed sensor input, this is interrupt number 5
//digital pin 19 – front right wheel speed sensor input, this is interrupt number 4#include <Arduino.h>
//***********************wheel speed sensors****************************
volatile byte RearRightInterruptPin = 0; //set interrupt Pin for right rear wheel speed sensor (this is the interrupt pin not the digital pin, pin 2 on board!!!)
volatile byte RearLeftInterruptPin = 1; //set interrupt Pin for left rear wheel speed sensor (pin 3 on board)
volatile byte FrontRightInterruptPin = 4; //set interrupt Pin for right frong wheel speed sensor (pin 19 on board)
volatile byte FrontLeftInterruptPin = 5; //set interrupt Pin for Left front wheel speed sensor (pin 18 on the board)
int RearRightInterruptCount = 0;
int RearLeftInterruptCount = 0;
int FrontRightInterruptCount = 0;
int FrontLeftInterruptCount = 0;
long previousWheelMillis = millis();
long currentWheelMillis = 0;
int wheelSampleTime = 30;
float RRwheelRPM, RLwheelRPM, FRwheelRPM, FLwheelRPM;
int RearWheelAverage, FrontWheelAverage;
int frontWheelTeeth = 46;
int rearWheelTeeth = 46;
float frontWheelDiameter = 25.5;
float rearWheelDiameter = 26;
float frontToRearOffset = 1.00; //compensation for different size front to rear tires. need to set in the “calibrate wheel sensor” menu then write to EEPROM!void setup() {
pinMode(2, INPUT); //set pin 2 as an input to be used for interrupt
pinMode(3, INPUT); //set pin 3 as an input to be used for interrupt
pinMode(19, INPUT); //set pin 19 as an input to be used for interrupt
pinMode(18, INPUT); //set pin 18 as an input to be used for interruptattachInterrupt(RearRightInterruptPin, RearRightInt, RISING); //setup interrupt for wheel speed sensor, pin is the interrupt pin number not the board pin number
attachInterrupt(RearLeftInterruptPin, RearLeftInt, RISING);
attachInterrupt(FrontRightInterruptPin, FrontRightInt, RISING);
attachInterrupt(FrontLeftInterruptPin, FrontLeftInt, RISING);}
void loop() {
WheelSpeeds();}
//************************************Wheel speed calculations**********************
void WheelSpeeds()
{
currentWheelMillis = millis();
if ((currentWheelMillis – previousWheelMillis) > wheelSampleTime)
{
RRwheelRPM = ((60000/wheelSampleTime)*(RearRightInterruptCount / 46.0));
RLwheelRPM = ((60000/wheelSampleTime)*(RearLeftInterruptCount / 46.0));
FRwheelRPM = ((60000/wheelSampleTime)*(FrontRightInterruptCount / 46.0));
FLwheelRPM = ((60000/wheelSampleTime)*(FrontLeftInterruptCount / 46.0));RearWheelAverage = frontToRearOffset*((RearRightInterruptCount + RearLeftInterruptCount)/2);
FrontWheelAverage = (FrontRightInterruptCount + FrontLeftInterruptCount)/2;previousWheelMillis = millis();
RearRightInterruptCount = 0;
RearLeftInterruptCount = 0;
FrontRightInterruptCount = 0;
FrontLeftInterruptCount = 0;
}
}//**************Right Rear wheel speed sensor interrupt********************
void RearRightInt()
{
RearRightInterruptCount++;
}
//**************Left Rear wheel speed sensor interrupt*********************
void RearLeftInt()
{
RearLeftInterruptCount++;
}
//**************Right Front wheel speed sensor interrupt********************
void FrontRightInt()
{
FrontRightInterruptCount++;
}
//**************Left Front wheel speed sensor interrupt*********************
void FrontLeftInt()
{
FrontLeftInterruptCount++;
}