diff --git a/SimpleNeoPixelTimingTester/SimpleNeoPixelTimingTester.ino b/SimpleNeoPixelTimingTester/SimpleNeoPixelTimingTester.ino deleted file mode 100644 index 9731b5f..0000000 --- a/SimpleNeoPixelTimingTester/SimpleNeoPixelTimingTester.ino +++ /dev/null @@ -1,493 +0,0 @@ - -/* - This is an example of how simple driving a Neopixel can be - This code is optimized for understandability and changability rather than raw speed - More info at http://wp.josh.com/2014/05/11/ws2812-neopixels-made-easy/ -*/ - -// Change this to be at least as long as your pixel string (too long will work fine, just be a little slower) - -#define PIXELS 144 // Number of pixels in the string - -// These values depend on which pin your string is connected to and what board you are using -// More info on how to find these at http://www.arduino.cc/en/Reference/PortManipulation - -// These values are for digital pin 8 on an Arduino Yun or digital pin 12 on a DueMilinove -// Note that you could also include the DigitalWriteFast header file to not need to to this lookup. - -#define PIXEL_PORT PORTB // Port of the pin the pixels are connected to -#define PIXEL_DDR DDRB // Port of the pin the pixels are connected to -#define PIXEL_BIT 4 // Bit of the pin the pixels are connected to - -// These are the timing constraints taken mostly from the WS2812 datasheet - -#define T1H 700 // Width of a 1 bit in ns -#define T1L 600 // Width of a 1 bit in ns - -#define T0H 350 // Width of a 0 bit in ns -#define T0L 800 // Width of a 0 bit in ns - -#define RES 6000 // Width of the low gap between bits to cause a frame to latch - -// Here are some convience defines for using nanoseconds specs to generate actual CPU delays - -#define NS_PER_SEC (1000000000L) // Note that this has to be SIGNED since we want to be able to check for negative values of derivatives - -#define CYCLES_PER_SEC (F_CPU) - -#define NS_PER_CYCLE ( NS_PER_SEC / CYCLES_PER_SEC ) - -#define NS_TO_CYCLES(n) ( (n) / NS_PER_CYCLE ) - -#define DELAY_CYCLES(n) ( ((n)>0) ? __builtin_avr_delay_cycles( n ) : __builtin_avr_delay_cycles( 0 ) ) // Make sure we never have a delay less than zero - - -// Actually send a bit to the string. We turn off optimizations to make sure the compile does -// not reorder things and make it so the delay happens in the wrong place. - -void sendBit(bool) __attribute__ ((optimize(0))); - -void sendBit( bool bitVal ) { - - if ( bitVal ) { - - bitSet( PIXEL_PORT , PIXEL_BIT ); - - DELAY_CYCLES( NS_TO_CYCLES( T1H ) - 2 ); // 1-bit width less overhead for the actual bit setting - // Note that this delay could be longer and everything would still work - bitClear( PIXEL_PORT , PIXEL_BIT ); - - DELAY_CYCLES( NS_TO_CYCLES( T1L ) - 10 ); // 1-bit gap less the overhead of the loop - - } else { - - bitSet( PIXEL_PORT , PIXEL_BIT ); - - DELAY_CYCLES( NS_TO_CYCLES( T0H ) - 2 ); // 0-bit width less overhead - // ************************************************************************** - // This line is really the only tight goldilocks timing in the whole program! - // ************************************************************************** - bitClear( PIXEL_PORT , PIXEL_BIT ); - - DELAY_CYCLES( NS_TO_CYCLES( T0L ) - 10 ); // 0-bit gap less overhead of the loop - - } - - // Note that the inter-bit gap can be as long as you want as long as it doesn't exceed the 5us reset timeout (which is A long time) - // Here I have been generous and not tried to squeeze the gap tight but instead erred on the side of lots of extra time. - // This has thenice side effect of avoid glitches on very long strings becuase - - -} - - - -void sendByteFast( unsigned char byte ) { - - - sendBit( bitRead( byte , 7 ) ); // Neopixel wants bit in highest-to-lowest order - // so send highest bit (bit #7 in an 8-bit byte since they start at 0) - byte <<= 1; // and then shift left so bit 6 moves into 7, 5 moves into 6, etc - - sendBit( bitRead( byte , 7 ) ); // Neopixel wants bit in highest-to-lowest order - // so send highest bit (bit #7 in an 8-bit byte since they start at 0) - byte <<= 1; // and then shift left so bit 6 moves into 7, 5 moves into 6, etc - sendBit( bitRead( byte , 7 ) ); // Neopixel wants bit in highest-to-lowest order - // so send highest bit (bit #7 in an 8-bit byte since they start at 0) - byte <<= 1; // and then shift left so bit 6 moves into 7, 5 moves into 6, etc - sendBit( bitRead( byte , 7 ) ); // Neopixel wants bit in highest-to-lowest order - // so send highest bit (bit #7 in an 8-bit byte since they start at 0) - byte <<= 1; // and then shift left so bit 6 moves into 7, 5 moves into 6, etc - sendBit( bitRead( byte , 7 ) ); // Neopixel wants bit in highest-to-lowest order - // so send highest bit (bit #7 in an 8-bit byte since they start at 0) - byte <<= 1; // and then shift left so bit 6 moves into 7, 5 moves into 6, etc - sendBit( bitRead( byte , 7 ) ); // Neopixel wants bit in highest-to-lowest order - // so send highest bit (bit #7 in an 8-bit byte since they start at 0) - byte <<= 1; // and then shift left so bit 6 moves into 7, 5 moves into 6, etc - sendBit( bitRead( byte , 7 ) ); // Neopixel wants bit in highest-to-lowest order - // so send highest bit (bit #7 in an 8-bit byte since they start at 0) - byte <<= 1; // and then shift left so bit 6 moves into 7, 5 moves into 6, etc - sendBit( bitRead( byte , 7 ) ); // Neopixel wants bit in highest-to-lowest order - // so send highest bit (bit #7 in an 8-bit byte since they start at 0) - byte <<= 1; // and then shift left so bit 6 moves into 7, 5 moves into 6, etc - - -} - - - -void sendByte( unsigned char byte ) { - - for( unsigned char bit = 0 ; bit < 8 ; bit++ ) { - - sendBit( bitRead( byte , 7 ) ); // Neopixel wants bit in highest-to-lowest order - // so send highest bit (bit #7 in an 8-bit byte since they start at 0) - byte <<= 1; // and then shift left so bit 6 moves into 7, 5 moves into 6, etc - - } -} - -/* - - The following three functions are the public API: - - ledSetup() - set up the pin that is connected to the string. Call once at the begining of the program. - sendPixel( r g , b ) - send a single pixel to the string. Call this once for each pixel in a frame. - show() - show the recently sent pixel on the LEDs . Call once per frame. - -*/ - - -// Set the specified pin up as digital out - -void ledsetup() { - - bitSet( PIXEL_DDR , PIXEL_BIT ); - -} - -void sendPixel( unsigned char r, unsigned char g , unsigned char b ) { - - sendByte(g); // Neopixel wants colors in green then red then blue order - sendByte(r); - sendByte(b); - -} - - -// Just wait long enough without sending any bots to cause the pixels to latch and display the last sent frame - -void show() { - DELAY_CYCLES( NS_TO_CYCLES(RES) ); -} - - -/* - - That is the whole API. What follows are some demo functions rewriten from the AdaFruit strandtest code... - - https://github.com/adafruit/Adafruit_NeoPixel/blob/master/examples/strandtest/strandtest.ino - - Note that we always turn off interrupts while we are sending pixels becuase an interupt - could happen just when we were in the middle of somehting time sensitive. - - If we wanted to minimize the time interrupts were off, we could instead - could get away with only turning off interrupts just for the very brief moment - when we are actually sending a 0 bit (~1us), as long as we were sure that the total time - taken by any interrupts + the time in our pixel generation code never exceeded the reset time (5us). - -*/ - - -// Display a single color on the whole string - -void showColor( unsigned char r , unsigned char g , unsigned char b ) { - - cli(); - for( int p=0; pg->b where - // hue of 0 = Full red - // hue of 128 = 1/2 red and 1/2 green - // hue of 256 = Full Green - // hue of 384 = 1/2 green and 1/2 blue - // ... - - unsigned int firstPixelHue = 0; // Color for the first pixel in the string - - for(unsigned int j=0; j=(3*256)) { // Normalize back down incase we incremented and overflowed - currentPixelHue -= (3*256); - } - - unsigned char phase = currentPixelHue >> 8; - unsigned char step = currentPixelHue & 0xff; - - switch (phase) { - - case 0: - sendPixel( ~step , step , 0 ); - break; - - case 1: - sendPixel( 0 , ~step , step ); - break; - - case 2: - sendPixel( step ,0 , ~step ); - break; - - } - - currentPixelHue+=pixelAdvance; - - - } - - sei(); - - show(); - - firstPixelHue += frameAdvance; - - } -} - - -// I added this one just to demonstrate how quickly you can flash the string. -// Flashes get faster and faster until *boom* and fade to black. - -void detonate( unsigned char r , unsigned char g , unsigned char b , unsigned int startdelayms) { - while (startdelayms) { - - showColor( r , g , b ); // Flash the color - showColor( 0 , 0 , 0 ); - - delay( startdelayms ); - - startdelayms = ( startdelayms * 4 ) / 5 ; // delay between flashes is halved each time until zero - - } - - // Then we fade to black.... - - for( int fade=256; fade>0; fade-- ) { - - showColor( (r * fade) / 256 ,(g*fade) /256 , (b*fade)/256 ); - - } - - showColor( 0 , 0 , 0 ); - - -} - -void inline trigger() { - PORTD |= _BV(1); - PORTD &= ~_BV(1); -} - - -void setup() { - - ledsetup(); - - pinMode( 2 , OUTPUT ); -} - - -void loop() { - n ; - showColor(0,0,0); - return; - showColor(0xff,0xff,0xff); - showColor(0,0,0); - showColor(0xff,0xff,0xff); - showColor(0,0,0); - showColor(0xff,0xff,0xff); - showColor(0,0,0); - showColor(0xff,0xff,0xff); - return; - - - cli(); - -// sendPixel(0x0,0x0,0x0); - sendPixel(0xff,0xff,0xff); - sendPixel(0xff,0xff,0xff); - - trigger(); - sendPixel(0xff,0xff,0xff); - - sendPixel(0x0,0x0,0x0); - sendPixel(0x0,0x0,0x0); - - sei(); - - - show(); - return; - - - const unsigned char o = 8; - const unsigned char d = 4; - - bitSet( PIXEL_PORT , PIXEL_BIT ); - - DELAY_CYCLES( o ); // 1-bit width less overhead for the actual bit setting - // Note that this delay could be longer and everything would still work - bitClear( PIXEL_PORT , PIXEL_BIT ); - - DELAY_CYCLES( d ); // 1-bit width less overhead for the actual bit setting - - bitSet( PIXEL_PORT , PIXEL_BIT ); - - DELAY_CYCLES( o ); // 1-bit width less overhead for the actual bit setting - // Note that this delay could be longer and everything would still work - bitClear( PIXEL_PORT , PIXEL_BIT ); - - DELAY_CYCLES( d ); // 1-bit width less overhead for the actual bit setting - bitSet( PIXEL_PORT , PIXEL_BIT ); - - DELAY_CYCLES( o ); // 1-bit width less overhead for the actual bit setting - // Note that this delay could be longer and everything would still work - bitClear( PIXEL_PORT , PIXEL_BIT ); - - DELAY_CYCLES( d ); // 1-bit width less overhead for the actual bit setting - bitSet( PIXEL_PORT , PIXEL_BIT ); - - DELAY_CYCLES( o ); // 1-bit width less overhead for the actual bit setting - // Note that this delay could be longer and everything would still work - bitClear( PIXEL_PORT , PIXEL_BIT ); - - DELAY_CYCLES( d ); // 1-bit width less overhead for the actual bit setting - bitSet( PIXEL_PORT , PIXEL_BIT ); - - DELAY_CYCLES( o ); // 1-bit width less overhead for the actual bit setting - // Note that this delay could be longer and everything would still work - bitClear( PIXEL_PORT , PIXEL_BIT ); - - DELAY_CYCLES( d ); // 1-bit width less overhead for the actual bit setting - bitSet( PIXEL_PORT , PIXEL_BIT ); - - DELAY_CYCLES( o ); // 1-bit width less overhead for the actual bit setting - // Note that this delay could be longer and everything would still work - bitClear( PIXEL_PORT , PIXEL_BIT ); - - DELAY_CYCLES( d ); // 1-bit width less overhead for the actual bit setting - bitSet( PIXEL_PORT , PIXEL_BIT ); - - DELAY_CYCLES( o ); // 1-bit width less overhead for the actual bit setting - // Note that this delay could be longer and everything would still work - bitClear( PIXEL_PORT , PIXEL_BIT ); - - DELAY_CYCLES( d ); // 1-bit width less overhead for the actual bit setting - bitSet( PIXEL_PORT , PIXEL_BIT ); - - DELAY_CYCLES( o ); // 1-bit width less overhead for the actual bit setting - // Note that this delay could be longer and everything would still work - bitClear( PIXEL_PORT , PIXEL_BIT ); - - DELAY_CYCLES( d ); // 1-bit width less overhead for the actual bit setting - bitSet( PIXEL_PORT , PIXEL_BIT ); - - DELAY_CYCLES( o ); // 1-bit width less overhead for the actual bit setting - // Note that this delay could be longer and everything would still work - bitClear( PIXEL_PORT , PIXEL_BIT ); - - DELAY_CYCLES( d ); // 1-bit width less overhead for the actual bit setting - - sendPixel(0xff,0xff,0xff); - - sendPixel(0xff,00,0xff); - show(); - delay(1000); - return; - - // Some example procedures showing how to display to the pixels: - colorWipe(255, 0, 0, 0); // Red - colorWipe(0, 255, 0, 0); // Green - colorWipe(0, 0, 255, 0); // Blue - - // Send a theater pixel chase in... - theaterChase(127, 127, 127, 0); // White - theaterChase(127, 0, 0, 0); // Red - theaterChase( 0, 0, 127, 0); // Blue - - rainbowCycle(1000 , 20 , 5 ); - detonate( 255 , 255 , 255 , 1000); - - return; - -} - - - - - diff --git a/SimpleNeopixelDemo/SimpleNeopixelDemo.ino b/SimpleNeopixelDemo_2812B/SimpleNeopixelDemo_2812B.ino similarity index 97% rename from SimpleNeopixelDemo/SimpleNeopixelDemo.ino rename to SimpleNeopixelDemo_2812B/SimpleNeopixelDemo_2812B.ino index e91333c..ade8a9d 100644 --- a/SimpleNeopixelDemo/SimpleNeopixelDemo.ino +++ b/SimpleNeopixelDemo_2812B/SimpleNeopixelDemo_2812B.ino @@ -29,13 +29,13 @@ // These are the timing constraints taken mostly from the WS2812 datasheets // These are chosen to be conservative and avoid problems rather than for maximum throughput -#define T1H 900 // Width of a 1 bit in ns -#define T1L 600 // Width of a 1 bit in ns +#define T1H 800 // Width of a 1 bit in ns +#define T1L 450 // Width of a 1 bit in ns #define T0H 400 // Width of a 0 bit in ns -#define T0L 900 // Width of a 0 bit in ns +#define T0L 850 // Width of a 0 bit in ns -#define RES 6000 // Width of the low gap between bits to cause a frame to latch +#define RES 40000 // Width of the low gap between bits to cause a frame to latch // Here are some convience defines for using nanoseconds specs to generate actual CPU delays