diff --git a/src/dynamixel.cpp b/src/dynamixel.cpp
index 7c85ff51a3bde2ff5e0469130f6a9316360d3ce6..a5a88cef27b34d24313a92eaeac92c6d865b6415 100644
--- a/src/dynamixel.cpp
+++ b/src/dynamixel.cpp
@@ -15,35 +15,291 @@ CDynamixel::CDynamixel(std::string& cont_id)
   this->node_address=-1;
   this->id_register=0x03;
   this->baudrate_register=0x04;
+  this->version=dyn_version1;
 }
 
-unsigned char CDynamixel::compute_checksum(unsigned char *packet,int len)
+void CDynamixel::send_instruction_packet_v1(dyn_inst_t inst,unsigned char *data,unsigned char len)
 {
-  int i=0;
-  short int checksum=0;
+  unsigned char *packet;
+  int i,length;
 
-  if(packet==NULL)
+  switch(inst)
   {
-    /* handle exceptions */
-    throw CDynamixelException(_HERE_,"Invalid packet structure",this->node_address);
+    case dyn_reg_write:
+    case dyn_write:
+    case dyn_read: length=6+len;
+                   packet=new unsigned char[length];
+                   break;
+    default: throw CDynamixelException(_HERE_,"Instruction not supported",this->node_address);
+             break;
   }
-  else
+  packet[0]=0xFF;
+  packet[1]=0xFF;
+  packet[2]=this->node_address;
+  packet[3]=len+2;
+  packet[4]=inst;
+  for(i=0;i<len;i++)
+    packet[5+i]=data[i];
+  // byte stuffing
+  packet[length-1]=0x00;
+  packet[length-1]=CDynamixelServer::compute_checksum_v1(packet,length);
+  if(this->usb_dev!=NULL)
   {
-    if(len<=0)
+    this->usb_access->enter();
+    if(this->usb_dev->write(packet,length)!=length)
     {
       /* handle exceptions */
-      throw CDynamixelException(_HERE_,"Invalid packet length",this->node_address);
+      this->usb_access->exit();
+      throw CDynamixelException(_HERE_,"Unexpected error while writing to the communication device",this->node_address);
     }
-    else
+    this->usb_access->exit();
+  }
+  else
+  {
+    /* handle exceptions */
+    throw CDynamixelException(_HERE_,"The communication device is not properly configured",this->node_address);
+  }
+}
+
+void CDynamixel::send_instruction_packet_v2(dyn_inst_t inst,unsigned char *data,unsigned short int len)
+{
+  unsigned char *packet;
+  int i,length,crc;
+
+  switch(inst)
+  {
+    case dyn_reg_write:
+    case dyn_write:
+    case dyn_read: length=10+len;
+                   packet=new unsigned char[length];
+                   break;
+    default: throw CDynamixelException(_HERE_,"Instruction not supported",this->node_address);
+             break;
+  }
+  packet[0]=0xFF;
+  packet[1]=0xFF;
+  packet[2]=0xFD;
+  packet[3]=0x00;
+  packet[4]=this->node_address;
+  packet[5]=(len+3)%256;
+  packet[6]=(len+3)/256;
+  packet[7]=inst;
+  for(i=0;i<len;i++)
+    packet[8+i]=data[i];
+  packet[length-2]=0x00;
+  packet[length-1]=0x00;
+  crc=CDynamixelServer::compute_checksum_v2(packet,length-2);
+  packet[length-2]=crc%256;
+  packet[length-1]=crc/256;
+  if(this->usb_dev!=NULL)
+  {
+    this->usb_access->enter();
+    if(this->usb_dev->write(packet,length)!=length)
     {
-      for(i=2;i<len;i++)
-        checksum+=packet[i];
-      checksum=~checksum;
-      checksum=checksum%256;
+      /* handle exceptions */
+      this->usb_access->exit();
+      throw CDynamixelException(_HERE_,"Unexpected error while writing to the communication device",this->node_address);
     }
+    this->usb_access->exit();
   }
+  else
+  {
+    /* handle exceptions */
+    throw CDynamixelException(_HERE_,"The communication device is not properly configured",this->node_address);
+  }
+}
 
-  return checksum;
+unsigned char CDynamixel::receive_status_packet_v1(unsigned char **data,unsigned char *len)
+{
+  std::list<std::string> events;
+  unsigned char data_int[256];
+  int num=0,read=0,length;
+
+  if(this->usb_dev!=NULL)
+  {
+    try{
+      this->usb_access->enter();
+      events.push_back(this->usb_dev->get_rx_event_id());
+      // read up to the length field
+      do{
+        if((num=this->usb_dev->get_num_data())==0)
+        {
+          this->event_server->wait_all(events,20);
+          num=this->usb_dev->get_num_data();
+        }
+        if((read+num)>256)
+        {
+          this->usb_dev->read(&data_int[read],256-read);
+          read=256;
+        }
+        else
+        {
+          this->usb_dev->read(&data_int[read],num);
+          read+=num;
+        }
+      }while(read<4);
+      length=data_int[3]+4;
+      // read the remaining of the packet
+      while(read<length)
+      {
+        if((num=this->usb_dev->get_num_data())==0)
+        {
+          this->event_server->wait_all(events,20);
+          num=this->usb_dev->get_num_data();
+        }
+        if((read+num)>256)
+        {
+          this->usb_dev->read(&data_int[read],256-read);
+          read=256;
+        }
+        else
+        {
+          this->usb_dev->read(&data_int[read],num);
+          read+=num;
+        }
+      }
+      // check the checksum
+      if(CDynamixelServer::compute_checksum_v1(data_int,length)!=0x00)
+      {
+        this->usb_access->exit();
+        /* handle exceptions */
+        throw CDynamixelException(_HERE_,"Invalid Checksum",this->node_address);
+      }
+      // byte destuffing
+      // return the error
+      if(length>6)
+      {
+        *data=new unsigned char[length-6];
+        memcpy(*data,&data_int[5],length-6);
+        *len=length-6;
+      }
+      else
+      {
+        *data=NULL;
+        *len=0;
+      }
+      this->usb_access->exit();
+      return data_int[4];
+    }catch(CEventTimeoutException &e){
+      this->usb_access->exit();
+      throw e;
+    }
+  }
+  else
+  {
+    /* handle exceptions */
+    throw CDynamixelException(_HERE_,"The communication device is not properly configured",this->node_address);
+  }
+}
+
+unsigned char CDynamixel::receive_status_packet_v2(unsigned char **data,unsigned short int *len)
+{
+  std::list<std::string> events;
+  unsigned char data_int[256];
+  int num=0,read=0,length;
+  unsigned short int crc;
+
+  if(this->usb_dev!=NULL)
+  {
+    try{
+      this->usb_access->enter();
+      events.push_back(this->usb_dev->get_rx_event_id());
+      // read up to the length field
+      do{
+        if((num=this->usb_dev->get_num_data())==0)
+        {
+          this->event_server->wait_all(events,20);
+          num=this->usb_dev->get_num_data();
+        }
+        if((read+num)>256)
+        {
+          this->usb_dev->read(&data_int[read],256-read);
+          read=256;
+        }
+        else
+        {
+          this->usb_dev->read(&data_int[read],num);
+          read+=num;
+        }
+      }while(read<7);
+      length=data_int[5]+data_int[6]*256+7;
+      // read the remaining of the packet
+      while(read<length)
+      {
+        if((num=this->usb_dev->get_num_data())==0)
+        {
+          this->event_server->wait_all(events,20);
+          num=this->usb_dev->get_num_data();
+        }
+        if((read+num)>256)
+        {
+          this->usb_dev->read(&data_int[read],256-read);
+          read=256;
+        }
+        else
+        {
+          this->usb_dev->read(&data_int[read],num);
+          read+=num;
+        }
+      }
+      // check the checksum
+      crc=CDynamixelServer::compute_checksum_v2(data_int,length-2);
+      if((crc%256)!=data_int[length-2] || (crc/256)!=data_int[length-1])
+      {
+        this->usb_access->exit();
+        /* handle exceptions */
+        throw CDynamixelException(_HERE_,"Invalid Checksum",this->node_address);
+      }
+      // return the error
+      if(length>11)
+      {
+        *data=new unsigned char[length-11];
+        memcpy(*data,&data_int[9],length-11);
+        *len=length-11;
+      }
+      else
+      {
+        *data=NULL;
+        *len=0;
+      }
+      this->usb_access->exit();
+      return data_int[8];
+    }catch(CEventTimeoutException &e){
+      this->usb_access->exit();
+      throw e;
+    }
+  }
+  else
+  {
+    /* handle exceptions */
+    throw CDynamixelException(_HERE_,"The communication device is not properly configured",this->node_address);
+  }
+}
+
+void CDynamixel::handle_error(unsigned char error)
+{
+  std::string error_msg;
+
+  if(error!=0x00)
+  {
+    /* handle exceptions */
+    if(error&0x01)
+      error_msg+="\nThe supply voltage is out of range";
+    if(error&0x02)
+      error_msg+="\nThe goal position is out of range";
+    if(error&0x04)
+      error_msg+="\nThe internal temperature is too high";
+    if(error&0x08)
+      error_msg+="\nThe provided parameter is out of range";
+    if(error&0x10)
+      error_msg+="\nThe packet sent to the dynamixel device had an invalid checksum";
+    if(error&0x20)
+      error_msg+="\nOverload";
+    if(error&0x40)
+      error_msg+="\nInvalid instruction";
+    std::cout << error_msg << std::endl;
+    throw CDynamixelAlarmException(_HERE_,error_msg,this->node_address,error);
+  }
 }
 
 void CDynamixel::set_baudrate(int baudrate)
@@ -56,6 +312,7 @@ void CDynamixel::set_baudrate(int baudrate)
   else
   {
     /* handle exceptions */
+    throw CDynamixelException(_HERE_,"The communication device is not properly configured",this->node_address);
   }
 }
   
@@ -76,6 +333,7 @@ void CDynamixel::set_id(unsigned char id)
   else
   {
     /* handle exceptions */
+    throw CDynamixelException(_HERE_,"The communication device is not properly configured",id);
   }
 }
 
@@ -109,829 +367,296 @@ void CDynamixel::resync(void)
   }
 }
 
-void CDynamixel::read_byte_register(unsigned char address,unsigned char *value)
+void CDynamixel::read_byte_register(unsigned short int address,unsigned char *value)
 {
-  unsigned char packet[8]={0xFF,0xFF,0x00,0x04,0x02,0x00,0x00,0x00};
-  int num=0,read=0,it=0,read_length=7,i=0;
-  std::list<std::string> events;
-  unsigned char data[7],dummy;
-  std::string error_msg;
-  bool rx_tx_ok=false;
+  unsigned char *data,error,length_v1,cmd[4];
+  unsigned short length_v2;
 
-  if(this->usb_dev!=NULL)
+  if(version==dyn_version1)
   {
-    events.push_back(this->usb_rx_event_id); 
-    while(!rx_tx_ok)
-    {
-      this->usb_access->enter();
-      packet[2]=this->node_address;
-      packet[5]=(unsigned char)address;
-      packet[6]=1;
-      packet[7]=this->compute_checksum(packet,8);
-
-      if(this->usb_dev->write(packet,8)!=8)
-      {
-        /* handle exceptions */
-        this->usb_access->exit();
-        throw CDynamixelException(_HERE_,"Unexpected error while writing to the dynamixel device",this->node_address);
-      }
-      else
-      {
-        try{
-          while(read<read_length)
-          {
-            this->event_server->wait_all(events,100);
-            num=this->usb_dev->get_num_data();
-            if(read+num>read_length)
-            {
-              this->usb_dev->read(&data[read],read_length-read);
-              for(i=0;i<(num-read_length+read);i++)
-                this->usb_dev->read(&dummy,1);
-            }
-            else
-              this->usb_dev->read(&data[read],num);  
-            read+=num;
-            if(read>5 && data[4]!=0x00)
-              read_length=6;
-          }
-          if(this->compute_checksum(data,read_length)!=0)
-          {
-            /* handle exceptions */
-            this->usb_access->exit();
-            it++;
-            if(it==NUM_RETRIES)
-              throw CDynamixelSyncException("Invalid packet checksum");
-            else
-            {
-              read=0;
-              read_length=7;
-            }
-          }
-          else 
-          { 
-            rx_tx_ok=true;// transmission ok
-            this->usb_access->exit();
-          }
-        }catch(CEventTimeoutException &e){
-          this->resync();
-          this->usb_access->exit();
-        }
-      }
-    }
-    if(data[4]!=0x00)
-    {
-      /* handle exceptions */
-      if(data[4]&0x01)
-        error_msg+="\nThe supply voltage is out of range";
-      if(data[4]&0x02)
-        error_msg+="\nThe goal position is out of range";
-      if(data[4]&0x04)
-        error_msg+="\nThe internal temperature is too high";
-      if(data[4]&0x08)
-        error_msg+="\nThe provided parameter is out of range";
-      if(data[4]&0x10)
-        error_msg+="\nThe packet sent to the dynamixel device had an invalid checksum";
-      if(data[4]&0x20)
-        error_msg+="\nOverload";
-      if(data[4]&0x40)
-        error_msg+="\nInvalid instruction";
-      throw CDynamixelAlarmException(_HERE_,error_msg,this->node_address,data[4]);
-    }
-    else
-      *value=data[5];
+    cmd[0]=address%256;
+    cmd[1]=1;
+    this->send_instruction_packet_v1(dyn_read,cmd,2);
+    error=this->receive_status_packet_v1(&data,&length_v1);
   }
   else
   {
-    /* handle exceptions */
-    throw CDynamixelException(_HERE_,"The communication device is not ready to send data",this->node_address);
+    cmd[0]=address%256;
+    cmd[1]=address/256;
+    cmd[2]=1;
+    cmd[3]=0;
+    this->send_instruction_packet_v2(dyn_read,cmd,4);
+    error=this->receive_status_packet_v2(&data,&length_v2);
+  }
+  try{
+    this->handle_error(error);
+    *value=data[0];
+    if(data!=NULL)
+      delete[] data;
+  }catch(CException &e){
+    if(data!=NULL)
+      delete[] data;
+    throw e;
   }
 }
 
