Build an Arduino Motor/Stepper/Servo Shield – Part 1: Servos
Join the DZone community and get the full member experience.
Join For Free
this post starts a small (or larger?) series of tutorials using the arduino motor/stepper/servo shield with the frdm-kl25z board. that motor shield is probably one of the most versatile on the market, and features 2 servo and 4 motor connectors for dc or stepper motors. that makes it a great shield for any robotic project
the series starts with a tutorial how to drive two servo motors. and if this is not what you are expecting to do with this shield, then you can vote and tell me what you want to see instead on this motor shield .
oem or original?
the original arduino motor/stepper/servo shield is available from adaftruit industries and costs less than $20. i’m using a oem version, see this link . the functionality is the same, except that the oem version only runs with motors up to 16 vdc, while the original shield is for motors up to 25 vdc.
the board has two stmicroelectronics l293d motor h-bridge ic’s which can drive up to 4 dc motors (or up to 2 stepper motors) with 0.6 a per bridge (1.2 a peak). the 74hct595n (my board has the sn74hc595 from texas instrument) is a shift register used for the h-bridges to reduce the number of pins needed (more about this in a next post). a terminal block with jumper is providing power to the dc/stepper motor. the 5 vdc for the servos is taken from the frdm board.
the frdm-kl25z can only give a few hundred ma on the 5v arduino header. that works for small servos, but i recommend to cut the 5v supply to the servos and use a dedicated 5v (or 6v) for the servos.
outline
in this tutorial, i’m creating a project with codewarrior for mcu10.4 for the frdm-kl25z board, and then add support for two servo motors.
processor expert components
this tutorial uses added processor expert components which are not part of codewarrior distribution. the following other components are used:
- wait : allows waiting for a given time
- servo : high level driver for hobby servp motors
make sure you have the latest and greatest components loaded from github . instructions how to download and install the additional components can be found here .
creating codewarrior project
to create a new project in codewarrior:
- file > new > bareboard project, give a project name
- specify the device to be used: mkl25z128
- opensda as connection
- i/o support can be set to ‘no i/o’
- processor expert as rapid application development option
this creates the starting point for my project:
servo motor
servo motors are used in rc (radio control) or (hobby) robotics.
the motor has 3 connectors:
- gnd (black)
- power (red), typically 5v, but can be 6v or even higher
- pwm (white or yellow), signal for position information
the pwm signal typically has frequency of 50 hz (20 ms), with a duty (high duration) between 1 ms and 2 ms.
the screenshot below shows such a 50 hz signal with 1.5 ms duty cycle (servo middle position):
many servos go below 1 ms and beyond 2 ms. e.g. many hitec servos have a range of 0.9…2.1 ms. check the data sheet of your servos for details. if you do not have a data sheet, then you might just experiment with different values.
with a pwm duty of 1 ms to 2 ms within a 20 ms period, this means that only 10% of the whole pwm duty are used. this means if you have a pwm resolution of only 8bits, then only 10% of 256 steps could be used. as such, an 8bit pwm signal does not give me a fine tuned servo positioning.
the duration of the duty cycle (1..2 ms) is translated into a motor position. typically the servo has a built-in closed-loop control with a microcontroller and a potentiometer.
i have found that it is not important to have an *exact* 50 hz pwm frequency. you need to experiment with your servo if it works as well with a lower or higher frequency, or with non-fixed frequency (e.g. if you do a software pwm). many servos build an average of the duty cycle, so you might need to send several pulses until the servo reacts to a changed value.
servo processor expert component
i’m using here my own ‘servo’ component which offers following capabilities:
- pwm configuration (duty and period)
- min/max and initialization values
- methods to change the duty cycle
- optional command line shell support: you can type in commands and control the servo. this is useful for testing or calibration.
- optional ‘timed’ moving, so you can move the servo faster or slower to the new position in an interrupt driven way
of course it is possible to use servos without any special components.
from the components view, i add the servo component. to add it to my project, i can double-click on it or use the ‘+’ icon in that view:
in case the processor expert views are not shown, use the menu processor expert > show views
this will add a new ‘servo’ component to the project:
but it shows errors as first the pwm and pin settings need to be configured.
pwm configuration
on the arduino motor/stepper/servo shield the two servo motor headers are connected to pwm1b and pwm1a (see schematic ):
following the signals, this ends up at following pins on the kl25z:
- servo 1 => pwm1b => arduino header d10 => frdm-kl25z d10 => kl25z pin 73 => ptd0/spi0_pcs0/ tpm0_ch0
- servo 2 => pwm1a => arduino header d9 => frdm-kl25z d9 => kl25z pin 78 => adc0_se6b/ptd5/spi1_sck/uart2_tx/ tpm0_ch5
from the pin names on the kinets (tpm0_ch0 and tpm0_ch5) i can see that this would be the same timer (tpm0), but with different channel numbers (ch0 and ch5).
for my first servo processor expert has created for me a ‘timerunit_ldd’ which i will be able to share (later more on this). the timerunit_ldd implements the ‘ l ogical d evice d river’ for my pwm:
so i select the pwm component inside the servo component and configure it for tpm0_c0v and the pin ptd0/spi0_pcs0/tpm0_ch0 with low initial polarity. the period of 20 ms (50 hz) and starting pulse with of 1.5 ms (mid-point) should already be pre-configured:
i recommend to give it a pin signal name (i used ‘servo1′)
that i need to set the ‘initial polarity’ to low is a bug of processor expert in my view: the device supports an initial ‘high’ polarity, but somehow this is not implemented? what it means is that the polarity of the pwm signal is now inverted: a ‘high’ duty cycle will mean that the signal is low. we need to ‘revert’ the logic later in the servo component.
because of the inverted pwm logic, i need to set the ‘inverted pwm’ attribute in the servo component:
the other settings of the servo component we can keep ‘as is’ for now. the ‘min pos pwm’ and ‘max pos pwm’ define the range of the pwm duty cycle which we will use later for the servo position.
adding second servo
as with the first servo, i add the second servo from the components library view. as i already have a timerunit_ldd present in my system, processor expert asks me if i want to re-use the existing one or to create a new component:
as explained above: i can use the same timer (just a different pin/channel), so i have my existing component selected and press ok.
as above, i configure the timer channel and pin with initial polarity:
and i should not forget to enable the inverted logic:
test application
time to try things out. for this i create a simple demo application which changes the position of both servos. first i add the wait component to the project from the components library:
as i have all my processor expert components configured, i can generate the code:
next i add a new header
application.h
file to my project. for this i select the ‘sources’ folder of my project and use the
new > header file
context menu to add my new header file:
in that header file
application.h
i add a prototype for my application ‘run’ routine:
from the
main()
in
processorexpert.c
, i call that function (not to forget to include the header file):
the same way i add a new source file application.c:
to test my servos, i’m using the setpos() method which accepts a 8bit (0 to 255) value which is the position. to slow things a bit, i’m waiting a few milliseconds between the different positions:
#include "application.h" #include "wait1.h" #include "servo1.h" #include "servo2.h" void app_run(void) { uint16_t pos; for(;;) { for(pos=0;pos<=255;pos++) { servo1_setpos(pos); servo2_setpos(pos); wait1_waitms(50); } } }
save all files, and we should be ready to try it out on the board.
build, download and run
that’s it! time to build the project (menu project > build project ) and to download it with the debugger (menu run > debug ) and to start the application. if everything is going right, then the two servos will slowly turn in one direction until the end position, and then return back to the starting position.
summary
using hobby servo motors with the frdm-kl25z, codewarrior, processor expert and the additional components plus the arduino/stepper/servo shield is very easy in my view. i hope this post is useful to start your own experiments with hobby servo motors to bring any robotic project to the next level.
i have here on github a project which features what is explained in this post, but with a lot more components, bells and whistles
Published at DZone with permission of Erich Styger, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments