Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connect with Honda #5

Open
man-go1 opened this issue May 4, 2020 · 29 comments
Open

Connect with Honda #5

man-go1 opened this issue May 4, 2020 · 29 comments

Comments

@man-go1
Copy link

man-go1 commented May 4, 2020

Hi,
Want to readout my bike using an Arduino.
I used some code to connect to it. But I can’t do anything past the handshake.
So I want to use you library. Can you help out?

@aster94
Copy link
Owner

aster94 commented May 5, 2020

Yes, as you may have read the library is not ready for Honda, yet.
Which model is your bike and year?
Do you have a sequence of request known to work?

@man-go1
Copy link
Author

man-go1 commented May 5, 2020

great,
I think i have the same bike as Stefan (in the other issue). its a VFR. m'n is from 2010.
i looked around on internet and found a table mapping http://projects.gonzos.net/wp-content/uploads/2015/09/Honda-data-tables.pdf
and it looks like all info is in table 16 for my bike. but it's not saying how and what.
i think i can figure that out what is wat. but i can't get a connection.
first off i'm not an expert. juist looked for stuf on the internet
what i think is needed.
send a low
wait 70 ms
Send a hi
wait 120ms
send a wake up:
0xFE, 0x04, 0x72, 0x8C
wait 200Ms
send a handshake?!
0x72, 0x05, 0x00, 0xF0, 0x99
and the ECU needs to respond with 02 04 00 FA

@aster94
Copy link
Owner

aster94 commented May 5, 2020

@man-go1 if you can double-check this sequence:

send a low
wait 70 ms
Send a high
wait 120ms
send: 0xFE, 0x04, 0x72, 0x8C
wait 200Ms
send: 0x72, 0x05, 0x00, 0xF0, 0x99

I can write a code for you, I will check with my logic analyzer and then I will send it to you
But I can't do it before Saturday

@man-go1
Copy link
Author

man-go1 commented May 5, 2020

i think so. what i did( see below) and i get a succes back.

//initialise communications
byte initHonda(){
debug.println("Starting initialise Honda");
bike.end();
delay(350);
//Sending LOW
digitalWrite(TX_PIN, LOW);
delay(70);
//Sending High
digitalWrite(TX_PIN, HIGH);
delay(120);
pinMode(TX_PIN, OUTPUT);
//Start Bike serial
bike.begin(10400);
bike.write(MessageWakeup, sizeof(MessageWakeup)); //Send WakeUp
delay(200);
bike.write(MessageInitialise, sizeof(MessageInitialise)); // initialise communications
bike.flush(); // wait to send all

resState = BUSY;
// Try to read a wakeup is send
while (resState == BUSY) resState = getResponse(resbuf);
if (resState == SUCCESS) {
delay(300);
resState = BUSY;
// Try to read initialise response
while (resState == BUSY) resState = getResponse(resbuf);
if (resState == SUCCESS) {

   if (resState == SUCCESS) {
      return SUCCESS; 
   } else {
        debug.println("Failed init Honda, something is wrong retry"); // Return false if diagnostic mode request was denied or failed
        return BUSY; 
     }
}
if (resState == TIMEOUT){
    debug.println("TIMEOUT init Honda"); // Return false if diagnostic mode request was denied or failed
    return BUSY; 
}

}
if (resState == TIMEOUT){
debug.println("TIMEOUT WakeUp Honda"); // Return false if diagnostic mode request was denied or failed
return BUSY;
}
}

@aster94
Copy link
Owner

aster94 commented May 5, 2020

where does your code stuck?

@man-go1
Copy link
Author

man-go1 commented May 5, 2020

This part is okay. But I can’t get info out of tables.

@aster94
Copy link
Owner

aster94 commented May 7, 2020

can you post what are you getting from the ECU?

@man-go1
Copy link
Author

man-go1 commented May 7, 2020

hi,
sorry for the late response but i fryde my Arduino.. and needed to fix it. i think i know how to communication works. i can get table 16 from the bike and calculate the RPM.

now i just need to implement it with your code.
This is my code: ( yeah its a mess, just needed it to talk)