-void CDynamixel::read_word_register(unsigned char address,unsigned short int *value)
+void CDynamixel::read_word_register(unsigned short int address,unsigned short int *value)
 {
-  unsigned char packet[8]={0xFF,0xFF,0x00,0x04,0x02,0x00,0x00,0x00};
-  int num=0,read=0,it=0,read_length=8,i=0;
-  std::list<std::string> events;
-  unsigned char data[8],dummy;
-  std::string error_msg;
-  bool rx_tx_ok=false;
+  unsigned char *data,error,length_v1,cmd[4];
+  unsigned short length_v2;
 
-  if(this->usb_dev!=NULL)
+  if(version==dyn_version1)
   {
-    events.push_back(this->usb_rx_event_id); 
-    while(!rx_tx_ok)
-    {
-      this->usb_access->enter();
-      packet[2]=this->node_address;
-      packet[5]=(unsigned char)address;
-      packet[6]=2;
-      packet[7]=this->compute_checksum(packet,8);
-
-      if(this->usb_dev->write(packet,8)!=8)
-      {
-        /* handle exceptions */
-        this->usb_access->exit();
-        throw CDynamixelException(_HERE_,"Unexpected error while writing to the dynamixel device",this->node_address);
-      }
-      else
-      {
-        try{
-          while(read<read_length)
-          {
-            this->event_server->wait_all(events,100);
-            num=this->usb_dev->get_num_data();
-            if(read+num>read_length)
-            {
-              this->usb_dev->read(&data[read],read_length-read);
-              for(i=0;i<(num-read_length+read);i++)
-                this->usb_dev->read(&dummy,1);
-            }
-            else
-              this->usb_dev->read(&data[read],num);  
-            read+=num;
-            if(read>5 && data[4]!=0x00)
-              read_length=6;
-          }
-          if(this->compute_checksum(data,read_length)!=0)
-          {
-            /* handle exceptions */
-            this->usb_access->exit();
-            it++;
-            if(it==NUM_RETRIES)
-              throw CDynamixelSyncException("Invalid packet checksum");
-            else
-            {
-              read=0;
-              read_length=8;
-            }
-          }
-          else
-          {
-            rx_tx_ok=true;// transmission ok
-            this->usb_access->exit();
-          }
-        }catch(CEventTimeoutException &e){
-          this->resync();
-          this->usb_access->exit();
-        }
-      }
-    }
-    if(data[4]!=0x00)
-    {
-      /* handle exceptions */
-      if(data[4]&0x01)
-        error_msg+="\nThe supply voltage is out of range";
-      if(data[4]&0x02)
-        error_msg+="\nThe goal position is out of range";
-      if(data[4]&0x04)
-        error_msg+="\nThe internal temperature is too high";
-      if(data[4]&0x08)
-        error_msg+="\nThe provided parameter is out of range";
-      if(data[4]&0x10)
-        error_msg+="\nThe packet sent to the dynamixel device had an invalid checksum";
-      if(data[4]&0x20)
-        error_msg+="\nOverload";
-      if(data[4]&0x40)
-        error_msg+="\nInvalid instruction";
-      throw CDynamixelAlarmException(_HERE_,error_msg,this->node_address,data[4]);
-    }
-    else
-      *value=data[5]+data[6]*256;
+    cmd[0]=address%256;
+    cmd[1]=2;
+    this->send_instruction_packet_v1(dyn_read,cmd,2);
+    error=this->receive_status_packet_v1(&data,&length_v1);
   }
   else
   {
-    /* handle exceptions */
-    throw CDynamixelException(_HERE_,"The communication device is not ready to send data",this->node_address);
+    cmd[0]=address%256;
+    cmd[1]=address/256;
+    cmd[2]=2;
+    cmd[3]=0;
+    this->send_instruction_packet_v2(dyn_read,cmd,4);
+    error=this->receive_status_packet_v2(&data,&length_v2);
+  }
+  try{
+    this->handle_error(error);
+    *value=data[0]+data[1]*256;
+    if(data!=NULL)
+      delete[] data;
+  }catch(CException &e){
+    if(data!=NULL)
+      delete[] data;
+    throw e;
   }
 }
 
-void CDynamixel::write_byte_register(unsigned char address, unsigned char data)
+void CDynamixel::write_byte_register(unsigned short int address, unsigned char value)
 {
-  unsigned char packet[8]={0xFF,0xFF,0x00,0x04,0x03,0x00,0x00,0x00};
-  std::list<std::string> events;
-  unsigned char answer[6],dummy;
-  int num=0,read=0,it=0,i=0;
-  std::string error_msg;
-  bool rx_tx_ok=false;
+  unsigned char *data,error,length_v1,cmd[3];
+  unsigned short length_v2;
 
-  if(this->usb_dev!=NULL)
+  if(version==dyn_version1)
   {
-    events.push_back(this->usb_rx_event_id); 
-    while(!rx_tx_ok)
-    {
-      this->usb_access->enter();
-      packet[2]=this->node_address;
-      packet[5]=(unsigned char)address;
-      packet[6]=data;
-      packet[7]=this->compute_checksum(packet,8);
-  
-      if(this->usb_dev->write(packet,8)!=8)
-      {
-        /* handle exceptions */
-        this->usb_access->exit();
-        throw CDynamixelException(_HERE_,"Unexpected error while writing to the dynamixel device",this->node_address);
-      }
-      else
-      {  
-        try{
-          while(read<6)
-          {
-            this->event_server->wait_all(events,100);
-            num=this->usb_dev->get_num_data();
-            if(read+num>6)
-            {
-              this->usb_dev->read(&answer[read],6-read);
-              for(i=0;i<(num-6+read);i++)
-                this->usb_dev->read(&dummy,1);
-            }
-            else
-              this->usb_dev->read(&answer[read],num);  
-            read+=num;
-          }
-          if(this->compute_checksum(answer,6)!=0)
-          {
-            /* handle exceptions */
-            this->usb_access->exit();
-            it++;
-            if(it==NUM_RETRIES)
-              throw CDynamixelSyncException("Invalid packet checksum");
-            else
-              read=0;
-          }
-          else
-          {
-            rx_tx_ok=true;// transmission ok
-            this->usb_access->exit(); 
-          }
-        }catch(CEventTimeoutException &e){
-          this->resync();
-          this->usb_access->exit();
-        }
-      }
-    }
-    if(answer[4]!=0x00)
-    {
-      /* handle exceptions */
-      if(answer[4]&0x01)
-        error_msg+="\nThe supply voltage is out of range";
-      if(answer[4]&0x02)
-        error_msg+="\nThe goal position is out of range";
-      if(answer[4]&0x04)
-        error_msg+="\nThe internal temperature is too high";
-      if(answer[4]&0x08)
-        error_msg+="\nThe provided parameter is out of range";
-      if(answer[4]&0x10)
-        error_msg+="\nThe packet sent to the dynamixel device had an invalid checksum";
-      if(answer[4]&0x20)
-        error_msg+="\nOverload";
-      if(answer[4]&0x40)
-        error_msg+="\nInvalid instruction";
-      throw CDynamixelAlarmException(_HERE_,error_msg,this->node_address,answer[4]);
-    }
+    cmd[0]=address%256;
+    cmd[1]=value;
+    this->send_instruction_packet_v1(dyn_write,cmd,2);
+    error=this->receive_status_packet_v1(&data,&length_v1);
   }
   else
   {
-    /* handle exceptions */
-    throw CDynamixelException(_HERE_,"The communication device is not ready to send data",this->node_address);
+    cmd[0]=address%256;
+    cmd[1]=address/256;
+    cmd[2]=value;
+    this->send_instruction_packet_v2(dyn_write,cmd,3);
+    error=this->receive_status_packet_v2(&data,&length_v2);
   }
+  if(data!=NULL)
+    delete[] data;
+  this->handle_error(error);
 }
 
-void CDynamixel::write_word_register(unsigned char address, unsigned short int data)
+void CDynamixel::write_word_register(unsigned short int address, unsigned short int value)
 {
-  unsigned char packet[9]={0xFF,0xFF,0x00,0x05,0x03,0x00,0x00,0x00,0x00};
-  std::list<std::string> events;
-  unsigned char answer[6],dummy;
-  int num=0,read=0,it=0,i=0;
-  std::string error_msg;
-  bool rx_tx_ok=false;
+  unsigned char *data,error,length_v1,cmd[4];
+  unsigned short length_v2;
 
-  if(this->usb_dev!=NULL)
+  if(version==dyn_version1)
   {
-    events.push_back(this->usb_rx_event_id); 
-    while(!rx_tx_ok)
-    {
-      this->usb_access->enter();
-      packet[2]=this->node_address;
-      packet[5]=(unsigned char)address;
-      packet[6]=((unsigned char *)&data)[0];
-      packet[7]=((unsigned char *)&data)[1];
-      packet[8]=this->compute_checksum(packet,9);
-
-      if(this->usb_dev->write(packet,9)!=9)
-      {
-        // handle exceptions
-        this->usb_access->exit();
-        throw CDynamixelException(_HERE_,"Unexpected error while writing to the dynamixel device",this->node_address);
-      }  
-      else
-      {  
-        try{
-          while(read<6)
-          {
-            this->event_server->wait_all(events,100);
-            num=this->usb_dev->get_num_data();
-            if(read+num>6)
-            {
-              this->usb_dev->read(&answer[read],6-read);
-              for(i=0;i<(num-6+read);i++)
-                this->usb_dev->read(&dummy,1);
-            }
-            else
-              this->usb_dev->read(&answer[read],num);  
-            read+=num;
-          }
-          if(this->compute_checksum(answer,6)!=0)
-          {
-            /* handle exceptions */
-            this->usb_access->exit();
-            it++;
-            if(it==NUM_RETRIES)
-              throw CDynamixelSyncException("Invalid packet checksum");
-            else
-              read=0;
-          }
-          else
-          {
-            rx_tx_ok=true;
-            this->usb_access->exit();
-          }
-        }catch(CEventTimeoutException &e){
-          this->resync();
-          this->usb_access->exit();
-        }
-      }
-    }
-    if(answer[4]!=0x00)
-    {
-      /* handle exceptions */
-      if(answer[4]&0x01)
-        error_msg+="\nThe supply voltage is out of range";
-      if(answer[4]&0x02)
-        error_msg+="\nThe goal position is out of range";
-      if(answer[4]&0x04)
-        error_msg+="\nThe internal temperature is too high";
-      if(answer[4]&0x08)
-        error_msg+="\nThe provided parameter is out of range";
-      if(answer[4]&0x10)
-        error_msg+="\nThe packet sent to the dynamixel device had an invalid checksum";
-      if(answer[4]&0x20)
-        error_msg+="\nOverload";
-      if(answer[4]&0x40)
-        error_msg+="\nInvalid instruction";
-      throw CDynamixelAlarmException(_HERE_,error_msg,this->node_address,answer[4]);
-    }
+    cmd[0]=address%256;
+    cmd[1]=value%256;
+    cmd[2]=value/256;
+    this->send_instruction_packet_v1(dyn_write,cmd,3);
+    error=this->receive_status_packet_v1(&data,&length_v1);
   }
   else
   {
-    /* handle exceptions */
-    throw CDynamixelException(_HERE_,"The communication device is not ready to send data",this->node_address);
+    cmd[0]=address%256;
+    cmd[1]=address/256;
+    cmd[2]=value%256; 
+    cmd[3]=value/256;
+    this->send_instruction_packet_v2(dyn_write,cmd,4);
+    error=this->receive_status_packet_v2(&data,&length_v2);
   }
+  if(data!=NULL)
+    delete[] data;
+  this->handle_error(error);
 }
 
