LED Cyr Wheel Pattern Editor
I’m still working on my LED cyr wheel. I’m creating a desktop application to edit patterns, and eventually simulate POV (persistence of vision). For now, it just runs the pattern in a mock-display. I simply re-wrote the LED graphics C++ class (AdaFruit_NeoPixel.h) that forwards to an associated NSView subclass on OS X. I did a lot of work on the code while in India, and had no way to test the hardware, so it was essential that I create a simple simulator. This also allows me to *way* more easily debug issues. I also created a wrapper for the “SD” class to read files from an SD card. The app itself uses CoreData and exports a custom file format to an SD card that I can then read with the teensy/arduino.
The document UI is pretty basic table:
Lots of popup options (and I’m coding more):
Many I wrote or re-wrote based on some demo code, however, some are stock examples (such as the ones past warm white shimmer). Originally a lot of the Adafruit demos simply use hardware timing and delay(XX) (essentially an Arduino sleep), which makes it hard to do specific timing. So, I had to re-write them all to be timing deponent.
The simulator screen shot:
And a video of it in action:
The Adafruit_NeoPixel library has issues. I’ve been fixing problems on my Adafruit_NeoPixel git hub repository. The most important fix has to do with timing; the library has to disable interrupts while it updates the strip. This unfortunately disables the interrupt that updates the the internal timer from millis()..and is dependent on how many LEDs are in your strip. I need more exact timing, so I fixed it (well, pretty close). Each LED takes about this much time to update:
// about 27.36us/LED. See https://learn.sparkfun.com/tutorials/ws2812-breakout-hookup-guide/ws2812-overview for datatransmission of 24 bits using the specified timing
#define MICROSECONDS_TO_UPDATE_EACH_LED 27.36
So at the end of the AdaFruit_NeoPixel::show() method before the enabling of interrupts I fix the value:
// Before we update the interrupts, we want to update the timing so people who depend on millis() being correct will get (somewhat) correct timing.
uint32_t amountMillisIsOff = (uint32_t)((MICROSECONDS_TO_UPDATE_EACH_LED * (float)numLEDs) / 1000.0);
systick_millis_count += amountMillisIsOff;
interrupts(); // original code…
Feel free to use this fix…
EDIT: I need to figure this out more. My timing is still off…I’m not increasing the amount enough