I trie to drive a servo with the Raspberry PI using the PWM on GPIO Pin 18 i wired the setup like you can see below.
When i drive the servo i can do this without any problems the commands that i use you can see below.
gpio -g mode 18 pwm
gpio pwm-ms
gpio pwmc 192
gpio pwmr 2000
gpio -g pwm 18 150
gpio -g pwm 18 200
That works fine, to go to the position without any problem but when i try to do the same with a C program using wiringpi like you can see below.
#include <wiringPi.h>
#include <stdio.h>
int main (void)
{
printf ("Raspberry Pi wiringPi test program\n");
wiringPiSetupGpio();
pinMode (18, PWM_OUTPUT) ;
pwmSetMode (PWM_MODE_MS);
pwmSetRange (2000);
pwmSetClock (192);
pwmWrite(18,150);
delay(1000);
pwmWrite(18,200);
return 0;
}
The program and the raspberry pi chrash so i have to reboot them does anybody know what i do wrong and how i can solve the problem it is very frustrating?
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.