Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sensor: Add PZEM004T V3.0 #2283

Merged
merged 17 commits into from
Jul 3, 2020
Merged

Sensor: Add PZEM004T V3.0 #2283

merged 17 commits into from
Jul 3, 2020

Conversation

mcspr
Copy link
Collaborator

@mcspr mcspr commented Jun 20, 2020

@davebuk

Fix #2277
Add new V3.0 version of PZEM004T, not tested. Default to factory default address 0xf8, configurable through pzemv30Addr 8-bit number
Add 'frequency' measurement & 'hz' unit
Add pz.address that configures address
Implemented energy reset

Right now we only support a single device. No way to test this properly (mostly, how exactly we need to connect this stuff), so left as not implemented.

@mcspr
Copy link
Collaborator Author

mcspr commented Jun 20, 2020

re

Codacy/PR Quality Review — Not up to standards. This pull request quality could be better.

Don't mind this. Will update down the line when settings are merged, Codacy wants to fix test framework.

@mcspr
Copy link
Collaborator Author

mcspr commented Jun 20, 2020

Also, in case TX and RX are connected to hardware serial, don't forget to add -DDEBUG_SERIAL_SUPPORT=0 / #define ....

@davebuk
Copy link
Contributor

davebuk commented Jun 20, 2020

So that will allow hardware serial rather than using software serial on the wemos D1 mini?

@mcspr
Copy link
Collaborator Author

mcspr commented Jun 20, 2020

This... depends? If I remember correctly how d1 works, powering it through the 3v3 pin instead of USB should allow to use TX and RX pins. Easy to test with a terminal connection first?

Otherwise, pzemv30TX and pzemv30RX settings set to something will enable SwSerial. Or, setting PZEM004TV30_SOFTWARE_SERIAL_TX and PZEM004TV30_SOFTWARE_SERIAL_RX

@davebuk
Copy link
Contributor

davebuk commented Jun 21, 2020

I have a basic wemos/sensor setup with the wemos running from a 240V to 5V supply on its USB port (not a PC/data enabled USB supply) and the sensor running from the 5V header pins. I built two versions, Software Serial and Hardware Serial as defined below.

#elif defined(MY_WEMOS_PZEMV3_HWS)

    #define MANUFACTURER            "WEMOS"
    #define DEVICE                  "PZEM004T_V3_HW"    // Hardware Serial

    // Disable these
    #define DEBUG_SERIAL_SUPPORT    0
    #define PZEM004TV30_SUPPORT     1
#elif defined(MY_WEMOS_PZEMV3_SWS)

    #define MANUFACTURER            "WEMOS"
    #define DEVICE                  "PZEM004T_V3_SW"    // Software Serial

    #define PZEM004TV30_SUPPORT     1
    #define PZEM004TV30_SOFTWARE_SERIAL_TX    14 // D5
    #define PZEM004TV30_SOFTWARE_SERIAL_RX    12 // D6

Status page shows:
Status-01

Every 6 seconds (or 1 second if I change the refresh rate in the sensor webUI) I get:
[SENSOR] Error reading data from PZEM004T V3.0 @ 248 (error: 3). There is a TX and RX LED on the sensor board and the RX flashes every 6 seconds (or 1 as above) but nothing from the TX LED. If I swap the TX/RX over the TX LED flashes instead.

I get the same TIMEOUT response with the SWS connected to GPIO 14/12 or HWS connected to the wemos TX/RX.

INFO at debug terminal gives:

---8<-------

[157724] [MAIN] ESPURNA 1.15.0-dev
[157724] [MAIN] [email protected]
[157725] [MAIN] http://tinkerman.cat

