PDA

View Full Version : AX12A sync write



DVS
08-12-2013, 05:45 PM
Hi all, i have tried to write a sync write function for my 12 ax12a servos used in my quadruped. I am using a arduino mega 2560 and i am experienceing some problems.
The function works fine if i call it only once, so for example Posture_Write(c); gives the correct positions and Posture_Write(d); would also give the correct positions. However if i try to do something like
Posture_Write(c);
delay(500);
Posture_Write(d);
my servos start acting erreatic.
I am not sure if this is maybe because i am not suppling them with enough current; i have 4 power suplys in parallel and have also tried connecting to a 1800ma 35c lipo and got similar problems (however not much testing was done with the lipo)
I thought it may be a problem with the baud rates and have set them 9600 and then have gotten no response from comands such as SetPostion(id,pos) but i have created another post on that all togther.
Thanks alot for any help


#include <ax12.h>
#include <BioloidController.h>
// float a[]={10,10,10,10,10,10,10,10,10,10,10,10};
float a[]={0,0,0,0,0,0,0,0,0,0,0,0};
float b[]={0,0,0};
float c[]={-20,45,-45,-20,45,-45,20,45,-45,20,45,-45};
float d[]={0,45,-45,0,45,-45,0,45,-45,0,45,-45};
void setup() {
Serial.begin(9600);
Posture_Write(c);

delay(1000);
}

void loop() {

//
// Posture_Write(c);
// c[0]=-c[0];
// c[3]=-c[3];
// c[6]=-c[6];
// c[9]=-c[9];


delay(1000);
//SetPosition(3,512);
}


void Posture_Write(float servo_positions[])
{
//float servo_positions[sizeof(Given_Position)/sizeof(Given_Position[0])];
// memcpy(servo_positions,Given_Position,sizeof(servo _positions[0]));
//Serial.println(servo_positions[0]);


int No_Legs=4; //Input the number of 3-DOF legs of the robot
int Length=(2+1)*3*No_Legs+4; //calculate the length as defined in ax12a datasheet
int Data_Len=2; //Length of data to be written (Goal pos low and high)
int checksum=254+Length+AX_SYNC_WRITE+AX_GOAL_POSITION _L+Data_Len; //Preliminary checksum
int total_servos=3*No_Legs; //Calculate total number of servos that need to be writen to
float mulfactor=1024.0/300.0;
int i;
for(i=0;i<No_Legs;i++) //Correct orientation for robot servo setup
{
if(i < No_Legs/2)
{
servo_positions[i*3]=servo_positions[i*3]*-1;
servo_positions[i*3+1]=servo_positions[i*3+1]*-1;
}
else
{
servo_positions[i*3+2]=servo_positions[i*3+2]*-1;
}
}

int s;
for (s=0;s<12;s++)
{
Serial.print("servo no: ");
Serial.println(s);
Serial.println(servo_positions[s]);
// Serial.println(Given_Position[s]);

}


setTXall();
ax12write(0xFF); //Writing Handshaking
ax12write(0xFF); //Writing Handshakng
ax12write(0xFE); //Sync Write Broadcast
ax12write(Length); //Length
ax12write(AX_SYNC_WRITE); // Instruction
ax12write(AX_GOAL_POSITION_L); //Parameter 1 (GP(L))
ax12write(0x02); //length of data to be written
for(int i=1;i<=total_servos;i++)
{
ax12write(i); //Servo to be written to
ax12write(int((servo_positions[i-1]+150)*mulfactor)&0xff); //GoalPosition(L) for servo i
ax12write(int((servo_positions[i-1]+150)*mulfactor)>>8); //GoalPosition(H) for servo i
// Serial.println(i);
// Serial.println((servo_positions[i-1]+150)*1024/300);

checksum+= i+(int((servo_positions[i-1]+150)*mulfactor)&0xff)+ (int((servo_positions[i-1]+150)*mulfactor)>>8);
}
ax12write(0xff - (checksum % 256)); //Calculate and send Fletchers Checksum

}

jwatte
08-12-2013, 09:25 PM
Power supplies in parallel is a recipe for trouble. Unless they are designed to be parallel-able, you are likely not helping things by paralleling them (but rather creating the possibility of explosions, fire, or power transients.)

kamondelious
08-12-2013, 09:28 PM
Here's silly question. Which/whose library are you using?

#include <ax12.h>
#include <BioloidController.h>

This leave a little too much guess work. Arbotix? Your own? From someone's blog? Other?

Help us, helping you. ;)

DVS
08-13-2013, 03:24 AM
I am using the Arbotix library.
Thanks alot for the help guys.

KurtEck
08-13-2013, 09:05 AM
I am not 100% sure of what is going on with your version, but will take a few guesses. I have expermented some using an ATmega board. Mine was an older 1280 board, but should not make much difference.

Also not sure how you have your AX12's wired up to the Atmega. I was using a DFRobot board sold by robotshop (http://www.robotshop.com/productinfo.aspx?pc=RB-Dfr-142&lang=en-US). So I did not have to play around with the RX/TX lines. Also not sure what you are using for serial port software. I am assuming you are using the standard Arduino hardware serial port code. Likewise not sure which version of the IDE your are running. But will assume at least 1.xxx

Things that I would look at include:
a) The writes to hardware serial port (at least later versions of IDE) are buffered. So might need to do a flush to make sure everything is out. Assuming that any of your timing code depends on when the command actually is acted on. In your case probably not issue as you are waiting a half second...

b) May need to clear input buffer at appropriate times (or disable input or...). That is if your input and output pins on the serial port are tied together, when you output stuff to the servos, it may be echoing it back in the RX pin which the interrupt processing then puts that character back into the input buffer... In your code just before trying to output the 2nd position, try reading from the serial port until you get an empty condition and see if that helps.

c) In my own Phoenix driver when I was experimenting with Syncwrite, I had a call to:
setRX(0);
Right after the output of the checksum byte, not sure if that would help you here or not...


d) I would hook up Logic Analyzer to see what is actually going in and out, but I know that is cheating.

As I mentioned I have my own hacked up version of the AX12 library that worked for me with that hardware...

Not sure if that helps, but...
Kurt

kamondelious
08-14-2013, 09:15 PM
I am using the Arbotix library.

Have a look at BioloidController::writePose() since it does a sync write. You may want to make use of the pose based code already there, or modify it to meet your needs.