Hi Arduino Community,
I'm working on a project with an Arduino Nano and am facing issues related to memory usage and display output. My code currently manages an oled display, handles button inputs, and controls actuators. However, I'm running into memory limitations with the Nano, and the menu display isn’t working as expected. I dont know what to do, please help - its my master thesis project ![]()
#include <splash.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <Wire.h> // I2C für RTC
#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)
/* nett am Rande: Mein Display hat die Adresse 0x3C _UND_ 64 Zeilen... */
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
// Pins für drei Buttons
#define BUTTON_LEFT 10
#define BUTTON_MIDDLE 9
#define BUTTON_RIGHT 8
// Pins für Aktuatoren
#define H2VALVE 2
#define O2VALVE 3
#define MOTOR 4
// Display-Objekt
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const uint8_t itemCount = 5; // Anzahl der Menü-Einträge
const uint8_t numShowing = 5; // Anzahl gleichzeitig angezeigter Einträge
uint8_t firstShown = 1; // oberster angezeigter Eintrag
uint8_t selectedItem = 1;// aktiver Eintrag
// Beschriftung, aus ästhetischen Gründen ein Dummyeintrag auf Position 0
String menuItems[itemCount+1] = {
"",
"temperature ",
"pressure ",
"voltage ",
"current ",
"power ",
};
bool showMenu = true; // true, wenn das Menü angezeigt wird
String title = "fc-control";
/* actuator states */
bool h2open = false;
bool o2open = false;
bool motor_running = false;
/*
--------------------------------------------------------------------------------------------------------
setup
--------------------------------------------------------------------------------------------------------
*/
void setup() {
Serial.begin(9600); // backup, nicht essentiell
pinMode(BUTTON_LEFT, INPUT_PULLUP);
pinMode(BUTTON_MIDDLE, INPUT_PULLUP);
pinMode(BUTTON_RIGHT, INPUT_PULLUP);
pinMode(H2VALVE, OUTPUT);
pinMode(O2VALVE, OUTPUT);
pinMode(MOTOR, OUTPUT);
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
display.setTextColor(SSD1306_WHITE, SSD1306_BLACK); // Draw white text
initializeDevice(); // init-Prozedur der Brennstoffzelle starten
}
/* Hilfsfunktion: Zeigt Text und einen Countdown an */
void showCountdown(String text, int dt) {
for (uint16_t i=dt; i>0; i--) {
makeTitle();
display.println(text + "\n");
display.print(String(i) + "s");
display.display();
delay(1000);
}
}
void makeTitle() {
display.setTextSize(2);
display.clearDisplay();
display.setCursor(0,0);
display.println(title);
display.setTextSize(1);
}
/* init-Prozedur der Brennstoffzelle */
void initializeDevice() {
makeTitle();
display.println("\nphase 1:\nconnect to cell");
display.display();
delay(2000);
digitalWrite(H2VALVE, HIGH);
showCountdown("\nphase 2:\nflushing H2", 10);
digitalWrite(H2VALVE, LOW);
digitalWrite(O2VALVE, HIGH);
showCountdown("\nphase 3:\nflushing O2", 5);
digitalWrite(O2VALVE, LOW);
digitalWrite(MOTOR, HIGH);
showCountdown("\nphase 4:\nmotor check", 2);
digitalWrite(MOTOR, LOW);
}
void updateActuators() {
digitalWrite(H2VALVE, (h2open?HIGH:LOW));
digitalWrite(O2VALVE, (o2open?HIGH:LOW));
digitalWrite(MOTOR, (motor_running?HIGH:LOW));
}
/* Prozedur für die Anzeige nach der Initialisierung */
void updateDisplay() {
/* Überschrift */
makeTitle();
display.println();
if (showMenu) {
/* Menü anzeigen */
for (uint8_t i=firstShown; i<=itemCount && i - firstShown < numShowing; i++) {
if (i == selectedItem) display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Draw white text
display.println((i<10?" ":" ") + String(i) + " " + menuItems[i]);
display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
}
} else {
String output;
/* Details für aktiven Menüeintrag anzeigen */
display.println("\n" + menuItems[selectedItem] + "\n");
display.setTextSize(2);
switch(selectedItem) {
case 1 : display.print("24.8 ");
display.print(char(247));
display.println("C");
break;
case 2 : display.println("1039 hPa");
break;
case 3 : display.println(String(5.0 * analogRead(A0) / 1023, 2) + " V");
break;
case 4 : display.println(String(5.0 * analogRead(A0) / 255, 2) + " mA");
break;
case 5 : display.println(String(50.0 * analogRead(A0) / 1023, 2) + " mW");
break;
}
}
display.display();
}
/*
--------------------------------------------------------------------------------------------------------
loop
--------------------------------------------------------------------------------------------------------
*/
void loop() {
/* "up"-Button */
if (showMenu && !digitalRead(BUTTON_LEFT)) {
delay(50);
selectedItem = --selectedItem;
if (selectedItem < 1) selectedItem = 1;
while (selectedItem < firstShown) firstShown--;
}
/* "down"-Button */
if (showMenu && !digitalRead(BUTTON_MIDDLE)) {
delay(50);
selectedItem = ++selectedItem;
if (selectedItem > itemCount) selectedItem = itemCount;
while (selectedItem > firstShown + numShowing - 1) firstShown++;
}
/* Detailanzeige ein- und abschalten */
if (!digitalRead(BUTTON_RIGHT)) {
delay(50);
switch (selectedItem) {
// 1-5 sind Anzeigen
case 1:
case 2:
case 3:
case 4:
case 5: showMenu = !showMenu;
break;
}
}
updateActuators();
updateDisplay();
delay(50);
}