0

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. enter image description here

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?

sanderfcb95
  • 59
  • 1
  • 12
  • You probably want some manner of transient and ESD protection there. Toss in some TVS diodes with slightly higher voltage than the PWM, and some series resistors. But that's a topic for https://electronics.stackexchange.com. Oh and there's also https://raspberrypi.stackexchange.com/. – Lundin May 09 '17 at 13:19
  • oh yes i forget that i ga place it there to :p – sanderfcb95 May 09 '17 at 13:23
  • Did you read manual for [wiringPiSetupGpio](http://wiringpi.com/reference/setup/)? _This is identical to above, however **it allows the calling programs to use the Broadcom GPIO pin numbers directly with no re-mapping.**_ _As above, this function needs to be called with root privileges, and note that some **pins are different from revision 1 to revision 2 boards.**_ – LPs May 09 '17 at 13:39
  • But why it whorks when i use wiringpi in c to yust blink a LED with wiringpi i just have problems when using PWM – sanderfcb95 May 09 '17 at 14:18
  • Even on the newest versions of wiringPi, the PWM functionality requires you to run your program with root privileges (ie. sudo). You are experiencing the crash/reboot issue because of this. To get around the sudo requirement, you'll need to use a digital potentiometer or digital-to-analog converter instead of the built-in PWM functionality. – stevieb May 09 '17 at 15:43
  • I've not used wiringpi, so I don't know if this matters or not, but you're pwm line is connected to pin 18, not GPIO 18. GPIO 18 is at pin 12. – b_laoshi Aug 05 '17 at 00:59
  • Additional note: Use GPIO18 & 19 (channel 0 & 1, ALT5, pins 12 & 35) or GPIO12 & 13 (channel 0 & 1, ALT0, pins 32 & 33) for **hardware_GPIO!** – gue22 Mar 28 '18 at 08:54

2 Answers2

0

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

Mou
  • 145
  • 1
  • 6
0

Try "sudo ./servo" Hope it will work.