Driving Real Gauges

Get yourself a set of modern instruments off something decent where the instruments are driven by CAN-bus, BMW's, Mazda's, probably Fords all have them. You'll have to research yourself which ones work but I'll show you how to use a set of Mazda RX-8 clocks.

Get yourself an Arduino (if you haven't already got one).
Get yourself a CAN shield (either from sparkfun or the cheaper diy one from http://www.fazjaxton.net/products/canshield/ )
If you haven't already got 12v then get yourself an old PC power supply and hack it to provide your 12v

Wire up the clocks to 12v (note that in the case of the RX-8 there are two power feeds, one permanent, one switched with the ign, you may want to stick a switch on the 'switched' feed).

Now if you have the connectors then just wire up CAN-L and CAN-H to the correct pins, if you don't then you may as well take the back off the clocks and solder direct to the connector pins as its nearly impossible to get hold of the connectors.

Now you just need to program the Arduino, exactly how you do it depends on how you want your PC to send it data but its very easy to send speed and rpm.

The CAN-bus id's in the case of the RX-8 (and likely Mazda6 / MX-5)

ID 300 is turn off Steering Warning Light, minimum 0.5 sec timing.
ID 212 is abs, dsc off, traction control warning and brake warning, minimum 0.5 sec timing.
ID 420 is temp, oil pressure gauge, coolent level, battery (alternator), oil warning and check engine light, minimum 5 second timing.
ID 201 is Speed (Max 300.00 Km/h, 186mph 9C 40 and RPM (Max 16382 FF FE, although scale goes non-linear after 10k), minimum 0.5 sec timing.

Forgot to mention, the Km/h and MPH display is switched purely on the button, the feed however is in Km/h, so send the speed in Km/h and use the button on the front to swap between MPH and Km/h depending on your country/preferences.
Trip meter is *not* driven off the speedo but triggered by another CAN id.

Here we go, this is arduino code for the RX-8 with the fazjaxton CAN shield and will 'rev' the tacho to 5500 and set speed to 100mph adjust as appropriate and enjoy.

All you would need to do is set some way to get the speed from the PC and you are away.

  1. include <SPI.h>
  2. include <CAN.h>

const int message_id_201 = 0x201;
const int message_id_212 = 0x212;
const int message_id_231 = 0x231;
const int message_id_420 = 0x420;
int message_id ;

byte message_to_send;

int id;
byte b;
int i;
char s8;
byte my_data8;
byte BitMap8;
int RPM;
int mphspeed;
int kmhspeed;

void setup()
CAN.begin ();


void loop()

/* Convert mph to kmh as all internal speeds are kmh*/
kmhspeed=mphspeed * 160.9344;


/* Turn off steering Warning */

if(steering == 0 ) {
CAN.setMessageID (message_id_300);
CAN.sendByte (0);

/* Speedo / tacho */

CAN.setMessageID (message_id_201);
my_data0 = (RPM * 4) / 256; // rpm
my_data1 = (RPM * 4) % 256; // rpm
my_data2 = 0xFF; // Unknown, 0xFF from 'live'.
my_data3 = 0xFF; // Unknown, 0xFF from 'live'.
my_data4 = (kmhspeed+10000) / 256; //speed
my_data5 = (kmhspeed+10000) % 256; //speed
my_data6 = 0x00; // Unknown possible accelerator pedel if Madox is correc
my_data7 = 0x00; //Unknown

/* Warning Lights */

CAN.setMessageID (message_id_212);
my_data0 = 0xFE; //Unknown
my_data1 = 0xFE; //Unknown
my_data2 = 0xFE; //Unknown
my_data3 = 0x34; //DSC OFF in combo with byte 5 Live data only seen 0x34
my_data4 = 0x00; // B01000000; // Brake warning B00001000; //ABS warning
my_data5 = 0x40; // TCS in combo with byte 3
my_data6 = 0x00; // Unknown
my_data7 = 0x00; // Unused

/* Other gauges / warning lights */

CAN.setMessageID (message_id_420);
my_data0 = 0x98 ; //temp gauge //~170 is red, ~165 last bar, 152 centre, 90 first bar, 92 second bar
my_data1 = 0x00; // something to do with trip meter 0x10, 0x11, 0x17 increments by 0.1 miles
my_data2 = 0x00; // unknown
my_data3 = 0x00; //unknown
my_data4 = 0x01; //Oil Pressure (not really a gauge)
my_data5 = 0x00; //check engine light
my_data6 = 0x00; //Coolant, oil and battery
my_data7 = 0x00; //unused

  • /

/* Cruise Control Light */

CAN.setMessageID (message_id_650);
my_data0 = 0xFF; // cruise control light 0x80 is yellow, 0xFF is green

  • /