-void CDynamixel::registered_byte_write(unsigned char address, unsigned char data)
+void CDynamixel::registered_byte_write(unsigned short int address, unsigned char value)
 {
-  unsigned char packet[8]={0xFF,0xFF,0x00,0x04,0x04,0x00,0x00,0x00};
-  std::list<std::string> events;
-  unsigned char answer[6],dummy;
-  int num=0,read=0,it=0,i=0;
-  std::string error_msg;
-  bool rx_tx_ok=false;
+  unsigned char *data,error,length_v1,cmd[3];
+  unsigned short length_v2;
 
-  if(this->usb_dev!=NULL)
+  if(version==dyn_version1)
   {
-    events.push_back(this->usb_rx_event_id); 
-    while(!rx_tx_ok)
-    {
-      this->usb_access->enter();
-      packet[2]=this->node_address;
-      packet[5]=(unsigned char)address;
-      packet[6]=data;
-      packet[7]=this->compute_checksum(packet,8);
-  
-      if(this->usb_dev->write(packet,8)!=8)
-      {
-        /* handle exceptions */
-        this->usb_access->exit();
-        throw CDynamixelException(_HERE_,"Unexpected error while writing to the dynamixel device",this->node_address);
-      }  
-      else
-      { 
-        try{
-          while(read<6)
-          {
-            this->event_server->wait_all(events,100);
-            num=this->usb_dev->get_num_data();
-            if(read+num>6)
-            {
-              this->usb_dev->read(&answer[read],6-read);
-              for(i=0;i<(num-6+read);i++)
-                this->usb_dev->read(&dummy,1);
-            }
-            else
-              this->usb_dev->read(&answer[read],num);  
-            read+=num;
-          }
-          if(this->compute_checksum(answer,6)!=0)
-          {  
-            /* handle exceptions */
-            this->usb_access->exit();
-            it++;
-            if(it==NUM_RETRIES)
-              throw CDynamixelSyncException("Invalid packet checksum");
-            else
-              read=0;
-          }
-          else
-          {
-            rx_tx_ok=true;
-            this->usb_access->exit();
-          }
-        }catch(CEventTimeoutException &e){
-          this->resync();
-          this->usb_access->exit();
-        }
-      }
-    }
-    if(answer[4]!=0x00)
-    {
-      /* handle exceptions */
-      if(answer[4]&0x01)
-        error_msg+="\nThe supply voltage is out of range";
-      if(answer[4]&0x02)
-        error_msg+="\nThe goal position is out of range";
-      if(answer[4]&0x04)
-        error_msg+="\nThe internal temperature is too high";
-      if(answer[4]&0x08)
-        error_msg+="\nThe provided parameter is out of range";
-      if(answer[4]&0x10)
-        error_msg+="\nThe packet sent to the dynamixel device had an invalid checksum";
-      if(answer[4]&0x20)
-        error_msg+="\nOverload";
-      if(answer[4]&0x40)
-        error_msg+="\nInvalid instruction";
-      throw CDynamixelAlarmException(_HERE_,error_msg,this->node_address,answer[4]);
-    }
+    cmd[0]=address%256;
+    cmd[1]=value;
+    this->send_instruction_packet_v1(dyn_reg_write,cmd,2);
+    error=this->receive_status_packet_v1(&data,&length_v1);
   }
   else
   {
-    /* handle exceptions */
-    throw CDynamixelException(_HERE_,"The communication device is not ready to send data",this->node_address);
+    cmd[0]=address%256;
+    cmd[1]=address/256;
+    cmd[2]=value;
+    this->send_instruction_packet_v2(dyn_reg_write,cmd,3);
+    error=this->receive_status_packet_v2(&data,&length_v2);
   }
+  if(data!=NULL)
+    delete[] data;
+  this->handle_error(error);
 }
 
-void CDynamixel::registered_word_write(unsigned char address, unsigned short int data)
+void CDynamixel::registered_word_write(unsigned short int address, unsigned short int value)
 {
-  unsigned char packet[9]={0xFF,0xFF,0x00,0x05,0x04,0x00,0x00,0x00,0x00};
-  std::list<std::string> events;
-  unsigned char answer[6],dummy;
-  int num=0,read=0,it=0,i=0;
-  std::string error_msg;
-  bool rx_tx_ok=false;
+  unsigned char *data,error,length_v1,cmd[4];
+  unsigned short length_v2;
 
-  if(this->usb_dev!=NULL)
+  if(version==dyn_version1)
   {
-    events.push_back(this->usb_rx_event_id); 
-    while(!rx_tx_ok)
-    {
-      this->usb_access->enter();
-      packet[2]=this->node_address;
-      packet[5]=(unsigned char)address;
-      packet[6]=((unsigned char *)&data)[0];
-      packet[7]=((unsigned char *)&data)[1];
-      packet[8]=this->compute_checksum(packet,9);
-  
-      if(this->usb_dev->write(packet,9)!=9)
-      {
-        // handle exceptions
-        this->usb_access->exit();
-        throw CDynamixelException(_HERE_,"Unexpected error while writing to the dynamixel device",this->node_address);
-      }
-      else
-      {
-        try{
-          while(read<6)
-          {
-            this->event_server->wait_all(events,100);
-            num=this->usb_dev->get_num_data();
-            if(read+num>6)
-            {
-              this->usb_dev->read(&answer[read],6-read);
-              for(i=0;i<(num-6+read);i++)
-                this->usb_dev->read(&dummy,1);
-            }
-            else
-              this->usb_dev->read(&answer[read],num);  
-            read+=num;
-          }
-          if(this->compute_checksum(answer,6)!=0)
-          { 
-            /* handle exceptions */
-            this->usb_access->exit();
-            it++;
-            if(it==NUM_RETRIES)
-              throw CDynamixelSyncException("Invalid packet checksum");
-            else
-              read=0;
-          }
-          else
-          {
-            rx_tx_ok=true;
-            this->usb_access->exit();
-          }
-        }catch(CEventTimeoutException &e){
-          this->resync();
-          this->usb_access->exit();
-        }
-      }
-    }
-    if(answer[4]!=0x00)
-    {
-      /* handle exceptions */
-      if(answer[4]&0x01)
-        error_msg+="\nThe supply voltage is out of range";
-      if(answer[4]&0x02)
-        error_msg+="\nThe goal position is out of range";
-      if(answer[4]&0x04)
-        error_msg+="\nThe internal temperature is too high";
-      if(answer[4]&0x08)
-        error_msg+="\nThe provided parameter is out of range";
-      if(answer[4]&0x10)
-        error_msg+="\nThe packet sent to the dynamixel device had an invalid checksum";
-      if(answer[4]&0x20)
-        error_msg+="\nOverload";
-      if(answer[4]&0x40)
-        error_msg+="\nInvalid instruction";
-      throw CDynamixelAlarmException(_HERE_,error_msg,this->node_address,answer[4]);
-    }
+    cmd[0]=address%256;
+    cmd[1]=value%256;
+    cmd[2]=value/256;
+    this->send_instruction_packet_v1(dyn_reg_write,cmd,3);
+    error=this->receive_status_packet_v1(&data,&length_v1);
   }
   else
   {
-    /* handle exceptions */
-    throw CDynamixelException(_HERE_,"The communication device is not ready to send data",this->node_address);
+    cmd[0]=address%256;
+    cmd[1]=address/256;
+    cmd[2]=value%256;
+    cmd[3]=value/256;
+    this->send_instruction_packet_v2(dyn_reg_write,cmd,4);
+    error=this->receive_status_packet_v2(&data,&length_v2);
   }
+  if(data!=NULL)
+    delete[] data;
+  this->handle_error(error);
 }
 
-void CDynamixel::write_registers(unsigned char address, unsigned char *data, unsigned int length)
+void CDynamixel::registered_write(unsigned short int address, unsigned char *values,unsigned int length)
 {
-  unsigned char *packet;
-  std::list<std::string> events;
-  unsigned char answer[6],dummy;
-  int num=0,read=0,it=0;
-  std::string error_msg;
-  bool rx_tx_ok=false;
-  unsigned int i=0;
+  unsigned char *data,error,length_v1,*cmd;
+  unsigned short length_v2,i;
 
-  if(this->usb_dev!=NULL)
+  if(version==dyn_version1)
   {
-    if(address+length>255)
-    {
-      /* handle exceptions */
-      throw CDynamixelException(_HERE_,"Invalid address range",this->node_address);
-    }
-    else
-    {
-      events.push_back(this->usb_rx_event_id); 
-      while(!rx_tx_ok)
-      { 
-        packet=new unsigned char[length+7];
-        this->usb_access->enter();
-        packet[0]=0xFF;
-        packet[1]=0xFF;
-        packet[2]=this->node_address;
-        packet[3]=length+3;
-        packet[4]=0x03;
-        packet[5]=(unsigned char)address;
-        for(i=0;i<length;i++)
-          packet[i+6]=data[i];
-        packet[length+6]=this->compute_checksum(packet,length+6);
-  
-        if(this->usb_dev->write(packet,length+7)!=(length+7))
-        {
-          /* handle exceptions */
-          this->usb_access->exit();
-          delete[] packet;
-          throw CDynamixelException(_HERE_,"Unexpected error while writing to the dynamixel device",this->node_address);
-        }
-        else
-        {  
-          delete[] packet;
-          try{
-            while(read<6)
-            {
-              this->event_server->wait_all(events,100);
-              num=this->usb_dev->get_num_data();
-              if(read+num>6)
-              {
-                this->usb_dev->read(&answer[read],6-read);
-                for(i=0;i<(num-6+read);i++)
-                  this->usb_dev->read(&dummy,1);
-              }
-              else
-                this->usb_dev->read(&answer[read],num);  
-              read+=num;
-            }
-            if(this->compute_checksum(answer,6)!=0)
-            {
-              /* handle exceptions */
-              this->usb_access->exit();
-              it++;
-              if(it==NUM_RETRIES)
-                throw CDynamixelSyncException("Invalid packet checksum");
-              else
-                read=0;
-            }
-            else
-            {
-              rx_tx_ok=true;// transmission ok
-              this->usb_access->exit(); 
-            }
-          }catch(CEventTimeoutException &e){
-            this->resync();
-            this->usb_access->exit();
-          }
-        }
-      }
-      if(answer[4]!=0x00)
-      {
-        /* handle exceptions */
-        if(answer[4]&0x01)
-          error_msg+="\nThe supply voltage is out of range";
-        if(answer[4]&0x02)
-          error_msg+="\nThe goal position is out of range";
-        if(answer[4]&0x04)
-          error_msg+="\nThe internal temperature is too high";
-        if(answer[4]&0x08)
-          error_msg+="\nThe provided parameter is out of range";
-        if(answer[4]&0x10)
-          error_msg+="\nThe packet sent to the dynamixel device had an invalid checksum";
-        if(answer[4]&0x20)
-          error_msg+="\nOverload";
-        if(answer[4]&0x40)
-          error_msg+="\nInvalid instruction";
-        throw CDynamixelAlarmException(_HERE_,error_msg,this->node_address,answer[4]);
-      }
-    }
+    cmd=new unsigned char[length+1];
+    cmd[0]=address%256;
+    for(i=0;i<length;i++)
+      cmd[1+i]=values[i];
+    this->send_instruction_packet_v1(dyn_reg_write,cmd,length+1);
+    delete[] cmd;
+    error=this->receive_status_packet_v1(&data,&length_v1);
   }
   else
   {
-    /* handle exceptions */
-    throw CDynamixelException(_HERE_,"The communication device is not ready to send data",this->node_address);
+    cmd=new unsigned char[length+2];
+    cmd[0]=address%256;
+    cmd[1]=address/256;
+    for(i=0;i<length;i++)
+      cmd[2+i]=values[i];
+    this->send_instruction_packet_v2(dyn_reg_write,cmd,length+2);
+    delete[] cmd;
+    error=this->receive_status_packet_v2(&data,&length_v2);
   }
+  if(data!=NULL)
+    delete[] data;
+  this->handle_error(error);
 }
 
