In memory of my mother, Gromova Margarita Ivanovna. Thank you, and rest in peace.
The following is a result of more than two years of efforts, in fields of PCB and schematics software mastering, C software design, ESP8266 platform development, and struggling through quirks of Embarcadero;s Firemonkey framework in C++, all in spare time between a supper, and night sleep.
Finally, ESP8266+PZEM T004 - based WIFI PowerMetering logger is here, both, as IoT firmware, and PC client software.
ESP8266, it's amazing!
Back in a distant 2016, after a bunch of experiments with BLE and WIFI SOCs, which were mainly work-related, I have finally decided to do something different in DIY field. The most obvious choice was an amazing ESP8266 module family from Espressif Systems.
It's very cheap, highly available, comes in many configurations, with different onboard antennae, or RF connectors, ROM and RAM sizes.
The heart of module's application-driven part usually has more than enough computing power and resources to fuel even serios IoT applications right off the bat, even interpreted-script based ones, not to mention a native code.
Right about that time there were troubles with power at our country household, blackouts, disbalansed phases, serious over- and undervoltage, to name a few.
I hate to experiment with things just for the sake of pure experiment. What is more pleasing, than setting a distinctive goal, and achieve it, while mastering new technologies and fields of programming?
That's when PowerMeter project was born, a simple tool to make possible a remote contonuous logging of a single phase power mains parameters.
From the start I decided to make it in pure C, utilizing only stuff that Espressif platform may offer though its RTOS-based SDK, the latter approach became event more preferable, when I realized, that RTOS was a well-known FreeRTOS, with which I had a long lasted positive experience.
Enter the PZEM T004
Next step was to select an affordable power metering hardware. While I decided to develop my own hardware platfrom (schematics and PCB) for ESP8266, an existing power metering hardware was a must, as I did not have enough neither experience nor time for developing and debugging that schematics and PCB too.
So, It appeared that our Chinese comrades have that pretty much covered with PZEM T004 module. The latter is a specialized single-phase metering and processing chip with serial IO interface. The module uses internal sensing for voltage, and requires an external current transformer for power current metering.
I started off with two PZEM modules of HW revision 1, which was not so great, in terms of IO interface, though it allowed me to make a project basics running, one module being demolished with a big bang in the process, when parasitic short corquit occasionally ocurred through oscilloscope wiring :)
Anyways, it took me almost hal a year to polish a schematics for ESP8266, develop a couple of PCB revisions, and make it running an initial C code, communicating with PZEM.
Given a rather modest, to say the least, amount of time, I could spare for a project, it seemed as eternity has been passed since then.
The PZEM revision 1 almost made it through entirety of the project life time, though, in the end I had to replace it with much more mature HW revision 3, with better high voltage isolation, more robust MODBUS communication layer, and other chip on board.
What's on WIFI side?
Though ESP8266 has a fair amount of ISP-programmable SPI ROM on board, I've decided to usitilze an external MICRO-SD over secondary SPI bus. This approach allows logger to have almost unlimited storage space at its disposal, while preserving ROM for firmware and WIFI-related settings only, saving its life cycle as well. Moreover, a MICRO-SD over SPI approach was a well-known, maintained, and thoroghly-tested in several work-related projects, I had a solid codebase for it too.
The logger board should be able to sustain brownouts and blackouts without any fails to reflect these events too, sustaining autonomous state even in abscence of external power. So, I have added a small LiPol battery cirquit with a dedicated charger, as a source of a backup power, preventing both data loss, and file system corruption. When main power goes off, a battery backup would provide enough juice to allow logger to write terminator record to a current file, close communication and file system tasks, and become dormant, waiting for power good state interrupt to occur, saving power, but at the same time allowing external WIFI client to connect and query hardware and software state.
When power is restored, module starts or continues functioning, while charging the backup battery.
To provie an ability to power itself from the main power line, a miniature low-power 220-to-5V AC-DC adapter module is used, its AC input proteccted to some extent with varistor and fuse.
A module uses ESP8266 usart 1 both for initial firmware upload, and communication with PZEM via 3v-to-5v level converter cirquit. An additional, reduced functionality, unidirectional usart 2 is used for debugging, and an application state trace output, which was the only way to debug a user firmware, actually. Better that, than none though.
Logger embedded IoT software
A logger firmware is based on Espressif RTOS SDK 2.0. I started developing it on Espressif's Linux-based SDK package, and that was as redious and slow (in terms of development process) as hell.
Things turned on much brighter side, when a brilliant open-source project, a Visual Studio Wizard for ESP8266, matured enough to be usable without requiring extra tweaks to get going. Finally, I was able to use marvellous Visual Studio IDE for ESP8266 development, with all that power of syntax highlighting, code completion, and refactoring tools.
In its final stage of version 1.0, a power metering firmware is configurable WIFI Station+AP, threaded NTP client for date-time synchronization. An asynchronous PZEM IO thread is running, if power is good, providing a full set of single-phase parameters each 5 seconds. A parameters are voltage, current, active power, energy, power factor and frequency.
A separate logger thread, if file system is ok, writes out these data nodes, grouped by day. In ideal conditions, if there are no IO errors, no blackouts, a logger maintains one file per full day. Otherwise, a set of shorter files may be created, one per a period while power-good condition is maintained.
An asynchronous HTTP REST server is running on any open interface, allowing a set of URIs to be accessed and changed, like device information reading, logged data time range query, selective data removal, selective data download, live data query, configuration read-write, and firmware OTA update.
More API may be added in the future, the planned ones are energy readings reset, factory reset with control button press-and-hold.
Client PC software
Being a REST server in nature, a power meter board may be accessed with any clients, Windows, Android, etc., like Embarcadero's REST debugger, Android RestClient, Restler.
Though I've decided to make a kind of project closure, developing a proof-of-concept PC client software, with minimal functionality, on start, at least.
To make codebase as reusabe as possible in potential future platform clients, I've used cross-platfrom Embarcadero's FMX framework for a UI, and a basic data model, as well as their non-visual cross-platofrm RTL classes to augment an application business logic functionality.
An initial functionality allows reading information, configuration, live data, query data range, delete and download power logs in selected date range. A downloaded data may be saved to, loaded from the local file in XML or binary format, and viewed on chart. Chart view allows a few options for specific data selection, zooming, panning, and scrolling through data array, and, finally browse values at specified time stamp.
An asynchronous REST IO utilizes Embarcadero's RTL threaded HTTP Client. Downloaded data are stored in in-memory table TFDMemTable. Chart component used, is great TChart component, namely, its TDBChart flavoiur, heavily tuned-up through custom helper objects.
The REST data IO is in JSON format. PC-side JSON parsing uses Embarcadero's RTL TJsonTextReader and TJSONIterator for parsing incoming data, backed with cutom JSON data tree model adapter for intermediated storage and input-output.
An installers for Win32 and Win64 platforms were created and compiled with well-known great InnoSetup engine, utilizing small parts of C++ project headers itself to provide consistent version information to generated setup binary through ISS preprocessor.