OBDII ELM327 mini and esp32 dev module by espressif ----- communication bluetooth problem

ciao a tutti , ho problemi ultimamente con il mio progetto che sto ultimando... sono riuscito a fare un bel manometro usando lvgl, dopodichè ho provato a far funzionare il tutto provando a collegare il mio esp all'obd usando il bluetooth. il mio obd ha un bluetooth low energy perchè se provo a collegarmi da cellulare non mi da un indirizzo mac ma bensì un codice alfanumerico strano.
ho provato questo codice trovato su altri forum e l'ho adattato al mio schermo gc9a01. vi lascio il codice e spero che qualcuno mi riesca ad aiutare, perchè riesco a comunicare con l'obd in quanto vedo la luce verde che lampeggia e questo significa che c'è una comunicazione tra esp e obd, però non riesco a completare il passaggio e a leggere i dati. inoltre ho notato da app che per collegarmi col cellulare, l'app prima fa il collegamento ELM e poi Collegamento ECM, solo dopo aver effettuato questi passaggi riesco a leggere i dati.

/*

* ESP32 OBD2 Reader (BLE) - Codice Completo con MTU Fix e UUID Estesi

*/

#include <BLEDevice.h>

#include <BLEUtils.h>

#include <BLEScan.h>

#include <BLEAdvertisedDevice.h>

#include <SPI.h>

#include <Adafruit_GFX.h>

#include <Adafruit_GC9A01A.h>

// Pinout GC9A01 (SPI)

#define TFT_SCL 18

#define TFT_SDA 23

#define TFT_CS 27

#define TFT_DC 2

#define TFT_RST 4

Adafruit_GC9A01A display(TFT_CS, TFT_DC, TFT_RST);

#define OBD_PROTOCOL "ATSP3"

// Array di UUID per il servizio BLE ELM327 (FFF0, FFE0, 18F0)

static BLEUUID serviceUUIDs[] = {

BLEUUID("0000fff0-0000-1000-8000-00805f9b34fb"),

BLEUUID("0000ffe0-0000-1000-8000-00805f9b34fb"),

BLEUUID("000018f0-0000-1000-8000-00805f9b34fb")

};

static BLEAdvertisedDevice* elmDevice = nullptr;

static BLEClient* pClient = nullptr;

static BLERemoteCharacteristic* pTxCharacteristic = nullptr;

static BLERemoteCharacteristic* pRxCharacteristic = nullptr;

static bool deviceConnected = false;

static bool doConnect = false;

static String receivedData = "";

void displayTemperature(float temperature);

// Callback scansione BLE

class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {

void onResult(BLEAdvertisedDevice advertisedDevice) {

    String name = advertisedDevice.getName().c_str();

    

    if (name == "OBDII" || name.indexOf("OBD") != -1 || name.indexOf("ELM") != -1) {

        Serial.print(">>> Dispositivo OBD trovato: ");

        Serial.println(advertisedDevice.getAddress().toString().c_str());

        

        BLEDevice::getScan()->stop();

        elmDevice = new BLEAdvertisedDevice(advertisedDevice);

        doConnect = true;

    }

}

};

static void notifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic,

                        uint8_t\* pData, size_t length, bool isNotify) {

for (size_t i = 0; i < length; i++) {

    receivedData += (char)pData\[i\];

}

}

class MyClientCallback : public BLEClientCallbacks {

void onConnect(BLEClient\* pclient) {

    Serial.println("✓ Connesso tramite BLE!");

    deviceConnected = true;

}

void onDisconnect(BLEClient\* pclient) {

    Serial.println("✗ Connessione BLE persa");

    deviceConnected = false;

}

};

