-
Notifications
You must be signed in to change notification settings - Fork 0
/
ethernetPins.ino
257 lines (232 loc) · 6.33 KB
/
ethernetPins.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
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
// Include libraries
#include <EtherCard.h>
// ethernet interface ip address
static byte myip[] = { 192,168,5,20 };
// gateway ip address
static byte gwip[] = { 192,168,5,1 };
// ethernet mac address - must be unique on your network
static byte mymac[] = { 0x74, 0x69, 0x69, 0x2D, 0x30, 0x31 };
// tcp/ip send and receive buffer
byte Ethernet::buffer[500];
static BufferFiller bfill;
/*
* Pin configuration
* Array uses key for pin number and value for mode, modify to suit your app
*/
int pins[14] = {
OUTPUT, // pin 0 RX
OUTPUT, // pin 1 TX
OUTPUT, // pin 2
OUTPUT, // pin 3 PWM
OUTPUT, // pin 4
OUTPUT, // pin 5 PWM
OUTPUT, // pin 6 PWM
OUTPUT, // pin 7
OUTPUT, // pin 8
OUTPUT, // pin 9 PWM
OUTPUT, // pin 10 PWM
OUTPUT, // pin 11 PWM
OUTPUT, // pin 12
OUTPUT, // pin 13
};
void setup() {
Serial.begin(57600);
Serial.println("[ethernetPins running]");
if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
Serial.println( "Failed to access Ethernet controller");
// setup lan
ether.staticSetup(myip, gwip);
ether.printIp("IP: ", ether.myip);
ether.printIp("GW: ", ether.gwip);
ether.printIp("DNS: ", ether.dnsip);
for (int i = 0; i < sizeof(pins) -1; i++) {
// initialize only non-reserved pins
if (!isReserved(i)) {
pinMode(i, pins[i]);
}
}
}
void loop() {
word pos = ether.packetLoop(ether.packetReceive());
// check if valid tcp data is received
if (pos) {
bfill = ether.tcpOffset();
char* data = (char *) Ethernet::buffer + pos;
// receive buf hasn't been clobbered by reply yet
if (strncmp("GET / ", data, 6) == 0) {
homePage(bfill, data);
}
else if (strncmp("GET /sts ", data, 6) == 0) {
statusPage(bfill, data);
}
else if (strncmp("GET /cmd ", data, 6) == 0) {
postCmd(bfill, data);
}
else {
notFound(bfill, data);
}
// send web page data
ether.httpServerReply(bfill.position());
}
}
/*
* Callback functions
* Respond to a given path on the main app routing entry point
*/
static void homePage(BufferFiller& buf, const char* data) {
bfill.emit_p(PSTR(
"HTTP/1.0 301 Moved Permanently\r\n"
"Content-Type: text/html\r\n"
"Location: /sts\r\n"
"\r\n"
"<h1>Redirecting...</h1>"));
}
static void statusPage(BufferFiller& buf, const char* data) {
/*
* Currently accepting arguments:
* m - mode: 1 for digital pins, 0 for analog pins (A0 to A5)
* p - pin: pin number
*/
if (data[8] == '?') {
int mode = getArgumentValue(data, 9, "m");
int pin = getArgumentValue(data, 9, "p");
if (pin >= 0 && pin <= 13 && !isReserved(pin)) {
// digital pin status
if (mode == 1) {
if (pins[pin] == INPUT || (pins[pin] == OUTPUT && !isPwm(pin))) {
// digital pin set to INPUT or OUTPUT non-pwm
// send json response back to requester
provideFeedback(bfill, mode, pin, NULL);
}
else {
// pwm pins do not allow digitalRead()
badRequest(bfill);
}
}
}
else {
// pin doesn't exist or is reserved and can't be used
badRequest(bfill);
}
}
}
static void postCmd(BufferFiller& buf, const char* data) {
/*
* Currently accepting arguments:
* m - mode: 1 for digital, 0 for analog
* p - pin: pin number
* v - value: if mode is digital, 1 for high and 0 for low; if mode is analog, an int from 0 to 255.
*/
if (data[8] == '?') {
int mode = getArgumentValue(data, 9, "m");
int pin = getArgumentValue(data, 9, "p");
int value = getArgumentValue(data, 9, "v");
if (pin >= 0 && pin <= 13 && !isReserved(pin)) {
// digital command
if (mode == 1) {
if (value == 1) {
digitalWrite(pin, HIGH);
}
else if (value == 0) {
digitalWrite(pin, LOW);
}
else {
// ambiguous value for digital command
badRequest(bfill);
}
}
// analog command
else if (mode == 0){
// to control a pin in analog mode the value should be in range and the pin should support pwm
if (value >= 0 && value <= 255 && isPwm(pin)) {
analogWrite(pin, value);
}
else {
// either out of range value or pin isn't pwm
badRequest(bfill);
}
}
else {
// ambiguous mode
badRequest(bfill);
}
// send json response back to requester
provideFeedback(bfill, mode, pin, value);
}
else {
// pin doesn't exist or is reserved and can't be used
badRequest(bfill);
}
}
// missplaced query param (?)
else {
badRequest(bfill);
}
}
static void notFound(BufferFiller& buf, const char* data) {
bfill.emit_p(PSTR(
"HTTP/1.0 404 Not Found\r\n"
"Content-Type: text/html\r\n"
"\r\n"
"<h1>404 Not Found</h1>"));
}
static void badRequest(BufferFiller& buf) {
bfill.emit_p(PSTR(
"HTTP/1.0 400 Bad Request\r\n"
"Content-Type: text/html\r\n"
"\r\n"
"<h1>400 Bad Request</h1>"));
deliverResponse(bfill);
}
static void provideFeedback(BufferFiller& buf, int mode, int pin, int state) {
// digitalRead gets mad when used on a currently pwm'ed pin
switch (mode) {
case 1 :
state = digitalRead(pin);
break;
case 0 :
break;
}
// debugging prints
Serial.println(mode);
Serial.println(pin);
Serial.println(state);
bfill.emit_p(PSTR("{ \"pin\" : \"$D\", \"state\" : \"$D\" }"), pin, state);
deliverResponse(bfill);
}
static void deliverResponse(BufferFiller& buf) {
// send web page data
ether.httpServerReply(bfill.position());
}
/*
* Utility functions
* Helper functions to abstract logic
*/
static int getArgumentValue(const char* data, int offset, const char* key) {
char temp[10];
int value = -1;
if (ether.findKeyVal(data + offset, temp, sizeof temp, key) > 0) {
value = atoi(temp);
}
return value;
}
static bool isPwm(int pin) {
// pwm pins
int pwmPins[6] = {3, 5, 6, 9, 10, 11};
for (int i = 0; i < sizeof(pwmPins) -1; i++) {
if (pin == pwmPins[i]) {
return true;
}
}
return false;
}
static bool isReserved(int pin) {
// reserved for ethernet shield
int reservedPins[6] = {10, 11, 12};
for (int i = 0; i < sizeof(reservedPins) -1; i++) {
if (pin == reservedPins[i]) {
return true;
}
}
return false;
}