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.
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.
Did you try this library?
https://github.com/wonho-maker/Adafruit_SH1106
And the examples?
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.
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
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.
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
/*********
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.
}