Help with merging codes and using presets within an LCD menu system

Hello everyone

I am currently working on a project for a timelapse slider which is at the moment, being driven by an Uno, Linksprite Motor Shield and a geared DC motor. This will eventually go over to a NEMA 17 stepper motor but hey, it works at the moment! :slight_smile:

I am having trouble getting my head around 1st, merging an LCD code with a motor control code, then furthermore, getting the ‚Äúpresets‚ÄĚ written in the LCD menu system. I have 3 codes written for differing speeds etc for the motor, but cannot work out how to write it all together!

I do have an Adafruit I2C 16x2 LCD on the way, so wanted to get the codes sorted so that when that arrives tomorrow, I can upload and test it all out. The following two codes are ones that both work individually on the current LCD and Motor respectively. I know i will be changing them slightly (pins etc) when the new LCD arrives.

I have read numerous tutorials, guides and information on this but cannot find anything that helps! So over to you fine and extremely knowledgable members! :slight_smile:

 #include <LiquidCrystal.h>
 
// Initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);
 
//States for the menu.
int currentMenuItem = 0;
int lastState = 0;
 
void setup() {
   //Set the characters and column numbers.
   lcd.begin(16, 2);
   //Print default title.
   clearPrintTitle();
}
 
void loop() {
  //Call the main menu.
  mainMenu();
}
 
void mainMenu() {
  //State = 0 every loop cycle.
  int state = 0;
  //Refresh the button pressed.
  int x = analogRead (0);
  //Set the Row 0, Col 0 position.
  lcd.setCursor(0,0);
 
  //Check analog values from LCD Keypad Shield
  if (x < 100) {
    //Right
  } else if (x < 200) {
   //Up
    state = 1;
  } else if (x < 400){
   //Down
    state = 2;
  } else if (x < 600){
    //Left
  } else if (x < 800){
    //Select
    state = 3;
  }
 
  //If we are out of bounds on th menu then reset it.
  if (currentMenuItem < 0 || currentMenuItem > 4) {
   currentMenuItem = 0; 
  }
 
   //If we have changed Index, saves re-draws.
   if (state != lastState) {
      if (state == 1) {
         //If Up
          currentMenuItem = currentMenuItem - 1; 
          displayMenu(currentMenuItem);
      } else if (state == 2) {
         //If Down
          currentMenuItem = currentMenuItem + 1;  
          displayMenu(currentMenuItem);
      } else if (state == 3) {
         //If Selected
         selectMenu(currentMenuItem); 
      }
      //Save the last State to compare.
      lastState = state;
   } 
   //Small delay
  delay(5);
}
 
//Display Menu Option based on Index.
void displayMenu(int x) {
     switch (x) {
      case 1:
        clearPrintTitle();
        lcd.print ("-> PRESET 1");
        break;
      case 2:
        clearPrintTitle();
        lcd.print ("-> PRESET 2");
        break;
       case 3:
        clearPrintTitle();
        lcd.print ("-> PRESET 3");
        break;
      case 4:
        clearPrintTitle();
        lcd.print ("-> PRESET 4");
        break;
    }
}
 
//Print a basic header on Row 1.
void clearPrintTitle() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("ISO100-TIMELAPSE");
  lcd.setCursor(0,1); 
}
 
//Show the selection on Screen.
void selectMenu(int x) {
   switch (x) {
      case 1:
        clearPrintTitle();
        lcd.print ("CHOSEN PRESET 1");
        //Call the function that belongs to Option 1
        break;
      case 2:
        clearPrintTitle();
        lcd.print ("CHOSED PRESET 2");
        //Call the function that belongs to Option 2
        break;
       case 3:
        clearPrintTitle();
        lcd.print ("CHOSEN PRESET 3");
        //Call the function that belongs to Option 3
        break;
      case 4:
        clearPrintTitle();
        lcd.print ("CHOSEN PRESET 4");
        //Call the function that belongs to Option 4
        break;
    }
}

and one of the motor codes

//. Motor shield
// 
// 

int pinI1=8;//define I1 interface
int pinI2=11;//define I2 interface 
int speedpinA=9;//enable motor A
int pinI3=12;//define I3 interface 
int pinI4=13;//define I4 interface 
int speedpinB=10;//enable motor B
int spead =100;//define the spead of motor
 
void setup()
{
  pinMode(pinI1,OUTPUT);
  pinMode(pinI2,OUTPUT);
  pinMode(speedpinA,OUTPUT);
  pinMode(pinI3,OUTPUT);
  pinMode(pinI4,OUTPUT);
  pinMode(speedpinB,OUTPUT);
}
 
void forward()
{
     analogWrite(speedpinA,spead);//input a simulation value to set the speed
     analogWrite(speedpinB,spead);
     digitalWrite(pinI4,HIGH);//turn DC Motor B move clockwise
     digitalWrite(pinI3,LOW);
     digitalWrite(pinI2,LOW);//turn DC Motor A move clockwise
     digitalWrite(pinI1,HIGH);

}
void stop()//
{
     digitalWrite(speedpinA,LOW);// Unenble the pin, to stop the motor. this should be done to avid damaging the motor. 
     digitalWrite(speedpinB,LOW);
     delay(5000); // pause time of camera moving in milliseconds
 
}

void loop()
{
  forward();
  delay(1500); // time motor spins for in milliseconds 
   stop(); 
}

Thank you all in advance

Jay

Does this help? http://www.thebox.myzen.co.uk/Tutorial/Merging_Code.html

Thanks Mike, certainly looks more "readable" than some I've read over! I'll have a proper read tomro at work :D

Now only to sort the LCD etc etc.... Think this'll be the headache if I'm honest!

Yes you need to resolve the issue that both sketches need the same pins for diffrent purposes.

Morning Mike. Certainly do need to sort that! Lol should be a lot easier when the adafruit arrives as it only uses two pins rather than most of them such as the current LCD.

I'm really think at the moment how to actually do it, then I can tweak it as required when the LCD is here and working. Any suggestions mate?

'm really think at the moment how to actually do it,

That is the problem if you have a shield. You have to cut tracks if there is no way the shield will allow you to reallocate pins. But you have to watch that some pins have special functions like the SPI pins which can not be moved easily. For example if you do have to move the SPI pins and want to use the SPI interface then you will have to alter the software and bit bang the SPI protocol in place of using the built in hardware support. You also have to watch the PWM capability of some pins if that is needed.

I would advise that you draw everything out on a piece of paper showing all the connections you need, then you know what you are dealing with.

Hopefully, it shouldn't be too much of a problem as the LCD only uses two I2C pins and that's it with the adafruit. The motor shield obviously uses more pics but not, as far as I can recall, the I2C.

It's writing the code all together with menu choices etc that's going to get me!

Right, I thought I was getting there…! As stated in the original post, both codes worked on their respective shields before, now I’ve started merging. Trying as hard as possible to use the wonders of google to find some sort of direction, but nothing jumping out at me. Here is the code once I started getting errors (which i cannot understand) Honestly not sure if I’m heading in the right direction to set up the presets so hopefully someone can help!

#include <LiquidCrystal.h>
 
// Initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);
 
//States for the menu.
int currentMenuItem = 0;
int lastState = 0;
   
int pinI1=8;//define I1 interface
int pinI2=11;//define I2 interface 
int speedpinA=9;//enable motor A
int pinI3=12;//define I3 interface 
int pinI4=13;//define I4 interface 
int speedpinB=10;//enable motor B
int spead =100;//define the spead of motor
 
void setup() {
   //Set the characters and column numbers.
   lcd.begin(16, 2);
   //Print default title.
   clearPrintTitle();

  pinMode(pinI1,OUTPUT);
  pinMode(pinI2,OUTPUT);
  pinMode(speedpinA,OUTPUT);
  pinMode(pinI3,OUTPUT);
  pinMode(pinI4,OUTPUT);
  pinMode(speedpinB,OUTPUT);
  
}
 
void loop() {
  //Call the main menu.
  mainMenu();

  preset 1();
  delay(1500); // time motor spins for in milliseconds 
   stop(); 
   
 }

 
