• Skip to main content
  • Skip to primary sidebar

RNTLab.com

The Ultimate Shortcut to Learn Electronics and Programming with Open Source Hardware and Software

  • Courses
  • Forum
    • Forum
    • Ask Question
  • Shop
  • Account
  • Blog
  • Login

OLED SH1106 with ESP32 devkit

Q&A Forum › Category: Questions › OLED SH1106 with ESP32 devkit
0 Vote Up Vote Down
Kees_01 asked 4 years ago

Is there an example of how to use an 0.96″ SH1106 OLED with the ESP32 devkit which needs the library Adafruit_SH1106-master?
I have bought one in the past and gave it a try with your example ESP32 + OLED where a SSD1306 is used. It is
“An example for our Monochrome OLEDs based on SSD1306 drivers” at https://randomnerdtutorials.com/esp32-ssd1306-oled-display-arduino-ide/ with the RAW sketch posted at
https://raw.githubusercontent.com/RuiSantosdotme/Random-Nerd-Tutorials/master/Projects/OLED/oled_adafruit_demo.ino
When I use this oled_adafruit_demo.ino file unmodified then after uploading, the OLED has the same picture as shown in
the forum threat https://rntlab.com/question/about-1-3-oledssh1106/
In that forum threat the textline above the video says “However, 0.96 “OLED works well, but 1.3” OLED operation is strange.” It is not clear to me which 0.96 OLED was working well. Probably he was meaning a SSD1306 OLED.
When I use the ‘SH1106’OLED with an Arduino Nano everything is working well, but with an ESP32 it does not work at once of course.
I say of course, because in the above mentioned example there is the use  of the Adafruit_SSD1306 library instead. And that does not match one to one.
Also the SH1106 library is using other libraries/references. When I compile the ESP32 sketch replacing <Adafruit_SSD1306.h> by <Adafruit_SH1106-master> then
a failure is popping up during compilation -> Adafruit_SH1106.cpp:29:26: fatal error: avr/pgmspace.h: No such file or directory.
I think this can happen because now in ArduinoIDE/Tools/Board, the DOIT ESP32 DEV kit V1 is chosen and not the avr/Nano board.
I can imagine that both boards have there own path.
With the probability that other subdirectories for the DOIT ESP32 DEV kit V1 are chosen now which do not contain avr/pgmspace.h.
So in the ESP32 sketch I changed the path avr/ (default) by a full path which contains pgmspace.h.
That solved the compiler error message, but that was apparently not enough. Another error message popped up now. I mean it a snowball effect.
Finally after modifying all reqested paths in files concerned by the compiler, the compiler now came with more complicated error messages. So I gave it up.
The Adafruit SH1106 has a few less possibilities w.r.t. the SSD1306. For me it’s acceptable.
So I hope you may help me a bit further.

Question Tags: ESP32 DEVkit OLED SH1106
9 Answers
0 Vote Up Vote Down
Steve Mercer answered 4 years ago

Which library did you download and did you follow the install instructions (Including the Adafruit GFX Library)? – https://github.com/davidperrenoud/Adafruit_SH1106

 

Note that there are examples there as well.

0 Vote Up Vote Down
Sara Santos Staff answered 4 years ago

Did you try this library?
https://github.com/wonho-maker/Adafruit_SH1106
And the examples?

0 Vote Up Vote Down
Steve Mercer answered 4 years ago

The link I posted appears to be the official Adafruit library.

0 Vote Up Vote Down
Kees_01 answered 4 years ago

