BasicMicroUK - Forums

www.basicmicro.co.uk
It is currently Sun Nov 19, 2017 11:39 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: packet serial control "robo claw" with arduino
PostPosted: Tue Aug 17, 2010 1:42 pm 
Offline
Citizen

Joined: Tue Aug 17, 2010 1:08 pm
Posts: 6
hello everyone:)

I want to control the basic-micro robo-claw 2x5A motor driver with an arduino (AVR mega1280) via paket-serial. In the robo-claw manual (http://downloads.basicmicro.com/downloa ... _B0099.pdf) are only e.g. for the basic-micro controller "basic atom-pro" wich differs a lot to an avr`s code.

Are there more known deatils about the robo claw-serial protocol?

Or code examples for the arduino enviroment??

Anybody an idea how to make them communicate (paket serial)??

Or code examples for the arduino enviroment??


thx dave


Top
 Profile  
 
 Post subject: Re: packet serial control "robo claw" with Arduino
PostPosted: Tue Aug 17, 2010 3:17 pm 
Offline
Master

Joined: Tue Nov 21, 2006 5:34 pm
Posts: 662
Hi Dave,

I have not tried this at all, but should not be difficult. The packet serial is just outputting data over a serial port to the roboclaw.

Since you are on a Mega Arduino. I would connect up the roboclaw up to one of the hardware serial ports like #1.

Startup the serial port to match the Roboclaws baud rate:
Code:
Serial1.begin(19200);


Then when you need to output, you can either directly to the port with constant values or create functions to do it.
Code:
;Basic Micro Robo Claw Packet Serial Test Commands 0 to 13.
;Switch settings: SW3=ON and SW5=ON.
Main
Pause 2000
Serout P15, i19200, [128, 0, 127, (255 & 0x7F)];M1 full speed forward
Serout P15, i19200, [128, 4, 127, (259 & 0x7F)];M2 full speed forward


This could be hard coded in several different ways.
Code:
static byte s_c1[] = {128, 0, 127, 255 & 0x7f};
static byte s_c2[] = {128, 0, 127, 255 & 0x7f};
...
delay(2000);
Serial1.write(s_c1, sizeof(s_c1));
Serial1.write(s_c1, sizeof(s_c2));

Note, I typed this in on the fly, did not compile or test this... Also if I were doing this I would not code it this way. I would probably have subroutines to output the commands. Would not hard code 128 as the logical address of the Roboclaw. Would either pass it or convert to a #define. So likewise would generate the checksum on the fly... Could be as simple as:
Code:
void RC_DriveMotor1(byte bCon, byte bSpeed)
{
    byte ab[4];
    ab[0] = bCon;
    ab[1] = 0;
    ab[2] = bSpeed;
    ab[3] = (ab[0]+ab[1]+ab[2]) & 0x7f;
    Serial1.write(ab, sizeof(ab));
}

Good Luck
Kurt


Top
 Profile  
 
 Post subject: Re: packet serial control "robo claw" with arduino
PostPosted: Tue Aug 17, 2010 4:41 pm 
Offline
Citizen

Joined: Tue Aug 17, 2010 1:08 pm
Posts: 6
when the sun sets i´ll give it a try!

thx a lot kurt


Top
 Profile  
 
 Post subject: Re: packet serial control "robo claw" with arduino
PostPosted: Tue Aug 17, 2010 5:01 pm 
Offline
Site Admin
User avatar

Joined: Thu Mar 01, 2001 7:00 pm
Posts: 1316
Location: Temecula, CA
Just so everyone is clear. The RoboClaw is processor agnostic. As long as you send the correct serial data it doesn't care what processor is sending it.

_________________
Tech Support
Basic Micro - Robotic Technology Evolved


Top
 Profile  
 
 Post subject: Re: packet serial control "robo claw" with arduino
PostPosted: Wed Aug 18, 2010 1:34 am 
Offline
Citizen

Joined: Tue Aug 17, 2010 1:08 pm
Posts: 6
yep everything worx fine:) thx again.
next step read quad encoder..

dave


Top
 Profile  
 
 Post subject: Re: packet serial control "robo claw" with arduino
PostPosted: Tue Nov 30, 2010 7:22 pm 
Offline
New User

Joined: Mon Nov 29, 2010 7:44 am
Posts: 2
Location: Los Angeles, CA
Since I found the responses by Kurt to be helpful, here is some more tested, but not beautiful code that extends what he suggested. The encoder numbers need to be changed to match your encoders.


Code:
void setup()
{
  Serial.begin(9600);
}

void loop()
{
delay(5000);
  //RC_DriveMotor1(128, 127);
  //M1Speed(128, 6000, 6000);
  M1Dist(128, 36000, 36000, 36000);
delay(5000);
  //RC_DriveMotor1(128, 0);
  //M1Speed(128, 6000,-6000);
  //M1Speed(128, 6000,0);
  M1Dist(128, 36000, -36000, 36000);
}

void RC_DriveMotor1(byte bCon, byte bSpeed)
{
    byte ab[4];
    ab[0] = bCon;
    ab[1] = 0;
    ab[2] = bSpeed;
    ab[3] = (ab[0]+ab[1]+ab[2]) & 0x7f;
    Serial.write(ab, sizeof(ab));
}

void M1Speed(byte bCon, long Accel, long Speed) {
    byte ab[11];
    ab[0] = bCon;
    ab[1] = 38;
    ab[2] = (Accel >> 24) & 0xff;
    ab[3] = (Accel >> 16) & 0xff;
    ab[4] = (Accel >> 8) & 0xff;
    ab[5] = (Accel >> 0) & 0xff;
    ab[6] = (Speed >> 24) & 0xff;
    ab[7] = (Speed >> 16) & 0xff;
    ab[8] = (Speed >> 8) & 0xff;
    ab[9] = (Speed >> 0) & 0xff;
    ab[10] = (ab[0]+ab[1]+ab[2]+ab[3]+ab[4]+ab[5]+ab[6]+ab[7]+ab[8]+ab[9]) & 0x7f;
    Serial.write(ab, sizeof(ab));
}

void M1Dist(byte bCon, long Accel, long Speed, long Dist) {
    //Accel, Speed Dist
    byte ab[16];
    ab[0] = bCon;
    ab[1] = 44;
    ab[2] = (Accel >> 24) & 0xff;
    ab[3] = (Accel >> 16) & 0xff;
    ab[4] = (Accel >> 8) & 0xff;
    ab[5] = (Accel >> 0) & 0xff;
    ab[6] = (Speed >> 24) & 0xff;
    ab[7] = (Speed >> 16) & 0xff;
    ab[8] = (Speed >> 8) & 0xff;
    ab[9] = (Speed >> 0) & 0xff;
    ab[10] = (Dist >> 24) & 0xff;
    ab[11] = (Dist >> 16) & 0xff;
    ab[12] = (Dist >> 8) & 0xff;
    ab[13] = (Dist >> 0) & 0xff;
    ab[14] = 0; //buffer 0=yes, 1=no (immediate)
    ab[15] = (ab[0]+ab[1]+ab[2]+ab[3]+ab[4]+ab[5]+ab[6]+ab[7]+ab[8]+ab[9]+ab[10]+ab[11]+ab[12]+ab[13]+ab[14]) & 0x7f;
    Serial.write(ab, sizeof(ab));
}


Top
 Profile  
 
 Post subject: Re: packet serial control "robo claw" with arduino
PostPosted: Tue Nov 30, 2010 7:34 pm 
Offline
Site Admin
User avatar

Joined: Thu Mar 01, 2001 7:00 pm
Posts: 1316
Location: Temecula, CA
The code looks beautiful enough to me. It's very clear and anything you could do to make it more efficient would make it harder to read.

_________________
Tech Support
Basic Micro - Robotic Technology Evolved


Top
 Profile  
 
 Post subject: Re: packet serial control "robo claw" with arduino
PostPosted: Wed Dec 01, 2010 8:54 am 
Offline
New User

Joined: Mon Nov 29, 2010 7:44 am
Posts: 2
Location: Los Angeles, CA
Thanks. Here's a bit more code to hopefully help the next person. I was about to post a question about the accuracy of the distance (encoder) commands, and found the helpful info in the encoders thread on how the RoboClaw does PID on the speed, and not the distance, so getting a precise distance takes some more work. So, here is a simple function to at least do the basic trapezoidal move, which is still not precise, but much better. This can definitely be further improved.

FWIW, it's hopefully going to be used in an updated version of my project at http://www.teletoyland.com/Projects/Sandbox. I know that CNC projects are not recommended, but this is a low precision application. :-)

Code:
#define RoboClawAddr 128    // the RoboClaw address
#define FullSpeed 36000L     // the top speed you want the motor to move in clicks per second
#define ClicksPerRev 12000L  // the number of encoder clicks per revolution

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  delay(6000);
  M1TrapezoidDist(ClicksPerRev * 3);  // forward 3 revolutions
  delay(6000);
  M1TrapezoidDist(-ClicksPerRev * 3); // backward 3 revolutions
}

// A better approximation of the distance based on the comments in the Basic Micro forum
// This is not super accurate since the RobOClaw does PID on Speed, not Distance, but it's
// better than a pure Dist command
// The input is a signed distance in clicks
void M1TrapezoidDist(long tDist) {
  long decelDist;
  long accel;
  int speedSign;
 
  speedSign = tDist / abs(tDist);  // get the sign of the dist since the RoboClaw uses the sign on the speed param
  accel = FullSpeed; // assuming the Accel is the Same as speed (1 second to get to full speed)
  decelDist = (FullSpeed * FullSpeed) / (2 * accel);
  M1Dist(RoboClawAddr, accel, speedSign * FullSpeed, abs(tDist) - decelDist);
  M1Dist(RoboClawAddr, accel, 0, 0);  // buffered command will kick in once the distance above is hit, then drop to zero
}

void M1Dist(byte bCon, long Accel, long Speed, long Dist) {
    //Accel, Speed Dist
    byte ab[16];
    ab[0] = bCon;
    ab[1] = 44;
    ab[2] = (Accel >> 24) & 0xff;
    ab[3] = (Accel >> 16) & 0xff;
    ab[4] = (Accel >> 8) & 0xff;
    ab[5] = (Accel >> 0) & 0xff;
    ab[6] = (Speed >> 24) & 0xff;
    ab[7] = (Speed >> 16) & 0xff;
    ab[8] = (Speed >> 8) & 0xff;
    ab[9] = (Speed >> 0) & 0xff;
    ab[10] = (Dist >> 24) & 0xff;
    ab[11] = (Dist >> 16) & 0xff;
    ab[12] = (Dist >> 8) & 0xff;
    ab[13] = (Dist >> 0) & 0xff;
    ab[14] = 0; //buffer 0=yes, 1=no (immediate)
    ab[15] = (ab[0]+ab[1]+ab[2]+ab[3]+ab[4]+ab[5]+ab[6]+ab[7]+ab[8]+ab[9]+ab[10]+ab[11]+ab[12]+ab[13]+ab[14]) & 0x7f;
    Serial.write(ab, sizeof(ab));
 }


Top
 Profile  
 
 Post subject: Re: packet serial control "robo claw" with arduino
PostPosted: Wed Dec 01, 2010 3:04 pm 
Offline
Master

Joined: Tue Nov 21, 2006 5:34 pm
Posts: 662
Thanks for the update here, I will have to try it out!

Kurt


Top
 Profile  
 
 Post subject: Re: packet serial control "robo claw" with arduino
PostPosted: Thu Feb 17, 2011 4:22 pm 
Offline
New User

Joined: Fri Jan 14, 2011 11:34 pm
Posts: 3
Encase anyone else is trying to use the roboclaw with an arduino, I am working on translating all the packet serial commands written in basic format to the arduino format.

I'm not an expert at programming, so if you see mistakes let me know and I will correct them. This is what I have so far, I will update this when I finish.

Code:
#define address 128


/*
** 0 - Drive Forward M1
** Drive motor 1 forward. Valid data range is 0 - 127. A value of 127 = full speed forward, 64 = about
** half speed forward and 0 = full stop. Example with Robo Claw address set to 128:
**
** Serout P15, i19200, [128, 0, 127, (255 & 0X7F)] ;M1 full speed forward
*/

void drive_forward_m1(byte m1_speed_f)
{
   byte serial_data[4];
   serial_data[0]=address;
   serial_data[1]=0;
   serial_data[2]=m1_speed_f;
   serial_data[3]=(serial_data[0] + serial_data[1] + serial_data[2] + serial_data[3]) & 0x7F;
   
   serial.write(serial_data, sizeof(serial_data));
}


/*
** 1 - Drive Backwards M1
** Drive motor 1 backwards. Valid data range is 0 - 127. A value of 127 full speed backwards, 64 =
** about half speed backward and 0 = full stop. Example with Robo Claw address set to 128:
**
** Serout P15, i19200, [128, 1, 127, (256 & 0X7F)] ;M1 full speed backward
*/

void drive_backwards_m1(byte m1_speed_b)
{
   byte serial_data[4];
   serial_data[0]=address;
   serial_data[1]=1;
   serial_data[2]=m1_speed_b;
   serial_data[3]=(serial_data[0] + serial_data[1] + serial_data[2] + serial_data[3]) & 0x7F;
   
   serial.write(serial_data, sizeof(serial_data));
}


/*
** 2 - Set Minimum Main Voltage
** Sets main battery (B- / B+) minimum voltage level. If the battery voltages drops below the set
** voltage level Robo Claw will shut down. The value is cleared at start up and must set after each
** power up. The voltage is set in .2 volt increments. A value of 0 sets the minimum value allowed which
** is 6V. The valid data range is 0 - 120 (6V - 30V). The formula for calculating the voltage is: (Desired
** Volts - 6) x 5 = Value. Examples of valid values are 6V = 0, 8V = 10 and 11V = 25. Example with
** Robo Claw address set to 128:
**
** Serout P15, i19200, [128, 2, 25, (165 & 0X7F)]
*/

void min_voltage_value(byte min_battery_voltage)
{
   byte serial_data[4];
   serial_data[0]=address;
   serial_data[1]=2;
   serial_data[2]=min_battery_voltage;
   serial_data[3]=(serial_data[0] + serial_data[1] + serial_data[2]) & 0x7F;

   serial.write(serial_data, sizeof(serial_data));
}


/*
** 3 - Set Maximum Main Voltage
** Sets main battery (B- / B+) maximum voltage level. The valid data range is 0 - 154 (0V - 30V). If
** you are using a battery of any type you can ignore this setting. During regenerative breaking a back
** voltage is applied to charge the battery. When using an ATX type power supply if it senses anything
** over 16V it will shut down. By setting the maximum voltage level, Robo Claw before exceeding it will
** go into hard breaking mode until the voltage drops below the maximum value set. The formula for
** calculating the voltage is: Desired Volts x 5.12 = Value. Examples of valid values are 12V = 62, 16V
** = 82 and 24V = 123. Example with Robo Claw address set to 128:
**
** Serout P15, i19200, [128, 3, 82, (213 & 0X7F)]
*/

