Skip to content

Commit 50dc76e

Browse files
committed
Initial code commit
1 parent 1ff141f commit 50dc76e

File tree

4 files changed

+323
-0
lines changed

4 files changed

+323
-0
lines changed

esp8266-arduino-wifirgb/WifiRGB.ino

Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
#include <ESP8266WiFi.h>
2+
#include <WiFiClient.h>
3+
#include <ESP8266WebServer.h>
4+
#include <ESP8266mDNS.h>
5+
#include <ArduinoJson.h>
6+
7+
#include "names.h"
8+
#include "web_interface.h"
9+
#include "web_iro_js.h"
10+
11+
const char* ssid = "your_ssid";
12+
const char* password = "your_wifi_password";
13+
const char* deviceName = "wifi-rgb";
14+
15+
#define BUILTIN_LED 2 // internal ESP-12 LED on GPIO2
16+
17+
#define REDPIN 12
18+
#define GREENPIN 14
19+
#define BLUEPIN 5
20+
21+
ESP8266WebServer server(80);
22+
IPAddress clientIP(192, 168, 178, 254); //the IP of the device
23+
IPAddress gateway(192, 168, 178, 1); //the gateway
24+
IPAddress subnet(255, 255, 255, 0); //the subnet mask
25+
26+
void setup(void) {
27+
Serial.begin(115200);
28+
29+
WiFi.mode(WIFI_STA);
30+
WiFi.hostname(deviceName);
31+
WiFi.config(clientIP, gateway, subnet); // Remove for DHCP
32+
33+
WiFi.begin(ssid, password);
34+
Serial.println("");
35+
36+
// Wait for connection
37+
while (WiFi.status() != WL_CONNECTED) {
38+
delay(500);
39+
Serial.print(".");
40+
}
41+
Serial.println("");
42+
Serial.print("Connected to ");
43+
Serial.println(ssid);
44+
Serial.print("IP address: ");
45+
Serial.println(WiFi.localIP());
46+
47+
if (MDNS.begin("esp8266")) {
48+
Serial.println("MDNS responder started");
49+
}
50+
51+
pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output
52+
digitalWrite(BUILTIN_LED, LOW); // Turn the LED ON by making the voltage LOW after wifi is connected
53+
54+
// adjust the PWM range
55+
// see https://esp8266.github.io/Arduino/versions/2.0.0/doc/reference.html#analog-output
56+
analogWriteRange(255);
57+
58+
// Root and 404
59+
server.on("/", handleRoot);
60+
server.onNotFound(handleNotFound);
61+
62+
// REST-API
63+
server.on("/api/v1/state", HTTP_POST, handleApiRequest);
64+
65+
// iro.js User Interface and Javascript
66+
server.on("/ui", HTTP_GET, []() {
67+
server.send(200, "text/html", WEBINTERFACE);
68+
});
69+
server.on("/iro.min.js", HTTP_GET, []() {
70+
server.send(200, "application/javascript", IRO_JS);
71+
});
72+
73+
server.begin();
74+
Serial.println("WifiRGB HTTP server started");
75+
}
76+
77+
void loop(void) {
78+
server.handleClient();
79+
}
80+
81+
82+
void handleRoot() {
83+
server.send(200, "text/plain", "hello from esp8266 wifi rgb!");
84+
}
85+
86+
87+
void handleNotFound() {
88+
String message = "File Not Found\n\n";
89+
message += "URI: ";
90+
message += server.uri();
91+
message += "\nMethod: ";
92+
message += (server.method() == HTTP_GET) ? "GET" : "POST";
93+
message += "\nArguments: ";
94+
message += server.args();
95+
message += "\n";
96+
for (uint8_t i = 0; i < server.args(); i++) {
97+
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
98+
}
99+
server.send(404, "text/plain", message);
100+
}
101+
102+
void handleApiRequest() {
103+
104+
if (server.hasArg("plain") == false) { //Check if body received
105+
server.send(200, "text/plain", "Body not received");
106+
return;
107+
}
108+
109+
DynamicJsonBuffer jsonBuffer(190);
110+
JsonObject& root = jsonBuffer.parseObject(server.arg("plain"));
111+
112+
Serial.println("JSON Body: ");
113+
root.printTo(Serial);
114+
Serial.println();
115+
116+
const char* state = root["state"]; // "ON" or "OFF"
117+
if(strcmp("OFF", state) == 0) {
118+
Serial.println("Switching OFF!");
119+
// Set Output
120+
analogWrite(REDPIN, 0);
121+
analogWrite(GREENPIN, 0);
122+
analogWrite(BLUEPIN, 0);
123+
124+
server.send(200, "application/json", server.arg("plain"));
125+
return;
126+
}
127+
128+
int brightness = root["brightness"];
129+
Serial.print("Brightness: ");
130+
Serial.println(brightness);
131+
132+
RGB rgb = {0, 0, 0};
133+
134+
root["color"].printTo(Serial);
135+
136+
// If RGB mode: Parse RGB values
137+
if(strcmp("rgb", root["color"]["mode"]) == 0) {
138+
Serial.println("Reading RGB values...");
139+
rgb.r = root["color"]["r"];
140+
rgb.b = root["color"]["g"];
141+
rgb.g = root["color"]["b"];
142+
}
143+
144+
// Parse HSV
145+
if(strcmp("hsv", root["color"]["mode"]) == 0) {
146+
Serial.println("Reading HSV values...");
147+
rgb = hsvToRgb(root["color"]["h"], root["color"]["s"], root["color"]["v"]);
148+
}
149+
150+
// DEBUG: Parsed values
151+
Serial.println("Parsed Values:");
152+
Serial.print("r=");
153+
Serial.print(rgb.r);
154+
Serial.print(", g=");
155+
Serial.print(rgb.g);
156+
Serial.print(", b=");
157+
Serial.println(rgb.b);
158+
159+
// Map Brightness
160+
byte mappedRed = map(rgb.r, 0, 100, 0, brightness);
161+
byte mappedGreen = map(rgb.g, 0, 100, 0, brightness);
162+
byte mappedBlue = map(rgb.b, 0, 100, 0, brightness);
163+
164+
Serial.println("Brighness Mapped RGB Values:");
165+
Serial.print("r=");
166+
Serial.print(mappedRed);
167+
Serial.print(", g=");
168+
Serial.print(mappedGreen);
169+
Serial.print(", b=");
170+
Serial.println(mappedBlue);
171+
172+
173+
// TODO: support different modes
174+
const char* jsonrgbmode = root["mode"]; // "SOLID"
175+
176+
// Set Output
177+
analogWrite(REDPIN, mappedRed);
178+
analogWrite(GREENPIN, mappedGreen);
179+
analogWrite(BLUEPIN, mappedBlue);
180+
181+
server.send(200, "application/json", server.arg("plain"));
182+
}
183+
184+
// this is a modified version of https://gist.github.com/hdznrrd/656996
185+
RGB hsvToRgb(double h, double s, double v) {
186+
int i;
187+
double f, p, q, t;
188+
byte r, g, b;
189+
190+
h = max(0.0, min(360.0, h));
191+
s = max(0.0, min(100.0, s));
192+
v = max(0.0, min(100.0, v));
193+
194+
s /= 100;
195+
v /= 100;
196+
197+
if (s == 0) {
198+
// Achromatic (grey)
199+
r = g = b = round(v * 255);
200+
return {0,0,0};
201+
}
202+
203+
h /= 60; // sector 0 to 5
204+
i = floor(h);
205+
f = h - i; // factorial part of h
206+
p = v * (1 - s);
207+
q = v * (1 - s * f);
208+
t = v * (1 - s * (1 - f));
209+
switch (i) {
210+
case 0:
211+
r = round(255 * v);
212+
g = round(255 * t);
213+
b = round(255 * p);
214+
break;
215+
case 1:
216+
r = round(255 * q);
217+
g = round(255 * v);
218+
b = round(255 * p);
219+
break;
220+
case 2:
221+
r = round(255 * p);
222+
g = round(255 * v);
223+
b = round(255 * t);
224+
break;
225+
case 3:
226+
r = round(255 * p);
227+
g = round(255 * q);
228+
b = round(255 * v);
229+
break;
230+
case 4:
231+
r = round(255 * t);
232+
g = round(255 * p);
233+
b = round(255 * v);
234+
break;
235+
default: // case 5:
236+
r = round(255 * v);
237+
g = round(255 * p);
238+
b = round(255 * q);
239+
}
240+
241+
return {r, g, b};
242+
}

