Bike interface OBD

Hi

I hava a suzuki gsx-r 1000 and want to log the serial data that the bike transmits over the k-line diagnostics interface called SDS:..
First step ist to attach a pc and log the comunication between pc and ecu. I want to use an arduino board if it ist possible...
Is it possible to connect each serial line to an rx line of the arduino and log them to sd?
I dont know exactly the baud rates, this is what i neet to find out...

Later i want to use the logged information to create a file definition and write direktly to ecu and store the recieved data to sd and maybee monitor it to an tft or webserver...
There are people who did this, i have a lot of definitions from them, but im not sure about the comunication...

1 Like

please replace the BMP image with a JPEG as it now take almost 3MB for a relative simple image.
a jpeg for this would be (estimate) 30x smaller.

you need a logic analyzer to determine the baudrate and to see the data.
another point of attention is what voltage comes out of the ECU as Arduino and the (USB) PC uses 0..5V levels.
The ECU might use real rs232 which uses higher voltages.

Ok..
About the Voltage, i need to add some ics, because the data is transfered by K-Line.. It is not problematic...
But i dont know if the sketch work.
I put a serial read of both serials in loop an than a print command... Is the arduino fast enough to write every single bit or i need to write first into ram? I think it sounds a litlebit strange, but im new here :smiley:
Later i post the sketch i have made...

probably the speed of the OBD is low to medium speed to be 100% reliable. You could use MAX speed for your print command

What board are you using UNO/MEGA?

Ok it works, i used the 10400 baud as described for kwp2000 on the RX Serial Ports.
First i connect to the print port whit 9600 and of course it was to slow, i changed it to 57600 and it was ok :smiley:
Now i have send and response data...
Here my sketch

