633 lines
16 KiB
C++
Executable File
633 lines
16 KiB
C++
Executable File
#include <Arduino.h>
|
|
#include <WiFi.h>
|
|
#include <ESPAsyncWebServer.h>
|
|
#include <Preferences.h>
|
|
#include <HTTPClient.h>
|
|
#include <Adafruit_NeoPixel.h>
|
|
#include <BleKeyboard.h>
|
|
#include <Battery.h>
|
|
|
|
|
|
|
|
|
|
|
|
Battery battery(3000, 4200, 36, 12);
|
|
|
|
BleKeyboard bleKeyboard("ESP Clicker");
|
|
Preferences prefs;
|
|
WiFiClient client;
|
|
HTTPClient http;
|
|
|
|
AsyncWebServer server(80);
|
|
Adafruit_NeoPixel led(1, 13, NEO_GRB + NEO_KHZ800);
|
|
|
|
|
|
String ssid, pass, ip_address, layer, name, serverPath;
|
|
char ssid_char[20];
|
|
char pass_char[20];
|
|
float voltage;
|
|
bool connected = false;
|
|
bool blemode;
|
|
unsigned long target_time;
|
|
int lazer_button;
|
|
String index_html;
|
|
int httpResponseCode = 0;
|
|
|
|
|
|
int LAZER = 15;
|
|
int BUTTON0 = 12;
|
|
int BUTTON1 = 14;
|
|
int BUTTON2 = 27;
|
|
int BUTTON3 = 26;
|
|
int BUTTON4 = 25;
|
|
int BUTTON5 = 33;
|
|
int BUTTON6 = 32;
|
|
int BUTTON7 = 35;
|
|
int BUTTON8 = 34;
|
|
int BUTTON9 = 39;
|
|
|
|
// Button Array
|
|
int button[10] = { BUTTON0, BUTTON1, BUTTON2, BUTTON3, BUTTON4, BUTTON5, BUTTON6, BUTTON7, BUTTON8, BUTTON9 };
|
|
|
|
|
|
|
|
// HTML web page to handle 3 input fields (input1, input2, input3)
|
|
const char index_html1[] PROGMEM = R"rawliteral(
|
|
<!DOCTYPE HTML>
|
|
<html>
|
|
|
|
<head>
|
|
<title>Clicker</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<style>
|
|
body {
|
|
font-family: Arial, sans-serif;
|
|
margin: 0;
|
|
padding: 20px;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
min-height: 100vh;
|
|
background-color: #f0f0f0;
|
|
}
|
|
|
|
#container {
|
|
text-align: center;
|
|
background-color: white;
|
|
padding: 20px;
|
|
border-radius: 10px;
|
|
max-width: 100%;
|
|
}
|
|
|
|
h1 {
|
|
margin-top: 0;
|
|
}
|
|
|
|
h2 {
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
form {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
input[type="text"],
|
|
input[type="password"] {
|
|
width: 100%;
|
|
max-width: 200px;
|
|
padding: 5px;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
button,
|
|
input[type="submit"] {
|
|
padding: 10px 20px;
|
|
cursor: pointer;
|
|
background-color: #007bff;
|
|
border: none;
|
|
color: white;
|
|
border-radius: 5px;
|
|
}
|
|
|
|
button:hover,
|
|
input[type="submit"]:hover {
|
|
background-color: #0056b3;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<div id="container">
|
|
<h1>ESP Clicker - )rawliteral";
|
|
|
|
const char index_html2[] PROGMEM = R"rawliteral(</h1>
|
|
<hr>
|
|
|
|
<h2>Change WIFI Password</h2>
|
|
<form action="/" id="form_wifi">
|
|
SSID: <input type="text" name="ssid" id="ssid">
|
|
<br>
|
|
Password: <input type="password" name="pass" id="pass">
|
|
<br>
|
|
<input type="submit" value="Update Wifi" id="submit_wifi">
|
|
</form>
|
|
<button onclick="window.location.href='/?data=1';">Get Current Wifi Data</button>
|
|
|
|
<br>
|
|
<br>
|
|
<br>
|
|
|
|
<h2>Set Companion IP address</h2>
|
|
<form action="/" id="form_ip_address">
|
|
<input type="text" minlength="7" maxlength="15" size="1" id="ipaddress" name="ipaddress" placeholder="xxx.xxx.xxx.xxx" autocomplete="off">
|
|
<br>
|
|
<input type="submit" value="Update IP" id="submit_ip">
|
|
</form>
|
|
<button onclick="window.location.href='/?ipget=1';">Get Current Remote IP</button>
|
|
|
|
<br>
|
|
<br>
|
|
<br>
|
|
|
|
<h2>Set Companion Layer</h2>
|
|
<form action="/" id="form_Companion_layer">
|
|
<input type="number" minlength="1" maxlength="2" size="1" id="layer" name="layer" placeholder="xx" autocomplete="off">
|
|
<br>
|
|
<input type="submit" value="Update Layer" id="submit_layer">
|
|
</form>
|
|
|
|
<br>
|
|
<br>
|
|
|
|
<h2>Set Lazer Button</h2>
|
|
<form action="/" id="lazer">
|
|
<select id="lazer_dropdown" name="lazer">
|
|
<option value="-2">-- Select One --</option>
|
|
<option value="0">1</option>
|
|
<option value="1">2</option>
|
|
<option value="2">3</option>
|
|
<option value="3">4</option>
|
|
<option value="4">5</option>
|
|
<option value="5">6</option>
|
|
<option value="6">7</option>
|
|
<option value="7">8</option>
|
|
<option value="8">9</option>
|
|
<option value="9">10</option>
|
|
<option value="-1">Disable</option>
|
|
</select>
|
|
<br>
|
|
<br>
|
|
<input type="submit" value="Update Lazer Button" id="submit_lazer">
|
|
</form>
|
|
|
|
<br>
|
|
<br>
|
|
|
|
<h2>Set Device Name</h2>
|
|
<form action="/" id="form_name">
|
|
<input type="text" name="name" id="name">
|
|
<br>
|
|
<input type="submit" value="Update Name" id="submit_name">
|
|
</form>
|
|
<br>
|
|
<br>
|
|
<button onclick="window.location.href='/?voltageget=1';">Get Current Battery Voltage</button>
|
|
|
|
|
|
<script>
|
|
|
|
const lazer_form = document.getElementById('lazer');
|
|
const lazer_selector = document.getElementById('lazer_dropdown');
|
|
|
|
lazer_form.addEventListener('submit', function(event) {
|
|
// Check if the default option is selected
|
|
if (lazer_selector.value == '-2') {
|
|
// If it is, prevent the default submission behavior and show a message
|
|
event.preventDefault();
|
|
alert("Please select an option other than '-- Select One --'");
|
|
}
|
|
});
|
|
|
|
|
|
document.getElementById('submit_wifi').disabled = true;
|
|
document.getElementById('submit_ip').disabled = true;
|
|
document.getElementById('submit_layer').disabled = true;
|
|
|
|
document.addEventListener('keyup', e => {
|
|
if (document.getElementById('ssid').value == "" || document.getElementById('pass').value == "") {
|
|
document.getElementById('submit_wifi').disabled = true;
|
|
} else {
|
|
document.getElementById('submit_wifi').disabled = false;
|
|
}
|
|
|
|
if (document.getElementById("ipaddress").value == "") {
|
|
document.getElementById('submit_ip').disabled = true;
|
|
} else {
|
|
document.getElementById('submit_ip').disabled = false;
|
|
}
|
|
|
|
if (document.getElementById("layer").value == "") {
|
|
document.getElementById('submit_layer').disabled = true;
|
|
} else {
|
|
document.getElementById('submit_layer').disabled = false;
|
|
}
|
|
|
|
if (document.getElementById("name").value == "") {
|
|
document.getElementById('submit_name').disabled = true;
|
|
} else {
|
|
document.getElementById('submit_name').disabled = false;
|
|
}
|
|
});
|
|
</script>
|
|
</div>
|
|
</body>
|
|
|
|
</html>
|
|
)rawliteral";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// the setup function runs once when you press reset or power the board
|
|
void setup() {
|
|
// Initialize Memory
|
|
prefs.begin("clicker");
|
|
|
|
// Battery
|
|
battery.begin(3300, 2.24);
|
|
|
|
|
|
//Get Device Name
|
|
name = prefs.getString("NAME", name);
|
|
|
|
// Initialize Serial
|
|
Serial.begin(9600);
|
|
|
|
// Initialize NeoPixel strip object (REQUIRED)
|
|
led.begin();
|
|
|
|
// Setup pins
|
|
pinMode(LAZER, OUTPUT);
|
|
|
|
pinMode(BUTTON0, INPUT);
|
|
pinMode(BUTTON1, INPUT);
|
|
pinMode(BUTTON2, INPUT);
|
|
pinMode(BUTTON3, INPUT);
|
|
pinMode(BUTTON0, INPUT);
|
|
pinMode(BUTTON1, INPUT);
|
|
pinMode(BUTTON2, INPUT);
|
|
pinMode(BUTTON3, INPUT);
|
|
pinMode(BUTTON4, INPUT);
|
|
pinMode(BUTTON5, INPUT);
|
|
pinMode(BUTTON6, INPUT);
|
|
pinMode(BUTTON7, INPUT);
|
|
pinMode(BUTTON8, INPUT);
|
|
pinMode(BUTTON9, INPUT);
|
|
|
|
|
|
//Set up Lazer
|
|
lazer_button = prefs.getInt("LAZER_BUTTON");
|
|
digitalWrite(LAZER, LOW);
|
|
|
|
// Check for BLE Mode
|
|
blemode = prefs.getBool("BLEMODE");
|
|
if (digitalRead(BUTTON8) && digitalRead(BUTTON9)) {
|
|
prefs.putBool("BLEMODE", !blemode);
|
|
blemode = !blemode;
|
|
}
|
|
if (blemode) {
|
|
bleclicker();
|
|
}
|
|
|
|
|
|
|
|
|
|
// Initilize WIFI
|
|
WiFi.mode(WIFI_STA);
|
|
ssid = prefs.getString("SSID");
|
|
pass = prefs.getString("PASS");
|
|
ssid.toCharArray(ssid_char, 20);
|
|
pass.toCharArray(pass_char, 20);
|
|
WiFi.begin(ssid_char, pass_char);
|
|
|
|
target_time = millis() + 10000;
|
|
|
|
while (millis() < target_time && WiFi.status() != WL_CONNECTED) {
|
|
led.setPixelColor(0, led.Color(0, 100, 0));
|
|
led.show();
|
|
delay(1000);
|
|
led.setPixelColor(0, led.Color(0, 0, 0));
|
|
led.show();
|
|
delay(1000);
|
|
}
|
|
|
|
if (WiFi.status() != WL_CONNECTED) {
|
|
WiFi.mode(WIFI_MODE_AP);
|
|
WiFi.softAP("clicker", "clcob5364");
|
|
WiFi.softAPIP();
|
|
}
|
|
|
|
|
|
|
|
// Get Companion Info
|
|
layer = prefs.getString("LAYER");
|
|
ip_address = prefs.getString("IPADDRESS");
|
|
|
|
// Send web page with input fields to client
|
|
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
|
|
if (request->hasParam("pass") && request->hasParam("ssid")) {
|
|
request->send_P(200, "text/html", index_html.c_str());
|
|
ssid = request->getParam("ssid")->value();
|
|
pass = request->getParam("pass")->value();
|
|
|
|
Serial.print("New Password is:\t");
|
|
Serial.println(pass);
|
|
Serial.print("New SSID is:\t");
|
|
Serial.println(ssid);
|
|
|
|
prefs.putString("SSID", ssid);
|
|
prefs.putString("PASS", pass);
|
|
Serial.println("Done");
|
|
} else if (request->hasParam("data")) {
|
|
ssid = prefs.getString("SSID");
|
|
pass = prefs.getString("PASS");
|
|
request->send(200, "text/html", "<!DOCTYPE HTML><html><head><title>ESP Clicker</title><meta name='viewport' content='width=device-width, initial-scale=1'></head><body><h1>Current WIFI Settings</h1><hr><br/>SSID: \"" + ssid + "\"<br/>Password: \"" + pass + "\"<br/><br/><br/><hr><button onclick=\"window.location.href='/';\">Back</button></body></html>");
|
|
} else if (request->hasParam("ipaddress")) {
|
|
request->send_P(200, "text/html", index_html.c_str());
|
|
ip_address = request->getParam("ipaddress")->value();
|
|
prefs.putString("IPADDRESS", ip_address);
|
|
|
|
} else if (request->hasParam("ipget")) {
|
|
ip_address = prefs.getString("IPADDRESS");
|
|
request->send(200, "text/html", "<!DOCTYPE HTML><html><head><title>ESP Clicker</title><meta name='viewport' content='width=device-width, initial-scale=1'></head><body><h1>Current IP Settings</h1><hr>Remote IP Address: \"" + ip_address + "\"<br/><br/><br/><hr><button onclick=\"window.location.href='/';\">Back</button></body></html>");
|
|
|
|
} else if (request->hasParam("layer")) {
|
|
request->send_P(200, "text/html", index_html.c_str());
|
|
layer = request->getParam("layer")->value();
|
|
prefs.putString("LAYER", layer);
|
|
|
|
} else if (request->hasParam("layerget")) {
|
|
layer = prefs.getString("LAYER");
|
|
request->send(200, "text/html", "<!DOCTYPE HTML><html><head><title>ESP Clicker</title><meta name='viewport' content='width=device-width, initial-scale=1'></head><body><h1>Current IP Settings</h1><hr>Remote Companion Layer: \"" + layer + "\"<br/><br/><br/><hr><button onclick=\"window.location.href='/';\">Back</button></body></html>");
|
|
|
|
} else if (request->hasParam("voltageget")) {
|
|
voltage = battery.voltage();
|
|
voltage = voltage / 1000;
|
|
|
|
Serial.println(voltage);
|
|
request->send(200, "text/html", "<!DOCTYPE HTML><html><head><title>ESP Clicker</title><meta name='viewport' content='width=device-width, initial-scale=1'></head><body><h1>Current voltage</h1><hr>\"" + String(voltage) + "\" Volts <br/>" + String(battery.level()) + "% Battery Percentage<br/><br/><br/><hr><button onclick=\"window.location.href='/';\">Back</button></body></html>");
|
|
|
|
} else if (request->hasParam("name")) {
|
|
name = request->getParam("name")->value();
|
|
index_html = index_html1 + name + index_html2;
|
|
prefs.putString("NAME", name);
|
|
request->send_P(200, "text/html", index_html.c_str());
|
|
|
|
} else if (request->hasParam("lazer")) {
|
|
lazer_button = request->getParam("lazer")->value().toInt();
|
|
prefs.putInt("LAZER_BUTTON", lazer_button);
|
|
request->send_P(200, "text/html", index_html.c_str());
|
|
|
|
} else {
|
|
request->send_P(200, "text/html", index_html.c_str());
|
|
}
|
|
index_html = index_html1 + name + index_html2;
|
|
});
|
|
|
|
server.begin();
|
|
}
|
|
|
|
|
|
|
|
// the loop function runs over and over again forever
|
|
void loop() {
|
|
|
|
lazer();
|
|
// Read port 0
|
|
if (digitalRead(BUTTON0)) {
|
|
Serial.println("Button 0");
|
|
httpResponseCode = POSTRequest("http://" + ip_address + ":8000/api/location/" + layer + "/0/1/press");
|
|
waitfor();
|
|
}
|
|
|
|
// Read port 1
|
|
if (digitalRead(BUTTON1)) {
|
|
Serial.println("Button 1");
|
|
httpResponseCode = POSTRequest("http://" + ip_address + ":8000/api/location/" + layer + "/0/2/press");
|
|
waitfor();
|
|
}
|
|
|
|
// Read port 2
|
|
if (digitalRead(BUTTON2)) {
|
|
Serial.println("Button 2");
|
|
httpResponseCode = POSTRequest("http://" + ip_address + ":8000/api/location/" + layer + "/0/3/press");
|
|
waitfor();
|
|
}
|
|
|
|
// Read port 3
|
|
if (digitalRead(BUTTON3)) {
|
|
Serial.println("Button 3");
|
|
httpResponseCode = POSTRequest("http://" + ip_address + ":8000/api/location/" + layer + "/0/4/press");
|
|
waitfor();
|
|
}
|
|
|
|
// Read port 4
|
|
if (digitalRead(BUTTON4)) {
|
|
Serial.println("Button 4");
|
|
httpResponseCode = POSTRequest("http://" + ip_address + ":8000/api/location/" + layer + "/0/5/press");
|
|
waitfor();
|
|
}
|
|
|
|
// Read port 5
|
|
if (digitalRead(BUTTON5)) {
|
|
Serial.println("Button 5");
|
|
httpResponseCode = POSTRequest("http://" + ip_address + ":8000/api/location/" + layer + "/0/6/press");
|
|
waitfor();
|
|
}
|
|
|
|
// Read port 6
|
|
if (digitalRead(BUTTON6)) {
|
|
Serial.println("Button 6");
|
|
httpResponseCode = POSTRequest("http://" + ip_address + ":8000/api/location/" + layer + "/0/7/press");
|
|
waitfor();
|
|
}
|
|
|
|
// Read port 7
|
|
if (digitalRead(BUTTON7)) {
|
|
Serial.println("Button 7");
|
|
httpResponseCode = POSTRequest("http://" + ip_address + ":8000/api/location/" + layer + "/1/1/press");
|
|
waitfor();
|
|
}
|
|
|
|
// Read port 8
|
|
if (digitalRead(BUTTON8)) {
|
|
Serial.println("Button 8");
|
|
httpResponseCode = POSTRequest("http://" + ip_address + ":8000/api/location/" + layer + "/1/2/press");
|
|
waitfor();
|
|
}
|
|
// Read port 9
|
|
if (digitalRead(BUTTON9)) {
|
|
Serial.println("Button 9");
|
|
httpResponseCode = POSTRequest("http://" + ip_address + ":8000/api/location/" + layer + "/1/3/press");
|
|
waitfor();
|
|
}
|
|
|
|
voltage = battery.voltage();
|
|
voltage = voltage / 1000;
|
|
|
|
lazer();
|
|
|
|
if (voltage < 3.68) {
|
|
led.setPixelColor(0, led.Color(1, 0, 0));
|
|
} else if (!connected) {
|
|
led.setPixelColor(0, led.Color(1, 1, 1));
|
|
} else {
|
|
led.setPixelColor(0, led.Color(0, 1, 0));
|
|
}
|
|
led.show();
|
|
}
|
|
|
|
|
|
|
|
void waitfor() {
|
|
while (digitalRead(BUTTON0) || digitalRead(BUTTON1) || digitalRead(BUTTON2) || digitalRead(BUTTON3) || digitalRead(BUTTON4) || digitalRead(BUTTON5) || digitalRead(BUTTON6) || digitalRead(BUTTON7) || digitalRead(BUTTON8) || digitalRead(BUTTON9)) {
|
|
led.setPixelColor(0, led.Color(0, 0, 0));
|
|
led.show();
|
|
}
|
|
led.show();
|
|
|
|
if (httpResponseCode == 200) {
|
|
connected = true;
|
|
Serial.println(httpResponseCode);
|
|
} else {
|
|
connected = false;
|
|
Serial.println(httpResponseCode);
|
|
}
|
|
httpResponseCode = -1;
|
|
}
|
|
|
|
|
|
|
|
void lazer() {
|
|
if (lazer_button != -1) {
|
|
if (digitalRead(button[lazer_button])) {
|
|
led.setPixelColor(0, led.Color(255, 0, 0));
|
|
led.show();
|
|
digitalWrite(LAZER, HIGH);
|
|
while (digitalRead(button[lazer_button]))
|
|
;
|
|
digitalWrite(LAZER, LOW);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
int GETRequest(String URL) {
|
|
|
|
int response;
|
|
|
|
HTTPClient http;
|
|
|
|
http.begin(URL.c_str());
|
|
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
|
|
http.setTimeout(5000);
|
|
response = http.GET();
|
|
http.end();
|
|
|
|
Serial.println(URL);
|
|
|
|
return response;
|
|
}
|
|
|
|
|
|
int POSTRequest(String URL) {
|
|
|
|
int response;
|
|
|
|
HTTPClient http;
|
|
|
|
http.begin(URL.c_str());
|
|
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
|
|
http.setTimeout(5000);
|
|
response = http.POST("");
|
|
http.end();
|
|
|
|
Serial.println(URL);
|
|
|
|
return response;
|
|
}
|
|
|
|
|
|
|
|
|
|
void bleclicker() {
|
|
bleKeyboard.setName("ESP Clicker");
|
|
bleKeyboard.begin();
|
|
|
|
bleKeyboard.setBatteryLevel(battery.level());
|
|
|
|
|
|
|
|
while (true) {
|
|
while (bleKeyboard.isConnected()) {
|
|
// Set LED Color
|
|
led.setPixelColor(0, led.Color(0, 0, 1));
|
|
led.show();
|
|
|
|
if (millis() > target_time) {
|
|
bleKeyboard.setBatteryLevel(battery.level());
|
|
Serial.println("battery update");
|
|
target_time = millis() + 60000;
|
|
}
|
|
|
|
|
|
|
|
// Read port 0
|
|
if (digitalRead(BUTTON0)) {
|
|
Serial.println("Button 0");
|
|
bleKeyboard.write(KEY_LEFT_ARROW);
|
|
waitfor();
|
|
}
|
|
|
|
// Read port 1
|
|
if (digitalRead(BUTTON1)) {
|
|
Serial.println("Button 1");
|
|
bleKeyboard.write(KEY_RIGHT_ARROW);
|
|
waitfor();
|
|
}
|
|
|
|
// Read port 2
|
|
if (digitalRead(BUTTON8)) {
|
|
Serial.println("Lazer");
|
|
led.setPixelColor(0, led.Color(255, 0, 0));
|
|
led.show();
|
|
digitalWrite(LAZER, HIGH);
|
|
while (digitalRead(BUTTON8))
|
|
;
|
|
digitalWrite(LAZER, LOW);
|
|
}
|
|
}
|
|
|
|
// Wait for a Second
|
|
led.setPixelColor(0, led.Color(0, 0, 100));
|
|
led.show();
|
|
delay(1000);
|
|
led.setPixelColor(0, led.Color(0, 0, 0));
|
|
led.show();
|
|
delay(1000);
|
|
}
|
|
}
|