]> git.0d.be Git - PanikSwitch.git/blob - FINAL2013V2.ino
enable POST code
[PanikSwitch.git] / FINAL2013V2.ino
1 // Panik Web Form Demo
2
3
4
5 // define network constants
6 #define MAC_DAVID { 0x90, 0xA2, 0xDA, 0x0D, 0xF4, 0x63 }
7 #define MAC_PANIK { 0x90, 0xA2, 0xDA, 0x00, 0x9A, 0x94 }
8 #define MAC_PANIK2 { 0x90, 0xA2, 0xDA, 0x0E, 0xF3, 0x77 }
9 #define MAC_ADDRESS MAC_PANIK
10
11
12 // include Arduino libraries
13 #include <Wire.h>
14 #include <SPI.h>
15 #include <SD.h>
16 #include <Ethernet.h>
17
18 // include third party libraries
19 #include "WebServer.h"
20
21 // include in-house libs
22 #include "PanikSwitch.h"    // contains variable types for panik switch
23
24 // define SD and Ethernet select ports
25 #define  SD_SELECT            4
26 #define  ETHERNET_SELECT     10
27
28 // define machine variables
29 #define DEBOUNCE_TRESHOLD     10   // 10 milliseconds
30 #define ABORT_TRESHOLD     3000L   // 3 seconds
31 #define PULSE_TRESHOLD        50   // 50 milliseconds
32 #define BLINK_TRESHOLD       100   // 100 milliseconds
33
34 // output pins
35 #define RELAY_BUTTON_LEDS        5   // Button LED indicator
36 #define RELAY_GREEN_LEDS         6   // ``Non-Stop`` LED indicator
37 #define RELAY_RED_LEDS           8   // ``Studio 1`` LED indicator
38 #define RELAY_YELLOW_LEDS        7   // ``Studio 2`` LED indicator
39
40 #define RELAY_NONSTOP_OR_STUD    4   // Relay : Non-stop or Studio
41 #define RELAY_STUD1_OR_STUD2     9   // Relay : Studio 1 or Studio 2
42
43 // input pins
44 #define BUTTON1                  2   // ``Select`` button
45 #define BUTTON2                  3   // ``Confirm`` button
46 #define NONSTOP_VIA_STUD1       14   // is nonstop coming out of studio 1
47 #define NONSTOP_VIA_STUD2       15   // is nonstop coming out of studio 2
48
49
50
51 /* define an array with led pins,
52    indexes in that array correspond to the values of possible selections
53    i.e.: RELAY_GREEN_LEDS: nonstop, RELAY_RED_LEDS: studio1, RELAY_YELLOW_LEDS: studio2
54 */
55 const int ledsArray[] = { RELAY_GREEN_LEDS, RELAY_RED_LEDS, RELAY_YELLOW_LEDS };
56
57
58 /* activeSelection is the variable that holds the active output of the switch
59    it is declared as an attribute that keeps its value between arduino resets
60 */
61 switchSelection_t activeSelection __attribute__ ((section (".noinit")));
62
63 // variables and timers for blinking selection (selected but not confirmed)
64 switchSelection_t blinkingSelection = nonstop;
65 bool blinkingLedState = RELAY_STATE_CLOSED;
66 unsigned long blinkingStartTime = 0, blinkingAbortTime = 0;
67
68
69 // declaration of possible button states as enum type
70 typedef enum { nochange, pressed, released } buttonEvent_t;
71
72 // button event timers
73 unsigned long button1LastEventTime = 0, button2LastEventTime = 0;
74
75 // variables holding the state of each button
76 // these are used during the debouncing process
77 uint8_t button1State = LOW, button2State = LOW;
78
79 // variables holding the non-stop status from studios 1 & 2
80 bool nonstop_via_stud1, nonstop_via_stud2;
81
82 // declare functions
83 buttonEvent_t debounce( const uint8_t buttonPin,
84                         uint8_t *buttonState,
85                         unsigned long *buttonLastEventTime );
86
87 static uint8_t mac[] = MAC_ADDRESS;
88 #define PREFIX ""
89
90 // instanciate web server
91 WebServer webserver(PREFIX, 80);
92
93 #define NAMELEN 4
94 #define VALUELEN 4
95
96 typedef enum responseStatus { NO_POST, POST_OK, POST_ERROR };
97
98
99 // web resource
100 void webCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
101 {
102
103   server.httpSuccess("application/json");
104
105   if (type == WebServer::HEAD)
106     return;
107
108   responseStatus response_status = NO_POST;
109
110   if (type == WebServer::POST)
111   {
112     char name[NAMELEN];
113     int  name_len;
114     char value[VALUELEN];
115     int value_len;
116
117     response_status = POST_ERROR;
118
119     while (server.readPOSTparam(name, NAMELEN, value, VALUELEN))
120     {
121       if (strcmp(name, "s") == 0) {
122         digitalWrite(ledsArray[activeSelection], RELAY_STATE_CLOSED);
123         blinkingSelection = static_cast<switchSelection_t>(atoi(value));
124         activeSelection = static_cast<switchSelection_t>(atoi(value));
125         response_status = POST_OK;
126       }
127     }
128   }
129
130   server.println(F("{"));
131
132   server.print(" \"response\": ");
133   server.print(response_status);
134
135   server.print(",\n \"active\": ");
136   server.print(activeSelection);
137
138   server.print(",\n \"nonstop-via-stud1\": ");
139   server.print(nonstop_via_stud1);
140   server.print(",\n \"nonstop-via-stud2\": ");
141   server.println(nonstop_via_stud2);
142
143   server.println(F("}"));
144 }
145
146
147 // setup function
148 void setup()
149 {
150   // make sure that activeSelection holds something valid
151 //  if (!(activeSelection > nonstop) || !(activeSelection < _NbrSwitchSelections))
152 //    activeSelection = nonstop;
153   blinkingSelection = activeSelection = nonstop;
154
155   // open serial communication for debugging
156   Serial.begin(9600);
157   Serial.println(F("Startup"));
158
159   // disable SD and Ethernet ports before setup
160   pinMode(SD_SELECT, OUTPUT);
161   digitalWrite(SD_SELECT, HIGH);                  // disable SD card
162   pinMode(ETHERNET_SELECT, OUTPUT);
163   digitalWrite(ETHERNET_SELECT, HIGH);           // disable Ethernet
164
165   // start SPI (because Ethernet shield needs it)
166   SPI.begin();                                          // start SPI
167
168   // start Ethernet
169   if (!(Ethernet.begin(mac) == 0))                    // start network
170     Serial.println(Ethernet.localIP());
171   else
172   {
173     Serial.println(F("Network Error"));
174     while (1) ;
175   }
176
177   // set mode for used pins
178   pinMode(RELAY_RED_LEDS, OUTPUT);
179   digitalWrite(RELAY_RED_LEDS, RELAY_STATE_CLOSED);
180   pinMode(RELAY_YELLOW_LEDS, OUTPUT);
181   digitalWrite(RELAY_YELLOW_LEDS, RELAY_STATE_CLOSED);
182   pinMode(RELAY_GREEN_LEDS, OUTPUT);
183   digitalWrite(RELAY_GREEN_LEDS, RELAY_STATE_CLOSED);
184   pinMode(RELAY_BUTTON_LEDS, OUTPUT);
185   digitalWrite(RELAY_BUTTON_LEDS, RELAY_STATE_CLOSED);
186
187   pinMode(RELAY_NONSTOP_OR_STUD, OUTPUT);
188   digitalWrite(RELAY_NONSTOP_OR_STUD, RELAY_STATE_CLOSED);
189   pinMode(RELAY_STUD1_OR_STUD2, OUTPUT);
190   digitalWrite(RELAY_STUD1_OR_STUD2, RELAY_STATE_CLOSED);
191
192   pinMode(BUTTON1, INPUT);
193   pinMode(BUTTON2, INPUT);
194   pinMode(NONSTOP_VIA_STUD1, INPUT);
195   pinMode(NONSTOP_VIA_STUD2, INPUT);
196
197   // configure web server pages
198   webserver.setDefaultCommand(&webCmd);
199
200   // start web server
201   webserver.begin();
202 }
203
204
205 // loop function
206 void loop()
207 {
208   // update variables indicating if non-stop is selected in studios 1&2
209   nonstop_via_stud1 = digitalRead(NONSTOP_VIA_STUD1);
210   if (nonstop_via_stud1 == 0)
211     nonstop_via_stud1 = 1;
212   else
213     nonstop_via_stud1 = 0;
214   nonstop_via_stud2 = digitalRead(NONSTOP_VIA_STUD2);
215   if (nonstop_via_stud2 == 0)
216     nonstop_via_stud2 = 1;
217   else
218     nonstop_via_stud2 = 0;
219
220   // check if we have a HTTP request (and respond)
221   webserver.processConnection();
222
223   // handle button 1 (select button)
224   switch ( debounce(BUTTON1, &button1State, &button1LastEventTime) )
225   {
226     case nochange:
227       break;
228     case pressed:
229       //Serial.println(F("Button 1 pressed"));
230       digitalWrite(ledsArray[blinkingSelection], RELAY_STATE_CLOSED);
231       blinkingSelection++;
232       blinkingStartTime = millis(),
233       blinkingAbortTime = millis();
234       blinkingLedState = RELAY_STATE_OPEN;
235       break;
236     case released:
237       //Serial.println(F("Button 1 released"));
238       break;
239   }
240
241   // handle button 2 (confirm button)
242   switch ( debounce(BUTTON2, &button2State, &button2LastEventTime) )
243   {
244     case nochange:
245       break;
246     case pressed:
247       //Serial.println(F("Button 2 pressed"));
248       blinkingAbortTime = 0;        // disable blinking auto abort
249       break;
250     case released:
251       //Serial.println(F("Button 2 released"));
252       if (activeSelection != blinkingSelection)
253       {
254         digitalWrite(ledsArray[activeSelection], RELAY_STATE_CLOSED);
255         activeSelection = blinkingSelection;  // relay states must be changed now
256         Serial.print(F("Active Selection: "));
257         Serial.println(activeSelection);
258         break;
259       }
260   }
261
262   // handle auto abort for blinking led (if any)
263   if ( (blinkingAbortTime != 0) &&
264        ((millis() - blinkingAbortTime) >= ABORT_TRESHOLD) ) {
265     digitalWrite(ledsArray[blinkingSelection], RELAY_STATE_CLOSED);
266     blinkingAbortTime = 0;
267     blinkingSelection = activeSelection;
268   }
269
270   // handle blinking led (if selected is not current state)
271   if (activeSelection != blinkingSelection) {
272     if ((millis() - blinkingStartTime) >= BLINK_TRESHOLD) {
273       digitalWrite(ledsArray[blinkingSelection], blinkingLedState);
274       digitalWrite(RELAY_BUTTON_LEDS, !blinkingLedState);
275       blinkingStartTime = millis();
276       blinkingLedState = !blinkingLedState;
277     }
278   }
279   else {
280     digitalWrite(RELAY_BUTTON_LEDS, RELAY_STATE_CLOSED);
281   }
282
283   digitalWrite(ledsArray[activeSelection], RELAY_STATE_OPEN);
284
285   // update audio channel relays
286   if (activeSelection == nonstop)
287   {
288     digitalWrite(RELAY_NONSTOP_OR_STUD, RELAY_STATE_CLOSED);
289     digitalWrite(RELAY_STUD1_OR_STUD2, RELAY_STATE_CLOSED);
290   }
291   else if (activeSelection == studio1)
292   {
293     digitalWrite(RELAY_NONSTOP_OR_STUD, RELAY_STATE_OPEN);
294     digitalWrite(RELAY_STUD1_OR_STUD2, RELAY_STATE_CLOSED);
295   }
296   else if (activeSelection == studio2)
297   {
298     digitalWrite(RELAY_NONSTOP_OR_STUD, RELAY_STATE_OPEN);
299     digitalWrite(RELAY_STUD1_OR_STUD2, RELAY_STATE_OPEN);
300   }
301 }
302
303 buttonEvent_t debounce( const uint8_t buttonPin,
304                         uint8_t *buttonState,
305                         unsigned long *buttonLastEventTime )
306 {
307   uint8_t buttonLastState = *buttonState;
308   uint8_t buttonReading = digitalRead(buttonPin);
309
310   if ( (*buttonLastEventTime == 0) &&
311        (*buttonState != buttonReading) ) {
312     // something happened, start the debouncing process
313     *buttonLastEventTime = millis();
314   }
315
316   if (*buttonLastEventTime != 0) {
317     long buttonEventTimer = millis() - *buttonLastEventTime;
318
319     if ( (buttonEventTimer < DEBOUNCE_TRESHOLD) &&
320          (*buttonState == buttonReading) ) {
321       // noise or bouncing, abort
322       *buttonLastEventTime = 0;
323     }
324
325     if ( (buttonEventTimer >= DEBOUNCE_TRESHOLD) &&
326          (buttonReading != *buttonState) ) {
327       // new button state was maintained
328       *buttonLastEventTime = 0;
329       *buttonState = buttonReading;
330     }
331   }
332
333   // debouncing finished, return button state
334   if (*buttonLastEventTime == 0) {
335     // comparing buttonState and buttonLastState tells whether the
336     // button is pressed or released
337     if ( (*buttonState == HIGH) &&
338          (buttonLastState == LOW) ) {
339       // button just pressed
340       buttonLastState = *buttonState;
341       return pressed;
342     }
343     if ( (*buttonState == LOW) &&
344          (buttonLastState == HIGH) ) {
345       // button just released
346       buttonLastState = *buttonState;
347       return released;
348     }
349   }
350   return nochange;
351 }
352