3

Hello I want to use 2 servo with different gpio pins. But Raspberry has one hardware pwm (GPIO 18). first of all I tried another pin to run servo and my code:

 wiringpi.pinMode(18,2)
 wiringpi.pwmSetMode(0)
 wiringpi.pwmSetClock(400)
 wiringpi.pwmSetRange(1024)
 wiringpi.pwmWrite(18, 100)

 wiringpi.pinMode(4,2)
 wiringpi.pwmSetMode(0)
 wiringpi.pwmSetClock(400)
 wiringpi.pwmSetRange(1024)
 wiringpi.pwmWrite(4, 100)

but my second servo which has connected to gpio 4 did not turn.

I googled my problem and I found a solution such using softpwm. But when I write these codes my servos are shaking not turning.

my codes:

import wiringpi2 as wiringpi


def main():

  print("starting PWM")
  wiringpi.wiringPiSetupGpio()                                                                                                                                                                
  wiringpi.pinMode(18,1)
  wiringpi.softPwmCreate(18,0,1000)

  wiringpi.pinMode(4,1)
  wiringpi.softPwmCreate(4,0,1000)


  dt = 100

  try:

    wiringpi.softPwmWrite(18, 50)
    wiringpi.softPwmWrite(11, 50)

these are not all my code only servo parts. But these are not working.

Is there any slution to using 2 servos with wiringpi

thanks from now

2 Answers 2

4

Lucky to see this question, I just 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

3

Pis with the 40 pin expansion header give access to two channels for hardware PWM. Channel 0 is on gpios 12/18, channel 1 is on gpios 13/19.

So with wiringPi you should be able to use two servos.

If you want to use more than two servos you'll need to use something like my pigpio library which can generate hardware timed PWM on all the user gpios, or buy some external hardware.

The following example uses servos connected to (Broadcom numbered) gpios 4, 11, and 18.

Save in a file called servo.py.

Make executable.

chmod +x servo.py

Make sure the daemon is running

sudo pigpiod

Run the script (no need for sudo).

./servo.py

servo.py

#!/usr/bin/env python

# servo.py
# 2015-05-20
# Public Domain

import time

import pigpio

SERVO = [4, 11, 18]     # Servos connected to gpios 4, 11, 18
DIR   = [1, -1, 1]
PW    = [1500, 1500, 1500]
SPEED = [50, 100, 150]


pi = pigpio.pi() # Connect to local Pi.

for x in SERVO:
   pi.set_mode(x, pigpio.OUTPUT) # Set gpio as an output.

start = time.time()

while (time.time() - start) < 60: # Spin for 60 seconds.

   for x in range (len(SERVO)): # For each servo.

      print("Servo {} pulsewidth {} microseconds.".format(x, PW[x]))

      pi.set_servo_pulsewidth(SERVO[x], PW[x])

      PW[x] += (DIR[x] * SPEED[x])

      if (PW[x] < 1100) or (PW[x] > 1900): # Bounce back at safe limits.
         DIR[x] = - DIR[x]

      time.sleep(0.5)

for x in SERVO:
   pi.set_servo_pulsewidth(x, 0) # Switch servo pulses off.

pi.stop()
4
  • I examined your library. and I want use your library. But do you have any example for servo. because I dont know python prgramming very well May 20, 2015 at 11:38
  • 1
    @MuhammedAliHAŞILOĞLU I have added a Python example.
    – joan
    May 20, 2015 at 11:54
  • 1
    thank you for your support. I'm using now but I cannat use fully performance my servo. I can control it only 0-100 degree. I need more PWM for 180degree but I get error such as: pigpio.error: 'pulsewidth not 0 or 500-2500' May 20, 2015 at 14:48
  • 1
    @MuhammedAliHAŞILOĞLU start a new post and include a link to the servos you are using. Standard servos need 1000 to 2000 µs pulses.
    – joan
    May 21, 2015 at 15:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.