Programming a robotic "Arm", class to control motors not working properly

Hello I'm new to programing and robotics. I have a project where I want to control a robotic "arm" this includes a dc motor to move a toothed belt which transports a gripper to different positions. The gripper is controlled via a micro servo.

I'm trying to use a class to initialize and control multiple robotic "arms". In the following code the dc motor moving the toothed belt works as intended but the servo does unexpected small and larger movements like wiggling or constant fast spinning. I have tried the code to control the servo (for loops to open and close the gripper) in a different sketch, and there it works fine as such I believe that the servo is not broken as I have tried my code with 2 separate servos.

Does someone know, where I have made a mistake?

#include <Adafruit_MotorShield.h>
#include <Servo.h>

Adafruit_MotorShield AFMS = Adafruit_MotorShield();


class Greif_system {
  
  private:
    Servo servo;
    Adafruit_DCMotor *dc_Motor;
    int position;
    int pos;
  
  public:
    //constructor
    Greif_system(int motor_pin , int servo_pin, Adafruit_MotorShield &motorShield){ 
      servo.attach(servo_pin);
      dc_Motor = motorShield.getMotor(motor_pin);
      position = 1;
      pos = 0;
    }

    /////////////
    //Move arm to different positions and always check, that the position starting from is correct
    /////////////

    void position_1_to_position_2(){
      if (position != 1){
        if (position == 3){
          position_3_to_position_2();
        }
        else{
          return;
        }
      }
      dc_Motor->setSpeed(100);
      dc_Motor->run(BACKWARD);
      delay(6000); 
      dc_Motor->setSpeed(0);
      position = 2;
    }

    void position_2_to_position_3(){
      if (position != 2){
        if (position == 1){
          position_1_to_position_3();
        }
        else{
          return; 
        }
      }
      dc_Motor->setSpeed(100);
      dc_Motor->run(BACKWARD);
      delay(6000); 
      dc_Motor->setSpeed(0);
      position = 3;
    }

    void position_1_to_position_3(){
      if (position != 1){
        if (position == 2){
          position_2_to_position_3();
        }
        else{
          return; 
        }
      }
      position_1_to_position_2();
      position_2_to_position_3();
      position = 3;
    }

    void position_3_to_position_2(){
      if (position != 3){
        if (position == 1){
          position_1_to_position_2();
        }
        else{
          return; 
        }
      }
      dc_Motor->setSpeed(100);
      dc_Motor->run(FORWARD);
      delay(6000); 
      dc_Motor->setSpeed(0);
      position = 2;
    }

    void position_2_to_position_1(){
      if (position != 2){
        if (position == 3){
          position_3_to_position_2();
          position_2_to_position_1();
        }
        else{
          return; 
        }
      }
      dc_Motor->setSpeed(100);
      dc_Motor->run(FORWARD);
      delay(6000); 
      dc_Motor->setSpeed(0);
      position = 1;
    }

    void position_3_to_position_1(){
      if (position != 3){
        if (position == 2){
          position_2_to_position_1();
        }
        else{
          return; 
        }
      }
      position_3_to_position_2();
      position_2_to_position_1();
      position = 1;
    }

    ///////////////////////
    //Gripper
    //////////////////////

    //close gripper
    void greifer_zu(){
      for (pos = 0; pos <= 75; pos++){
        servo.write(pos);
        delay(10);
      }
    }
    
    //open gripper
    void greifer_auf(){
      for (pos = 75; pos >= 0; pos--){
        servo.write(pos);
        delay(10);
      }
    }
    //neutral position for gripper 1
    void greifer_1_neutral(){
      servo.write(0);
    }
    //neutral position for gripper 2
    void greifer_2_neutral(){
      servo.write(50);
    }

};

//Initialise Objects
Greif_system Arm_rechts(4, 8, AFMS); 
Greif_system Arm_links(3, 10, AFMS);

void setup() {
  AFMS.begin();
  Arm_rechts.greifer_1_neutral(); //Set starting position of the servo
  delay(5000);
}

void loop() {
  Arm_rechts.position_1_to_position_2();
  delay(1000);
  Arm_rechts.greifer_zu(); //Close gripper
  delay(1000);
  Arm_rechts.position_2_to_position_1();
  delay(3000);
  Arm_rechts.position_1_to_position_3();
  delay(1000);
  Arm_rechts.greifer_auf(); //Open gripper
  delay(5000);
  Arm_rechts.position_3_to_position_1();
  delay(1000);
}

What specific servo are you using? I have seen some servos work correctly only in ranges from 10°-170°.

Also, share a diagram of your setup. A picture of a hand-drawn one will be enough.

I'm using a SG90 micro servo. It has worked with a range of 0 to 180 degrees in different small projects.


I hope this is what you meant.

Ahh, SG90…

Try changing the limit position to something other than zero. 30, for example.

If it ceases to work funny you will have to adjust the position of your servos so you can work with, say, 30-105.

Doesn't seem to work, now to servo makes a constant rumbling noise while the dc motor works as intended.

 void greifer_zu(){
      for (pos = 30; pos <= 105; pos++){
        servo.write(pos);
        delay(10);
      }
    }
    
    //open gripper
    void greifer_auf(){
      for (pos = 105; pos >= 30; pos--){
        servo.write(pos);
        delay(10);
      }
    }
    //neutral position for gripper 1
    void greifer_1_neutral(){
      servo.write(30);
    }

What kind of Arduino are you using

The servos must be controlled by a PWM pin. On the Arduino Uno these are 3,5,6,9,10 and 11. They are marked with a “~” symbol on the board next to the PIN number.

You are using 8 and 10.

Arduino uno R3 .Currently I have only 1 arm running and I changed the servo to pin 9, but it still does the same thing.

I am wondering if the constructor is calling attach() at the proper time.

To discard this as a potential cause you can add this method to your Greif_system class

void begin() {
  servo.attach(servo_pin);
}

And call it from setup():

void setup() {
  AFMS.begin();
  Arm_rechts.begin();
  Arm_rechts.greifer_1_neutral(); //Set starting position of the servo
  delay(5000);
}
1 Like

Powering a servo from the 5volt regulator of the Uno, which is powered with 12volt, is a good way of frying the regulator of the Uno.
Those motor shields should never have had a servo connector fitted, let alone two.
Leo..

1 Like

Thank you, attaching the servo similarly to how you explained worked. I took the servo_pin out of the constructor all together and added the begin function like you said, but I had to change the calling function in setup to Arm_rechts.begin(9);

Thank you for your comment, I will look into a different way of supplying power to my servos :).

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