A few weeks back I made a RGB Light for my homebridge, now I wanted to see if I could make a NeoPixel Light.

First I needed a NeoPixel Led strip so I found this one.

For those who haven’t read my previous post, you must first install HomeBridge on a Raspberry Pi, and configure it as a HomeKit bridge device. For who did’t read my previous  post about the Raspian Pi update, there are a few thing changed! first read this post https://www.studiopieters.nl/raspberry-pi-a-security-update-for-raspbian-pixel/

So once again we have to alter a few things in the installation process. For a headless installation we need to add the ssh file to the root of the SD-Card. This in order to connect to the Raspberry Pi. After we have done this we can install Xrdp as described in this post https://www.studiopieters.nl/raspberry-pi-remote-desktop-connection/

But then I stumbled on a new problem.It has to do with the fact that the Raspbian Jessie with pixel, which officially stands for “Pi Improved Xwindows Environment, Lightweight”, now comes pre-packaged with RealVNC, which conflicts with both xrdp (which uses vnc4server) and tightvncserver.

So I needed a solution: Google me this google me that….

The fix:

Let’s assume you already did sudo apt-get update and sudo apt-get install xrdp.

Now, let’s disable the RealVNC install. I have tested this and followed these steps to disable the RealVNC install and allow xrdp to work:

sudo apt-get remove xrdp vnc4server tightvncserver

sudo apt-get install xrdp

Remote logins using xrdp now work. After this you can make a remote connection and follow the steps as described in this post https://www.studiopieters.nl/raspberry-pi-apple-homebridge/

When you have installed the homebridge you need to install the Homebridge-NeoPixel package in order to let the homebride communicate with your ESP8266 over http.

Edit the HomeBridge /var/homebridge/config.json file on the Raspberry Pi HomeBridge. the file may alternatively be in /home/.homebridge or /root/home/./homebridge.

add this code to the config.json file.

sudo nano ~/.homebridge/config.json

mind the last comma, you may or may not need it if you have other accessories, or Homebridge is crashing on load.



{
   "bridge": {
      "name": "Homebridge",
      "username": "CC:22:3D:E3:CE:30",
      "port": 51826,
      "pin": "031-45-154"
   },

"description": "Example configuration file for Apple Homebridge - NeoPixel",

"platforms": [

],

"accessories": [
{    "accessory": "HTTP-NEO",
"name": "Neo Lamp",

"switch": {
"status": "http://192.168.1.10:80/status",
"powerOn": "http://192.168.1.10:80/on",
"powerOff": "http://192.168.1.10:80/off"
},

"color": {
"status": "http://192.168.1.10:80/color",
"url": "http://192.168.1.10:80/set/%s"
},

"brightness": {
"status": "http://192.168.1.10:80/bright",
"url": "http://192.168.1.10:80/set/%s"
}
}

]
}

The Hardware

Now we can make our setup so we can see if everything is working. In the fritting digram below you can see that now I have added a NeoPixel Strip plus a external power supply 5V 1A.
We are keeping the RX and TX connected so we can see in the monitor from the Arduino IDE if everything is working as we want to.

Upload the program below to your ESP8266-12E

/* Project name: Apple Homebridge - NeoPixel  
*  Project URI: https://www.studiopieters.nl/apple-homebridge-neopixel-light 
*  Description: Apple Homebridge - NeoPixel Light
*  Version: 6.0.3 
*  License: GNU General Public License V2 or later  */


#include <ESP8266WiFi.h>
#include <Adafruit_NeoPixel.h>
#include <math.h>



////////////////////////////////////////////////////////////////////
// Which pin On which pin is the ESP8266-12E connected to the NeoPixels
#define PIN 13

// How many NeoPixels are attached to the ESP8266-12E
#define NUMPIXELS      144
 
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXEL, PIN, NEO_GRB + NEO_KHZ800);

///////////////////////////////////////////////////////////////////

WiFiServer server(80); //Set server port

String readString;           //String to hold incoming request
String hexString = "000000"; //Define inititial color here (hex value)

int state;

int r;
int g;
int b;

float R;
float G;
float B;

int x;
int V;



///// WiFi SETTINGS - Replace with your values /////////////////
const char* ssid = "YOUR_ROUTER_SSID";
const char* password = "YOUR_ROUTER_PASSWORD";
IPAddress ip(192,168,1,10);      // set a fixed IP for the NodeMCU
IPAddress gateway(192,168,1,1);  // Your router IP
IPAddress subnet(255,255,255,0); // Subnet mask
////////////////////////////////////////////////////////////////////

void WiFiStart() {
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  WiFi.config(ip, gateway, subnet);
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print("_");
  }
  Serial.println();
  Serial.println("Done");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println("");

  server.begin();                   
}

void allOff() {
  for(int i=0;i<NUMPIXELS;i++)
  strip.setPixelColor(i, 0, 0, 0);
  strip.show();
  }

