Trying to get my menu systems updating the screen as new data arrives *HELP*

I'm working on building a menu system that allows me to view in real time my sensor output.
right now I only have the Data and Time that I'm focusing on right now. once I get the correct output on this menu item I can add it to the other items.

here is the current code, Menu_6 is for focus point right now:

#include <Arduino.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>
#include <Adafruit_I2CDevice.h>
#include <RTClib.h>
#include <SD.h>
File root;
RTC_PCF8523 rtc;

// 32u4, M0, M4, nrf52840 and 328p
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32

//MENU
#define BUTTON_UP 9
#define BUTTON_DOWN 6
#define BUTTON_SELECT 5
int menuitem = 1;
int page = 1;
int downButtonState = 0;
int upButtonState = 0;
int selectButtonState = 0;
int lastDownButtonState = 0;
int lastSelectButtonState = 0;
int lastUpButtonState = 0;
volatile boolean up = false; // Up Button
volatile boolean down = false; // Down Button
volatile boolean middle = false; // Select Button

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

Adafruit_SH110X display = Adafruit_SH110X(64, 128, &Wire);

//Other Pins
int currentVal = 0;
int voltVal = 0;
int freqVal = 0;
int userVal1 = 0;
int powVal = 11;
bool Warning = 0;
bool Fault01 = 0;
bool Fault02 = 0;
int ledGRN = 0;
int ledRED = 0;
int dispDelay = 2750;

void dateandtime() {
DateTime now = rtc.now();

Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(" (");
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(") ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
// delay(1000);
}

void Menu_1() {
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SH110X_WHITE); // Draw white text
display.setCursor(0,0);
display.println(F("TECNIX Upepo Umeme"));
display.println(F("<< Power Mon 1/6 >>"));
display.print(voltVal);
display.println(" Volts -Vbat");
display.print(currentVal);
display.print(" Amps -Abat");
display.display();
display.clearDisplay();
}
void Menu_2() {
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SH110X_WHITE); // Draw white text
display.setCursor(0,0);
display.println(F("TECNIX Upepo Umeme"));
display.println(F("<< Power Mon 2/6 >>"));
display.print(freqVal);
display.println(" Hz -freq");
display.print(powVal);
display.print(" Watts -Pturb");
display.display();
display.clearDisplay();

}
void Menu_3() {
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SH110X_WHITE); // Draw white text
display.setCursor(0,0);
display.println(F("TECNIX Upepo Umeme"));
display.println(F("<< Power Mon 3/6 >>"));
display.print(freqVal);
display.println(" kWH -now");
display.print(powVal);
display.print(" kWH -total");
display.display();
// delay(dispDelay);
display.clearDisplay();

}
void Menu_4() {
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SH110X_WHITE); // Draw white text
display.setCursor(0,0);
display.println(F("TECNIX Upepo Umeme"));
display.println(F("<< System Info 4/6 >>"));
display.println("Turb Ser #0000");
display.println("firmware V0.10");
display.display();
display.clearDisplay();

}
void Menu_5() {
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SH110X_WHITE); // Draw white text
display.setCursor(0,0);
display.println("TECNIX Upepo Umeme");
display.println("<< Settings 5/6 >>");
display.println("<< Tech Menu");
display.println(" Eng/Swah Lang >>");
display.display();
display.clearDisplay();

}
void Menu_6() {
dateandtime();
DateTime now = rtc.now();
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SH110X_WHITE); // Draw white text
display.setCursor(0,0);
display.println("TECNIX Upepo Umeme");
display.print(now.year(), DEC);
display.print('/');
display.print(now.month(), DEC);
display.print('/');
display.print(now.day(), DEC);
display.print(" (");
display.print(daysOfTheWeek[now.dayOfTheWeek()]);
display.println(") ");
display.print(now.hour(), DEC);
display.print(':');
display.print(now.minute(), DEC);
display.print(':');
display.print(now.second(), DEC);
display.println();;
display.display();
display.clearDisplay();
while (digitalRead(selectButtonState) == LOW) {
Menu_6();
}

}

