A Simple rgb light controller made with an ESP8266 and 3 MOSFETs. To use simply make a get request to it like so:
$ curl http://1.2.3.4/api.json?color=#ff0000
There are also two other interfaces:
/*
RGB Light Controller For ESP8266
Copyright (C) 2019 openstatic.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ArduinoJson.h>
#include <ESP8266mDNS.h>
#include <WiFiClient.h>
#include <IotWebConf.h>
#include <WiFiUdp.h>
#include "AppleMidi.h"
#include <ESP8266mDNS.h>
#undef IOTWEBCONF_DEBUG_TO_SERIAL
#define IOTWEBCONF_DEFAULT_AP_MODE_TIMEOUT_MS 120000
#define PWMRANGE
const int port = 23;
WiFiServer telnetServer(port);
WiFiClient telnetClient;
DNSServer dnsServer;
ESP8266WebServer httpServer(80);
wl_status_t wl_status;
IotWebConf iotWebConf("rgb_lights", &dnsServer, &httpServer, "initpass");
const int RED_PIN = 12;
const int GREEN_PIN = 14;
const int BLUE_PIN = 16;
const int MIDI_CHANNEL = 11;
const int RED_MIDI_CC = 20;
const int GREEN_MIDI_CC = 21;
const int BLUE_MIDI_CC = 22;
int red = 0;
int green = 0;
int blue = 0;
APPLEMIDI_CREATE_INSTANCE(WiFiUDP, AppleMIDI); // see definition in AppleMidi_Defs.h
// Forward declaration
void OnAppleMidiControlChange(byte channel, byte number, byte value);
String inputString = "";
boolean stringComplete = false;
extern "C" {
#include "user_interface.h"
}
void writeRGB()
{
analogWrite(RED_PIN, red);
analogWrite(GREEN_PIN, green);
analogWrite(BLUE_PIN, blue);
}
int hex2int(char h)
{
if (h >= '0' && h <= '9')
return (int) h - 48;
else if (h >= 'A' && h <= 'F')
return (int) h - 55;
else if (h >= 'a' && h <= 'f')
return (int) h - 87;
else
return 0;
}
void processLine(String data)
{
if (data.startsWith("#"))
{
//Serial.println(data);
int r, g, b;
//const char* hex = data.substring(1).c_str();
//Serial.println(hex);
red = (hex2int(data.charAt(1)) * 16) + hex2int(data.charAt(2));
green = (hex2int(data.charAt(3)) * 16) + hex2int(data.charAt(4));
blue = (hex2int(data.charAt(5)) * 16) + hex2int(data.charAt(6));
writeRGB();
}
}
void serialEvent()
{
while (Serial.available())
{
char inChar = (char)Serial.read();
if (inChar == '\n' || inChar == '\r') {
if (inputString.length() > 0)
{
stringComplete = true;
}
} else {
inputString += inChar;
}
}
if (stringComplete)
{
processLine(inputString);
// clear the string:
inputString = "";
stringComplete = false;
}
}
void readClient()
{
while (telnetClient.available())
{
char inChar = (char) telnetClient.read();
if (inChar == '\n' || inChar == '\r') {
if (inputString.length() > 0)
{
stringComplete = true;
}
} else {
inputString += inChar;
}
}
if (stringComplete)
{
processLine(inputString);
// clear the string:
inputString = "";
stringComplete = false;
}
}
void setup()
{
//Setting the analogWriteRange ensures that the pin will output max at 255
analogWriteRange(255);
iotWebConf.init();
Serial.begin(115200);
pinMode(RED_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
pinMode(BLUE_PIN, OUTPUT);
WiFi.hostname(iotWebConf.getThingName());
AppleMIDI.begin(iotWebConf.getThingName());
AppleMIDI.OnReceiveControlChange(OnAppleMidiControlChange);
delay(200);
Serial.println("INIT");
writeRGB();
telnetServer.begin();
httpServer.on("/api.json", jsonRespond );
httpServer.on("/config", []{ iotWebConf.handleConfig(); });
httpServer.on("/", handleRoot );
httpServer.onNotFound ( handleNotFound );
httpServer.begin();
tryMDNS();
}
void handleRoot()
{
if (iotWebConf.handleCaptivePortal())
{
// -- Captive portal request were already served.
return;
}
}
// Broadcast MDNS services
void tryMDNS()
{
if (MDNS.begin(iotWebConf.getThingName(), WiFi.localIP()))
{
MDNS.addService("http", "tcp", 80);
MDNS.addService("apple-midi", "udp", 5004);
}
}
void OnAppleMidiControlChange(byte channel, byte number, byte value)
{
if (channel == MIDI_CHANNEL)
{
if (number == RED_MIDI_CC)
{
red = map(value, 0, 127, 0, 255);
} else if (number == GREEN_MIDI_CC) {
green = map(value, 0, 127, 0, 255);
} else if (number == BLUE_MIDI_CC) {
blue = map(value, 0, 127, 0, 255);
}
writeRGB();
}
}
void loop()
{
iotWebConf.doLoop();
if (WiFi.status() == WL_CONNECTED)
{
MDNS.update();
AppleMIDI.run();
httpServer.handleClient();
if (telnetServer.hasClient())
{
if (!telnetClient || !telnetClient.connected())
{
if (telnetClient)
{
telnetClient.stop();
}
telnetClient = telnetServer.available();
} else {
telnetServer.available().stop();
}
}
if (telnetClient && telnetClient.connected() && telnetClient.available())
{
readClient();
}
}
// put your main code here, to run repeatedly:
if (Serial.available())
{
serialEvent();
}
//delay(1);
}
// this is the only right way to turn storage data into json
void generateJSONObject(char* bfr, int s)
{
DynamicJsonBuffer jsonBuffer;
JsonObject& rootObject = jsonBuffer.createObject();
rootObject["_freemem"] = system_get_free_heap_size();
rootObject["red"] = red;
rootObject["blue"] = blue;
rootObject["green"] = green;
rootObject.printTo(bfr, s);
}
// what we respond to /api.json with....
void jsonRespond( void )
{
for ( uint8_t i = 0; i < httpServer.args(); i++ )
{
String argname = httpServer.argName(i);
String argvalue = httpServer.arg(i);
if (argname.equals("color"))
{
processLine(argvalue);
}
}
char out[2048];
generateJSONObject(out, 2048);
httpServer.send(200, "text/javascript", out);
}
void handleNotFound()
{
String message = "File Not Found\n\n";
message += "URI: ";
message += httpServer.uri();
message += "\nMethod: ";
message += ( httpServer.method() == HTTP_GET ) ? "GET" : "POST";
message += "\nArguments: ";
message += httpServer.args();
message += "\n";
for ( uint8_t i = 0; i < httpServer.args(); i++ ) {
message += " " + httpServer.argName ( i ) + ": " + httpServer.arg ( i ) + "\n";
}
httpServer.send ( 404, "text/plain", message );
}
Latest Update: May 02 2020 04:48:00 PM EDT
rgb_controller_esp8266.ino (Arduino Project) |