I have tried both, https://github.com/wonho-maker/Adafruit_SH1106 as well as https://github.com/davidperrenoud/Adafruit_SH1106 but  without success (also tried the 4 examples). avr/pgmspace.h is also popping up again during compilation etc. It seems to me that’s not going to work in this way. Sorry about that.
As said, with Arduino IDE I can select between two boards installed, the Nano and the ESP32 Devkit.
If I use the Nano I can run the File/Example/Adafruit SH1106/SH1106_128x64_I2C correct.
Unfortunately, I didn’t succeed after modifying the sketch https://raw.githubusercontent.com/RuiSantosdotme/Random-Nerd-Tutorials/master/Projects/OLED/oled_adafruit_demo.ino.
When I have installed one of the Adafruit libraries with: Sketch/Use library/Add .ZIP library then when I open Manage library, I may expect that when I type SH1106 in the search field that the SH1106 library should be visible. That was not the case. A similar case as with installing the ESP32 devkit. But maybe I’ll get two things mixed up. 
Moreover the ESP32 Devkit is installed according the instructions for Windows successfully. Using the ESP32 as webserver works perfectly.
Now I am looking for a very simple sketch (for example to draw only a rectangle on the SH1106 OLED) when I have selected the ESP32 Devkit. 
 

0 Vote Up Vote Down
Sara Santos Staff answered 4 years ago

There is also this library: https://github.com/olikraus/u8g2
That is compatible with the SH1106.
It seems that you may have some library conflicts. Check that you only have one Arduino installation in your computer.
If things get too messed up, maybe it would be better to start with a fresh install.
Regards,
Sara

0 Vote Up Vote Down
Kees_01 answered 4 years ago

Hi Sara,
Thank you so much for the U8g2 library-link. It is a universal library for a lot of display types.
All supported OLED display types are mentioned in the example sketches which you can try.
All you have to do is uncomment the line which corresponds to your display.
On your advice I have checked if I had more than one Arduino IDE installed. That was not the case.
It is installed in C:/program Files (x86)/Arduino with the very basic default libraries.
There is more than one location where libraries are installed as it turned out.
When I install the Adafruit_GFX library and the SSD1306 library, using the library tool of Arduino IDE, then they are placed in
C:/Users/Kees_01/Documents/Arduino/libraries, one level lower than the sketches.
But now it comes, when I install the DOIT ESP32 DEV kit V1 in Arduino IDE, then this board stuff is placed in a new created location:
C:/Users/Kees_01/AppData/Local/Arduino15.
And in C:/Users/Kees_01/AppData/Local/Arduino15/staging/libraries I find also a Adafruit_GFX-1.10.zip library and a SSD1306-2.4.3.zip library.
Admittedly not under the same name, but the content of both files are exactly the same as those in C:/Users/Kees_01/Documents/Arduino/libraries
And that can be a bit confusing.
But I have tried several example sketches which are included in U8g2 and they all worked very well with my SH1106 OLED. So I am happy with that.
However when I use one of your OLED projects which are written for the SSD1306 OLED,
I have to rewrite all relevant code in your sketch, assumed I could manage that (no experience at all),
to make it suitable for the SH1106 with the U8g2 library.
Or there should be some mechanism that converts SSD1306 code into u8g2 code. I am afraid not.
If the impact is not too big for your (already) published projects then it may be worth to write them always with the universal U8g2 library.
On the other hand a SSD1306 based OLED is a low cost one now, I admit.

0 Vote Up Vote Down
Sara Santos Staff answered 4 years ago

Hi
I think you have to rewrite all the parts that use the OLED.
The SSD1306 is the most widely used OLED display. That’s why we have all projects using the SSD1306 library.
At the moment, we don’t plan to modify our existing projects with the U8g2 library.
Maybe we can build a tutorial for that library… but I don’t know when.. 
Regards,
Sara

0 Vote Up Vote Down
Bielo Lopez Lauber answered 1 year ago

 

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/
/**********
  Código adecuado para SH1106 por Bielo López
**********/

#include <Arduino.h>
#include <U8g2lib.h>
#include “BLEDevice.h”
#include <Adafruit_GFX.h>
#include <Arduino.h>
#include <SPI.h>
#include <Wire.h>

#define clock 22
#define data 21
#define reset 4

