CuVoodoo

the sorcery of copper

User Tools

Site Tools


spark_counter

This is an old revision of the document!


The spark counter is a custom electricity meter with wireless data logging capability.

On one side I have:

On the other side:

complete spark counter

warning: the electricity meter I am presenting will only work for 1 phase 2 wires power distribution systems. I have a 3 phases 4 wires system and I am doing it wrong.

peacefair PZEM-004

The peacefair PZEM-004 is a simple power meter (datasheet). It:

  • measures voltages 80-260 V AC
  • measures current 0-100 A AC
  • calculates the resulting power (W)
  • records the overall energy consumption (Wh)
  • displays all these 4 values using 4×7 segments
  • is powered using 80-260 V AC
  • provides a TTL UART port to query these values (or set an alarm so to beep when a provided power threshold is reached)

PZEM-004 front PZEM-004 back

The voltage measurement is done over the power input port. The current measurement is done using a coil. Pass the wire on which you would like to measure the current through the coil, and connect the coil to the power meter. A drawing on the back of the device will describe how to connect the wires.

PZEM-004 opto-couplers

The meter also provides a UART port to query the measured values. Two opto-couplers isolate the main power meter circuits from the TX and RX UART ports.

UART PZEM-004 note
5V VDD 3.3V is not enough
TX RX the UART pin needs to be able to sink ~4 mA
RX TX the UART pin needs to be idle high
GND GND

I used a CP2102 based USB to UART converter. CH340 based USB to UART converters will not work (it seems to not be able to sink enough current). And when using the Arduino you should not use the USB port (for serial), since that interferes with the UART signals.

The manual provides the corresponding commands, but lacks some information. The UART configurations is 9600 bps 8N1. Before querying the measurements, you have to set an address to the device. Else it won't reply to the other commands. The manual uses an IP as address (192.168.1.1 = C0 A8 01 01). No idea why you would set an IP for a UART address.

The commands use the following 7 bytes message format:

  1. the 1st byte defines the type of command (query/response) and type of content (voltage, current, …)
    • the type of command (query/response) is the first nibble
      • Bx is used for query commands
      • Ax is used for response commands
    • type of content (voltage, current, …) is the second nibble
      • x0 is used to get the voltage
      • x1 is used to get the current
      • x2 is used to get the power
      • x3 is used to get the energy
      • x4 is used to set the address
      • x5 is used to set the power alarm threshold
  2. the next 4 bytes are the address of the device when sending commands, and the measured values in the responses
    • response values for voltage, current, and power are stored as “%u.%u”,bytes[1]«8+bytes[2],bytes[3] V/A/W
    • response values for energy is stored as “%lu”,bytes[1]«16+bytes[2]«8+bytes[3]
    • setting the address or power threshold returns 00 00 00 00
  3. the 6th byte is used to provide the value of the alarm threshold (in kW), 00 else
  4. the 7th byte is a simple CRC: the sum of all previous bytes

Have a look at the manual for examples. Each command triggers a very loud buzzer beep (same a for the alarm). I removed the pizeo-element to prevent this annoying sound.

PZEM-004 board front PZEM-004 board back PZEM-004 board IC

The power meter uses a single chip solution, the SDIC microelectronics SD3004 (datasheet). This chip does all the necessary work: measure voltage and current, drive the 7-segments LED displays, communicate over UART. There is only an additional external I²C EEPROM to store the global energy consumption.

ATmega328P

development board development setup Arduino Nano pinout

To read out the measurements from the power meter and send them over radio I used an Atmel ATmega328P micro-controller. Because the development board costs less than the chip itself I simply used a cheap Arduino Nano clone.

USART to query the power meter, SPI to communicate with the nRF24L01+, and the nRF24L01+ protocol are implemented in C (using a lot of interrupts). The source code is available in this git. I prefer directly writing in the registers as described in the datasheet rather than using an abstract IDE and libraries. This way I learn how it works in details.

Arduino - nRF24L01+ connection:

ATmega328P signal ATmega328P pin Arduino Nano pin nRF24L01+ board pin nRF24L01+ signal
GND GND GND 1 GND
3V (add cap.) 2 VCC
I/O PB1 D9 3 CE
SS PB2 D10 4 CSN
SCK PB5 D13 5 SCK
MOSI PB3 D11 6 MOSI
MISO PB4 D12 7 MISO
INT0 PD2 D2 8 IRQ

nRF24L01+

nRF24L01+ module nRF24L01+ pinout

To transmit the measurements from the ATmega328P to the RPi I used nordic nRF24L01+ RF transceivers. There are very inexpensive, require low power, provide enough bandwidth for such application, are easy to control, and because I always wanted to try them out.

On the micro-controller side I implemented the complete SPI-based protocol using the datasheet. The source code is available in this git.

On the computer side I use the RF24 library. The documentation is straight forward and saved me some time re-implementing the protocol a second time.

Raspberry Pi

RPi setup RPi P1 header

To store the measurements I use a Raspberry Pi Model B1 (rev 0002). It's a tiny single board computer which was laying around for quite some time now.

To receive the measurements I used a nRF24L01+ transceiver with the RF24 library. The source code is available in this git.

RPi - nRF24L01+ connection:

RPi signal RPi pin nRF24L01+ board pin nRF24L01+ signal
GND P1_20 1 GND
+3V3 P1_17 2 VCC
GPIO25 P1_22 3 CE
GPIO8/CE0# P1_24 4 CSN
GPIO11/SCLK P1_23 5 SCK
GPIO10/MOSI P1_19 6 MOSI
GPIO9/MISO P1_21 7 MISO
GPIO24 P1_18 8 IRQ

The values are then simply stored in an InfluxDB time series database for visualisation in grafana.

Note: there is no ARM build of grafana (armel for RPi 1, armhf for later versions). This is also because there is no ARM release of PhantomJS. I'm running grafana on my local computer (amd64), using the remote database on the RPi.

grafana visualization

Orange Pi

The Orange Pi PC is a cheap $15 alternative to the Raspberry Pi 2. This single board computer is based on an Allwinner H3 (sun8iw7p1) SoC with ARM Cortex-A7 @ 1.2GHz (often over-clocked), and 1 GB of RAM.

For this price the hardware is unbeatable, but the software support is really poor. Also only Android supports the video hardware acceleration currently. The official images are quite old (e.g. Android 4.2.2), but there are a bit newer images made available by the community:

Since I'll only use it as server I decided to go with debian jessie minimal.

The pin header is the same as the 40-pin Raspberry Pi. The SPI port to connect the nRF24L01 is also available over /dev/spi. But else this board is not really worth spending time on.

Also don't forget to put a heat sink on the CPU, else they will be slowed down quite often because of the high temperatures.

spark_counter.1456051226.txt.gz · Last modified: 2024/01/07 17:49 (external edit)