Hello,
I am a complete beginner with most electronic things. I applied for a research project through my school to push myself outside of my comfort zone in making a stabilizing leg. This forum is one of my last hopes as even though this project was supposed to be with a teacher, I have not been able to receive much help as my teacher has been in Brazil for the entire duration of the project. The leg design ended up being a hexapod leg that I will need to make code for later for self-stabilization. I have been struggling with getting my servo motors to consistently move.
I am using three Hiwonder servo motors. Two of which are LD-220MG Full Metal Gear Digital Servo with Dual Ball Bearing and 20kg strong torque (Working voltage 6V-8.4V / No-load current 100mA / Stalled current 2.4~3A). The other servo motor is a LD-20MG Full Metal Gear Digital Servo with 20kg high torque(Working voltage 6V-7.4V / No-load current 100mA / Min Working current 1A / Their website did not put a stalled current but I would figure it is still in that 2.4~3A range). All the information on the servos were obtained from the specifications on Hiwonder's website.
Right now, I need to get a better understanding on how to power the servo motors. I am using a Hiletgo PCA9685 16-channel servo driver. There are three servo motors connected to it. The power supply I have is a battery holder that holds four AA batteries. I have four Rayovac High Energy batteries. The datasheet for the battery shows that each battery can have an output of 750mA for around 1.2 hours(each battery is 1.5V). This means I have 6V with a current of 3A. This power supply has in no way been consistent over the past week. I did a demo yesterday where all of the servos were moving 50% of the time when the grey part of the leg was not apart of the project. 50% Meaning sometimes I could get a minute of it moving, while the other times it would just jitter. When the grey part was attached, the servos would either only jitter and move in slight intervals, or they would just make a buzzing noise and not move at all. I know that the increased load makes the current rise, but I have not been able to figure out a way to measure the current draw even after watching a couple videos. I am ignorant of the basic principles in using Arduino or an Ammeter in order to measure the current draw.
Should I just guess the current needed? I would guess I need a total of 4A-5A, but I have not been able to find a set of four AA batteries that fit my specifications. I would like to use the recommended lithium polymer battery for the servo motors, but I don't know how to connect them to the PCA, as the PCA needs stripped wires inserted into clamps for the power supply.
below is a rough set of code that I had used to get the servos moving with the PCA-9685. I couldn't send a video of my leg moving using the accelerometer in my project, so I tried to simplify everything to just the leg with the servo motors, as the code with the accelerometer includes hundreds of lines of code where 95% of it just deals with the accelerometer.
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// you can also call it with a different address you want
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
// you can also call it with a different address and I2C interface
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40, Wire);
// Depending on your servo make, the pulse width min and max may vary, you
// want these to be as small/large as possible without hitting the hard stop
// for max range. You'll have to tweak them as necessary to match the servos you
// have!
#define SERVOMIN 150 // This is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX 520 // This is the 'maximum' pulse length count (out of 4096)
#define USMIN 500 // This is the rounded 'minimum' microsecond length based on the minimum pulse of 150
#define USMAX 2400 // This is the rounded 'maximum' microsecond length based on the maximum pulse of 600
#define SERVO_FREQ 100 // Analog servos run at ~50 Hz updates
// our servo # counter
uint8_t servonum = 0;
uint8_t servonumMax = 1;
void setup() {
Serial.begin(9600);
Serial.println("First 2 channels, Servo test!");
pwm.begin();
/*
* In theory the internal oscillator (clock) is 25MHz but it really isn't
* that precise. You can 'calibrate' this by tweaking this number until
* you get the PWM update frequency you're expecting!
* The int.osc. for the PCA9685 chip is a range between about 23-27MHz and
* is used for calculating things like writeMicroseconds()
* Analog servos run at ~50 Hz updates, It is importaint to use an
* oscilloscope in setting the int.osc frequency for the I2C PCA9685 chip.
* 1) Attach the oscilloscope to one of the PWM signal pins and ground on
* the I2C PCA9685 chip you are setting the value for.
* 2) Adjust setOscillatorFrequency() until the PWM update frequency is the
* expected value (50Hz for most ESCs)
* Setting the value here is specific to each individual I2C PCA9685 chip and
* affects the calculations for the PWM update frequency.
* Failure to correctly set the int.osc value will cause unexpected PWM results
*/
pwm.setOscillatorFrequency(27000000);
pwm.setPWMFreq(SERVO_FREQ); // Analog servos run at ~50 Hz updates
delay(10);
}
// You can use this function if you'd like to set the pulse length in seconds
// e.g. setServoPulse(0, 0.001) is a ~1 millisecond pulse width. It's not precise!
void setServoPulse(uint8_t n, double pulse) {
double pulselength;
pulselength = 1000000; // 1,000,000 us per second
pulselength /= SERVO_FREQ; // Analog servos run at ~60 Hz updates
Serial.print(pulselength); Serial.println(" us per period");
pulselength /= 4096; // 12 bits of resolution
Serial.print(pulselength); Serial.println(" us per bit");
pulse *= 1000000; // convert input seconds to us
pulse /= pulselength;
Serial.println(pulse);
pwm.setPWM(n, 0, pulse);
}
void loop() {
int dly = 1000;
pwm.setPWM(0, 0, 515); //servo 1 PWM is from 515(180 degrees) to 95(0 degrees)
pwm.setPWM(1,0,492); //servo 2 PWM is from 492(180 degrees) to 87(0 degrees)
pwm.setPWM(2,0,492);
delay(dly);
pwm.setPWM(0, 0, 305); //Middle Values
pwm.setPWM(1,0,290);
pwm.setPWM(2,0,300);
delay(dly);
pwm.setPWM(0, 0, 95);
pwm.setPWM(1,0,87);
pwm.setPWM(2,0,90);
delay(dly);
pwm.setPWM(0, 0, 305);
pwm.setPWM(2,0,492);
pwm.setPWM(1,0,300);
delay(dly);
}