/////////////////////////////////////////////////////////////////////////
//BLE Server name (the other ESP32 name running the server sketch)
#define bleServerName “ESP32_DHT”

//UUID’s of the service, characteristic that we want to read
static BLEUUID dhtServiceUUID(BLEUUID((uint16_t)0x181A));

//Temperature Characteristic
static BLEUUID temperatureCharacteristicUUID((uint16_t)0x2A6E);

//Humidity Characteristic
static BLEUUID humidityCharacteristicUUID((uint16_t)0x2A6F);

//Flags stating if should begin connecting and if the connection is up
static boolean doConnect = false;
static boolean connected = false;

//Address of the peripheral device. Address will be found during scanning..
static BLEAddress *pServerAddress;
 
//Characteristic that we want to read and characteristic that we want to write.
static BLERemoteCharacteristic* temperatureCharacteristic;
static BLERemoteCharacteristic* humidityCharacteristic;

//Activate notify
const uint8_t notificationOn[] = {0x1, 0x0};
const uint8_t notificationOff[] = {0x0, 0x0};
/////////////////////////////////////////////////////////

U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE);

///////////////////////////////////////////////////////////////
//Variables to store temperature and humidity
#define MAX_STRING_LENGTH 10
char temperatureR[MAX_STRING_LENGTH];
char humidityR[MAX_STRING_LENGTH];

//Flags to check whether new temperature and humidity readings are available
boolean newTemperatureR = false;
boolean newHumidityR = false;

//Connect to the BLE Server that has the name, Service, and Characteristics
bool connectToServer(BLEAddress pAddress) {
   BLEClient* pClient = BLEDevice::createClient();
 
  // Connect to the remove BLE Server.
  pClient->connect(pAddress);
  Serial.println(” – Connected to server”);
 
  // Obtain a reference to the service we are after in the remote BLE server.
  BLERemoteService* pRemoteService = pClient->getService(dhtServiceUUID);
  if (pRemoteService == nullptr) {
    Serial.print(“Failed to find our service UUID: “);
    Serial.println(dhtServiceUUID.toString().c_str());
    return (false);
  }
 
  // Obtain a reference to the characteristics in the service of the remote BLE server.
  temperatureCharacteristic = pRemoteService->getCharacteristic(temperatureCharacteristicUUID);
  humidityCharacteristic = pRemoteService->getCharacteristic(humidityCharacteristicUUID);

  if (temperatureCharacteristic == nullptr || humidityCharacteristic == nullptr) {
    Serial.print(“Failed to find our characteristic UUID”);
    return false;
  }
  Serial.println(” – Found our characteristics”);
 
  //Assign callback functions for the Characteristics
  temperatureCharacteristic->registerForNotify(temperatureNotifyCallback);
  humidityCharacteristic->registerForNotify(humidityNotifyCallback);
  return true;
}

//Callback function that gets called, when another device’s advertisement has been received
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
  void onResult(BLEAdvertisedDevice advertisedDevice) {
    if (advertisedDevice.getName() == bleServerName) { //Check if the name of the advertiser matches
      advertisedDevice.getScan()->stop(); //Scan can be stopped, we found what we are looking for
      pServerAddress = new BLEAddress(advertisedDevice.getAddress()); //Address of advertiser is the one we need
      doConnect = true; //Set indicator, stating that we are ready to connect
      Serial.println(“Device found. Connecting!”);
    }
  }
};
 
//When the BLE Server sends a new temperature reading with the notify property
static void temperatureNotifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic,
                                      uint8_t* pData, size_t length, bool isNotify) {
  // Reinterpret the received data as a uint16_t value
  uint16_t temperatureValue = *(uint16_t*)pData;
  // Convert the temperature value to a string for u8x8
  snprintf(temperatureR, MAX_STRING_LENGTH, “%d”, temperatureValue);
  newTemperatureR = true;
}

