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

not an issue, nor a pull request as it's a change the API, but got a working samd21 and pzem. #43

Closed zelogik closed 2 years ago

zelogik commented 3 years ago

Hi,

So as I have wrote in that long title after some hours I got a working SAMD21 with pzem-004t-v30 using Uart/Sercom. First thank @mandulaj for your work :-D ie: I got inspiration from the TinyGSM library and a post on stackoverflow, and the knx from thelsing, and many bug report :-D

Instead of using traditional hardwareSerial or softwareserial, as neither work well with new microcontroller like the samd21/51 (DUE, Feather M0, sparkfun SAMD21 ....), I have used the Stream class with reference instead of pointer...

in the .ino file:

PZEM004Tv30 pzem(Serial1, PZEM_DEFAULT_ADDR); Setup call add: Serial1.begin(9600);

In .h

Change : PZEM004Tv30(HardwareSerial* port, uint8_t addr=PZEM_DEFAULT_ADDR); to PZEM004Tv30(HardwareSerial& serialPZEM, uint8_t addr=PZEM_DEFAULT_ADDR);

And Stream* _serial; // Serial interface to Stream& _serial; // Serial interface

And in .cpp comment: //extern HardwareSerial Serial;

Replace:

PZEM004Tv30::PZEM004Tv30(HardwareSerial* port, uint8_t addr) {

port->begin(PZEM_BAUD_RATE); this->_serial = port; this->_isSoft = false; init(addr); }

with: PZEM004Tv30::PZEM004Tv30(HardwareSerial& serialPZEM, uint8_t addr) : _serial(serialPZEM) { this->_serial = serialPZEM; init(addr); }

Remove: // Need to find cleaner way that completely removing :-D

if(_isSoft) delete this->_serial;

And line around line 244 change _serial->write(sendBuffer, 8); to _serial.write(sendBuffer, 8);

same for 431/432 change the => with . same for 463-466

This solution could remove many DEFINE and condition in the .h and .cpp and just need something like: for softwareSerial: SoftwareSerial SerialPZEM(2, 3);

HardwareSerial \ Uart and sercom should be the same. ie for an another sercom on a samd21 Uart Serial2(&sercom1, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX); //TX D10, RX D12 The "extern HardwareSerial serial" could be define here....?!?!

@mandulaj : what do you think about changing a little bit the API? to be more future proof and use direct Stream class ?

mandulaj commented 3 years ago

Hi @zelogik, Thanks for the work. I am currently not able to spend much time on this project. However a couple of things...

I think you are probably right that the API of this library isn't the best. However the problem is, changing the API could break existing projects. Therefor it's unfortunately mandatory, that the API stays backwards compatible.

It would be really helpful if someone could have a look at the code, test it and edit it into a form that would allow for backwards compatibility while enabling the new features.

zygisjas commented 3 years ago

Hello,

I've tried to follow those changes to make it working on arduino nano 33 IoT, but getting this error message:

C:\Users\Zygimantas Jasiunas\AppData\Local\Temp\arduino_build_252423\sketch\sketch_mar16a.ino.cpp.o: In function `_GLOBAL__sub_I_pzem':

C:\Users\Zygimantas Jasiunas\Documents\Arduino\sketch_mar16a/sketch_mar16a.ino:59: undefined reference to `PZEM004Tv30::~PZEM004Tv30()'

collect2.exe: error: ld returned 1 exit status

Using library PZEM-004T-v30 at version 1.0.0 in folder: C:\Users\Zygimantas Jasiunas\Documents\Arduino\libraries\PZEM-004T-v30 
exit status 1
Error compiling for board Arduino NANO 33 IoT.

Update:

Finally got some life from the sensor, Arduino is trying to read the values, but... it does not. The only output I get right now is this:

00:52:30.297 -> Error reading voltage 00:52:30.391 -> Error reading current 00:52:30.484 -> Error reading power 00:52:30.578 -> Error reading energy 00:52:30.672 -> Error reading frequency 00:52:30.765 -> Error reading power factor