element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Arduino
  • Products
  • More
Arduino
Arduino Forum Arduino LCD 20x4 I2C problem
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Arduino to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • State Suggested Answer
  • Replies 17 replies
  • Answers 2 answers
  • Subscribers 393 subscribers
  • Views 3332 views
  • Users 0 members are here
  • i2c
  • 20x4
  • led
  • arduino
Related

Arduino LCD 20x4 I2C problem

Former Member
Former Member over 11 years ago

Hi

 

I have some problem with geting my code to work after a changed my LCD from a 16x2 to a 20x4 with I2C inteface.

 

If i try the sample code below the new LCD works:

 

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR    0x3F
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7

int n = 1;

LiquidCrystal_I2C        lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

void setup()
{
lcd.begin (20,4); // <<----- My LCD was 16x2

 
// Switch on the backlight
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
lcd.home (); // go home

lcd.print("SainSmartI2C16x2");
}

void loop()
{
// Backlight on/off every 3 seconds
lcd.setCursor (0,1);        // go to start of 2nd line
lcd.print(n++,DEC);
lcd.setBacklight(LOW);      // Backlight off
delay(3000);
lcd.setBacklight(HIGH);     // Backlight on
delay(3000);
}

 

 

But when I try to do it with my own code I just got 2 rows with "#"

 

I use this library:

LiquidCrystal_V1.2.1 - https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads

MenuBackEnd V1.4 - http://www.arduino.cc/playground/uploads/Profiles/MenuBackend_1-4.zip

 

 

Here is my code that I can't get to work.

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <MenuBackend.h>


#define I2C_ADDR    0x3F
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7


const int buttonPinLeft = 8;      // pin for the Up button
const int buttonPinRight = 9;    // pin for the Down button
const int buttonPinEsc = 10;     // pin for the Esc button
const int buttonPinEnter = 11;   // 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


int Motor1=1;
int Motor2=0;
int Backlight=255;


String CWCCW, CWCCW2, TPD, TPD2;



LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);




//Menu variables


MenuBackend menu = MenuBackend(menuUsed,menuChanged);


//initialize menuitems
    MenuItem Item1 = MenuItem("Item1"); //Motor 1 Settings


  MenuItem Item1Sub1 = MenuItem("Item1Sub1"); //TPD
  MenuItem Item1Sub1Sub1 = MenuItem("Item1Sub1Sub1"); //650
  MenuItem Item1Sub1Sub2 = MenuItem("Item1Sub1Sub2"); //750
  MenuItem Item1Sub1Sub3 = MenuItem("Item1Sub1Sub3"); //850
  MenuItem Item1Sub1Sub4 = MenuItem("Item1Sub1Sub4"); //950


  MenuItem Item1Sub2 = MenuItem("Item1Sub2");
  MenuItem Item1Sub2Sub1 = MenuItem("Item1Sub2Sub1"); //CW
  MenuItem Item1Sub2Sub2 = MenuItem("Item1Sub2Sub2"); //CCW
  MenuItem Item1Sub2Sub3 = MenuItem("Item1Sub2Sub3"); //Both
     
  MenuItem Item1Sub3 = MenuItem("Item1Sub3"); 
  MenuItem Item1Sub3Sub1 = MenuItem("Item1Sub3Sub1"); //Stop
  MenuItem Item1Sub3Sub2 = MenuItem("Item1Sub3Sub2"); //Start
     
  MenuItem Item2 = MenuItem("Item2"); //Motor 2 Settings

  MenuItem Item2Sub1 = MenuItem("Item2Sub1"); //TPD
  MenuItem Item2Sub1Sub1 = MenuItem("Item2Sub1Sub1"); //650
  MenuItem Item2Sub1Sub2 = MenuItem("Item2Sub1Sub2"); //750
  MenuItem Item2Sub1Sub3 = MenuItem("Item2Sub1Sub3"); //850
  MenuItem Item2Sub1Sub4 = MenuItem("Item2Sub1Sub4"); //950


  MenuItem Item2Sub2 = MenuItem("Item2Sub2");
  MenuItem Item2Sub2Sub1 = MenuItem("Item2Sub2Sub1"); //CW
  MenuItem Item2Sub2Sub2 = MenuItem("Item2Sub2Sub2"); //CCW
  MenuItem Item2Sub2Sub3 = MenuItem("Item2Sub2Sub3"); //Both
     
  MenuItem Item2Sub3 = MenuItem("Item2Sub3");
  MenuItem Item2Sub3Sub1 = MenuItem("Item2Sub3Sub1"); //Stop
  MenuItem Item2Sub3Sub2 = MenuItem("Item2Sub3Sub2"); //Start


  MenuItem Item3 = MenuItem("Item3"); //Backlight
  MenuItem Item3Sub1 = MenuItem("Item3Sub1"); //25%
  MenuItem Item3Sub2 = MenuItem("Item3Sub2"); //50%
  MenuItem Item3Sub3 = MenuItem("Item3Sub3"); //75%
  MenuItem Item3Sub4 = MenuItem("Item3Sub4"); //100%



void setup()
{
  lcd.begin (20,4); //  <<----- My LCD was 16x2
  // Switch on the backlight
  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.home (); // go home
  lcd.print("SainSmart"); 


  CWCCW = String("Both");
  CWCCW2 = String(" CCW");
    TPD = String("650");
  TPD2 = String("850");

  pinMode(buttonPinLeft, INPUT);
  pinMode(buttonPinRight, INPUT);
  pinMode(buttonPinEnter, INPUT);
  pinMode(buttonPinEsc, INPUT);




  //configure menu
  menu.getRoot().add(Item1);

  Item1.addRight(Item2).addRight(Item3);

  Item1.add(Item1Sub1).addRight(Item1Sub2).addRight(Item1Sub3); //Motor 1 Settings
    Item1Sub1.add(Item1Sub1Sub1).addRight(Item1Sub1Sub2).addRight(Item1Sub1Sub3).addRight(Item1Sub1Sub4);
    Item1Sub2.add(Item1Sub2Sub1).addRight(Item1Sub2Sub2).addRight(Item1Sub2Sub3);
    Item1Sub3.add(Item1Sub3Sub1).addRight(Item1Sub3Sub2);


  Item2.add(Item2Sub1).addRight(Item2Sub2).addRight(Item2Sub3); //Motor 2 Settings
    Item2Sub1.add(Item2Sub1Sub1).addRight(Item2Sub1Sub2).addRight(Item2Sub1Sub3).addRight(Item2Sub1Sub4);
    Item2Sub2.add(Item2Sub2Sub1).addRight(Item2Sub2Sub2).addRight(Item2Sub2Sub3);
    Item2Sub3.add(Item2Sub3Sub1).addRight(Item2Sub3Sub2);

  Item3.add(Item3Sub1).addRight(Item3Sub2).addRight(Item3Sub3).addRight(Item3Sub4); //Backlight


  menu.toRoot();


}


void loop()
{
  readButtons();  //I splitted 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; //get the destination menu


  if(newMenuItem.getName()==menu.getRoot()){
        lcd.setCursor(6,0);
        lcd.print("23:00:00");
        lcd.setCursor(5,1);
        lcd.print("2014/12/31");
  lcd.setCursor(0,2);
        lcd.print("                    ");
  lcd.setCursor(0,3);
        lcd.print("                    ");

  if (Motor1==1){
  lcd.setCursor(0,2); //set the start position for lcd printing to the second row
        lcd.print(TPD);
  lcd.setCursor(3,2);
  lcd.print("TPD");
  lcd.setCursor(0,3);
  lcd.print(CWCCW);
        } else if (Motor1==0){
          lcd.setCursor(0,2); //set the start position for lcd printing to the second row
          lcd.print("Not");
          lcd.setCursor(0,3);
   lcd.print("Active");
        }
       
  if (Motor2==1){
  lcd.setCursor(14,2); //set the start position for lcd printing to the second row
        lcd.print(TPD2);
  lcd.setCursor(17,2);
  lcd.print("TPD");
  lcd.setCursor(14,3);
  lcd.print(CWCCW2);
  } else if (Motor2==0){
          lcd.setCursor(17,2);
   lcd.print("Not");
   lcd.setCursor(14,3);
   lcd.print("Active");
   lcd.setCursor(0,2);
        lcd.print("test");
  
    }
  }
  else if(newMenuItem.getName()=="Item1"){ //Motor 1 Settings
  lcd.setCursor(0,3);
        lcd.print("                    ");
  lcd.setCursor(0,2);
        lcd.print("Motor 1 Settings    ");
  }
  else if(newMenuItem.getName()=="Item1Sub1"){ //M1 TPD
  lcd.setCursor(0,2);
        lcd.print("Motor 1 Settings    ");
  lcd.setCursor(0,3);
  lcd.print("TPD                 ");
  }
  else if(newMenuItem.getName()=="Item1Sub1Sub1"){ //650
  lcd.setCursor(0,2);
        lcd.print("Motor 1> TPD        ");
        if(TPD=="650"){
  lcd.setCursor(0,3);
  lcd.print("650 *               ");
  }else{
  lcd.setCursor(0,3);
  lcd.print("650                 ");
  }
  }
  else if(newMenuItem.getName()=="Item1Sub1Sub2"){ //750
  lcd.setCursor(0,2);
    lcd.print("Motor 1> TPD        ");
  if(TPD=="750"){
  lcd.setCursor(0,3);
  lcd.print("750 *               ");
  }else{
  lcd.setCursor(0,3);
  lcd.print("750                 ");
  }
  }
  else if(newMenuItem.getName()=="Item1Sub1Sub3"){ //850
  lcd.setCursor(0,2);
    lcd.print("Motor 1> TPD        ");
  if(TPD=="850"){
  lcd.setCursor(0,3);
  lcd.print("850 *               ");
  }else{
  lcd.setCursor(0,3);
  lcd.print("850                 ");
  }
  }
  else if(newMenuItem.getName()=="Item1Sub1Sub4"){ //950
  lcd.setCursor(0,2);
    lcd.print("Motor 1> TPD        ");
  if(TPD=="950"){
  lcd.setCursor(0,3);
  lcd.print("950 *               ");
  }else{
  lcd.setCursor(0,3);
  lcd.print("950                 ");
  }
  }
  else if(newMenuItem.getName()=="Item1Sub2"){ //M1 Driection
  lcd.setCursor(0,2);
    lcd.print("Motor 1 Settings    ");
  lcd.setCursor(0,3);
    lcd.print("Direction           ");
  }
  else if(newMenuItem.getName()=="Item1Sub2Sub1"){ //CW
  lcd.setCursor(0,2);
        lcd.print("Motor 1> Direrection");
  if(CWCCW=="CW"){
  lcd.setCursor(0,3);
  lcd.print("CW *                ");
  }else{
  lcd.setCursor(0,3);
  lcd.print("CW                  ");
  }
  }
  else if(newMenuItem.getName()=="Item1Sub2Sub2"){ //CCW
  lcd.setCursor(0,2);
        lcd.print("Motor 1> Direrection");
  if(CWCCW=="CCW"){
  lcd.setCursor(0,3);
  lcd.print("CCW *               ");
  }else{
  lcd.setCursor(0,3);
  lcd.print("CCW                 ");
  }
  }
  else if(newMenuItem.getName()=="Item1Sub2Sub3"){ //Both
  lcd.setCursor(0,2);
        lcd.print("Motor 1> Direrection");
  if(CWCCW=="CW/CCW"){
  lcd.setCursor(0,3);
  lcd.print("Both *              ");
  }else{
  lcd.setCursor(0,3);
  lcd.print("Both                ");
  }
  }
  else if(newMenuItem.getName()=="Item1Sub3"){ // M1 START/STOP
  lcd.setCursor(0,2);
        lcd.print("Motor 1 Settings    ");
  lcd.setCursor(0,3);
  lcd.print("STOP/START          ");
  }
  else if(newMenuItem.getName()=="Item1Sub3Sub1"){
  lcd.setCursor(0,2);
        lcd.print("Motor 1> STOP/START ");
  lcd.setCursor(0,3);
  lcd.print("START               ");
  }
  else if(newMenuItem.getName()=="Item1Sub3Sub2"){
  lcd.setCursor(0,2);
        lcd.print("Motor 1> STOP/START ");
  lcd.setCursor(0,3);
  lcd.print("STOP                ");
  }
  else if(newMenuItem.getName()=="Item2"){ //Motor2 settings
  lcd.setCursor(0,3);
        lcd.print("                    ");
  lcd.setCursor(0,2);
        lcd.print("Motor 2 Settings    ");
  }
  else if(newMenuItem.getName()=="Item2Sub1"){ //M2 TPD
  lcd.setCursor(0,2);
    lcd.print("Motor 2 Settings    ");
  lcd.setCursor(0,3);
  lcd.print("TPD                 ");
  }
  else if(newMenuItem.getName()=="Item2Sub1Sub1"){ //650
        lcd.setCursor(0,2);
        lcd.print("Motor 2> TPD        ");
  if(TPD2=="650"){
  lcd.setCursor(0,3);
  lcd.print("650 *           ");
  }else{
  lcd.setCursor(0,3);
  lcd.print("650             ");
  }
  }
  else if(newMenuItem.getName()=="Item2Sub1Sub2"){ //750
  lcd.setCursor(0,2);
    lcd.print("Motor 2> TPD        ");
  if(TPD2=="750"){
  lcd.setCursor(0,3);
  lcd.print("750 *               ");
  }else{
  lcd.setCursor(0,3);
  lcd.print("750                 ");
  }
  }
  else if(newMenuItem.getName()=="Item2Sub1Sub3"){ //850
  lcd.setCursor(0,2);
        lcd.print("Motor 2> TPD        ");
  if(TPD2=="850"){
  lcd.setCursor(0,3);
  lcd.print("850 *               ");
  }else{
  lcd.setCursor(0,3);
  lcd.print("850                 ");
  }
  }
  else if(newMenuItem.getName()=="Item2Sub1Sub4"){ //950
  lcd.setCursor(0,2);
        lcd.print("Motor 2> TPD        ");
  if(TPD=="950"){
  lcd.setCursor(0,3);
  lcd.print("950 *               ");
  }else{
  lcd.setCursor(0,3);
  lcd.print("950                 ");
  }
  }
  else if(newMenuItem.getName()=="Item2Sub2"){ //M2 Direction
  lcd.setCursor(0,2);
        lcd.print("Motor 2> Direction  ");
  lcd.setCursor(0,3);
        lcd.print("Direction           ");
  }
  else if(newMenuItem.getName()=="Item2Sub2Sub1"){ //CW
  lcd.setCursor(0,2);
        lcd.print("Motor 2> Direction  ");
  if(CWCCW2=="    CW"){
  lcd.setCursor(0,3);
  lcd.print("CW *                ");
  }else{
  lcd.setCursor(0,3);
  lcd.print("CW                  ");
  }
  }
  else if(newMenuItem.getName()=="Item2Sub2Sub2"){ //CCW
  lcd.setCursor(0,2);
    lcd.print("Motor 2> Direction  ");
  if(CWCCW2=="   CCW"){
  lcd.setCursor(0,3);
  lcd.print("CCW *               ");
  }else{
  lcd.setCursor(0,3);
  lcd.print("CCW                 ");
  }
  }
  else if(newMenuItem.getName()=="Item2Sub2Sub3"){ //Both
  lcd.setCursor(0,2);
        lcd.print("Motor 2> Direction  ");
  if(CWCCW2=="CW/CCW"){
  lcd.setCursor(0,3);
  lcd.print("Both *              ");
  }else{
  lcd.setCursor(0,3);
  lcd.print("Both                ");
  }
  }
  else if(newMenuItem.getName()=="Item2Sub3"){ // M2 START/STOP
  lcd.setCursor(0,2);
        lcd.print("Motor 2 Settings    ");
  lcd.setCursor(0,3);
  lcd.print("STOP/START          ");
  }
  else if(newMenuItem.getName()=="Item2Sub3Sub1"){
  lcd.setCursor(0,2);
        lcd.print("Motor 2> STOP/START ");
  lcd.setCursor(0,3);
  lcd.print("START               ");
  }
  else if(newMenuItem.getName()=="Item2Sub3Sub2"){
  lcd.setCursor(0,2);
        lcd.print("Motor 2> STOP/START ");
  lcd.setCursor(0,3);
  lcd.print("STOP                ");
  }
  else if(newMenuItem.getName()=="Item3"){ //backlight
  lcd.setCursor(0,3);
    lcd.print("                    ");
  lcd.setCursor(0,2);
    lcd.print("LCD Backlight       ");
  }
  else if(newMenuItem.getName()=="Item3Sub1"){ //25%
  lcd.setCursor(0,2);
    lcd.print("LCD Backlight       ");
  if(Backlight==64){
  lcd.setCursor(0,3);
  lcd.print("25% *               ");
  }else{
  lcd.setCursor(0,3);
  lcd.print("25%                 ");
  }
  }
  else if(newMenuItem.getName()=="Item3Sub2"){ //50%
  lcd.setCursor(0,2);
    lcd.print("LCD Backlight       ");
  if(Backlight==128){
  lcd.setCursor(0,3);
  lcd.print("50% *               ");
  }else{
  lcd.setCursor(0,3);
  lcd.print("50%                 ");
  }
  }
  else if(newMenuItem.getName()=="Item3Sub3"){ //75%
  lcd.setCursor(0,2);
    lcd.print("LCD Backlight       ");
  if(Backlight==192){
  lcd.setCursor(0,3);
  lcd.print("75% *               ");
  }else{
  lcd.setCursor(0,3);
  lcd.print("75%                 ");
  }
  }
  else if(newMenuItem.getName()=="Item3Sub4"){ //100%
  lcd.setCursor(0,2);
    lcd.print("LCD Backlight       ");
  if(Backlight==255){
  lcd.setCursor(0,3);
  lcd.print("100% *              ");
  }else{
  lcd.setCursor(0,3);
  lcd.print("100%                ");
  }
  }
   
}


