New!!OBD2 Com with Xsim3 and Arduino-New!!

Dashboard, gauge projects etc.
Please use the image gallery for your pictures, a short tutorial can be found here.
The first image in the first post will be shown in the project gallery.

Re: New!!OBD2 Com with Xsim3 and Arduino-New!!

Postby vicpopo » Wed 18. Sep 2013, 00:04

Hi Prodigy,

The problem you are facing to is that the arduino nano isn't recognize .
The last test I made is with a new extractor release given from Sirnoname.
Sirnoname will share it after a last test from Yokoyoko.
But if you installed the last xsim sofware (3.0.2.3) that should work.You can change the timeout in the code like the line below:
'' for(int z=0; z < 500; z++) //500ms timeout should be enough'' , change the original value setup to 500 to 1500 ms.

Give me the answer if you succeed with this modification.
User avatar
vicpopo
 
Posts: 645
Joined: Fri 20. Apr 2012, 18:04
Location: Strasbourg France
Has thanked: 39 times
Been thanked: 80 times

Re: New!!OBD2 Com with Xsim3 and Arduino-New!!

Postby prodigy » Wed 18. Sep 2013, 00:14

Thanks for the answer Vicpopo, I just got it to work.
I didn't noticed that new version of FTDI drivers were released and new version of Arduino, I didn't use my dashboard in months.
I have installed everything new and now the dashboard is working fine with OBD2. I have Speed, RPM numbers and RPM Leds. I will probably change RPM numbers to Gear number because I don't have big segment like you.

Thanks!
User avatar
prodigy
X-Sim Supporter
 
Posts: 274
Images: 42
Joined: Tue 16. Oct 2012, 12:32
Location: Pula, Croatia
Has thanked: 20 times
Been thanked: 22 times

Re: New!!OBD2 Com with Xsim3 and Arduino-New!!

Postby RacingMat » Thu 19. Sep 2013, 15:13

For information, here is the link to the drivers :
www.ftdichip.com/FTDrivers.htm

I needed these as well (for my nano and win7 64bits)
2 DOF playseat : arduino, motomonster, 12V truck wiper motors
http://www.x-sim.de/forum/viewtopic.php?f=37&t=943
User avatar
RacingMat
X-Sim Stage 2 edition
 
Posts: 456
Images: 147
Joined: Wed 20. Feb 2013, 21:30
Location: Marseille - FRANCE
Has thanked: 4 times
Been thanked: 130 times

Re: New!!OBD2 Com with Xsim3 and Arduino-New!!

Postby sirnoname » Thu 19. Sep 2013, 16:33

Hi vicpopo,

the V3 in your video only solve the 100ms delay, the hotplug option and some disconnects with high CPU load of games.
The rest is not changed.
Yokoyoko seems to have less time, so I need a verification to free this version. As far I know the only last problem was iRacing and some disconnects after some minutes of racing (maybe high cpu load). Perhaps you can help and test this?

Best regards,
SirNoName
If a answer is correct or did help you for a solution, please use the solve button.
User avatar
sirnoname
Site Admin
 
Posts: 1829
Images: 45
Joined: Thu 1. Sep 2011, 22:02
Location: Munich, Germany
Has thanked: 35 times
Been thanked: 128 times

Re: New!!OBD2 Com with Xsim3 and Arduino-New!!

Postby vicpopo » Fri 20. Sep 2013, 18:03

Hi ,

For those who would like to make a dashboard with analog gauge, I ordered some aircore gauge on e#ay .I found these aicore gauges when I was looking at analog gauge.I ordered instead these real car aircore gauge stepper motors but the gear ratio was to high 1/64.
Tombo contacted me via pm and give me the link for driving these gauges via arduino.These gauge are directly connected to output arduino pins.Below links for the library and an exemple of application :

https://github.com/clearwater/SwitecX25

http://guy.carpenter.id.au/gaugette/2012/04/04/making-wiring-harnesses/

And the test I made with one of theses aircore gauges :



Many thanks to Tombo for this research and sharing with us. ;)
Hope this aircore gauge could run fast for analog rpm gauge .

