Stepper Controller with Keypad and LCD

Hello everyone.

Im building a stepper controller to test a few stepper motors I have and because Im kinda new I would like to spice it up by adding a keypad to enter the stepper info and desired speed/distance and a 2 line LCD to display the entries and monitor the output to the stepper. I have played with both the keypad and lcd4bit libraries in the past but never used them together. I know I have a long way to go, but I just started getting my code ideas down. I like to compile and check for errors as I write the code so it doesnt take so long in the end. I have a few issues that I am curious to see what the veterans here have to say about them.

Here's my code so far (far from finished):

#include <LCD4Bit.h>
#include <Keypad.h>

LCD4Bit lcd = LCD4Bit(2); 
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','+'},
  {'4','5','6','-'},
  {'7','8','9','<'},
  {'C','0','.','E'}
};
byte rowPins[ROWS] = {3, 2, 1, 0}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {7, 6, 5, 4}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad cusomKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

int totalSteps = 0;
int stepSpeed = 0;
int entrydone = 0;
String entry = "";

void setup(){
  lcd.init();
  lcd.clear();
  Serial.begin(9600);
}

void loop(){
//EnterSteps();
//EnterSpeed(); 
}

void GetEntry(){
entrydone = 0;
  if (entrydone = 0){
    char key = cusomKeypad.getKey();
       if (key != NO_KEY){
          switch (key) {
            case '+':
            break;
            case '-':
            break;
            case '<':
            break;
            case 'C':
               lcd.clear();
               lcd.cursorTo(1, 0);
               entry = "000";
               lcd.printIn("Entry Cleared");
            break;
            case '.':
               lcd.clear();
               lcd.cursorTo(1, 0);
               lcd.printIn("Invalid Keypress");
               delay(1000);
            break;
            case 'E':
               if (entry == "000"){
                  lcd.clear();
                  lcd.cursorTo(1, 0);
                  lcd.printIn("Invalid Entry");
                  delay(1000);
                  //possible break needed here?
               }
               else {
                  entrydone++;
               }
            break;
            
    }
  //lcd.printIn(" " + key);
  entry = String(entry + key);
   }
  }
 }
  void EnterSteps(){
  if (totalSteps != 0){
  lcd.clear();
  lcd.cursorTo(1, 0);
  lcd.printIn("Enter Steps Per");
  lcd.cursorTo(2, 0);
  lcd.printIn("Revolution:");
  lcd.cursorTo(2, 12);
  GetEntry();
  if (entrydone = 1){
     int x = atoi(entry);
     totalSteps = x;
  }
 }
}
  void EnterSpeed(){
  if (Speed != 0){
  lcd.clear();
  lcd.cursorTo(1, 0);
  lcd.printIn("Enter Stepper");
  lcd.cursorTo(2, 0);
  lcd.printIn("Speed:");
  lcd.cursorTo(2, 12);
  GetEntry();
  if (entrydone = 1){
     int holder = atoi(entry);
     stepSpeed = holder;
  }
 }
} 
    
  
  
  
}

Currently the errors that I am trying to resolve are where the variables that contain the combined keypad numbers are displayed to the LCD and are set to the variables required by the libraries. I understand the stepper library isn't included yet but im workin on it after the code here is all set.

Here s my error:

sketch_feb16a.cpp: In function 'void EnterSteps()':
sketch_feb16a:88: error: cannot convert 'String' to 'const char*' for argument '1' to 'int atoi(const char*)'

I searched here and found a few previous issues similar to what I have here but I dont really understand the explanations given to the individuals having the problem. I assume its a problem with syntax and I tried a few solutions as they were written for others with no luck. I appreciate any input and I will repost code as this project comes together better in the future.

1 Like

Ok, I added a lot more code in tonight. Here's the updated sketch:

#include <Stepper.h>
#include <LCD4Bit.h>
#include <Keypad.h>

LCD4Bit lcd = LCD4Bit(2); 
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','+'},
  {'4','5','6','-'},
  {'7','8','9','<'},
  {'C','0','.','E'}
};
byte rowPins[ROWS] = {3, 2, 1, 0}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {7, 6, 5, 4}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad cusomKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

const int stepsPerRevolution = 200;
Stepper myStepper(stepsPerRevolution, 8,9,10,11);   //can i change 'stepsPerRevolution' after init from main loop or setup?
                                                    //If I did it from setup would I have to reset somehow?   
                                                    
int stepsToGo = 0;         // number of steps the motor has/will take
int stepsToGoOK = 0;
int totalSteps = 0;        //Total number of steps, later used as 'stepsPerRevolution'
int totalStepsOK = 0;
int stepSpeed = 0;         // holds stepper speed entry from keypad
int stepSpeedOK = 0;
int entrydone = 0;         //indicator to tell me that an entry is completed
int toggleReverse = 0;
int runCount = 0;
String entry = "";         //combined keypad characters to form a int for values

