====== NeoPixel Bandwidth Room Light ======
{{:projects:neopixel_bandwidth_room_light.gif?direct|}}
===== Overview =====
A 5 meter NeoPixel strip should light up the room. \\
The first pixel shows is calculated based on something (loudliness in the room, incoming bandwidth, ...) \\
Over time the pixels move to the next and create a pattern based real life events. \\
A ESP8266 will control the strip and will accept commands over WiFi (UDP) \\
One UDP port will accept the json data for the current situation. It will also handle the pixel scrolling. \\
Every client on the network is able to send data to it and impact the mood light. \\
**Light wars incoming!**
The ESP8266 board is a NodeMCU Amica
{{:projects:nodemcu_v0.9_pinout.png?400|}}
===== Identify Hardware =====
Depending on your OS you might need a driver. \\
MacOS caused the most trouble. First you need to make sure to identify the hardware. \\
* Boot Linux
* plugin USB cable from the NodeMCU
* dmesg
*
... usb 1-2: new full-speed USB device number 7 using uhci_hcd
... usb 1-2: New USB device found, idVendor=10c4, idProduct=ea60
... usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
... usb 1-2: Product: CP2102 USB to UART Bridge Controller
... usb 1-2: Manufacturer: Silicon Labs
... cp210x 1-2:1.0: cp210x converter detected
===== Driver =====
In this case MacOS needs a driver \\
* [[https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers]]
* sudo kextload /Library/Extensions/SiLabsUSBDriver.kext
* ls /dev | grep SLAB
* > cu.SLAB_USBtoUART
* > tty.SLAB_USBtoUART
===== Arduino IDE Config =====
* Preferences
* Additional Board Manager URLs: http://arduino.esp8266.com/stable/package_esp8266com_index.json
* Tools -> Board -> Board Manager
* add esp8266
* Sketch -> Include Library -> Manage Libraries
* Adafruit NeoPixel
===== Programm =====
#include
#include
#include
#include
#ifdef __AVR__
#include
#endif
///////////////////////////// config /////////////////////////////
// Network
const char* ssid = "yourSSID";
const char* password = "yourPassw0rd";
unsigned int localUdpPort = 2342;
char incomingPacket[255];
char replyPacekt[] = "message received";
// neopixel
const int LEDPIN = 15;
const int NUMPIXELS = 300;
int displayrefresh = 10;
int shiftpixels = 2; //2 = shift pixels, 1 = no shift
int alwaysoff = 0; //1 = blank 1st pixel if no new color
//////////////////////////////////////////////////////////////////
// usage examples:
// echo "{red:0,green:100,blue:0}" | nc -w 0 -u 192.168.x.x 2342
// echo "{red:32,green:32,blue:0,all:1}" | nc -w 0 -u 192.168.x.x 2342
// echo "{clearall:1}" | nc -w 0 -u 192.168.x.x 2342
// echo "{refresh:50}" | nc -w 0 -u 192.168.x.x 2342
// echo "{red:0,green:100,blue:0,pin:50}" | nc -w 0 -u 192.168.x.x 2342
// echo "{scroll:1}" | nc -w 0 -u 192.168.x.x 2342
// echo "{effect:1}" | nc -w 0 -u 192.168.x.x 2342
// echo "{effect:1,option1:20}" | nc -w 0 -u 192.168.x.x 2342
WiFiUDP Udp;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, LEDPIN, NEO_GRB + NEO_KHZ800);
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.printf("Connecting to %s ", ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println(" connected");
Udp.begin(localUdpPort);
Serial.printf("Now listening at IP %s, UDP port %d\n", WiFi.localIP().toString().c_str(), localUdpPort);
pixels.begin();
pixels.show();
}
void loop()
{
int red = 0;
int green = 0;
int blue = 0;
int refresh = 0;
int scroll = 0;
int pixel = 0;
int all = 0;
int clearall = 0;
int effect = 0;
int option1 = 0;
int packetSize = Udp.parsePacket();
if (packetSize)
{
// receive incoming UDP packets
// Serial.printf("Received %d bytes from %s, port %d\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());
int len = Udp.read(incomingPacket, 255);
if (len > 0)
{
incomingPacket[len] = 0;
// Serial.printf("UDP packet contents: %s", incomingPacket);
StaticJsonBuffer<200> jsonBuffer;
JsonObject& json = jsonBuffer.parseObject(incomingPacket);
if (!json.success())
{
Serial.println("parseObject() failed");
} else {
// for (JsonObject::iterator it=json.begin(); it!=json.end(); ++it)
// {
// Serial.println(it->key);
// Serial.println(it->value.asString());
// }
red = json["red"];
green = json["green"];
blue = json["blue"];
refresh = json["refresh"];
pixel = json["pixel"];
all = json["all"];
clearall = json["clearall"];
scroll = json["scroll"];
effect = json["effect"];
option1 = json["option1"];
}
}
// send back a reply, to the IP address and port we got the packet from
// Serial.println("send UDP response");
// Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
// Udp.write(replyPacekt);
// Udp.endPacket();
}
// new refreshrate received
if (refresh > 0) {
Serial.println("new refresh rate received");
displayrefresh = refresh;
}
// change of scroll parameter
if (scroll > 0) {
Serial.printf("change scroll: %i", scroll);
if (scroll == 1) {
shiftpixels = 1;
} else {
shiftpixels = 2;
}
}
// set all pixel to color
if(all == 1) {
Serial.printf("set all pixels -> red: %i, green: %i, blue: %i", red, green, blue);
for(int i=0; i=0; i--) {
uint32_t color = pixels.getPixelColor(i);
pixels.setPixelColor(i+1, color);
}
}
if (effect == 1) {
if (option1 == 0) { option1 = 128; }
fade(option1);
}
else if (effect == 2) {
if (option1 == 0) { option1 = 20; }
rainbow(option1);
}
// set color of Pixel
// new color proviced color changed?
else if (red >0 || green >0 || blue >0) {
//read current color
uint32_t CurrentColor = pixels.getPixelColor(1);
uint8_t CurrentRed = CurrentColor >> 16;
uint8_t CurrentGreen = CurrentColor >> 8;
uint8_t CurrentBlue = CurrentColor;
// if no new color was set -> reuse the old color
if (red == 0) {red = CurrentRed;}
if (green == 0) {green = CurrentGreen;}
if (blue == 0) {blue = CurrentBlue;}
// set pixel 0 in case no spesific pixel was requested
if (pixel == 0) {
// Serial.printf("New color LED 0 -> red: %i, green: %i, blue: %i \n", red, green, blue);
pixels.setPixelColor(0, pixels.Color(red,green,blue));
} else {
// if spesific pixel was request change the color and also copy pixel 1 to pixel 0
// Serial.printf("New color LED %i -> red: %i, green: %i, blue: %i \n", pixel, red, green, blue);
pixels.setPixelColor(pixel, pixels.Color(red,green,blue));
if (shiftpixels == 2) {
uint32_t color = pixels.getPixelColor(1);
pixels.setPixelColor(0, color);
}
}
} else {
// Serial.printf("no new color");
if (shiftpixels == 2) {
uint32_t color = pixels.getPixelColor(1);
if (alwaysoff = 1) {
pixels.setPixelColor(0, color);
} else {
pixels.setPixelColor(0, 0, 0, 0);
}
}
}
pixels.show();
delay(displayrefresh);
}
// Effects
void fade(int maxBrightness){
for(int brightness = 0; brightness < maxBrightness; brightness++) {
for(int i = 0; i < NUMPIXELS; i++ ) {
pixels.setPixelColor(i, pixels.Color(0, brightness, 0));
}
pixels.show();
delay(5);
}
// Fade OUT
for(int brightness = maxBrightness; brightness >= 0; brightness--) {
for(int i = 0; i < NUMPIXELS; i++ ) {
pixels.setPixelColor(i, pixels.Color(0, brightness, 0));
}
pixels.show();
delay(5);
}
}
void rainbow(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256; j++) {
for(i=0; i < NUMPIXELS; i++) {
pixels.setPixelColor(i, Wheel((i+j) & 255));
}
pixels.show();
delay(wait);
}
for(int i=0; i
===== Flash ====
* Tools -> Board
* NodeMCU 0.9 (ESP-12 Module)
* Tools -> CPU
* 80 MHz
* Tools -> Flash
* 4M (3M SPIFFS)
* Tools -> Upload Speed
* 115200
* Tools -> Port
* /dev/cu.SLAB_USBtoUART
===== Flash OTA (OverTheAir) ====
The ESP8266 with an Arduino Core provieds a possibility for a OverTheAir Update.
http://esp8266.github.io/Arduino/versions/2.0.0/doc/ota_updates/ota_updates.html
===== LED Test =====
#!/bin/bash
IP=192.168.x.x
PORT=2342
SLEEP=0.1
while : ; do
for i in $(seq 32 -4 0); do
echo Led intensity: $i
echo "{red:$i,green:0,blue:0}" | nc -w 0 -u $IP $PORT ; sleep $SLEEP
done
sleep 1
for i in $(seq 32 -4 0); do
echo Led intensity: $i
echo "{red:0,green:$i,blue:0}" | nc -w 0 -u $IP $PORT ; sleep $SLEEP
done
sleep 1
for i in $(seq 32 -4 0); do
echo Led intensity: $i
echo "{red:0,green:0,blue:$i}" | nc -w 0 -u $IP $PORT ; sleep $SLEEP
done
sleep 1
done
===== snmp2neopixel.sh ======
#!/bin/bash
GATEWAYIP=192.168.x.1 #Your gateway
SNMPCOMMUNITY=public #snmp read community string
INTNUMBER=1 #Interface number in SNMP; snmpwalk -v2c -c readcommstring | grep IF-MIB::ifName
MESASURETIME=1 #Time in seconds between messurment
INBOUNDBANDWIDTH=300000 #Max Interface bandwidth
OUTBOUNDBANDWIDTH=100000 #Max Interface bandwidth
MAXBRIGHTNESS=32 #NeoPixel brightness (max value = 255)
NEOPIXELIP=192.168.x.10 #IP of your ESP8266
NEOPIXELPORT=2342 #UDP port of your ESP8266
while true; do
TIME=$(date +%s)
OUT=$(snmpget -v2c -c $SNMPCOMMUNITY $GATEWAYIP ifOutOctets.$INTNUMBER | awk '{print $4}')
IN=$(snmpget -v2c -c $SNMPCOMMUNITY $GATEWAYIP ifInOctets.$INTNUMBER | awk '{print $4}')
if [ -z "$OUT" ] || [ -z "$IN" ]; then
msg="Unable to retrieve SNMP info."
exit 2
else
sleep $MESASURETIME
TIME2=$(date +%s)
OUT2=$(snmpget -v2c -c $SNMPCOMMUNITY $GATEWAYIP ifOutOctets.$INTNUMBER | awk '{print $4}')
IN2=$(snmpget -v2c -c $SNMPCOMMUNITY $GATEWAYIP ifInOctets.$INTNUMBER | awk '{print $4}')
if [ "$OUT2" -gt "$OUT" ] || [ "$IN2" -gt "$IN" ] ; then
clear
if [ "$TIME2" == "$TIME" ]; then
TIME=1
fi
DELTAOUT=$(echo "$OUT2-$OUT" | bc)
DELTAIN=$(echo "$IN2-$IN" | bc)
DELTATIME=$(echo "$TIME2-$TIME" | bc)
INPUTBW=$(echo "$DELTAIN/$DELTATIME/1024" | bc)
OUTPUTBW=$(echo "$DELTAOUT/$DELTATIME/1024" | bc)
echo Inbound: $INPUTBW"KB/s"
echo Outbound: $OUTPUTBW"KB/s"
INPUTPERCENT=$(echo "$DELTAIN*8/$DELTATIME/$INBOUNDBANDWIDTH" | bc)
OUTPUTPERCENT=$(echo "$DELTAOUT*8/$DELTATIME/$OUTBOUNDBANDWIDTH" | bc)
echo Inbound %: $INPUTPERCENT"%"
echo Outbound %: $OUTPUTPERCENT"%"
RED=$(echo "($MAXBRIGHTNESS*$OUTPUTPERCENT/100)+1" | bc)
GREEN=$(echo "($MAXBRIGHTNESS*$INPUTPERCENT/100)+1" | bc)
echo "{red:$RED,green:$GREEN}"
echo "{red:$RED,green:$GREEN}" | nc -w 0 -u $NEOPIXELIP $NEOPIXELPORT
else
echo "no change"
fi
fi
done
===== Webcam Motion Detection Notification =====
You can use a RPi, a webcam and [[https://github.com/Motion-Project/motion|Motion]] to send commands
on_event_start echo "{red:10,green:1,blue:1,all:1}" | nc -w 0 -u 192.168.x.x 2342
on_event_end echo "{red:1,green:1,blue:1,all:1}" | nc -w 0 -u 192.168.x.x 2342