void max_voltage_value(byte max_battery_value)
{

   byte serial_data[4];
   serial_data[0]=address;
   serial_data[1]=3;
   serial_data[2]=min_battery_voltage;
   serial_data[3]=(serial_data[0] + serial_data[1] + serial_data[2]) & 0x7F;

   serial.write(serial_data, sizeof(serial_data));
}


/*
** 4 - Drive Forward M2
** Drive motor 2 forward. Valid data range is 0 - 127. A value of 127 = full speed forward, 64 = about
** half speed forward and 0 = full stop. Example with Robo Claw address set to 128:
**
** Serout P15, i19200, [128, 0, 127, (255 & 0X7F)] ;M2 full speed forward
*/

void drive_forward_m2(byte m2_speed_f)
{
   byte serial_data[4];
   serial_data[0]=address;
   serial_data[1]=4;
   serial_data[2]=m2_speed_f;
   serial_data[3]=(serial_data[0] + serial_data[1] + serial_data[2] + serial_data[3]) & 0x7F;
   
   serial.write(serial_data, sizeof(serial_data));
}


/*
** 5 - Drive Backwards M2
** Drive motor 2 backwards. Valid data range is 0 - 127. A value of 127 full speed backwards, 64 =
** about half speed backward and 0 = full stop. Example with Robo Claw address set to 128:
**
** Serout P15, i19200, [128, 1, 127, (256 & 0X7F)] ;M2 full speed backward
*/

void drive_backwards_m2(byte m2_speed_b)
{
   byte serial_data[4];
   serial_data[0]=address;
   serial_data[1]=5;
   serial_data[2]=m2_speed_b;
   serial_data[3]=(serial_data[0] + serial_data[1] + serial_data[2] + serial_data[3]) & 0x7F;
   
   serial.write(serial_data, sizeof(serial_data));
}


/*
** 6 - Drive M1 (7 Bit)
** Drive motor 1 forward and reverse. Valid data range is 0 - 127. A value of 0 = full speed reverse, 64 =
** stop and 127 = full speed forward. Example with Robo Claw address set to 128:
**
** Serout P15, i19200, [128, 6, 96, (230 & 0X7F)] ;M1 half speed forward
*/

void drive_m1(byte m1_speed)
{
   
   byte serial_data[4];
   serial_data[0]=address;
   serial_data[1]=6;
   serial_data[2]=m1_speed;
   serial_data[3]=(serial_data[0] + serial_data[1] + serial_data[2] + serial_data[3]) & 0x7F;
   
   serial.write(serial_data, sizeof(serial_data));
}

   
/*
** 7 - Drive M2 (7 Bit)
** Drive motor 2 forward and reverse. Valid data range is 0 - 127. A value of 0 = full speed reverse, 64 =
** stop and 127 = full speed forward. Example with Robo Claw address set to 128:
**
** Serout P15, i19200, [128, 7, 32, (167 & 0X7F)] ;M2 half speed reverse
*/

void drive_m2(byte m2_speed)
{

   byte serial_data[4];
   serial_data[0]=address;
   serial_data[1]=7;
   serial_data[2]=m2_speed_b;
   serial_data[3]=(serial_data[0] + serial_data[1] + serial_data[2] + serial_data[3]) & 0x7F;
   
   serial.write(serial_data, sizeof(serial_data));
}



Top
 Profile  
 
 Post subject: Re: packet serial control "robo claw" with arduino
PostPosted: Thu Feb 17, 2011 8:46 pm 
Offline
Master

Joined: Tue Jun 22, 2010 9:15 pm
Posts: 228
Thanks for posting !

I hope to be doing something with Roboclaw and Arduino soon.

Alan KM6VV

elimenohpee wrote:
Encase anyone else is trying to use the roboclaw with an arduino, I am working on translating all the packet serial commands written in basic format to the arduino format.

I'm not an expert at programming, so if you see mistakes let me know and I will correct them. This is what I have so far, I will update this when I finish.

_________________
Visit:
http://groups.yahoo.com/group/SherlineCNC/
http://tech.groups.yahoo.com/group/HexapodRobotIK/