void setup(){
  lcd.init();
  lcd.clear();
  Serial.begin(9600);   //for debugging, first time attempting using serial in this manner
}

void loop(){
int a = 0;
  while (totalStepsOK < 1) {
    EnterSteps();}
  while (stepSpeedOK < 1) {
    EnterSpeed();}
  while (stepsToGoOK < 1) {
    StepsToGo();}
  while (runCount = 0);
    RunCounter();
         if (runCount > 0) {
         lcd.clear();
         lcd.cursorTo(1, 0);
         lcd.printIn("Motor Initialize");
         lcd.cursorTo(2, 0);
         delay(1000);
         while (runCount > 0) {
            motorStart();
            runCount--;
         }
        }
}


void GetEntry(){  //universal entry getter to be called on for values
entrydone = 0;
  if (entrydone = 0){
    char key = cusomKeypad.getKey();
       if (key != NO_KEY){
          switch (key) {
            case '+':  //would like to later use + and - as increment/decrement
            break;
            case '-':
               if (totalStepsOK = 1) {
                  if (stepSpeedOK = 1) {
                      if (toggleReverse = 0){
                         toggleReverse = 1;
                         }
                      if (toggleReverse = 1){
                         toggleReverse = 0;
                      }
                  }
               }
            break;
            case '<':
            break;
            case 'C':
               lcd.clear();
               lcd.cursorTo(1, 0);
               entry = "000";
               lcd.printIn("Entry Cleared");
            break;
            case '.':
               lcd.clear();
               lcd.cursorTo(1, 0);
               lcd.printIn("Invalid Keypress");
               delay(1000);
            break;
            case 'E':
               if (entry == "000"){
                  lcd.clear();
                  lcd.cursorTo(1, 0);
                  lcd.printIn("Invalid Entry");
                  delay(1000);
                  //possible break needed here?
               }
               else {
                  entrydone++;
                  Serial.print("Entry Completed");
               }
            break;
            
    }
  //lcd.printIn(" " + key);
  Serial.println(key);
  entry = String(entry + key);
   }
  }
 }
  void EnterSteps(){ //To get the Total number of steps per revolution of motor under test
  int x;
  if (totalSteps != 0){
  lcd.clear();
  lcd.cursorTo(1, 0);
  lcd.printIn("Enter Steps Per");
  lcd.cursorTo(2, 0);
  lcd.printIn("Revolution:");
  lcd.cursorTo(2, 12);
  GetEntry();
  if (entrydone = 1){
     //int x = atoi(entry);
     totalSteps = x;
  Serial.print("EnterSteps ok");
  }
 }
}
  void EnterSpeed(){ //To get motor Speed (Range - 0 to ???) range has to be filtered to usable values
  int y;
  lcd.clear();
  lcd.cursorTo(1, 0);
  lcd.printIn("Enter Stepper");
  lcd.cursorTo(2, 0);
  lcd.printIn("Speed:");
  lcd.cursorTo(2, 12);
  GetEntry();
  if (entrydone = 1){
     //int y = atoi(entry);
     stepSpeed = y;
   Serial.println("EnterSpeed ok");
  }
 }
  void StepsToGo(){
  lcd.clear();
  lcd.cursorTo(1, 0);
  lcd.printIn("Enter Steps to Go");
  lcd.cursorTo(2, 0);
  lcd.printIn("(- for rev)");
  lcd.cursorTo(2, 12);
  GetEntry();
  }
  
  void RunCounter(){
  lcd.clear();
  lcd.cursorTo(1, 0);
  lcd.printIn("Enter Number of");
  lcd.cursorTo(2, 0);
  lcd.printIn("Motor Runs:");
  lcd.cursorTo(2, 12);
  GetEntry();
  if (entry > 0){
     entry = runCount;
  }
  else{
     lcd.clear();
     lcd.cursorTo(1, 0);
     lcd.printIn("Need + Run Count");
  }
  }
  
  void motorStart() {  //I want to move-it move-it! lol
  if (toggleReverse = 1){
     myStepper.step(-stepsToGo);
  }
  else{
     myStepper.step(stepsToGo);
  }
}

All I need is the solution to the char* conversion error from before where I commented the code conversions for the sake of checking the remaining code for errors. There's a good amount here but I still have more things to check and make sure they work correctly as I am new to this and things never work first shot lol.

Let me know what you think like, tips and suggestions and stuff. I appreciate it.

1 Like

