Legacy Forum: Preserving Nearly 20 Years of Community History - A Time Capsule of Discussions, Memories, and Shared Experiences.

Programming for AX-12

Bioloid robot kit from Korean company Robotis; CM5 controller block, AX12 servos..
5 postsPage 1 of 1
5 postsPage 1 of 1

Programming for AX-12

Post by Starlight » Fri Feb 27, 2009 9:44 am

Post by Starlight
Fri Feb 27, 2009 9:44 am

Hi all. currently I'm writing moving position for sync write. I'm using PIC18F4550, and for single dynamixel, it perform well. By the way, I wanna control up to 14 number of dynamixel, so it will waste a lots of time to calculate the checksum. So I came up with the following code:
(control only 2 number of dynamixel)

*******MOVING POSITION (SYNC WRITE)***********
uart_send(0xFF);
uart_send(0xFF);
uart_send(0xFE);
uart_send(0x0E); //LENGTH = (L+1)*N+4
uart_send(0x83);
uart_send(0x1E); //goal position
uart_send(0x04); //length of data to be written (1 dynamixel)
sendSW(1,0x0010,0x0150);
checksum_1 = sendSW (1,0x0010,0x0150);
sendSW(2,0x0220,0x0360);
checksum_2 = sendSW (2,0x0220,0x0360);
t_checksum = checksum_1 + checksum_2;
uart_send(0x4E+t_checksum); //total checksum

char sendSW (char id, int pos, int speed)
{
uart_send(id); //ID
uart_send((char)pos);
uart_send((char)(pos>>8));
uart_send((char)speed); //Moving Speed
uart_send((char)(speed>>8));
return(~(char)(id+(char)pos+(char)(pos>>8)+(char)speed+(char)(speed>>8))); //checksum
}

But it seem not exactly corret, is there any error or mistake in calculating the return value of checksum ?

Or have anyone came out with better method for controlling up to 14 number of dynamixel without wasting lots of time in calculating the checksum and reduce the line of programming ?

Thanks !
Hi all. currently I'm writing moving position for sync write. I'm using PIC18F4550, and for single dynamixel, it perform well. By the way, I wanna control up to 14 number of dynamixel, so it will waste a lots of time to calculate the checksum. So I came up with the following code:
(control only 2 number of dynamixel)

*******MOVING POSITION (SYNC WRITE)***********
uart_send(0xFF);
uart_send(0xFF);
uart_send(0xFE);
uart_send(0x0E); //LENGTH = (L+1)*N+4
uart_send(0x83);
uart_send(0x1E); //goal position
uart_send(0x04); //length of data to be written (1 dynamixel)
sendSW(1,0x0010,0x0150);
checksum_1 = sendSW (1,0x0010,0x0150);
sendSW(2,0x0220,0x0360);
checksum_2 = sendSW (2,0x0220,0x0360);
t_checksum = checksum_1 + checksum_2;
uart_send(0x4E+t_checksum); //total checksum

char sendSW (char id, int pos, int speed)
{
uart_send(id); //ID
uart_send((char)pos);
uart_send((char)(pos>>8));
uart_send((char)speed); //Moving Speed
uart_send((char)(speed>>8));
return(~(char)(id+(char)pos+(char)(pos>>8)+(char)speed+(char)(speed>>8))); //checksum
}

But it seem not exactly corret, is there any error or mistake in calculating the return value of checksum ?

Or have anyone came out with better method for controlling up to 14 number of dynamixel without wasting lots of time in calculating the checksum and reduce the line of programming ?

Thanks !
Starlight
Robot Builder
Robot Builder
Posts: 21
Joined: Wed Oct 08, 2008 2:52 am

Re: Programming for AX-12

Post by StuartL » Fri Feb 27, 2009 10:14 pm

Post by StuartL
Fri Feb 27, 2009 10:14 pm

Starlight wrote:Or have anyone came out with better method for controlling up to 14 number of dynamixel without wasting lots of time in calculating the checksum and reduce the line of programming ?


The way we do it in libbioloid (check out the other threads on this) is to have a function to send the start of a packet, a function to send packet data and a function to send the end of a packet.

The logic goes something like this:

Code: Select all
uint8_t packetchecksum;

void packet_start(uint8_t id, uint8_t length) {
   checksum = id + length;
   uart_send(0xff);
   uart_send(0xff);
   uart_send(id);
   uart_send(length);
}

void packet_data(uint8_t *data, uint8_t length) {
   uint8_t count = length;
   uint8_t *ptr = data;
   while (count--) {
      uart_send(*ptr);
      checksum += *ptr;
      ptr++;
   }
}

void packet_end(void) {
   uart_send(~checksum);
}

void send_ping(uint8_t id) {
   packet_start(id, PING_LENGTH);
   packet_data(PING_DATA, PING_DATALENGTH);
   packet_end();
}


Please don't use the code above as-is without sanity checking it, it's written off the top of my head and probably has many bugs. It's more to illustrate a point :D
Starlight wrote:Or have anyone came out with better method for controlling up to 14 number of dynamixel without wasting lots of time in calculating the checksum and reduce the line of programming ?


The way we do it in libbioloid (check out the other threads on this) is to have a function to send the start of a packet, a function to send packet data and a function to send the end of a packet.

The logic goes something like this:

Code: Select all
uint8_t packetchecksum;

void packet_start(uint8_t id, uint8_t length) {
   checksum = id + length;
   uart_send(0xff);
   uart_send(0xff);
   uart_send(id);
   uart_send(length);
}

void packet_data(uint8_t *data, uint8_t length) {
   uint8_t count = length;
   uint8_t *ptr = data;
   while (count--) {
      uart_send(*ptr);
      checksum += *ptr;
      ptr++;
   }
}

void packet_end(void) {
   uart_send(~checksum);
}

void send_ping(uint8_t id) {
   packet_start(id, PING_LENGTH);
   packet_data(PING_DATA, PING_DATALENGTH);
   packet_end();
}


Please don't use the code above as-is without sanity checking it, it's written off the top of my head and probably has many bugs. It's more to illustrate a point :D
StuartL
Savvy Roboteer
Savvy Roboteer
Posts: 350
Joined: Mon Jun 04, 2007 3:46 pm
Location: Thatcham, Berkshire, UK

Post by Starlight » Sat Feb 28, 2009 7:51 am

Post by Starlight
Sat Feb 28, 2009 7:51 am

Hi. May I ask how to implementing a continuously rotating wheel ? from the manual, it state that set the CW and CCW angle limit to 0. then set the Goal Speed.

uart_send(0xff);
uart_send(0xff);
uart_send(0x0d); //ID
uart_send(0x07); //length
uart_send(0x03); //write_data
uart_send(0x06); //starting address: CW angle limit
uart_send(0x00); //CW angle limit
uart_send(0x00);
uart_send(0x00); //CCW angle limit
uart_send(0x00);
uart_send(0xe9); //checksum

~~waiting for transmit


uart_send(0xff);
uart_send(0xff);
uart_send(0x0d); //ID
uart_send(0x05); //length
uart_send(0x03); //write data
uart_send(0x20); //starting address: moving speed
uart_send(0x50);
uart_send(0x01);
uart_send(0x79); //checksum

while(TXSTAbits.TRMT==0);

LATCbits.LATC0 =1;

So the above code is the correct one?
Hi. May I ask how to implementing a continuously rotating wheel ? from the manual, it state that set the CW and CCW angle limit to 0. then set the Goal Speed.

uart_send(0xff);
uart_send(0xff);
uart_send(0x0d); //ID
uart_send(0x07); //length
uart_send(0x03); //write_data
uart_send(0x06); //starting address: CW angle limit
uart_send(0x00); //CW angle limit
uart_send(0x00);
uart_send(0x00); //CCW angle limit
uart_send(0x00);
uart_send(0xe9); //checksum

~~waiting for transmit


uart_send(0xff);
uart_send(0xff);
uart_send(0x0d); //ID
uart_send(0x05); //length
uart_send(0x03); //write data
uart_send(0x20); //starting address: moving speed
uart_send(0x50);
uart_send(0x01);
uart_send(0x79); //checksum

while(TXSTAbits.TRMT==0);

LATCbits.LATC0 =1;

So the above code is the correct one?
Starlight
Robot Builder
Robot Builder
Posts: 21
Joined: Wed Oct 08, 2008 2:52 am

Post by Starlight » Sat Feb 28, 2009 8:01 am

Post by Starlight
Sat Feb 28, 2009 8:01 am

uint8_t packetchecksum;

void packet_start(uint8_t id, uint8_t length) {
checksum = id + length;
uart_send(0xff);
uart_send(0xff);
uart_send(id);
uart_send(length);
}

void packet_data(uint8_t *data, uint8_t length) {
uint8_t count = length;
uint8_t *ptr = data;
while (count--) {
uart_send(*ptr);
checksum += *ptr;
ptr++;
}
}

void packet_end(void) {
uart_send(~checksum);
}

void send_ping(uint8_t id) {
packet_start(id, PING_LENGTH);
packet_data(PING_DATA, PING_DATALENGTH);
packet_end();
}


is that the above code controlling 1 dynamixel ? I wanna control up to 14 dynamixel on the same time for sync write. from the user manual page 23, there is more like instruction(0x83), ID(0xfe), .etc.
uint8_t packetchecksum;

void packet_start(uint8_t id, uint8_t length) {
checksum = id + length;
uart_send(0xff);
uart_send(0xff);
uart_send(id);
uart_send(length);
}

void packet_data(uint8_t *data, uint8_t length) {
uint8_t count = length;
uint8_t *ptr = data;
while (count--) {
uart_send(*ptr);
checksum += *ptr;
ptr++;
}
}

void packet_end(void) {
uart_send(~checksum);
}

void send_ping(uint8_t id) {
packet_start(id, PING_LENGTH);
packet_data(PING_DATA, PING_DATALENGTH);
packet_end();
}


is that the above code controlling 1 dynamixel ? I wanna control up to 14 dynamixel on the same time for sync write. from the user manual page 23, there is more like instruction(0x83), ID(0xfe), .etc.
Starlight
Robot Builder
Robot Builder
Posts: 21
Joined: Wed Oct 08, 2008 2:52 am

Post by Starlight » Sun Mar 01, 2009 3:55 pm

Post by Starlight
Sun Mar 01, 2009 3:55 pm

Hi all. I have another question about the time delay of programming. As I know that Ax-12 have the feedback position, so how can I using this kind of method? let say I have movement1 and movement2. after the execution of movement1, wait for about 2 second, the movement2 are execute. So how we write this kind of programming using the feedback position of movement1, confirm the position of movement1(executed), then execute movement2 ? Thanks.
Hi all. I have another question about the time delay of programming. As I know that Ax-12 have the feedback position, so how can I using this kind of method? let say I have movement1 and movement2. after the execution of movement1, wait for about 2 second, the movement2 are execute. So how we write this kind of programming using the feedback position of movement1, confirm the position of movement1(executed), then execute movement2 ? Thanks.
Starlight
Robot Builder
Robot Builder
Posts: 21
Joined: Wed Oct 08, 2008 2:52 am


5 postsPage 1 of 1
5 postsPage 1 of 1