//When the BLE Server sends a new humidity reading with the notify property
static void humidityNotifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic,
                                   uint8_t* pData, size_t length, bool isNotify) {
  // Reinterpret the received data as a uint16_t value
  uint16_t humidityValue = *(uint16_t*)pData;
  // Convert the humidity value to a string for u8x8
  snprintf(humidityR, MAX_STRING_LENGTH, “%d”, humidityValue);
  newHumidityR = true;
}
/////////////////////////////////////////////////////////////////////
void init_affich()
{
  Serial.println(F(“début init_affich”));
 // u8x8.setI2CAddress(0x3C); // set I2C adress
  u8x8.begin();
  u8x8.setPowerSave(0);
  delay(100);
  u8x8.setFont(u8x8_font_chroma48medium8_r);
 
   u8x8.print(”      Clima”);
    u8x8.refreshDisplay();
    delay(3000);
 
    Serial.println(F(“fin init_affich”));
 
}

void setup()
{
  //Serial.begin(115200); //init impression par USB

  //OLED u8x8 setup
  // SSD1306_SWITCHCAPVCC = generate u8x8 voltage from 3.3V internally
  //if(!u8x8.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128×32
  //  Serial.println(F(“SSD1306 allocation failed”));
  //  for(;;); // Don’t proceed, loop forever
  //}
  init_affich();
   //Start serial communication
  Serial.begin(115200);
  Serial.println(“Starting Arduino BLE Client application…”);

  //Init BLE device
  BLEDevice::init(“”);
 
  // Retrieve a Scanner and set the callback we want to use to be informed when we
  // have detected a new device.  Specify that we want active scanning and start the
  // scan to run for 30 seconds.
  BLEScan* pBLEScan = BLEDevice::getScan();
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setActiveScan(true);
  pBLEScan->start(30);

}

//function that prints the latest sensor readings in the OLED u8x8
void printDHTReadings(){

 
 
  //u8x8 temperature
  u8x8.setCursor(0, 0);
  u8x8.drawString(0, 1, “Temperatura”);
  u8x8.draw1x2String(2,2,temperatureR);
  u8x8.draw1x2String(5,2,”°C”);

  u8x8.drawString(0,4, “Humedad”);
  u8x8.draw1x2String(2,5,humidityR);
  u8x8.draw1x2String(5,5,”hPa”);

}
void loop() {
  // If the flag “doConnect” is true then we have scanned for and found the desired
  // BLE Server with which we wish to connect.  Now we connect to it.  Once we are
  // connected we set the connected flag to be true.
  if (doConnect == true) {
    if (connectToServer(*pServerAddress)) {
      Serial.println(“We are now connected to the BLE Server.”);
      //Activate the Notify property of each Characteristic
      temperatureCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)notificationOn, 2, true);
      humidityCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)notificationOn, 2, true);
      connected = true;
    } else {
      Serial.println(“We have failed to connect to the server; Restart your device to scan for nearby BLE server again.”);
    }
    doConnect = false;
  }
  //if new temperature readings are available, print in the OLED
  if (newTemperatureR && newHumidityR){
    newTemperatureR = false;
    newHumidityR = false;
    printDHTReadings();
  }
  delay(1000); // Delay a second between loops.
}

0 Vote Up Vote Down
Sara Santos Staff answered 1 year ago

Hi.
Thank you so much for sharing.
Regards,
Sara

Primary Sidebar

Login to Ask or Answer Questions

This Forum is private and it’s only available for members enrolled in our Courses.

Login »

Latest Course Updates

  • [New Edition] Build ESP32-CAM Projects eBook – 2nd Edition April 16, 2025
  • [eBook Updated] Learn ESP32 with Arduino IDE eBook – Version 3.2 April 16, 2025

You must be logged in to view this content.

Contact Support - Refunds - Privacy - Terms - MakerAdvisor.com - Member Login

Copyright © 2013-2025 · RandomNerdTutorials.com · All Rights Reserved

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.