Driving WS2811, WS2812 and other NeoPixel devices from ESP8266 #5645
Replies: 1 comment
-
Posted at 2015-11-03 by @gfwilliams Just to add for others - driving WS2811/etc on normal Espruino boards is absolutely no problem at all. See the WS2811 page. @Kolban what are the chances of just fixing hardware SPI support on the ESP8266? For this specific issue that would seem to be the most sensible course of action, and would be useful to far more people? Or, maybe you could detect the specific use of Since it is possible to have 'native' functions - even in ESP8266 - I guess one other option is to have a set of native code functions that get built for each major release of Espruino, and which can be loaded in on demand - but again that's quite a lot of effort. The issue for me is I think it's good to have flexible support built in to Espruino itself, but building support for one specific bit of hardware just seems like a bad idea - even more so when it's for one bit of hardware on one specific processor. Posted at 2015-11-03 by @gfwilliams I suppose one more option is to make a simple neopixel 'wrapper' module for normal Espruino boards. We could tweak Posted at 2015-11-03 by DrAzzy Oh.... I see why you need it on the ESP8266... You can't use the SPI pin, since it only has one SPI, and that's used for the EEPROM, so any use of the EEPROM would confuse the WS2812's... Ugh. There will need to be some solution to this for the ESP8266 - it's gotta be able to drive neopixels. In general, I don't like the idea of doing that sort of thing, but I don't see an alternative for this specific case. On STM32 platforms, with multiple SPIs, I think we should stick to the current method, as it covers more than just the WS2812's, and I haven't heard people complaining that they don't have enough SPI pins for WS2812's on the normal Espruino boards.
This.... this might be a good, more general solution to this sort of case... Posted at 2015-11-03 by JumJum First of all, I would like to have more options to extend firmware by myself. Let me add my 2 cents:
What I could imagine is something like this:
Right now we have some limitations, even I know about
Posted at 2015-11-03 by @gfwilliams Yes, being able to pull in C code would be good. For me, the problem is the compiler service. I have to run a server with that on, and right now I do it, for free, for any ARM boards. Honestly I don't see any reason I should take on the maintenance headache of supporting other boards though. ... and the reason I don't allow C code right now is it seems like a security nightmare. I'd somehow have to find a way of making sure someone didn't However (and this is something I've been thinking about for a while), why couldn't users spin up their own VM and compile a custom Espruino firmware themselves? For instance Virtual x86, which runs in the browser. It wouldn't be fast, but I imagine it'd take 10 mins max to compile the Espruino firmware - I'm sure people would be willing to wait. I'd think that with a relatively small amount of hacking, someone could come up with a webpage that loaded v86 with a Linux image, downloaded the zip of the latest Espruino source code from GitHub, built it, and then let you save the result to a file. Potentially all of that could even be built into the Web IDE at some point. Posted at 2015-11-03 by @gfwilliams So someone could:
To be honest I don't really have time for this right now - I could probably get the Web IDE loading from a file though. Posted at 2015-11-03 by Kolban The good news is that I have mechanically tested calling NeoPixels from JS using a combination of C and assembler as the driver and it seems to work great. Using JS as the driver means I can write net code and use JS as the driver for the pixels. However, until and unless we reach consensus on whether or not to include it in the ESP8266 base distribution, I'll leave it out of the GIT repository. Posted at 2015-11-03 by @allObjects ...so this conversation is not really about NeoPixels. Can we change the title to something like Custom builds, of Builds on demand, Selective builds,...? ...and use NeiPixels as (the) practical example for pursuing this effort? Old technology used several steps to get 'there': compiling delivers object modules that include meta data which then in a linker were used the put all the stuff together... Tubo Pascal was a great example to get rid of this multi-step process - even the need for multi-pass compiling - to get faster to the executable. I'm not familiar enough with the tool chain/build process of Espruino (and alike), but my guts tell me that something modelled after the old world could work - and it well may already work this way, just named differently. Like every module has dependencies, module components could have dependencies... (Classes have dependencies on their members for state (data type classes) and behavior (method used classes). Java (and a lot of alikes) are stuck with atomic-granularity on the class level - matches a file. There are other implementations that go further and allow granularity on the method level: A class can be extended by adding methods without having to subclass (What I have not seen yet is comparable state extensibility). All in all, it would not be composition yet, but comes close... Javascript can do all that at runtime... but I'm looking for a build time for that: compose sources on that level. As a concrete idea, a build system could present a catalog of component and sub-components with check-boxes, with dependency support/constraints active. Checking/unchecking a functionality will also pick(indicate check) the minimal dependencies, and at the same time say what the (minimal) hardware requirements are in RAM and EEPROM, and as an icing on the cake: allow assignment of requirment compatible hardware profiles, such as PICO, Standard, ESP8266-xx,... If this all could be done in an IDE extension (additional page or left-hand side), why not... Posted at 2015-11-03 by Kolban I think we probably don't want to miss the wood for the trees. The reason that there is a current usefulness for native code in C/Assembler for NeoPixels is because they have sub microsecond timing requirements that can't be done at the JavaScript level. To the best of my limited knowledge, this appears to be the only example of such a story. If it is a very rare boundary case ... then I'd hate for us to set up an infrastructure for custom builds and there be no other value or need beyond NeoPixels. If a contributor to Espruino internals development has an hour to spare ... would we want that hour spent on custom code inclusion or would we prefer that the hour be spent burning down the open Issues that already exist? The NeoPixels story came up because there was an apparent "usage pattern" being asked for by user after user. However, I'm not hearing of other stories that seem to "require" native code (C/Assembler) support. Posted at 2015-11-03 by @gfwilliams I think realisatically that falls under @Kolban's 'However, lets be practical ...' heading :) But I think a v86-based build would work very well indeed, with minimal effort. Even that would be a great help, and Posted at 2015-11-03 by tve I'm lost here... Is this about neopixels? And can neopixels be driven by using SPI hardware? Then isn't the solution to use the available esp8266's SPI hardware interface? Or am I missing something? Posted at 2015-11-03 by Kolban A NeoPixel also known as the WS2812 has an ultra specific set of timing criteria ... see for example: https://www.adafruit.com/datasheets/WS2812.pdf We need a signal length of 0.35us to represent low and 0.7us to represent high. These have tolerances of +/- 150ns. The overall period of 1 bit is about 1.3us. As such, timing is absolutely critical. The AdaFruit sample code for an ESP8266 can be found here which uses assembly to access the ESP8266 special register called "ccount" which uses the 80MHz/160MHz clock cycle counter for this level of precision: https://github.com/adafruit/Adafruit_NeoPixel/blob/master/esp8266.c The equivalent Adruino code seems to be mostly written in assembler ... see: https://github.com/adafruit/Adafruit_NeoPixel/blob/master/Adafruit_NeoPixel.cpp Using these as references, we see both an API and an implementation that has been demonstrated to work. If it is possible to drive reliable signals at these rates using SPI, I'm afraid I personally don't know how to do that. We are also stuck on hardware SPI support on the ESP8266 and that has been an outstanding issue for a while now with no obvious resolution. If we can achieve NeoPixel driving with hardware SPI, that would be fantastic ... but in the interim, this story talks about a potential code fragment that works today using the recipes that others (Adafruit) are advocating ... as opposed to SPI techniques. If it is possible to drive NeoPixels using hardware SPI on an ESP8266, that may indeed be a breakthrough that even folks like AdaFruit would be interested in hearing about. Posted at 2015-11-03 by @gfwilliams Neopixels can be driven by SPI hardware, as Espruino has always done. You just need the clock speed to be about right, and then you can send the pulses as a series of The good thing with that is it gives you enough headroom to decode Espruino's array structures. To use Adafruit's method you'll have to decode the arrays into a flat area of memory and then feed through that... Rather than adding a hack just for flashy lights on ESP8266, if hardware SPI was working it'd make ESP8266 a whole lot more faster for all kinds of things and all the existing tutorials for WS2811 should 'just work'. Posted at 2015-11-03 by DrAzzy Isn't the ESP8266's only SPI used for the EEPROM that holds the firmware though? Or does it have a second one? Posted at 2015-11-03 by Kolban @drazzy ... There is an open issue on hardware support for the ESP8266 SPI which is Issue #606 ... espruino/Espruino#606 There are a bunch of links from there to the available docs and other forum entries. From what I can tell, it appears that one can use a hardware SPI for I/O driving without it affecting the operation of flash ... however, I for one, have not been able to comprehend the documentation to figure out a design that would allow us to include the hardware SPI support in Espruino. This is one of those areas where I had been hoping to engage an SPI skilled ESP8266 resource ... or at the very least, find others who would be willing to collaborate on bit-by-bit comprehension of the story. Posted at 2015-11-03 by DrAzzy Hmm.... I'm sure that could work in the case of "well behaved" SPI devices, with a CS pin and all that don't care what comes down the MOSI line when CS isn't asserted. But the WS2812's don't have that - I think any shit coming down the MOSI line would (or could) confuse them... Posted at 2015-11-03 by profra I have found a ready HW SPI library for ESP8266... Posted at 2015-11-04 by @gfwilliams It's a good point about the CS/MOSI @drazzy - if the HWSPI can't be connected to any other pins then it might not work for WS2811 :( Posted at 2015-11-04 by MarkusGritsch Take a look here: https://github.com/nodemcu/nodemcu-devkit-v1.0/blob/master/Documents/NODEMCU-DEVKIT-V1.0-INSTRUCTION-EN.pdf The SPI on the left side (orange SDIO pins) is used to talk to the flash. The HSPI on the right side (bright green) can be used freely. Posted at 2015-11-04 by @gfwilliams Awesome - thanks! I guess this does put a spanner in the works for someone who just wants to use WS2811 with the ESP01 board though :( Posted at 2015-11-04 by MarkusGritsch Yup, no HSPI on ESP-01 boards. Posted at 2015-11-05 by Kolban The MetalPhreak library proved to be a g*d-send ... fantastic. The latest firmware build now includes the first pas at hardware SPI and Github issue #606 contains the code which has been submitted as a pull request. Now we just need some users to test and see what happens. Posted at 2015-11-05 by Kolban One can use NeoPixels with an ESP-1 ... The first is that although the hardware SPI is not exposed on edge pins, it is still there on the physically exposed ESP8266. In "theory" one could solder on some wires directly to the SMD IC. From my perspective, I'd discount this immediately ... but Ive seen it "talked about" in some forums ... I for one couldn't solder that finely. The other option would, of course, be the 1 wire solution written in C code that had been mentioned before ... bypassing the use of SPI. As I was thinking about SPI driven NeoPixels on an ESP8266, we may have distaste for that solution. It strikes me that the hardware SPI will now consume 4 pins for driving the NeoPixel as opposed to the 1 that is strictly needed. SPI has 4 pins:
Since we will be driving data down MOSI and ignoring the other 3 pins, that may be considered a waste if users are finding themselves pin constrained. We might also find ourselves getting stuck if users need hardware SPI in addition to NeoPixel driving. For example, if the data describing the colors of the pixels over time were on an SD card which was being read by hardware SPI, we would need to introduce some form of SS to decouple it from MOSI data that it would otherwise detect when communicating with other devices. Posted at 2015-11-05 by MarkusGritsch So maybe the dedicated WS2812 driving code should just be included as well in the Espruino build for ESP8266? These are all valid points:
Posted at 2015-11-05 by tve the 4 pins don't have to be wasted. the SPI could be taught to only switch 1 pin to SPI mode, or you could switch them back yourself to gpio after initializing the spi interface. Posted at 2015-11-05 by MarkusGritsch ok. Nevertheless with SPI you can only have one pin driving a LED strip, whereas the dedicated code can use any pin. Posted at 2015-11-05 by tve yup, but the dedicated code would not leave time to drive any other pin, so why have other pins? ;-) Posted at 2015-11-05 by MarkusGritsch I didn't mean that the dedicated code handles multiple strips at the same time. You can send data to one strip and then send data to another strip. Since this is quite fast, you won't notice the delay. Posted at 2015-11-05 by tve I'm wondering whether it wouldn't be more effective to use the uart to drive the LEDs due to the fact that there's a 128 character buffer. I suspect that one could encode 3 bits per character, that one buffer-full would drive 10 LEDs... Posted at 2015-11-05 by MarkusGritsch But the start and stopbits... don't they interfere with the desired bit stream? Also, the idle state for a NeoPixel data line is a low voltage, while the idle state for a serial line is a high voltage. With major trickery it seems to be doable (see e.g. http://wp.josh.com/2014/09/03/inside-neouart-tricking-a-serial-port-into-being-a-signal-generator/), but it's probably not the way to go. Posted at 2015-11-05 by @gfwilliams That's an interesting thought - I think you might have to negate the output because the idle state is high rather than low, but potentially you could use the UART - you'd just use the start bit as part of one of the pulses. You'd have to be able to run the UART pretty quick though... Has HWSPI been tested for Neopixels? It looks to me from the code like it's unlikely to be fast enough. IMO the library really needs pulling apart in order to be able to send individual bytes with jshSPISend without having to poke a whole bunch of registers first. I think realistically adding a software library specifically for neopixels is probably the best way to go for now :( Posted at 2015-11-05 by MarkusGritsch I just did some testing (see espruino/Espruino#606 (comment)), and currently it seems not to be possible to drive WS2812 LEDs. Posted at 2015-11-05 by Kolban Another possible line of thought is starting to be captured by this issue: Posted at 2015-11-05 by tve
The UART output can be inverted and you just factor the start and stop bits into the "calculation" for the waveform. Posted at 2015-11-06 by tve If we want to go the custom code route maybe we could add a digitalVector that is similar to the digitalPulse, something like: Posted at 2015-11-06 by Kolban An experimental build is now up at: https://github.com/espruino/EspruinoBuilds/tree/master/ESP8266 This has the following extra function:
The array can be as long as you like but must be multiple of 3 in size. The pin is the Pin id of the pin you are using for the data line. The timing is hard-coded for the neopixel speeds. @tve ... I like the idea but am not yet seeing how it would work for NeoPixels which appear to be our focus de-jure. At the NeoPixel level we want a pixel to be 3 bytes/pixel ... with 8 bits for red, 8 bits for green and 8 bits for blue. Not yet sure how we would turn that into a digital vector .... Posted at 2015-11-06 by @gfwilliams I guess
Potentially we could do a simple module that looked like:
It's a small waste of memory, but it might make life easier. Posted at 2015-11-06 by MarkusGritsch I think I had to call
additionally, before neopixelWrite() did anything. (I am using GPIO2 on an ESP-01 board.) As for the test:
I have repeatedly pointed to this really excellent article which describes the needed timing: http://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/ Or, maybe just use the timings from the manuka/adafruit code, where you have taken the rest of the code from. I am going to add two screenshots... Posted at 2015-11-06 by MarkusGritsch ad 1. Attachments: Posted at 2015-11-06 by MarkusGritsch ad 2. Attachments: Posted at 2015-11-06 by JumJum First I had the same problem with all three being white.
Posted at 2015-11-06 by JumJum Oh, everything back to ground ;-) Posted at 2015-11-06 by Kolban Thanks for the feedback ... the two 100us long pulses at the start are debug that I put in ... I'll remove them for sure. I have also been testing with PL9823s as opposed to WS2811s or WS2812s. I'll next dig out some WS2812s ... and see if those start to fail. I'm kicking myself for not having tested with those in the first place. @markusgritsch ... everywhere I surf on the Internet I find your name related to these NeoPixel devices. You are certainly the most knowledgeable in that area. Folks like myself are acolytes in your footsteps here. I'll study the article you pointed at in great depth and see if I can't get the timings more accurate. If the WS2812 area for Espruino is something you yourself have particular interest in, I'll be delighted to work with you if you would be interested in getting a build environment for Espruino running at your work area. If not, your comments and timing results are EXTREMELY helpful ... thank you sir. Posted at 2015-11-06 by Kolban I tested with real WS2812s and exactly as you stated, the results were horrible. I examined my own timings and got exactly what y'all measured. The timing diagram for the PL9823s that I was using gives T0H as 0.35us and T1H as 1.36us ... while for real WS2812s ... T0H as 0.35us and T1H as 0.7us. In the actual timings now ... I have T0H as ~0.4us and T1H as ~0.95us. My tests are showing no errors. I have uploaded a new firmware ... can I ask y'all to try this build and see if we are getting closer? Posted at 2015-11-07 by MarkusGritsch Did a quick test. Seems to work fine :) The article I mentioned suggests 350 ns and 700 ns as the typical timings though. Posted at 2015-11-07 by JumJum May be, this is of help to define timing for several LED-strings. Posted at 2015-11-07 by Kolban @jumjum ... well ... that idea of yours makes perfect sense. Instead of "neopixelWrite" being a static function, maybe we create a class called "NeoPixel" with methods on it like "write" to write a stream of data and "init" to identify the data pin as well as set the T0H, T1H, T0L and T0H values. Then, in principle, any and all devices would work and all we would have to do is publish the working values. However ... at this point, given that the current neopixelWrite() method seems to be working for the majority of us ... I'm tempted to flag that as "future" and attack some of the higher priority items in Espruino land. As it is, I'm not sure we ever reached consensus on whether or not to include NeoPixel support in native Espruino (ESP8266 specific or otherwise). I'm assuming that you yourself are able to drive NeoPixels? Posted at 2015-11-08 by MarkusGritsch
I think in comment #32 (http://forum.espruino.com/comments/12608810/) Gordon already gave his blessing: Posted at 2015-11-08 by JumJum Family part of weekend is gone, and I have some time again to play with my ESP8266 ;-) Posted at 2015-11-09 by @gfwilliams Yes, I'd just add what you have for now, a utility function. I replied to you earlier on this thread as well with some ideas. I actually added something useful to the AES branch called I'll merge in today, but that should really help to simplify your code. Posted at 2015-11-21 by AlexOwen Hi, Is this currently working? I'm trying to drive a single WS2811s (in particular this circuit: https://hackaday.io/project/4603-pixiflood). I've tried using the hardware SPI implementation on the ESP8266 too but I've had no joy with that either. The LED works fine on my Espruino Pico using hardware SPI so I know that's fine. My environment is: Here's the code I've been using:
Any help would be really appreciated as I'd like to use this for a demo of some of my research on Wednesday. Thanks! Posted at 2015-11-21 by Kolban Try the following:
It may be that setting the pinMode explicitly to output is required. Posted at 2015-11-22 by AlexOwen Unfortunately that hasn't helped. I managed to get SPI1 working occasionally but only by putting a number as padding at the start of the array, but that still only seems to work some of the time.
Edit: with more testing it seems almost random what colour comes out compared to the array that gets sent. Edit 2: The hardware SPI seems to give a different output even if I send the same command several times, it looks like a timing problem to me, but that's a guess from playing around with the baud rate. It looks like software SPI is the only option for me at the moment. Edit 3: This works, but don't ask me why. The timeout and the leading 0 in the array are essential for it to reliably output the correct colour.
Posted at 2015-11-22 by Kolban By any chance do you have any raw NeoPixels to test with? I'm wondering if that circuit is giving us some problems? Posted at 2015-11-23 by MarkusGritsch Hi, I was surprised to see that the SPI approach actually worked for you, so I tried it too. The timing diagram with a logic analyzer shows, that it is barely working. The gap between the individual 4 bits is about 5,5 µs, which is on the margin of latching the sent data into the LEDs. The gap after the first byte is about 11 µs which explains the first dummy byte you had to send. In your code you specify mosi:D15 which is of no use and a bit misleading, as MOSI in the ESP8255 is hardwired to pin GPIO13. But as already said it is not evaluated anyways. Further, I saw no difference in the timings whether using the setTimeout call or not. Both produce the same output for me. Finally, I verified that esp.neopixelWrite() still works fine. Posted at 2015-11-23 by @gfwilliams When using SPI send, you can probably get more performance by putting the data into a Uint8Array first. ... did you check the signal with an oscilloscope? Your problem could be electrical - WS2811s don't like running off 5v while being driven off a 3.3v signal. It works on Espruino boards because the 5v line comes off USB via a diode, so is actually nearer 4.5v. In the docs on the site it's suggested that you put the pin into open drain mode and then pull it up to 5v with a resistor, but I'm not sure if the ESP8266 is 5v tolerant? Posted at 2015-11-23 by AlexOwen @Kolban, I don't have any real NeoPixels here unfortunately. The circuit could well be the problem. @markusgritsch, I've taken out the D15 reference for anyone that looks at it later. The timing is definitely flakey and sometimes it doesn't quite work out, but what I'm doing isn't mission critical so I don't care too much if it sometimes goes wrong. I have no idea why I needed the setTimeout(), but it was a lot more flakey without it. @gfwilliams, it seems slightly contentious as to whether the ESP8266 is 5V tolerant, but I've not had any problems using a 5V signal yet. I have some logic level shifters I'll try out too. I can borrow a scope but it's going to be a few days before I have the time to do much with it. I'll report back what I find and hopefully somewhere in there will be something useful. Posted at 2015-11-23 by AlexOwen More results. I tried using the opendrain mode with a resistor pulling up to 5V but it stopped any visible output. I also tried a logic level converter but that made it less reliable. It seems the ESP8266 is pretty tolerant to 5V after all. Completely inexplicably the esp.neopixelWrite() started working for me! I wish I knew why but I can only assume something improved when I was swapping cables around. I think I'm going to use this and leave the hardware SPI to those of you that know more what you're doing, at least for now. Thanks for all the help :) Summary for anyone that comes in to this thread later: Posted at 2015-11-23 by MarkusGritsch I tried the code from the official Espruino WS2812 example: http://www.espruino.com/WS2811 replacing the calls to SPI by esp.neopixelWrite(), but I get the error >esp.neopixelWrite(pin, arr);
Uncaught Error: Data must be an array.
at line 1 col 27
esp.neopixelWrite(pin, arr);
^ It would be nice if neopixelWrite would also take an Uint8ClampedArray or Uint8Array. Posted at 2015-11-23 by MarkusGritsch I further tried the example as is (just replaced SPI2 by SPI1), and it roughly works (neglecting the first-byte delay problem), but it runs VERY slow: The LEDs are updated only every 120 ms. Calling require("ESP8266").logDebug(false); improved it a bit but still 108 ms. Is it really supposed to run that slow? Posted at 2015-12-01 by bluebie I don't think this is a good solution for Espruino, but this I2S DMA WS2812 driver is really neat: https://github.com/cnlohr/esp8266ws2812i2s Posted at 2016-01-11 by jnewcomb Tip: My ESP-7 defaults to 160MHz when newly flashed - which runs neopixelWrite(..) at twice speed
fixed it.. Posted at 2016-01-11 by DrAzzy Yeah, current builds default to 160mhz, which offers significantly better performance. It looks like the neopixel code needs to be updated to work at 160. Posted at 2016-01-12 by tve Ugh, I did forget to update the neopixel code! Apologies. I knew I was forgetting something but couldn't put my finger on it. Please run at 80Mhz in the meantime. Posted at 2016-02-22 by creationix I've got a ton of different neopixels from Adafruit for testing (including the new GRBW variants). I can get them to work on my ESP8266 as long as I knock the CPU freq down to 80Mhz. As I helped with neopixel support on nodemcu and am adding support on my own platform for esp8266, I can help with updating the code here if someone would direct me to the right place. Also a suggestion. I bought one real espruino board (the pico) and using the SPI method I can mix GRB neopixels and GRBW neopixels just fine on the same pin. I just need need proper byte offsets in my logic. But using the esp.neopixelWrite command, I'm restricted to multiples of 3 bytes which is wrong once the 4-bytes-per-pixel GRBW hardware is introduced. We should remove that constraint. Posted at 2016-02-22 by creationix Also I just noticed that the Posted at 2016-02-22 by @MaBecker don't miss this nice and cheap ones Posted at 2016-02-22 by JumJum One more option (even cheaper and delivery from GreatBritain) could be this: Posted at 2016-02-22 by @MaBecker I definitely have to check more sides in the UK - thanks ! Posted at 2016-02-22 by DrAzzy Why are we discussing neopixel hardware here? Shouldn't we be more concerned with the bugs reported by @creationix ? What version of the Espruino-for-ESP8266 firmware are you using? As noted above, this problem was known - but I thought it was fixed! Posted at 2016-02-23 by tve @creationix which firmware version are you using? espruino_1v84.tve_master_f35ac96_esp8266.tgz is supposed to work with both cpu freq's. I tested both, but of course I may not have been thorough enough or not all neopixels are created equal... Posted at 2016-02-23 by @gfwilliams @tve for the saving, I guess it's not such a big deal - but in jsiDumpState (iirc?) it can create an init string that is executed before Posted at 2016-02-25 by tve yup, that makes sense. it's also not that difficult to set the clock freq in the onInit()... Posted at 2016-04-20 by creationix I'm trying again today. I've got what I think is the latest firmware (espruino_1v85.tve_master_66fde09_esp8266) flashed onto my brand new Wio Link (esp-12-ish). The repl works great over serial (much nicer than nodemcu's raw repl). The wio link deluxe kit comes with a neopixel strip. It works great using their provided software (HTTP based interface), now I'm trying the same hardware using espruino. No matter what I do, the pixels don't light up.
Posted at 2016-04-20 by creationix Hmm, not sure what's up. When I use my full program it does work. See for comparison. Posted at 2016-04-21 by tve Looks to me like your full program uses a UInt8Array and your short test doesn't... Posted at 2016-04-21 by @MaBecker @creationix your code is working on my ESP8266 with 1v85.tve_master_cee7141 can you try a different pin ? Posted at 2016-09-16 by Kolban Has anyone gotten the NeoPixels function working recently. When I try and run it, the first neopixelWrite() works but ones after that seem to be ignored. This is the sample I am using:
Posted at 2016-09-16 by JumJum I have the neopixelWrite working (most of the time) Posted at 2016-09-18 by Kolban I still can't get the latest builds to run my ws2812b Neopixels ... so I got out my signal viewer which is super high resolution and started looking at the signals. In my tests, I have just one Neopixel connected (again ... just for testing) and every second, change its color from red to green. This should be the byte sequence 0xff 0x00 0x00 (red) and then a second later 0x00 0xff 0x00 (green). The way that bits are sent to a Neopixel is that a "1" bit is high for longer than a "0" bit. This page gives a good reference ... https://cpldcpu.wordpress.com/2014/01/14/light_ws2812-library-v2-0-part-i-understanding-the-ws2812/ The summary is that a "1" bit should be high for >= 625ns and a "0" bit should be high for less than 563ns. My logic trace shows that we are all over the place. See the attached diagrams: What I am seeing is that the "relative" durations of highs vs lows is working but the absolute values are out of whack. @jumjum ... I'm really interested to hear what you have and have not got working. What kind of NeoPixels are you using? Do you known if they are WS2812s or WS2812b's or something else? Attachments: Posted at 2016-09-18 by JumJum @Kolban, take a look to this Posted at 2016-09-18 by Kolban In an attempt to provide more information, I created a 70 second you tube video ... see here: https://www.youtube.com/watch?v=z8TJu-3PxqA The Script I am using is as follows:
which alternates a string of 20 pixels between red, green and blue once a second. The Espruino build is the downloadable binaries for 1v87. The ESP8266 is a NodeMCU DevKit module. When I started capturing the video, all was working as expected. At about the 20 second mark, we can start to see the weirdness creep in ... this goes on until about 1:00 and then we seem to "resynch". There doesn't appear to be any patterns ... it can start generating ambiguity immediately or can be "correct" immediately ... the duration between weirdness and correctness also appears to be non deterministic. I have tried a variety of different pixels, power sources, pixel strings and pixel types. I'm very much open to the notion that I am doing something wrong in my setup ... but I'm hoping to hear experiences from other NeoPixel users ... how "stable" are your outputs? What are your configurations? etc etc. Posted at 2016-09-18 by tve I'm running the following code on a string of 8 neopixels. It walks a rainbow of colors. Not seeing any oddity.
Posted at 2016-09-19 by Kolban I spent the bulk of the day trouble shooting my issue and think I found it ... here is the story and the then the conclusion. With so many variables in my story, I wasn't sure where to start. Was it timing with Espruino, interrupts in ESP8266, bad pixel strips, bad power, bad comprehension on my part .... so many possibilities. What I did was broke out an Arduino and used it to drive my NeoPixel strip through an Arduino sketch which was an implementation of my JavaScript sketch but this time in C. It worked fine and all the pixels lit properly. I watched it for a long period of time. My confidence in the NeoPixel strip was now high. I captured a low level timing through a logic analyzer and saved the results. Then I went back to the ESP8266 and Espruino using the same strip. Again, same issues as before. I captured the input timings into the NeoPixels and generated by Espruino/ESP8266 and compared them against my "reference set" which I took from the Arduino. Although not identical, they were within tolerance of what I have been reading from NeoPixel theory. Next I had an idea ... the output of one NeoPixel feeds into the input of the next. Now I decided to capture signals from the input to the first NeoPixel to the output of the next ... and ... Aha!! We got something. When the pixels started not showing correctly, I saw that the input to the first NeoPixel looked "good" but the output from the first NeoPixel was poor ... i.e. a lot of missing high signals on the DOUT line. What this was telling me was that the first NeoPixel was not forwarding its correct sequence of pulses. Now we get to cut to the chase ... I knew that powering a NeoPixel strand from the 5V output of ESP8266 wasn't going to fly so I was using an MB-102 as a power source for the NeoPixel strand. I was delivering 5V from the MB-102s to the NeoPixels with a common ground to the ESP8266 (NodeMCU dev kit). This had been my test environment. Knowing that the Arduino was a working test environment, I took the MB-102 out of the story and powered my NeoPixels from the 5V/GND of the Arduino ... i.e. I am using the Arduino ONLY as a source of power to the NeoPixels. I obviously continue to have a common ground .... and the result ... perfection. I have been running the strand for about 10 minutes now with it right in front of me and not a single glitch. What this is telling me is that power output of the MB-102 is not sufficient/clean enough to power the NeoPixel strand. I don't have nearly enough skills in electrical or electronics to know why ... tomorrow I'm going to start studying up on MB-102s ... and also see what I have in my box of bits for a power source that is neither MB-102 nor an Arduino ... but what I have now is an ESP8266 running Espruino driving a NeoPixel strand in exactly the fashion I had hoped for and that others had said they had achieved. I'd be really interested to hear from you what you are using to power your NeoPixels/ws2812s? Posted at 2016-09-19 by tve I'm glad you got it sorted out :-) Posted at 2016-09-19 by @allObjects A single NeoPixel can 'eat up' up to 60mA, when full white light... (20mA per color...). When the load of all NeoPixel pulls, the power source may tank just enough so that the hardware logic in the NeoPixel just has not enough juice anymore to pass on a clean signal... Therefore, making sure that you source enough juice makes your day... your power consumption with full brightness - with 20 pixels - is between 400mA - 1 color, R xor G xor B - and 1200mA - all colors, R and G and B, white. With only one color on, you may run of a standard USB power - 500mA... Posted at 2016-09-19 by @gfwilliams Just to add that NeoPixels are also a bit picky on voltages for the data signal. Basically if you power them from 5v and then give them 3.3v data the result can be a bit glitchy. As a result, for Espruino boards I usually recommend putting the the pin into pulldown mode and pulling it up to 5v with a resistor (to get a 5v data signal). ... or generally if you run them from 4.3v (5v with a diode's voltage drop) then 3.3v data is good enough. Posted at 2017-02-14 by Phando Bump... Posted at 2017-02-17 by DrAzzy I know at various times, there has been a way to drive WS281x's from ESP8266 on Espruino, I think via a specific hackjob... Yah, here: http://www.espruino.com/Reference#l_ESP8266_neopixelWrite But - you will probably need to level shift the signal up to 5v. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Posted at 2015-11-03 by Kolban
While working on the ESP8266 port of Espruino, we came across requests for driving WS2811, WS2812 and other NeoPixel devices. Unfortunately, hardware ESP8266 support for SPI or I2C isn't there yet. However, others in un-related ESP8266 projects have pioneered correct driving of NeoPixels using C and Assembler. These code snippets can easily be incorporated into Espruino builds as new modules. For example:
However, just because we can do something ... never means we should. Now we have a community and project owner question. What should we do about the (hopefully few) modules that need to be implemented in the Espruino base code in C?
These are the choices I see:
We bake it into Espruino ... it is just "there" for folks to use ... it increases the firmware size by an amount but we live with it. (I think the WS2812 code came out to be an increase of about 150-200 bytes).
We don't bake it into Espruino ... but leave it in the "source" such that a custom build could be attempted by those who wish to make a custom build containing the code.
As (2) but multiple firmware builds are distributed for each release ... some with features and some without.
We don't accommodate function into Espruino that isn't "obviously" going to be used by the vast majority of Espruino users.
Let's open this up for discussion and see what we, as a community, think and can come up with. Maybe there are other ideas or solutions? However, lets be practical ... ideas such as "Let us create a build server where a custom Espruino build can be generated on demand based upon a user's selection" sure sounds awesome ... but multiply the number of boards and environments ... and monies ... that might be needed for that ... it isn't likely to fly ... and ... if it did, chances are we would have to fall back to one of the simpler ideas so that function could be delivered before such a "build machine" became practical and then we might be back at the start again.
Besides NeoPixel support, what have others heard of that might require "native C" support within Espruino?
Beta Was this translation helpful? Give feedback.
All reactions