我花了数周时间使用 WiringPi 控制两个伺服 (SG90) 并用 C 编程,我推荐了三件事。
1.使用BCM GPIO
而不是WiringPi Pin
因为控制多个伺服,您可能需要多个引脚,例如 1( WiringPi Pin
)/18( BCM GPIO
) 用于另一个伺服,对于 RPi3 B+ 版本,它可以访问两个硬件 PWM 通道。gpios 12/18 上的通道 0 和 gpios 13/19 上的通道 1,如果您采用 ,这很容易,无需担心存在引脚映射BCM GPIO
。
2.最好确保只有一个程序访问PWM。一次引脚。根据我的经验,如果您发现使用“ gpio -g pwm 18 25
”之类的命令是可行的,但使用“ pwmWrite(18, 25)
”之类的代码不会得到任何伺服响应,则可以尝试“ ps -A
”以确保是否有任何其他程序正在竞相访问您的伺服。
3.对我来说最后也是最难的一个,当我执行pwmWrite(18, 25)
“on PWM. pin 18
triggers the same instruction on”时PWM. pin 12
,表示pwmWrite(18, 25)
触发pwmWrite(12, 25)
。为了解决这种情况,将舵机的其他引脚模式更改为输入模式和将它们全部设置为下拉。
有关详细信息,请使用 PWM 控制两个舵机的代码。gpios 12/18 上的通道 0。
基本功能:
void servo_init() {
servo_open(0);
delay(DELAY_SERVO);
servo_open(1);}
和
void servo_open(int servo) {
switch (servo) {
case 0:
pullUpDnControl(SERVO_0, PUD_OFF);
pinMode(SERVO_0, PWM_OUTPUT);
pwmSetMode(PWM_MODE_MS);
pwmSetClock(PWM_CHANNEL_0_CLOCK);
pwmSetRange(PWM_CHANNEL_0_RANGE);
break;
case 1:
pullUpDnControl(SERVO_1, PUD_OFF);
pinMode(SERVO_1, PWM_OUTPUT);
pwmSetMode(PWM_MODE_MS);
pwmSetClock(PWM_CHANNEL_0_CLOCK);
pwmSetRange(PWM_CHANNEL_0_RANGE);
break;
default:
break;
}}
和
void servo_close(int servo) {
switch (servo) {
case 0:
pinMode(SERVO_0, INPUT);
pullUpDnControl(SERVO_0, PUD_DOWN);
break;
case 1:
pinMode(SERVO_1, INPUT);
pullUpDnControl(SERVO_1, PUD_DOWN);
break;
default:
break;
}}
和
void servo(int servo, int angle) {
switch (servo) {
case 0:
servo = SERVO_0;
break;
case 1:
servo = SERVO_1;
break;
default:
servo = -1;
break;
}
switch (angle) {
case 90:
value = 25;
break;
case -90:
value = 10;
break;
case 0:
value = 14;
break;
default:
break;
}
if (servo == -1) return;
pwmWrite(servo, value);}
旋转一舵机连接18(BCM GPIO)
在轮换一个之前关闭其他
servo_close(1);
delay(DELAY_SERVO);
旋转
servo(0, 90);
delay(3*DELAY_MAGIC);
servo(0, 0);
将所有舵机重置为其初始角度,以修复舵机偶尔抖动
delay(DELAY_SERVO);
servo_init();
在 Raspberry 上查看更多关于伺服和传感器的源代码和信息:MY GitHub