Skip to content

Commit 2cd73bd

Browse files
committed
Remove blank sketch
1 parent d3e89bd commit 2cd73bd

File tree

4 files changed

+327
-341
lines changed

4 files changed

+327
-341
lines changed
File renamed without changes.
Lines changed: 327 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,333 @@
1-
// Open IOT
2-
// Control/interface with your Electric Scooter
3-
// Standalone version, does not require a backend
4-
// https://github.com/joeybab3/Open-IOT
1+
///////////////////
2+
// Open IOT //
3+
///////////////////
4+
// Models //
5+
///////////////////
6+
// Bird Zero //
7+
// Okai ES100 //
8+
// Okai ES200B //
9+
///////////////////
510
// https://joeybabcock.me/blog/electric_scooters/open-iot/
6-
void setup() {
7-
// put your setup code here, to run once:
11+
///////////////////
812

13+
#include <Arduino.h>
14+
#include <FastCRC.h>
15+
#include <ESP8266WiFi.h>
16+
#include <ESP8266WebServer.h>
17+
#include <ESP8266mDNS.h>
18+
#include <WiFiUdp.h>
19+
#include <ArduinoOTA.h>
20+
#include <strings_en.h>
21+
#include <WiFiManager.h>
22+
23+
#define HEARTBEAT_INTERVAL 500
24+
#define PACKET_SIZE 5
25+
26+
FastCRC8 CRC8;
27+
ESP8266WebServer server(80);
28+
WiFiManager wm;
29+
30+
IPAddress local_ip(192,168,1,1);
31+
IPAddress gateway(192,168,1,1);
32+
IPAddress subnet(255,255,255,0);
33+
34+
uint32_t crc;
35+
int loopCount = 0;
36+
int model = 0;
37+
const int enablePin = 15;
38+
39+
bool isRunning = false;
40+
bool headlightStatus = false;
41+
bool flashStatus = false;
42+
bool locked = false;
43+
bool isMetric = false;
44+
bool debug = false;
45+
bool isBit4 = false; // "Fast Acceleration"
46+
bool isBit7 = false;
47+
bool isBit8 = false;
48+
49+
const char* ssid = "vehicle";
50+
const char* password = "SPINB0001";
51+
52+
// The packet structure, 00 is a placeholder for the command, a speed variable, and the Checksum
53+
uint8_t okaiPacket[] = {0xA6, 0x12, 0x02, 0x00, 0x00, 0x00};
54+
55+
byte okaiMaxSpeed = 0xFF;
56+
byte okaiDefaultConfig = 0xE1;
57+
58+
int chksm = 0;
59+
60+
void reCalculateCommand()
61+
{
62+
crc = CRC8.maxim(okaiPacket, PACKET_SIZE);
63+
okaiPacket[5] = crc;
64+
}
65+
66+
void sendCommand()
67+
{
68+
if(debug)
69+
{
70+
Serial.print(okaiPacket[0], HEX);
71+
Serial.print(" ");
72+
Serial.print(okaiPacket[1], HEX);
73+
Serial.print(" ");
74+
Serial.print(okaiPacket[2], HEX);
75+
Serial.print(" ");
76+
Serial.print(okaiPacket[3], HEX);
77+
Serial.print(" ");
78+
Serial.print(okaiPacket[4], HEX);
79+
Serial.print(" ");
80+
Serial.print(okaiPacket[5], HEX);
81+
Serial.println();
82+
}
83+
else
84+
{
85+
Serial.write(okaiPacket, sizeof(okaiPacket));
86+
}
87+
}
88+
89+
void restartEsp()
90+
{
91+
server.send(200, "text/html", SendRestart());
92+
delay(500);
93+
ESP.restart();
94+
}
95+
96+
void setup()
97+
{
98+
Serial.begin(115200);
99+
delay(10);
100+
101+
WiFi.mode(WIFI_AP_STA);
102+
103+
wm.setConfigPortalBlocking(false);
104+
105+
if(wm.autoConnect(ssid,password)){
106+
Serial.println("Connected");
107+
}
108+
else {
109+
Serial.println("No");
110+
}
111+
112+
delay(100);
113+
114+
pinMode(enablePin, OUTPUT);
115+
116+
MDNS.begin("joeybabcock.me");
117+
MDNS.addService("http", "tcp", 80);
118+
119+
ArduinoOTA.onStart([]() {
120+
String type;
121+
if (ArduinoOTA.getCommand() == U_FLASH) {
122+
type = "sketch";
123+
} else { // U_FS
124+
type = "filesystem";
125+
}
126+
127+
// NOTE: if updating FS this would be the place to unmount FS using FS.end()
128+
Serial.println("Start updating " + type);
129+
});
130+
131+
ArduinoOTA.onEnd([]() {
132+
//Serial.println("\nEnd");
133+
});
134+
135+
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
136+
//Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
137+
});
138+
139+
ArduinoOTA.onError([](ota_error_t error) {
140+
//Serial.printf("Error[%u]: ", error);
141+
if (error == OTA_AUTH_ERROR) {
142+
//Serial.println("Auth Failed");
143+
} else if (error == OTA_BEGIN_ERROR) {
144+
//Serial.println("Begin Failed");
145+
} else if (error == OTA_CONNECT_ERROR) {
146+
//Serial.println("Connect Failed");
147+
} else if (error == OTA_RECEIVE_ERROR) {
148+
//Serial.println("Receive Failed");
149+
} else if (error == OTA_END_ERROR) {
150+
//Serial.println("End Failed");
151+
}
152+
});
153+
154+
//ArduinoOTA.setPassword("8266!");
155+
ArduinoOTA.begin();
156+
157+
server.on("/", handle_OnConnect);
158+
server.onNotFound(handle_NotFound);
159+
server.on("/default", setDefaultConfig);
160+
server.on("/power", power);
161+
server.on("/headlight", headlight);
162+
server.on("/headlightOn", enableHeadlight);
163+
server.on("/headlightOff", disableHeadlight);
164+
server.on("/flash", flash);
165+
server.on("/units", setUnitSystem);
166+
server.on("/restart", restartEsp);
167+
server.on("/ping", ping);
168+
server.on("/toggle4", toggleBit4);
169+
server.on("/toggle7", toggleBit7);
170+
server.on("/toggle8", toggleBit8);
171+
172+
server.begin();
173+
setDefaultConfig();
174+
Serial.begin(9600);
175+
pinMode(enablePin, OUTPUT);
176+
digitalWrite(enablePin, HIGH);
177+
}
178+
179+
void loop()
180+
{
181+
if(loopCount > 1000)
182+
{
183+
restartEsp();
184+
}
185+
else if(loopCount < 5 && WiFi.status() != WL_CONNECTED) {
186+
wm.process();
187+
delay(1000);
188+
}
189+
else
190+
{
191+
MDNS.update();
192+
ArduinoOTA.handle();
193+
server.handleClient();
194+
sendCommand();
195+
yield();
196+
delay(HEARTBEAT_INTERVAL);
197+
}
198+
loopCount++;
199+
}
200+
201+
void handle_OnConnect() {
202+
server.sendHeader("Connection", "close");
203+
server.send(200, "text/html", SendHTML());
9204
}
10205

