Power Measurement Revisited

Spot Measurement

I finally got around to tinker with things again and opted to digress from the zigbee standalone mote-like development to revisit the power measurement.

I have three types of sensors to measure currents lying around and decided that given I already wrote the C++ classes and modbus integration for total home energy consumption, I could easily create a spot measurement modbus slave device to monitor specific loads.  Note that all my arduinos+zigbee are modbus slave devices and only the mote-like devices shall use a different protocol.

Sensors

The sensors in questions include a SeeedStudio Non-Invasive AC Current Sensor,  a general purpose 0-20A for experimentation CR Magnetics  (CR8410-1000) Hall effect bases chips from Allegro ACS712ELCTR-20A-T

 

 

 

 

 

 

With known loads, I compared the output from each of the sensors as illustrated below.

Allegro hall effect chip.

What I liked about the hall effect chip was a dc offset of 2.5V was already in place to feed into the A/D of the Arduino and fit in the 0-5v range requirement. The CT from CR magnetic was clean and was sensitive down to the half-amp range which I wanted for spot measurements. The non-invasive one was bulky and noisier on the low end.

I did not spend much effort on the linearity of the sensors.  Like the total home energy solution completed a while back, I generated a scatter plot for know currents vs my calculated currents then fit a line of the type mx+b to use to linearize the calculations in the desired operating regions.

 Phase Shift

Now when it comes to delays introduced by the CT relative to the voltage, it can introduce errors in non-unity power factor loads. I put both signals on the scope and examined the phase offset introduced. My scope software can calculate the phase difference between two signals. I was not getting too much phase delay to warrant compensation for my home application.

 Housing the Components

A plastic electrical box was used to host the arduino (fio) and xbee + power supply + voltage measurement transformer. Not the prettiest, but it serves the purpose.

The same host software was used for total home energy monitoring to poll, display, and trend the information from my modbus aware device. The chart below is for the power consumption of my PC and other stuff plugged into the power bar.

Pin Sleep Xbee with Arduino Host

Making it work.

I got everything to function with a rather messy board setup as shown below.

The output from the Arduino shows the delta T between messages received from the end-devices.  It is pretty close to the calculated ones. I will change the duration to be 15 minutes later on but for debugging purposes 10s intervals for pin sleep is tolerable.

 Code

The following are the libraries were referenced.

Arduino library for communicating with XBees in API mode – I used both Java and C++ versions for this.

Standard Template library (STL) for AVR – I wanted some maps and other stuff in the dev environment.

Streaming C++ style Output – print and println gets to be a pain after a while

Ardunio Modbus Slave - I used this for my energy monitoring project as well and hacked in a modbus function 6. Since then, a new library that includes function 6 has been deployed, but I still used the older version as I wrapped the C++ class – SerialModbusSlave and did not feel like manually merging code.

 HardwareSerial

I leveraged the serial ports available in the Mega2560 and created global variables to reference instances of the serial port as follows:

HardwareSerial gModbusPort = Serial;
HardwareSerial gDebugPort = Serial2;
HardwareSerial gXBeePort = Serial1;

Which allowed me to do things like the following:

  xbee.setSerial( gXBeePort);
  xbee.begin(BAUD_RATE);
 
  gDebugPort.begin(BAUD_RATE);
 
  // TODO: send from host
  setTime( 1308482002 );  
  gModbusSlave.setRegisterBuffer( gModbusRegs, MAX_MODBUS_REGS  );
  gModbusSlave.init( &gModbusPort, MOD_SLAVE_ID, BAUD_RATE, 'n', 0);

I can change ports around in one spot in the code rather than find an replace things.

I opted to over design things a bit as I wanted to avoid changing the code later on as tacit information tends to be forgotten over time. What I wanted to do is be able to provision new end devices without changing the arduino code and follow a simple 4 step process:

  1. update to appropriate firmware in XBee, set Pan ID, and API mode 2
  2. utilize the home grown Java app to set up the details such as IO types and lines  ( I am thinking of adding a clone function to make this even simpler)
  3. wire up xbee related circuitry
  4. provision the end device in the Arduino via Mango HMI over Modbus

The following illustrates the concept in a non-formal way of describing software. When a ioresponse is received from an end device I look up the corresponding meshdevice entry in map using the string representation of the address64. I was thinking of using int64_t  type rather than a string as the string takes more space but that is not at a premium at this point.

The address64 string for managed end devices are stored in eeprom and loaded on setup(). Provisioning of end devices are sent over modbus from the HMI host and written to eeprom as well. Yes overkill, but t I want to evolve the system and focus on some abstraction to allow the evolution the meshdevice representation. All the smarts to evolve will be confined in one class. The tacit information like how to provision and communicate with the HMI, etc. will hopefilly remain static.

Map of Meshdevices

A map of using the STL for AVR to reference the MeshDevice is as follows:

// a place to reference devices and corresponding data
typedef std::map<String,MeshDevice> RemoteDevicesMapType;
 
RemoteDevicesMapType gRemoteDevices;

And updating meshdevices is coded as follows and will change later on as the error handling is uber weak.

void refreshDeviceReference( ZBRxIoSampleResponse aIOSample ) {
 
  MeshDevice lCandidateDevice;
 
  RemoteDevicesMapType::iterator lItr;
  std::pair<std::map<String,MeshDevice>::iterator,bool> lRetVal;
 
  String lAddress64 = String((long) aIOSample.getRemoteAddress64().getMsb(),HEX)  
                      + String((long) aIOSample.getRemoteAddress64().getLsb(),HEX);
 
  lItr = gRemoteDevices.find( lAddress64 );
  if( lItr != gRemoteDevices.end())
  {
    lItr->second.beginTransaction();
 
    for (int i = 0; i <= MAX_ANALOG_INPUTS; i++) {
      if (aIOSample.isAnalogEnabled(i))
        lItr->second.setAnalogInput( i, aIOSample.getAnalog(i) );
    }
 
    for (int i = 0; i <= MAX_DIGITAL_INPUTS; i++) {
      if (aIOSample.isDigitalEnabled(i))
        lItr->second.setDigitalInput( i, aIOSample.isDigitalOn(i) );
    }    
 
    // lItr->second.dumpContent( gDebugPort );
    lItr->second.endTransaction();
    gDebugPort << "Received I/O Sample from: " << lAddress64 <<" detalt="
               << lItr->second.getDeltaT() << " ms" << endl;
 
  }
  else
    gDebugPort.println( "Not Found : " + lAddress64 );
}

Modbus Register Buffer

Lastly the mapping to modbus style registers are set up as clusters for each device and terminated with a set of register to accept commands and address64 strings from the host. The code for it is rather simple and I will shoehorn this later on. Up to 13 discrete (digital) and 5 analog I/O are reserved for each device. What is used depends on how the XBee device is configured which is explained in the XBee datasheet 90000976_D Datasheet

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

The prototype basically implemented the following data flow model. The issue for me is battery powered end device is not green enough of a solution for me.  I’m thinking of exploring energy harvesting to help things along. The plan was to also send battery voltage level on the end device to the SCADA host to generate low battery alarms. Still, it would be nicer to tap into ambient environment (vibration, etc) to generate energy to help power the end device. This will be explored later.

Pin Sleep Xbee and Documentation Rant

Well everything is wired up and works as planned. Sort of. The journey there was not simple. The datasheets on the xbee around sleep modes covers everything one needs to set that up. The problem is that it is not a first pass approach for a newbie. I had to scratch my head a few times. Specifically the following:

Pin Sleep for periods longer than 5 seconds caused the end device to send information every 30 seconds or so. In the back of my mind, I knew that the coordinator and router handled all the registration process for end devices and that if one of them went MIA then it would be removed from the child table entry. It did not dawn on me that I had to set the SP/SN on the coordinator and router to a value that is longer than the sleepiest end device. I thought those parameters were to be used for just sleep mode configuration. Alas, I was wrong and perusing the data sheet it states for the SN value.

On the parent, this value determines how long the parent will buffer a
message for the sleeping end device. It should be set at least equal to
the longest SP time of any child end device.

