Modifications on NeoMatrix library to fit the recent Mbed system

Dependents:   4180_final_project_github

Committer:
oscargao
Date:
Wed Dec 02 18:17:05 2020 +0000
Revision:
4:f5c7124c262f
Parent:
3:9a2779957e46
made it work

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tpowell33 2:97ef32687eba 1 /**********************************************
tpowell33 3:9a2779957e46 2 * NeoMatrix.cpp
tpowell33 2:97ef32687eba 3 *
tpowell33 2:97ef32687eba 4 * Taylor Powell
tpowell33 2:97ef32687eba 5 * March 2015
tpowell33 2:97ef32687eba 6 *
tpowell33 2:97ef32687eba 7 * Controls an Adafruit Neopixel NeoMatrix 8x8
tpowell33 2:97ef32687eba 8 * Because of the global nature of the IO register and bitmask variables, only one contiguous chain of NeoMatrix Arrays can be connected
tpowell33 2:97ef32687eba 9 * A large number of NeoMatrix arrays can be chained together by tying Din to Dout of sucessive arrays, but an external power sourece may be required
tpowell33 2:97ef32687eba 10 *
tpowell33 2:97ef32687eba 11 * This library supports only the NXP LPC1768
tpowell33 2:97ef32687eba 12 */
tpowell33 2:97ef32687eba 13
tpowell33 2:97ef32687eba 14 #include "mbed.h"
tpowell33 3:9a2779957e46 15 #include "NeoMatrix.h"
tpowell33 2:97ef32687eba 16 #include "font.h"
tpowell33 2:97ef32687eba 17
tpowell33 2:97ef32687eba 18
tpowell33 2:97ef32687eba 19 // FastIO register address and bitmask for the GPIO pin
tpowell33 2:97ef32687eba 20 // because these are imported in the assembly
tpowell33 2:97ef32687eba 21 uint32_t neo_fio_reg;
tpowell33 2:97ef32687eba 22 uint32_t neo_bitmask;
tpowell33 2:97ef32687eba 23
tpowell33 2:97ef32687eba 24 // function to write to the strip, implemented in ARM assembly
tpowell33 2:97ef32687eba 25 extern "C" void neo_out(NeoColor*, int);
tpowell33 2:97ef32687eba 26
tpowell33 2:97ef32687eba 27 #define max(a,b) \
tpowell33 2:97ef32687eba 28 ({ __typeof__ (a) _a = (a); \
tpowell33 2:97ef32687eba 29 __typeof__ (b) _b = (b); \
tpowell33 2:97ef32687eba 30 _a > _b ? _a : _b; })
tpowell33 2:97ef32687eba 31
tpowell33 2:97ef32687eba 32 #define min(a,b) \
tpowell33 2:97ef32687eba 33 ({ __typeof__ (a) _a = (a); \
tpowell33 2:97ef32687eba 34 __typeof__ (b) _b = (b); \
tpowell33 2:97ef32687eba 35 _a < _b ? _a : _b; })
tpowell33 2:97ef32687eba 36
tpowell33 2:97ef32687eba 37
tpowell33 2:97ef32687eba 38
tpowell33 2:97ef32687eba 39 NeoArr::NeoArr(PinName pin, int N) : N(N)
tpowell33 2:97ef32687eba 40 {
tpowell33 2:97ef32687eba 41 bright = 0.5;
tpowell33 2:97ef32687eba 42 Nbytes = N * 64 * 3;
tpowell33 2:97ef32687eba 43 arr = (NeoColor*)malloc(N * 64 * sizeof(NeoColor));
tpowell33 2:97ef32687eba 44 if (arr == NULL)
tpowell33 2:97ef32687eba 45 {
tpowell33 2:97ef32687eba 46 printf("NeoArr: ERROR unable to malloc pixel array data");
tpowell33 2:97ef32687eba 47 N = 0;
tpowell33 2:97ef32687eba 48 }
tpowell33 2:97ef32687eba 49
oscargao 4:f5c7124c262f 50 gpio_init_out(&gpio, pin); // initialize GPIO registers
tpowell33 2:97ef32687eba 51 neo_fio_reg = (uint32_t)gpio.reg_dir; // set registers and bitmask for
tpowell33 2:97ef32687eba 52 neo_bitmask = 1 << ((int)pin & 0x1F); // the assembly to use
tpowell33 2:97ef32687eba 53 }
tpowell33 2:97ef32687eba 54
tpowell33 2:97ef32687eba 55 void NeoArr::setBrightness(float bright)
tpowell33 2:97ef32687eba 56 {
tpowell33 2:97ef32687eba 57 this->bright = bright;
tpowell33 2:97ef32687eba 58 }
tpowell33 2:97ef32687eba 59
tpowell33 2:97ef32687eba 60
tpowell33 2:97ef32687eba 61 void NeoArr::setPixel(int idx, int x, int y, int color)
tpowell33 2:97ef32687eba 62 {
tpowell33 2:97ef32687eba 63 int red = (color & 0xFF0000) >> 16;
tpowell33 2:97ef32687eba 64 int green = (color & 0x00FF00) >> 8;
tpowell33 2:97ef32687eba 65 int blue = (color & 0x0000FF);
tpowell33 2:97ef32687eba 66
tpowell33 2:97ef32687eba 67 setPixel(idx, x, y, red, green, blue);
tpowell33 2:97ef32687eba 68 }
tpowell33 2:97ef32687eba 69
tpowell33 2:97ef32687eba 70 void NeoArr::setPixel(int idx, int x, int y, uint8_t red, uint8_t green, uint8_t blue)
tpowell33 2:97ef32687eba 71 {
tpowell33 2:97ef32687eba 72 int pixel = idx*64 + x*8 + y; // specify pixel based on board index, x, and y values
tpowell33 2:97ef32687eba 73 // modulate pixel by the total number of pixels
tpowell33 2:97ef32687eba 74 arr[pixel % (N*64)].red = (uint8_t)(red * bright);
tpowell33 2:97ef32687eba 75 arr[pixel % (N*64)].green = (uint8_t)(green * bright);
tpowell33 2:97ef32687eba 76 arr[pixel % (N*64)].blue = (uint8_t)(blue * bright);
tpowell33 2:97ef32687eba 77 }
tpowell33 2:97ef32687eba 78
tpowell33 2:97ef32687eba 79 void NeoArr::drawLine(int idx, int x1, int y1, int x2, int y2, int color)
tpowell33 2:97ef32687eba 80 {
tpowell33 2:97ef32687eba 81 int red = (color & 0xFF0000) >> 16;
tpowell33 2:97ef32687eba 82 int green = (color & 0x00FF00) >> 8;
tpowell33 2:97ef32687eba 83 int blue = (color & 0x0000FF);
tpowell33 2:97ef32687eba 84
tpowell33 2:97ef32687eba 85 drawLine(idx, x1, y1, x2,y2, red, green, blue);
tpowell33 2:97ef32687eba 86 }
tpowell33 2:97ef32687eba 87
tpowell33 2:97ef32687eba 88 void NeoArr::drawLine(int idx, int x1, int y1, int x2, int y2, uint8_t red, uint8_t green, uint8_t blue)
tpowell33 2:97ef32687eba 89 {
tpowell33 2:97ef32687eba 90 float k;
tpowell33 2:97ef32687eba 91 int j = rint(sqrt(pow((x1-x2),2.0) + pow((y1-y2),2.0))); // calculates magnitude of line
tpowell33 2:97ef32687eba 92 if(x1 != x2) // handle infinite case
tpowell33 2:97ef32687eba 93 k = atan2( (float)(y2-y1),(float) ( x2-x1)); // calculates angle of line
tpowell33 2:97ef32687eba 94 else
tpowell33 2:97ef32687eba 95 k = acos(0.0);
tpowell33 2:97ef32687eba 96
tpowell33 2:97ef32687eba 97 for(float n=0; n<=j; n++) // set a number pixels equal to the magnitude of the line along the closest (rounded) line
tpowell33 2:97ef32687eba 98 if((x1+ rint(n*cos(k))) >=0 && (x1+rint( n*cos(k))) <=7 && (y1+rint(n*sin(k)))>=0 && (y1+rint(n*sin(k)))<=7)
tpowell33 2:97ef32687eba 99 setPixel(idx, x1+ rint(n*cos(k)), y1+ rint(n*sin(k)), red, green, blue);
tpowell33 2:97ef32687eba 100
tpowell33 2:97ef32687eba 101
tpowell33 2:97ef32687eba 102 }
tpowell33 2:97ef32687eba 103
tpowell33 2:97ef32687eba 104 void NeoArr::drawRect(int idx, int x1, int y1, int x2, int y2, int color)
tpowell33 2:97ef32687eba 105 {
tpowell33 2:97ef32687eba 106 int red = (color & 0xFF0000) >> 16;
tpowell33 2:97ef32687eba 107 int green = (color & 0x00FF00) >> 8;
tpowell33 2:97ef32687eba 108 int blue = (color & 0x0000FF);
tpowell33 2:97ef32687eba 109
tpowell33 2:97ef32687eba 110 drawRect(idx, x1, y1, x2,y2, red, green, blue);
tpowell33 2:97ef32687eba 111 }
tpowell33 2:97ef32687eba 112
tpowell33 2:97ef32687eba 113 void NeoArr::drawRect(int idx, int x1, int y1, int x2, int y2, uint8_t red, uint8_t green, uint8_t blue)
tpowell33 2:97ef32687eba 114 {
tpowell33 2:97ef32687eba 115 // note: drawRect does not use drawLine function because the angles will always be 90 degrees and so for these for loops are faster
tpowell33 2:97ef32687eba 116 for(int i=0; i<=(abs(x2-x1)); i++){ // draws horizontal lines
tpowell33 2:97ef32687eba 117 if ((max(x1,x2)-i) >= 0 && max(x1, x2) -i <=7){
tpowell33 2:97ef32687eba 118 if(max(y1,y2) <= 7)
tpowell33 2:97ef32687eba 119 setPixel(idx, max(x1,x2)-i, max(y1,y2), red, green, blue);
tpowell33 2:97ef32687eba 120
tpowell33 2:97ef32687eba 121 if(min(y1,y2) >= 0)
tpowell33 2:97ef32687eba 122 setPixel(idx, max(x1,x2)-i, min(y1,y2), red, green, blue);
tpowell33 2:97ef32687eba 123 }
tpowell33 2:97ef32687eba 124 }
tpowell33 2:97ef32687eba 125
tpowell33 2:97ef32687eba 126 for(int i=0; i<=(abs(y2-y1)); i++){ // draws verticle lines
tpowell33 2:97ef32687eba 127 if ((max(y1,y2)-i) >= 0 && max(y1, y2) -i <=7){
tpowell33 2:97ef32687eba 128 if(max(x1,x2) <= 7)
tpowell33 2:97ef32687eba 129 setPixel(idx, max(x1,x2), max(y1,y2)-i, red, green, blue);
tpowell33 2:97ef32687eba 130
tpowell33 2:97ef32687eba 131 if(min(x1,x2) >= 0)
tpowell33 2:97ef32687eba 132 setPixel(idx, min(x1,x2), max(y1,y2)-i, red, green, blue);
tpowell33 2:97ef32687eba 133 }
tpowell33 2:97ef32687eba 134 }
tpowell33 2:97ef32687eba 135 }
tpowell33 2:97ef32687eba 136
tpowell33 2:97ef32687eba 137
tpowell33 2:97ef32687eba 138 void NeoArr::drawFilledRect(int idx, int x1, int y1, int x2, int y2, int color)
tpowell33 2:97ef32687eba 139 {
tpowell33 2:97ef32687eba 140 int red = (color & 0xFF0000) >> 16;
tpowell33 2:97ef32687eba 141 int green = (color & 0x00FF00) >> 8;
tpowell33 2:97ef32687eba 142 int blue = (color & 0x0000FF);
tpowell33 2:97ef32687eba 143
tpowell33 2:97ef32687eba 144 drawFilledRect(idx, x1, y1, x2,y2, red, green, blue);
tpowell33 2:97ef32687eba 145 }
tpowell33 2:97ef32687eba 146
tpowell33 2:97ef32687eba 147 void NeoArr::drawFilledRect(int idx, int x1, int y1, int x2, int y2, uint8_t red, uint8_t green, uint8_t blue)
tpowell33 2:97ef32687eba 148 {
tpowell33 2:97ef32687eba 149 for(int i=0; i<=(abs(x2-x1)); i++){
tpowell33 2:97ef32687eba 150 if ((max(x1,x2)-i) >= 0 && max(x1, x2) -i <=7){
tpowell33 2:97ef32687eba 151 for(int n=0; n<=(abs(y2-y1)); n++){
tpowell33 2:97ef32687eba 152 if((max(y1,y2)-n) >= 0 && max(y1, y2)-n <=7){
tpowell33 2:97ef32687eba 153 setPixel(idx, max(x1,x2)-i, max(y1,y2)-n, red, green, blue);
tpowell33 2:97ef32687eba 154 }
tpowell33 2:97ef32687eba 155 }
tpowell33 2:97ef32687eba 156 }
tpowell33 2:97ef32687eba 157 }
tpowell33 2:97ef32687eba 158
tpowell33 2:97ef32687eba 159 }
tpowell33 2:97ef32687eba 160
tpowell33 2:97ef32687eba 161 void NeoArr::fillScreen(int idx, int color)
tpowell33 2:97ef32687eba 162 {
tpowell33 2:97ef32687eba 163 int red = (color & 0xFF0000) >> 16;
tpowell33 2:97ef32687eba 164 int green = (color & 0x00FF00) >> 8;
tpowell33 2:97ef32687eba 165 int blue = (color & 0x0000FF);
tpowell33 2:97ef32687eba 166
tpowell33 2:97ef32687eba 167 fillScreen(idx, red, green, blue);
tpowell33 2:97ef32687eba 168 }
tpowell33 2:97ef32687eba 169
tpowell33 2:97ef32687eba 170 void NeoArr::fillScreen(int idx,uint8_t red, uint8_t green, uint8_t blue)
tpowell33 2:97ef32687eba 171 {
tpowell33 2:97ef32687eba 172 for(int i=0; i<8; i++)
tpowell33 2:97ef32687eba 173 for(int n=0; n<8; n++)
tpowell33 2:97ef32687eba 174 setPixel(idx, i, n, red, green, blue);
tpowell33 2:97ef32687eba 175 }
tpowell33 2:97ef32687eba 176
tpowell33 2:97ef32687eba 177
tpowell33 2:97ef32687eba 178 void NeoArr::drawTriangle(int idx, int x1, int y1, int x2, int y2, int x3, int y3, int color)
tpowell33 2:97ef32687eba 179 {
tpowell33 2:97ef32687eba 180 int red = (color & 0xFF0000) >> 16;
tpowell33 2:97ef32687eba 181 int green = (color & 0x00FF00) >> 8;
tpowell33 2:97ef32687eba 182 int blue = (color & 0x0000FF);
tpowell33 2:97ef32687eba 183
tpowell33 2:97ef32687eba 184 drawTriangle(idx, x1, y1, x2,y2, x3, y3, red, green, blue);
tpowell33 2:97ef32687eba 185 }
tpowell33 2:97ef32687eba 186
tpowell33 2:97ef32687eba 187 void NeoArr::drawTriangle(int idx, int x1, int y1, int x2, int y2, int x3, int y3, uint8_t red, uint8_t green, uint8_t blue)
tpowell33 2:97ef32687eba 188 {
tpowell33 2:97ef32687eba 189
tpowell33 2:97ef32687eba 190 drawLine(idx, x1, y1, x2, y2, red, green, blue);
tpowell33 2:97ef32687eba 191 drawLine(idx, x2, y2, x3, y3, red, green, blue);
tpowell33 2:97ef32687eba 192 drawLine(idx, x3, y3, x1, y1, red, green, blue);
tpowell33 2:97ef32687eba 193
tpowell33 2:97ef32687eba 194 }
tpowell33 2:97ef32687eba 195
tpowell33 2:97ef32687eba 196 void NeoArr::drawFilledTriangle(int idx, int x1, int y1, int x2, int y2, int x3, int y3, int color)
tpowell33 2:97ef32687eba 197 {
tpowell33 2:97ef32687eba 198 int red = (color & 0xFF0000) >> 16;
tpowell33 2:97ef32687eba 199 int green = (color & 0x00FF00) >> 8;
tpowell33 2:97ef32687eba 200 int blue = (color & 0x0000FF);
tpowell33 2:97ef32687eba 201
tpowell33 2:97ef32687eba 202 drawFilledTriangle(idx, x1, y1, x2,y2, x3, y3, red, green, blue);
tpowell33 2:97ef32687eba 203 }
tpowell33 2:97ef32687eba 204
tpowell33 2:97ef32687eba 205 void NeoArr::drawFilledTriangle(int idx, int x1, int y1, int x2, int y2, int x3, int y3, uint8_t red, uint8_t green, uint8_t blue)
tpowell33 2:97ef32687eba 206 {
tpowell33 2:97ef32687eba 207 // note: drawFilledTriangle draws two legs of the triangle and then draws lines from their corner to each point on the opposite leg
tpowell33 2:97ef32687eba 208 drawLine(idx, x1, y1, x2, y2, red, green, blue);
tpowell33 2:97ef32687eba 209 drawLine(idx, x2, y2, x3, y3, red, green, blue);
tpowell33 2:97ef32687eba 210
tpowell33 2:97ef32687eba 211
tpowell33 2:97ef32687eba 212 float k;
tpowell33 2:97ef32687eba 213 int j = rint(sqrt(pow((x1-x3),2.0) + pow((y1-y3),2.0))); // magnitude of opposite leg
tpowell33 2:97ef32687eba 214 if(x1 != x3)
tpowell33 2:97ef32687eba 215 k = atan2( (float)(y3-y1),(float) ( x3-x1)); // angle of line of opposite leg
tpowell33 2:97ef32687eba 216 else
tpowell33 2:97ef32687eba 217 k = acos(0.0);
tpowell33 2:97ef32687eba 218
tpowell33 2:97ef32687eba 219 for(float n=0; n<=j; n++)
tpowell33 2:97ef32687eba 220 if((x1+ rint(n*cos(k))) >=0 && (x1+rint( n*cos(k))) <=7 && (y1+rint(n*sin(k)))>=0 && (y1+rint(n*sin(k)))<=7)
tpowell33 2:97ef32687eba 221 drawLine(idx, x1+ rint(n*cos(k)), y1+ rint(n*sin(k)), x2, y2, red, green, blue); // draw line from corner to each point on opposite leg
tpowell33 2:97ef32687eba 222 }
tpowell33 2:97ef32687eba 223
tpowell33 2:97ef32687eba 224 void NeoArr::drawChar(int idx, int x, int y, char c, int color)
tpowell33 2:97ef32687eba 225 {
tpowell33 2:97ef32687eba 226 int red = (color & 0xFF0000) >> 16;
tpowell33 2:97ef32687eba 227 int green = (color & 0x00FF00) >> 8;
tpowell33 2:97ef32687eba 228 int blue = (color & 0x0000FF);
tpowell33 2:97ef32687eba 229
tpowell33 2:97ef32687eba 230 drawChar(idx, x, y, c, red, green, blue);
tpowell33 2:97ef32687eba 231 }
tpowell33 2:97ef32687eba 232
tpowell33 2:97ef32687eba 233 void NeoArr::drawChar(int idx, int x, int y, char c, uint8_t red, uint8_t green, uint8_t blue)
tpowell33 2:97ef32687eba 234 {
tpowell33 2:97ef32687eba 235 uint8_t i,j;
tpowell33 2:97ef32687eba 236
tpowell33 2:97ef32687eba 237 c = c & 0x7F; // mask c to avoid errors
tpowell33 2:97ef32687eba 238
tpowell33 2:97ef32687eba 239 if (c < ' ') { // convert c into index of font array
tpowell33 2:97ef32687eba 240 c = 0;
tpowell33 2:97ef32687eba 241 } else {
tpowell33 2:97ef32687eba 242 c -= ' ';
tpowell33 2:97ef32687eba 243 }
tpowell33 2:97ef32687eba 244
tpowell33 2:97ef32687eba 245 // font is BMplain, a 96x6 array stored in font.h, many free available fonts are online and can be swapped into this font
tpowell33 2:97ef32687eba 246 const uint8_t* chr = font[c];
tpowell33 2:97ef32687eba 247
tpowell33 2:97ef32687eba 248 for (j=0; j<6; j++) { // character width is 6
tpowell33 2:97ef32687eba 249 for (i=0; i<8; i++) { // character height is 8
tpowell33 2:97ef32687eba 250 if (chr[j] & (1<<i)) { // if there is a pixel in the vertical line, set pixel on board
tpowell33 2:97ef32687eba 251 if((x+j) <= 7 && (x+j)>=0 && (y+7-i)>=0 && (y+7-i) <=7)
tpowell33 2:97ef32687eba 252 setPixel(0, x+j, y+ 7-i, red,green,blue);
tpowell33 2:97ef32687eba 253 }
tpowell33 2:97ef32687eba 254 }
tpowell33 2:97ef32687eba 255 }
tpowell33 2:97ef32687eba 256 }
tpowell33 2:97ef32687eba 257
tpowell33 2:97ef32687eba 258 void NeoArr::showImage(int idx, const int *img)
tpowell33 2:97ef32687eba 259 {
tpowell33 2:97ef32687eba 260 int r, g, b;
tpowell33 2:97ef32687eba 261 for (int i = 0; i < 8; i++)
tpowell33 2:97ef32687eba 262 for(int n=0; n<8;n++){
tpowell33 2:97ef32687eba 263 r = (img[i] & 0xFF0000) >> 16;
tpowell33 2:97ef32687eba 264 g = (img[i] & 0x00FF00) >>8;
tpowell33 2:97ef32687eba 265 b = img[i] & 0x0000FF;
tpowell33 2:97ef32687eba 266 setPixel(idx,i,n, r, g, b);
tpowell33 2:97ef32687eba 267 }
tpowell33 2:97ef32687eba 268 }
tpowell33 2:97ef32687eba 269
tpowell33 2:97ef32687eba 270 void NeoArr::clear()
tpowell33 2:97ef32687eba 271 {
tpowell33 2:97ef32687eba 272 for (int i = 0; i < (N*64); i++)
tpowell33 2:97ef32687eba 273 {
tpowell33 2:97ef32687eba 274 arr[i].red = 0;
tpowell33 2:97ef32687eba 275 arr[i].green = 0;
tpowell33 2:97ef32687eba 276 arr[i].blue = 0;
tpowell33 2:97ef32687eba 277 }
tpowell33 2:97ef32687eba 278 }
tpowell33 2:97ef32687eba 279
tpowell33 2:97ef32687eba 280 void NeoArr::write()
tpowell33 2:97ef32687eba 281 {
tpowell33 2:97ef32687eba 282 __disable_irq(); // disable interrupts
tpowell33 2:97ef32687eba 283 neo_out(arr, Nbytes); // output to the strip
tpowell33 2:97ef32687eba 284 __enable_irq(); // enable interrupts
tpowell33 2:97ef32687eba 285 wait_us(50); // wait 50us for the reset pulse
tpowell33 2:97ef32687eba 286 }
tpowell33 2:97ef32687eba 287
tpowell33 2:97ef32687eba 288