11-
void loop() {
12-
// put your main code here, to run repeatedly:
206+
void handle_NotFound(){
207+
server.sendHeader("Location", "/", true); //Redirect to our html web page
208+
server.send(302, "text/plane","");
209+
}
210+
211+
212+
void handle_okai() {
213+
Serial.begin(9600);
214+
pinMode(enablePin, OUTPUT);
215+
digitalWrite(enablePin, HIGH);
216+
enableFastAcceleration();
217+
server.send(200, "text/html", SendHTML());
218+
}
219+
220+
void goHome()
221+
{
222+
server.sendHeader("Location", "/", true); //Redirect to our html web page
223+
server.send(302, "text/plane","");
224+
}
225+
226+
String SendHTML(){
227+
String page = "<!DOCTYPE html>\n";
228+
page += "<html>\n";
229+
page += "<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
230+
page += "<title>Scooter Config</title>\n";
231+
page += "<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
232+
page += "body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}#status {font-size: 36px;}\n";
233+
page += ".button {display: block;width: 120px;background-color: #1abc9c;border: none;color: white;padding: 13px 30px;";
234+
page += "text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";
235+
page += ".button2 {display: inline;width: 100px;background-color: #1abc9c;border: none;color: white;padding: 13px 30px;";
236+
page += "text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";
237+
page +=".button-on {background-color: #1abc9c;}\n";
238+
page +=".button-on:active {background-color: #16a085;}\n";
239+
page +=".button-off {background-color: #34495e;}\n";
240+
page +=".button-off:active {background-color: #2c3e50;}\n";
241+
page +="p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
242+
page +="</style>\n";
243+
page +="</head>\n";
244+
page +="<body>\n";
245+
page +="<h1>Scooter Config</h1>\n";
246+
page +="<a class=\"button ";
247+
if(!isRunning){page += "button-off";}
248+
page += "\" href=\"/power\">POWER</a>\n";
249+
page +="<a class=\"button ";
250+
if(!headlightStatus){page += "button-off";}
251+
page += "\" href=\"/headlight\">HEADLIGHT</a>\n";
252+
page += "<a class=\"button ";
253+
if(!flashStatus){page += "button-off";}
254+
page += "\" href=\"/flash\">LIGHT FLASH</a>\n";
255+
page += "<a class=\"button button-off\" href=\"/units\">";
256+
if(!isMetric)
257+
{page += "SET KMH";}
258+
else
259+
{page += "SET MPH";}
260+
page += "</a>\n";
261+
page +="<a class=\"button button-off\" href=\"/restart\">RESTART</a>\n";
262+
page += "<span id='status'>&bull; 0x"+String(okaiPacket[3], HEX)+" </span>\n";
263+
page +="<small style='vertical-align: super;'>"+WiFi.localIP().toString()+" | "+WiFi.softAPIP().toString()+"</small>\n";
264+
page +="</body>\n";
265+
page +="</html>\n";
266+
return page;
267+
}
13268

269+
String SendRestart(){
270+
String page = "<!DOCTYPE html> <html>\n";
271+
page +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
272+
page +="<title>Restarting...</title>\n";
273+
page +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
274+
page +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}#status {font-size: 36px;}\n";
275+
page +="</style>\n";
276+
page +="</head>\n";
277+
page +="<body>\n";
278+
page +="<h1>Restarting...</h1>\n";
279+
page +="<h1>Reloading in <span id='timer'>10</span> seconds</h1>\n";
280+
page += "<span id='status'>&bull;</span>\n";
281+
page +="<small style='vertical-align: super;'>"+WiFi.localIP().toString()+" | "+WiFi.softAPIP().toString()+"</small>\n";
282+
page += "<script>\n";
283+
page += "var numFailures = 0;\n";
284+
page += "var timer;\n";
285+
page +="function checkStatus()\n";
286+
page +="{\n";
287+
page +="var xhr = new XMLHttpRequest();\n";
288+
page +="xhr.open('GET', '/ping', true);\n";
289+
page +="xhr.timeout = 500; // time in milliseconds\n";
290+
page +="xhr.ontimeout = function (e) {\n";
291+
page +=" document.getElementById('status').style.color = 'red';\n";
292+
page +="};\n";
293+
page +="xhr.onload = function () {\n";
294+
page +=" if (xhr.readyState === xhr.DONE) {\n";
295+
page +=" if (xhr.status === 200) {\n";
296+
page +=" document.getElementById('status').style.color = 'green';\n";
297+
page += " window.location.href = '/';\n";
298+
page += " clearInterval(timer);\n";
299+
page += " document.getElementById('timer').innerHTML = '0';\n";
300+
page +=" }\n";
301+
page +=" else\n";
302+
page +=" {\n";
303+
page +=" document.getElementById('status').style.color = 'red';\n";
304+
page +=" }\n";
305+
page +=" }\n";
306+
page +=" else\n";
307+
page +=" {\n";
308+
page +=" document.getElementById('status').style.color = 'red';\n";
309+
page +=" }\n";
310+
page +="};\n";
311+
page +=" xhr.send();\n";
312+
page +="}\n";
313+
page += "\tvar seconds = 10;\n";
314+
page += "\tfunction asecondhaspassed()\n";
315+
page += "\t{\n";
316+
page += "\t\tif(seconds < 1)\n";
317+
page += "\t\t{";
318+
page += "\t\t\twindow.location.href = '/';\n";
319+
page += "\t\t}\n";
320+
page += "\t\telse\n";
321+
page += "\t\t{\n";
322+
page += "\t\t\tseconds--;\n";
323+
page += "\t\t\tdocument.getElementById('timer').innerHTML = seconds;\n";
324+
page += "\t\tcheckStatus();\n";
325+
page += "\t\t}\n";
326+
page += "\t}\n";
327+
page += "\ttimer = setInterval(asecondhaspassed, 1000);\n";
328+
page += "</script>\n";
329+
page +="</body>\n";
330+
331+
page +="</html>\n";
332+
return page;
14333
}
File renamed without changes.

0 commit comments

Comments
 (0)