Solved: I2C with SSD1306 Display

Go To Last Post
25 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am currently trying to get a SSD1306 display to function (https://www.adafruit.com/product...). I am using an ATMEGA328 microcontroller and have been able to successfully send commands/data to the SSD1306 and receive ACK's, odd thing is I have not been able to get the display to actually turn on at all, just a black screen. I've seen a bunch of command sequences online to send to the display to initialize it, and I have tried this with no luck. 

 

I've included the .c file's where I've written the initialization and tested it.

 

I've tried just about everything, I have made sure to make RESET go from high to low, made sure I am sending to the correct address, I tied the SA0 pin to ground ( I am using 0x3C device address). Is there something I am missing??

 

 

Attachment(s): 

Last Edited: Thu. Mar 16, 2017 - 12:20 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your code "looks" ok.   

Have you actually connected RESET to PD4?  

Have you connected SDA, SCL ? (PC4. PC5)

Do you have proper external pullups?   (most Ebay modules have them on the pcb)

 

Have you tried the OLED hardware with Arduino code?

If you verify that Arduino works ok,   I will try your C code on a real OLED.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have connected the RESET, SDA, and SCL to the proper pins. I've also used two 4.7k resistors to pull up the SDA and SCL. It doesn't appear that there is an issue with the display receiving the commands, since on my scope I can verify that there is an ACK appearing.

 

I did try with Arduino and yes the display did function.

 

Hard to think of what else to try...

 

 

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Also, I have CS, Chip Select, tied to ground.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is that /CS or CS tied to ground. Big difference...

 

Ross McKenzie, Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

CS, the pin on the breakout board. I thought that it was active low, is it otherwise?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I do not know if it is active LOW, but if it is, it should be labelled /CS. That is, with a bar over the top of the CS letters.

Ross McKenzie, Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Looking at your Adafruit page, the breakout board is clearly labelled as "CS"... no bar. So I think  it is enabled with CS tied high rather than low. I have to go for dinner now (wife called) so don't have time to investigate closer for you.

Ross McKenzie, Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You omitted the SSD1306.h file.   So I had to reconstruct it by hand.   I duplicated your wiring.   And the program "works".

 

Life is simpler if you ZIP up your complete project.   Then we can see exactly what you have got.   And replicate it.

 

Why do you not use the Arduino libraries?

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Would it be presumptuous of me to ask if you shorted the two jumpers (SJ1 & SJ2) on the display to put it into I2C mode?

David

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

valusoft wrote:
Looking at your Adafruit page, the breakout board is clearly labelled as "CS"... no bar. So I think  it is enabled with CS tied high rather than low.

I wouldn't rely on that - I don't know how fastidious Adafruit are about such things.

 

The only sure way to check is to look at the schematic - which is linked from the page in the OP

 

https://learn.adafruit.com/monoc...

 

Which does seem to suggest that it's actually /CS ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Back from dinner and watching the mandatory news/current affairs programs.

 

I see that y'all have added to the unravelling of the mystery. Links for I2C are mentioned below as is the /CS on the chip itself. Poor show on Adafruit's part changing its name to then be CS_3.3V (misleading at the very least)

 

Ross McKenzie, Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok,  my SSD1306 that I was using was from Ebay.   Configured for I2C and with separate CS, DC, RES pins as well as SDA/SCK.

 

I tried it with Adafruit Library on Arduino.   Verified the hardware.

I built the OP's C code.   Which does not really do anything much.

 

The OP has already verified his hardware with an Arduino library.   So we know  that his module is configured for I2C and his wiring is ok.

 

I would guess that the OP has hand-rolled his own I2C with 8-bit Slave Addresses.

But used the 7-bit Address from the Arduino code.

 

Without seeing the SSD1306_DEFAULT_ADDRESS that he is using,  I can only speculate.

 

Yes, DC=0 selects 7-bit address=0x3C.  DC=1 selects 0x3D

RES (on my module) has no pullup.   So the OLED will randomly reset if you do not have under program control.    Adafruit examples tend to omit the RES pin in their constructor.    I presume that they have a pullup.    And this strategy will show that Ebay is "no good"

CS on my module is ok with n/c.   And ok with CS=0 or CS=1

 

David.

Last Edited: Wed. Mar 15, 2017 - 11:49 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
I would guess that the OP has hand-rolled his own I2C with 8-bit Slave Addresses.

But used the 7-bit Address from the Arduino code.

Ha ha - that old chestnut:

 

https://www.avrfreaks.net/comment...

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes... RES and CS_3.3V are both pulled high via 10Ks

 

Note the I2C address comments in the left of this partial capture of Adafruit's schematic.

 

Ross McKenzie, Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I understand 7-bit Slave addresses. It is the most common problem that most punters have with I2C. Especially when they decide to have chosen to reinvent their own wheels. Are you really expecting them to read the notes on the schematic?
.
David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
I understand 7-bit Slave addresses.

 

Where did I suggest otherwise?

 

david.prentice wrote:
It is the most common problem that most punters have with I2C. Especially when they decide to have chosen to reinvent their own wheels. Are you really expecting them to read the notes on the schematic? . David.
I guess there is no point in publishing datasheets either .... devil

Ross McKenzie, Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

valusoft wrote:
I guess there is no point in publishing datasheets either ....

 

They can publish them.   People don't necessarily read them.

 

I am as guilty as anyone else.    I just put the OP's attached files into an AS7 project.    Then had to reconstruct the missing ssd1306.h with the #defines from the Adafruit_SSD1306.h file.   (which uses 7-bit addresses)

 

I did not even look at the i2c.c file until the OLED did not respond.    I changed the 0x3C to (0x3C << 1) and the OLED sprang into life.

 

Complete speculation on my part.   I do not know what Slave address he was actually using.   But his #1 message said:

jakchrmr wrote:
I tied the SA0 pin to ground ( I am using 0x3C device address). Is there something I am missing??

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But, surely, if you're going to write code from scratch then you need to read the datasheet?!

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Did that... it is good to make sure of everything.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:

valusoft wrote:

 

I did not even look at the i2c.c file until the OLED did not respond.    I changed the 0x3C to (0x3C << 1) and the OLED sprang into life.

 

Complete speculation on my part.   I do not know what Slave address he was actually using.   But his #1 message said:

jakchrmr wrote:
I tied the SA0 pin to ground ( I am using 0x3C device address). Is there something I am missing??

 

 

 

I used 0x78, these are my defines....

 

#define SSD1306_DEFAULT_ADDRESS 0x78
#define SSD1306_SETCONTRAST 0x81
#define SSD1306_DISPLAYALLON_RESUME 0xA4
#define SSD1306_DISPLAYALLON 0xA5
#define SSD1306_NORMALDISPLAY 0xA6
#define SSD1306_INVERTDISPLAY 0xA7
#define SSD1306_DISPLAYOFF 0xAE
#define SSD1306_DISPLAYON 0xAF
#define SSD1306_SETDISPLAYOFFSET 0xD3
#define SSD1306_SETCOMPINS 0xDA
#define SSD1306_SETVCOMDETECT 0xDB
#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
#define SSD1306_SETPRECHARGE 0xD9
#define SSD1306_SETMULTIPLEX 0xA8
#define SSD1306_SETLOWCOLUMN 0x00
#define SSD1306_SETHIGHCOLUMN 0x10
#define SSD1306_SETSTARTLINE 0x40
#define SSD1306_MEMORYMODE 0x20
#define SSD1306_COLUMNADDR 0x21
#define SSD1306_PAGEADDR   0x22
#define SSD1306_COMSCANINC 0xC0
#define SSD1306_COMSCANDEC 0xC8
#define SSD1306_SEGREMAP 0xA0
#define SSD1306_CHARGEPUMP 0x8D
#define SSD1306_SWITCHCAPVCC 0x2
#define SSD1306_NOP 0xE3
#define SSD1306_DEACTIVATE_SCROLL 0x2E

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The display is finally working. Stumbled upon the issue while I had the scope attached to the board. I noticed that the display began to work, so I then took off the probes and realized that the display immediately went off when I removed them. Put the probes back on and removed them one by one and noticed that when I removed one of the alligator clips from ground bus it went off... so I rewired a few things attached to ground and there we go, all works. That was annoying...

Thanks everyone for the help!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I replaced my invented H file with your one from #21. The program compiled and ran juat fine.
.
I had exactly the same hardware for Arduino and AS7. So any wiring problems would have been found with the proven Arduino code.
.
I am pleased that you have solved your problem.
.
David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
I replaced my invented H file with your one from #21. The program compiled and ran juat fine. . I had exactly the same hardware for Arduino and AS7. So any wiring problems would have been found with the proven Arduino code. . I am pleased that you have solved your problem. . David.

 

When I used my arduino the display flickered and didn't remain on, but at the time flickering was more than anything I had achieved, also when I did it with the arduino I had to use super thin wire that I was using for wire wrapping to put into the headers of the arduino board, so I just figured that was the issue and not other wiring on the board.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I wired one OLED as SPI.  And the other OLED as I2C.

 

I just ran the first OLED sketch that I came across.

#include <Wire.h>                     // required to run I2C SSD106
#include <SPI.h>                      // required to run SPI SSD106
#include <Adafruit_GFX.h>             // https://github.com/adafruit/Adafruit-GFX-Library
#include <Adafruit_SSD1306.h>         // https://github.com/adafruit/Adafruit_SSD1306

#define OLED_CLK 13
#define OLED_MOSI 11
#define OLED_RESET 8
#define OLED_I2C_RESET 4
#define OLED_DC 9
#define OLED_CS 10

//Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS); // I use SPI
//Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); // I use SPI
Adafruit_SSD1306 display(OLED_I2C_RESET); // reset required for SSD1306

...

and simply used the appropriate constructor.

 

Yes,  in fact the pullups,   header for SPI display etc were on a home made ProtoShield.   The fixed wiring is done with soldered wire-wrap wire.

The temporary wiring is with ready-made female to female jumper cables.

 

Buying a pack of jumper cables, headers, some Protoboard, ... is so cheap and available through Ebay.

It means that I can plug the same "Shield" into an Arduino, XMINI, NUCLEO, FRDM, ... and know that the hardware is reliable.

Bare wires or breadboards are always risky.   Quite Honestly,   no one would think of using 30AWG wire-wrap into breadboard or header sockets.

 

David.

Last Edited: Wed. Mar 15, 2017 - 07:33 PM