Voting resources, early voting, and poll worker information - VOTE. ... Adafruit is open and shipping.
0

App to Contro 6 Servo Motors based from a pca9685l
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

App to Contro 6 Servo Motors based from a pca9685l

by DebuA on Sun Apr 05, 2020 10:24 am

Hello!
So, project is to make an app on and connect it to a Arduino uno via HC 05 then use that app to control 6 Servo motors 3xsg90 and 3xMG995 via the PCA9685 board

In my first attempt I just used the Vcc and Gnd available on the pca 9685 to power my servos while the pwm was given via 6 Arduino pins, i.e. I did not use the pwm pins on the pca 9685, it worked flawlessly.

My second attempt is where I need some assistance, this time I connected all my 6 servo motors to my pca9685 gnd>gnd, vcc>vcc and pwm(servo number)>servo

and uploaded the code given below:

Code: Select all | TOGGLE FULL SIZE

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


Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

#define MIN_PULSE_WIDTH 125 // this is the 'minimum' pulse length count (out of 4096)
#define MAX_PULSE_WIDTH 575 // this is the 'maximum' pulse length count (out of 4096)
//#define DEFAULT_PULSE_WIDTH 1500
#define FREQUENCY 60

//uint8_t servonum = 0;
int bluetoothTx = 7;
int bluetoothRx = 4;



SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);

void setup()
{

  Serial.begin(38400);

  //Setup Bluetooth serial connection to android
  bluetooth.begin(38400);
  pwm.begin();
  pwm.setPWMFreq(FREQUENCY);
  yield();
}


void loop()
{
  int pulse_width, analog_value;
 
  if(bluetooth.available()>= 2 )
  {

    unsigned int servopos = bluetooth.read();
    unsigned int servopos1 = bluetooth.read();
    unsigned int realservo = (servopos1 *256) + servopos;
     
   
    if (realservo >= 1000 && realservo <=1180){
    int servo1 = realservo;
    analog_value=map(servo1, 1000,1180,0,180);
    pulse_width = map(analog_value, 0, 180, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);   
    pwm.setPWM(0, 0, pulse_width);   
    Serial.println("Base");
    delay(10);
    }
   
    if (realservo >=2000 && realservo <=2180){
      int servo2 = realservo;
      analog_value=map(servo2, 2000,2180,0,180);
      pulse_width = map(analog_value, 0, 180, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);     
      pwm.setPWM(1, 0, pulse_width);   
      Serial.println("Waist");
      delay(10);
     
    }
   
    if (realservo >=3000 && realservo <= 3180){
      int servo3 = realservo;
      analog_value=map(servo3, 3000,3180,0,180);
      pulse_width = map(analog_value, 0, 180, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);     
      pwm.setPWM(2, 0, pulse_width);     
      Serial.println("Shoulder");
      delay(10);
    }
   
   
    if (realservo >=4000 && realservo <=4180){
      int servo4 = realservo;
      analog_value=map(servo4, 4000,4180,0,180);
      pulse_width = map(analog_value, 0, 180, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);     
      pwm.setPWM(3, 0, pulse_width);     
      Serial.println("Elbow");       
      delay(10);
    }
   
    if (realservo >=5000 && realservo <= 5180){
      int servo5 = realservo;
      analog_value=map(servo5, 5000,5180,0,180);
      pulse_width = map(analog_value, 0, 180, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);     
      pwm.setPWM(4, 0, pulse_width);
      Serial.println("Wrist");     
      delay(10);
    }   
   
    if (realservo >=6000 && realservo <=6180){
      int servo6 = realservo;
      analog_value=map(servo6, 6000,6180,0,180);
      pulse_width = map(analog_value, 0, 180, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
      pwm.setPWM(5, 0, pulse_width);     
      Serial.println("Gripper");     
      delay(10);
    }
  }
}


unlike first time when I only used vcc and gnd of pca9685 I used the pwm pin too thus I added the following code that you can see above
Code: Select all | TOGGLE FULL SIZE
      analog_value=map(servo6, 6000,6180,0,180);
      pulse_width = map(analog_value, 0, 180, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
      pwm.setPWM(5, 0, pulse_width);


the problem is that everything works exactly as I expected except the servos do not rotate at all, I checked the Bluetooth connection too, its good, and prints the related serial.println, that I have added based on what the command the Bluetooth receives so why aren't the servos rotating?

DebuA
 
Posts: 5
Joined: Sun Apr 05, 2020 10:03 am

Re: App to Contro 6 Servo Motors based from a pca9685l

by adafruit_support_bill on Sun Apr 05, 2020 11:00 am

Have you tested the board using the example code from the library?

adafruit_support_bill
 
Posts: 78759
Joined: Sat Feb 07, 2009 10:11 am

Re: App to Contro 6 Servo Motors based from a pca9685l

by DebuA on Sun Apr 05, 2020 11:53 pm

yeah I have, it works, maybe there is some problem in min and max width
can you please list what general problems are related to PWM control that people face?

DebuA
 
Posts: 5
Joined: Sun Apr 05, 2020 10:03 am

Re: App to Contro 6 Servo Motors based from a pca9685l

by adafruit_support_bill on Mon Apr 06, 2020 5:34 am

The min and max pulse widths typically require some tuning per servo for best accuracy. The values in the example code are usually a good starting point.

But if your servos are not moving at all, that suggests a different problem. Please post some photos showing your soldering and connections.

adafruit_support_bill
 
Posts: 78759
Joined: Sat Feb 07, 2009 10:11 am

Re: App to Contro 6 Servo Motors based from a pca9685l

by DebuA on Mon Apr 06, 2020 4:18 pm

Thank you for quick replies, Unfortunately I am not in possession of the physical circuit, it is at my school which is closed due to the outbreak of coronavirus.

Instead of it, I made it on Proteus, image is attached

pca 9685 breakout board: scl > A5, sda>A4, 5V (on pca9685 breakout board)> Vcc (+5v on arduino) and gnd>gnd. I also powered the servo motors using a external battery pack and have connected their signal pin to their respective pwm pin

I cleaned the code a little bit (by removing some unnecessary comments):

this code does not use the pca9685's pwm pin but works fine all motors rotate:
Code: Select all | TOGGLE FULL SIZE
#include <SoftwareSerial.h>

#include <Servo.h>
Servo myservo1, myservo2, myservo3, myservo4, myservo5, myservo6;

int bluetoothTx = 7;
int bluetoothRx = 4;

SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);

void setup()
{
  myservo1.attach(9);
  myservo2.attach(10);
  myservo3.attach(11);
  myservo4.attach(3);
  myservo5.attach(5);
  myservo6.attach(6);
  //Setup usb serial connection to computer
  Serial.begin(38400);

  //Setup Bluetooth serial connection to android
  bluetooth.begin(38400);
}

void loop()
{
  //Read from bluetooth and write to usb serial
  if(bluetooth.available()>= 2 )
  {
    unsigned int servopos = bluetooth.read();
    unsigned int servopos1 = bluetooth.read();
    unsigned int realservo = (servopos1 *256) + servopos;
    //Serial.println(realservo);
   
    if (realservo >= 1000 && realservo <=1180){
    int servo1 = realservo;
    servo1 = map(servo1, 1000,1180,0,180);
    myservo1.write(servo1);
    Serial.println("Base_");
    Serial.println(servo1);

   
    delay(10);

    }
   
    if (realservo >=2000 && realservo <=2180){
      int servo2 = realservo;
      servo2 = map(servo2,2000,2180,0,180);
      myservo2.write(servo2);
      Serial.println("Waist_");
      Serial.println(servo2);

      delay(10);
     
    }
   
    if (realservo >=3000 && realservo <= 3180){
      int servo3 = realservo;
      servo3 = map(servo3, 3000, 3180,0,180);
      myservo3.write(servo3);
      Serial.println("Shoulder_");
      Serial.println(servo3);       

      delay(10);
    }
    if (realservo >=4000 && realservo <=4180){
      int servo4 = realservo;
      servo4 = map(servo4, 4000, 4180,0,180);
      myservo4.write(servo4);
      Serial.println("Elbow_");
      Serial.println(servo4);

      delay(10);
    }
   
    if (realservo >=5000 && realservo <= 5180){
      int servo5 = realservo;
      servo5 = map(servo5, 5000, 5180,0,180);
      myservo5.write(servo5);
      Serial.println("Wrist_");
      Serial.println(servo5);
      delay(10);
    }   
    if (realservo >=6000 && realservo <=6180){
      int servo6 = realservo;
      servo6 = map(servo6, 6000, 6180,0,180);
      myservo6.write(servo6);
      Serial.println("Gripper_");
      Serial.println(servo6);
      delay(10);
    }
 
  }
}


but doesn't work when I use the pwm pin on the pca9685 breakout board

Code: Select all | TOGGLE FULL SIZE
#include <SoftwareSerial.h>
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
#include <Servo.h>

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40);

#define SERVOMIN  125 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX  575 // this is the 'maximum' pulse length count (out of 4096

#define FREQUENCY 60


int bluetoothTx = 7;
int bluetoothRx = 4;



SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);

void setup()
{

  Serial.begin(38400);

  //Setup Bluetooth serial connection to android
  bluetooth.begin(38400);
  pwm.begin();
  pwm.setPWMFreq(FREQUENCY);
 // yield();
}


