CAN BUS Gaming Simulator

Controlling a VW CAN BUS dashboard of a Polo 6R with an Arduino and a CAN BUS shield using the Telemetry API of Euro Truck Simulator 2

Similar projects worth following
Ever wanted to play a car/truck simulator with a real dashboard on your PC? Me too! I'm trying to control a VW Polo 6R dashboard via CAN Bus with an Arduino Uno and a Seeed CAN Bus Shield. Inspired by Silas Parker.

[!!!] PLEASE NOTE [!!!]
This project only works with an instrument cluster of a Volkswagen Polo 6R.
I can't give you any help when you try out this project with other instruments from different manufacturers, as every company has their own CAN BUS protocol.

I use this dashboard in combination with a Logitech G27 wheel and coded a program for it. Just come round to my other Hackaday Project:

Click on one of the following Links to navigate through the project page:

All Project LogsAll CAN Codes
Project Page @ Seeed Studios
Silas Parker's Blog
YouTube ChannelYouTube Playlist
Download CenterSources
Supporters and Sponsors

See the project in action:

German demonstration:

VW Speedometer

Source of the circuit board used to connect the instrument cluster to the arduino

Zip Archive - 676.76 kB - 12/19/2017 at 09:13



Newest version of test sketch. For Arduino with Seeed CAN BUS Shield and installed libraries.

ino - 12.51 kB - 12/30/2016 at 15:31



