This library lets you control the addressable RGB LED strips from Pololu Robotics & Electronics.
Dependents: WoYaoChengGOng V2-WoYaoChengGOng STM32_MagneticLight tape_Led_Sample ... more
Summary
This is a library for the mbed that allows you to control these addressable RGB LED products from Pololu:
- Addressable RGB 30-LED Strip, 5V, 1m (SK6812)
- Addressable RGB 60-LED Strip, 5V, 2m (SK6812)
- Addressable RGB 150-LED Strip, 5V, 5m (SK6812)
- Addressable RGB 60-LED Strip, 5V, 1m (SK6812)
- Addressable RGB 120-LED Strip, 5V, 2m (SK6812)
- Addressable High-Density RGB 72-LED Strip, 5V, 0.5m (SK6812)
- Addressable RGB 30-LED Strip, 5V, 1m (WS2812B)
- Addressable RGB 60-LED Strip, 5V, 2m (WS2812B)
- Addressable RGB 150-LED Strip, 5V, 5m (WS2812B)
- Addressable RGB 60-LED Strip, 5V, 1m (WS2812B)
- Addressable RGB 120-LED Strip, 5V, 2m (WS2812B)
- Addressable High-Density RGB 72-LED Strip, 5V, 0.5m (WS2812B)
- Addressable Through-Hole 5mm RGB LED with Diffused Lens, WS2811 Driver
- Addressable Through-Hole 8mm RGB LED with Diffused Lens, WS2811 Driver
- Adafruit 16 WS2812 LED NeoPixel Ring
- Adafruit 24 WS2812 LED NeoPixel Ring
- Adafruit 15 WS2812 LED NeoPixel 1/4-Ring
- Adafruit 5×8 WS2812 LED NeoPixel Shield for Arduino
- Addressable RGB 30-LED Strip, 5V, 1m (High-Speed TM1804)
- Addressable RGB 60-LED Strip, 5V, 2m (High-Speed TM1804)
- Addressable RGB 150-LED Strip, 5V, 5m (High-Speed TM1804)
This library is optimized for the SK6812 and WS2812B, so it transmits colors in green-red-blue order.
If you have a WS2811 LED or a high-speed TM1804 LED strip, please note that its red and green channels are swapped relative to the WS2812B, so you will need to swap those channels in your code. You might prefer to use the version of the library from October 2013, which does not require you to swap red and green in your code.
If you need to control the older, low-speed LED strips (items #2540, #2541, and #2542), you will need to use the version of this library from March 2013.
This library allows complete control over the color of an arbitrary number of LED strips with an arbitrary number of LEDs. Each LED can be individually controlled, and LED strips can be chained together.
This library should also work with any other LED strip based on the SK6812, WS281x, or TM1804.
Supported Platforms
This library has been tested on the mbed NXP LPC1768 (Cortex-M3 at 96 MHz), the mbed NXP LPC11U24 (Cortex-M0 at 48 MHz), and the NUCLEO-F303K8 (Cortex-M4 at 72 MHz). It will probably work on many other boards without modification.
This library does not work on chips families such as the STM32F4 where there is a single register for setting and clearing the value of an output pin. The library checks for the GPIO_IP_WITHOUT_BRR preprocessor macro and triggers a compile-time error if that macro is set.
Getting Started
Software
Here are two example programs that show how to use the library:
Import programLedStripRainbow
This is an example program for the PololuLedStrip library. It generates a simple moving rainbow pattern.
Import programLedStripGradient
This is an example program for the PololuLedStrip library. It generates a simple moving gradient pattern.
As a first step, you should compile and upload one of these to the mbed. When the program runs, the mbed should output color data on pin p8 dozens of times per second. The expected signal is documented on the Pololu website. The example programs only send colors for 60 LEDs, but they can easily be changed to send more for a longer strip.
Hardware
The addressable RGB LED strips can be purchased on Pololu's website using the links above.
The LED strip’s data input connector has two pins that should be connected to the Arduino. The LED strip’s ground will need to be connected to one of the mbed’s GND pins, and the LED strip’s signal input line will be need to be connected to one of the Arduino’s I/O lines. Our example programs assume the signal line is connected to p8. These connections can be made using two Male-Female Premium Jumper Wires, with the female ends plugging into the LED strip and the male ends plugged into a breadboard that houses the mbed.
You will also need to connect a suitable power supply to the LED strip using one of the power connectors. The power supply must be at the right voltage and provide enough current to meet the LED strip's requirements.
If everything works properly, you will see a moving pattern of colors on the LED strip.
Timing Details
This library takes about 1.3 ms to update 30 LEDs (1 meter). The LED strips use a high speed one-wire protocol with relatively strict timing requirements, so this library disables interrupts to ensure reliable color transmission. Unfortunately, disabling the interrupts could cause problems in other libraries that uses interrupts.
This library provides an interruptFriendly
option that can let it coexist with interrupt-based libraries. When this option is enabled, the library will temporarily enable interrupts after each color is sent, about every 45 microseconds. If you can keep all of your interrupts short enough, then this option should allow this library to work in conjunction with your interrupt-based libraries. However, if you have an interrupt enabled that takes too long, then this interrupt will sometimes cause an extra long low pulse to emitted, which will be interpreted by the LED strip as a reset command. This can cause visible flickering in the LED strip. To turn on the interruptFriendly
option, add this line to the beginning of your main()
function:
PololuLedStrip::interruptFriendly = true;
Chaining LED Strips together
No special code is required to chain LED strips together. An X-meter LED strip chained to a Y-meter LED strip can be controlled in exactly the same way as a single (X+Y)-meter LED strip.
led_strip_write_color.s@26:c3193bc73cff, 2017-11-01 (annotated)
- Committer:
- DavidEGrayson
- Date:
- Wed Nov 01 23:11:49 2017 +0000
- Revision:
- 26:c3193bc73cff
- Parent:
- 24:5c01a6fa1556
Make it be a compile-time error if GPIO_IP_WITHOUT_BRR is set.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
DavidEGrayson | 0:06475317f283 | 1 | AREA asm_func, CODE, READONLY |
DavidEGrayson | 0:06475317f283 | 2 | EXPORT led_strip_write_color |
DavidEGrayson | 6:9d0530b7dae2 | 3 | IMPORT led_strip_write_delays |
DavidEGrayson | 0:06475317f283 | 4 | |
DavidEGrayson | 7:9a088f042ee0 | 5 | MACRO |
DavidEGrayson | 7:9a088f042ee0 | 6 | delay $id |
DavidEGrayson | 7:9a088f042ee0 | 7 | ldr r5, =led_strip_write_delays |
DavidEGrayson | 7:9a088f042ee0 | 8 | ldrb r5, [r5, $id] |
DavidEGrayson | 7:9a088f042ee0 | 9 | ldr r4, =delay_region_end |
DavidEGrayson | 9:6ffb85d69eaf | 10 | subs r4, r4, r5 |
DavidEGrayson | 7:9a088f042ee0 | 11 | blx r4 |
DavidEGrayson | 7:9a088f042ee0 | 12 | MEND |
DavidEGrayson | 7:9a088f042ee0 | 13 | |
DavidEGrayson | 0:06475317f283 | 14 | led_strip_write_color |
DavidEGrayson | 5:690fdfb595de | 15 | ; Register usage: |
DavidEGrayson | 5:690fdfb595de | 16 | ; These are the first 4 arguments to the method: |
DavidEGrayson | 5:690fdfb595de | 17 | ; R0: pointer to the color to send |
DavidEGrayson | 5:690fdfb595de | 18 | ; R1: pointer to the register for setting the pin |
DavidEGrayson | 5:690fdfb595de | 19 | ; R2: pointer to the register for clearing the pin |
DavidEGrayson | 5:690fdfb595de | 20 | ; R3: pin mask |
DavidEGrayson | 5:690fdfb595de | 21 | ; Additionally, we use these registers: |
DavidEGrayson | 5:690fdfb595de | 22 | ; R4: temporary register |
DavidEGrayson | 6:9d0530b7dae2 | 23 | ; R5: temporary register |
DavidEGrayson | 20:656bbcb64e3b | 24 | ; R6: shift register that holds the 24-bit color |
DavidEGrayson | 5:690fdfb595de | 25 | ; R7: the number of bits we still need to send |
DavidEGrayson | 5:690fdfb595de | 26 | ; R13: Link Register, holds return addresses. |
DavidEGrayson | 7:9a088f042ee0 | 27 | |
DavidEGrayson | 9:6ffb85d69eaf | 28 | ; Push those registers so we can restore them later. |
DavidEGrayson | 11:e00ba70ac54c | 29 | push {r4, r5, r6, r7, lr} |
DavidEGrayson | 10:f1bb84b97788 | 30 | |
DavidEGrayson | 20:656bbcb64e3b | 31 | ldrb r6, [r0, #1] ; Load green. |
DavidEGrayson | 20:656bbcb64e3b | 32 | lsls r6, r6, #24 ; Put green in MSB of r6. |
DavidEGrayson | 9:6ffb85d69eaf | 33 | ldrb r4, [r0, #0] ; Load red. |
DavidEGrayson | 9:6ffb85d69eaf | 34 | lsls r4, r4, #16 |
DavidEGrayson | 20:656bbcb64e3b | 35 | orrs r6, r6, r4 ; Put red in r6. |
DavidEGrayson | 9:6ffb85d69eaf | 36 | ldrb r4, [r0, #2] ; Load blue. |
DavidEGrayson | 9:6ffb85d69eaf | 37 | lsls r4, r4, #8 |
DavidEGrayson | 21:87fd6273e0ff | 38 | orrs r6, r6, r4 ; Put blue in r6. |
DavidEGrayson | 9:6ffb85d69eaf | 39 | |
DavidEGrayson | 21:87fd6273e0ff | 40 | ; On the Cortex-M3 we simply did: |
DavidEGrayson | 9:6ffb85d69eaf | 41 | ; ldr r6, [r0] ; Read the color. Now we have: xxBbGgRr |
DavidEGrayson | 9:6ffb85d69eaf | 42 | ; rbit r6, r6 ; Reverse the order of the bits: rRgGbBxx |
DavidEGrayson | 9:6ffb85d69eaf | 43 | ; rev r6, r6 ; Reverse the order of the bytes: xxbBgGrR |
DavidEGrayson | 9:6ffb85d69eaf | 44 | ; and then we used rrxs for shifting to the right through carry. |
DavidEGrayson | 9:6ffb85d69eaf | 45 | |
DavidEGrayson | 9:6ffb85d69eaf | 46 | ldr r7, =24 ; Initialize the loop counter register. |
DavidEGrayson | 0:06475317f283 | 47 | |
DavidEGrayson | 0:06475317f283 | 48 | send_led_strip_bit |
DavidEGrayson | 0:06475317f283 | 49 | str r3, [r1] ; Drive the line high. |
DavidEGrayson | 0:06475317f283 | 50 | |
DavidEGrayson | 19:46d7ab0ba3e7 | 51 | ; It doesn't really matter exactly how long we delay here as long as it is |
DavidEGrayson | 24:5c01a6fa1556 | 52 | ; less than the LED's threshold between 0 and 1. |
DavidEGrayson | 19:46d7ab0ba3e7 | 53 | nop |
DavidEGrayson | 19:46d7ab0ba3e7 | 54 | nop |
DavidEGrayson | 19:46d7ab0ba3e7 | 55 | nop |
DavidEGrayson | 19:46d7ab0ba3e7 | 56 | nop |
DavidEGrayson | 19:46d7ab0ba3e7 | 57 | nop |
DavidEGrayson | 19:46d7ab0ba3e7 | 58 | nop |
DavidEGrayson | 0:06475317f283 | 59 | |
DavidEGrayson | 9:6ffb85d69eaf | 60 | ldr r4, =0x80000000 |
DavidEGrayson | 9:6ffb85d69eaf | 61 | tst r6, r4 |
DavidEGrayson | 19:46d7ab0ba3e7 | 62 | bne delay0 |
DavidEGrayson | 12:b6df8ac053c8 | 63 | str r3, [r2] ; If the bit to send it 0, drive the line low. |
DavidEGrayson | 24:5c01a6fa1556 | 64 | |
DavidEGrayson | 19:46d7ab0ba3e7 | 65 | delay0 |
DavidEGrayson | 19:46d7ab0ba3e7 | 66 | delay #0 |
DavidEGrayson | 0:06475317f283 | 67 | |
DavidEGrayson | 9:6ffb85d69eaf | 68 | ldr r4, =0x80000000 |
DavidEGrayson | 9:6ffb85d69eaf | 69 | tst r6, r4 |
DavidEGrayson | 19:46d7ab0ba3e7 | 70 | beq delay1 |
DavidEGrayson | 12:b6df8ac053c8 | 71 | str r3, [r2] ; If the bit to send is 1, drive the line low. |
DavidEGrayson | 24:5c01a6fa1556 | 72 | |
DavidEGrayson | 19:46d7ab0ba3e7 | 73 | delay1 |
DavidEGrayson | 19:46d7ab0ba3e7 | 74 | delay #1 |
DavidEGrayson | 4:d3b60bd43811 | 75 | |
DavidEGrayson | 12:b6df8ac053c8 | 76 | lsls r6, r6, #1 ; Shift color bits. |
DavidEGrayson | 6:9d0530b7dae2 | 77 | subs r7, r7, #1 ; Decrement the loop counter. |
DavidEGrayson | 12:b6df8ac053c8 | 78 | bne send_led_strip_bit ; Send another bit if we have not reached zero. |
DavidEGrayson | 12:b6df8ac053c8 | 79 | pop {r4, r5, r6, r7, pc} ; Otherwise, restore the registers and return. |
DavidEGrayson | 19:46d7ab0ba3e7 | 80 | bx lr; |
DavidEGrayson | 4:d3b60bd43811 | 81 | |
DavidEGrayson | 4:d3b60bd43811 | 82 | delay_region |
DavidEGrayson | 5:690fdfb595de | 83 | ; The following is 128 nops. |
DavidEGrayson | 0:06475317f283 | 84 | nop |
DavidEGrayson | 0:06475317f283 | 85 | nop |
DavidEGrayson | 0:06475317f283 | 86 | nop |
DavidEGrayson | 0:06475317f283 | 87 | nop |
DavidEGrayson | 0:06475317f283 | 88 | nop |
DavidEGrayson | 0:06475317f283 | 89 | nop |
DavidEGrayson | 0:06475317f283 | 90 | nop |
DavidEGrayson | 0:06475317f283 | 91 | nop |
DavidEGrayson | 0:06475317f283 | 92 | nop |
DavidEGrayson | 0:06475317f283 | 93 | nop |
DavidEGrayson | 0:06475317f283 | 94 | nop |
DavidEGrayson | 0:06475317f283 | 95 | nop |
DavidEGrayson | 0:06475317f283 | 96 | nop |
DavidEGrayson | 4:d3b60bd43811 | 97 | nop |
DavidEGrayson | 4:d3b60bd43811 | 98 | nop |
DavidEGrayson | 4:d3b60bd43811 | 99 | nop |
DavidEGrayson | 4:d3b60bd43811 | 100 | |
DavidEGrayson | 0:06475317f283 | 101 | nop |
DavidEGrayson | 0:06475317f283 | 102 | nop |
DavidEGrayson | 0:06475317f283 | 103 | nop |
DavidEGrayson | 0:06475317f283 | 104 | nop |
DavidEGrayson | 0:06475317f283 | 105 | nop |
DavidEGrayson | 0:06475317f283 | 106 | nop |
DavidEGrayson | 0:06475317f283 | 107 | nop |
DavidEGrayson | 0:06475317f283 | 108 | nop |
DavidEGrayson | 0:06475317f283 | 109 | nop |
DavidEGrayson | 0:06475317f283 | 110 | nop |
DavidEGrayson | 0:06475317f283 | 111 | nop |
DavidEGrayson | 0:06475317f283 | 112 | nop |
DavidEGrayson | 0:06475317f283 | 113 | nop |
DavidEGrayson | 0:06475317f283 | 114 | nop |
DavidEGrayson | 0:06475317f283 | 115 | nop |
DavidEGrayson | 0:06475317f283 | 116 | nop |
DavidEGrayson | 4:d3b60bd43811 | 117 | |
DavidEGrayson | 0:06475317f283 | 118 | nop |
DavidEGrayson | 0:06475317f283 | 119 | nop |
DavidEGrayson | 0:06475317f283 | 120 | nop |
DavidEGrayson | 0:06475317f283 | 121 | nop |
DavidEGrayson | 4:d3b60bd43811 | 122 | nop |
DavidEGrayson | 4:d3b60bd43811 | 123 | nop |
DavidEGrayson | 0:06475317f283 | 124 | nop |
DavidEGrayson | 0:06475317f283 | 125 | nop |
DavidEGrayson | 0:06475317f283 | 126 | nop |
DavidEGrayson | 0:06475317f283 | 127 | nop |
DavidEGrayson | 0:06475317f283 | 128 | nop |
DavidEGrayson | 0:06475317f283 | 129 | nop |
DavidEGrayson | 0:06475317f283 | 130 | nop |
DavidEGrayson | 0:06475317f283 | 131 | nop |
DavidEGrayson | 0:06475317f283 | 132 | nop |
DavidEGrayson | 0:06475317f283 | 133 | nop |
DavidEGrayson | 0:06475317f283 | 134 | |
DavidEGrayson | 0:06475317f283 | 135 | nop |
DavidEGrayson | 0:06475317f283 | 136 | nop |
DavidEGrayson | 0:06475317f283 | 137 | nop |
DavidEGrayson | 0:06475317f283 | 138 | nop |
DavidEGrayson | 0:06475317f283 | 139 | nop |
DavidEGrayson | 0:06475317f283 | 140 | nop |
DavidEGrayson | 0:06475317f283 | 141 | nop |
DavidEGrayson | 0:06475317f283 | 142 | nop |
DavidEGrayson | 0:06475317f283 | 143 | nop |
DavidEGrayson | 0:06475317f283 | 144 | nop |
DavidEGrayson | 4:d3b60bd43811 | 145 | nop |
DavidEGrayson | 4:d3b60bd43811 | 146 | nop |
DavidEGrayson | 4:d3b60bd43811 | 147 | nop |
DavidEGrayson | 4:d3b60bd43811 | 148 | nop |
DavidEGrayson | 4:d3b60bd43811 | 149 | nop |
DavidEGrayson | 4:d3b60bd43811 | 150 | nop |
DavidEGrayson | 0:06475317f283 | 151 | |
DavidEGrayson | 0:06475317f283 | 152 | nop |
DavidEGrayson | 0:06475317f283 | 153 | nop |
DavidEGrayson | 0:06475317f283 | 154 | nop |
DavidEGrayson | 0:06475317f283 | 155 | nop |
DavidEGrayson | 0:06475317f283 | 156 | nop |
DavidEGrayson | 0:06475317f283 | 157 | nop |
DavidEGrayson | 0:06475317f283 | 158 | nop |
DavidEGrayson | 0:06475317f283 | 159 | nop |
DavidEGrayson | 0:06475317f283 | 160 | nop |
DavidEGrayson | 0:06475317f283 | 161 | nop |
DavidEGrayson | 4:d3b60bd43811 | 162 | nop |
DavidEGrayson | 4:d3b60bd43811 | 163 | nop |
DavidEGrayson | 4:d3b60bd43811 | 164 | nop |
DavidEGrayson | 4:d3b60bd43811 | 165 | nop |
DavidEGrayson | 4:d3b60bd43811 | 166 | nop |
DavidEGrayson | 4:d3b60bd43811 | 167 | nop |
DavidEGrayson | 0:06475317f283 | 168 | |
DavidEGrayson | 0:06475317f283 | 169 | nop |
DavidEGrayson | 0:06475317f283 | 170 | nop |
DavidEGrayson | 0:06475317f283 | 171 | nop |
DavidEGrayson | 0:06475317f283 | 172 | nop |
DavidEGrayson | 0:06475317f283 | 173 | nop |
DavidEGrayson | 0:06475317f283 | 174 | nop |
DavidEGrayson | 0:06475317f283 | 175 | nop |
DavidEGrayson | 0:06475317f283 | 176 | nop |
DavidEGrayson | 0:06475317f283 | 177 | nop |
DavidEGrayson | 0:06475317f283 | 178 | nop |
DavidEGrayson | 0:06475317f283 | 179 | nop |
DavidEGrayson | 0:06475317f283 | 180 | nop |
DavidEGrayson | 0:06475317f283 | 181 | nop |
DavidEGrayson | 0:06475317f283 | 182 | nop |
DavidEGrayson | 0:06475317f283 | 183 | nop |
DavidEGrayson | 0:06475317f283 | 184 | nop |
DavidEGrayson | 0:06475317f283 | 185 | |
DavidEGrayson | 0:06475317f283 | 186 | nop |
DavidEGrayson | 0:06475317f283 | 187 | nop |
DavidEGrayson | 0:06475317f283 | 188 | nop |
DavidEGrayson | 0:06475317f283 | 189 | nop |
DavidEGrayson | 0:06475317f283 | 190 | nop |
DavidEGrayson | 0:06475317f283 | 191 | nop |
DavidEGrayson | 0:06475317f283 | 192 | nop |
DavidEGrayson | 0:06475317f283 | 193 | nop |
DavidEGrayson | 0:06475317f283 | 194 | nop |
DavidEGrayson | 0:06475317f283 | 195 | nop |
DavidEGrayson | 4:d3b60bd43811 | 196 | nop |
DavidEGrayson | 4:d3b60bd43811 | 197 | nop |
DavidEGrayson | 4:d3b60bd43811 | 198 | nop |
DavidEGrayson | 4:d3b60bd43811 | 199 | nop |
DavidEGrayson | 4:d3b60bd43811 | 200 | nop |
DavidEGrayson | 4:d3b60bd43811 | 201 | nop |
DavidEGrayson | 4:d3b60bd43811 | 202 | |
DavidEGrayson | 0:06475317f283 | 203 | nop |
DavidEGrayson | 0:06475317f283 | 204 | nop |
DavidEGrayson | 0:06475317f283 | 205 | nop |
DavidEGrayson | 0:06475317f283 | 206 | nop |
DavidEGrayson | 0:06475317f283 | 207 | nop |
DavidEGrayson | 0:06475317f283 | 208 | nop |
DavidEGrayson | 4:d3b60bd43811 | 209 | nop |
DavidEGrayson | 4:d3b60bd43811 | 210 | nop |
DavidEGrayson | 4:d3b60bd43811 | 211 | nop |
DavidEGrayson | 4:d3b60bd43811 | 212 | nop |
DavidEGrayson | 4:d3b60bd43811 | 213 | nop |
DavidEGrayson | 4:d3b60bd43811 | 214 | nop |
DavidEGrayson | 4:d3b60bd43811 | 215 | nop |
DavidEGrayson | 4:d3b60bd43811 | 216 | nop |
DavidEGrayson | 4:d3b60bd43811 | 217 | nop |
DavidEGrayson | 4:d3b60bd43811 | 218 | nop |
DavidEGrayson | 5:690fdfb595de | 219 | delay_region_end |
DavidEGrayson | 4:d3b60bd43811 | 220 | bx lr ; return |
DavidEGrayson | 0:06475317f283 | 221 | |
DavidEGrayson | 0:06475317f283 | 222 | END |