Connecting real car cluster with pc games (X-sim)

This is a project in progress but someone asked for the code
so here is what i have made so far

*yes i am a bad driver

it has an variable frequency output for driving the speedometer and two PWM's for the fuel and temp "slow" meters

i am using the freeware programs from X-simulator.de to export the data from the game (LFS) to the Arduino using serial communication

UPDATING...........

Here is the code:

int rpm;
int i;
int leds;
int Speed;
int fuel;
int ebrake;
int brake;
int fuelled;
int Turbo;
int gear;
int previous_potion = 0;
int rotate;

char kind_of_data;

void setup(){

Serial.begin(115200);

pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(5, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(10, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);

}

void loop()
{
//****************************** READ DATA FROM SERIAL ******************************
while(Serial.available() > 0)
{

kind_of_data = Serial.read();
if (kind_of_data == 'R' ) Read_Rpm();
if (kind_of_data == 'S' ) Read_Speed();
if (kind_of_data == 'F' ) Read_Fuel();
if (kind_of_data == 'E' ) Read_EBrake();
if (kind_of_data == 'B' ) Read_Brake();

}

//****************************** READ DATA FROM SERIAL END ******************************
}

void Read_Rpm(){

delay(1);
int Rpm100 = Serial.read()- '0';
delay(1);
int Rpm10 = Serial.read()- '0';
delay(1);
int Rpm1 = Serial.read()- '0';

int rpm = 100Rpm100 + 10Rpm10 + Rpm1;
analogWrite(7,map(rpm,127,255,75,210));
if (rpm<135) digitalWrite(13,HIGH);
if (rpm>135) digitalWrite(13,LOW);
if (rpm>245) digitalWrite(8,HIGH);
if (rpm<245) digitalWrite(8,LOW);

}

void Read_Speed(){

delay(1);
int Speed100 = Serial.read()- '0';
delay(1);
int Speed10 = Serial.read()- '0';
delay(1);
int Speed1 = Serial.read()- '0';

Speed = 100Speed100 + 10Speed10 + Speed1;

tone(12, map(Speed,127,255,0,950));

}

void Read_Fuel(){
delay(1);
int Fuel100 = Serial.read()- '0';
delay(1);
int Fuel10 = Serial.read()- '0';
delay(1);
int Fuel1 = Serial.read()- '0';

fuel = 100Fuel100 + 10Fuel10 + Fuel1;

analogWrite(2,map(fuel,127,255,53,183));
if (fuel<135) digitalWrite(10,HIGH);
if (fuel>135) digitalWrite(10,LOW);

}

void Read_EBrake(){
delay(1);
int EBrake100 = Serial.read()- '0';
delay(1);
int EBrake10 = Serial.read()- '0';
delay(1);
int EBrake1 = Serial.read()- '0';

ebrake = 100EBrake100 + 10EBrake10 + EBrake1;

if (ebrake>200) digitalWrite(3,HIGH);
if (ebrake<200) digitalWrite(3,LOW);

}
void Read_Brake(){
delay(1);
int Brake100 = Serial.read()- '0';
delay(1);
int Brake10 = Serial.read()- '0';
delay(1);
int Brake1 = Serial.read()- '0';

brake = 100Brake100 + 10Brake10 + Brake1;

if (brake>200) digitalWrite(5,HIGH);
if (brake<200) digitalWrite(5,LOW);

}

and some photos from the setup of the X-sim

you might need to remove the diode ( its not needed ) because your output will be on 4.3V and not on 5

and a custom made cluster
that i made with the mega that i had at this time

#include <Stepper.h>
#include <Servo.h>

Stepper stepper(48, 24, 23, 22, 25);
Servo fuelservo;
Servo turboservo;

int rpm;
int i;
int leds;
int Speed;
int fuel;
int fuelled;
int Turbo;
int gear;
int previous_potion = 0;
int rotate;

char kind_of_data;

void setup(){

Serial.begin(9600);

stepper.setSpeed(300);
fuelservo.attach(2);
turboservo.attach(3);

pinMode(3, OUTPUT);
pinMode(8, OUTPUT);

//****************************** Set LCD ******************************
Serial.print(0xFE, BYTE);
Serial.print("B");
Serial.print(9); //

Serial.print(0xFE, BYTE);
Serial.print("Z");

Serial.print(0xFE, BYTE);
Serial.print("L");
Serial.print("01");
Serial.print("01");
Serial.print("Speed :");

Serial.print(0xFE, BYTE);
Serial.print("L");
Serial.print("02");
Serial.print("01");
Serial.print("Gear :");

}

void loop()
{
//****************************** READ DATA FROM SERIAL ******************************
while(Serial.available() > 0)
{

kind_of_data = Serial.read();
if (kind_of_data == 'R' ) Read_Rpm();
if (kind_of_data == 'S' ) Read_Speed();
//if (kind_of_data == 'F' ) Read_Fuel();
//if (kind_of_data == 'T' ) Read_Turbo();
if (kind_of_data == 'G' ) Read_Gear();

}

//****************************** READ DATA FROM SERIAL END ******************************
}

void Read_Rpm(){

delay(2);
int Rpm100 = Serial.read()- '0';
delay(2);
int Rpm10 = Serial.read()- '0';
delay(2);
int Rpm1 = Serial.read()- '0';

int rpm = 100Rpm100 + 10Rpm10 + Rpm1;

rpm = map(rpm,127,255,0,45);
if (rpm >=42) digitalWrite(3,HIGH);
rotate = rpm - previous_potion;
stepper.step(rotate);
previous_potion = rpm;
if (rpm <42) digitalWrite(3,LOW);

for(i=38; i<=leds ; i++)digitalWrite(i,LOW);
for(leds=38; leds<=(rpm+7); leds++)digitalWrite(leds,HIGH);

}

void Read_Speed(){

delay(2);
int Speed100 = Serial.read()- '0';
delay(2);
int Speed10 = Serial.read()- '0';
delay(2);
int Speed1 = Serial.read()- '0';

Speed = 100Speed100 + 10Speed10 + Speed1;

Speed = map(Speed,127,255,0,200);
tone(12, map(Speed,0,200,0,950));

Serial.print(0xFE, BYTE);
Serial.print("L");
Serial.print("01");
Serial.print("09");
Serial.print(Speed);
Serial.print(" ");
}

void Read_Fuel(){
delay(2);
int Fuel100 = Serial.read()- '0';
delay(2);
int Fuel10 = Serial.read()- '0';
delay(2);
int Fuel1 = Serial.read()- '0';

fuel = 100Fuel100 + 10Fuel10 + Fuel1;

fuelled = map(fuel,127,255,0,100);
fuel = map(fuel,127,255,60,130);

fuelservo.write(fuel);

if (fuelled <= 4)digitalWrite(51,HIGH);
if (fuelled > 4)digitalWrite(51,LOW);
}

void Read_Turbo(){

delay(2);
int turbo100 = Serial.read()- '0';
delay(2);
int turbo10 = Serial.read()- '0';
delay(2);
int turbo1 = Serial.read()- '0';

Turbo = 100turbo100 + 10turbo10 + turbo1;

Turbo = map(Turbo,127,255,10,100);
turboservo.write(Turbo);
}

void Read_Gear(){
delay(2);
int Gear100 = Serial.read()- '0';
delay(2);
int Gear10 = Serial.read()- '0';
delay(2);
int Gear1 = Serial.read()- '0';

gear = 100* Gear100 + 10*Gear10 + Gear1;

gear = map(gear,127,255,0,8);

Serial.print(0xFE, BYTE);
Serial.print("L");
Serial.print("02");
Serial.print("09");
if ( (gear != 0) && (gear != 1) ) Serial.print(gear-1);
if ( gear == 0 ) Serial.print("R");
if ( gear == 1 ) Serial.print("N");

digitalWrite(30,LOW);
digitalWrite(31,LOW);
digitalWrite(37,LOW);
digitalWrite(35,LOW);
digitalWrite(34,LOW);
digitalWrite(33,LOW);
digitalWrite(32,LOW);

if ( gear == 0 ){
digitalWrite(35,HIGH);
digitalWrite(37,HIGH);
}

if ( gear == 1 ){
digitalWrite(30,HIGH);
digitalWrite(35,HIGH);
digitalWrite(37,HIGH);
}

if ( gear == 2 ){
digitalWrite(30,HIGH);
digitalWrite(31,HIGH);
}

if ( gear == 3 ){
digitalWrite(33,HIGH);
digitalWrite(31,HIGH);
digitalWrite(37,HIGH);
digitalWrite(35,HIGH);
digitalWrite(34,HIGH);
}

if ( gear == 4 ){
digitalWrite(30,HIGH);
digitalWrite(31,HIGH);
digitalWrite(37,HIGH);
digitalWrite(33,HIGH);
digitalWrite(34,HIGH);
}

if ( gear == 5 ){
digitalWrite(32,HIGH);
digitalWrite(37,HIGH);
digitalWrite(30,HIGH);
digitalWrite(31,HIGH);
}

if ( gear == 6 ){
digitalWrite(33,HIGH);
digitalWrite(32,HIGH);
digitalWrite(37,HIGH);
digitalWrite(30,HIGH);
digitalWrite(34,HIGH);
}

if ( gear == 7 ){
digitalWrite(35,HIGH);
digitalWrite(30,HIGH);
digitalWrite(34,HIGH);
digitalWrite(32,HIGH);
digitalWrite(37,HIGH);
digitalWrite(33,HIGH);
}

}

CooL

I'm retro-fitting Peugeot 407 clocks into a Mk2 Scirocco... this will be a BIG help, thankyou!

Although I'm not quite sure why you didn't just use clocks with a rev counter on them?

If you're in the UK, gimme a shout... I have a set of Golf Mk1 clocks (with rev counter) that you can have.

because i am not in uk

i bought the cluster for 50euros

and i am not a gamer

i am trying now to controll directly the 6 aircores of a e36 cluster that a friend gave me

the E36 cluster is a nice unit :slight_smile:

I think this is a really cleaver project. I remember seeing a couple of YouTube videos many months ago showing real car clusters interfaced with video games. Are there many hobbyist that do this, or was I probably just seeing your videos herctrap?

no there are not mine

i am working with arduino ( and uC ) for 3 months only

there were a company that had make a product that controlled the whole instruments of the car

i think that is not so hard to make it with 10 arduinos maybe

(becase serial reads needs delays *for me at least)

but there are no funding

Hi there,

I was working on something quite similar. This thread helped way far...Your work is great, man!

But now my knowledge gets to its borders.
I declared everything in the Profiler. In Math all data is showed up but I get an error when I start the Profiler. Error message: error opening comport COM18. Why is COM18 assigned? It was automatically chosen.

How can I make this work now?

Regards, Tomasz

This is interesting, what you've done.
I am planning to do something similar with Flightgear (flight simulator), not a full cockpit but only the essential stuff.

A question, though, about the speedometer. Do you only have to apply a voltage over it to make it respond?
I do not own any speedometer at the moment but if I'll buy one I want to know how to use it.

check the top red button

"add comport to list"


the cosra speedo has a +12V , Gnd and signal input

the signal is a pulse with 50% duty cycle with a varialble frequency from 0 to 900Hz for the corsa cluster

check the tone function

Hello herctrap,

thanks for your tip. I tried it before, changing the port to a number below 10, but it didnt work. but today port 2 worked very good!

Thanks, ill post some vids when everything is online =)