void loop()
{
  int angle;
 
  if(bluetooth.available()>= 2 )
  {

    unsigned int servopos = bluetooth.read();
    unsigned int servopos1 = bluetooth.read();
    unsigned int realservo = (servopos1 *256) + servopos;
     
   
    if (realservo >= 1000 && realservo <=1180){
    int servo1 = realservo;
    angle=map(servo1, 1000,1180,0,180);   
    pwm.setPWM(0, 0, angleToPulse(angle));   
    Serial.println("Base");
    delay(10);
    }
   
    if (realservo >=2000 && realservo <=2180){
    int servo2 = realservo;
    angle=map(servo2, 2000,2180,0,180);   
    pwm.setPWM(1, 0, angleToPulse(angle));   
    Serial.println("Waist");
    delay(10);
    }
   
    if (realservo >=3000 && realservo <= 3180){
    int servo3 = realservo;
    angle=map(servo3, 3000,3180,0,180);   
    pwm.setPWM(2, 0, angleToPulse(angle));   
    Serial.println("Shoulder");
    delay(10);
    }
   
   
    if (realservo >=4000 && realservo <=4180){
    int servo4 = realservo;
    angle=map(servo4, 4000,4180,0,180);   
    pwm.setPWM(3, 0, angleToPulse(angle));   
    Serial.println("Elbow");
    delay(10);
    }
   
    if (realservo >=5000 && realservo <= 5180){
    int servo5 = realservo;
    angle=map(servo5, 5000,5180,0,180);   
    pwm.setPWM(4, 0, angleToPulse(angle));   
    Serial.println("Wrist");
    delay(10);
    }   
   
    if (realservo >=6000 && realservo <=6180){
    int servo6 = realservo;
    angle=map(servo6, 6000, 6180,0,180);   
    pwm.setPWM(5, 0, angleToPulse(angle));   
    Serial.println("Gripper");
    delay(10);
    }
  }
}

int angleToPulse(int ang){
   int pulse = map(ang,0, 180, SERVOMIN,SERVOMAX);// map angle of 0 to 180 to Servo min and Servo max
   Serial.print("Angle: ");Serial.print(ang);
   Serial.print(" pulse: ");Serial.println(pulse);
   return pulse;
}
Attachments
Screenshot (111).png
Screenshot (111).png (46.96 KiB) Viewed 37 times
Last edited by DebuA on Mon Apr 06, 2020 4:28 pm, edited 1 time in total.

DebuA
 
Posts: 5
Joined: Sun Apr 05, 2020 10:03 am

Re: App to Contro 6 Servo Motors based from a pca9685l

by adafruit_support_bill on Mon Apr 06, 2020 4:27 pm

I do not see a ground connection between the Arduino and the PCA9685. You need a ground connection for a signal reference - as well as a return path for power to the chip.

adafruit_support_bill
 
Posts: 78759
Joined: Sat Feb 07, 2009 10:11 am

Re: App to Contro 6 Servo Motors based from a pca9685l

by DebuA on Mon Apr 06, 2020 4:31 pm

I have connected the gnd on pca > gnd on Arduino:

this is the image I followed:
Attachments
adafruit_products_I2C_bb-1024.jpg
adafruit_products_I2C_bb-1024.jpg (51.79 KiB) Viewed 36 times

DebuA
 
Posts: 5
Joined: Sun Apr 05, 2020 10:03 am

Re: App to Contro 6 Servo Motors based from a pca9685l

by adafruit_support_bill on Mon Apr 06, 2020 5:53 pm

So, when you run your code, is there any sign of life from any of the servos? Do they twitch or hum? Are you able to turn them by hand?

adafruit_support_bill
 
Posts: 78759
Joined: Sat Feb 07, 2009 10:11 am

Re: App to Contro 6 Servo Motors based from a pca9685l

by DebuA on Thu Apr 09, 2020 9:36 am

It worked!

all I did was changing this
Code: Select all | TOGGLE FULL SIZE
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();


to
Code: Select all | TOGGLE FULL SIZE
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40);


I also got to ask, is there a library for pca9685 breakout board available to use in proteus, because in stock proteus all I see is the pca9685 IC?

DebuA
 
Posts: 5
Joined: Sun Apr 05, 2020 10:03 am

Re: App to Contro 6 Servo Motors based from a pca9685l

by adafruit_support_bill on Thu Apr 09, 2020 11:06 am

Good to hear you solved it.

All our board files are on Github in EagleCAD format. EagleCAD is a free download and supports export to a number of different formats. You may find one of them to be compatible with Proteus.

https://github.com/adafruit/Adafruit-16 ... Driver-PCB

adafruit_support_bill
 
Posts: 78759
Joined: Sat Feb 07, 2009 10:11 am

Please be positive and constructive with your questions and comments.