/
OKG_RN-XV
283 lines (244 loc) · 7.92 KB
/
OKG_RN-XV
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
/* Credits:
Based on the work of the openenergymonitor.org project
Licence: GNU GPL V3 Authors: Trystan Lea and Glyn Hudson
https://github.com/openenergymonitor/Open-Kontrol-Gateway/blob/master/OKG_RN_XV_Wifi_RFM12B_emoncms/OKG_RN_XV_Wifi_RFM12B_emoncms.ino
Based on Arduino DNS and DHCP-based Web client by David A. Mellis
modified 12 April 2011by Tom Igoe, based on work by Adrian McEwen
Uses Jeelabs.org JeeLib library for RFM12B
*/
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#undef PROGMEM
#define PROGMEM __attribute__(( section(".progmem.data") ))
#undef PSTR
#define PSTR(s) (__extension__({static prog_char __c[] PROGMEM = (s); &__c[0];}))
#include <WiFlyHQ.h>
#include <JeeLib.h>
#include <SoftwareSerial.h>
SoftwareSerial ftdiSerial(5,6);
//#define SERIALPRINT // include print statement for commissioning - comment this line to exclude
// RFM12B Wireless Config
#define MYNODE 17 // node ID of OKG (Change in print statement below also!)
#define freq RF12_433MHZ // frequency - must match RFM12B module and emonTx
#define group 220 // network group - must match emonTx (Change in print statement below also!)
// RN-XV wifi Config & MyPowerBase
WiFly wifly;
/* Change these to match your WiFi network */
const char mySSID[] = "SSID";
const char myPassword[] = "PASSWD";
char apiurl[] = "http://powermeter.ie/mypowerbase/api/post.json?apikey&json=";
const char site[] = "powermeter.ie";
void terminal();
void print_P(const prog_char *str);
void println_P(const prog_char *str);
// Open Kontrol Gateway Config
const int LEDpin=17; //front status LED on OKG
// The PacketBuffer class is used to generate the json string that is send via ethernet - JeeLabs
class PacketBuffer : public Print {
public:
PacketBuffer () : fill (0) {}
const char* buffer() { return buf; }
byte length() { return fill; }
void reset()
{
memset(buf,NULL,sizeof(buf));
fill = 0;
}
virtual size_t write (uint8_t ch)
{ if (fill < sizeof buf) buf[fill++] = ch; }
byte fill;
char buf[150];
private:
};
PacketBuffer str;
int data_ready, rf_error;
unsigned long last_rf, reboot_timer;
int resetCounter, reboot_count = 0;
// SETUP
void setup() {
char buf[32];
ftdiSerial.begin(9600);
#ifdef SERIALPRINT
println_P(PSTR("Starting-ID 17:Net Grp 210"));
print_P(PSTR("Free memory: "));
ftdiSerial.println(wifly.getFreeMemory(),DEC);
#endif
pinMode(LEDpin, OUTPUT);
digitalWrite(LEDpin,HIGH);
rf12_set_cs(9); //RFM12B CS connnected to Dig 9 on OKG - change to 10 for JeeNode/emonTx ...
rf12_initialize(MYNODE, freq,group);
last_rf = millis()-40000; // setting lastRF back 40s is useful as it forces the ethernet code to run straight away
Serial.begin(9600);
if (!wifly.begin(&Serial, &ftdiSerial)) {
#ifdef SERIALPRINT
println_P(PSTR("Failed to start wifly"));
#endif
wifly.reboot();
terminal();
}
/* Join wifi network if not already associated */
if (!wifly.isAssociated()) {
/* Setup the WiFly to connect to a wifi network */
#ifdef SERIALPRINT
println_P(PSTR("Joining network"));
#endif
wifly.setSSID(mySSID);
wifly.setPassphrase(myPassword);
wifly.enableDHCP();
if (wifly.join()) {
#ifdef SERIALPRINT
println_P(PSTR("Joined wifi network"));
#endif
} else {
#ifdef SERIALPRINT
println_P(PSTR("Failed to join wifi network"));
#endif
terminal();
}
} else {
#ifdef SERIALPRINT
println_P(PSTR("Already joined network"));
#endif
}
//terminal();
#ifdef SERIALPRINT
print_P(PSTR("MAC: "));
ftdiSerial.println(wifly.getMAC(buf, sizeof(buf)));
print_P(PSTR("IP: "));
ftdiSerial.println(wifly.getIP(buf, sizeof(buf)));
print_P(PSTR("Netmask: "));
ftdiSerial.println(wifly.getNetmask(buf, sizeof(buf)));
print_P(PSTR("Gateway: "));
ftdiSerial.println(wifly.getGateway(buf, sizeof(buf)));
print_P(PSTR("SSID: "));
ftdiSerial.println(wifly.getSSID(buf, sizeof(buf)));
#endif
wifly.setDeviceID("Wifly-WebClient");
#ifdef SERIALPRINT
print_P(PSTR("DeviceID: "));
ftdiSerial.println(wifly.getDeviceID(buf, sizeof(buf)));
#endif
if (wifly.isConnected()) {
#ifdef SERIALPRINT
println_P(PSTR("Old connection active. Closing"));
#endif
wifly.close();
}
if (wifly.open(site, 80)) {
#ifdef SERIALPRINT
print_P(PSTR("Connected to "));
ftdiSerial.println(site);
#endif
}
/* Send the request */
//wifly.println("GET / HTTP/1.0");
//wifly.println();
/*} else {
#ifdef SERIALPRINT
println_P(PSTR("Failed to connect"));
#endif
}*/
wdt_enable(WDTO_8S); //enable an 8's reset watchdog
}
void loop() {
// 1) Receive date from emonTx via RFM12B
wdt_reset();
reboot_count = millis();
if (rf12_recvDone()){
if (rf12_crc == 0 && (rf12_hdr & RF12_HDR_CTL) == 0)
{
digitalWrite(LEDpin,HIGH);
int node_id = (rf12_hdr & 0x1F);
byte n = rf12_len;
str.reset();
str.print("{&node="); str.print(node_id);
str.print("&csv=");
for (byte i=0; i<n; i+=2)
{
int num = ((unsigned char)rf12_data[i+1] << 8 | (unsigned char)rf12_data[i]);
if (i) str.print(",");
str.print(num);
}
data_ready = 1;
last_rf = millis();
//ftdiSerial.println("rf12_recvDone");
rf_error=0;
}
}
// 2) If no data is recieved from rf12 emoncms is updated every 30s with RFfail = 1 indicator for debugging
if ((millis()-reboot_timer)>600000)
{
reboot_timer = millis(); // reset reboot timer
str.reset(); // reset json string
str.print("{reboot:");
str.println(reboot_count);
reboot_count++;
data_ready = 1; // Ok, data is ready
delay(10000);
}
// 3) Post Data
if (data_ready)
{
if (wifly.isConnected()) {
#ifdef SERIALPRINT
ftdiSerial.println("Old connection active. Closing....");
#endif
wifly.close();
}
if (wifly.open(site, 80)) {
/* Send the request */
str.print("}\0");
#ifdef SERIALPRINT
ftdiSerial.print("Connected to ");
ftdiSerial.println(site);
ftdiSerial.print("Free memory: ");
ftdiSerial.println(wifly.getFreeMemory(),DEC);
ftdiSerial.print("Sent: "); ftdiSerial.println(str.buf);
#endif
resetCounter ++;
wifly.print("GET "); wifly.print(apiurl); wifly.print(str.buf);
wifly.println();
}
} else { ; }
data_ready=0;
digitalWrite(LEDpin,LOW); // turn off status LED to indicate succesful data receive and online posting
delay (300);
if (resetCounter > 10) {delay(10000);}
// 4) Read Reply
if (wifly.available() > 0) {
char ch = wifly.read();
ftdiSerial.write(ch);
if (ch == '\n') {
/* add a carriage return */
ftdiSerial.write('\r');
}
}
if (ftdiSerial.available() > 0) {
wifly.write(ftdiSerial.read());
}
}//end loop
/* Connect the WiFly serial to the serial monitor. */
void terminal()
{
while (1) {
if (wifly.available() > 0) {
ftdiSerial.write(wifly.read());
}
if (ftdiSerial.available() > 0) {
wifly.write(ftdiSerial.read());
}
}
}
/* Print a string from program memory */
void print_P(const prog_char *str)
{
char ch;
while ((ch=pgm_read_byte(str++)) != 0) {
ftdiSerial.write(ch);
}
}
void println_P(const prog_char *str)
{
print_P(str);
ftdiSerial.println();
}