Any commentary is welcome
User avatar
vicpopo
 
Posts: 645
Joined: Fri 20. Apr 2012, 18:04
Location: Strasbourg France
Has thanked: 39 times
Been thanked: 80 times

Re: New!!OBD2 Com with Xsim3 and Arduino-New!!

Postby RacingMat » Fri 20. Sep 2013, 22:09

Bravo ! Well done !
It's smooth and fast : i'll have a look at these links :-)
2 DOF playseat : arduino, motomonster, 12V truck wiper motors
http://www.x-sim.de/forum/viewtopic.php?f=37&t=943
User avatar
RacingMat
X-Sim Stage 2 edition
 
Posts: 456
Images: 147
Joined: Wed 20. Feb 2013, 21:30
Location: Marseille - FRANCE
Has thanked: 4 times
Been thanked: 130 times

Re: New!!OBD2 Com with Xsim3 and Arduino-New!!

Postby tronicgr » Fri 20. Sep 2013, 23:13

You can find these stepper motors very cheap!!! Cool!

Here 6 of them for $14.00 (+$4.99 shipping): http://www.amazon.com/Instrument-Dashboard-Silverado-Cavalier-Avalanche/dp/B004PXAUGC


On second thought, these look exactly like the micro-stepping motors I have from my dashboard... I'll have to check their mA consumption... ;)

Thanos
User avatar
tronicgr
 
Posts: 624
Images: 11
Joined: Tue 20. Mar 2012, 22:10
Location: San Diego, CA
Has thanked: 130 times
Been thanked: 50 times

Re: New!!OBD2 Com with Xsim3 and Arduino-New!!

Postby vicpopo » Sat 21. Sep 2013, 11:22

Hi ,

Thanks for your comments.
If you had a look on the links above , you maybe noticed that there is the posibility to use also a quad driver which can drive 4 of these stepper motors with 3 wires from microcontroller.I don't know if the code could be written to drive 4 stepper motors for our application with obd2 feature and if the motor power consumption wouldn't be not so high for an arduino.
This driver could save more pins on arduino to plug another digital dashboard (gear , best lap time , temperature etc ....)

Link : http://guy.carpenter.id.au/gaugette/blog/2012/01/19/x12-quad-driver-chip/
User avatar
vicpopo
 
Posts: 645
Joined: Fri 20. Apr 2012, 18:04
Location: Strasbourg France
Has thanked: 39 times
Been thanked: 80 times

Re: New!!OBD2 Com with Xsim3 and Arduino-New!!

Postby mreiner » Mon 23. Sep 2013, 09:25

Hi

For anyone interested, here is the code, that I'm currently using for my dash with the OBD2 interface.
As I don't have the extra 7-segment display, I show the gear on the first digit.

Button 1 shows Gear and Speed.
Button 2 shows Gear and RPM.
Button 3 shows Gear and current Position.
Button 8 switches to Mode to set MaxRPM (Apply full throttle and press Button again.)

Would be great to have the OBD2 interface also provide the current fuel left in the car.

Code: Select all
//  X-Sim Sample code for receiving OBD2 values from the extractor without using the converter
//  OBD2 is industry standard, X-Sim will additionally expand the OBD2 PID with gear and other values
//
//  Usage:
//  Arduino has to be connected to a free USB port on the computer where the extractor is running
//  Open the extractor and open the settings menu, there you have to select the OBD2 menu
//  Add now your arduino comport to the OBD2 list.
//  After closing the dialog you will see the arduino LED will be enabled which represents receiving data.
//  After closing the extractor application the LED will switch off.
//  Use this code to insert your own display code at the fitting positions
//  Copyright 2013 Martin Wiedenbauer, X-Sim.de
//
//  References:
//  http://en.wikipedia.org/wiki/OBD-II_PIDs
//  http://elmelectronics.com/DSheets/ELM327DS.pdf
//  http://www.x-sim.de


#include <TM1638.h> //can be downloaded from http://code.google.com/p/tm1638-library/

