-
Notifications
You must be signed in to change notification settings - Fork 49
/
Copy pathHomeEnergyMonitor.ino
169 lines (137 loc) · 7.01 KB
/
HomeEnergyMonitor.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
//------------------------------------------------------------------------------------------------------------------------------------------------
// emonGLCD Home Energy Monitor example
// to be used with nanode Home Energy Monitor example
// Uses power1 variable - change as required if your using different ports
// emonGLCD documentation http://openEnergyMonitor.org/emon/emonglcd
// RTC to reset Kwh counters at midnight is implemented is software.
// Correct time is updated via NanodeRF which gets time from internet
// Temperature recorded on the emonglcd is also sent to the NanodeRF for online graphing
// GLCD library by Jean-Claude Wippler: JeeLabs.org
// 2010-05-28 <jcw@equi4.com> http://opensource.org/licenses/mit-license.php
//
// Authors: Glyn Hudson and Trystan Lea
// Part of the: openenergymonitor.org project
// Licenced under GNU GPL V3
// http://openenergymonitor.org/emon/license
// THIS SKETCH REQUIRES:
// Libraries in the standard arduino libraries folder:
//
// - OneWire library http://www.pjrc.com/teensy/td_libs_OneWire.html
// - DallasTemperature http://download.milesburton.com/Arduino/MaximTemperature
// or https://github.com/milesburton/Arduino-Temperature-Control-Library
// - JeeLib https://github.com/jcw/jeelib
// - RTClib https://github.com/adafruit/RTClib
// - GLCD_ST7565 https://github.com/openenergymonitor/glcdlib
//
// Other files in project directory (should appear in the arduino tabs above)
// - icons.ino
// - templates.ino
//
//-------------------------------------------------------------------------------------------------------------------------------------------------
#define RF69_COMPAT 1 // set to 1 to use RFM69CW
#include <JeeLib.h> // make sure V12 (latest) is used if using RFM69CW
#include <GLCD_ST7565.h>
#include <avr/pgmspace.h>
GLCD_ST7565 glcd;
#include <OneWire.h> // http://www.pjrc.com/teensy/td_libs_OneWire.html
#include <DallasTemperature.h> // http://download.milesburton.com/Arduino/MaximTemperature/ (3.7.2 Beta needed for Arduino 1.0)
#include <RTClib.h> // Real time clock (RTC) - used for software RTC to reset kWh counters at midnight
#include <Wire.h> // Part of Arduino libraries - needed for RTClib
RTC_Millis RTC;
//--------------------------------------------------------------------------------------------
// RFM12B Settings
//--------------------------------------------------------------------------------------------
#define MYNODE 20 // Should be unique on network, node ID 30 reserved for base station
#define RF_freq RF12_433MHZ // frequency - match to same frequency as RFM12B module (change to 868Mhz or 915Mhz if appropriate)
#define group 210
#define ONE_WIRE_BUS 5 // temperature sensor connection - hard wired
unsigned long fast_update, slow_update;
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
double temp,maxtemp,mintemp;
//---------------------------------------------------
// Data structures for transfering data between units
//---------------------------------------------------
typedef struct { int power1, power2, power3, Vrms; } PayloadTX; // neat way of packaging data for RF comms
PayloadTX emontx;
typedef struct { int temperature; } PayloadGLCD;
PayloadGLCD emonglcd;
int hour = 12, minute = 0;
double usekwh = 0;
const int greenLED=6; // Green tri-color LED
const int redLED=9; // Red tri-color LED
const int LDRpin=4; // analog pin of onboard lightsensor
int cval_use;
//--------------------------------------------------------------------------------------------
// Flow control
//--------------------------------------------------------------------------------------------
unsigned long last_emontx; // Used to count time from last emontx update
unsigned long last_emonbase; // Used to count time from last emontx update
//--------------------------------------------------------------------------------------------
// Setup
//--------------------------------------------------------------------------------------------
void setup()
{
delay(500); //wait for power to settle before firing up the RF
rf12_initialize(MYNODE, RF_freq,group);
delay(100); //wait for RF to settle befor turning on display
glcd.begin(0x19);
glcd.backLight(200);
sensors.begin(); // start up the DS18B20 temp sensor onboard
sensors.requestTemperatures();
temp = (sensors.getTempCByIndex(0)); // get inital temperture reading
mintemp = temp; maxtemp = temp; // reset min and max
pinMode(greenLED, OUTPUT);
pinMode(redLED, OUTPUT);
}
//--------------------------------------------------------------------------------------------
// Loop
//--------------------------------------------------------------------------------------------
void loop()
{
if (rf12_recvDone())
{
if (rf12_crc == 0 && (rf12_hdr & RF12_HDR_CTL) == 0) // and no rf errors
{
int node_id = (rf12_hdr & 0x1F);
if (node_id == 10) {emontx = *(PayloadTX*) rf12_data; last_emontx = millis();} //Assuming 10 is the emonTx NodeID
if (node_id == 15) //Assuming 15 is the emonBase node ID
{
RTC.adjust(DateTime(2012, 1, 1, rf12_data[1], rf12_data[2], rf12_data[3]));
last_emonbase = millis();
}
}
}
//--------------------------------------------------------------------------------------------
// Display update every 200ms
//--------------------------------------------------------------------------------------------
if ((millis()-fast_update)>200)
{
fast_update = millis();
DateTime now = RTC.now();
int last_hour = hour;
hour = now.hour();
minute = now.minute();
usekwh += (emontx.power1 * 0.2) / 3600000;
if (last_hour == 23 && hour == 00) usekwh = 0; //reset Kwh/d counter at midnight
cval_use = cval_use + (emontx.power1 - cval_use)*0.50; //smooth transitions
draw_power_page( "POWER" ,cval_use, "USE", usekwh);
draw_temperature_time_footer(temp, mintemp, maxtemp, hour,minute);
glcd.refresh();
int LDR = analogRead(LDRpin); // Read the LDR Value so we can work out the light level in the room.
int LDRbacklight = map(LDR, 0, 1023, 50, 250); // Map the data from the LDR from 0-1023 (Max seen 1000) to var GLCDbrightness min/max
LDRbacklight = constrain(LDRbacklight, 0, 255); // Constrain the value to make sure its a PWM value 0-255
if ((hour > 22) || (hour < 5)) glcd.backLight(0); else glcd.backLight(LDRbacklight);
}
if ((millis()-slow_update)>10000)
{
slow_update = millis();
sensors.requestTemperatures();
temp = (sensors.getTempCByIndex(0));
if (temp > maxtemp) maxtemp = temp;
if (temp < mintemp) mintemp = temp;
emonglcd.temperature = (int) (temp * 100); // set emonglcd payload
rf12_sendNow(0, &emonglcd, sizeof emonglcd); //send temperature data via RFM12B using new rf12_sendNow wrapper -glynhudson
rf12_sendWait(2);
}
}