-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrfm69-sp-ctrl.cc
247 lines (224 loc) · 7.13 KB
/
rfm69-sp-ctrl.cc
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
#include <RFM69.h>
#include <SPI.h>
#include <NodeMsg.h>
#include <NodeConf.h>
#include <EEPROM.h>
// REFERENCES
RFM69 radio;
// FUNCTIONS - Local
void Blink(byte PIN, int DELAY_MS);
void setZone();
void disableAllZones();
//void setZoneStatus();
void sendZoneStatus();
// GLOBAL Variables
unsigned int zoneSprinkleTimeSeconds = 0;
bool zoneActive = false;
//byte activeZone = 0; // current zone
byte ackCount=0;
bool timerActive = false;
int lastPeriod = -1;
bool promiscuousMode = false; //set to 'true' to sniff all packets on the same network
float b;
// SETUP...
void setup() {
/*---------------------------------------------------------------------------------
| System Setup
|
|
*/
Serial.begin(SERIAL_BAUD);
delay(10);
radio.initialize(FREQUENCY,NODEID,NETWORKID);
//radio.setHighPower(); //uncomment only for RFM69HW!
radio.encrypt(KEY);
radio.promiscuous(promiscuousMode);
// Print Radio Config...
char buff[50];
sprintf(buff, "\nListening at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
Serial.println(buff);
// Configure all zone IO as Outputs
for (int x = 0; x < sizeof(zoneList); x++) {
// set IO Zones to digital outputs.
// Set inital state of OFF
pinMode(zoneList[x], OUTPUT);
digitalWrite(zoneList[x], LOW);
}
}
// EXECUTION Loop
void loop() {
/*---------------------------------------------------------------------------------
| Execution Loop
|
|
*/
if (radio.receiveDone()) {
Serial.print('[');Serial.print(radio.SENDERID, DEC);Serial.print("] ");
Serial.print(" [RX_RSSI:");Serial.print(radio.readRSSI());Serial.print("]");
if (promiscuousMode) {
Serial.print("to [");Serial.print(radio.TARGETID, DEC);Serial.print("] ");
}
if (radio.DATALEN != sizeof(Payload))
Serial.print("Invalid payload received, not matching Payload struct!");
else
{
// Get the date
theData = *(Payload*)radio.DATA; //assume radio.DATA actually contains our struct and not something else
Serial.print(" S=");
Serial.print(radio.SENDERID);
Serial.print(" T=");
Serial.println(radio.TARGETID);
Serial.print(" msgID=");
Serial.print(theData.msgID);
Serial.print(" pkgType=");
Serial.print(theData.pkgType);
Serial.print(" Size=");
Serial.println(radio.DATALEN);
Serial.println("Package Info..... ");
// Find method to process based on package type
switch(theData.pkgType) {
case spklZone:
switch(theData.msgMethod) {
case SET:
Serial.println("--- Executing Sprinkle Zone SET Method \n");
setZone();
break;
case STATUS:
Serial.println("\n--- Executing Sprinkle Zone STATUS Method \n");
// return the zone status to the requestor....
sendZoneStatus();
break;
default:
Serial.println(" Method is not supported ... ");
}
break;
default:
Serial.println(" No Function defined... ");
}
}
if (radio.ACK_REQUESTED)
{
byte theNodeID = radio.SENDERID;
radio.sendACK();
Serial.print(" - ACK sent.");
// When a node requests an ACK, respond to the ACK
// and also send a packet requesting an ACK (every 3rd one only)
// This way both TX/RX NODE functions are tested on 1 end at the GATEWAY
if (ackCount++ %3 == 0)
{
Serial.print(" Pinging node ");
Serial.print(theNodeID);
Serial.print(" - ACK...");
delay(3); //need this when sending right after reception .. ?
if (radio.sendWithRetry(theNodeID, "ACK TEST", 8, 0)) // 0 = only 1 attempt, no retries
Serial.print("ok!");
else Serial.print("nothing");
}
}
Serial.println();
Blink(LED,3);
}
/*---------------------------------------------------------------------------------
| Watchdog timer
| 1. check run cycle every 10 seconds
| 2. Verify sprinkle time is not over run time MAX
*/
// Watchdog Timer
// Execute an action every 10 seconds...
if (millis() % WATCHDOG_DEFAULT == 0) { // Defined NodeMsg.h
if (! timerActive) {
Serial.print("Timer Active, State: ");
Serial.println(spklZonePkg.zoneState);
if (spklZonePkg.zoneState == 1) {
// Increment Sprinkle timer
Serial.println("Execute WatchDog ");
spklZonePkg.activeCycleTime ++;
if (spklZonePkg.activeCycleTime >= spklZonePkg.zoneCycleTime) {
// Zone time complete.
// Disable and reset zone
spklZonePkg.zoneState = 3;
disableAllZones();
}
//float a = (float)spklZonePkg.activeCycleTime;
b = (float)spklZonePkg.zoneCycleTime;
spklZonePkg.percentComplete = 100 * (spklZonePkg.activeCycleTime / b);
Serial.print("% Complete: ");
Serial.println(spklZonePkg.percentComplete);
}
timerActive = true;
}
} else {
// handle debounce
timerActive = false;
}
/*
int currPeriod = millis()/EVENTPERIOD;
if (currPeriod != lastPeriod) {
// Real time timer
disableAllZones();
lastPeriod = currPeriod;
}
*/
}
/// END EXECUTION LOOP
void Blink(byte PIN, int DELAY_MS) {
pinMode(PIN, OUTPUT);
digitalWrite(PIN,HIGH);
delay(DELAY_MS);
digitalWrite(PIN,LOW);
}
//void setZone(spklZonePkg& pkg) {
void setZone() {
// Process recieved Zone instruction
// CAST to package type
spklZonePkg = *(_spklZone*)theData.pkg; // Cast package as zone structure
Serial.print(" zoneNumber =");
Serial.println(spklZonePkg.zoneNumber);
Serial.print(" dataDirection =");
Serial.println(spklZonePkg.dataDirection);
Serial.print(" zoneState =");
Serial.println(spklZonePkg.zoneState);
Serial.print(" totalSprinkleTime =");
Serial.println(spklZonePkg.zoneCycleTime);
Serial.print(" activeSprinkleTime =");
Serial.println(spklZonePkg.activeCycleTime);
Serial.print(" percentComplete =");
Serial.println(spklZonePkg.percentComplete);
Serial.print(" pauseTime =");
Serial.println(spklZonePkg.pauseTime);
/*
if (spklZonePkg.zoneNumber == 3) {
// Flip outout
digitalWrite(6, ! digitalRead(6));
}
*/
// Enable Requested Zone.
//activeZone = spklZonePkg.zoneNumber;
//zoneActive = true;
disableAllZones();
digitalWrite(zoneList[spklZonePkg.zoneNumber], HIGH);
}
void sendMsg() {
}
void sendZoneStatus() {
/*---------------------------------------------------------------------------------
| sendZoneStatus -
| Send last note status state to the calling application.
|
|
*/
radio.sendACK();
theData.msgID = millis(); // Suggest changing method to return original msgID
theData.pkgType = spklZone;
theData.msgMethod = STATUS;
memcpy(theData.pkg, &spklZonePkg, sizeof(spklZonePkg));
if (radio.sendWithRetry(GATEWAYID, (const void*)(&theData), sizeof(theData))) // 0 = only 1 attempt, no retries
Serial.print("ok!");
else Serial.print("nothing");
}
void disableAllZones(){
// Turn all zones off
for (int x = 0; x < sizeof(zoneList); x++) {
digitalWrite(zoneList[x], LOW);
}
}