Let's Make Robots!

picaxe programming sd21


I am using a sd21 servo controller board with a 18x picaxe inserted. I have downloaded the sample program it ti works ( moves sevo to each end). What I need to know is how to control the speed of the servo.

What i am really after is someone to give me some program showing how i can move a couple of servos at different speeds after an imput has been activated. I tried reading manuals over and over and still dont get it.





Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Typical hobby servos don't have speed control, only position commands. To get around this, the most common method is to feed the servo incremental changes in position.

Let's say you want a servo to move from 20° to 80°. If you tell it to go to 20°, and then to go to 80°, it moves too quickly.
Instead what you can do it tell the servo to move to 20°, then to 21°, then to 22°... and so on ... then to 79°, then to 80°.
If the servo move to slowly then you can increment the position by a larger number, perhaps 5° instead of 1°.
Instead, if the servo is still moving too fast, you can add an extra delay between each position command.

This board has speed control built in, Mr. Fox... (You know, that sounded like "Mr. Bond...." in my head)

Alright dude, I'll try this one... You are sending commands to this guy using the i2c lines. If you need help with i2c protocall, just ask and I can give you a hand. Lets assume you are familiar with the commands used and/or you can figure it out with some cutting and pasting from what you have. Each servo has 3 registers (addresses --I might say address, I mean register) to make it go. Two of them relate to the posistion and the third is the speed to get there. Let's start with the first 2 registers. The servo's posistion is determined by the width of a pulse, and that pulse sent to the servo is between 1.2us to 2us --or so. The first two bytes you send determine the length of the pulse that will be sent and thus the position. Two bytes (16 bits) are used to obtain better accuracy when positioning the servo. Think of it this way: If you send a byte, you can only send a number between 0 and 255 which gets converted to the pulswidth. If you send two bytes, the same conversion happens but the number being converted is now between 0 and 65,535. You can see that we just increased the "resolution" 256 times better!

In picaxe speak, 2 bytes is a word variable or b1/b0=w0, b2,b3=w1 etc. There is a high byte and a low byte that comprises each word variable. Using the debug window, you can see how a word variable is broken down to it's corresponding bytes and the value of its bytes. This is what we are doing in the first and second registers you are sending to the servo controller. To be honest, I don't know what you which one you should send first but here is how I would experiment:

Pick a number, any number and stick it into a word variable, debug and figure out what bytes you get out of it. Send the bytes as register 1 and 2 and see where the servo goes. Play around with this and make yourself a little table of what numbers do what.

Now speed it seems is the third chunk of data you need to send. It seems that 0 is full speed and bigger numbers sent slow it down. There are some examples on the data sheet --i'm sure you can convert from there.

Back to position for a second, there is a different set of registers you can command the servos with that use just one byte to determine position but it has to be done with some kinda offset conversion and it confused me and I stopped reading.

If some real code guy reads this, he can explain what the high and low bytes are.

Your code :

i2cslave whatever your sample code says -cut and paste this

writei2c first-register-for-your-servo,(one of the bytes) 'stick a # before the byte maybe

writei2c second register,(the other byte) 'stick a # before the byte maybe

writei2c third register,(how much slower than full speed you want to go) 'with a # maybe

Oops, looks like the SD21 is doing all the stuff I was talking about for you, serves me right for not reading the post properly =)

Not sure if this was the same documentation you had Chris, but this guide seems to cover all the bases nicely. There's a good explanation of how the speed control works, and what results you'll get, plus there's some example code right at the end.

Yeah, that's the data sheet I was reading. I'll be curious to see if anything I wrote above makes sense to the poster or anyone for that matter! :)

ok, now I watch the servo moving back and forth as per the sample program. Can someone show me the change in the sample program to change the speed of the servo regards michael '*************************** '* SD21 example code * '* with picaxe 18x * '*************************** i2cslave $C2,i2cfast,i2cbyte ' Join i2c with SD21 main: i2cwrite 63,(255) ' Set servo 1 to 255 pause 500 i2cwrite 63,(128) ' Set servo 1 to 128 pause 500 i2cwrite 63,(0) ' Set servo 1 to 0 pause 500 i2cwrite 63,(128) ' set servo 1 to 128 pause 500 goto main

You want something along the lines of:

i2cwrite 0,(16)

Where 0 is the address for the speed setting of servo 1, and 16 is the speed value you're writing to it.

I managed to get it working, thanks for all your posts

This is what I ended up with. The first part was to work out the limits of the crane (grapper, lift and slew).

The second bit is an attempt to attach a switch and the third part is the looped program




i2cslave $C2,i2cslow,i2cbyte ' Join i2c with SD21                                                           ' grabber (servo 1) 1.           'i2cwrite 0,(10)                       ' speed opening (1 to 16)

            'i2cwrite 63,(225)       ' Set servo 1 to 255 (full open 225)

            'pause 3000

            'i2cwrite 0,(10)                       ' speed closing

            'i2cwrite 63,(70)                     ' closed 70

            'pause 3000    


                                                            ' lift (servo 3)lower number adds height

            'i2cwrite 6,(10)                       ' speed opening (1 to 16)

            'i2cwrite 65,(60)                     ' Set servo 1 to 255

            'pause 3000


                                                            ' slew (servo 2)

'main:i2cwrite 3,(5)                ' speed 

            'i2cwrite 64,(10)                     ' slew anticlockwise

            'pause 4000

            'i2cwrite 3,(5)             ' slew clockwise 

            'i2cwrite 64,(145)                  

            'pause 4000    






                        if pin0 = 1 then label_7          'Decision command

                        goto label_2



                        high 1

                        high 4

                        low 1

                        low 4

                        goto label_2














            i2cwrite 6,(10)                        ' lift (servo 3)lower number adds height

            i2cwrite 65,(60)                      ' start position


            i2cwrite 3,(5)              ' slew (servo 2)

            i2cwrite 64,(145)                    ' start position



            i2cwrite 0,(10)                        ' grabber (servo 1) open position

            i2cwrite 63,(225)                    ' start position


            i2cwrite 3,(5)              ' slew anticlockwise 

            i2cwrite 64,(10)                     

            pause 4000


            i2cwrite 6,(5)              ' lower arm

            i2cwrite 65,( 130)                  

            pause 3000


            i2cwrite 0,(10)                        ' grabber closing

            i2cwrite 63,(70)                       

            pause 3000     



            i2cwrite 6,(5)              ' lift arm

            i2cwrite 65,(60)                     

            pause 3000



            i2cwrite 3,(5)              ' slew clockwise

            i2cwrite 64,(145)                   

            pause 4000



            i2cwrite 0,(10)                        ' open grabber 

            i2cwrite 63,(225)                   

            pause 3000


            goto main

My next question is how to activate a servo sequence from a high input. There are 2 seperate servo sequences operated by 2 seperate inputs