Strange problems programming SSC-32, using sprintf in C code

I’m trying to control some servos from a simple C program in linux, and I noticed that my setServoPosition function only works once or twice (testing with 1 servo). My test function worked like a charm, even though it was the same code basically, except the test code was sending commands for two different servos (even though one is plugged in).

This is my setServoPosition function:

void setServoPosition(int servo, int newPos)
{
char command[100];

sprintf(&command[0], “#%dP%d\r”, servo, newPos);
cout<<"Sending command: "<<command<<endl;
write(fd, command, 27);
usleep(1000000);
}

This works once or twice, then the servo will no longer move. I added an extra bit at the end telling the SSC-32 to also set some non-existent servo to a position, and it works everytime:

void setServoPosition(int servo, int newPos)
{
char command[100];

// Add extra BS servo commands at the end…
sprintf(&command[0], “#%dP%d#10P1500\r”, servo, newPos);
cout<<"Sending command: "<<command<<endl;
write(fd, command, 27);
usleep(1000000);
}

What am I doing wrong with this sprintf? I’m glad I found a workaround, but I would like to know what I’m doing wrong here. Any tips would be most appreciated!

isn’t the 27 in your write() command the string length? wouldn’t the string length vary depending on servo and newPos unless you fixed their length in the sprintf() format string?

something like sprintf( &command 0 ], "#%-2dP%-4d\r", servo, newPos ) ; and/or write( fd, command, strlen( command ) ) ;

The SSC-32 will not act on any command until it receives a CR. I’m not a C programmer, but I don’t see the CR in the first example.

Doh. It is, I just pulled that 27 over from a code sample, that is supposed to be sizeof. However it still doesn’t work without the bogus servo command at the end…

The /r is a carriage return, this works perfectly as long as I have an extra servo command tacked on:

void setServoPosition(int servo, int newPos)
{
char command[100];

sprintf(&command[0], “#%dP%d#10P1500\r”, servo, newPos);
// sprintf(&command[0], “#%dP%d\r”, servo, newPos);
// cout<<"Sending command: "<<command<<endl;
// cout<<"Command length: "<<sizeof(command);
write(fd, command, sizeof(command));
}

I don’t actually have a servo “10”, but having an extra servo command after my real one makes the write work everytime.

You might have to send \n\r or \r\n to terminate the command to the SSC-32. I have found this is true for regular serial communication written in C using PICs.

8-Dale

sizeof( command ) returns the length of the entire array, in this case 100.
strlen( command ) will return the number of characters in the array command until it finds a \0 character (which is put there by the sprintf() function after your string.)

try it you’ll like it. :wink:

seems like a combination of the \n\r and strlen did it, thanks a ton for the help!

Hi,

you can also just use the return value of the printf().

And as you probably know, you can combine strings with printf() quite easily:

len = sprintf(&buff[0], “#9P1500”);
len += sprintf(&buff[len], “#8P1500T160”);
loc += sprintf(&buff[len], “\n(A3)\r\n”);

And the SSC-32 appears to tolerate comments. This can be useful to annotate writes to the SSC32.

Alan KM6VV

I don’t think “sizeof” returns the size of arrays at all(I haven’t used it in a long time). “sizeof” returns the size of the pointer to the array(in this case).So you end up with “sizeof” always returning 4(bytes).

Also the \r is a linefeed command(decimal 11 IIRC) and the \n is the carriage return(decimal 13).

I’m not sure what K&R or ANSI say sizeof() is supposed to do but the Visual C 6 implementation returns 100 for {unsigned char command[100];} Trust me on this. :wink:

hi,

sizeof() returns the size of the array, as Eddie has indicated. If one wants the quantity of entries of arrays other then char, then one often does this:

sizeof(command) / sizeof(int)

If the command was made up of int. This is platform independent, and recommended.

Alan KM6VV