my custom wireless electricity meter:
While renewing my distribution board the land lord decided to remove the electricity meter. Now I can't note how much electricity I am using. So I decided to build and install my own electricity meter: the spark counter. Using a cheap power meter (i.e. peacefair PZEM-004), a microcontroller (i.e. Arduino Nano 3.0), radio transceivers (i.e. nordic nRF24L01+), a single board computer (i.e. Raspberry Pi), and some storage and visualization tools (i.e. influxDB and grafana) I am now able to measure, log, and monitor my electricity consumption.
I also briefly describe how to use a Saleae Logic clone logic analyzer with PulseView and sigrok.
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.
Published: 2015-10-29 by King Kévin
34 thoughts on “CuVoodoo #014 – the spark counter”
hello, please can you tell me, how many ohms the resistant R47 is, it is the rsistant at the Input from the CT , so it is the first one, beause my one is bemaged.
Thanks so lot
sorry, I did not get notified by the comments. I just saw your question. I’ll check this evening.
the notification is now fixed. I should not miss comments any more.
R47 is marked as R500 and measures (in circuit) as 0.50 ohm.
have you tried to link the PZEM-004 straight to the raspberry PI UART port?
i can’t get it to work..
no I haven’t. the UART part is a bit tricky because of the opto-couplers. it also doesn’t work with CH340 USB to serial adapters. more details here: https://wiki.cuvoodoo.info/doku.php?id=spark_counter#peacefair_pzem-004
Did you manage to make it work, or should I still verify it?
The RPi GPIOs can sink up to 16 mA (http://elinux.org/RPi_Low-level_peripherals#Interfacing_with_GPIO_pins). That should be enough.
But the PZEM-004 requires 5V at VDD for TX, and the RPi GPIOs are at 3.3V, and not 5V tolerant. Under these conditions you would damage the RPi.
I’d like to say a big “thank you”. Your site is really awesome.
I like this post about “spark counter”. I’m trying to reproduce it. I have everything but I can’t upload the code to my arduino pro mini.
The program seems to be stuck on the reset line.
Where do you add the capacitor ? How exactly ?
Otherwise, I was able to test my peacefair PZEM-004 with your ruby code and usb to serial converter. It’s a great code.
My raspberry pi is also setup. I’m just missing the arduino part.
Waiting your answer.
Thanks in advance
I’m happy to help, but which program do you mean? The ATmega firmware (I don’t remember of a reset line in the code), or the Makefile (which tries to flash by reseting the arduino so the bootloader is started)?
The capacitor is simply between the 3V3 and GND pins. This is because the 3V3 is provided by the USB to UART chip and mainly meant to provide power to itself, and not additional chips. The capacitor will hold enough charge so the nRF24 can transmit.
As you said, I mean in the MakeFile (line 17) which tries to flash by reseting the arduino.
I’m sure that it’s something stupide.
I plugged my new arduino pro to my Mac via the usb plug. There is nothing linked to my arduino except the usb plug (no capacitor). Then, I open my terminal and run the command “MakeFile”.
It’s blocking on line 17.
In the MakeFile, I have already updated the port variable (line 13) by the correct one in my case => /dev/tty.wchusbserial1410
I tried with an arduino uno as well without success.
Do you see something wrong in my steps ?
Thank you again for your help. I really appreciate it
ah, now I get where your first question about the capacitor is coming from. I think your a referring to the comment “# the capacitor on DTR will create a pulse on RESET” in https://git.cuvoodoo.info/kingkevin/spark_counter/blob/master/arduino_nano/Makefile#L60.
If this is the case, you don’t need to add any capacitor. This should already be present on your arduino pro. This is “C2” in the schematic https://www.arduino.cc/en/uploads/Main/Arduino-Pro-schematic.pdf.
As you can see on the schematic this capacitor is connected to the “DTR” net line (through the solder jumper). DTR is a RS232/UART signal line. It is usually set high when the serial port is opened. The capacitor will transform this high signal into a pulse on the ATmega reset line. This will reset the micro-controller, which will start the arduino bootloader (already programmed on the micro-controller by arduino).
This is exactly what the “reset” rule does using the stty command https://git.cuvoodoo.info/kingkevin/spark_counter/blob/master/arduino_nano/Makefile#L64. It simply resets the board to start the bootloader.
This bootloader allows you to re-program the micro-controller with the main firmware, which you else would have to do using a dedicated programmer.
This is what the “flash” rule will do, after it “reset”, with the flasher command (using avrdude).
There is a nasty detail with the spark counter firmware: it uses the watchdog to reset the micro-controller in case it gets stuck. I didn’t see it happen yet, but it’s a safety measure. Sadly the default arduino bootloader the arduino ships with does not support watchdogs. Thus you will have to flash another bootloader first. This is what the “bootloader” rule will do https://git.cuvoodoo.info/kingkevin/spark_counter/blob/master/arduino_nano/Makefile#L78, and you only have to run it once. But for that you will need an external programmer (I use a usbtiny as you can see in the command). There are many other programmer alternative. Even another arduino could do the job.
Once the optiboot bootloader is flashed, you can flash the firmware using this internal bootloader instead of the external programmer.
The optiboot bootlaoder also allows to flash at a higher speed (115200bps instead of 57600bps of the arduino bootloader) https://git.cuvoodoo.info/kingkevin/spark_counter/blob/master/arduino_nano/Makefile#L17.
You also said it’s blocking on this line 17. But that should not happen, since this is not a command to execute, but a makefile variable.
The Makefile file is not an actual program or script. It’s rather a set of rule for the “make” program. The Makefile has been designed for Linux, and requires some changes to work for Mac. And you guessed right, the USB serial port are not mapped the same way and you will need to adjust the path to the arduino USB serial port in PORT variable https://git.cuvoodoo.info/kingkevin/spark_counter/blob/master/arduino_nano/Makefile#L13.
Then you can run “make flash” in a terminal, within the same folder as the Makefile.
Similarly you can run “make bootloader” to flash the optiboot bootloader using the external bootloader, or “make reset” to reset the arduino board.
Thank you for your help. It’s really interesting. I always use the arduino IDE that’s why I’m bit lost.
I have issue to compile and upload the code to the microcontroller with avrdude. I’ll find the solution.
I’ll come back with my feedback.
The arduino IDE makes it really easy to use the micro-controller, and that’s probably one of reasons for the success of this development platform. Understanding how it works in the back takes some efforts and time, but it is worth it. It provides a better feeling of accomplishment. Also it removes the “I don’t know why it doesn’t work and can’t do anything about it” feeling since you can always refer to the source code and datasheet. I can only support your interest.
Finally, I got it working (arduino,rpi, influxdb, grafana).
If it helps someone, here is a quick code in Arduino IDE :
I see you were using one closed loop sensor for all three phases. The guys of openenergymonitor use three sensors – one for every phase- because they say measuring would not be correct using just one sensor. do you know more about this ?
Thanks for pointing it out, and it seems they are right.
I am not familiar with power distribution systems, and something was actually already bothering me.
I was wondering why I have three line wires but only one neutral wire, with all the same thickness.
If it’s only to allow more power to come in, why isn’t the neutral wire thicker than the line wires, so this one neutral wire can carry the load of the three line wires.
With a bit of reading it turns out they installed a 3 phase 4 wire system (not sure why, since it’s only a small flat).
The phases are balanced (they have angle differences of 120°). I verified it by measuring 400V between two line wires.
This is also why a same-thick single return path is sufficient, since the sum of the currents will not exceeded one of them (they are distributed over time due to the phase difference).
But to measure the total power I use, I do have to sum the power of the 3 lines, and thus put coils on each of them.
I also have some open questions I could not find the answer to before replying to you:
– what am I actually measuring?
– if it would be a single phase in 3 wires, do I also have to measure the current in each wire (e.g. if there is a phase shift on one of them due to a capacitive/inductive load)?
At least I will put a warning on the episode description and in the wiki.
And you just gave me a good opportunity for a next episode (to tackle this issue).
Each of the phases peak at different times. You need to add each phase to measure total usage. I understand that you can chain the PZEM-004 modules.
I am aware that the electricity meter I presented (the spark counter) is only applicable to 1 phase 2 wires electricity distribution systems. Accordingly I’ve added a warning in the wiki article.
For electricity distribution systems with multiple phase the collected data (when only measuring the current on the neutral wire) will not show the actual electricity consumption. An upcoming episode will provide more information.
I can also confirm that multiple PZEM-004 modules can be connected to the same UART bus (star topology).
Do you know the current sensor specs?
Can it ben that it is a 1000 to 1 ratio (10A = 10mA) ?
I like to use a split core CT because of it’s easy install in the utility case.
I don’t know the ratio for the coil provided with the PZEM-004, but if you would like to use a split core current transformer with known included resistor I can recommend the SCT-013-030.
Kévin, good job.
I think you are not right if you propose the SCT-013-030, it is 30A/1V (voltage output), so is writed in the datasheet http://www.yhdc.com/en/product/320/.
I think PZEM-004 can be completed by the transformer SCT-013-000 or 100A/20mA like here https://www.aliexpress.com/item/Precision-AC-Current-Transformer-Coil-PZCT-100A-20mA-for-AC-Voltmeter-Ammeter/32763708969.html?spm=2114.30010308.3.2.kn7d7t&ws_ab_test=searchweb0_0,searchweb201602_2_10065_10068_10084_10083_10080_10082_10081_10060_10061_10062_10056_10037_10055_10054_10059_10032_10078_10079_10077_10073_10070_10052_423_10050_10051,searchweb201603_1&btsid=397a56a3-40eb-4f28-b182-270f1bfe62be
By “not right” I suppose you are referring to my statements in the video around 45:00 about using the SCT-013-030 as alternative to the coil provided along with the PZEM-004, when being used with the PZEM-004 electricity meter. I agree with you. I don’t know if their are compatible (I don’t think they are). Also the SCT-013-030 has already an internal resistor (used to get 1V when measuring 30A) while the PZEM-004 has a resistor on the board, and probably expect a coil without additional resistance to be connected.
If this is not what you where referring to, or if you have additional information, please let me know.
Yes, I agree with you that the transformer with voltage output expect to remove the input R47 resistor. What value have R47 and it is connected in parallel ?
But that is not all… you should be to calibrate the item and to adjust a R47 resistor – after that you can see right values in the LED’s display.
For PZEM-004T it is not necesary – you can use a multiplication factor in your software.
1. do you can read a value of the reverse current over a serial interface?
2. do you can read the module address?
It is not ethernet address – it means 4 bytes and range 0000h – FFFFh. It is maybe interesting if you have one RS232 and many modules…
here a couple of answers:
– What value have R47: 0.50 ohms
– it is connected in parallel ?: yes
– you should be to calibrate the item and to adjust a R47 resistor: a potentiometer would be handy to adjust the resistance value until the correct one is found (e.g. when the output data corresponds).
– For PZEM-004T it is not necesary – you can use a multiplication factor in your software: yes, but you have to be aware that you are also affecting the resolution, precision, and limits of the measurements if you change the coil and resistor. I preferred using the included coil in my application.
– do you can read a value of the reverse current over a serial interface?: no (I have to verify if you can calculate it though)
– do you can read the module address?: no (no command to do that is documented). but you can set the address, and this is all you need. also querying a device without know its address would cause collisions when multiple devices are on the same bus
– It is not ethernet address: I think you meant IP (the Ethernet address is generally the MAC, consisting of 6 bytes)
– it means 4 bytes and range 0000h: yes. it’s just funny that they used IP addresses as example in the documentation instead of starting with 0x00000001. but you can set whatever address you want AFAIK
– It is maybe interesting if you have one RS232 and many modules: I’m currently working on project which does exactly that. An episode about it might come in the near future 😉
Bingo!!! How useful is to communicate with a smart man :)…
All is ok with the module address and it is possible to use many modules on same bus (for example 3-phase system etc.) – if you send any request to the module you write in the command a module address!!!
B5 C0 A8 01 01 14 33
The format of the command:
D0 D1 D2 D3 D4 D5 D6
D0 – the parameter (=0xB0…0xB5)
D1 D2 D3 D4 – the module address
D5 – a additional parameter (for ex. for power value 0x14 = 22kW )
D6 – the cumulative sum
We don’t need a separate command for the reading of the module address.
Right, you just have to set the address once, with only one device on the UART bus. Then you can talk to as many devices as you want (individually) on one bus (up to 2^32 devices because of the 4 bytes address, and the electrical signal needs to cope with them all) as long as you know their address (which you’ve set before) and this address is unique (on the bus).
But one question more:
If you send send a command to a wrong module address what is answer?
nothing, no device responds. only the set address command is a broadcast message affecting all devices (at least the only one documented).
that’s the reason why you should set the address only once, with only one device on the UART bus.
Could not it be possible to simply use PZEM-004 + level shifter + Raspberry?
PI could then stor datas directly and even send it over its integrated wifi.
But I can be wrong.
Let me know waht you think.
Sure, that would be a working alternative, but then I would have to lay an Ethernet cable across my apartment for the Raspberry Pi to get network connectivity. Plus one of this project’s goal for me was to learn how these nRF24 transceivers work and how to use them.
Meanwhile I found an even better solution. Stay tuned for more details in an upcoming episode ;).
I will stay tuned, trust me 😉
But regarding the Pi : on PI 3 you dont need ethernet, rather you can simply use the integrated wifi
When the spark counter was put into the world the Raspberry Pi 3 was yet just an idea in the mind of its creators ;).
I’m really happy to find out your experiment here.
I try to do something like you that measure and keep how much I consume an energy.
I want to use another CT instead of PZEM-004T its own ct.
Current Tranformer that I want to use is
1. Efergy : https://goo.gl/rAXco8
2. YHDC SCT013 : https://goo.gl/8845mC
The problem is measured current from those 2 CT not equal to clamp meter that I use as reference. It always half current from CT when compare with meter for example,
Mesured current from meter : 1.8 A
Mesured current from CT : 0.9 A
But the original one CT has the same value with meter.
Please suggest me how I can obtain the right current from those 2 CT.
Thank you so much.
If you want to use another CT you will have to use a compatible one, or multiple the measured value by the factor corresponding to the other CT (e.g. its ratio compared to the original). The PZEM-004(T) measures current at its input, thus you it need a pure current transformer (not one with an internal resistor and outputting voltage). Since I don’t have any original CT for this module I don’t know its ratio. From a quick search it seems it uses a PZCT-2 CT split core with a 100A/100mA ratio. But to be sure you should measure it by yourself.
Regarding the SCT013, this is not a pure current transformer as it has an internal resistor and outputs a voltage, thus it will not be compatible with the PZEM-004T (unless you remove its internal resistance and multiply the measurement you read over serial with the right ratio).
Regarding the Efergy CT I can’t comment because no information is provided about this product. But here too you can also figure out its ratio (and multiply the measured value with the corresponding factor), or if it also has an internal resistor apply the same procedure as for the SCT013.
I confirm the 1/1000 (100A/100mA) ratio. I received my http://www.ebay.com/itm/PZCT-2-0-100A-Current-Transformer-Split-core-Snap-type-/182285206716 today, and it works fine 🙂