Recent Changes - Search:

Home

edit SideBar

SD-21

SD-21 on Flickr 
SD-21 on Flickr 

The SD-21  is a 21 channel servo controller that is a slave on the I2C bus. It is just a PIC18F2220 chip preprogrammed to continuously update the position of each servo with the input it receives from the master, making it as easy as writing a single line of code to update any servo's position.

In our setup, the SD-21 requires two power sources: one for the logic and another for powering the servos. There is a way to bridge the servo power source if need be, but as we are using two power supplies anyway, it works well.

A Quick Note About Servos

Servos are boxes with small motors, a gearbox and a potentiometer inside. This allows the output shaft to be positioned within a 180 degree range of motion with great accuracy. A standard hobby servo produces about 40 oz./in. of torque, which is enough to rotate a head, control steering system, or actuate an arm.

Servos have three pins: two provide power (red and black) and the third is the input which tells the servo which position to rotate to. The signal is a continuous series of pulses ranging from 1ms to 2ms, spaced at intervals of ~20ms. A 1ms pulse tells the servo to rotate counter-clockwise 90 degrees from center, 2ms is 90 degrees clockwise from center, and 1.5ms means to return to the center state.

The pulses must be continuous, that is if they stop the servo might behave unpredictably. It is a small chore for any microcontroller to send a pule out on an output pin every 20ms in addition to performing other tasks, let alone sending 20 pulses every 20ms! It is for this reason that we abstract this to a servo controller; we can tell the controller to send servo 1 to center position, and forget about it knowing that the controller has it taken care of.

Read more about servo theory and how to work with them on Lynxmotion's "what is a servo?"  page

Registers

The SD-21 shows up as a series of registers that can be read to and written from the I2C bus:

SD-21 Register Table
RegisterServoFunction RegisterServoFunction RegisterServoFunction
01Speed 249Speed 4817Speed
11Low byte 259Low byte 4917Low byte
21High byte 269High byte 5017High byte
32Speed 2710Speed 5118Speed
42Low byte 2810Low byte 5218Low byte
52High byte 2910High byte 5318High byte
63Speed 3011Speed 5419Speed
73Low byte 3111Low byte 5519Low byte
83High byte 3211High byte 5619High byte
94Speed 3312Speed 5720Speed
104Low byte 3412Low byte 5820Low byte
114High byte 3512High byte 5920High byte
125Speed 3613Speed 6021Speed
135Low byte 3713Low byte 6121Low byte
145High byte 3813High byte 6221High byte
156Speed 3914Speed 63-
166Low byte 4014Low byte 64-Software version
176High byte 4114High byte 65-Battery Volts
187Speed 4215Speed
197Low byte 4315Low byte
207High byte 4415High byte
218Speed 4516Speed
228Low byte 4616Low byte
238High byte 4716High byte

(Table shamelessly copied from robot-electronics.com)

You might notice that each channel has three registers associated with it: speed, low byte and high byte.

In order to control a servo, you must set the low byte and high byte for the position desired in microseconds. To center a servo, you would send it a 1.5ms pulse, so sending the SD-21 a value of 1500 will do the same thing.

A single byte (such as 0xFF) has a resolution of only 255 steps, so in order to get the full range of motion from a servo, the SD-21 requires a low byte and a high byte for each servo.

1500 (decimal) is 0x05DC in hexadecimal. In order to get the low byte, simply AND the value desired with 0xFF; to get the high byte, shift the value right by 8 bits. In C/C++, the code would look something like:

int myValue = 1500;
int lowByte = myValue & 0xFF;
int highByte = myValue >> 8;

The speed register for each channel is a way to linearly set the speed at which the servo will be directed to reach the desired position. The default is 0, full speed ahead. The speed is reset to 0 every time the power is cycled on the SD-21, so be sure to set it to the desired value every time your robot restarts.

The equation for the speed is: ((Target position-Start position)/Speed Reg)*20mS

That is, if you have a servo at position 2000 and you want to move it to position 1000 (180 degrees), and the speed register is set to 5 then it would take 4 seconds to complete the rotation.

Battery Checking

Register 65 on the SD-21 is a live readout of the current battery voltage updated every 20ms whether it is checked or not. It is measured in 39mV units, so a typical 7.2V battery should give a reading of 184.6 when full. The equation is simply register_65 * 0.039 = battery_volts

Edit - History - Print - Recent Changes - Search
Page last modified on May 08, 2008, at 02:13 PM EST