I did some tests and I think the MCU won't be able to make it. WS2812B timing pretty fast (around 1us) and the Quark GPIO is slower than what I thought (18us period for switching from 1 to 0 on pin 12).
People on the Raspberry Pi are able to do it with a serial mode on the PWM hardware, but it does not look available on the Edison.
Do you think it would work for VERY basic uses? The project I'm working on will need to change colors and such, but I'm not doing any fancy fades and the transition speeds doesn't need to be very precise/quick.
It would not work at all. At least, on the current firmware revision.
I'm pretty sure it can be done in the future... The Quark is a 100MHz microcontroller, there is no reason it would not be fast enough to do it if it can be done on a 20MHz AVR.
Talking about AVR, the WS2812 library works pretty well on it. You could just talk to an Arduino via serial with the Edison and the Arduino would control the LEDs.
For 3$ you have an Atmega328. Just burn optiboot on the Atmega, add a crystal and some caps and you are good to go.
I was afraid that's what your were saying. Thanks for your help.
Instead of the WS2812 model, use the APA102 strips. They work perfectly. You can use SPI to push data out to them. Up until Intel broke the Edison with their latest version of the SPI driver that is. You will need to use the V2 image as SPI has been kneecaped at 25khz on the latest image.
The SPI connections should work fine with the Edison. Intel has currently completely hobbled the MCU to the point that it probably isn't useful in any meaningful way other than a very simple Arduino for very simple use cases. The OS and capabilities of the MCU are far and away capable of programming the WS2812, but nothing to make that happen is supported on the MCU. I'm wondering if it might be time to see if MQX could be made to boot, or how hard it would be to run bare metal on the MCU. With bare metal, you could just count cycles for timing and handle writing to the LED's.
I think this is a problem Intel needs to solve. The NeoPixels are a huge draw for hobbyists, even as a secondary use case. It is so simple to make them dance, even if you just use a single LED for notifications. NeoPixel ease of use and the variety of form factors means they can be used so many ways for so many different types of projects. I've had to drop the Edison on several projects at home now because it is unlikely the Edison will ever be able to support them (even though it is more than capable), and that other similar low cost boards can be made to work better (BeagleBone specifically, spark core, photon, the newest Arduino Mcore boards, the Teensy, ...).
NeoPixel ease of use and the variety of form factors means they can be used so many ways for so many different types of projects.
In my specific case it's the form factors that are the deciding issue. I need a couple of the round LED "plates" for a project, and there really aren't any alternatives (short of fabricating my own which isn't going to happen for this project).
Yep, Intel has completely crippled the Edison with their last update. I have opened a support case with them, and posted a few issues on this forum, and their response is "meh".
I suggest moving to the Rpi which costs half as much as the Edison, is faster, and has full MRAA support so you dont have port your code too much.
i have also been working with the NodeMCU modules which are just amazing for $10!
Both of these work with the ws28xx and the apa102 LEDs
DmxSimple, an open source DMX library for Arduino, utilizes an inline assembly coded function as follows. If someone can port this AVR code to x86 and did some tuning of timing, I can not see why it should not work on Edison.
/** Transmit a complete DMX byte
* We have no serial port for DMX, so everything is timed using an exact
* number of instruction cycles.
* Really suggest you don't touch this function.
void dmxSendByte(volatile uint8_t value)
uint8_t bitCount, delCount;
__asm__ volatile (
"ldi %[bitCount],11\n" // 11 bit intervals per transmitted byte
"rjmp bitLoop%=\n" // Delay 2 clock cycles.
[bitCount] "=&d" (bitCount),
[delCount] "=&d" (delCount)
[dmxPort] "e" (dmxPort),
[outMask] "r" (~dmxBit),
[outBit] "r" (dmxBit),
[delCountVal] "M" (F_CPU/1000000-3),
[value] "r" (value)
It's not so simple (I don't believe) to code an application library up in assembly and magically solve the timing issues. For your case, you still have scheduling issues that the Linux kernel confines us with even with a simple assembly language app (it's still an app, still runs in userspace, and still is confined to the kernel resources and model). It might be possible to do a NeoPixel driver as a Linux kernel driver, which may allow us to run in the time frames we need, but even that is probably a long shot, and would require some pretty hefty kerne knowledge. It also assumes you can get nanosecond timing accurate enough for the NeoPixel strips from kernel timers where you can disable interrupts for the time scales needed. I'm not sure that is even possible. The assembly doesn't help in this case, it's just a lower level language that has the same scheduling constraints as any other application running in Linux user space.
However, running on the MCU, it's a possibility. I can honestly say I have never even looked to see if there is an assembler for the MCU, much less assembly documentation to help with the port. I wonder how hard it would be to write a bare metal, no OS app for the Quark? Basically, if I could code up in assembly a small bare metal app that can run and communicate with the Linux side, then realistically, you could do the timing part the same way as Arduino or other micro based boards. However, while it might be simple to do the timing in assembly, it's probably an enormous undertaking to implement a way to communicate with the Quark without the OS.
The problem isn't counting cycles to do timing, the problem is how to implement it using existing resources which seem to be limited to not providing timing sources at the resolution needed.
Thanks for comments.
>However, running on the MCU, it's a possibility
That is what I thought. Quark runs RTOS and timing-critical tasks are exactly what it is supposed to handle.
For those who are familiar with x86 instruction set, it should not be that difficult. One can use Intel's MCU SDK to write a C++ script with the above "dmxSendByte" function using x86 equivalent inline assembly codes. You just upload it to Edison like other sketches.
The above low level function is written in 8-bit ARM instruction set which is so simle that even I can understand what each nmemonic does. Problem is that Quark has 32-bit x86 compatible instruction set and I do not know how to translate 8-bit code to 32-bit code. I will not be surprised if there were an automatic translator.
If only Intel had made Edison with ATOM and ATmega328!
Sorry, it doesn't work like that. In this case, simply writing in assembly doesn't actually solve a problem. It still has to live in the environment already presented. So, you still have issues with scheduling and timers.
There are a few ways to make this work.
- Bare metal on the Quark, but this still has issues as you would need to write up all of the helper stuff that Intel already made
- boot a new RTOS on the Quark, but you would have to implement all the helper stuff that Intel already made
- Up the timer resolution on the Quark, and allow to disable interrupts in userspace. This would be the preferred method, and the solution that Intel most likely would provide. This assumes they care. It doesn't seem like they care much.
- Probably a few others I haven't thought of
My point here is that there is no easy magic. You can't simply port 8 bit assembly from one micro to 32 bit assembly on another micro and expect it will magically work. And, going bare metal would be a huge effort for anyone doing it, or you would have to choose not to care about 99% of the stuff the Quark OS gets you. What good is having NeoPixels if you can't control them with the Atom/Linux side. Just buy a $10 Arduino and use that, it's better and faster. The benefits of using the Edison are WiFi, BT, and Linux to run custom applications with tons of memory that can do a whole lot of things that micros can't do (even the faster bigger ones like the Photon). I like the idea of porting another RTOS, but that's still a huge effort to get it wired into all of the Edison goodies and to be able to talk to the Atom side.
I agree that Edison + Arduino compatible board is the most practical solution.
I wonder what was the purpose/intention of Quark's sitting there. What was it meant for to start with? At the moment, it looks like something left over or forgotten to be removed between changing product designs. Curious.