-
Notifications
You must be signed in to change notification settings - Fork 125
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
custom pid for DPF #235
Comments
hello i'm traing this code but i receive error on sending the headr: `#include "BluetoothSerial.h" BluetoothSerial SerialBT; ELM327 myELM327; void setup() {
// Imposta l'intestazione OBD specifica per Alfa Romeo Stelvio } void loop() {
} |
i'm traing different code without success... `void setup { void loop() { // Controlla lo stato della risposta
} else if (myELM327.nb_rx_state == ELM_GETTING_MSG) { // Attendi prima di inviare una nuova richiesta without success...if someone can help |
hello! i'm going ahaed with my test waiting for your help... i have tested a custom pid with an ios app with confirmed result, so i know that works well with my car. on the app i see this result: i'm trying to read data from odb with two strategy: processpid and sendCommand, with no success, here is the loop code, void loop() {
myELM327.sendCommand("ATSH DA18F1");
// Imposta l'header OBD, se necessario
delay(100); // Dà tempo per elaborare il comando
// Tentativo con processPID
float gearboxOilTemp = myELM327.processPID(0x22, 0x04FE, 1, 7, 1.0, 0.0);
delay(2000); // Dà tempo alla risposta di arrivare
if (myELM327.nb_rx_state == ELM_SUCCESS) {
int A = myELM327.payload[6]; // Prende il valore A dalla risposta
float temperature = A - 40; // Applica la formula per ottenere la temperatura
displayTemperature(temperature);
} else {
// Se processPID fallisce, prova con sendCommand
myELM327.sendCommand("2204FE");
delay(2000); // Dà tempo alla risposta di arrivare
if (myELM327.nb_rx_state == ELM_SUCCESS) {
// Estrai il byte dei dati dalla risposta
int dataByteIndex = myELM327.recBytes - 1; // L'ultimo byte dei dati
int A = myELM327.payload[dataByteIndex];
float temperature2 = A - 40; // Applica la formula per ottenere la temperatura
// Mostra la temperatura sul TFT
displayTemperature(temperature2);
delay(100); // Dà tempo alla risposta di arrivare
} else {
// Se anche sendCommand fallisce, mostra l'errore sul TFT
displayError();
myELM327.printError(); // Stampa l'errore sul monitor seriale per il debug
}
}
delay(5000); // Attendere 5 secondi prima della prossima query
}
void displayTemperature(float temperature) {
tft.fillScreen(TFT_BLACK);
tft.setCursor(0, 0);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextSize(2);
tft.print("Temperatura: ");
tft.print(temperature);
tft.println(" °C");
}
void displayError() {
tft.fillScreen(TFT_BLACK);
tft.setCursor(0, 0);
tft.setTextColor(TFT_RED, TFT_BLACK);
tft.setTextSize(2);
tft.println("Errore nella lettura del PID");
}
|
Ok, that's not quite the correct way to query in a loop. First, for a simple sketch, I'd move the header setting into your setup() method and use sendCommandBlocking(): sendCommandBlocking("ATSH DA18F1"); Then remove the delays from the loop and restructure it: void loop() {
if (nb_query_state == SEND_COMMAND)
{
myELM327.sendCommand("2204FE");
nb_query_state = WAITING_RESP;
}
else if (nb_query_state == WAITING_RESP)
{
get_response();
}
if (myELM327.nb_rx_state == ELM_SUCCESS)
{
nb_query_state = SEND_COMMAND;
int A = myELM327.payload[6]; // Prende il valore A dalla risposta
float temperature = A - 40; // Applica la formula per ottenere la temperatura
displayTemperature(temperature);
}
else if (nb_rx_state != ELM_GETTING_MSG)
{
nb_query_state = SEND_COMMAND;
displayError();
myELM327.printError();
} |
thanks a lot for your replay, i'm traing with your suggestion but i receive some compiling error: then i receive this errors: `/Users/Gianlu/Documents/Arduino/chatgpt-dpf/chatgpt-dpf.ino: In function 'void loop()': exit status 1 Compilation error: 'nb_query_state' was not declared in this scope` |
You are right on item 1, that's the correct way to call the method (same for other ELMduino methods used). Note that the code I posted is just a snippet to get you going, not the complete sketch. It looks like your sketch has not included the Can you post the full sketch that you're using (formatted please)? |
hello, i'm not a developer i'm just had a arduino training some years ago...so i found so hard to get some custom pid because there is not example in the library, instead for the standard pid starting fromthe exempla i did it well. so thank you for your help, here is the full code:
|
OK, I took a quick look at this for you and made a couple changes. It compiles without error but I can't test it as I currently don't have access to a TFT panel. #include "BluetoothSerial.h"
#include "ELMduino.h"
#include <TFT_eSPI.h> // Include the TFT_eSPI library for the display
BluetoothSerial SerialBT;
#define ELM_PORT SerialBT
ELM327 myELM327;
TFT_eSPI tft = TFT_eSPI(); // Create a tft object for the display
String obdName = "V-LINK"; // Variable for the OBD Bluetooth name
int nb_query_state = SEND_COMMAND; // Variabile di stato inizializzata a SEND_COMMAND
uint8_t ctoi(uint8_t value)
{
if (value >= 'A')
return value - 'A' + 10;
else
return value - '0';
};
void setup() {
Serial.begin(115200); // Comment or remove after debugging
tft.init(); // Initialize the TFT display
tft.setRotation(1); // Set display orientation if needed
tft.fillScreen(TFT_BLACK); // Clear the screen
tft.setTextFont(4); // Set a larger font size for better readability
tft.setTextColor(TFT_WHITE, TFT_BLACK); // Set text and background color
// Initial Bluetooth connection message
tft.setCursor(0, 0); // Reposition the cursor to the top left corner
tft.println("Connecting to OBD-II");
delay(3000); // Wait for 3 seconds
SerialBT.setPin("1234");
ELM_PORT.begin("ArduHUD", true);
if (!ELM_PORT.connect(obdName)) { // Use obdName variable
tft.fillScreen(TFT_BLACK);
tft.println("Couldn't connect to OBD scanner");
while (1) delay(1000); // Stop the loop if unable to connect
}
if (!myELM327.begin(ELM_PORT, true, 2000)) {
tft.fillScreen(TFT_BLACK);
tft.println("OBD scanner connect failed");
while (1) delay(1000); // Stop the loop if unable to connect
}
// Connected to Bluetooth
tft.fillScreen(TFT_BLACK);
tft.println("Connected to OBD-II");
delay(3000); // Wait for 3 seconds before proceeding
// Clear screen for subsequent data display
tft.fillScreen(TFT_BLACK);
// Imposta l'intestazione OBD specifica per Alfa Romeo Stelvio
myELM327.sendCommand_Blocking("ATSH DA18F1");
}
void loop() {
if (nb_query_state == SEND_COMMAND)
{
myELM327.sendCommand("2204FE");
nb_query_state = WAITING_RESP;
}
else if (nb_query_state == WAITING_RESP)
{
myELM327.get_response();
if (myELM327.nb_rx_state == ELM_SUCCESS)
{
Serial.println("success");
nb_query_state = SEND_COMMAND;
int A = (ctoi(myELM327.payload[6]) << 4) | ctoi(myELM327.payload[7]);
float temperature = float (A - 40); // Applica la formula per ottenere la temperatura
Serial.println(temperature);
}
else if (myELM327.nb_rx_state != ELM_GETTING_MSG)
{
nb_query_state = SEND_COMMAND;
//displayError();
myELM327.printError();
}
}
} |
now is working! i'm so happy! why there isnt examples for that in the librarly example? now i have another problems, i changed the esp32 ttigo to another esp32 t-display s3, that dosn't support classic bluetooth but only BLE. So i'm trying to connect with wifi, the sketch seems to work well, the custom pid initially are correct but after some requests (exaclty after two times that the loops receive correctly the three pids) i receive this error in the serial monitor: Sending the following command/query: 2218E4 this is the sketch, i'm trying to change some delay but without success, the code is the same of the old sketch with bluetooth connection that works well.: #include <WiFi.h>
#include "ELMduino.h"
#include <TFT_eSPI.h>
const char* ssid = "V-LINK";
const char* password = "your-password";
//IP Adress of your ELM327 Dongle
IPAddress server(192, 168, 0, 10);
WiFiClient client;
ELM327 myELM327;
TFT_eSPI tft = TFT_eSPI(); // Crea un oggetto TFT per il display
enum QueryState {
SEND_DPF_CLOGGING, WAITING_DPF_CLOGGING,
SEND_DISTANCE_SINCE_DPF, WAITING_DISTANCE_SINCE_DPF,
SEND_DPF_REGEN_PROCESS, WAITING_DPF_REGEN_PROCESS // Aggiungi gli stati per il processo di rigenerazione DPF
};
QueryState queryState = SEND_DPF_CLOGGING; // Stato iniziale della macchina a stati
uint8_t ctoi(uint8_t value) {
if (value >= 'A')
return value - 'A' + 10;
else
return value - '0';
}
float lastDpfClogging = -1; // Inizializza con un valore che non sarà mai un risultato valido
float lastDistanceSinceDpf = -1; // Analogamente, inizializza con un valore non valido
float lastDpfRegenProcess = -1; // Aggiungi variabile per il processo di rigenerazione DPF
void displayData() {
tft.fillScreen(TFT_BLACK);
tft.setCursor(0, 0);
// Visualizza DPF Clogging con "%"
tft.setTextColor(TFT_WHITE, TFT_BLACK); // Imposta il colore del testo a bianco
if (lastDpfClogging >= 0) {
String dpfCloggingStr = String((int)lastDpfClogging) + "%";
tft.print("DPF Clogging: ");
tft.println(dpfCloggingStr);
}
// Visualizza DPF Distance con "km"
if (lastDistanceSinceDpf >= 0) {
String distanceSinceDpfStr = String((int)lastDistanceSinceDpf) + "km";
tft.print("DPF Distance: ");
tft.println(distanceSinceDpfStr);
}
// Imposta il colore del testo per DPF Regen Process in base al valore
if (lastDpfRegenProcess >= 0) {
if (lastDpfRegenProcess == 0) {
tft.setTextColor(TFT_GREEN, TFT_BLACK); // Verde se 0
} else {
tft.setTextColor(TFT_RED, TFT_BLACK); // Rosso se diverso da 0
}
String dpfRegenProcessStr = String((int)lastDpfRegenProcess) + "%"; // Anche se è un valore percentuale, aggiungiamo "%" per coerenza
tft.print("DPF Regen Proc: ");
tft.println(dpfRegenProcessStr);
}
}
void setup() {
Serial.begin(115200); // Inizia la comunicazione seriale per il debug
tft.init(); // Inizializza il display TFT
tft.setRotation(1); // Imposta l'orientamento del display, se necessario
tft.fillScreen(TFT_BLACK); // Pulisce lo schermo
tft.setTextFont(4); // Imposta una dimensione del font più grande per una migliore leggibilità
tft.setTextColor(TFT_WHITE, TFT_BLACK); // Imposta il colore del testo e dello sfondo
Serial.print("Connecting to ");
tft.println("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_AP);
WiFi.begin(ssid);
// WiFi.begin(ssid, password); //Use this line if your ELM327 has a password protected WiFi
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
tft.print(".");
}
Serial.println("");
Serial.println("Connected to Wifi");
Serial.println("IP address: ");
tft.println("");
tft.println("Connected to Wifi");
tft.println("IP address: ");
Serial.println(WiFi.localIP());
tft.println(WiFi.localIP());
if (client.connect(server, 35000))
tft.println("connected");
else
{
Serial.println("connection failed");
tft.println("connection failed");
while(1);
}
delay(3000); // Attendere prima di procedere
myELM327.begin(client, true, 5000);
delay(3000); // Attendere prima di procedere
myELM327.sendCommand_Blocking("ATSH DA10F1"); // Imposta l'intestazione OBD specifica, se necessario
}
void loop() {
switch (queryState) {
case SEND_DPF_CLOGGING:
Serial.println("Sending command for DPF Clogging...");
myELM327.sendCommand("2218E4");
queryState = WAITING_DPF_CLOGGING;
break;
case WAITING_DPF_CLOGGING:
myELM327.get_response();
if (myELM327.nb_rx_state == ELM_SUCCESS) {
Serial.println("DPF Clogging response received.");
int A = (ctoi(myELM327.payload[6]) << 4) | ctoi(myELM327.payload[7]);
int B = (ctoi(myELM327.payload[8]) << 4) | ctoi(myELM327.payload[9]);
lastDpfClogging = ((A*256) + B) * (1000.0 / 65535.0);
Serial.println(lastDpfClogging);
displayData(); // Aggiorna i dati sul display
queryState = SEND_DISTANCE_SINCE_DPF;
} else if (myELM327.nb_rx_state != ELM_GETTING_MSG) {
Serial.println("Error receiving DPF Clogging data.");
myELM327.printError();
queryState = SEND_DPF_CLOGGING;
}
break;
case SEND_DISTANCE_SINCE_DPF:
Serial.println("Sending command for Distance Since DPF Regeneration...");
myELM327.sendCommand("223807");
queryState = WAITING_DISTANCE_SINCE_DPF;
break;
case WAITING_DISTANCE_SINCE_DPF:
myELM327.get_response();
if (myELM327.nb_rx_state == ELM_SUCCESS) {
Serial.println("Distance Since DPF Regeneration response received.");
int A = (ctoi(myELM327.payload[6]) << 4) + ctoi(myELM327.payload[7]);
int B = (ctoi(myELM327.payload[8]) << 4) + ctoi(myELM327.payload[9]);
int C = (ctoi(myELM327.payload[10]) << 4) + ctoi(myELM327.payload[11]);
lastDistanceSinceDpf = ((A*65536) + (B*256) + C) * 0.1;
Serial.println(lastDistanceSinceDpf);
displayData(); // Aggiorna i dati sul display
queryState = SEND_DPF_REGEN_PROCESS;
} else if (myELM327.nb_rx_state != ELM_GETTING_MSG) {
Serial.println("Error receiving Distance Since DPF Regeneration data.");
myELM327.printError();
queryState = SEND_DISTANCE_SINCE_DPF;
}
break;
case SEND_DPF_REGEN_PROCESS:
Serial.println("Sending command for DPF Regeneration Process...");
myELM327.sendCommand("22380B");
queryState = WAITING_DPF_REGEN_PROCESS;
break;
case WAITING_DPF_REGEN_PROCESS:
myELM327.get_response();
if (myELM327.nb_rx_state == ELM_SUCCESS) {
Serial.println("DPF Regeneration Process response received.");
int A = (ctoi(myELM327.payload[6]) << 4) + ctoi(myELM327.payload[7]);
int B = (ctoi(myELM327.payload[8]) << 4) + ctoi(myELM327.payload[9]);
lastDpfRegenProcess = ((A*256) + B) * (100.0 / 65535.0);
Serial.println(lastDpfRegenProcess);
displayData(); // Aggiorna i dati sul display
queryState = SEND_DPF_CLOGGING; // Ritorna al primo PID per ricominciare il ciclo
} else if (myELM327.nb_rx_state != ELM_GETTING_MSG) {
Serial.println("Error receiving DPF Regeneration Process data.");
myELM327.printError();
queryState = SEND_DPF_REGEN_PROCESS;
}
break;
}
delay(500); // Aggiustamento per ridurre il carico di richieste
} |
Hey! I'm glad to hear it's working for you now. For the sketch above, I have a few observations:
Serial.println(lastDpfClogging);
displayData(); // Aggiorna i dati sul display
queryState = SEND_DISTANCE_SINCE_DPF;
sendCommandBlocking("ATD"); //reset to defaults |
is the three pids have the same header: • DPF clogging: • DPF regeneration process: • Distance covered from last DPF regeneration: the strange fact is that for the first two iterations the pid responds well, on the 3rd with timeout... also the sketch works well of each iteration with the bluetooth obd2 :| what can i test? |
here is the serial monitor
|
To help people with similar queries, I have added a new example sketch to show how to use custom headers and PID. e81f308 It is now on the latest master branch. |
Can you post the full serial output with debugging on so we can see the context of what happens? |
yes, here the full serial monitor:
|
i also tested the simple custom pid with 1 pid and without tft library, with bluetooth connection and odb vgate pro bluetooth classic works well, but wgate wifi and wifi connection do this error described above...i don't know what else to test... |
I don't have a lot of experience with ELM327 via wifi - enough to know that a few of my tests work, but that's about it. It looks like there's some kind of timing issues that are occurring. You could try adding a small delay (100-200ms) after you change query_state in each switch case. The issue you're seeing here clearly hardware specific and not directly related to the ELMduino library itself. |
hello! thank for your work,
can you help me to create a sketch to read de DPF Clogging?, i know that the information to obtain are the following but i don't know exactly to create the sketch
any help?
• DPF clogging:
-> PID = 2218E4
-> equation = ((A256)+B)(1000/65535)
-> OBD Header = DA10F1
The text was updated successfully, but these errors were encountered: