Problem with Multitasking Servos Using Adafruit 16-Channel Servo Shield

Hi,

I am working on a Bluetooth bipedal robot project and I am using an Adafruit 16-Channel Servo Shield to control 14 servos. As of now, I am trying to control two servos and have them move simultaneously. I have looked at a couple of multitasking codes used without the Adafruit shield and tried to make it compatible with the shield, as well as tweaking it for my own needs. What I want to happen is for the servos to move simultaneously to the positions I give them. In the code, I set a starting position for the servos, but I would like them to move from any position they are at. I also want to be able to use the same idea so I can have the robot move its legs to scooch(not an actual walk) and go into specific positions with its arms and legs. I am kind of a beginner with code in general so be kind, but here is the program I have so far:

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>


Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();




#define SERVO_FREQ 50 // Analog servos run at ~50 Hz updates



  int pos1 = 270;   // starting position for first servo
  int pos2 = 390;   // starting position for second servo
  int increment1 = 1;        // increment to move for each interval for first servo
  double increment2 = -1.6;  //increment to move for each interval for second servo 
  int  updateInterval1 = 15; // interval between updates for first servo
  int  updateInterval2 = 25; // interval between updates for second servo
  unsigned long lastUpdate1; // last update of position for second servo
  unsigned long lastUpdate2; // last update of position for second servo
 


void setup() {
  Serial.begin(9600);
  pwm.begin();
  pwm.setOscillatorFrequency(27000000);  
  pwm.setPWMFreq(SERVO_FREQ);  

  delay(10);
}




void loop() {


  if((millis() - lastUpdate1) > updateInterval1) 
        {
          lastUpdate1 = millis();
          pos1 += increment1;
          pwm.setPWM(6, 0, pos1); // first servo at port 6 goes to pos1
           Serial.println(pos1);
          if(pos1 >= 500)  // end of sweep
          {
            // reverse direction
           increment1 = 0;
          }
        }
        
      if((millis() - lastUpdate2) > updateInterval2)  
        {
          lastUpdate2 = millis();
          pos2 += increment2;
          pwm.setPWM(5, 0, pos2); // second servo at port 5 goes to pos2
           Serial.println(pos2);
          if (pos2 <= 1) // end of sweep
          {
            // reverse direction
            increment2 = 0;
          }
        }


   
}

When this code runs, all that happens is the first servo goes to the correct position, while the second servo does not move, nor does it stay firmly in the position it starts at(like it is powered, even though it is). Even if I comment out the first "if" statement it still does the same thing. Is there a better way to multitask? Also, are my servos doing this because of a bad connection or something to do with the code?

If you need more clear details I can help clarify.

Thanks.

Let's clarify what multi-tasking means and does not mean. It means the operating system takes care of starting and stopping the tasks assigned to it. It can do this based on time slicing or it can do this based on cooperative releasing control by a task back to the operating system. In no stretch of the imagination does this mean the tasks can run at the same time. The Arduino does not have an operating system.

Now, with some processors with multiple cores, the operating system can actually run some code at the same time as another piece of code runs. But, any input/output operations cannot be done during this multitasking. It is processor only. The Arduino does not have multiple processor cores, nor does it have memory that can be shared between cores.

Are you doing your best to make your project seem like the servo operations are going at the same time? This means using the millis() function to identify when something should be done. And it can be done quite rapidly so it appears to us humans that the operations are being done at the same time.

Paul

Hi

Yes, I am using millis() to identify when something should be done. That is what I do in my code.

Thanks.

Ok. Then to clear things up, do have servos that you have tested to see if they move the same at the same time?

Paul

I have the servos on the robot and they do not. Are you talking about servos that are not connected through the shield?

Thanks.

Owen_Diesenhaus:
I have the servos on the robot and they do not. Are you talking about servos that are not connected through the shield?

Thanks.

I mean the servos that are not loaded by anything, if they do not move identically, then they likely will not move identically when in your robot unless they are physically forced to move that way by some mechanism.

Paul