I'll preface this by saying yes, I probably did bite off more than I can chew here. I am working on a project for my engineering class and have decided to use a series of servos to make a self playing xylophone. Each servo will have a small mallet attached to it and the plan is to make them quickly sweep forward and back to hit the keys. I have never used an Arduino before this project and am not familiar with coding. I am using an Arduino Uno with the 16-Channel PWM controller to control my servos. I did install the library for it but have been struggling to find servo basics.
For example:
What is a tick?
What does the servo min and max mean?
What does a low/high point of a sweep mean?
I have had experience with basic python and understand some of the logic of coding. Any help understanding the basics so I can get my code up and running would be helpful!
Using the Adafruit 16-Channel 12-bit PWM/Servo Shield
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- tigress303
- Posts: 4
- Joined: Thu May 21, 2015 12:00 am
- adafruit_support_mike
- Posts: 67446
- Joined: Thu Feb 11, 2010 2:51 pm
Re: Using the Adafruit 16-Channel 12-bit PWM/Servo Shield
The PWM controller has an internal 12-bit counter. Each time that counter increments, it's called a 'tick'.
More specific words don't apply because you can adjust the length of a tick pretty widely. For servos, you want a whole 4096-tick cycle to happen about 50 times per second, so each tick is slightly less than 5 microseconds. If you wanted to update 100 times per second, the duration of a tick would be about 2.5 microseconds.
The signal that tells a servo what to do is a pulse between 1ms and 2ms long. A 1.5ms pulse tells the servo to move to its center position. A 1ms pulse tells the servo to move to its extreme left rotation, and a 2ms pulse tells the servo to move to its extreme right rotation.
The PWM driver only knows ticks and counting though, so we have to run the math ourselves to find the number of ticks that correspond to 1ms and 2ms. In this case, 205 ticks last about 1ms and 410 ticks last about 2ms. Using those numbers, you can calculate the tick count for any servo position. The 1ms count is called servoMin, the 2ms tick count is called servoMax.
I'm not sure exactly what 'high point' and 'low point' indicate, but would guess that they refer to the smallest and largest tick counts for the motion that just happened.
More specific words don't apply because you can adjust the length of a tick pretty widely. For servos, you want a whole 4096-tick cycle to happen about 50 times per second, so each tick is slightly less than 5 microseconds. If you wanted to update 100 times per second, the duration of a tick would be about 2.5 microseconds.
The signal that tells a servo what to do is a pulse between 1ms and 2ms long. A 1.5ms pulse tells the servo to move to its center position. A 1ms pulse tells the servo to move to its extreme left rotation, and a 2ms pulse tells the servo to move to its extreme right rotation.
The PWM driver only knows ticks and counting though, so we have to run the math ourselves to find the number of ticks that correspond to 1ms and 2ms. In this case, 205 ticks last about 1ms and 410 ticks last about 2ms. Using those numbers, you can calculate the tick count for any servo position. The 1ms count is called servoMin, the 2ms tick count is called servoMax.
I'm not sure exactly what 'high point' and 'low point' indicate, but would guess that they refer to the smallest and largest tick counts for the motion that just happened.
- tigress303
- Posts: 4
- Joined: Thu May 21, 2015 12:00 am
Re: Using the Adafruit 16-Channel 12-bit PWM/Servo Shield
Thank you that clears quite a bit up.
- tigress303
- Posts: 4
- Joined: Thu May 21, 2015 12:00 am
Re: Using the Adafruit 16-Channel 12-bit PWM/Servo Shield
One more question: I have figured out what different parts of the code mean. Now my objective is to create a function that will move a single selected servo from its min to its max. This way, I can control the individual servos to move when needed. How does one control individual servos? This is my code so far.
Code: Select all
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
#include <Servo.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#define SERVOMIN 150 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX 350 // this is the 'maximum' pulse length count (out of 4096)
// our servo # counter
uint8_t servonum = 0;
Servo servo1;
void setup() {
servo1.attach(0);
Serial.begin(9600);
Serial.println("16 channel Servo test!");
pwm.begin();
pwm.setPWMFreq(60); // Analog servos run at ~60 Hz updates
}
// 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. its not precise!
void setServoPulse(uint16_t n, double pulse) {
double pulselength;
pulselength = 1000000; // 1,000,000 us per second
pulselength /= 60; // 60 Hz
Serial.print(pulselength); Serial.println(" us per period");
pulselength /= 4096; // 12 bits of resolution
Serial.print(pulselength); Serial.println(" us per bit");
pulse *= 1000;
pulse /= pulselength;
Serial.println(pulse);
pwm.setPWM(n, 0, pulse);
}
void hit()
{
for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
pwm.setPWM(servonum, 0, pulselen); //Controls servo arm out
}
delay (500); //This can be adjusted for faster or slower strikes
for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
pwm.setPWM(servonum, 0, pulselen); //Controls servo arm back in
}
delay(500);
}
void loop()
hit();
- adafruit_support_mike
- Posts: 67446
- Joined: Thu Feb 11, 2010 2:51 pm
Re: Using the Adafruit 16-Channel 12-bit PWM/Servo Shield
In the line:
the value 'servonum' identifies the servo.
Code: Select all
pwm.setPWM(servonum, 0, pulselen); //Controls servo arm out
- tigress303
- Posts: 4
- Joined: Thu May 21, 2015 12:00 am
Re: Using the Adafruit 16-Channel 12-bit PWM/Servo Shield
Ah I see. Is there a way to set seronum to different servos in the loop? For example having servo one use the hit function then servo three, etc.
- adafruit_support_mike
- Posts: 67446
- Joined: Thu Feb 11, 2010 2:51 pm
- orchard800
- Posts: 48
- Joined: Fri Apr 17, 2015 9:25 pm
Re: Using the Adafruit 16-Channel 12-bit PWM/Servo Shield
Your 'learn' article on this states:
Why would you want to control where in the cycle the pulse starts and ends? Why not just the beginning and end?This function sets the start (on) and end (off) of the high segment of the PWM pulse on a specific channel. You specify the 'tick' value between 0..4095 when the signal will turn on, and when it will turn of. Channel indicates which of the 16 PWM outputs should be updated with the new values.
- orchard800
- Posts: 48
- Joined: Fri Apr 17, 2015 9:25 pm
Re: Using the Adafruit 16-Channel 12-bit PWM/Servo Shield
Ps. I think these are the high and low points the poster was referring to.
- adafruit_support_mike
- Posts: 67446
- Joined: Thu Feb 11, 2010 2:51 pm
Re: Using the Adafruit 16-Channel 12-bit PWM/Servo Shield
Power management. Let's say you have 16 LEDs and want to run them at a 25% duty cycle:orchard800 wrote:Why would you want to control where in the cycle the pulse starts and ends? Why not just the beginning and end?
If you have them all on during counts 0-1023, the power supply has to deliver 400mA for that time, then nothing for the rest of the cycle.
If you divide the LEDs into four groups and power them on the following counts:
set 1 - 0-1023
set 2 - 1024 - 2047
set 3 - 2048 - 3071
set 4 - 3072 - 4095
The power supply sees a more or less constant load of 100mA. That isn't such a big deal for 16 LEDs, but can make the difference between a small, simple power supply and a large/heavy/complex one if you're running a hundred LEDs or so.
- orchard800
- Posts: 48
- Joined: Fri Apr 17, 2015 9:25 pm
Re: Using the Adafruit 16-Channel 12-bit PWM/Servo Shield
Aaaah!!!!! I get it. Thank-you.
So where the pulse happens in the cycle doesn't affect the operation of each device but allows you to not run everything at the same moment.
Perfect for the hexapod I'm building with a ras pi, 2x servo hats and 18 tower pro servos!
Thanks!
So where the pulse happens in the cycle doesn't affect the operation of each device but allows you to not run everything at the same moment.
Perfect for the hexapod I'm building with a ras pi, 2x servo hats and 18 tower pro servos!
Thanks!
Please be positive and constructive with your questions and comments.