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