Top
 Profile  
 
 Post subject: Re: packet serial control "robo claw" with arduino
PostPosted: Thu Apr 07, 2011 5:26 pm 
Offline
New User

Joined: Thu Mar 10, 2011 10:16 pm
Posts: 4
ok, i have a really dumb question.
when its says
Code:
void M1Speed(byte bCon, long Accel, long Speed) {
    byte ab[11];
    ab[0] = bCon;
    ab[1] = 38;
    ab[2] = (Accel >> 24) & 0xff;
    ab[3] = (Accel >> 16) & 0xff;
    ab[4] = (Accel >> 8) & 0xff;
    ab[5] = (Accel >> 0) & 0xff;
    ab[6] = (Speed >> 24) & 0xff;
    ab[7] = (Speed >> 16) & 0xff;
    ab[8] = (Speed >> 8) & 0xff;
    ab[9] = (Speed >> 0) & 0xff;
    ab[10] = (ab[0]+ab[1]+ab[2]+ab[3]+ab[4]+ab[5]+ab[6]+ab[7]+ab[8]+ab[9]) & 0x7f;
    Serial.write(ab, sizeof(ab));
}


what are the "& 0xff;" for? i dont see anything about it in the data sheet and when you Serial.write it why do you have to write the array, and the "sizeof"? is that for the CRC? but i would think that the CRC would simply be the last element of the array. i'm really new to all this and just trying to learn what i can. thanks :)


Top
 Profile  
 
 Post subject: Re: packet serial control "robo claw" with arduino
PostPosted: Thu Apr 07, 2011 5:32 pm 
Offline
Site Admin
User avatar

Joined: Thu Mar 01, 2001 7:00 pm
Posts: 1316
Location: Temecula, CA
the & 0xFF is to make sure the values are each 8 bits(eg bytes) long. This should not be necessary because the array is made of bytes so anything over 8 bits should be truncated anyway, but its a good idea never to assume. This is on the processor side(arduino) and he is just being safe, it really doesn't have anything to do with the Roboclaw other than making sure the values are of the right size to send to the Roboclaw.

sizeof(ab) should return 11, the defined size of the ab array. He could have just hard coded 11 there, since the array size was hard coded anyway, instead of using sizeof.

So the 11(eg returned value from sizeof) is telling the Serial.write function to write 11 bytes from array ab out the serial port that was previously setup.

The CRC is being calculated and stored in array index 10 of ab. The 11 has nothing to do with the CRC, other than it's telling the write command to write it(the CRC) plus the other 10 bytes of data from the array.

_________________
Tech Support
Basic Micro - Robotic Technology Evolved


Top
 Profile  
 
 Post subject: Re: packet serial control "robo claw" with arduino
PostPosted: Thu Apr 07, 2011 8:33 pm 
Offline
Master

Joined: Tue Jun 22, 2010 9:15 pm
Posts: 228
Using sizeof() also makes it automatically adjust the size if the array is changed. doesn't cost anything!

It's also quite useful to use #define to declare the size to be used by the array. Then other functions can use the label, again making modifications automatic! (One doesn't have to chase all over the code to find all the references to the array, etc.) Not bad if only one reference is needed, but just good practice. Again, Free!

Alan KM6VV

_________________
Visit:
http://groups.yahoo.com/group/SherlineCNC/
http://tech.groups.yahoo.com/group/HexapodRobotIK/


Top
 Profile  
 
 Post subject: Re: packet serial control "robo claw" with arduino
PostPosted: Fri Apr 08, 2011 7:55 pm 
Offline
Site Admin
User avatar

Joined: Thu Mar 01, 2001 7:00 pm
Posts: 1316
Location: Temecula, CA
This, "#define to declare the size", is the method I prefer. I'm lazy. :)

_________________
Tech Support
Basic Micro - Robotic Technology Evolved


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group

phpBB SEO