`*/
#define SWversion "version 0.4"
// Serial Debug USB
#define debug Serial
//Serial to connect to the bike
#define bike Serial1
#define TX_PIN 18
#define t0

//Status Flags
#define SUCCESS 0
#define TIMEOUT 1
#define BUSY 2
#define BUFFEROVERFLOW 3

// default variable
// Flag for ECU connection
byte ECUconnected;
byte resbuf[26];
byte resState;
uint16_t RPM;

//initialise communications messages
byte MessageWakeup[] = {0xFE, 0x04, 0x72, 0x8C}; // wakeup no responce from ECU
byte MessageInitialise[] = {0x72, 0x05, 0x00, 0xF0, 0x99}; //initialise communications The ECU should respond with: 02 04 00 FA

//get info from ECU VFR Specific
byte Table00[] = { 0x72, 0x07, 0x72, 0x00, 0x00, 0x06, 0x0F}; //unknown
byte Table10[] = { 0x72, 0x07, 0x72, 0x10, 0x00, 0x06, 0xFF}; //unknown
byte Table11[] = { 0x72, 0x07, 0x72, 0x11, 0x00, 0x06, 0xFE}; //unknown
byte Table16[] = { 0x72, 0x07, 0x72, 0x16, 0x00, 0x06, 0xF9}; //vfr 1200f responce
byte Table20[] = { 0x72, 0x07, 0x72, 0x20, 0x00, 0x06, 0xEF}; //unknown
byte Table21[] = { 0x72, 0x07, 0x72, 0x21, 0x00, 0x06, 0xEE}; //unknown
byte TableD0[] = { 0x72, 0x07, 0x72, 0xD0, 0x00, 0x06, 0x3F}; //unknown
byte TableD1[] = { 0x72, 0x07, 0x72, 0xD1, 0x00, 0x06, 0x3E}; //unknown
byte Table61[] = { 0x72, 0x07, 0x72, 0x61, 0x00, 0x06, 0xAE}; //unknown
byte Table70[] = { 0x72, 0x07, 0x72, 0x70, 0x00, 0x06, 0x9F}; //unknown

// needed to calculate checksum
byte calculate[] = {0x72, 0x07, 0x72, 0x60, 0x00, 0x06};

void setup() {
// put your setup code here, to run once:
debug.begin(115200);// For debugging
debug.println("Starting setup");
// needed for Bluetooth
//EEBlue.begin(9600); //Default Baud for comm, it may be different for your Module.

}

void loop() {

unsigned long startedWaiting = millis();

ECUconnected = BUSY;
//Try to connect with the ECU
while (ECUconnected == BUSY){
 ECUconnected = initHonda();
 }
while (ECUconnected == SUCCESS) {

   // Request table 16
  bike.write(Table16, sizeof(Table16));
  bike.flush();
  bikeFlush();
  // Receive the response. Receiving this way will block the Arduino.
  resState = BUSY;
  delay(300);
  //checkResponse();
  while (resState == BUSY) {
    resState = getResponse(resbuf);
  }
  // Successfully received the response message which is stored in resbuf
  if (resState == SUCCESS) {
   // Check if response is positive
     if (resbuf[3] == 0x16) { // change from 0x16 to D1
        uint16_t varY = resbuf[5];
        varY = varY << 8;
        varY = varY + resbuf[4];
        RPM = varY;            
        // Do something with RPM e.g. show on LCD
        debug.println("");
        debug.print("RPM ");
        debug.println(RPM,DEC);
        debug.println("");  
        debug.println("Tabel 16");          
        debug.print("hex");
        debug.println("");
        
        for(int i = 0; i< 26; i++)
         {
           debug.print(resbuf[i],HEX);
           debug.print("-");
          }
        debug.println("");

     } 
     else {
        // No positive response, reset ECU connection
        ECUconnected = BUSY;
     }
} 
else if (resState == TIMEOUT) {
  // Timeout, reinitiate ECU
  debug.println("Timeout Getting Responce");
  RPM = 0;
 ECUconnected = BUSY;

}

}

}

// Simple check the response to debug terminal
void checkResponse(){
while (bike.available() > 0){
byte incomingByte = bike.read();
debug.print(incomingByte, HEX);
debug.print(' ');
}
}
// cleare bike terminal
void bikeFlush(){
while(bike.available()) bike.read();
}

//initialise communications
byte initHonda(){
debug.println("Starting initialise Honda");
bike.end();
delay(350);
//Sending LOW
digitalWrite(TX_PIN, LOW);
delay(70);
//Sending High
digitalWrite(TX_PIN, HIGH);
delay(120);
pinMode(TX_PIN, OUTPUT);
//Start Bike serial1
bike.begin(10400);
bike.write(MessageWakeup, sizeof(MessageWakeup)); //Send WakeUp
delay(200);
bike.write(MessageInitialise, sizeof(MessageInitialise)); // initialise communications
bike.flush(); // wait to send all

resState = BUSY;
// Try to read a wakeup is send
while (resState == BUSY) resState = getResponse(resbuf);
if (resState == SUCCESS) {
delay(300);
resState = BUSY;
// Try to read initialise responce
while (resState == BUSY) resState = getResponse(resbuf);
if (resState == SUCCESS) {
if (resState == SUCCESS) {
return SUCCESS;
} else {
debug.println("Failed init Honda, somthing is wrong retry"); // Return false if diagnostic mode request was denied or failed
return BUSY;
}
}
if (resState == TIMEOUT){
debug.println("TIMEOUT init Honda"); // Return false if diagnostic mode request was denied or failed
return BUSY;
}
}
if (resState == TIMEOUT){
debug.println("TIMEOUT WakeUp Honda"); // Return false if diagnostic mode request was denied or failed
return BUSY;
}
}

byte getResponse(byte *rbuffer) {
// These bytes remain unchanged in between function calls
// Used to monitor the response while not blocking the program
static int index = 0;
static int len = 255;
static unsigned long t = 0;

// After a request is send the timer is set
if (t == 0) t = millis();
// Check if function call is within timeout limit
if (millis() - t < 250) {
// Check if more bytes need to be received
if (index < len) {
// Check if bytes are available
unsigned long startedWaiting = millis();
while (bike.available() > 0) {
t=0;
rbuffer[index] = bike.read();

    // First received byte must be correct 0xFE, 0x04, 0x72, 0x8C
    if (rbuffer[0] == 0xFE){
   // debug.print(rbuffer[0], HEX);
      // Clear bike RX buffer
      while(bike.available()) bike.read();
      memset(rbuffer, 0, sizeof(rbuffer));
      debug.println("Wakeup OK");
       
          t = 0;
          index = 0;
          len = 255; 
      return SUCCESS;
      
     }

     if ((rbuffer[0] == 0x02) && (rbuffer[1] == 0x04) && (rbuffer[2] == 0x00) && (rbuffer[3] == 0xFA)){
        // Clear bike RX buffer
        while(bike.available()) bike.read();
        debug.println("ini OK");  
          t = 0;
          index = 0;
          len = 255;
          delay(200);
          memset(rbuffer, 0, sizeof(rbuffer));
        return SUCCESS;
     }
    if (rbuffer[3] == 0x16){

          t = 0;
          //index = 0;
          index++;
          len = 12;
        return BUSY;
     }
     index++;
      return BUSY; 
      
   }
   debug.println("Timeout");
    return TIMEOUT;
    
 }
  // Read all bytes, reset timer, index and length
 else {
  t = 0;
  index = 0;
  len = 255;
  delay(55);
  //debug.println("succes");
  return SUCCESS;
 }

}
else {
t = 0;
index = 0;
len = 255;
//debug.println("Timeout");
return TIMEOUT;
//return BUSY;
}
}
`

