Page 1 of 1
adafruit 16 channel servo driver
Posted: Thu May 22, 2014 11:24 am
by razor1331
Hi guys,
first of all I am new to RP please help me out here. (
https://learn.adafruit.com/adafruit-16- ... spberry-pi)
I am using this i2c servo driver for my project. how can i get a digital signal using pwm (ON/OFF)? because i ve 2 dc motors and 5 servos to control. i want use 4 pwm channels(basically how to get a digital output from this channels ) to control 2 motors that attached to l 298d. please help me out here.
thanks
Re: adafruit 16 channel servo driver
Posted: Thu May 22, 2014 12:02 pm
by BMS Doug
How far have you followed the tutorial you linked to?
this page of the tutorial tells you how to configure the outputs to PWM
Re: adafruit 16 channel servo driver
Posted: Thu May 22, 2014 12:06 pm
by razor1331
all.......
i tried "To turn an output OFF, set both ON and OFF times to 0.
To turn it ON, set the ON time to 0 and the OFF time to 4095".
already. it doesnt work. i even checked the voltage levels. they are 0V.but when i attached a servo its working just fine.
do i ve to change the frequency?
Re: adafruit 16 channel servo driver
Posted: Thu May 22, 2014 12:09 pm
by joan
That board is limited by design. It will not provide general PWM for servos, DC motors and LEDs. You have to use the same PWM frequency for all devices. Servos typically need 50Hz which isn't a good choice for DC motors or LEDs.
You do not need that board on the Pi. There are plenty of ways of providing PWM signals without additional hardware.
My
pigpio library will let you drive servos, DC motors and LEDs from C, Python, or the command line.
Re: adafruit 16 channel servo driver
Posted: Thu May 22, 2014 12:14 pm
by razor1331
thanks.
but i ve to save many giop for my other sensors,...that's why i am trying to control my servos and dc motors using the board. is there any way i can do that with this board?
Re: adafruit 16 channel servo driver
Posted: Thu May 22, 2014 12:28 pm
by joan
razor1331 wrote:thanks.
but i ve to save many giop for my other sensors,...that's why i am trying to control my servos and dc motors using the board. is there any way i can do that with this board?
You'll have to set the frequency to suit the servos and settle for less than optimal performance for DC motors and LEDs.
What connections have you made to the motor driver board? The connections you have made will determine how you control them with PWM.
Re: adafruit 16 channel servo driver
Posted: Thu May 22, 2014 3:28 pm
by razor1331
i did this modification to example code given with the lib..
pwm.setPWM(0,0,4096)
pwm.setPWM(1,0,0)
pwm.setPWM(2,0,4096)
pwm.setPWM(3,0,0)
i want the output in the board to be channel 0 => 5v ,ch 1=> 0v and go on...is it possible with this board?
Re: adafruit 16 channel servo driver
Posted: Thu May 22, 2014 9:23 pm
by joan
The documentation is unclear.
To be safe I'd try
pwm.setPWM(0,0,4095) # on at 0, off at 4095, pretty much full on
pwm.setPWM(1,0,1) # on at 0, off at 1, pretty much full off
pwm.setPWM(2,0,4095)
pwm.setPWM(3,0,1)
Re: adafruit 16 channel servo driver
Posted: Sat Mar 26, 2016 9:34 am
by RogerWhitfield
First I should say I am very new to Raspberry Pi and electronics so I have been experimenting to see what is and isn't possible.
Due to a desire to build a complex robot and because the RasPi does not have an unlimited number of pins I thought that using the Adafruit 16 channel servo controller and driver would leave me plenty of scope for many servo's and motors without using up all my GPIO pins.
I have successfully managed to drive 2 servo's, however I found the instructions somewhat complex and as soon as I started to experiment I got some quite unexpected results. To shed some light on what was happening I purchased a cheap USB oscilloscope so I could see on screen exactly what output I was getting from the PWM controller.
Now if I want to drive servo's I have to use a 50Hz frequency, and 50Hz may not be the best frequency for controlling DC motors but as this can only be set once on the board I am stuck with it. The board does support 40Hz to 1000Kz and with a little experimenting I found that it really does not make too much difference to the power output or the current used.
To hook up the DC motors I used an L293D H-Bridge controller, this requires 3 inputs to control a DC motor (forwards, reverse and enable). Manual testing showed that this works so then I started pulsing the enable pin on and off using the Pi and this controlled the speed of the motor.
So armed with this knowledge I hooked up the servo driver PWM pin only to the enable pin of the L293D, now when I set the PWM frequency and pulse length it directly controls the speed of each motor and if I set the PMW channel to off the motor stops. This means that I now only need to use 2 GPIO pins or each motor (forward and reverse) with the enable pin (speed) now controlled by the servo board.
The servo board uses a the notion of ticks to control the pulses so each cycle is measured as 4096 ticks (0 to 4095), this means to set a particular pulse length you need to specify the tick on which to send the signal high and the tick on which to send the cycle low. The actual length of a tick varies based upon the frequency used. To make more sense of this I manually calculated and then wrote code to replicate my calculations and then tested the results on an oscilloscope until I got it right.
I wrote the following code to allow me to set the speed as a pertcentage:-
def pulse_width(duty_rate): # enter between 1 and 100, although in practice you will probably need to start at about 20
cycle_length = float(1) / frequency
tick_length = float(cycle_length) / 4096
off_tick = 4096 * (duty_rate/100)
if off_tick > 4095:
off_tick = 4095 # make sure the maximum pulse value is not exceeded
return int(off_tick)
Armed with this code I can now control the speed of each motor by just setting the percentage of maximum I would like.
from Adafruit_PWM_Servo_Driver import PWM
power_percent = float(25) # set to 25%
off = pulse_width(power_percent) # send the percentage to get the off tick
pwm = PWM(0x40) # initialize PWM board (this address may vary on your Pi)
pwm.setPWMFreq(50) # sets frequency to 50Hz
pwm.setPWM(15, 0, off) # set channel 15 to go high at tick 0 and to go low at the off tick
High ___
| |
_______________| |
0 4095
At 50Hz 0 to 4096 is one 50th of a second, at 25% the PWM will stay low (output nothing) for three quarters of a cycle and then go high (output a signal) for one quarter of the cycle (one quarter of one 50th of one second)
So if you set the percentage at 100 (100%) the off tick will be 4095 so for each cycle the power will come on at 0 and go off at 4096, this means the power will be on for 100% of each cycle, therefore you get full power, equally 50% will give a pulse that is half of the cycle so you get half power. The power is pulsed 50 times a second (50Hz).
At all the frequencies this board is capable of (40Hz to 1000Hz) you will find that the motors will output a whine due to the frequency of the pulse. I believe that if you want to eliminate this whine you will have to use frequencies that fall outside of the range of human hearing but as this board cannot generate frequencies that high you would need to find another solution.
I hope that my struggles in learning how this works will help others in my position.
Re: adafruit 16 channel servo driver
Posted: Sat Mar 26, 2016 10:36 am
by joan
A fixed frequency for all outputs is a known limitation of the chip used by the board (I referred to it in my first post in the thread).
You don't actually need the board at all unless you need more GPIO than the Pi can supply. The Pi itself can generate the PWM needed for servos, LEDs, motors etc. on any GPIO in a more flexible fashion.
Some code I wrote for the PCA9685 chip may be of interest.
http://abyz.co.uk/rpi/pigpio/examples.h ... PCA9685_py