Advertisement
skizziks_53

Reddit 128x64 i2c oled tester v1.0

Oct 5th, 2019
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.18 KB | None | 0 0
  1. /*
  2.    Reddit oled 128x64 tester version 1.0
  3.    5 October 2019
  4.  
  5.    This sketch is written to use a generic 128x64 OLED over I2C.
  6.    Using an I2C address scanner sketch, the address that is reported for this screen (with mine) is 0x3C ... which isn't either of the addresses printed on the PCB (?)
  7.    And yours might be different.
  8.  
  9.    Also note: this sketch is for a monochrome OLED screen.
  10.    The actual screen I have has a yellow band across the top, and the rest of the screen is blue.
  11.    That still counts as monochrome however, because it only accepts monochrome pixel data.
  12.    You cannot change those yellow and blue colors; that is how the screen was made.
  13.  
  14.    I am also not using the reset pin for the OLED screen (the generic screen doesn't have one) so there is one line changed for that.
  15.  
  16.    I am using the Adafruit libraries here, as I could not get the U8glib library to work at all.
  17. */
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27. // (below is standard Adafruit boilerplate comments)
  28. /**************************************************************************
  29.   This is an example for our Monochrome OLEDs based on SSD1306 drivers
  30.  
  31.   Pick one up today in the adafruit shop!
  32.   ------> http://www.adafruit.com/category/63_98
  33.  
  34.   This example is for a 128x32 pixel display using I2C to communicate
  35.   3 pins are required to interface (two I2C and one reset).
  36.  
  37.   Adafruit invests time and resources providing this open
  38.   source code, please support Adafruit and open-source
  39.   hardware by purchasing products from Adafruit!
  40.  
  41.   Written by Limor Fried/Ladyada for Adafruit Industries,
  42.   with contributions from the open source community.
  43.   BSD license, check license.txt for more information
  44.   All text above, and the splash screen below must be
  45.   included in any redistribution.
  46.  **************************************************************************/
  47.  
  48.  
  49. #include <SPI.h>
  50. #include <Wire.h>
  51.  
  52. #include <Adafruit_GFX.h> // Adafruit library - google for where to download it.
  53. #include <Adafruit_SSD1306.h> // Adafruit library - google for where to download it.
  54.  
  55. /*
  56.   Notice! I had to edit the Adafruit_SSD1306.h file to get this to work...
  57.  
  58.   Open Adafruit_SSD1306.h in a text editor, and then uncomment line #28 that says:
  59.  
  60.   #define SSD1306_128_64 ///< DEPRECTAED: old way to specify 128x64 screen
  61.  
  62.   and then comment out the other two screen definitions (lines 29 and 30) if they are not already commented out.
  63. */
  64.  
  65. #define SCREEN_WIDTH 128 // OLED display width, in pixels
  66. #define SCREEN_HEIGHT 64 // OLED display height, in pixels
  67.  
  68. // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
  69.  
  70.  
  71. #define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
  72. // Note: the above was originally set to [4], but you use -1 if you aren't using the reset pin.
  73.  
  74.  
  75. Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
  76.  
  77. #define NUMFLAKES     10 // Number of snowflakes in the animation example
  78.  
  79. #define LOGO_HEIGHT   16
  80. #define LOGO_WIDTH    16
  81. static const unsigned char PROGMEM logo_bmp[] =
  82. { B00000000, B11000000,
  83.   B00000001, B11000000,
  84.   B00000001, B11000000,
  85.   B00000011, B11100000,
  86.   B11110011, B11100000,
  87.   B11111110, B11111000,
  88.   B01111110, B11111111,
  89.   B00110011, B10011111,
  90.   B00011111, B11111100,
  91.   B00001101, B01110000,
  92.   B00011011, B10100000,
  93.   B00111111, B11100000,
  94.   B00111111, B11110000,
  95.   B01111100, B11110000,
  96.   B01110000, B01110000,
  97.   B00000000, B00110000
  98. };
  99.  
  100. void setup() {
  101.   Serial.begin(9600);
  102.  
  103.   // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  104.  
  105.   //if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) { // Address 0x3D for 128x64 -----> 0x3D is the original (adafruit) value
  106.  
  107.   if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // This is the correct address of the generic 128 x 64 OLED screen that I have.
  108.  
  109.     // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  110.     // To find the address of a new I2C device, the easiest way is to use an I2C scanner sketch.
  111.     // There is one on the official Arduino site at -- https://playground.arduino.cc/Main/I2cScanner/
  112.     // The address that is reported for this screen (with mine) is 0x3C
  113.     // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  114.  
  115.  
  116.     Serial.println(F("SSD1306 allocation failed"));
  117.     for (;;); // Don't proceed, loop forever
  118.   }
  119.  
  120.   // Show initial display buffer contents on the screen --
  121.   // the library initializes this with an Adafruit splash screen.
  122.   display.display();
  123.   delay(2000); // Pause for 2 seconds
  124.  
  125.   // Clear the buffer
  126.   display.clearDisplay();
  127.  
  128.   // Draw a single pixel in white
  129.   display.drawPixel(10, 10, WHITE);
  130.  
  131.   // Show the display buffer on the screen. You MUST call display() after
  132.   // drawing commands to make them visible on screen!
  133.   display.display();
  134.   delay(2000);
  135.   // display.display() is NOT necessary after every single drawing command,
  136.   // unless that's what you want...rather, you can batch up a bunch of
  137.   // drawing operations and then update the screen all at once by calling
  138.   // display.display(). These examples demonstrate both approaches...
  139.  
  140.   testdrawline();      // Draw many lines
  141.  
  142.   testdrawrect();      // Draw rectangles (outlines)
  143.  
  144.   testfillrect();      // Draw rectangles (filled)
  145.  
  146.   testdrawcircle();    // Draw circles (outlines)
  147.  
  148.   testfillcircle();    // Draw circles (filled)
  149.  
  150.   testdrawroundrect(); // Draw rounded rectangles (outlines)
  151.  
  152.   testfillroundrect(); // Draw rounded rectangles (filled)
  153.  
  154.   testdrawtriangle();  // Draw triangles (outlines)
  155.  
  156.   testfilltriangle();  // Draw triangles (filled)
  157.  
  158.   testdrawchar();      // Draw characters of the default font
  159.  
  160.   testdrawstyles();    // Draw 'stylized' characters
  161.  
  162.   testscrolltext();    // Draw scrolling text
  163.  
  164.   testdrawbitmap();    // Draw a small bitmap image
  165.  
  166.   // Invert and restore display, pausing in-between
  167.   display.invertDisplay(true);
  168.   delay(1000);
  169.   display.invertDisplay(false);
  170.   delay(1000);
  171.  
  172.   testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); // Animate bitmaps
  173. }
  174.  
  175. void loop() {
  176. }
  177.  
  178. void testdrawline() {
  179.   int16_t i;
  180.  
  181.   display.clearDisplay(); // Clear display buffer
  182.  
  183.   for (i = 0; i < display.width(); i += 4) {
  184.     display.drawLine(0, 0, i, display.height() - 1, WHITE);
  185.     display.display(); // Update screen with each newly-drawn line
  186.     delay(1);
  187.   }
  188.   for (i = 0; i < display.height(); i += 4) {
  189.     display.drawLine(0, 0, display.width() - 1, i, WHITE);
  190.     display.display();
  191.     delay(1);
  192.   }
  193.   delay(250);
  194.  
  195.   display.clearDisplay();
  196.  
  197.   for (i = 0; i < display.width(); i += 4) {
  198.     display.drawLine(0, display.height() - 1, i, 0, WHITE);
  199.     display.display();
  200.     delay(1);
  201.   }
  202.   for (i = display.height() - 1; i >= 0; i -= 4) {
  203.     display.drawLine(0, display.height() - 1, display.width() - 1, i, WHITE);
  204.     display.display();
  205.     delay(1);
  206.   }
  207.   delay(250);
  208.  
  209.   display.clearDisplay();
  210.  
  211.   for (i = display.width() - 1; i >= 0; i -= 4) {
  212.     display.drawLine(display.width() - 1, display.height() - 1, i, 0, WHITE);
  213.     display.display();
  214.     delay(1);
  215.   }
  216.   for (i = display.height() - 1; i >= 0; i -= 4) {
  217.     display.drawLine(display.width() - 1, display.height() - 1, 0, i, WHITE);
  218.     display.display();
  219.     delay(1);
  220.   }
  221.   delay(250);
  222.  
  223.   display.clearDisplay();
  224.  
  225.   for (i = 0; i < display.height(); i += 4) {
  226.     display.drawLine(display.width() - 1, 0, 0, i, WHITE);
  227.     display.display();
  228.     delay(1);
  229.   }
  230.   for (i = 0; i < display.width(); i += 4) {
  231.     display.drawLine(display.width() - 1, 0, i, display.height() - 1, WHITE);
  232.     display.display();
  233.     delay(1);
  234.   }
  235.  
  236.   delay(2000); // Pause for 2 seconds
  237. }
  238.  
  239. void testdrawrect(void) {
  240.   display.clearDisplay();
  241.  
  242.   for (int16_t i = 0; i < display.height() / 2; i += 2) {
  243.     display.drawRect(i, i, display.width() - 2 * i, display.height() - 2 * i, WHITE);
  244.     display.display(); // Update screen with each newly-drawn rectangle
  245.     delay(1);
  246.   }
  247.  
  248.   delay(2000);
  249. }
  250.  
  251. void testfillrect(void) {
  252.   display.clearDisplay();
  253.  
  254.   for (int16_t i = 0; i < display.height() / 2; i += 3) {
  255.     // The INVERSE color is used so rectangles alternate white/black
  256.     display.fillRect(i, i, display.width() - i * 2, display.height() - i * 2, INVERSE);
  257.     display.display(); // Update screen with each newly-drawn rectangle
  258.     delay(1);
  259.   }
  260.  
  261.   delay(2000);
  262. }
  263.  
  264. void testdrawcircle(void) {
  265.   display.clearDisplay();
  266.  
  267.   for (int16_t i = 0; i < max(display.width(), display.height()) / 2; i += 2) {
  268.     display.drawCircle(display.width() / 2, display.height() / 2, i, WHITE);
  269.     display.display();
  270.     delay(1);
  271.   }
  272.  
  273.   delay(2000);
  274. }
  275.  
  276. void testfillcircle(void) {
  277.   display.clearDisplay();
  278.  
  279.   for (int16_t i = max(display.width(), display.height()) / 2; i > 0; i -= 3) {
  280.     // The INVERSE color is used so circles alternate white/black
  281.     display.fillCircle(display.width() / 2, display.height() / 2, i, INVERSE);
  282.     display.display(); // Update screen with each newly-drawn circle
  283.     delay(1);
  284.   }
  285.  
  286.   delay(2000);
  287. }
  288.  
  289. void testdrawroundrect(void) {
  290.   display.clearDisplay();
  291.  
  292.   for (int16_t i = 0; i < display.height() / 2 - 2; i += 2) {
  293.     display.drawRoundRect(i, i, display.width() - 2 * i, display.height() - 2 * i,
  294.                           display.height() / 4, WHITE);
  295.     display.display();
  296.     delay(1);
  297.   }
  298.  
  299.   delay(2000);
  300. }
  301.  
  302. void testfillroundrect(void) {
  303.   display.clearDisplay();
  304.  
  305.   for (int16_t i = 0; i < display.height() / 2 - 2; i += 2) {
  306.     // The INVERSE color is used so round-rects alternate white/black
  307.     display.fillRoundRect(i, i, display.width() - 2 * i, display.height() - 2 * i,
  308.                           display.height() / 4, INVERSE);
  309.     display.display();
  310.     delay(1);
  311.   }
  312.  
  313.   delay(2000);
  314. }
  315.  
  316. void testdrawtriangle(void) {
  317.   display.clearDisplay();
  318.  
  319.   for (int16_t i = 0; i < max(display.width(), display.height()) / 2; i += 5) {
  320.     display.drawTriangle(
  321.       display.width() / 2  , display.height() / 2 - i,
  322.       display.width() / 2 - i, display.height() / 2 + i,
  323.       display.width() / 2 + i, display.height() / 2 + i, WHITE);
  324.     display.display();
  325.     delay(1);
  326.   }
  327.  
  328.   delay(2000);
  329. }
  330.  
  331. void testfilltriangle(void) {
  332.   display.clearDisplay();
  333.  
  334.   for (int16_t i = max(display.width(), display.height()) / 2; i > 0; i -= 5) {
  335.     // The INVERSE color is used so triangles alternate white/black
  336.     display.fillTriangle(
  337.       display.width() / 2  , display.height() / 2 - i,
  338.       display.width() / 2 - i, display.height() / 2 + i,
  339.       display.width() / 2 + i, display.height() / 2 + i, INVERSE);
  340.     display.display();
  341.     delay(1);
  342.   }
  343.  
  344.   delay(2000);
  345. }
  346.  
  347. void testdrawchar(void) {
  348.   display.clearDisplay();
  349.  
  350.   display.setTextSize(1);      // Normal 1:1 pixel scale
  351.   display.setTextColor(WHITE); // Draw white text
  352.   display.setCursor(0, 0);     // Start at top-left corner
  353.   display.cp437(true);         // Use full 256 char 'Code Page 437' font
  354.  
  355.   // Not all the characters will fit on the display. This is normal.
  356.   // Library will draw what it can and the rest will be clipped.
  357.   for (int16_t i = 0; i < 256; i++) {
  358.     if (i == '\n') display.write(' ');
  359.     else          display.write(i);
  360.   }
  361.  
  362.   display.display();
  363.   delay(2000);
  364. }
  365.  
  366. void testdrawstyles(void) {
  367.   display.clearDisplay();
  368.  
  369.   display.setTextSize(1);             // Normal 1:1 pixel scale
  370.   display.setTextColor(WHITE);        // Draw white text
  371.   display.setCursor(0, 0);            // Start at top-left corner
  372.   display.println(F("Hello, world!"));
  373.  
  374.   display.setTextColor(BLACK, WHITE); // Draw 'inverse' text
  375.   display.println(3.141592);
  376.  
  377.   display.setTextSize(2);             // Draw 2X-scale text
  378.   display.setTextColor(WHITE);
  379.   display.print(F("0x")); display.println(0xDEADBEEF, HEX);
  380.  
  381.   display.display();
  382.   delay(2000);
  383. }
  384.  
  385. void testscrolltext(void) {
  386.   display.clearDisplay();
  387.  
  388.   display.setTextSize(2); // Draw 2X-scale text
  389.   display.setTextColor(WHITE);
  390.   display.setCursor(10, 0);
  391.   display.println(F("scroll"));
  392.   display.display();      // Show initial text
  393.   delay(100);
  394.  
  395.   // Scroll in various directions, pausing in-between:
  396.   display.startscrollright(0x00, 0x0F);
  397.   delay(2000);
  398.   display.stopscroll();
  399.   delay(1000);
  400.   display.startscrollleft(0x00, 0x0F);
  401.   delay(2000);
  402.   display.stopscroll();
  403.   delay(1000);
  404.   display.startscrolldiagright(0x00, 0x07);
  405.   delay(2000);
  406.   display.startscrolldiagleft(0x00, 0x07);
  407.   delay(2000);
  408.   display.stopscroll();
  409.   delay(1000);
  410. }
  411.  
  412. void testdrawbitmap(void) {
  413.   display.clearDisplay();
  414.  
  415.   display.drawBitmap(
  416.     (display.width()  - LOGO_WIDTH ) / 2,
  417.     (display.height() - LOGO_HEIGHT) / 2,
  418.     logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);
  419.   display.display();
  420.   delay(1000);
  421. }
  422.  
  423. #define XPOS   0 // Indexes into the 'icons' array in function below
  424. #define YPOS   1
  425. #define DELTAY 2
  426.  
  427. void testanimate(const uint8_t *bitmap, uint8_t w, uint8_t h) {
  428.   int8_t f, icons[NUMFLAKES][3];
  429.  
  430.   // Initialize 'snowflake' positions
  431.   for (f = 0; f < NUMFLAKES; f++) {
  432.     icons[f][XPOS]   = random(1 - LOGO_WIDTH, display.width());
  433.     icons[f][YPOS]   = -LOGO_HEIGHT;
  434.     icons[f][DELTAY] = random(1, 6);
  435.     Serial.print(F("x: "));
  436.     Serial.print(icons[f][XPOS], DEC);
  437.     Serial.print(F(" y: "));
  438.     Serial.print(icons[f][YPOS], DEC);
  439.     Serial.print(F(" dy: "));
  440.     Serial.println(icons[f][DELTAY], DEC);
  441.   }
  442.  
  443.   for (;;) { // Loop forever...
  444.     display.clearDisplay(); // Clear the display buffer
  445.  
  446.     // Draw each snowflake:
  447.     for (f = 0; f < NUMFLAKES; f++) {
  448.       display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE);
  449.     }
  450.  
  451.     display.display(); // Show the display buffer on the screen
  452.     delay(200);        // Pause for 1/10 second
  453.  
  454.     // Then update coordinates of each flake...
  455.     for (f = 0; f < NUMFLAKES; f++) {
  456.       icons[f][YPOS] += icons[f][DELTAY];
  457.       // If snowflake is off the bottom of the screen...
  458.       if (icons[f][YPOS] >= display.height()) {
  459.         // Reinitialize to a random position, just off the top
  460.         icons[f][XPOS]   = random(1 - LOGO_WIDTH, display.width());
  461.         icons[f][YPOS]   = -LOGO_HEIGHT;
  462.         icons[f][DELTAY] = random(1, 6);
  463.       }
  464.     }
  465.   }
  466. }
  467.  
  468.  
  469. // ~~~~~~~~~ the end ~~~~~~~~~~~
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement