User avatar
joan
Posts: 14017
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Hardware PWM for servos, motors, and LEDs

Wed Nov 14, 2012 9:08 pm

***************************************************************************************
NOW VERSION 3.

See http://www.raspberrypi.org/phpBB3/viewt ... 30#p347830
***************************************************************************************

I have followed the development of servoblaster (http://www.raspberrypi.org/phpBB3/viewt ... p?p=153708) with a great deal of interest.

For some time it has been apparent that the same techniques could be generalised to provide PWM.

I have put together an experimental library which implements Richard's DMA/PWM techniques into a userland C library. Testing has so far been limited to my own Pis.

The library is available at http://abyz.co.uk/rpi/pigpio/pigpio.tar

A short video of the library being used to drive servos, motors, and LEDs is at http://www.youtube.com/watch?v=9GWgFoHpX9I

The PWM is similar to that provided by Arduinios. The pulse frequency is 392Hz with each pulse being specified by a number between 0 and 255. I.e 0 is off, 255 fully on, and 127 being a 50% duty cycle.

Servo pulses, PWM etc. can be used on any or all of the user gpios simultaneously.
Last edited by joan on Thu May 16, 2013 11:48 am, edited 4 times in total.

almarlow
Posts: 6
Joined: Thu Aug 02, 2012 12:47 am

Re: Hardware PWM for servos, motors, and LEDs

Fri Nov 16, 2012 2:59 am

Hi joan,

That looks like a great addition to the pi's toolset for controlling devices. Looking forward to testing it out over the next couple of weeks. Thanks for your efforts in putting this together for the rest of us.

almarlow

dx21
Posts: 9
Joined: Sun Nov 18, 2012 9:17 pm

Re: Hardware PWM for servos, motors, and LEDs

Sun Nov 18, 2012 9:40 pm

Hi!

I wrote a small program with your library, but i cannot compile it. :(
gcc says:

Code: Select all

/usr/bin/ld: error: gpio_test uses VFP register arguments, /usr/local/lib/libpigpio.a(pigpio.o) does not
/usr/bin/ld: failed to merge target specific data of file /usr/local/lib/libpigpio.a(pigpio.o)
I'm using Arch Linux.
Could you help me out?

User avatar
joan
Posts: 14017
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Hardware PWM for servos, motors, and LEDs

Tue Nov 20, 2012 7:05 pm

I think that means you are using hard float and the library is using soft float. Possibly the library has some internal dioagnostics in soft float. I'll try to identify and remove them.

User avatar
joan
Posts: 14017
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Hardware PWM for servos, motors, and LEDs

Tue Nov 20, 2012 10:22 pm

I have updated http://abyz.co.uk/rpi/pigpio/pigpio.tar to include soft and hard versions of the library. I'd assumed that not using float would make the library distribution neutral. Apparently not.

After extracting the archive you'll have to copy the appropriate version to libpigpio.a

i.e.
[email protected]:~/PIGPIO$ cp libpigpio.a-soft libpigpio.a
or
[email protected]:~/PIGPIO$ cp libpigpio.a-hard libpigpio.a
then do

make install
make
Last edited by joan on Fri May 24, 2013 10:25 pm, edited 1 time in total.

dx21
Posts: 9
Joined: Sun Nov 18, 2012 9:17 pm

Re: Hardware PWM for servos, motors, and LEDs

Wed Nov 21, 2012 7:08 pm

Wow it works, it really works!
I have tested with a servo, and a cpu fan in one time (so far), and they worked flawlessly.
Great library, thank you for sharing it. :)

dx21
Posts: 9
Joined: Sun Nov 18, 2012 9:17 pm

Re: Hardware PWM for servos, motors, and LEDs

Wed Nov 21, 2012 8:39 pm

Is there any way to improve the responsiveness of the servo control?
If i call the gpioServo() function many times in a second, there's a slight delay in the servo movement.
The same code worked well with ServoBlaster.
ps.: i'm sorry for my English

skb13
Posts: 1
Joined: Wed Nov 21, 2012 11:08 pm

Re: Hardware PWM for servos, motors, and LEDs

Wed Nov 21, 2012 11:12 pm

I don't know why this is so hard to find, but I have a motor driver that I've soldered up that I need to connect the hardware PWM to. I know which pin it is on the GPIO connector, but I don't know how to actually use the built in hardware PWM driver in the raspberry PI. All searches turn up with Drogon or this. Since I only have two drivers and they have separate enables, I don't see why I can't use the hardware PWM. Any pointers to the relevant bit of the Broadcom datasheet would be greatly appreciated (or someone who's written higher level routines to access that functionality....).
Thanks,
Simon

User avatar
joan
Posts: 14017
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Hardware PWM for servos, motors, and LEDs

Thu Nov 22, 2012 12:06 am

You must have very responsive servos! I will optimise the servo transitions. I do it conservatively at the moment as when testing using a laser I have seen spurious pulses. I'm beginning to think these spurious pulses have nothing to do with the software. I think I'm drawing too much power from the Pi (the laser takes 20mA, plus whatever the control lines for motors, servos, and LEDs all being switched at the same time are drawing).

User avatar
joan
Posts: 14017
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Hardware PWM for servos, motors, and LEDs

Thu Nov 22, 2012 10:27 pm

skb13 wrote:I don't know why this is so hard to find, but I have a motor driver that I've soldered up that I need to connect the hardware PWM to. I know which pin it is on the GPIO connector, but I don't know how to actually use the built in hardware PWM driver in the raspberry PI. All searches turn up with Drogon or this. Since I only have two drivers and they have separate enables, I don't see why I can't use the hardware PWM. Any pointers to the relevant bit of the Broadcom datasheet would be greatly appreciated (or someone who's written higher level routines to access that functionality....).
Thanks,
Simon
To use the hardware pwm pin see page 138 of the Broadcom peripherals manual for PWM. You'll also to have a look at the gpios and the clock peripherals.

A good code example is http://www.frank-buss.de/raspberrypi/pwm.c

dx21
Posts: 9
Joined: Sun Nov 18, 2012 9:17 pm

Re: Hardware PWM for servos, motors, and LEDs

Fri Nov 23, 2012 3:59 pm

joan wrote:You must have very responsive servos! I will optimise the servo transitions. I do it conservatively at the moment as when testing using a laser I have seen spurious pulses. I'm beginning to think these spurious pulses have nothing to do with the software. I think I'm drawing too much power from the Pi (the laser takes 20mA, plus whatever the control lines for motors, servos, and LEDs all being switched at the same time are drawing).
They are just regular servos: http://www.servodatabase.com/servo/towerpro/sg90
When I call the function many times with two or more servo, is seems they reproduce the movement in slow-motion.

I haven't tested lasers, but when I change the pwm of the fan, there are rpm "pulses" rarely. It might be the same thing, what you noticed with the laser. Nowadays I feed my pi with a 200W FSP PSU. The fan and the servos are on a different 5v branch, so I don't think it's a power related issue in my case.

User avatar
joan
Posts: 14017
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Hardware PWM for servos, motors, and LEDs

Fri Nov 23, 2012 5:14 pm

dx21 wrote:
joan wrote:You must have very responsive servos! I will optimise the servo transitions. I do it conservatively at the moment as when testing using a laser I have seen spurious pulses. I'm beginning to think these spurious pulses have nothing to do with the software. I think I'm drawing too much power from the Pi (the laser takes 20mA, plus whatever the control lines for motors, servos, and LEDs all being switched at the same time are drawing).
They are just regular servos: http://www.servodatabase.com/servo/towerpro/sg90
When I call the function many times with two or more servo, is seems they reproduce the movement in slow-motion.

I haven't tested lasers, but when I change the pwm of the fan, there are rpm "pulses" rarely. It might be the same thing, what you noticed with the laser. Nowadays I feed my pi with a 200W FSP PSU. The fan and the servos are on a different 5v branch, so I don't think it's a power related issue in my case.
I've just driven my hobby servos as fast I dare without breaking the poor things. Changing the pulse width 20 times per second. Seems OK.

