NeoPixel NeoMatrix 8x8 RGB LED library. Product found at https://www.adafruit.com/products/1487. NeoCore.s from Allen Wild's NeoStrip library: http://developer.mbed.org/users/aswild/code/NeoStrip/
Fork of NeoStrip by
NeoMatrix.cpp
00001 /********************************************** 00002 * NeoMatrix.cpp 00003 * 00004 * Taylor Powell 00005 * March 2015 00006 * 00007 * Controls an Adafruit Neopixel NeoMatrix 8x8 00008 * Because of the global nature of the IO register and bitmask variables, only one contiguous chain of NeoMatrix Arrays can be connected 00009 * 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 00010 * 00011 * This library supports only the NXP LPC1768 00012 */ 00013 00014 #include "mbed.h" 00015 #include "NeoMatrix.h" 00016 #include "font.h" 00017 00018 00019 // FastIO register address and bitmask for the GPIO pin 00020 // because these are imported in the assembly 00021 uint32_t neo_fio_reg; 00022 uint32_t neo_bitmask; 00023 00024 // function to write to the strip, implemented in ARM assembly 00025 extern "C" void neo_out(NeoColor*, int); 00026 00027 #define max(a,b) \ 00028 ({ __typeof__ (a) _a = (a); \ 00029 __typeof__ (b) _b = (b); \ 00030 _a > _b ? _a : _b; }) 00031 00032 #define min(a,b) \ 00033 ({ __typeof__ (a) _a = (a); \ 00034 __typeof__ (b) _b = (b); \ 00035 _a < _b ? _a : _b; }) 00036 00037 00038 00039 NeoArr::NeoArr(PinName pin, int N) : N(N) 00040 { 00041 bright = 0.5; 00042 Nbytes = N * 64 * 3; 00043 arr = (NeoColor*)malloc(N * 64 * sizeof(NeoColor)); 00044 if (arr == NULL) 00045 { 00046 printf("NeoArr: ERROR unable to malloc pixel array data"); 00047 N = 0; 00048 } 00049 00050 gpio_init(&gpio, pin, PIN_OUTPUT); // initialize GPIO registers 00051 neo_fio_reg = (uint32_t)gpio.reg_dir; // set registers and bitmask for 00052 neo_bitmask = 1 << ((int)pin & 0x1F); // the assembly to use 00053 } 00054 00055 void NeoArr::setBrightness(float bright) 00056 { 00057 this->bright = bright; 00058 } 00059 00060 00061 void NeoArr::setPixel(int idx, int x, int y, int color) 00062 { 00063 int red = (color & 0xFF0000) >> 16; 00064 int green = (color & 0x00FF00) >> 8; 00065 int blue = (color & 0x0000FF); 00066 00067 setPixel(idx, x, y, red, green, blue); 00068 } 00069 00070 void NeoArr::setPixel(int idx, int x, int y, uint8_t red, uint8_t green, uint8_t blue) 00071 { 00072 int pixel = idx*64 + x*8 + y; // specify pixel based on board index, x, and y values 00073 // modulate pixel by the total number of pixels 00074 arr[pixel % (N*64)].red = (uint8_t)(red * bright); 00075 arr[pixel % (N*64)].green = (uint8_t)(green * bright); 00076 arr[pixel % (N*64)].blue = (uint8_t)(blue * bright); 00077 } 00078 00079 void NeoArr::drawLine(int idx, int x1, int y1, int x2, int y2, int color) 00080 { 00081 int red = (color & 0xFF0000) >> 16; 00082 int green = (color & 0x00FF00) >> 8; 00083 int blue = (color & 0x0000FF); 00084 00085 drawLine(idx, x1, y1, x2,y2, red, green, blue); 00086 } 00087 00088 void NeoArr::drawLine(int idx, int x1, int y1, int x2, int y2, uint8_t red, uint8_t green, uint8_t blue) 00089 { 00090 float k; 00091 int j = rint(sqrt(pow((x1-x2),2.0) + pow((y1-y2),2.0))); // calculates magnitude of line 00092 if(x1 != x2) // handle infinite case 00093 k = atan2( (float)(y2-y1),(float) ( x2-x1)); // calculates angle of line 00094 else 00095 k = acos(0.0); 00096 00097 for(float n=0; n<=j; n++) // set a number pixels equal to the magnitude of the line along the closest (rounded) line 00098 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) 00099 setPixel(idx, x1+ rint(n*cos(k)), y1+ rint(n*sin(k)), red, green, blue); 00100 00101 00102 } 00103 00104 void NeoArr::drawRect(int idx, int x1, int y1, int x2, int y2, int color) 00105 { 00106 int red = (color & 0xFF0000) >> 16; 00107 int green = (color & 0x00FF00) >> 8; 00108 int blue = (color & 0x0000FF); 00109 00110 drawRect(idx, x1, y1, x2,y2, red, green, blue); 00111 } 00112 00113 void NeoArr::drawRect(int idx, int x1, int y1, int x2, int y2, uint8_t red, uint8_t green, uint8_t blue) 00114 { 00115 // note: drawRect does not use drawLine function because the angles will always be 90 degrees and so for these for loops are faster 00116 for(int i=0; i<=(abs(x2-x1)); i++){ // draws horizontal lines 00117 if ((max(x1,x2)-i) >= 0 && max(x1, x2) -i <=7){ 00118 if(max(y1,y2) <= 7) 00119 setPixel(idx, max(x1,x2)-i, max(y1,y2), red, green, blue); 00120 00121 if(min(y1,y2) >= 0) 00122 setPixel(idx, max(x1,x2)-i, min(y1,y2), red, green, blue); 00123 } 00124 } 00125 00126 for(int i=0; i<=(abs(y2-y1)); i++){ // draws verticle lines 00127 if ((max(y1,y2)-i) >= 0 && max(y1, y2) -i <=7){ 00128 if(max(x1,x2) <= 7) 00129 setPixel(idx, max(x1,x2), max(y1,y2)-i, red, green, blue); 00130 00131 if(min(x1,x2) >= 0) 00132 setPixel(idx, min(x1,x2), max(y1,y2)-i, red, green, blue); 00133 } 00134 } 00135 } 00136 00137 00138 void NeoArr::drawFilledRect(int idx, int x1, int y1, int x2, int y2, int color) 00139 { 00140 int red = (color & 0xFF0000) >> 16; 00141 int green = (color & 0x00FF00) >> 8; 00142 int blue = (color & 0x0000FF); 00143 00144 drawFilledRect(idx, x1, y1, x2,y2, red, green, blue); 00145 } 00146 00147 void NeoArr::drawFilledRect(int idx, int x1, int y1, int x2, int y2, uint8_t red, uint8_t green, uint8_t blue) 00148 { 00149 for(int i=0; i<=(abs(x2-x1)); i++){ 00150 if ((max(x1,x2)-i) >= 0 && max(x1, x2) -i <=7){ 00151 for(int n=0; n<=(abs(y2-y1)); n++){ 00152 if((max(y1,y2)-n) >= 0 && max(y1, y2)-n <=7){ 00153 setPixel(idx, max(x1,x2)-i, max(y1,y2)-n, red, green, blue); 00154 } 00155 } 00156 } 00157 } 00158 00159 } 00160 00161 void NeoArr::fillScreen(int idx, int color) 00162 { 00163 int red = (color & 0xFF0000) >> 16; 00164 int green = (color & 0x00FF00) >> 8; 00165 int blue = (color & 0x0000FF); 00166 00167 fillScreen(idx, red, green, blue); 00168 } 00169 00170 void NeoArr::fillScreen(int idx,uint8_t red, uint8_t green, uint8_t blue) 00171 { 00172 for(int i=0; i<8; i++) 00173 for(int n=0; n<8; n++) 00174 setPixel(idx, i, n, red, green, blue); 00175 } 00176 00177 00178 void NeoArr::drawTriangle(int idx, int x1, int y1, int x2, int y2, int x3, int y3, int color) 00179 { 00180 int red = (color & 0xFF0000) >> 16; 00181 int green = (color & 0x00FF00) >> 8; 00182 int blue = (color & 0x0000FF); 00183 00184 drawTriangle(idx, x1, y1, x2,y2, x3, y3, red, green, blue); 00185 } 00186 00187 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) 00188 { 00189 00190 drawLine(idx, x1, y1, x2, y2, red, green, blue); 00191 drawLine(idx, x2, y2, x3, y3, red, green, blue); 00192 drawLine(idx, x3, y3, x1, y1, red, green, blue); 00193 00194 } 00195 00196 void NeoArr::drawFilledTriangle(int idx, int x1, int y1, int x2, int y2, int x3, int y3, int color) 00197 { 00198 int red = (color & 0xFF0000) >> 16; 00199 int green = (color & 0x00FF00) >> 8; 00200 int blue = (color & 0x0000FF); 00201 00202 drawFilledTriangle(idx, x1, y1, x2,y2, x3, y3, red, green, blue); 00203 } 00204 00205 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) 00206 { 00207 // note: drawFilledTriangle draws two legs of the triangle and then draws lines from their corner to each point on the opposite leg 00208 drawLine(idx, x1, y1, x2, y2, red, green, blue); 00209 drawLine(idx, x2, y2, x3, y3, red, green, blue); 00210 00211 00212 float k; 00213 int j = rint(sqrt(pow((x1-x3),2.0) + pow((y1-y3),2.0))); // magnitude of opposite leg 00214 if(x1 != x3) 00215 k = atan2( (float)(y3-y1),(float) ( x3-x1)); // angle of line of opposite leg 00216 else 00217 k = acos(0.0); 00218 00219 for(float n=0; n<=j; n++) 00220 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) 00221 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 00222 } 00223 00224 void NeoArr::drawChar(int idx, int x, int y, char c, int color) 00225 { 00226 int red = (color & 0xFF0000) >> 16; 00227 int green = (color & 0x00FF00) >> 8; 00228 int blue = (color & 0x0000FF); 00229 00230 drawChar(idx, x, y, c, red, green, blue); 00231 } 00232 00233 void NeoArr::drawChar(int idx, int x, int y, char c, uint8_t red, uint8_t green, uint8_t blue) 00234 { 00235 uint8_t i,j; 00236 00237 c = c & 0x7F; // mask c to avoid errors 00238 00239 if (c < ' ') { // convert c into index of font array 00240 c = 0; 00241 } else { 00242 c -= ' '; 00243 } 00244 00245 // font is BMplain, a 96x6 array stored in font.h, many free available fonts are online and can be swapped into this font 00246 const uint8_t* chr = font[c]; 00247 00248 for (j=0; j<6; j++) { // character width is 6 00249 for (i=0; i<8; i++) { // character height is 8 00250 if (chr[j] & (1<<i)) { // if there is a pixel in the vertical line, set pixel on board 00251 if((x+j) <= 7 && (x+j)>=0 && (y+7-i)>=0 && (y+7-i) <=7) 00252 setPixel(0, x+j, y+ 7-i, red,green,blue); 00253 } 00254 } 00255 } 00256 } 00257 00258 void NeoArr::showImage(int idx, const int *img) 00259 { 00260 int r, g, b; 00261 for (int i = 0; i < 8; i++) 00262 for(int n=0; n<8;n++){ 00263 r = (img[i] & 0xFF0000) >> 16; 00264 g = (img[i] & 0x00FF00) >>8; 00265 b = img[i] & 0x0000FF; 00266 setPixel(idx,i,n, r, g, b); 00267 } 00268 } 00269 00270 void NeoArr::clear() 00271 { 00272 for (int i = 0; i < (N*64); i++) 00273 { 00274 arr[i].red = 0; 00275 arr[i].green = 0; 00276 arr[i].blue = 0; 00277 } 00278 } 00279 00280 void NeoArr::write() 00281 { 00282 __disable_irq(); // disable interrupts 00283 neo_out(arr, Nbytes); // output to the strip 00284 __enable_irq(); // enable interrupts 00285 wait_us(50); // wait 50us for the reset pulse 00286 } 00287 00288
Generated on Tue Jul 12 2022 15:51:38 by 1.7.2