It's hard to help you if you don't tell us where the line 88 was in the code. Compile, then report which line is creating the problem. Quote the entire line in your post so we can use ctrl+f to search your code to locate where it is. The "insert code" on the forum doesn't generate line numbers. I hate to count 88 lines.

  if (toggleReverse = 1){ There is your first error, to compare two items, you use == , what you have done here is set toggleReverse to 1. This will never return a value so will never be true.
while (runCount = 0); Same Issue again.

  if (entrydone = 1){
     int holder = atoi(entry);

Again, but this time, you are trying to convert entry (a string) to an int (holder) using atoi, atoi needs a char, not a string.

Someone help me here, but I also think that the Case statement is designed for numbers, not characters.

Thank you very much.

I will change those so they dont give me a problem later on. Im working now but I should be able to update the code when I get home. I may write some of it while im here at lunch. I appreciate all help and reccommendations as this is my first "big" project aside from just messing with sample sketches (I did this for a long time though).

ok, I fixed the comparison =='s as mentioned previously (Thanks for that) and added some comments to the top as to what is left.

Here is the code as it stands now (still workin on it lol)

//Josh Nolan
//Stepper Controller
//Started 2/10/11

//Things left:
// 1)find a fix that will convert the numeric keypad entried to integers so they can be used
//   by the subroutines and strings so they can be displayed on the LCD as they are entered.
//
// 2)fix the motor start part.  Maybe have something like "Vals ok, Press enter to start!"
//   
// 3)look into how this thing is going to act after the motor runs finish.  can I hold the 
//   steps per full revolution value and reset the others for reentry? or reset the whole
//   thing?
//
// 4)figure out the pin assignments and build it up.  If I can use an 328 I will, if not Ill
//   hook it up to the Mega.



#include <Stepper.h>
#include <LCD4Bit.h>
#include <Keypad.h>

LCD4Bit lcd = LCD4Bit(2); 
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','+'},
  {'4','5','6','-'},
  {'7','8','9','<'},
  {'C','0','.','E'}
};
byte rowPins[ROWS] = {3, 2, 1, 0}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {7, 6, 5, 4}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad cusomKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

const int stepsPerRevolution = 200;
Stepper myStepper(stepsPerRevolution, 8,9,10,11);   //can i change 'stepsPerRevolution' after init from main loop or setup?
                                                    //If I did it from setup would I have to reset somehow?   
                                                    
int stepsToGo = 0;         // number of steps the motor has/will take
int stepsToGoOK = 0;
int totalSteps = 0;        //Total number of steps, later used as 'stepsPerRevolution'
int totalStepsOK = 0;
int stepSpeed = 0;         // holds stepper speed entry from keypad
int stepSpeedOK = 0;
int entrydone = 0;         //indicator to tell me that an entry is completed
int toggleReverse = 0;
int runCount = 0;
String entry = "";         //combined keypad characters to form a int for values

void setup(){
  lcd.init();
  lcd.clear();
  Serial.begin(9600);   //for debugging, first time attempting using serial in this manner
}

void loop(){
  while (totalStepsOK < 1) {
    EnterSteps();}
  while (stepSpeedOK < 1) {
    EnterSpeed();}
  while (stepsToGoOK < 1) {
    StepsToGo();}
  while (runCount == 0);
    RunCounter();}
    
  if (runCount > 0) {
  lcd.clear();
  lcd.cursorTo(1, 0);
  lcd.printIn("Step Initialized");
  lcd.cursorTo(2, 0);
  delay(1000);
  while (runCount > 0) {
     lcd.cursorTo(2, 0);
     lcd.printIn(runcount);
     lc
            motorStart();
            runCount--;
         }
        }
char key = cusomKeypad.getKey();
  if (key != NO_KEY){
     switch (key) {
            case 'E':  //would like to later use + and - as increment/decrement
            lcd.clear();
            lcd.cursorTo(1, 0);
            lcd.printIn("-Ready to Run-")
            delay(1000);
            lcd.cursorTo(2, 0);
            lcd.printIn("(ENTER to Start)") 
            break;
            case 'C':
            
            break;
     }
  }
}


