明石高専ロボ研 mbedライブラリ
Dependents: MDD_L432KC USB2RS485 pathtracking odometry ... more
neopixel.cpp@7:4ad54efe2fdd, 2020-12-06 (annotated)
- Committer:
- TanakaRobo
- Date:
- Sun Dec 06 08:09:01 2020 +0000
- Revision:
- 7:4ad54efe2fdd
- Parent:
- 5:a7894e6982ea
- Child:
- 8:82727add54ce
can use printf with scrp;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
TanakaRobo | 0:ca84ed7518f5 | 1 | #include "mbed.h" |
TanakaRobo | 0:ca84ed7518f5 | 2 | #include "neopixel.h" |
TanakaRobo | 0:ca84ed7518f5 | 3 | |
TanakaRobo | 7:4ad54efe2fdd | 4 | #if defined(TARGET_NUCLEO_L432KC) |
TanakaRobo | 7:4ad54efe2fdd | 5 | |
TanakaRobo | 7:4ad54efe2fdd | 6 | #define PIXEL_WAIT_1_ (6) |
TanakaRobo | 7:4ad54efe2fdd | 7 | #define PIXEL_WAIT_2_ (2) |
TanakaRobo | 7:4ad54efe2fdd | 8 | #define PIXEL_WAIT_3_ (2) |
TanakaRobo | 7:4ad54efe2fdd | 9 | #define PIXEL_WAIT_4_ (5) |
TanakaRobo | 7:4ad54efe2fdd | 10 | |
TanakaRobo | 7:4ad54efe2fdd | 11 | #elif defined(TARGET_NUCLEO_F446RE) |
TanakaRobo | 7:4ad54efe2fdd | 12 | |
TanakaRobo | 7:4ad54efe2fdd | 13 | #define PIXEL_WAIT_1_ (9) |
TanakaRobo | 7:4ad54efe2fdd | 14 | #define PIXEL_WAIT_2_ (5) |
TanakaRobo | 7:4ad54efe2fdd | 15 | #define PIXEL_WAIT_3_ (4) |
TanakaRobo | 7:4ad54efe2fdd | 16 | #define PIXEL_WAIT_4_ (9) |
TanakaRobo | 7:4ad54efe2fdd | 17 | |
TanakaRobo | 7:4ad54efe2fdd | 18 | #else |
TanakaRobo | 7:4ad54efe2fdd | 19 | #error "This board is not supported" |
TanakaRobo | 7:4ad54efe2fdd | 20 | #endif |
TanakaRobo | 0:ca84ed7518f5 | 21 | |
TanakaRobo | 5:a7894e6982ea | 22 | NeoPixelOut::NeoPixelOut(PinName pin, int num) : DigitalOut(pin) |
TanakaRobo | 0:ca84ed7518f5 | 23 | { |
TanakaRobo | 0:ca84ed7518f5 | 24 | normalize = false; |
TanakaRobo | 0:ca84ed7518f5 | 25 | global_scale = 1.0f; |
TanakaRobo | 5:a7894e6982ea | 26 | num_pixels_ = num; |
TanakaRobo | 5:a7894e6982ea | 27 | strip_.resize(num); |
TanakaRobo | 0:ca84ed7518f5 | 28 | } |
TanakaRobo | 0:ca84ed7518f5 | 29 | |
TanakaRobo | 0:ca84ed7518f5 | 30 | // The timing should be approximately 800ns/300ns, 300ns/800ns |
TanakaRobo | 0:ca84ed7518f5 | 31 | void NeoPixelOut::byte(register uint32_t byte) |
TanakaRobo | 0:ca84ed7518f5 | 32 | { |
TanakaRobo | 0:ca84ed7518f5 | 33 | for (int i = 0; i < 8; i++) { |
TanakaRobo | 0:ca84ed7518f5 | 34 | gpio_write(&gpio, 1); |
TanakaRobo | 0:ca84ed7518f5 | 35 | |
TanakaRobo | 0:ca84ed7518f5 | 36 | // duty cycle determines bit value |
TanakaRobo | 0:ca84ed7518f5 | 37 | if (byte & 0x80) { |
TanakaRobo | 0:ca84ed7518f5 | 38 | // one |
TanakaRobo | 7:4ad54efe2fdd | 39 | for(int j = 0; j < PIXEL_WAIT_1_; j++) asm("NOP");//6 9 |
TanakaRobo | 0:ca84ed7518f5 | 40 | |
TanakaRobo | 0:ca84ed7518f5 | 41 | gpio_write(&gpio, 0); |
TanakaRobo | 7:4ad54efe2fdd | 42 | for(int j = 0; j < PIXEL_WAIT_2_; j++) asm("NOP");//2 5 |
TanakaRobo | 0:ca84ed7518f5 | 43 | } |
TanakaRobo | 0:ca84ed7518f5 | 44 | else { |
TanakaRobo | 0:ca84ed7518f5 | 45 | // zero |
TanakaRobo | 7:4ad54efe2fdd | 46 | for(int j = 0; j < PIXEL_WAIT_3_; j++) asm("NOP");//2 4 |
TanakaRobo | 0:ca84ed7518f5 | 47 | |
TanakaRobo | 0:ca84ed7518f5 | 48 | gpio_write(&gpio, 0); |
TanakaRobo | 7:4ad54efe2fdd | 49 | for(int j = 0; j < PIXEL_WAIT_4_; j++) asm("NOP");//5 9 |
TanakaRobo | 0:ca84ed7518f5 | 50 | } |
TanakaRobo | 0:ca84ed7518f5 | 51 | |
TanakaRobo | 0:ca84ed7518f5 | 52 | byte = byte << 1; // shift to next bit |
TanakaRobo | 0:ca84ed7518f5 | 53 | } |
TanakaRobo | 0:ca84ed7518f5 | 54 | |
TanakaRobo | 0:ca84ed7518f5 | 55 | } |
TanakaRobo | 0:ca84ed7518f5 | 56 | |
TanakaRobo | 5:a7894e6982ea | 57 | void NeoPixelOut::setPixelColor(uint32_t i,uint32_t color){ |
TanakaRobo | 5:a7894e6982ea | 58 | if(i >= num_pixels_){ |
TanakaRobo | 5:a7894e6982ea | 59 | return; |
TanakaRobo | 5:a7894e6982ea | 60 | } |
TanakaRobo | 5:a7894e6982ea | 61 | strip_[i].hex = color; |
TanakaRobo | 5:a7894e6982ea | 62 | } |
TanakaRobo | 5:a7894e6982ea | 63 | |
TanakaRobo | 5:a7894e6982ea | 64 | void NeoPixelOut::show(){ |
TanakaRobo | 5:a7894e6982ea | 65 | // Disable interrupts in the critical section |
TanakaRobo | 5:a7894e6982ea | 66 | __disable_irq(); |
TanakaRobo | 5:a7894e6982ea | 67 | |
TanakaRobo | 5:a7894e6982ea | 68 | float fr,fg,fb; |
TanakaRobo | 7:4ad54efe2fdd | 69 | for (int i = 0; i < num_pixels_; i++) { |
TanakaRobo | 5:a7894e6982ea | 70 | fr = strip_[i].r; |
TanakaRobo | 5:a7894e6982ea | 71 | fg = strip_[i].g; |
TanakaRobo | 5:a7894e6982ea | 72 | fb = strip_[i].b; |
TanakaRobo | 5:a7894e6982ea | 73 | |
TanakaRobo | 5:a7894e6982ea | 74 | if (normalize) { |
TanakaRobo | 5:a7894e6982ea | 75 | float scale = 255.0f/(fr+fg+fb); |
TanakaRobo | 5:a7894e6982ea | 76 | fr *= scale; |
TanakaRobo | 5:a7894e6982ea | 77 | fg *= scale; |
TanakaRobo | 5:a7894e6982ea | 78 | fb *= scale; |
TanakaRobo | 5:a7894e6982ea | 79 | } |
TanakaRobo | 5:a7894e6982ea | 80 | |
TanakaRobo | 5:a7894e6982ea | 81 | fr *= global_scale; |
TanakaRobo | 5:a7894e6982ea | 82 | fg *= global_scale; |
TanakaRobo | 5:a7894e6982ea | 83 | fb *= global_scale; |
TanakaRobo | 5:a7894e6982ea | 84 | |
TanakaRobo | 5:a7894e6982ea | 85 | if (fr > 255) fr = 255; |
TanakaRobo | 5:a7894e6982ea | 86 | if (fg > 255) fg = 255; |
TanakaRobo | 5:a7894e6982ea | 87 | if (fb > 255) fb = 255; |
TanakaRobo | 5:a7894e6982ea | 88 | if (fr < 0) fr = 0; |
TanakaRobo | 5:a7894e6982ea | 89 | if (fg < 0) fg = 0; |
TanakaRobo | 5:a7894e6982ea | 90 | if (fb < 0) fb = 0; |
TanakaRobo | 5:a7894e6982ea | 91 | |
TanakaRobo | 5:a7894e6982ea | 92 | // Black magic to fix distorted timing |
TanakaRobo | 5:a7894e6982ea | 93 | #ifdef __HAL_FLASH_INSTRUCTION_CACHE_DISABLE |
TanakaRobo | 5:a7894e6982ea | 94 | __HAL_FLASH_INSTRUCTION_CACHE_DISABLE(); |
TanakaRobo | 5:a7894e6982ea | 95 | #endif |
TanakaRobo | 5:a7894e6982ea | 96 | |
TanakaRobo | 5:a7894e6982ea | 97 | byte((int)fg); |
TanakaRobo | 5:a7894e6982ea | 98 | byte((int)fr); |
TanakaRobo | 5:a7894e6982ea | 99 | byte((int)fb); |
TanakaRobo | 5:a7894e6982ea | 100 | |
TanakaRobo | 5:a7894e6982ea | 101 | #ifdef __HAL_FLASH_INSTRUCTION_CACHE_ENABLE |
TanakaRobo | 5:a7894e6982ea | 102 | __HAL_FLASH_INSTRUCTION_CACHE_ENABLE(); |
TanakaRobo | 5:a7894e6982ea | 103 | #endif |
TanakaRobo | 5:a7894e6982ea | 104 | } |
TanakaRobo | 5:a7894e6982ea | 105 | |
TanakaRobo | 5:a7894e6982ea | 106 | __enable_irq(); |
TanakaRobo | 5:a7894e6982ea | 107 | |
TanakaRobo | 5:a7894e6982ea | 108 | flip(); |
TanakaRobo | 5:a7894e6982ea | 109 | } |
TanakaRobo | 5:a7894e6982ea | 110 | |
TanakaRobo | 0:ca84ed7518f5 | 111 | void NeoPixelOut::send(Pixel *colors, uint32_t count, bool flipwait) |
TanakaRobo | 0:ca84ed7518f5 | 112 | { |
TanakaRobo | 0:ca84ed7518f5 | 113 | // Disable interrupts in the critical section |
TanakaRobo | 0:ca84ed7518f5 | 114 | __disable_irq(); |
TanakaRobo | 0:ca84ed7518f5 | 115 | |
TanakaRobo | 0:ca84ed7518f5 | 116 | Pixel* rgb; |
TanakaRobo | 0:ca84ed7518f5 | 117 | float fr,fg,fb; |
TanakaRobo | 0:ca84ed7518f5 | 118 | for (int i = 0; i < count; i++) { |
TanakaRobo | 0:ca84ed7518f5 | 119 | rgb = colors++; |
TanakaRobo | 0:ca84ed7518f5 | 120 | fr = (int)rgb->r; |
TanakaRobo | 0:ca84ed7518f5 | 121 | fg = (int)rgb->g; |
TanakaRobo | 0:ca84ed7518f5 | 122 | fb = (int)rgb->b; |
TanakaRobo | 0:ca84ed7518f5 | 123 | |
TanakaRobo | 0:ca84ed7518f5 | 124 | if (normalize) { |
TanakaRobo | 0:ca84ed7518f5 | 125 | float scale = 255.0f/(fr+fg+fb); |
TanakaRobo | 0:ca84ed7518f5 | 126 | fr *= scale; |
TanakaRobo | 0:ca84ed7518f5 | 127 | fg *= scale; |
TanakaRobo | 0:ca84ed7518f5 | 128 | fb *= scale; |
TanakaRobo | 0:ca84ed7518f5 | 129 | } |
TanakaRobo | 0:ca84ed7518f5 | 130 | |
TanakaRobo | 0:ca84ed7518f5 | 131 | fr *= global_scale; |
TanakaRobo | 0:ca84ed7518f5 | 132 | fg *= global_scale; |
TanakaRobo | 0:ca84ed7518f5 | 133 | fb *= global_scale; |
TanakaRobo | 0:ca84ed7518f5 | 134 | |
TanakaRobo | 0:ca84ed7518f5 | 135 | if (fr > 255) fr = 255; |
TanakaRobo | 0:ca84ed7518f5 | 136 | if (fg > 255) fg = 255; |
TanakaRobo | 0:ca84ed7518f5 | 137 | if (fb > 255) fb = 255; |
TanakaRobo | 0:ca84ed7518f5 | 138 | if (fr < 0) fr = 0; |
TanakaRobo | 0:ca84ed7518f5 | 139 | if (fg < 0) fg = 0; |
TanakaRobo | 0:ca84ed7518f5 | 140 | if (fb < 0) fb = 0; |
TanakaRobo | 0:ca84ed7518f5 | 141 | |
TanakaRobo | 0:ca84ed7518f5 | 142 | // Black magic to fix distorted timing |
TanakaRobo | 0:ca84ed7518f5 | 143 | #ifdef __HAL_FLASH_INSTRUCTION_CACHE_DISABLE |
TanakaRobo | 0:ca84ed7518f5 | 144 | __HAL_FLASH_INSTRUCTION_CACHE_DISABLE(); |
TanakaRobo | 0:ca84ed7518f5 | 145 | #endif |
TanakaRobo | 0:ca84ed7518f5 | 146 | |
TanakaRobo | 0:ca84ed7518f5 | 147 | byte((int)fg); |
TanakaRobo | 0:ca84ed7518f5 | 148 | byte((int)fr); |
TanakaRobo | 0:ca84ed7518f5 | 149 | byte((int)fb); |
TanakaRobo | 0:ca84ed7518f5 | 150 | |
TanakaRobo | 0:ca84ed7518f5 | 151 | #ifdef __HAL_FLASH_INSTRUCTION_CACHE_ENABLE |
TanakaRobo | 0:ca84ed7518f5 | 152 | __HAL_FLASH_INSTRUCTION_CACHE_ENABLE(); |
TanakaRobo | 0:ca84ed7518f5 | 153 | #endif |
TanakaRobo | 0:ca84ed7518f5 | 154 | } |
TanakaRobo | 0:ca84ed7518f5 | 155 | |
TanakaRobo | 0:ca84ed7518f5 | 156 | __enable_irq(); |
TanakaRobo | 0:ca84ed7518f5 | 157 | |
TanakaRobo | 0:ca84ed7518f5 | 158 | if (flipwait) flip(); |
TanakaRobo | 0:ca84ed7518f5 | 159 | } |
TanakaRobo | 0:ca84ed7518f5 | 160 | |
TanakaRobo | 5:a7894e6982ea | 161 | uint32_t NeoPixelOut::color(uint32_t b,uint32_t g,uint32_t r){ |
TanakaRobo | 5:a7894e6982ea | 162 | return b + (g << 8) + (r << 16); |
TanakaRobo | 5:a7894e6982ea | 163 | } |
TanakaRobo | 5:a7894e6982ea | 164 | |
TanakaRobo | 5:a7894e6982ea | 165 | int NeoPixelOut::numPixels(){ |
TanakaRobo | 5:a7894e6982ea | 166 | return num_pixels_; |
TanakaRobo | 5:a7894e6982ea | 167 | } |
TanakaRobo | 5:a7894e6982ea | 168 | |
TanakaRobo | 5:a7894e6982ea | 169 | void NeoPixelOut::off(bool flag){ |
TanakaRobo | 5:a7894e6982ea | 170 | for(int i = 0;i < strip_.size();i++){ |
TanakaRobo | 5:a7894e6982ea | 171 | strip_[i].hex = 0; |
TanakaRobo | 5:a7894e6982ea | 172 | } |
TanakaRobo | 5:a7894e6982ea | 173 | if(flag){ |
TanakaRobo | 5:a7894e6982ea | 174 | show(); |
TanakaRobo | 5:a7894e6982ea | 175 | } |
TanakaRobo | 5:a7894e6982ea | 176 | } |
TanakaRobo | 5:a7894e6982ea | 177 | |
TanakaRobo | 5:a7894e6982ea | 178 | void NeoPixelOut::changeNum(uint32_t num){ |
TanakaRobo | 5:a7894e6982ea | 179 | strip_.resize(num); |
TanakaRobo | 5:a7894e6982ea | 180 | num_pixels_ = num; |
TanakaRobo | 5:a7894e6982ea | 181 | } |
TanakaRobo | 5:a7894e6982ea | 182 | |
TanakaRobo | 5:a7894e6982ea | 183 | void NeoPixelOut::setBrightness(float brightness){ |
TanakaRobo | 5:a7894e6982ea | 184 | global_scale = brightness; |
TanakaRobo | 5:a7894e6982ea | 185 | } |
TanakaRobo | 0:ca84ed7518f5 | 186 | |
TanakaRobo | 0:ca84ed7518f5 | 187 | void NeoPixelOut::flip(void) |
TanakaRobo | 0:ca84ed7518f5 | 188 | { |
TanakaRobo | 0:ca84ed7518f5 | 189 | wait_us(50); |
TanakaRobo | 0:ca84ed7518f5 | 190 | } |