我想不停地循环移动伺服电机!怎么了?
#include <Adafruit_PWMServoDriver.h>
#include <Wire.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
int motors[] = {0, 1, 2, 3};
int degrees[] = {0, 0, 0, 0};
void setup() {
Serial.begin(9600);
pwm.begin();
pwm.setPWMFreq(50);
pwm.setOscillatorFrequency(27000000);
for(int i=0; i<15; i++){
pwm.setPWM(i, 0, 150);
}
Serial.setTimeout(10);
}
void joystick_val(int pin){
Serial.print(pin);
Serial.print(" ");
}
void Move_motor(int motor, int degree, int int_val){
if(int_val <= 1){
degree += 5;
if(degree > 180) degree = 180;
int pul = map(degree,0,180,150,600);
pwm.setPWM(motor, 0, pul);
}
else if(int_val >= 4){
degree -= 5;
if(degree < 0) degree = 0;
int pul = map(degree,0,180,150,600);
pwm.setPWM(motor, 0, pul);
}
}
void loop() {
//int e = Serial.parseInt();
int analogPin[] = {analogRead(A0), analogRead(A1), analogRead(A2), analogRead(A3)};
int int_Pin[] = { map(analogPin[0], 0, 1023, 0, 5),
map(analogPin[1], 0, 1023, 0, 5),
map(analogPin[2], 0, 1023, 0, 5),
map(analogPin[3], 0, 1023, 0, 5)
};
int Pin_amount = sizeof(analogPin)-4;
Move_motor(motors[0], degrees[0], map(analogPin[0], 0, 1023, 0, 5));
Move_motor(motors[1], degrees[1], map(analogPin[1], 0, 1023, 0, 5));
Move_motor(motors[2], degrees[2], map(analogPin[2], 0, 1023, 0, 5));
Move_motor(motors[3], degrees[3], map(analogPin[3], 0, 1023, 0, 5));
for(int j=0; j<Pin_amount; j++){
Serial.print(map(analogPin[j], 0, 1023, 0, 5));
Serial.print(" ");
}
Serial.println("");
}
原本,只要握住连接到电机的操纵杆,伺服电机就必须保持旋转,只有松开操纵杆才停止。然而,当摇杆移动时,伺服电机会在旋转一瞬间后停止,而不是连续旋转。
我尝试使用“for”循环,也尝试改变 PWM 的频率。我想要的是使代码功能相同,而无需编写四次 Move_motor 函数。预先感谢您。
当您更改
degree
中的 Move_motor
时,它只会更改本地值。
它不会更改全局数组degrees
,因此当调用
degree
时,
Move_motor
的值是always 0。
degree
只会是 0 或 5
可以将degrees
作为指针传递给
Move_motor
。但是,有很多[不必要的]重复代码。
解决此问题的最佳方法是使用单个
struct
数组,而不是使用相同值索引的多个数组。
#include <Adafruit_PWMServoDriver.h>
#include <Wire.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// per-motor control
typedef struct mctl {
int motidx; // motor index
int apin; // AnalogRead port number
int aval; // AnalogRead value
int ival; // int of aval
int degree; // current rotation
int pul; // old motor pul value
} mctl_t;
#define NCTL 4
mctl_t controls[NCTL];
void
setup(void)
{
Serial.begin(9600);
pwm.begin();
pwm.setPWMFreq(50);
pwm.setOscillatorFrequency(27000000);
for (int i = 0; i < 15; i++)
pwm.setPWM(i, 0, 150);
Serial.setTimeout(10);
int aport[] = { A0, A1, A2, A3 };
for (mctl_t mctl = &controls[0]; mctl < &controls[NCTL]; ++mctl) {
int motidx = mctl - controls;
mctl->motidx = motidx;
mctl->aport = aport[motidx];
mctl->pul = 0x7FFFFFFFF;
}
}
void
joystick_val(int pin)
{
Serial.print(pin);
Serial.print(" ");
}
void
move_motor(mctl_t *mctl)
{
int degree = mctl->degree;
int setflg = 0;
int int_val = map(mctl->aval, 0, 1023, 0, 5),
do {
if (int_val <= 1) {
degree += 5;
setflg = 1;
break;
}
if (int_val >= 4) {
degree -= 5;
setflg = 1;
break;
}
// do nothing???
} while (0);
if (degree > 180)
degree = 180;
if (degree < 0)
degree = 0;
do {
if (! setflg)
break;
int pul = map(degree, 0, 180, 150, 600);
// optional speedup: don't send value if hasn't changed since the last
// time
if (pul == mctl->pul)
break;
pwm.setPWM(mctl->motidx, 0, pul);
// remember the value we just output
mctl->pul = pul;
} while (0);
// save updated values
mctl->degree = degree;
mctl->ival = int_val;
}
void
loop(void)
{
// grab all values quickly
for (mctl_t mctl = &controls[0]; mctl < &controls[NCTL]; ++mctl)
mctl->aval = AnalogRead(mctl->apin);
// change all motor values
for (mctl_t mctl = &controls[0]; mctl < &controls[NCTL]; ++mctl)
move_motor(mctl);
// show all values
for (mctl_t mctl = &controls[0]; mctl < &controls[NCTL]; ++mctl) {
Serial.print(mctl->ival);
Serial.print(" ");
}
Serial.println("");
}