The software used in my latest videos. It simulates an RNS310 from VW and plays online radio stations over the Internet (m3u-Streams and RTMP://) and also plays Windows Media Playlists (WPL file format). You can also visit some webpages (like maps for games) with it. Have fun. This file is a WinRAR-self-extracting archive. Just double-click it and install it. For support, or feedback please PM me.

x-msdownload - 16.04 MB - 04/06/2016 at 21:50


3D-Print Radio-Case.stl

3D-Print Radio-Case (STL 3d-printable Sketch)

- 30.43 MB - 12/24/2015 at 14:30


3D-Print Radio-Case.123dx

3D-Print Radio-Case (Autodesk 123D Design Project File)

- 4.68 MB - 12/24/2015 at 14:30


View all 8 files

View all 7 components

  • Reverse Engineering the Steering Column Switch

    Leon Bataille10/22/2019 at 06:19 1 comment

    As mentioned before in my last project log, I used the long silence to dive deeper in the electronics of the Polo 6R.
    In this project log I want to share some details regarding the Steering Column Switch (or in German “Lenkstockschalter”).
    Its Task is to measure the rotation position of the steering wheel and it provides the switches for wipers, turning signal and light options.
    A while ago I bought an old steering column switch from eBay as well as the case for it. I also bought a key switch for usage as a ignition lock.
    Here’re some photos:

    What I wanted to build was an USB interface which connects to the PC running the simulation game. That way you could control the corresponding functions with the simulation game.
    I used an Arduino micro which can use USB HID profiles, so that it will be recognized as a keyboard by my PC.
    Now my task was to find out the pin assignments for the column switch, which you can find below.

    If you want to build this part of the project as well, here’s the Arduino sketch and the wiring diagram for it.

    VW Polo 6R - Lenkstockschalter - Controller Software
    by Leon Bataille
    Version 1.0
    Last modified: 04.07.2017
    Pin assignments:
    A0: HW  (FSW Wischwasser)
    A1: 53c (HSW)
    A2: (R) (MFA OK/Reset)
    A3: I   (SW Intervallschaltung)
    A4: 1   (SW Wischer-Stufe 1)
    A5: 2   (SW Wischer-Stufe 2)
    D2: SDA - I2C Arduino Communication
    D3: SCL - I2C Arduino Communication
    D4: L   (Blinker links <-)
    D5: R   (Blinker rechts ->)
    D6: 30  (Klemme 30: Lichthupe)
    D7: 56  (Klemme 56: Fernlicht)
    D8: 7   (GRA Reset/+)
    D9: 8   (GRA Set/-)
    D10: 3  (GRA an)
    D12: auf (Trip/MFA+ auf)
    D13: ab  (Trip/MFA+ ab)
    More information on my hackaday project site:
    #include <Wire.h>
    #include <Keyboard.h>
    //Pin Definitions
    int SW_WW = A0;
    int HSW = A1;
    int MFA_OK = A2;
    int SW_INT = A3;
    int SW_lv1 = A4;
    int SW_lv2 = A5;
    int tisch_hoch = 0;
    int tisch_runter = 1;
    int blnk_l = 4;
    int blnk_r = 5;
    int licht_hupe = 6;
    int licht_fern = 7;
    int GRA_plus = 8;
    int GRA_minus = 9;
    int GRA_an = 10;
    int MFA_auf = 11;
    int MFA_ab = 12;
    bool state_GRA = 0;
    bool lastState_SW_WW = 0;
    bool lastState_HSW = 0;
    bool lastState_MFA_OK = 0;
    bool lastState_SW_INT = 0;
    bool lastState_SW_lv1 = 0;
    bool lastState_SW_lv2 = 0;
    bool lastState_blnk_l = 0;
    bool lastState_blnk_r = 0;
    bool lastState_licht_hupe = 0;
    bool lastState_licht_fern = 0;
    bool lastState_GRA_plus = 0;
    bool lastState_GRA_minus = 0;
    bool lastState_GRA_an = 0;
    bool lastState_MFA_auf = 0;
    bool lastState_MFA_ab = 0;
    void setup() {
      // put your setup code here, to run once:
      //-> Alle Eingänge sind mit Pull-Up-Widerständen verbunden
      pinMode(SW_WW, INPUT);
      pinMode(HSW, INPUT);
      pinMode(MFA_OK, INPUT);
      pinMode(SW_INT, INPUT);
      pinMode(SW_lv1, INPUT);
      pinMode(SW_lv2, INPUT);
      pinMode(blnk_l, INPUT);
      pinMode(blnk_r, INPUT);
      pinMode(licht_hupe, INPUT);
      pinMode(licht_fern, INPUT);
      pinMode(GRA_plus, INPUT);
      pinMode(GRA_minus, INPUT);
      pinMode(GRA_an, INPUT);
      pinMode(MFA_auf, INPUT);
      pinMode(MFA_ab, INPUT);
      pinMode(tisch_hoch, OUTPUT);
      pinMode(tisch_runter, OUTPUT);
    void loop() {
      // put your main code here, to run repeatedly:
      if (digitalRead(MFA_OK) == LOW && lastState_MFA_OK == 0) //If the switch is pressed
          lastState_MFA_OK = 1;
      else if (digitalRead(MFA_OK) == HIGH && lastState_MFA_OK == 1) //If the switch is released
          lastState_MFA_OK = 0;
      if (digitalRead(SW_lv1) == LOW && lastState_SW_lv1 == 0) //If the switch is pressed
          lastState_SW_lv1 = 1;
      else if (digitalRead(SW_lv1) == HIGH && lastState_SW_lv1 == 1) //If the switch is released
          lastState_SW_lv1 = 0;
      if (digitalRead(blnk_l) == LOW && lastState_blnk_l == 0) //If the switch is pressed
          lastState_blnk_l = 1;
      else if (digitalRead(blnk_l) == HIGH &&...
    Read more »

  • Back again...

    Leon Bataille10/20/2019 at 12:43 4 comments

    Hi there,

    here're some updates regarding the project after long two years of silence and some explanation.

    So, why isn't there an up-to-date source code available?

    As the project has grown over time, I got some help of very capable people and was able to develop the source code further with them. We squished most of the known bugs like the wrong blinking turning signal or randomly flashing oil indicators and added many new indicators and functions to the project. But the problem is that the source code of the project is open source on this page (which is good of course) but unfortunately I am not allowed anymore to release the source code in its current state due to copyright problems.

    I reverse engineered the dashboard first by myself which is completely fine.

    But later on I got information from other people and specifically these information mustn't be published here.

    So what's the solution to this problem?

    Yeah, that's the point at the moment. I don't know...

    What else did you do in the meantime?

    I changed some essential parts of the project to not only work with the ETS2 game but also with many other simulator and racing games by using another component between my adapter board and the PC.
    I'm using a RevBurner Pro from SymProjects (no sponsoring here). Their software collects through game plugins or APIs the telemetry data from the games and transfers them to the RevBurner. More about this in a future update.

    And now...?

    I will release further project updates regarding the general state of the project, some wiring diagrams, as well as the new parts I'm using for this. But as mentioned before I cannot post any more source code for this project.

    Thanks for your understanding.

  • Circuit Board Source online

    Leon Bataille12/19/2017 at 09:16 0 comments


    I just uploaded the source files for the circuit board which connects the instrument cluster with the CAN-BUS Shield. You can find it in the Download section of this project.

    I hope this clears the questions about connection problems in the comments.

    I wish you all merry christmas and nice holidays!

  • New Version of VWRadio available (v1.2.1)

    Leon Bataille06/12/2017 at 14:55 0 comments

    I've just released a newer version for the VWRadio software.

    I fixed several small bugs. Especially the loop after the first launch without a prior configuration file has been fixed.

    There's now the option to enable a graphic visualization for music playback in the lower left corner.

    You can now also shut down your computer within the program. Therefore you have to go to the settings menu and click on exit. There you're can choose either to exit the program or to completely shut down your PC. I'll show you this feature in a future video. But at the moment it's a surprise for what I implemented it in the software.

  • Building a dashboard desk

    Leon Bataille06/09/2017 at 17:12 1 comment

    Hi there.

    It's been a long time since the last update.
    I'm back with some great news and some exciting plans.

    At the moment I'm building a new desk out of an Polo 6R dashboard. All buttons of the dashboard shall be used as controller in ETS2 and other simulation games.

    Even the Navigation System will display the map of the game (at least that's my goal).

    So here're some pictures of my new sub-project:

  • Creating an automatic Install and Setup Tool

    Leon Bataille05/08/2017 at 11:39 0 comments

    I'm in the process of building an Installation and Setup Tool for those of you, who wanted a detailed instruction on how to set everything up. This software does the job for you!

    I hope to complete this Setup Tool as fast as I can.

    Here's already a screenshot (You can manually choose the packages which you want to install)

  • New Demo-Sketch for Dashboard

    Leon Bataille12/30/2016 at 15:32 3 comments


    Just as promised a few days ago: Here's the new version of the test sketch.

    It contains more CAN BUS functions (such as much more LEDs to switch on or off) and is completely rewritten for a better structure and easier usage.

    These are the LEDs you can manually turn on or off in the sketch

    There's also a new section where you can setup a userdefined setup for testing your dashboard's functions!

    You find the new sketch in the download section of this project,

    or directly here.

    Best regards, and a happy new year!

  • More dashboard functions found

    Leon Bataille12/27/2016 at 21:20 2 comments

    Happy Holidays to all of you!

    The last few days I worked pretty hard on finding new functions of some CAN Commands for the dashboard!

    New functions I found:

    • Battery low warning
    • Fog Light
    • High Beam
    • ABS signal
    • Seat Belt warning
    • Hand brake
    • Low tire pressure warning
    • Offroad mode
    • Diesel particle filter
    • Diesel preheater
    • Water temperature alarm

    I also rewrote the hole demo script with more explanations and comments. The speed needle should also be more accurate (but sadly still not perfect yet)

    I will release the new demo source code in the next few days, so stay tuned.

    And I wish all of you a happy new year!

  • It's been a while

    Leon Bataille07/27/2016 at 11:36 5 comments

    After moving to antother city and my exams there's now time again for hackin'!

    So expect frequent updates from now on.

    I've bought a real dashboard from a VW Polo 6R and I want to build something like a desk out of it. So you can play great racing games and work on it.

    I'm really excited about the next months and hope to get everything working :D

  • Dashboard Photoshoot

    Leon Bataille04/18/2016 at 11:45 0 comments

    Hello Tech-Enthusiasts!

    I just updated the thumbnails for this project. Therefore I got help in a photo studio to take some better profile pics. I hope you enjoy them!

View all 50 project logs

  • 1
    Step 1

    Known CAN Codes so far:

    For CAN Codes please visit the Sources-Page.

  • 2
    Step 2

    Instruction Video:

  • 3
    Step 3

    Arduino Source Code:

    //Volkswagen CAN BUS Gaming
    //Test Sketch v3.0
    //(C) by Leon Bataille 2015-2016
    //Hackaday Project Page:
    //Sketch information #DO NOT REMOVE!
    String game = "VW Static v3.0";
    String vendor = "Leon Bataille";
    //END Sketch information
    //For individual setup scroll down to the section MAIN CONFIGURATION
    #include <mcp_can.h>            //CAN Bus Shield Compatibility Library
    #include <SPI.h>                //CAN Bus Shield SPI Pin Library
    #include <Servo.h>              //Library for Controlling Servos
    #include <Wire.h>               //Extension Library for measuring current
    #include <LiquidCrystal_I2C.h>  //Libraries for controlling LC Displays
    #include <LCD.h>                
    #include <LiquidCrystal.h>
    #define lo8(x) ((int)(x)&0xff)
    #define hi8(x) ((int)(x)>>8)
    //Variables (Dashboard LEDs)
    int high_beam = 13;
    int fog_beam = 12;
    int park_brake = 11;
    //Variables (VW Dashboard Adapter)
    int LEFT_INDICATOR  = A0;
    int PARKING_BREAK   = A2;
    int FUEL_WARNING    = A3;
    //Variables (Dashboard Functions)
    int turning_lights = 3;
    boolean turning_lights_blinking = true;
    int turning_lights_counter = 0;
    int temp_turning_lights = 0;
    boolean backlight = false;
    int oilpswitch = 8;
    int pack_counter = 0;
    boolean add_distance = false;
    int drive_mode = 0;
    int distance_multiplier = 2;
    boolean oil_pressure_simulation = true;
    boolean door_open = false;
    boolean clutch_control = false;
    int temp_clutch_control = 0;
    boolean check_lamp = false;
    int temp_check_lamp = 0;
    boolean trunklid_open = false;
    int temp_trunklid_open = 0;
    boolean battery_warning = false;
    int temp_battery_warning = 0;
    boolean keybattery_warning = false;
    int temp_keybattery_warning = 0;
    int lightmode = 0;
    boolean seat_belt = false;
    int temp_seat_belt = 0;
    int engine_control = 0;
    int temp_dpf_warning = 0;
    boolean dpf_warning = false;
    boolean light_fog = false;
    int temp_light_fog = 0;
    boolean light_highbeam = false;
    int temp_light_highbeam = 0;
    boolean signal_abs = false;
    boolean signal_offroad = false;
    boolean signal_handbrake = false;
    boolean signal_lowtirepressure = false;
    boolean signal_dieselpreheat = false;
    boolean signal_watertemp = false;
    int temp_signal_abs = 0;
    int temp_signal_offroad = 0;
    int temp_signal_handbrake = 0;
    int temp_signal_lowtirepressure = 0;
    int temp_signal_dieselpreheat = 0;
    int temp_signal_watertemp = 0;
    //Variables (Speed and RPM)
    int speed = 0;
    byte speedL = 0;
    byte speedH = 0;
    int rpm = 0;
    short tempRPM = 0;
    byte rpmL = 0;
    byte rpmH = 0;
    int distance_adder = 0;
    int distance_counter = 0;
    //Variables LCD
    LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Addr, En, Rw, Rs, d4, d5, d6, d7, backlightpin, polarity
    //Variables CAN BUS
    /* the cs pin of the version after v1.1 is default to D9
    v0.9b and v1.0 is default D10 */
    const int SPI_CS_PIN = 9;
    MCP_CAN CAN(SPI_CS_PIN);  // Set CS pin
    //Setup Configuration
    void setup()
      //Initialize LCD
      showLCD("VW Dashboard","by Leon Bataille");
      showLCD("VW Dashboard","booting...");
      //Define Dashboard LEDs as Outputs
      pinMode(high_beam, OUTPUT);
      pinMode(fog_beam, OUTPUT); 
      pinMode(park_brake, OUTPUT);
      pinMode(oilpswitch, OUTPUT);
      //Visual Start Sequence on Dashboard
      digitalWrite(high_beam, HIGH);
      digitalWrite(fog_beam, HIGH);
      digitalWrite(park_brake, LOW);
      digitalWrite(PARKING_BREAK, HIGH);
      delay(500);               // wait for a second
      digitalWrite(high_beam, LOW);
      digitalWrite(FUEL_WARNING, HIGH);
      digitalWrite(PARKING_BREAK, LOW);
      digitalWrite(FUEL_WARNING, LOW);
      digitalWrite(LEFT_INDICATOR, HIGH);
      digitalWrite(RIGHT_INDICATOR, HIGH);
      digitalWrite(fog_beam, LOW);
      digitalWrite(LEFT_INDICATOR, LOW);
      digitalWrite(RIGHT_INDICATOR, LOW);
      //Begin with Serial Connection
      //Show Sketch information on LCD
      showLCD(game,"by "+vendor);
      //Begin with CAN Bus Initialization
        if(CAN_OK == CAN.begin(CAN_500KBPS))                   // init can bus : baudrate = 500k
            Serial.println("CAN BUS Shield init ok!");
            Serial.println("CAN BUS Shield init fail");
            Serial.println("Init CAN BUS Shield again");
            goto START_INIT;
    //Reload LC Display
    void showLCD(String line1,String line2)
      lcd.setCursor(0, 0);
      lcd.setCursor(0, 1);
    //Send CAN Command (short version)
    void CanSend(short address, byte a, byte b, byte c, byte d, byte e, byte f, byte g, byte h)
      unsigned char DataToSend[8] = {a,b,c,d,e,f,g,h};
      CAN.sendMsgBuf(address, 0, 8, DataToSend);
    //fuel gauge (0-100%)
    void Fuel(int amount)
      pinMode(2, INPUT);
      pinMode(3, INPUT);
      pinMode(4, INPUT);
      pinMode(5, INPUT);
      pinMode(6, INPUT);
      pinMode(7, INPUT);
      if (amount >= 90)
        pinMode(2, OUTPUT);
        digitalWrite(2, LOW);
      if (amount >= 75)
        pinMode(3, OUTPUT);
        digitalWrite(3, LOW);
      if (amount >= 50)
        pinMode(4, OUTPUT);
        digitalWrite(4, LOW);
      if (amount >= 25)
        pinMode(5, OUTPUT);
        digitalWrite(5, LOW);
      if (amount >= 10)
        pinMode(6, OUTPUT);
        digitalWrite(6, LOW);
      if (amount >= 0)
        pinMode(7, OUTPUT);
        digitalWrite(7, LOW);
    void loop()
      //Set constant speed and RPM to show on Dashboard
      speed = 0;                        //Set the speed in km/h
      rpm = 800;                        //Set the rev counter
      Fuel(30);                          //Set the fuel gauge in percent
      //Set Dashboard Functions
      backlight = true;                  //Turn the automatic dashboard backlight on or off
      turning_lights = 0;                //Turning Lights: 0 = none, 1 = left, 2 = right, 3 = both
      turning_lights_blinking = false;   //Choose the mode of the turning lights (blinking or just shining)
      add_distance = false;              //Dashboard counts the kilometers (can't be undone)
      distance_multiplier = 2;           //Sets the refresh rate of the odometer (Standard 2)
      signal_abs = false;                //Shows ABS Signal on dashboard
      signal_offroad = false;            //Simulates Offroad drive mode
      signal_handbrake = false;          //Enables handbrake
      signal_lowtirepressure = false;    //Simulates low tire pressure
      oil_pressure_simulation = true;    //Set this to true if dashboard starts to beep
      door_open = false;                 //Simulate open doors
      clutch_control = false;            //Displays the Message "Kupplung" (German for Clutch) on the dashboard's LCD
      check_lamp = false;                //Show 'Check Lamp' Signal on dashboard. B00010000 = on, B00000 = off
      trunklid_open = false;             //Simulate open trunk lid (Kofferraumklappe). B00100000 = open, B00000 = closed
      battery_warning = false;           //Show Battery Warning.
      keybattery_warning = false;        //Show message 'Key Battery Low' on Display. But just after first start of dashboard.
      light_fog = false;                 //Enable Fog Light
      light_highbeam = false;            //Enable High Beam Light
      seat_belt = false;                 //Switch Seat Betl warning light.
      signal_dieselpreheat = false;      //Simualtes Diesel Preheating
      signal_watertemp = false;          //Simualtes high water temperature
      dpf_warning = false;               //Shows the Diesel particle filter warning signal.
      //Conversion Speed
      speed = speed / 0.0075; //KMH=1.12 MPH=0.62
      //Conversion Low and High Bytes
      speedL = lo8(speed);
      speedH = hi8(speed);
      tempRPM = rpm*4;
      rpmL = lo8(tempRPM);
      rpmH = hi8(tempRPM);
      if (add_distance == true)
        distance_adder = speed * distance_multiplier;
        distance_counter += distance_adder;
        if (distance_counter > distance_adder) { distance_counter = 0; }
      if ( oil_pressure_simulation == true)
      //Set Oil Pressure Switch
        if (rpm > 1500) {
          digitalWrite(oilpswitch, LOW);
        else {
          digitalWrite(oilpswitch, HIGH);
      /*Send CAN BUS Data*/
      CanSend(0x3D0, 0, 0x80, 0, 0, 0, 0, 0, 0);
      //Engine on and ESP enabled
      CanSend(0xDA0, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
      //Enable Cruise Control
      //CanSend(0x289, 0x00, B00000001, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
      //Dashboard Functions
      //Turning Light blinking
      if (turning_lights_blinking == true)
        if (turning_lights_counter == 15)
          temp_turning_lights = turning_lights;
          turning_lights_counter = turning_lights_counter + 1;
        if (turning_lights_counter == 30)
          temp_turning_lights = 0;
          turning_lights_counter = 0;
          turning_lights_counter = turning_lights_counter + 1;
        temp_turning_lights = turning_lights;
      //Check main settings
      if (dpf_warning == true) temp_dpf_warning = B00000010;
      else temp_dpf_warning = B00000000;
      //Seat Belt
      if (seat_belt == true) temp_seat_belt = B00000100;
      else temp_seat_belt = B00000000;
      //Battery Warning
      if (battery_warning == true) temp_battery_warning = B10000000;
      else temp_battery_warning = B00000000;
      //Trunk Lid (Kofferraumklappe)
      if (trunklid_open == true) temp_trunklid_open = B00100000;
      else temp_trunklid_open = B00000000;
      //Check Lamp Signal
      if (check_lamp == true) temp_check_lamp = B00010000;
      else temp_check_lamp = B00000000;
      //Clutch Text on LCD
      if (clutch_control == true) temp_clutch_control = B00000001;
      else temp_clutch_control = B00000000;
      //Warning for low key battery
      if (keybattery_warning == true) temp_keybattery_warning = B10000000;
      else temp_keybattery_warning = B00000000;
      //Lightmode Selection (Fog Light and/or High Beam)
      if (light_highbeam == true) temp_light_highbeam = B01000000;
      else temp_light_highbeam = B00000000;
      if (light_fog == true) temp_light_fog = B00100000;
      else temp_light_fog = B00000000;
      lightmode = temp_light_highbeam + temp_light_fog;
      //Engine Options (Water Temperature, Diesel Preheater)
      if (signal_dieselpreheat == true) temp_signal_dieselpreheat = B00000010;
      else temp_signal_dieselpreheat = B00000000;
      if (signal_watertemp == true) temp_signal_watertemp = B00010000;
      else temp_signal_watertemp = B00000000;
      engine_control = temp_signal_dieselpreheat + temp_signal_watertemp;
      //Drivemode Selection (ABS, Offroad, Low Tire Pressure, handbrake)
      if (signal_abs == true) temp_signal_abs = B0001;
      else temp_signal_abs = B0000;
      if (signal_offroad == true) temp_signal_offroad = B0010;
      else temp_signal_offroad = B0000;
      if (signal_handbrake == true) temp_signal_handbrake = B0100;
      else temp_signal_handbrake = B0000;
      if (signal_lowtirepressure == true) temp_signal_lowtirepressure = B1000;
      else temp_signal_lowtirepressure = B0000;
      drive_mode = temp_signal_abs + temp_signal_offroad + temp_signal_handbrake + temp_signal_lowtirepressure;
      //Send CAN data every 200ms
      if (pack_counter == 20)
        //Turning Lights 2
        CanSend(0x470, temp_battery_warning + temp_turning_lights, temp_trunklid_open + door_open, backlight, 0x00, temp_check_lamp + temp_clutch_control, temp_keybattery_warning, 0x00, lightmode);
        //Diesel engine
        CanSend(0x480, 0x00, engine_control, 0x00, 0x00, 0x00, temp_dpf_warning, 0x00, 0x00);
        //CanSend(0x388, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
        //Cruise Control
        //CanSend(0x289, 0x00, B00000101, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
        pack_counter = 0;
      CanSend(0x320, 0x00, (speedL * 100), (speedH * 100), 0x00, 0x00, 0x00, 0x00, 0x00);
      CanSend(0x280, 0x49, 0x0E, rpmL, rpmH, 0x0E, 0x00, 0x1B, 0x0E);
      CanSend(0x5A0, 0xFF, speedL, speedH, drive_mode, 0x00, lo8(distance_counter), hi8(distance_counter), 0xad);
      CanSend(0x1A0, 0x18, speedL, speedH, 0x00, 0xfe, 0xfe, 0x00, 0xff);
      CanSend(0x050, 0x00, 0x80, temp_seat_belt, 0x00, 0x00, 0x00, 0x00, 0x00);
      //Wait a time

View all 3 instructions

Enjoy this project?



MirceaCulita wrote 06/12/2023 at 10:12 point

Hello, I've connected the power wires and the grounds to a power supply, but the dash backlight keeps flashing and some lights turn on at half intensity. Could it be the power supply is not strong enough to power them up? The center display doesn't turn on either.

  Are you sure? yes | no

stx55588 wrote 04/10/2023 at 15:44 point

The speed needle goes to 0 every 20 seconds. is there a fix for this

  Are you sure? yes | no

Adel wrote 08/13/2022 at 23:50 point

based on this project, i was able to build an improved version, the instrument cluster i used is for a Touran 2005

i found a fix for the issue of the speedometer needle going down to 0, this actually throws an error "ABS implausible signal" when the dash is diagnosed via VCDS, the issue lies in the way the data of distance is sent through the message of speed, a random number helped fixing the issue. but as a consequence, the distance meter will calculate more than needed.

  Are you sure? yes | no

Asım Şenyuva wrote 12/26/2020 at 21:00 point


I try to integrate VW GOLF MK7 series instrument cluster like yuor solution. I connected pins over instrument cluster chart. ( CANH and CANL ) and send 12V and GND. when i send power i see only needle led druing a few minute. During this time the device send can data and it code ligths ( like sleep ).

I can not open lights and control cluster. I try to send can command 1 - 4095 like your but still nothing. can you help me about this. or any idea ?

  Are you sure? yes | no

lego wrote 02/14/2021 at 07:26 point

it won't work with the mk7 cluster(needs a bunch of auto hardware to turn on)

  Are you sure? yes | no

troy wrote 08/06/2020 at 11:06 point

Hi Leon,

I wonder if you could help me out with a related project.

I am building a race car and have removed the belt driven hydraulic power steering pump and have decided to use the electro-hydraulic power steering pump unit from the same VW Polo you have used the instrument cluster from. For the electro-hydraulic pump to run, it needs to see the engine RPM signal over the can bus network to start the pump in additon to basic power and earth supplies.

I have purchased the seeed studio can bus shield v2 and I have an arduino uno, and I have tried to send can bus data using the can bus rpm message you have listed (which I was so pleased to find here!), but I am struggling to get the pump to run - I am unsure if this is down to my basic programming understanding and I'm not actually sending the correct message at all.

Would it be possible to ask you to write the very basic code (or at least have me send you my code, to check it)? I don't mind paying for your time.



  Are you sure? yes | no

lego wrote 05/27/2020 at 12:56 point

hi. does anyone have a working .dll and how to wire the arduino and the dash?

  Are you sure? yes | no

Doru Opritoiu wrote 04/01/2020 at 09:03 point

Hi Leon, I want to thank you for this wonderful project, I find it amazing, all good and beautiful, I gathered everything I need, I think I did everything according to the project provided, but still I have a problem, I would be grateful if you could give me a helping hand. The problem is something like this: I switch on the 12V power supply, I attach the usb (com3) the clocks are initialized and the RPM goes up to 800 as we have in the arduino code at the // MAIN SETUP FOR OPERATION line, but when I launch ETS2 with the specified plugin and I get in the Drive of ETS2 nothing happens, if it matters on the arduino board start to have TX RX activity on the USB port when accessing DRIVE in ETS2, but on the Dashboard nothing change ☹☹☹

Leon sincerely, I am sure you are very busy and I do not want to disturb you in any way, I appreciate this project provided by you and I greatly appreciate any help from you, thank you in advance

  Are you sure? yes | no

nuanohd wrote 03/15/2020 at 14:29 point

Hello Leon! I need some help with the wiring. First of all I want to only power the dashboard on. According to your log I only need to connect Pin 16 and 20 to both GND Outputs and PIN 31 and 32 to the Vin output. Now the question: How have you connected PIN 31 and 32 to the Vin output? As there is only one output for two pins it's not possible to use normal cables. Can you help me. 

I would be very happy if someone could help me. 

  Are you sure? yes | no

lego wrote 05/27/2020 at 12:57 point

use a breadborad. best way to do it

  Are you sure? yes | no

ge wrote 01/05/2020 at 11:05 point

Hi Leon, thanks a lot for this wonderful project. I could manage to connect everything and with your Arduino sketch my Seat Ibiza 2009 tacho/cluster lights up normally, but I get no feedback from ETS2. I have put the telemetry DLL in the required folder, game recognizes it and no errors are shown in game, the Arduino Uno led is blinking during gameplay which probably means that COM port is also set correctly (using the small txt provided by Silas on his v3 DLL). What could be going wrong? Do you have any idea how are the messages sent over to the COM port by the DLL telemetry plugin?

  Are you sure? yes | no

Joschua wrote 01/03/2020 at 12:43 point


Can you update the components list? I now forgot to order a potentiometer. Or can I use a 50k instead of 200 Ohm?

  Are you sure? yes | no

samuorai97 wrote 11/27/2019 at 17:10 point

hi leon,

Is the project applies to vw golf mk4 when right wiring connected? 

Also is it supporting all games ?

Finally,  is SIMHUB needed to run the the cluster as taking from the game and giving to arduino? 

  Are you sure? yes | no

apichlinski wrote 04/22/2019 at 13:17 point

Hi Leon, 

Thank you for sharing this projekt! I have strange issue with my speedometer: after 20-30 sec from start i have very loud sound. What's happening?

  Are you sure? yes | no

Leon Bataille wrote 10/20/2019 at 13:00 point

Hi, this is probably a missing oil pressure switch. If the RPM of the cluster is above 2000 the oil pressure switch has to be permanantly "pressed", otherwise the cluster starts beeping as it would become a motor damage in real life. In version 3.0 of my code there is an option called "oil_pressure_simulation", which should be set to true. You also have to make sure that arduino pin 8 is connected to pin 27 on the cluster. Hope that helps.

  Are you sure? yes | no

heiner.pahlings wrote 10/31/2018 at 13:50 point


I do have a Porsche 911 electrified, it is from 1998 so a little before CAN-BUS was introduced. Now I try to get some Engine noise added. As I have a Android based Car radio and a nice app found (voom voom) I would be able to emulate Engine sound. It works best if the Car Radio would connect to CAN-BUS to detect the RPM. Here I use the electronic available RPM signal of my engine controller and intend via CAN-BUS schield to make this as CAN Bus signal available for the radio. and for that you written code is quite helpful.

there is one thing I do not get. Why do you multiply the rpm input you have by 4?

Many Thanks for your project, and Many Thanks for your reply.

  Are you sure? yes | no

Ahmed lz wrote 05/14/2018 at 17:56 point

hi , i want to control my polo 6 lights with arduino (high beam , low beam , blikers doors lock ....) but i can't find thier canbus adresse i wish you can help me please answer yes or no thanks anyway

  Are you sure? yes | no

Anthony wrote 02/26/2018 at 12:55 point

Can you show dumps of messages with ID 0x320 coming from panel? I'm trying to run with VW dashboard, but can't adjust speedometer. Messages with ID 0x1A0 and 0x5A0 affects speedometer, but not stable, in messages 0x320 I see error bit in speed calculation.

  Are you sure? yes | no

Tai Bui wrote 02/07/2018 at 20:43 point

I got this error message in compiling tne sketch :

Arduino: 1.8.5 (Windows 10), Board: "Arduino/Genuino Uno"
C:\Users\Tai\Documents\VWCode3.0_static\VWCode3.0_static.ino:23:33: fatal error: LCD.h: No such file or directory
 #include <LCD.h>                                                 ^
compilation terminated.
exit status 1
Error compiling for board Arduino/Genuino Uno.
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Please help.

  Are you sure? yes | no

kurt wrote 08/28/2019 at 16:48 point

add the library in the arduino IDE. You may need to do this with other libraries as well. Just youtube how to add a library. It is pretty standard

  Are you sure? yes | no

gautier.p62 wrote 01/08/2018 at 10:13 point

Hi Leon!

I have a question.

How is possible to use 

int high_beam = 13;
int fog_beam = 12;
int park_brake = 11;

ports for LED-s, if this pins are used by the SPI bus for communication with CAN-BUS?

  Are you sure? yes | no

Leon Bataille wrote 10/20/2019 at 13:03 point

the LEDs are used before initializing the CAN BUS, so that I see when I reupload the sketch when the process is completed. It's just a debugging help and could be removed without a problem.

  Are you sure? yes | no

Udo Schneider wrote 08/30/2017 at 18:17 point

What's the newest (best?) source for wiring? On first glance the fritzing diagram is not identical to Is0-Mick's diagram ... and both do contain things which didn't work on the dashboard I'm using. Maybe (the source for) the PCB might be a good reference - but where to get that? 

  Are you sure? yes | no

Leon Bataille wrote 12/19/2017 at 09:18 point

Hi! I just uploaded the source files of the circuit board.

  Are you sure? yes | no

lego wrote 01/05/2018 at 17:45 point

downloaded the updated diagram, found out it's made with autodesk eagle which in order to use i need an account, any chance for an exported file like .pdf or something that doesn't require to create accounts?

  Are you sure? yes | no

Leon Bataille wrote 01/05/2018 at 18:11 point

Oh I see. Apparently it was Freeware a year ago. Could you please try it with the free version by Cadsoft?

  Are you sure? yes | no

lego wrote 01/07/2018 at 09:43 point

the Cadsoft link no longer works, it redirects to the same autodesk eagle which you have to make an account.

  Are you sure? yes | no

Leon Bataille wrote 01/07/2018 at 10:10 point

OK, I think my PC had the original download page in cache. I‘ll make an PDF of the schematic and the board. Sorry for this misunderstanding.

  Are you sure? yes | no

Anthony Whittle wrote 07/27/2017 at 13:15 point

Hello again,

When will the installation setup tool be available?


  Are you sure? yes | no

Anthony Whittle wrote 07/07/2017 at 17:46 point


Does it work with the petrol version dash?


  Are you sure? yes | no

Leon Bataille wrote 07/11/2017 at 18:58 point

Should also work with the petrol version, yes.

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates