vortigont / pzem-edl

An event-driven library for ESP32 implementing PZEM-004T v3.0 / PZEM-003 / PZEM-017 Modbus-RTU proto
GNU General Public License v3.0
21 stars 4 forks source link

Multiple instance example crashes #4

Closed ndastur closed 2 years ago

ndastur commented 2 years ago

I've setup my PZEMs as per the CLI instructions and run the sample. Only change is that my GPIO pins are 16 and 17. So changed

#define RX_PIN 16           // custom RX pin number
#define TX_PIN 17           // custom TX pin number

Upon running the example crashes with:

PZEM multiple instance example

Added port id:10
Added PZEM id:42 addr:10, port id:1
Added PZEM id:43 addr:11, port id:1
Added PZEM id:44 addr:12, port id:1
abort() was called at PC 0x400ebf8b on core 1

ELF file SHA256: 0000000000000000

Backtrace: 0x40084f18:0x3ffb1e50 0x4008518d:0x3ffb1e70 0x400ebf8b:0x3ffb1e90 0x400ebfd2:0x3ffb1eb0 0x400ec0eb:0x3ffb1ed0 0x400eec13:0x3ffb1ef0 0x400d12a6:0x3ffb1f10 0x400d4492:0x3ffb1fb0 0x40086dfd:0x
--- exit ---
3ffb1fd0
  #0  0x40084f18:0x3ffb1e50 in invoke_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c:715
  #1  0x4008518d:0x3ffb1e70 in abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c:715
  #2  0x400ebf8b:0x3ffb1e90 in __cxxabiv1::__terminate(void (*)()) at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/eh_terminate.cc:112
  #3  0x400ebfd2:0x3ffb1eb0 in std::terminate() at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/eh_terminate.cc:112
  #4  0x400ec0eb:0x3ffb1ed0 in __cxa_pure_virtual at ??:?
  #5  0x400eec13:0x3ffb1ef0 in PZPool::updateMetrics() at .pio/libdeps/example/pzem-edl/src/pzem_edl.cpp:303
  #6  0x400d12a6:0x3ffb1f10 in setup() at src/main.cpp:110
  #7  0x400d4492:0x3ffb1fb0 in loopTask(void*) at /Users/nevilledastur/.platformio/packages/framework-arduinoespressif32/cores/esp32/main.cpp:18
  #8  0x40086dfd:0x3ffb1fd0 in vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c:355 (discriminator 1)
vortigont commented 2 years ago

Hi. Could you test with default pin numbers if it crashes the same way or not? I'm not sure which board you are running, i.e. some WROVER modules uses 16 and 17 for PSRAM, might be a conflict.

vortigont commented 2 years ago

Oh, and you can't use 16 and 17 as custom pins for UART1 as it is already mapped to UART2, so you need to either remap UART2 also or change #define PZEM_UART_PORT_1 UART_NUM_2 so there won't be any conflict.

ndastur commented 2 years ago

Sorry I should have given those details. The board I have is the DevC v4 Dev board https://docs.espressif.com/projects/esp-idf/en/latest/esp32/hw-reference/esp32/get-started-devkitc.html#get-started-esp32-devkitc-board-front

I've got the single pzem working on those pins 16 and 17 so don't think that's the issue. Also tried single pzem in the pool thinking there is no reason it shouldn't work for 1 or 3 devices. Looking at the source I wonder if a pointer is being lost somewhere. The update metrics func doesn't check for a null PTR to the pzem object from what I can see.

I've also tried creating my own pool by creating multiple pzem4 objects on a single UART port object. That doesn't crash but only one device ever returns values.

I haven't quite figured out how to create my own receive queue.

vortigont commented 2 years ago

Also tried single pzem in the pool thinking there is no reason it shouldn't work for 1 or 3 devices.

true. Should be OK for one device also. Does it crashes the same way with a single device?

The update metrics func doesn't check for a null PTR to the pzem object from what I can see.

PZPool::updateMetrics() iterates registered instances of the objects, should not be any dangling pointers if objects has been registered previously. Not sure where this 'abort' comes from.

I've also tried creating my own pool by creating multiple pzem4 objects on a single UART port object. That doesn't crash but only one device ever returns values.

I did not get it, Multiple instance example does exactly the same, no? Can you share the code? Have changed modbus addresses for each device there?

I haven't quite figured out how to create my own receive queue.

MsgQ is an abstract class. Receive queue is bound to the PortQ object, you can check pzem_cli example on how to directly exchange messages via PortQ object.

vortigont commented 2 years ago

Huh! Silly me... how could I've missed that. Pls, try a fix from this branch

ndastur commented 2 years ago

Thanks. Sorry how do I try that branch ?

Found how to: https://github.com/vortigont/pzem-edl.git#916cc6ff47b5db6783d6b4f2b9cec8ca867f5ce3 in platformio.ini

ndastur commented 2 years ago

I can confirm that fixes the problem. Works with 1 and 2 devices now. Will be testing with 3 tomorrow. Thanks

vortigont commented 2 years ago

you can also specify the branch in platformio.ini https://github.com/vortigont/pzem-edl.git#addPZEMfix I've updated the fix in a more proper way. Could you please test it and provide feedback, than I will merge it into main branch. Thanks for the report!

ndastur commented 2 years ago

I can confirm the latest branch works

vortigont commented 2 years ago

thanks, @ndastur, fix merged to main