mandulaj / PZEM-004T-v30

Arduino library for the Updated PZEM-004T v3.0 Power and Energy meter
MIT License
256 stars 108 forks source link

Is it possible to achieve multiple PZEM on one bus on ESP32? SoftSerial fails, HardSerial constructor problems #64

Closed loopyengineeringco closed 2 years ago

loopyengineeringco commented 2 years ago

Hi, I'm trying to get multiple PZEMs working on one bus on the ESP32.

Ideally, I want be able to use HardwareSerial and address multiple PZEMs in the constructor, as SoftwareSerial on ESP32 doesn't work at all (results are all NaN - logic analyser shows loads of frame errors.)

On the ESP8266, this works (I believe this is SoftwareSerial):

#include <PZEM004Tv30.h>

PZEM004Tv30 pzem1(5,4,0x07);
PZEM004Tv30 pzem2(5,4,0x08);
PZEM004Tv30 pzem3(5,4,0x09);

void setup() {
  Serial.begin(115200);
}

void loop() {
    Serial.println(pzem1.voltage());
    Serial.println(pzem2.voltage());
    Serial.println(pzem3.voltage());
    Serial.println();
    delay(1000);
}

But on the ESP32, this code fails compile: no matching function for call to 'PZEM004Tv30::PZEM004Tv30(int, int, int)' I found this is because the #if & #endif blocks don't detect ESP32 architecture properly in PZEM004Tv30.h, so I force #define PZEM004_SOFTSERIAL manually. It compiles and runs, but I now get 3x NaN replies. PZEM indicators flashing in the correct order, logic analyser shows the first few bytes are addressing the PZEMS correctly, but there are multiple errors after this and the responses fall apart aswell, creating the NaN replies presumably.

So moving on to HardwareSerial - a single non-addressed HardwareSerial constructor works well, but the ESP32 only has 2 usable UARTS and I need 3, so I want them all on the same bus.

Is there a way to address multiple PZEM on a HardwareSerial scenario on the ESP32?

The reason for the ESP32 is because I want to use the Lilygo Ethernet POE board and avoid WiFi due to security/reliability. https://github.com/Xinyuan-LilyGO/LilyGO-T-ETH-POE

Thanks for any help

loopyengineeringco commented 2 years ago

Update: Method suggested in issue #40 crashes the ESP32 in an infinite loop

#include <PZEM004Tv30.h>
#include <HardwareSerial.h>

HardwareSerial MeterSerial(2);

PZEM004Tv30 pzem1(&MeterSerial,0x07);
PZEM004Tv30 pzem2(&MeterSerial,0x08);
PZEM004Tv30 pzem3(&MeterSerial,0x09);

void setup() {
  Serial.begin(115200);
  MeterSerial.begin(9600,SERIAL_8N1,15,4);
}

void loop() {
    Serial.println(pzem1.voltage());
    Serial.println(pzem2.voltage());
    Serial.println(pzem3.voltage());
    Serial.println();
    delay(1000);
}
Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:10944
load:0x40080400,len:6388
entry 0x400806b4
Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.
Core 0 register dump:
PC      : 0x400d1f44  PS      : 0x00060d30  A0      : 0x800d1f86  A1      : 0x3ffe3aa0  
A2      : 0x3ffbdbdc  A3      : 0x00000000  A4      : 0x00000000  A5      : 0x00000000  
A6      : 0x00000000  A7      : 0x00000000  A8      : 0x3ff6e000  A9      : 0x3ffe3a60  
A10     : 0x00000001  A11     : 0x00000000  A12     : 0x3ffb7f60  A13     : 0x00000000  
A14     : 0x00000000  A15     : 0x00000000  SAR     : 0x00000011  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x00000000  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0xffffffff  

ELF file SHA256: 0000000000000000

Backtrace: 0x400d1f44:0x3ffe3aa0 0x400d1f83:0x3ffe3ac0 0x400d2074:0x3ffe3ae0 0x400d1211:0x3ffe3b00 0x400d123f:0x3ffe3b20 0x400d0d54:0x3ffe3b60 0x400d0cf1:0x3ffe3b90 0x400e1d43:0x3ffe3bb0 0x40081e9d:0x3ffe3bd0 0x4008209d:0x3ffe3c20 0x4007925f:0x3ffe3c40 0x400792c5:0x3ffe3c70 0x400792d0:0x3ffe3ca0 0x4007947d:0x3ffe3cc0 0x400806e6:0x3ffe3df0 0x40007c31:0x3ffe3eb0 0x4000073d:0x3ffe3f20

@morganflint solution in #33 seems interesting, any chance you could share your modified library which lets me address the PZEM as a parameter?

loopyengineeringco commented 2 years ago

Will do some more testing this evening, but it seems to be working now, with the library modification from #31 šŸ‘

// This works with the ESP32 when using the mandulaj PZEM-004t-v30 firmware, with this modification:
// https://github.com/mandulaj/PZEM-004T-v30/pull/31/files/2d527aae8011b274a23bb981cf9b9e6a7b0e35a0

#include <PZEM004Tv30.h>

PZEM004Tv30 pzem1(&Serial2,15,4,0x07);
PZEM004Tv30 pzem2(&Serial2,15,4,0x08);
PZEM004Tv30 pzem3(&Serial2,15,4,0x09);

void setup() {
  Serial.begin(115200);
}

void loop() {
    Serial.println(pzem1.voltage());
    Serial.println(pzem2.voltage());
    Serial.println(pzem3.voltage());
    Serial.println();
    delay(1000);
}

Might be worth noting as well, that my TX2 and RX2 pins are remapped in HardwareSerial.cpp to 15 and 4 respectively, in C:\Users\xxxxxx\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\cores\esp32\HardwareSerial.cpp

loopyengineeringco commented 2 years ago

Seems to be working really well. Tested by pulling one out at a time and replugging, one being removed does not affect others (only the acquisition time seems to increase). I've made a video to show the system working https://youtu.be/ieh3ErHjdZo @mandulaj feel free to close the issue if you think it doesn't need to stay up but I hope it might help some people

mandulaj commented 2 years ago

Good work. Having a second look, I think I will try merging #31 into the main branch. I initially didn't want to modify the library API too much. However since this is quite useful and has now been tested, I can confidently add it.

However I think for compatibility reasons, I will keep the old API interface and only switch it out for the new interface when detecting the ESP32 platform. Would you care to test the library then @ASMotionLab ?

loopyengineeringco commented 2 years ago

Great - I forked it for now just so I have it somewhere, but if you do merge it into yours I will remove my fork to keep things tidy :-). I'm happy to test the ESP32 detection šŸ‘

mandulaj commented 2 years ago

If everything works now, we can close this issue

loopyengineeringco commented 2 years ago

Hi @mandulaj just tested the new release, but got a compile error: image

Any ideas?

mandulaj commented 2 years ago

Ah, yes, it was a fix for a bug for Software serial. But its not meant for the ESP32. I must have merged that by accident into master. Shouldn't have gone directly into master. I am currently reworking the SoftwareSerial. For now try using the rel1.1 branch. It should be commented out through the #ifdef. If not then please just comment it out for now.

loopyengineeringco commented 2 years ago

Ahh, thats my bad for using the Master branch, sorry! Unfortunately still a compile error :(. This was both with my sketch specifying addresses, and the built in HardSerial example: image