I'm working on a project that has an LCD screen, 20x4, that has two pages controlled by a push button. It works but, sometimes the screen changes with a simple button push and sometimes it won't change unless I hold the button down. Sometimes multiple pushes changes the screen every time. It seems like the more times I change it the slower it gets. Am I just bogging the Arduino down? This is part of a larger project but, I like to make sure smaller bits work before adding them together.
and code. I'm terrible at coding but, it does work.
=================
#include "Wire.h"
#include "Adafruit_LiquidCrystal.h"
#include "SDL_Arduino_INA3221.h"
SDL_Arduino_INA3221 ina3221;
#include <DallasTemperature.h>
// -------------------------------the three channels of the INA3221 for voltage
#define HOUSE_BATTERY 1
#define CHARGER_CHANNEL 2
#define START_BATTERY_CHANNEL 3
Adafruit_LiquidCrystal lcd(0);
//===============================Temperature
#define ONE_WIRE_BUS 7 //pin for DS18B20
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
int analogInput = A1;
float vout = 0.0;
float vin = 0.0;
float R1 = 30000.0; //
float R2 = 7500.0; //
int value = 0;
//------------------------------------Counter to change positions of pages
int page_counter = 1 ; //To move beetwen pages
//-------Pins-----
int up = 8; //menu button
//---------Storage debounce function-----
boolean current_up = LOW;
boolean last_up = LOW;
boolean last_down = LOW;
boolean current_down = LOW;
void setup() {
lcd.begin(20, 4);
ina3221.begin();
sensors.begin();
}
//---- De-bouncing function for all buttons----
boolean debounce(boolean last, int pin)
{
boolean current = digitalRead(pin);
if (last != current)
{
delay(2);
current = digitalRead(pin);
}
return current;
}
void loop() {
float busvoltage1 = 0;
busvoltage1 = ina3221.getBusVoltage_V(HOUSE_BATTERY);
float busvoltage2 = 0;
busvoltage2 = ina3221.getBusVoltage_V(CHARGER_CHANNEL);
float busvoltage3 = 0;
busvoltage3 = ina3221.getBusVoltage_V(START_BATTERY_CHANNEL);
current_up = debounce(last_up, up); //Debounce for Up button
//----Page counter function to move pages----
//Page Up
if (last_up == LOW && current_up == HIGH) { //When up button is pressed
lcd.clear(); //When page is changed, lcd clear to print new page
if (page_counter < 2) { //Page counter never higher than 3(total of pages)
page_counter = page_counter + 1; //Page up
}
else {
page_counter = 1;
}
}
last_up = current_up;
last_down = current_down;
//------- Switch function to write and show what you want---//
switch (page_counter)
{
case 1: { //Design of home page 1
lcd.setCursor(0, 0);
lcd.print("House Batt");
lcd.setCursor(13, 0);
lcd.print(busvoltage1);
lcd.setCursor(0, 1);
lcd.print("Charge Batt");
lcd.setCursor(13, 1);
lcd.print(busvoltage2);
lcd.setCursor(0, 2);
lcd.print("Start Batt");
lcd.setCursor(13, 2);
lcd.print(busvoltage3);
}
break;
case 2: { //Design of page 2
sensors.requestTemperatures();
float temperature1 = sensors.getTempFByIndex(0);
lcd.setCursor(0, 0);
lcd.print("Battery Temp");
lcd.setCursor(13, 0);
lcd.print(sensors.getTempFByIndex(0));
float temperature2 = sensors.getTempFByIndex(1);
lcd.setCursor(0, 1);
lcd.print("Cabin Temp");
lcd.setCursor(13, 1);
lcd.print(sensors.getTempFByIndex(1));
float temperature3 = sensors.getTempFByIndex(2);
lcd.setCursor(0, 2);
lcd.print("Heat Temp");
lcd.setCursor(13, 2);
lcd.print(sensors.getTempFByIndex(2));
float temperature4 = sensors.getTempFByIndex(3);
lcd.setCursor(0, 3);
lcd.print("Outside Temp");
lcd.setCursor(13, 3);
lcd.print(sensors.getTempFByIndex(3));
}
break;
}//switch end
}//loop end
Try adding a debouncing capacitor to the pushbutton circuit. See https://circuitdigest.com/electronic-circuits/what-is-switch-bouncing-and-how-to-prevent-it-using-debounce-circuit for an explanation. I do not think that your debounce function is fail-safe.
Also the code below can be simplified with the following:
// increment modulo 2. This will yield a 2 when initial value is 1 and 1 when initially 2
page_counter = ( page _counter % 2 ) + 1;
if (page_counter < 2) { //Page counter never higher than 3(total of pages)
page_counter = page_counter + 1; //Page up}
else {
page_counter = 1;
}
Two things come to my mind, reading your code :
- maybe the debouncing is too short ?
- when I used 20x4 LCD I found it to be rather slow so i tried to avoid writing the "constant labels" during every loop() if possible (maybe you can manage a "page change" event where you could isolate them), and aso only print out the values only when they change if possible
Eric
Indeed, that is (was) my initial thought too! 2ms is very short (I'd also argue, that the delay (pugwash territory) should not even be in the function itself, let alone ahead of the next statement that follows). Debouncing can be considered a black art... I don't think I have ever seen anyone come up with a silver bullet solution on it to date, and there are many different implementations promoted for this purpose.
2ms is very short
I've tried various times up to 15. Doesn't seem to change much. That leads me to believe the code may be in the wrong place or not written right.
I still think the delay should not be in the function, and if anywhere, prefer it in the main function loop.
Some people use interrupts with good results, so may be worth a try?
I still think the delay should not be in the function, and if anywhere, prefer it in the main function loop.
Some people use interrupts with good results, so may be worth a try?
Thanks, I'll try that. Have to figure out what that means first. ?