It's 🐍CircuitPython Monday🐍 at Adafruit! Use the code ADATY to get 20% off CircuitPython and 15% off items storewide!
0

Hardware SPI from the latest SSD1306 Oled Library?
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Hardware SPI from the latest SSD1306 Oled Library?

by satoer on Sun Jun 03, 2012 8:50 am

I Want to use hardware SPI (from the Arduino UNO) to drive my SSD1306 based oled.
The provided library uses the much slower software (bitbanging) SPI:
https://github.com/adafruit/Adafruit_SSD1306

A year ago, NickGammon profided some adjustments to the code, to use the display with hardware SPI.
This post: viewtopic.php?f=19&t=19079&start=15#p103938

But if I look at the current code, it seems there’s been some heavy rewritten parts. And I can’t find the parts that needs to be replaced to use it with Hardware SPI.
Luckely, Github profides downloading older versions. And if I adjust the version from January:
https://github.com/adafruit/Adafruit_SS ... 561d7c472d
It works with Hardware SPI.

Now, my question. I’m not that skilled programmer (at least, not in C). Can someone point out what needs to be changed to use the current SSD1306 library with hardware SPI?
If I look at the library code, there seems to be references to hardware SPI commented out, for example:
Code: Select all | TOGGLE FULL SIZE
 
void Adafruit_SSD1306::ssd1306_command(uint8_t c) {
  if (sid != -1)
  {
    // SPI
    //digitalWrite(cs, HIGH);
    *csport |= cspinmask;
    //digitalWrite(dc, LOW);
    *dcport &= ~dcpinmask;
    //digitalWrite(cs, LOW);
    *csport &= ~cspinmask;
    fastSPIwrite(c);
    //digitalWrite(cs, HIGH);
    *csport |= cspinmask;
  }
  else
  {
    // I2C
    uint8_t control = 0x00;   // Co = 0, D/C = 0
    Wire.beginTransmission(SSD1306_I2C_ADDRESS);
    Wire.write(control);
    Wire.write(c);
    Wire.endTransmission();
  }
}

But uncommenting and commenting the “csport” code does not transform the library into hardware SPI.
satoer
 
Posts: 5
Joined: Sun Jun 03, 2012 8:41 am

Re: Hardware SPI from the latest SSD1306 Oled Library?

by adafruit_support_rick on Sun Jun 03, 2012 12:22 pm

The current adafruit library supports hardware SPI. To use it, you only specify your RESET pin when you define your display object:
For example:
Code: Select all | TOGGLE FULL SIZE
Adafruit_SSD1306 display(OLED_RESET);

adafruit_support_rick
 
Posts: 35095
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: Hardware SPI from the latest SSD1306 Oled Library?

by satoer on Sun Jun 03, 2012 3:03 pm

Hi driverblock, thanks I didn’t know that.

I’ve made a test program that quickly draws a bitmap and clears the screen. spits the framerate on the serial port. With the old hardware SPI adjusted library I get a framerate of 34fps

With the new library I get a framerate of 16 fps if I define it with:
Adafruit_SSD1306 oled(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

If I define it with:
Adafruit_SSD1306 oled(OLED_RESET);

Nothing happens. It seems to hang on:
oled.begin(SSD1306_SWITCHCAPVCC);

Here’s the testcode I used:
Code: Select all | TOGGLE FULL SIZE
 
#define OLED_DC 8
#define OLED_CS 10     // SPI slave-select
#define OLED_CLK 13    // hardware SPI clock
#define OLED_MOSI 11   // hardware SPI MOSI
#define OLED_RESET 7


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

//Adafruit_SSD1306 oled(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
Adafruit_SSD1306 oled(OLED_RESET);


const unsigned char __attribute__ ((progmem)) crownlinelogozw [] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x80, 0x80, 0xC0, 0xE0, 0xE0, 0xE0, 0xF0, 0xF0, 0xF8, 0x78, 0x78, 0x78, 0x3C, 0x3C, 0x3C,
  0x3C, 0x3C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x18, 0x38, 0x38, 0x38, 0x70, 0x70, 0xE0,
  0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF8, 0xFC, 0xFE, 0xFE,
  0x7F, 0x1F, 0x0F, 0x0F, 0x07, 0x83, 0x81, 0x81, 0xC0, 0xC0, 0xC0, 0x60, 0x60, 0xE0, 0xE0, 0xE0,
  0xE0, 0xE0, 0xE0, 0xA0, 0xA0, 0x80, 0x80, 0x80, 0x80, 0x80, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
  0xC0, 0x81, 0x83, 0x87, 0x8E, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x79, 0x3C,
  0x3C, 0x3E, 0x9E, 0x9F, 0xDF, 0xCF, 0xCF, 0xEF, 0x6F, 0x67, 0x77, 0x37, 0x37, 0x3F, 0x1B, 0x1B,
  0x1B, 0x1B, 0x1B, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x87,
  0xC3, 0xC3, 0xE3, 0xF3, 0x7B, 0x3B, 0x1F, 0x1F, 0x0F, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x33, 0x71, 0xF9, 0xF8, 0xF8, 0xDC, 0x8C, 0x0E,
  0x06, 0x07, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x40, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x1C, 0x8C, 0xCE, 0xC7, 0x67, 0x73,
  0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x0F, 0x0F,
  0x1E, 0x1E, 0x3C, 0x3C, 0x38, 0x38, 0x38, 0x78, 0x70, 0x70, 0x70, 0x70, 0x70, 0x30, 0x30, 0x30,
  0x38, 0x38, 0x18, 0x18, 0x1C, 0x0C, 0x0C, 0x0E, 0x06, 0x07, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x80, 0x80, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00,
  0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
  0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x80, 0x80, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
  0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0,
  0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
  0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0,
  0xC0, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0,
  0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
  0xFC, 0xFE, 0xFF, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x07, 0x00,
  0x00, 0xFF, 0xFF, 0x6E, 0x60, 0x60, 0xE1, 0xFF, 0xBF, 0x1F, 0x00, 0x20, 0xFC, 0xFE, 0xFF, 0x03,
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0xFF, 0xFE, 0xFF, 0x1F, 0xFF, 0xFC,
  0xE0, 0x00, 0xE0, 0xF8, 0x3F, 0x0F, 0x3F, 0xFF, 0xF8, 0xE0, 0x00, 0xE0, 0xFC, 0x3F, 0x07, 0x00,
  0xFF, 0xFF, 0x07, 0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xE0, 0xC0, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0x00,
  0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
  0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x07, 0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xE0, 0xC0, 0xC0,
  0x80, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x30, 0x30, 0x30, 0x30, 0x30, 0x71, 0x71,
  0x01, 0x03, 0x07, 0x0F, 0x0E, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x0F, 0x00,
  0x18, 0x1F, 0x1F, 0x1F, 0x18, 0x18, 0x00, 0x03, 0x07, 0x0F, 0x0E, 0x1C, 0x19, 0x1B, 0x1F, 0x0F,
  0x1E, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1C, 0x0C, 0x0F, 0x07, 0x03, 0x01, 0x00, 0x00, 0x07,
  0x1F, 0x1F, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1F, 0x1F, 0x07, 0x01, 0x00, 0x18, 0x18,
  0x1F, 0x1F, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x0F, 0x1F, 0x1F, 0x00,
  0x00, 0x18, 0x1F, 0x1F, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1C, 0x00, 0x18, 0x1F, 0x1F,
  0x1F, 0x18, 0x18, 0x00, 0x18, 0x1F, 0x1F, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03,
  0x07, 0x0F, 0x1F, 0x1F, 0x00, 0x18, 0x1F, 0x1F, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E
};

int counter=0, SecondTimer=0;

void setup()
{
  Serial.begin(9600);
  Serial.println("Start setup" );
  SPI.begin ();
  Serial.println("SPI Started" );
  oled.begin(SSD1306_SWITCHCAPVCC); 
  Serial.println("End setup" );
}

void loop()
{   
  oled.drawBitmap(0, 0, crownlinelogozw ,128, 64, 1);
  oled.display();
  counter++;
  oled.clearDisplay();
  oled.display();
  counter++;
  if (millis() > (SecondTimer + 1000)) // 1 keer per seconde
  {
    Serial.println(counter);
    SecondTimer=millis();
    counter=0;
  }
 

What did I do wrong?
satoer
 
Posts: 5
Joined: Sun Jun 03, 2012 8:41 am

Re: Hardware SPI from the latest SSD1306 Oled Library?

by adafruit_support_rick on Sun Jun 03, 2012 3:53 pm

Which display are you using? There is a #define in the header file that needs to be changed if you are using the 128 X 32 display.
If you're using the 128x32 OLED, be sure to uncomment the "#define SSD1306_128_32" in the top of Adafruit_SSD1306.h to change the buffer size.

Code: Select all | TOGGLE FULL SIZE
//   #define SSD1306_128_64
   #define SSD1306_128_32


Check your wiring: It has to be like this:
Finally, connect the pins to your Arduino - GND goes to ground, Vin goes to 5V, DATA to digital 9, CLK to digital 10, D/C to digital 11, RST to digital 13 and finally CS to digital 12


Here the picture from the tutorial:
Image

adafruit_support_rick
 
Posts: 35095
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: Hardware SPI from the latest SSD1306 Oled Library?

by satoer on Sun Jun 03, 2012 4:12 pm

No, I’m using the 128x64 version.
So I’ts probably wrong “wired”.
Finally, connect the pins to your Arduino - GND goes to ground, Vin goes to 5V, DATA to digital 9, CLK to digital 10, D/C to digital 11, RST to digital 13 and finally CS to digital 12

My wiring is:
Code: Select all | TOGGLE FULL SIZE
 #define OLED_DC 8
#define OLED_CS 10     // SPI slave-select
#define OLED_CLK 13    // hardware SPI clock
#define OLED_MOSI 11   // hardware SPI MOSI
#define OLED_RESET 7

These are te preconfigured hardware SPI pins I should use. Besides the display, I also want to use a SD card on the same pins (except of course the CS).
From the SPI reference on the Arduino site: http://arduino.cc/en/Reference/SPI
On the Arduino Duemilanove and other ATmega168 / 328-based boards, the SPI bus uses pins 10 (SS), 11 (MOSI), 12 (MISO), and 13 (SCK). […]It is possible to use a pin other than pin 10 as the slave select (SS) pin. For example, the Arduino Ethernet shield uses pin 4 to control the SPI connection to the on-board SD card, and pin 10 to control the connection to the Ethernet controller.
(CS = SS)
So there’s a misconfiguration in the SSD1306 Library if you want to use hardware SPI?
satoer
 
Posts: 5
Joined: Sun Jun 03, 2012 8:41 am

Re: Hardware SPI from the latest SSD1306 Oled Library?

by adafruit_support_rick on Sun Jun 03, 2012 4:35 pm

Sorry, sorry - my mistake. I had a brain-cramp when I looked at the library code.
Code: Select all | TOGGLE FULL SIZE
Adafruit_SSD1306 oled(OLED_RESET);
selects I2C, not hardware SPI. Looking again, the library does not do hardware SPI. Ignore everything I said.

Are you using a level-shifter with your 128X64?

adafruit_support_rick
 
Posts: 35095
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: Hardware SPI from the latest SSD1306 Oled Library?

by satoer on Sun Jun 03, 2012 4:50 pm

Ah, so there’s no easy fix to adjust the new library code to hardware SPI like NickGammon has done in topic: viewtopic.php?f=19&t=19079&start=15#p103938 for the old library code?
Yes, I’m using a level shifter to transform the signal voltage to 3.3V ;)
satoer
 
Posts: 5
Joined: Sun Jun 03, 2012 8:41 am

Re: Hardware SPI from the latest SSD1306 Oled Library?

by adafruit_support_rick on Sun Jun 03, 2012 4:55 pm

Not that I know of. 'Fraid you're on your own.

adafruit_support_rick
 
Posts: 35095
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: Hardware SPI from the latest SSD1306 Oled Library?

by NickGammon on Sun Jun 03, 2012 11:23 pm

I have amended the library to support hardware SPI. Documentation here:

http://arduino.cc/forum/index.php/topic,108542

Note that you will need to use different pins than in the tutorial. It's discussed in the above post.

The changes are pretty minimal. Maybe one day a define in "official" code will allow you to select them as an option.
NickGammon
 
Posts: 8
Joined: Thu Dec 30, 2010 5:33 pm

Re: Hardware SPI from the latest SSD1306 Oled Library?

by satoer on Mon Jun 04, 2012 11:28 am

Fantastic! Thank you NickGammon!
satoer
 
Posts: 5
Joined: Sun Jun 03, 2012 8:41 am

Please be positive and constructive with your questions and comments.