Skip to content

Commit 28c88b5

Browse files
committed
First commit
0 parents  commit 28c88b5

6 files changed

+1324
-0
lines changed

.gitattributes

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
* linguist-vendored
2+
*.ino linguist-vendored=false

LICENSE.txt

+674
Large diffs are not rendered by default.

README.md

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
## An example implementation of a web interface for an Arduino Nano 33 IoT using a websocket (AP version)
2+
3+
This web interface communicates with the Arduino using a websocket on port 8080.
4+
5+
The Arduino serves as both a web server and a websocket server.
6+
7+
The Arduino is set up as a WiFi Access Point; you need to connect to its Access Point before you try to open the web interface page.
8+
9+
### Libraries used:
10+
11+
- https://github.com/ocrdu/WiFiNINA for WiFi connection and servers (**Don't** use https://github.com/arduino-libraries/WiFiNINA 1.4.0 for this sketch)
12+
- https://github.com/ocrdu/NINA-Websocket as the websocket library (Minor change from https://github.com/morrissinger/ESP8266-Websocket);
13+
- https://github.com/ocrdu/Arduino_LSM6DS3_T as the LSM6DS3 (IMU) library (Adds code for LSM6DS3 internal temperature sensor to https://github.com/arduino-libraries/Arduino_LSM6DS3);
14+
- https://github.com/adamvr/arduino-base64 for base64 decoding;
15+
- https://github.com/arduino-libraries/RTCZero as the Real Time Clock library.
16+
17+
### Notes:
18+
19+
There is no documentation yet, but the least you need to do to get it to work is this:
20+
21+
- Edit the wifi_secrets.h to the SSID and password you want to use for the Arduino's WiFi Access Point
22+
23+
This example will then show the interface in your web browser when you point it at the Arduino's IP address http://192.168.2.1/ .
24+
25+
Almost forgot: if you want to see something happen, put a LED on pin 12 😎.
26+
27+
If you feel like donating for this, you can do so here: http://ocrdu.nl/donations .

WebpageServedByArduino.html

+334
Large diffs are not rendered by default.

apwebsocketserver.ino

