I need help writing a code that controls multiple servo motors using a matrix keypad

I'm new to arduino and I need help writing a code that controls (up to 12) servo motors using a matrix keypad. The servo motors I'm using are custom 360degree servo motors and I want them to be able to rotate (x)degrees when I click 2 digits on the matrix keypad.
This is my code so far.

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

Servo servo1;  // create servo object to control a servo
Servo servo2;
int servo = 11;

const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3', 'A'},
  {'4','5','6', 'B'},
  {'7','8','9', 'C'},
  {'*','0','#', 'D'}
};
char numbers[10] = {'0','1','2','3','4','5','6', '7', '8','9'}; 
byte rowPins[ROWS] = {24,25,26,27}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {28, 29, 30, 31}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup(){
  Serial.begin(9600);
  servo1.attach(2);  // attaches the servo on pin 9 to the servo object
  servo2.attach(3);
}

int toInt(char input) //converts chars to int for numbers
{
  int output;
  for (int i = 0; i < 10; i++)
  {
    if (input == numbers[i])
    {
      output = i;
    }
  }
  return output;
}
  
void loop(){
  char key[3];
  int keyNum;
  boolean isNumber;
  keyNum = 0;
  servo1.detach();
  

  for (int i= 0;i < 3; i++) // store three keys
  {
    key[i] = keypad.getKey();
    while (key[i] == NULL)
    {
      key[i] = keypad.getKey();
    }
    Serial.println(key[i]);
  }
  isNumber = false;
  for (int i= 0;i < 3; i++) // Check for numbers
  {
    if (key[i] >= '0' && key[i] <= '9')
    {
      
      keyNum = keyNum * 10 + toInt(key[i]);
      Serial.println("keyNum: ");
      Serial.println(keyNum);
      Serial.println("key,keyNum");
      Serial.println(key[i]);
      Serial.println(toInt(key[i]));
      if(i == 2) //if we have reach the third number with no problem start servo write
      {
        if (keyNum > 1 and keyNum < 2) //Start the rotation of Servo 1
        {
          keyNum = 1;
        }

        Serial.println("Write:");
        Serial.println(keyNum);
        servo1.attach(2);
        servo1.write(0);
        delay (300);
        servo1.write(90); 
        delay (3500);
      }
    }
    else
    {
      Serial.println("Not an number");
      break;
    }
  }
  
  
  
  
}


Post the code you have so far, pointing out the specific part you are having issues with.

do you have a feedback wire that gives you the absolute location/rotation of the horn?
link to the hardware or description of what you built would help (along with the code)

@omaralrawi

Assume that you have an Arduino UNO, a 4x4 matrix Keypad (Fig-1), and a SG-90 type Servo Motor. Connect them together as per Fig-1 and then create a sketch to turn the motor by 32 degrees which will be inputted from the Keypad. (If connecting more than one Servo, then use separate 5V supply.) Hints: Use Keypad.h and Servo.h Libraries and consult the examples that come with them.

Kbblk-5x
Figure-1:

@omaralrawi what is your actual question?

It’s a bad idea to recommend powering the servo through the arduino.

I think We should teach that motors require usually important current and you don’t want that current draw to go through the arduino.

In this case OP needs 12 motors so..

A single SG-90 takes about 220 mA (running/loaded?) and about 650 mA (at stalled). So, I respect your remark and accordingly, I have edited Fig-1 of post #4.

In the Lab during demonstration, I usually operate an unloaded Servo just for a while which I think permissible considering the 20 mA source current of the IO port line.

I have told OP to use separate 5V if using more than one Servos.

The servo-signal line takes maybe 1 mA. You can't power a servo from an IO-pin.
I think you mean if 10 IO-pins with each used with 20 mA makes up 200 mA so an unloaded servo should work. Still depends on the the voltages on the supply-jack. If you supply with 12V even the 200mA might be too much. Adding the low knowledge of newcomers about such things I allways recommend:
"as soon as you drive more than 3 LEDs use a extra power-supply"

to keep the unexperienced newcomers on the safe side and make them aware of there is a need for an extra power-supply

best regards Stefan

thats a bit extreme But gets the point across :wink:

The sketch as suggested by GolamMostafa

This is a Forum where a user has only an UNO and a PC. It is very unlikely that he will posses a separate power supply unit. In that case, he might be taught how to use the UNO power rails conservatively to avoid damage to the IO pins.

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

Servo servo1;  // create servo object to control a servo
Servo servo2;
int servo = 11;

const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
char numbers[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
byte rowPins[ROWS] = {24, 25, 26, 27}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {28, 29, 30, 31}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup() {
  Serial.begin(9600);
  servo1.attach(2);  // attaches the servo on pin 9 to the servo object
  servo2.attach(3);
}

int toInt(char input) //converts chars to int for numbers
{
  int output;
  for (int i = 0; i < 10; i++)
  {
    if (input == numbers[i])
    {
      output = i;
    }
  }
  return output;
}

void loop() {
  char key[3];
  int keyNum;
  boolean isNumber;
  keyNum = 0;
  servo1.detach();
  servo2.detach();


  for (int i = 0; i < 3; i++) // store three keys
  {
    key[i] = keypad.getKey();
    while (key[i] == NULL)
    {
      key[i] = keypad.getKey();
    }
    Serial.println(key[i]);
  }
  isNumber = false;
  for (int i = 0; i < 3; i++) // Check for numbers
  {
    if (key[i] >= '0' && key[i] <= '9')
    {

      keyNum = keyNum * 10 + toInt(key[i]);
      Serial.println("keyNum: ");
      Serial.println(keyNum);
      Serial.println("key,keyNum");
      Serial.println(key[i]);
      Serial.println(toInt(key[i]));
      if (i == 2) //if we have reach the third number with no problem start servo write
      {
        if (keyNum < 2 ) //manage the limit of rotation
        {
          keyNum = 1;
        }

        Serial.println("Write:");
        Serial.println(keyNum);
        servo1.attach(2);
        servo1.write(5000);
        delay (3000);
        servo1.detach();
        delay (5000);
      }
      else if (keyNum < 3 )
      {
        keyNum = 2;
      }
      Serial.println("Write:");
      Serial.println(keyNum);
      servo2.attach(3);
      servo2.write(5000);
      delay (3000);
      servo2.detach();
      delay (5000);

    }
    else
    {
      Serial.println("Not an number");
      break;
    }

  }




}


I have an external 5v and 12v power supplies for my project

If this is your very first project this is ambitious. You should do what each professional does:
subdivide it into easier parts.
This means:
Use an example code that just checks the function of a matrix-keypad to make sure you have the keypad wired correctly

Use an example-code that just moves a single servo back and forth to make sure you have the servo wired correctly.
After that start modifying the testcode to learn how to use the functions that control the servo

after that do it for 2 servos.

best regards Stefan

I do have a separate power supply to power everything up, I know this project requires alot of power

there is no need for a detach inside loop
detach will make the servo undefined

1 Like

I was able to make the code work for 1 servo where I make the servo do 3 continuous rotations when I type in 3 digits on the keypad, but after that I got stuck trying to make it work for a second servo.

This approach is perfectly in line with SSS Strategy (Small Start Strategy); where, a project is begun with a basic (simple and elementary) hardware and the associate software. After testing the basic unit, another incremental amount is added and tested. And so on ..., until the project is completed.

the value 5000 is way off the allowed range.
if you lookup the documentation

Writes a value to the servo, controlling the shaft accordingly. On a standard servo, this will set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous rotation servo, this will set the speed of the servo (with 0 being full-speed in one direction, 180 being full speed in the other, and a value near 90 being no movement).

So stopping the servo is done by a

servo2.write(90);

maybe you have to tweak the value.

A more precise method is to use the function

Again there is a allowed range that makes sense for the values
And as a general advice: rerad the documentation. If you have questions related to the documentation asking such a question show own effort and will be specific.
And for this kind of questions you will always get answers.
A comment like your title "need help writing code" makes a little skeptic
Then reading a very short description with no code makes even more sceptic.
fortunately you rescued the situation with posting your code.

best regards Stefan

What are the ampere ratings of these power supplies? If you are using 12xSG-90 Servos and they get stalled (extreme case), how much fault current the 5V supply must deliver for a minute?