ssd1306_128x64_spi.ino (11930B)
1 /************************************************************************** 2 This is an example for our Monochrome OLEDs based on SSD1306 drivers 3 4 Pick one up today in the adafruit shop! 5 ------> http://www.adafruit.com/category/63_98 6 7 This example is for a 128x64 pixel display using SPI to communicate 8 4 or 5 pins are required to interface. 9 10 Adafruit invests time and resources providing this open 11 source code, please support Adafruit and open-source 12 hardware by purchasing products from Adafruit! 13 14 Written by Limor Fried/Ladyada for Adafruit Industries, 15 with contributions from the open source community. 16 BSD license, check license.txt for more information 17 All text above, and the splash screen below must be 18 included in any redistribution. 19 **************************************************************************/ 20 21 #include <SPI.h> 22 #include <Wire.h> 23 #include <Adafruit_GFX.h> 24 #include <Adafruit_SSD1306.h> 25 26 #define SCREEN_WIDTH 128 // OLED display width, in pixels 27 #define SCREEN_HEIGHT 64 // OLED display height, in pixels 28 29 // Declaration for SSD1306 display connected using software SPI (default case): 30 #define OLED_MOSI 9 31 #define OLED_CLK 10 32 #define OLED_DC 11 33 #define OLED_CS 12 34 #define OLED_RESET 13 35 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, 36 OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); 37 38 /* Comment out above, uncomment this block to use hardware SPI 39 #define OLED_DC 6 40 #define OLED_CS 7 41 #define OLED_RESET 8 42 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, 43 &SPI, OLED_DC, OLED_RESET, OLED_CS); 44 */ 45 46 #define NUMFLAKES 10 // Number of snowflakes in the animation example 47 48 #define LOGO_HEIGHT 16 49 #define LOGO_WIDTH 16 50 static const unsigned char PROGMEM logo_bmp[] = 51 { B00000000, B11000000, 52 B00000001, B11000000, 53 B00000001, B11000000, 54 B00000011, B11100000, 55 B11110011, B11100000, 56 B11111110, B11111000, 57 B01111110, B11111111, 58 B00110011, B10011111, 59 B00011111, B11111100, 60 B00001101, B01110000, 61 B00011011, B10100000, 62 B00111111, B11100000, 63 B00111111, B11110000, 64 B01111100, B11110000, 65 B01110000, B01110000, 66 B00000000, B00110000 }; 67 68 void setup() { 69 Serial.begin(9600); 70 71 // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally 72 if(!display.begin(SSD1306_SWITCHCAPVCC)) { 73 Serial.println(F("SSD1306 allocation failed")); 74 for(;;); // Don't proceed, loop forever 75 } 76 77 78 // Show initial display buffer contents on the screen -- 79 // the library initializes this with an Adafruit splash screen. 80 display.display(); 81 delay(2000); // Pause for 2 seconds 82 83 // Clear the buffer 84 display.clearDisplay(); 85 86 // Draw a single pixel in white 87 display.drawPixel(10, 10, SSD1306_WHITE); 88 89 // Show the display buffer on the screen. You MUST call display() after 90 // drawing commands to make them visible on screen! 91 display.display(); 92 delay(2000); 93 // display.display() is NOT necessary after every single drawing command, 94 // unless that's what you want...rather, you can batch up a bunch of 95 // drawing operations and then update the screen all at once by calling 96 // display.display(). These examples demonstrate both approaches... 97 98 testdrawline(); // Draw many lines 99 100 testdrawrect(); // Draw rectangles (outlines) 101 102 testfillrect(); // Draw rectangles (filled) 103 104 testdrawcircle(); // Draw circles (outlines) 105 106 testfillcircle(); // Draw circles (filled) 107 108 testdrawroundrect(); // Draw rounded rectangles (outlines) 109 110 testfillroundrect(); // Draw rounded rectangles (filled) 111 112 testdrawtriangle(); // Draw triangles (outlines) 113 114 testfilltriangle(); // Draw triangles (filled) 115 116 testdrawchar(); // Draw characters of the default font 117 118 testdrawstyles(); // Draw 'stylized' characters 119 120 testscrolltext(); // Draw scrolling text 121 122 testdrawbitmap(); // Draw a small bitmap image 123 124 // Invert and restore display, pausing in-between 125 display.invertDisplay(true); 126 delay(1000); 127 display.invertDisplay(false); 128 delay(1000); 129 130 testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); // Animate bitmaps 131 } 132 133 void loop() { 134 } 135 136 void testdrawline() { 137 int16_t i; 138 139 display.clearDisplay(); // Clear display buffer 140 141 for(i=0; i<display.width(); i+=4) { 142 display.drawLine(0, 0, i, display.height()-1, SSD1306_WHITE); 143 display.display(); // Update screen with each newly-drawn line 144 delay(1); 145 } 146 for(i=0; i<display.height(); i+=4) { 147 display.drawLine(0, 0, display.width()-1, i, SSD1306_WHITE); 148 display.display(); 149 delay(1); 150 } 151 delay(250); 152 153 display.clearDisplay(); 154 155 for(i=0; i<display.width(); i+=4) { 156 display.drawLine(0, display.height()-1, i, 0, SSD1306_WHITE); 157 display.display(); 158 delay(1); 159 } 160 for(i=display.height()-1; i>=0; i-=4) { 161 display.drawLine(0, display.height()-1, display.width()-1, i, SSD1306_WHITE); 162 display.display(); 163 delay(1); 164 } 165 delay(250); 166 167 display.clearDisplay(); 168 169 for(i=display.width()-1; i>=0; i-=4) { 170 display.drawLine(display.width()-1, display.height()-1, i, 0, SSD1306_WHITE); 171 display.display(); 172 delay(1); 173 } 174 for(i=display.height()-1; i>=0; i-=4) { 175 display.drawLine(display.width()-1, display.height()-1, 0, i, SSD1306_WHITE); 176 display.display(); 177 delay(1); 178 } 179 delay(250); 180 181 display.clearDisplay(); 182 183 for(i=0; i<display.height(); i+=4) { 184 display.drawLine(display.width()-1, 0, 0, i, SSD1306_WHITE); 185 display.display(); 186 delay(1); 187 } 188 for(i=0; i<display.width(); i+=4) { 189 display.drawLine(display.width()-1, 0, i, display.height()-1, SSD1306_WHITE); 190 display.display(); 191 delay(1); 192 } 193 194 delay(2000); // Pause for 2 seconds 195 } 196 197 void testdrawrect(void) { 198 display.clearDisplay(); 199 200 for(int16_t i=0; i<display.height()/2; i+=2) { 201 display.drawRect(i, i, display.width()-2*i, display.height()-2*i, SSD1306_WHITE); 202 display.display(); // Update screen with each newly-drawn rectangle 203 delay(1); 204 } 205 206 delay(2000); 207 } 208 209 void testfillrect(void) { 210 display.clearDisplay(); 211 212 for(int16_t i=0; i<display.height()/2; i+=3) { 213 // The INVERSE color is used so rectangles alternate white/black 214 display.fillRect(i, i, display.width()-i*2, display.height()-i*2, SSD1306_INVERSE); 215 display.display(); // Update screen with each newly-drawn rectangle 216 delay(1); 217 } 218 219 delay(2000); 220 } 221 222 void testdrawcircle(void) { 223 display.clearDisplay(); 224 225 for(int16_t i=0; i<max(display.width(),display.height())/2; i+=2) { 226 display.drawCircle(display.width()/2, display.height()/2, i, SSD1306_WHITE); 227 display.display(); 228 delay(1); 229 } 230 231 delay(2000); 232 } 233 234 void testfillcircle(void) { 235 display.clearDisplay(); 236 237 for(int16_t i=max(display.width(),display.height())/2; i>0; i-=3) { 238 // The INVERSE color is used so circles alternate white/black 239 display.fillCircle(display.width() / 2, display.height() / 2, i, SSD1306_INVERSE); 240 display.display(); // Update screen with each newly-drawn circle 241 delay(1); 242 } 243 244 delay(2000); 245 } 246 247 void testdrawroundrect(void) { 248 display.clearDisplay(); 249 250 for(int16_t i=0; i<display.height()/2-2; i+=2) { 251 display.drawRoundRect(i, i, display.width()-2*i, display.height()-2*i, 252 display.height()/4, SSD1306_WHITE); 253 display.display(); 254 delay(1); 255 } 256 257 delay(2000); 258 } 259 260 void testfillroundrect(void) { 261 display.clearDisplay(); 262 263 for(int16_t i=0; i<display.height()/2-2; i+=2) { 264 // The INVERSE color is used so round-rects alternate white/black 265 display.fillRoundRect(i, i, display.width()-2*i, display.height()-2*i, 266 display.height()/4, SSD1306_INVERSE); 267 display.display(); 268 delay(1); 269 } 270 271 delay(2000); 272 } 273 274 void testdrawtriangle(void) { 275 display.clearDisplay(); 276 277 for(int16_t i=0; i<max(display.width(),display.height())/2; i+=5) { 278 display.drawTriangle( 279 display.width()/2 , display.height()/2-i, 280 display.width()/2-i, display.height()/2+i, 281 display.width()/2+i, display.height()/2+i, SSD1306_WHITE); 282 display.display(); 283 delay(1); 284 } 285 286 delay(2000); 287 } 288 289 void testfilltriangle(void) { 290 display.clearDisplay(); 291 292 for(int16_t i=max(display.width(),display.height())/2; i>0; i-=5) { 293 // The INVERSE color is used so triangles alternate white/black 294 display.fillTriangle( 295 display.width()/2 , display.height()/2-i, 296 display.width()/2-i, display.height()/2+i, 297 display.width()/2+i, display.height()/2+i, SSD1306_INVERSE); 298 display.display(); 299 delay(1); 300 } 301 302 delay(2000); 303 } 304 305 void testdrawchar(void) { 306 display.clearDisplay(); 307 308 display.setTextSize(1); // Normal 1:1 pixel scale 309 display.setTextColor(SSD1306_WHITE); // Draw white text 310 display.setCursor(0, 0); // Start at top-left corner 311 display.cp437(true); // Use full 256 char 'Code Page 437' font 312 313 // Not all the characters will fit on the display. This is normal. 314 // Library will draw what it can and the rest will be clipped. 315 for(int16_t i=0; i<256; i++) { 316 if(i == '\n') display.write(' '); 317 else display.write(i); 318 } 319 320 display.display(); 321 delay(2000); 322 } 323 324 void testdrawstyles(void) { 325 display.clearDisplay(); 326 327 display.setTextSize(1); // Normal 1:1 pixel scale 328 display.setTextColor(SSD1306_WHITE); // Draw white text 329 display.setCursor(0,0); // Start at top-left corner 330 display.println(F("Hello, world!")); 331 332 display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Draw 'inverse' text 333 display.println(3.141592); 334 335 display.setTextSize(2); // Draw 2X-scale text 336 display.setTextColor(SSD1306_WHITE); 337 display.print(F("0x")); display.println(0xDEADBEEF, HEX); 338 339 display.display(); 340 delay(2000); 341 } 342 343 void testscrolltext(void) { 344 display.clearDisplay(); 345 346 display.setTextSize(2); // Draw 2X-scale text 347 display.setTextColor(SSD1306_WHITE); 348 display.setCursor(10, 0); 349 display.println(F("scroll")); 350 display.display(); // Show initial text 351 delay(100); 352 353 // Scroll in various directions, pausing in-between: 354 display.startscrollright(0x00, 0x0F); 355 delay(2000); 356 display.stopscroll(); 357 delay(1000); 358 display.startscrollleft(0x00, 0x0F); 359 delay(2000); 360 display.stopscroll(); 361 delay(1000); 362 display.startscrolldiagright(0x00, 0x07); 363 delay(2000); 364 display.startscrolldiagleft(0x00, 0x07); 365 delay(2000); 366 display.stopscroll(); 367 delay(1000); 368 } 369 370 void testdrawbitmap(void) { 371 display.clearDisplay(); 372 373 display.drawBitmap( 374 (display.width() - LOGO_WIDTH ) / 2, 375 (display.height() - LOGO_HEIGHT) / 2, 376 logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1); 377 display.display(); 378 delay(1000); 379 } 380 381 #define XPOS 0 // Indexes into the 'icons' array in function below 382 #define YPOS 1 383 #define DELTAY 2 384 385 void testanimate(const uint8_t *bitmap, uint8_t w, uint8_t h) { 386 int8_t f, icons[NUMFLAKES][3]; 387 388 // Initialize 'snowflake' positions 389 for(f=0; f< NUMFLAKES; f++) { 390 icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width()); 391 icons[f][YPOS] = -LOGO_HEIGHT; 392 icons[f][DELTAY] = random(1, 6); 393 Serial.print(F("x: ")); 394 Serial.print(icons[f][XPOS], DEC); 395 Serial.print(F(" y: ")); 396 Serial.print(icons[f][YPOS], DEC); 397 Serial.print(F(" dy: ")); 398 Serial.println(icons[f][DELTAY], DEC); 399 } 400 401 for(;;) { // Loop forever... 402 display.clearDisplay(); // Clear the display buffer 403 404 // Draw each snowflake: 405 for(f=0; f< NUMFLAKES; f++) { 406 display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, SSD1306_WHITE); 407 } 408 409 display.display(); // Show the display buffer on the screen 410 delay(200); // Pause for 1/10 second 411 412 // Then update coordinates of each flake... 413 for(f=0; f< NUMFLAKES; f++) { 414 icons[f][YPOS] += icons[f][DELTAY]; 415 // If snowflake is off the bottom of the screen... 416 if (icons[f][YPOS] >= display.height()) { 417 // Reinitialize to a random position, just off the top 418 icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width()); 419 icons[f][YPOS] = -LOGO_HEIGHT; 420 icons[f][DELTAY] = random(1, 6); 421 } 422 } 423 } 424 }