Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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

NeoPixel NeoMatrix 8x8