Keyword-Protocol-2000
Keyword-Protocol-2000 copied to clipboard
Connect with Honda
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?
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?
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
@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
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; } }
where does your code stuck?
This part is okay. But I can’t get info out of tables.
can you post what are you getting from the ECU?
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-
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?
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
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
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 😬
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
send: 0xFE, 0x04, 0x72, 0x8C and wait 200ms
send: 0x72, 0x05, 0x00, 0xF0, 0x99
send: 0x72, 0x07, 0x72, 0x16, 0x00, 0x06, 0xF9 (table 16)
Also here there are a few other questions:
- does honda have a delay between bytes?
- does it have a connection time-out? (for example on suzuki is 2 seconds)
- 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
- Which arduino board are you using?
- which IDE?
Please before trying the above code on your motorbike answer these questions
Tnx, Will check tomorrow. 👍🏻
@man-go1 did you had time to check it? Any update?
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.
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?
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
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
ok, which arduino board? do you have a board with 2 or more serial port?
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.
hi there, From my experience software serial is not good, often uses timers used by other libraries, go for mega.
cheers
On Mon, 26 Oct 2020 at 21:15, Maximouss89 [email protected] wrote:
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.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/aster94/Keyword-Protocol-2000/issues/5#issuecomment-716538003, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKOIO3ENDOTIOBY7Z3YH45DSMVY6LANCNFSM4MZD46HA .
-- With Best Regards Bartek Chrzanowski
mobile UK: (+44) 0 757 099 8842 <%28%2B44%29%2007570998842>
e-mail: [email protected] [email protected] linked-in: Bartek-Chrzanowski http://www.linkedin.com/pub/bartek-chrzanowski/33/121/987 ( https://uk.linkedin.com/pub/bartek-chrzanowski/33/121/987 ) -KJM-
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
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 ;/ )
Yes, and also the arduino-compatible board like the stm32f103 as the bluepill 3.3V is ok
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 :angel: I didn't know this board, there are faster than arduino for TFT screen etc... It will be usefull thank you !
yes these are my favourite boards! the ratio between price and power is awesome, I usually use them
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; // } } }
if you want you can use the library sorry but I can't check your code