Tuesday, December 8, 2015

Mailbag !! SSD1306 OLED Display for ESP8266 nEXT EVO Board





 


   I think everybody knows already the popular  SSD1306 0.96" OLED Display available all over the place for a very good price:

SSD1306 0.96" I2C OLED Display


  My first option for a Alphanumeric Display still remain the ST7032i LCD one, but as looking also for a Graphical Display option found this SSD1306 OLED as a easy to use one with the CBDB nEXT EVO Board.

It is a very good choice because:

 -  From the Hardware point of view, as been a Display with a native I2C interface, it is very easy to connect thru the CBDB EVO nEXT Bus (no extra wires, PSU, etc)

 -  From the Software point of view, even more good news:
  • if you want to use NodeMCU in your projects, a driver for SSD1306 is already there, based on the u8glib library.
  • if you want your Arduino IDE also the u8glib driver is there!
  • Full Datasheet available, so you can also implement your own driver very easy.



  The SSD1306 is a 128x64 Dot Matrix Driver/Controller manufactured by Solomon Systech.
Controller Power Supply for IC Logic is between 1.65V to 3.3V so we have here a 3.3V compatible device, no need for any kind of logical levels converter.

   I will not insist too much about the SSD1306 controller, just one thing that might worth to explain a bit, as it looks that it is creating a lot of confusion for many people:

If you look on the back of the module you can see a jumper option for the Display I2C address: 0x7A or 0x78, with default selected on 0x78:




   If you will try to use it like that, with the addresses from above, it will not work, as many people has already found it.

   Why?

  The I2C communication interface consists of slave address with set bit SA0, I2C-bus data signal SDA (SDAOUT/D2 for output and SDAIN/D1 for input) and I2C-bus clock signal SCL (D0). Both the data and clock signals must be connected to pull-up resistors. 

  SSD1306 has to recognize the slave address before transmitting or receiving any information by the
I2C-bus. The device will respond to the slave address following by the slave address bit (“SA0” bit)
and the read/write select bit (“R/W#” bit) with the following byte format:


b7 b6 b5 b4 b3 b2 b1     b0
 0   1  1   1   1   0   SA0  R/W#


 “SA0” bit provides an extension bit for the slave address.
Either “0111100” or “0111101”, can be selected as the slave address of SSD1306.
D/C# pin acts as SA0 for slave address selection, and actually this is a Address Select pin from the above.

So, if we take the 7 Bit I2C address representation from above we will have:

0 1 1 1 1 0 0  - > 0x3C (default)
OR
0 1 1 1 1 0 1   - > 0x3D (alternate)


The 8th bit is the “R/W#” bit and is used to determine the operation mode of the I2C-bus interface:

 - R/W#=1 - readmode.
 - R/W#=0 - write mode.

  For more details please take a look at the SSD1306 Datasheet




What we will need:


Connection with the nEXT EVO Board is very easy, as SSD1306 connector is fully compatible with the nEXT connector:

Connecting SSD1306 Display to the CBDB nEXT EVO Board


 No wires, no hasle, a nice and compact unit:






Software implementation

 As the driver is already available for this type of Display, for simple projects no driver implemetantion is needed, just few functions to make it running:

  1. Display initialisation
function init_OLED(sda,scl) --Set up the u8glib lib
     sla = 0x3C
     i2c.setup(0, sda, scl, i2c.SLOW)
     disp = u8g.ssd1306_128x64_i2c(sla)
     disp:setFont(u8g.font_6x10)
     disp:setFontRefHeightExtendedText()
     disp:setDefaultForegroundColor()
     disp:setFontPosTop()
     --disp:setRot180()           -- use it for rotate display
end

2. Print Text routine
str1="ESP8266-Projects.com"
str2="Hello World!!"

function PrintText()
  disp:drawStr(5, 10, str1)
  disp:drawStr(20, 20, str2)
end


3. Print on Display function
function print_OLED()
   disp:firstPage()
   repeat
     PrintText()
     disp:drawCircle(64, 47, 14)
     disp:drawFrame(2,2,126,62)
   until disp:nextPage() == false
end

4. Main program
str1="ESP8266-Projects.com"
str2="Hello World!!"

init_OLED(2,1)
print_OLED()

5. Drawing animation 
function draw_tst()
 for r=1, 31 do
   disp:firstPage()
   repeat
     disp:drawCircle(64, 32, r)
   until disp:nextPage() == false
   tmr.wdclr()
 end

 for r=30, 1, -1 do
   disp:firstPage()
   repeat
     disp:drawCircle(64, 32, r)
   until disp:nextPage() == false
   tmr.wdclr()
 end

print_OLED() end


7 comments:

Pete said...
This comment has been removed by the author.
Pete said...

Great stuff. Thanks!

You have one error -

print_LCD() in your main program throws an error. No biggie, I just removed the command. :)

Thanks for writing this up. I used your work as a basis to connect to a ESP-12E dev kit.

David said...

My OLED screen only shows pixels, any idea?

Unknown said...

Check you wiring: power, I2C (SDA & SCL in correct order), etc.

Run a I2C scanbus to check that you can properly detect your OLED Display on your I2C Bus. A simple I2C scanbus() function can be found in the articles below.

It will worth to read also these I2C related articles:

- I2C Basics & Scanbus(): http://www.esp8266-projects.com/2015/12/esp8266-next-evo-analog-extension-board.html

- I2C Programming considerations: http://www.esp8266-projects.com/2015/08/esp8266-nodemcu-i2c-programming.html


Unknown said...

Thanks Pete, typo error, print_LCD() should be read print_OLED() :)

Corrected now

Fedex said...

Is there anybody can explain me why we have to cicle the pages until next does not exist calling same method ?
Tnx

Unknown said...

Thank you for this information

"Oderlachs.de"

Post a Comment