I spent weeks on controlling two servo (SG90) using WiringPi and programming in C, there're three things that I recommend.
1.Using BCM GPIO
instead of WiringPi Pin
because controlling more than one servo, you might need more than one pin such like 1(WiringPi Pin
)/18(BCM GPIO
) for another servo, For RPi3 B+ version, it give access to two channels for hardware PWM. Channel 0 on gpios 12/18 and channel 1 on gpios 13/19, it's easy and no need to worry about pin mapping exists if you adpopt BCM GPIO
.
2.Better make sure there is only one program access PWM. pins at one time. Based on my experience, if you find that using command like "gpio -g pwm 18 25
" is workable but otherwise using code like "pwmWrite(18, 25)
" doesn's get any servo responds, maybe try "ps -A
" to make sure if any other program is racing the access of your servo.
3.The last and the hardest one for me, when I execute pwmWrite(18, 25)
" on PWM. pin 18
triggers the same instruction onto PWM. pin 12
, which means pwmWrite(18, 25)
triggers pwmWrite(12, 25)
. To solve this situation, changing the modes of other pins of servos which should freeze without any moving to be input mode and set all of them to be pull-down.
For details, codes for controlling two servos with PWM. Channel 0 on gpios 12/18.
Basic function:
void servo_init() {
servo_open(0);
delay(DELAY_SERVO);
servo_open(1);}
and
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;
}}
and
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;
}}
and
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);}
Rotate one servo connected to 18 (BCM GPIO)
Close others before you are going to rotate one
servo_close(1);
delay(DELAY_SERVO);
Rotate
servo(0, 90);
delay(3*DELAY_MAGIC);
servo(0, 0);
Reset all of servos to their init angles for fixing servo occasional jitter
delay(DELAY_SERVO);
servo_init();
Check more source code and informations about servo and sensor on Raspberry: MY GitHub