I was looking for solutions to make a notifier to for various projects. I while back I made something similar with a small OLED screen but this time I wanted something more “wife friendly” so I set out. I had a few neopixel WS2812 RGB LEDs laying around and some NodeMCU ESPs. I went with a NodeMCU board for simplicity of micro USB power already onboard but you could use any ESP for this project and it should work.
So I started searching how to cobble them together and I found https://www.reddit.com/r/esp8266/comments/5f8x8t/mqtt_and_neopixels_with_the_arduino_ide/
Which led me to https://github.com/joshhodgson/ESPNeopixelMQTTDriver… which led me to here https://goo.gl/KdtWUz.
This was perfect. I took the ESP8266 and connected it via MQTT to subscribe to a topic for changing the colors of a WS2812 (neopixel). All you do is send RBGW code (255000000000 is red for example) via the topic.
The code works great, after changing the topics and such. But its not up to my liking. So here is my re-coded version. I basically made it easily editable, add all the variables to the top.
Now I can slap an ESP and the neopixel in something for notification. I just have to remember what each color means and I will let Node-Red send the changes when needed. Fucking awesome. I can use this for temperature, rain, mail delivery, change the color if someone has ever pressed the doorbell that day…its endless. Only downfall is one alert overrides the previous color (is that really a downfall?) so the alert is “over-written”. So if you are going to use it for say timing on something or modes of the day or what have you, single project use, then it should fit the bill.
I happened to have to have a 3D printer and came across a really nice model of a lamp (Bioh Lamp) that I decided would work perfect as a notifier. After I made some modifications and added NodeMCU standoffs it worked perfectly. Don’t get me wrong it took a few tries to get the spacing right and I tried a few approaches before using the NodeMCU so the older standoff for centering the WS2812 is still there. Unfortunately the author has is locked up pretty tight and used the Creative Commons – Attribution – Non-Commercial – No Derivatives license so I cannot share it.
I used an old Apple iPod USB cable and chopped it up wired it to the boards. Also repurposed an old iPhone charger to use as the power supply. Perfect!
Code below.
The code!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
/* * ESP8266-01 and a single WS2812 neopixel (or strip) * Connects to your wifi and subscribes to an MQTT topic * Listens for incoming RRRGGGBBBWWW codes and changes the color * Original code https://github.com/joshhodgson/ESPNeopixelMQTTDriver * May 19, 2017 * */ #include <ESP8266WiFi.h> #include <PubSubClient.h> #include <Adafruit_NeoPixel.h> // The pin the neopixel is on, I am using an ESP-01 so its 0 or 2. #define NEO_PIN 2 // how many pixels you have, max 16? #define NUM_LEDS 1 Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, NEO_PIN, NEO_GRBW + NEO_KHZ800); // Update these with values suitable for your network. const char* ssid = "xxxxxx"; const char* password = "xxxxxx"; const char* mqtt_server = "10.0.0.10"; const char* clientId = "esp-notifier"; const char* inTopic = "notifier/In/"; const char* outTopic = "notifier/Out/"; float red = 0.0; float green = 0.0; float blue = 0.0; float white = 0.0; bool fading = 0; int targetN = 0; int targetRed, targetBlue, targetGreen, targetWhite; WiFiClient espClient; PubSubClient client(espClient); long lastMsg = 0; char msg[50]; int value = 0; void setup() { Serial.begin(9600); strip.begin(); strip.setPixelColor(0, strip.Color(0, 0, 0, 0)); // default the pixel to off strip.show(); setup_wifi(); client.setServer(mqtt_server, 1883); client.setCallback(callback); } void setup_wifi() { delay(10); // We start by connecting to a WiFi network Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } void callback(char* topic, byte* payload, unsigned int length) { String message = ""; Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); message += (char)payload[i]; } Serial.println(); String thistopic = String(topic); // Serial.println(thistopic); // BLOCK COLOR - rrrgggbbbwww if (thistopic == inTopic) { Serial.println("Setting color to"); // Send a reply Serial.println(message); targetRed = message.substring(0, 3).toInt(); targetGreen = message.substring(3, 6).toInt(); targetBlue = message.substring(6, 9).toInt(); targetWhite = message.substring(9, 12).toInt(); targetN = message.substring(12).toInt() / 10; if (targetN > 0) { fading = true; } else { for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setPixelColor(i, targetRed, targetGreen, targetBlue, targetWhite); } strip.show(); red = targetRed; green = targetGreen; blue = targetBlue; white = targetWhite; } } // Rainbow? } void reconnect() { // Loop until we're reconnected while (!client.connected()) { Serial.print("Attempting MQTT connection..."); // Attempt to connect if (client.connect(clientId, outTopic, 0, false, "disconnected")) { Serial.println("connected"); // Once connected, publish an announcement... client.publish(outTopic, "connected"); // ... and resubscribe client.subscribe(inTopic); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); // Wait 5 seconds before retrying delay(5000); } } } void loop() { if (!client.connected()) { reconnect(); } client.loop(); if (fading) { int n = 0; float deltaRed = (targetRed - red) / targetN; float deltaGreen = (targetGreen - green) / targetN; float deltaBlue = (targetBlue - blue) / targetN; float deltaWhite = (targetWhite - white) / targetN; while (fading) { red += deltaRed; green += deltaGreen; blue += deltaBlue; white += deltaWhite; for (uint16_t i = 0; i < strip.numPixels(); i++) { strip.setPixelColor(i, (int)red, (int)green, (int)blue, (int)white); } strip.show(); n += 1; if (n >= targetN) { n = 0; fading = false; } delay(10); client.loop(); } } yield(); } |
This was sitting as a draft for a quite a while so I cannot remember if this is the exact code I used. If it doesn’t work let me know. My notifier works fine.
https://github.com/jhaury/esp-neopixel-notifier
Discover more from Its_All.Lost
Subscribe to get the latest posts sent to your email.