this is the Result from the serial interface:

Starting initialise Honda
Wakeup OK
ini OK
RPM 0
Tabel 16
hex
2-C-72-16-0-0-0-19-A-0-0-47-0-0-0-0-0-0-0-0-0-0-0-0-0-0-

@aster94
Copy link
Owner

aster94 commented May 9, 2020

okkkk we have a starting point

I can write some code about it but I need some explanation:

send a low
wait 70 ms
Send a high
wait 120ms
send: 0xFE, 0x04, 0x72, 0x8C
receive: ????
wait 200Ms
send: 0x72, 0x05, 0x00, 0xF0, 0x99
receive: ????
send: 0x72, 0x07, 0x72, 0x16, 0x00, 0x06, 0xF9
receive: data

can you check if this is correct and fill the part that I don't know?

@man-go1
Copy link
Author

man-go1 commented May 14, 2020

hi,

as i have learned. is this step an initialise:
-/---------------------------------------
send a low
wait 70 ms
Send a high
wait 120ms
send: 0xFE, 0x04, 0x72, 0x8C
receive: Nothing
wait 200Ms
send: 0x72, 0x05, 0x00, 0xF0, 0x99
receive: Nothing.
-/---------------------------------------
then I can send a request to send data. in this example table 16.
send: 0x72, 0x07, 0x72, 0x16, 0x00, 0x06, 0xF9
receive: data
-/---------------------------------------
as long as I ask for data the link keeps alive. when I stop I need to initialise again

@aster94
Copy link
Owner

aster94 commented May 14, 2020

Okkk, in the next days I will write the code.

Actually, it is something bad that the ECU doesn't answer back. We can't know if the initialization has gone well 😔

Can you give me a few samples of the data the ECU return when you send the table 16 and an explanation of them? For example I see that the rpm are between byte 4 and 5

@man-go1
Copy link
Author

man-go1 commented May 14, 2020

If you have some other code to look at response I’m happy to try. But I can’t get a response back.

About the other question.
I’m still cracking my brain for all the response back I’m getting of ecu.
And what is what? I have no manual.
And theres not much to find on the internet for the VFR. It does not match other Honda’s. And binaire is not my best thing.
4 and 5 are RPM
Calculating it like this will get the correct RPM.

uint16_t varY = resbuf[5];
varY = varY << 8;
varY = varY + resbuf[4];
RPM = varY;
The rest I need to find.
My goal is to create a mile to the galon calculation. To calculate how far I can go with the fuel in the tank. . 😓 but I’m a long way from there 😬

@aster94
Copy link
Owner

aster94 commented May 21, 2020

good news!

I wrote the code and put it on a branch: https://github.com/aster94/Keyword-Protocol-2000/tree/honda

I tested it with a logic analyzer and it looks good. You may wish to double-check it with https://sigrok.org/wiki/Downloads this is the file honda.zip

a few example:
LOW for 70 and then HIGH for 120
image

send: 0xFE, 0x04, 0x72, 0x8C and wait 200ms
image

send: 0x72, 0x05, 0x00, 0xF0, 0x99
image

send: 0x72, 0x07, 0x72, 0x16, 0x00, 0x06, 0xF9 (table 16)
image

Also here there are a few other questions:

  1. does honda have a delay between bytes?
  2. does it have a connection time-out? (for example on suzuki is 2 seconds)
  3. I strongly need a real data to make sure everything is fine can you provide one or two of these?

send: 0x72, 0x07, 0x72, 0x16, 0x00, 0x06, 0xF9
receive: data

  1. Which arduino board are you using?
  2. which IDE?

Please before trying the above code on your motorbike answer these questions

@man-go1
Copy link
Author

man-go1 commented May 21, 2020

Tnx, Will check tomorrow. 👍🏻

@aster94
Copy link
Owner

aster94 commented Jun 13, 2020

@man-go1 did you had time to check it? Any update?

@Maximouss89
Copy link

Hi, I don't have enough kwonledge about this, but I found this, maybe it could be help you to finalize the code :

The ECU will not respond until it has received the correct initialisation sequence. I used this:

    Pull the K-line low for 70msec

    Return the K-line to the high state for 120msec

    Send “Wakeup” message: FE 04 FF FF. No response is expected

    Wait 200msec

    Send “Initialise” message: 72 05 00 F0 99

    The ECU should respond with: 02 04 00 FA

That’s it. You can then send requests and the ECU should respond with the data requested. The communications needs to be “kept alive”, however. That means that if the ECU hasn’t received a request within a certain time it goes back to sleep and needs to be initialised again. I think the time is around 3 sec.

@aster94
Copy link
Owner

aster94 commented Oct 24, 2020

Hi @Maximouss89 which motorbike do you have? The sequence is a little bit different (but still very similar) to the VFR 2010 of @man-go1
Do you have the hardware and knowledge to test a snippet of code?

@Maximouss89
Copy link

Hello, I have a 2010 - CBR1000RR.
I would connect an Arduino to DLC and know RPM and vehicule Speed. But I didn't know K-line and have few knowledge in programmation. (I'll do all tuto with arduino's kit but I'm not a master ;) )
All informations I gave you are on this website : http://forum.pgmfi.org/viewtopic.php?f=57&t=22199&start=45

I would like to learn how to interact with my CBR and arduino

@Maximouss89
Copy link

If you have the code, I could try to test if code works.
I have Arduino and I'm going to have MC33290 and 510Ohm resistor.
If I understood correctly I have to connect like that : http://compcar.ru/forum/attachment.php?s=f0cd48d1c97ceffe7a692e527d7bf43c&attachmentid=18808&d=1453708488

@aster94
Copy link
Owner

aster94 commented Oct 26, 2020

ok, which arduino board? do you have a board with 2 or more serial port?

@Maximouss89
Copy link

I have an Arduino UNO and Nano, but I could use other pins (10 an 11 for example) and SoftwareSerial Library right?
If it's necessary I'll buy a arduino mega.

@BartasCh
Copy link

BartasCh commented Oct 26, 2020 via email

@aster94
Copy link
Owner

aster94 commented Oct 26, 2020

Yes, you can use a software serial but an hardware one would be better. I don't want you to spend this extra money for now, we can just try the software serial on the arduino Uno/nano and see if it will work

In reply to @BartasCh I do agree that the soft serial is not good but we can run a test

P.S: sorry I closed the issue for mistake

@aster94 aster94 closed this as completed Oct 26, 2020
@aster94 aster94 reopened this Oct 26, 2020
@Maximouss89
Copy link

Maximouss89 commented Oct 26, 2020

Which board has 2 or more serial port ? I found : Arduino MEGA, et ZERO, right? Arduino Zero use 3.3V, doesn't matter?
I don't buy yet, but I'm looking for in case it would be necessary. (sorry for my English, I'm not very good ;/ )

@aster94
Copy link
Owner

aster94 commented Oct 26, 2020

Yes, and also the arduino-compatible board like the stm32f103 as the bluepill
3.3V is ok

@Maximouss89
Copy link

Yes, and also the arduino-compatible board like the stm32f103 as the bluepill
3.3V is ok

I'll have a STM32F103 board tomorrow it's good 👼
I didn't know this board, there are faster than arduino for TFT screen etc... It will be usefull thank you !

@aster94
Copy link
Owner

aster94 commented Oct 26, 2020

yes these are my favourite boards! the ratio between price and power is awesome, I usually use them

@Maximouss89
Copy link

Maximouss89 commented Nov 5, 2020

Hi,
I tried to write a piece of code, could you tell me if you see any mistakes pls ?

byte wakeup[]={0xFE, 0x04, 0xFF, 0xFF};
byte initialise[]={0x72, 0x05, 0x00, 0xF0, 0x99};
byte answer[]={0x02,0x04,0x00,0xFA};
byte message[24];
//byte checksum=0xF0;
int RX1 = PA10;
int TX1 = PA9;
bool connection=false;
bool goodrep=false;

void setup() {
// put your setup code here, to run once:
pinMode(TX1,OUTPUT);
pinMode(RX1,INPUT);
Serial1.begin(10400);
while(connection==false){
digitalWrite(TX1,HIGH);
delay(10);
digitalWrite(TX1,LOW);
delay(70);
digitalWrite(TX1,HIGH);
delay(120);
digitalWrite(TX1,LOW);
Serial1.write(wakeup,sizeof(wakeup));
delay(200);
Serial1.write(initialise,sizeof(initialise));
int i=0;
while(Serial1.available()>0){
message[i]=Serial1.read();
Serial.print(message[i]);
i=i+1;
}
int j=0;
while(j<i-1){
if(answer[j]==message[j]){
j++;
goodrep=true;
}else{
goodrep=false;
break;
}
}
if (goodrep==true){
connection=true;
}
}
}

void loop() {
// put your main code here, to run repeatedly:
int i=0;
Serial.println(" ");
while(Serial1.available()>0){
message[i]=Serial1.read();
Serial.print(message[i]);
// if (message[i]<>checksum){
// i=i+1;
// }else{
// break;
// }
}
}

@aster94
Copy link
Owner

aster94 commented Nov 6, 2020

if you want you can use the library sorry but I can't check your code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants