176 lines
12 KiB
C++
176 lines
12 KiB
C++
#include <Adafruit_GFX.h>
|
|
#include <Adafruit_NeoMatrix.h>
|
|
#include <Adafruit_NeoPixel.h>
|
|
#include <Fonts/TomThumb.h>
|
|
|
|
#include <M5Atom.h>
|
|
#include <Arduino.h>
|
|
#include <IRsend.h>
|
|
#include <WebServer.h>
|
|
#include <WiFi.h>
|
|
|
|
#define DISPLAY_PIN 27
|
|
|
|
#define BTN_POWER 1
|
|
#define BTN_SPEED 2
|
|
#define BTN_OSC 3
|
|
#define BTN_TIMER 4
|
|
#define BTN_NIGHT 5
|
|
|
|
// Lasko tower fan IR codes
|
|
uint16_t ir_data_power[431] = { 1285, 431, 1256, 434, 409, 1278, 1252, 437, 1260, 430, 413, 1274, 413, 1274, 412, 1274, 413, 1275, 411, 1275, 412, 1275, 1255, 7313, 1286, 429, 1258, 432, 411, 1276, 1254, 435, 1252, 437, 406, 1281, 406, 1281, 406, 1281, 405, 1282, 405, 1282, 415, 1272, 1258, 7309, 1280, 436, 1251, 438, 405, 1282, 1259, 431, 1256, 433, 410, 1277, 410, 1277, 410, 1277, 410, 1277, 410, 1277, 409, 1278, 1252, 7315, 1284, 431, 1255, 434, 409, 1278, 1252, 437, 1250, 439, 414, 1273, 414, 1273, 414, 1273, 414, 1273, 414, 1273, 414, 1273, 1257, 7310, 1279, 437, 1260, 429, 414, 1273, 1257, 432, 1255, 435, 408, 1278, 409, 1279, 408, 1279, 408, 1279, 408, 1279, 408, 1280, 1250, 7316, 1283, 433, 1254, 435, 408, 1279, 1251, 438, 1259, 430, 413, 1273, 414, 1274, 413, 1274, 413, 1274, 413, 1274, 413, 1274, 1256, 7311, 1278, 437, 1260, 429, 414, 1273, 1257, 432, 1255, 434, 409, 1278, 409, 1278, 409, 1278, 408, 1278, 409, 1279, 408, 1279, 1251, 7315, 1284, 431, 1256, 434, 409, 1277, 1253, 436, 1251, 439, 404, 1282, 405, 1282, 405, 1282, 405, 1282, 405, 1282, 415, 1272, 1258, 7307, 1282, 433, 1254, 436, 407, 1279, 1251, 438, 1259, 430, 413, 1274, 413, 1273, 414, 1273, 414, 1273, 414, 1273, 414, 1273, 1257, 7308, 1281, 434, 1253, 437, 406, 1280, 1250, 439, 1258, 431, 412, 1274, 413, 1274, 413, 1274, 413, 1274, 412, 1274, 413, 1274, 1256, 7310, 1279, 436, 1251, 438, 405, 1282, 1258, 430, 1257, 432, 411, 1276, 411, 1276, 410, 1276, 411, 1276, 410, 1276, 411, 1276, 1254, 7311, 1278, 437, 1260, 429, 414, 1272, 1258, 431, 1256, 433, 410, 1276, 411, 1276, 411, 1276, 410, 1276, 411, 1276, 411, 1276, 1254, 7311, 1278, 437, 1260, 429, 414, 1272, 1258, 431, 1256, 433, 410, 1277, 410, 1276, 411, 1276, 411, 1276, 411, 1276, 411, 1276, 1254, 7312, 1277, 437, 1260, 430, 413, 1273, 1257, 432, 1255, 434, 409, 1277, 410, 1277, 410, 1277, 410, 1277, 410, 1277, 409, 1277, 1253, 7312, 1277, 438, 1259, 430, 413, 1273, 1257, 432, 1255, 434, 409, 1277, 410, 1277, 409, 1277, 409, 1277, 410, 1277, 410, 1277, 1253, 7313, 1276, 439, 1258, 431, 412, 1274, 1256, 433, 1254, 435, 408, 1278, 408, 1278, 409, 1278, 408, 1278, 409, 1278, 409, 1277, 1253, 7312, 1277, 438, 1259, 430, 413, 1273, 1257, 432, 1255, 434, 409, 1277, 410, 1277, 410, 1277, 410, 1276, 411, 1276, 411, 1276, 1254, 7311, 1278, 437, 1250, 439, 414, 1272, 1258, 431, 1256, 433, 410, 1276, 411, 1276, 411, 1276, 410, 1276, 411, 1276, 411, 1276, 1254 };
|
|
uint16_t ir_data_speed[287] = { 1280, 435, 1252, 438, 405, 1282, 1259, 430, 1257, 433, 410, 1276, 411, 1277, 410, 1277, 410, 1277, 410, 1277, 1253, 436, 407, 8157, 1286, 429, 1258, 432, 411, 1276, 1254, 434, 1253, 437, 406, 1280, 407, 1280, 407, 1280, 407, 1280, 407, 1280, 1250, 439, 414, 8149, 1284, 431, 1256, 434, 409, 1277, 1253, 436, 1251, 439, 404, 1282, 405, 1282, 405, 1281, 406, 1281, 406, 1281, 1259, 430, 413, 8150, 1282, 433, 1254, 435, 408, 1278, 1252, 437, 1260, 429, 414, 1273, 414, 1272, 415, 1272, 415, 1272, 415, 1272, 1258, 432, 411, 8151, 1281, 434, 1252, 436, 407, 1280, 1250, 438, 1259, 430, 413, 1273, 414, 1273, 414, 1273, 414, 1272, 415, 1272, 1258, 431, 412, 8151, 1281, 433, 1253, 435, 408, 1279, 1251, 437, 1260, 429, 414, 1272, 415, 1272, 415, 1272, 415, 1271, 405, 1281, 1259, 430, 413, 8150, 1283, 432, 1255, 434, 409, 1278, 1252, 436, 1251, 439, 404, 1282, 405, 1282, 405, 1281, 406, 1281, 406, 1281, 1260, 429, 414, 8149, 1283, 431, 1256, 433, 410, 1277, 1253, 435, 1252, 437, 406, 1280, 407, 1280, 407, 1280, 407, 1279, 408, 1279, 1251, 438, 405, 8157, 1286, 429, 1258, 431, 412, 1275, 1255, 433, 1254, 435, 408, 1279, 408, 1278, 409, 1278, 409, 1278, 408, 1278, 1252, 437, 406, 8156, 1276, 439, 1258, 431, 412, 1274, 1256, 433, 1254, 435, 408, 1278, 409, 1278, 409, 1278, 408, 1278, 409, 1278, 1252, 437, 406, 8156, 1276, 438, 1259, 430, 413, 1273, 1257, 432, 1255, 434, 409, 1277, 410, 1277, 410, 1276, 411, 1276, 411, 1276, 1254, 435, 408, 8154, 1279, 436, 1251, 438, 405, 1281, 1260, 430, 1257, 432, 411, 1275, 412, 1274, 413, 1274, 413, 1274, 413, 1274, 413, 1274, 413 };
|
|
uint16_t ir_data_osc[239] = { 1278, 437, 1260, 429, 414, 1273, 1257, 431, 1256, 433, 410, 1277, 410, 1277, 1253, 435, 408, 1279, 408, 1279, 408, 1279, 408, 8155, 1277, 438, 1259, 430, 413, 1273, 1257, 432, 1255, 434, 409, 1277, 410, 1277, 1253, 436, 407, 1279, 408, 1279, 408, 1279, 408, 8155, 1277, 437, 1250, 439, 414, 1272, 1258, 431, 1256, 433, 410, 1277, 410, 1276, 1254, 435, 408, 1278, 409, 1278, 409, 1278, 409, 8154, 1279, 436, 1251, 439, 404, 1282, 1259, 430, 1257, 432, 411, 1275, 412, 1275, 1255, 433, 410, 1277, 410, 1277, 410, 1276, 411, 8152, 1280, 435, 1252, 437, 406, 1280, 1250, 439, 1258, 430, 413, 1274, 413, 1273, 1257, 432, 411, 1275, 412, 1275, 412, 1275, 411, 8151, 1281, 433, 1254, 435, 408, 1279, 1251, 437, 1250, 439, 414, 1272, 404, 1282, 1259, 430, 413, 1273, 414, 1273, 414, 1272, 415, 8148, 1285, 430, 1257, 432, 411, 1275, 1255, 434, 1253, 436, 407, 1279, 408, 1278, 1252, 437, 406, 1280, 407, 1280, 407, 1279, 408, 8155, 1278, 437, 1250, 439, 404, 1282, 1259, 430, 1257, 432, 411, 1275, 412, 1275, 1255, 433, 410, 1276, 411, 1276, 411, 1276, 411, 8151, 1281, 433, 1254, 435, 408, 1278, 1252, 437, 1250, 438, 405, 1281, 406, 1281, 1260, 429, 414, 1272, 415, 1272, 404, 1281, 406, 8157, 1286, 429, 1258, 431, 412, 1274, 1256, 433, 1254, 435, 408, 1278, 409, 1277, 1253, 436, 407, 1279, 408, 1279, 408, 1278, 409 };
|
|
uint16_t ir_data_timer[239] = { 1285, 431, 1256, 433, 410, 1276, 1254, 435, 1252, 437, 406, 1281, 406, 1280, 407, 1280, 1250, 439, 414, 1272, 415, 1271, 405, 8158, 1284, 431, 1256, 433, 410, 1276, 1254, 435, 1252, 437, 406, 1280, 407, 1280, 407, 1279, 1251, 438, 405, 1281, 406, 1281, 406, 8157, 1285, 429, 1258, 432, 411, 1275, 1255, 433, 1253, 435, 408, 1278, 408, 1278, 408, 1277, 1253, 437, 406, 1279, 408, 1252, 435, 8154, 1278, 437, 1250, 439, 414, 1272, 1258, 430, 1256, 433, 410, 1276, 410, 1275, 411, 1275, 1255, 434, 409, 1277, 409, 1276, 410, 8152, 1280, 434, 1252, 437, 406, 1279, 1251, 438, 1259, 430, 413, 1273, 414, 1272, 415, 1271, 1259, 430, 413, 1273, 414, 1273, 414, 8147, 1285, 430, 1257, 432, 411, 1275, 1255, 434, 1252, 436, 407, 1279, 408, 1278, 409, 1277, 1253, 436, 407, 1279, 408, 1278, 408, 8153, 1279, 435, 1252, 437, 406, 1280, 1250, 439, 1258, 430, 413, 1273, 414, 1273, 414, 1272, 1258, 431, 412, 1274, 412, 1273, 414, 8148, 1284, 431, 1255, 433, 410, 1276, 1254, 435, 1252, 436, 407, 1279, 408, 1278, 408, 1251, 1279, 437, 406, 1279, 408, 1279, 408, 8154, 1278, 437, 1250, 438, 405, 1281, 1259, 429, 1258, 431, 412, 1274, 413, 1273, 414, 1272, 1258, 432, 411, 1274, 412, 1274, 412, 8149, 1283, 432, 1254, 434, 409, 1277, 1253, 436, 1251, 437, 406, 1280, 407, 1279, 408, 1279, 1251, 438, 405, 1281, 406, 1280, 406 };
|
|
|
|
IRsend irsend(25); // (Atom IR LED is on pin 12.) ESP8266 GPIO pin to use. Recommended: 4 (D2).
|
|
WebServer server(80);
|
|
|
|
const char SSID[] = "azeroth";
|
|
const char PASSWORD[] = "Icecrown2004!";
|
|
|
|
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(5, 5, DISPLAY_PIN, NEO_MATRIX_TOP + NEO_MATRIX_RIGHT + NEO_MATRIX_COLUMNS + NEO_MATRIX_PROGRESSIVE, NEO_GRB + NEO_KHZ800);
|
|
|
|
String message = F("HELLO WORLD");
|
|
int msgLength = message.length();
|
|
int charWidth = 5;
|
|
int numTrailingSpaces = 3;
|
|
int maxLeftPosition = (msgLength + numTrailingSpaces) * (charWidth + 1);
|
|
int scrollDelay = 100;
|
|
int xPos = matrix.width();
|
|
|
|
void handleNotFound() {
|
|
server.send(404, "text/plain", "404");
|
|
}
|
|
|
|
String javascript() {
|
|
String output = "";
|
|
output += "<script type=\"text/javascript\">";
|
|
output += "function ajaxCall(n){var a=new XMLHttpRequest;a.open(\"GET\",n,!0),a.send()}";
|
|
output += "</script>";
|
|
return output;
|
|
}
|
|
void setup() {
|
|
Serial.begin(115200);
|
|
while (!Serial && millis() < 5000) {};
|
|
//M5.begin(true, false, true);
|
|
irsend.begin();
|
|
|
|
matrix.begin();
|
|
matrix.setFont(&TomThumb);
|
|
matrix.setTextWrap(false);
|
|
matrix.setBrightness(40);
|
|
matrix.setTextColor(matrix.Color(0, 0, 255));
|
|
matrix.setRotation(3);
|
|
|
|
WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP
|
|
WiFi.hostname("fancontroller");
|
|
WiFi.begin(SSID, PASSWORD);
|
|
|
|
while (WiFi.status() != WL_CONNECTED) {
|
|
delay(5000);
|
|
Serial.println("Connecting...");
|
|
}
|
|
|
|
Serial.println("Connected!");
|
|
delay(5000);
|
|
Serial.print("MAC: ");
|
|
Serial.print(WiFi.macAddress());
|
|
Serial.println();
|
|
Serial.print("IP: ");
|
|
Serial.print(WiFi.localIP());
|
|
Serial.println();
|
|
Serial.print("HOSTNAME: ");
|
|
Serial.print(WiFi.getHostname());
|
|
Serial.println();
|
|
|
|
server.on("/", []() {
|
|
String ptr = "<!DOCTYPE html> <html>\n";
|
|
ptr += "<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
|
|
ptr += javascript();
|
|
ptr += "<title>Bedroom Fans</title>\n";
|
|
ptr += "<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
|
|
ptr += "body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}\n";
|
|
ptr += ".button {display: block;width: 130px;background-color: #3498db;border: none;color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";
|
|
ptr += ".button-on {background-color: #3498db;}\n";
|
|
ptr += ".button-on:active {background-color: #2980b9;}\n";
|
|
ptr += ".button-off {background-color: #34495e;}\n";
|
|
ptr += ".button-off:active {background-color: #2c3e50;}\n";
|
|
ptr += "p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
|
|
ptr += "</style>\n";
|
|
ptr += "</head>\n";
|
|
ptr += "<body>\n";
|
|
ptr += "<h1>Bedroom Fan Controller</h1>\n";
|
|
ptr += "<a class=\"button button-off\" onClick=\"ajaxCall('power');\">ON/OFF</a>\n";
|
|
ptr += "<a class=\"button button-off\" onClick=\"ajaxCall('speed');\">SPEED</a>\n";
|
|
ptr += "<a class=\"button button-off\" onClick=\"ajaxCall('osc');\">OSCILLATE</a>\n";
|
|
ptr += "</body>\n";
|
|
ptr += "</html>\n";
|
|
|
|
server.send(200, "text/html", ptr);
|
|
});
|
|
|
|
server.on("/reset", []() {
|
|
message = "RESET";
|
|
xPos = matrix.width();
|
|
server.send(200, "text/html", "reset");
|
|
ESP.restart();
|
|
});
|
|
|
|
server.on("/power", []() {
|
|
message = "POWER";
|
|
xPos = matrix.width();
|
|
server.send(200, "text/html", "power");
|
|
irsend.sendRaw(ir_data_power, 431, 38);
|
|
});
|
|
|
|
server.on("/speed", []() {
|
|
message = "SPEED";
|
|
xPos = matrix.width();
|
|
Serial.println("sendserver");
|
|
server.send(200, "text/html", "speed");
|
|
irsend.sendRaw(ir_data_speed, 287, 38);
|
|
});
|
|
|
|
server.on("/osc", []() {
|
|
message = "OSC";
|
|
xPos = matrix.width();
|
|
Serial.println("sendserver");
|
|
server.send(200, "text/html", "osc");
|
|
irsend.sendRaw(ir_data_osc, 239, 38);
|
|
});
|
|
server.on("/timer", []() {
|
|
message = "TIMER";
|
|
xPos = matrix.width();
|
|
Serial.println("sendserver");
|
|
server.send(200, "text/html", "timer");
|
|
irsend.sendRaw(ir_data_timer, 239, 38);
|
|
});
|
|
|
|
server.onNotFound(handleNotFound);
|
|
server.begin();
|
|
}
|
|
|
|
int resetPos = 15;
|
|
|
|
void loop() {
|
|
if (WiFi.status() == WL_CONNECTED) {
|
|
server.handleClient();
|
|
}
|
|
|
|
if (message.length() > 0) {
|
|
matrix.fillScreen(0);
|
|
matrix.setCursor(xPos, matrix.height());
|
|
matrix.print(message);
|
|
|
|
if (--xPos < -maxLeftPosition) {
|
|
xPos = matrix.width();
|
|
Serial.println("end of message");
|
|
message = "";
|
|
}
|
|
|
|
matrix.show();
|
|
delay(scrollDelay);
|
|
}
|
|
}
|