Simple Web-Interface for WS2812B LEDs

Posted on
  • For a temporary interface for the strip of WS2812b LEDs I use to light my bed area, I built a very simple web interface making use of the jscolor library for easy colour selection. Feel free to try it out and suggest improvements, I'm sure there are plenty to be made. Anyway here's what the interface looks like and this is the code:

    var ESP8266 = require("ESP8266"),
        Wifi = require("Wifi"),
        curCol = '00FF00',
        index = '<title>Brightness</title><script src="//cdnjs.cloudflare.com/ajax/libs/js­color/2.0.4/jscolor.js"></script><form><­label>Color: <input class="jscolor" value="" name="color"><br><input type="submit">',
        arr = new Uint8ClampedArray(111*3);
    
    function onPageRequest(req, res) {
      var a = url.parse(req.url, true);
      if(a.search !== null){
        if(a.search.indexOf("color")){
          curCol = a.search.split('=')[1];
          updateLEDs(hexToRgb(curCol));
        }
      }
      if(a.pathname=="/"){
        res.writeHead(200, {'Content-Type': 'text/HTML'});
        res.end(index.replace('value=""', 'value="' + curCol + '"'));
      }else {
        res.writeHead(404, {'Content-Type': 'text/plain'});
        res.end("404: Page "+a.pathname+" not found");
      }
    }
    
    function hexToRgb(hex) {
      var bigint = parseInt(hex, 16);
      var r = (bigint >> 16) & 255;
      var g = (bigint >> 8) & 255;
      var b = bigint & 255;
      return {"r":r, "g":g, "b":b};
    }
    
    function updateLEDs(color){
      for (var i=0;i<arr.length;i+=3) {
        arr[i  ] = color.g;
        arr[i+1] = color.r;
        arr[i+2] = color.b;
      }
      ESP8266.neopixelWrite(NodeMCU.D1, arr);
    }
    
    function onInit(){
      console.log(Wifi.getIP().ip);
      require("http").createServer(onPageReque­st).listen(80);
      updateLEDs(hexToRgb(curCol));
    }
    
    onInit();
    
  • ...screenshot of the UI?

    making use of...

    That's the beauty of Javascript in the Browser: Espruino/ESP8266 needs to deliver only a minimal html5 document with references to all sorts of useful componenents as url <script src="//url"></script>. If you can trust what you pull in, then it works just perfect...

  • Sure, there was a link to try out the UI in the first post, but I've attached a screenshot here anyway.
    Indeed, HTML is also quite lenient allowing you to miss off closing statements making the code you need in the Espruino less memory hungry.


    1 Attachment

    • UI.PNG
  • Can the jscColor do events on color change? If so, you can make the colors change while clicking into or slide on the gradients. Use AJAX call to Espruino to do that. You can then also have two buttons - OK and Cancel - which keep the new color or re-instate the previous one...

    Update... yes, jsColor can do events... since it will have some delay due to latency, the code may be a bit nifty to queue the requests and when too many sit in the queue, drop some/them.

    That's a very cool and very instructional application!

  • Yes it supports an "onFineChange" event, but that would be called so many times, like you say, it will require some sort of bottle neck limit the ammount of requests to the Espruino.

  • There we go, just mocked this up, this gist is what you'd upload to the Espruino, by default its set to update every 250 ms.

  • ...modifying the html example that comes with the download... and it produced about every 17 milliseconds an event...

      var ts = Date.now();
      function setTextColor(picker) {
        var newTs = Date.now();
        console.log(newTs - ts); ts = newTs;
        document.getElementsByTagName('body'
            )[0].style.color = '#' + picker.toString();
      }
    

    Instead of talking to the console, it would be talking to Espruino... like in you mock... A socket connection can keep up with more than what AJAX can... but still is a challenge, because it has the unpredictable network delays... The best I got out of an real world app was about what you are looking at: 250ms from one Wifi LAN connected device/browser to another one via an app server/jetty of a different Wifi LAN, and the Wifi LANs connected through the Internet. The app was controlling a pointer in an html page on a mobile device / phone / tablet / desktop / smart tv by an html page on an other mobile device / phone / tablet. It was at a time when Bayeux Protocol, CometD, and Long Polling were the only things that worked cross platforms (cross platform in regard of Browser and underlaying OS). Server side there were not many options yet, but jetty was pretty good at it.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Simple Web-Interface for WS2812B LEDs

Posted by Avatar for MrTimcakes @MrTimcakes

Actions