Skip to content

Instantly share code, notes, and snippets.

@mherweg
Last active August 19, 2017 19:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mherweg/4b230ef389f1ed14669c07fd357b8f7b to your computer and use it in GitHub Desktop.
Save mherweg/4b230ef389f1ed14669c07fd357b8f7b to your computer and use it in GitHub Desktop.
#define NUMPIXELS 254
#define PIN 5 //GPIO5 = D1
// http://esp8266-server.de/wemos.html#Pinbelegung
const char* ssid = "XXXXXXXXXXXXXX";
const char* password = "XXXXXXXXXXXXX";
const char* mqtt_server = "192.168.1.3";
const char* inTopic = "huette/clubraum/000/ws2812tonne/frame";
const char* inTopic2 ="huette/clubraum/000/ws2812tonne/actuators/set_pixel";
const char* outTopic = "huette/clubraum/000/ws2812tonne/status";
/*
ESP8266 MQTT
Version 2017-08-15
* using decimal values (0..255) for mode,speed, brightness !!
* less use of ws2812fx.stop();
* ws2812fx.start() only when a mode is recieved.
this sketch subscibes 2 MQTT topics:
topic: "huette/clubraum/000/ws2812tonne/actuators/frame"
- receive a binary MQTT message with seperate RGB values for all pixels
(1 frame / ein Bild ) and control Neopixel LEDs
3 bytes per pixel (r,g,b)
topic: "huette/clubraum/000/ws2812tonne/actuators/set_pixel"
- receive a command (ascii)
possible commands:
0-n #RRGGBB (set one pixel, disable effects)
255 #RRGGBB (set all pixels, disable effects)
mode 0-46 (WS2812FX mode, enable effects)
speed 0-255
brightness 0-255
color #RRGGBB
*/
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <PubSubClient.h>
#include <Adafruit_NeoPixel.h>
#include <WS2812FX.h>
#include "conf.h"
// I moved this to conf.h
//const char* ssid = "XXXXXXX";
//const char* password = "XXXXXXX";
//const char* mqtt_server = "XXXX";
WiFiClient espClient;
PubSubClient client(espClient);
WS2812FX ws2812fx = WS2812FX(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
int r,g,b;
byte framebuffer[NUMPIXELS*3];
String stringPixel, stringFrame, stringIntopic ;
bool fx_is_active;
void printModes() {
Serial.println(F("Supporting the following modes: "));
Serial.println();
for(int i=0; i < ws2812fx.getModeCount(); i++) {
Serial.print(i);
Serial.print(F("\t"));
Serial.println(ws2812fx.getModeName(i));
}
Serial.println();
}
void setup() {
//pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output
Serial.begin(115200);
pixels.begin();
setup_wifi();
client.setServer(mqtt_server, 1883);
client.subscribe("inTopic");
client.subscribe("inTopic2");
client.setCallback(callback);
stringPixel = String(inTopic2);
stringFrame = String(inTopic);
ArduinoOTA.setHostname("saturnring"); // give an name to our module
ArduinoOTA.begin(); // OTA initialization
ws2812fx.init();
ws2812fx.setBrightness(30);
ws2812fx.setSpeed(200);
ws2812fx.setColor(0x220022);
ws2812fx.setMode(9);
ws2812fx.start();
fx_is_active = true;
printModes();
} //setup
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
// Serial.print("BUILTIN_LED Value: ");
// Serial.println(BUILTIN_LED);
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.softAPdisconnect(true);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
pixels.setPixelColor(0, pixels.Color(50,0,0));
pixels.show();
//Serial.println("trying SSID2..");
//pixels.setPixelColor(0, pixels.Color(50,50,0));
//WiFi.begin(ssid2, password2);
}
Serial.println("");
Serial.println("WiFi connected");
pixels.setPixelColor(0, pixels.Color(0,50,0));
pixels.show();
delay(500);
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
client.subscribe(inTopic);
client.setCallback(callback);
} //setup_wifi
void parse_mqtt_message( byte* payload, unsigned int length){
int splitat;
// Einmal die ganze Payload durcharbeiten...
String s = "";
for(int i = 0; i < length; i++) {
// und Seriell ausgeben
s += (char)payload[i];
// Serial.println((char)payload[i]);
if (isWhitespace((char)payload[i])) {
splitat = i;
i = length;
}
}
String Numberstring = "";
String Colorstring = "";
for(int i = 0; i < splitat; i++) {
Numberstring += (char) payload[i];
}
for (int i = (splitat + 1); i < length; i++) {
Colorstring += (char) payload[i];
}
//Colorstring contains something like = "#00ff00" or "00ff00"
// you need to convert it to 0,255,0 and insert it to the two calls below
// Am ende Newline.
int intcolors=(int) strtol(&Colorstring[1],NULL,16);
int r = intcolors >> 16;
int g = intcolors >> 8 & 0xFF;
int b = intcolors & 0xFF;
Serial.print("Numberstring:" + Numberstring + " Colorstring:" + Colorstring + " intcolors:");
Serial.print(intcolors);
Serial.print(" " );
Serial.print( Numberstring.toInt() );
Serial.print(" " );
Serial.println( Colorstring.toInt() );
if(Numberstring == "mode") {
ws2812fx.setMode(Colorstring.toInt());
if(! fx_is_active){
ws2812fx.start();
fx_is_active = true;
}
}
else if(Numberstring == "speed") {
ws2812fx.setSpeed(Colorstring.toInt());
}
else if(Numberstring == "brightness") {
ws2812fx.setBrightness(Colorstring.toInt());
}
else if(Numberstring == "color") {
ws2812fx.setColor(intcolors);
}
else if(Numberstring.toInt() == 255) {
//set all pixels to the same color
if(fx_is_active){
ws2812fx.stop();
fx_is_active = false;
}
for(int i = 0; i < NUMPIXELS; i++) {
pixels.setPixelColor(i, pixels.Color(r,g,b));
}
pixels.show();
}
// needs testing:
// toInt returns 0 if it is not a number !
else if(Numberstring.toInt() >= 0 && Numberstring.toInt() < NUMPIXELS)
{
if( fx_is_active){
ws2812fx.stop();
fx_is_active = false;
}
pixels.setPixelColor(Numberstring.toInt(), pixels.Color(r,g,b));
pixels.show(); // This sends the updated pixel color to the hardware.
}
} //parse_mqtt_message
void writeframe(byte* payload, unsigned int length){
//Serial.print("TOPIC=frame");
if(fx_is_active){
ws2812fx.stop();
fx_is_active = false;
}
//write bytes to framebuffer
for (int i = 0; i < (length) ; i++) {
// Serial.print((char)payload[i]);
// Serial.print(" ");
if (i < NUMPIXELS*3)
{
framebuffer[i] = payload[i];
}
}
//write frame to LEDs
int j=0;
for(int i = 0; i < NUMPIXELS*3 ; i=i+3) {
//Serial.print(" ");
//Serial.print(j);
//Serial.print(":");
r = framebuffer[i];
g = framebuffer[i+1];
b = framebuffer[i+2];
//Serial.print(r);
//Serial.print(g);
//Serial.print(b);
pixels.setPixelColor(j, pixels.Color(r,g,b));
j++;
}
//Serial.println();
pixels.show();
} //writeframe
void callback(char* topic, byte* payload, unsigned int length) {
//Serial.print("Message arrived [");
//Serial.print(topic);
//Serial.print("] ");
//Serial.print("length:");
//Serial.print( length );
stringIntopic = String(topic);
if (stringIntopic == stringPixel ){
//Serial.print("TOPIC=setpixel");
parse_mqtt_message(payload,length);
}
if (stringIntopic == stringFrame ){
writeframe(payload,length);
}
} //callback
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("")) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish(outTopic, "hello world");
// ... and resubscribe
client.subscribe(inTopic);
client.subscribe(inTopic2);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
} //reconnect
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
ArduinoOTA.handle();
delay(20);
ws2812fx.service();
} //loop
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment