Literally hundreds of these energy monitors have been sold, but judging from the various articles I've run across, not too many of them have actually been used to meaningfully monitor power around the house. I'm going to install one of them on a troublesome device and actually use it to help understand my power usage. My current victim is my hot water heater.
I've described it before <link>, it's a solar hot water heater with a helper element in it for times when the sun isn't shining. Basically every day here in the desert I'm supplied with unlimited heating for water, but how often do I need the heater element? The element is designed to turn on any time the temperature drops below a certain temperature, but I have no idea what temperature that is. I have the solar heating set for 138F, and since it is an 80 gallon heater, this supplies my needs quite well. Nevertheless, I still want to understand the device and how it uses power.
The first thing I need to do is both read the serial output from the power monitor and be able to transmit it to my house controller so I can save the readings over time. This turned out to be a problem because an arduino only has one hardware serial port. It is possible using software to get another one, but having two software ports is a problem.
The SoftwareSerial library allows for two serial ports, but you can only work with one at a time. Each time you switch ports, the input buffer for the other one is cleared. When I tried it, that meant that the buffers were wiped such that I couldn't actually get enough data from either the XBee or the power monitor to construct a usable packet. I want the serial port for debugging and commands, so I had to work out another method.
What I did was set up a timer that fires off every 15 seconds to interrogate the power monitor, saving the data in global variables. Every 30 seconds another timer fires and sends a report of whatever the variables happen to hold at that time over the XBee network. This way I have reasonably fresh data to send every thirty seconds and only use the two software ports one at a time.
The exception is that in the main loop of the code I check for incoming data from the XBee network at every iteration. Basically in the idle periods between gathering and reporting, I check the network. To prevent the arduino startup from sending bad data from the variables that aren't filled in yet, I read the power monitor before I do anything else. Then I wait for a time message from my house clock, set the two timers and let it run.
It seemed to work pretty well.
Now, how the heck am I going to attach this mess to the water heater? I'm dealing with mains voltages here, I can't just stuff it in a cardboard box and hang it by its USB cord on a nail. This will take some consideration. Additionally, since there is no neutral line to the water heater, everything needs to work from a 220VAC source. Yes, I know, most of the world already has this to deal with; for me, it's a new experience.
Being impatient, I took a big rag and insulated (if you can call it that) the top of the water heater and hooked the power monitor to the high power solid state relay that I use to control the power to the water heater. Then I draped the USB cord over to a wall plug for 5VDC power to the arduino and XBee combination. This way I could actually watch the water heater power usage real time and work on the software to add the data to my Graphana display.
I had some foresight though, I put in plugs for the connections to the CT, 240VAC voltage monitor and serial input so I wouldn't have to flip the breaker when I did something, and it worked like a charm after some programming to save the data I had gathered and a little work in the charting software:
Granted, it's not much to look at. The heater only turned on three times, and even then, it was only for a minute. Slow day around here, but notice that the spikes are 4500 watts. This thing can really pull the power; remember, the solar is running also.
What is happening is that using hot water causes the temperature in the tank to drop and both the solar and the helper element kick on. This heated the water back up in a hurry. Or, maybe I have a bug I haven't discovered yet. Over the next few days I intend to look at how hot water is used for showers and general use around the house. I won't get good data on how this thing is working until I can also monitor the small solar pump as well, but that will take some thought, and probably, some more parts and pieces. Keep in mind that the small pump is 120VAC and I'm working with 240 at this point. A transformer maybe??
My data gathering will be impacted by the fact that the water here doesn't get cold enough to need much of it. This time of year, the rest of summer and early fall, one can take a shower with nothing but the cold water turned on. The best we get for cold water is tepid, and maybe use a tiny bit of water from the hot side. Not that way in the winter though, then hot water usage is much higher.
I'm starting to like the PZEM-004; when this project is running, I want to look around at other similar devices. It's hard to beat less than $15 for a device like this. I certainly can't build an equivalent for less.
I'll put the code for this on github when it is a little farther along. There may be too many bugs right now.
Previous post on PZEM-004 <link>
I've described it before <link>, it's a solar hot water heater with a helper element in it for times when the sun isn't shining. Basically every day here in the desert I'm supplied with unlimited heating for water, but how often do I need the heater element? The element is designed to turn on any time the temperature drops below a certain temperature, but I have no idea what temperature that is. I have the solar heating set for 138F, and since it is an 80 gallon heater, this supplies my needs quite well. Nevertheless, I still want to understand the device and how it uses power.
The first thing I need to do is both read the serial output from the power monitor and be able to transmit it to my house controller so I can save the readings over time. This turned out to be a problem because an arduino only has one hardware serial port. It is possible using software to get another one, but having two software ports is a problem.
The SoftwareSerial library allows for two serial ports, but you can only work with one at a time. Each time you switch ports, the input buffer for the other one is cleared. When I tried it, that meant that the buffers were wiped such that I couldn't actually get enough data from either the XBee or the power monitor to construct a usable packet. I want the serial port for debugging and commands, so I had to work out another method.
What I did was set up a timer that fires off every 15 seconds to interrogate the power monitor, saving the data in global variables. Every 30 seconds another timer fires and sends a report of whatever the variables happen to hold at that time over the XBee network. This way I have reasonably fresh data to send every thirty seconds and only use the two software ports one at a time.
The exception is that in the main loop of the code I check for incoming data from the XBee network at every iteration. Basically in the idle periods between gathering and reporting, I check the network. To prevent the arduino startup from sending bad data from the variables that aren't filled in yet, I read the power monitor before I do anything else. Then I wait for a time message from my house clock, set the two timers and let it run.
It seemed to work pretty well.
Now, how the heck am I going to attach this mess to the water heater? I'm dealing with mains voltages here, I can't just stuff it in a cardboard box and hang it by its USB cord on a nail. This will take some consideration. Additionally, since there is no neutral line to the water heater, everything needs to work from a 220VAC source. Yes, I know, most of the world already has this to deal with; for me, it's a new experience.
Being impatient, I took a big rag and insulated (if you can call it that) the top of the water heater and hooked the power monitor to the high power solid state relay that I use to control the power to the water heater. Then I draped the USB cord over to a wall plug for 5VDC power to the arduino and XBee combination. This way I could actually watch the water heater power usage real time and work on the software to add the data to my Graphana display.
I had some foresight though, I put in plugs for the connections to the CT, 240VAC voltage monitor and serial input so I wouldn't have to flip the breaker when I did something, and it worked like a charm after some programming to save the data I had gathered and a little work in the charting software:
Granted, it's not much to look at. The heater only turned on three times, and even then, it was only for a minute. Slow day around here, but notice that the spikes are 4500 watts. This thing can really pull the power; remember, the solar is running also.
What is happening is that using hot water causes the temperature in the tank to drop and both the solar and the helper element kick on. This heated the water back up in a hurry. Or, maybe I have a bug I haven't discovered yet. Over the next few days I intend to look at how hot water is used for showers and general use around the house. I won't get good data on how this thing is working until I can also monitor the small solar pump as well, but that will take some thought, and probably, some more parts and pieces. Keep in mind that the small pump is 120VAC and I'm working with 240 at this point. A transformer maybe??
My data gathering will be impacted by the fact that the water here doesn't get cold enough to need much of it. This time of year, the rest of summer and early fall, one can take a shower with nothing but the cold water turned on. The best we get for cold water is tepid, and maybe use a tiny bit of water from the hot side. Not that way in the winter though, then hot water usage is much higher.
I'm starting to like the PZEM-004; when this project is running, I want to look around at other similar devices. It's hard to beat less than $15 for a device like this. I certainly can't build an equivalent for less.
I'll put the code for this on github when it is a little farther along. There may be too many bugs right now.
Previous post on PZEM-004 <link>