rr1991
May 21, 2021, 3:48pm
#1
Hi,
Using an Arduino Uno and a PCA9685 16 channel driver I'm trying to sweep all the servos from 0 to 15 at the same time but in an alternate manner. i.e. odd number servos sweep from left to right and even numbered ones sweep in the opposite direction. The following code sweeps all the servos together but in the same direction :
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
#include <math.h>
#include "SoftwareSerial.h"
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#define Lft 150 // left
#define Rt 250 // right
#define Ct 200 // center
int pulselen;
int myservo;
void setup() {
Serial.begin(9600);
pwm.begin();
pwm.setOscillatorFrequency(27000000);
pwm.setPWMFreq(50);
delay(10);
}
void loop() {
for (uint16_t pulselen = Lft; pulselen < Rt; pulselen += 1) {
for (myservo = 0; myservo < 15; myservo++) {
pwm.setPWM(myservo, 0, pulselen);
}
}
for (uint16_t pulselen = Rt; pulselen > Lft; pulselen -=1 ) {
for (myservo = 0; myservo < 15; myservo++){
pwm.setPWM(myservo, 0, pulselen);
}
}
}
How could I throw in an IF myservo is odd go from left to right and vice versa and have all the servos sweep at the same time ?
Thanks.
value & 1
if true (non-zero), means value is odd.
blh64
May 21, 2021, 4:58pm
#3
uint16_t pulse;
for (uint16_t pulselen = Lft; pulselen < Rt; pulselen += 1) {
for (myservo = 0; myservo < 15; myservo++) {
if ( myservo % 1 ) {
pulse = pulselen;
}
else {
pulse = Rt - pulselen;
}
pwm.setPWM(myservo, 0, pulse);
}
}
You can also remove the outer for() loop and just let loop() do what it does. Each time through loop() you calculate the pulsewidth, set it, and increment, When you reach the limit, switch direction. repeat for all eternity.
1 Like
anon73444976:
value & 1
means bit wise AND
decimal 1 binary 00000001
decimal 2 binary 00000010
decimal 3 binary 00000011
decimal 4 binary 00000100
decimal 5 binary 00000101
best regards Stefan
1 Like
rr1991
May 22, 2021, 8:55am
#6
Thanks all.
@blh64 Your code moves only the odd ones, sweeping in one direction but then jumps (not sweep) in the other direction.
I read it's better to do the IF test in binary so I changed to
if ( (myservo & 0x01) == 0){
now I get all the even ones. But again they sweep only in one direction and jump to (no sweep) as they go back.
My rookie brain can't figure out how to have all the servos sweep together in both directions without jumping.
The processor doesn't care about the base you express the constant in.
Because any value modulo 1 is always zero, aka false.
Which is why you should try modulo 2
Post the code you have now, and tell us what it does.
1 Like
And you'll probably do better if you change
pulse = Rt - pulselen;
to
pulse = (Ct * 2) - pulselen;
That should keep pulse within the correct Lft to Rt range.
Steve
1 Like
rr1991
May 22, 2021, 3:34pm
#9
@slipstick Thanks Steve, nice suggestion.
Thanks all, now I got it, it works fine.
void Sweep_Alternate(){
uint16_t pulse;
for (uint16_t pulselen = Lft; pulselen < Rt; pulselen += 1) {
for (myservo = 0; myservo < 15; myservo++) {
if ( (myservo & 0x01) == 0){
pulse = pulselen;
}
else {
pulse = (Ct * 2) - pulselen;
}
pwm.setPWM(myservo, 0, pulse);
}
}
for (uint16_t pulselen = Rt; pulselen > Lft; pulselen -= 1) {
for (myservo = 0; myservo < 15; myservo++) {
if ( (myservo & 0x01) == 0){
pulse = pulselen;
}
else {
pulse = (Ct * 2) - pulselen;
}
pwm.setPWM(myservo, 0, pulse);
}
}
}
blh64
May 24, 2021, 4:02pm
#10
Either would be better than my mistake
system
Closed
September 21, 2021, 4:03pm
#11
This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.