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

custom pid for DPF #235

Open
gianluca-tursi opened this issue Mar 10, 2024 · 17 comments
Open

custom pid for DPF #235

gianluca-tursi opened this issue Mar 10, 2024 · 17 comments
Assignees
Labels
question Further information is requested

Comments

@gianluca-tursi
Copy link

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

@gianluca-tursi gianluca-tursi added the question Further information is requested label Mar 10, 2024
@gianluca-tursi
Copy link
Author

hello i'm traing this code but i receive error on sending the headr:

`#include "BluetoothSerial.h"
#include "ELMduino.h"
#include <TFT_eSPI.h> // Include the TFT_eSPI library for the display

BluetoothSerial SerialBT;
#define ELM_PORT SerialBT
// #define DEBUG_PORT Serial // Comment or remove after debugging

ELM327 myELM327;
TFT_eSPI tft = TFT_eSPI(); // Create a tft object for the display
String obdName = "V-LINK"; // Variable for the OBD Bluetooth name

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.c_str())) { // 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("AT SH DA10F1");

}

void loop() {
// Verifica se l'intestazione è stata impostata correttamente
if (myELM327.queryPID(0x01, 0x00)) { // Questa è una richiesta di prova per vedere se otteniamo una risposta
Serial.println("Intestazione impostata, inviando comando custom...");
} else {
Serial.println("Errore nell'impostazione dell'intestazione OBD.");
}

// Invia il comando custom per ottenere i dati di interesse
myELM327.sendCommand("2218E4");
Serial.println("Comando inviato, attendendo la risposta...");

delay(100); // Dà tempo alla risposta di arrivare

// Controlla lo stato della risposta ricevuta
if (myELM327.nb_rx_state == ELM_SUCCESS) {
    Serial.println("Risposta ricevuta con successo. Dati:");
    for (byte i = 0; i < myELM327.recBytes; i++) {
        Serial.print(myELM327.payload[i], HEX);
        Serial.print(" ");
    }
    Serial.println();
} else if (myELM327.nb_rx_state == ELM_GETTING_MSG) {
    Serial.println("In attesa della risposta...");
} else {
    Serial.println("Nessuna risposta valida ricevuta.");
    // Mostra il codice di errore per il debugging
    Serial.print("Codice di errore: ");
    Serial.println(myELM327.nb_rx_state);
}

delay(5000); // Attendi prima di inviare una nuova richiesta

}
`

@gianluca-tursi
Copy link
Author

i'm traing different code without success...

`void setup {
....
myELM327.sendCommand("AT SH DA10F1");
....
}

void loop() {
myELM327.sendCommand("2218E4");
delay(100); // Questo valore può variare a seconda del modulo OBD-II

// Controlla lo stato della risposta
if (myELM327.nb_rx_state == ELM_SUCCESS) {
Serial.println("Risposta ricevuta. Dati grezzi:");

// Itera attraverso i byte ricevuti e li stampa sul monitor seriale
for (byte i = 0; i < myELM327.recBytes; i++) {
  Serial.print(myELM327.payload[i], HEX);
  Serial.print(" ");
}
Serial.println(); // Vai a capo dopo l'ultimo byte

} else if (myELM327.nb_rx_state == ELM_GETTING_MSG) {
Serial.println("In attesa della risposta...");
} else {
Serial.println("Errore nella ricezione della risposta o nessun dato ricevuto.");
}

// Attendi prima di inviare una nuova richiesta
delay(5000); // Aumenta o diminuisci secondo le necessità
}
`

without success...if someone can help

@gianluca-tursi
Copy link
Author

gianluca-tursi commented Mar 13, 2024

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.
this is the pid
#7 Gearbox oil temperature
OBD Mode&PID -- 2204fe
Unit Type -- ℃
Equation -- A-40
OBD Header -- DA18F1

on the app i see this result:
ELM: 18DAF118046204FE52
A:52
result: 42°

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");
}

@jimwhitelaw
Copy link
Collaborator

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();
}

@gianluca-tursi
Copy link
Author

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:
1: the command that you wrote: sendCommandBlocking("ATSH DA18F1"); is correct? i thinkthat is myELM327.sendCommand_Blocking("ATSH DA18F1"); the correct one.

then i receive this errors:

`/Users/Gianlu/Documents/Arduino/chatgpt-dpf/chatgpt-dpf.ino: In function 'void loop()':
/Users/Gianlu/Documents/Arduino/chatgpt-dpf/chatgpt-dpf.ino:59:5: error: 'nb_query_state' was not declared in this scope
if (nb_query_state == SEND_COMMAND)
^~~~~~~~~~~~~~
/Users/Gianlu/Documents/Arduino/chatgpt-dpf/chatgpt-dpf.ino:66:5: error: 'get_response' was not declared in this scope
get_response();
^~~~~~~~~~~~
/Users/Gianlu/Documents/Arduino/chatgpt-dpf/chatgpt-dpf.ino:66:5: note: suggested alternative: 'transpose'
get_response();
^~~~~~~~~~~~
transpose
/Users/Gianlu/Documents/Arduino/chatgpt-dpf/chatgpt-dpf.ino:71:14: error: 'obd_cmd_states ELM327::nb_query_state' is private within this context
myELM327.nb_query_state = SEND_COMMAND;
^~~~~~~~~~~~~~
In file included from /Users/Gianlu/Documents/Arduino/chatgpt-dpf/chatgpt-dpf.ino:2:
/Users/Gianlu/Documents/Arduino/libraries/ELMDuino/src/ELMduino.h:428:34: note: declared private here
obd_cmd_states nb_query_state = SEND_COMMAND; // Non-blocking query state
^~~~~~~~~~~~
/Users/Gianlu/Documents/Arduino/chatgpt-dpf/chatgpt-dpf.ino:74:5: error: 'displayTemperature' was not declared in this scope
displayTemperature(temperature);
^~~~~~~~~~~~~~~~~~
/Users/Gianlu/Documents/Arduino/chatgpt-dpf/chatgpt-dpf.ino:74:5: note: suggested alternative: 'temperature'
displayTemperature(temperature);
^~~~~~~~~~~~~~~~~~
temperature
/Users/Gianlu/Documents/Arduino/chatgpt-dpf/chatgpt-dpf.ino:79:5: error: 'nb_query_state' was not declared in this scope
nb_query_state = SEND_COMMAND;
^~~~~~~~~~~~~~
/Users/Gianlu/Documents/Arduino/chatgpt-dpf/chatgpt-dpf.ino:80:5: error: 'displayError' was not declared in this scope
displayError();
^~~~~~~~~~~~

exit status 1

Compilation error: 'nb_query_state' was not declared in this scope`

@jimwhitelaw
Copy link
Collaborator

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)?

@gianluca-tursi
Copy link
Author

gianluca-tursi commented Mar 19, 2024

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:

#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

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.c_str())) { // 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)
{
  get_response();
}
  // Clear screen for subsequent data display
    //tft.fillScreen(TFT_BLACK);
if (myELM327.nb_rx_state == ELM_SUCCESS) 
{ 
    Serial.println("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
    Serial.println(temperature);
}
 
else if (myELM327.nb_rx_state != ELM_GETTING_MSG)
{
    nb_query_state = SEND_COMMAND; 
    //displayError();
    myELM327.printError();
}
}

@jimwhitelaw
Copy link
Collaborator

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();
        }
    }
}

@gianluca-tursi
Copy link
Author

gianluca-tursi commented Mar 28, 2024

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.

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
Timeout detected with overflow of 0ms
Error receiving Distance Since DPF Regeneration data.
Received:
ERROR: ELM_TIMEOUT
Sending command for Distance Since DPF Regeneration...
Clearing input serial buffer

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
}

@jimwhitelaw
Copy link
Collaborator

Hey! I'm glad to hear it's working for you now. For the sketch above, I have a few observations:

  • I don't think adding a delay in every iteration of your loop will be helpful. If it's needed at all, it would make more sense to do so after a query is complete before starting the next one.
  • The issue seen now could be related to how the header is being set with myELM327.sendCommand_Blocking("ATSH DA10F1"). That header requests a specific ECU in the system to respond. Are you sure that is the correct setting for each of the commands being sent?
  • If the second and third queries do need to have a different header set then the best place to do so would be when the queryState is updated, so it's ready for the next query. Either set it to defaults, or the new required header. Example:
Serial.println(lastDpfClogging);
displayData(); // Aggiorna i dati sul display
queryState = SEND_DISTANCE_SINCE_DPF;
sendCommandBlocking("ATD"); //reset to defaults

@gianluca-tursi
Copy link
Author

  • That header requests a specific ECU in the system to respond. Are you sure that is the correct settin

is the three pids have the same header:

• DPF clogging:
-> PID = 2218E4
-> equation = ((A256)+B)(1000/65535)
-> OBD Header = DA10F1

• DPF regeneration process:
-> PID = 22380B
-> equation = ((A256)+B)(100/65535)
-> OBD Header = DA10F1

• Distance covered from last DPF regeneration:
-> PID = 223807
-> equation = ((A65536)+(B256)+C)*0.1
-> OBD Header = DA10F1

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?

@gianluca-tursi
Copy link
Author

here is the serial monitor

Sending command for Distance Since DPF Regeneration...
Clearing input serial buffer
Sending the following command/query: 223807
Timeout detected with overflow of 0ms
Error receiving Distance Since DPF Regeneration data.
Received: 
ERROR: ELM_TIMEOUT
Sending command for Distance Since DPF Regeneration...
Clearing input serial buffer
Sending the following command/query: 223807

@jimwhitelaw
Copy link
Collaborator

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.

@jimwhitelaw
Copy link
Collaborator

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 :|

Can you post the full serial output with debugging on so we can see the context of what happens?

@gianluca-tursi
Copy link
Author

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 :|

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:

Connecting to V-LINK
.
Connected to Wifi
IP address: 
192.168.0.150
Clearing input serial buffer
Sending the following command/query: AT D
	Received char: A
	Received char: T
	Received char: _
	Received char: D
	Received char: \r
	Received charClearing input serial buffer
Sending the following command/query: AT AL
	Received char: O
	Received char: K
	Received char: \r
	Received char: \r
	Received char: >
Delimiter found.
All chars received: OK
Clearing input serial buffer
Sending the following command/query: AT ST 00
Received char: O
	Received char: K
	Received char: \r
	Received char: \r
	Received char: >
Delimiter found.
All chars received: OK
Clearing input serial buffer
Sending the following command/query: AT SP A0
	Received char: O
	Received char: K
	Received char: \r
	Received char: \r
	Received char: >
Delimiter found.
All chars received: OK
Clearing input serial buffer
Sending the following command/query: 0100
	Received char: S
	Received char: E
Received char: A
	Received char: R
	Received char: C
	Received char: H
	Received char: I
	Received char: N
	Received char: G
	Received char: .
	Received char: .
	Received char: .
	Received char: \r
	Received char: 4
	Received char: 1
	Received char: 0
	Received char: 0
	Received char: 9
	Received char: 8
	Received char: 1
	Received char: 8
	Received char: 0
Received char: 0
	Received char: 1
	Received char: 1
	Received char: \r
	Received char: 4
	Received char: 1
	Received char: 0
	Received char: 0
	Received char: 9
	Received char: 8
	Received char: 3
	Received char: 9
	Received char: 2
	Received char: 0
	Received char: 1
	Received char: 3
	Received char: \r
	Received char: 4
	Received char: 1
	Received char: 0
	Received char: 0
Received char: 9
OBD receive buffer overflow (> 40 bytes)
Setting protocol via AT TP A%c did not work - trying via AT SP %c
Clearing input serial buffer
Sending the following command/query: AT SP 0
	Received char: S
	Received char: T
	Received char: O
	Received char: P
	Received char: P
	Received char: E
	Received char: D
	Received char: \r
	Received char: \r
	Received char: >
Delimiter found.
All chars received: STOPPED
ELM responded with error "STOPPED"
Setting protocol via AT SP %c did not work
Clearing input serial buffer
Sending the following command/query: ATSH DA10F1
Received char: O
	Received char: K
	Received char: \r
	Received char: \r
	Received char: >