// define a module on data pin 5, clock pin 4 and strobe pin 3
TM1638 module(5, 4, 3);

//définition des broches du décodeur 7 segments (vous pouvez changer
//les numéros si bon vous semble)
const int bit_A= 6;
const int bit_B= 7;
const int bit_C= 8;
const int bit_D= 9;
//Definition des Pin pour Affichage Neutral et reverse
const int bit_E= 10;
const int bit_F= 11;
const int ledPin =  13;   // the number of the LED pin
//byte buttons;
unsigned int rpmmax = 7000;
unsigned int rpmlast;
int setrpm = 0;
int mode = 1;

//long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
//long interval = 40;           // interval at which to blink (milliseconds)

bool extractordetected=false;   //Will get updated from last positive or negative receive
int receivebuffer[20]={0};      //Receive buffer


void setup()
{
   pinMode(13, OUTPUT); //Arduino UNO LED off
   digitalWrite(13, LOW);
   Serial.begin(9600);
    //Do here stuff to init display and zero to default
   pinMode(ledPin, OUTPUT);
   //The pins are all outputs
   pinMode(bit_A, OUTPUT);
   pinMode(bit_B, OUTPUT);
   pinMode(bit_C, OUTPUT);
   pinMode(bit_D, OUTPUT);
   pinMode(bit_E, OUTPUT);
   pinMode(bit_F, OUTPUT);

   //The pins are all set to low for the BCD decoder and up to neutral and reverse control
   digitalWrite(bit_A, LOW);
   digitalWrite(bit_B, LOW);
   digitalWrite(bit_C, LOW);
   digitalWrite(bit_D, LOW);
   digitalWrite(bit_E, HIGH);
   digitalWrite(bit_F, HIGH);

   // initialize the screen:
   module.clearDisplay();              //clears the display from garbage if any
   module.setDisplayToString( "X-Sim 3");    //prints the banner
   
   module.setLEDs(0b10000000 | 0b00000001<< 8 );
   delay(50);
   module.setLEDs(0b11000000 | 0b00000011<< 8 );
   delay(50);
   module.setLEDs(0b11100000 | 0b00000111<< 8 );
   delay(50);
   module.setLEDs(0b11110000 | 0b00001111<< 8 );
   delay(50);
   module.setLEDs(0b11111000 | 0b00011111<< 8 );
   delay(50);
   module.setLEDs(0b11111100 | 0b00111111<< 8 );
   delay(50);
   module.setLEDs(0b11111110 | 0b01111111<< 8 );
   delay(50);
   module.setLEDs(0b11111111 | 0b11111111<< 8 );
   delay(200);
   module.setLEDs(0b00000000 | 0b00000000<< 8 );
   delay(50);
   module.setLEDs(0b11111111 | 0b11111111<< 8 );
   delay(100);
   module.setLEDs(0b00000000 | 0b00000000<< 8 );
   delay(50);
   module.setLEDs(0b11111111 | 0b11111111<< 8 );
   delay(100);
   module.setLEDs(0b00000000 | 0b00000000<< 8 );
   delay(50);
   module.setLEDs(0b11111111 | 0b11111111<< 8 );
   delay(100);
   module.setLEDs(0b00000000 | 0b00000000<< 8 );
   delay(3000);                         //small delay 3 sec
   module.clearDisplay();              //clears the 1st display
}


int HexToInt(int c)
{
   if (c >= '0' && c <= '9')
   {
      return c - '0';
   }
   else if (c >= 'a' && c <= 'f')
   {
      return c - 'a' + 10;
   }
   else if (c >= 'A' && c <= 'F')
   {
      return c - 'A' + 10;
   }
   else
   {
      return -1; // getting here is bad: it means the character was invalid
   }
}

