Last active
December 9, 2015 20:47
-
-
Save bugduino/6e33999e53c5c98d87d5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <WiFi.h> | |
#include <PubSubClient.h> | |
#include <JsonParser.h> | |
using namespace ArduinoJson::Parser; | |
#define WIFI_SSID "XXX" | |
#define WIFI_PWD "XXXXX" | |
/* Properties of light type */ | |
#define LIGHT_STATUS "54986537bbd5a45b84000001" // on || off | |
#define LIGHT_STATUS_TIME "54986555bbd5a4a974000001" // | |
#define LIGHT_INTENSITY "54986591bbd5a45b84000002" // range: from to | |
#define LIGHT_INTENSITY_TIME "549865b0bbd5a45b84000003" // | |
#define LIGHT_COLOR "549865c6bbd5a4c34c000002" // hex | |
#define LIGHT_COLOR_TIME "549865dbbbd5a4c34c000003" // | |
#define LIGHT_BLINKING "549865eabbd5a4a974000002" // on || off | |
#define LIGHT_BLINKING_TIME "54986633bbd5a45b84000004" // | |
#define LIGHT_BLINKING_COLOR "54986643bbd5a4a974000003" // HEX | |
#define LIGHT_RAINBOW_MODE "54986730bbd5a4c34c000008" // on || off | |
// #define LIGHT_BLINK_TIMES "518be95500045e1521000009" // times | |
// #define LIGHT_BLINK_FREQ "518be9aa00045e0610000009" // s | |
// #define LIGHT_FADE_SPEED "5497e32513437b4a6b000002" // ms | |
#define CLIENT_ID "bugmanclient4" | |
/* Device topics */ | |
#define DEVICE_ID "____YOUR_DEVICE_ID____" | |
#define DEVICE_SECRET "___YOUR_DEVICE_SECRET___" | |
#define DEVICE_IN_TOPIC "devices/____YOUR_DEVICE_ID____/get" | |
#define DEVICE_OUT_TOPIC "devices/____YOUR_DEVICE_ID____/set" | |
/* Pins configuration */ | |
#define RPIN 31 // red P17 | |
#define GPIN 10 // green P64 | |
#define BPIN 29 // blue P02 | |
/* Global variables */ | |
boolean isBlinking = false; | |
int times; | |
float freqMs; | |
int fadeSpeed = 15; // ms default | |
int lastR = 0; // cyan same color of leiConnected | |
int lastG = 255; | |
int lastB = 255; | |
int lastRFull; // used to mantain color when setting intensity | |
int lastGFull; | |
int lastBFull; | |
WiFiClient wclient; | |
byte server[] = { 96, 126, 109, 170 }; // Lelylan | |
PubSubClient client(server, 1883, callback, wclient); | |
void callback(char* inTopic, byte* payload, unsigned int length){ | |
// copy the payload content into a char* | |
char* json; | |
json = (char*) malloc(length + 1); | |
memcpy(json, payload, length); | |
json[length] = '\0'; | |
Serial.println(json); | |
JsonParser<14> parser; | |
JsonObject root = parser.parse(json); | |
if (!root.success()) { | |
// Parsing fail: could be an invalid JSON, or too many tokens | |
Serial.println("parsing failed, return."); | |
leiError(); | |
return; | |
} | |
char* property = root["properties"][0]["id"]; | |
char* value = root["properties"][0]["value"]; | |
char* value2 = root["properties"][1]["value"]; | |
resetLoopVariables(); // set all loop variables to false | |
Serial.println(value); | |
Serial.println(value2); | |
if (strcmp(property, LIGHT_STATUS ) == 0) {setStatus(value, json); return;} | |
if (strcmp(property, LIGHT_INTENSITY ) == 0) {setIntensity(value, json); return;} | |
if (strcmp(property, LIGHT_COLOR ) == 0) {setColor(value, json); return;} | |
if (strcmp(property, LIGHT_BLINK_TIMES) == 0) {setBlinkingTimesAndFreq(value, value2, json); return;} | |
if (strcmp(property, LIGHT_FADE_SPEED ) == 0) {setFadeSpeed(value, json); return;} | |
Serial.println("Something went wrong"); | |
free(json); | |
return; | |
} | |
void setup() { | |
//Initialize serial and wait for port to open: | |
pinMode(RPIN, OUTPUT); | |
pinMode(GPIN, OUTPUT); | |
pinMode(BPIN, OUTPUT); | |
Serial.begin(115200); | |
delay(500); | |
Serial.println("Start WiFi"); | |
leiStarted(); | |
WiFi.begin(WIFI_SSID, WIFI_PWD); | |
while(WiFi.localIP() == INADDR_NONE) { | |
Serial.print("."); | |
delay(300); | |
} | |
printWifiStatus(); | |
if (client.connect(CLIENT_ID, DEVICE_ID, DEVICE_SECRET)) { | |
Serial.println("[P]MQTT-OK!!"); | |
leiConnected(); | |
lelylanSubscribe(); | |
} | |
} | |
void loop() { | |
client.loop(); | |
if (isBlinking && times-- > 0) {leiBlink(times, freqMs);} | |
} | |
/// ########################################################### | |
/* MQTT subscribe */ | |
void lelylanSubscribe() { | |
client.subscribe(DEVICE_IN_TOPIC); | |
} | |
/* MQTT publish */ | |
void lelylanPublish(char* json) { | |
client.publish(DEVICE_OUT_TOPIC, json); | |
} | |
// Callback Handlers =================== | |
// Set the received color and set lastColor to the current color | |
void setColor(char* value, char* json) { | |
int* rgb = rgbArrayFromHex(value); | |
fadeFromColorToColor(lastR, lastG, lastB, rgb[0], rgb[1], rgb[2], fadeSpeed); | |
setLastFullColor(rgb[0], rgb[1], rgb[2]); | |
//lelylanPublish(json); | |
free(rgb); | |
return; | |
} | |
// Turn light on setting last color, or turn light off | |
void setStatus(char* value, char* json) { | |
if (String(value) == "on") { | |
fadeFromZeroToColor(lastR, lastG, lastB, fadeSpeed); | |
} else { | |
fadeFromColorToZero(lastR, lastG, lastB, fadeSpeed); | |
} | |
//lelylanPublish(json); | |
return; | |
} | |
void setIntensity(char* value, char* json) { | |
int val = atoi(value); | |
int newR, newG, newB; | |
newR = (int) ((lastRFull/100) * val); | |
newG = (int) ((lastGFull/100) * val); | |
newB = (int) ((lastBFull/100) * val); | |
fadeFromColorToColor(lastR, lastG, lastB, newR, newG, newB, fadeSpeed); | |
return; | |
} | |
void setFadeSpeed(char* value, char* json) { | |
fadeSpeed = atoi(value); | |
return; | |
} | |
void setBlinkingTimesAndFreq(char* value, char* value2, char* json) { | |
isBlinking = true; | |
times = atoi(value); | |
freqMs = ((float) atof(value2) * 1000); // ms | |
} | |
void setFade(char* speed, char* json) { | |
int r, g, b; | |
int vel = atoi(speed); | |
// un while wrappa tutto e si ferma se non è piu in breathing e dentro tutti i for la condizione contiene anche is breathing | |
for (r = 0; r < 256; r++) { // fade from blue to violet | |
analogWrite(RPIN, r); | |
delay(vel); | |
} | |
for (b = 255; b > 0; b--) { // fade from violet to red | |
analogWrite(BPIN, b); | |
delay(vel); | |
} | |
for (g = 0; g < 256; g++) { // fade from red to yellow | |
analogWrite(GPIN, g); | |
delay(vel); | |
} | |
for (r = 255; r > 0; r--) { // fade from yellow to green | |
analogWrite(RPIN, r); | |
delay(vel); | |
} | |
for (b = 0; b < 256; b++) { // fade from green to teal | |
analogWrite(BPIN, b); | |
delay(vel); | |
} | |
for (g = 255; g > 0; g--) { // fade from teal to blue | |
analogWrite(GPIN, g); | |
delay(vel); | |
} | |
} | |
// Helpers ============================== | |
void leiBlink(int times, float freqMs) { | |
Serial.println(times); | |
setRGB(0, 0, 0); | |
delay(freqMs); | |
setRGB(lastR, lastG, lastB); | |
delay(freqMs); | |
} | |
void resetLoopVariables() { | |
isBlinking = false; | |
} | |
void fadeFromColorToZero(int r, int g, int b, int delayMs) { | |
fadeFromColorToColor(r,g,b,0,0,0,delayMs); | |
return setLastColor(r, g, b); | |
} | |
void fadeFromZeroToColor(int r, int g, int b, int delayMs) { | |
return fadeFromColorToColor(0,0,0,r,g,b,delayMs); | |
} | |
void fadeFromColorToColor(int fromR, int fromG, int fromB, int toR, int toG, int toB, int delayMs) { | |
while(fromR != toR || fromG != toG || fromB != toB) { | |
if (fromR < toR) ++fromR; | |
if (fromR > toR) --fromR; | |
if (fromG < toG) ++fromG; | |
if (fromG > toG) --fromG; | |
if (fromB < toB) ++fromB; | |
if (fromB > toB) --fromB; | |
setRGB(fromR, fromG, fromB); | |
delay(delayMs); | |
} | |
return setLastColor(fromR, fromG, fromB); | |
} | |
void setRGB(int rVal, int gVal, int bVal) { | |
analogWrite(RPIN, rVal); | |
analogWrite(GPIN, gVal); | |
analogWrite(BPIN, bVal); | |
return; | |
} | |
int* rgbArrayFromHex(char* hexValue) { // Expects '#FFFFFF' | |
long number = strtol(&hexValue[1], NULL, 16); | |
int r = number >> 16; | |
int g = number >> 8 & 0xFF; | |
int b = number & 0xFF; | |
int* rgb = rgbToArray(r, g, b); | |
return rgb; | |
} | |
int* rgbToArray(int r, int g, int b) { | |
int* rgb = (int *) malloc(sizeof(int) * 3); | |
rgb[0] = r; | |
rgb[1] = g; | |
rgb[2] = b; | |
return rgb; | |
} | |
// Set last color to a global variables | |
void setLastColor(int newR, int newG, int newB) { | |
lastR = newR; | |
lastG = newG; | |
lastB = newB; | |
return; | |
} | |
// Set last color full to a global variables for intensity | |
void setLastFullColor(int newR, int newG, int newB) { | |
lastRFull = newR; | |
lastGFull = newG; | |
lastBFull = newB; | |
return; | |
} | |
void printWifiStatus() { | |
// print the SSID of the network you're attached to and IP: | |
Serial.print("SSID: "); | |
Serial.println(WiFi.SSID()); | |
IPAddress ip = WiFi.localIP(); | |
Serial.print("IP Address: "); | |
Serial.println(ip); | |
} | |
// Debug ====================== | |
void printRGB(char* label, int r, int g, int b) { | |
Serial.print(String(label)); | |
Serial.print(r); | |
Serial.print(", "); | |
Serial.print(g); | |
Serial.print(", "); | |
Serial.println(b); | |
} | |
// Notifications ====================== | |
void leiError() { setRGB(255, 0, 0); } // red | |
void leiConnected() { setRGB(0, 255, 255);} // cyan | |
void leiStarted() { setRGB(0, 255, 0); } // green |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment