New to Arduinos, first attempt (0.96 OLED)

Hey everyone, just purchased an 0.96 OLED and have some questions. Also, I'm new to Arduinos (and circuits in general) and this is my first attempt at anything, so if anything can be chalked up to my ignorance or can be referenced elsewhere, any info is likewise appreciated.

The board I'm using is an Uno clone, and the part itself was referenced by the vendor as SSD1306, but the picture on the website (and the only information I've found on similar parts) is for a part with four pins, and mine has seven. How would I go about setting this up, and is there any way I can test it works once doing so (even just displaying text)? Thanks!

Here's some pictures

Post a link to your actual display. e.g. find an Ebay item with matching photos.
Make sure that any link accurately matches the item on your desk.

Some Ebay vendors put photos of different screens and often have mendacious text.
You can compare photos easily. You may not understand the text.

David.

I was typing #2 when you posted the photos in #1. At the time I read the OP you said the screen had six pins.

Pictures never lie! And I note that your maths skills have improved. The OP now says seven pins.

Anyway, thanks for the photos. You have an SPI display. Just use an SPI constructor instead of an I2C constructor in the Adafruit_SSD1306 library e.g.

  Adafruit_SSD1306(int8_t SID, int8_t SCLK, int8_t DC, int8_t RST, int8_t CS);
  Adafruit_SSD1306(int8_t DC, int8_t RST, int8_t CS);
  Adafruit_SSD1306(int8_t RST = -1);

Or u8g2lib uncomment one of these:

//U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1306_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 12, /* dc=*/ 4, /* reset=*/ 6);	// Arduboy (Production, Kickstarter Edition)
//U8G2_SSD1306_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1306_128X64_NONAME_F_3W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* reset=*/ 8);
//U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* reset=*/ 8);
//U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);   // All Boards without Reset of the Display
//U8G2_SSD1306_128X64_NONAME_F_6800 u8g2(U8G2_R0, 13, 11, 2, 3, 4, 5, 6, A4, /*enable=*/ 7, /*cs=*/ 10, /*dc=*/ 9, /*reset=*/ 8);
//U8G2_SSD1306_128X64_NONAME_F_8080 u8g2(U8G2_R0, 13, 11, 2, 3, 4, 5, 6, A4, /*enable=*/ 7, /*cs=*/ 10, /*dc=*/ 9, /*reset=*/ 8);
//U8G2_SSD1306_128X64_VCOMH0_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);	// same as the NONAME variant, but maximizes setContrast() range

These displays are 3.3V. I am not sure how happy they will be with 5V GPIO from your Uno.

Note that both libraries will let you omit the Reset pin in the constructor.
I strongly recommend that you always use the Reset pin argument in the constructor.

David.

Oh great, thanks! Haha yeah, caught they mistake and was hoping no one would catch it before I did. And thanks for the info, very helpful! And I'm guessing since this is also 3.3v that l would need to use level shifters as well?

Luckily I still have this shield to try again, but it's an mcufriend and I noticed you recently post something about those, so I'm sure I'll be asking questions again before too long. Thanks again!

Hi guys,

I'm also new to OLED displays and using an SPI display. I've followed all the steps to install the adafruit library. I found an error which was solved with the #1 reaction on the following forum:
https://forum.arduino.cc/index.php?topic=364400.msg2524546#msg2524546

However, step 4. mentions they are working on an i2C display. I still put in the line of code to see if it works, but I get the following error:
"At least one SSD1306 display must be specified in SSD1306.h"

Even though my the code in the .h file seems correct:

The driver is used in multiple displays (128x64, 128x32, etc.).
Select the appropriate display below to create an appropriately
sized framebuffer, etc.

SSD1306_128_64 128x64 pixel display

SSD1306_128_32 128x32 pixel display

SSD1306_96_16


#define SSD1306_128_64
//#define SSD1306_128_32
//#define SSD1306_96_16

Any tips on how to fix this for an SPI display?

(note. I post this here since the mentioned forum has no activity for more than 120 days and this post is fresh)

The SPI constructors are:

  Adafruit_SSD1306(int8_t SID, int8_t SCLK, int8_t DC, int8_t RST, int8_t CS);  //bit-bash SPI pins
  Adafruit_SSD1306(int8_t DC, int8_t RST, int8_t CS);  //hardware SPI pins

Personally, I use the hardware SPI on a Uno. i.e. DO on digital#13 (SCK), DI on digital#11 (MOSI)
and RES on digital#8, DC on digital#9, CS on digital#10.

  Adafruit_SSD1306 oled(9, 8, 10);  //hardware SPI pins

If you have multiple displays:

  Adafruit_SSD1306 oled1(9, 8, 10);  //hardware SPI pins CS on digital#10
  Adafruit_SSD1306 oled2(5, 6, 7);  //hardware SPI pins, different control pins

You can possibly share DC, RES on both displays but you need to be careful. You MUST have different lines for CS on each display.
You have zero hope of two independent 128x64 OLEDs on Uno. You have enough SRAM for two 128x32 OLEDs.
Untested.

Oliver can advise better on this subject. He is the author of u8g2.

David.

David, thank you for your fast reply.

To be honest I do not really understand your reply.

I found the following link on the Arduino site where a table explains how to connect the display. SPI - Arduino Reference
I am using an Arduino Mega and only one display.
But I am assuming bit-bash or hardware SPI use a different way of connecting the display?
Inserting eighter one of the codes does not solve the original error.

I've added the code I am using, that might help. (It's the standard Adafruit library).

/*********************************************************************
This is an example for our Monochrome OLEDs based on SSD1306 drivers

  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/category/63_98

This example is for a 128x64 size display using SPI to communicate
4 or 5 pins are required to interface

Adafruit invests time and resources providing this open source code, 
please support Adafruit and open-source hardware by purchasing 
products from Adafruit!

Written by Limor Fried/Ladyada  for Adafruit Industries.  
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// If using software SPI (the default case):
#define OLED_MOSI   9
#define OLED_CLK   10
#define OLED_DC    11
#define OLED_CS    12
#define OLED_RESET 13
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

/* Uncomment this block to use hardware SPI
#define OLED_DC     6
#define OLED_CS     7
#define OLED_RESET  8
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);
*/

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2

#define LOGO16_GLCD_HEIGHT 16 
#define LOGO16_GLCD_WIDTH  16 
static const unsigned char PROGMEM logo16_glcd_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000 };


#define SSD1306_LCDHEIGHT 64
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

void setup()   {                
  Serial.begin(9600);

  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC);
  // init done
  
  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.
  display.display();
  delay(2000);

  // Clear the buffer.
  display.clearDisplay();

  // draw a single pixel
  display.drawPixel(10, 10, WHITE);
  // Show the display buffer on the hardware.
  // NOTE: You _must_ call display after making any drawing commands
  // to make them visible on the display hardware!
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw many lines
  testdrawline();
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw rectangles
  testdrawrect();
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw multiple rectangles
  testfillrect();
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw mulitple circles
  testdrawcircle();
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw a white circle, 10 pixel radius
  display.fillCircle(display.width()/2, display.height()/2, 10, WHITE);
  display.display();
  delay(2000);
  display.clearDisplay();

  testdrawroundrect();
  delay(2000);
  display.clearDisplay();

  testfillroundrect();
  delay(2000);
  display.clearDisplay();

  testdrawtriangle();
  delay(2000);
  display.clearDisplay();
   
  testfilltriangle();
  delay(2000);
  display.clearDisplay();

  // draw the first ~12 characters in the font
  testdrawchar();
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw scrolling text
  testscrolltext();
  delay(2000);
  display.clearDisplay();

  // text display tests
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("Hello, world!");
  display.setTextColor(BLACK, WHITE); // 'inverted' text
  display.println(3.141592);
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.print("0x"); display.println(0xDEADBEEF, HEX);
  display.display();
  delay(2000);
  display.clearDisplay();

  // miniature bitmap display
  display.drawBitmap(30, 16,  logo16_glcd_bmp, 16, 16, 1);
  display.display();

  // invert the display
  display.invertDisplay(true);
  delay(1000); 
  display.invertDisplay(false);
  delay(1000); 
  display.clearDisplay();

  // draw a bitmap icon and 'animate' movement
  testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH);
}

You are using a Mega. So hardware SPI is on different pins.

When you add a message to someone else's thread, please verify that you are using an OLED like photos in #1.

You have chosen the Adafruit example. Connect VCC to 5V, GND to 0V, Connect the OLED according to the specified pins i.e.

// If using software SPI (the default case):
#define OLED_MOSI   9 //DI
#define OLED_CLK   10 //DO
#define OLED_DC    11 //DC
#define OLED_CS    12 //CS
#define OLED_RESET 13 //RES
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

Personally, I don't like connecting 3.3V displays to a Mega that has 5V GPIO. But many people do.

David.

Dear David,

Sorry I did not mention it, but I am using the same display as in the pictures.
Thank you for your answers. I'll try to use a different Arduino in the future.

I found the original problem that gave me the error "that at least one display should be selected". I did not delete the right "//". Your reactions probably helped me to prevent struggles with connecting the pins.

Thank you!

Adafruit examples work out of the box. If you copy the exact wiring.

U8g2 examples require you to un-comment the constructor that you want.

Always start with the bit-bang constructor. It allows you to use random pins.
When you have verified that the new toy works, change to the hardware SPI pins.

David.

David, since you said my display was a 3.3v also, would that mean I'd have to use level shifters like with that 3.3v 2.0 TFT? Or can it just still be done, just iffy how it'll take it? Sorry, I'm just so new to this I'm trying to differentiate, and since you'd said to the other guy above that many people will connect 3.3vs to megas, (though I'm using an Uno), just figured I'd ask.

I also have a digispark clone, which i know is also 5v, but would that potentially be any different or better in using this display, or would the 5v logic levels just make it the same? Thanks!

This is the digispark clone too, just for general reference. It includes the specs in the description

http://www.wish.com/c/582be4ee5513781db60f4c89

Okay, I'm back (with more understanding what in doing/looking at now), but still more questions.

So, I've gathered as much what the PCB tells me I need to solder or desolder in order to use i2c or spi, and see now that it is currently configured for spi. I see which pins on my Arduino clone are used for i2c and spi. I've identified what pins on the screen are meant to be used for what (through several tutorials of people using similar parts) and I've been able to identify what are the clk and mosi pins, gnd and power, and the last three in (what appears to be) their respective inputs.

But, still no luck! Ive gotten ahold of many different libraries through my trial/error/figuring this out, and have been trying to upload an example (spi specific) sketch, but can't figure out what might need changed. Any advice?

Also, I realize this screen is common enough these questions likely come up often, even so far as me finding an old thread from July with someone using the exact same part and David likewise providing them with information (which is where I also learned some of this from), so sorry about that, just not sure what im missing. Thanks!

Also, just scrolled up and gleaned some info from David's response to beags, and should note the connection I currently have into the Arduino is sck to d13 and mosi into d11, but Res in d9 (so should this be d8?) And DC into d8, cs into d10.

Do I need to change anything in the u8g library, or is there somewhere I can look to see where the pins are set to be input? Thanks!

Also, I've partly identified the spi constructors as well, but not sure what else to do with them or how that may correlate. Sorry for the ignorance, but thanks for the info so far as what I've learned

This is what im looking at in the ssd1306 library

class Adafruit_SSD1306 : public Adafruit_GFX {
 public:
  Adafruit_SSD1306(int8_t SID, int8_t SCLK, int8_t DC, int8_t RST, int8_t CS);
  Adafruit_SSD1306(int8_t DC, int8_t RST, int8_t CS);
  Adafruit_SSD1306(int8_t RST = -1);

// constructor for hardware SPI - we indicate DataCommand, ChipSelect, Reset
Adafruit_SSD1306::Adafruit_SSD1306(int8_t DC, int8_t RST, int8_t CS) : Adafruit_GFX(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT) {
  dc = DC;
  rst = RST;
  cs = CS;
  hwSPI = true;
}

Sorry, last one, promise. Found this for the ug8lib stuff, but wasnt in the library code, was in the example codes. Is this what you meant?

//U8GLIB_SSD1306_128X64 u8g(13, 11, 10, 9);	// SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_SSD1306_128X64 u8g(4, 5, 6, 7);	// SW SPI Com: SCK = 4, MOSI = 5, CS = 6, A0 = 7 (new white HalTec OLED)
//U8GLIB_SSD1306_128X64 u8g(10, 9);		// HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are  SCK = 13 and MOSI = 11)
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);	// I2C / TWI 
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_NO_ACK|U8G_I2C_OPT_FAST);	// Fast I2C / TWI 
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK);	// Display which does not send AC
//U8GLIB_SSD1306_ADAFRUIT_128X64 u8g(13, 11, 10, 9);	// SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_SSD1306_ADAFRUIT_128X64 u8g(10, 9);		// HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are  SCK = 13 and MOSI = 11)
//U8GLIB_SSD1306_128X32 u8g(13, 11, 10, 9);	// SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_SSD1306_128X32 u8g(10, 9);             // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are  SCK = 13 and MOSI = 11)
//U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE);	// I2C / TWI 
//U8GLIB_SSD1306_64X48 u8g(13, 11, 10, 9);	// SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_SSD1306_64X48 u8g(10, 9);             // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are  SCK = 13 and MOSI = 11)
//U8GLIB_SSD1306_64X48 u8g(U8G_I2C_OPT_NONE);	// I2C / TWI

CatDadJynx,

Yes, but u8glib is not supported any more. Please use u8g2. It can be installed from the Arduino Library manager.

Unlike Adafruit lib, for u8g2 you need to select a special constructor (modificaton of the library code is not required, so you do not need to leave Arduino IDE). The constructor defines the type of the display which is connected. Many constructors for common displays are included into the examples, so you just need to uncomment the constructor, which fits to your display and update the GPIO port numbers to your personal wiring.

Oliver

Ohh, awesome! Yeah, looks like Id at least had everything wired into where it should be, just completely new to all this and still been learning about commenting/uncommenting lines, that much went right over my head. But now i see the greater amount of flexibility/compatibility in it being set up that way, makes sense. Got it working now though, and have successfully run two different ug82 test sketches. Thanks a lot!