// här sätter man vad som ska hända efter man har valt något


void menuUsed(MenuUseEvent used){
  if(used.item=="Item1Sub1Sub1"){ //sätter TPD 650
  lcd.clear();
  TPD = String("650");
  lcd.setCursor(0,1);
  lcd.print("M1 TPD set to 650");
  delay(3000);  //delay to allow message reading
  lcd.clear();
  menu.toRoot();  //back to Main
  }
  else if(used.item=="Item1Sub1Sub2"){ //sätter TPD 750
  lcd.clear();
  TPD = String("750");
  lcd.setCursor(0,1);
  lcd.print("M1 TPD set to 750");
  delay(3000);  //delay to allow message reading
  lcd.clear();
  menu.toRoot();  //back to Main
  }
  else if(used.item=="Item1Sub1Sub3"){ //sätter TPD 850
  lcd.clear();
  TPD = String("850");
  lcd.setCursor(0,1);
  lcd.print("M1 TPD set to 850");
  delay(3000);  //delay to allow message reading
  lcd.clear();
  menu.toRoot();  //back to Main
  }
        else if(used.item=="Item1Sub1Sub4"){ //sätter TPD 950
  lcd.clear();
  TPD = String("950");
  lcd.setCursor(0,1);
  lcd.print("M1 TPD set to 950");
  delay(3000);  //delay to allow message reading
  lcd.clear();
  menu.toRoot();  //back to Main
  }
  else if(used.item=="Item1Sub2Sub1"){ //sätter CW
  lcd.clear();
  CWCCW = String("CW");
  lcd.setCursor(0,1);
  lcd.print("M1 Direction = CW");
  delay(3000);  //delay to allow message reading
  lcd.clear();
  menu.toRoot();  //back to Main
  }
  else if(used.item=="Item1Sub2Sub2"){ //sätter CCW
  lcd.clear();
  CWCCW = String("CCW");
  lcd.setCursor(0,1);
  lcd.print("M1 Direction = CCW");
  delay(3000);  //delay to allow message reading
  lcd.clear();
  menu.toRoot();  //back to Main
  }
  else if(used.item=="Item1Sub2Sub3"){ //sätter CW&CCW
  lcd.clear();
  CWCCW = String("CW/CCW");
  //turnmode = 0;
  lcd.setCursor(0,1);
  lcd.print("M1 Direction = Both");
  delay(3000);  //delay to allow message reading
  lcd.clear();
  menu.toRoot();  //back to Main
  }
  else if(used.item=="Item1Sub3Sub1"){ //Startar M1
  lcd.clear();
  lcd.setCursor(0,1);
                Motor1=1;
  lcd.print("Start Motor 1   ");
  delay(3000);  //delay to allow message reading
  lcd.clear();
  menu.toRoot();  //back to Main
  }
  else if(used.item=="Item1Sub3Sub2"){ //Stoppar M1
  lcd.clear();
  lcd.setCursor(0,1);
                Motor1=0;
  lcd.print("Stop Motor 1    ");
  delay(3000);  //delay to allow message reading
  lcd.clear();
  menu.toRoot();  //back to Main
  }
  else if(used.item=="Item2Sub1Sub1"){ //sätter TPD 650
  lcd.clear();
  TPD2 = String("650");
  lcd.setCursor(0,1);
  lcd.print("M2 TPD set to 650");
  delay(3000);  //delay to allow message reading
  lcd.clear();
  menu.toRoot();  //back to Main
  }
  else if(used.item=="Item2Sub1Sub2"){ //sätter TPD 750
  lcd.clear();
  TPD2 = String("750");
  lcd.setCursor(0,1);
  lcd.print("M2 TPD set to 750");
  delay(3000);  //delay to allow message reading
  lcd.clear();
  menu.toRoot();  //back to Main
  }
  else if(used.item=="Item2Sub1Sub3"){ //sätter TPD 850
  lcd.clear();
  TPD2 = String("850");
  lcd.setCursor(0,1);
  lcd.print("M2 TPD set to 850");
  delay(3000);  //delay to allow message reading
  lcd.clear();
  menu.toRoot();  //back to Main
  }
    else if(used.item=="Item2Sub1Sub4"){ //sätter TPD 950
  lcd.clear();
  TPD2 = String("950");
  lcd.setCursor(0,1);
  lcd.print("M2 TPD set to 950");
  delay(3000);  //delay to allow message reading
  lcd.clear();
  menu.toRoot();  //back to Main
  }
  else if(used.item=="Item2Sub2Sub1"){ //sätter CW
  lcd.clear();
  CWCCW2 = String("    CW");
  lcd.setCursor(0,1);
  lcd.print("M2 Direction = CW");
  delay(3000);  //delay to allow message reading
  lcd.clear();
  menu.toRoot();  //back to Main
  }
  else if(used.item=="Item2Sub2Sub2"){ //sätter CCW
  lcd.clear();
  CWCCW2 = String("   CCW");
  lcd.setCursor(0,1);
  lcd.print("M2 Direction = CCW");
  delay(3000);  //delay to allow message reading
  lcd.clear();
  menu.toRoot();  //back to Main
  }
  else if(used.item=="Item2Sub2Sub3"){ //sätter CW&CCW
  lcd.clear();
  CWCCW2 = String("CW/CCW");
  lcd.setCursor(0,1);
  lcd.print("M2 Direction = Both");
  delay(3000);  //delay to allow message reading
  lcd.clear();
  menu.toRoot();  //back to Main
  }
  else if(used.item=="Item2Sub3Sub1"){ //Startar M1
  lcd.clear();
  lcd.setCursor(0,1);
                Motor2=1;
  lcd.print("Start Motor 2   ");
  delay(3000);  //delay to allow message reading
  lcd.clear();
  menu.toRoot();  //back to Main
  }
  else if(used.item=="Item2Sub3Sub2"){ //Stoppar M1
  lcd.clear();
  lcd.setCursor(0,1);
                Motor2=0;
  lcd.print("Stop Motor 2   ");
  delay(3000);  //delay to allow message reading
  lcd.clear();
  menu.toRoot();  //back to Main
  }
  else if(used.item=="Item3Sub1"){ //Blacklight 25%
  lcd.clear();
  Backlight=64;
  lcd.setBacklight(64);
  lcd.setCursor(0,1);
  lcd.print("Backlight = 25% ");
  delay(3000);  //delay to allow message reading
  lcd.clear();
  menu.toRoot();  //back to Main
  }
  else if(used.item=="Item3Sub2"){ //Blacklight 50%
  lcd.clear();
  Backlight=128;
  lcd.setBacklight(128);
  lcd.setCursor(0,1);
  lcd.print("Backlight = 50% ");
  delay(3000);  //delay to allow message reading
  lcd.clear();
  menu.toRoot();  //back to Main
  }
  else if(used.item=="Item3Sub3"){ //Blacklight 75%
  lcd.clear();
  Backlight=192;
  lcd.setBacklight(192);
  lcd.setCursor(0,1);
  lcd.print("Backlight = 75% ");
  delay(3000);  //delay to allow message reading
  lcd.clear();
  menu.toRoot();  //back to Main
  }
  else if(used.item=="Item3Sub4"){ //Blacklight 100%
  lcd.clear();
  Backlight=255;
  lcd.setBacklight(255);
  lcd.setCursor(0,1);
  lcd.print("Backlight = 100%");
  delay(3000);  //delay to allow message reading
  lcd.clear();
  menu.toRoot();  //back to Main
  }

}


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
}

