Arduino Project, Multiple Sensors, Menu With Push Button

So I'm working on a project, where I make a water feasibility meter using 3 sensors (temperature, tds, and turbidity), I use arduino uno and i2c LCD (20x4) as the output.

now I'm trying to create menus and submenus that display the results of each sensor, the problem is that when I enter the push button code for the sensor, the result I get is feedback that takes too long, sometimes when the button is pressed it can run the menu and sometimes not (the push button code alone without me entering the sensor code works normally)

can you help me solve this problem?
this is my temporary full sketch

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "GravityTDS.h"

LiquidCrystal_I2C lcd(0x27, 20, 4); // Alamat I2C LCD, ukuran 20x4

#define btnBack 7
#define btnOk   6
#define btnDown 5

boolean statusBtnBack = false;
boolean statusBtnOk   = false;
boolean statusBtnDown = false;

boolean statusAkhirBtnBack = false;
boolean statusAkhirBtnOk   = false;
boolean statusAkhirBtnDown = false;

boolean BACK = false;
boolean OK   = false;
boolean DOWN = false;

int halaman  = 1;
int menuItem = 1;

#define ONE_WIRE_BUS 2
#define TdsSensorPin A2
#define TurbiditySensorPin A0

OneWire oneWire(ONE_WIRE_BUS);
GravityTDS gravityTds;
DallasTemperature sensors(&oneWire);

float tdsValue = 0;
float turbidityVolt;
float turbidityNTU;

void setup() {
  Serial.begin(115200);
  lcd.init();
  lcd.backlight();

  pinMode(btnBack, INPUT_PULLUP);
  pinMode(btnOk,   INPUT_PULLUP);
  pinMode(btnDown, INPUT_PULLUP);

  sensors.begin();
  sensors.setResolution(12);
  gravityTds.setPin(TdsSensorPin);
  gravityTds.setAref(5.0);
  gravityTds.setAdcRange(1024);
  gravityTds.begin();
}

void loop() {
  tampil();

  statusBtnBack = digitalRead(btnBack);
  statusBtnOk   = digitalRead(btnOk);
  statusBtnDown = digitalRead(btnDown);

  saatBackDitekan();
  saatOkDitekan();
  saatDownDitekan();

  // Read TDS and Temperature
  sensors.requestTemperatures();
  gravityTds.setTemperature(sensors.getTempCByIndex(0));
  gravityTds.update();
  tdsValue = gravityTds.getTdsValue();

  // Read Turbidity
  turbidityVolt = 0;
  for (int i = 0; i < 800; i++) {
    turbidityVolt += (analogRead(TurbiditySensorPin) / 1023.0) * 5;
  }
  turbidityVolt /= 800;
  turbidityVolt = round_to_dp(turbidityVolt, 2);

  if (turbidityVolt < 2.5) {
    turbidityNTU = 3;
  } else {
    turbidityNTU = -1120.4 * sq(turbidityVolt) + 5742.3 * turbidityVolt - 4353.8;
    turbidityNTU = turbidityNTU / 1000; // dividing by 1000

  }

  // Handle button actions
  if (BACK) {
    BACK = false;
    if (halaman == 2 || halaman == 3 || halaman == 4) {
      halaman = 1;
    }
  }

  if (OK) {
    OK = false;
    if (halaman == 1 && menuItem == 1) {
      halaman = 2;
    } else if (halaman == 1 && menuItem == 2) {
      halaman = 3;
    } else if (halaman == 1 && menuItem == 3) {
      halaman = 4;
    }
  }

  if (DOWN && halaman == 1) {
    DOWN = false;
    menuItem ++;
    if (menuItem > 3)menuItem = 1;
  }

  Serial.println(menuItem);
  delay(100);
}

void saatBackDitekan() {
  if (statusBtnBack != statusAkhirBtnBack) {
    if (statusBtnBack == 0) {
      BACK = true;
    }
    delay(50);
  }
  statusAkhirBtnBack = statusBtnBack;
}

void saatOkDitekan() {
  if (statusBtnOk != statusAkhirBtnOk) {
    if (statusBtnOk == 0) {
      OK = true;
    }
    delay(50);
  }
  statusAkhirBtnOk = statusBtnOk;
}

void saatDownDitekan() {
  if (statusBtnDown != statusAkhirBtnDown) {
    if (statusBtnDown == 0) {
      DOWN = true;
    }
    delay(50);
  }
  statusAkhirBtnDown = statusBtnDown;
}

void tampil() {
  if (halaman == 1) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("SENSOR MENU");

    if (menuItem == 1) {
      lcd.setCursor(0, 1);
      lcd.print("> Temperature");
    } else {
      lcd.setCursor(0, 1);
      lcd.print("  Temperature");
    }

    if (menuItem == 2) {
      lcd.setCursor(0, 2);
      lcd.print("> TDS");
    } else {
      lcd.setCursor(0, 2);
      lcd.print("  TDS");
    }

    if (menuItem == 3) {
      lcd.setCursor(0, 3);
      lcd.print("> Turbidity");
    } else {
      lcd.setCursor(0, 3);
      lcd.print("  Turbidity");
    }
  } else if (halaman == 2) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Suhu: ");
    lcd.print(sensors.getTempCByIndex(0));
    lcd.print(" C");
  } else if (halaman == 3) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("TDS: ");
    lcd.print(tdsValue, 0);
    lcd.print(" PPM");
  } else if (halaman == 4) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Turbidity: ");
    lcd.print(turbidityNTU);
    lcd.print(" NTU");
  }
}

float round_to_dp(float in_value, int decimal_place) {
  float multiplier = pow(10.0, decimal_place);
  in_value = round(in_value * multiplier) / multiplier;
  return in_value;
}

Hello nadhdp

Welcome to the world's best Arduino forum ever.

I´ve made a code review and the code seems to have grown dynamically.
I did not want to use the word spaghetti code.

And now?

Take a piece of paper, a pencil and design, based on the IPO model, a program structure plan before start coding.
Identify functions and their depencies. Now start with coding and testing, function by function.
These functions might be:

  • button manager
  • LCD manager
  • Sensor manager
  • tick time manager
  • ....

At the end merge all tested function together to get the final sketch.
The basics for coding the project are to be found in the IDE as examples.

Have a nice day and enjoy coding in C++.

p.s. enums, arrays and structs are your friends.

1 Like

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