void setup() {
  // initialize serial ports:
  //console
  Serial.begin(57600);    
  // Serial PORT 1
  Serial1.begin(10400);
  // Serial PORT 2
  Serial2.begin(10400);
  // Welcome Message
  Serial.println("##################################################");
  Serial.println("###########  Serial Logging Interface  ###########");
  Serial.println("##################################################");
  Serial.println();
}
void loop() {
    if (Serial1.available()) {
      Serial.print("ECU: ");
      Serial.print(Serial1.read(), HEX);
      Serial.println("");
    if (Serial2.available()) {
      Serial.print("PC: ");
      Serial.print(Serial2.read(), HEX);
      Serial.println("");
  }
}

But now i neet to know how the initialiton works... I saw something in the obduino sketch an i think i try that...

This is the Logfile:
I think the pc writes a lot of strings whitout reading answeres at the same time. The Ecu at this point is much slower answering because the string is longer...
Ex.
PC Startpoint: bla bla bla bla bla bla
ECU Startpoint: blablablablabla blablablablabla blablablablabla blablablablabla blablablablabla blablablablabla

PC: 80
ECU: 12
PC: 12
ECU: F1
PC: F1
ECU: 2
PC: 2
ECU: 21
PC: 21
PC: 80
ECU: 80
PC: 26
ECU: 26
ECU: 80
ECU: F1
ECU: 12
ECU: 66
ECU: 61
ECU: 80
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: FF
ECU: FF
ECU: FF
ECU: FF
ECU: FF
ECU: FF
ECU: 57
ECU: 6B
ECU: 62
ECU: FF
ECU: FF
ECU: FF
ECU: 80
ECU: 15
ECU: FF
ECU: FF
ECU: FF
ECU: 0
ECU: 80
ECU: 0
ECU: FF
ECU: 80
ECU: 0
ECU: FF
ECU: FF
ECU: FF
ECU: 80
ECU: FF
ECU: FF
ECU: FF
ECU: FF
ECU: 80
ECU: 80
ECU: 80
ECU: 80
ECU: 0
ECU: D
ECU: 0
ECU: D
ECU: 0
ECU: D
ECU: 0
ECU: D
ECU: FF
ECU: FF
ECU: 80
ECU: 0
ECU: 15
ECU: 0
ECU: 1D
ECU: 0
ECU: 17
ECU: FF
ECU: FF
ECU: FF
ECU: FF
ECU: 80
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 80
ECU: 80
ECU: 80
ECU: 80
ECU: FF
ECU: FF
ECU: FF
ECU: FF
ECU: FF
ECU: FF
ECU: FF
ECU: 8C
ECU: 80
ECU: F0
ECU: C1
ECU: FF
ECU: FF
ECU: FF
ECU: FF
PC: 80
ECU: FF
PC: 12
ECU: FF
PC: F1
ECU: 16
PC: 2
ECU: E5
PC: 21
ECU: 5
PC: 8
ECU: 0
PC: AE
ECU: 0
ECU: FF
ECU: FF
ECU: 14
ECU: 80
ECU: 12
ECU: F1
ECU: 2
ECU: 21
ECU: 8
ECU: AE
ECU: 80
PC: 80
ECU: 12
PC: 12
ECU: F1
PC: F1
ECU: 2
PC: 2
ECU: 21
PC: 21
PC: 8
ECU: 8
ECU: AE
PC: AE
ECU: 80
ECU: F1
ECU: 12
ECU: 34
ECU: 61
ECU: 8
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: FF
ECU: FF
ECU: FF
ECU: FF
ECU: 0
ECU: 0
ECU: 3A
ECU: A1
ECU: 52
ECU: 4E
ECU: A1
ECU: 0
ECU: FF
ECU: 0
ECU: FF
ECU: FF
ECU: FF
ECU: FF
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: FF
ECU: FF
ECU: 40
ECU: 40
ECU: 40
ECU: 40
ECU: FF
ECU: F4
ECU: FF
ECU: FF
ECU: FF
ECU: 0
ECU: 0
ECU: 4
ECU: 8
ECU: FF
ECU: FF
ECU: 2B
ECU: 80
PC: 80
ECU: 12
PC: 12
ECU: F1
PC: F1
ECU: 2
PC: 2
ECU: 21
PC: 21
ECU: 8
PC: 8
ECU: AE
PC: AE
ECU: 80
ECU: F1
ECU: 12
ECU: 34
ECU: 61
ECU: 8
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: FF
ECU: FF
ECU: FF
ECU: FF
ECU: 0
ECU: 0
ECU: 3A
ECU: A1
ECU: 52
ECU: 4E
ECU: A1
ECU: 0
ECU: FF
ECU: 0
ECU: FF
ECU: FF
ECU: FF
ECU: FF
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: FF
ECU: FF
ECU: 40
ECU: 40
ECU: 40
ECU: 40
ECU: FF
ECU: F4
ECU: FF
ECU: FF
ECU: FF
ECU: 0
ECU: 0
ECU: 4
ECU: 8
ECU: FF
ECU: FF
ECU: 2B
ECU: 80
PC: 80
ECU: 12
PC: 12
ECU: F1
PC: F1
ECU: 2
PC: 2
ECU: 21
PC: 21
ECU: 8
PC: 8
ECU: AE
PC: AE
ECU: 80
ECU: F1
ECU: 12
ECU: 34
ECU: 61
ECU: 8
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: FF
ECU: FF
ECU: FF
ECU: FF
ECU: 0
ECU: 0
ECU: 3A
ECU: A1
ECU: 52
ECU: 4E
ECU: A1
ECU: 0
ECU: FF
ECU: 0
ECU: FF
ECU: FF
ECU: FF
ECU: FF
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: FF
ECU: FF
ECU: 40
ECU: 40
ECU: 40
ECU: 40
ECU: FF
ECU: F4
ECU: FF
ECU: FF
ECU: FF
ECU: 0
ECU: 0
ECU: 4
ECU: 8
ECU: FF
ECU: FF
ECU: 2B
ECU: 80
PC: 80
ECU: 12
PC: 12
ECU: F1
PC: F1
ECU: 2
PC: 2
ECU: 21
PC: 21
ECU: 8
PC: 8
ECU: AE
PC: AE
ECU: 80
ECU: F1
ECU: 12
ECU: 34
ECU: 61
ECU: 8
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: FF
ECU: FF
ECU: FF
ECU: FF
ECU: 0
ECU: 0
ECU: 3A
ECU: A1
ECU: 52
ECU: 4E
ECU: A1
ECU: 0
ECU: FF
ECU: 0
ECU: FF
ECU: FF
ECU: FF
ECU: FF
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: 0
ECU: FF
ECU: FF
ECU: 40
ECU: 40
ECU: 40
ECU: 40
ECU: FF
ECU: F4
ECU: FF
ECU: FF
ECU: FF
ECU: 0
ECU: 0
ECU: 4
ECU: 8
ECU: FF
ECU: FF
ECU: 2B
ECU: 80

small remark

      Serial.print(Serial1.read(), HEX);
      Serial.println("");

==>

      Serial.println(Serial1.read(), HEX);

:wink:

try to change loop to

void loop()
{
    if (Serial2.available()) 
    {
        Serial.print("PC:\t");
        while(Serial2.available())
        {
            int b = Serial2.read();
            if (b < 10) : Serial.print("0");
            Serial.print(b , HEX);
            Serial.print(" ");
        }
        Serial.println();
    }

    if (Serial1.available()) 
    {
        Serial.print("ECU:\t");
        while(Serial1.available())
        {
            int b = Serial1.read();
            if (b < 10) : Serial.print("0");
            Serial.print(b , HEX);
            Serial.print(" ");
        }
        Serial.println();
    }
}

might give you more insight in the handshakes

Now i need to do this whit the arduino, dont know where begin, maybee by decoding it?
I have a question, the digital outputs, if state is not defined are they on high resistance? There are some pins on the ecu e want to switch but i only know that they can be switched by switches, if i put them from 0-5V maybee it want work.. 2 are switched to 0V one to 5V... Is it possibe to use the arduino as serial to usb converter? If i put a switch the inputs from usb / serial 0 to an other port... Or is it dangerous for the arduino because it is the programing interface?

Hi, i did some work...
But i added only some analog inputs and one serial for the Wideband Lambda...
How is the best way to get the code? I think an array would be the best way to go?
How can i create the checksum of an array whit 61 values?

#include <SD.h>
#include <UTFT.h>

#define CONSOLE Serial                      // CONSOLE PORT
#define CONSOLEBAUD 57600
#define WBL Serial1                          // WIDEBAND LAMBDA PORT
#define WBLBAUD 9600
#define SDS Serial2                          // SDSPORT
#define SDSBAUD 10400

const int chipSelect = 53;                  // SD CS Pin
const int startlog = 8;                     // Start stop
const int mode = 9;                         // Logger - Flash mode

float sensors[99];
String name_sensors[99];

int inputpin;
int numbersensors;
int lineposition;
int sensornumber;
int SDPRESENT;
int SDDETECT;

extern uint8_t SmallFont[];
extern uint8_t BigFont[];

UTFT myGLCD(SSD1289,38,39,40,41);

void getvalues();
void clear_console();
void sd_print();
void console_print();
void tft_printvalues();
void sd_init();

void setup() {
  CONSOLE.begin(CONSOLEBAUD);
  WBL.begin(WBLBAUD);
  SDS.begin(SDSBAUD);

  pinMode(startlog, INPUT);
  pinMode(mode, INPUT);
  pinMode(10, OUTPUT);

  myGLCD.InitLCD();
  myGLCD.clrScr();
  myGLCD.setFont(SmallFont);
  myGLCD.fillScr(0, 0, 150);
  myGLCD.setBackColor(0, 0, 150);
  myGLCD.setColor(255,255,255);
}

void loop() {
  getvalues();
  sd_init();
  sd_print();
  console_print();
  tft_printvalues();
  clear_console();
}

void getvalues () {
  sensornumber = 0;
  inputpin = 3;
  name_sensors[sensornumber] = "Abgas Temp (analog) [C]";
  sensors[sensornumber] = float(analogRead(inputpin)) / 1.5 - 200;

  sensornumber = 1;
  inputpin = 4;
  name_sensors[sensornumber] = "Motor Temp (analog) [C]";
  sensors[sensornumber] = float(analogRead(inputpin)) * 0.1;

  sensornumber = 2;
  inputpin = 5;
  name_sensors[sensornumber] = "Drosselklappe (analog) [%]";
  sensors[sensornumber] = float(analogRead(inputpin)) * 0.103 ;

  sensornumber = 3;
  name_sensors[sensornumber] = "Gemisch (seriell) [LAMBDA]";
  if (WBL.available() > 0) {
    sensors[sensornumber] = WBL.read();
  }

  numbersensors = sensornumber;
}

void tft_printvalues() {
  for (sensornumber = 0;sensornumber <= numbersensors; sensornumber = sensornumber + 1) {
    myGLCD.print(name_sensors[sensornumber], LEFT, lineposition);
    myGLCD.print(String(int(sensors[sensornumber])), RIGHT, lineposition);
    lineposition = lineposition + 20;
  }
  lineposition = 0;
}
void console_print() {
  for (sensornumber = 0;sensornumber <= numbersensors; sensornumber = sensornumber + 1) {
    CONSOLE.print(name_sensors[sensornumber]);
    CONSOLE.print(": ");
    CONSOLE.println(sensors[sensornumber]);
  }
}
void clear_console() {
  CONSOLE.write(27);
  CONSOLE.print("[2J");
  CONSOLE.write(27);
  CONSOLE.print("[H");
}
void sd_init() {
  while (!SDDETECT) {
    CONSOLE.println("###### Detecting SD Card ######"); 
    myGLCD.print("###### Detecting SD Card ######", CENTER, 220);
    if (!SD.begin(chipSelect)) {
      CONSOLE.print("#### SD Card not found ######");
      myGLCD.print("###### SD Card not found ######", CENTER, 220);
      SDDETECT++;
    }
    else {
      CONSOLE.print("###### SD Card Initialized ######");
      myGLCD.print("###### SD Card Initialized ######", CENTER, 220);
      SDDETECT++;
      SDPRESENT++;
    }
  }
}
void sd_print() {
  if ((SDPRESENT)&&(SDDETECT)) {
    File datafile = SD.open("LOGFILE.TXT", FILE_WRITE);
    if (datafile) {
      CONSOLE.println("###### Writing into LOGFILE.TXT ######");
      myGLCD.print("###### Writing into LOGFILE.TXT ######", CENTER, 220);
      datafile.print(millis());
      for (sensornumber = 0;sensornumber <= numbersensors; sensornumber = sensornumber + 1) {
        datafile.print(":");
        datafile.print(sensors[sensornumber]);
      }
      datafile.println(":");
      datafile.close();
    }
    else {
      CONSOLE.println("###### SD Card writing ERROR ######");
      myGLCD.print("###### SD Card writing ERROR ######", CENTER, 220);
      SDPRESENT = 0;
    }
  }
}

How can i create the checksum of an array whit 61 values?

a for loop over all 61 values

  • either with a defined formula
  • or your own formula (simplest is to add all the values and see if the sum matches)

Ok, i have managed the formula.. Now, at the start of the communication i need to do a fastinit how it ist described in kwp protocol.. I need to put the Serial output for 300ms high than 25ms low and again 25ms low before i can start the serial communication whit 10400baud... or slowinit is 0x33 @ 5 baud...
Can i do "serial.begin(baud)" more than 1 time?

o5i_:
Ok, i have managed the formula.. Now, at the start of the communication i need to do a fastinit how it ist described in kwp protocol.. I need to put the Serial output for 300ms high than 25ms low and again 25ms low before i can start the serial communication whit 10400baud... or slowinit is 0x33 @ 5 baud...
Can i do "serial.begin(baud)" more than 1 time?

Yes you can but this sounds more like you need a dedicated handshake , setting high and low "manually".
in my (limited) experience the very low baud rates are not that reliable

How can i manage it?
I want to do fastinit how described in kwp2000 ISO 14230 ...

use digitalWrite(1, HIGH/LOW);
and use delay to time the pulses.
Be sure your serial buffer is empty when starting

I have a lot of trouble get this done..
Somone want to help me?
I tried to read the data while it is connected to the pc but it won`t work... But i earn only a lot of bugs...
same whit init... Dont know whats wrong... Im shure there are people who did this successfull...
But whitout skills no way...

I have some parts and information that could be helpful. I'm not at home right now. What country or area are you from? I will try to post more later on.

Hi, im from north italy.. If you can help me would be great :slight_smile:

o5i,

The first thing you will need is the hardware to connect your 5 volt arduino to your 12 volt motorcycle communication line. I have a circuit board that uses a LM393 as a level shifter. I had a bunch of circuit boards made and I was selling an interface that goes from computer USB to the bikes computer.....I have a few boards left over. They work with 07 GSXRs and newer as far as I know. Personally, I have an 08 GSXR and it works well on it. If you want to go the computer route, let me know. Otherwise, I will help you with your Arduino project.

I have put a lot of work on getting an Atmel 1284 chip to talk to the motorcycle computer and I have had some success but, the project is not completed. I will share some of my hard work with you to get you started.

Here is the initiation part of the code that works well for me. I am providing you with a snippet to get you started. After the initiation part of the code, you are going to need read incoming data. Add you coding ideas, put in effort, and I will help more.

You will need to define your TX and RX pins based on the board you are using. In my case, my board is the Bobuino with a 1284 chip.

//variables
byte message[6] = {
  0x81,0x12,0xF1,0x81,0x05};
int mode = 0;
/////////////////DATA START///////////////
void datastart(){
  mode = 0;                 //reset mode to 0 for first step of logging
  digitalWrite (TX, HIGH);  // makes K-line high 3
  digitalWrite(ledPin,HIGH);
  delay(2000);             // wait for K-line to be clear 3
  digitalWrite (TX, LOW);  // makes K-line low  3
  delay(25);
  digitalWrite (TX, HIGH); // makes K-line high  3
  delay(25);               //last delay before first message
  Serial1.begin(10400);  // baud rate of the OBD
  //send package 0x81,0x12,0xF1,0x81,0x05
  for (int i = 0; i < 5; i++){
    Serial1.write(message[i]);
    byte inByte = Serial1.read();
    delay(1);                 //inter byte delay for to match k-line spec. changed from 15ms to 1, tune as needed
  }
}