control systems for 3 linear actuators and 1 motor using a 4 by 4 key and LCD

The useForCaseX functions actually need to copy the input value to some global variable.

int valueA =0;
int valueB = 0;
int valueC = 0;
int valueD = 0;

void useForCaseA(input num)
{
   valueA = num;
   // The rest of the code
}

void useForCaseB(input num)
{
   valueB = num;
   // The rest of the code
}

void useForCaseC(input num)
{
   valueC = num;
   // The rest of the code
}

void useForCaseD(input num)
{
   valueD = num;
   // The rest of the code
}

Then, in the CheckNumber() function, you CAN reference valueA, valueB, valueC, and valueD.

Hi Paul,

Thank you for your advice. I have put defined the following code as global variables.

int valueA =0;
int valueB = 0;
int valueC = 0;
int valueD = 0;

I decided to change it a little bit and add an “If” and “else” condition in the useForCaseX Void Function.
I wanted to add a condition that accepts the number if it is within the range and if not then it will reject the data (return the integer to 0) and prompt an error message back to zero. At the moment, when I enter a number greater than 600, the does not return to zero and it prevents me from entering a new number.

void useForCaseA(int num){
   valueA = num;
 if((valueA >1) && (valueA<600)){
 lcd.setCursor(10,0);
 lcd.print("       ");
 lcd.setCursor(10,0);
 lcd.print(valueA);

 }else // should return the number to zero because it is outside the range.
 {
  valueA=0;
 ErrorMessage();
 }
}


void ErrorMessage(){
  //Display messages for (0x3E) 16 by 2 LCD
  lcd2.setCursor(0,0);
  lcd2.print("Error Please");
  lcd2.setCursor(0,1);
  lcd2.print("Check input values");
  delay(10000);
  lcd2.clear();
}

I think my error is in the “else” condition. How can I reset my number to zero after the wrong number has been inputted and be able to enter another number?

Why not assign num to valueA only if it IS in range?

  if(num >= 1 && num <= 600)
  {
     valueA = num;

     // other stuff
  }

I think my error is in the “else” condition.

I think your code does something, in a rather unusual fashion, but you haven’t explained what it actually does.

You haven’t posted all of your code, so we can’t see where valueA is defined, or all the places where it is used.

So, you may be right. Or, you may be wrong. We can’t tell.

Hi,

Here is the code below. To simplify it this is for only PinA. I tried placing the valueA +num; inside if statement, however, it doesn’t seem to work.

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

int valueA = 0;
int valueB = 0;
int valueC = 0;
int valueD = 0;

const byte ROWS = 4; //four rows
const byte COLS = 4; //four colums
//define the smybols on the buttons of the keyboard

char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

byte rowPins[COLS] = {2,3,4,5}; //connect to the row pinouts of the keypad
byte colPins[ROWS] = {6,7,8,9}; //connect to the colum pinouts of the keypad

//initalize an instance of class NewKeypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

LiquidCrystal_I2C lcd(0x3F,2,1,0,4,5,6,7,3,POSITIVE);
//0x3F is 20 by 4 LCD

LiquidCrystal_I2C lcd2(0x3E,2,1,0,4,5,6,7,3,POSITIVE);
//0x3E is 16 by 2 LCD


void setup() {

//Display messages for (0x3F) 20 by 4 LCD
  lcd.backlight();
  lcd.begin(20,4);
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("Pin A");
  lcd.setCursor(17,0);
  lcd.print("mm");


//Display messages for (0x3E) 16 by 2 LCD
  lcd2.begin(16,2);
  lcd2.backlight();
  lcd2.setCursor(0, 0);
  lcd2.print("No of Cycles:");
  lcd2.setCursor(0,1);
  }

void loop() {


   static int number = 0;
  char key = keypad.waitForKey();
   switch(key)
   {
       case '0'...'9':
          number *= 10;
          number += key - '0';
          break;

       case 'A':
          useForCaseA(number);
          number = 0;

          break;
}
}

void useForCaseA(int num){ 
 if((valueA >=1) && (valueA<=600)){
 valueA = num;
 lcd.setCursor(10,0);
 lcd.print("       ");
 lcd.setCursor(10,0);
 lcd.print(valueA);
 }else
 {
  valueA=0;
 ErrorMessage();
 }
}