after you press the add comport to list you have to go on the botton to select the port and make the settings for it

allright,

maybe I´ll have today some time to check whether, LfS, X-Sim² and the Arduino are working together.
I´m looking forward to get some electronics stuff like resistors, potentiometers cable, solder etc. so the next step will be wiring it up!

Regards, Tomasz

PS: can someone describe what the following code does?

void Read_Fuel(){
delay(1);
int Fuel100 = Serial.read()- '0';
delay(1);
int Fuel10 = Serial.read()- '0';
delay(1);
int Fuel1 = Serial.read()- '0';

fuel = 100Fuel100 + 10Fuel10 + Fuel1;

analogWrite(2,map(fuel,127,255,53,183));
if (fuel<135) digitalWrite(10,HIGH);
if (fuel>135) digitalWrite(10,LOW);

lfs sends a number from 127-255 for the fuel (0-100)%

now when you call a=Serial.read() it will store on a only one byte for example if the output is 245 the it will send first the 2 then the 4 and then the 5

now the Serial.read()- '0'; is used to get the actual number because 0 is 48 on ascii i think
then 1 is 49, 2 is 50 etc

so you are removing each time the 48 to get the true number and 48 is the 0 number or '0'

now you have to use delays bettween the serial reads or else the arduino freezes

then you are calculating the number for example the 245
a=2
b=4
c=5

so
100a =200
10
b=40
1*c=5

and we have the 245 again

then i use the map to move the neddle by using a pwm outuput

hello herctrap,
thanks for the explanation! it was very helpful.
but one question remains: which Arduino do you use? I guess a mega. is the code identical to the code i need for a duemilanove?

regards,
tomasz

if someone could help
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1282037579/

Hi there,

how did you manage to get the lights light up? I got no clue, where to find the lights like full beam or handbrake in the input setup if the profiler.

Regards,
tomasz

there are not comming from the game

but from the controller

so if you are using a keyboard you cant