+285
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
#include <WiFiNINA.h>
2+
#include <WebSocketServer.h>
3+
#include <Arduino_LSM6DS3.h>
4+
#include <Base64.h>
5+
#include <RTCZero.h>
6+
#include "wifi_secrets.h"
7+
8+
#define DEBUG 1
9+
10+
#ifdef DEBUG
11+
#define Sprint(a) (Serial.print(a))
12+
#define Sprintln(a) (Serial.println(a))
13+
#else
14+
#define Sprint(a)
15+
#define Sprintln(a)
16+
#endif
17+
18+
char ssid[] = SECRET_SSID;
19+
char pass[] = SECRET_PASS;
20+
IPAddress APIP(192, 168, 2, 1);
21+
int APStatus = WL_IDLE_STATUS;
22+
const int APChannel = 14;
23+
const int webPort = 80;
24+
const int socketPort = 8080;
25+
WiFiServer webServer(webPort);
26+
WiFiServer socketServer(socketPort);
27+
WebSocketServer webSocketServer;
28+
WiFiClient socketClient;
29+
RTCZero rtc;
30+
const int ledPin = 12;
31+
boolean on = false;
32+
float volume = 0;
33+
int cowbell = 1000;
34+
float zdata[] = {1,1,1,1,1};
35+
int zdatasize = sizeof(zdata) / sizeof(zdata[0]);
36+
float tdata[] = {20,20,20,20,20,20,20,20,20,20};
37+
int tdatasize = sizeof(tdata) / sizeof(tdata[0]);
38+
int ledState = 0;
39+
unsigned long epoch;
40+
unsigned long previousCowbellMillis = 0;
41+
unsigned long previousGravityMillis = 0;
42+
unsigned long previousTemperatureMillis = 0;
43+
char interface_gz_base64[] = "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";
44+
45+
void setup() {
46+
#ifdef DEBUG
47+
Serial.begin(115200);
48+
while (!Serial);
49+
#endif
50+
pinMode(LED_BUILTIN, OUTPUT);
51+
pinMode(ledPin, OUTPUT);
52+
rtc.begin();
53+
IMU.begin();
54+
WiFiConnect();
55+
}
56+
57+
void loop() {
58+
59+
if (APStatus != WiFi.status()) {
60+
APStatus = WiFi.status();
61+
if (APStatus == WL_AP_CONNECTED) {
62+
Sprintln("\n--A device connected to the AP");
63+
} else {
64+
Sprintln("\n--A device disconnected from the AP");
65+
}
66+
}
67+
68+
WiFiClient webClient = webServer.available();
69+
if (webClient.connected()) {
70+
Sprint("\n--New client: "); Sprint(webClient.remoteIP()); Sprint(":"); Sprintln(webClient.remotePort());
71+
String header = "";
72+
while (webClient.available()) {
73+
char c = webClient.read();
74+
if (c != '\r') {
75+
header += c;
76+
}
77+
if (header.indexOf("Upgrade") > -1 && header.indexOf("ebsocket") > -1) {
78+
Sprintln("--Websocket upgrade requested on webserver port");
79+
webClient.println("HTTP/1.1 400 Bad Request\nContent-Type: text/plain; charset=utf-8\n\n400 Bad Request; websocket not available on this port\n");
80+
webClient.stop();
81+
Sprintln("--Client disconnected");
82+
}
83+
if (header.substring(0,1) != "G" && header.substring(0,2) != "GE" && header.substring(0,3) != "GET") {
84+
Sprintln("--Wrong method in header");
85+
webClient.println("HTTP/1.1 405 Method Not Allowed\nAllow: GET\nContent-Type: text/plain; charset=utf-8\n\n405 Method not allowed; GET only\n");
86+
webClient.stop();
87+
Sprintln("--Client disconnected");
88+
}
89+
if (header.indexOf("event-stream") > -1) {
90+
Sprintln("--SSE content type request in header");
91+
webClient.println("HTTP/1.1 406 Not Acceptable\nContent-Type: text/plain; charset=utf-8\n\n406 Not Acceptable; SSE not available\n");
92+
webClient.stop();
93+
Sprintln("--Client disconnected");
94+
}
95+
if (header.length() > 512) {
96+
Sprintln("--Header too long");
97+
webClient.println("HTTP/1.1 431 Request Header Fields Too Large\nContent-Type: text/plain; charset=utf-8\n\n431 Request header fields too large\n");
98+
webClient.stop();
99+
Sprintln("--Client disconnected");
100+
}
101+
if (header.substring(header.length() - 2) == "\n\n") {
102+
Sprint(header.substring(0, header.length() - 1));
103+
if (header.indexOf("GET / HTTP") > -1) {
104+
sendBase64Page(interface_gz_base64, webClient, 1024);
105+
Sprintln("--Interface webpage sent");
106+
} else if (header.indexOf("GET /author HTTP") > -1) {
107+
webClient.println("HTTP/1.1 200 OK\nContent-Type: text/plain; charset=utf-8\n\nOscar den Uijl, [email protected]\n");
108+
Sprintln("--Email address sent");
109+
} else if (header.indexOf("GET /coffee HTTP") > -1) {
110+
webClient.println("HTTP/1.1 418 I'm a teapot\nContent-Type: text/plain; charset=utf-8\n\n418 I'm a teapot\n");
111+
Sprintln("--Coffee request denied");
112+
} else {
113+
webClient.println("HTTP/1.1 404 Not Found\nContent-Type: text/plain; charset=utf-8\n\n404 Not Found\n");
114+
Sprintln("--Page not found");
115+
}
116+
webClient.stop();
117+
Sprintln("--Client disconnected");
118+
}
119+
}
120+
}
121+
122+
if (!socketClient.connected()) {
123+
socketClient = socketServer.available();
124+
if (socketClient.connected() && webSocketServer.handshake(socketClient)) {
125+
Sprint("\n--Websocket connected to: "); Sprint(socketClient.remoteIP()); Sprint(":"); Sprintln(socketClient.remotePort());
126+
if (on) {
127+
webSocketServer.sendData("sw:true");
128+
} else {
129+
webSocketServer.sendData("sw:false");
130+
}
131+
webSocketServer.sendData("volume:" + (String)round((volume*100)/255));
132+
webSocketServer.sendData("cowbell:" + (String)((1000-cowbell)/10));
133+
Sprintln("--Settings sent");
134+
} else {
135+
//Sprintln("\n--Couldn't connect websocket");
136+
socketClient.stop();
137+
delay(100);
138+
}
139+
}
140+
141+
if (socketClient.connected()) {
142+
String data = webSocketServer.getData();
143+
if (data.length() > 0) {
144+
String name = data.substring(0, data.indexOf(":"));
145+
String value = data.substring(data.indexOf(":") + 1);
146+
boolean goodSettings = true;
147+
if (name == "switch") {
148+
on = (value == "true");
149+
} else if (name == "volume") {
150+
volume = (value.toFloat()*255)/100;
151+
if (cowbell == 1000) {
152+
analogWrite(ledPin, (int)round(volume));
153+
}
154+
} else if (name == "cowbell") {
155+
cowbell = 1000 - (value.toInt()*10);
156+
} else {
157+
goodSettings = false;
158+
webSocketServer.sendData("message:Bad data; ignored");
159+
}
160+
if (goodSettings) {
161+
webSocketServer.sendData("message:" + name + " set to " + value);
162+
}
163+
}
164+
}
165+
166+
unsigned long currentCowbellMillis = millis();
167+
if ((currentCowbellMillis - previousCowbellMillis) > cowbell) {
168+
previousCowbellMillis = currentCowbellMillis;
169+
if (on) {
170+
if (cowbell == 1000) {
171+
analogWrite(ledPin, (int) round(volume));
172+
} else {
173+
if (ledState == 0) {
174+
ledState = 1;
175+
analogWrite(ledPin, (int) round(volume));
176+
} else {
177+
ledState = 0;
178+
analogWrite(ledPin, 0);
179+
}
180+
}
181+
} else {
182+
analogWrite(ledPin, 0);
183+
}
184+
}
185+
186+
float t, tsum = 0;
187+
if (IMU.temperatureAvailable()) {
188+
IMU.readTemperature(t);
189+
for (int i = 0; i < tdatasize - 1; i++) {
190+
tdata[i] = tdata[i+1];
191+
}
192+
tdata[tdatasize-1] = t;
193+
for (int i = 0; i < tdatasize; i++) {
194+
tsum += tdata[i];
195+
}
196+
if (socketClient.connected()) {
197+
unsigned long currentTemperatureMillis = millis();
198+
if ((currentTemperatureMillis - previousTemperatureMillis) > 5000) {
199+
previousTemperatureMillis = currentTemperatureMillis;
200+
webSocketServer.sendData("temperature:" + String(tsum/tdatasize, 3));
201+
}
202+
}
203+
}
204+
205+
float x, y, z, zsum = 0;
206+
if (IMU.accelerationAvailable()) {
207+
IMU.readAcceleration(x, y, z);
208+
if (x > 0.2 || x < -0.2 || y > 0.2 || y < -0.2 || z > 1.2 || z < 0.8) {
209+
analogWrite(ledPin, 0);
210+
Sprintln("\n--TILT!!");
211+
if (on) {
212+
on = false;
213+
if (socketClient.connected()) {
214+
webSocketServer.sendData("sw:false");
215+
}
216+
}
217+
}
218+
for (int i = 0; i < zdatasize - 1; i++) {
219+
zdata[i] = zdata[i+1];
220+
}
221+
zdata[zdatasize-1] = z;
222+
for (int i = 0; i < zdatasize; i++) {
223+
zsum += zdata[i];
224+
}
225+
if (socketClient.connected()) {
226+
unsigned long currentGravityMillis = millis();
227+
if ((currentGravityMillis - previousGravityMillis) > 2000) {
228+
previousGravityMillis = currentGravityMillis;
229+
webSocketServer.sendData("gravity:" + String(zsum/zdatasize, 3));
230+
}
231+
}
232+
}
233+
234+
}
235+
236+
void WiFiConnect() {
237+
Sprintln("--Setting up access point " + (String)ssid + " ...");
238+
WiFi.setHostname("nano");
239+
WiFi.config(APIP, APIP, APIP, IPAddress(255,255,255,0));
240+
APStatus = WiFi.beginAP(ssid, pass, APChannel);
241+
if (APStatus != WL_AP_LISTENING) {
242+
Sprintln("--Setting up access point " + (String)ssid + " failed");
243+
while (true);
244+
}
245+
webServer.begin();
246+
socketServer.begin();
247+
#ifdef DEBUG
248+
printWifiStatus();
249+
#endif
250+
WiFi.lowPowerMode();
251+
Sprintln("--Access point " + (String)ssid + " set up");
252+
digitalWrite(LED_BUILTIN, HIGH);
253+
}
254+
255+
void sendBase64Page(char base64Page[], WiFiClient client, int packetSize) {
256+
const int base64Page_length = strlen(base64Page);
257+
const int page_length = base64_dec_len(base64Page, base64Page_length);
258+
char page[page_length];
259+
int done = 0;
260+
base64_decode(page, base64Page, base64Page_length);
261+
client.println("HTTP/1.1 200 OK\nContent-Type: text/html");
262+
if (page[0] == 0x1f && page[1] == 0x8b) {
263+
client.println("Content-Encoding: gzip");
264+
}
265+
client.println("");
266+
while (page_length > done) {
267+
if (page_length - done < packetSize) {
268+
packetSize = page_length - done;
269+
}
270+
client.write(page + done, packetSize * sizeof(char));
271+
done = done + packetSize;
272+
}
273+
}
274+
275+
#ifdef DEBUG
276+
void printWifiStatus() {
277+
Sprint("Access point SSID: "); Sprintln(WiFi.SSID());
278+
Sprint("Signal strength (RSSI): "); Sprint(WiFi.RSSI()); Sprintln(" dBm");
279+
Sprint("IP address: "); Sprintln(WiFi.localIP());
280+
Sprint("Gateway: "); Sprintln(WiFi.gatewayIP());
281+
Sprint("Netmask: "); Sprintln(WiFi.subnetMask());
282+
Sprint("Webserver is at http://"); Sprint(WiFi.localIP()); Sprintln(":" + (String)webPort + "/");
283+
Sprint("Websocket is at http://"); Sprint(WiFi.localIP()); Sprintln(":" + (String)socketPort + "/");
284+
}
285+
#endif

wifi_secrets.h

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#define SECRET_SSID "Your WiFi SSID goes here"
2+
#define SECRET_PASS "Your WiFi password goes here"

0 commit comments

Comments
 (0)