void ErrorMessage(){
  //Display messages for (0x3E) 16 by 2 LCD
  lcd2.setCursor(0,0);
  lcd2.print("Error Please");
  lcd2.setCursor(0,1);
  lcd2.print("Check input values");
  delay(10000);
  lcd2.clear();
}

Hi Paul,

I think I may have figured out the issue because my lower limit is 1 and I want to return the value to 0 I think that has caused an issue. My only issue is that the limits don’t seem to be working. I can enter a number greater than 600 and it will display on the screen without the error message being prompt.

oid useForCaseA(int num){ 
 if((valueA >=0) && (valueA<=600)){ //limits from 0-600
 valueA = num;
 lcd.setCursor(10,0);
 lcd.print("       ");
 lcd.setCursor(10,0);
 lcd.print(valueA);
 }else if(valueA>600){ //if greater than 600 follow error command
 valueA = num; 
 valueA=0;
 ErrorMessage();
 lcd.setCursor(10,0);
 lcd.print("       ");
 lcd.setCursor(10,0);
 lcd.print(valueA);
 }
}
void useForCaseA(int num){
 if((valueA >=1) && (valueA<=600)){
 valueA = num;

valueA is 0 the first time this code is called. 0 is not between 1 and 600, inclusive. Why are you testing valueA, when it is num that needs to be in that range?

Hi,

I was just trying to return a value of 0 to the function to clear the number out of range. How should I write the code then?

Suf: Hi,

I was just trying to return a value of 0 to the function to clear the number out of range. How should I write the code then?

As in reply #22, where I test num, not valueA. I store the value that is in num in valueA only if the value in num is valid.

Okay, I see what you mean. I did it slightly differently.

I first stored my num value into valueA first and then tested it using “if” and “else” statement.

“if” it is within the range of 1-600 then it will remain as “valueA = num”.

“else” if it does not fit into the range than “valueA=0”

void useForCaseA(int num){ 

valueA = num; //places num into valueA
 
if((valueA >= 1) && (valueA <= 600)){
//Sets Curosr and Prints Code

 }else{
 valueA=0;
 ErrorMessage();
//Clears message on screen and Sets Curosr and New Value ( valueA=0) on screen

 }
}

Would this method that I am using also work for storing and holding the values?

Would this method that I am using also work for storing and holding the values?

Send me your hardware, and I'll upload the code and test it for you. Then, I'll send the hardware back in the prepaid mailer you include.

Hi Paul,

I have tested the menu part of my code using an Arduino Uno, a 4 by 4 matrix, 2 lcd screen (20 by 4 and 16 by 2) with I2C modules. At the moment I am waiting for another person in my group to finish design the stepper motor driver.

My code is below:

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

int valueA = 0;
int valueB = 0;
int valueC = 0;
int valueD = 0;

const byte ROWS = 4; //four rows
const byte COLS = 4; //four colums
//define the smybols on the buttons of the keyboard

char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

byte rowPins[COLS] = {2,3,4,5}; //connect to the row pinouts of the keypad
byte colPins[ROWS] = {6,7,8,9}; //connect to the colum pinouts of the keypad

//initalize an instance of class NewKeypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

LiquidCrystal_I2C lcd(0x3F,2,1,0,4,5,6,7,3,POSITIVE);
//0x3F is 20 by 4 LCD

LiquidCrystal_I2C lcd2(0x3E,2,1,0,4,5,6,7,3,POSITIVE);
//0x3E is 16 by 2 LCD


void setup() {
  // put your setup code here, to run once:

//START UP MESSAGE Display messages for (0x3F) 20 by 4 LCD
  lcd.begin(20,4);
  lcd.backlight();
  lcd.setCursor(4,0);
  lcd.print("Nitinol Wire");
  lcd.setCursor(3,1);
  lcd.print("Fatigue Machine");
  lcd.setCursor(0,2);
  lcd.print("UH Research Project");
  lcd.setCursor(4,3);
  lcd.print("Version 1.0");

//START UP MESSAGE Display messages for (0x3E) 16 by 2 LCD
  lcd2.begin(16,2);
  lcd2.backlight();
  lcd2.setCursor(2,0);
  lcd2.print("Material's");
  lcd2.setCursor(2,1);
  lcd2.print("Engineering");
  delay(10000);
  lcd.clear();
  lcd2.clear();

  
  //Display messages for (0x3F) 20 by 4 LCD
  lcd.backlight();
  lcd.begin(20,4);
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("Pin A");
  lcd.setCursor(17,0);
  lcd.print("mm");
  lcd.setCursor(0,1);
  lcd.print("Pin B");
  lcd.setCursor(17,1);
  lcd.print("mm");
  lcd.setCursor(0,2);
  lcd.print("Pin C");
  lcd.setCursor(17,2);
  lcd.print("mm");
  lcd.setCursor(0,3);
  lcd.print("MOTOR Speed");
  lcd.setCursor(17,3);
  lcd.print("RPM");


//Display messages for (0x3E) 16 by 2 LCD
  lcd2.begin(16,2);
  lcd2.backlight();
  lcd2.setCursor(0, 0);
  lcd2.print("No of Cycles:");
  lcd2.setCursor(0,1);
  
}

void loop() {


   static int number = 0;
  char key = keypad.waitForKey();
   switch(key)
   {
       case '0'...'9':
          number *= 10;
          number += key - '0';
          break;

       case 'A':
          useForCaseA(number);
          number = 0;
          break;

       case 'B':
          useForCaseB(number);
          number = 0;     
          break;

       case 'C':
          useForCaseC(number);
          number = 0;
          break;

       case 'D':
          useForCaseD(number);
          number = 0;
          break;
          
       case '*': // Set Home Position
          break;

       case '#': // Move Motors on Position and Start Test
          break;

          
   }
}

void useForCaseA(int num){ 
 valueA = num;
 if((valueA >= 1) && (valueA <= 600)){
 lcd.setCursor(10,0);
 lcd.print("       ");
 lcd.setCursor(10,0);
 lcd.print(valueA);

 }else{
 lcd.setCursor(10,0);
 lcd.print("       ");
 lcd.setCursor(10,0);
 lcd.print(valueA); 
 valueA=0;
 ErrorMessage();
 lcd.setCursor(10,0);
 lcd.print("       ");
 lcd.setCursor(10,0);
 lcd.print(valueA);
 }
}

void useForCaseB(int num){ 
 valueB = num;
 if((valueB >= 1) && (valueB <= 600)){
 lcd.setCursor(10,1);
 lcd.print("       ");
 lcd.setCursor(10,1);
 lcd.print(valueB);

 }else{
 lcd.setCursor(10,1);
 lcd.print("       ");
 lcd.setCursor(10,1);
 lcd.print(valueB); 
 valueB=0;
 ErrorMessage();
 lcd.setCursor(10,1);
 lcd.print("       ");
 lcd.setCursor(10,1);
 lcd.print(valueB);
 }
}


void useForCaseC(int num){ 
 valueC = num;
 if((valueC >= 1) && (valueC <= 600)){
 lcd.setCursor(10,2);
 lcd.print("       ");
 lcd.setCursor(10,2);
 lcd.print(valueC);
 
 }else{
 lcd.setCursor(10,2);
 lcd.print("       ");
 lcd.setCursor(10,2);
 lcd.print(valueC); 
 valueC=0;
 ErrorMessage();
 lcd.setCursor(10,2);
 lcd.print("       ");
 lcd.setCursor(10,2);
 lcd.print(valueC);
 }
}


void useForCaseD(int num){ 
 valueD = num;
 if((valueD >= 100) && (valueD <= 600)){
 lcd.setCursor(13,3); 
 lcd.print("    ");
 lcd.setCursor(13,3);
 lcd.print(valueD);
 
 }else{
 lcd.setCursor(13,3);
 lcd.print("    ");
 lcd.setCursor(13,3);
 lcd.print(valueD); 
 valueD=0;
 ErrorMessage();
 lcd.setCursor(13,3);
 lcd.print("    ");
 lcd.setCursor(13,3);
 lcd.print(valueD);
 lcd.setCursor(17,3);
 lcd.print("RPM");
 }
}


void ErrorMessage(){
  //Display messages for (0x3E) 16 by 2 LCD
  lcd2.clear();
  lcd2.setCursor(2,0);
  lcd2.print("Error Check");
  lcd2.setCursor(1,1);
  lcd2.print("Values Entered");
  delay(10000);
  lcd2.clear();
  lcd2.begin(16,2);
  lcd2.backlight();
  lcd2.setCursor(0, 0);
  lcd2.print("No of Cycles:");
}