[157725] [MAIN] CPU chip ID: 0x79A1C9
[157725] [MAIN] CPU frequency: 80 MHz
[157725] [MAIN] SDK version: 2.2.2-dev(38a443e)
[157726] [MAIN] Core version: 2.7.1
[157729] [MAIN] Core revision: a5432625
[157729] [MAIN] Build time: 1592694507
[157729] 
[157730] [MAIN] Flash chip ID: 0x164068
[157730] [MAIN] Flash speed: 40000000 Hz
[157730] [MAIN] Flash mode: DOUT
[157730] 
[157731] [MAIN] Flash size (CHIP)   :  4194304 bytes / 1024 sectors (   0 to 1023)
[157737] [MAIN] Flash size (SDK)    :  4194304 bytes / 1024 sectors (   0 to 1023)
[157738] [MAIN] Reserved            :     4096 bytes /    1 sectors (   0 to    0)
[157738] [MAIN] Firmware size       :   594656 bytes /  146 sectors (   1 to  146)
[157739] [MAIN] Max OTA size        :  2543616 bytes /  621 sectors ( 147 to  767)
[157739] [MAIN] SPIFFS size         :  1015808 bytes /  248 sectors ( 768 to 1015)
[157740] [MAIN] EEPROM size         :    16384 bytes /    4 sectors (1016 to 1019)
[157740] [MAIN] Reserved            :    16384 bytes /    4 sectors (1020 to 1023)
[157740] 
[157744] [MAIN] EEPROM sectors: 1019, 1018, 1017, 1016
[157744] [MAIN] EEPROM current: 1018
[157744] 
[157747] [MAIN] EEPROM:  4096 bytes initially |   208 bytes used ( 5%) |  3888 bytes free (94%)
[157749] [MAIN] Heap  : 36832 bytes initially | 19184 bytes used (52%) | 17648 bytes free (47%)
[157749] [MAIN] Heap  : 15992 contiguous bytes available (10% fragmentation)
[157749] [MAIN] Stack :  4096 bytes initially |  1680 bytes used (41%) |  2416 bytes free (58%)
[157750] 
[157752] [MAIN] Boot version: 31
[157752] [MAIN] Boot mode: 1
[157752] [MAIN] Last reset reason: External System
[157752] [MAIN] Last reset info: External System
[157752] 
[157753] [MAIN] Board: WEMOS_PZEM004T_V3_HW
[157754] [MAIN] Support: ALEXA API BROKER BUTTON DEBUG_TELNET DEBUG_WEB DOMOTICZ HOMEASSISTANT LED MDNS_SERVER MQTT NTP SCHEDULER SENSOR TELNET TERMINAL THINGSPEAK WEB 
[157756] [MAIN] OTA: ARDUINO ASYNCTCP WEB 
[157759] [MAIN] Sensors: 
[157759] [MAIN] WebUI image: SENSOR
[157759] 
[158028] [MAIN] Firmware MD5: 9d72e26c57e49a30c5e686abec0f89f2
[158034] [MAIN] Power: 2982 mV
[158035] [MAIN] Power saving delay value: 10 ms
[158035] 

---8<-------

@mcspr
Copy link
Collaborator Author

mcspr commented Jun 21, 2020

Serial leds just see the raw signal :) idk if that really means the pzem gets any data. Only possible issues that I read of are 5v vs. 3v3 signals, since the the pzem board itself is supposed to be 5v, isn't it? Note the:

Its (PZEM004T) RX and TX communication pin needs external 5V power. Connect the 5V pin of Wemos D1 mini to PZEM004T 5V pin, Rx pin to D6 of arduino and Tx pin to D5 pin of Wemos, gnd to gnd.

Idk how sound that advice is though.

Does example software & hardware serial code from the https://github.com/mandulaj/PZEM-004T-v30/tree/master/examples work?
Just download the .ino file in some directory with the following platformio.ini and pio run

[platformio]
src_dir = ./

[env:example]
platform = espressif8266
framework = arduino
board = d1_mini
lib_deps =
    https://github.com/mandulaj/PZEM-004T-v30#d4590976
    https://github.com/plerup/espsoftwareserial#3.4.1

Note that I also used the swserial library version that we use here, otherwise it will use a more recent one. In case swserial is somehow broken, that can also test this theory. But, we can't exactly mix them as PIO will be confused when building the source, .pio/libdeps/example can only have one of espsoftwareserial versions (i.e. you'd need to remove libdeps directory and remove the espsoftwareserial line from lib_deps entry).

// Core does not allow us to begin(baud, cfg, rx, tx) / pins(rx, tx) before begin(baud)
// b/c internal UART handler does not exist yet
// Also see https://github.com/esp8266/Arduino/issues/2380 as to why there is flush()
if (getSetting("pzemv30HwsSwap", 1 == PZEM004TV30_HARDWARE_SERIAL_SWAP)) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for debugging only, configuration is very confusing right now...
Maybe

  • have pzemv30Soft 0 or 1, like existing pzemSoft, instead of this magic
  • make pzemv30RX and TX checks for 13 and 15, 1 and 3 as valid HardwareSerial pins, don't do anything otherwise.

Comment on lines 1022 to 1032
#ifndef PZEM004TV30_USE_SOFT
#define PZEM004TV30_USE_SOFT 0 // By default, use Hardware serial with GPIO15 (TX) and GPIO13 (RX)
#endif

#ifndef PZEM004TV30_RX_PIN
#define PZEM004TV30_RX_PIN 13 // Serial RX GPIO (if PZEM004T_USE_SOFT == 1, creates a SoftwareSerial object)
#endif

#ifndef PZEM004TV30_TX_PIN
#define PZEM004TV30_TX_PIN 15 // Serial TX GPIO (if PZEM004T_USE_SOFT == 1, creates a SoftwareSerial object)
#endif
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that flags have changed.
Default is HardwareSerial on 13 & 15

_ready = (_stream != nullptr);
_last_reading = millis() - _update_interval;
#if TERMINAL_SUPPORT
terminalRegisterCommand(F("PZ.ADDRESS"), [](const terminal::CommandContext& ctx) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pz.address N should change PZEM's address to N, where N is some number between 1 and 247 (per http://www.modbus.org/docs/Modbus_over_serial_line_V1_01.pdf)
PZEM pdf never mentioned 0 as broadcast, only 248 (0xF8), so it is unclear what exactly happens with numbers 0,248...255.

kvs_type kv_store(
EepromStorage{},
#if DEBUG_SUPPORT
EepromReservedSize + CrashReservedSize,
Copy link
Collaborator Author

@mcspr mcspr Jun 28, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davebuk I also noticed a bug here with the current storage system. Settings get confused and 'hide' keys after a certain point, so kv might get lost accidentally when value length is the same as the previous one. Easy way to reproduce is to:

set one 1
set two 2
set one 2
get two

two will get lost

// we also need to pad the space *after* the value
// but, only when we still have some space left
if ((start_pos - need) >= 2) {
_cursor_set_position(writer.begin);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I thought this would be harder to find. Never-mind the previous workaround comment, can you please test this instead?

Suggested change
_cursor_set_position(writer.begin);
_cursor_set_position(writer.begin - _cursor.begin);

Suggested 'test' still stands, key should not disappear.

@davebuk
Copy link
Contributor

davebuk commented Jun 28, 2020

Built using 2dbf94f7.

pz.address 247 sets address to 0xf7 with valid data
pz.address 1 sets address to 0x1 with valid data

pz.address 0 or 248 or 255 fails to set an address.

[039226] [PZEM004TV3] Received: 0186030261 (5 bytes)
[039227] [PZEM004TV3] ERROR: Illegal data value (0x03)
-ERROR: Could not change the address
set one 1
set two 2
set one 2
get two

gives > two =>

With the suggested change in line 409, it now gives > two => "2"

Energy reset also works.

@mcspr
Copy link
Collaborator Author

mcspr commented Jun 29, 2020 via email

@mcspr mcspr changed the title [wip] Add PZEM004T V3.0 Sensor: Add PZEM004T V3.0 Jul 3, 2020
@mcspr mcspr merged commit 7b57274 into xoseperez:dev Jul 3, 2020
@mcspr mcspr deleted the sns/pzem004t-v3 branch July 3, 2020 20:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

PZEM004T, V3.0 serial and libraries.
2 participants