esp8266-arduino-wifirgb/names.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
struct RGB {
2+
byte r;
3+
byte g;
4+
byte b;
5+
};
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
const char WEBINTERFACE[] PROGMEM = R"=====(
2+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3+
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
4+
5+
<head>
6+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7+
<title>WifiRGB Controller Interface</title>
8+
<script type="text/javascript" src="iro.min.js"></script>
9+
<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
10+
<style>
11+
body {
12+
color: #fff;
13+
background: #272727;
14+
text-align: center;
15+
}
16+
17+
#color-picker-container svg {
18+
margin: 48px auto;
19+
}
20+
</style>
21+
</head>
22+
<body>
23+
<div id="color-picker-container"></div>
24+
<script type="text/javascript">
25+
var size = 0;
26+
if (window.innerWidth > window.innerHeight) {
27+
size = window.innerHeight * 0.8;
28+
} else {
29+
size = window.innerWidth * 0.8;
30+
}
31+
32+
var demoColorPicker = new iro.ColorPicker("#color-picker-container", {
33+
// color picker options
34+
// Option guide: https://rakujira.jp/projects/iro/docs/guide.html#Color-Picker-Options
35+
width: size,
36+
height: size,
37+
color: {r: 0, g: 0, b: 0},
38+
anticlockwise: true,
39+
borderWidth: 10,
40+
borderColor: "#313131"
41+
});
42+
43+
demoColorPicker.on("color:change", function(color, changes) {
44+
// Log the color's hex RGB value to the dev console
45+
console.log(color.rgb);
46+
console.log(color.hsv.v);
47+
// If the "H" channel has changed, log the color's HSV value too
48+
//if (changes.h) {
49+
// console.log(color.hsv);
50+
//}
51+
var json = {state:"ON",brightness:color.hsv.v,color:{r:color.rgb.r,g:color.rgb.g,b:color.rgb.b},mode:"SOLID"};
52+
console.log(json);
53+
console.log(JSON.stringify(json));
54+
55+
$.ajax( "/api/v1/state", { data: JSON.stringify(json), dataType: "json", method: "POST", contentType: "application/json"})
56+
.done(function( data ) {
57+
console.log( "Response: " );
58+
console.log( data );
59+
})
60+
.fail(function( data ) {
61+
console.log( "Error: " );
62+
console.log( data );
63+
});
64+
});
65+
</script>
66+
</body>
67+
</html>
68+
)=====";

0 commit comments

Comments
 (0)