-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Node support for ws2812 #24
Comments
How can I help with this? I realized that the T1 was using custom firmware support to make this work, do we need the same approach or the current setup is more flexible in this regard? |
Yes, we need to write some custom firmware. Here are some notes I've taken:
Will research a bit more later. |
Starting this work here. |
Ah! Just seen the PR! My microcontroller skills are a bit dented at this level (honest, I tried looking at the SAMD21 datasheet...), so I resort to believing you that this is going to be great 😜 |
That's probably more trust than I deserve :) |
My two requests:
|
So I am working on this but I've never written this kind of firmware before so I'm frantically reading to get caught up. Any and all assistance is appreciated. |
@nodebotanist have you looked through the readings I suggested here? It's pretty dense and I, frankly, didn't understand all of it. If you have specific questions after looking through those sections, call out me or @kevinmehall and we might be able to help. |
@nodebotanist @johnnyman727 Pals, I'm on board with this! I really want to help, but my C knowledge is limited. Getting started with it all is confusing to say the least. Has anyone else been working on this and made any progress? |
Turns out the documentation beyond the datasheet is actually incredible! Here's a link to the documentation for the drivers used by the SAMD21: http://www.atmel.com/search.aspx?q=sam%2Bd21%2Bdriver&filter=p&btnG=Search&client=search_frontend&proxystylesheet=search_frontend&output=xml_no_dtd&getfields=*&oe=UTF-8&ie=UTF-8&ud=1&ulang=&sort=date%3AD%3AL%3Ad1&entsp=a&wc=200&wc_mc=1&exclude_apps=1&site=en_collection |
If we can break out all possible C APIs to JS then I think the community creating libraries to have opinionated syntax is best. I know I'd be happy to do so - I'm just no C programmer so will be happy to write JS libraries ;) |
Why does this need to be in t2-firmware at all? The C code can be written as a compiled module that gets built through our pre compilation system, right? Not all Tessels will want this and shouldn't have the additional burden unless they opt-in. This issue was filed way before we had any compiled module support, and now we have strong compiled module support. |
A fair point. |
Agreed. Any chance we could get an official repo up on Tessel's GitHub account for this and we'll take the chat there? |
@rwaldron this can't be a pre-compiled module because that mechanism is used to patch in binaries that run on the MediaTek. Neopixel firmware would need to run on the SAMD21 and we don't have a mechanism for updating that binary on the fly. |
ooo well then it really does need to be in the binary. Either way - as long as the API is exposed to either C hooks or JS the actual writing of interface and control libraries can be written by the community. |
So, there's still not any real traction on this yet? Could anything be gleaned from FastLED and its SAMD support (Arduino Zero, MKR1000 and Wino)? |
@dougalcampbell I don't think anyone is working on WS2812 support at the moment but @nodebotanist recently got Dotstars (very similar to WS2812 but with a "better" interface) working on T2: https://twitter.com/nodebotanist/status/753590795823964161 |
Dotstars have a "better" interface but are a worse LED solution overall and less flexible (and less popular) as they only come in strips, which are much less useful generally. NeoPixel support is important to be taken credibly in a maker-scene that is rife with them. If the hardware can be controlled by JS with sufficient clock accuracy there's no reason why this even has to be a C module. Anyone know if that's possible? |
for example: this library can control them over an I2C interface: does the Tessel 2 have that/break it out at all? |
Hey so that demeaning and explanatory tone does not help. I personally am I Second, if we didn't plan to figure this out at some point we'd have closed --Kas On Tuesday, July 26, 2016, Gregory Wild-Smith notifications@github.com
|
Demeaning is pointing out that the dotstars are not a replacement for neopixels and asking about about actual solutions to the task at hand... ooookay. What a toxic attitude you have. |
@johnnyman727: Thanks for pointing out the DotStar work by @nodebotanist. So there's probably hope for APA102 strips, which also have a clock line. @abritinthebay: That node-pixel solution is using I2C to talk to an Arduino, which is actually driving the pixels. But then the t2 isn't actually driving the pixels, it's just doing communication. It's a solution, but the real goal will be a native implementation. I'm passingly familiar with the real-time timing constraints that make WS2812 difficult. Does the t2 give access to DMA in a way that you could implement a driver similar the one for RasPi? |
Well at least you agree... Look, I appreciate the work you've put in here -seriously - but I'm also trying to find solutions to this problem as well (it's important to projects I work on/prototype). A reply (not by you) that said "try something else that doesn't actually solve the problem space" wasn't actually as helpful as it thought. I pointed the issues with that solution out - not that it was a bad thing by itself (dotstars are neat, limited atm, but very neat). Wasn't being demeaning - I was explaining why it wasn't a complete solution. Rather than just rudely say "it doesn't fix the problem" I tried to explain why. I guess as you are even more invested than me you're better qualified to answer the question: What is the best starting point to get support for them? T1 had support and if anything was more complex and abstracted away from the hardware so what's the difference between T1 and T2 that's the blocker here? |
Just putting a reminder in this issue that Tessel has a Code of Conduct (https://github.com/tessel/project/blob/master/CONDUCT.md) we expect all participants to follow. @abritinthebay A lot of prior research has been done around this issue already, see #24 (comment) as an example. I appreciate you participating and checking in on the progress. We are still working on solutions, including a working proof of concept with Dotstars. Let's keep this conversation constructive. |
Meta Comment: the Tessel Steering Committee discussed the conflict that arose over this issue at the weekly Steering Committee meeting and you can read the notes here. From a technical perspective, animations (on any LED hardware) can be a tricky task - they are not just timing-dependent but are relatively memory-intensive. The tl;dr is that I think it's a non-trivial problem to get Neopixels working, they may never work on T2 without changing the system architecture, and Dotstars are a reasonable alternative (only currently for projects that require strips as @abritinthebay points out). From my experience, Tessel 2's timing resolution from JavaScript is on the milliseconds scale. I don't think it will likely work out if we try to bit bang out the WS2812 protocol from JavaScript. One productive step for a community member to take, would be to confirm that with an o-scope/logic analyzer. We could potentially do this at the required resolution by writing a driver in the firmware using the SAMD21s TCC peripheral. I outlined that strategy in an early comment here. We went this route with Tessel 1 using the NXP microcontroller's SCT peripheral instead of Atmel's (almost) equivalent TCC. However, even if we had that driver written now, we could have issues with running smooth animations because of scheduling limitations. Tessel 1 was unique in that we had a single microcontroller doing everything: it allocated the memory necessary for the animation, setup the TCC configuration to modulate the output pin, and handled hardware interrupts when it was finished processing each bit of data. Tessel 2 is more complex; here is the process that would have to go down to animate Neopixels:
The biggest question mark in my mind, is how well it will actually handle those animations. The SPI data packet for each command is currently a maximum of 256 bytes so all of the animation data would likely have to be written over multiple (many?) transactions (assuming #115 gets merged first). We can experiment with making that size bigger but I'm not sure how much, if any, RAM is available on the SAMD21. The microcontroller on T1 had significantly more RAM so this wasn't as much of an issue. The TCC (I believe) also has an option for double buffering so the contents from the first batch of animation data can be sent out on the wire while the second batch of data is coming in over SPI and being configured with the TCC. As you can see, there are a lot of factors at play here: RAM size determines how much of an animation we can animate at a time and therefore how long the animation persists, while the OpenWRT scheduler determines how often the SPI daemon sends over that data. It's totally possible that it will all work smoothly but it's difficult to determine without actually building it out which is a pretty significant time investment. @abritinthebay does that answer your question? I don't mean to be a downer here, I just think this feature would be difficult to add given the T2 architecture. I'm happy to help/support anyone who wants to work on any of the following tasks that could help move it along:
|
Yes, it does. Thank you. Exhaustively even. I think, outside of the internals of the Tessel team, this may have been under-communicated. It my feel like very old/common information but it's not really well detailed on this thread (until now). Thank you. It's disappointing to hear the Tessel 2 may be a non-starter for many of the projects I was hoping to use it for (given the T1 had support), but I understand. I guess I will have to rethink how Tessel fits into my projects and plans for now. |
@johnnyman727 Thanks for those details! I'm practically certain that you'd never be able to make a 100% JS solution work. The timing requires precision down to about 250ns. I found the Just In Time site to be helpful in understanding the challenges. Personally, I wouldn't care too much about an animation API, as such. If I could just feed a bunch of RGB values into a buffer array, all I'd really need would be a function that would feed the buffer to the strip via the driver, and another function that would clear the strip (latch the data pin low long enough for a reset to black). Even if managing "animation" myself by manipulating the buffer is slow, it would be better than nothing. 😄 I wish I knew enough about the low-level hardware/C/asm to offer help with the coding. I know a little about hardware, and I can understand almost all of what's going on in the assembly on the Just In Time site above, but I'm mostly a high-level guy. |
@abritinthebay Sorry about that. In all honesty, I hadn't thought through the implementations thoroughly enough until recently. @kevinmehall might have some tips on how a better implementation or point out mistakes in my logic.
@dougalcampbell that sounds reasonable to me. I also documented the process of building support for WS2812 on T1 a couple of years ago here. That could be useful for understanding the type of driver that needs to be written (but it will be a little bit different since it's a different MCU). |
To provide some additional context to the challenge of this and some solutions too. Apologies for length - there's quite a few considerations in here. On current hardware you cannot guarantee the timing constraints needed in JS to reliably get a length of pixels to update on anything longer than a handful. The timing cycles are short yes, but more importantly they don't have a lot of slack in them to mark when a frame is complete. The implication of this is that whilst you may get it to work for less than a handful of LEDs you can't guarantee you'll keep the timing over a long length as you pass the data through the length. This means the update cycle will occur when you're only half way through pumping the data along and not only will half your length of LEDs not light up, the other half will be out of position. One inopportune GC or a process switch and you can drop the whole frame through a mistimed latch - this happens surprisingly often with long lengths of pixels. Great if you like glitch, not so handy if you want to do something useful or accurate. Most importantly it's sub microsecond accuracy that is needed - at a resolution of about 100ns to get by from whatever language you are going to use. There were points about not needing animation and the like, that's all fine but the reality is that for a viable solution to work you need to be able to individually address any given pixel at a reasonable framerate for updates. If you only want to have a whole strip that is one colour then there are far cheaper solutions to this with straight RGB LED strips with 3 analog inputs. On the other hand if you do your animation at the JS level which is also viable, you then have to pump all of that data down to the pins as a buffer. This is possible but lowers your throughput. To do this accurately you need to do it as close to the metal as possible which in the case of the tessel would mean extending the firmware to make it work. I haven't got a tessel 2 yet (Australia - price & timing to get them still means I'm waiting) so I can't determine exactly what would be needed to add a module to it but can guess it's non-trivial and will be tessel-specific. The idea of extending core firmware was discussed long and hard by a group of Johnny-Five developers and users during and after RobotsConf in 2014. In the end we abandoned the idea of natively extending firmata because of the resources that are taken up to manage large numbers of pixels. What needs to be considered is not just how long it can take to update a frame that contains lots of pixels but also the memory overhead required to hold the state of those pixels (1 byte per colour channel per pixel). You can very quickly consume the entire resources of an MCU and not leave it capable of doing anything else. DotStars and other types of controllable RGB LED are better, however they are typically much more expensive ($1 per pixel is very expensive - I can't afford to spend literally thousands of dollars on LEDs for one display), limited in form factor etc. The approach taken by the J5 team was to offload the heavy lifting to an I2C Backpack. This is what node-pixel does and created the purpose of the Interchange project. The node-pixel I2C backpack can control several hundred pixels at high frame rates and only requires changed data to be sent to the backpack to deal with framing and timing. The current price on a pro-mini or nano is sub $2. You also get the benefit of being able to use node-pixel which will make your life easier too. Whilst "native" solutions are handy, the tessel isn't the only SBC in the ecosystem that wants to use controllable RGB LEDs so if people are interested in writing and optimising firmware then I'd love to have you over in the node-pixel project where there are serious optimisation and firmware tasks still needing to be done to eke every last drop out of the backpack solution that will work for every board that can use I2C (and using NodeBots or not). Having spent the last several years working with these pixels at large and small scale on a variety of platforms, I'm happy to help (once I can get my hands on a tessel) however I still believe that a board-agnostic approach is more viable in the longer term for the ecosystem as a whole. |
@ajfisher: I appreciate that node-pixel offers a solution now. But there are going to be people (like myself) who are surprised that the t2 doesn't have "out of the box" support for NeoPixels. Especially when they can be driven on something like a 8MHz ATtiny85. Of course, I realize that t2 is a different platform, with different constraints, and a different ecosystem. Expectations aside, I'm pretty sure it should be possible to implement something in the t2 firmware that can drive some reasonable number of pixels ("reasonable" defined mostly by memory limits), without concerns about starting a new update halfway through the last cycle or something. I don't know enough about how things fit together to say that with 100% certainty, but given what I've read about drivers for the RasPi, BeagleBone, etc. It looks like the general strategy is to use DMA and PWM, converting the actual bytes into a stream of 1s and 0s that can approximate the WS2812 timing. For example, this RasPi driver transforms every source 1 bit into I gather that the SAMD chip is what drives the hardware ports on the t2, while the MediaTek chip handles OpenWRT, wifi, JavaScript, and such. I would think the general strategy could be something like:
The trickiest part, obviously is the SAMD-side of the |
@dougalcampbell, that's basically correct. T2 has the SAMD21 coprocessor for exactly these kinds of low-level timing-critical code; it just takes someone interested in implementing firmware for it. Hardware resources aren't necessarily limiting there. It's significantly more powerful than the Arduino Uno, for instance, and it has a DMA controller, which is key for keeping timing without completely blocking execution. There are two firmware steps needed to add support:
Then JS code could prepare the waveform for a frame in a buffer, and send it over to the coprocessor to be played back on the pins with exact timing. |
I was able to use the SPI interface clocking at 2.4MHz to control a Neopixel strip but was only able to address about 20 LEDs because of the buffer size limitation. @kevinmehall 's suggestion to use chained DMA sounds like a plan. I'll see if my limited knowledge is sufficient to come up with something to contribute here. |
I just noticed that #115 was merged and closed recently. |
So this finally came out of that giant jar of side project ideas to work on while (for lack of wanting to reveal more) coding to distract myself. I'll be noodling with this based on @PaintYourDragon 's work with the Adafruit Feather M0: https://learn.adafruit.com/dma-driven-neopixels/overview This may provide a little more stability over using the SPI functions (mostly avoiding edge cases or folks trying to mod the SPI to meet neopixel's timing demands) |
@qimyi - how did you manage that? I need to address only 12. Anything to share? |
Currently investigating the Adafruit PXL8 library on an Adafruit Feather running on a SAMD21 chip, if it works I might need guidance to get the lib on the T2 but I think this could work. |
Okay, so the lib works perfectly on SAM21 via Adafruit Feather M0. Need guidance as to how to run a C lib on the T2 to test the library on the SAMD21 on the T2. @johnnyman727 @flaki @Frijol any suggestions on where to start? |
I couldn't get that lib to work even after a LOT of trying |
@nodebotanist You should be able to update the SAMD21 using |
Thanks @HipsterBrown I'll try that tomorrow! |
You are talking about https://github.com/qimyi/party-lights ? |
Yes |
So I tried to wire up the NeoPXL8 lib and I don't think just using that library is the right approach. However, I think we can use the knowledge within it to add DMA-ready WS2812 support to the T2 firmware. This is still far from finished, but we're making some good progress. |
@nodebotanist Thanks for your continued work on this front. 😄 |
Can someone tell me what the div argument byte required for CMD_ENABLE_SPI is? Source: Line 211 in b67e803
|
@nodebotanist It appears to be used when enabling the serial clock -> Lines 3 to 10 in 0d08218
Used in the node module: https://github.com/tessel/t2-firmware/blob/master/node/tessel-export.js#L1091-L1135 @kevinmehall should know more about that |
IIRC the SERCOM module is limited in how low its frequency can go relative to its input clock, so to get lower baud rates, you have to divide the input clock to the SERCOM. |
Okay took a new approach with FastLED. Notes are here:https://github.com/nodebotanist/T2-Investigation-Notes/blob/master/notes/2018-12-15.md Making slow but reasonable progress. Will alert when FastLED is at least compiling and running on the T2 itself. |
@nodebotanist I'm really looking forward to your work and would love to hear of any updates! 👍 |
Still going! A little slow due to new job onboarding. Working on FastLED firrmware in the T2 firmware still. Will post soon! |
Hey @nodebotanist. Thank you for all your work on this so far! How are you getting on with this? |
Gotta get those Neopixels™ working.
The text was updated successfully, but these errors were encountered: