1. For downloading SimTools plugins you need a Download Package. Get it with virtual coins that you receive for forum activity or Buy Download Package - We have a zero Spam tolerance so read our forum rules first.

    Buy Now a Download Plan!
  2. Do not try to cheat our system and do not post an unnecessary amount of useless posts only to earn credits here. We have a zero spam tolerance policy and this will cause a ban of your user account. Otherwise we wish you a pleasant stay here! Read the forum rules
  3. We have a few rules which you need to read and accept before posting anything here! Following these rules will keep the forum clean and your stay pleasant. Do not follow these rules can lead to permanent exclusion from this website: Read the forum rules.
    Are you a company? Read our company rules

News Build a real car instrument cluster for racing simulation on a PC

Discussion in 'DIY Motion Simulator Projects' started by jjanu, Dec 4, 2017.

  1. jjanu

    jjanu LiveForSim Gold Contributor

    Joined:
    Apr 13, 2013
    Messages:
    66
    Occupation:
    Multimedia
    Location:
    Québec
    Balance:
    503Coins
    Ratings:
    +57 / 1 / -0
    My Motion Simulator:
    DC motor, Arduino, Motion platform, 4DOF
    The following instructions will guide you through the many steps required in order to use a Mazda 3 instrument cluster with most of the racing games. The pictures and instructions included in the attached PDF document will help you to get the right configuration. With the proper game telemetry plugins the cluster should react to all the inputs related to speed, rpm and gear shift.

    Useful links:

    OneDrive documentation:
    EDIT (NEW LINK): https://1drv.ms/u/s!AtwKGzBk3VOon64e1rfH-a1O9A9zgQ?e=3RpeIK

    Instrument cluster in action with Dirt3:


    Instrument cluster in action with Assetto Corsa:


    Please note that this project was initially developed using the X-Sim package and my goal is to adapt the equivalent configuration to SimTools environment so the XSimulator community can also use it and tweak it as they like.

    Attached Files:

    • Like Like x 2
    • Informative Informative x 1
    Last edited: Jan 15, 2020
  2. Ads Master

    Ads Master

    Balance:
    Coins
    Ratings:
    +0 / 0 / -0
  3. noorbeast

    noorbeast VR Tassie Devil Staff Member Moderator Race Director

    Joined:
    Jul 13, 2014
    Messages:
    15,324
    Occupation:
    Innovative tech specialist for NGOs
    Location:
    St Helens, Tasmania, Australia
    Balance:
    112,707Coins
    Ratings:
    +9,076 / 46 / -2
    My Motion Simulator:
    3DOF, DC motor, JRK
    Nice work, that would likely be of interest to a number of members if ported to SimTools :thumbs
    • Agree Agree x 2
  4. jjanu

    jjanu LiveForSim Gold Contributor

    Joined:
    Apr 13, 2013
    Messages:
    66
    Occupation:
    Multimedia
    Location:
    Québec
    Balance:
    503Coins
    Ratings:
    +57 / 1 / -0
    My Motion Simulator:
    DC motor, Arduino, Motion platform, 4DOF
    Thanks a lot NoorBeast. As soon as I get my DIY licence for SimTools I will start to adapt the data to make it work. Stay tuned!
    • Like Like x 2
  5. noorbeast

    noorbeast VR Tassie Devil Staff Member Moderator Race Director

    Joined:
    Jul 13, 2014
    Messages:
    15,324
    Occupation:
    Innovative tech specialist for NGOs
    Location:
    St Helens, Tasmania, Australia
    Balance:
    112,707Coins
    Ratings:
    +9,076 / 46 / -2
    My Motion Simulator:
    3DOF, DC motor, JRK
  6. jjanu

    jjanu LiveForSim Gold Contributor

    Joined:
    Apr 13, 2013
    Messages:
    66
    Occupation:
    Multimedia
    Location:
    Québec
    Balance:
    503Coins
    Ratings:
    +57 / 1 / -0
    My Motion Simulator:
    DC motor, Arduino, Motion platform, 4DOF
    Noted @noorbeast. Tks. I have a brand new 3DOF DIY motion platform but it is based on the Simukit solution so it's not my idea. Therefore I can't propose it to the community as a owned DIY project. I was hoping that my instrument cluster project could be seen as a kind of motion simulation project since it is using game telemetry to activate motors that make the cluster panel needles work. But instead of being motors on a motion base, it is motors inside an instrument panel. So in conclusion the base concept remains the same. I just made the request for the licence and I hope it gets accepted in order for me to get the plugins to make the project works with SimTools and allow the community to enjoy the results. Cheers!
    • Agree Agree x 2
  7. yobuddy

    yobuddy Well-Known Member Staff Member Moderator SimAxe Beta Tester SimTools Developer Gold Contributor

    Joined:
    Feb 9, 2007
    Messages:
    3,773
    Occupation:
    Computer Technician
    Location:
    Portland, Oregon - USA
    Balance:
    33,298Coins
    Ratings:
    +3,876 / 10 / -0
    @jjanu,
    That's true, but you could still show a pic of the sim you built.
    It's always fun checking out new builds.

    I understand, and while this really does not qualify, what you did do is very well done.
    So I'll PM you a DIY license.

    Just a note, SimTools only comes with the Live for Speed plugin.
    The rest you download using the coins you collect in the forums.
    (or you can get a download package for xsimulator.net)
    But really you only need to collect 250 coins, and you can download them all in the allowed time.
    I'll send you some coins to get you started.

    take care,
    yobuddy
    • Friendly Friendly x 3
    • Like Like x 1
  8. jjanu

    jjanu LiveForSim Gold Contributor

    Joined:
    Apr 13, 2013
    Messages:
    66
    Occupation:
    Multimedia
    Location:
    Québec
    Balance:
    503Coins
    Ratings:
    +57 / 1 / -0
    My Motion Simulator:
    DC motor, Arduino, Motion platform, 4DOF
    Thanks guys for all your good comments and support. And thanks for the DIY and coins. I really appreciate it and will make good usage out of it. I have plenty of ideas, especially with the new sim that I'm currently assembling. I will post pictures and vids when the 3DOF+YAW motion base is fully assembled. I will upgrade to the Pro version in order to port my cluster solution to SimTools since I'm very curious about how the components will interact with this new environment. I want to fulfill my "duty" and provide the community with a solution that works with SimTools. My goal is to ensure that the instrument cluster could be integrated to an already existing motion platform and be controlled by SimTools, without being to intrusive in term of resource requirement so the motion platform itself is not affected and continue to perform nominally.
    • Like Like x 3
    • Winner Winner x 2
  9. jjanu

    jjanu LiveForSim Gold Contributor

    Joined:
    Apr 13, 2013
    Messages:
    66
    Occupation:
    Multimedia
    Location:
    Québec
    Balance:
    503Coins
    Ratings:
    +57 / 1 / -0
    My Motion Simulator:
    DC motor, Arduino, Motion platform, 4DOF
    Hi All. Last week I received all the parts required to start the building of my new 3DOF+YAW sim. I did some paint job of the steel base, the assembly of the servo/pot components on the 4 motors and Sabertooth+Arduino, and code uploading to the logic boards. This weekend I should be able to complete all the wiring/soldering phase, and take pictures/vids to document the whole process. It's hard to squeeze the time required to take care of all the tiny little details especially after a full day of work so I'm eager to reach the weekend to have the wiring complete and initiate the first phase of test to see the motors finally move ! After will come the time to insert all the organs into the belly of the beast and watch the rig perform its motions for the first time. I really look forward to testing the SimTool plugins generously provided by our supporters. Pictures/vids are coming. Stay tuned!
    • Like Like x 2
    Last edited: Dec 14, 2017
  10. jjanu

    jjanu LiveForSim Gold Contributor

    Joined:
    Apr 13, 2013
    Messages:
    66
    Occupation:
    Multimedia
    Location:
    Québec
    Balance:
    503Coins
    Ratings:
    +57 / 1 / -0
    My Motion Simulator:
    DC motor, Arduino, Motion platform, 4DOF
    The motion 3DOF+YAW simulator platform I'm working on is almost complete; the 3-motor motion base is fully functional and the next step is to bolt my cockpit on. I've been so busy putting all the parts together and do the programming during the 2-week holidays that I didn't have time to prepare a documentation with all the pictures and videos that I captured along the process. As soon as I get some time I'll create a new post for this motion simulator project and share all the visual. I also upgraded my account to Gold Contributor as a mark of appreciation and respect for the outstanding work that everyone put in Simtools. The more I've been working with the program during the development phase and the more I'm loving it. Congrats to everyone who have been contributing to the making of this great tool.

    I will eventually get back to the conversion of the coding for my dashboard project in order to make it work with Simtools Dashboard. More info on this soon.
    • Like Like x 2
  11. jjanu

    jjanu LiveForSim Gold Contributor

    Joined:
    Apr 13, 2013
    Messages:
    66
    Occupation:
    Multimedia
    Location:
    Québec
    Balance:
    503Coins
    Ratings:
    +57 / 1 / -0
    My Motion Simulator:
    DC motor, Arduino, Motion platform, 4DOF
    Last edited: Jan 12, 2018
  12. jjanu

    jjanu LiveForSim Gold Contributor

    Joined:
    Apr 13, 2013
    Messages:
    66
    Occupation:
    Multimedia
    Location:
    Québec
    Balance:
    503Coins
    Ratings:
    +57 / 1 / -0
    My Motion Simulator:
    DC motor, Arduino, Motion platform, 4DOF
    I started to make some attempts at writing the right commands in Gamedash Command Editor to get smooth RPM input but I'm going blind since I have absolutely no clue what command I should use. X-Sim and Simtools interfaces are very different. I had perfect inputs with X-Sim. The motion I get now with Simtools Game Dash are not smooth and there's a huge lag although I'm using the same output rate. See the commands I'm using in the attached pic. Tks

    My goal is to achieve the same level of fidelity as the project depicted in this thread: https://www.xsimulator.net/community/threads/tacho-controller-arduino-e46-canbus.5463/#post-155294

    Anyone has a clue what command should I use for RPM with CAN-BUS system? Tks

    Attached Files:

  13. jjanu

    jjanu LiveForSim Gold Contributor

    Joined:
    Apr 13, 2013
    Messages:
    66
    Occupation:
    Multimedia
    Location:
    Québec
    Balance:
    503Coins
    Ratings:
    +57 / 1 / -0
    My Motion Simulator:
    DC motor, Arduino, Motion platform, 4DOF
    And I tried these commands that give a better input but it is not a 100% perfect. Still a bit of lag-half-a-second-and I can't get the exact same revs as in Assetto Corsa, i.e. the car is reving from 950 to 7000 RPM and my dash goes from 700 RPM to 7500 RPM. I don't know how to tweak the data to match the RPM perfectly.
    Capture.JPG
    • Like Like x 1
  14. jjanu

    jjanu LiveForSim Gold Contributor

    Joined:
    Apr 13, 2013
    Messages:
    66
    Occupation:
    Multimedia
    Location:
    Québec
    Balance:
    503Coins
    Ratings:
    +57 / 1 / -0
    My Motion Simulator:
    DC motor, Arduino, Motion platform, 4DOF
    I can't get speed to work with Gamedash Command Editor and Assetto Corsa. I tried many commands but none is working. So far I'm just getting RPM and it is not perfect. If someone has an idea what command I should use it will be welcomed. Without help with Gamedash commands I won't be able to advance that project further. My plan was to prepare a document with the complete procedure that I could share with the community. But until someone could provide me with some expertise with Gamedash I will have to put that project on ice.
  15. yobuddy

    yobuddy Well-Known Member Staff Member Moderator SimAxe Beta Tester SimTools Developer Gold Contributor

    Joined:
    Feb 9, 2007
    Messages:
    3,773
    Occupation:
    Computer Technician
    Location:
    Portland, Oregon - USA
    Balance:
    33,298Coins
    Ratings:
    +3,876 / 10 / -0
    There is a bit of info missing here, So I will make some up just to show you the thought process behind it.
    Lets say we need to send a 8 bit char to an Arduino in an effort to make the RPM gauge match the in games RPM's.

    So the rpm gauge on the instrument cluster goes from 700 to 7500.
    So let's get the Percent used from the RPM input of the game for this range like this:
    1) Percent 700 7500
    This gives us a whole number between 0 and 100
    (You can test the output of this command with the output tester to see it working)

    Now we need 8 bit, so lets scale the output to 8 bit like this:
    2) Scale 0 255
    This give us a number between 0 and 255
    (You can test the output of this new command with the output tester and see what it adds)

    After you test the new command above you see a problem, we have digits and we cant use them.
    So let's get rid of them like this:
    3) Round 0
    And we now have 256 outputs, or 8 bit!
    (The output tester will show that its dropping the digits now)

    Now we just need to format the output to get a char
    We can represent the output as a Char like this:
    4) ToChr
    (The output tester will show a corresponding char now)

    And there you have it, all bases are covered.
    (The full command set looks like this)
    Percent 700 7500
    Scale 0 255
    Round 0
    ToChr

    Once we know a bit more about what you need to send, I'm sure we can get it running buddy.
    Take care,
    yobuddy
    • Informative Informative x 4
  16. jjanu

    jjanu LiveForSim Gold Contributor

    Joined:
    Apr 13, 2013
    Messages:
    66
    Occupation:
    Multimedia
    Location:
    Québec
    Balance:
    503Coins
    Ratings:
    +57 / 1 / -0
    My Motion Simulator:
    DC motor, Arduino, Motion platform, 4DOF
    Thanks for providing such a thorough answer buddy, that's exactly what I was looking for. Can't wait to try it out. I'll report back as soon as possible.
  17. jjanu

    jjanu LiveForSim Gold Contributor

    Joined:
    Apr 13, 2013
    Messages:
    66
    Occupation:
    Multimedia
    Location:
    Québec
    Balance:
    503Coins
    Ratings:
    +57 / 1 / -0
    My Motion Simulator:
    DC motor, Arduino, Motion platform, 4DOF
    I'm also including the snips of the commands that I was using with X-Sim.
    XSim_RPM_Math.JPG
    XSim_RPM_USO.JPG
    XSim_SPEED_Math.JPG
    XSim_SPEED_USO.JPG
  18. jjanu

    jjanu LiveForSim Gold Contributor

    Joined:
    Apr 13, 2013
    Messages:
    66
    Occupation:
    Multimedia
    Location:
    Québec
    Balance:
    503Coins
    Ratings:
    +57 / 1 / -0
    My Motion Simulator:
    DC motor, Arduino, Motion platform, 4DOF
    As a reference, below is the code I inject into the Arduino. The maths values for RPM and SPEED, and the CAN messages are predefined by Mazda constructor.

    Code:
    
    #include <mcp_can.h>
    #include <mcp_can_dfs.h>
    #include <SPI.h>
    #include <TM1638.h> //can be downloaded from http://code.google.com/p/tm1638-library/
    
    const int SPI_CS_PIN;
    
    MCP_CAN CAN(SPI_CS_PIN);                                    // Set CS pin
    
    // Declare RPM, Speed and Gear
    int RPM;
    int Speed;
    
    long previousMillis = 0;        // will store last time LED was updated
    
    unsigned long currentMillis = millis();
    unsigned int CarRPM;
    // unsigned int CarSpeedKM;
    long interval = 40;             // interval at which to blink (milliseconds)
    
    // Unsigned char stmp[8] = {0, 1, 2, 3, 4, 5, 6, 7};
    char kind_of_data;
    byte my_data[8];
    
    void setup()
    {
      Serial.begin(115200);
      // Send a diagnostic test to the Serial Monitor for the CAN shield
      if(CAN.begin(CAN_500KBPS) == CAN_OK) Serial.print("can init ok!!\r\n");
      else Serial.print("Can init fail!!\r\n");
    }
    
    void loop()
    {
    int i;
    char bufferArray[20];              // holds all serial data into a array
    
    if (Serial.available() >= 9)  {    //if 6 bytes available in the Serial buffer...
          for (i=0; i<9; i++) {         // for each byte
          bufferArray = Serial.read();        // put into array
         }
      }
        // Parsers used by X-SIM to send game datas for Gear, RPM, Speed, Temperature and the external LEDs to the cluster over serial port (USB)
      while(Serial.available() > 8)
      {
        kind_of_data = Serial.read();
        if (kind_of_data == 'R' ) Read_RPM();    // Send RPM data to the cluster and flash RPM red LED when RPM hits 6500
        kind_of_data = Serial.read();
        if (kind_of_data == 'S' ) Read_Speed();  // Send Speed to the cluster
      }
    }
    
    // RPM Data and Maths
    void Read_RPM()
    {
      //Read from Serial
      delay(1);
      int RPM100 = Serial.read()- '0';
      delay(1);
      int RPM10 = Serial.read()- '0';
      delay(1);
      int RPM1 = Serial.read()- '0';
      int RPM = 100*RPM100 + 10*RPM10 + RPM1;
    
      //Set values
      my_data[0] = (RPM * 4) / 256; // rpm
      my_data[1] = (RPM * 4) % 256; // rpm
      CAN.sendMsgBuf(0x201, 0, 8, my_data);
      delay(1);
    }
    
    // Speed Data and Maths
    void Read_Speed()
    { 
      //Read from Serial
      delay(1);
      int Speed100 = Serial.read()- '0';
      delay(1);
      int Speed10 = Serial.read()- '0';
      delay(1);
      int Speed1 = Serial.read()- '0';
      int Speed = 100*Speed100 + 10*Speed10 + Speed1;
    
      // Set values
      my_data[4] = (Speed-8000) / 150; //speed
      my_data[5] = (Speed-8000) % 150; //speed
      my_data[6] = 0xFF;
      my_data[7] = 0xFF;
    
      //Send Message
      CAN.sendMsgBuf(0x201, 1, 8, my_data);
    }
    
    
  19. yobuddy

    yobuddy Well-Known Member Staff Member Moderator SimAxe Beta Tester SimTools Developer Gold Contributor

    Joined:
    Feb 9, 2007
    Messages:
    3,773
    Occupation:
    Computer Technician
    Location:
    Portland, Oregon - USA
    Balance:
    33,298Coins
    Ratings:
    +3,876 / 10 / -0
    Hi Buddy,
    So the output string for Game Dash would look like this:
    G<DashX>R<DashX>S<DashX>D<DashX>
    Where X is the dash value of the corresponding output for the game.
    And the output is a char Character from 0 to 255.

    Looks like we have:
    G for Gear?
    R for RPM?
    S for Speed?
    and D for?

    Let's take them one at a time.
    What game are you using for the tests?
    Dustin
    • Informative Informative x 1
  20. jjanu

    jjanu LiveForSim Gold Contributor

    Joined:
    Apr 13, 2013
    Messages:
    66
    Occupation:
    Multimedia
    Location:
    Québec
    Balance:
    503Coins
    Ratings:
    +57 / 1 / -0
    My Motion Simulator:
    DC motor, Arduino, Motion platform, 4DOF
    Yes, the string is correct. The D is for Digital Speed that sends speed data in a digital format to my little tm1638 display. I'm uploading a snip for gear. Below is the complete Arduino code for all the functions. The one shown in a previous comment was limited to Speed and RPM for testing purpose.

    Code:
    #include <mcp_can.h>
    #include <mcp_can_dfs.h>
    #include <SPI.h>
    #include <TM1638.h> //can be downloaded from http://code.google.com/p/tm1638-library/
    
    const int SPI_CS_PIN;
    
    MCP_CAN CAN(SPI_CS_PIN);                                    // Set CS pin
    
    // Declare RPM, Speed and Gear
    int RPM;
    int Speed;
    int Gear;
    int EngineOFF;
    
    int ledState = LOW;             // ledState used to set the LED
    long previousMillis = 0;        // will store last time LED was updated
    
    unsigned long currentMillis = millis();
    unsigned int CarRPM;
    unsigned int CarSpeedKM;
    long interval = 40;             // interval at which to blink (milliseconds)
    
    // Associate a LED with its respective pin and determine its brightness
    int ShiftLED = A0;
    int ShiftLEDbrightness = 255;
    
    // Associate TM1638 LED display with its respective data pins
    TM1638 module1(8, 7, 9);
    
    // Unsigned char stmp[8] = {0, 1, 2, 3, 4, 5, 6, 7};
    char kind_of_data;
    byte my_data[8];
    
    void setup()
    {
      Serial.begin(115200);
    
      // Send a diagnostic test to the Serial Monitor for the CAN shield
      if(CAN.begin(CAN_500KBPS) == CAN_OK) Serial.print("can init ok!!\r\n");
      else Serial.print("Can init fail!!\r\n");
    
      // Initialize the LED pin for Shift LED
      pinMode(ShiftLED, OUTPUT);  
    
      // initialize the TM1638 display:
      module1.clearDisplay();               //clears the display from garbage if any
      String name1 = "HELLO jj";               //sets a custom logo start up banner
      module1.setDisplayToString(name1);    //prints the banner
    
      module1.setLEDs(0b10000000 | 0b00000001<< 8 );
      delay(50);
      module1.setLEDs(0b11000000 | 0b00000011<< 8 );
      delay(50);
      module1.setLEDs(0b11100000 | 0b00000111<< 8 );
      delay(50);
      module1.setLEDs(0b11110000 | 0b00001111<< 8 );
      delay(50);
      module1.setLEDs(0b11111000 | 0b00011111<< 8 );
      delay(50);
      module1.setLEDs(0b11111100 | 0b00111111<< 8 );
      delay(50);
      module1.setLEDs(0b11111110 | 0b01111111<< 8 );
      delay(50);
      module1.setLEDs(0b11111111 | 0b11111111<< 8 );
      delay(200);
      module1.setLEDs(0b00000000 | 0b00000000<< 8 );
      delay(50);
      module1.setLEDs(0b11111111 | 0b11111111<< 8 );
      delay(100);
      module1.setLEDs(0b00000000 | 0b00000000<< 8 );
      delay(50);
      module1.setLEDs(0b11111111 | 0b11111111<< 8 );
      delay(100);
      module1.setLEDs(0b00000000 | 0b00000000<< 8 );
      delay(50);
      module1.setLEDs(0b11111111 | 0b11111111<< 8 );
      delay(100);
      module1.setLEDs(0b00000000 | 0b00000000<< 8 );
      delay(2000);                       //small delay 2 sec
      module1.clearDisplay();            //clears the 1st display
    }
    
    void loop()
    {
    int i;
    char bufferArray[20];              // holds all serial data into a array
    byte gear;                         // holds gear value data
    byte geardata = 0;                 // marker that new data are available
    
    if (Serial.available() >= 9)  {    //if 6 bytes available in the Serial buffer...
          for (i=0; i<9; i++) {         // for each byte
          bufferArray[i] = Serial.read();        // put into array
         }
      }
    if (bufferArray[7] == 'G' ){
       gear = bufferArray[8];         // retrieves the single byte of gear (0-255 value)
       geardata=1;                    // we got new data!
    }
    if (geardata == 1) {
       char* neutral = "n";                // sets the character for neutral
       char* reverse = "r";                // sets the character for reverse
       gear = gear - 127;                  // offset the 0 value in 8-bit
       if (gear >= 1 and gear <10 ){
          module1.setDisplayDigit(gear, 0, false);   // displays numerical value of the current gear
       }
       if (gear == 0){
          module1.setDisplayToString(neutral, 0, 0);  // displays the character for neutral
       }
       if (gear == 255){                        // -1 that reprecents reverse rollover to 255 so...
          module1.setDisplayToString(reverse, 0, 0);  // displays the character for reverse
       }
       geardata=0;
      }
     
      // Parsers used by X-SIM to send game datas for Gear, RPM, Speed, Temperature and the external LEDs to the cluster over serial port (USB)
      while(Serial.available() > 8)
      { 
        kind_of_data = Serial.read();
        if (kind_of_data == 'D' ) Read_Gear();   // Send Gear data to the cluster
        kind_of_data = Serial.read();
        if (kind_of_data == 'R' ) Read_RPM();    // Send RPM data to the cluster and flash RPM red LED when RPM hits 6500
        kind_of_data = Serial.read();
        if (kind_of_data == 'S' ) Read_Speed();  // Send Speed to the cluster
      }
    }
    
    // Gear Data and Maths
    void Read_Gear()
    {
      delay(1);
      int Gear100 = Serial.read()- '0';
      delay(1);
      int Gear10 = Serial.read()- '0';
      delay(1);
      int Gear1 = Serial.read()- '0';
    
      Gear = 100* Gear100 + 10*Gear10 + Gear1;
    
      Gear = map(Gear,127,255,0,7);
     
      // Send data to the temp gauge to move the needle on middle position when the engine has started
      // (the needle will remain static at all time)
      if ( Gear == 0,1,2,3,4,5,6,7 )
      {
        my_data[0] = 0x98; // Temp Gauge Data
        my_data[1] = 0x00;
        my_data[2] = 0xFF;
        my_data[3] = 0x00;
        CAN.sendMsgBuf(0x420, 0, 8, my_data);
      }
     
      if ( Gear == 0 )
      {
        // show 'N' (Neutral) on dashboard
        my_data[0] = 0x3; // Gear: Neutral
        CAN.sendMsgBuf(0x228, 0, 8, my_data);
      }
    }
    
    // RPM Data and Maths
    void Read_RPM()
    {
      //Read from Serial
      delay(1);
      int RPM100 = Serial.read()- '0';
      delay(1);
      int RPM10 = Serial.read()- '0';
      delay(1);
      int RPM1 = Serial.read()- '0';
      int RPM = 100*RPM100 + 10*RPM10 + RPM1;
    
      //Set values
      my_data[0] = (RPM * 4) / 256; // rpm
      my_data[1] = (RPM * 4) % 256; // rpm
     
      CAN.sendMsgBuf(0x201, 0, 8, my_data);
      // delay(6);
    
      // Engine and Battery Lights will turn on when engine has started
      if (RPM>200)
      {
        my_data[2] = 0xFF; // Check Engine Light + Coolant, oil and battery ON
      }
     
      // Engine and Battery Lights will turn off when engine has stopped
      if (RPM<200)
      {
        my_data[3] = 0x00; // Check Engine Light + Coolant, oil and battery OFF
        CAN.sendMsgBuf(0x420, 0, 8, my_data);
      }
     
      // Fuel Gauge needle goes up when engine is off (fake value not based on game telemetry)
      if (RPM<300) // 0RPM
      {
        // Initialize the pin 2 to drive the Fuel Gauge needle up
        pinMode(2, OUTPUT); // pin to which the Fuel Gauge is connected
      }
     
      // Fuel Gauge needle goes down when engine is on (fake value not based on game telemetry)
      if (RPM>300) // 1000RPM
      {
        // Initialize and empty pin to drive the Fuel Gauge needle down
        pinMode(4, OUTPUT); // empty pin
      }   
      // RPM LEDs will turn on at increasing RPM and Fuel Gauge needle goes up when engine is off
      if (RPM<100) // 0RPM
      {
        module1.setLEDs(0b00000000 | 0b00000000); // All TM1638 LED off
      }
      if (RPM >= 101 && RPM <=500) // 1000RPM
      {
        module1.setLEDs(0b00000001 | 0b00000000); // TM1638 Green LED 1 on
      }
      if (RPM >= 501 && RPM <=800) // 2000RPM
      {
        module1.setLEDs(0b00000011 | 0b00000000 << 8 ); // TM1638 Green LED 1 and 2 on
      }
      if (RPM >= 801 && RPM <=1000) // 3000RPM
      {
        module1.setLEDs(0b00000111 | 0b00000000 << 8 ); // TM1638 Green LED 1, 2 and 3 on
      }
      if (RPM >= 1001 && RPM <=1200) // 4000RPM
      {
        module1.setLEDs(0b00001111 | 0b00000000 << 8 ); // TM1638 Green LED 1, 2, 3 and 4 on
      }
      if (RPM >= 1201 && RPM <=1450) // 5000RPM
      {
        module1.setLEDs(0b00001111 | 0b00010000 << 8 ); // TM1638 Green LED 1, 2, 3, 4 and Red LED 1 on
      }
      if (RPM >= 1451 && RPM <=1700) // 6000RPM
      {
        module1.setLEDs(0b00001111 | 0b00110000 << 8 ); // TM1638 Green LED 1, 2, 3, 4 and Red LED 1, 2 on
      }
      if (RPM >= 1701 && RPM <=1940) // 7000RPM
      {
        module1.setLEDs(0b00001111 | 0b01110000 << 8 ); // TM1638 Green LED 1, 2, 3, 4 and Red LED 1, 2, 3 on
      }
      if (RPM >= 1941 && RPM <=2200) // 8000RPM
      {
        module1.setLEDs(0b00001111 | 0b11110000 << 8 ); // TM1638 Green LED 1, 2, 3, 4 and Red LED 1, 2, 3 on
      }
    
      // RPM Red LED will turn on at 6500 RPM
      if (RPM>1600) analogWrite(ShiftLED, ShiftLEDbrightness);   // turn the LED on
      if (RPM<1600) analogWrite(ShiftLED, LOW);    // turn the LED off
    }
    
    // Speed Data and Maths
    void Read_Speed()
    {  
      //Read from Serial
      delay(1);
      int Speed100 = Serial.read()- '0';
      delay(1);
      int Speed10 = Serial.read()- '0';
      delay(1);
      int Speed1 = Serial.read()- '0';
      int Speed = 100*Speed100 + 10*Speed10 + Speed1;
    
      // Set values
      my_data[4] = (Speed-8000) / 150; //speed
      my_data[5] = (Speed-8000) % 150; //speed
      my_data[6] = 0xFF;
      my_data[7] = 0xFF;
     
      //Send Message
      CAN.sendMsgBuf(0x201, 1, 8, my_data);
    
      // Show digital speed on TM1638 display
      CarSpeedKM = Speed / 59 - 138; // Calculation accounting for X-Sim values used with the Mazda dashboard
      module1.setDisplayToDecNumber(CarSpeedKM, 8, false);
    }

    Attached Files:

  21. yobuddy

    yobuddy Well-Known Member Staff Member Moderator SimAxe Beta Tester SimTools Developer Gold Contributor

    Joined:
    Feb 9, 2007
    Messages:
    3,773
    Occupation:
    Computer Technician
    Location:
    Portland, Oregon - USA
    Balance:
    33,298Coins
    Ratings:
    +3,876 / 10 / -0
    So let's figure out what your code needs.

    Looks like the G is a single 8bit digit.
    (don't think you need this) - (gear = gear - 127; // offset the 0 value in 8-bit)

    (possible commands for G)
    Replace -1 255 (if -1 is reverse for the game, replace with what's used for the game)
    ToChr

    I just need to know how many char's are used for each (G, R, S, D)
    Chat soon,
    yobuddy
    • Informative Informative x 1