Interfacing & displaying a custom graphic on an 0.96″ I2C OLED with Arduino

Description

Hey guys, i just bought a cheap 0.96″ 128×64 I2C OLED display from ebay, and can’t wait to test it out.

For this project i will use a driver called U8glib2, which is pretty much kind of a universal driver for driving various LCDs and OLEDs  on Arduino and other microcontrollers/embedded platforms.

In case you want to display your own custom graphic, you will need to convert it into a suitable format, so that it can be used by the microcontroller. For this purpose i used an open source software called Gimp .

I guess this pretty much sums up all the parts. Now its time to get your hands dirty!

Requirements

  • Arduino UNO R3
  • 0.96″ 128×64 I2C OLED display
  • jumper wires
  • A Computer with a working Internet connection

Steps

  1.  First let us get the hardware connections right, connect our OLED to Arduino. Its pretty simple, and for your reference i have attached all the details below. Just follow the breadcrumbs!

    Pin connections

    Arduino pin OLED pin
    5V VCC
    GND GND
    SDA SDA
    SCL SCL

    Breadboard Layout

    I2C OLED Arduino Uno_bb

    Schematic diagram

    I2C OLED Arduino Uno_schem

  2. Now for programming any Arduino based development board, we need the Arduino IDE, which can be downloaded freely and installed from the Arduino website.
  3. Once the Arduino IDE is up and running  we need to install the U8glib2 library. For this we need to access the Library Manager from Sketch > Include Library > Manage Libraries. Then search for u8g2 in the search entry and click install.library manager
  4. To make sure that the OLED is properly connected and is working, load the “GraphicsTest” sketch from File > Examples > U8g2 > page_buffer > GraphicsTest.Note: To use the U8g2 library, you need to enable one of the constructors for initializing the u8g2 class object, from the commented constructor list as shown in the image below. This constructor initializes the u8g2 object for the particular hardware configuration we are using. In our case since we are using the hardware I2C bus of Arduino Uno and our OLED has a 128×64 resolution and SSD1306 CMOS driver ,so you need to uncomment this specific line as shown in the picture.

    U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
    

    Screenshot from 2017-04-16 23-22-29.png
    A complete reference of all the available constructors can be found  here

  5. Selecting and converting an image in Gimp

    5.1.   Now for loading custom graphics, you need to first select your image and convert it to X BitMap format, which gives the files a .xbm extension. As our resolution is only 128×64 we need to go for an image with very less details. For my purpose and initial tests i choose this Iron Man helmet. Cool Huh!
    ironman5.2.   Next load this image in Gimp and set color map to black and white 1-bit palette, form Image > Mode > Indexed > Use black and white (1-bit)palette > Convert.5.3.  Now we crop the image using Rectangular select tool to tightly fit inside a box, and then Image > Crop to selection.Screenshot from 2017-04-16 23-55-59Screenshot from 2017-04-16 23-56-32

    5.4.   Now  go to Image > Scale Image, and in the Scale Image dialog box, first make sure that the aspect ratio is locked and dimension is set in pixels as shown below.

    Screenshot from 2017-04-17 00-06-48
    Now change the height to 64 px and click inside the width input box, it will automatically change to match the aspect ratio, and then click Scale.

    Screenshot from 2017-04-17 00-06-32

    5.5.   You may need to edit the image further to add/remove features that were lost in scaling.
    ironman2

    5.6.   Now  go to File > Export As > save it as ironman.xbm

     

  6.  Writing and uploading the code to Arduino

    6.1.  Now open the Arduino IDE and start a new project and name it as IronMan.6.2.  Copy the following code into your IronMan Sketch.

    #include<Arduino.h>
    #include<U8g2lib.h>
    
    #ifdef U8X8_HAVE_HW_SPI
    #include<SPI.h>
    #endif
    #ifdef U8X8_HAVE_HW_I2C
    #include<Wire.h>
    #endif
    
    U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
    
    // Copy the contents of your .xbm file below
    
    void draw(void) {
    // graphic commands to redraw the complete screen should be placed here
    u8g2.drawXBMP(x,y,width,height,btimap);
    }
    
    void setup(void) {
    u8g2.begin();
    }
    
    void loop(void) {
    // picture loop
    u8g2.firstPage();
    do {
    draw();
    } while( u8g2.nextPage() );
    
    // rebuild the picture after some delay
    delay(1000);
    }
    

    6.3.   Now open your ironman.xbm file with a text editor and copy everything in it to your IronMan Sketch under the following line.

    // Copy the contents of your .xbm file below

    6.4.   After copying the code make the following changes in  your IronMan Sketch.

    u8g2.drawXBMP(x,y,width,height,btimap);

    find the above line and replace x with 42, y with 0, width with ironman_width, height with ironman_height and bitmap with ironman_bits as shown below.

    u8g2.drawXBMP( 42, 0, ironman_width, ironman_height, ironman_bits)

    next find and change the line below

    static unsigned char ironman_bits[]

    to

    static const unsigned char ironman_bits[] PROGMEM

    The complete code will look like this.

    #include<Arduino.h>
    #include<U8g2lib.h>
    
    #ifdef U8X8_HAVE_HW_SPI
    #include<SPI.h>
    #endif
    #ifdef U8X8_HAVE_HW_I2C
    #include<Wire.h>
    #endif
    
    U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
    
    // Copy the contents of your .xbm file below
    #define ironman_width 44
    #define ironman_height 64
    static const unsigned char ironman_bits[] PROGMEM = {
     0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x3f, 0x00, 0x00,
     0x00, 0xf8, 0xff, 0xff, 0x01, 0x00, 0x00, 0x86, 0xff, 0x1f, 0x06, 0x00,
     0x80, 0x81, 0xff, 0x1f, 0x18, 0x00, 0xc0, 0x80, 0xff, 0x1f, 0x30, 0x00,
     0x20, 0x80, 0xff, 0x1f, 0xc0, 0x00, 0x10, 0x00, 0xff, 0x0f, 0x80, 0x01,
     0x08, 0x00, 0xff, 0x0f, 0x00, 0x01, 0x08, 0x00, 0xff, 0x0f, 0x00, 0x02,
     0x08, 0x00, 0xff, 0x0f, 0x00, 0x02, 0x08, 0x00, 0xfe, 0x07, 0x00, 0x02,
     0x08, 0x00, 0xfe, 0x07, 0x00, 0x02, 0x08, 0x00, 0xfe, 0x07, 0x00, 0x02,
     0x08, 0x00, 0x00, 0x00, 0x00, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00, 0x06,
     0x08, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x06,
     0x0c, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x06,
     0x0c, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x06,
     0x0c, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x06,
     0x06, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x06,
     0x06, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc6, 0x07, 0x00, 0x00, 0x7c, 0x0e,
     0xe6, 0xff, 0xff, 0xff, 0xff, 0x0e, 0xe6, 0xff, 0x03, 0xf8, 0xff, 0x0c,
     0x02, 0x3f, 0x00, 0x80, 0x1f, 0x0c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x0c,
     0x03, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0c,
     0x03, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0c,
     0x03, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x06,
     0x07, 0x00, 0x00, 0x00, 0x00, 0x06, 0x16, 0x00, 0x00, 0x00, 0x00, 0x06,
     0x2e, 0x00, 0x00, 0x00, 0x80, 0x07, 0x6e, 0x00, 0x00, 0x00, 0x40, 0x07,
     0x6e, 0x00, 0x00, 0x00, 0x60, 0x07, 0xde, 0x00, 0x00, 0x00, 0xb0, 0x07,
     0xde, 0x00, 0x00, 0x00, 0xb0, 0x07, 0x9c, 0x01, 0x00, 0x00, 0xd8, 0x03,
     0xbc, 0x01, 0x00, 0x00, 0xf8, 0x03, 0x3c, 0x01, 0x00, 0x00, 0xe8, 0x03,
     0x7c, 0x03, 0x00, 0x00, 0xf4, 0x03, 0xfc, 0x02, 0x00, 0x00, 0xf4, 0x03,
     0xfc, 0xc2, 0xff, 0x1f, 0xfa, 0x03, 0xf8, 0x25, 0xff, 0x27, 0xfa, 0x01,
     0xf8, 0x38, 0x00, 0x60, 0xf9, 0x01, 0xf8, 0x10, 0x00, 0xc0, 0xf8, 0x01,
     0xf0, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xf0, 0x00, 0x00, 0x00, 0xf8, 0x01,
     0xf0, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0xe0, 0xc1, 0xff, 0x0f, 0xf8, 0x00,
     0xc0, 0xe3, 0xff, 0x1f, 0x7c, 0x00, 0x80, 0xff, 0xff, 0x7f, 0x3e, 0x00,
     0x00, 0xff, 0xff, 0x7f, 0x0f, 0x00, 0x00, 0xf6, 0x00, 0xfe, 0x07, 0x00,
     0x00, 0x3c, 0x00, 0xb0, 0x01, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00 };
    
    void draw(void) {
     // graphic commands to redraw the complete screen should be placed here  
     u8g2.drawXBMP( 42, 0, ironman_width, ironman_height, ironman_bits);
    }
    
    void setup(void) {
     u8g2.begin();
    }
    
    void loop(void) {
     // picture loop
     u8g2.firstPage();
     do {
         draw();
        } while( u8g2.nextPage() );
    
     // rebuild the picture after some delay
     delay(1000);
    }
    
    
  7. Finally select the board as Genuino Uno/Arduino under Tools > Boards and select the appropriate com port under Tools > Port, and click Upload.P_20170417_013258
    Enjoy !!!
    All the project files can be found here
Advertisements