void menubuttons() {
if (up && page == 1 ) {
up = false;
menuitem--;
if (menuitem==0) {
menuitem=6;
}
} else if (up && page == 2 ) {
up = false;
}

if (down && page == 1) {
down = false;
menuitem++;
if (menuitem==7)
{
menuitem=0;
}
}else if (down && page == 2 ) {
down = false;
}

if (middle) {
middle = false;
if(page == 1 && menuitem ==1) {
if (menuitem==0) {
middle = false;
}
else {
middle = true;
Menu_1();
}
}
middle = false;
if(page == 1 && menuitem ==2) {
if (menuitem==1) {
middle = false;
}
else {
middle = true;
Menu_2();
}
}
middle = false;
if(page == 1 && menuitem ==3) {
if (menuitem==2) {
middle = false;
}
else {
middle = true;
Menu_3();
}
}
middle = false;
if(page == 1 && menuitem ==4) {
if (menuitem==3) {
middle = false;
}
else {
middle = true;
Menu_4();
}
}
middle = false;
if(page == 1 && menuitem ==5) {
if (menuitem==4) {
middle = false;
}
else {
middle = true;
Menu_5();
}
}
middle = false;
if(page == 1 && menuitem ==6) {
if (menuitem==5) {
middle = false;
}
else {
middle = true;
Menu_6();
}
middle = false;
}
if(page == 1 && menuitem ==7) {
if (menuitem==6) {
middle = false;
}
else {
middle = true;
}
middle = false;
}
else if (page == 1 && menuitem>=1) {
page=2;
}
else if (page == 2) {
page=1;
}
}
}

void checkIfDownButtonIsPressed() {
if (downButtonState != lastDownButtonState) {
if (downButtonState == 0) {
down=true;
}
delay(50);
}
lastDownButtonState = downButtonState;
}
void checkIfUpButtonIsPressed() {
if (upButtonState != lastUpButtonState) {
if (upButtonState == 0) {
up=true;
}
delay(50);
}
lastUpButtonState = upButtonState;
}
void checkIfSelectButtonIsPressed() {
if (selectButtonState != lastSelectButtonState)
{
if (selectButtonState == 0) {
middle=true;
}
delay(50);
}
lastSelectButtonState = selectButtonState;
}
void drawMenu() {
if (page==1) {
display.setTextSize(1);

if (menuitem==1) {
  display.setTextColor(SH110X_WHITE, SH110X_BLACK);
}
else {
  display.setTextColor(SH110X_BLACK, SH110X_WHITE);
}
display.setCursor(0, 5);
display.print("Menu 1");
display.setTextColor(SH110X_BLACK);
display.print(" ");
display.display();


if (menuitem==2) {
  display.setTextColor(SH110X_WHITE, SH110X_BLACK);
}
else {
  display.setTextColor(SH110X_BLACK, SH110X_WHITE);
}
display.print("Menu 2");
display.setTextColor(SH110X_BLACK);
display.print(" ");
display.display();

if (menuitem==3) {
  display.setTextColor(SH110X_WHITE, SH110X_BLACK);
}
else {
  display.setTextColor(SH110X_BLACK, SH110X_WHITE);
}
display.print("Menu 3");
display.display();

if (menuitem==4) {
  display.setTextColor(SH110X_WHITE, SH110X_BLACK);
}
else {
  display.setTextColor(SH110X_BLACK, SH110X_WHITE);
}
  display.setCursor(0, 25);
  display.print("Menu 4");
  display.setTextColor(SH110X_BLACK);
  display.print(" ");
  display.display();

if (menuitem==5) {
  display.setTextColor(SH110X_WHITE, SH110X_BLACK);
}
else {
  display.setTextColor(SH110X_BLACK, SH110X_WHITE);
}
display.print("Menu 5");
display.setTextColor(SH110X_BLACK);
display.print(" ");
display.display();

if (menuitem==6) {
  display.setTextColor(SH110X_WHITE, SH110X_BLACK);
}
else {
  display.setTextColor(SH110X_BLACK, SH110X_WHITE);
}
display.print("Clock ");
display.display();

}

}
void pinouts() {
voltVal = analogRead(A1);
currentVal = analogRead(A2);
freqVal = analogRead(A3);
userVal1 = analogRead(A4);
Fault01 = digitalRead(0);
}

void setup() {
Serial.begin (9600);
// Serial.begin(57600);
display.begin(0x3C, true); //display info
// display.begin(SH110X_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.display();
display.setRotation(1);
pinMode(BUTTON_UP, INPUT_PULLUP);
pinMode(BUTTON_DOWN, INPUT_PULLUP);
pinMode(BUTTON_SELECT, INPUT_PULLUP);
rtc.begin();
delay(1000);

}