void mainMenu() {
  //State = 0 every loop cycle.
  int state = 0;
  //Refresh the button pressed.
  int x = analogRead (0);
  //Set the Row 0, Col 0 position.
  lcd.setCursor(0,0);
 
  //Check analog values from LCD Keypad Shield
  if (x < 100) {
    //Right
  } else if (x < 200) {
   //Up
    state = 1;
  } else if (x < 400){
   //Down
    state = 2;
  } else if (x < 600){
    //Left
  } else if (x < 800){
    //Select
    state = 3;
  }
 
  //If we are out of bounds on th menu then reset it.
  if (currentMenuItem < 0 || currentMenuItem > 4) {
   currentMenuItem = 0; 
  }
 
      if (state != lastState) {
      if (state == 1) {
         //If Up
          currentMenuItem = currentMenuItem - 1; 
          displayMenu(currentMenuItem);
      } else if (state == 2) {
         //If Down
          currentMenuItem = currentMenuItem + 1;  
          displayMenu(currentMenuItem);
      } else if (state == 3) {
         //If Selected
         selectMenu(currentMenuItem); 
      }
    
      lastState = state;
   } 
   //delay
  delay(5);
}
 
//Display Menu Option based on Index.
void displayMenu(int x) {
     switch (x) {
      case 1:
        clearPrintTitle();
        lcd.print ("-> PRESET 1");
        break;
      case 2:
        clearPrintTitle();
        lcd.print ("-> PRESET 2");
        break;
       case 3:
        clearPrintTitle();
        lcd.print ("-> PRESET 3");
        break;
      case 4:
        clearPrintTitle();
        lcd.print ("-> PRESET 4");
        break;
    }
}
 
//Print a basic header on Row 1.
void clearPrintTitle() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("ISO100-TIMELAPSE");
  lcd.setCursor(0,1); 
}
 
//Show the selection on Screen.
void selectMenu(int x) {
   switch (x) {
      case 1:
        clearPrintTitle();
        lcd.print ("CHOSEN PRESET 1");
        //Call function that belongs to preset 1
        break;
      case 2:
        clearPrintTitle();
        lcd.print ("CHOSED PRESET 2");
        //Call function that belongs to preset 2
        break;
       case 3:
        clearPrintTitle();
        lcd.print ("CHOSEN PRESET 3");
        //Call function that belongs to preset 3
        break;
      case 4:
        clearPrintTitle();
        lcd.print ("CHOSEN PRESET 4");
        //Call function that belongs to preset 4
        break;
    }
}

void preset A()
{
     analogWrite(speedpinA,spead);//input a simulation value to set the speed
     analogWrite(speedpinB,spead);
     digitalWrite(pinI4,HIGH);//turn DC Motor B move anticlockwise
     digitalWrite(pinI3,LOW);
     digitalWrite(pinI2,LOW);//turn DC Motor A move clockwise
     digitalWrite(pinI1,HIGH);

}

void stop()//
{
     digitalWrite(speedpinA,LOW);// Unenble the pin, to stop the motor. this should be done to avid damaging the motor. 
     digitalWrite(speedpinB,LOW);
     delay(5000); // pause time of camera motion in milliseconds
     
       preset 1();
  delay(1500); // time motor spins for in milliseconds 
   stop(); 
 
}

and the error messages…

Arduino: 1.0.6 (Windows 7), Board: ‚ÄúArduino Uno‚ÄĚ
LCD_Menu_System:11: error: expected initializer before ‚ÄėA‚Äô
LCD_Menu_System.ino: In function ‚Äėvoid loop()‚Äô:
LCD_Menu_System:37: error: ‚Äėpreset‚Äô was not declared in this scope
LCD_Menu_System:37: error: expected ;' before numeric constant LCD_Menu_System.ino: At global scope: LCD_Menu_System:149: error: expected initializer before 'A' LCD_Menu_System.ino: In function 'void stop()': LCD_Menu_System:166: error: 'preset' was not declared in this scope LCD_Menu_System:166: error: expected ;’ before numeric constant

Now this was verifying ok with no errors, although I can’t be certain it works at the moment, not until i get the adafruit and motor shield running together

#include <LiquidCrystal.h>
 
// Initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);
 
//States for the menu.
int currentMenuItem = 0;
int lastState = 0;

// Motor 
 

int pinI1=8;//define I1 interface
int pinI2=11;//define I2 interface 
int speedpinA=9;//enable motor A
int pinI3=12;//define I3 interface 
int pinI4=13;//define I4 interface 
int speedpinB=10;//enable motor B
int spead =100;//define the spead of motor
 
