User Tools

Site Tools


projects:neopixel-bandwidth-room-light

This is an old revision of the document!


NeoPixel Bandwidth Room Light

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 ESPP8266 board is a NodeMCU Amica

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

Arduino IDE Config

Programm

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <ArduinoJson.h>
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

///////////////////////////// config /////////////////////////////
// Network
const char*  ssid         = "your_wifi_ssid";
const char*  password     = "our_wifi_psk";
unsigned int localUdpPort = 2342;
char incomingPacket[255];  // buffer for incoming packets
char replyPacket[] = "message received";  // a reply string to send back

// neopixel
const int LEDPIN          =   15;
const int NUMPIXELS       =  300;
int displayrefresh        =   10;
//////////////////////////////////////////////////////////////////

// usage examples: 
// echo "{red:0,green:100,blue:0}" | nc -w 1 -u 192.168.x.x 2342
// echo "{red:32,green:32,blue:0,all:1}" | nc -w 1 -u 192.168.x.x 2342
// echo "{clearall:1}" | nc -w 1 -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      = -1;
  int green    = -1;
  int blue     = -1;
  int refresh  =  0;
  int all      =  0;
  int clearall =  0;
  
  int packetSize = Udp.parsePacket();
  if (packetSize)
  {
//    Serial.println("Read Packet");
    // 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);
//      Serial.println("Parse Packet");
      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"];
        all      = json["all"];
        clearall = json["clearall"];
      }
    }

    // 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(replyPacket);
//    Udp.endPacket();
  }

  // new refresh rate received
  if (refresh > 0) {
    Serial.println("new refresh rate received");
    displayrefresh = refresh;
  }

  // set all pixel to black if clearall was set to 1
  if(all == 1) {
//    Serial.println("set all pixels");
    for(int i=0; i<NUMPIXELS; i++) {
      pixels.setPixelColor(i, pixels.Color(red,green,blue));
    }
  }

  // set all pixel to black if clearall was set to 1
  if(clearall == 1) {
//    Serial.println("clear all received");
    for(int i=0; i<NUMPIXELS; i++) {
      pixels.setPixelColor(i, pixels.Color(0,0,0));
    }
  }

  //shift pixels 
  for(int i=NUMPIXELS; i>=0; i--) {
    uint32_t color = pixels.getPixelColor(i);
    pixels.setPixelColor(i+1, color);
  }

  //set color of Pixel 0
  // new color proviced color changed?
  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 new color < 0 reuse the old color
    if (red   < 0) {red   = CurrentRed;}
    if (green < 0) {green = CurrentGreen;}
    if (blue  < 0) {blue  = CurrentBlue;}
    
//    Serial.printf("New color LED 0 -> red: %i, green: %i, blue: %i", red, green, blue);
    pixels.setPixelColor(0, pixels.Color(red,green,blue));
  } else {
//    Serial.printf("no new color");
    uint32_t color = pixels.getPixelColor(1);
    pixels.setPixelColor(0, color);
  }

  pixels.show(); 

  delay(displayrefresh);
}

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 <IP> | 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
       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" | bc)
       GREEN=$(echo "$MAXBRIGHTNESS*$INPUTPERCENT/100" | bc)
       echo "{red:$RED,green:$GREEN}"
       echo "{red:$RED,green:$GREEN}" | nc -w 0 -u $NEOPIXELIP $NEOPIXELPORT
     else
      echo "no change"
    fi
  fi
done
projects/neopixel-bandwidth-room-light.1508057064.txt.gz · Last modified: 2017-10-15 08:44 by trinitor