Comments (26)
Thanks guys, its working now.
I have programmed a Dash Cluster
The result of my work: https://vm.tiktok.com/ZS4XktLp/
from elmduino.
Fortunately, Matthew, who wrote the SafeString library, helped me with this issue.
Just finished a live test, while charging the car for 50 minutes.
No reboot or WiFi and BT connection issues at all.
OBD BT queried once/sec and the datas (in multiple groups) was sent every 2 seconds to Blynk.
So here is the working parser for OBD protocol 6 with multiple dataframes (from 0: 1: 2: to 8: ).
I hope this will help others (maybe @PowerBroker2 will add this to a new release)
Thanks guys!
#include "SafeString.h"
createSafeString(dataFrame0, 14); // will also add space for the terminating null =>15 sized array
createSafeString(dataFrame1, 14);
createSafeString(dataFrame2, 14);
createSafeString(dataFrame3, 14);
createSafeString(dataFrame4, 14);
createSafeString(dataFrame5, 14);
createSafeString(dataFrame6, 14);
createSafeString(dataFrame7, 14);
createSafeString(dataFrame8, 14);
void clearData() {
dataFrame0.clear();
dataFrame1.clear();
dataFrame2.clear();
dataFrame3.clear();
dataFrame4.clear();
dataFrame5.clear();
dataFrame6.clear();
dataFrame7.clear();
dataFrame8.clear();
}
void addToFrame(int frame, char c) {
switch(frame) {
case 0:
dataFrame0 += c;
break;
case 1:
dataFrame1 += c;
break;
case 2:
dataFrame2 += c;
break;
case 3:
dataFrame3 += c;
break;
case 4:
dataFrame4 += c;
break;
case 5:
dataFrame5 += c;
break;
case 6:
dataFrame6 += c;
break;
case 7:
dataFrame7 += c;
break;
case 8:
dataFrame8 += c;
break;
}
}
void frameSubstr(SafeString& frame, int m, int n, SafeString& subStr) {
frame.substring(subStr,m,n); // SafeString substring is inclusive m to n
}
int convertToInt(SafeString& dataFrame, size_t m, size_t n) {
// define a local SafeString on the stack for this method
createSafeString(hexSubString, 14); // allow for taking entire frame as a substring
frameSubstr(dataFrame, m, n, hexSubString);
return (int)strtol(hexSubString.c_str(), NULL, 16);
}
void parse(char *raw) {
int frame = -1;
int len = strlen(raw);
for(int i=0; i<len; i++) {
if(raw[i+1] == ':') { //start frame
frame = (int) raw[i] - '0';
continue;
}
if(raw[i] == ':') {
continue;
}
if(frame == -1) {
continue;
}
if(raw[i] == '>') {
frame = -1;
continue;
}
addToFrame(frame, raw[i]);
}
}
void read_rawdata(){
// move data from OBD to Rawdata array
char rawData[myELM327.recBytes];
int n = 0;
DEBUG_PORT.print("Payload received: ");
for (int i=0; i<myELM327.recBytes; i++) {
rawData[n++] = myELM327.payload[i];
DEBUG_PORT.print(myELM327.payload[i]); // Serial print OBD Rawdata
}
DEBUG_PORT.println();
parse(rawData); // parse data received from OBD
}
// loop
void loop(){
// insert timer/delay (ex. 1sec)
...
myELM327.sendCommand("AT SH 7E4"); // Set Header BMS
if (myELM327.queryPID("220101")) { // BMS PID = hex 22 0101 => dec 34, 257
read_rawdata();
BATTv = ((convertToInt(dataFrame2, 4, 5)<<8) + convertToInt(dataFrame2, 6, 7))/10;
DEBUG_PORT.print("Main Battery Voltage (V): ");
DEBUG_PORT.println(BATTv);
clearData();
}
}
from elmduino.
Gents,
With Jaukb's help - our sketch works.
The issue was in this line of code:
sprintf(command, SET_HEADER, "7E0");
Elmduino.h const as below:
const char * const SET_HEADER = "AT SH"; // OBD
has been edited to this line
const char * const SET_HEADER = "AT SH %s"; // OBD
finally we have received proper data, same as in the App DPM Monitor.
Thanks to both of you and Jakub too!
from elmduino.
Thanks guys, @PowerBroker2 / Matthew for your library & help!
Here is the almost finished OBD Google TTS project :)
https://youtu.be/mUl9IHsN-ao
from elmduino.
You can do something like this:
if (myELM327.queryPID("221E12"))
{
int32_t temp = myELM327.findResponse();
Serial.print("Raw Response: ");
for (byte i = 0; i < PAYLOAD_LEN; i++)
Serial.write(myELM327.payload[i]);
Serial.println();
if (myELM327.status == ELM_SUCCESS)
{
Serial.print("Parsed Response: "); Serial.println(temp);
}
else
{
Serial.print("ERROR: "); Serial.println(myELM327.status);
}
}
from elmduino.
You can do something like this:
if (myELM327.queryPID("221E12")) { int32_t temp = myELM327.findResponse(); Serial.print("Raw Response: "); for (byte i = 0; i < PAYLOAD_LEN; i++) Serial.write(myELM327.payload[i]); Serial.println(); if (myELM327.status == ELM_SUCCESS) { Serial.print("Parsed Response: "); Serial.println(temp); } else { Serial.print("ERROR: "); Serial.println(myELM327.status); } }
'PAYLOAD_LEN' was not declared in this scope
Screenshot: https://prnt.sc/unl6rm
from elmduino.
Sorry, that was a snippet from old code. Change PAYLOAD_LEN
to myELM327.PAYLOAD_LEN
from elmduino.
Thank its work :)
from elmduino.
Sorry, that was a snippet from old code. Change
PAYLOAD_LEN
tomyELM327.PAYLOAD_LEN
im get every time "Parsed Response: 0" how i can fix it?
i have testet the PID on "Torque"-APP and it give me value back
Transmission Gear Shifter Position 6.7 –
PID – 221E23– Testing
Long Name (used in menus) – Transmission Shifter Position 6.7L
Short Name (used in gauge display) – Shifter
Min Value – 0.0
Max Value – 100
Scale Factor – x1
Unit Type – PRNDM21
Equation – A
OBD Header –
Park - 70.0
Reverse - 60.0
Neutral - 50.0
Drive - 46.0
Manual - 10.0
2nd Gear - 22.0
1st Gear - 21.0
from elmduino.
What does the Arduino say for the "Raw Response"?
from elmduino.
What does the Arduino say for the "Raw Response"?
621E2346
from elmduino.
Hmm, that should parse to 1646142278
(decimal), I can double check everything and let you know
from elmduino.
What about this?:
if (myELM327.queryPID("221E12"))
{
uint64_t temp = myELM327.findResponse();
Serial.print("Raw Response: ");
for (byte i = 0; i < myELM327.PAYLOAD_LEN; i++)
Serial.write(myELM327.payload[i]);
Serial.println();
if (myELM327.status == ELM_SUCCESS)
{
Serial.print("Parsed Response: "); Serial.println(temp);
}
else
{
Serial.print("ERROR: "); Serial.println(myELM327.status);
}
}
from elmduino.
if (myELM327.queryPID("221E12")) { uint64_t temp = myELM327.findResponse(); Serial.print("Raw Response: "); for (byte i = 0; i < myELM327.PAYLOAD_LEN; i++) Serial.write(myELM327.payload[i]); Serial.println(); if (myELM327.status == ELM_SUCCESS) { Serial.print("Parsed Response: "); Serial.println(temp); } else { Serial.print("ERROR: "); Serial.println(myELM327.status); } }
Arduino_hardware_serial_test.ino
call of overloaded 'println(uint64_t&)' is ambiguous
PID "221E23" (shifter Gear) --> https://prnt.sc/uompf8
PID "221E12" (Current Gear) respons too "0"
from elmduino.
im get every time "Parsed Response: 0" how i can fix it?
i have testet the PID on "Torque"-APP and it give me value back
I have same problem, all the time response is equal "0".
So I'm curious about solution. Looking forward.
PowerBroker2 -> I have tried to contact you on Arduino.cc forum in private message.
from elmduino.
Please post exactly what you're trying to do along with your entire sketch in tags along with a description of your physical setup and experiment parameters (i.e. car make/model, is the car on and running, etc). Also, make sure all other bluetooth devices are either disabled or turned off. Testing with different bauds also clears some people's issues.
from elmduino.
Project: Retrive information about DPF,
Physical setup: Arduino Nano + BlueTooth HC-05 -> iCar2Pro(ELM327)+Opel Insignia; engine A20DTH.
Code below
/*
Code base on PowerBroker2 & miguelos6 - Github https://github.com/PowerBroker2/ELMduino/issues/4
HEADER for Engine parameters Jakub Dziworski - http://jakubdziworski.github.io/
Car: Vauxhal/OPEL; model: Insignia; Engine: A20DTH
Communication->Arduino > BT HC-05 > ELM V-Link ICAR2Pro
Results printed on LCD 16x2
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>
#include <ELMduino.h>
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
SoftwareSerial mySerial(10, 7); // RX, TX for BlueTooth HC-05
#define ELM_PORT mySerial
ELM327 myELM327;
/*//////////////CONST & VARIABLE DEFINITION///////////////// */
const long debugRate = 115200;
const long mySerialRate = 38400; //one working BT BOUND 34800,0,0
int32_t dirtLevel = -1;
int32_t burn = -1;
int32_t regenStatus = -1;
int32_t kmsSinceDpf = -1;
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0,0);
lcd.print("...CONNECTING...");
lcd.setCursor(0,1);
lcd.print("BT HC05 > V-LINK");
Serial.begin(debugRate);
Serial.println("Serial Monitor - START");
ELM_PORT.begin(mySerialRate);
Serial.println("...Connecting to ELM327...");
/*//////////////CHECK BT CONNECTION///////////////// */
if (!myELM327.begin(ELM_PORT))
{
Serial.println("V-LINK - NOT CONNECTED");
lcd.clear();
lcd.setCursor(0,0);
lcd.print("..NOT CONNECTED.");
lcd.setCursor(0,1);
lcd.print("BT HC05 > V-LINK");
while (1);
}
Serial.println("V-LINK - CONNECTED SUCCESFUL");
lcd.clear();
lcd.setCursor(0,0);
lcd.print("BT HC05 > V-LINK");
lcd.setCursor(0,1);
lcd.print("....CONNECTED...");
/*//////////////CONFIRM BY FLASHING BUILT LED///////////////// */
flashLEDx5();
/*//////////////SET HEADER FOR ENGINE///////////////// */
myELM327.sendCommand(PRINTING_SPACES_ON);
char command[20] = { '\0' };
sprintf(command, SET_HEADER, "7E0");
if (myELM327.sendCommand(command) != ELM_SUCCESS)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("UNABLE TO SET ");
lcd.setCursor(0,1);
lcd.print("...HEADER 7E0...");
Serial.println("UNABLE TO SET AT SH 7E0");
}
lcd.clear();
lcd.setCursor(0,0);
lcd.print("...HEADER 7E0...");
lcd.setCursor(0,1);
lcd.print(" HAS BEEN SET ");
Serial.println("AT SH 7E0 - SUCCESS!!!");
/*//////////////CONFIRM BY FLASHING BUILT LED///////////////// */
flashLEDx5();
}
/*//////////////RETRIEVING DATA/////////////////
0x22, 0x3274 = 34,12916 - regeneration status
0x22, 0x3277 = 34,12919 - km's since last DPF clean
0x22, 0x3275 = 34,12917 - DPF dirt level
*/
void loop()
{
/*
////////////////////REGENERATION STATUS//////////////////
int32_t getRegenerationStatus() {return queryVgate(0x22, 0x3274);}
*/
if (myELM327.queryPID(34, 12916))
{
int32_t tempregenStatus = myELM327.findResponse();
Serial.print("Payload received for soot: ");
for (byte i = 0; i < myELM327.PAYLOAD_LEN; i++)
Serial.write(myELM327.payload[i]);
Serial.println();
if (myELM327.status == ELM_SUCCESS)
{
regenStatus = tempregenStatus;
Serial.print("RegenStat: "); Serial.println(regenStatus);
}
else
printError();
}
/*
////////////////////KMs SINCE DPF//////////////////
int32_t getKmsSinceDpf() {return queryVgate(0x22, 0x3277);}
*/
if (myELM327.queryPID(34, 12919))
{
int32_t tempkmsSinceDpf = myELM327.findResponse();
Serial.print("Payload received for soot: ");
for (byte i = 0; i < myELM327.PAYLOAD_LEN; i++)
Serial.write(myELM327.payload[i]);
Serial.println();
if (myELM327.status == ELM_SUCCESS)
{
kmsSinceDpf = tempkmsSinceDpf;
Serial.print("Km since DPF: "); Serial.println(kmsSinceDpf);
}
else
printError();
}
/*
////////////////////DPF Dirt Level//////////////////
int32_t getDpfDirtLevel() {return queryVgate(0x22, 0x3275);}
*/
if (myELM327.queryPID(34, 12917))
{
int32_t tempdirtLevel = myELM327.findResponse();
Serial.print("Payload received for dirtLevel: ");
for (byte i = 0; i < myELM327.PAYLOAD_LEN; i++)
Serial.write(myELM327.payload[i]);
Serial.println();
if (myELM327.status == ELM_SUCCESS)
{
dirtLevel = tempdirtLevel;
Serial.print("DPF dirt level: "); Serial.println(dirtLevel);
}
else
printError();
}
/*//////////////CONFIRM BY FLASHING BUILT LED///////////////// */
flashLEDx5();
/*//////////////CHECK REGENERATING IS IN PROGRESS OR NOT/////////////////
> */
if(burn > 0) {
printRegenerating(regenStatus);
return;
}
/*//////////////PRINT STATUS OF PARAMETERS///////////////// */
printDpfStatus();
/*//////////////WAIT 1s BEFORE ASK AGAIN///////////////// */
delay(1000);
}
/*//////////////CHECK ELM327 - ANSWER///////////////// */
void printError()
{
if (myELM327.status == ELM_SUCCESS)
Serial.println(F("\tELM_SUCCESS"));
else if (myELM327.status == ELM_NO_RESPONSE)
Serial.println(F("\tERROR: ELM_NO_RESPONSE"));
else if (myELM327.status == ELM_BUFFER_OVERFLOW)
Serial.println(F("\tERROR: ELM_BUFFER_OVERFLOW"));
else if (myELM327.status == ELM_GARBAGE)
Serial.println(F("\tERROR: ELM_GARBAGE"));
else if (myELM327.status == ELM_UNABLE_TO_CONNECT)
Serial.println(F("\tERROR: ELM_UNABLE_TO_CONNECT"));
else if (myELM327.status == ELM_NO_DATA)
Serial.println(F("\tERROR: ELM_NO_DATA"));
else if (myELM327.status == ELM_STOPPED)
Serial.println(F("\tERROR: ELM_STOPPED"));
else if (myELM327.status == ELM_TIMEOUT)
Serial.println(F("\tERROR: ELM_TIMEOUT"));
else if (myELM327.status == ELM_GENERAL_ERROR)
Serial.println(F("\tERROR: ELM_GENERAL_ERROR"));
delay(500);
}
/*//////////////FLASHING BUILT LED - LOOP///////////////// */
void flashLEDx5()
{
for (int a = 0; a < 5; ++a)
{
digitalWrite(LED_BUILTIN,HIGH); delay(100);
digitalWrite(LED_BUILTIN,LOW); delay(100);
}
}
/*//////////////JAKUB's FUNCTIONS TO DETERMINE LEVEL OF SOOT AND STATUS///////////////// */
void printDpfStatus() {
lcd.clear();
lcd.setCursor(0,0);
String message = "LAST: ";
message = message + kmsSinceDpf + "KM";
Serial.println(message);
lcd.print(message);
lcd.setCursor(0,1);
message = "FILL: ";
message = message + dirtLevel + "%";
lcd.print(message);
}
void printRegenerating(int32_t regenStatus) {
int32_t percentRegenerated = map(regenStatus, 0, 255, 0, 100);
String statusMessage = " ";
statusMessage = statusMessage + percentRegenerated + "% ";
lcd.clear();
lcd.setCursor(0,0);
lcd.print("!!REGENERATING!!");
lcd.setCursor(0,1);
lcd.print(statusMessage);
lcd.noBacklight();
delay(200);
lcd.backlight();
delay(200);
}
With sketch above the answer for LCD is always 0.
Answer visible in Serial Monitor of Arduino IDE and it doesn't matter engine is running or not.
https://www.dropbox.com/s/djp31qyjkiw51df/silnik%20zgaszony%20i%20odpalony.jpg?dl=0
20:54:41.253 -> AT SH 7E0 - SUCCESS!!!
20:54:42.334 -> Payload received for soot: SEARCHING...7F2222
20:54:50.129 -> Payload received for soot: 7F2222
20:54:42.334 -> Payload received for soot: SEARCHING...7F2222
20:54:42.334 -> RegenStat: 0
20:54:42.674 -> Payload received for soot: 7F2222
20:54:42.674 -> Km since DPF: 0
20:54:43.002 -> Payload received for dirtLevel: 7F2222
20:54:43.002 -> DPF dirt level: 0
20:54:45.024 -> LAST: 0KM
When I used code provided by you:
void loop()
{
if(DEBUG_PORT.available())
{
char c = DEBUG_PORT.read();
DEBUG_PORT.write(c);
ELM_PORT.write(c);
}
if(ELM_PORT.available())
{
char c = ELM_PORT.read();
if(c == '>')
DEBUG_PORT.println();
DEBUG_PORT.write(c);
}
}
And sent request thru the serial monitor like below:
20:00:24.528 -> ATZ
ELM327 v2.2
>AT SH 7E0
OK
>223275
62 32 75 4E
the recived value 4E converted to decimal gave me same result as DPF Monitor App.
I'm begginer at programing so if you could support me I will appriciate that.
Let me know if there is lack of needed information.
I have also tried code below
if (myELM327.queryPID("221E12"))
{
uint64_t temp = myELM327.findResponse();
Serial.print("Raw Response: ");
for (byte i = 0; i < myELM327.PAYLOAD_LEN; i++)
Serial.write(myELM327.payload[i]);
Serial.println();
if (myELM327.status == ELM_SUCCESS)
{
Serial.print("Parsed Response: "); Serial.println(temp);
}
else
{
Serial.print("ERROR: "); Serial.println(myELM327.status);
}
}
and I got result during verifiying of sketch same as Jastreb07
overloaded 'println(uint64_t&)' is ambiguous
So, i'm waiting your feedback.
Thank you in advance
KoYoT77
from elmduino.
You can typecast temp into a normal int for printing in your case. Also, what exactly is going wrong in your case? Also, can you edit the lib files to print the exact command bytes sent to the ELM327 the next time you test?
from elmduino.
In my case (Hyundai Kona EV), when the car is turned OFF, the OBD adapter sends something like this (Rawdata, OBD protocol 6):
03E0:620101FFF7E7
But when it is ON, "7F2212" frames appears (random length, before or after the first actual dataframe 0:620101FFF7E7, where 0: is the indicator for DataFrame 0. Can send even 8 similar dataframes. Each dataframe contains 7bytes, except 0:, which contains only 6bytes).
7F22127F22127F22127F22127F221203E0:620101FFF7E71:FF8A00000000802:00000ED91814133:141713000011C2
Need to modify the 'payloadlen' value to 200 for 8 dataframes in elmduino.h :
bool begin(Stream& stream, char protocol='0', uint16_t payloadLen = 200);
So your actual data will be after this 7Fxxx bytes.
from elmduino.
You can typecast temp into a normal int for printing in your case. Also, what exactly is going wrong in your case? Also, can you edit the lib files to print the exact command bytes sent to the ELM327 the next time you test?
PowerBroker2
What is going wrong
In my case id doesn't matter what I asked:
myELM327.queryPID(34, 12916)
myELM327.queryPID(34, 12919)
myELM327.queryPID(34, 12917)
answer is all the time the same
Payload received for soot: 7F2222
change of uint64_t
to int
still gave me same answer.
Same for engine running & not.
I suppose somewhere in my code there is a bug, but I'm really newbie in programming.
So if you be so kind please check it.
from elmduino.
In my case (Hyundai Kona EV), when the car is turned OFF, the OBD adapter sends something like this (Rawdata, OBD protocol 6):
03E0:620101FFF7E7
But when it is ON, "7F2212" frames appears (random length, before or after the first actual dataframe 0:620101FFF7E7, where 0: is the indicator for DataFrame 0. Can send even 8 similar dataframes. Each dataframe contains 7bytes, except 0:, which contains only 6bytes).
7F22127F22127F22127F22127F221203E0:620101FFF7E71:FF8A00000000802:00000ED91814133:141713000011C2
Need to modify the 'payloadlen' value to 200 for 8 dataframes in elmduino.h :
bool begin(Stream& stream, char protocol='0', uint16_t payloadLen = 200);
So your actual data will be after this 7Fxxx bytes.
I have tried what you suggest, Elmduino.h opened, I look for payloadLen in my lib its value is set to 40.
But there are two declaration of variables:
uint16_t PAYLOAD_LEN;
called in my sketch for iteration
for (byte i = 0; i < myELM327.PAYLOAD_LEN; i++)
and
uint16_t payloadLen = 40
used in begin function of the lib.
But please be forgiving to the beginner if I said something stupid.
Regards
from elmduino.
payloadLen
is used by the begin()
member function to set the value of PAYLOAD_LEN
(or myELM327.PAYLOAD_LEN
in the sketch). By default that value is 40, but you can change it to another value, i.e. 200.
from elmduino.
@KoYoT77 I think we have similar issues.
Your data is there, after 7F.... bytes, but probable the parser stops after a few bytes.
One of my friends sent me a parser, which worked great for ~15seconds :) , after this the ESP32 module crashed (picture attached at the end, where you can see where is the issue, but I don't know how to fix it and he is busy now).
Here is the code for parsing:
void clearData() {
dataFrame0 = "";
dataFrame1 = "";
dataFrame2 = "";
dataFrame3 = "";
dataFrame4 = "";
dataFrame5 = "";
dataFrame6 = "";
dataFrame7 = "";
dataFrame8 = "";
}
char* appendCharToCharArray(char* array, char c) {
int len = strlen(array);
char ret[len + 2];
strcpy(ret, array);
ret[len] = c;
ret[len + 1] = '\0';
return strdup(ret);
}
void addToFrame(int frame, char c) {
switch (frame) {
case 0:
dataFrame0 = appendCharToCharArray(dataFrame0, c);
break;
case 1:
dataFrame1 = appendCharToCharArray(dataFrame1, c);
break;
case 2:
dataFrame2 = appendCharToCharArray(dataFrame2, c);
break;
case 3:
dataFrame3 = appendCharToCharArray(dataFrame3, c);
break;
case 4:
dataFrame4 = appendCharToCharArray(dataFrame4, c);
break;
case 5:
dataFrame5 = appendCharToCharArray(dataFrame5, c);
break;
case 6:
dataFrame6 = appendCharToCharArray(dataFrame6, c);
break;
case 7:
dataFrame7 = appendCharToCharArray(dataFrame7, c);
break;
case 8:
dataFrame8 = appendCharToCharArray(dataFrame8, c);
break;
}
}
// get substring between m and n (excluding n)
char* substr(const char *src, int m, int n) {
n += 1;
int len = n - m;
char *dest = (char*)malloc(sizeof(char) * (len + 1));
for (int i = m; i < n && (*(src + i) != '\0'); i++)
{
*dest = *(src + i);
dest++;
}
*dest = '\0';
return dest - len;
}
void parse(char *raw) {
int frame = -1;
int len = strlen(raw);
for (int i = 0; i < len; i++) {
if (raw[i + 1] == ':') { //start frame
frame = (int) raw[i] - '0';
continue;
}
if (raw[i] == ':') {
continue;
}
if (frame == -1) {
continue;
}
if (raw[i] == '>') {
frame = -1;
continue;
}
addToFrame(frame, raw[i]);
}
}
int convertToInt(char *hexStr) {
return (int)strtol(hexStr, NULL, 16);
}
And here is how to use it in the loop(), with some delay/timer (in my case, this will return/print battery voltage):
myELM327.sendCommand("AT SH 7E4"); // Set Header BMS (Battery Management System)
if (myELM327.queryPID("220101")) { // BMS PID
read_rawdata();
BATTv = ((convertToInt(substr(dataFrame2, 4, 5)) << 8) + convertToInt(substr(dataFrame2, 6, 7))) / 10;
DEBUG_PORT.print("Main Battery Voltage (V): ");
DEBUG_PORT.println(BATTv);
clearData();
}
Read_rawdata function looks like this (will print the rawdata coming from OBD, then will parse it):
void read_rawdata() {
// move data from OBD to Rawdata array
char rawData[myELM327.recBytes];
int n = 0;
DEBUG_PORT.print("Payload received: ");
for (int i = 0; i < myELM327.recBytes; i++) {
rawData[n++] = myELM327.payload[i];
DEBUG_PORT.print(myELM327.payload[i]);
}
DEBUG_PORT.println();
parse(rawData); // parse data received from OBD
}
Rawdata from OBD:
Payload received: 7F22127F22127F22127F22127F221203E0:620101FFF7E71:FF8A00000000832:00240ED71713133:141713000010C14:22C12800008B005:00450B0000434B6:000019A80000187:1200200EE70D018:7B0000000003E8
Parse(rawData), will look for dataframes, which begins with 0: 1: 2: 3: etc... then I can select any byte in any dataframe:
Ex.:
Dataframe2 >>>>>>>>>>> 2:00240ED7171313
convertToInt(substr(dataFrame2, 4, 5))
>>>> will return a single byte on location 4 and 5 (from 0) in dataframe 2.
convertToInt(substr(dataFrame2, 6, 7))
>>>> will return a single byte on location 6 and 7 (from 0) in dataframe 2.
Result >>>
0E =14;
D7 = 215;
Formula for Battery voltage = (14 * 256 + 215) / 10.0 = 379.9V
Now the problem is the parser will crash (possible memory leak) after 10-15seconds, until the crash, the parser works great.
Maybe @PowerBroker2 can help both of us, with this parser :) .
As I know we should not use malloc() at all (or use it with free() ).
from elmduino.
This is dope! I'll take a closer look later and see if/how I can incorporate it.
However, @cyberelectronics, feel free to fork and PR if you want to do it yourself. Either way, thanks!
from elmduino.
Thanks, but I don't know how to use github :D .
Also if you can, please add/modify the code for other cases, where the dataframe delimiters are missing (no 0: , when all datas are in a single frame package) like in @KoYoT77 example.
Ex. PID >223275
Response: 62 32 75 4E
Skip any 7F... bytes at the beginning sent by OBD adapter, and Search/Compare for the first byte of PID 22hex + 40hex = 623275hex >>> 4E..... hex data bytes (dataframe).
from elmduino.
what should I do I wanna use service22 and service01 both?
should I set header to 7E4 to get bms system data and set filter off to get data from service01 and set header to 7E4 again in loop??
from elmduino.
Related Issues (20)
- Odometer value HOT 6
- Service 22 PID's for GM LS PCM HOT 1
- ELM327 to HC-05 Module HOT 11
- Why does it take so long to connect? HOT 9
- Trying to get to work monitorStatus(); HOT 2
- "Guru Meditation Error: Core 1 panic'ed (StoreProhibited)" error when using a function, example 'myELM327.rpm()' HOT 5
- M5STACK with ELMduino not working HOT 10
- BLE functionality ESP32-C3/S3 HOT 1
- Pulling PID 119 HOT 14
- Vgate iCar Pro BLE 4.0 not getting data HOT 7
- Repeating pid request ( stopped car just turn on, esp32, elm327) HOT 11
- Wrong RPM HOT 16
- How to use PIDs for EV HOT 2
- Issue with getting data from .rpm() or .throttle() HOT 12
- ELM327 Bluetooth don't connection HOT 14
- Arduino obd monitoring Opel Insignia HOT 8
- Connection with OBDII adapter not possible HOT 2
- connection to Ircama/ELM327-emulator or PowerBroker2/ELM_Simulator HOT 3
- Checking Parking Brake Status HOT 3
- Elm327 hc05 connected show HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from elmduino.