-void CDynamixel::read_registers(unsigned char address, unsigned char *data, unsigned int length)
+void CDynamixel::write_registers(unsigned short int address, unsigned char *values, unsigned int length)
 {
-  unsigned char packet[8]={0xFF,0xFF,0x00,0x04,0x02,0x00,0x00,0x00};
-  int num=0,read=0,it=0,read_length=length+6;
-  std::list<std::string> events;
-  unsigned char *answer,dummy;
-  std::string error_msg;
-  bool rx_tx_ok=false;
-  unsigned int i=0;
+  unsigned char *data,error,length_v1,*cmd;
+  unsigned short length_v2,i;
 
-  if(this->usb_dev!=NULL)
+  if(version==dyn_version1)
   {
-    events.push_back(this->usb_rx_event_id); 
-    while(!rx_tx_ok)
-    {
-      this->usb_access->enter();
-      packet[2]=this->node_address;
-      packet[5]=(unsigned char)address;
-      packet[6]=length;
-      packet[7]=this->compute_checksum(packet,8);
-
-      if(this->usb_dev->write(packet,8)!=8)
-      {
-        /* handle exceptions */
-        this->usb_access->exit();
-        throw CDynamixelException(_HERE_,"Unexpected error while writing to the dynamixel device",this->node_address);
-      }
-      else
-      {
-        try{
-          answer=new unsigned char[length+6];
-          while(read<read_length)
-          {
-            this->event_server->wait_all(events,100);
-            num=this->usb_dev->get_num_data();
-            if(read+num>read_length)
-            {
-              this->usb_dev->read(&answer[read],read_length-read);
-              for(i=0;i<(num-read_length+read);i++)
-                this->usb_dev->read(&dummy,1);
-            }
-            else
-              this->usb_dev->read(&answer[read],num);  
-            read+=num;
-            if(read>5 && answer[4]!=0x00)
-              read_length=6;
-          }
-          if(this->compute_checksum(answer,read_length)!=0)
-          {
-            /* handle exceptions */
-            this->usb_access->exit();
-            it++;
-            if(it==NUM_RETRIES)
-            {
-              delete[] answer;
-              throw CDynamixelSyncException("Invalid packet checksum");
-            }
-            else
-            {
-              read=0;
-              read_length=length+6;
-            }
-          }
-          else 
-          { 
-            rx_tx_ok=true;// transmission ok
-            this->usb_access->exit();
-          }
-        }catch(CEventTimeoutException &e){
-          this->resync();
-          this->usb_access->exit();
-        }
-      }
-    }
-    if(answer[4]!=0x00)
-    {
-      /* handle exceptions */
-      if(answer[4]&0x01)
-        error_msg+="\nThe supply voltage is out of range";
-      if(answer[4]&0x02)
-        error_msg+="\nThe goal position is out of range";
-      if(answer[4]&0x04)
-        error_msg+="\nThe internal temperature is too high";
-      if(answer[4]&0x08)
-        error_msg+="\nThe provided parameter is out of range";
-      if(answer[4]&0x10)
-        error_msg+="\nThe packet sent to the dynamixel device had an invalid checksum";
-      if(answer[4]&0x20)
-        error_msg+="\nOverload";
-      if(answer[4]&0x40)
-        error_msg+="\nInvalid instruction";
-      delete[] answer;
-      throw CDynamixelAlarmException(_HERE_,error_msg,this->node_address,answer[4]);
-    }
-    else
-    {
-      for(i=0;i<length;i++)
-        data[i]=answer[i+5];
-      delete[] answer;
-    }
+    cmd=new unsigned char[length+1];
+    cmd[0]=address%256;
+    for(i=0;i<length;i++)
+      cmd[1+i]=values[i];
+    this->send_instruction_packet_v1(dyn_write,cmd,length+1);
+    delete[] cmd;
+    error=this->receive_status_packet_v1(&data,&length_v1);
   }
   else
   {
-    /* handle exceptions */
-    throw CDynamixelException(_HERE_,"The communication device is not ready to send data",this->node_address);
+    cmd=new unsigned char[length+2];
+    cmd[0]=address%256;
+    cmd[1]=address/256;
+    for(i=0;i<length;i++)
+      cmd[2+i]=values[i];
+    this->send_instruction_packet_v2(dyn_write,cmd,length+2);
+    delete[] cmd;
+    error=this->receive_status_packet_v2(&data,&length_v2);
   }
+  if(data!=NULL)
+    delete[] data;
+  this->handle_error(error);
 }
 
-void CDynamixel::reset(void)
+void CDynamixel::read_registers(unsigned short int address, unsigned char *values, unsigned int length)
 {
-  unsigned char packet[6]={0xFF,0xFF,0x00,0x02,0x06,0x00};
-  std::list<std::string> events;
-  unsigned char data[6];
-  int num=0,read=0;
+  unsigned char *data,error,length_v1,cmd[4];
+  unsigned short length_v2,i;
 
-  if(this->usb_dev!=NULL)
+  if(version==dyn_version1)
   {
-    this->usb_access->enter();
-    packet[2]=this->node_address;
-    packet[5]=this->compute_checksum(packet,6);
+    cmd[0]=address%256;
+    cmd[1]=length%256;
+    this->send_instruction_packet_v1(dyn_read,cmd,2);
+    error=this->receive_status_packet_v1(&data,&length_v1);
+  }
+  else
+  {
+    cmd[0]=address%256;
+    cmd[1]=address/256;
+    cmd[2]=length%256;
+    cmd[3]=length/256;
+    this->send_instruction_packet_v2(dyn_read,cmd,4);
+    error=this->receive_status_packet_v2(&data,&length_v2);
+  }
+  try{
+    this->handle_error(error);
+    for(i=0;i<length;i++)
+      values[i]=data[i];
+    if(data!=NULL)
+      delete[] data;
+  }catch(CException &e){
+    if(data!=NULL)
+      delete[] data;
+    throw e;
+  }
+}
 
-    events.push_back(this->usb_rx_event_id);
- 
-    if(this->usb_dev->write(packet,6)!=6)
-    {
-      // handle exceptions
-      this->usb_access->exit();
-      throw CDynamixelException(_HERE_,"Unexpected error while writing to the dynamixel device",this->node_address);
-    }
-    else
-    {
-      try{
-        while(read<6)
-        {
-          this->event_server->wait_all(events,100);
-          num=this->usb_dev->get_num_data();
-          if(num>(6-read))
-            this->usb_dev->read(&data[read],6-read);
-          else
-            this->usb_dev->read(&data[read],num);
-          read+=num;
-        }
-      }catch(CEventTimeoutException &e){
-        this->usb_access->exit();
-        throw;
-      }
-    }
-    this->usb_access->exit();
+void CDynamixel::reset(dyn_reset_mode_t mode)
+{
+  unsigned char *data,error,length_v1,cmd;
+  unsigned short length_v2;
+
+  if(version==dyn_version1)
+  {
+    this->send_instruction_packet_v1(dyn_read,NULL,0);
+    error=this->receive_status_packet_v1(&data,&length_v1);
   }
   else
   {
-    /* handle exceptions */
-    throw CDynamixelException(_HERE_,"The communication device is not ready to send data",this->node_address);
+    cmd=mode;
+    this->send_instruction_packet_v2(dyn_read,&cmd,1);
+    error=this->receive_status_packet_v2(&data,&length_v2);
+  }
+  try{
+    this->handle_error(error);
+    if(data!=NULL)
+      delete[] data;
+  }catch(CException &e){
+    if(data!=NULL)
+      delete[] data;
+    throw e;
   }
 }
 
diff --git a/src/dynamixel.h b/src/dynamixel.h
index c38753e399b176876d2c78b8deeee76538c4fefa..682879c3775d6d28b1df4b354f327d7f6127f93b 100644
--- a/src/dynamixel.h
+++ b/src/dynamixel.h
@@ -12,6 +12,23 @@
 
 const int NUM_RETRIES=10;
 
+typedef enum {dyn_version1,dyn_version2} dyn_version_t;
+
+typedef enum {dyn_ping=0x01,
+              dyn_read=0x02,
+              dyn_write=0x03,
+              dyn_reg_write=0x04,
+              dyn_action=0x05,
+              dyn_factory_reset=0x06,
+              dyn_reboot=0x08,
+              dyn_status=0x55,
+              dyn_sync_read=0x82,
+              dyn_sync_write=0x83,
+              dyn_bulk_read=0x92,
+              dyn_bulk_write=0x93} dyn_inst_t;
+
+typedef enum {dyn_reset_all=0xFF,dyn_reset_keep_id=0x01,dyn_reset_keep_id_baud=0x02} dyn_reset_mode_t;
+
 /**
  * \brief 
  *
@@ -55,11 +72,6 @@ class CDynamixel
      *
      */
     unsigned char baudrate_register;
-    /**
-     * \brief Function to compute the checksum of the data packets
-     *
-     */
-    unsigned char compute_checksum(unsigned char *packet,int len);   
     /**
      * \brief 
      *
@@ -70,6 +82,37 @@ class CDynamixel
      *
      */
     void resync(void);
+    /**
+     * \brief
+     *
+     */
+    dyn_version_t version;
+  protected:
+    /**
+     * \brief 
+     *
+     */
+    void send_instruction_packet_v1(dyn_inst_t inst,unsigned char *data=NULL,unsigned char len=0);
+    /**
+     * \brief 
+     *
+     */
+    void send_instruction_packet_v2(dyn_inst_t inst,unsigned char *data=NULL,unsigned short int len=0);
+    /**
+     * \brief 
+     *
+     */
+    unsigned char receive_status_packet_v1(unsigned char **data,unsigned char *len);
+    /**
+     * \brief 
+     *
+     */
+    unsigned char receive_status_packet_v2(unsigned char **data,unsigned short int *len);
+    /**
+     * \brief 
+     *
+     */
+    void handle_error(unsigned char error); 
   public:
     /**
      * \brief
@@ -80,47 +123,52 @@ class CDynamixel
      * \brief Function to read a register
      *
      */
-    void read_byte_register(unsigned char address, unsigned char *value);
+    void read_byte_register(unsigned short int address, unsigned char *value);
     /**
      * \brief Function to read a register
      *
      */
-    void read_word_register(unsigned char address,unsigned short int *value);
+    void read_word_register(unsigned short int address,unsigned short int *value);
+    /**
+     * \brief Function to write to a register
+     *
+     */
+    void write_byte_register(unsigned short int address, unsigned char value);
     /**
      * \brief Function to write to a register
      *
      */
-    void write_byte_register(unsigned char address, unsigned char data);
+    void write_word_register(unsigned short int address, unsigned short int value);
     /**
      * \brief Function to write to a register
      *
      */
-    void write_word_register(unsigned char address, unsigned short int data);
+    void registered_byte_write(unsigned short int address, unsigned char value);
     /**
      * \brief Function to write to a register
      *
      */
-    void registered_byte_write(unsigned char address, unsigned char data);
+    void registered_word_write(unsigned short int address, unsigned short int value);
     /**
      * \brief Function to write to a register
      *
      */
-    void registered_word_write(unsigned char address, unsigned short int data);
+    void registered_write(unsigned short int address, unsigned char *values,unsigned int length);
     /**
      * \brief Function to write to a register
      *
      */
-    void write_registers(unsigned char address, unsigned char *data, unsigned int length);
+    void write_registers(unsigned short int address, unsigned char *values, unsigned int length);
     /**
      * \brief Function to write to a register
      *
      */
-    void read_registers(unsigned char address, unsigned char *data, unsigned int length);
+    void read_registers(unsigned short int address, unsigned char *values, unsigned int length);
     /**
      * \brief 
      *  
      */ 
-    void reset(void);
+    void reset(dyn_reset_mode_t mode=dyn_reset_all);
     /**
      * \brief
      *
diff --git a/src/dynamixelserver.cpp b/src/dynamixelserver.cpp
index dfea759629db4d2296396b9186fac726b4dcd6ef..94839ebcec0f67ea9e0ff4669a618a0fc194b02e 100644
--- a/src/dynamixelserver.cpp
+++ b/src/dynamixelserver.cpp
@@ -4,6 +4,41 @@
 #include "ftdiserver.h"
 #include <sstream>
 
+const unsigned short crc_table[256] = {
+        0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
+        0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022,
+        0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072,
+        0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041,
+        0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2,
+        0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1,
+        0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1,
+        0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082,
+        0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192,
+        0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1,
+        0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1,
+        0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2,
+        0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151,
+        0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162,
+        0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132,
+        0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101,
+        0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312,
+        0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321,
+        0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371,
+        0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342,
+        0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1,
+        0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2,
+        0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2,
+        0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381,
+        0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291,
+        0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2,
+        0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2,
+        0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1,
+        0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252,
+        0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261,
+        0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231,
+        0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202
+    };
+
 CDynamixelServer *CDynamixelServer::pinstance=NULL;
 
 CDynamixelServer::CDynamixelServer()
@@ -13,16 +48,21 @@ CDynamixelServer::CDynamixelServer()
   this->event_server->create_event(this->stop_scan_event_id);
   this->scan_done_event_id="dynamixel_server_scan_done_event";
   this->event_server->create_event(this->scan_done_event_id);
+  this->scan_error_event_id="dynamixel_server_scan_error_event";
+  this->event_server->create_event(this->scan_error_event_id);
   this->thread_server=CThreadServer::instance();
   this->scan_thread_id="dynamixel_server_scan_thread";
   this->thread_server->create_thread(this->scan_thread_id);
   this->thread_server->attach_thread(this->scan_thread_id,this->scan_thread,this);
   this->state=dyn_created;
-  this->devices.clear();
+  this->devices_v1.clear();
+  this->devices_v2.clear();
   this->comm_dev=NULL; 
   this->bus_info.baud_rate=-1;
   this->bus_info.bus_id=-1;
   this->bus_info.serial="";
+  this->scan_version=dyn_version1;
+  this->scan_error="No error";
 }
 
 CDynamixelServer::CDynamixelServer(const CDynamixelServer& object)
@@ -44,7 +84,275 @@ CDynamixelServer *CDynamixelServer::instance(void)
   return CDynamixelServer::pinstance; // Retornamos la dirección de la instancia
 }
 
-unsigned char CDynamixelServer::compute_checksum(unsigned char *packet,int len)
+void CDynamixelServer::send_instruction_packet_v1(dyn_inst_t inst,unsigned char *data,unsigned char len,unsigned char id)
+{
+  unsigned char *packet;
+  int i,length;
+
+  switch(inst)
+  {
+    case dyn_action: id=0xFE;// set the broadcast address
+    case dyn_ping: length=6;
+                   packet=new unsigned char[length];
+                   if(len!=0)
+                     throw CDynamixelServerException(_HERE_,"Invalid data length");
+                   break;
+    case dyn_sync_write: id=0xFE;
+                         length=6+len;
+                         data=new unsigned char[length];
+                         break;
+    default: throw CDynamixelServerException(_HERE_,"Instruction not supported");
+             break;
+  }
+  packet[0]=0xFF;
+  packet[1]=0xFF;
+  packet[2]=id;
+  packet[3]=len+2;
+  packet[4]=inst;
+  for(i=0;i<len;i++)
+    packet[5+i]=data[i];
+  // byte stuffing
+  packet[length-1]=0x00;
+  packet[length-1]=this->compute_checksum_v1(packet,length);
+  if(this->comm_dev!=NULL)
+  {
+    this->dynamixel_access.enter();
+    if(this->comm_dev->write(packet,length)!=length)
+    {
+      /* handle exceptions */
+      this->dynamixel_access.exit();
+      throw CDynamixelServerException(_HERE_,"Unexpected error while writing to the communication device");
+    }
+    this->dynamixel_access.exit();
+  }
+  else
+  {
+    /* handle exceptions */
+    throw CDynamixelServerException(_HERE_,"The communication device is not properly configured");
+  }
+}
+
+void CDynamixelServer::send_instruction_packet_v2(dyn_inst_t inst,unsigned char *data,unsigned short int len,unsigned char id)
+{
+  unsigned char *packet;
+  int i,length,crc;
+
+  switch(inst)
+  {
+    case dyn_action: id=0xFE;// set the broadcast address
+    case dyn_ping: length=10;
+                   packet=new unsigned char[length];
+                   if(len!=0)
+                     throw CDynamixelServerException(_HERE_,"Invalid data length");
+                   break;
+    case dyn_sync_write: id=0xFE;
+                         length=10+len;
+                         data=new unsigned char[length];
+                         break;
+    default: throw CDynamixelServerException(_HERE_,"Instruction not supported");
+             break;
+  }
+  packet[0]=0xFF;
+  packet[1]=0xFF;
+  packet[2]=0xFD;
+  packet[3]=0x00;
+  packet[4]=id;
+  packet[5]=(len+3)%256;
+  packet[6]=(len+3)/256;
+  packet[7]=inst;
+  for(i=0;i<len;i++)
+    packet[8+i]=data[i];
+  packet[length-2]=0x00;
+  packet[length-1]=0x00;
+  crc=this->compute_checksum_v2(packet,length-2);
+  packet[length-2]=crc%256;
+  packet[length-1]=crc/256;
+  if(this->comm_dev!=NULL)
+  {
+    this->dynamixel_access.enter();
+    if(this->comm_dev->write(packet,length)!=length)
+    {
+      /* handle exceptions */
+      this->dynamixel_access.exit();
+      throw CDynamixelServerException(_HERE_,"Unexpected error while writing to the communication device");
+    }
+    this->dynamixel_access.exit();
+  }
+  else
+  {
+    /* handle exceptions */
+    throw CDynamixelServerException(_HERE_,"The communication device is not properly configured");
+  }
+}
+
+unsigned char CDynamixelServer::receive_status_packet_v1(unsigned char **data,unsigned char *len)
+{
+  std::list<std::string> events;
+  unsigned char data_int[256];
+  int num=0,read=0,length;
+
+  if(this->comm_dev!=NULL)
+  {
+    try{
+      this->dynamixel_access.enter();
+      events.push_back(this->comm_dev->get_rx_event_id());
+      // read up to the length field
+      do{
+        if((num=this->comm_dev->get_num_data())==0)
+        {
+          this->event_server->wait_all(events,20);
+          num=this->comm_dev->get_num_data();
+        }
+        if((read+num)>4)
+        {
+          this->comm_dev->read(&data_int[read],4-read);
+          read=4;
+        }
+        else
+        {
+          this->comm_dev->read(&data_int[read],num);
+          read+=num;
+        }
+      }while(read<4);
+      length=data_int[3]+4;
+      // read the remaining of the packet
+      while(read<length)
+      {
+        if((num=this->comm_dev->get_num_data())==0)
+        {
+          this->event_server->wait_all(events,20);
+          num=this->comm_dev->get_num_data();
+        }
+        if((read+num)>length)
+        {
+          this->comm_dev->read(&data_int[read],length-read);
+          read=length;
+        }
+        else
+        {
+          this->comm_dev->read(&data_int[read],num);
+          read+=num;
+        }
+      }
+      // check the checksum
+      if(this->compute_checksum_v1(data_int,length)!=0x00)
+      {
+        this->dynamixel_access.exit();
+        /* handle exceptions */
+        throw CDynamixelServerException(_HERE_,"Invalid Checksum");
+      }
+      // byte destuffing
+      // return the error
+      if(length>6)
+      {
+        *data=new unsigned char[length-6];
+        memcpy(*data,&data_int[5],length-6);
+        *len=length-6;
+      }
+      else
+      {
+        *data=NULL;
+        *len=0;
+      }
+      this->dynamixel_access.exit();
+      return data_int[4];
+    }catch(CEventTimeoutException &e){
+      this->dynamixel_access.exit();
+      throw e;
+    }
+  }
+  else
+  {
+    /* handle exceptions */
+    throw CDynamixelServerException(_HERE_,"The communication device is not properly configured");
+  }
+}
+
+unsigned char CDynamixelServer::receive_status_packet_v2(unsigned char **data,unsigned short int *len)
+{
+  std::list<std::string> events;
+  unsigned char data_int[256];
+  int num=0,read=0,length;
+  unsigned short int crc;
+
+  if(this->comm_dev!=NULL)
+  {
+    try{
+      this->dynamixel_access.enter();
+      events.push_back(this->comm_dev->get_rx_event_id());
+      // read up to the length field
+      do{
+        if((num=this->comm_dev->get_num_data())==0)
+        {
+          this->event_server->wait_all(events,20);
+          num=this->comm_dev->get_num_data();
+        }
+        if((read+num)>7)
+        {
+          this->comm_dev->read(&data_int[read],7-read);
+          read=7;
+        }
+        else
+        {
+          this->comm_dev->read(&data_int[read],num);
+          read+=num;
+        }
+      }while(read<7);
+      length=data_int[5]+data_int[6]*256+7;
+      // read the remaining of the packet
+      while(read<length)
+      {
+        if((num=this->comm_dev->get_num_data())==0)
+        {
+          this->event_server->wait_all(events,20);
+          num=this->comm_dev->get_num_data();
+        }
+        if((read+num)>length)
+        {
+          this->comm_dev->read(&data_int[read],length-read);
+          read=length;
+        }
+        else
+        {
+          this->comm_dev->read(&data_int[read],num);
+          read+=num;
+        }
+      }
+      // check the checksum
+      crc=this->compute_checksum_v2(data_int,length-2);
+      if((crc%256)!=data_int[length-2] || (crc/256)!=data_int[length-1])
+      {
+        this->dynamixel_access.exit();
+        /* handle exceptions */
+        throw CDynamixelServerException(_HERE_,"Invalid Checksum");
+      }
+      // return the error
+      if(length>11)
+      {
+        *data=new unsigned char[length-11];
+        memcpy(*data,&data_int[9],length-11);
+        *len=length-11;
+      }
+      else
+      {
+        *data=NULL;
+        *len=0;  
+      }
+      this->dynamixel_access.exit();
+      return data_int[8];
+    }catch(CEventTimeoutException &e){
+      this->dynamixel_access.exit();
+      throw e;
+    }
+  }
+  else
+  {
+    /* handle exceptions */
+    throw CDynamixelServerException(_HERE_,"The communication device is not properly configured");
+  }
+}
+
+unsigned char CDynamixelServer::compute_checksum_v1(unsigned char *packet,int len)
 {
   int i=0;
   short int checksum=0;
@@ -73,6 +381,111 @@ unsigned char CDynamixelServer::compute_checksum(unsigned char *packet,int len)
   return checksum;
 }
 
