by Ike » Sun Mar 16, 2008 11:22 pm
by Ike
Sun Mar 16, 2008 11:22 pm
I am actually looking to go wireless, but have been very tempted by Jon's USB board.
For anyone who is interested in some C# code to work with in Toss Mode, here is something I hobbled together from various sources. The WritePacket code is from the RoboticsLibrary, modified to talk to a COM port. You will need to put a GUI around it (comPort, txtOutput window, and a few buttons/sliders) but it works well if you are looking to send commands longer than 60 characters, or just want to bypass the CM5.
This is a work in progress, so there is some junk/redundant code. Also, please note that most of this was created from pieces of code written by people who are much smarter than I am; all credit goes to the original authors. You can tell the parts that I wrote... they haven't the vaguest sense of good coding practices.
- Code: Select all
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
namespace BioloidChat
{
public partial class BioloidToss : Form
{
#region Dynamixel IDs
public const byte ID01 = 0x01;
public const byte ID02 = 0x02;
public const byte ID03 = 0x03;
public const byte ID04 = 0x04;
public const byte ID05 = 0x05;
public const byte ID06 = 0x06;
public const byte ID07 = 0x07;
public const byte ID08 = 0x08;
public const byte ID09 = 0x09;
public const byte ID10 = 0x0A;
public const byte ID11 = 0x0B;
public const byte ID12 = 0x0C;
public const byte ID13 = 0x0D;
public const byte ID14 = 0x0E;
public const byte ID15 = 0x0F;
public const byte ID16 = 0x10;
public const byte ID17 = 0x11;
public const byte ID18 = 0x12;
public const byte BroadcastID = 0xFE;
#endregion
#region Instruction Set
// Instruction Set
public const byte InstPing = 0x01;
public const byte InstReadData = 0x02;
public const byte InstWriteData = 0x03;
public const byte InstRegWrite = 0x04;
public const byte InstAction = 0x05;
public const byte InstReset = 0x06;
public const byte InstDigitalReset = 0x07;
public const byte InstSystemRead = 0x0C;
public const byte InstSystemWrite = 0x0D;
public const byte InstSyncWrite = 0x83;
public const byte InstSyncRegWrite = 0x84;
#endregion
#region Control Table
// Control Table
public const byte AddressModelNumberLow = 0X00;
public const byte AddressModelNumberHigh = 0X01;
public const byte AddressVersionOfFirmware = 0X02;
public const byte AddressID = 0X03;
public const byte AddressBaudRate = 0X04;
public const byte AddressReturnDelayTime = 0X05;
public const byte AddressCWAngleLimitLow = 0X06;
public const byte AddressCWAngleLimitHigh = 0X07;
public const byte AddressCCWAngleLimitLow = 0X08;
public const byte AddressCCWAngleLimitHigh = 0X09;
public const byte AddressSystemData2 = 0x0A;
public const byte AddressHighestLimitTemperature = 0X0B;
public const byte AddressLowestLimitVoltage = 0X0C;
public const byte AddressHighestLimitVoltage = 0X0D;
public const byte AddressMaxTorqueLow = 0X0E;
public const byte AddressMaxTorqueHigh = 0X0F;
public const byte AddressStatusReturnLevel = 0X10;
public const byte AddressAlarmLed = 0X11;
public const byte AddressAlarmShutdown = 0X12;
public const byte AddressOperatingMode = 0X13;
public const byte AddressDownCalibrationLow = 0X14;
public const byte AddressDownCalibrationHigh = 0X15;
public const byte AddressUpCalibrationLow = 0X16;
public const byte AddressUpCalibrationHigh = 0X17;
public const byte AddressTorqueEnable = 0X18;
public const byte AddressLed = 0X19;
public const byte AddressCWComplianceMargin = 0X1A;
public const byte AddressCCWComplianceMargin = 0X1B;
public const byte AddressCWComplianceSlope = 0X1C;
public const byte AddressCCWComplianceSlope = 0X1D;
public const byte AddressGoalPositionLow = 0X1E;
public const byte AddressGoalPositionHigh = 0X1F;
public const byte AddressMovingSpeedLow = 0X20;
public const byte AddressMovingSpeedHigh = 0X21;
public const byte AddressTorqueLimitLow = 0X22;
public const byte AddressTorqueLimitHigh = 0X23;
public const byte AddressPresentPositionLow = 0X24;
public const byte AddressPresentPositionHigh = 0X25;
public const byte AddressPresentSpeedLow = 0X26;
public const byte AddressPresentSpeedHigh = 0X27;
public const byte AddressPresentLoadLow = 0X28;
public const byte AddressPresentLoadHigh = 0X29;
public const byte AddressPresentVoltage = 0X2A;
public const byte AddressPresentTemperature = 0X2B;
public const byte AddressRegisteredInstruction = 0X2C;
public const byte AddressPauseTime = 0X2D;
public const byte AddressMoving = 0x2E;
public const byte AddressLock = 0x2F;
public const byte AddressPunchLow = 0x30;
public const byte AddressPunchHigh = 0x31;
#endregion
public BioloidToss()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Control.CheckForIllegalCrossThreadCalls = false;
this.comPort.ReadTimeout = 1000;
this.comPort.Open();
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
this.comPort.Close();
}
private byte[] HexStringToByteArray(string s)
{
s = s.Replace(" ", "");
byte[] buffer = new byte[s.Length / 2];
for (int i = 0; i <s> 0)
{
Byte[] comByte = new byte[this.comPort.BytesToRead];
this.comPort.Read(comByte, 0, this.comPort.BytesToRead);
this.txtOutput.AppendText("<Recv>: " + ByteArrayToHexString(comByte) + "\r\n");
this.txtOutput.SelectionStart = this.txtOutput.Text.Length;
this.txtOutput.ScrollToCaret();
}
}
private void btnOpenCOM_Click(object sender, EventArgs e)
{
if (this.comPort.IsOpen)
{
this.txtOutput.AppendText("COM2 is already open\r\n");
this.txtOutput.SelectionStart = this.txtOutput.Text.Length;
this.txtOutput.ScrollToCaret();
}
else
{
this.comPort.ReadTimeout = 500;
this.comPort.Open();
this.txtOutput.AppendText("COM2 Opened\r\n");
this.txtOutput.SelectionStart = this.txtOutput.Text.Length;
this.txtOutput.ScrollToCaret();
}
}
private void btnCloseCOM_Click(object sender, EventArgs e)
{
this.comPort.Close();
this.txtOutput.AppendText("COM2 Closed\r\n");
this.txtOutput.SelectionStart = this.txtOutput.Text.Length;
this.txtOutput.ScrollToCaret();
}
private void btnServoOff_Click(object sender, EventArgs e)
{
WriteInstructionPacket(BroadcastID, //Broadcast ID
InstSyncWrite, //SyncWrite
HexStringToByteArray("18" + //Starting Address (Torque Enable)
"01" + //Number of bytes to write
"01 00" + //Disable Torque for ID 1
"02 00" + //Disable Torque for ID 2
"03 00" + //Disable Torque for ID 3
"04 00" + //Disable Torque for ID 4
"05 00" + //Disable Torque for ID 5
"06 00" + //Disable Torque for ID 6
"07 00" + //Disable Torque for ID 7
"08 00" + //Disable Torque for ID 8
"09 00" + //Disable Torque for ID 9
"0A 00" + //Disable Torque for ID 10
"0B 00" + //Disable Torque for ID 11
"0C 00" + //Disable Torque for ID 12
"0D 00" + //Disable Torque for ID 13
"0E 00" + //Disable Torque for ID 14
"0F 00" + //Disable Torque for ID 15
"10 00" + //Disable Torque for ID 16
"11 00" + //Disable Torque for ID 17
"12 00")); //Disable Torque for ID 18
}
private void btnStandUp_Click(object sender, EventArgs e)
{
WriteInstructionPacket(BroadcastID, //Broadcast ID
InstSyncWrite, //SyncWrite
HexStringToByteArray
(
"1E" + //Starting Address (Goal Position)
"04" + //Number of bytes to write
"01 FF 01 FF 00" + //ID01 Pos 255 001 Speed 255 000
"02 FF 01 FF 00" + //ID02 Pos 255 001 Speed 255 000
"03 FF 01 FF 00" + //ID03 Pos 255 001 Speed 255 000
"04 FF 01 FF 00" + //ID04 Pos 255 001 Speed 255 000
"05 FF 01 FF 00" + //ID05 Pos 255 001 Speed 255 000
"06 FF 01 FF 00" + //ID06 Pos 255 001 Speed 255 000
"07 FF 01 FF 00" + //ID07 Pos 255 001 Speed 255 000
"08 FF 01 FF 00" + //ID08 Pos 255 001 Speed 255 000
"09 FF 01 FF 00" + //ID09 Pos 255 001 Speed 255 000
"0A FF 01 FF 00" + //ID10 Pos 255 001 Speed 255 000
"0B FF 01 FF 00" + //ID11 Pos 255 001 Speed 255 000
"0C FF 01 FF 00" + //ID12 Pos 255 001 Speed 255 000
"0D FF 01 FF 00" + //ID13 Pos 255 001 Speed 255 000
"0E FF 01 FF 00" + //ID14 Pos 255 001 Speed 255 000
"0F FF 01 FF 00" + //ID15 Pos 255 001 Speed 255 000
"10 FF 01 FF 00" + //ID16 Pos 255 001 Speed 255 000
"11 FF 01 FF 00" + //ID17 Pos 255 001 Speed 255 000
"12 FF 01 FF 00") //ID18 Pos 255 001 Speed 255 000
);
}
private void trackbarPosition_Changed(object sender, EventArgs e)
{
int Position_Low = this.trackBar1.Value % 256;
String PosL = Position_Low.ToString("X2");
int Position_High = this.trackBar1.Value / 256;
String PosH = Position_High.ToString("X2");
WriteInstructionPacket(ID01, InstWriteData, HexStringToByteArray("1E" + PosL + PosH));
}
private void trackbarSpeed_Changed(object sender, EventArgs e)
{
int Speed_Low = this.trackBar2.Value % 256;
String SpeedL = Speed_Low.ToString("X2");
int Speed_High = this.trackBar2.Value / 256;
String SpeedH = Speed_High.ToString("X2");
WriteInstructionPacket(ID01, InstWriteData, HexStringToByteArray("20" + SpeedL + SpeedH));
}
private void btnSendBinary_Click(object sender, EventArgs e)
{
WriteInstructionPacket(ID01,InstWriteData,HexStringToByteArray("1EFF01"));
//byte[] data = HexStringToByteArray("FFFF0105031EFF01D8");
//this.comPort.Write(data, 0, data.Length);
}
private void btnTossMode_Click(object sender, EventArgs e)
{
this.comPort.WriteLine("T");
}
}
}
I am actually looking to go wireless, but have been very tempted by Jon's USB board.
For anyone who is interested in some C# code to work with in Toss Mode, here is something I hobbled together from various sources. The WritePacket code is from the RoboticsLibrary, modified to talk to a COM port. You will need to put a GUI around it (comPort, txtOutput window, and a few buttons/sliders) but it works well if you are looking to send commands longer than 60 characters, or just want to bypass the CM5.
This is a work in progress, so there is some junk/redundant code. Also, please note that most of this was created from pieces of code written by people who are much smarter than I am; all credit goes to the original authors. You can tell the parts that I wrote... they haven't the vaguest sense of good coding practices.
- Code: Select all
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
namespace BioloidChat
{
public partial class BioloidToss : Form
{
#region Dynamixel IDs
public const byte ID01 = 0x01;
public const byte ID02 = 0x02;
public const byte ID03 = 0x03;
public const byte ID04 = 0x04;
public const byte ID05 = 0x05;
public const byte ID06 = 0x06;
public const byte ID07 = 0x07;
public const byte ID08 = 0x08;
public const byte ID09 = 0x09;
public const byte ID10 = 0x0A;
public const byte ID11 = 0x0B;
public const byte ID12 = 0x0C;
public const byte ID13 = 0x0D;
public const byte ID14 = 0x0E;
public const byte ID15 = 0x0F;
public const byte ID16 = 0x10;
public const byte ID17 = 0x11;
public const byte ID18 = 0x12;
public const byte BroadcastID = 0xFE;
#endregion
#region Instruction Set
// Instruction Set
public const byte InstPing = 0x01;
public const byte InstReadData = 0x02;
public const byte InstWriteData = 0x03;
public const byte InstRegWrite = 0x04;
public const byte InstAction = 0x05;
public const byte InstReset = 0x06;
public const byte InstDigitalReset = 0x07;
public const byte InstSystemRead = 0x0C;
public const byte InstSystemWrite = 0x0D;
public const byte InstSyncWrite = 0x83;
public const byte InstSyncRegWrite = 0x84;
#endregion
#region Control Table
// Control Table
public const byte AddressModelNumberLow = 0X00;
public const byte AddressModelNumberHigh = 0X01;
public const byte AddressVersionOfFirmware = 0X02;
public const byte AddressID = 0X03;
public const byte AddressBaudRate = 0X04;
public const byte AddressReturnDelayTime = 0X05;
public const byte AddressCWAngleLimitLow = 0X06;
public const byte AddressCWAngleLimitHigh = 0X07;
public const byte AddressCCWAngleLimitLow = 0X08;
public const byte AddressCCWAngleLimitHigh = 0X09;
public const byte AddressSystemData2 = 0x0A;
public const byte AddressHighestLimitTemperature = 0X0B;
public const byte AddressLowestLimitVoltage = 0X0C;
public const byte AddressHighestLimitVoltage = 0X0D;
public const byte AddressMaxTorqueLow = 0X0E;
public const byte AddressMaxTorqueHigh = 0X0F;
public const byte AddressStatusReturnLevel = 0X10;
public const byte AddressAlarmLed = 0X11;
public const byte AddressAlarmShutdown = 0X12;
public const byte AddressOperatingMode = 0X13;
public const byte AddressDownCalibrationLow = 0X14;
public const byte AddressDownCalibrationHigh = 0X15;
public const byte AddressUpCalibrationLow = 0X16;
public const byte AddressUpCalibrationHigh = 0X17;
public const byte AddressTorqueEnable = 0X18;
public const byte AddressLed = 0X19;
public const byte AddressCWComplianceMargin = 0X1A;
public const byte AddressCCWComplianceMargin = 0X1B;
public const byte AddressCWComplianceSlope = 0X1C;
public const byte AddressCCWComplianceSlope = 0X1D;
public const byte AddressGoalPositionLow = 0X1E;
public const byte AddressGoalPositionHigh = 0X1F;
public const byte AddressMovingSpeedLow = 0X20;
public const byte AddressMovingSpeedHigh = 0X21;
public const byte AddressTorqueLimitLow = 0X22;
public const byte AddressTorqueLimitHigh = 0X23;
public const byte AddressPresentPositionLow = 0X24;
public const byte AddressPresentPositionHigh = 0X25;
public const byte AddressPresentSpeedLow = 0X26;
public const byte AddressPresentSpeedHigh = 0X27;
public const byte AddressPresentLoadLow = 0X28;
public const byte AddressPresentLoadHigh = 0X29;
public const byte AddressPresentVoltage = 0X2A;
public const byte AddressPresentTemperature = 0X2B;
public const byte AddressRegisteredInstruction = 0X2C;
public const byte AddressPauseTime = 0X2D;
public const byte AddressMoving = 0x2E;
public const byte AddressLock = 0x2F;
public const byte AddressPunchLow = 0x30;
public const byte AddressPunchHigh = 0x31;
#endregion
public BioloidToss()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Control.CheckForIllegalCrossThreadCalls = false;
this.comPort.ReadTimeout = 1000;
this.comPort.Open();
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
this.comPort.Close();
}
private byte[] HexStringToByteArray(string s)
{
s = s.Replace(" ", "");
byte[] buffer = new byte[s.Length / 2];
for (int i = 0; i <s> 0)
{
Byte[] comByte = new byte[this.comPort.BytesToRead];
this.comPort.Read(comByte, 0, this.comPort.BytesToRead);
this.txtOutput.AppendText("<Recv>: " + ByteArrayToHexString(comByte) + "\r\n");
this.txtOutput.SelectionStart = this.txtOutput.Text.Length;
this.txtOutput.ScrollToCaret();
}
}
private void btnOpenCOM_Click(object sender, EventArgs e)
{
if (this.comPort.IsOpen)
{
this.txtOutput.AppendText("COM2 is already open\r\n");
this.txtOutput.SelectionStart = this.txtOutput.Text.Length;
this.txtOutput.ScrollToCaret();
}
else
{
this.comPort.ReadTimeout = 500;
this.comPort.Open();
this.txtOutput.AppendText("COM2 Opened\r\n");
this.txtOutput.SelectionStart = this.txtOutput.Text.Length;
this.txtOutput.ScrollToCaret();
}
}
private void btnCloseCOM_Click(object sender, EventArgs e)
{
this.comPort.Close();
this.txtOutput.AppendText("COM2 Closed\r\n");
this.txtOutput.SelectionStart = this.txtOutput.Text.Length;
this.txtOutput.ScrollToCaret();
}
private void btnServoOff_Click(object sender, EventArgs e)
{
WriteInstructionPacket(BroadcastID, //Broadcast ID
InstSyncWrite, //SyncWrite
HexStringToByteArray("18" + //Starting Address (Torque Enable)
"01" + //Number of bytes to write
"01 00" + //Disable Torque for ID 1
"02 00" + //Disable Torque for ID 2
"03 00" + //Disable Torque for ID 3
"04 00" + //Disable Torque for ID 4
"05 00" + //Disable Torque for ID 5
"06 00" + //Disable Torque for ID 6
"07 00" + //Disable Torque for ID 7
"08 00" + //Disable Torque for ID 8
"09 00" + //Disable Torque for ID 9
"0A 00" + //Disable Torque for ID 10
"0B 00" + //Disable Torque for ID 11
"0C 00" + //Disable Torque for ID 12
"0D 00" + //Disable Torque for ID 13
"0E 00" + //Disable Torque for ID 14
"0F 00" + //Disable Torque for ID 15
"10 00" + //Disable Torque for ID 16
"11 00" + //Disable Torque for ID 17
"12 00")); //Disable Torque for ID 18
}
private void btnStandUp_Click(object sender, EventArgs e)
{
WriteInstructionPacket(BroadcastID, //Broadcast ID
InstSyncWrite, //SyncWrite
HexStringToByteArray
(
"1E" + //Starting Address (Goal Position)
"04" + //Number of bytes to write
"01 FF 01 FF 00" + //ID01 Pos 255 001 Speed 255 000
"02 FF 01 FF 00" + //ID02 Pos 255 001 Speed 255 000
"03 FF 01 FF 00" + //ID03 Pos 255 001 Speed 255 000
"04 FF 01 FF 00" + //ID04 Pos 255 001 Speed 255 000
"05 FF 01 FF 00" + //ID05 Pos 255 001 Speed 255 000
"06 FF 01 FF 00" + //ID06 Pos 255 001 Speed 255 000
"07 FF 01 FF 00" + //ID07 Pos 255 001 Speed 255 000
"08 FF 01 FF 00" + //ID08 Pos 255 001 Speed 255 000
"09 FF 01 FF 00" + //ID09 Pos 255 001 Speed 255 000
"0A FF 01 FF 00" + //ID10 Pos 255 001 Speed 255 000
"0B FF 01 FF 00" + //ID11 Pos 255 001 Speed 255 000
"0C FF 01 FF 00" + //ID12 Pos 255 001 Speed 255 000
"0D FF 01 FF 00" + //ID13 Pos 255 001 Speed 255 000
"0E FF 01 FF 00" + //ID14 Pos 255 001 Speed 255 000
"0F FF 01 FF 00" + //ID15 Pos 255 001 Speed 255 000
"10 FF 01 FF 00" + //ID16 Pos 255 001 Speed 255 000
"11 FF 01 FF 00" + //ID17 Pos 255 001 Speed 255 000
"12 FF 01 FF 00") //ID18 Pos 255 001 Speed 255 000
);
}
private void trackbarPosition_Changed(object sender, EventArgs e)
{
int Position_Low = this.trackBar1.Value % 256;
String PosL = Position_Low.ToString("X2");
int Position_High = this.trackBar1.Value / 256;
String PosH = Position_High.ToString("X2");
WriteInstructionPacket(ID01, InstWriteData, HexStringToByteArray("1E" + PosL + PosH));
}
private void trackbarSpeed_Changed(object sender, EventArgs e)
{
int Speed_Low = this.trackBar2.Value % 256;
String SpeedL = Speed_Low.ToString("X2");
int Speed_High = this.trackBar2.Value / 256;
String SpeedH = Speed_High.ToString("X2");
WriteInstructionPacket(ID01, InstWriteData, HexStringToByteArray("20" + SpeedL + SpeedH));
}
private void btnSendBinary_Click(object sender, EventArgs e)
{
WriteInstructionPacket(ID01,InstWriteData,HexStringToByteArray("1EFF01"));
//byte[] data = HexStringToByteArray("FFFF0105031EFF01D8");
//this.comPort.Write(data, 0, data.Length);
}
private void btnTossMode_Click(object sender, EventArgs e)
{
this.comPort.WriteLine("T");
}
}
}