IoT Zone is brought to you in partnership with:

Erich is Professor at Lucerne University of Applied Sciences and Arts and Distinguished Member of Technical Staff at Freescale Semiconductor. Erich has a MsCS degree and 18+ years of experience in the embedded software and tools world. He created many embedded cross C/C++ compilers and debuggers. Additionally he is researching in the domain of programming languages, real time and mechatronic systems. Erich is a DZone MVB and is not an employee of DZone and has posted 130 posts at DZone. You can read more from them at their website. View Full User Profile

Build an Arduino Motor/Stepper/Servo Shield – Part 1: Servos

06.02.2013
| 9312 views |
  • submit to reddit

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 :-) 

Arduino Motor Stepper Servo Shield with FRDM-KL25Z

Arduino Motor Stepper Servo Shield with FRDM-KL25Z

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.

Motor Stepper Servo Shield Details

Motor Stepper Servo Shield Details

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:

  1. Wait: allows waiting for a given time
  2. 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:

  1. File > New > Bareboard Project, give a project name
  2. Specify the device to be used: MKL25Z128
  3. OpenSDA as connection
  4. I/O support can be set to ‘No I/O’
  5. Processor Expert as Rapid Application Development option

This creates the starting point for my project:

New Servo Project Created

New Servo Project Created

Servo Motor

Servo motors are used in RC (Radio Control) or (hobby) robotics.

Typical Servo Motor (Hitec HS-303)

Typical Servo Motor (Hitec HS-303)

The motor has 3 connectors:

  1. GND (Black)
  2. Power (Red), typically 5V, but can be 6V or even higher
  3. 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):

Servo Signal

Servo Signal

:idea: 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.

:idea: 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

:idea: 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:

Servo Component in Components Library View

Servo Component in Components Library View

:idea: 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:

Servo Component added

Servo Component added

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):

 DK Electronics Shield Schematic)

Servo Header on Board (Source: DK Electronics Shield 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 ‘Logical Device Driver’ for my PWM:

TimerUnit_LDD

TimerUnit_LDD

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:

Servo1 PWM Configuration

Servo1 PWM Configuration

:idea: 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:

Inverted PWM

Inverted PWM

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:

Shared Component Dialog

Shared Component Dialog

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:

Servo2 PWM Configuration

Servo2 PWM Configuration

And I should not forget to enable the inverted logic:

Inverted PWM for Servo2

Inverted PWM for Servo2

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:

Added Wait Component

Added Wait Component

As I have all my Processor Expert components configured, I can generate the code:

Generating Processor Expert Code

Generating Processor Expert 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:

New Application.h

New Application.h

In that header file Application.h I add a prototype for my application ‘run’ routine:

Added APP_Run Prototype

Added APP_Run Prototype

From the main() in ProcessorExpert.c, I call that function (not to forget to include the header file):

Calling APP_Run from main

Calling APP_Run from main

The same way I add a new source file Application.c:

New Application.c

New 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, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)