int ParseReceiveBuffer(int commandhighbyte, int commandlowbyte, int receivelength)
{
   //First character is removed of the receivebuffer string and must not be verified again
   if( receivebuffer[0]=='1' && receivebuffer[2]==commandhighbyte && receivebuffer[3]==commandlowbyte )
   {
      //Parse 2 byte values on position 5 and 6 in the buffer string
      if(receivelength==7)
      {
         int highresult=HexToInt(receivebuffer[5]);
         int lowresult =HexToInt(receivebuffer[6]);
         if(highresult==-1 || lowresult==-1){return -1;}
         return ((16*highresult) + lowresult);
      }
      //Parse 4 byte values on position 5,6,8 and 9 in the buffer string
      if(receivelength==10)
      {
         int tophighresult=HexToInt(receivebuffer[5]);
         int toplowresult =HexToInt(receivebuffer[6]);
         int highresult=HexToInt(receivebuffer[8]);
         int lowresult =HexToInt(receivebuffer[9]);
         if(tophighresult==-1 || toplowresult==-1 || highresult==-1 || lowresult==-1){return -1;}
         return ((4096*tophighresult) + (256*toplowresult) + (16*highresult) + lowresult);
      }
   }
   return -1; //Something is wrong with the returned OBD2 echo command byte
}

//This function will wait for the first character in receivetrigger and will parse the result
int ReceiveValueWithTimeout(int receivetrigger, int commandhighbyte, int commandlowbyte, int receivelength)
{
   int arduinoserialbuffer=0;
   int buffercount=-1;
   for(int z=0; z < 500; z++) //500ms timeout should be enough
   {
      while(Serial.available())
      {
         if(buffercount==-1)
         {
            arduinoserialbuffer = Serial.read();
            if(arduinoserialbuffer != receivetrigger) //Wait until the trigger is reached, ignore echo, first character is not in the buffer
            {
               buffercount=-1;
            }
            else
            {
               buffercount=0;
            }
         }
         else
         {
            arduinoserialbuffer = Serial.read();
            receivebuffer[buffercount]=arduinoserialbuffer;
            buffercount++;
            if(buffercount > receivelength) //buffer has now waitlen character length
            {
               return ParseReceiveBuffer(commandhighbyte, commandlowbyte, receivelength);
               buffercount=-1;
            }
         }
      }
      delay(1);
   }
   return -1;
}

void SendEchoDisabled() //not used here and a part of the OBD2 ELM327 specifications, as INFO
{
   //ATE0 Echo disabled
   Serial.write('A');
   Serial.write('T');
   Serial.write('E');
   Serial.write('0');
   Serial.write('\r');
}

//010c Request RPM, remember:  OBD2 RPM is ((A*256)+B)/4
int GetOBD2RpmValue()
{
   //010c
   Serial.write('0');
   Serial.write('1');
   Serial.write('0');
   Serial.write('c');
   Serial.write('\r');
   return ReceiveValueWithTimeout('4','0','C',10);
}

//010d Request speed in kmh
int GetOBD2SpeedValue()
{
   //010d
   Serial.write('0');
   Serial.write('1');
   Serial.write('0');
   Serial.write('d');
   Serial.write('\r');
   return ReceiveValueWithTimeout('4','0','D',7);
}

//01e0 Request gear number
int GetOBD2GearValue()
{
   //01e0
   Serial.write('0');
   Serial.write('1');
   Serial.write('e');
   Serial.write('0');
   Serial.write('\r');
   return ReceiveValueWithTimeout('4','E','0',7);
}

//01e1 Request curent position
int GetOBD2PositionValue()
{
   //01e0
   Serial.write('0');
   Serial.write('1');
   Serial.write('e');
   Serial.write('1');
   Serial.write('\r');
   return ReceiveValueWithTimeout('4','E','1',7);
}

//function to display the gear on the big 7 segmemts display
void afficher(char chiffre)
{
   // pin are all set to lower levelet high level for neutral reverse
   digitalWrite(bit_A, LOW);
   digitalWrite(bit_B, LOW);
   digitalWrite(bit_C, LOW);
   digitalWrite(bit_D, LOW);
   digitalWrite(bit_E, HIGH);
   digitalWrite(bit_F, HIGH);
   //display the numerical needed
   if(chiffre >= 8)
   {
      digitalWrite(bit_D, HIGH);
      chiffre= chiffre - 8;
   }
   if(chiffre>= 4)
   {
      digitalWrite(bit_C, HIGH);
      chiffre= chiffre - 4;
   }
   if(chiffre >= 2)
   {
      digitalWrite(bit_B, HIGH);
      chiffre= chiffre - 2;
   }
   if(chiffre >= 1)
   {
      digitalWrite(bit_A, HIGH);
      chiffre= chiffre - 1;
   }
}