//Write requested hex-color to the pins
void setHex() {
  state = 1;
  long number = (long) strtol( &hexString[0], NULL, 16);
  r = number >> 16;
  g = number >> 8 & 0xFF;
  b = number & 0xFF;

  for(int i=0;i<NUMPIXELS;i++)
  strip.setPixelColor (i, r, g, b);
  strip.show();
  }

//Compute current brightness value
void getV() {
  R = roundf(r/2.55);
  G = roundf(g/2.55);
  B = roundf(b/2.55);
  x = _max(R,G);
  V = _max(x, B);
  strip.setBrightness(V);
  strip.show();
}

//For serial debugging only
void showValues() {
  Serial.print("Status on/off: ");
  Serial.println(state);
  Serial.print("RGB color: ");
  Serial.print(r);
  Serial.print(".");
  Serial.print(g);
  Serial.print(".");
  Serial.println(b);
  Serial.print("Hex color: ");
  Serial.println(hexString);
  getV();
  Serial.print("Brightness: ");
  Serial.println(V);
  Serial.println("");
}

void setup(){
  Serial.begin(115200);
  setHex(); //Set initial color after booting. Value defined above
  WiFi.mode(WIFI_STA);
  WiFiStart();
  showValues(); //Uncomment for serial output

  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {
  //Reconnect on lost WiFi connection
  if (WiFi.status() != WL_CONNECTED) {
    WiFiStart();
  }
 
  WiFiClient client = server.available();
 
  if (!client) {
    return;
  }
 
  while(client.connected() && !client.available()) {
    delay(1);
  }
   
  //Respond on certain Homebridge HTTP requests
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (readString.length() < 100) {
          readString += c;
        }
        if (c == '\n') {
          Serial.print("Request: "); //Uncomment for serial output
          Serial.println(readString); //Uncomment for serial output
         
          //Send reponse
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
         
          //On
          if(readString.indexOf("on") >0) {
            setHex();
            showValues();
          }
     
          //Off
          if(readString.indexOf("off") >0) {
            allOff();
            showValues();
          }

          //Set color
          if(readString.indexOf("set") >0) {
            hexString = "";
            hexString = (readString.substring(9,15));
            setHex();
            showValues();
          }
         
          //Status on/off
          if(readString.indexOf("status") >0) {
          client.println(state);
          }

          //Status color (hex)
          if(readString.indexOf("color") >0) {
          client.println(hexString);
          }

          //Status brightness (%)
          if(readString.indexOf("bright") >0) {
          getV();
          client.println(V);
          }
         
          delay(1);
          client.stop();
          readString="";
        }
      }
    }
  }
}

Now we have to connect our iPhone to the home bridge and add the new accesoires.

Hooray! It works!

Download all Files for this project on github

Do you have any questions? Leave a comment down below!

