I have written a program for an Arduino NANO with a 0.9" display using the SSD1306 Library. To improve the readability of the information on the display, I changed to a 1.3" display using the required SH110X library.
Now I have a problem that there is a limitation to the amount of information that I can display. This was not the case with the 0.9" SSD1306 Library.
As an example, if I add one more character to the program, even if it is a space, certain things will no longer be displayed, especially floating point numbers. If I remove this one single character then it all works perfectly.
It is as though there is a smaller display buffer assigned by the SH110X library than by the SSD1306 library.
As soon as I convert the program back to the SSD1306 version and swap the 1.3" display back to the 0.9", this restriction goes away.
It's a total pain because I have had to absolutely minimalise the information I display so that I can achieve all of the required functionality for the program to carry out it's functions and communicate with the user.
Update:27May2024
This is the Dummy Code set up for the 1.3" SH110X Library:
Go to ******************* Test Variables *****************************
Here I have created a string "Test1" of different lengths. Anything over 25 characters will cause problems in varying degrees with the floating point numbers I am displaying.
I have used the identical code simply converted to the SSD1306 Library for the 0.9" display and this problem does not occur.
// --> Include libraries
#include <Wire.h>
#include <Adafruit_SH110X.h> // ** 1.3" Display **
// #include <Adafruit_SSD1306.h> // ** 0.9" Display **
// --> Defines and constants for peripherals
// 1.3" Display
#define i2c_Address 0x3c //initialize with the I2C addr 0x3C Typically eBay OLED's
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// 0.9" Display
// #define SCREEN_WIDTH 128 // OLED display width, in pixels
// #define SCREEN_HEIGHT 64 // OLED display height, in pixels
// #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
// #define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3C for 128x64, 0x3D for 128x32
// Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// ******************* Test Variables *****************************
String Test1 = "12345678901234567890123456789"; // Not OK!
// String Test1 = "123456789012345678901234567"; // Not OK!
// String Test1 = "12345678901234567890123456"; // Not OK!
// String Test1 = "1234567890123456789012345"; // OK
// Constants
const float LoadR100K = 100000.0;
const float LoadR15K = 14831.0;
const float DCCorr = 1.215;
const float BattVCorr = 1.96;
const float VCorrAC= 1.195;
const float IndCorr = 1.28;
const float GaussZOffset = 9.0;
// General
const String Version = "24May2024 12:00";
float CoilVoltsAC = 1.5;
float IVoltsAC = 3.9;
const float ZeroDB = 2.19;
float RefVoltsF = 1000.0;
// Start screen and Button
const byte IntPin = 3;
const float MinBattery = 8.0;
volatile bool ButtonPressed;
const byte MinMaxSamples = 200;
// Frequency Scan
const float incrementSteps = 157.32;
const float ScreenMaxV = 4.2;
const unsigned int SweepStartFreq = 20;
float StartVAC = 0.1;
float EndVAC = 1.5;
// Resonant Search Measurement
const unsigned int R100K = 5;
float MaxVAC = 3.1;
float ResoF = 12000.0;
// Inductance
const unsigned int IndStartFreq = 20;
float L = 8.6;
const float IMult = 0.707;
const unsigned int R15K = 4;
// Resistance Measurement
float DCResistance = 8000.0;
// Setup: -----------------------------------------------------------------------------
void setup() { // The setup routine runs once when you press reset
// 1.3" Display
display.begin(i2c_Address, true);
display.setTextColor(SH110X_WHITE,SH110X_BLACK);
// 0.9" Display
// display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
// display.setTextColor(WHITE, BLACK); // Draw white text with a black background (instead of transparent) to overwrite previous info
// SSD1306_WHITE ******************* to replace SH110X_WHITE for pixel and line commands
display.clearDisplay();
display.display();
pinMode(IntPin, INPUT_PULLUP); // Set all unused Dig pins to INPUT_PULLUP to prevent noise caused by floating inputs!!!
pinMode(0, INPUT_PULLUP); pinMode(1, INPUT_PULLUP);pinMode(6, INPUT_PULLUP); pinMode(7, INPUT_PULLUP);pinMode(8, INPUT_PULLUP); pinMode(10, INPUT_PULLUP); pinMode(12, INPUT_PULLUP);
pinMode(2, INPUT);
}
// Main routine: -----------------------------------------------------------------------------
void loop() {
StartScreen();
F1();
F2();
F3();
F4();
F5();
F6();
}
void StartScreen(){
display.setCursor(11,0);
display.print("Press O To Proceed");
display.setCursor(13,56);
display.print("R:" + Version);
display.display();
attachInterrupt(digitalPinToInterrupt(IntPin),ISR_Button,LOW);// Interrupt Vector for pin 3 = 1
while (ButtonPressed != true){BatteryTest();} // Allows battery test to run without delaying the button press as the interrupt will respond instantaneously regardless of battery test.
ButtonPressed = false;
Button(); // Wait to go to next function
}
void BatteryTest(){
display.setTextSize(2);
float BatteryV = (analogRead(A3) * (5.0 / 1023)*BattVCorr);
if (BatteryV <= MinBattery) { // Battery too low
display.setCursor(18,24);
display.print(" "); // Print nothing to create a flashing function
display.display();
delay(150);
display.setCursor(18,24);
display.print("Bat=" + String(BatteryV,1) + "V ");
display.display();
delay(150);
} else {
display.setCursor(18,24);
display.print("Bat=" + String(BatteryV,1) + "V ");
display.display();
}
}
void Button(){
while (digitalRead(3) == HIGH){} // Waiting for button to be pressed
display.clearDisplay(); // Erase previous screen
display.setTextSize(1);
display.setCursor(5,0);
display.print ("Release O To Proceed");
display.display();
while (digitalRead(3) == LOW){} // Waiting for button to be released
display.clearDisplay(); // Clear display ready for next function
display.display(); // Clear screen for next function
}
void ISR_Button(){ // Interrupt routine for the button
ButtonPressed=true;
detachInterrupt(digitalPinToInterrupt(IntPin));// Interrupt Vector for pin 3 = 1;
}
void F1(){
display.setTextSize(2);
display.setCursor(24,12);
display.print("GETTING");
display.setCursor(24,32);
display.print(" STUFF ");
display.display();
display.setTextSize(1);
display.setCursor(11,0);
display.print("Press O To Proceed");
display.display();
Button();
display.setTextSize(1);
display.clearDisplay();
display.display();
}
void F2(){
float SweepFreq = SweepStartFreq;
byte xAxis = 1;
display.drawLine(0,((ScreenMaxV-ZeroDB)*15), 128, ((ScreenMaxV-ZeroDB)*15),SH110X_WHITE); // 0 db line
display.setCursor(46,(((ScreenMaxV-ZeroDB)*15)-4));
display.print(" 0dBu ");
display.display();
while (xAxis < 129){
display.setCursor(32,0);
display.print("F = " + String(SweepFreq,0) + "Hz");
display.drawPixel(xAxis, (((ScreenMaxV-CoilVoltsAC)*15)), SH110X_WHITE);
display.display();
SweepFreq = SweepFreq + incrementSteps;
xAxis ++;
}
display.setCursor(11,0);
display.print("Press O To Proceed");
display.display();
Button();
}
void F3(){
float SweepFreq = ResoF - 1000.0; // ResoF taken from Frequency sweep function
display.setCursor(34,0);
display.print("RESONANT F");
display.display();
display.setCursor(12,40);
display.setTextSize(2);
display.print("F=" + String(SweepFreq,0) + "Hz ");
display.display();
display.setTextSize(1);
display.setCursor(11,0);
display.print("Press O To Proceed");
display.display();
Button();
display.setCursor(2,20);
display.setTextSize(1);
display.print("Resonant F = " + String((ResoF/1000),1) + "kHz ");
display.setCursor(11,0);
display.print("Press O To Proceed");
display.display();
Button();
display.setTextSize(1);
display.clearDisplay();
display.display();
}
// ******************** Inductance Test **********************************
void F4(){
float TVoltsAC = CoilVoltsAC*IMult;
float IndFreq = ResoF;
display.setTextSize(1);
display.setCursor(34,0);
display.print("INDUCTANCE");
display.display();
display.setTextSize(1);
display.setCursor(11,8);
display.print("Press O To Proceed");
display.display();
Button();
display.setTextSize(1);
display.setCursor(16,20);
display.print("Test F = " + String(IndFreq,0) + " Hz ");
display.setTextSize(2);
display.setCursor(6,40);
display.print("Diff " + String(CoilVoltsAC - TVoltsAC)); // Remaining difference
display.display();
display.setTextSize(1);
display.setCursor(11,0);
display.print("Press O To Proceed");
display.display();
Button();
display.setTextSize(1);
display.clearDisplay();
display.display();
}
void F5(){ // Results
float Cp = 100.0/((sq(0.0628*ResoF))*L);
display.setCursor(0,0);
display.println("RESULTS: Press O To >");
display.println("R = " + String((DCResistance/1000),1) + " kR");
display.println("L = " + String(L,1) + " H");
display.println("Res. F = " + String(ResoF,1) + " kHz");
display.println("Cp = " + String(Cp,0) + " pF");
display.println("Max = " + String(8.68*(log(MaxVAC/ZeroDB)),2) + " dBu"); // 8.68 converts the natural log to Log10
display.println("Span = " + String(8.68*(log(MaxVAC/StartVAC)),1) + " dB");
display.print("20kHz = " + String(8.68*(log(EndVAC/ZeroDB)),1) + " dBu");
display.display();
Button();
}
void F6(){
ReGauss:
float Gauss = -248.0;
String stringNS = "N";
float RawGauss = -248.0;
display.setTextSize(2);
display.setCursor(34,12);
display.print("Gauss");
display.setCursor(42,32);
display.print(String(Gauss,0) + " ");
display.setTextSize(2);
display.setCursor(54,50);
display.print(stringNS);
display.display();
display.setTextSize(1);
display.setCursor(11,0);
display.print("Press O To Proceed");
display.display();
Button();
goto ReGauss;
}