I am trying to write a get a very basic menu up and running that converts Fahrenheit to Celcius.
I have a menu to select whether to show temp in Fahrenheit or Celcius (fahrenheit is default)
I can navigate through the menu with no problems, however when I select Celcius, it prints 0.00 on the LCD instead of carrying out the temp conversion.
Is there something wrong with the math I am using? From what I have read on the arduino.cc site, it should work.
Here is the code I am using, any advice would be greatly appreciated.
#include <MenuBackend.h> //MenuBackend library - copyright by Alexander Brevig
#include <LiquidCrystal.h> //this library is modified by Lady Ada to support I2C
#include <Wire.h>
const int buttonPinLeft = 7; // pin for the Up button
const int buttonPinRight = 8; // pin for the Down button
const int buttonPinEsc = 9; // pin for the Esc button
const int buttonPinEnter = 10; // pin for the Enter button
int lastButtonPushed = 0;
int lastButtonEnterState = LOW; // the previous reading from the Enter input pin
int lastButtonEscState = LOW; // the previous reading from the Esc input pin
int lastButtonLeftState = LOW; // the previous reading from the Left input pin
int lastButtonRightState = LOW; // the previous reading from the Right input pin
long lastEnterDebounceTime = 0; // the last time the output pin was toggled
long lastEscDebounceTime = 0; // the last time the output pin was toggled
long lastLeftDebounceTime = 0; // the last time the output pin was toggled
long lastRightDebounceTime = 0; // the last time the output pin was toggled
long debounceDelay = 500; // the debounce time
double SetPoint = 200.75;
double printSetPoint = 0.00;
int changeScale = 0; //variable for checking whether C or F selected in Menu (F is default)
LiquidCrystal lcd(0); //Default address for I2C LCD
MenuBackend menu = MenuBackend(menuUsed,menuChanged);
MenuItem menu1Item1 = MenuItem("Convert Temp");
MenuItem menuItem1SubItem1 = MenuItem("Fahrenheit");
MenuItem menuItem1SubItem2 = MenuItem("Celcius");
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
lcd.setBacklight(HIGH);
delay (500);
lcd.setCursor(0, 0);
pinMode(buttonPinLeft, INPUT);
pinMode(buttonPinRight, INPUT);
pinMode(buttonPinEnter, INPUT);
pinMode(buttonPinEsc, INPUT);
menu.getRoot().add(menu1Item1);
menu1Item1.add(menuItem1SubItem1).addRight(menuItem1SubItem2);
menu.toRoot();
lcd.setCursor(0, 0);
lcd.print("S:");
lcd.setCursor(2, 0);
lcd.print(SetPoint);
}
void loop() {
readButtons(); //I split button reading and navigation in two procedures because
navigateMenus(); //in some situations I want to use the button for other purpose (eg. to change some settings)
}
void menuChanged(MenuChangeEvent changed) {
MenuItem newMenuItem = changed.to;
char* newMenuItemName = const_cast<char *>(newMenuItem.getName());
int newSetting = 0;
//get the destination menu
lcd.setCursor(0, 1);
//set the start position for lcd printing to the second row
if(newMenuItemName == menu.getRoot().getName())
{
lcd.print("Menu ");
}
else if(newMenuItemName == "Convert Temp"){
lcd.print("Convert Temp ");
}
else if(newMenuItemName == "Fahrenheit")\
{
lcd.print("Fahrenheit ");
printSetPoint = SetPoint;
lcd.setCursor(0,0);
lcd.print("S:");
lcd.print(printSetPoint);// print the setpoint in Fahrenheit (default)
}
else if(newMenuItemName == "Celcius")
{
lcd.print("Celcius ");
printSetPoint = ((SetPoint - 32) * (5/9)); //Convert to celcius
lcd.print(" ");
lcd.setCursor(0,0);
lcd.print("S:");
lcd.print(printSetPoint); //print celcius setpoint
lcd.print(" ");
}
}
void menuUsed(MenuUseEvent used)
{
menu.toRoot();
}
void readButtons() {
//read buttons status
int reading;
int buttonEnterState = LOW; // the current reading from the Enter input pin
int buttonEscState = LOW; // the current reading from the input pin
int buttonLeftState = LOW; // the current reading from the input pin
int buttonRightState = LOW; // the current reading from the input pin
//Enter button
// read the state of the switch into a local variable:
reading = digitalRead(buttonPinEnter);
// check to see if you just pressed the enter button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonEnterState) {
// reset the debouncing timer
lastEnterDebounceTime = millis();
}
if ((millis() - lastEnterDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonEnterState = reading;
lastEnterDebounceTime = millis();
}
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonEnterState = reading;
//Esc button
// read the state of the switch into a local variable:
reading = digitalRead(buttonPinEsc);
// check to see if you just pressed the Down button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonEscState) {
// reset the debouncing timer
lastEscDebounceTime = millis();
}
if ((millis() - lastEscDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonEscState = reading;
lastEscDebounceTime = millis();
}
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonEscState = reading;
//Down button
// read the state of the switch into a local variable:
reading = digitalRead(buttonPinRight);
// check to see if you just pressed the Down button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonRightState) {
// reset the debouncing timer
lastRightDebounceTime = millis();
}
if ((millis() - lastRightDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonRightState = reading;
lastRightDebounceTime = millis();
}
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonRightState = reading;
//Up button
// read the state of the switch into a local variable:
reading = digitalRead(buttonPinLeft);
// check to see if you just pressed the Down button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonLeftState) {
// reset the debouncing timer
lastLeftDebounceTime = millis();
}
if ((millis() - lastLeftDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonLeftState = reading;
lastLeftDebounceTime = millis();
}
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonLeftState = reading;
//records which button has been pressed
if (buttonEnterState == HIGH) {
lastButtonPushed = buttonPinEnter;
} else if (buttonEscState == HIGH) {
lastButtonPushed = buttonPinEsc;
} else if (buttonRightState == HIGH) {
lastButtonPushed = buttonPinRight;
} else if (buttonLeftState == HIGH) {
lastButtonPushed = buttonPinLeft;
} else {
lastButtonPushed = 0;
}
}
void navigateMenus() {
MenuItem currentMenu = menu.getCurrent();
switch (lastButtonPushed) {
case buttonPinEnter:
if (! (currentMenu.moveDown())) { // if the current menu has a child and has been pressed enter then menu navigate to item below
menu.use();
} else { // otherwise, if menu has no child and has been pressed enter the current menu is used
menu.moveDown();
}
break;
case buttonPinEsc:
menu.toRoot();
//back to main
break;
case buttonPinRight:
menu.moveRight();
break;
case buttonPinLeft:
menu.moveLeft();
break;
}
lastButtonPushed = 0;
//reset the lastButtonPushed variable
}