void loop() {
pinouts();
drawMenu();

upButtonState = digitalRead(9);
downButtonState = digitalRead(6);
selectButtonState = digitalRead(5);

checkIfSelectButtonIsPressed();
checkIfDownButtonIsPressed();
checkIfUpButtonIsPressed();

menubuttons();

}

This is dubious:

while (digitalRead(selectButtonState) == LOW) {
Menu_6();

If that read does return LOW you will probably crash your system with recursive calls to Menu_6. Also, selectButtonState doesn't hold the pin number you want I suspect.

It is also very odd that all your menu functions go to so much trouble writing to the display and then you immediately erase it

void Menu_5() {
  display.clearDisplay();
  ...
  display.display();
  display.clearDisplay();
}

You would be much better served with more of a state machine approach

You are also reading the Rx pin????

  Fault01 = digitalRead(0);

I’m using the Adafruit M0 Wifi board. I don’t think there is an RX pin on it. Just GPIO 9, 6, and 5 are used on the screen as buttons.

The main setup is Adafruit M0 WiFi, Feather Adalogger, and FeatherWing OLED - 128x64 OLED.

I never thought about doing class and state. Only been coding in C++ and Arduino for a little over a week.

Fair enough. It is good to start out small and concise when learning something new. If you do stick with it, you will find that the idea of a state machine or finite-state-machine will come up again and again in microcontroller projects so it is a good idea to learn and understand. Also, how to to many things at the same time several things at the same time

consider a table driven approach (see bottom)

#undef MyHW
#ifdef MyHW

# include "SPI.h"
# include "Wire.h"
# include "Adafruit_GFX.h"
# include "Adafruit_SH110X.h"
# include "Adafruit_I2CDevice.h"
# include "RTClib.h"
# include "SD.h"

#undef  F
#define F(x)    (x)

byte butPins [] = { A1, A2, A3 };
# define N_BUT   sizeof(butPins)
byte butState [N_BUT];

#else   // ------------------------------------------------
# include <SPI.h>
# include <Wire.h>
# include <Adafruit_GFX.h>
# include <Adafruit_SH110X.h>
# include <Adafruit_I2CDevice.h>
# include <RTClib.h>
# include <SD.h>

byte butPins [] = { 9, 6, 5 };
# define N_BUT   sizeof(butPins)
byte butState [N_BUT];
#endif


 // File root;
RTC_PCF8523 rtc;
// 32u4, M0, M4, nrf52840 and 328p
#define SCREEN_WIDTH   128  // OLED display width, in pixels
#define SCREEN_HEIGHT  64   // OLED display height, in pixels
#define OLED_RESET     4    // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

Adafruit_SH110X display = Adafruit_SH110X(64, 128, &Wire);

//Other Pins
int currentVal = 0;
int voltVal = 0;
int freqVal = 0;
int userVal1 = 0;
int powVal = 11;
bool Warning = 0;
bool Fault01 = 0;
bool Fault02 = 0;
int ledGRN = 0;
int ledRED = 0;
int dispDelay = 2750;

// -----------------------------------------------------------------------------
void dateandtime() {
    DateTime now = rtc.now();
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
    // delay(1000);
}
void Menu_1() {
    display.clearDisplay();
    display.setTextSize(1); // Normal 1:1 pixel scale
    display.setTextColor(SH110X_WHITE); // Draw white text
    display.setCursor(0,0);
    display.println(F("TECNIX Upepo Umeme"));
    display.println(F("<< Power Mon 1/6 >>"));
    display.print(voltVal);
    display.println(" Volts -Vbat");
    display.print(currentVal);
    display.print(" Amps -Abat");
    display.display();
    display.clearDisplay();
}
void Menu_2() {
    display.clearDisplay();
    display.setTextSize(1); // Normal 1:1 pixel scale
    display.setTextColor(SH110X_WHITE); // Draw white text
    display.setCursor(0,0);
    display.println(F("TECNIX Upepo Umeme"));
    display.println(F("<< Power Mon 2/6 >>"));
    display.print(freqVal);
    display.println(" Hz -freq");
    display.print(powVal);
    display.print(" Watts -Pturb");
    display.display();
    display.clearDisplay();
}
void Menu_3() {
    display.clearDisplay();
    display.setTextSize(1); // Normal 1:1 pixel scale
    display.setTextColor(SH110X_WHITE); // Draw white text
    display.setCursor(0,0);
    display.println(F("TECNIX Upepo Umeme"));
    display.println(F("<< Power Mon 3/6 >>"));
    display.print(freqVal);
    display.println(" kWH -now");
    display.print(powVal);
    display.print(" kWH -total");
    display.display();
    // delay(dispDelay);
    display.clearDisplay();
}
void Menu_4() {
    display.clearDisplay();
    display.setTextSize(1); // Normal 1:1 pixel scale
    display.setTextColor(SH110X_WHITE); // Draw white text
    display.setCursor(0,0);
    display.println(F("TECNIX Upepo Umeme"));
    display.println(F("<< System Info 4/6 >>"));
    display.println("Turb Ser #0000");
    display.println("firmware V0.10");
    display.display();
    display.clearDisplay();
}
void Menu_5() {
    display.clearDisplay();
    display.setTextSize(1); // Normal 1:1 pixel scale
    display.setTextColor(SH110X_WHITE); // Draw white text
    display.setCursor(0,0);
    display.println("TECNIX Upepo Umeme");
    display.println("<< Settings 5/6 >>");
    display.println("<< Tech Menu");
    display.println(" Eng/Swah Lang >>");
    display.display();
    display.clearDisplay();
}
void Menu_6() {
    dateandtime();
    DateTime now = rtc.now();
    display.clearDisplay();
    display.setTextSize(1); // Normal 1:1 pixel scale
    display.setTextColor(SH110X_WHITE); // Draw white text
    display.setCursor(0,0);
    display.println("TECNIX Upepo Umeme");
    display.print(now.year(), DEC);
    display.print('/');
    display.print(now.month(), DEC);
    display.print('/');
    display.print(now.day(), DEC);
    display.print(" (");
    display.print(daysOfTheWeek[now.dayOfTheWeek()]);
    display.println(") ");
    display.print(now.hour(), DEC);
    display.print(':');
    display.print(now.minute(), DEC);
    display.print(':');
    display.print(now.second(), DEC);
    display.println();
    display.display();
    display.clearDisplay();
#if 0
    while (digitalRead(selectButtonState) == LOW) {
        Menu_6();
    }
#endif
}

// -----------------------------------------------------------------------------
struct Menu_s {
    void (*func) (void);
    const char *label;
} menus [] = {
    { Menu_1,  "Menu 1" },
    { Menu_2,  "Menu 2" },
    { Menu_3,  "Menu 3" },
    { Menu_4,  "Menu 4" },
    { Menu_5,  "Menu 5" },
    { Menu_6,  "Menu 6" },
};

void
menuUpdate (
    int  idx )
{
    display.setTextSize (1);
    display.setTextColor (SH110X_WHITE);
    display.setCursor (0, 5);
    display.print (menus [idx].label);
}

// -----------------------------------------------------------------------------
void pinouts() {
    voltVal    = analogRead(A1);
    currentVal = analogRead(A2);
    freqVal    = analogRead(A3);
    userVal1   = analogRead(A4);
    Fault01    = digitalRead(0);
}

// -----------------------------------------------------------------------------
#define N_MENU  6
int  menuIdx = 0;

void setup() {
    Serial.begin (9600);
    // Serial.begin(57600);
    display.begin(0x3C, true); //display info
    // display.begin(SH110X_SWITCHCAPVCC, 0x3C);
    display.clearDisplay();
    display.display();
    display.setRotation(1);

    for (unsigned n = 0; n < N_BUT; n++)  {
        pinMode (butPins [n], INPUT_PULLUP);
        butState [n] = digitalRead (butPins [n]);
    }

    rtc.begin();
    menuUpdate (menuIdx);
    delay(1000);
}

// -----------------------------------------------------------------------------
void loop() {
    pinouts ();

    for (unsigned n = 0; n < N_BUT; n++)  {
        byte but = digitalRead (butPins [n]);

        if (butState [n] != but)  {
            butState [n] = but;

            if (LOW == but)  {
                switch (n)  {
                case 0:
                    menuIdx = (menuIdx + 1) % N_MENU;
                    menuUpdate (menuIdx);
                    break;
                case 1:
                    menuIdx = 0 > (menuIdx - 1) ? N_MENU - 1 : menuIdx-1;
                    menuUpdate (menuIdx);
                    break;
                case 2:
                    menus [menuIdx].func ();
                    break;
                }
            }
        }
    }

}
1 Like

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.