How to get keypad buttons running continuous loop until condition is met

Hi,

I'm very new to programming and I'm working on a project for school. Basically, I'm using a keypad and a servo motor for this part. The goal here is that if I press a certain number on the keypad, the servo motor turns on and goes at a certain speed continuously unless another number is pressed. At the moment, I have it so that when I press those buttons, the motor does go at the speed I want but does not do it continuously and I need to press the button again to get it going again.
How do I make the motor run continuously at one speed until another button is pressed??

Here's the code I have s far:

#include <Keypad.h>
#include <Servo.h>


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','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {A15, A14, A13, A12}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {A11, A10, A9, A8}; //connect to the column pinouts of the keypad

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

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards
char customKey = customKeypad.getKey();
int pos = 0;

void setup(){
  Serial.begin(9600);
  myservo.attach(8);
}


void level_One(){  //slow servo motor speed

    //Serial.print("keypad");
    //Serial.println(customKey);
          for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
            // in steps of 1 degree
          myservo.write(pos);              // tell servo to go to position in variable 'pos'
          delay(15);                       // waits 15 ms for the servo to reach the position
          }
          for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
          myservo.write(pos);              // tell servo to go to position in variable 'pos'
          delay(15);  
  }
}

void level_Two(){ //medium servo motor speed

    //Serial.print("keypad");
    //Serial.println(customKey);
          for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
            // in steps of 1 degree
          myservo.write(pos);              // tell servo to go to position in variable 'pos'
          delay(10);                       // waits 15 ms for the servo to reach the position
          }
          for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
          myservo.write(pos);              // tell servo to go to position in variable 'pos'
          delay(10);  
  }
}

void level_Three(){  //fast servo motor speed

    //Serial.print("keypad");
    //Serial.println(customKey);
          for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
            // in steps of 1 degree
          myservo.write(pos);              // tell servo to go to position in variable 'pos'
          delay(5);                       // waits 15 ms for the servo to reach the position
          }
          for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
          myservo.write(pos);              // tell servo to go to position in variable 'pos'
          delay(5);  
  }
}

void loop(){
 
 // char customKey = customKeypad.getKey(); 

 char customKey = customKeypad.getKey();
  
  if (customKey){
    Serial.println(customKey);
  }
  delay(20);
      switch (customKey){
          
      case '1': 
          level_One();
          break;

      case '2':
          level_Two();
          break;

      case '3':
          level_Three();
          break;
        }  
        
        
        
      return 0;
}

Don't use for-loops (or while-loops) and don't use delays. Use a millis() based approach. The guide in Having trouble understanding how to convert from delay to millis - #8 by sterretje demonstrates how to approach the conversion from a for-loop with delays to a millis() based approach (the code was not compiled nor tested).

#include <Keypad.h>
#include <Servo.h>


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', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {A15, A14, A13, A12}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {A11, A10, A9, A8}; //connect to the column pinouts of the keypad

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

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards
int pos = 0;

void setup() {
  Serial.begin(9600);
  myservo.attach(8);
}

void loop() {
  static uint32_t previousMillis = 0;
  static byte DELAy = 15;
  static bool DIR = true;
  char customKey = customKeypad.getKey();

  if (customKey != NO_KEY)Serial.println(customKey);
  if (customKey > '0' && customKey < '4')DELAy = (customKey - '0') * 5;

  if (millis() - previousMillis >= DELAy) {
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    previousMillis += DELAy;
    if (DIR)pos++;
    else pos--;
    if (pos == 0)DIR = true;
    if (pos == 180)DIR = false;
  }
}

Hello renwillow

Welcome to the world's best Arduino forum ever.

Take a view to these modifications of your sketch:

#include <Keypad.h>
#include <Servo.h>
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
constexpr uint8_t ServoPin {9};
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] =
{
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'},
};
byte rowPins[ROWS] = {A15, A14, A13, A12}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {A11, A10, A9, A8}; //connect to the column pinouts of the keypad
//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards
char customKey = customKeypad.getKey();
int pos = 0;
void setup()
{
  Serial.begin(9600);
  myservo.attach(ServoPin);
}
void loop()
{
  static uint32_t interval = 20;
  char customKey = customKeypad.getKey();
  if (customKey)
  {
    Serial.println(customKey);
  }
  switch (customKey)
  {
    case '1':
      interval = 15;
      break;
    case '2':
      interval = 10;
      break;
    case '3':
      interval = 5;
      break;
  }
  //------
  uint32_t currentMillis = millis();
  static uint32_t previousMillis = 0;
  if (currentMillis - previousMillis >= interval)
  {
    static uint8_t direction = 0;
    static uint16_t pos = 0;
    previousMillis = currentMillis;
    (direction == 0) ? myservo.write(++pos) : myservo.write(--pos);
    if ((pos == 0) or (pos == 180)) direction = direction ? LOW : HIGH, Serial.println(direction ? "angle+" : "angle-");
  }
}

Have a nice day and enjoy coding in C++.

Amazing, thank you! It's working now!

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.