void setup() {
   //Set the characters and column numbers.
   lcd.begin(16, 2);
   //Print default title.
   clearPrintTitle();
   
   pinMode(pinI1,OUTPUT);
  pinMode(pinI2,OUTPUT);
  pinMode(speedpinA,OUTPUT);
  pinMode(pinI3,OUTPUT);
  pinMode(pinI4,OUTPUT);
  pinMode(speedpinB,OUTPUT);
}

void forward()
{
     analogWrite(speedpinA,spead);//input a simulation value to set the speed
     analogWrite(speedpinB,spead);
     digitalWrite(pinI4,HIGH);//turn DC Motor B move clockwise
     digitalWrite(pinI3,LOW);
     digitalWrite(pinI2,LOW);//turn DC Motor A move clockwise
     digitalWrite(pinI1,HIGH);

 digitalWrite(speedpinA,LOW);// Unenble the pin, to stop the motor. this should be done to avid damaging the motor. 
     digitalWrite(speedpinB,LOW);
     delay(5000); // pause time of camera moving in milliseconds
     
}

void loop() 
{
  //Call the main menu.
  mainMenu();
  
    forward();
  delay(1500); // time motor spins for in milliseconds 

  
}
 
void mainMenu() {
  //State = 0 every loop cycle.
  int state = 0;
  //Refresh the button pressed.
  int x = analogRead (0);
  //Set the Row 0, Col 0 position.
  lcd.setCursor(0,0);
 
  //Check analog values from LCD Keypad Shield
  if (x < 100) {
    //Right
  } else if (x < 200) {
   //Up
    state = 1;
  } else if (x < 400){
   //Down
    state = 2;
  } else if (x < 600){
    //Left
  } else if (x < 800){
    //Select
    state = 3;
  }
 
  //If we are out of bounds on th menu then reset it.
  if (currentMenuItem < 0 || currentMenuItem > 4) {
   currentMenuItem = 0; 
  }
 
   //If we have changed Index, saves re-draws.
   if (state != lastState) {
      if (state == 1) {
         //If Up
          currentMenuItem = currentMenuItem - 1; 
          displayMenu(currentMenuItem);
      } else if (state == 2) {
         //If Down
          currentMenuItem = currentMenuItem + 1;  
          displayMenu(currentMenuItem);
      } else if (state == 3) {
         //If Selected
         selectMenu(currentMenuItem); 
      }
      //Save the last State to compare.
      lastState = state;
   } 
   //Small delay
  delay(5);
}
 
//Display Menu Option based on Index.
void displayMenu(int x) {
     switch (x) {
      case 1:
        clearPrintTitle();
        lcd.print ("-> PRESET 1");
        break;
      case 2:
        clearPrintTitle();
        lcd.print ("-> PRESET 2");
        break;
       case 3:
        clearPrintTitle();
        lcd.print ("-> PRESET 3");
        break;
      case 4:
        clearPrintTitle();
        lcd.print ("-> PRESET 4");
        break;
    }
}
 
//Print a basic header on Row 1.
void clearPrintTitle() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("ISO100-TIMELAPSE");
  lcd.setCursor(0,1); 
}
 
//Show the selection on Screen.
void selectMenu(int x) {
   switch (x) {
      case 1:
        clearPrintTitle();
        lcd.print ("CHOSEN PRESET 1");
        //Call the function that belongs to Option 1
        break;
      case 2:
        clearPrintTitle();
        lcd.print ("CHOSED PRESET 2");
        //Call the function that belongs to Option 2
        break;
       case 3:
        clearPrintTitle();
        lcd.print ("CHOSEN PRESET 3");
        //Call the function that belongs to Option 3
        break;
      case 4:
        clearPrintTitle();
        lcd.print ("CHOSEN PRESET 4");
        //Call the function that belongs to Option 4
        break;
    
  }
}

Did you notice in reply #7 that the stop function is recursive, that is it calls itself? And the preset 1() is not the way you call a function?

Grumpy_Mike: Did you notice in reply #7 that the stop function is recursive, that is it calls itself? And the preset 1() is not the way you call a function?

Erm, nope! Lol unfortunately Mike I'm a real newby with this so still trying to learn it! :)