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