bool connectToELM327() {

pClient = BLEDevice::createClient();

pClient->setClientCallbacks(new MyClientCallback());



if (!pClient->connect(elmDevice)) return false;



pClient->setMTU(517); // Forzatura MTU per moduli BLE cinesi

delay(500);



BLERemoteService\* pRemoteService = nullptr;



for (int i = 0; i < 3; i++) {

    pRemoteService = pClient->getService(serviceUUIDs\[i\]);

    if (pRemoteService != nullptr) {

        Serial.print("✓ Trovato Servizio BLE: ");

        Serial.println(serviceUUIDs\[i\].toString().c_str());

        break;

    }

}



if (pRemoteService == nullptr) {

    pClient->disconnect();

    return false;

}



std::map<std::string, BLERemoteCharacteristic\*>\* pChars = pRemoteService->getCharacteristics();

for (auto const& pair : \*pChars) {

    BLERemoteCharacteristic\* pChar = pair.second;

    if (pChar->canNotify() || pChar->canIndicate()) pTxCharacteristic = pChar;

    if (pChar->canWrite() || pChar->canWriteNoResponse()) pRxCharacteristic = pChar;

}



if (pTxCharacteristic == nullptr || pRxCharacteristic == nullptr) {

    pClient->disconnect();

    return false;

}



if (pTxCharacteristic->canNotify()) {

    pTxCharacteristic->registerForNotify(notifyCallback);

}



return true;

}

void sendOBDCommand(String command) {

if (!deviceConnected || pRxCharacteristic == nullptr) return;

receivedData = "";

command += "\\r";

pRxCharacteristic->writeValue(command.c_str(), command.length());

}

String waitForResponse(int timeoutMs = 2000) {

unsigned long startTime = millis();

while (millis() - startTime < (unsigned long)timeoutMs) {

    if (receivedData.indexOf('>') != -1) {

        String response = receivedData;

        receivedData = "";

        return response;

    }

    delay(10);

}

return receivedData;

}

bool initializeELM327() {

sendOBDCommand("ATZ"); delay(2500); waitForResponse(3000);

sendOBDCommand("ATE0"); delay(500); waitForResponse();

sendOBDCommand("ATS0"); delay(500); waitForResponse();

sendOBDCommand("ATL0"); delay(500); waitForResponse();

sendOBDCommand(OBD_PROTOCOL); delay(2000); waitForResponse(2500);

sendOBDCommand("0100"); delay(1500); waitForResponse(5000);

return true;

}

float readCoolantTemperature() {

sendOBDCommand("0105");

delay(800);

String response = waitForResponse(4000);



response.replace(" ", "");

response.replace("\\r", "");

response.replace("\\n", "");

response.replace(">", "");



int pidPos = response.indexOf("4105");

if (pidPos == -1) return -999.0;



String hexValue = response.substring(pidPos + 4, pidPos + 6);

if (hexValue.length() < 2) return -999.0;



int tempValue = (int)strtol(hexValue.c_str(), NULL, 16);

float temperature = tempValue - 40.0;



displayTemperature(temperature);

return temperature;

}

void displayTemperature(float temperature) {

display.fillScreen(GC9A01A_BLACK);

display.drawCircle(120, 120, 118, GC9A01A_WHITE);

display.drawCircle(120, 120, 117, GC9A01A_BLUE);



if (temperature <= -999.0) {

    display.setTextSize(3);

    display.setTextColor(GC9A01A_RED);

    display.setCursor(75, 90);

    display.println("ERROR");

    

    display.setTextSize(2);

    display.setTextColor(GC9A01A_WHITE);

    display.setCursor(45, 135);

    display.println("No Connection");

} else {

    display.setTextSize(2);

    display.setTextColor(GC9A01A_CYAN);

    display.setCursor(70, 50);

    display.print("COOLANT");



    display.setTextSize(6);

    display.setTextColor(GC9A01A_WHITE);

    

    String tempStr = String((int)temperature);

    int16_t x = 120 - (tempStr.length() \* 18);

    

    display.setCursor(x - 10, 100);

    display.print((int)temperature);

    

    display.setTextSize(3);

    display.setTextColor(GC9A01A_YELLOW);

    display.print("C");

}

}

void setup() {

Serial.begin(115200);

SPI.begin(TFT_SCL, -1, TFT_SDA, TFT_CS);



display.begin();

display.setRotation(0);

display.fillScreen(GC9A01A_BLACK);



display.drawCircle(120, 120, 118, GC9A01A_BLUE);

display.setTextSize(2);

display.setTextColor(GC9A01A_WHITE);

display.setCursor(50, 110);

display.println("Scanning...");



BLEDevice::init("ESP32_OBD_Reader");

}