My initial thoughts were that I don’t have any messages sent from the host as they are initiated by the end device upon waking so why bother to change the defaults on the coordinator and router? Then I started questioning the datasheet version I was using. Although the datasheet supported the firmware version of the xbee, I did not pay attention to the differences between OEM (doc # 9000976a) vs non-oem (doc #9000976d). The d version has a lot more updates and included a section on child poll timeout. That was the aha moment for me to get things to work.

To quote the datasheet “D” and not in “A”.

The child poll timeout is settable with the SP and SN commands. SP and
SN should be set such that SP * SN matches the longest expected sleep
time of any end devices in the network. The actual timeout is
calculated as (3 * SP * SN), with a minimum of 5 seconds.

Rant

What is the difference between A and D from the front page? A Hardware line not in previous versions and the absence of OEM. Nice change log.

Now as a hobbyist, I have to ramp up on a lot of fronts and time wasting, although annoying, is par for the course. When one googles xbee and sleep modes, etc. there is a lot of chatter. I’m sensing the XBee evolution and corresponding documentation suffers from a quality issue around information management. What is the cost of ignoring quality in productivity losses in companies? A lot.

Perhaps the problem was between the chair and keyboard in this case. If I compare the effort in  ramping up on the arduino vs xbee, the arduino is a no brainer. I can focus on algorithms and more cerebrally challenging problems. I can’t say that for the XBee.

I’ll get into the mechanics next.

Sleep Mode – Timer Setup

Upgraded to wordpress 3.2. Quite painless.

Setting up the Timer

I received my components from digikey to finish the mesh based data collection prototyping. One of the components is the LTC6991 timer chip. I never soldered surface mount devices before so I did my share of reading up on it. Mine turned out functional but not the best looking. Hats off to those who make it look easy. The IC is TSOT-23 and I purchased a breadboard friendly board to solder it to.

 

 

 Note US penny is same diameter as Canadian penny.

This chip is awesome and worked flawlessly. The datasheet has all the information and includes a sample-circuit for a self-resetting timer. The vendor also has an excel based calculator to facilitate resistor value calculations. It does not have provisions for the  resistor/capacitor portion self-resetting portion of the circuit. One can refer to the datasheet to get the formulas to compute those. For my experiment, the circuit used from the datasheet is reproduced below.

Solve the above equation for R_{pw} to get

R_{pw} = \frac{-t_{pulse}}{C_{pw}\cdot ln(1.429/3.3)}  (1)

where
C_{pw} = 4.3 nF
t_{pulse} = 55 to 56 ms  I may have to lengthen the pulse duration later.

 

R_{pw} came to 15.4 M\Omega  and I had a couple of 7.68 M\Omega 1% resistors available. Close enough.

The rest of the components values where calculated from the the vendor tool.

R_{set}= 118k\Omega \approx 120k\Omega
R1 = 392k\Omega
R2 = 1M\Omega

I wanted a period of 10 seconds and active low. That is a very high duty cycle that you would not get with a 555 timer. The final solution will have around 5 minutes between pulses but for testing purposes, 10 seconds is easier.

The output from the scope below shows (click on it for zoom). The period is 10.1s.

The pulse came in at 57ms as shown below.


Now time to move on to setup the arduino and Xbee integration.

Sleep Mode

I opted for hardware driven sleep mode (SM=1) in the XBee. I felt that that cyclic sleep mode (SM=4) to be a pain to setup. I felt that that keeping the XBee asleep for extended durations, the device would be MIA from host. With a hardware based sleep, I could use a swith to to force  it awake, configure remotely with the software tool I wrote, flick the switch back to the timer based sleep. Simple in my mind.

The tested scenario is illustrated below and it worked as planned. The XBee would be taken out of sleep for 30 ms and back to sleep for 100 seconds. As stated earlier, the power consumption does not lend itself to using batteries. xbee visio

I found this link for an alternative to the 555 and will look into it.  I would also not require a level shifter and can operate from a single 3.3 battery. This would surely extend the battery life as it would remove the dependency on the 78L33 and 555.  Now I just need to deal with the LM35 and other sensors and I think I have a way to deal with that and that is to keep them “offline” when sleeping. More experimentation.

Estimated Battery Lifetime

The resulting solution must run on batteries (coin type ideally) and I wanted to get a sense of the operating time between battery changes.  The spreadsheet utilized the cells in red as variables. Assuming a wake up during of 30ms and sending a sample every 100 seconds, I can run for an acceptable amount of time.  The problem occurs when I include a 78L33 level converter, 555 timer, and a sample sensor like the LM35. I will need to look into this as this might be a show stopper on the battery only constraint.

I have set up my test circuits to using a 555 timer and create a 99% duty cycle for a duration of 100 seconds or so. It does wake the xbee up and transmits to the host software. Now I need to re-evaluate things from a power consumption side.

I will measure the actual current when I build the prototype.

Device Current
Xbee Sleep 0.01 mA
Xbee TX 45 mA
Xbee RX 50 mA
Battery 200 mAh
555 timer 0.1 mA
LM35 0.06 mA
78L33 5.5 mA
Level Converter (5 to 3.3 V)
Sleep Period 100 seconds
Tx 1 per wakeup
Rx 1 per wakeup
Wakeup Duration 30 ms
Aprrox Wakeups per 24 hr 864 count
Approx wakeup duration per 24 hr 25920 ms
XBee Current per wakeup 95 mA
Xbee mA per 24 hours consumed during wakeup 0.684 mA
Xbee mA per 24 hours consumed during sleep 0.009997 mA
mA per 24 consumed 555 2.4 mA
mA per 24 consumed LM35 1.44 mA
mA per 24 consumed 78L33 132 mA
# of days for one battery w/o 78L33 44.0 days
# of days for one battery 78L33 1.0 days
# of days for one battery w/o 78L33,555, LM35 288.0 days

XBee API Mode

So now that I have the latest firmware installed on a coordinator, router, and 2 end devices all set up for PAN ID=47, it is time to write some software to experiment with the other settings. I am not a fan of the X-CTU software and decided to write a simple test application to configure my devices. The vision is to use X-CTU software to upgrade the firmware, set the API mode, and Pan ID. After that, the rest of the provisioning would occur from the software I wrote to configure the devices. I want to commission new XBees for the “field” with just a few clicks of a mouse. I tend to forget things after a while so tacit information should be captured in the software.

I used the Java API for Digi XBee/XBee and jformdesigner within Eclipse to write a simple application as shown below. The software I wrote allows me to discover devices and drill down a given device to change parameters.

xbee discover

I also needed a way for me to experiment with I/O settings and sampling modes as well. This allows me to configure a device and poll the data values. The XBee sheet I use is found here.

xbee io

In the end, the goal is to have the end device send their values after a sleep time so I added a listen that posts IO from end devices along with deltaTs between samples.

xbee listen

Time to experiment.

New Project – Xbee Mesh Network and Data Collection

I needed a project to dabble and distract me in a constructive manner.  The goal for this project is to build a low power data collection network to sample  slow changing analog data such as temperature, ambient lighting, among other things. The constraint given was to use XBee Series 2,  run in API mode, and operate on batteries.

I purchased 5 XBee Series 2s to experiment with. I used X-CTU software to configure the Xbee chips as per the last project I did. The difference this time is I did not want to use AT mode but API mode to give me more control over XBee interactions from the Arduino host software. The  project context is as shown below.

Arduino to-be

The XBee USB Explorer was used and I soldered break away pins and a push button switch between ground and reset.   When I first load an XBee, I select the proper port with default settings. Query the device and you should get a dialog box pop up as shown below.

xctu read new

My XBees don’t come with the latest firmware and perusing the web about which is the latest for the Series 2 indicated that that the ZB supersedes the ZNet stuff.   This is where the push button approach comes in and described here. I picked the XB24ZB firmware with the correct device type. I included 1 Coord, 1 Router, and 2 End Devices. I used a PAN ID of 47 to setup the devices and ensured that I included that in my firmware configuration.

x-ctu default

I  get the following error and that is where the push button wiring that connects reset to ground comes in. I just push the switch for a couple of seconds, release, then upgrade continues. I has something to do with the new firmware and default sleep mode and described here.

x-ctu programmingOnce the new firmware is installed, I head back to the PC Setting tab and select API mode as shown below and set the include escape character as well.

x-ctu api

Now I see the the latest firmware upgrade.

Finished–Good Enough

Wiring to the Power Main

I finally got around to put in the current transformers  (CTs) in the panel last weekend. I had an electrician come and pull the meter out so I could install them. If you are wondering, I got permission from the utility company to do so. In hind-sight, I should have purchased split core transformers and just clip them on.

I can’t say much more about this, as it was quite a no brainer to do. This was the first time I tested  my Arduino with more than 13 amps and my only concern was if I was off in my scaling. Using commercial grade CT provide linear operation in the range I’m interested.

panel

I took a utilitarian view in packaging the Ardiuno and circuitry and ended up using a dead router enclosure to host the solution. With limited tools, I cut out a place for the LCD and xbee radio.  It works and is out of the way so it met my simple requirements.

mounted

Collecting the Data

I can collect power related information as shown below and log it over time for trending purposes. I can also collect reactive and apparent power but for power factor tells me the story at a glance. As stated in an earlier post, I used Mango to do all that.  I was posting stuff on Pachube and exceeded the posts allowed for free so I disabled it. I will revisit this later as this is not a high priority.

screenshot 1

Also trended it the cumulative lbs of CO2 that is spewed out based on my consumption.  I reset the counter at midnight every night. I do the same with costs and kWatt-hr consumption.

screen 2

gfgffgfgfghfg

If I had to Start Over

I would have wired and programmed the solution to handle updates over the xbee.  I settled for plugging the laptop in the device and load changes that way.

Next Project

I would like to stuff the server side software in a fanless PC like an ARTiGO. I must admit this stuff is boring and prefer to venture into more math/physic problems. Migrating the server side software is not really a project and more something I have to do  as one of my desktop PCs is doing the data collection.

The next project is to measure the temperature in different rooms and just use the XBee and a temperature transmitter. I also want to sense the on/off of key appliances as well over XBee. Alas, I don’t have the cycles to work on this as this is a part-time hobby.

So far I slapped together an Arduiono with XBee and transmit the temperature over modbus as illustrated in the diagram below.

Arduino as-built

The power monitoring Arduino has a slave ID of 2 and the temperature Arduino of 3. Using an Arduino to collect a temperature is overkill and is why I want to change it to be low power over a mesh network around the house. I may have a data concentrator over modbus to bridge the mesh with the host and something like the diagram below. Who knows.

Arduino to-be

xBee, Debugging, et al

Relatively Easy

I’ve been busy with work and never have the time to get back to this project. Anyway, I penciled in a few hours to wire up the xBee transmitter/receiver to the arduino. The xBee explorer is a time saver. What I wanted to do is to program the arduino over wireless as well. Given that time is limited, I opted to just send data over wireless to simplify connectivity.

The xBee explorer had 4 connection points that made it easy to hookup:

  • +5 to arduino +5
  • gnd to arduino ground
  • dout to rx (pin 1 of ardiuino)
  • din to tx (pint 2 of arduino)

That is pretty all that is required to wire up the xbee. The explorer takes care of the 5v to 3.3v level shifting.  Remember I am using the Duemilanove as the reference board. Note that you can’t plug in the USB in the Duemilanove and xBee in the explorer at the same time. The two will conflict with each other. This is rather trivial to hook up so no wiring diagram other than pin connection mapping is provided.

On the host side, I used the USB explorer which is basically leads to a plug and play model which I like.  Rather than regurgitate xBee configuration, I found that it is well explained here. (Xbee Configuration tutorial)  I tweaked the PAN, Baud rate, and type. I made the host a coordinator and the slave device a routing type. Again, explained well in the tutorial.

Just like the other parts of this project, I found soldering and wiring it up the hardest. I used left over wire wrap wires (I think the stuff is 20 years old) to connect things. I don’t wire wrap them and still solder. I like it because it is not tot bulky. It does break easy though.   Anyway, I have a renewed appreciation for those who package hardware. Although mine works, only a mother could love the way it looks. Alas, it is for my own use so prototype mode is good enough.

xbee

Current Transformer Revisited

I revisited the current transformer wiring in the context of safety. Rather than use terminal blocks, I should have used simple audio jacks to simplify the wiring. Either way, there was a safety issue that loomed in the back of my head and I wanted to address it before wiring the sensors to the power mains. The secondary in an open circuit mode of a transformer (not connected to anything) can reach a high voltage and should it come in contact to a person, guess who is going to be the resistor for that voltage to close the circuit. You.  It does not take much to kill you.

What I did was add a switch that shunts (shorts) the secondary of the transformer that I flip to “field work mode” before handling the terminals.  This is not like shorting a 120 AC line. The voltage on the secondary is the function of the reflection of the impedance on the primary. This can get mathematical so I will spare the math. Suffice it to say that shunting the secondary won’t hurt the current transformer and will add another level of safety.

current xformer