Modified library of Pixel Array showing main.cpp code implementing buffer/array of pixels method of updating pixel chain.
Dependents: NeoPixel-DemoBuffer Final_project Final_project
Fork of PixelArray by
neopixel.h
00001 #ifndef NEOPIXEL_H 00002 #define NEOPIXEL_H 00003 00004 #include <stdint.h> 00005 #include "mbed.h" 00006 #include "BurstSPI.h" 00007 00008 namespace neopixel 00009 { 00010 00011 /** Represent the value of a single pixel. 00012 * 00013 * Each channel uses the full 8 bits: 0x00 is fully off and 0xff is fully on. 00014 */ 00015 struct Pixel { 00016 uint8_t red; 00017 uint8_t green; 00018 uint8_t blue; 00019 }; 00020 00021 00022 /** Control the byte order used by the connected pixels. 00023 * 00024 * The vast majority of NeoPixels use a GRB byte order, so this is the default. 00025 * A few use a RGB byte order. 00026 * 00027 * In principle, the WS281x controllers could be connected with _any_ byte 00028 * ordering, but only GRB and RGB are supported at the moment. 00029 */ 00030 enum ByteOrder { 00031 BYTE_ORDER_GRB, 00032 BYTE_ORDER_RGB, 00033 }; 00034 00035 /** Set the protocol mode. 00036 * 00037 * The protocol is named after the clock, as though WS8211 supports only the 00038 * 400kHz clock, WS8212 supports both. 00039 */ 00040 enum Protocol { 00041 PROTOCOL_800KHZ, 00042 PROTOCOL_400KHZ, 00043 }; 00044 00045 typedef void (*PixelGenerator)(Pixel* out, uint32_t index, uintptr_t extra); 00046 00047 /** Control an array or chain of NeoPixel-compatible RGB LEDs. 00048 * 00049 * "NeoPixel" is Adafruit's name for WS2812- and WS2811-based addressable RGB 00050 * LEDs. This library should work with any WS2811- or WS2812-based devices, as 00051 * long as they support the fast-mode (800kHz) interface. 00052 * 00053 * Most example code uses bit-banging to generate the timed signal precisely. 00054 * This library uses an SPI peripheral instead. The main advantage of this is 00055 * that the chip can service interrupts and the like without disrupting the 00056 * signal (as long as the interrupts don't take _too_ long). The main 00057 * disadvantage is that it requires the use of an SPI peripheral. 00058 * 00059 * @note SPI peripherals will tend to leave the output pin ('MOSI') floating 00060 * after a packet is sent. This will confuse the connected pixels, which expect 00061 * the line to be driven low when idle. One way to fix this is to add a 10k 00062 * resistor between 'MOSI' and ground so that it drops to '0' when not driven. 00063 * Another method is to enable the on-chip pull-down resistor on the output pin. 00064 * However, the mbed API only exposes this function through the DigitalIn and 00065 * DigitalInOut classes. If you want to use the on-chip pull-down, you'll have 00066 * to temporarily connect a DigitalIn peripheral _before_ creating instantiating 00067 * the PixelArray. 00068 * 00069 * @code 00070 * // Sample generator: Cycle through each colour combination, increasing the 00071 * // brightness each time. `extra` is used as an iteration counter. 00072 * void generate(neopixel::Pixel * out, uint32_t index, uintptr_t extra) { 00073 * uint32_t brightness = (index + extra) >> 3; 00074 * out->red = ((index + extra) & 0x1) ? brightness : 0; 00075 * out->green = ((index + extra) & 0x2) ? brightness : 0; 00076 * out->blue = ((index + extra) & 0x4) ? brightness : 0; 00077 * } 00078 * 00079 * int main() { 00080 * // Create a temporary DigitalIn so we can configure the pull-down resistor. 00081 * // (The mbed API doesn't provide any other way to do this.) 00082 * // An alternative is to connect an external pull-down resistor. 00083 * DigitalIn(p5, PullDown); 00084 * 00085 * // The pixel array control class. 00086 * neopixel::PixelArray array(p5); 00087 * 00088 * uint32_t offset = 0; 00089 * while (1) { 00090 * array.update(generate, 100, offset++); 00091 * wait_ms(250); 00092 * } 00093 * } 00094 * @endcode 00095 */ 00096 class PixelArray 00097 { 00098 public: 00099 /** Initialize a PixelArray. 00100 * 00101 * @param out Output (SPI MOSI) pin. 00102 * @param byte_order The order in which to transmit colour channels. 00103 */ 00104 PixelArray(PinName out, 00105 ByteOrder byte_order = BYTE_ORDER_RGB, 00106 Protocol protocol = PROTOCOL_800KHZ); 00107 00108 /** Update the pixel display from a buffer. 00109 * 00110 * This update method is good in the following situations: 00111 * - You want to make incremental changes to a fixed frame pattern. 00112 * - The frame is hard (or impossible) to generate procedurally. 00113 * - The frame requires a lot of time to generate. 00114 * 00115 * @param buffer Pixel data to be written. 00116 * @param length The number of pixels to write. 00117 * 00118 * buffer[0] is written to the pixel nearest the mbed. 00119 * buffer[length-1] is written to the pixel furthest from the mbed. 00120 */ 00121 void update(Pixel buffer[], uint32_t length); 00122 00123 /** Update a pixel chain using the callback to generate the value for each 00124 * pixel. 00125 * 00126 * This update method is good in the following situations: 00127 * - You have a lot of pixels to drive and don't have enough RAM to buffer 00128 * them all. 00129 * - You want to display a frame pattern that can be generated procedurally 00130 * generated without intensive processing. 00131 * 00132 * @param generator A callback which is called to generate a value for each 00133 * pixel on demand. This function must be fairly fast: if it takes more 00134 * than about 8-9us, the interface will reset and the display will be 00135 * corrupted. The exact time limits will vary between WS281x variants. As a 00136 * rough guide, an LPC1768 at 96MHz can (conservatively) execute about 750 00137 * instructions in that time. 00138 * 00139 * @param length The number of pixels to write. 00140 * 00141 * @param extra An arbitrary value to pass into the generator function. For 00142 * example, this is a good way to pass an animation time index to the 00143 * generator function. 00144 */ 00145 void update(PixelGenerator generator, uint32_t length, uintptr_t extra); 00146 00147 private: 00148 BurstSPI spi_; 00149 ByteOrder byte_order_; 00150 Protocol protocol_; 00151 00152 static int const latch_time_us_ = 50; 00153 00154 void send_pixel(Pixel& pixel); 00155 }; 00156 00157 } 00158 00159 #endif
Generated on Mon Jul 18 2022 13:00:31 by 1.7.2