We’ve got our OLED set up (if not click here) and now we need to plotting some text/ graphics to it, let’s go…
If you want to watch the video see below otherwise scroll past the video link for the rest of the article
First things – Text
Open up your Arduino IDE and enter the following code;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <Adafruit_SSD1306.h> #include <Adafruit_GFX.h> // DISPLAY SETTINGS #define OLED_ADDRESS 0x3C Adafruit_SSD1306 display(1); void setup() { display.begin(SSD1306_SWITCHCAPVCC,OLED_ADDRESS); } void loop() { display.clearDisplay(); display.setTextColor(WHITE); display.setCursor(0,0); display.print("Space Invaders"); display.display(); } |
Compile and upload and your display should look like this:
The line;
Adafruit_SSD1306 display(1);
Creates an object called “display” which is an instance of “Adafruit_SSD1306 “. OK we won’t delve to much into Object Orientated Programming (OOP) but basically the type “Adafruit_SSD1306 ” can be thought of as representing the screen display and we have procedures that we can call and tun on that display such printing text, plotting graphics etc. The “1” in the brackets is just an initialiser telling the object which pin is connected to the screens reset line – at least that’s what I could figure from Adafruits code, and as my display and a lot of displays do not have one it seems to work fine with passing any value.
Next we initialise the display to tell it where it exists on the I²C bus;
display.begin(SSD1306_SWITCHCAPVCC,OLED_ADDRESS);
SSD1306_SWITCHCAPVCC can be ignored, just use it as part of the initialise routine, I’ve not looked at what it does yet, but it was used in the original Adafruit demo. OLED_ADDRESS was set up earlier as 0x3C and is just the address (number assigned) by the hardware manufacturer of our screen, yours will probably be the same or very similar.
In the main loop we just repeatedly clear the screen and reprint the words “Space Invaders”. You may wonder why we clear the screen all the time when nothing is changing, and quite rightly there is no point to doing that every time, we could just do it once in the setup function. However as we will soon be moving some graphics it seems wise to include it from the start. What would happen if we didn’t clear the screen between graphics moves? Have a think or experiment by taking the clear screen line out of the code to find out!
Plotting a character
Look at the code below, we’ve now added in a graphic definition and plotting code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
#include <Adafruit_SSD1306.h> #include <Adafruit_GFX.h> // DISPLAY SETTINGS #define OLED_ADDRESS 0x3C // graphics static const unsigned char PROGMEM InvaderMiddleGfx []={ B00100000,B10000000, B00010001,B00000000, B00111111,B10000000, B01101110,B11000000, B11111111,B11100000, B10111111,B10100000, B10100000,B10100000, B00011011,B00000000 }; Adafruit_SSD1306 display(1); void setup() { display.begin(SSD1306_SWITCHCAPVCC,OLED_ADDRESS); } void loop() { display.clearDisplay(); display.setTextColor(WHITE); display.setCursor(0,0); display.print("Space Invaders"); display.drawBitmap(0,20,InvaderMiddleGfx,11,8,WHITE); display.display(); } |
The line:
static const unsigned char PROGMEM InvaderMiddleGfx
sets up the start of the graphics definition. Which as you can see is a set of Bytes where each “bit” (a 0 or 1) defines the invaders shape. A 1 represents a pixel being “on” and a 0 represents it being “off”. In our case for this screen it would be a white pixel or a black (nothing) pixel respectively. Now, a byte is 8 bits wide, if your character is only 6 pixels (bits) wide then you must padd with 0’s to the nearest byte. So for out graphic it is 11 pixels wide, so the remaining bits of the second byte are padded with zeros.
PROGMEM This is a special “directive” for Atmel processors (which are in the Arduino boards) to instruct the compiler to store the following data into program memory and not normal static memory storage. We do this because graphics often take up a significant amount of memory and the small amount in the Atmel processors would be quickly used up so we use the more generous program memory to store our images.
Plotting the image
The line:
display.drawBitmap(0,20,InvaderMiddleGfx,11,8,WHITE);
plots the graphic to screen the first two parameters are X and Y positions on the screen with the Y “0” location being at the top of the screen. The next param is your graphics data variable,the “11” is the width of the graphic and “8” the height. The last parameter is not useful for use as we only have the one colour but we must still include it.
Compile and upload and your display should look like this:
Moving the image
Finally we add a very few lines to get the character moving. We set a XPos variable to store the current position of the graphic and then increment this. When it’s reached the end of the screen we reset it back to the start and repeat forever. The final complete code is shown below;
In the next episode we design out Invader data structure and plot several of them on screen at once, till next time
Enjoy and Learn 🙂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#include <Adafruit_SSD1306.h> #include <Adafruit_GFX.h> // DISPLAY SETTINGS #define OLED_ADDRESS 0x3C // graphics static const unsigned char PROGMEM InvaderMiddleGfx []={ B00100000,B10000000, B00010001,B00000000, B00111111,B10000000, B01101110,B11000000, B11111111,B11100000, B10111111,B10100000, B10100000,B10100000, B00011011,B00000000 }; Adafruit_SSD1306 display(1); int XPos=0; void setup() { display.begin(SSD1306_SWITCHCAPVCC,OLED_ADDRESS); } void loop() { display.clearDisplay(); display.setTextColor(WHITE); display.setCursor(0,0); display.print("Space Invaders"); display.drawBitmap(XPos,20,InvaderMiddleGfx,11,8,WHITE); display.display(); XPos+=1; if(XPos>127) XPos=0; } |