+unsigned short int CDynamixelServer::compute_checksum_v2(unsigned char *packet,int len)
+{
+  unsigned short int i,j,crc_accum=0;
+
+  if(packet==NULL)
+  {
+    /* handle exceptions */
+    throw CDynamixelServerException(_HERE_,"Invalid packet structure");
+  }
+  else
+  {
+    if(len<=0)
+    {
+      /* handle exceptions */
+      throw CDynamixelServerException(_HERE_,"Invalid packet length");
+    }
+    else
+    {
+      for(j=0;j<len;j++)
+      {
+        i=((unsigned short)(crc_accum >> 8)^packet[j])&0xFF;
+        crc_accum=(crc_accum<<8)^crc_table[i];
+      }
+    }
+  }
+
+  return crc_accum;
+}
+
+void CDynamixelServer::byte_stuffing(unsigned char *packet_in,int len_in,unsigned char *packet_out,int *len_out)
+{
+  int i,num_bytes=0,stuffed_bytes=0;;
+
+  for(i=0;i<8;i++)
+    packet_out[i]=packet_in[i];
+  for(;i<len_in;i++)
+  {
+    packet_out[i+stuffed_bytes]=packet_in[i];
+    if(num_bytes==0 && packet_in[i]==0xFF)
+      num_bytes++;
+    else if(num_bytes==1 && packet_in[i]==0xFF)
+      num_bytes++;
+    else if(num_bytes==2 && packet_in[i]==0xFD)
+    {
+      stuffed_bytes++;
+      packet_out[i+stuffed_bytes]=0xFD;
+      num_bytes=0;
+    }
+    else 
+      num_bytes=0;
+  }
+  *len_out=len_in+stuffed_bytes;
+}
+
+void CDynamixelServer::byte_destuffing(unsigned char *packet_in,int len_in,unsigned char *packet_out,int *len_out)
+{
+  int i,num_bytes=0,stuffed_bytes=0;
+
+  for(i=0;i<9;i++)
+    packet_out[i]=packet_in[i];
+  for(;i<len_in;i++)
+  {
+    packet_out[i-stuffed_bytes]=packet_in[i];
+    if(num_bytes==0 && packet_in[i]==0xFF)
+      num_bytes++;
+    else if(num_bytes==1 && packet_in[i]==0xFF)
+      num_bytes++;
+    else if(num_bytes==2 && packet_in[i]==0xFD)
+    {
+      stuffed_bytes++;
+      i++;
+      num_bytes=0;
+    }
+    else 
+      num_bytes=0;
+  }
+  *len_out=len_in-stuffed_bytes;
+}
+
+void CDynamixelServer::handle_error(unsigned char error)
+{
+  std::string error_msg;
+
+  if(error!=0x00)
+  {
+    /* handle exceptions */
+    if(error&0x01)
+      error_msg+="\nThe supply voltage is out of range";
+    if(error&0x02)
+      error_msg+="\nThe goal position is out of range";
+    if(error&0x04)
+      error_msg+="\nThe internal temperature is too high";
+    if(error&0x08)
+      error_msg+="\nThe provided parameter is out of range";
+    if(error&0x10)
+      error_msg+="\nThe packet sent to the dynamixel device had an invalid checksum";
+    if(error&0x20)
+      error_msg+="\nOverload";
+    if(error&0x40)
+      error_msg+="\nInvalid instruction";
+    std::cout << error_msg << std::endl;
+    throw CDynamixelAlarmException(_HERE_,error_msg,0xFE,error);
+  }
+}
+
 void *CDynamixelServer::scan_thread(void *param)
 {
   CDynamixelServer *dyn_server=(CDynamixelServer *)param;
@@ -82,7 +495,6 @@ void *CDynamixelServer::scan_thread(void *param)
   int freq=0,id=0;
   bool end=false,found=false;
 
-  dyn_server->close();
   dyn_server->state=dyn_scanning;
   while(!end)
   {
@@ -100,22 +512,30 @@ void *CDynamixelServer::scan_thread(void *param)
           if(dyn_server->event_server->event_is_set(dyn_server->stop_scan_event_id))
           {
             dyn_server->event_server->reset_event(dyn_server->stop_scan_event_id);
+            if(dyn_server->scan_version==dyn_version1)
+              dyn_server->devices_v1.clear();
+            else
+              dyn_server->devices_v2.clear();
             dyn_server->close();
             pthread_exit(NULL);
           }
           else
           {
             try{
-              dyn_server->ping(id,200);
+              dyn_server->ping(id,20,dyn_server->scan_version);
             }catch(CEventTimeoutException &e){
               continue;
             }
             dyn_server->dynamixel_access.enter();
             dyn_server->bus_info.baud_rate=frequencies[freq];
             device.id=id;
+            device.version=dyn_server->scan_version;
             device.used=false;
             dyn_server->dynamixel_access.exit();
-            dyn_server->devices.push_back(device);
+            if(dyn_server->scan_version==dyn_version1)
+              dyn_server->devices_v1.push_back(device);
+            else
+              dyn_server->devices_v2.push_back(device);
             found=true;
           }
         }
@@ -125,8 +545,18 @@ void *CDynamixelServer::scan_thread(void *param)
           break;
         }
       }
+      end=true;// nothing found
     }catch(CException &e){
+      dyn_server->dynamixel_access.enter();
+      if(dyn_server->scan_version==dyn_version1)
+        dyn_server->devices_v1.clear();
+      else
+        dyn_server->devices_v2.clear();
+      dyn_server->state=dyn_created;
+      dyn_server->scan_error=e.what();
+      dyn_server->event_server->set_event(dyn_server->scan_error_event_id);
       dyn_server->close();
+      dyn_server->dynamixel_access.exit();
       pthread_exit(NULL);
     }
   }
@@ -275,7 +705,7 @@ void CDynamixelServer::set_bus_id(std::string &bus_id)
   }
 }
 
-void CDynamixelServer::start_scan(void)
+void CDynamixelServer::start_scan(dyn_version_t version)
 {
   if(this->bus_info.bus_id==-1 && this->bus_info.serial.size()==0)
   {
@@ -284,7 +714,12 @@ void CDynamixelServer::start_scan(void)
   }
   else
   {
+    this->scan_version=version;
     this->stop_scan();
+    if(version==dyn_version1)
+      this->devices_v1.clear();
+    else
+      this->devices_v2.clear();
     this->close();
     this->thread_server->start_thread(this->scan_thread_id);
   }
@@ -322,6 +757,16 @@ std::string CDynamixelServer::get_scan_done_event_id(void)
   return this->scan_done_event_id;
 }
 
+std::string CDynamixelServer::get_scan_error_event_id(void)
+{
+  return this->scan_error_event_id;
+}
+
+std::string CDynamixelServer::get_scan_error(void)
+{
+  return this->scan_error;
+}
+
 int CDynamixelServer::get_baudrate(void)
 {
   int baud_rate=0;
@@ -333,31 +778,38 @@ int CDynamixelServer::get_baudrate(void)
   return baud_rate;
 }
 
-int CDynamixelServer::get_num_devices(void)
+int CDynamixelServer::get_num_devices(dyn_version_t version)
 {
   int num=0;
 
   this->dynamixel_access.enter();
-  num=this->devices.size();
+  if(version==dyn_version1)
+    num=this->devices_v1.size();
+  else
+    num=this->devices_v2.size();
   this->dynamixel_access.exit();
 
   return num;
 }
 
-std::vector<int> CDynamixelServer::get_device_ids(void)
+std::vector<int> CDynamixelServer::get_device_ids(dyn_version_t version)
 {
   std::vector<int> ids;
   unsigned int i=0;
 
   this->dynamixel_access.enter();
-  for(i=0;i<this->devices.size();i++)
-    ids.push_back(this->devices[i].id);
+  if(version==dyn_version1)
+    for(i=0;i<this->devices_v1.size();i++)
+      ids.push_back(this->devices_v1[i].id);
+  else
+    for(i=0;i<this->devices_v2.size();i++)
+      ids.push_back(this->devices_v2[i].id);
   this->dynamixel_access.exit();
 
   return ids;
 }
 
-CDynamixel *CDynamixelServer::get_device(int dev_id)
+CDynamixel *CDynamixelServer::get_device(int dev_id,dyn_version_t version)
 {
   std::stringstream device_name;
   CDynamixel *dynamixel=NULL;
@@ -375,16 +827,32 @@ CDynamixel *CDynamixelServer::get_device(int dev_id)
   }
   else
   {
-    for(i=0;i<this->devices.size();i++)
-      if(this->devices[i].id==dev_id)
-      {
-        if(this->devices[i].used)
+    if(version==dyn_version1)
+    {
+      for(i=0;i<this->devices_v1.size();i++)
+        if(this->devices_v1[i].id==dev_id)
         {
-          /* handle exceptions */
-          this->dynamixel_access.exit();
-          throw CDynamixelServerException(_HERE_,"Device has already been assigned.");
+          if(this->devices_v1[i].used)
+          {
+            /* handle exceptions */
+            this->dynamixel_access.exit();
+            throw CDynamixelServerException(_HERE_,"Device has already been assigned.");
+          }
         }
-      }
+    }
+    else
+    {
+      for(i=0;i<this->devices_v2.size();i++)
+        if(this->devices_v2[i].id==dev_id)
+        {
+          if(this->devices_v2[i].used)
+          {
+            /* handle exceptions */
+            this->dynamixel_access.exit();
+            throw CDynamixelServerException(_HERE_,"Device has already been assigned.");
+          }
+        }
+    }
   }
   this->dynamixel_access.exit();
   if(dynamixel==NULL)
@@ -398,34 +866,56 @@ CDynamixel *CDynamixelServer::get_device(int dev_id)
     else
     {
       try{  
-        this->ping(dev_id,500);
-//      }catch(CEventTimeoutException &e){
+        this->ping(dev_id,500,version);
       }catch(...){
         /* handle exceptions */
         throw CDynamixelServerException(_HERE_,"No Dynamixel device found with the specified identifier");
       }
       this->dynamixel_access.enter();
       device_name.str("");
-      device_name << "dynamixel_bus_" << this->bus_info.bus_id << "_dev_" << dev_id;
+      device_name << "dynamixel_bus_" << this->bus_info.bus_id << "_dev_" << dev_id << "_v" << version;
       name=device_name.str();
       dynamixel=new CDynamixel(name);
       dynamixel->usb_dev=this->comm_dev;
       dynamixel->usb_access=&this->dynamixel_access;
       dynamixel->node_address=dev_id;
+      dynamixel->version=version;
       dynamixel->usb_rx_event_id=this->comm_dev->get_rx_event_id();
-      for(i=0;i<devices.size();i++)
+      if(version==dyn_version1)
       {
-        if(this->devices[i].id==dev_id)
+        for(i=0;i<devices_v1.size();i++)
         {
-          this->devices[i].used=true;
-          updated=true;
+          if(this->devices_v1[i].id==dev_id)
+          {
+            this->devices_v1[i].used=true;
+            updated=true;
+          }
+        }
+        if(!updated)
+        {
+          device.id=dev_id;
+          device.version=version;
+          device.used=true;
+          this->devices_v1.push_back(device);
         }
       }
-      if(!updated)
+      else
       {
-        device.id=dev_id;
-        device.used=true;
-        this->devices.push_back(device);
+        for(i=0;i<devices_v2.size();i++)
+        {
+          if(this->devices_v2[i].id==dev_id)
+          {
+            this->devices_v2[i].used=true;
+            updated=true;
+          }
+        }
+        if(!updated)
+        {
+          device.id=dev_id;
+          device.version=version;
+          device.used=true;
+          this->devices_v2.push_back(device);
+        }
       }
       this->dynamixel_access.exit();
     }
@@ -434,26 +924,40 @@ CDynamixel *CDynamixelServer::get_device(int dev_id)
   return dynamixel;
 }
 
-void CDynamixelServer::free_device(int dev_id)
+void CDynamixelServer::free_device(int dev_id,dyn_version_t version)
 {
   unsigned int i=0;
 
-  for(i=0;i<this->devices.size();i++)
+  if(version==dyn_version1)
   {
-    if(this->devices[i].id==dev_id)
+    for(i=0;i<this->devices_v1.size();i++)
     {
-      if(this->devices[i].used)
-        this->devices[i].used=false;
+      if(this->devices_v1[i].id==dev_id)
+      {
+        if(this->devices_v1[i].used)
+          this->devices_v1[i].used=false;
+      }
+    }
+  }
+  else
+  {
+    for(i=0;i<this->devices_v2.size();i++)
+    {
+      if(this->devices_v2[i].id==dev_id)
+      {
+        if(this->devices_v2[i].used)
+          this->devices_v2[i].used=false;
+      }
     }
   }
 }
 
 void CDynamixelServer::set_baudrate(int baudrate)
 {
+  std::vector< std::vector<unsigned char> > data;
+  std::vector<unsigned char> servo_ids;
   TFTDIconfig ftdi_config;
-  unsigned char *packet;
   unsigned int i=0;
-  int length=0;
 
   if(this->comm_dev!=NULL)
   {
@@ -465,34 +969,29 @@ void CDynamixelServer::set_baudrate(int baudrate)
     else
     {
       try{
-        if(this->devices.size()>0)
+        if(this->devices_v1.size()>0)
         {
-          length=8+2*devices.size();
-          packet=new unsigned char[length];
-          packet[0]=0xFF;
-          packet[1]=0xFF;
-          packet[2]=0XFE;
-          packet[3]=length-4;
-          packet[4]=0x83;
-          packet[5]=0x04;
-          packet[6]=0x01;
-          for(i=0;i<this->devices.size();i++)
+          servo_ids.clear();
+          data.resize(this->devices_v1.size());
+          for(i=0;i<this->devices_v1.size();i++)
           {
-            packet[7+i*2]=devices[i].id;
-            packet[7+i*2+1]=((2000000/baudrate)-1);
+            servo_ids.push_back(devices_v1[i].id);
+            data[i].clear();
+            data[i].push_back(((2000000/baudrate)-1));
           }
-          packet[length-1]=0x00;
-          packet[length-1]=this->compute_checksum(packet,length);
-          // send the data
-          this->dynamixel_access.enter();
-          if(this->comm_dev->write(packet,length)!=length)
+          this->write_sync(servo_ids,0x04,data,dyn_version1);
+        }
+        if(this->devices_v2.size()>0)
+        {
+          servo_ids.clear();
+          data.resize(this->devices_v2.size());
+          for(i=0;i<this->devices_v2.size();i++)
           {
-            delete[] packet;
-            this->dynamixel_access.exit();
-            throw CDynamixelServerException(_HERE_,"Unexpected error while writing to the communication device");
+            servo_ids.push_back(devices_v2[i].id);
+            data[i].clear();
+            data[i].push_back(((2000000/baudrate)-1));
           }
-          delete[] packet;
-          this->dynamixel_access.exit();
+          this->write_sync(servo_ids,0x04,data,dyn_version2);
         }
         sleep(1);
         /* reconfigure the communciations device */
@@ -518,79 +1017,42 @@ void CDynamixelServer::set_baudrate(int baudrate)
   }
 }
 
-void CDynamixelServer::action(void)
+void CDynamixelServer::action(dyn_version_t version)
 {
-  unsigned char packet[6]={0xFF,0xFF,0xFE,0x02,0x05,0x00};
-
-  if(this->comm_dev!=NULL)
-  {
-    packet[5]=0xFA;
- 
-    this->dynamixel_access.enter();
-    if(this->comm_dev->write(packet,6)!=6)
-    {
-      // handle exceptions
-      this->dynamixel_access.exit();
-      throw CDynamixelServerException(_HERE_,"Unexpected error while writing to the communication device");
-    }
-    this->dynamixel_access.exit();
-  }
+  if(version==dyn_version1)
+    this->send_instruction_packet_v1(dyn_action,NULL,0);
   else
-  {
-    /* handle exceptions */
-    throw CDynamixelServerException(_HERE_,"The communication device is not ready to send information");
-  }
+    this->send_instruction_packet_v2(dyn_action,NULL,0);
 }
 
-void CDynamixelServer::ping(int dev_id,int time)
+void CDynamixelServer::ping(int dev_id,int time,dyn_version_t version,unsigned short *model,unsigned char *fw_ver)
 {
-  unsigned char packet[6]={0xFF,0xFF,0x00,0x02,0x01,0x00};
-  std::list<std::string> events;
-  unsigned char data[6];
-  int num=0,read=0;
+  unsigned char *data,length_v1;
+  unsigned short length_v2;
 
-  if(this->comm_dev!=NULL)
+  if(version==dyn_version1)
   {
-    this->dynamixel_access.enter();
-    packet[2]=dev_id;
-    packet[5]=(~(dev_id+3))%256;
-    events.push_back(this->comm_dev->get_rx_event_id());
-
-    if(this->comm_dev->write(packet,6)!=6)
-    {
-      /* handle exceptions */
-      this->dynamixel_access.exit();
-      throw CDynamixelServerException(_HERE_,"Unexpected error while writing to the communication device");
-    }
-    else
-    {
-      try{
-        do{
-          this->event_server->wait_all(events,time);
-          num=this->comm_dev->read(&data[read],6-read);
-          read+=num;
-        }while(read<6);
-      }catch(CEventTimeoutException &e){
-        this->dynamixel_access.exit();
-        throw e;
-      }
-    }
-    this->dynamixel_access.exit();
+    this->send_instruction_packet_v1(dyn_ping,NULL,0,dev_id);
+    this->receive_status_packet_v1(&data,&length_v1);
+    if(data!=NULL)
+      delete[] data;
   }
   else
   {
-    /* handle exceptions */
-    throw CDynamixelServerException(_HERE_,"The communication device is not ready to send information");
+    this->send_instruction_packet_v2(dyn_ping,NULL,0,dev_id);
+    this->receive_status_packet_v2(&data,&length_v2);
+    if(model!=NULL)
+      *model=data[0]+data[1]*256;
+    if(fw_ver!=NULL)
+      *fw_ver=data[2];
+    if(data!=NULL)
+      delete[] data;
   }
 } 
 
 void CDynamixelServer::close(void)
 {
   this->dynamixel_access.enter();
-  if(this->devices.size()>0)
-  {
-    this->devices.clear();
-  }
   if(this->comm_dev!=NULL)
   {
     this->comm_dev->close();
@@ -602,59 +1064,213 @@ void CDynamixelServer::close(void)
   this->dynamixel_access.exit();
 }
 
-void CDynamixelServer::write_sync(std::vector<unsigned char>& servo_ids,unsigned char start_addr, std::vector< std::vector<unsigned char> >& data)
+void CDynamixelServer::write_sync(std::vector<unsigned char>& servo_ids,unsigned short int start_addr, std::vector< std::vector<unsigned char> >& data,dyn_version_t version)
 {
-  unsigned char *packet;
+  unsigned char *data_int;
   unsigned int i,j=0;
-  int  length=0;
+  int length=0;
 
-  if(this->comm_dev!=NULL)
+  if(servo_ids.size()==0)
   {
-    try{
-      if(servo_ids.size()>0)
-      {
-	length=8+(data[0].size()+1)*servo_ids.size();
-	packet=new unsigned char[length];
-	packet[0]=0xFF;
-	packet[1]=0xFF;
-	packet[2]=0XFE;
-	packet[3]=length-4;
-	packet[4]=0x83;
-	packet[5]=start_addr;
-	packet[6]=data[0].size();
-
-	for(i=0;i<servo_ids.size();i++)
-	{
-	  packet[7+(data[i].size()+1)*i]= servo_ids[i];
-
-	  for(j=0;j<data[i].size();j++)
-	    packet[7+(data[i].size()+1)*i+1+j]=data[i][j];
-	}
-	packet[length-1]=0x00;
-	packet[length-1]=this->compute_checksum(packet,length); 
-	this->dynamixel_access.enter();
-	if(this->comm_dev->write(packet,length)!=length)
-	{
-	  delete[] packet;
-	  this->dynamixel_access.exit();
-	  throw CDynamixelServerException(_HERE_,"Unexpected error while writing to the communication device");
-	}
-	delete[] packet;
-	this->dynamixel_access.exit();
-      }
-    }catch(CException &e){
-      /* handle exceptions */
-      throw;
+    /* handle exceptions */
+    throw CDynamixelServerException(_HERE_,"No servos specified");
+  }
+  if(servo_ids.size()>data.size())
+  {
+    /* handle exception */
+    throw CDynamixelServerException(_HERE_,"Missing data for some servos");
+  }
+  if(servo_ids.size()<data.size())
+  {
+    /* handle exception */
+    throw CDynamixelServerException(_HERE_,"Too much data blocks or some missing servos");
+  }
+  if(version==dyn_version1)
+  {
+    length=2+(data[0].size()+1)*servo_ids.size();
+    data_int=new unsigned char[length];
+    data_int[0]=(unsigned char)start_addr;
+    data_int[1]=data[0].size();
+    for(i=0;i<servo_ids.size();i++)
+    {
+      data_int[2+(data[i].size()+1)*i]= servo_ids[i];
+      for(j=0;j<data[i].size();j++)
+        data_int[2+(data[i].size()+1)*i+1+j]=data[i][j];
     }
-  }else
+    this->send_instruction_packet_v1(dyn_sync_write,data_int,length);
+  }
+  else
   {
-    /* handle exceptions */
-    throw CDynamixelServerException(_HERE_,"The communication device is not ready to send information");
+    length=4+(data[0].size()+1)*servo_ids.size();
+    data_int=new unsigned char[length];
+    data_int[0]=start_addr%256;
+    data_int[1]=start_addr/256;
+    data_int[2]=data[0].size()%256;
+    data_int[3]=data[0].size()/256;
+    for(i=0;i<servo_ids.size();i++)
+    {
+      data_int[4+(data[i].size()+1)*i]= servo_ids[i];
+      for(j=0;j<data[i].size();j++)
+        data_int[4+(data[i].size()+1)*i+1+j]=data[i][j];
+    }
+    this->send_instruction_packet_v2(dyn_sync_write,data_int,length);
   }
 }
 
+void CDynamixelServer::read_sync(std::vector<unsigned char>& servo_ids,unsigned short int start_addr,unsigned short int length, std::vector< std::vector<unsigned char> >& data,dyn_version_t version)
+{
+  unsigned char *data_int,*data_out,error;
+  unsigned short length_v2;
+  unsigned int i,j=0;
+  int length_int=0;
 
+  if(servo_ids.size()==0)
+  {
+    /* handle exceptions */
+    throw CDynamixelServerException(_HERE_,"No servos specified");
+  }
+  if(version==dyn_version1)
+  {
+    /* handle exception */
+    throw CDynamixelServerException(_HERE_,"Operation not supported in version 1");
+  }
+  else
+  {
+    length_int=4+servo_ids.size();
+    data_int=new unsigned char[length_int];
+    data_int[0]=start_addr%256;
+    data_int[1]=start_addr/256;
+    data_int[2]=length%256;
+    data_int[3]=length/256;
+    for(i=0;i<servo_ids.size();i++)
+      data_int[4+i]=servo_ids[i];
+    this->send_instruction_packet_v2(dyn_sync_read,data_int,length_int);
+    /* read all the data from all the servos */
+    data.resize(servo_ids.size());
+    for(i=0;i<servo_ids.size();i++)
+    {
+      error=this->receive_status_packet_v2(&data_out,&length_v2);
+      try{
+        this->handle_error(error);
+        if(data_out!=NULL)
+        {
+          data[i].resize(length_v2);
+          for(j=0;j<length_v2;j++)
+            data[i][j]=data_out[j];
+          delete[] data_out;
+        }
+      }catch(CException &e){
+        if(data_out!=NULL)
+          delete[] data_out;
+      }
+    }
+  }
+}
 
+void CDynamixelServer::write_bulk(std::vector<unsigned char>& servo_ids,std::vector<unsigned short int> &start_addr, std::vector< std::vector<unsigned char> >& data,dyn_version_t version)
+{
+  unsigned char *data_int;
+  unsigned int i;
+  int length=0,offset=0;
 
+  if(servo_ids.size()==0)
+  {
+    /* handle exceptions */
+    throw CDynamixelServerException(_HERE_,"No servos specified");
+  }
+  if(start_addr.size()!=servo_ids.size())
+  {
+    /* handle exceptions */
+    throw CDynamixelServerException(_HERE_,"Too many or not enough write addresses");
+  }
+  if(data.size()!=servo_ids.size())
+  {
+    /* handle exceptions */
+    throw CDynamixelServerException(_HERE_,"Too many or not enough data blocks");
+  }
+  if(version==dyn_version1)
+  {
+    /* handle exception */
+    throw CDynamixelServerException(_HERE_,"Operation not supported in version 1");
+  }
+  else
+  {
+    length=0;
+    for(i=0;i<servo_ids.size();i++)
+      length+=5+data[i].size();
+    data_int=new unsigned char[length];
+    for(i=0;i<servo_ids.size();i++)
+    {
+      data_int[offset]=servo_ids[i];
+      data_int[offset+1]=start_addr[i]%256;
+      data_int[offset+2]=start_addr[i]/256;
+      data_int[offset+3]=data[i].size()%256;
+      data_int[offset+4]=data[i].size()/256;
+      offset+=5+data[i].size();
+    }
+    this->send_instruction_packet_v2(dyn_sync_read,data_int,length);
+  }
+}
 
+void CDynamixelServer::read_bulk(std::vector<unsigned char>& servo_ids,std::vector<unsigned short int> &start_addr,std::vector<unsigned short int> &length, std::vector< std::vector<unsigned char> >& data,dyn_version_t version)
+{
+  unsigned char *data_int,*data_out,error;
+  unsigned short int length_v2;
+  unsigned int i,j=0;
+  int length_int=0;
+
+  if(servo_ids.size()==0)
+  {
+    /* handle exceptions */
+    throw CDynamixelServerException(_HERE_,"No servos specified");
+  }
+  if(start_addr.size()!=servo_ids.size())
+  {
+    /* handle exceptions */
+    throw CDynamixelServerException(_HERE_,"Too many or not enough read addresses");
+  }
+  if(length.size()!=servo_ids.size())
+  {
+    /* handle exceptions */
+    throw CDynamixelServerException(_HERE_,"Too many or not enough read lengths");
+  }
+  if(version==dyn_version1)
+  {
+    /* handle exception */
+    throw CDynamixelServerException(_HERE_,"Operation not supported in version 1");
+  }
+  else
+  {
+    length_int=5*servo_ids.size();
+    data_int=new unsigned char[length_int];
+    for(i=0;i<servo_ids.size();i++)
+    {
+      data_int[i*5]=servo_ids[i];
+      data_int[i*5+1]=start_addr[i]%256;
+      data_int[i*5+2]=start_addr[i]/256;
+      data_int[i*5+3]=length[i]%256;
+      data_int[i*5+4]=length[i]/256;
+    }
+    this->send_instruction_packet_v2(dyn_sync_read,data_int,length_int);
+    /* read all the data from all the servos */
+    data.resize(servo_ids.size());
+    for(i=0;i<servo_ids.size();i++)
+    {
+      error=this->receive_status_packet_v2(&data_out,&length_v2);
+      try{
+        this->handle_error(error);
+        if(data_out!=NULL)
+        {
+          data[i].resize(length_v2);
+          for(j=0;j<length_v2;j++)
+            data[i][j]=data_out[j];
+          delete[] data_out;
+        }
+      }catch(CException &e){
+        if(data_out!=NULL)
+          delete[] data_out;
+      }
+    }
+  }
+}
 
diff --git a/src/dynamixelserver.h b/src/dynamixelserver.h
index 18d866a6dab2bcfc9e4581150570cab4556c79af..f941278d33ece74ec8aff68edd7e797ddbdabd2d 100644
--- a/src/dynamixelserver.h
+++ b/src/dynamixelserver.h
@@ -52,7 +52,8 @@ typedef struct
 
 typedef struct
 {
-  unsigned char id;
+  unsigned char id; 
+  dyn_version_t version;
   bool used;
 }TDynDevice;
 
@@ -89,6 +90,11 @@ class CDynamixelServer
      *
      */ 
     std::string scan_done_event_id;
+    /**
+     * \brief 
+     *
+     */ 
+    std::string scan_error_event_id;
     /**
      * \brief 
      *
@@ -123,7 +129,42 @@ class CDynamixelServer
      * \brief 
      *
      */ 
-    std::vector<TDynDevice> devices;
+    std::vector<TDynDevice> devices_v1;
+    /**
+     * \brief 
+     *
+     */ 
+    std::vector<TDynDevice> devices_v2;
+    /**
+     * \brief 
+     *
+     */ 
+    std::string scan_error;
+    /**
+     * \brief 
+     *
+     */ 
+    dyn_version_t scan_version;
+    /**
+     * \brief 
+     *
+     */ 
+    void send_instruction_packet_v1(dyn_inst_t inst,unsigned char *data=NULL,unsigned char len=0,unsigned char id=0xFE);
+    /**
+     * \brief 
+     *
+     */ 
+    void send_instruction_packet_v2(dyn_inst_t inst,unsigned char *data=NULL,unsigned short int len=0,unsigned char id=0xFE);
+    /**
+     * \brief 
+     *
+     */ 
+    unsigned char receive_status_packet_v1(unsigned char **data,unsigned char *len);
+    /**
+     * \brief 
+     *
+     */ 
+    unsigned char receive_status_packet_v2(unsigned char **data,unsigned short int *len);
   protected:
     /**
      * \brief 
@@ -149,7 +190,12 @@ class CDynamixelServer
      * \brief 
      *
      */ 
-    unsigned char compute_checksum(unsigned char *packet,int len);
+    static void byte_stuffing(unsigned char *packet_in,int len_in,unsigned char *packet_out,int *len_out);
+    /**
+     * \brief 
+     *
+     */ 
+    static void byte_destuffing(unsigned char *packet_in,int len_in,unsigned char *packet_out,int *len_out);
     /**
      * \brief 
      *
@@ -160,12 +206,27 @@ class CDynamixelServer
      *
      */ 
     void set_bus_id(std::string &bus_id);
+    /**
+     * \brief 
+     *
+     */ 
+    void handle_error(unsigned char error);
   public:
     /**
      * \brief 
      *
      */ 
     static CDynamixelServer *instance(void);
+    /**
+     * \brief 
+     *
+     */ 
+    static unsigned char compute_checksum_v1(unsigned char *packet,int len);
+    /**
+     * \brief 
+     *
+     */ 
+    static unsigned short int compute_checksum_v2(unsigned char *packet,int len);
     /**
      * \brief 
      *
@@ -200,7 +261,7 @@ class CDynamixelServer
      * \brief 
      *
      */ 
-    void start_scan(void);
+    void start_scan(dyn_version_t version=dyn_version1);
     /**
      * \brief 
      *
@@ -216,6 +277,16 @@ class CDynamixelServer
      *
      */ 
     std::string get_scan_done_event_id(void);
+    /**
+     * \brief 
+     *
+     */ 
+    std::string get_scan_error_event_id(void);
+    /**
+     * \brief 
+     *
+     */ 
+    std::string get_scan_error(void);
     /**
      * \brief 
      *
@@ -225,32 +296,32 @@ class CDynamixelServer
      * \brief 
      *
      */ 
-    int get_num_devices(void);
+    int get_num_devices(dyn_version_t version=dyn_version1);
     /**
      * \brief 
      *
      */ 
-    std::vector<int> get_device_ids(void);
+    std::vector<int> get_device_ids(dyn_version_t version=dyn_version1);
     /**
      * \brief 
      *
      */ 
-    CDynamixel *get_device(int dev_id);
+    CDynamixel *get_device(int dev_id,dyn_version_t version=dyn_version1);
     /**
      * \brief 
      *
      */ 
-    void free_device(int dev_id);
+    void free_device(int dev_id,dyn_version_t version=dyn_version1);
     /**
      * \brief
      *
      */
-    void action(void);
+    void action(dyn_version_t version=dyn_version1);
     /**
      * \brief 
      *
      */ 
-    void ping(int dev_id,int time=100);
+    void ping(int dev_id,int time=100,dyn_version_t version=dyn_version1,unsigned short *model=NULL,unsigned char *fw_ver=NULL);
     /**
      * \brief
      *
@@ -260,7 +331,22 @@ class CDynamixelServer
      * \brief
      *
      */    
-    void write_sync(std::vector<unsigned char>& servo_ids,unsigned char start_addr, std::vector< std::vector<unsigned char> >& data);
+    void write_sync(std::vector<unsigned char>& servo_ids,unsigned short int start_addr, std::vector< std::vector<unsigned char> >& data,dyn_version_t version=dyn_version1);
+    /**
+     * \brief
+     *
+     */    
+    void read_sync(std::vector<unsigned char>& servo_ids,unsigned short int start_addr,unsigned short int length, std::vector< std::vector<unsigned char> >& data,dyn_version_t version=dyn_version2);
+    /**
+     * \brief
+     *
+     */    
+    void write_bulk(std::vector<unsigned char>& servo_ids,std::vector<unsigned short int> &start_addr, std::vector< std::vector<unsigned char> >& data,dyn_version_t version=dyn_version2);
+    /**
+     * \brief
+     *
+     */    
+    void read_bulk(std::vector<unsigned char>& servo_ids,std::vector<unsigned short int> &start_addr,std::vector<unsigned short int> &length, std::vector< std::vector<unsigned char> >& data,dyn_version_t version=dyn_version2);
 };
 
 #endif
diff --git a/src/examples/test_dynamixel_server.cpp b/src/examples/test_dynamixel_server.cpp
index 86e69fc9ef4d1a717f7055190a302fe5f4e4bdf9..12e416f7a70903d22e5c1c3cc84a66a7399342d2 100644
--- a/src/examples/test_dynamixel_server.cpp
+++ b/src/examples/test_dynamixel_server.cpp
@@ -6,10 +6,12 @@ int main(int argc, char *argv[])
 {
   CDynamixelServer *dyn_server=CDynamixelServer::instance();
   CEventServer *event_server=CEventServer::instance();
-  int num_buses=0,num_dev=0,baudrate=0,i=0;
+  int num_buses=0,num_dev=0,baudrate=0,i=0,event_id;
   std::list<std::string> events;
   std::vector<float> position;
   std::vector<int> devices;
+  unsigned short int model;
+  unsigned char margin;
   CDynamixel *dyn_motor;
 
   num_buses=dyn_server->get_num_buses();
@@ -17,17 +19,33 @@ int main(int argc, char *argv[])
   if(num_buses>0)
   {
     events.push_back(dyn_server->get_scan_done_event_id());
+    events.push_back(dyn_server->get_scan_error_event_id());
     dyn_server->config_bus(0,1000000);
     dyn_server->start_scan();
-    event_server->wait_first(events);
-    num_dev=dyn_server->get_num_devices();
-    std::cout << "Num. devices: " << num_dev << std::endl;
-    baudrate=dyn_server->get_baudrate();
-    std::cout << "Baudrate: " << baudrate << " bps" << std::endl;
-    devices=dyn_server->get_device_ids();
-    for(i=0;i<num_dev;i++)
-      std::cout << "Device " << i << ": id -> " << devices[i] << std::endl;
-    dyn_motor=dyn_server->get_device(devices[0]);
+    event_id=event_server->wait_first(events);
+    if(event_id==0)
+    {
+      num_dev=dyn_server->get_num_devices();
+      std::cout << "Num. devices: " << num_dev << std::endl;
+      baudrate=dyn_server->get_baudrate();
+      std::cout << "Baudrate: " << baudrate << " bps" << std::endl;
+      devices=dyn_server->get_device_ids();
+      for(i=0;i<num_dev;i++)
+      {
+        dyn_motor=dyn_server->get_device(devices[i]);
+        dyn_motor->write_byte_register(0x1A,0x10);
+        dyn_motor->read_word_register(0x00,&model);
+        dyn_motor->read_byte_register(0x1A,&margin);
+        dyn_motor->write_word_register(0x1E,0x03FF);
+        sleep(2);
+        dyn_motor->write_word_register(0x1E,0x000);
+        sleep(2);
+        std::cout << "Device " << std::dec << i << ": id -> " << devices[i] << " model: " << std::hex << model << " margin: " << (int)margin << std::endl;
+        dyn_server->free_device(devices[i]);
+      }
+    }
+    else
+      std::cout << "Error while scanning the bus: " << dyn_server->get_scan_error() << std::endl;
     try{
       dyn_server->config_bus(0,1000000);
       dyn_server->start_scan();
@@ -36,12 +54,32 @@ int main(int argc, char *argv[])
       dyn_server->stop_scan();
       std::cout << "Scanning canceled !!!" << std::endl;
     }
-    num_dev=dyn_server->get_num_devices();
-    std::cout << "Num. devices: " << num_dev << std::endl;
-    baudrate=dyn_server->get_baudrate();
-    std::cout << "Baudrate: " << baudrate << " bps" << std::endl;
-    devices=dyn_server->get_device_ids();
-    for(i=0;i<num_dev;i++)
-      std::cout << "Device " << i << ": id -> " << devices[i] << std::endl;
+    /* scan for version 2 devices */
+    dyn_server->config_bus(0,1000000);
+    dyn_server->start_scan(dyn_version2);
+    event_id=event_server->wait_first(events);
+    if(event_id==0)
+    {
+      num_dev=dyn_server->get_num_devices(dyn_version2);
+      std::cout << "Num. devices: " << num_dev << std::endl;
+      baudrate=dyn_server->get_baudrate();
+      std::cout << "Baudrate: " << baudrate << " bps" << std::endl;
+      devices=dyn_server->get_device_ids(dyn_version2);
+      for(i=0;i<num_dev;i++)
+      {
+        dyn_motor=dyn_server->get_device(devices[i],dyn_version2);
+        dyn_motor->write_byte_register(0x1A,0x10);
+        dyn_motor->read_word_register(0x00,&model);
+        dyn_motor->read_byte_register(0x1A,&margin);
+        dyn_motor->write_word_register(0x1E,0x03FF);
+        sleep(2);
+        dyn_motor->write_word_register(0x1E,0x000);
+        sleep(2);
+        std::cout << "Device " << std::dec << i << ": id -> " << devices[i] << " model: " << std::hex << model << " margin: " << (int)margin << std::endl;
+        dyn_server->free_device(devices[i],dyn_version2);
+      }
+    }
+    else
+      std::cout << "Error while scanning the bus: " << dyn_server->get_scan_error() << std::endl;
   }
 }