Serial 8-servo controller

Hey, I’ve got 4AA batteries to the controller, and 4 more to the servo power. When powered the orange LED comes on, I assume this is normal? because without a servo connected it’s lit up. My servo’s wires are orange, red, brown. I assumed brown was the black(-) so I plugged it in like it was and the servo jerked (so I assume everything is good so far).
But when I run
colinkarpfinger.com/pololu/
with the right com port, 9600 baud
I click send with 3000 in the “servo coordinates” box.
When I do that the red LED starts blinking, I’ve been trying to play around with the baud and other things and looking at other threads, but haven’t had any luck, any suggestions?

Hey, I haven’t seen that tutorial before. Thanks for posting the link!

It sounds to me like your serial cable might be a null-modem cable, rather than a serial extension cable. In a null-modem cable the transmit and receive serial lines are switched (like an ethernet crossover cable).

If you have a multimeter you could test pins 2 and 3, you want them to be wired straight (2-2, 3-3) but if they’re swapped (2-3,3-2) you have a crossover cable. To see if the cable is the problem you could also unscrew the standoffs from the servo controller board and try plugging it directly into your computer’s com port!

Was that it?

-Adam

Thanks for the help, but the cable is not the problem, I checked the box of the cable and it’s not a crossover, and I put the controller directly into the port. I have found out that with that code I can get MiniSSC Protocol to work! But pololu just flashes red :\ Also in miniSSC mode I can move the slider from the far left to the far right and the servo moves a little over 90 degrees, I’m wondering if this is as far as the servo can go or not. Read that pololu mode was more accurate or something…so that’s why I want to use it.
Thankyou

I’ll take a look at the program (I’m not too familiar with Visual Basic) but my guess is that it’s using Mini-SSCII mode using the lower set of servo address numbers, which basically limits the servo motion to half of it’s possible range of motion. You can reach the full range of motion using Mini-SSCII mode, you just have to send commands to servo numbers 8-15 rather than 0-7.

Here’s a quick question though, did you remember to remove the blue protocol selection jumper before powering up your servo controller when you tried Pololu mode? It’s the one on the right of this picture:

-Adam

Taking a quick look at the serial data your test program sends out, lets say I tell it to send position 127 in Mini-SSCII mode, it outputs:

So that’s a start byte, servo address number 7, and position 127. Mini-SSCII mode has 255 possible positions. Since it’s addressing the last servo as number 7, it’s limiting the servo controller to half the possible servo range in order to double the position precision. If the program were sending commands to servo 15, the same servo would move, and would have double the motion range, but still only 255 possible positions, so the increments you could move it in would be twice as large.

Pololu mode is a little more complicated, but has many more features like speed control and higher resolution. In Pololu mode, the servo’s whole range of motion (and then some) is split up into 5000 increments, which is probably higher range and resolution than your servo can actually reach/measure, so you’re sure to get its best possible performance.

When I use your demo program to send position 3000 in Pololu mode, it outputs:

Hex: 80 01 01 07 00 80 01 04 07 (17 38)=(3000 in Pololu protocol) Dec: 128 1 1 7 0 128 1 4 7 (23 56)

This is actually two commands, one which sets the servo controller’s servo 7 speed to full (which is the default, and so really unnecessary) and one which sets servo seven’s absolute position to 3000, the middle of its range (like 127 in Mini-SSCII mode).

Anyway, I could go on all day about servo controller protocol (really, I could), but the important thing is that the test program is sending out proper commands in both Mini-SSCII and Pololu modes, so if your controller works in Mini-SSCII mode, I’m guessing that the mode selection jumper is the issue. The jumper needs to be connecting the protocol selection pins when you power up the servo controller to operate in Mini-SSCII mode, and off the pins when you power it up for Pololu mode. Was that it?

-Adam

hahaha, yeah it was the jumper :stuck_out_tongue:
thankyou

I’ll have to reread your posts a few times to fully understand them (shouldn’t be too hard), but how did the programmer get these values as the min and max.
const int MIN_ANGLE = 1350 , MAX_ANGLE = 4350;
It varies from servo to servo I know that, but is there a safe way to determine the min and max of a specific servo?

I was gonna ask this later on, but if I modded a servo for infinite rotation the servo controller couldn’t do the absolute postion mode4 because it eventually peak at it’s voltage output. Haven’t read into the other modes too much yet, but would it be possible to just keep adding one to whatever the position was? Not sure if that was clear.
Thank you :smiley:

Cool, glad you’re in business.

The only real way to determine the safe range of a servo is to try it and see, as the exact values will vary from servo to servo. There is a mechanical stop built into one of the gears in the gear train to protect the potentiometer, which is what you hit when you turn a servo by hand as far as it will go. If you command your servo to or past this point, it will press against the mechanical stop, stall the motor, draw lots of current, heat things up, etc… None of this is immediately fatal for your servo, but it can be very bad for it over time. If you send a position command way out of range you’ll probably hear the servo shuddering, but even a slightly out of range command will stall the motor.

The best way to determine the safe range of a servo is to command it incrementally to one side, lets say towards the maximum position, until it is clearly not moving with successive commands. Start decrementing the position command until you see the servo twitch slightly back towards center. That position is your safe maximum, as far as you can go towards max without physically hitting the mechanical stop. Do the same for other side to find the safe minimum and you’re in business!