void loop() {

if (!deviceConnected && !doConnect) {

    BLEScan\* pBLEScan = BLEDevice::getScan();

    pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());

    pBLEScan->setInterval(1349);

    pBLEScan->setWindow(449);

    pBLEScan->setActiveScan(true);

    pBLEScan->start(5, false);

}



if (doConnect) {

    display.fillScreen(GC9A01A_BLACK);

    display.drawCircle(120, 120, 118, GC9A01A_BLUE);

    display.setTextSize(2);

    display.setTextColor(GC9A01A_YELLOW);

    display.setCursor(45, 110);

    display.println("Connecting..");



    if (connectToELM327()) {

        doConnect = false;

        if (initializeELM327()) {

            Serial.println("Connessione avviata!");

        }

    } else {

        doConnect = false;

        delay(3000);

    }

}



if (deviceConnected) {

    readCoolantTemperature();

    delay(500);

}

}

--------------------------------altro programma con stesso blocco di connessione----------------------------

/*

* ESP32 ELM327 BLE OBD2 Reader - Fix Scansione Continua e Nome OBDII

*/

#include <BLEDevice.h>

#include <BLEUtils.h>

#include <BLEScan.h>

#include <BLEAdvertisedDevice.h>

#include <SPI.h>

#include <Adafruit_GFX.h>

#include <Adafruit_GC9A01A.h>

// ===== GC9A01 Display Pinout (SPI) =====

#define TFT_SCL 18 // Clock (SCL / SCK)

#define TFT_SDA 23 // Data (SDA / MOSI)

#define TFT_CS 27 // Chip Select (CS)

#define TFT_DC 2 // Data/Command (DC)

#define TFT_RST 4 // Reset (RES / RST)

Adafruit_GC9A01A display(TFT_CS, TFT_DC, TFT_RST);

#define SCREEN_WIDTH 240

#define SCREEN_HEIGHT 240

// Protocollo OBD2

#define OBD_PROTOCOL "ATSP3"

#define PROTOCOL_NAME "ISO 9141-2"

// UUID BLE Standard ELM327

#define SERVICE_UUID "0000fff0-0000-1000-8000-00805f9b34fb"

#define CHARACTERISTIC_UUID_TX "0000fff1-0000-1000-8000-00805f9b34fb"

#define CHARACTERISTIC_UUID_RX "0000fff2-0000-1000-8000-00805f9b34fb"

static BLEAdvertisedDevice* elmDevice = nullptr;

static BLEClient* pClient = nullptr;

static BLERemoteCharacteristic* pTxCharacteristic = nullptr;

static BLERemoteCharacteristic* pRxCharacteristic = nullptr;

static bool deviceConnected = false;

static bool doConnect = false;

static String receivedData = "";

void displayTemperature(float temperature);

// Callback scansione BLE migliorata

class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {

void onResult(BLEAdvertisedDevice advertisedDevice) {

    String deviceName = String(advertisedDevice.getName().c_str());

    

    Serial.print("Dispositivo BLE trovato: \[");

    Serial.print(deviceName);

    Serial.print("\] MAC: ");

    Serial.println(advertisedDevice.getAddress().toString().c_str());

    

    // Cerca OBDII, OBD, ELM (sia maiuscolo che minuscolo)

    if (deviceName.indexOf("OBD") != -1 ||

        deviceName.indexOf("ELM") != -1 ||

        deviceName.indexOf("obd") != -1 ||

        deviceName.indexOf("elm") != -1 ||

        deviceName.indexOf("OBDII") != -1) {

        

        Serial.println(">>> TROVATO ADATTATORE OBD! Avvio connessione...");

        BLEDevice::getScan()->stop();

        elmDevice = new BLEAdvertisedDevice(advertisedDevice);

        doConnect = true;

    }

}

};

static void notifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic,

                        uint8_t\* pData, size_t length, bool isNotify) {

for (int i = 0; i < length; i++) {

    receivedData += (char)pData\[i\];

}

}