void GetEntry(){  //universal entry getter to be called on for values
entrydone = 0;
  if (entrydone == 0){
    char key = cusomKeypad.getKey();
       if (key != NO_KEY){
          switch (key) {
            case '+':  //would like to later use + and - as increment/decrement
            break;
            case '-':
               if (totalStepsOK == 1) {
                  if (stepSpeedOK == 1) {
                      if (toggleReverse == 0){
                         toggleReverse = 1;
                         }
                      if (toggleReverse == 1){
                         toggleReverse = 0;
                      }
                  }
               }
            break;
            case '<':
            break;
            case 'C':
               lcd.clear();
               lcd.cursorTo(1, 0);
               entry = "000";
               lcd.printIn("Entry Cleared");
            break;
            case '.':
               lcd.clear();
               lcd.cursorTo(1, 0);
               lcd.printIn("Invalid Keypress");
               delay(1000);
            break;
            case 'E':
               if (entry == "000"){
                  lcd.clear();
                  lcd.cursorTo(1, 0);
                  lcd.printIn("Invalid Entry");
                  delay(1000);
                  //possible break needed here?
               }
               else {
                  entrydone++;
                  Serial.print("Entry Completed");
               }
            break;
            
    }
  //lcd.printIn(" " + key);
  Serial.println(key);
  entry = String(entry + key);
   }
  }
 }
  void EnterSteps(){ //To get the Total number of steps per revolution of motor under test
  int x;
  if (totalSteps != 0){
  lcd.clear();
  lcd.cursorTo(1, 0);
  lcd.printIn("Enter Steps Per");
  lcd.cursorTo(2, 0);
  lcd.printIn("Revolution:");
  lcd.cursorTo(2, 12);
  GetEntry();
  if (entrydone == 1){
     //int x = atoi(entry);
     totalSteps = x;
  Serial.print("EnterSteps ok");
  }
 }
}
  void EnterSpeed(){ //To get motor Speed (Range - 0 to ???) range has to be filtered to usable values
  int y;
  lcd.clear();
  lcd.cursorTo(1, 0);
  lcd.printIn("Enter Stepper");
  lcd.cursorTo(2, 0);
  lcd.printIn("Speed:");
  lcd.cursorTo(2, 12);
  GetEntry();
  if (entrydone == 1){
     //int y = atoi(entry);
     stepSpeed = y;
   Serial.println("EnterSpeed ok");
  }
 }
  void StepsToGo(){
  lcd.clear();
  lcd.cursorTo(1, 0);
  lcd.printIn("Enter Steps to Go");
  lcd.cursorTo(2, 0);
  lcd.printIn("(- for rev)");
  lcd.cursorTo(2, 12);
  GetEntry();
  }
  
  void RunCounter(){
  lcd.clear();
  lcd.cursorTo(1, 0);
  lcd.printIn("Enter Number of");
  lcd.cursorTo(2, 0);
  lcd.printIn("Motor Runs:");
  lcd.cursorTo(2, 12);
  GetEntry();
  if (entry > 0){
     entry = runCount;
  }
  else{
     lcd.clear();
     lcd.cursorTo(1, 0);
     lcd.printIn("Need + Run Count");
  }
  }
  
  void motorStart() {  //I want to move-it move-it! lol
  if (toggleReverse = 1){
     myStepper.step(-stepsToGo);
  }
  else{
     myStepper.step(stepsToGo);
  }
}

Update:

lots fixed from last post. Also here's a screenshot of an error I get while trying to send some text and a string to the LCD with atoi():

//Josh Nolan
//Stepper Controller
//Started 2/10/11

//Things left:
// 1)find a fix that will convert the numeric keypad entried to integers so they can be used
//   by the subroutines and strings so they can be displayed on the LCD as they are entered.
//
// 2)fix the motor start part.  Maybe have something like "Vals ok, Press enter to start!"
//   
// 3)look into how this thing is going to act after the motor runs finish.  can I hold the 
//   steps per full revolution value and reset the others for reentry? or reset the whole
//   thing?
//
// 4)figure out the pin assignments and build it up.  If I can use an 328 I will, if not Ill
//   hook it up to the Mega.



#include <Stepper.h>
#include <LCD4Bit.h>
#include <Keypad.h>

LCD4Bit lcd = LCD4Bit(2); 
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','+'},
  {'4','5','6','-'},
  {'7','8','9','<'},
  {'C','0','.','E'}
};
byte rowPins[ROWS] = {3, 2, 1, 0}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {7, 6, 5, 4}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad cusomKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

const int stepsPerRevolution = 200;
Stepper myStepper(stepsPerRevolution, 8,9,10,11);   //can i change 'stepsPerRevolution' after init from main loop or setup?
                                                    //If I did it from setup would I have to reset somehow?   
                                                    
int stepsToGo = 0;         // number of steps the motor has/will take
int stepsToGoOK = 0;
int totalSteps = 0;        //Total number of steps, later used as 'stepsPerRevolution'
int totalStepsOK = 0;
int stepSpeed = 0;         // holds stepper speed entry from keypad
int stepSpeedOK = 0;
int entrydone = 0;         //indicator to tell me that an entry is completed
int toggleReverse = 0;
int runCount = 0;
int motorFinished = 0;
String entry = "";         //combined keypad characters to form a int for values

void setup(){
  lcd.init();
  lcd.clear();
  Serial.begin(9600);   //for debugging, first time attempting using serial in this manner
}