Now, unfortunately, modifying a servo for continuous rotation doesn’t mean you still have direct position control (i.e. you can’t exactly command the servo to turn 500 degrees clockwise). Inside your servo (and I highly recommend taking one apart to see) there is a rotary potentiometer, which is basically a variable resistor, turned by the last gear in the gear-train (same as the output shaft). This is the same kind of component behind most simple volume control knobs, and you can’t turn it all the way around. In fact, the mechanical stop is there to keep the motor from driving the potentiometer past it’s limits and damaging it.

When you modify a servo for continuous rotation, you really have three options:

  1. Remove the potentiometer, cut/file off the mechanical gearstop, remove the electronics and power the motor directly. This gives you a small, high torque continuous rotation motor and gear train enclosed in a neat little box, which you can drive with your own DC motor controller.

  2. Cut/file off the mechanical gearstop, and replace the potentiometer with two constant resistors. This gives you a continuous rotation motor which will go forward/stop/reverse (but with poor speed control in between) in response to a normal servo control signal.

  3. Cut/file off the mechanical gearstop, and move the potentiometer out of the servo (extend its three wires) to some other rotary linkage driven by the servo. This gives you rotary position control over something rotated by the servo, even if there is more gearing in between them. You can also use this for linear control by replacing the rotary potentiometer with a linear slide potentiometer. I did both for this project. Those are modified servos on the base, and the long wires lead to potentiometers I took out of the servos and hacked onto the joints of the robot arm driven by each servo.

If you want to do continuous rotation with position control and rotate more than 180 degrees, you’ll need a motor with an encoder, or a stepper motor, which are quite different, but also fun!

-Adam

Just to clarify… the program is written in C#, not VB.

You were right, those values for max / min are just arbitrary, I agree w/ Adam’s method for finding them.

Glad to see more people using my tutorial :slight_smile:

Been busy with school, but I started playing around again, I just go my java program to move it to the center! Hopefully it should not be too long till I have some worth while code, but the only really painful part for me right now is the splitting up of the bits.
Thanks for the tutorial cfinger!!! :smiley:
I think I understood how you got the upper and lower bits in your code awhile ago, but I’ll have to read over it again. Could anyone possibly explain what’s happening with out the code? To clarify I am talking about

Hex: 80 01 01 07 00 80 01 04 07 (17 38)=(3000 in Pololu protocol) Dec: 128 1 1 7 0 128 1 4 7 (23 56)

how you get the 0x17 and 0x38 from 23 and 56, and how’d you figure out 23 and 56 are the middle and what not lol

17 is 23 expressed in base 16 (and Dec 56=Hex 38, and Dec 128=Hex 80). Hexadecimal numbers (0x17) are numbers in base 16, as opposed to base 10 like we’re all used to. The letters A through F are used for the extra six digits (unfortunately not apparent in any of the numbers mentioned so far). If we were all born with eight fingers on each hand, we’d all probably be counting in Hex! Number systems based on powers of two are common in computer applications, since they lend themselves to digital representation.

To illustrate, lets do a little counting in binary (base 2), octal (base 8), decimal (base 10), and hexidecimal (base 16).

Binary, Octal, Decimal, Hexidecimal:
0, 0, 0, 0
1, 1, 1, 1
10, 2, 2, 2
11, 3, 3, 3
100, 4, 4, 4
101, 5, 5, 5
110, 6, 6, 6
111, 7, 7, 7
1000, 10, 8, 8
1001, 11, 9, 9
1010, 12, 10, A
1011, 13, 11, B
1100, 14, 12, C
1101, 15, 13, D
1110, 16, 14, E
1111, 17, 15, F
10000, 20, 16, 10
10001, 21, 17, 11
10010, 22, 18, 12
10011, 23, 19, 13
10100, 24, 20, 14
10101, 25, 21, 15
10110, 26, 22, 16
10111, 27, 23, 17
11000, 30, 24, 18
11001, 31, 25, 19
11010, 32, 26, 1A
11011, 33, 27, 1B
11100, 34, 28, 1C
11101, 35, 29, 1D
11110, 36, 30, 1E
11111, 37, 31, 1F
100000, 40, 32, 20

If you use a Windows computer, load up the calculator, and under the “view” menu select “scientific”. You should now have a set of buttons that let you switch the displayed number between Hex, Dec, Oct, and Bin. Play around a little! You’re all set when you get this joke:

Why did the programmer wear a scary costume to the Christmas party? Because he confused Dec 25 with Oct 31! Hahahaha!

Anyway, you can generally enter numbers in whatever base you like in your code, and the compiler will convert it all to binary anyway. So, you can type in MAX_ANGLE=4350, or MAX_ANGLE=0x10FE. The 0x just lets the compiler know you’re talking in hex now, in either case it will internally represent the number as 1000011111110 anyway.

For an answer to your second question, I think I’ve got a good explanation of how to calculate the Pololu mode absolute position command numbers this thread. Let me know if anything is unclear!

-Adam

:open_mouth: wow, I actually understand it, that one thread you posted was extremely helpful! Thank You!