Pin on Pinterest2Share on Facebook0Share on Google+0Tweet about this on TwitterShare on LinkedIn0Buffer this pageDigg thisEmail this to someone
Flattr the authorShare on Reddit0Share on StumbleUpon0Share on Tumblr0Share on VKShare on Yummly0
  • Should this work with neopixel ring as well?

  • Yes, this should work with a NeoPixel Ring as well!
    I would recommend reading Adafruit NeoPixel Überguide for more information.

  • Thanks! Will try tonight!

  • Great! Let me know how it worked out!

  • Should the URLs be pointed towards a server or to the ESP8266’s static IP?
    I’ve only been using MQTT before.

  • The IP address has to correspond with the ESP8266’s static IP. This way the homebridge server and your ESP can communicate.

  • Got it working with a 16-diode ring! looks great! Thanks for the tutorial

  • You’re welcome!

  • Please share my post on your social media, so more people can enjoy this post!

  • Jimmy Patrick

    Can this work at the same time as ‘homebridge-better-http-rgb’? It doesn’t on my system. everything gets stuck with a status of “Updating.”

  • As far as I know it should work, The error you describe is sounding familiar, make shore your hardware is connected properly. This error appears when there something wrong with the power supply, your ESP wil reset. Therefor make shore you have the right capacitors and your power supply is sufficient (5V, 1A). This should resolve your problem.

  • Jimmy Patrick

    I see. So is each homebridge-neopixel blocking? So if one of my ESPs goes down it will stop my entire hombridge from updating? Is there a timeout, where I there is no response, that can be noted for that fixture, and homebridge can carry on? I’m not sure how to see the source of an NPM, and I don’t understand much about javascript, but I’ll take a look. Thanks for the response!

  • Lethegrin

    Is there a way to add options when selecting the light to trigger a custom light pattern? These are neopixels after all! i.e. could I add a “rainbow chase” option which would activate a rainbow animation that I added to the flashed program?

  • That should be possible you need to add code: https://learn.adafruit.com/multi-tasking-the-arduino-part-3/recycling-the-rainbow to the Arduino Part, then you need to add the option to the plugin so that when you want the “rainbow” to show, Siri knows that when you ask for the “rainbow” it has to excute this code.

    if you want it always, when you turn it on or of, to show the “rainbow”just replace:

    //Write requested hex-color to the pins

    void setHex() {

    state = 1;

    long number = (long) strtol( &hexString[0], NULL, 16);

    r = number >> 16;

    g = number >> 8 & 0xFF;

    b = number & 0xFF;

    for(int i=0;i<NUMPIXELS;i++)

    strip.setPixelColor (i, r, g, b);

    strip.show();

    }

    with the rainbow code, so it will execute 😉

    Good luck, and let us know when you have it working!

  • Lethegrin

    Hey, thanks for the reply. I’m not looking to replace any of the RGB functionality. I would simply like to add for example “rainbow” as an option as you suggested. Could you give me an example of what I would need to add to your plugin to get siri to recognize it as an option? I’m not familiar with it.

  • Well there isn’t a out of the box solution for that. You need to know how to program in C or C++, JavaScript Object Notation. if you have this knowledge, then i would recommend reading the information that the founder of homebridge added regarding plugins (https://github.com/nfarina/homebridge) the plugins are based upon a NPM package using HAP-NodeJS. It took me also some time gathering all information needed to setup this plugin in and hardware. As I’m sharing this information for free, there are somethings you need to figure out yourself.

  • Lethegrin

    I see. Well I’ll do some research.

  • eqsone

    Nice work, though my altered ‘getV’ function puzzles me by now. It’s supposed to calculate a given hex-color into a matching 0-100 ‘brightness’ value to be passed to Homekit on request. This actually has been the trickiest part for me to understand in communication with Homekit when I had to draw a sketch for classic RGB stripes. Obviously your ‘getV’ now gets and SETS this brightness value to the LEDs, while LED brightness already results of the color value it was set to. Besides that, adafruit states setBrightness() was intended to be called only once in setup. Well, still waiting for my neopixels to arrive, some fiddling with them might enlighten me about this..

  • Menno Broere

    Nice work! I got it to work thanks to you!

    I want to make a Letterbox with Neo pixels and control every letter individually as a RGB Light. It would be great to run this from a single ESP8266.

    How should I approach this? Should I make a new homebridge accessoir and send this over another port or should I change the sending value’s?

  • @ Menno Boere

    Thank you for your compliment.

    Regrading your question, that depends of the number of letters and if you want to control each letter separately?

    Normally, each Neo string is a new hardware setup. you need to give each setup a unique name in the config.json file.

    Pleas post a photo of your setup so others can see how you build your

    Apple Homebridge – NeoPixel Light 😉

  • Menno Broere

    Thanks! I haven’t build it yet. I’m more testing the basics. Eventually it should be the letters “LUX” which could be controller individually running on a single ESP8266. Ideally I also attach a Temperature and Humanity sensor to give feedback to home bridge. But thats another story.

    I testing on a single ESP8266 with a 16 pixel neopixel ring to this. So I could test different colours on the leds. But for now my Arduino sketch runs as a single RGB receiver and runs as letter L.

    So my first step is to add an extra accessory to homebridge and changed the parameters like below. Homebridge still runs and the letter L still works as long as I don’t touch the letter U. When i turn the U light off the L letters also goes off. They sort of interfere. Any idea how to solve this?

    { “accessory”: “HTTP-RGB”,

    “name”: “L-Lux”,

    “switch”: {

    “status”: “http://192.168.2.200:80/status”,

    “powerOn”: “http://192.168.2.200:80/on”,

    “powerOff”: “http://192.168.2.200:80/off”

    },

    “color”: {

    “status”: “http://192.168.2.200:80/color”,

    “url”: “http://192.168.2.200:80/set/%s”

    },

    “brightness”: {

    “status”: “http://192.168.2.200:80/bright”,

    “url”: “http://192.168.2.200:80/set/%s”

    }

    }

    ,

    { “accessory”: “HTTP-RGB”,

    “name”: “U-Lux”,

    “switch”: {

    “status”: “http://192.168.2.200:80/status2”,

    “powerOn”: “http://192.168.2.200:80/on2”,

    “powerOff”: “http://192.168.2.200:80/off2”

    },

    “color”: {

    “status”: “http://192.168.2.200:80/color2”,

    “url”: “http://192.168.2.200:80/set2/%s”

    },

    “brightness”: {

    “status”: “http://192.168.2.200:80/bright2”,

    “url”: “http://192.168.2.200:80/set2/%s”

    }

    }

  • @mennobroere:disqus

    First of all putting all on one ESP8266 will seriously stress it.
    But your problem lies in the Code you write to your ESP.

    You need to define each letter and address it separately. So first you need to figure out how to define each letter in the code. maybe this will help: https://learn.adafruit.com/adafruit-neopixel-uberguide/the-magic-of-neopixels

    Once you figured out how to define each letter,like for example neopixel-l, neopixel-u and neopixel-x you will be able to adress it trough the config.json file. Now each letter wil respond to its own settings. Theocraticly …

    good luck!