class MyClientCallback : public BLEClientCallbacks {

void onConnect(BLEClient\* pclient) {

    Serial.println("✓ Connesso a ELM327");

    deviceConnected = true;

}

void onDisconnect(BLEClient\* pclient) {

    Serial.println("✗ Connessione persa");

    deviceConnected = false;

    

    display.fillScreen(GC9A01A_BLACK);

    display.setTextColor(GC9A01A_RED);

    display.setTextSize(2);

    display.setCursor(50, 100);

    display.println("Connessione");

    display.setCursor(70, 130);

    display.println("Persa!");

}

};

bool connectToELM327() {

Serial.println("\\n=== Connessione in corso ===");

pClient = BLEDevice::createClient();

pClient->setClientCallbacks(new MyClientCallback());



if (!pClient->connect(elmDevice)) {

    Serial.println("✗ Errore di connessione");

    return false;

}



BLERemoteService\* pRemoteService = pClient->getService(SERVICE_UUID);

if (pRemoteService == nullptr) {

    pClient->disconnect();

    return false;

}



pTxCharacteristic = pRemoteService->getCharacteristic(CHARACTERISTIC_UUID_TX);

if (pTxCharacteristic == nullptr) {

    pClient->disconnect();

    return false;

}



pRxCharacteristic = pRemoteService->getCharacteristic(CHARACTERISTIC_UUID_RX);

if (pRxCharacteristic == nullptr) {

    pClient->disconnect();

    return false;

}



if (pTxCharacteristic->canNotify()) {

    pTxCharacteristic->registerForNotify(notifyCallback);

}



return true;

}

void sendOBDCommand(String command) {

if (!deviceConnected) return;

receivedData = "";

command += "\\r";

pRxCharacteristic->writeValue(command.c_str(), command.length());

}

String waitForResponse(int timeoutMs = 2000) {

unsigned long startTime = millis();

while (millis() - startTime < timeoutMs) {

    if (receivedData.indexOf('>') != -1) {

        String response = receivedData;

        receivedData = "";

        return response;

    }

    delay(10);

}

return receivedData;

}

bool initializeELM327() {

sendOBDCommand("ATZ"); delay(2500); waitForResponse(3000);

sendOBDCommand("ATE0"); delay(500); waitForResponse();

sendOBDCommand("ATS0"); delay(500); waitForResponse();

sendOBDCommand("ATL0"); delay(500); waitForResponse();



sendOBDCommand(OBD_PROTOCOL); delay(2000); waitForResponse(2500);



sendOBDCommand("ATH0"); delay(500); waitForResponse();

sendOBDCommand("ATAT2"); delay(500); waitForResponse();

sendOBDCommand("ATSTFF"); delay(500); waitForResponse();

sendOBDCommand("ATAL"); delay(500); waitForResponse();

sendOBDCommand("ATKW"); delay(500); waitForResponse();



sendOBDCommand("0100"); delay(1500); waitForResponse(5000);

return true;

}

float readCoolantTemperature() {

sendOBDCommand("0105");

delay(800);

String response = waitForResponse(4000);



if (response.indexOf("NO DATA") != -1 || response.indexOf("UNABLE") != -1) {

    sendOBDCommand("ATZ"); delay(2000); waitForResponse(3000);

    sendOBDCommand(OBD_PROTOCOL); delay(1500); waitForResponse(2000);

    return -999.0;

}



response.replace(" ", "");

response.replace("\\r", "");

response.replace("\\n", "");

response.replace(">", "");



int pidPos = response.indexOf("4105");

if (pidPos == -1) return -999.0;



String hexValue = response.substring(pidPos + 4, pidPos + 6);

if (hexValue.length() < 2) return -999.0;



int tempValue = (int)strtol(hexValue.c_str(), NULL, 16);

float temperature = tempValue - 40.0;



displayTemperature(temperature);

return temperature;

}

