Description

100%
100%

I already showed you how to connect LCD 16×2 using I2C in a STM32 microcontroller, you can check that out here. Today we will take a step forward and interface OLED display using I2C with STM32.

The display I will be using is a 0.96″ 128×64 oled display with black and blue colors.

This display uses the I2C protocol to communicate to the microcontroller. So here you need only 2 pins i.e. SDA and SCL from the microcontroller and the VCC and GND.  I am using STM32f103c8t6  but as I mentioned before, the code will remain same for all STM32 devices. I searched a lot for the libraries but all I could find were that of arduino. Than at last I found one by Alexander Lutsai, and I modified it so that it can be used with the STM32 CubeMx

Let’s get to work now. Fire up your STM32cubeMx and generate a new project for your microcontroller with I2C protcol running at 400KHz and duty cycle at I2C_DUTYCYCLE_2. By default, the library will use I2C1 handler but you can change that later in the program.

Connect the  SCL of the controller with the SCL of the display and SDA to SDA by using a pull-up resistor for both the pins.

HOW TO

Download the code below, unzip it, Copy the fonts.h, test.h and ssd1306.h in the Inc folder of your project and fonts.c, test.c and ssd1306.c in the Src folder and open the project now.

Include the following files in the main.c:-

#include "ssd1306.h"
#include "fonts.h"
#include "test.h"

Open the ssd1306.c and change the handler accordingly 

extern I2C_HandleTypeDef hi2c1;

You can see the functions available in the functions tab under ssd1306.c or in the ssd1306.h file. I am going to initialise the display and print “Hello World !!”…

SSD1306_Init (); // initialize the diaply 

SSD1306_GotoXY (10,10); // goto 10, 10 
SSD1306_Puts ("HELLO", &Font_11x18, 1); // print Hello 
SSD1306_GotoXY (10, 30); 
SSD1306_Puts ("WORLD !!", &Font_11x18, 1); 
SSD1306_UpdateScreen(); // update screen

You can scroll the display LEFT, RIGHT, DIAGONAL LEFT or DIAGONAL RIGHT also. The following are the functions available to do so.

void SSD1306_ScrollRight(uint8_t start_row, uint8_t end_row);

void SSD1306_ScrollLeft(uint8_t start_row, uint8_t end_row);

void SSD1306_Scrolldiagright(uint8_t start_row, uint8_t end_row);

void SSD1306_Scrolldiagleft(uint8_t start_row, uint8_t end_row);

void SSD1306_Stopscroll(void);

The colour of the display can be inverted using void SSD1306_InvertDisplay (int i);
i=1 will invert the display
i=0 will normalise it.

Drawing bitmap is also supported and the following function is assigned to do so

/**
 * @brief  Draws the Bitmap
 * @param  X:  X location to start the Drawing
 * @param  Y:  Y location to start the Drawing
 * @param  *bitmap : Pointer to the bitmap
 * @param  W : width of the image
 * @param  H : Height of the image
 * @param  color : 1-> white/blue, 0-> black
 */
void SSD1306_DrawBitmap(int16_t x, int16_t y, const unsigned char* bitmap, int16_t w, int16_t h, uint16_t color);

We can also display the animation. Check out the video below, to see, how to do it.

100%
100%

Connections

100%
100%
100%
100%

Result

100%
100%
Check out the video below
100%
100%

You can buy me a coffee sensor 🙂

Or Just download the CODE below

100%
100%

23
Leave a Reply

avatar
15 Comment threads
8 Thread replies
1 Followers
 
Most reacted comment
Hottest comment thread
16 Comment authors
Joao Piferpablito TapialesMampfiGLettDenis Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
Lee Thuc
Guest
Lee Thuc

Hi there! If I connect directly sda and scl wires without external resistor, Is it ok?

JM
Guest
JM

Thank you very much! I’ve used this display in my project following your post and it works perfectly! Please, keep doing more stm32 tutorials, very interesting and useful!

martin
Guest
martin

thanks,very professional and useful.

Cabral
Guest

Hi, thanks for the explanation, I’m trying to port this code to a STM32L4 family.
I have managed to change all STM32f1xx lines. As well as changes the I2C number that I’m using hi2c3.

What’s is strange is that I’m getting only one error now which is on a completely different part of the code. It’s telling me the variable “count” needs a constant value. So maybe it’s not receiving anything.

void ssd1306_I2C_WriteMulti(uint8_t address, uint8_t reg, uint8_t* data, uint16_t count) {
uint8_t dt[count + 1];
dt[0] = reg;
uint8_t i;
for(i = 1; i <= count; i++)
dt[i] = data[i-1];
HAL_I2C_Master_Transmit(&hi2c3, address, dt, count, 10);
}

thorben
Guest
thorben

many thanks for this, really good c code

Oleksandr Gusiev
Guest
Oleksandr Gusiev

Hello. I followed your guide. Thanks a lot, it helped me clarify some points, but i have some troubles. First of all https://goo.gl/XD3yQC there are some dots at right side of screen (tested on two screens, same problem). And the second, but the most important, during run in debug, screen looks https://goo.gl/UMFquG at any
debug step, and it is always so when boot pins in such a state. Please, relpy, if possible. Thanks.

ramin_javadi
Guest
ramin_javadi

thanks….
it was fantastic

Sandip Maurya
Guest
Sandip Maurya

Thanks Working good,
please tell me command to clear lcd.

Liberman
Guest
Liberman

How I can Put float number from adc in the display?

Denis
Guest
Denis

/* USER CODE BEGIN Includes */
#include “ssd1306.h”
#include “i2c-lcd.h”
/* USER CODE END Includes */
Why i2c-lcd.h in code exists,but in video are not?

Denis
Guest
Denis

/* USER CODE BEGIN Includes */
#include “ssd1306.h”
#include “i2c-lcd.h”
/* USER CODE END Includes */
Why i2c-lcd.h in code exists,but in video are not??

GLett
Guest
GLett

A detail…
The ssd1306_I2C_WriteMulti() function has a little bug in the counters, that is the reason why @Oleksandr Gusiev had to change SSD1306_WIDTH 128 to 129
Here is the fix

void ssd1306_I2C_WriteMulti(uint8_t address, uint8_t reg, uint8_t* data, uint16_t count) {
uint8_t dt[256];
dt[0] = reg;
uint8_t i;
for(i = 0; i < count; i++)
dt[i+1] = data[i];
HAL_I2C_Master_Transmit(&hi2c1, address, dt, count+1, 10);
}

I hope it can help to another freaky electronic lover like us 😉

Mampfi
Guest
Mampfi

Works very well on my STM32F407 board, Thank you!

pablito Tapiales
Guest
pablito Tapiales

MUCHAS GRACIAS. It works perfectly, you saved my day, I didn’t know how to use it in keil. Thank you so much.
STM32F103 (BLUE-PILL)
SCK (oled) to PB6
SDA(oled) to PB7

Joao Pifer
Guest
Joao Pifer

I adapted the code for Nucleo-32, it works perfectly but sometimes it stops working for no reason. Once the display just scrolled down alone and almost half-top was the bottom part of the display. Then I disassembled the display to try to reset it or something but when I assembled it again it stopped working. This happened to me before but without de scrolling. The code works perfectly, I was just adjusting some parameters. I have searched some information about it and some people says it’s because of using the nucleo’s power supply but it doesn’t work when I put… Read more »

Menu