Category: Modular kits and software

CM-510 firmware for using as multiple sensor item updated

CM-510 firmware and post updated

 

 

XL-320 Ollo Explorer

XL-320, CM 9.04 and Ollo parts

XL-320, CM 9.04 and Ollo parts

Source code (I should clean it …)

(I) Reading sensors connected to Robotis CM-510

This entry is part 5 of 5 in the series Bioloid C++ tutorial

cm-510 sensorsUsing the Dynamixel SDK instead of RoboPlus Tasks is not possible to query sensors connected to the CM-5xx controller. But, of course, using standard programming languages, like C++, and tools, line QT Creator or Eclipse, with its full featured IDEs and debuggers is a hugue gain.

So I created a firmware for the CM-510 which can be queried and receive commands to itself, including its sensors, or to Dynamyxel devices.

The idea is very simple:

This program running in the CM-510 receives:

– commands or queries to IDs of Dynamixel devices. These are not processed, only redirected to the Dynamixel bus only if it was received by serial port ( serial cable or zigbee). If it was received from the Dynamixel bus nothing is done.

– commands or queries to the CM-510 ID (I chose ID=200), like beep, or to the sensors connected to it. This commands and queries are processed in the CM-510, basically querying the sensors.

In both cases the answer is sent to the connection from which the query or command was received.

After power on the CM-510, you can select the mode with the 4 cursor keys as showed in a terminal connected to its serial port:

“For ‘Toss mode’ press (Up), for ‘Device mode’ (Down), for ‘Device debug mode’ (Left),to start press (Right)”

In the Device mode:

all the receptions and sends are through the Dynamixel bus, the CM-510 is simply another device.

In the Toss mode:

– what is received from the serial connection is sent to the Dynamixel bus or processed in the CM-510 (If sent to its ID)

-what is received from the Dynamixel bus is sent to the serial connection

Finally, the Debug mode:

is like the Device mode, but all the debug messages included in the CM-510 are sent to the serial connection.

A complete sequence with code snippets from the CM-510 program and from the code running in the other computer:

Some C++ code snippets from this example: (C# in the next post)

enum AX12Address  //and functions implemented in the CM-510 program, like
{
	ReadCM510SensorRaw = 1,
        Beep = 8,
	ReadCM510SensorFiltered = 4,
	SetSensorValuesToFilter = 5,
...
}
void doBeep()
{
    cout << "Beep" << endl;
    mySystem.dynamixelCommunication.sendOrder(100, AXS1_Buzzer, (byte) DO, (short) 500);
    usleep (200000);
    mySystem.dynamixelCommunication.sendOrder(200,MyCommunications::Beep short)5);
}

Querying sensor:

void doQuerySensor()
{
    int sensorPort=getSensorPort();
    int value=mySystem.dynamixelCommunication.readSensorValue (200,ReadCM510SensorRaw, sensorPort);
   cout << "the sensor reads: [" << value << "] " << endl << endl << endl;
}

These command and query are processed in the CM-510:

Getting the sensor value:


int executeCM510Function()
{
...
		case F_GET_SENSOR_VALUE_RAW:
			values[1] = getSensorValueRaw(parameters[1]);
			break;

		case F_GET_SENSOR_VALUE_FILTERED:
			values[1] = getSensorValueFiltered(parameters[1], sensorValuesToFilterDefined);
			break;

		case F_GET_TWO_DMS_SENSOR_VALUES:
			parametersReceived=3;
			getTwoDMSSensorsValues();
			break;

		case F_GET_MULTIPLE_SENSOR_VALUE:
			getMultipleSensorsValues();
			break;

		case F_DO_SENSOR_SCAN: 
			values[1]= sensorScan(parameters[1]);
			break;

		case F_SET_VALUE_DMS1 : //set default value DMS1
			DMS1=parameters[1];
			break;

		case F_SET_VALUE_DMS2 : //set default value DMS1
			DMS2=parameters[1];
			break;

		case F_BEEP:
			if (debugMode)
				printf("executeCM510Function beep\n");
			beep();
			break;

		case F_SET_SENSOR_VALUES_TO_FILTER:
			sensorValuesToFilterDefined=parameters[1];
			break;
	}

	return function;
}

}
...
int getSensorValueRaw(unsigned char portId)
{
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1);

		setPort(portId);
		//PORTA &= ~0x80;
		//PORTA &= ~0x20;

		//_delay_us(12);				// Short Delay for rising sensor signal
		_delay_us(24);
		ADCSRA |= (1 << ADIF);		// AD-Conversion Interrupt Flag Clear
		ADCSRA |= (1 << ADSC);		// AD-Conversion Start

		while( !(ADCSRA & (1 << ADIF)) );	// Wait until AD-Conversion complete

		PORTA = 0xFC;				// IR-LED Off

		//printf( "%d\r\n", ADC); // Print Value on USART

		//_delay_ms(50);
		_delay_ms(ReadSensorDelayMS);

		return ADC;
}

 


void beep()
{
   buzzOn(100);
   buzzOff();
}

But we can do a little more with the CM-510 processor, we can do some filtering to the sensor values.

The readings from the DMS are usually somewhat erratic, so we can simply:

– discard the minimum and maximum values:

– if we take 5 more than measures, then return the average if the are more than 3, if 3 or less it

Previously we should set how many readings should be done, if not, the default number of readings are 5:

int getSensorValueFiltered(unsigned char portId, int times)
{
...
	switch(function)
	{		
		case F_GET_SENSOR_VALUE_RAW:
			values[1] = getSensorValueRaw(parameters[1]);
			break;

		case F_GET_SENSOR_VALUE_FILTERED:
			values[1] = getSensorValueFiltered(parameters[1], sensorValuesToFilterDefined);
			break;

		case F_GET_TWO_DMS_SENSOR_VALUES:
			parametersReceived=3;
			getTwoDMSSensorsValues();
			break;

		case F_GET_MULTIPLE_SENSOR_VALUE:
			getMultipleSensorsValues();
			break;

		case F_DO_SENSOR_SCAN: 
			values[1]= sensorScan(parameters[1]);
			break;

		case F_SET_VALUE_DMS1 : //set default value DMS1
			DMS1=parameters[1];
			break;

		case F_SET_VALUE_DMS2 : //set default value DMS1
			DMS2=parameters[1];
			break;

		case F_BEEP:
			if (debugMode)
				printf("executeCM510Function beep\n");
			beep();
			break;

		case F_SET_SENSOR_VALUES_TO_FILTER:
			sensorValuesToFilterDefined=parameters[1];
			break;
	}
...

We also can take values from multiple sensors with one query, but It will be explained in the next post…

(I) Robotis CM-900 C++ crash examples tutorial

This entry is part 4 of 5 in the series Programming CM-900

This is the first example in a serie of cheap (absolutely free and cheap) articles to get some basic and practical C++ knowledge. It will references the great explanations provided at www.cplusplus.com C++ tutorial. And using the very cheap and opensource (about 20$/€) Robotis 32 bits microcontroller board CM-900 (STM32 based) and Arduino based IDE.

Here you can download the file with the code, and you can find links to a lot of free tutorials, courses and books to learn C++ here.

// C++ crash tutorial with Robotis CM-900.

// First example: http://softwaresouls.com/softwaresouls/2013/06/23/c-crash-tutorial-using-robotis-cm-900-board-and-ide-i/

/*
Hello World shows messages on construction and destruction
Also it lets you to salute.
Showing always its assigned identifiction number MyId
*/
class HelloWorld
{
  private:
    int myId; //Object identification num ber

  public:

    // class constructor http://www.cplusplus.com/doc/tutorial/classes/
    HelloWorld(char *message, byte id)
    {
      myId=id;
      SerialUSB.print(message);
      printId();
    }

    // class destructor http://www.cplusplus.com/doc/tutorial/classes/
    ~HelloWorld()
    {
      SerialUSB.print ("Destructing object: ");
      printId();
    }

    void printId()
    {
      SerialUSB.print(" ID:");
      SerialUSB.println(myId);
      SerialUSB.println(" ");
    }

    void Salute(char *name)
    {
      SerialUSB.print("Hi!, ");
      SerialUSB.println(name);
      SerialUSB.print("Regards from object: ");
      printId();
    }
};

/*
void setup() function it's only executed one time at the start of the execution.
It is called from a hidden main() function in the Ronbotis CM-900 IDE core.

\ROBOTIS-v0.9.9\hardware\robotis\cores\robotis\main.cpp
Note: "while (1)" is a forevr loop ( http://www.cplusplus.com/doc/tutorial/control ):

(Basic structure http://www.cplusplus.com/doc/tutorial/program_structure/)

int main(void) {
    setup();

    while (1) {
        loop();
    }
    return 0;
}
*/
void setup()
{
  SerialUSB.begin(); //initialize serial USB connection
  delay(3000); //We will wait 3 seconds, let the user open (Control+Shift+M) the Monitor serial console
}

//We will not see neither the construction nor the destruction of this global object because serial port it's not still initiated
HelloWorld hw0("construction object", 0); //Object construction http://www.cplusplus.com/doc/tutorial/classes/

// A counter to see progress and launch events
int iterationCounter=0; //An integer variable to count iterations http://www.cplusplus.com/doc/tutorial/variables

// void loop() will be executing the sentences it contains while CM-900 is on.
void loop()
{
  // Lets's show only the first 5 iterations http://www.cplusplus.com/doc/tutorial/control/
  if (iterationCounter<5)
  {
    SerialUSB.print("starting iteration #");
    SerialUSB.println(++iterationCounter); // firts, iterationCounter is incremented and then printed

    // We will see the consttruction and destruction messages from this local (inside the loop function) object. Object construction http://www.cplusplus.com/doc/tutorial/classes/
    HelloWorld hw1("constructing object", 1);
    hw1.Salute("Joe");

    if (iterationCounter==3)
    {
        // We will see the consttructiona and destruction messages from this local (inside the "if" block inside the "loop" function) object. Objet construction http://www.cplusplus.com/doc/tutorial/classes/
        HelloWorld hw2("constructing object", 2);
        hw2.Salute("Jones");
    } // Objet hw2 destruction http://www.cplusplus.com/doc/tutorial/classes/

    //Let's show that object hw0 is alive
    hw0.Salute("Pepe");

    SerialUSB.print("ending iteration #");
    SerialUSB.println(iterationCounter++); // first cpunter is printed, then incremented.
  } // Objet hw1 destruction http://www.cplusplus.com/doc/tutorial/classes/
} // Program end. Objet hw0 destruction http://www.cplusplus.com/doc/tutorial/classes/

Robotis CM-900 in Toss Mode and querying connected sensors

This entry is part 3 of 5 in the series Programming CM-900

CM-900 is a very cheap and tiny Robotis Dynamixel controller based in the STM32 ARM 32 bits microcontroller. Here you can find several links to documents.

CM-900_Size

I think it’s ideal as a controller managed with, for example, a Raspberry Pi or a Pandaboard, so I have created a program which can be managed externally to control Dynamixel items (AX-12, AX-S1), Toss Mode, and sensors connected to the CM-900 with a simple protocol similar but simpler than the Dynamixel protocol:

[Headers] [ID] [Command code] [Nº Params] [Param1] [Param2] [ParamN]

Toss Mode works like USB2Dynamixel, but with this program in addition you can get sensor vales.

Toss Mode was a software feature, at least since CM-5, which allows you to use the elements connected to the controller from another device, usually a more powerful computer. What it receives from the USB or serial is sent to the Dynamixel bus, and whatever it receives from Dynamyxel bus is sent to the serial or USB connection.

Example for blinking twice: { 0xFF, 0xFF, 90, 1, 1, 2 }

Headers: 0xFF 0xFF

ID: 90

Command code: 1

Number of parameters: 1

Parameter #1:  2

Example for reading ultrasonic sensor (HC-SR04) : { 0xFF, 0xFF, 90, 2, 0 }


void MainWindow::testCM900_Sensor_US()
{
const int size=5;
byte buffer2[size] = { 0xFF, 0xFF, 90, 2, 0 };
pDynComm->rawWrite(buffer2, size);
}
Ultrasonic sensor hc-sr04

Ultrasonic sensor hc-sr04

And here the file with the code for Robotis CM-9 IDE version 0.9.9. You also need to copy Prof. Mason library for ultrasonic sensor to CM 900 IDE libraries folder. Althought it i still a beta version, I think it works ok. Asigning true to these variables, the messages for debugging are sent either to USB connection o Serial2 (connecting Zigbee is the easy option):

bool debugOutputSerial2On=true;
bool debugOutputOn=false;

Robotis CM-900 as a tosser for Dynamixel commands

This entry is part 2 of 5 in the series Programming CM-900

CM-900 is really tiny and cheap, so is perfect to use as communication bridge between any computer (Raspberry Pi, Pandaboard, etc. included, of course) and the Dynamixel bus. Whatever it receives from the Serial USB (usually commands and queries) is sent to the Dynamixel bus, and what it receives from the Dynamixel bus is sent to the SerialUSB (usually answers)

Here is the source code of the little program for CM-900 IDE:

int counter;
bool onlyOnceHappened;

void blinkOnce()
{
    digitalWrite(BOARD_LED_PIN, LOW);
    delay_us(100);
    digitalWrite(BOARD_LED_PIN, HIGH);
}

void setup()
{  
  pinMode(BOARD_LED_PIN, OUTPUT);

  onlyOnceHappened=false;
  counter=0;

  //USB Serial initialize
  SerialUSB.begin();
//  SerialUSB.attachInterrupt(USBDataReceived);
  //DXL initialize
  Dxl.begin(1);  
}

byte aByte=0;
uint8 aUint8;

void loop() 
{	
//  SerialUSB.println (counter++);

  if (onlyOnceHappened==false)
  {    
    blinkOnce();
    onlyOnceHappened=true;
    delay (3000); //Some time to the user to activate the monitor/console
    SerialUSB.println ("v1.1.1 Orders receiver started");  
  }    
  
  if (SerialUSB.available())
  {
    aUint8=SerialUSB.read();
    blinkOnce();
    Dxl.writeRaw(aUint8);
//    delay(20);
  }   
  
  if (Dxl.available())
  {
    aByte=Dxl.readRaw();
    blinkOnce();
    SerialUSB.write(aByte);
//    delay(20);
  } 
}

Here the file.

In the next post I will include an improved version that could read sensors connected to the CM-900, “expanding” the Dynamixel protocol.

[UPDATED] A simple but pretty complete Linux C++ example for Bioloid

This entry is part 5 of 6 in the series Bioloid Workshop

[Jun 12, 2013, Some source code typos fixed and code updated]:

.
.
.
.
.

bool nonValidOption(int option)
{
  return (optionMaxOption);
}

This is a very simple but pretty complete example, trying to use the least possible dependencies. I have tested in a just installed Ubuntu and you only needed the AXControl library (I created and use it because then there were no Robotis library and because it can use serial port, Dynamixel bus, Zigbee, BT (Robotis or other adaptors)

It use the terminal, no QT, to avoid library dependencies. But you should add the AXControl_v2 lib files to your /usr/lib folder as administrator (sudo). Click here if you want one unique executable for Linux (tested with Linux Mint 14) using these sources files

When executed, it shows the values configured in the HexaWheels.conf file and any problem it founds, like SerialPort2Dynamixel.open(ss)=> [Serial port NOT opened]:


ubuntu@A3820 ~/projects/trunk/bioloid/Herramientas/CommandLine $ ./commandline
init to load configuration(ss)=> [./HexaWheels.conf]
Configuration file=> (ss)=> [./HexaWheels.conf]
Tiempo_Espera_ms(ss)=> [35]
Tiempo_Espera_Sensores_ms(ss)=> [60]
Nombre_Puerto_Serie(ss)=> [/dev/ttyUSB0]
Baudios_Puerto_Serie(ss)=> [1000000]
Motion_File_Name(ss)=> [HexaWheels_2.0.mtn]
UmbralContacto(ss)=> [550]
UmbralDeteccion(ss)=> [200]
loadConfigurationValues: (si)=> [134529476]
getIntValue: (ss)=> [Tiempo_Espera_ms]
getIntValue: (ss)=> [Tiempo_Espera_Sensores_ms]
getIntValue: (ss)=> [Baudios_Puerto_Serie]
getStringValue: (ss)=> [Nombre_Puerto_Serie]

Device /dev/ttyUSB0, Speed B1000000
SerialPort2Dynamixel.open(ss)=> [Serial port NOT opened]
SerialPort2Dynamixel.open, serialPortName(ss)=> [/dev/ttyUSB0]
SerialPort2Dynamixel.open, baudRate(si)=> [4104]
I can’t open DynamixelCommunication, name: (ss)=> [/dev/ttyUSB0]
terminate called after throwing an instance of ‘std::exception*’
Aborted

If it can connect an there are no problem you should see:


ubuntu@A3820 ~/projects/trunk/bioloid/Herramientas/CommandLine $ ./commandline
init to load configuration(ss)=> [./HexaWheels.conf]
Configuration file=> (ss)=> [./HexaWheels.conf]
Tiempo_Espera_ms(ss)=> [35]
Tiempo_Espera_Sensores_ms(ss)=> [60]
Nombre_Puerto_Serie(ss)=> [/dev/ttyUSB0]
Baudios_Puerto_Serie(ss)=> [1000000]
Motion_File_Name(ss)=> [HexaWheels_2.0.mtn]
UmbralContacto(ss)=> [550]
UmbralDeteccion(ss)=> [200]
loadConfigurationValues: (si)=> [134529476]
getIntValue: (ss)=> [Tiempo_Espera_ms]
getIntValue: (ss)=> [Tiempo_Espera_Sensores_ms]
getIntValue: (ss)=> [Baudios_Puerto_Serie]
getStringValue: (ss)=> [Nombre_Puerto_Serie]

Device /dev/ttyUSB0, Speed B1000000
SerialPort2Dynamixel.open, serialPortName(ss)=> [/dev/ttyUSB0]
SerialPort2Dynamixel.open, baudRate(si)=> [4104]
V01
2.- Toggle AX-12 LED
3.- Query AX-12
4.- Move AX-12
5.- Torque AX-12
6.- Query CM-510 sensor
7.- Show menu
8.- Beep
9.- Quit
Select option (2-9)


/*------------------------------------------------------------------------------*\
 * This source file is subject to the GPLv3 license that is bundled with this   *
 * package in the file COPYING.                                                 *
 * It is also available through the world-wide-web at this URL:                 *
 * http://www.gnu.org/licenses/gpl-3.0.txt                                      *
 * If you did not receive a copy of the license and are unable to obtain it     *
 * through the world-wide-web, please send an email to                          *
 * siempre.aprendiendo@gmail.com so we can send you a copy immediately.         *
 *                                                                              *
 * @category  Robotics                                                          *
 * @copyright Copyright (c) 2011 Jose Cortes (<a href="https://plus.google.com/105007891378677151287/about">https://plus.google.com/105007891378677151287/about</a>) *
 * @license   http://www.gnu.org/licenses/gpl-3.0.txt GNU v3 Licence            *
 *                                                                              *
\*------------------------------------------------------------------------------*/

#include "stdafx.h"
#include
#include "BasicSystem.h"
#include "Util.h"

using namespace std;

class UI
{
public:
  static const int OptionQuit=8;

  UI(MyBasicSystem::BasicSystem& aMySystem) : mySystem(aMySystem) {}

  void showMenu();
  int selectOption();
  bool executeSelectedOption(int selected);
  void doBeep();

private:
  MyBasicSystem::BasicSystem mySystem;

  static const int OptionSetLEDOnOff=1;
  static const int OptionQueryAX12=2;
  static const int OptionMoveAX12=3;
  static const int OptionTorqueAX12=4;
  static const int OptionQuerySensor=5;
  static const int OptionShowMenu=6;
  static const int OptionBeep=7;

  static const int MinOption=OptionSetLEDOnOff;
  static const int MaxOption=OptionQuit;

  bool validRange(int value, int MinValue, int MaxValue);
  bool nonValidOption(int option);
  int getPosition();
  int getId();
  int getSensorPort();
  void doGetPosition();
  void doSetPosition();
  void doQuerySensor();
  void doSetLEDOnOff();
  void doSetTorqueOnOff();

};

void UI::showMenu()
{
  cout << "V02" << endl;

  cout << OptionSetLEDOnOff << ".- Toggle AX-12 LED" << endl;
  cout << OptionQueryAX12 << ".- Query AX-12" << endl;
  cout << OptionMoveAX12 << ".- Move AX-12" << endl;
  cout << OptionTorqueAX12 << ".- Torque AX-12" << endl;
  cout << OptionQuerySensor << ".- Query CM-510 sensor" << endl;
  cout << OptionShowMenu << ".- Show menu" << endl;
  cout << OptionBeep << ".- Beep" << endl;
  cout << OptionQuit << ".- Quit" << endl;
}

bool UI::nonValidOption(int option)
{
  return (optionMaxOption);
}

int UI::selectOption()
{
  int option=-1;

  while (nonValidOption(option))
  {
    cout << "Select option (" << MinOption << "-" << MaxOption << ")" << endl;     cin >> option;
    if (nonValidOption(option))
    {
      cout << endl;
      cout << endl;
      cout << "(" << option << ") is NOT a valid option" << endl;     }   }   return option; } bool UI::validRange(int value, int MinValue, int MaxValue) {   return (value>=MinValue && value<=MaxValue);
}

int UI::getPosition()
{
  int position=0;

  do
  {
    cout << "Type a value between 0 and 1023 to set the AX-12 in that position" << endl;     cin>>position;

  }while(!validRange(position, 0, 1023));

  cout << "Position:" <<  position << endl;   return position; } int UI::getId() {   int ax12Id=1;   do   {     puts ("Type the ID of the AX-12 to use, a value between 1 and 18, ");     cin >> ax12Id;

  }while(!validRange(ax12Id, 1, 18));

  cout << "AX12 Id:" << ax12Id << endl;   return ax12Id; } int UI::getSensorPort() {   int sensorPort=1;   do   {     puts ("Type the sensor Port to read, a value between 1 and 6, ");     cin >> sensorPort;

  }while(!validRange(sensorPort, 1, 6));

  cout << "Sensor Port number:" << sensorPort << endl;

  return sensorPort;
}

void UI::doBeep()
{
  cout << "Beep" << endl;
  mySystem.dynamixelCommunication.sendOrder(100, AXS1_Buzzer, (byte) DO, (short) 500);
  Sleep (2);
  mySystem.dynamixelCommunication.sendOrder(200, MyCommunications::Beep, (byte) 5);
}

void UI::doGetPosition()
{
  int ax12Id=getId();

  int position = mySystem.dynamixelCommunication.readValue(ax12Id, MyCommunications::PresentPosition);
  cout << "the position is: [" << position << "] " << endl << endl << endl;
}

void UI::doSetPosition()
{
  int ax12Id=getId();
  int position=getPosition();

  mySystem.dynamixelCommunication.sendOrder(ax12Id, MyCommunications::GoalPosition,(short) position);

}

void UI::doQuerySensor()
{
  int sensorPort=getSensorPort();

  int value=mySystem.dynamixelCommunication.readSensorValue (200, ReadCM510SensorRaw, sensorPort);
  cout << "the sensor reads: [" << value << "] " << endl << endl << endl;
}

void UI::doSetLEDOnOff()
{
  byte lByte=0, hByte=0;
  int ledValue;

  int ax12Id=getId();

  ledValue=mySystem.dynamixelCommunication.readValue(ax12Id, MyCommunications::LED);
  Hex::toHexHLConversion(ledValue, hByte, lByte);

  bool onOff=false;
  if (lByte!=0)
    onOff=true;

  cout << "The LED is: [" << (onOff?"on":"off") << "], putting it: [" << (onOff?"Off":"on") << "] " << endl << endl << endl;
  mySystem.dynamixelCommunication.sendOrder(ax12Id, MyCommunications::LED, byte(onOff?0:1));
}

void UI::doSetTorqueOnOff()
{
  byte lByte=0, hByte=0;
  int ax12Id=getId();

  int torque=mySystem.dynamixelCommunication.readValue(ax12Id, MyCommunications::Torque);
  Hex::toHexHLConversion(torque, hByte, lByte);
  bool onOff=(lByte!=0?true:false);

  cout << "The Torque is: [" << (onOff?"on":"off") << "], putting it: [" << (onOff?"Off":"on") << "] " << endl << endl << endl;

  mySystem.dynamixelCommunication.sendOrder(ax12Id, MyCommunications::Torque,(byte) (onOff?0:1));
}

bool UI::executeSelectedOption(int option)
{
  bool isOk=true;
  cout << endl;
  cout << endl;

  cout << "Selected option: [" << option << "] " << endl;

  switch(option)
  {
    case OptionSetLEDOnOff:
         doSetLEDOnOff();
         break;
    case OptionQueryAX12:
         doGetPosition();
         break;
    case OptionMoveAX12:
         doSetPosition();
         break;
    case OptionTorqueAX12:
         doSetTorqueOnOff();
         break;
    case OptionQuerySensor:
         doQuerySensor();
         break;
    case OptionShowMenu:
	 showMenu();
	 break;
    case OptionBeep:
         doBeep();
         break;
  }

  return isOk;
}

int _tmain(int argc, _TCHAR* argv[])
{
  cout << "AXControl_v2_VS_CPP test v0" << endl;

  bool quit=false;
  MyBasicSystem::BasicSystem mySystem;
  UI ui(mySystem);
  do
  {
    ui.showMenu();
    int selected=ui.selectOption();
    if (selected==ui.OptionQuit)
	quit=true;
    ui.executeSelectedOption(selected);
  }while (!quit);

  mySystem.dynamixelCommunication.close();

	return 0;
}

%d bloggers like this: