# SSD1306 via Hardware SPI

**URL:** <https://community.particle.io/t/ssd1306-via-hardware-spi/8448>\
**Category:** Hardware\
**Created:** [November 27, 2014, 7:22pm UTC](https://community.particle.io/t/ssd1306-via-hardware-spi/8448 "2014-11-27T19:22:36Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![michaelkrog](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/michaelkrog/32/4708_2.png) [@michaelkrog](https://community.particle.io/u/michaelkrog)\
**Post date:** [November 27, 2014, 7:22pm UTC](https://community.particle.io/t/ssd1306-via-hardware-spi/8448/1 "2014-11-27T19:22:36Z")

</div>

I have my SSD1306 running fine via Software SPI initializing it like this:

```
#define OLED_MOSI D0
#define OLED_CLK D1
#define OLED_DC D2
#define OLED_CS D3
#define OLED_RESET D4
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

```

But I am struggling to figure out how to wire up the display to hardware SPI and then initialize it.

The docs say about hardware SPI pins:

```
A2: SS (Slave Select)
A3: SCK (Serial Clock)
A4: MISO (Master In Slave Out)
A5: MOSI (Master Out Slave In)

```

The example I have for initializing the display as hardware SPI suggests this:

```
// use hardware SPI
#define OLED_DC D3
#define OLED_CS D4
#define OLED_RESET D5
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);

```

Does any of you guys know how to set it up?

---

<div class="post-metadata">

**Author:** ![kennethlimcp](https://avatars.discourse-cdn.com/v4/letter/k/c0e974/32.png) [@kennethlimcp](https://community.particle.io/u/kennethlimcp)\
**Post date:** [November 28, 2014, 12:18am UTC](https://community.particle.io/t/ssd1306-via-hardware-spi/8448/2 "2014-11-28T00:18:56Z")

</div>

I took a look and it should probably be:

```
SSD1306 --> Core
CS ---> SS (A2)
CLK ---> SCK (A3)
MOSI --> MOSI (A5)
DC --> Any pin you defined (eg. D3)
CS ---> A2 (can be changed but we use the default chip select pin)
Reset ---> Any pin you defined (eg. D5)

```

Let us know how it goes 😉

---

<div class="post-metadata">

**Author:** ![michaelkrog](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/michaelkrog/32/4708_2.png) [@michaelkrog](https://community.particle.io/u/michaelkrog)\
**Post date:** [November 28, 2014, 7:44am UTC](https://community.particle.io/t/ssd1306-via-hardware-spi/8448/3 "2014-11-28T07:44:13Z")

</div>

Thx Kenneth!

I’ll give it a go. 😃

---

<div class="post-metadata">

**Author:** ![ScruffR](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/scruffr/32/6952_2.png) [@ScruffR](https://community.particle.io/u/ScruffR)\
**Post date:** [November 28, 2014, 8:38am UTC](https://community.particle.io/t/ssd1306-via-hardware-spi/8448/4 "2014-11-28T08:38:23Z")

</div>

Just to make things even clearer than @kennethlimcp has already done:

The DC or D/C pin is needed by some devices to distinguish between commands or data for the controler.  
Since SPI only pushes out anonymous bitsreams the user code has to “tell” the controler if this will be a command (e.g. D/C LOW) or a data (e.g. D/C HIGH) bitstream. And so D/C is not actually an SPI pin, but this gives you freedom which Core pin to choose.

Similarly the Reset pin can be chosen freely or even pulled high or left open if it’s pulled high on the board already, if you don’t need to reset the device via user code.

The CS pin is a kind of hybrid here. While SPI brings its own version of it (SS) you might want to use any other free digital pin if you’d like to attach multiple SPI devices, selecting each individual one via its own designated chip select pin.  
For each SPI stream only one CS should be active to ensure that only the meant device listens to it.  
And since only user code “knows” who is meant at a given time you have to decide which Core pin to use as CS for which device.

---

<div class="post-metadata">

**Author:** ![michaelkrog](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/michaelkrog/32/4708_2.png) [@michaelkrog](https://community.particle.io/u/michaelkrog)\
**Post date:** [November 29, 2014, 2:58pm UTC](https://community.particle.io/t/ssd1306-via-hardware-spi/8448/5 "2014-11-29T14:58:16Z")

</div>

Ok. I just tried it without any luck.  
I initialize like this:

```
#define OLED_DC A1
#define OLED_CS A2
#define OLED_RESET A4
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);

```

I have connected it like this:

```
SSD1306 --> Core
DC ---> A1
CS ---> A2
CLK ---> A3
Reset ---> A4
MOSI ---> A5

```

I going to look more into it in a few days to figure it out.

---

<div class="post-metadata">

**Author:** ![kennethlimcp](https://avatars.discourse-cdn.com/v4/letter/k/c0e974/32.png) [@kennethlimcp](https://community.particle.io/u/kennethlimcp)\
**Post date:** [November 29, 2014, 3:19pm UTC](https://community.particle.io/t/ssd1306-via-hardware-spi/8448/6 "2014-11-29T15:19:55Z")

</div>

I think A4 might not work as it’s a SPI oin on the core. Try maybe a Digital pin 😉

---

<div class="post-metadata">

**Author:** ![ScruffR](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/scruffr/32/6952_2.png) [@ScruffR](https://community.particle.io/u/ScruffR)\
**Post date:** [November 29, 2014, 6:57pm UTC](https://community.particle.io/t/ssd1306-via-hardware-spi/8448/7 "2014-11-29T18:57:46Z")

</div>

The reason why A4 won’t do is that this is already a dedicated SPI pin (MISO) - as @kennethlimcp already stated 😉  
Look here

[http://docs.spark.io/hardware/#pins-and-i-o-spi](http://docs.spark.io/hardware/#pins-and-i-o-spi)

---

<div class="post-metadata">

**Author:** ![michaelkrog](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/michaelkrog/32/4708_2.png) [@michaelkrog](https://community.particle.io/u/michaelkrog)\
**Post date:** [November 30, 2014, 10:26am UTC](https://community.particle.io/t/ssd1306-via-hardware-spi/8448/8 "2014-11-30T10:26:45Z")

</div>

Heureka! — it’s alive. 😃

Moved Reset to D0 as initialized accordingly and it worked.  
I have a question more though. The Adafruit\_1306 lib has the frequency for HW SPI set at 9mhz:

```
SPI.setClockDivider(SPI_CLOCK_DIV8);	// 72MHz / 8 = 9Mhz

```

What is the reason of this limit? Is the SSD1306 not able to run at a higher frequency?

---

<div class="post-metadata">

**Author:** ![kennethlimcp](https://avatars.discourse-cdn.com/v4/letter/k/c0e974/32.png) [@kennethlimcp](https://community.particle.io/u/kennethlimcp)\
**Post date:** [November 30, 2014, 10:37am UTC](https://community.particle.io/t/ssd1306-via-hardware-spi/8448/9 "2014-11-30T10:37:03Z")

</div>

That might be possible but checking the data sheet will give us the best answer. 😉

Or maybe the arduino they interfaced to cannot handle too high a freq and 72Mhz seems like a stm32f103 thing on the core and divided to get the same freq used in the original library.

You can try bumping it up and see how it goes 😉

---

<div class="post-metadata">

**Author:** ![michaelkrog](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/michaelkrog/32/4708_2.png) [@michaelkrog](https://community.particle.io/u/michaelkrog)\
**Post date:** [November 30, 2014, 12:20pm UTC](https://community.particle.io/t/ssd1306-via-hardware-spi/8448/10 "2014-11-30T12:20:28Z")

</div>

Tried it, but makes not difference.

I tried measuring the FPS, and it doesn’t seem like its the SPI that limits a good FPS.

If I draw 1 frame per loop then before wifi is connected I get a good 210FPS. After WIFI connects I get 100FPS. If I draw 4 frames per loop it jumps to 170FPS after WIFI connects.

And all I need really is 60FPS. Im gonna measure I2C now. If that gives me 60FPS I might as well use that to have more pins available. 😃