void loop()
{
    //unsigned long currentMillis = millis();
    int          i ;
   char*          neutral = "n";                // sets the character for neutral
   char*          reverse = "r";                // sets the character for reverse
    unsigned int    rpmleds; //holds the 8 leds values
    char          message [8];     // variable to display the message on the display
   int          speed = 0;
   unsigned int    rpm;
   unsigned int   pos;
   int          gear = GetOBD2GearValue();
   byte          button;
   String          output;
   
   while( gear >= 0 )
   {
      //unsigned long currentMillis = millis();   
        if(extractordetected==false)
      {
         SendEchoDisabled();   //Will cause a OK\r as answer from the extractor, ignored in this code
         extractordetected=true;
      }
      //Read all values
      gear = GetOBD2GearValue(); //Notice: offset +1 because of reverse gear
      speed = GetOBD2SpeedValue();
      rpm  = GetOBD2RpmValue();
      pos = GetOBD2PositionValue();
        rpm = rpm/4;
        //unsigned long currentMillis = millis();
      
      button = module.getButtons();
      
      switch ( button )
      {
         case 0b00000001:
            mode = 1;
            module.clearDisplay();
            output = "Gear Spd";
            module.setDisplayToString( output );
                delay ( 500 );
            module.clearDisplay();
            break;
         case 0b00000010:
            mode = 2;
            module.clearDisplay();
            output = "Gear Rpm";
            module.setDisplayToString( output );
                delay ( 500 );
            module.clearDisplay();
            break;
         case 0b00000100:
            mode = 3;
            module.clearDisplay();
            output = "Posion";
            module.setDisplayToString( output );
            delay ( 500 );
            module.clearDisplay();
            break;
         case 0b00001000:   mode = 4;
            break;
         case 0b00010000:   mode = 5;
            break;
         case 0b00100000:   mode = 6;
            break;
         case 0b01000000:   mode = 7;
            break;
         case 0b10000000:   
            mode = 8;
            module.clearDisplay();
            switch ( setrpm )
                {
                  case 0:
                    setrpm = 1;
                    output = "Set RPM";
                    rpmmax = 100;
                    module.setDisplayToString( "Set RPM" );
                    mode = 8;
                    delay (500);
                    break;
                   
                  case 1:
                    setrpm = 0;
                    module.clearDisplay();
               module.setDisplayToString( "Gear Spd" );
                    mode = 1;
                    delay (500);
                    break;
                }
            break;
      }
      
      if(gear!=-1 && speed!=-1 && rpm!=-1)
      {
         digitalWrite(13, HIGH); //We have connection and all values are ok, turn on the LED
         
         //Do here your LCD or display stuff
         
         if ( mode == 1 )
         {
            module.setDisplayToDecNumber( speed, 0, false );  //displays numerical the speed
            if ( gear >= 2 and gear <10 )
            {
               module.setDisplayDigit( gear - 1, 0, false );   // displays numerical value of the current gear
            }
            if ( gear == 1 )
            {
               module.setDisplayToString( neutral, 0, 0 );  // displays the character for neutral
            }
            if ( gear == 0 )
            {                        // -1 that reprecents reverse rollover to 255 so...
               module.setDisplayToString( reverse, 0, 0 );  // displays the character for reverse
            }
         }
         
         if ( mode == 2 )
         {
            module.setDisplayToDecNumber( rpm, 0, false );  //displays numerical the speed
            if ( gear >= 2 and gear <10 )
            {
               module.setDisplayDigit( gear - 1, 0, false );   // displays numerical value of the current gear
            }
            if ( gear == 1 )
            {
               module.setDisplayToString( neutral, 0, 0 );  // displays the character for neutral
            }
            if ( gear == 0 )
            {                        // -1 that reprecents reverse rollover to 255 so...
               module.setDisplayToString( reverse, 0, 0 );  // displays the character for reverse
            }
         }
         
         if ( mode == 3 )
         {
            module.setDisplayToDecNumber( pos, 0, false );
            if ( gear >= 2 and gear <10 )
            {
               module.setDisplayDigit( gear - 1, 0, false );   // displays numerical value of the current gear
            }
            if ( gear == 1 )
            {
               module.setDisplayToString( neutral, 0, 0 );  // displays the character for neutral
            }
            if ( gear == 0 )
            {                        // -1 that reprecents reverse rollover to 255 so...
               module.setDisplayToString( reverse, 0, 0 );  // displays the character for reverse
            }
         }

         if ( mode == 8 )
         {
                module.setDisplayToDecNumber( rpmmax, 0, false );
                if ( rpmlast > ( rpmmax + 200 ) )
            {
               rpmmax = rpmlast;
                }
         }
         
         
         //color the leds
         
            rpmleds = map( rpm,0,rpmmax,0,16 );    // distributes the rpm level to the 8 leds + 1 for shift change
         if ( rpmleds==1 ) {
            module.setLEDs( 0b00000000 | 0b00000000 << 8);
         }
         if ( rpmleds==7 ) {
            module.setLEDs( 0b00000001 | 0b00000000 << 8 );
         }
         if ( rpmleds==8 ) {
            module.setLEDs( 0b00000011 | 0b00000000 << 8 );
         }
         if ( rpmleds==9 ) {
            module.setLEDs( 0b00000111 | 0b00000000 << 8 );
         }
         if ( rpmleds==10 ) {
            module.setLEDs( 0b00001111 | 0b00000000 << 8 );
         }
         if ( rpmleds==11 ) {
            module.setLEDs( 0b00011111 | 0b00000000 << 8 );
         }
            if ( rpmleds==12 ) {
            module.setLEDs( 0b00111111 | 0b00000000 << 8 );
         }
            if ( rpmleds==13 ) {
            module.setLEDs( 0b01111111 | 0b00000000 << 8 );
         }
         if ( rpmleds==14 ) {
            module.setLEDs( 0b00000000 | 0b11111111 << 8 );
         }
         if ( rpmleds>=15 ) {
            module.setLEDs( 0b00000000 | 0b11111111 << 8 );
            delay ( 20 );
            module.setLEDs( 0b00000000 | 0b00000000 << 8 );
            delay ( 20 );
         }
      }         
      
      rpmlast = rpm;
   }

   extractordetected=false;
   digitalWrite(13, LOW); //No connection, turn off the LED

   //Do here stuff to set display to zero or default
   module.setDisplayToString( "No Data" );    //prints the banner
}
mreiner
 
Posts: 32
Images: 22
Joined: Wed 15. May 2013, 08:53
Location: Lower Austria / Europe
Has thanked: 1 time
Been thanked: 15 times

Re: New!!OBD2 Com with Xsim3 and Arduino-New!!

Postby vicpopo » Mon 23. Sep 2013, 19:50

Hi Mreiner,

Thanks for sharing your code !

I watch at your code and I had a idea to change my code . To avoid using buttons to increase or decrease the rpmmax ,now you push the last button when gear is at neutral and push the throttle to the maximum to get the maxrpm .The rpmmax is registered , and for blinking the leds correctly I changed the code as follow "rpmleds = map( rpm, 0, rpmmax-400,0,5) " , when the rpm achieve rpmmax -400 rpm the leds flashing to indicate gear up.

In the code you can change the timeout line for the next xsim relaease (if it works now change anything , you can just test)

"for (int z= 0 , z<500 ,z++) " you can test changing 500 to 1500.
User avatar
vicpopo
 
Posts: 645
Joined: Fri 20. Apr 2012, 18:04
Location: Strasbourg France
Has thanked: 39 times
Been thanked: 80 times

PreviousNext

Return to Peripheral Projects

Who is online

Users browsing this forum: No registered users and 1 guest