Energy Monitoring System (EMS) Abstract
Dean J. Boman Project ID: 74315 Rev - March 22, 2012 Prepared for: DesignSpark chipKitTM Challenge
Abstract
The Energy Monitoring System (EMS) provides real-time home electrical energy usage data to the occupants so informed energy usage decisions can be made. The system hosts a web server that provides a web page with the current energy usage on a circuit-by-circuit basis. In addition, the system interfaces with the overall home automation system so long term monitoring and logging can be accomplished. The Energy Monitoring System consists of the chipKit Max32 development board along with two extension board that hosts the unique interfaces required by the system. A block diagram is shown in Figure 1 and the completed project in shown in Figure 2. The main electrical panel for the home contains 32 individual circuits, so 32 current sensors are used to measure the current consumed by each branch circuit. The branch circuits consist of a mixture of 15 A, 20 A, 25 A, 30 A, 40 A, and 50 A circuits so the sensor sensitivity is tailored to the capacity of the individual branch circuits. The current sensors drive the EMS Interface Board which filters the sensor signal and adjusts the voltage level to be compatible with the Max32 analog to digital converter (ADC) inputs. The EMS Interface Board provides the conditioned signals to the EMS Max32 Board which contains a 32 to 4 analog mux which route the signals to four of the Max32 ADC channels. The EMS Max32 Board also contains an Ethernet interface and power supply. A representative web page display is shown in Figure 3.
The software design for the Energy Monitoring System utilizes custom software written in the C language using the Microchip MPLAB development environment to implement all the functions required to measure the real-time energy usage. This custom software is integrated with the Microchip TCPIP stack, which provides the web server interface and all the other standard network functions.
Figure 1 EMS Block Diagram
chipKit Max32Development Board
48 to 1 Muxes
Buffer Amp/1 KHz Filter
Sensor 0
Sensor 31
Electrical Panel
324 ADC Inputs
Select
EthernetInterface
SP
I
Power Supply
12 V
EMS Max32 Board
120 V AC Input
Router
Internet
HomeAutomation
System
Energy Monitoring System
EMS Interface Board
Buffer Amp/1 KHz Filter
-9 V
+9 V
Part of project
Not part of project
Purchased item
Legend
Figure 2 Photo of Completed EMS Project
Figure 3 Representative Web Page
Sample of Code
In order to measure the energy usage of each circuit the current waveform provided to the PIC32 ADC via the EMS Interface Board and current sensors must be sampled sufficiently fast enough such that the RMS current value can be calculated. The filter design on the EMS Interface Board limits the bandwidth to 1 KHz so a 99.8 usec sample period (10 KHz) was chosen. In order to calculate the RMS current the waveform must be measured over precisely one cycle of the 60 Hz AC waveform. To implement the timing for the sampling and RMS calculation timer2 was configured to generate an interrupt at a 99.8 usec rate. The timer is configured with the following code: //Configure timer2 for realtime keeping but setting it for a 99.8 usec interrupt rate
T2CON = 0x0040; //Timer off, 16 bit mode, /16 from peripheral clk
TMR2 = 0;
PR2 = TIMER2_MATCH; //Configure for the 99.8 usec rate
IFS0CLR = _IFS0_T2IF_MASK;
IEC0SET = _IEC0_T2IE_MASK;
//Configure Timer2 Interrupt
INTEnable(INT_T2 , INT_ENABLED);
INTSetVectorPriority(INT_TIMER_2_VECTOR, INT_PRIORITY_LEVEL_2);
INTSetVectorSubPriority(INT_TIMER_2_VECTOR, INT_SUB_PRIORITY_LEVEL_0);
//Configure for multi-vectored mode
INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);
//Enable interrupts
INTEnableInterrupts();
//Timer is ready so turn it on
T2CON = 0x8040; //Timer on, 16 bit mode, /16 from peripheral clk
When the timer times out after 99.8 usec, the interrupt service routine (Timer2Handler) is called, which set various flags as shown in the following code. The TickFlag is set to indicate to the while(1) loop in main() that it is time to sample the ADC, the HalfSecondFlag is used to toggle an LED for indication that the system is operating. Once per second the UpdateRTC() routine is called to update the real time clock. The real time clock is set once per hour based on an external time server. //
// Interrupt Service Routines
//
void __ISR(_TIMER_2_VECTOR,ipl2) Timer2Handler(void)
{
//Update the second counter with the 50 msec timer ticks
Sec_counter++;
TickFlag = TRUE;
if(Sec_counter == 5010)
HalfSecondFlag = TRUE;
if(Sec_counter == 10020)
{
Sec_counter = 0;
HalfSecondFlag = TRUE;
UpdateRTC();
}
// Reset interrupt flag
IFS0CLR = _IFS0_T2IF_MASK;
}
Within the main() function a while(1) loop continuously looks for the TickFlag to go true. When a TRUE flag is detected a measurement is taken on a specific measurement channel and after 167 samples have been collected (167 samples equals 1 cycle of the 60 Hz AC waveform) the RMS value is calculated using the following equation.
166
0
2)(1
i
iIxN
Irms
The measurement process starts with measurement channel 0 (as defined by the ChannelIndex variable) by making a call to the ReadCurrent() function at the beginning of a second (as defined by the SecondFlag) and proceeds through all 32 channels. A code snippet from main() that implements this functionality is shown below. //
// Main application entry point.
//
void main(void)
{
...
while(1)
{
//The TickFlag is set every time the 99.8 usec interrupt from timer2 fires
if(TickFlag == TRUE)
{
//The ChannelIndex variable is set to 0 at the top of each second
if(ChannelIndex < 32)
{
//Sample the given channel current measurements for one cycle of the
//60 Hz cycle (167 * 99.8 usec is one cycle)
ChannelCurrentData[ChannelDataIndex++] = ReadCurrent(ChannelIndex);
if(ChannelDataIndex >= 167)
{
//We have a full cycle of data in memory so calculate the RMS value
//Tests show this calculation takes about 330 usec
ChannelSquareSum = 0;
//First calculate the sum of the square
for(i=0;i<167;i++)
ChannelSquareSum += pow(ChannelCurrentData[i],2);
//Now calculate the RMS current
ChannelRMSCurrent[ChannelIndex] = sqrt(ChannelSquareSum/167);
ChannelIndex++; //Advance to the next channel
ChannelDataIndex = 0;
}
}
TickFlag = FALSE;
}
//Do the one second tasks
if((SecondFlag == TRUE))
{
//Since it is the top of the second we start a data collection
ChannelIndex = 0;
ChannelDataIndex = 0;
SecondFlag = FALSE;
...
} //if((SecondFlag == TRUE))
EMS Interface Board Schematic
EMS Max32 Board Schematic
EMS Interconnect