void loop(){
  while (totalStepsOK < 1) {    //run each routine until a suitable value is obtained, then on to the next
    EnterSteps();}
  while (stepSpeedOK < 1) {
    EnterSpeed();}
  while (stepsToGoOK < 1) {
    StepsToGo();}
  while (runCount == 0);{
    RunCounter();}
    
  if (totalStepsOK == 1){
     if (stepSpeedOK == 1){
        if (stepsToGoOK == 1){
           if (runCount != 0) {
              if (motorFinished == 0) {
                 //Motor is ready to run
                 lcd.clear();
                 lcd.cursorTo(1, 0);
                 lcd.printIn("Values Ready!");
                 delay(1000);
                 lcd.clear();
                 lcd.cursorTo(1, 0);
                 lcd.printIn("ENTER To Start");
                 lcd.cursorTo(2, 0);
                 lcd.printIn("CLEAR To Reset");
                 char key = cusomKeypad.getKey();
                    if (key != NO_KEY){
                       switch (key) {
                          case 'E':  //would like to later use + and - as increment/decrement
                          while (runCount > 0){
                             lcd.clear();
                             lcd.cursorTo(1, 0);
                             lcd.printIn("Stepper Running!");
                             lcd.cursorTo(2, 0);
                             lcd.printIn("Runs To Go:  " + atoi(runCount));
                             motorStart();
                             delay(1000);
                             runCount--;
                             if (runCount = 0) {
                                motorFinished = 1;
                             }
                          }
                          break;
                          case 'C':
                             lcd.clear();
                             lcd.cursorTo(1, 0);
                             lcd.printIn("Values Cleared!");
                             stepsToGo = 0; 
                             stepsToGoOK = 0;
                             totalSteps = 0;
                             totalStepsOK = 0;
                             stepSpeed = 0;
                             stepSpeedOK = 0;
                             entrydone = 0;
                             toggleReverse = 0;
                             runCount = 0;
                             motorFinished = 0;
                             entry = "";
                          break;
       }
      }
     }
    }
   }
  }
 }
}

void GetEntry(){  //universal entry getter to be called on for values
entrydone = 0;
  if (entrydone == 0){
    char key = cusomKeypad.getKey();
       if (key != NO_KEY){
          switch (key) {
            case '+':  //would like to later use + and - as increment/decrement
            break;
            case '-':
               if (totalStepsOK == 1) {
                  if (stepSpeedOK == 1) {
                      if (toggleReverse == 0){
                         toggleReverse = 1;
                         }
                      if (toggleReverse == 1){
                         toggleReverse = 0;
                      }
                  }
               }
            break;
            case 'C':
               lcd.clear();
               lcd.cursorTo(1, 0);
               entry = "000";
               lcd.printIn("Entry Cleared");
            break;
            case '.':
               lcd.clear();
               lcd.cursorTo(1, 0);
               lcd.printIn("Invalid Keypress");
               delay(1000);
            break;
            case 'E':
               if (entry == "000"){
                  lcd.clear();
                  lcd.cursorTo(1, 0);
                  lcd.printIn("Invalid Entry");
                  delay(1000);
                  //possible break needed here?
               }
               else {
                  entrydone++;
                  Serial.print("Entry Completed");
               }
            break;
            
    }
  //lcd.printIn(" " + key);
  Serial.println(key);
  entry = String(entry + key);
   }
  }
 }
 
  void EnterSteps(){ //To get the Total number of steps per revolution of motor under test
  int x;
  if (totalSteps != 0){
  lcd.clear();
  lcd.cursorTo(1, 0);
  lcd.printIn("Enter Steps Per");
  lcd.cursorTo(2, 0);
  lcd.printIn("Revolution:");
  lcd.cursorTo(2, 12);
  GetEntry();
  if (entrydone == 1){
     //int x = atoi(entry);
     totalSteps = x;
  Serial.print("EnterSteps ok");
  }
 }
}

  void EnterSpeed(){ //To get motor Speed (Range - 0 to ???) range has to be filtered to usable values
  int y;
  lcd.clear();
  lcd.cursorTo(1, 0);
  lcd.printIn("Enter Stepper");
  lcd.cursorTo(2, 0);
  lcd.printIn("Speed:");
  lcd.cursorTo(2, 12);
  GetEntry();
  if (entrydone == 1){
     //int y = atoi(entry);
     stepSpeed = y;
   Serial.println("EnterSpeed ok");
  }
 }
 
  void StepsToGo(){
  lcd.clear();
  lcd.cursorTo(1, 0);
  lcd.printIn("Enter Steps to Go");
  lcd.cursorTo(2, 0);
  lcd.printIn("(- for rev)");
  lcd.cursorTo(2, 12);
  GetEntry();
  }
  
  void RunCounter(){
  lcd.clear();
  lcd.cursorTo(1, 0);
  lcd.printIn("Enter Number of");
  lcd.cursorTo(2, 0);
  lcd.printIn("Motor Runs:");
  lcd.cursorTo(2, 12);
  GetEntry();
  if (entry > 0){
     entry = runCount;
  }
  else{
     lcd.clear();
     lcd.cursorTo(1, 0);
     lcd.printIn("Need + Run Count");
  }
  }
  
  void motorStart() {  //I want to move-it move-it! lol
  if (toggleReverse = 1){
     myStepper.step(-stepsToGo);
  }
  else{
     myStepper.step(stepsToGo);
  }
}