Could you post or PM your control code?

dx21
Posts: 9
Joined: Sun Nov 18, 2012 9:17 pm

Re: Hardware PWM for servos, motors, and LEDs

Mon Nov 26, 2012 6:05 pm

Code: Select all

#include <stdio.h>
#include <pigpio.h>

#define SERVO_X 22

int servo_pos=600;

void servo_move(){
        gpioServo(SERVO_X,servo_pos);
        servo_pos+=100;
        if (servo_pos>=2400) servo_pos=600;

}

int main (void){

gpioInitialise();
gpioSetMode(SERVO_X,PI_OUTPUT);
gpioSetTimerFunc(0,1000,servo_move);
getchar();
gpioTerminate();
return 0;
This is not my original code, just an experiment. Even with this, the controlled servo is delay or jump a lot. Same behaviour when using gpioServo function with usleep.

User avatar
joan
Posts: 14017
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Hardware PWM for servos, motors, and LEDs

Mon Nov 26, 2012 6:38 pm

I modified your test code to reflect my servo end stops.

Code: Select all

#include <stdio.h>
#include <pigpio.h>

#define SERVO_X 22

int servo_pos=800;

void servo_move(){
        gpioServo(SERVO_X,servo_pos);
        servo_pos+=100;
        if (servo_pos>=2200) servo_pos=800;

}

int main (void){

gpioInitialise();
gpioSetMode(SERVO_X,PI_OUTPUT);
gpioSetTimerFunc(0,1000,servo_move);
getchar();
gpioTerminate();
return 0;
}
Unfortunately it works as expected for me.

I'll try to come up with a simple way of checking the output pulses.

dx21
Posts: 9
Joined: Sun Nov 18, 2012 9:17 pm

Re: Hardware PWM for servos, motors, and LEDs

Tue Nov 27, 2012 7:11 pm

What OS do you have in your Raspberry?

User avatar
joan
Posts: 14017
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Hardware PWM for servos, motors, and LEDs

Tue Nov 27, 2012 8:41 pm

dx21 wrote:What OS do you have in your Raspberry?
I normally use Debian. I only use Raspbian if I wan't to compile for hard float.

dx21
Posts: 9
Joined: Sun Nov 18, 2012 9:17 pm

Re: Hardware PWM for servos, motors, and LEDs

Fri Nov 30, 2012 7:11 pm

I've tested the library with Raspbian, and Debian. The behaviour is just the same. :(
Maybe something wrong with my pi? But if it's the case then why Servoblaster runs correctly?
What type of RaspPi do you have? I've got 1.1 B model.

User avatar
joan
Posts: 14017
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Hardware PWM for servos, motors, and LEDs

Fri Nov 30, 2012 7:52 pm

I loaded Arch and pacman'd this and pacman'd that and found the same as you. It works as I expect.

What does the output of

sudo ./checklib

say?

dx21
Posts: 9
Joined: Sun Nov 18, 2012 9:17 pm

Re: Hardware PWM for servos, motors, and LEDs

Fri Nov 30, 2012 11:58 pm

joan wrote:I loaded Arch and pacman'd this and pacman'd that and found the same as you. It works as I expect.

What does the output of

sudo ./checklib

say?
The output of "sudo ./checklib" :

Code: Select all

Initialisation test
TEST 1: PASS, pigpio version is 1

Alert function test, wait 2 seconds
No detected events on gpio 4 expected
Events=0
TEST 2: PASS

Servo pulse test (1500 micros), wait 10 seconds
Expect 500 pulses and an off/on ratio of 12.3
servo pulses=489 on ms=938 off ms=9042 ratio=9.6
TEST 3: FAILED

Servo pulse test (2000 micros), wait 10 seconds
Expect 500 pulses and an off/on ratio of 9.0
servo pulses=500 on ms=998 off ms=8983 ratio=9.0
TEST 4: PASS

Servo pulse test (2500 micros), wait 10 seconds
Expect 500 pulses and an off/on ratio of 7.0
servo pulses=500 on ms=1224 off ms=8759 ratio=7.2
TEST 5: PASS

PWM test (50), wait 5 seconds
Expect an off/on ratio of 0.804
pwm on ms=983 off ms=4008 ratio=0.803
TEST 6: PASS

PWM test (100), wait 5 seconds
Expect an off/on ratio of 0.608
pwm on ms=1967 off ms=3029 ratio=0.606
TEST 7: PASS

PWM test (150), wait 5 seconds
Expect an off/on ratio of 0.412
pwm on ms=2949 off ms=2050 ratio=0.410
TEST 8: PASS

PWM test (200), wait 5 seconds
Expect an off/on ratio of 0.216
pwm on ms=3932 off ms=1066 ratio=0.213
TEST 9: PASS

Timer ticktest (250 ms), wait 5 seconds
Expect 19 to 21 ticks
[email protected]:05:15.941
[email protected]:05:16.191
[email protected]:05:16.441
[email protected]:05:16.691
[email protected]:05:16.941
[email protected]:05:17.191
[email protected]:05:17.441
[email protected]:05:17.691
[email protected]:05:17.941
[email protected]:05:18.191
[email protected]:05:18.441
[email protected]:05:18.691
[email protected]:05:18.941
[email protected]:05:19.191
[email protected]:05:19.441
[email protected]:05:19.691
[email protected]:05:19.941
[email protected]:05:20.191
[email protected]:05:20.441
ticks=19
TEST 10: PASS

Timer ticktest (333 ms), wait 5 seconds
Expect 14 to 16 ticks
[email protected]:05:22.034
[email protected]:05:22.367
[email protected]:05:22.700
[email protected]:05:23.033
[email protected]:05:23.366
[email protected]:05:23.699
[email protected]:05:24.032
[email protected]:05:24.365
[email protected]:05:24.698
[email protected]:05:25.031
[email protected]:05:25.364
[email protected]:05:25.697
[email protected]:05:26.030
[email protected]:05:26.363
[email protected]:05:26.696
ticks=15
TEST 11: PASS

Timer ticktest (1000 ms), wait 5 seconds
Expect 4 to 6 ticks
[email protected]:05:28.708
[email protected]:05:29.708
[email protected]:05:30.708
[email protected]:05:31.708
ticks=4
TEST 12: PASS

Function parameter validation tests
Expect error messages

pigpio: gpioSetMode: bad gpio:54
pigpio: gpioSetMode: bad gpio:-1
pigpio: gpioSetMode: bad mode:8
pigpio: gpioSetMode: bad mode:-1
TEST 13: PASS

pigpio: gpioGetMode: bad gpio:54
pigpio: gpioGetMode: bad gpio:-1
TEST 14: PASS

pigpio: gpioSetPullUpDown: bad gpio:54
pigpio: gpioSetPullUpDown: bad gpio:-1
pigpio: gpioSetPullUpDown: bad pud:3
pigpio: gpioSetPullUpDown: bad pud:-1
TEST 15: PASS

pigpio: gpioRead: bad gpio:-1
pigpio: gpioRead: bad gpio:54
TEST 16: PASS

pigpio: gpioWrite: bad gpio:54
pigpio: gpioWrite: bad gpio:-1
pigpio: gpioWrite: bad level:2
pigpio: gpioWrite: bad level:-1
TEST 17: PASS

pigpio: gpioPWM: bad gpio:32
pigpio: gpioPWM: bad gpio:-1
pigpio: gpioPWM: bad dutycycle:256
pigpio: gpioPWM: bad dutycycle:-1
TEST 18: PASS

pigpio: gpioServo: bad gpio:32
pigpio: gpioServo: bad gpio:-1
pigpio: gpioServo: bad pulsewidth:1
pigpio: gpioServo: bad pulsewidth:-1
pigpio: gpioServo: bad pulsewidth:499
pigpio: gpioServo: bad pulsewidth:2501
TEST 19: PASS

pigpio: gpioSetAlertFunc: bad gpio:54
pigpio: gpioSetAlertFunc: bad gpio:-1
TEST 20: PASS

pigpio: gpioSetTimerFunc: bad timer id:5
pigpio: gpioSetTimerFunc: bad timer id:-1
pigpio: gpioSetTimerFunc: bad ms:9
pigpio: gpioSetTimerFunc: bad ms:60001
TEST 21: PASS

pigpio: gpioTime: bad timetype:-1
pigpio: gpioTime: bad timetype:2
TEST 22: PASS

pigpio: gpioSleep: bad timetype:-1
pigpio: gpioSleep: bad timetype:2
pigpio: gpioSleep: bad seconds:-1
pigpio: gpioSleep: bad micros:-1
pigpio: gpioSleep: bad micros:1000000
pigpio: gpioSleep: bad seconds:-1
pigpio: gpioSleep: bad micros:-1
pigpio: gpioSleep: bad micros:1000000
TEST 23: PASS

Library timer tests.
ABS time diff=6, REL time diff=54
ABS time diff=4, REL time diff=56
ABS time diff=5, REL time diff=55
ABS time diff=4, REL time diff=57
ABS time diff=4, REL time diff=56
ABS time diff=3, REL time diff=58
ABS time diff=4, REL time diff=57
ABS time diff=3, REL time diff=57
ABS time diff=4, REL time diff=57
ABS time diff=3, REL time diff=57
TEST 24: PASS

Library gpioSleep RELATIVE tests.
secs=1 micros=500000 err=402
secs=1 micros=400000 err=101
secs=1 micros=300000 err=103
secs=1 micros=200000 err=106
secs=1 micros=100000 err=106
secs=1 micros=0 err=104
secs=0 micros=900000 err=108
secs=0 micros=800000 err=106
secs=0 micros=700000 err=104
secs=0 micros=600000 err=106
secs=0 micros=500000 err=104
secs=0 micros=400000 err=111
secs=0 micros=300000 err=103
secs=0 micros=200000 err=100
secs=0 micros=100000 err=104
TEST 25: PASS

Library gpioSleep ABSOLUTE tests.
secs=371 micros=331355 err=86
secs=372 micros=732921 err=89
secs=374 micros=34546 err=85
secs=375 micros=236079 err=80
secs=376 micros=337688 err=83
secs=377 micros=339298 err=87
secs=378 micros=240819 err=79
secs=379 micros=42351 err=84
secs=379 micros=743927 err=87
secs=380 micros=345462 err=94
secs=380 micros=846989 err=87
secs=381 micros=248525 err=42
secs=381 micros=550023 err=86
secs=381 micros=751542 err=80
secs=381 micros=853038 err=82
TEST 26: PASS

Library gpioRead/Write_Bits_x_x_Set/Clear Tests
Expect 0 for pin 47 and >200000 for pin 48.
Expect the green LED to flash.

bank1=1000C1CF, bank2=003F0000, 47=0 48=731228
bank1=1004C1CF, bank2=003E0000, 47=0 48=736295
bank1=1005C1CF, bank2=003F0000, 47=0 48=731337
bank1=1000C1CF, bank2=003F0000, 47=0 48=735636
bank1=1000C1CF, bank2=003F0000, 47=0 48=732130
bank1=1005C1CF, bank2=003F0000, 47=0 48=735135
bank1=1004C1CF, bank2=003E0100, 47=0 48=732474
bank1=1000C1CF, bank2=003F0000, 47=0 48=736077
bank1=1001C1CF, bank2=003E0100, 47=0 48=731895
bank1=1004C1CF, bank2=003F0000, 47=0 48=736604
bank1=1004C1CF, bank2=003F0000, 47=0 48=732559
bank1=1000C1CF, bank2=003E0000, 47=0 48=737374
bank1=1000C1CF, bank2=003F0000, 47=0 48=734208
bank1=1004C1CF, bank2=003E0000, 47=0 48=736091
bank1=1004C1CF, bank2=003F0000, 47=0 48=736837
bank1=1000C1CF, bank2=003F0100, 47=0 48=735097
bank1=1000C1CF, bank2=003E0000, 47=0 48=737127
bank1=1004C1CF, bank2=003E0000, 47=0 48=734194
bank1=1004C1CF, bank2=003F0000, 47=0 48=737067
bank1=1000C1CF, bank2=003F0100, 47=0 48=733102
TEST 27: PASS

Summary: 27 tests, 26 passes

User avatar
joan
Posts: 14017
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Hardware PWM for servos, motors, and LEDs

Sat Dec 01, 2012 12:29 am

I'm afraid those tests suggest the library is working as expected. The tests use the sampling code and the pulse generation code in an isolated way. They have no knowledge of what the other is doing. Given that the sampling code detects a correct number(ish) of (servo) pulses and a correct ratio(ish) of on to off as generated by the pulsing code I'd say everything works as expected.

The first servo test failure may be an abberation. If you run it again it will probably pass.

I thought perhaps you had servoblaster loaded at the same time. Such a module would potentially conflict with another using DMA/PWM. As you have also tested on Debian/Raspbian that is less likely.

I am stumped.

aasdf
Posts: 2
Joined: Sun Dec 02, 2012 11:24 pm

Re: Hardware PWM for servos, motors, and LEDs

Mon Dec 03, 2012 11:54 am

Have you considered using the realtime PREEMPT capabilities of the more recent Arch linux kernels? Would probably guarantee a lot more stable timing.

emklaus
Posts: 1
Joined: Mon Jan 07, 2013 2:20 am

Re: Hardware PWM for servos, motors, and LEDs

Mon Jan 07, 2013 2:38 am

Hi joan;
I have download and used your excellent library.
Truly a fine piece of work, Thanks for all your efforts.

Is there any chance you would be sharing the source code for this project?

I'm really just getting started with my RPi (just got it for Christmas) and would love to see
how you managed to get all those lovely features working.
Plus it would be comforting to know I could re-compile it if a system update stopped it from working.

Thanks again
Eric

fallenwoods
Posts: 1
Joined: Fri Jan 18, 2013 4:31 pm

Re: Hardware PWM for servos, motors, and LEDs

Fri Jan 18, 2013 4:43 pm

I appreciate all the effort you put in to create this library. Nice wrok.

I do have some questions.

I tried using the library with mixed success. The LED stuff seems to work grea. For the servos, the first time I used it, the server ticked along in nice increments as expected. The 2nd, just made some tick noises, 3rd time swung all the way clockwise, now back to ticking noises.

My thought is that its either a) low power voltage to the server or b) some type of uninitialized pwm state left over from prior runs.

Regarding a), I tried to use 3v to the servos (*should* be sufficient). In the video you seem to go with a direct 6v. Is there a risk of damaging the RPi using 6v at the servo?

Regarding b), Do I have to do anything to reinitialize the pwm. I'm using the demolib code.

Many thanks

Tim

User avatar
joan
Posts: 14017
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Hardware PWM for servos, motors, and LEDs

Fri Jan 18, 2013 10:28 pm

The servos usually have 3 wires being red, black or brown, white or yellow.

Our sort of hobby servos should be powered with around 5V to the red wire and ground to the black or brown wire.

The white/yellow is a control signal from the Pi and is not connected to the 5V line.

How are you providing voltage to the servo?

User avatar
joan
Posts: 14017
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Hardware PWM for servos, motors, and LEDs

Tue Jan 22, 2013 10:12 pm

I prefer people to be using version 2 of the library. If you click the link in the first post you will now be downloading version 2 rather than version 1.

http://www.raspberrypi.org/phpBB3/viewt ... 37&t=30489

Return to “Automation, sensing and robotics”