Puck.js and Neopixels – Possible?

Posted on
  • I've got a Neopixel Ring (12 LEDs), and two Pucks. I know they run on different voltages, so I've connected the Neopixel to a 5v USB supply, and used an opto-isolator to drive the data pin at 5v from the Puck.

    I can't figure out how to make it work, though.

    I've cobbled this together from various posts that I've found, but I assume I'm doing something wrong (or the Puck can't do the data rate I need perhaps?):

    const PIN = D30;
    const LEDS = 3;
    function main() {
      pinMode(PIN, 'output');
      // I'm using 400000 here because I read they need a 4- or 8kHz stream, but no dice.
      SPI1.setup({ baud: 400000, mosi: PIN });
      let arr = new Uint8ClampedArray(3 * LEDS);
      let idx = 0;
      for (let i = 0; i < LEDS; ++i) {
        arr[idx++] = 255;
        arr[idx++] = 0;
        arr[idx++] = 0;
      SPI1.send4bit(arr, 0b0001, 0b0011);

    I've confirmed that the isolator can do upwards of 50kHz, and that it's working (by using a plain LED and setting D30 high – it lights from the 5v rail).

    Help! Thanks in advance.

  • Connect the grounds of both puck and neopixel. You don't need an isolator between, neopixels normally run with an input signal of 3.3V. Isolators tend to make a sine wave out of a rectangular wave pattern ;-)

  • Unfortunately I'm yet to update the documentation - it's got a lot easier recently :)

    As of 1v92, you can use require("neopixel").write: http://www.espruino.com/Reference#l_neop­ixel_write

    The Puck's current SPI.send4bit implementation isn't fast enough to send all the data without gaps (especially when the Bluetooth stack kicks in), so it was easier to use a specific function to handle it. I took the opportunity to make something that works the same across all devices.

    Only gotcha is there's still some annoying bug where the first LED seems to be set to random colours. Other than that it all works great though.

    In terms of voltages, an opto is probably great. You can connect it direct if you're running Neopixels off of 3.5-4v (so directly off a LiPo), but yeah - if you try and run them off 5v you'll hit problems, and the Puck's IO isn't 5v tolerant so you can't do the resistor + pulldown trick that you could on STM32 boards

  • @Spocki – Hmm, that's weird. I read elsewhere that they need a 5v supply and data line.

    @Gordon – ah, amazing! I'll update to 1v92 and see how I get on after that. Thanks!

  • I've found it's a bit touch and go with the voltages - it depends on the type of pixel. Generally you can connect neopixels straight to a normal USB Espruino board because there's a diode from USB volts. That drops the voltage by 0.7v or so to 4.3v, which means they're fine off of 3.3v data.

    However sometimes if you plug them into a USB wall supply, they often give out 5.5v which means the pixels get 4.8v - which is then too much for reliable data :)

  • I've powered the ring off the 3.3v line of my power supply, and connected D30 direct to the ring's data pin, and now it's working!

    Every so often, it has a bit of a wobble, but I think there's weird capacitance or grounding issues making the signals a bit unreliable.

  • but I think there's weird capacitance or grounding issues making the signals a bit unreliable.

    It's not just you. I just tried it out here (I told @benjaminbenben I'd look at it a while back too) and there's definitely some extra stuff being sent right at the end of the data that'll be confusing some of the LEDs. Hopefully a little more digging around and I'll have a fix for it though.

  • Well, that took longer than expected. I'd used a neopixel library from somewhere else, and it had some interesting issues - looks like the extra info being output to the neopixels was in fact the contents of the stack :/

    In a few minutes you should find a binary here, which has it all fixed.


    @benjaminbenben ^^^

  • @Gordon WOAH. That's such awesome news - thanks so much for fixing that.

    I'm heading out today, though I'm looking forward to giving it a try (I can stop telling people that the first light is intentional to show me that it's powered on!)

    I'm not sure if I said, but I built a E.neopixel stub that lets you try out animations in a browser https://github.com/benfoxall/ador-puck-d­emo/blob/master/stub.html - I found it pretty useful for working out animations. It's a bit wrapped up in the mqtt stuff I was working on, but I could probably pull it out if useful.

  • Thanks! The neopixel stub looks great! Just having it linked here is probably a good start.

    Actually if there were a jsfiddle/similar with it in then I could link to it from the neopixel page as a way for people to test out their patterns?

  • @Gordon cheers! I've put together a bit of a test page here https://benjaminbenben.com/espruino-pixe­ls/ it's got a couple of examples from the docs, and the flood one I was using for my web-bluetooth lights. Hopefully it'll be useful for other people (would love to see a few more examples if anyone can contribute.)

    If it's more useful to have it in a jsbin - I could do that too.

  • Wow, no - that's awesome! I've got to update the neopixels page anyway to mention the new multi-platform way of doing things, so I'll stick a link to that in there!

  • Hah, brilliant! I built a little library to make it a little simpler for myself – I kept mixing up pixel index and the fact that each one is made of 3 array elements.

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

Puck.js and Neopixels – Possible?

Posted by Avatar for Drarok @Drarok