torres.electronico
Well-known-Alfil
buenas, como va?
estoy armando una interface de comunicacion entre un arduino nano (+ HC05 + OLED128x64 I2c) y el ELM327 y estoy teniendo problemas con el HC-05...
Como no queria depender de librerias, arranque con un formato de comandos de comunicacion estandar del ELM327 y note que no tenia respuesta alguna (hice mas de 7 versiones distintas y nada...)
llegue al punto de dudar si realmente me estaba respondiendo el HC-05, asi que arme el siguiente sketch para ver si podía configurar el modulo bluetooth y de ahi, usando el monitor configurar manualmente todo para que quede guardada la mac y despues se conecte solo:
los comandos implementados fueron:
AT
AT+NAME=HC05_OBD
AT+PSWD=1234
AT+ROLE=1
AT+UART=9600,0,0 (probe casi todas)
AT+CMODE=0
AT+BIND=1C,A1,35,69,8D,C5
AT+LINK=1C,A1,35,69,8D,C5
AT+RESET
y nada....
AT
AT+ROLE=1
AT+CMODE=0
AT+INQM=1,9,48
AT+INIT
AT+INQ
espere ver la mac y nunca respondio...asi que me fije desde una app del telefono la mac y...
AT+PAIR=1C,A1,35,69,8D,C5,20
AT+BIND=1C,A1,35,69,8D,C5
AT+LINK=1C,A1,35,69,8D,C5
AT+RESET
Todo esto me dio errores (0/6y16)... la verdad no recuerdo exactamente el orden, pero en fin... Intente hacer algo de emparejamiento automatico:
y seguia sin comunicacion... Al parecer, este modulo es muy chino y viene con una version de firmware muy vieja (eso interpreto de los foros que lei) y no reconoce muchos comandos... la cosa es que no pude hacerlo funcionar, asi que cai en una libreria
(ELMDuino) y tampoco funciono...
estoy suponiendo que el problema esta en el modulo bluetooth... si alguien experimento lo mismo y me puede dar una mano, le agradezco de antemano... La otra que me queda, es implementar un esp32 que tengo guardadito como oro por ahi, pero es caro para este proyecto...
El hardware en esta beta es sencillo:
-Arduino NANO
-Oled SH1106 I2c
-HC-05
estoy armando una interface de comunicacion entre un arduino nano (+ HC05 + OLED128x64 I2c) y el ELM327 y estoy teniendo problemas con el HC-05...
Como no queria depender de librerias, arranque con un formato de comandos de comunicacion estandar del ELM327 y note que no tenia respuesta alguna (hice mas de 7 versiones distintas y nada...)
CSS:
#include <U8glib.h>
#include <SoftwareSerial.h>
// ------------------- OLED SH1106 -------------------
U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE);
// ------------------- HC-05 (SoftwareSerial) -------------------
SoftwareSerial HC05(10, 11); // RX, TX
// ------------------- Variables OBD -------------------
int rpm = 0;
float boost = 0;
float tempRefrig = 0;
float voltaje = 0;
// ------------------- Setup -------------------
void setup() {
Serial.begin(115200); // Debug PC
HC05.begin(9600); // HC-05 maestro ya configurado
// Debug inicial en OLED
u8g.firstPage();
do {
u8g.setFont(u8g_font_6x10);
u8g.drawStr(0,0,"DEBUG INICIAL");
u8g.drawStr(0,15,"HC-05 configurado a 9600");
u8g.drawStr(0,30,"Rol: Maestro");
u8g.drawStr(0,45,"Nombre: HC05_OBD");
} while(u8g.nextPage());
delay(1000);
// Inicialización ELM327
sendELM("ATZ");
sendELM("ATE0");
sendELM("ATL0");
sendELM("ATS0");
sendELM("ATH0");
sendELM("ATSP0");
}
// ------------------- Loop -------------------
void loop() {
// Leer PIDs reales desde ELM327
rpm = leerPID("010C"); // RPM
boost = leerPID("010B")/10.0; // Boost bar
tempRefrig = leerPID("0105"); // Temp C
voltaje = leerPID("012F")/10.0; // Voltaje
// Mostrar en pantalla
u8g.firstPage();
do {
u8g.setFont(u8g_font_6x10);
u8g.drawStr(0,0,"RPM / BOOST / TEMP / VOLT");
char buf[20];
sprintf(buf,"RPM: %d", rpm);
u8g.drawStr(0,15,buf);
sprintf(buf,"Boost: %.2f bar", boost);
u8g.drawStr(0,30,buf);
sprintf(buf,"Temp: %.1f C", tempRefrig);
u8g.drawStr(0,45,buf);
sprintf(buf,"Volt: %.1f V", voltaje);
u8g.drawStr(0,60,buf);
} while(u8g.nextPage());
delay(500);
}
// ------------------- Funciones -------------------
// Enviar comando al ELM327 y mostrar debug
void sendELM(String cmd) {
HC05.println(cmd);
delay(300);
String resp = "";
unsigned long t = millis();
while(millis()-t < 300) {
while(HC05.available()) {
char c = HC05.read();
resp += c;
}
}
Serial.print("CMD: "); Serial.print(cmd);
Serial.print(" RESP: "); Serial.println(resp);
// Debug en OLED
u8g.firstPage();
do {
u8g.setFont(u8g_font_6x10);
u8g.drawStr(0,0,("CMD: "+cmd).c_str());
u8g.drawStr(0,15,("RESP: "+resp).c_str());
} while(u8g.nextPage());
delay(200);
}
// ------------------- Leer PID simple -------------------
int leerPID(String pid) {
HC05.println(pid);
delay(200);
String resp = "";
unsigned long t = millis();
while(millis()-t < 300) {
while(HC05.available()) {
char c = HC05.read();
if(c != '\r' && c != '\n') resp += c;
}
}
resp.trim();
resp.toUpperCase();
// Extraer los últimos 2-4 bytes de la respuesta
if(resp.length() >= 4) {
int a = strtoul(resp.substring(resp.length()-4,resp.length()-2).c_str(),NULL,16);
int b = strtoul(resp.substring(resp.length()-2).c_str(),NULL,16);
return a*256 + b;
}
return 0;
}
llegue al punto de dudar si realmente me estaba respondiendo el HC-05, asi que arme el siguiente sketch para ver si podía configurar el modulo bluetooth y de ahi, usando el monitor configurar manualmente todo para que quede guardada la mac y despues se conecte solo:
CSS:
#include <SoftwareSerial.h>
SoftwareSerial BT(10,11); // RX,TX
long bauds[] = {9600, 38400};
void setup(){
Serial.begin(115200);
Serial.println(F("=== HC-05 AUTO TEST ==="));
delay(200);
for(int i=0;i<2;i++){
long b = bauds[i];
Serial.print("Probar baud "); Serial.println(b);
BT.end();
delay(50);
BT.begin(b);
delay(200);
// enviar AT simple y AT+VERSION?
Serial.print("-> Enviando 'AT' a "); Serial.println(b);
BT.print("AT\r\n");
delay(400);
readDump();
Serial.print("-> Enviando 'AT+VERSION?' a "); Serial.println(b);
BT.print("AT+VERSION?\r\n");
delay(600);
readDump();
Serial.println("-------------------------");
delay(300);
}
Serial.println("FIN PRUEBA. Ahora escribe comandos (monitor -> BT).");
}
void loop(){
if (Serial.available()) BT.write(Serial.read()); // lo que escribas va a HC-05
if (BT.available()) Serial.write(BT.read()); // lo que responda HC-05 va al monitor
}
void readDump(){
unsigned long t = millis();
String r="";
while(millis()-t < 800){
while(BT.available()){
char c = (char)BT.read();
r += c;
}
}
if(r.length()) {
Serial.print(" RESPUESTA: '"); Serial.print(r); Serial.println("'");
} else {
Serial.println(" RESPUESTA: (sin datos)");
}
}
los comandos implementados fueron:
AT
AT+NAME=HC05_OBD
AT+PSWD=1234
AT+ROLE=1
AT+UART=9600,0,0 (probe casi todas)
AT+CMODE=0
AT+BIND=1C,A1,35,69,8D,C5
AT+LINK=1C,A1,35,69,8D,C5
AT+RESET
y nada....
AT
AT+ROLE=1
AT+CMODE=0
AT+INQM=1,9,48
AT+INIT
AT+INQ
espere ver la mac y nunca respondio...asi que me fije desde una app del telefono la mac y...
AT+PAIR=1C,A1,35,69,8D,C5,20
AT+BIND=1C,A1,35,69,8D,C5
AT+LINK=1C,A1,35,69,8D,C5
AT+RESET
Todo esto me dio errores (0/6y16)... la verdad no recuerdo exactamente el orden, pero en fin... Intente hacer algo de emparejamiento automatico:
CSS:
#include <SoftwareSerial.h>
SoftwareSerial BT(10, 11); // RX, TX
void setup() {
Serial.begin(9600);
Serial.println("=== HC-05 Auto-Link ELM327 ===");
BT.begin(38400); // Modo AT completo
delay(1000);
enviar("AT");
enviar("AT+RESET");
enviar("AT+ROLE=1"); // Modo maestro
enviar("AT+CMODE=1"); // Permitir conexión con cualquier dispositivo
enviar("AT+INIT");
enviar("AT+INQ"); // Buscar dispositivos cercanos
delay(5000);
Serial.println("Intentando conectar al ELM327...");
enviar("AT+LINK=1C,A1,35,69,8D,C5"); // tu dirección (ajustar si cambia)
delay(5000);
Serial.println("Listo. Si LED del HC-05 queda fijo, se conectó al ELM327.");
Serial.println("Podés cargar ahora el sketch principal.");
}
void loop() {
if (BT.available()) Serial.write(BT.read());
if (Serial.available()) BT.write(Serial.read());
}
void enviar(String cmd) {
Serial.print(">> "); Serial.println(cmd);
BT.print(cmd); BT.print("\r\n");
delay(500);
while (BT.available()) Serial.write(BT.read());
}
CSS:
#include <Wire.h>
#include <U8glib.h>
#include <SoftwareSerial.h>
#include "ELMduino.h"
// --- OLED U8glib ---
U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE);
// --- SoftwareSerial para HC-05 / ELM327 ---
#define ELM_RX 10
#define ELM_TX 11
SoftwareSerial elmSerial(ELM_RX, ELM_TX);
ELM327 myELM327;
// --- Variables OBD ---
float rpmVal = 0;
float speed = 0;
float coolantTemp = 0;
float batteryV = 0;
float boostKPa = 0;
unsigned long lastUpdate = 0;
const unsigned long updateInterval = 500; // ms
unsigned long lastDataTime = 0;
const unsigned long timeoutComm = 3000; // ms antifreeze
typedef enum { ENG_RPM, SPEED, COOLANT_TEMP, BATT_VOLT, BOOST } obd_pid_states;
obd_pid_states obd_state = ENG_RPM;
// --- Setup ---
void setup() {
Serial.begin(115200);
Wire.begin();
delay(250);
// Inicializar OLED
Serial.println("Iniciando OLED...");
u8g.firstPage();
do {
u8g.setFont(u8g_font_6x10);
u8g.drawStr(10, 30, "OLED OK!");
} while(u8g.nextPage());
Serial.println("OLED inicializado correctamente");
// Inicializar ELM327
elmSerial.begin(38400); // coincide con HC-05 configurado
myELM327.begin(elmSerial);
lastDataTime = millis();
Serial.println("Esperando datos del ELM327...");
}
// --- Loop ---
void loop() {
unsigned long currentMillis = millis();
if(currentMillis - lastUpdate >= updateInterval){
lastUpdate = currentMillis;
bool newData = false;
// --- Lectura PID ---
switch(obd_state){
case ENG_RPM:
rpmVal = myELM327.rpm();
obd_state = SPEED;
newData = true; break;
case SPEED:
speed = myELM327.kph();
obd_state = COOLANT_TEMP;
newData = true; break;
case COOLANT_TEMP:
coolantTemp = myELM327.engineCoolantTemp();
obd_state = BATT_VOLT;
newData = true; break;
case BATT_VOLT:
batteryV = myELM327.batteryVoltage();
obd_state = BOOST;
newData = true; break;
case BOOST:
boostKPa = myELM327.manifoldPressure();
obd_state = ENG_RPM;
newData = true; break;
}
if(newData) lastDataTime = millis();
// --- Dibujar en pantalla ---
u8g.firstPage();
do {
drawData();
} while(u8g.nextPage());
}
}
// --- Función para dibujar datos ---
void drawData() {
char buf[20];
u8g.setFont(u8g_font_6x10);
// Fila 1: Voltaje
sprintf(buf, "Volt: %.1f V", batteryV);
u8g.drawStr(0, 10, buf);
// Fila 2: RPM
sprintf(buf, "RPM: %.0f", rpmVal);
u8g.drawStr(0, 22, buf);
// Fila 3: Temp
sprintf(buf, "Temp: %.0f C", coolantTemp);
u8g.drawStr(0, 34, buf);
// Fila 4: Boost
if(millis() - lastDataTime > timeoutComm){
u8g.drawStr(0, 46, "Perdida de comunicacion");
} else {
sprintf(buf, "Boost: %.0f kPa", boostKPa);
u8g.drawStr(0, 46, buf);
}
}
estoy suponiendo que el problema esta en el modulo bluetooth... si alguien experimento lo mismo y me puede dar una mano, le agradezco de antemano... La otra que me queda, es implementar un esp32 que tengo guardadito como oro por ahi, pero es caro para este proyecto...
El hardware en esta beta es sencillo:
-Arduino NANO
-Oled SH1106 I2c
-HC-05