Attachments:
image
  • Sign in to reply
  • Cancel
Parents
  • Robert Peter Oakes
    0 Robert Peter Oakes over 11 years ago

    One of the things you also need to be careful of is running out of RAM, it will just starting behaving badly if you do run out or just go unresponsive .

     

    The reason I say this is because you have a huge volume of strings in your code and they will ALL be moved into the RAM space at run time

     

    Watch Tutorials 3 here for tips on how to correct this and optimize other areas in your code http://www.element14.com/community/groups/arduino/blog/2014/06/09/fast-track-to-arduino-programming

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
  • Former Member
    0 Former Member over 11 years ago in reply to Robert Peter Oakes

    Okey, I think it is a RAM problem.

    Because when I add the code for "MenuBackend" the LCD stops to work.

     

    I will try it later today.

    And thanks for all help.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
Reply
  • Former Member
    0 Former Member over 11 years ago in reply to Robert Peter Oakes

    Okey, I think it is a RAM problem.

    Because when I add the code for "MenuBackend" the LCD stops to work.

     

    I will try it later today.

    And thanks for all help.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
Children
  • mcb1
    0 mcb1 over 11 years ago in reply to Former Member

    Filip

    Ram issues are a pain.

     

    You can save yourself some memory if you change the variables to something more suitable.

    image

    The first 4 are simply on or off so could be a boolean.

    The debounceDelay doesn't require to be a long.

     

    You seem to have a lot of text that could be saved into a single variable and then reused each time you want to display it

    image

    The "Item1Sub" is used extensively and only needs to be stored once.

    You could also make up the text with adding the numbers if you still need more room.

     

    Theses parts here look for a variable text then print the same text, when you could simply print the variable (you already checks is that)

    image

    Line 4 (0,3) of you display mostly seems to print 5 chars  ie CCW or CCW * (CCW space *)

    You don't need to print the whole line, and could also just print the * by using

    lcd.setCursor(4.3);

    lcd.print("*") ;

     

     

    So you may be able to tidy what you have and save enough memory to get it to work.

     

     

    Mark

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
  • Former Member
    0 Former Member over 11 years ago in reply to Former Member

    After I did some PROGMEM fixes the LCD started to work agian. image

     

    thanks for all tips and tricks guys.

     

    Is there any recommended limit of free RAM?

    My code is is not finished yet so it will grow a bit more before I'm done.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • mcb1
    0 mcb1 over 11 years ago in reply to Former Member

    Filip

    Did you want to upload you revised code.

     

    Peter is right in that C will solve your ram issues, but if you are like me, then this is easier said than done ...image

     

    There may be some other things that we can use to save ram.

     

     

    Mark

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • Former Member
    0 Former Member over 11 years ago in reply to mcb1

    Hi Mark

     

    This is my first time I'm coding a arduino so i want to keep it simple.

    I have some coding experience but it's just a hobby for me, so yes, C is easier said than done image

     

    Here is my code.

    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    #include <MenuBackend.h>
    
    
    
    
    int ledPin = A2;
    const int buttonPinLeft = 8;      // pin for the Up button
    const int buttonPinRight = 9;    // pin for the Down button
    const int buttonPinEsc = 10;     // pin for the Esc button
    const int buttonPinEnter = 11;   // 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
    
    
    int lastEnterDebounceTime = 0;  // the last time the output pin was toggled
    int lastEscDebounceTime = 0;  // the last time the output pin was toggled
    int lastLeftDebounceTime = 0;  // the last time the output pin was toggled
    int lastRightDebounceTime = 0;  // the last time the output pin was toggled
    int debounceDelay = 500;    // the debounce time
    
    
    int Motor1=1;
    int Motor2=0;
    int Backlight=255;
    
    
    String CWCCW, CWCCW2, TPD, TPD2;
    
    
    // Set the LCD address to 0x27 for a 16 chars and 2 line display
    LiquidCrystal_I2C lcd(0x3F, 20, 4);
    
    
    //Menu variables
    MenuBackend menu = MenuBackend(menuUsed,menuChanged);
    //initialize menuitems
        MenuItem I1 = MenuItem("I1"); //Motor 1 Settings
      MenuItem I1S1 = MenuItem("I1S1"); //TPD
      MenuItem I1S1S1 = MenuItem("I1S1S1"); //650
      MenuItem I1S1S2 = MenuItem("I1S1S2"); //750
      MenuItem I1S1S3 = MenuItem("I1S1S3"); //850
      MenuItem I1S1S4 = MenuItem("I1S1S4"); //950
      MenuItem I1S2 = MenuItem("I1S2");
      MenuItem I1S2S1 = MenuItem("I1S2S1"); //CW
      MenuItem I1S2S2 = MenuItem("I1S2S2"); //CCW
      MenuItem I1S2S3 = MenuItem("I1S2S3"); //Both
      MenuItem I1S3 = MenuItem("I1S3"); 
      MenuItem I1S3S1 = MenuItem("I1S3S1"); //Stop
      MenuItem I1S3S2 = MenuItem("I1S3S2"); //Start
      MenuItem I2 = MenuItem("I2"); //Motor 2 Settings
      MenuItem I2S1 = MenuItem("I2S1"); //TPD
      MenuItem I2S1S1 = MenuItem("I2S1S1"); //650
      MenuItem I2S1S2 = MenuItem("I2S1S2"); //750
      MenuItem I2S1S3 = MenuItem("I2S1S3"); //850
      MenuItem I2S1S4 = MenuItem("I2S1S4"); //950
      MenuItem I2S2 = MenuItem("I2S2");
      MenuItem I2S2S1 = MenuItem("I2S2S1"); //CW
      MenuItem I2S2S2 = MenuItem("I2S2S2"); //CCW
      MenuItem I2S2S3 = MenuItem("I2S2S3"); //Both
      MenuItem I2S3 = MenuItem("I2S3");
      MenuItem I2S3S1 = MenuItem("I2S3S1"); //Stop
      MenuItem I2S3S2 = MenuItem("I2S3S2"); //Start
      MenuItem I3 = MenuItem("I3"); //Backlight
      MenuItem I3S1 = MenuItem("I3S1"); //25%
      MenuItem I3S2 = MenuItem("I3S2"); //50%
      MenuItem I3S3 = MenuItem("I3S3"); //75%
      MenuItem I3S4 = MenuItem("I3S4"); //100%
    
    void setup()
    {
      pinMode(ledPin, OUTPUT);
      // initialize the LCD
            //lcd.begin();
      // Turn on the blacklight and print a message.
      analogWrite(ledPin, 255);
    
    
      CWCCW = String("Both");
      CWCCW2 = String("   CCW");
      TPD = String("650");
      TPD2 = String("850");
    
    
      pinMode(buttonPinLeft, INPUT);
      pinMode(buttonPinRight, INPUT);
      pinMode(buttonPinEnter, INPUT);
      pinMode(buttonPinEsc, INPUT);
    
    
      //configure menu
      menu.getRoot().add(I1);
      I1.addRight(I2).addRight(I3);
    
    
      I1.add(I1S1).addRight(I1S2).addRight(I1S3); //Motor 1 Settings
      I1S1.add(I1S1S1).addRight(I1S1S2).addRight(I1S1S3).addRight(I1S1S4);
      I1S2.add(I1S2S1).addRight(I1S2S2).addRight(I1S2S3);
      I1S3.add(I1S3S1).addRight(I1S3S2);
    
    
      I2.add(I2S1).addRight(I2S2).addRight(I2S3); //Motor 2 Settings
      I2S1.add(I2S1S1).addRight(I2S1S2).addRight(I2S1S3).addRight(I2S1S4);
      I2S2.add(I2S2S1).addRight(I2S2S2).addRight(I2S2S3);
      I2S3.add(I2S3S1).addRight(I2S3S2);
    
    
      I3.add(I3S1).addRight(I3S2).addRight(I3S3).addRight(I3S4); //Backlight
    
    
      menu.toRoot();
    
    
    }
    
    
    
    
    
    
    void loop()
    
    
    {
      readButtons();  //I splitted 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)
      lcd.setCursor(15,0);
      lcd.println(freeRam(), DEC);
    }
    
    
    
    
    
    
    
    
    
    
    void menuChanged(MenuChangeEvent changed){
    
    
    MenuItem newMenuItem=changed.to; //get the destination menu
      //switch (value)
      if(newMenuItem.getName()==menu.getRoot()){
      lcd.setCursor(6,0);
      lcd.print(F("23:00:00"));
      lcd.setCursor(5,1);
      lcd.print(F("2014/12/31"));
      lcd.setCursor(0,2);
      lcd.print(F("                    "));
      lcd.setCursor(0,3);
      lcd.print(F("                    "));
      if (Motor1==1){
      lcd.setCursor(0,2); //set the start position for lcd printing to the second row
      lcd.print(TPD);
      lcd.setCursor(3,2);
      lcd.print(F("TPD"));
      lcd.setCursor(0,3);
      lcd.print(CWCCW);
      }else if (Motor1==0){
      lcd.setCursor(0,2); //set the start position for lcd printing to the second row
      lcd.print(F("Not"));
      lcd.setCursor(0,3);
      lcd.print(F("Active"));
      }
      if (Motor2==1){
      lcd.setCursor(14,2); //set the start position for lcd printing to the second row
      lcd.print(TPD2);
      lcd.setCursor(17,2);
      lcd.print(F("TPD"));
      lcd.setCursor(14,3);
      lcd.print(CWCCW2);
      } else if (Motor2==0){
      lcd.setCursor(17,2);
      lcd.print(F("Not"));
      lcd.setCursor(14,3);
      lcd.print(F("Active"));
      }
      }
      else if(newMenuItem.getName()=="I1"){ //Motor 1 Settings
      lcd.setCursor(0,3);
      lcd.print(F("                    "));
      lcd.setCursor(0,2);
      lcd.print(F("Motor 1 Settings    "));
      }
      else if(newMenuItem.getName()=="I1S1"){ //M1 TPD
      lcd.setCursor(0,2);
      lcd.print(F("Motor 1 Settings    "));
      lcd.setCursor(0,3);
      lcd.print(F("TPD                 "));
      }
      else if(newMenuItem.getName()=="I1S1S1"){ //650
      lcd.setCursor(0,2);
      lcd.print(F("Motor 1> TPD        "));
      lcd.setCursor(0,3);
      lcd.print(F("650                 "));
      if(TPD=="650"){
      lcd.setCursor(5,3);
      lcd.print(F("*"));
      }
      }
      else if(newMenuItem.getName()=="I1S1S2"){ //750
      lcd.setCursor(0,2);
      lcd.print(F("Motor 1> TPD        "));
      lcd.setCursor(0,3);
      lcd.print(F("750                 "));
      if(TPD=="750"){
      lcd.setCursor(5,3);
      lcd.print(F("*"));
      }
      }
      else if(newMenuItem.getName()=="I1S1S3"){ //850
      lcd.setCursor(0,2);
      lcd.print(F("Motor 1> TPD        "));
      lcd.setCursor(0,3);
      lcd.print(F("850                 "));
      if(TPD=="850"){
      lcd.setCursor(5,3);
      lcd.print(F("*"));
      }
      }
      else if(newMenuItem.getName()=="I1S1S4"){ //950
      lcd.setCursor(0,2);
      lcd.print(F("Motor 1> TPD        "));
      lcd.setCursor(0,3);
      lcd.print(F("950                 "));
      if(TPD=="950"){
      lcd.setCursor(5,3);
      lcd.print(F("*"));
      }
      }
      else if(newMenuItem.getName()=="I1S2"){ //M1 Driection
      lcd.setCursor(0,2);
      lcd.print(F("Motor 1 Settings    "));
      lcd.setCursor(0,3);
      lcd.print(F("Direction           "));
      }
      else if(newMenuItem.getName()=="I1S2S1"){ //CW
      lcd.setCursor(0,2);
      lcd.print(F("Motor 1> Direrection"));
      lcd.setCursor(0,3);
      lcd.print(F("CW                  "));
      if(CWCCW=="CW"){
      lcd.setCursor(4,3);
      lcd.print(F("*"));
      }
      }
      else if(newMenuItem.getName()=="I1S2S2"){ //CCW
      lcd.setCursor(0,2);
      lcd.print(F("Motor 1> Direrection"));
      lcd.setCursor(0,3);
      lcd.print(F("CCW                 "));
      if(CWCCW=="CCW"){
      lcd.setCursor(5,3);
      lcd.print(F("*"));
      }
      }
      else if(newMenuItem.getName()=="I1S2S3"){ //Both
      lcd.setCursor(0,2);
      lcd.print(F("Motor 1> Direrection"));
      lcd.setCursor(0,3);
      lcd.print(F("CW/CCW              "));
      if(CWCCW=="CW/CCW"){
      lcd.setCursor(8,3);
      lcd.print(F("*"));
      }
      }
      else if(newMenuItem.getName()=="I1S3"){ // M1 START/STOP
      lcd.setCursor(0,2);
      lcd.print(F("Motor 1 Settings    "));
      lcd.setCursor(0,3);
      lcd.print(F("STOP/START          "));
      }
      else if(newMenuItem.getName()=="I1S3S1"){
      lcd.setCursor(0,2);
      lcd.print(F("Motor 1> STOP/START "));
      lcd.setCursor(0,3);
      lcd.print(F("START               "));
      }
      else if(newMenuItem.getName()=="I1S3S2"){
      lcd.setCursor(0,2);
      lcd.print(F("Motor 1> STOP/START "));
      lcd.setCursor(0,3);
      lcd.print(F("STOP                "));
      }
      else if(newMenuItem.getName()=="I2"){ //Motor2 settings
      lcd.setCursor(0,3);
      lcd.print(F("                    "));
      lcd.setCursor(0,2);
      lcd.print(F("Motor 2 Settings    "));
      }
      else if(newMenuItem.getName()=="I2S1"){ //M2 TPD
      lcd.setCursor(0,2);
      lcd.print(F("Motor 2 Settings    "));
      lcd.setCursor(0,3);
      lcd.print(F("TPD                 "));
      }
      else if(newMenuItem.getName()=="I2S1S1"){ //650
      lcd.setCursor(0,2);
      lcd.print(F("Motor 2> TPD        "));
      lcd.setCursor(0,3);
      lcd.print(F("650             "));
      if(TPD2=="650"){
      lcd.setCursor(5,3);
      lcd.print(F("*"));
      }
      }
      else if(newMenuItem.getName()=="I2S1S2"){ //750
      lcd.setCursor(0,2);
      lcd.print(F("Motor 2> TPD        "));
      lcd.setCursor(0,3);
      lcd.print(F("750                 "));
      if(TPD2=="750"){
      lcd.setCursor(5,3);
      lcd.print(F("*"));
      }
      }
      else if(newMenuItem.getName()=="I2S1S3"){ //850
      lcd.setCursor(0,2);
      lcd.print(F("Motor 2> TPD        "));
      lcd.setCursor(0,3);
      lcd.print(F("850                 "));
      if(TPD2=="850"){
      lcd.setCursor(5,3);
      lcd.print(F("*"));
      }
      }
      else if(newMenuItem.getName()=="I2S1S4"){ //950
      lcd.setCursor(0,2);
      lcd.print(F("Motor 2> TPD        "));
      lcd.setCursor(0,3);
      lcd.print(F("950                 "));
      if(TPD=="950"){
      lcd.setCursor(5,3);
      lcd.print(F("*"));
      }
      }
      else if(newMenuItem.getName()=="I2S2"){ //M2 Direction
      lcd.setCursor(0,2);
      lcd.print(F("Motor 2 Settings    "));
      lcd.setCursor(0,3);
      lcd.print(F("Direction           "));
      }
      else if(newMenuItem.getName()=="I2S2S1"){ //CW
      lcd.setCursor(0,2);
      lcd.print(F("Motor 2> Direction  "));
      lcd.setCursor(0,3);
      lcd.print("CW                  ");
      if(CWCCW2=="    CW"){
      lcd.setCursor(4,3);
      lcd.print("*");
      }
      }
      else if(newMenuItem.getName()=="I2S2S2"){ //CCW
      lcd.setCursor(0,2);
      lcd.print(F("Motor 2> Direction  "));
      lcd.setCursor(0,3);
      lcd.print("CCW                 ");
      if(CWCCW2=="   CCW"){
      lcd.setCursor(5,3);
      lcd.print("*");
      }
      }
      else if(newMenuItem.getName()=="I2S2S3"){ //Both
      lcd.setCursor(0,2);
      lcd.print(F("Motor 2> Direction  "));
      lcd.setCursor(0,3);
      lcd.print(F("CW/CCW              "));
      if(CWCCW2=="CW/CCW"){
      lcd.setCursor(8,3);
      lcd.print(F("*"));
      }
      }
      else if(newMenuItem.getName()=="I2S3"){ // M2 START/STOP
      lcd.setCursor(0,2);
      lcd.print(F("Motor 2 Settings    "));
      lcd.setCursor(0,3);
      lcd.print(F("STOP/START          "));
      }
      else if(newMenuItem.getName()=="I2S3S1"){
      lcd.setCursor(0,2);
      lcd.print(F("Motor 2> STOP/START "));
      lcd.setCursor(0,3);
      lcd.print(F("START               "));
      }
      else if(newMenuItem.getName()=="I2S3S2"){
      lcd.setCursor(0,2);
      lcd.print(F("Motor 2> STOP/START "));
      lcd.setCursor(0,3);
      lcd.print(F("STOP                "));
      }
      else if(newMenuItem.getName()=="I3"){ //backlight
      lcd.setCursor(0,3);
      lcd.print(F("                    "));
      lcd.setCursor(0,2);
      lcd.print(F("LCD Backlight       "));
      }
      else if(newMenuItem.getName()=="I3S1"){ //25%
      lcd.setCursor(0,2);
      lcd.print(F("LCD Backlight       "));
      lcd.setCursor(0,3);
      lcd.print(F("25%                 "));
      if(Backlight==64){
      lcd.setCursor(5,3);
      lcd.print(F("*"));
      }
      }
      else if(newMenuItem.getName()=="I3S2"){ //50%
      lcd.setCursor(0,2);
      lcd.print(F("LCD Backlight       "));
      if(Backlight==128){
      lcd.setCursor(0,3);
      lcd.print(F("50% *               "));
      }else{
      lcd.setCursor(0,3);
      lcd.print(F("50%                 "));
      }
      }
      else if(newMenuItem.getName()=="I3S3"){ //75%
      lcd.setCursor(0,2);
      lcd.print(F("LCD Backlight       "));
      lcd.setCursor(0,3);
      lcd.print(F("75%                 "));
      if(Backlight==192){
      lcd.setCursor(5,3);
      lcd.print(F("*"));
      }
      }
      else if(newMenuItem.getName()=="I3S4"){ //100%
      lcd.setCursor(0,2);
      lcd.print(F("LCD Backlight       "));
      lcd.setCursor(0,3);
      lcd.print(F("100%                "));
      if(Backlight==255){
      lcd.setCursor(6,3);
      lcd.print(F("*"));
      }
      }
    }
    
    
    // här sätter man vad som ska hända efter man har valt något
    void menuUsed(MenuUseEvent used){
    
    
      if(used.item=="I1S1S1"){ //sätter TPD 650
      lcd.clear();
      TPD = String("650");
      lcd.setCursor(0,1);
      lcd.print(F("M1 TPD set to 650"));
      delay(3000);  //delay to allow message reading
      lcd.clear();
      menu.toRoot();  //back to Main
      }
      else if(used.item=="I1S1S2"){ //sätter TPD 750
      lcd.clear();
      TPD = String("750");
      lcd.setCursor(0,1);
      lcd.print(F("M1 TPD set to 750"));
      delay(3000);  //delay to allow message reading
      lcd.clear();
      menu.toRoot();  //back to Main
      }
      else if(used.item=="I1S1S3"){ //sätter TPD 850
      lcd.clear();
      TPD = String("850");
      lcd.setCursor(0,1);
      lcd.print(F("M1 TPD set to 850"));
      delay(3000);  //delay to allow message reading
      lcd.clear();
      menu.toRoot();  //back to Main
      }
      else if(used.item=="I1S1S4"){ //sätter TPD 950
      lcd.clear();
      TPD = String("950");
      lcd.setCursor(0,1);
      lcd.print(F("M1 TPD set to 950"));
      delay(3000);  //delay to allow message reading
      lcd.clear();
      menu.toRoot();  //back to Main
      }
      else if(used.item=="I1S2S1"){ //sätter CW
      lcd.clear();
      CWCCW = String("CW");
      lcd.setCursor(0,1);
      lcd.print(F("M1 Direction = CW"));
      delay(3000);  //delay to allow message reading
      lcd.clear();
      menu.toRoot();  //back to Main
      }
      else if(used.item=="I1S2S2"){ //sätter CCW
      lcd.clear();
      CWCCW = String("CCW");
      lcd.setCursor(0,1);
      lcd.print(F("M1 Direction = CCW"));
      delay(3000);  //delay to allow message reading
      lcd.clear();
      menu.toRoot();  //back to Main
      }
      else if(used.item=="I1S2S3"){ //sätter CW&CCW
      lcd.clear();
      CWCCW = String("CW/CCW");
      //turnmode = 0;
      lcd.setCursor(0,1);
      lcd.print(F("M1 Direction = Both"));
      delay(3000);  //delay to allow message reading
      lcd.clear();
      menu.toRoot();  //back to Main
      }
      else if(used.item=="I1S3S1"){ //Startar M1
      lcd.clear();
      lcd.setCursor(0,1);
      Motor1=1;
      lcd.print(F("Start Motor 1"));
      delay(3000);  //delay to allow message reading
      lcd.clear();
      menu.toRoot();  //back to Main
      }
      else if(used.item=="I1S3S2"){ //Stoppar M1
      lcd.clear();
      lcd.setCursor(0,1);
      Motor1=0;
      lcd.print(F("Stop Motor 1"));
      delay(3000);  //delay to allow message reading
      lcd.clear();
      menu.toRoot();  //back to Main
      }
      else if(used.item=="I2S1S1"){ //sätter TPD 650
      lcd.clear();
      TPD2 = String("650");
      lcd.setCursor(0,1);
      lcd.print(F("M2 TPD set to 650"));
      delay(3000);  //delay to allow message reading
      lcd.clear();
      menu.toRoot();  //back to Main
      }
      else if(used.item=="I2S1S2"){ //sätter TPD 750
      lcd.clear();
      TPD2 = String("750");
      lcd.setCursor(0,1);
      lcd.print(F("M2 TPD set to 750"));
      delay(3000);  //delay to allow message reading
      lcd.clear();
      menu.toRoot();  //back to Main
      }
      else if(used.item=="I2S1S3"){ //sätter TPD 850
      lcd.clear();
      TPD2 = String("850");
      lcd.setCursor(0,1);
      lcd.print(F("M2 TPD set to 850"));
      delay(3000);  //delay to allow message reading
      lcd.clear();
      menu.toRoot();  //back to Main
      }
      else if(used.item=="I2S1S4"){ //sätter TPD 950
      lcd.clear();
      TPD2 = String("950");
      lcd.setCursor(0,1);
      lcd.print(F("M2 TPD set to 950"));
      delay(3000);  //delay to allow message reading
      lcd.clear();
      menu.toRoot();  //back to Main
      }
      else if(used.item=="I2S2S1"){ //sätter CW
      lcd.clear();
      CWCCW2 = String("    CW");
      lcd.setCursor(0,1);
      lcd.print(F("M2 Direction = CW"));
      delay(3000);  //delay to allow message reading
      lcd.clear();
      menu.toRoot();  //back to Main
      }
      else if(used.item=="I2S2S2"){ //sätter CCW
      lcd.clear();
      CWCCW2 = String("   CCW");
      lcd.setCursor(0,1);
      lcd.print(F("M2 Direction = CCW"));
      delay(3000);  //delay to allow message reading
      lcd.clear();
      menu.toRoot();  //back to Main
      }
      else if(used.item=="I2S2S3"){ //sätter CW&CCW
      lcd.clear();
      CWCCW2 = String("CW/CCW");
      lcd.setCursor(0,1);
      lcd.print(F("M2 Direction = Both"));
      delay(3000);  //delay to allow message reading
      lcd.clear();
      menu.toRoot();  //back to Main
      }
      else if(used.item=="I2S3S1"){ //Startar M1
      lcd.clear();
      lcd.setCursor(0,1);
      Motor2=1;
      lcd.print(F("Start Motor 2"));
      delay(3000);  //delay to allow message reading
      lcd.clear();
      menu.toRoot();  //back to Main
      }
      else if(used.item=="I2S3S2"){ //Stoppar M1
      lcd.clear();
      lcd.setCursor(0,1);
      Motor2=0;
      lcd.print(F("Stop Motor 2"));
      delay(3000);  //delay to allow message reading
      lcd.clear();
      menu.toRoot();  //back to Main
      }
      else if(used.item=="I3S1"){ //Blacklight 25%
      lcd.clear();
      Backlight=64;
    analogWrite(ledPin, 64);
      lcd.setCursor(0,1);
      lcd.print(F("Backlight = 25%"));
      delay(3000);  //delay to allow message reading
      lcd.clear();
      menu.toRoot();  //back to Main
      }
      else if(used.item=="I3S2"){ //Blacklight 50%
      lcd.clear();
      Backlight=128;
    analogWrite(ledPin, 128);
      lcd.setCursor(0,1);
      lcd.print(F("Backlight = 50%"));
      delay(3000);  //delay to allow message reading
      lcd.clear();
      menu.toRoot();  //back to Main
      }
      else if(used.item=="I3S3"){ //Blacklight 75%
      lcd.clear();
      Backlight=192;
    analogWrite(ledPin, 192);
      lcd.setCursor(0,1);
      lcd.print(F("Backlight = 75% "));
      delay(3000);  //delay to allow message reading
      lcd.clear();
      menu.toRoot();  //back to Main
      }
      else if(used.item=="I3S4"){ //Blacklight 100%
      lcd.clear();
      Backlight=255;
    analogWrite(ledPin, 255);
      lcd.setCursor(0,1);
      lcd.print(F("Backlight = 100%"));
      delay(3000);  //delay to allow message reading
      lcd.clear();
      menu.toRoot();  //back to Main
      }
    }
    
    
    
    
    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
    }
    
    
    int freeRam () {
      extern int __heap_start, *__brkval;
      int v;
      return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
    }

     

    I tried replacing "IF THEN ELSE" with "Switch case" but it didn't work so I gave up on that.

     

    With this code I have around 900 in free RAM

     

    I have noticed that when I have selected something from the menu the keys become very sensitive, is there something wrong with the keys in the code?

    I have tried to fix this but I'm clueless.

     

    Maybe it will solves itself when I replace some of the buttons with a rotery encoder.

     

    Just so you get what is coming...

    My next steps is to connect the following:

    1x Rotery encoder (replace some buttons)

    1x RTC

    2x easy drivers

    2x Line sensor

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • mcb1
    0 mcb1 over 11 years ago in reply to Former Member

    Filip

    A quick reply.

    Your code is looking tidier up until line 189, where you could easily save more ram by not duplicating the text and LCD print.

    You may need to clear old text on a line, but you shouldn't require to do it each time.

     

    Do it once then add the appropriate new chars.

     

    I suggest printing it out and highlight the common text to see how you could save more ram.

     

     

    the keys become very sensitive

    You'll have to qualify 'sensitive' .. do they operate quickly so you end up with the wrong choice, do you have to hold them from a while to have the menu change?

    You seem to have 500mS for the debounce time (line 28) which is far too long IMO

     

    Mark

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • Former Member
    0 Former Member over 11 years ago in reply to mcb1

    Mark, about the sensitive keys.....

    They operate quickly so ot end up with the wrong choice in the menu.

    But it's only after I have done one choise... with other words.


    First time I browse in the menu it works great and if we say that I choose to change the backlight and then when I try to change it agian the menu is operate to quickly and I end up with a wrong choice in menu.


    I hope you understand me even if I have some problem with my english image

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • Robert Peter Oakes
    0 Robert Peter Oakes over 11 years ago in reply to Former Member

    Another observation is the menu system

     

    It is ALL going to be in RAM and take a huge amount of it too, all those strings add up real fast, never mind the management of the link list to allow you to manage it, what MPU are you running this on, an ATMEGA328 (UNO) or MEGA ATMEGA2560 ?? and you done apear to be using all of them, just declaring them, delete or comment out the ones your not using.

     

    the video should show you alternate approach

     

    can yo sketch what your trying to achieve with this, maybe a picture of the menu and layout of the system etc

     

    I will then along with Mark be able to suggest some good fixes

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • Former Member
    0 Former Member over 11 years ago in reply to Robert Peter Oakes

    I have an UNO (ATMEGA328)

     

    The project I'm doing is my own watch winder with 2 slots.

    I don't know how much you guys know about watch winders but depending on the watch it supposed to turn X turns per day (TPD) and in different directions.

    In the end it's going to be an advanced version of the one you see in the picture link below.

    http://livedoor.blogimg.jp/a_lange_sohne/imgs/1/4/14156f10.jpg

     

    My "watch tube" will be black with a white line, which will register(thanks to a line sensor) the number of turns it has taken.

     

    I have just start the project and my first milestone in to get the code to work before I start to buy every things else.

     

    And I am doing the code step by step before I add more things to it, and as you know you can see where I am now.

    I don't know if I have like you say in Swedish.. "Taken water over my head" but I like to have some challenges when my girl is watching crap on the television.

     

     

    I want the menu to look like a list but i didn't achieve that by myself that why I used the Menubackend-lib.

    To navigate in the menu I want to use a rotary encoder, one select button and one back/esc button.

    Here is a menu sketch:

     

    Motor 1 settings
         ->TPD
              ->650
              ->750
              ->850
              ->950
         ->Direction
              ->CW
              ->CCW
              ->CW&CCW
         ->Start/Stop //manual inactivate the motor
              ->Start
              ->Stop
    Motor 2 settings
         ->TPD
              ->650
              ->750
              ->850
              ->950
         ->Direction
              ->CW
              ->CCW
              ->CW&CCW
         ->Start/Stop //manual inactivate the motor
              ->Start
              ->Stop
    Backlight //I do not know if I really need this, so I will maybe remove this to save RAM
         ->25%
         ->50%
         ->75%
         ->100%

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube