PowerBroker2 / ELMduino

Arduino OBD-II Bluetooth Scanner Interface Library for Car Hacking Projects
MIT License
635 stars 123 forks source link

Crash on calling batteryVoltage() #226

Closed suoivilbo2 closed 7 months ago

suoivilbo2 commented 7 months ago

Describe the bug When making calls to batteryVoltage(), the board crashes (tested on both a LilyGo T-Beam 1.1 and a Heltec Wifi LoRa V2). The console output is

...
V: 13.50
V: 13.50
assert failed: block_trim_free heap_tlsf.c:371 (block_is_free(block) && "block must be free")

Backtrace: 0x400836a9:0x3ffca300 0x400934f9:0x3ffca320 0x400989a1:0x3ffca340 0x40097df6:0x3ffca470 0x400984bb:0x3ffca490 0x400985f8:0x3ffca4b0 0x40083a48:0x3ffca4d0 0x40083a5d:0x3ffca500 0x40083a86:0x3ffca520 0x400989b1:0x3ffca540 0x400ff5a4:0x3ffca560 0x400e54e8:0x3ffca590 0x400e2fe9:0x3ffca5f0 0x400d2dfb:0x3ffca610 0x400d2e7d:0x3ffca630

ELF file SHA256: 17f70b36d61480de

Rebooting...

So, it crashes after printing the voltage twice.

To Reproduce On the OBD client, here is the simple Arduino code that results the above crash message:

#include "BluetoothSerial.h"
#include "ELMduino.h"

BluetoothSerial SerialBT;
#define ELM_PORT   SerialBT
#define DEBUG_PORT Serial

ELM327 myELM327;
float volts = 0.0;

void setup() {
  DEBUG_PORT.begin(115200);
  ELM_PORT.begin("Client", true);
  delay(1000);

  if (!ELM_PORT.connect("Android-Vlink")) {
    DEBUG_PORT.println("Couldn't connect to OBD scanner - Phase 1");
    while(1);
  }

  if (!myELM327.begin(ELM_PORT, false, 2000)) {
    Serial.println("Couldn't connect to OBD scanner - Phase 2");
    while (1);
  }
  Serial.println("Connected to ELM327");
}

void loop() {
  float volts = myELM327.batteryVoltage();

  if (myELM327.nb_rx_state == ELM_SUCCESS)
  {
    Serial.print("V: "); Serial.println(volts);
  }
  else if (myELM327.nb_rx_state != ELM_GETTING_MSG)
    myELM327.printError();
}

As you can see, this is essentially the BT example file from ELMduino.

I am using ELMulator (also on a T-Beam board) with the following simple Arduino code:

#include <ATCommands.h>
#include <ELMulator.h>
#include <OBDSerialComm.h>
#include <PidProcessor.h>
#include <definitions.h>

const String deviceName = "Android-Vlink"; // Bluetooth device name to use (no pin)
ELMulator ELMulator;
void setup() {
    Serial.begin(115200);
    ELMulator.init(deviceName, true); // Initialize with support for all PIDs 0x00 to 0x65, providing mock data
    ELMulator.begin();                // ELMulator will run continuously, listening for and respondng to requests
}
void loop() {}

(That being said, I don't think it is a problem with ELMulator, as I have ELMduino also crashing in my car with a real ELM327 BT dongle.)

Expected behavior Continuously printing voltage on the serial.

Equipment I am using a Lilygo T-Beam V1.1 (ESP32) with ELMulator as OBD device and either another T-Beam or a Heltec Wifi LoRa V2 (also ESP32) as the OBD client running ELMduino (<---not sure about the terminology). As you can see, both boards communicate over Bluetooth.

Code See code snippets above.

Wiring No wiring

jimwhitelaw commented 7 months ago

I see this similar issue that occurred with an older version of ESP IDF. What version of ESP-IDF are you building with? From what I've been able to find, arduino-esp32 for Arduino IDE is using an older version (4.4.6) than the PlatformIO espressif32 framework (ESP-IDF 5.1.2). That might have an impact on your project.

suoivilbo2 commented 7 months ago

Indeed, I am running the latest version of Arduino (2.3.2) which uses ESP-IDF 4.4. It's weird, because this bug shows up only when querying for batteryVoltage(). Other PIDs, e.g., rpm() run fine.

jimwhitelaw commented 7 months ago

If there's a way to use a newer version of ESP-IDF in Arduino IDE, that looks to be worth a try for you. (Or you could patch your local ESP-IDF with the change in (https://github.com/espressif/esp-idf/commit/b43e777e0a25fecd4652d5282427366fadae8b1d).

I don't know exactly what is happening and it could be completely irrelevant, but the batteryVoltage() request is bit different from other PID requests. It uses the "AT RV" command and the ELM327 returns the voltage it reads at its own power supply pin. There's no communication to the vehicle ECU for that request.

Fichte79 commented 7 months ago

Hello The Problem is in the ELMduino.cpp in the function "float ELM327::batteryVoltage(void)".

If you uncomment the "payload = start + 4;" the error is gone. Or Copy the complet function fron Ver. 3.2.0 in the 3.2.5

Is not the best way, but works ;)

jimwhitelaw commented 7 months ago

Reverting to v3.2.0 will re-introduce a bug where if the ECU returns "ATRV" as part of the response (as some do), then the value will not be parsed correctly. So be careful if implementing that solution. I believe that the payload = start + 4; code triggers the bug in ESP-IDF, but is not the root cause of the crash.

Fichte79 commented 7 months ago

It may not be the root cause, that's why I said it's not the best way. But it was only an update from 3.2.0 that caused the error and it is exactly this function that is responsible for it for me. I use the programming as an emulator and on an ELM327 Bluetooth (China plug). And things work fine in both systems.

jimwhitelaw commented 6 months ago

@Fichte79 or @suoivilbo2 are you able to test the PR I have just committed? I think it may be a fix, but I don't have hardware that exhibits the crash, so I can't test thoroughly. I can only test that the new code has not introduced a regression. Thx