Here's another error I get, again with the conversions of the entry recieved from the keypad (string) to a usable numeric value (integer) I just cant seem to figure this one out, but I need it in a few places. Really need some help on this...

The first one was simply not C or C++, it is a BASIC or Java format. You can't use a "+" to concatenate strings or convert numbers to strings and concatenate them. You may have indulged yourself with Java too much, but to use C or C++, you should use:

sprintf(target_string, format, list of parameters);
like:

sprintf(out_str, "%s %d", "Runs to go", runCount);
Then you can lcd.print(out_str);

You should check this link:

http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/

The second one, you simply can't do that. READ the reference of atoi()

http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/

Thanks for the reply. and yes I have played with some java and BASIC recently lol.

So, there's no way that I can start a string variable, and add a numeral every keypress for instance:

(pressed 1)
x = "1"

(pressed 2)
x = "12"

(pressed 7)
x = "127"

(pressed Enter)
stepper.setspeed(x); for instance wont work because its a string, not an int.

and then somehow convert this string to an integer? I understand obviously that i cant give it a "-" or "." or anything not numeric, but I hope there's a way to convert this...

fliggygeek:
Again, but this time, you are trying to convert entry (a string) to an int (holder) using atoi, atoi needs a char, not a string.

Someone help me here, but I also think that the Case statement is designed for numbers, not characters.

So If I can convert single characters and not the whole string at once, would I be able to set up atoi() to convert each character on keypress before that number is added to the entry string (well, it would be int at that point if it can be done)

ok I think I have a solution to the big problem, the string->int conversion on keypress.

will this work you think?

void GetEntry(){  //universal entry getter to be called on for values
int keycombo = 0;
entrydone = 0;
  if (entrydone == 0){
    char key = cusomKeypad.getKey();
       if (key != NO_KEY){
          switch (key) {
            case '+':  //would like to later use + and - as increment/decrement
            break;
            case '-':
               if (totalStepsOK == 1) {
                  if (stepSpeedOK == 1) {
                      if (toggleReverse == 0){
                         toggleReverse = 1;
                         }
                      if (toggleReverse == 1){
                         toggleReverse = 0;
                      }
                  }
               }
            break;
            case 'C':
               lcd.clear();
               lcd.cursorTo(1, 0);
               entry = 000;
               lcd.printIn("Entry Cleared");
            break;
            case '.':
               lcd.clear();
               lcd.cursorTo(1, 0);
               lcd.printIn("Invalid Keypress");
               delay(1000);
            break;
            case 'E':
               if (entry == 000){
                  lcd.clear();
                  lcd.cursorTo(1, 0);
                  lcd.printIn("Invalid Value");
                  delay(1000);
               }
               else {
                  entrydone++;
                  Serial.print("Entry Completed");
               }
            break;
    }
  //lcd.printIn(" " + key);
  Serial.println(key);
  if (keycombo == 0);{  //first keypress
     keycombo = atoi(key);
  }
  else{
     keycombo = ((keycombo * 10) + atoi(key));
    }
   }
  }  
 }
entrydone = 0;
  if (entrydone == 0){

How can this test ever evaluate to false?

will this work you think?

No. I don't think it will. There is no looping going on. If no key is being pressed when that function is called, it will do nothing.

The function does not return a value. The only variables that it sets entrydone (global, why?), keycombo (local), key (local), totalStepsOK, stepSpeedOK, toggleReverse (all global) (Why? What do these have to do with collecting key board entry data?), and entry (global).

The entry global variable, to only one that makes any sense to be setting, is only set to 0.

Thanks thats good stuff.

ok, the entrydone is global because I wanted to use it to distinguish when an entry was ready. The problem is 1) the one you mentioned has been fixed (I hope). 2) I didnt use that variable anywhere else in the code where I wanted to, so I also fixed this by adding entrydone = 0 at the end of the functions so when getEntry() is called again it will be already set to 0. i removed the entrydone = 0 at the beginning of getEntry().

I see what you mean about the looping to get the keys. I will place the getKey() part inside of a while() so it loops like it should.

go easy on me in a noob lol

ok here's what im looking at. issues mentioned from that last comment have been revised (I think ;))

#include <Stepper.h>
#include <LCD4Bit.h>
#include <Keypad.h>

LCD4Bit lcd = LCD4Bit(2); 
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','+'},
  {'4','5','6','-'},
  {'7','8','9','<'},
  {'C','0','.','E'}
};
byte rowPins[ROWS] = {3, 2, 1, 0}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {7, 6, 5, 4}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad cusomKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

const int stepsPerRevolution = 200;
Stepper myStepper(stepsPerRevolution, 8,9,10,11);   //can i change 'stepsPerRevolution' after init from main loop or setup?
                                                    //If I did it from setup would I have to reset somehow?                                              
int stepsToGo = 0;         // number of steps the motor has/will take
int stepsToGoOK = 0;
int totalSteps = 0;        //Total number of steps, later used as 'stepsPerRevolution'
int totalStepsOK = 0;
int stepSpeed = 0;         // holds stepper speed entry from keypad
int stepSpeedOK = 0;
int entrydone = 0;         //indicator to tell me that an entry is completed
int toggleReverse = 0;
int runCount = 0;
int motorFinished = 0;
int entry = 000;         //combined keypad characters to form a int for values

void setup(){
  lcd.init();
  lcd.clear();
  Serial.begin(9600);   //for debugging, first time attempting using serial in this manner
}

void loop(){
  while (totalStepsOK < 1) {    //run each routine until a suitable value is obtained, then on to the next
    EnterSteps();}
  while (stepSpeedOK < 1) {
    EnterSpeed();}
  while (stepsToGoOK < 1) {
    StepsToGo();}
  while (runCount == 0);{
    RunCounter();}
    
  if (totalStepsOK == 1){
     if (stepSpeedOK == 1){
        if (stepsToGoOK == 1){
           if (runCount != 0) {
              if (motorFinished == 0) {
                 Stepper myStepper(totalSteps, 8,9,10,11); //set stepsPerRevolution
                 myStepper.setSpeed(stepSpeed); //set speed
                 //Motor is ready to run
                 lcd.clear();
                 lcd.cursorTo(1, 0);
                 lcd.printIn("Values Ready!");
                 delay(1000);
                 lcd.clear();
                 lcd.cursorTo(1, 0);
                 lcd.printIn("ENTER To Start");
                 lcd.cursorTo(2, 0);
                 lcd.printIn("CLEAR To Reset");
                 while (entrydone == 0);{
                    char key = cusomKeypad.getKey();
                    if (key != NO_KEY){
                       switch (key) {
                          case 'E':  //would like to later use + and - as increment/decrement
                          while (runCount > 0){
                             lcd.clear();
                             lcd.cursorTo(1, 0);
                             lcd.printIn("Stepper Running!");
                             lcd.cursorTo(2, 0);
                             //lcd.printIn(runCount); convert this to print to LCD
                             motorStart();
                             delay(1000);
                             runCount--;
                             if (runCount = 0) {
                                motorFinished = 1;
                                entrydone = 1;
                             }
                          }
                          break;
                          case 'C':
                             lcd.clear();
                             lcd.cursorTo(1, 0);
                             lcd.printIn("Values Cleared!");
                             stepsToGo = 0; 
                             stepsToGoOK = 0;
                             totalSteps = 0;
                             totalStepsOK = 0;
                             stepSpeed = 0;
                             stepSpeedOK = 0;
                             toggleReverse = 0;
                             runCount = 0;
                             motorFinished = 0;
                             entry = 0;
                             entrydone = 1;
                          break;
                          
        }
       }
      }
     }
    }
   }
  }
 }
}