void displayTemperature(float temperature) {

display.fillScreen(GC9A01A_BLACK);

display.drawCircle(120, 120, 118, GC9A01A_WHITE);

display.drawCircle(120, 120, 117, GC9A01A_BLUE);



if (temperature <= -999.0) {

    display.setTextSize(3);

    display.setTextColor(GC9A01A_RED);

    display.setCursor(75, 90);

    display.println("ERROR");

    

    display.setTextSize(2);

    display.setTextColor(GC9A01A_WHITE);

    display.setCursor(45, 135);

    display.println("No Connection");

} else {

    display.setTextSize(2);

    display.setTextColor(GC9A01A_CYAN);

    display.setCursor(70, 50);

    display.print("COOLANT");



    display.setTextSize(6);

    display.setTextColor(GC9A01A_WHITE);

    

    String tempStr = String((int)temperature);

    int16_t x = 120 - (tempStr.length() \* 18);

    

    display.setCursor(x - 10, 100);

    display.print((int)temperature);

    

    display.setTextSize(3);

    display.setTextColor(GC9A01A_YELLOW);

    display.print("C");

}

}

void setup() {

Serial.begin(115200);



SPI.begin(TFT_SCL, -1, TFT_SDA, TFT_CS);



display.begin();

display.setRotation(0);

display.fillScreen(GC9A01A_BLACK);



display.drawCircle(120, 120, 118, GC9A01A_BLUE);

display.setTextSize(3);

display.setTextColor(GC9A01A_WHITE);

display.setCursor(80, 80);

display.println("OBD2");

display.setCursor(65, 115);

display.println("Reader");



display.setTextSize(2);

display.setTextColor(GC9A01A_GREEN);

display.setCursor(60, 160);

display.println("Starting...");

delay(2000);



BLEDevice::init("ESP32_OBD_Reader");



display.fillScreen(GC9A01A_BLACK);

display.drawCircle(120, 120, 118, GC9A01A_BLUE);

display.setTextSize(2);

display.setTextColor(GC9A01A_WHITE);

display.setCursor(50, 110);

display.println("Scanning...");

}

void loop() {

// Se non è connesso e non ha trovato il dispositivo, continua la scansione

if (!deviceConnected && !doConnect) {

    BLEScan\* pBLEScan = BLEDevice::getScan();

    pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());

    pBLEScan->setInterval(1349);

    pBLEScan->setWindow(449);

    pBLEScan->setActiveScan(true);

    pBLEScan->start(5, false); // Scansiona a blocchi di 5 secondi in continuo

}



if (doConnect) {

    display.fillScreen(GC9A01A_BLACK);

    display.drawCircle(120, 120, 118, GC9A01A_BLUE);

    display.setTextSize(2);

    display.setTextColor(GC9A01A_YELLOW);

    display.setCursor(45, 110);

    display.println("Connecting..");



    if (connectToELM327()) {

        doConnect = false;

        if (initializeELM327()) {

            Serial.println("Inizio lettura dati!");

        }

    } else {

        doConnect = false;

        delay(3000);

    }

}



if (deviceConnected) {

    readCoolantTemperature();

    delay(500);

}

}

Buongiorno e benvenuto nella sezione Italiana del forum,

cortesemente, come prima cosa, leggi attentamente il REGOLAMENTO di detta sezione, (... e, per evitare future possibili discussioni/incomprensioni, prestando molta attenzione al punto 15), dopo di che, come da suddetto regolamento (punto 16.7), fai la tua presentazione NELL'APPOSITA DISCUSSIONE (... quello che vedi in blu è un link, fai click su di esso per raggiungere la discussione) spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.

Inoltre ti invito a modificare il listato che hai messo nel primo post, e selezionare tutto e solo il codice e cliccare sul pulsante "<CODE/>" il quale lo inserisce tra opportuni marcatori, impedendo al forum di "interpretare" male caratteri speciali che renderebbero inutilizzabile il tuo codice (che, come forse puoi vedere, non è corretto e quindi impedisce anche a noi sia di leggerlo sia di copiarlo per provarlo).

Grazie,

Alex

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposita discussione, nel rispetto del succitato regolamento nessuno ti risponderà (eventuali risposte o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farla al più presto. ;)

Perche qualcuno si e altri no?

Ciao, Ale.

Perché docdoc NON controlla mai il profilo utente ... :roll_eyes:

Guglielmo