Power data logger with GUI

I made this system to monitor and record the power production of my photovoltaic plant and the power consumed by the house and the heat pumps. The reason for this is to investigate the convenience of a battery storage. This is my first computer graphical interface, made in Python 3.7 with the PyQt 5.

The active power is read by using a three-phase multimeter with three hall effect current sensors. Being the system single phase, the three voltages inputs of the multimeter are connected together to the single phase. The three current sensors read: current from the photovoltaic plant, current to the heat pump, current to the house (including heat pump). The multimeter does the calculation of the active power.

Electric cabinet, before:

Electric cabinet, after:


The multimeter is connected to an Arduino Uno with a RS485 interface. The Arduino read the measured power using the Modbus RTU protocol and send them via radio in csv format using a HC-12 433 Mhz serial radio module.

A second HC-12 is connected to the computer using a serial TTL to USB adapter with CH340 chip. The computer is running Ubuntu 16.04, Python 3.7, and PyQt 5.


About current measurements

I could have used the SCT0013 (15 A/ 1V) current transformers which are available on ebay for 5€ each, quite popular to use with Arduino. The problem is that I would have need also to measure the voltage, and calculate the active power with Arduino, which isn’t fast enough. The 10 bit ADC resolution isn’t enough, Atmega328 does not have hardware multiplication. So, a 150-300€ multimeter was chosen for better accuracy.

Obviously, I could not resist to open up the expensive Electrex Femto D4 multimer to see what components it use. The main chip is a ADUC7022 from Analog Devices. There are two LVC4066 (four single pole, single-throw analog switch functions). Two 050L photo-transistor optocoupler (probably for the two digital outputs). One i2c 24LC32 Eeprom probably used to store the settings. The RS485 transceiver is a VP12 from Texas.

It seems that all the analog and digital circuits are not isolated from the high voltage side. Maybe the optocouplers are used to isolate the RS485 chip.


Challenges I faced

Making a 32 bit floating point from Modbus variables

The Modbus is meant to read/write 16 bit values. The multimeter uses two Modbus addresses to provide a 32 bit (floating point) number. So, the software in the Arduino makes the 32 bit value merging the two 16 bit byte. We define the variable u as a type union. u is a 32 bit variable which can be read as a usigned integer 32 bit, or as a floating point. So, we write the one 16 bit byte into the first half of the 32 bit byte, then the other 16 bit byte into the second half of the 32 bit byte. Then, we read it as if it was (it is!) a floating point variable, into the P1, which is defined as float.


Threading (multi tasking) in the GUI

One loop of the program need to read the incoming serial data, while a second independent loop need to update the GUI (graphical user interface). If only one loop is used, the graphical interface is frozen while waiting the next incoming character.

The multi tasking is made using the threading module provided in the PyQt binding (not the multithreading of python).


Arduino program


Python program