void GetEntry(){  //universal entry getter to be called on for values
int keycombo = 0;
entry = 0;
while (entrydone == 0){
    char key = cusomKeypad.getKey();
       if (key != NO_KEY){
          switch (key) {
            case '+':  //would like to later use + and - as increment/decrement
            break;
            case '-':
               if (totalStepsOK == 1) {
                  if (stepSpeedOK == 1) {
                      if (toggleReverse == 0){
                         toggleReverse = 1;
                         }
                      if (toggleReverse == 1){
                         toggleReverse = 0;
                      }
                  }
               }
            break;
            case 'C':
               lcd.clear();
               lcd.cursorTo(1, 0);
               keycombo = 000;
               lcd.printIn("Entry Cleared");
            break;
            case '.':
               lcd.clear();
               lcd.cursorTo(1, 0);
               lcd.printIn("Invalid Keypress");
               delay(1000);
            break;
            case 'E':
               if (keycombo == 000){
                  lcd.clear();
                  lcd.cursorTo(1, 0);
                  lcd.printIn("Invalid Value");
                  delay(1000);
               }
               else {
                  entry = keycombo;
                  keycombo = 0;  //set to 0 to be ready for the next entry
                  Serial.print("Entry Completed");
                  entrydone = 1;
               }
            break;
    }
  //lcd.printIn(" " + key);
  Serial.println(key);
  if (keycombo == 0);{  //first keypress
     //keycombo = atoi(key);
  }
  }
  else{
     //keycombo = ((keycombo * 10) + atoi(key));
    }
   }
  }  


 
  void EnterSteps(){ //To get the Total number of steps per revolution of motor under test
  lcd.clear();
  lcd.cursorTo(1, 0);
  lcd.printIn("Enter Steps Per");
  lcd.cursorTo(2, 0);
  lcd.printIn("Revolution:");
  lcd.cursorTo(2, 12);
  entrydone = 0;
  GetEntry();
  if (entrydone == 1){
     totalSteps = entry;
  Serial.print("EnterSteps ok");
  }
  entrydone = 0;
 }


  void EnterSpeed(){ //To get motor Speed (Range - 0 to ???) range has to be filtered to usable values
  lcd.clear();
  lcd.cursorTo(1, 0);
  lcd.printIn("Enter Stepper");
  lcd.cursorTo(2, 0);
  lcd.printIn("Speed:");
  lcd.cursorTo(2, 12);
  entrydone = 0;
  GetEntry();
  if (entrydone == 1){
     stepSpeed = entry;
     Serial.println("EnterSpeed ok");
  }
  entrydone = 0;
 }
 
  void StepsToGo(){
  lcd.clear();
  lcd.cursorTo(1, 0);
  lcd.printIn("Enter Steps to Go");
  lcd.cursorTo(2, 0);
  lcd.printIn("(- = rev)");
  lcd.cursorTo(2, 12);
  entrydone = 0;
  GetEntry();
  if (entrydone == 1){
     stepsToGo = entry;
  }
  entrydone = 0;
  if (toggleReverse == 1){
     lcd.cursorTo(2, 11);
     lcd.printIn("-");
     //no need to set the - now because its done later on in motorStart()
   }
  }
  
  void RunCounter(){
  lcd.clear();
  lcd.cursorTo(1, 0);
  lcd.printIn("Enter Number of");
  lcd.cursorTo(2, 0);
  lcd.printIn("Motor Runs:");
  lcd.cursorTo(2, 12);
  entrydone = 0;
  GetEntry();
  if (entrydone == 1){
     runCount = entry;
  }
 }
  
  
  void motorStart() {  //I want to move-it move-it! lol
  if (toggleReverse = 1){
     myStepper.step(-stepsToGo);
  }
  else{
     myStepper.step(stepsToGo);
  }
}

Still not going to work. The { on the same line as the statement, and inconsistent indenting makes it very hard to see what GetEntry is doing. I copied it to Notepad++, moved each { to a new line, and fixed the indenting.

When a key is pressed, there are cases to deal with + (do nothing), - (hard to follow), C (set keycombo to 0), . (print error message), and E (set entry to keycombo, unless keycombo is 0).

If any other key is pressed, such as a number key, this is the code left that deals with that key:

void GetEntry()
{  //universal entry getter to be called on for values
	int keycombo = 0;
	entry = 0;
	while (entrydone == 0)
	{
		char key = cusomKeypad.getKey();
		if (key != NO_KEY)
		{
			//lcd.printIn(" " + key);
			Serial.println(key);
			if (keycombo == 0);
			{  //first keypress
				//keycombo = atoi(key);
			}
		}
		else
		{
			//keycombo = ((keycombo * 10) + atoi(key));
		}
	}
}

Lets presume that entrydone is 0. The code loops, doing nothing if there is no key pressed. When a key is pressed, say the 4, key is not NO_KEY, so the key press is printed to the serial port. Then, keycombo is tested. Nothing happens if keycombo is 0. Nothing happens if it isn't. That ; on the end is the body of the if test, and there is no else block.

There is no way to break out of the while loop, except by pressing E while keycombo is not 0, and there is no way to make keycombo have any value other than 0.

Create a new sketch. Copy the code before the start of loop(), and the GetEntry() method to that sketch. In loop, call GetEntry(), and print the value of all global variables (at least entry) when GetEntry() returns.

Work on the GetEntry() function until it does what it is supposed to, then use the revised GetEntry() function in this sketch.

I think you will quickly determine that GetEntry() should return a value, and that no global variables are needed.

ok I will try that as you said. I think the code that was left was stray code that I was supposed to remove...in any case, ill post back with what I come up with. Thank you very much for your help

1 Like

Hows the project going?

Could you correct the problem? How is the final code?

2 Likes