Delimiter found.
All chars received: OK
Sending command for DPF Clogging...
Clearing input serial buffer
Sending the following command/query: 2218E4
	Received char: N
	Received char: O
	Received char: _
	Received char: D
	Received char: A
	Received char: T
	Received char: A
	Received char: \r
	Received char: \r
	Received char: >
Delimiter found.
All chars received: NODATA
ELM responded with error "NO DATA"
Error receiving DPF Clogging data.
Received: NODATA
ERROR: ELM_NO_DATA
errore conto1Sending command for DPF Clogging...
Clearing input serial buffer
Sending the following command/query: 2218E4
	Received char: 6
	Received char: 2
	Received char: 1
	Received char: 8
	Received char: E
	Received char: 4
	Received char: 0
	Received char: 4
	Received char: C
	Received char: 8
Received char: \r
	Received char: \r
	Received char: >
Delimiter found.
All chars received: 6218E404C8
DPF Clogging response received.
18.68
Sending command for Distance Since DPF Regeneration...
Clearing input serial buffer
Sending the following command/query: 223807
	Received char: 6
	Received char: 2
	Received char: 3
	Received char: 8
	Received char: 0
	Received char: 7
	Received char: 0
	Received char: 0
Received char: 0
	Received char: 0
	Received char: D
	Received char: 2
	Received char: \r
	Received char: \r
	Received char: >
Delimiter found.
All chars received: 6238070000D2
Distance Since DPF Regeneration response received.
21.00
Sending command for DPF Regeneration Process...
Clearing input serial buffer
Sending the following command/query: 22380B
	Received char: 6
	Received char: 2
	Received char: 3
	Received char: 8
	Received char: 0
	Received char: B
	Received char: 0
	Received char: 0
	Received char: 0
	Received char: 0
	Received char: \r
	Received char: \r
	Received char: >
Delimiter found.
All chars received: 62380B0000
DPF Regeneration Process response received.
0.00
Sending command for DPF Clogging...
Clearing input serial buffer
Sending the following command/query: 2218E4
	Received char: 6
	Received char: 2
	Received char: 1
	Received char: 8
	Received char: E
	Received char: 4
Received char: 0
	Received char: 4
	Received char: C
	Received char: 8
	Received char: \r
	Received char: \r
	Received char: >
Delimiter found.
All chars received: 6218E404C8
DPF Clogging response received.
18.68
Sending command for Distance Since DPF Regeneration...
Clearing input serial buffer
Sending the following command/query: 223807
	Received char: 6
	Received char: 2
Received char: 3
	Received char: 8
	Received char: 0
	Received char: 7
	Received char: 0
	Received char: 0
	Received char: 0
	Received char: 0
	Received char: D
	Received char: 2
	Received char: \r
	Received char: \r
	Received char: >
Delimiter found.
All chars received: 6238070000D2
Distance Since DPF Regeneration response received.
21.00
Sending command for DPF Regeneration Process...
Clearing input serial buffer
Sending the following command/query: 22380B
Received char: 6
	Received char: 2
	Received char: 3
	Received char: 8
	Received char: 0
	Received char: B
	Received char: 0
	Received char: 0
	Received char: 0
	Received char: 0
	Received char: \r
	Received char: \r
	Received char: >
Delimiter found.
All chars received: 62380B0000
DPF Regeneration Process response received.
0.00
Sending command for DPF Clogging...
Clearing input serial buffer
Sending the following command/query: 2218E4
Timeout detected with overflow of 0ms
Error receiving DPF Clogging data.
Received: 
ERROR: ELM_TIMEOUT
errore conto2Sending command for DPF Clogging...
Clearing input serial buffer
Sending the following command/query: 2218E4
Timeout detected with overflow of 0ms
Error receiving DPF Clogging data.
Received: 
ERROR: ELM_TIMEOUT

@gianluca-tursi
Copy link
Author

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...

@jimwhitelaw
Copy link
Collaborator

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.

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

No branches or pull requests

3 participants