[SOLVED] SPI OLED SSD1331 with Nano 33 BLE

tl:dr Issue with SPI use, now fixed with support for SPI transactions in the Arduino Core see [SPI] missing setClockDivider, setBitOrder, and setDataMode API's · Issue #5 · arduino/ArduinoCore-nRF528x-mbedos · GitHub

Can anyone point me in the direction of some support for an SSD1331 SPI OLED display on the new Nano 33 BLE? I had some success with the adafruit ssd1331 library on an original nano but switching to this new one I am struggling and get errors at compile related to hardware SPI, no doubt due to the different chip and those libraries not supporting it. These are the errors I get with the displayOnOffTest example:

error: 'arduino::SPIClass {aka class arduino::HardwareSPI}' has no member named 'setClockDivider'
error: 'arduino::SPIClass {aka class arduino::HardwareSPI}' has no member named 'setBitOrder'
error: 'arduino::SPIClass {aka class arduino::HardwareSPI}' has no member named 'setDataMode'

Perhaps the library can be modified but I don't know where to start?

  1. Upgrade any libraries via IDE Library Manager
  2. Quote which library(s) and which version number(s).
  3. Run every example from the relevant library
  4. Quote which library example sketch is giving a problem.

Life is easier if you enable File->Preferences->verbose compile

Then copy-paste the library and memory usage lines to a code window.
They contain library location and version used.


Thanks for the reply David, hopefully this is what you are after:

1.Already Done.
2.Adafruit_GFX_Library at version 1.5.6
Adafruit_SSD1331_OLED_Driver_Library_for_Arduino at version 1.1.3
SPI in folder: userpath\ArduinoData\packages\arduino\hardware\mbed\1.1.0\libraries\SPI (legacy)

  1. Done. Using Adafruit_SSD1331_OLED_Driver_Library_for_Arduino examples which include "DisplayOnOffTest", "test", and "LCDGFXDemo"
  2. Same error with each example (my specific paths removed). Error occurs at 'Compiling library "Adafruit_GFX_Library"':

userpath\Arduino\libraries\Adafruit_GFX_Library\Adafruit_SPITFT.cpp: In member function 'void Adafruit_SPITFT::SPI_BEGIN_TRANSACTION()':
userpath\Arduino\libraries\Adafruit_GFX_Library\Adafruit_SPITFT.cpp:1799:21: error: 'arduino::SPIClass {aka class arduino::HardwareSPI}' has no member named 'setClockDivider'
userpath\Arduino\libraries\Adafruit_GFX_Library\Adafruit_SPITFT.cpp:1805:21: error: 'arduino::SPIClass {aka class arduino::HardwareSPI}' has no member named 'setBitOrder'
userpath\Arduino\libraries\Adafruit_GFX_Library\Adafruit_SPITFT.cpp:1806:21: error: 'arduino::SPIClass {aka class arduino::HardwareSPI}' has no member named 'setDataMode'

OK, after some more sleuthing it seems that part of the Adafruit GFX library (Adafruit_SPITFT.cpp) is calling functions that aren’t defined in the SPI file that is used for the Nano 33 BLE hardware. I assume they do exist for the AVR Nano. I don’t fully comprehend it all but am pretty sure it means the Adafruit GFX library won’t work without significant modification which is way over my head.

Time to find a new graphics library, open to suggestions…

  1. I installed Nano_BLE core via Tools->Boards Manager
  2. I installed Adafruit_GFX and Adafruit_SSD1331 via Library Manager
  3. I built displayOnOffTest from Adafruit_SSD1331/examples for a Uno
Using library Adafruit_GFX_Library at version 1.5.6 in folder: C:\Users\David Prentice\Documents\Arduino\libraries\Adafruit_GFX_Library 
Using library Adafruit_SSD1331_OLED_Driver_Library_for_Arduino at version 1.1.3 in folder: C:\Users\David Prentice\Documents\Arduino\libraries\Adafruit_SSD1331_OLED_Driver_Library_for_Arduino 
Using library SPI at version 1.0 in folder: C:\Program Files (x86)\Arduino-1.8.9\hardware\arduino\avr\libraries\SPI 
"C:\\Program Files (x86)\\Arduino-1.8.9\\hardware\\tools\\avr/bin/avr-size" -A "C:\\Users\\DAVIDP~1\\AppData\\Local\\Temp\\arduino_build_679378/displayOnOffTest.ino.elf"
Sketch uses 12602 bytes (39%) of program storage space. Maximum is 32256 bytes.
Global variables use 393 bytes (19%) of dynamic memory, leaving 1655 bytes for local variables. Maximum is 2048 bytes.
  1. I selected Tools->Board->Nano_33_BLE
  2. started to build displayOnOffTest from Adafruit_SSD1331/examples
  3. all goes well until we get to Adafruit_SPITFT.cpp
"C:\\Users\\David Prentice\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\arm-none-eabi-gcc\\7-2017q4/bin/arm-none-eabi-g++" -c -I. -g -Os -nostdlib "@C:\\Users\\David Prentice\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed\\1.1.0\\variants\\ARDUINO_NANO33BLE/defines.txt" "@C:\\Users\\David Prentice\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed\\1.1.0\\variants\\ARDUINO_NANO33BLE/cxxflags.txt" -DARDUINO_ARCH_NRF52840 -MMD -mcpu=cortex-m4 -DARDUINO=10809 -DARDUINO_ARDUINO_NANO33BLE -DARDUINO_ARCH_MBED "-IC:\\Users\\David Prentice\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed\\1.1.0\\cores\\arduino" "-IC:\\Users\\David Prentice\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed\\1.1.0\\variants\\ARDUINO_NANO33BLE" "-IC:\\Users\\David Prentice\\Documents\\Arduino\\libraries\\Adafruit_GFX_Library" "-IC:\\Users\\David Prentice\\Documents\\Arduino\\libraries\\Adafruit_SSD1331_OLED_Driver_Library_for_Arduino" "-IC:\\Users\\David Prentice\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed\\1.1.0\\libraries\\SPI" "-IC:\\Users\\David Prentice\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed\\1.1.0\\cores\\arduino/api/deprecated" "-iprefixC:\\Users\\David Prentice\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed\\1.1.0\\cores\\arduino" "@C:\\Users\\David Prentice\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed\\1.1.0\\variants\\ARDUINO_NANO33BLE/includes.txt" "C:\\Users\\David Prentice\\Documents\\Arduino\\libraries\\Adafruit_GFX_Library\\Adafruit_GFX.cpp" -o "C:\\Users\\DAVIDP~1\\AppData\\Local\\Temp\\arduino_build_679378\\libraries\\Adafruit_GFX_Library\\Adafruit_GFX.cpp.o"
C:\Users\David Prentice\Documents\Arduino\libraries\Adafruit_GFX_Library\Adafruit_SPITFT.cpp: In member function 'void Adafruit_SPITFT::SPI_BEGIN_TRANSACTION()':

C:\Users\David Prentice\Documents\Arduino\libraries\Adafruit_GFX_Library\Adafruit_SPITFT.cpp:1799:21: error: 'arduino::SPIClass {aka class arduino::HardwareSPI}' has no member named 'setClockDivider'


The SPI library on my PC is

"C:\\Users\\David Prentice\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed\\1.1.0\\libraries\\SPI\\SPI.cpp"

Sure enough. This class does not have the regular “Arduino” SPI methods

I suggest that you edit SPITFT.cpp to conditionally avoid those methods e.g.
in Adafruit_SPITFT.cpp add the two “.kbv” lines

inline void Adafruit_SPITFT::SPI_BEGIN_TRANSACTION(void) {
    if(connection == TFT_HARD_SPI) {
#else // No transactions, configure SPI manually...
#if !defined(ARDUINO_ARCH_MBED) //.kbv
 #if defined(__AVR__) || defined(TEENSYDUINO) || defined(ARDUINO_ARCH_STM32F1)
 #elif defined(__arm__)
 #elif defined(ESP8266) || defined(ESP32)
 #elif defined(RASPI) || defined(ARDUINO_ARCH_STM32F1)
#endif //.kbv
#endif // end !SPI_HAS_TRANSACTION

This compiles. I suspect that your hardware will get default values for clock, order, mode, …
Try it.

Then do some studying of the “mbed” SPI code. You will then add some accurate conditional calls in the same style as the conditional ESP8266, RASPI, …

When you have got it working nicely, fork Adafruit_GFX from GitHub. Post a “Pull Request” to GitHub with your solution.

I don’t have your hardware. You can post your “efforts” on this Forum. Another reader can / might help with the “Pull Request”

I suggest that you persevere with your “new hardware”. You will be assisting Adafruit and the rest of the world.

You can try U8g2lib. I suspect that all libraries will have issues until they get feedback from punters like yourself.


It works! Thank you very much!

This is actually my first Arduino project and getting in this deep is daunting but good :slight_smile: What I've found after some digging.

In Adafruit_SPITFT (within the GFX library) the undefined functions are only called from the function we found, SPI_BEGIN_TRANSACTION. No danger of any other undefined functions being called elsewhere.

The mbed version of SPI.h does not include any functions to set mode or frequency like for the other board types. If it's ever required to change these, it's my understanding that these would have to be defined in a settings object as a transaction as described here. https://www.arduino.cc/en/Tutorial/SPITransaction

(This is where I might be getting MHz and Mbps mixed up, I don;t know SPI!)

Adafruit_SPITFT.h includes SPI.h(mbed) which in turn includes SPIMaster.h(mbed). The default SPI settings in SPIMaster are 8-bit, frequency 1Mhz, mode 0.

In Adafruit_SPITFT.h these defaults are overridden for some boards with a default speed of 16Mbps set for everything else. I assume the other board definitions are there due to incompatibility with some of these defaults. This doesn't seem to be the case with the nrf52840, the defaults work though they could probably be tuned to the hardware.

It would appear on first look that the nrf52840 is capable of 32Mbps, I don't know what that means yet but worth posting for someone who might.

In the actual library i was using directly, Adafruit_SSD1331 the frequency is set to 8Mbps in the begin() function. I see no reason to change that for now.

After all that I would guess that there is actually no need to add another condition for mbed to the SPI_BEGIN_TRANSACTION function.

I am seeing some flickering of the display so it may be a case that adjustments would improve that but I don't know what those would be at this stage, perhaps someone who knows the hardware better could contribute. It could also be caused by something else entirely, like the cheap chinese display I'm using :slight_smile:

I will raise an issue and fork the repo for a pull request in due course and link it here. Thanks again.

It looks as if the Nano_BLE supports SPI Transactions.
So you have probably just got to define SPI_HAS_TRANSACTION for your target.


Thanks for tracking this down, looks like a lot of work.

Would a novice be able to make this fix? Seems like you have to modify the Arduino Core API -> SPI.h, and recompile? I don't know how that is done.

No need to change anything yourself other than make sure your board configuration is up to date.

Tools > Board > Boards Manager, change type to Updateable and if you don't have the latest version it will show up there, click Update

Arduino nRF528x Boards (Mbed OS) should be version 1.1.1

p.s. I'm a novice too, there's a good chance that many libraries are not supporting this new architecture yet, it'll might be an uphill struggle for a little while. If you can, keep the library developers up to date by posting github issues.

You are right, update did the trick. Thanks, you guys keep this community alive. Just wish I could get Bluetooth central / client working on the new BLE boards.