diff --git a/dynamixel_base/include/dynamixel.h b/dynamixel_base/include/dynamixel.h
index 29b35c00bcd38f3de34e17a61442c7e40297be3e..2b06e605e40e14a2ec8821a79cb50d0acd84f076 100755
--- a/dynamixel_base/include/dynamixel.h
+++ b/dynamixel_base/include/dynamixel.h
@@ -23,7 +23,7 @@ void dyn_copy_packet(unsigned char *source, unsigned char *destination);
  * \brief
  *
  */
-inline unsigned char dyn_get_id(unsigned char *packet)
+static inline unsigned char dyn_get_id(unsigned char *packet)
 {
   return packet[DYN_ID_OFF];
 }
@@ -31,7 +31,7 @@ inline unsigned char dyn_get_id(unsigned char *packet)
  * \brief
  *
  */
-inline unsigned char dyn_get_length(unsigned char *packet)
+static inline unsigned char dyn_get_length(unsigned char *packet)
 {
   return packet[DYN_LENGTH_OFF];
 }
@@ -39,7 +39,7 @@ inline unsigned char dyn_get_length(unsigned char *packet)
  * \brief
  *
  */
-inline TDynInstruction dyn_get_instruction(unsigned char *packet)
+static inline TDynInstruction dyn_get_instruction(unsigned char *packet)
 {
   return (TDynInstruction)packet[DYN_INST_OFF];
 }
@@ -81,7 +81,7 @@ void dyn_init_read_packet(unsigned char *packet,unsigned char id,unsigned char a
  * \brief
  *
  */
-inline unsigned char dyn_get_read_length(unsigned char *packet)
+static inline unsigned char dyn_get_read_length(unsigned char *packet)
 {
   return packet[DYN_DATA_OFF+1];
 }
@@ -89,7 +89,7 @@ inline unsigned char dyn_get_read_length(unsigned char *packet)
  * \brief
  *
  */
-inline unsigned char dyn_get_read_address(unsigned char *packet)
+static inline unsigned char dyn_get_read_address(unsigned char *packet)
 {
   return packet[DYN_DATA_OFF];
 }
@@ -103,7 +103,7 @@ void dyn_init_write_packet(unsigned char *packet,unsigned char id,unsigned char
  * \brief
  *
  */
-inline unsigned char dyn_get_write_address(unsigned char *packet)
+static inline unsigned char dyn_get_write_address(unsigned char *packet)
 {
   return packet[DYN_DATA_OFF];
 }
@@ -111,7 +111,7 @@ inline unsigned char dyn_get_write_address(unsigned char *packet)
  * \brief
  *
  */
-inline unsigned char dyn_get_write_length(unsigned char *packet)
+static inline unsigned char dyn_get_write_length(unsigned char *packet)
 {
   return packet[DYN_LENGTH_OFF]-3;
 }
@@ -130,7 +130,7 @@ void dyn_init_reg_write_packet(unsigned char *packet,unsigned char id,unsigned c
  * \brief
  *
  */
-inline unsigned char dyn_get_reg_write_address(unsigned char *packet)
+static inline unsigned char dyn_get_reg_write_address(unsigned char *packet)
 {
   return packet[DYN_DATA_OFF];
 }
@@ -138,7 +138,7 @@ inline unsigned char dyn_get_reg_write_address(unsigned char *packet)
  * \brief
  *
  */
-inline unsigned char dyn_get_reg_write_length(unsigned char *packet)
+static inline unsigned char dyn_get_reg_write_length(unsigned char *packet)
 {
   return packet[DYN_LENGTH_OFF]-3;
 }
@@ -208,7 +208,7 @@ void dyn_init_status_packet(unsigned char *packet,unsigned char id,TDynError err
  * \brief
  *
  */
-inline TDynError dyn_get_status_error(unsigned char *packet)
+static inline TDynError dyn_get_status_error(unsigned char *packet)
 {
   return (TDynError)packet[DYN_ERROR_OFF];
 }
@@ -222,7 +222,7 @@ unsigned char dyn_get_read_status_data(unsigned char *packet,unsigned char *data
  * \brief
  *
  */
-inline unsigned char dyn_get_read_status_id(unsigned char *packet)
+static inline unsigned char dyn_get_read_status_id(unsigned char *packet)
 {
   return packet[DYN_ID_OFF];
 }
diff --git a/dynamixel_base/include/dynamixel2.h b/dynamixel_base/include/dynamixel2.h
index f4303061ff52d4fde5b34c664ebad18f47cadd41..8b6b3d440aecb4321f5a5d6beedc4a15841431f8 100644
--- a/dynamixel_base/include/dynamixel2.h
+++ b/dynamixel_base/include/dynamixel2.h
@@ -24,7 +24,7 @@ void dyn2_copy_packet(unsigned char *source, unsigned char *destination);
  * \brief
  * 
  */
-inline unsigned char dyn2_get_id(unsigned char *packet)
+static inline unsigned char dyn2_get_id(unsigned char *packet)
 {
   return packet[DYN2_ID_OFF];
 }
@@ -32,7 +32,7 @@ inline unsigned char dyn2_get_id(unsigned char *packet)
  * \brief
  * 
  */
-inline unsigned short int dyn2_get_length(unsigned char *packet)
+static inline unsigned short int dyn2_get_length(unsigned char *packet)
 {
   return (packet[DYN2_LENGTH_OFF]+packet[DYN2_LENGTH_OFF+1]*256);
 }
@@ -40,7 +40,7 @@ inline unsigned short int dyn2_get_length(unsigned char *packet)
  * \brief
  * 
  */
-inline TDynInstruction dyn2_get_instruction(unsigned char *packet)
+static inline TDynInstruction dyn2_get_instruction(unsigned char *packet)
 {
   return (TDynInstruction)packet[DYN2_INST_OFF];
 }
@@ -82,7 +82,7 @@ void dyn2_init_read_packet(unsigned char *packet,unsigned char id,unsigned short
  * \brief
  * 
  */
-inline unsigned short int dyn2_get_read_length(unsigned char *packet)
+static inline unsigned short int dyn2_get_read_length(unsigned char *packet)
 {
   return (packet[DYN2_DATA_OFF+2]+packet[DYN2_DATA_OFF+3]*256);
 }
@@ -90,7 +90,7 @@ inline unsigned short int dyn2_get_read_length(unsigned char *packet)
  * \brief
  * 
  */
-inline unsigned short int dyn2_get_read_address(unsigned char *packet)
+static inline unsigned short int dyn2_get_read_address(unsigned char *packet)
 {
   return (packet[DYN2_DATA_OFF]+packet[DYN2_DATA_OFF+1]*256);
 }
@@ -104,7 +104,7 @@ void dyn2_init_write_packet(unsigned char *packet,unsigned char id,unsigned shor
  * \brief
  * 
  */
-inline unsigned short int dyn2_get_write_address(unsigned char *packet)
+static inline unsigned short int dyn2_get_write_address(unsigned char *packet)
 {
   return (packet[DYN2_DATA_OFF]+packet[DYN2_DATA_OFF+1]*256);
 }
@@ -112,7 +112,7 @@ inline unsigned short int dyn2_get_write_address(unsigned char *packet)
  * \brief
  * 
  */
-inline unsigned short int dyn2_get_write_length(unsigned char *packet)
+static inline unsigned short int dyn2_get_write_length(unsigned char *packet)
 {
   return (packet[DYN2_LENGTH_OFF]+packet[DYN2_LENGTH_OFF+1]*256)-5;
 }
@@ -131,7 +131,7 @@ void dyn2_init_reg_write_packet(unsigned char *packet,unsigned char id,unsigned
  * \brief
  * 
  */
-inline unsigned short int dyn2_get_reg_write_address(unsigned char *packet)
+static inline unsigned short int dyn2_get_reg_write_address(unsigned char *packet)
 {
   return (packet[DYN2_DATA_OFF]+packet[DYN2_DATA_OFF+1]*256);
 }
@@ -139,7 +139,7 @@ inline unsigned short int dyn2_get_reg_write_address(unsigned char *packet)
  * \brief
  * 
  */
-inline unsigned short int dyn2_get_reg_write_length(unsigned char *packet)
+static inline unsigned short int dyn2_get_reg_write_length(unsigned char *packet)
 {
   return (packet[DYN2_LENGTH_OFF]+packet[DYN2_LENGTH_OFF+1]*256)-5;
 }
@@ -231,7 +231,7 @@ void dyn2_init_status_packet(unsigned char *packet,unsigned char id,TDynError er
  * \brief
  * 
  */
-inline TDynError dyn2_get_status_error(unsigned char *packet)
+static inline TDynError dyn2_get_status_error(unsigned char *packet)
 {
   return (TDynError)packet[DYN2_DATA_OFF];
 }
@@ -245,7 +245,7 @@ unsigned short int dyn2_get_read_status_data(unsigned char *packet,unsigned char
  * \brief
  * 
  */
-inline unsigned char dyn2_get_read_status_id(unsigned char *packet)
+static inline unsigned char dyn2_get_read_status_id(unsigned char *packet)
 {
   return packet[DYN2_ID_OFF];
 }
diff --git a/dynamixel_base/include/dynamixel_master.h b/dynamixel_base/include/dynamixel_master.h
index f1fdf2e6fed4c8daa094bb9f2324ba1191768ff4..3c7f0470418d0303be47617347f68b0ed145fb4c 100644
--- a/dynamixel_base/include/dynamixel_master.h
+++ b/dynamixel_base/include/dynamixel_master.h
@@ -100,7 +100,7 @@ void dyn_master_init(TDynamixelMaster *master,TComm *dev,TDynVersion version);
  * \brief
  *
  */
-inline void dyn_master_set_rx_timeout(TDynamixelMaster *master,unsigned short int timeout_ms)
+static inline void dyn_master_set_rx_timeout(TDynamixelMaster *master,unsigned short int timeout_ms)
 {
   if(master!=0x00000000)
     master->rx_timeout_ms=timeout_ms;
@@ -109,7 +109,7 @@ inline void dyn_master_set_rx_timeout(TDynamixelMaster *master,unsigned short in
  * \brief
  *
  */
-inline void dyn_master_set_return_level(TDynamixelMaster *master,return_level_t level)
+static inline void dyn_master_set_return_level(TDynamixelMaster *master,return_level_t level)
 {
   if(master!=0x00000000)
     master->return_level=level;
@@ -118,7 +118,7 @@ inline void dyn_master_set_return_level(TDynamixelMaster *master,return_level_t
  * \brief
  *
  */
-inline return_level_t dyn_master_get_return_level(TDynamixelMaster *master)
+static inline return_level_t dyn_master_get_return_level(TDynamixelMaster *master)
 {
   if(master!=0x00000000)
     return master->return_level;
diff --git a/dynamixel_base/include/dynamixel_slave.h b/dynamixel_base/include/dynamixel_slave.h
index 067ad7ee7fd164a9c212ccf8502eae5e534ccd31..c680e17aff39e41b2d9005eb3136cff4f7d4e180 100644
--- a/dynamixel_base/include/dynamixel_slave.h
+++ b/dynamixel_base/include/dynamixel_slave.h
@@ -126,7 +126,7 @@ unsigned char dyn_slave_add_device(TDynamixelSlave *slave, TDynamixelSlaveDevice
  * \brief
  *
  */
-inline void dyn_slave_set_baudrate(TDynamixelSlave *slave,unsigned int baudrate)
+static inline void dyn_slave_set_baudrate(TDynamixelSlave *slave,unsigned int baudrate)
 {
   if(slave!=0x00000000)
     slave->set_baudrate(slave->comm_dev,baudrate);
@@ -135,7 +135,7 @@ inline void dyn_slave_set_baudrate(TDynamixelSlave *slave,unsigned int baudrate)
  * \brief
  *
  */
-inline void dyn_slave_set_rx_timeout(TDynamixelSlave *slave,unsigned short int timeout_ms)
+static inline void dyn_slave_set_rx_timeout(TDynamixelSlave *slave,unsigned short int timeout_ms)
 {
   if(slave!=0x00000000)
     slave->rx_timeout_ms=timeout_ms;
@@ -144,7 +144,7 @@ inline void dyn_slave_set_rx_timeout(TDynamixelSlave *slave,unsigned short int t
  * \brief
  *
  */
-inline TDynVersion dyn_slave_get_version(TDynamixelSlave *slave)
+static inline TDynVersion dyn_slave_get_version(TDynamixelSlave *slave)
 {
   if(slave!=0x00000000)
     return slave->version;
@@ -155,7 +155,7 @@ inline TDynVersion dyn_slave_get_version(TDynamixelSlave *slave)
  * \brief
  *
  */
-inline void dyn_slave_start(TDynamixelSlave *slave)
+static inline void dyn_slave_start(TDynamixelSlave *slave)
 {
   scheduler_enable_channel(slave->scheduler,slave->sch_channel);
 }
@@ -163,7 +163,7 @@ inline void dyn_slave_start(TDynamixelSlave *slave)
  * \brief
  *
  */
-inline void dyn_slave_stop(TDynamixelSlave *slave)
+static inline void dyn_slave_stop(TDynamixelSlave *slave)
 {
   scheduler_disable_channel(slave->scheduler,slave->sch_channel);
 }
diff --git a/dynamixel_base/include/dynamixel_slave_device.h b/dynamixel_base/include/dynamixel_slave_device.h
index 34b28e1daf6fef7d317a3b7de74e66767baa7920..aa7617bd3597beff62bb39baa10c2740aa500e8b 100644
--- a/dynamixel_base/include/dynamixel_slave_device.h
+++ b/dynamixel_base/include/dynamixel_slave_device.h
@@ -132,7 +132,7 @@ unsigned char dyn_slave_device_init(TDynamixelSlaveDevice *device,unsigned char
  * \brief
  *
  */
-inline void dyn_slave_device_set_address(TDynamixelSlaveDevice *device,unsigned char address)
+static inline void dyn_slave_device_set_address(TDynamixelSlaveDevice *device,unsigned char address)
 {
   if(device!=0x00000000)
     device->address=address;
@@ -141,7 +141,7 @@ inline void dyn_slave_device_set_address(TDynamixelSlaveDevice *device,unsigned
  * \brief
  *
  */
-inline unsigned char dyn_slave_device_get_address(TDynamixelSlaveDevice *device)
+static inline unsigned char dyn_slave_device_get_address(TDynamixelSlaveDevice *device)
 {
   if(device!=0x00000000)
     return device->address;
@@ -152,7 +152,7 @@ inline unsigned char dyn_slave_device_get_address(TDynamixelSlaveDevice *device)
  * \brief
  *
  */
-inline void dyn_slave_device_set_return_delay(TDynamixelSlaveDevice *device,unsigned char delay)
+static inline void dyn_slave_device_set_return_delay(TDynamixelSlaveDevice *device,unsigned char delay)
 {
   if(device!=0x00000000)
     device->return_delay=delay;
@@ -161,7 +161,7 @@ inline void dyn_slave_device_set_return_delay(TDynamixelSlaveDevice *device,unsi
  * \brief
  *
  */
-inline unsigned char dyn_slave_device_get_return_delay(TDynamixelSlaveDevice *device)
+static inline unsigned char dyn_slave_device_get_return_delay(TDynamixelSlaveDevice *device)
 {
   if(device!=0x00000000)
     return device->return_delay;
@@ -172,7 +172,7 @@ inline unsigned char dyn_slave_device_get_return_delay(TDynamixelSlaveDevice *de
  * \brief
  *
  */
-inline void dyn_slave_device_set_return_level(TDynamixelSlaveDevice *device,return_level_t level)
+static inline void dyn_slave_device_set_return_level(TDynamixelSlaveDevice *device,return_level_t level)
 {
   if(device!=0x00000000)
     device->return_level=level;
@@ -181,7 +181,7 @@ inline void dyn_slave_device_set_return_level(TDynamixelSlaveDevice *device,retu
  * \brief
  *
  */
-inline return_level_t dyn_slave_device_get_return_level(TDynamixelSlaveDevice *device)
+static inline return_level_t dyn_slave_device_get_return_level(TDynamixelSlaveDevice *device)
 {
   if(device!=0x00000000)
     return device->return_level;
@@ -202,7 +202,7 @@ unsigned char dyn_v2_slave_loop(TDynamixelSlaveDevice *device,unsigned char *rx_
  * \brief
  *
  */
-inline TMemory *dyn_slave_device_get_memory(TDynamixelSlaveDevice *device)
+static inline TMemory *dyn_slave_device_get_memory(TDynamixelSlaveDevice *device)
 {
   return &device->memory;
 }
diff --git a/dynamixel_base/include/dynamixel_slave_registers.h b/dynamixel_base/include/dynamixel_slave_registers.h
index 46cef2b79342753136e2514c7ce41c79383306a1..40f60b49385636e2d818fc5562af66efefb639b8 100644
--- a/dynamixel_base/include/dynamixel_slave_registers.h
+++ b/dynamixel_base/include/dynamixel_slave_registers.h
@@ -14,13 +14,15 @@
 #define RETURN_LEVEL                          0
 
 #define dyn_slave_control_eeprom_data(name,section_name,base_address1,base_address2,DEFAULT_DEVICE_MODEL,DEFAULT_FIRMWARE_VERSION,DEFAULT_DEVICE_ID,DEFAULT_BAUDRATE,DEFAULT_RETURN_DELAY,DEFAULT_RETURN_LEVEL) \
-unsigned short int name##_eeprom_data[] __attribute__ ((section (section_name)))={DEFAULT_DEVICE_MODEL&0x00FF,(DEFAULT_DEVICE_ID<<8) + base_address1+DEVICE_MODEL, \
-                                                                                  (DEFAULT_DEVICE_MODEL>>8)&0x00FF,(DEFAULT_DEVICE_ID<<8) + base_address1+DEVICE_MODEL+1, \
-                                                                                  DEFAULT_FIRMWARE_VERSION,(DEFAULT_DEVICE_ID<<8) + base_address1+FIRMWARE_VERSION, \
-                                                                                  DEFAULT_DEVICE_ID,(DEFAULT_DEVICE_ID<<8) + base_address1+DEVICE_ID, \
-                                                                                  DEFAULT_BAUDRATE,(DEFAULT_DEVICE_ID<<8) + base_address1+BAUDRATE, \
-                                                                                  DEFAULT_RETURN_DELAY,(DEFAULT_DEVICE_ID<<8) + base_address1+RETURN_DELAY, \
-                                                                                  DEFAULT_RETURN_LEVEL,(DEFAULT_DEVICE_ID<<8) + base_address2+RETURN_LEVEL};
+unsigned short int name##_eeprom_data[] __attribute__ ((section (section_name))) __attribute__ ((aligned (4)))= {\
+  DEFAULT_DEVICE_MODEL&0x00FF,base_address1+DEVICE_MODEL, \
+  (DEFAULT_DEVICE_MODEL>>8)&0x00FF,base_address1+DEVICE_MODEL+1, \
+  DEFAULT_FIRMWARE_VERSION,base_address1+FIRMWARE_VERSION, \
+  DEFAULT_DEVICE_ID,base_address1+DEVICE_ID, \
+  DEFAULT_BAUDRATE,base_address1+BAUDRATE, \
+  DEFAULT_RETURN_DELAY,base_address1+RETURN_DELAY, \
+  DEFAULT_RETURN_LEVEL,base_address2+RETURN_LEVEL \
+};
 
 
 #endif
diff --git a/dynamixel_base/src/dynamixel_slave_device.c b/dynamixel_base/src/dynamixel_slave_device.c
index 25ae4dfa993643d1b031add57f913495caace089..3d792dc043937e39ce47630f8ed16f8b8c868ee4 100644
--- a/dynamixel_base/src/dynamixel_slave_device.c
+++ b/dynamixel_base/src/dynamixel_slave_device.c
@@ -403,7 +403,7 @@ unsigned char dyn_slave_device_init(TDynamixelSlaveDevice *device,unsigned char
   device->bulk_read_pending=0x00;
 
   /* initialize memory module */
-  mem_init(&device->memory,address);
+  mem_init(&device->memory);
   mem_module_init(&device->mem_module);
   device->mem_module.data=device;
   device->mem_module.write_cmd=(void(*)(void *,unsigned short int, unsigned short int,unsigned char *))dyn_slave_device_write_cmd;
diff --git a/dynamixel_manager/Makefile b/dynamixel_manager/Makefile
index 020c8182f704eec57c52c1efec5a4c7590ff25d3..1eb0622aba6cb3ccd78e5a4df4867c0c583003d3 100755
--- a/dynamixel_manager/Makefile
+++ b/dynamixel_manager/Makefile
@@ -15,8 +15,9 @@ COMM_PATH = ../comm
 UTILS_PATH = ../utils
 DYN_BASE_PATH = ../dynamixel_base
 MEMORY_PATH = ../memory
+SCHEDULER_PATH = ../scheduler
 
-INCLUDE_DIRS = -I./include/ -I./include/modules -I$(COMM_PATH)/include -I$(UTILS_PATH)/include -I$(DYN_BASE_PATH)/include -I$(MEMORY_PATH)/include
+INCLUDE_DIRS = -I./include/ -I./include/modules -I$(COMM_PATH)/include -I$(UTILS_PATH)/include -I$(DYN_BASE_PATH)/include -I$(MEMORY_PATH)/include -I$(SCHEDULER_PATH)/include
 
 MACROS = -DMAX_DYN_MASTER_TX_BUFFER_LEN=256 -DMAX_DYN_MASTER_RX_BUFFER_LEN=256 -DDYN_MANAGER_MAX_NUM_MASTERS=4 -DDYN_MANAGER_MAX_NUM_MODULES=8 -DDYN_MANAGER_MAX_NUM_DEVICES=32 -DDYN_MANAGER_MAX_NUM_SINGLE_OP=16 -DDYN_MANAGER_MAX_NUM_SYNC_OP=4 -DDYN_MANAGER_MAX_NUM_BULK_OP=4 -DMODULE_MAX_NUM_MODELS=32 -DMM_MAX_NUM_MOTION_MODULES=8
 
@@ -35,8 +36,10 @@ DYNAMIXEL_OUT_M3 = ./lib/dynamixel_manager_m3.a
 
 SRC_DIR=./src/
 SRC=$(wildcard $(SRC_DIR)*.c)
-#SRC_DIR_MODULES=./src/modules/
-#SRC+=$(wildcard $(SRC_DIR_MODULES)*.c)
+SRC_DIR_MODULES=./src/modules/
+SRC+=$(wildcard $(SRC_DIR_MODULES)*.c)
+SRC_DIR_SCHEDULER=$(SCHEDULER_PATH)/src
+SRC+=$(wildcard $(SRC_DIR_SCHEDULER)*.c)
 
 DYNAMIXEL_M4_FPU_OBJ_DIR=build/m4_fpu/
 DYNAMIXEL_M4_FPU_OBJS_TMP = $(notdir $(SRC:.c=.o))
diff --git a/dynamixel_manager/include/dyn_manager.h b/dynamixel_manager/include/dyn_manager.h
index 948c040cb0bb4e0ae4dd4083bc276cc1881fd925..2860e0ceb0d8171eac3301e512d87df7c28aca57 100644
--- a/dynamixel_manager/include/dyn_manager.h
+++ b/dynamixel_manager/include/dyn_manager.h
@@ -8,6 +8,7 @@ extern "C" {
 #include "dyn_manager_registers.h"
 #include "dynamixel_master.h"
 #include "memory.h"
+#include "scheduler.h"
 
 #ifndef DYN_MANAGER_MAX_NUM_MASTERS
   #error "Please, specify the maximum number of masters with the DYN_MANAGER_MAX_NUM_MASTERS macro"
@@ -116,24 +117,42 @@ typedef struct{
   unsigned char num_devices;
   OP_HANDLE op_handles[DYN_MANAGER_MAX_NUM_OP];
   unsigned char num_ops;
-  unsigned short int period_us;
-  void (*init_timer)(void);
-  void (*set_period)(unsigned short int period_us);
+  unsigned char period_ms;
+  TScheduler *scheduler;
+  sched_channel_t sch_loop_ch;
+  sched_channel_t sch_scan_ch;
   TMemory *memory;
   TMemModule mem_module;
+  unsigned char running;
+  unsigned int present_devices;
+  volatile unsigned char lock;
 }TDynManager;
 
 // public functions
-unsigned char dyn_manager_init(TDynManager *manager,TMemory *memory,unsigned short int eeprom_base_address,unsigned short int ram_base_address);
-void dyn_manager_set_period(TDynManager *manager,unsigned short int period_us);
-unsigned short int dyn_manager_get_period(TDynManager *manager);
+unsigned char dyn_manager_init(TDynManager *manager,TMemory *memory,TScheduler *scheduler,sched_channel_t loop_ch,sched_channel_t scan_ch,unsigned short int eeprom_base_address,unsigned short int ram_base_address);
+void dyn_manager_set_period(TDynManager *manager,unsigned char period_ms);
+static inline unsigned char dyn_manager_get_period(TDynManager *manager)
+{
+  return manager->period_ms;
+}
+void dyn_manager_start(TDynManager *manager);
+void dyn_manager_stop(TDynManager *manager);
 void dyn_manager_scan(TDynManager *manager);
 void dyn_manager_add_master(TDynManager *manager,TDynamixelMaster *master);
-unsigned char dyn_manager_get_num_masters(TDynManager *manager);
+static inline unsigned char dyn_manager_get_num_masters(TDynManager *manager)
+{
+  return manager->num_masters;
+}
 TDynamixelMaster *dyn_manager_get_device_master(TDynManager *manager,unsigned char device_id);
-unsigned short int dyn_manager_get_device_model(TDynManager *manager,unsigned char device_id);
+static inline unsigned short int dyn_manager_get_device_model(TDynManager *manager,unsigned char device_id)
+{
+  return manager->devices[device_id].model;
+}
 void dyn_manager_add_module(TDynManager *manager,struct TDynModule *module);
-unsigned char dyn_manager_get_num_modules(TDynManager *manager);
+static inline unsigned char dyn_manager_get_num_modules(TDynManager *manager)
+{
+  return manager->num_modules;
+}
 void dyn_manager_delete_op(TDynManager *manager,OP_HANDLE *op);
 void dyn_manager_set_op_period(TDynManager *manager,OP_HANDLE *op,unsigned char period_count);
 unsigned char dyn_manager_get_op_period(TDynManager *manager,OP_HANDLE *op);
diff --git a/dynamixel_manager/include/dyn_manager_registers.h b/dynamixel_manager/include/dyn_manager_registers.h
index c7d360be6c57731f044ba572f5d6af9b17b51455..c7e37603271f9a28d6f40e92dea1048af36cecb6 100644
--- a/dynamixel_manager/include/dyn_manager_registers.h
+++ b/dynamixel_manager/include/dyn_manager_registers.h
@@ -1,18 +1,29 @@
 #ifndef _DYN_MANAGER_REGISTERS_H
 #define _DYN_MANAGER_REGISTERS_H
 
-#define RAM_DYN_MANAGER_LENGTH                2
+#define RAM_DYN_MANAGER_LENGTH                8
 
-#define EEPROM_DYN_MANAGER_LENGTH             2
+#define DYN_MANAGER_NUM_MODULES_OFFSET        0
+#define DYN_MANAGER_NUM_MASTERS_OFFSET        1
+#define DYN_MANAGER_CONTROL_OFFSET            2 //   bit 7  |  bit 6  | bit 5 | bit 4 | bit 3 |    bit 2   | bit 1 | bit 0
+                                                // scanning | running |       |       |       | start scan | stop  | start 
+#define DYN_MANAGER_START                     0x01
+#define DYN_MANAGER_STOP                      0x02
+#define DYN_MANAGER_START_SCAN                0x04
+#define DYN_MANAGER_RUNNING                   0x40
+#define DYN_MANAGER_SCANNING                  0x80
 
-#define DYN_MANAGER_PERIOD                    0
+#define DYN_MANAGER_NUM_DEVICES_OFFSET        3
+#define DYN_MANAGER_PRESENT_DEVICES           4
 
-#define DYN_MANAGER_NUM_MODULES               0
-#define DYN_MANAGER_NUM_MASTERS               1
+#define EEPROM_DYN_MANAGER_LENGTH             1
+
+#define DYN_MANAGER_PERIOD_OFFSET             0
 
 #define dyn_manager_eeprom_data(name,section_name,base_address,DEFAULT_PERIOD) \
-unsigned short int name##_eeprom_data[] __attribute__ ((section (section_name)))={DEFAULT_PERIOD&0x00FF,base_address+DYN_MANAGER_PERIOD, \
-                                                                                  (DEFAULT_PERIOD>>8)&0x00FF,base_address+DYN_MANAGER_PERIOD+1};
+unsigned short int name##_eeprom_data[] __attribute__ ((section (section_name))) __attribute__ ((aligned (4)))={ \
+  DEFAULT_PERIOD&0x00FF,base_address+DYN_MANAGER_PERIOD_OFFSET \
+};
 
 #endif
 
diff --git a/dynamixel_manager/include/dyn_module.h b/dynamixel_manager/include/dyn_module.h
index 77c5ce1e462af9ce4fb367b943413377732c401a..9291e3470a0452da3802b640186d6751b44fe4fa 100644
--- a/dynamixel_manager/include/dyn_module.h
+++ b/dynamixel_manager/include/dyn_module.h
@@ -21,26 +21,47 @@ typedef struct TDynModule{
   unsigned char period_count;
   unsigned char enabled;
   void (*add_device)(void *module_data,unsigned char id,unsigned short int model);
-  void (*set_period)(void *module_data,unsigned short int period_us);
+  void (*set_period)(void *module_data,unsigned short int period_ms);
   void (*setup)(void *module_data);
   void (*pre_process)(void *module_data);
   void (*post_process)(void *module_data);
   void *data;
-  TMemModule *mem_module;
+  TMemory *memory;
+  TMemModule mem_module;
+  unsigned short int ram_base_address;
+  unsigned short int eeprom_base_address;
 }TDynModule;
 
 //public functions
-unsigned char dyn_module_init(TDynModule *module);
-inline void dyn_module_enable(TDynModule *module);
-inline void dyn_module_disable(TDynModule *module);
-inline unsigned char dyn_module_is_enabled(TDynModule *module);
+unsigned char dyn_module_init(TDynModule *module,TMemory *memory,unsigned short int ram_base_address, unsigned short int eeprom_base_address);
+static inline void dyn_module_enable(TDynModule *module)
+{
+  module->enabled=0x01;
+}
+static inline void dyn_module_disable(TDynModule *module)
+{
+  module->enabled=0x00;
+}
+static inline unsigned char dyn_module_is_enabled(TDynModule *module)
+{
+  return module->enabled;
+}
 void dyn_module_add_model(TDynModule *module,unsigned short int model);
-inline unsigned char dyn_module_get_num_models(TDynModule *module);
+static inline unsigned char dyn_module_get_num_models(TDynModule *module)
+{
+  return module->num_models;
+}
 void dyn_module_add_device(TDynModule *module,unsigned char id, unsigned short int model);
-inline unsigned char dyn_module_get_num_assigned_devices(TDynModule *module);
+static inline unsigned char dyn_module_get_num_assigned_devices(TDynModule *module)
+{
+  return module->num_assigned_ids;
+}
 unsigned char dyn_module_device_is_assigned(TDynModule *module,unsigned char id);
 void dyn_module_set_period(TDynModule *module,unsigned char period);
-inline unsigned char dyn_module_get_period(TDynModule *module);
+static inline unsigned char dyn_module_get_period(TDynModule *module)
+{
+  return module->period_count;
+}
 
 #ifdef __cplusplus
   }
diff --git a/dynamixel_manager/include/dyn_module_registers.h b/dynamixel_manager/include/dyn_module_registers.h
index fe27dbb309ebefbe6eb880dd716b8ce44518836e..4e1fc4477f7062f637eaf3f45850ef8670de8266 100644
--- a/dynamixel_manager/include/dyn_module_registers.h
+++ b/dynamixel_manager/include/dyn_module_registers.h
@@ -1,18 +1,19 @@
 #ifndef _DYN_MODULE_REGISTERS_H
 #define _DYN_MODULE_REGISTERS_H
 
-#define RAM_DYN_MODULE_LENGTH                3
+#define RAM_DYN_MODULE_LENGTH                2
 
-#define EEPROM_DYN_MODULE_LENGTH             1
+#define DYN_MODULE_NUM_MODELS_OFFSET         0
+#define DYN_MODULE_NUM_DEVICES_OFFSET        1
 
-#define DYN_MODULE_PERIOD                    0
+#define EEPROM_DYN_MODULE_LENGTH             1
 
-#define DYN_MODULE_CNTRL                     0
-#define DYN_MODULE_NUM_MODELS                1
-#define DYN_MODULE_NUM_DEVICES               2
+#define DYN_MODULE_PERIOD_OFFSET             0
 
 #define dyn_module_eeprom_data(name,section_name,base_address,DEFAULT_PERIOD) \
-unsigned short int name##_eeprom_data[] __attribute__ ((section (section_name)))={DEFAULT_PERIOD,base_address+DYN_MODULE_PERIOD};
+unsigned short int name##_eeprom_data[] __attribute__ ((section (section_name))) __attribute__ ((aligned (4)))={ \
+  DEFAULT_PERIOD,base_address+DYN_MODULE_PERIOD_OFFSET \
+};
 
 #endif
 
diff --git a/dynamixel_manager/include/modules/action.h b/dynamixel_manager/include/modules/action.h
index 506b11d5ab837a58f7d08b45041c49cf0994aeb2..309c50ccca35e54327abf3c241ff714a3874ff73 100755
--- a/dynamixel_manager/include/modules/action.h
+++ b/dynamixel_manager/include/modules/action.h
@@ -7,16 +7,62 @@ extern "C" {
 
 #include "motion_pages.h"
 #include "motion_module.h"
+#include "motion_pages.h"
+#include "memory.h"
+
+typedef enum {ACTION_PRE,ACTION_MAIN,ACTION_POST,ACTION_PAUSE} action_states;
+
+typedef struct{
+  TMotionModule mmodule;
+  TMemory *memory;
+  TMemModule mem_module;
+  unsigned short int ram_base_address;
+  unsigned short int eeprom_base_address;  
+  TPage next_page;
+  TPage current_page;
+  unsigned char current_step_index;
+  unsigned char current_page_index;
+  // angle variables
+  long long int moving_angles[PAGE_MAX_NUM_SERVOS];// fixed point 48|16 format
+  long long int start_angles[PAGE_MAX_NUM_SERVOS];// fixed point 48|16 format
+  // speed variables
+  long long int start_speed[PAGE_MAX_NUM_SERVOS];// fixed point 48|16 format
+  long long int main_speed[PAGE_MAX_NUM_SERVOS];// fixed point 48|16 format
+  // control variables
+  unsigned char end;
+  unsigned char stop;
+  unsigned char zero_speed_finish[PAGE_MAX_NUM_SERVOS];
+  unsigned char next_index;
+  unsigned char running;
+  // time variables (in time units (7.8 ms each time unit))
+  long long int total_time;// fixed point 48|16 format
+  long long int pre_time;// fixed point 48|16 format
+  long long int main_time;// fixed point 48|16 format
+  long long int step_time;// fixed point 48|16 format
+  long long int pause_time;// fixed point 48|16 format
+  long long int current_time;// fixed point 48|16 format
+  long long int section_time;// fixed point 48|16 format
+  long long int period;
+  // angle variables 
+  long long int accel_angles[PAGE_MAX_NUM_SERVOS];// fixed point 48|16 format
+  long long int main_angles[PAGE_MAX_NUM_SERVOS];// fixed point 48|16 format
+  // speed variables (in controller units)
+  long long int current_speed[PAGE_MAX_NUM_SERVOS];// fixed point 48|16 format
+  long long int delta_speed;
+  char num_repetitions;
+  // control variables 
+  action_states state;
+}TActionMModule;
 
 // public functions
-void action_init(void);
-TMotionModule *action_get_module(void);
-unsigned char action_load_page(unsigned char page_id);
-void action_start_page(void);
-void action_stop_page(void);
-unsigned char action_is_running(void);
-unsigned char action_get_current_page(void);
-unsigned char action_get_current_step(void);
+unsigned char action_init(TActionMModule *action,TMemory *memory,unsigned short int ram_base_address);
+TMotionModule *action_get_module(TActionMModule *action);
+unsigned char action_load_page(TActionMModule *action,unsigned char page_id);
+void action_start_page(TActionMModule *action);
+void action_stop_page(TActionMModule *action);
+unsigned char action_is_running(TActionMModule *action);
+unsigned char action_get_current_page(TActionMModule *action);
+unsigned char action_get_current_step(TActionMModule *action);
 
 #ifdef __cplusplus
 }
diff --git a/dynamixel_manager/include/modules/action_mm_registers.h b/dynamixel_manager/include/modules/action_mm_registers.h
new file mode 100644
index 0000000000000000000000000000000000000000..847f0534efaf38bafcf6ac2c3b8e00ee1fec57e9
--- /dev/null
+++ b/dynamixel_manager/include/modules/action_mm_registers.h
@@ -0,0 +1,13 @@
+#ifndef _ACTION_MM_REGISTERS_H
+#define _ACTION_MM_REGISTERS_H
+
+#define RAM_ACTION_MM_LENGTH                 2
+
+#define ACTION_MM_CONTROL_OFFSET             0
+#define ACTION_MM_PAGE_OFFSET                1
+  #define ACTION_MM_START                    0x01
+  #define ACTION_MM_STOP                     0x02
+  #define ACTION_MM_RUNNING                  0x80
+
+#endif
+
diff --git a/dynamixel_manager/include/modules/dyn_servos.h b/dynamixel_manager/include/modules/dyn_servos.h
index 07d4e55521b0279fda66c9fe001c91c7623ce551..f3dc02d85a8e1f20bfe293e8d8e9bfc336db1db7 100755
--- a/dynamixel_manager/include/modules/dyn_servos.h
+++ b/dynamixel_manager/include/modules/dyn_servos.h
@@ -1,125 +1,107 @@
 #ifndef _DYN_SERVOS_H
 #define _DYN_SERVOS_H
 
-// Servo register map
-typedef enum{
-  P_MODEL_NUMBER_L            = 0,
-  P_MODEL_NUMBER_H            = 1,
-  P_VERSION                   = 2,
-  P_ID                        = 3,
-  P_BAUD_RATE                 = 4,
-  P_RETURN_DELAY_TIME         = 5,
-  P_CW_ANGLE_LIMIT_L          = 6,
-  P_CW_ANGLE_LIMIT_H          = 7,
-  P_CCW_ANGLE_LIMIT_L         = 8,
-  P_CCW_ANGLE_LIMIT_H         = 9,
-  P_SYSTEM_DATA2              = 10,
-  P_HIGH_LIMIT_TEMPERATURE    = 11,
-  P_LOW_LIMIT_VOLTAGE         = 12,
-  P_HIGH_LIMIT_VOLTAGE        = 13,
-  P_MAX_TORQUE_L              = 14,
-  P_MAX_TORQUE_H              = 15,
-  P_RETURN_LEVEL              = 16,
-  P_ALARM_LED                 = 17,
-  P_ALARM_SHUTDOWN            = 18,
-  P_OPERATING_MODE            = 19,
-  P_LOW_CALIBRATION_L         = 20,
-  P_LOW_CALIBRATION_H         = 21,
-  P_HIGH_CALIBRATION_L        = 22,
-  P_HIGH_CALIBRATION_H        = 23,
-  P_TORQUE_ENABLE             = 24,
-  P_LED                       = 25,
-  P_CW_COMPLIANCE_MARGIN      = 26,
-  P_CCW_COMPLIANCE_MARGIN     = 27,
-  P_CW_COMPLIANCE_SLOPE       = 28,
-  P_CCW_COMPLIANCE_SLOPE      = 29,
-  P_D_GAIN                    = 26,
-  P_I_GAIN                    = 27,
-  P_P_GAIN                    = 28,
-  P_RESERVED                  = 29,
-  P_GOAL_POSITION_L           = 30,
-  P_GOAL_POSITION_H           = 31,
-  P_MOVING_SPEED_L            = 32,
-  P_MOVING_SPEED_H            = 33,
-  P_TORQUE_LIMIT_L            = 34,
-  P_TORQUE_LIMIT_H            = 35,
-  P_PRESENT_POSITION_L        = 36,
-  P_PRESENT_POSITION_H        = 37,
-  P_PRESENT_SPEED_L           = 38,
-  P_PRESENT_SPEED_H           = 39,
-  P_PRESENT_LOAD_L            = 40,
-  P_PRESENT_LOAD_H            = 41,
-  P_PRESENT_VOLTAGE           = 42,
-  P_PRESENT_TEMPERATURE       = 43,
-  P_REGISTERED_INSTRUCTION    = 44,
-  P_PAUSE_TIME                = 45,
-  P_MOVING                    = 46,
-  P_LOCK                      = 47,
-  P_PUNCH_L                   = 48,
-  P_PUNCH_H                   = 49,
-  P_RESERVED4                 = 50,
-  P_RESERVED5                 = 51,
-  P_POT_L                     = 52,
-  P_POT_H                     = 53,
-  P_PWM_OUT_L                 = 54,
-  P_PWM_OUT_H                 = 55,
-  P_P_ERROR_L                 = 56,
-  P_P_ERROR_H                 = 57,
-  P_I_ERROR_L                 = 58,
-  P_I_ERROR_H                 = 59,
-  P_D_ERROR_L                 = 60,
-  P_D_ERROR_H                 = 61,
-  P_P_ERROR_OUT_L             = 62,
-  P_P_ERROR_OUT_H             = 63,
-  P_I_ERROR_OUT_L             = 64,
-  P_I_ERROR_OUT_H             = 65,
-  P_D_ERROR_OUT_L             = 66,
-  P_D_ERROR_OUT_H             = 67}TDynServo;
+#define NUM_REG 62
 
-typedef enum{
-  XL_MODEL_NUMBER_L            = 0,
-  XL_MODEL_NUMBER_H            = 1,
-  XL_VERSION                   = 2,
-  XL_ID                        = 3,
-  XL_BAUD_RATE                 = 4,
-  XL_RETURN_DELAY_TIME         = 5,
-  XL_CW_ANGLE_LIMIT_L          = 6,
-  XL_CW_ANGLE_LIMIT_H          = 7,
-  XL_CCW_ANGLE_LIMIT_L         = 8,
-  XL_CCW_ANGLE_LIMIT_H         = 9,
-  XL_SYSTEM_DATA2              = 10,
-  XL_CONTROL_MODE              = 11,
-  XL_HIGH_LIMIT_TEMPERATURE    = 12,
-  XL_LOW_LIMIT_VOLTAGE         = 13,
-  XL_HIGH_LIMIT_VOLTAGE        = 14,
-  XL_MAX_TORQUE_L              = 15,
-  XL_MAX_TORQUE_H              = 16,
-  XL_RETURN_LEVEL              = 17,
-  XL_ALARM_SHUTDOWN            = 18,
-  XL_TORQUE_ENABLE             = 24,
-  XL_LED                       = 25,
-  XL_D_GAIN                    = 27,
-  XL_I_GAIN                    = 28,
-  XL_P_GAIN                    = 29,
-  XL_GOAL_POSITION_L           = 30,
-  XL_GOAL_POSITION_H           = 31,
-  XL_MOVING_SPEED_L            = 32,
-  XL_MOVING_SPEED_H            = 33,
-  XL_TORQUE_LIMIT_L            = 35,
-  XL_TORQUE_LIMIT_H            = 36,
-  XL_PRESENT_POSITION_L        = 37,
-  XL_PRESENT_POSITION_H        = 38,
-  XL_PRESENT_SPEED_L           = 39,
-  XL_PRESENT_SPEED_H           = 40,
-  XL_PRESENT_LOAD_L            = 41,
-  XL_PRESENT_LOAD_H            = 42,
-  XL_PRESENT_VOLTAGE           = 45,
-  XL_PRESENT_TEMPERATURE       = 46,
-  XL_REGISTERED_INSTRUCTION    = 47,
-  XL_MOVING                    = 49,
-  XL_HARDWARE_ERROR_STATUS     = 50,
-  XL_PUNCH_L                   = 51,
-  XL_PUNCH_H                   = 51}TXLServo;
+typedef struct{
+  unsigned short int address;
+  unsigned char size;
+  unsigned char eeprom;
+}TDynReg;
 
+extern TDynReg ax_reg[NUM_REG];
+extern TDynReg mx_1_0_reg[NUM_REG];
+extern TDynReg mx_2_0_reg[NUM_REG];
+extern TDynReg xl_reg[NUM_REG];
+
+typedef enum {
+  //                           [Access] [Description]
+  // Info
+  model_number=0,      //   (R)     Model Number
+  model_info,          //   (R)
+  firmware_version,    //   (R)     Version of the Firmware
+  id,                  //   (RW)    ID of Dynamixel
+  baudrate,            //   (RW)    Baud Rate of Dynamixel
+  return_delay_time,   //   (RW)    Return Delay Time 
+  second_id,           //   (RW)
+  protocol,            //   (RW)
+  return_level,        //   (RW)    Status Return Level
+  // Configuration
+  drive_mode,          //   (RW)    Drive mode
+  op_mode,             //   (RW)    Joint or wheel mode
+  homming_offset,      //   (RW)
+  moving_threshold,    //   (RW)
+  min_angle_limit,     //   (RW)    Clockwise Angle Limit
+  max_angle_limit,     //   (RW)    Counterclockwise Angle Limit 
+  temp_limit,          //   (RW)    Internal Temperature Limit
+  min_voltage_limit,   //   (RW)    Lowest Voltage Limit
+  max_voltage_limit,   //   (RW)    Highest Voltage Limit
+  pwm_limit,           //   (RW)    Maximum Torque 
+  max_pwm,             //   (RW)    Maximum Torque 
+  current_limit,       //   (RW)
+  max_current,         //   (RW)
+  velocity_limit,      //   (RW)
+  multi_turn_off,      //   (RW)    Multi turn offset position
+  resolution_div,      //   (RW)    Resolution divider
+  // Status
+  alarm_led,           //   (RW)    LED for Alarm 
+  alarm_shtdwn,        //   (RW)    Shutdown for Alarm 
+  led,                 //   (RW)    LED On/Off 
+  bus_watchdog,        //   (RW)
+  moving,              //   (R)     Means if there is any movement 
+  moving_status,       //   (R)
+  lock,                //   (RW)    Locking EEPROM 
+  reg_inst,            //   (RW)    Means if Instruction is registered 
+  hardware_error,      //   (R)     Means if there is any movement 
+  // control
+  torque_en,           //   (RW)    Torque On/Off 
+  vel_pid_i,           //   (RW)
+  vel_pid_p,           //   (RW)
+  pos_pid_p,           //   (RW)     
+  pos_pid_i,           //   (RW)     
+  pos_pid_d,           //   (RW)     
+  feedfwd_gain_2,      //   (RW)
+  feedfwd_gain_1,      //   (RW)
+  cw_comp_margin,      //   (RW)    CW Compliance Margin
+  ccw_comp_margin,     //   (RW)    CCW Compliance Margin
+  cw_comp_slope,       //   (RW)    CW Compliance Slope
+  ccw_comp_slope,      //   (RW)    CCW Compliance Slope 
+  punch,               //   (RW)    Punch 
+  // Set point
+  goal_pos,            //   (RW)    Goal Position 
+  goal_speed,          //   (RW)    Moving Speed 
+  goal_pwm,            //   (RW)
+  goal_current,        //   (RW)
+  profile_accel,       //   (RW)
+  profile_vel,         //   (RW)
+  // Feedback
+  current_pos,         //   (R)     Current Position 
+  current_speed,       //   (R)     Current Speed 
+  current_load,        //   (R)     Current Load 
+  current_voltage,     //   (R)     Current Voltage 
+  current_temp,        //   (R)     Current Temperature 
+  current_pwm,         //   (R)
+  realtime_tick,       //   (R)     Realtime tick
+  velocity_traj,       //   (R)
+  pos_traj             //   (R)
+} reg_id;
+
+#define NUM_SERVO_MODELS 11
+
+typedef struct{
+  unsigned short int model;
+  unsigned short int encoder_resolution;
+  unsigned char gear_ratio;
+  unsigned short int max_angle;
+  unsigned short int center_angle;
+  unsigned short int max_speed;
+  long long int cw_angle_limit;
+  long long int ccw_angle_limit;
+  TDynReg *registers;
+  unsigned char pid;
+  unsigned char protocol_ver;
+}TServoConfig;
+
+extern TServoConfig servo_data[NUM_SERVO_MODELS];
 
 #endif
diff --git a/dynamixel_manager/include/modules/motion_manager.h b/dynamixel_manager/include/modules/motion_manager.h
index 7ebf98851692aa2f1eae350e0e8c9b33f4cb9db4..59ef8ffd3c0529094abdf8d2fb14ce052d0a4468 100644
--- a/dynamixel_manager/include/modules/motion_manager.h
+++ b/dynamixel_manager/include/modules/motion_manager.h
@@ -6,34 +6,25 @@ extern "C" {
 #endif
 
 #include "dyn_module.h"
+#include "dyn_servos.h"
+#include "motion_manager_registers.h"
 
 #ifndef MM_MAX_NUM_MOTION_MODULES
   #error "Please, specify the maximum number of motion modules with the MM_MAX_NUM_MOTION_MODULES macro"
 #endif
 
-typedef enum {MM_NONE          = -1,
+typedef enum {MM_NONE          = 7,
               MM_ACTION        = 0,
               MM_WALKING       = 1,
               MM_JOINTS        = 2,
               MM_HEAD          = 3} TModules;
 
-typedef struct{
-  unsigned short int model;
-  unsigned short int encoder_resolution;
-  unsigned char gear_ratio;
-  unsigned short int max_angle;
-  unsigned short int center_angle;
-  unsigned short int max_speed;
-  long long int cw_angle_limit;
-  long long int ccw_angle_limit;
-}TServoConfig;
-
 typedef struct{
   unsigned char cw_compliance;
   unsigned char ccw_compliance;
   unsigned short int target_value;
   long long int target_angle;
-  unsigned short int current_value;
+  unsigned int current_value;
   long long int current_angle;
   TModules module;
   unsigned char enabled;
@@ -46,26 +37,48 @@ typedef struct {
   TDynModule dyn_module;
   struct TMotionModule *modules[MM_MAX_NUM_MOTION_MODULES];
   unsigned char num_modules;
-  TServoConfig servo_configs[DYN_MANAGER_MAX_NUM_DEVICES];
+  TServoConfig *servo_configs[DYN_MANAGER_MAX_NUM_DEVICES];
   TServoValues servo_values[DYN_MANAGER_MAX_NUM_DEVICES];
   OP_HANDLE *enable_op;
-  OP_HANDLE *motion_op;
-  OP_HANDLE *feedback_op;
+  OP_HANDLE *motion_op[2];
+  OP_HANDLE *feedback_op[2];
   unsigned char balance_enabled;
   void (*balance)(short int offsets[DYN_MANAGER_MAX_NUM_DEVICES]);
+  TMemory *memory;
+  TMemModule mem_module;
+  unsigned short int ram_base_address;
+  unsigned short int eeprom_base_address;
+  unsigned int present_servos;
 }TMotionManager;  
 
-unsigned char mmanager_init(TMotionManager *mmanager,TMemory *memory);
-TDynModule *mmanager_get_dyn_module(TMotionManager *mmanager);
-void mmanager_enable_balance(TMotionManager *mmanager);
-void mmanager_disable_balance(TMotionManager *mmanager);
-unsigned char mmanager_is_balance_enabled(TMotionManager *mmanager);
+unsigned char mmanager_init(TMotionManager *mmanager,TMemory *memory,unsigned short int ram_base_address,unsigned short int eeprom_base_address);
+static inline TDynModule *mmanager_get_dyn_module(TMotionManager *mmanager)
+{
+  return &mmanager->dyn_module;
+}
+static inline void mmanager_enable_balance(TMotionManager *mmanager)
+{
+  if(mmanager->balance!=0x00000000)
+    mmanager->balance_enabled=0x01;
+}
+static inline void mmanager_disable_balance(TMotionManager *mmanager)
+{
+  mmanager->balance_enabled=0x00;
+}
+static inline unsigned char mmanager_is_balance_enabled(TMotionManager *mmanager)
+{
+  return mmanager->balance_enabled;
+}
 void mmanager_set_module(TMotionManager *mmanager,unsigned char servo_id,TModules module);
 TModules mmanager_get_module(TMotionManager *mmanager,unsigned char servo_id);
 void mmanager_enable_servo(TMotionManager *mmanager,unsigned char servo_id);
 void mmanager_disable_servo(TMotionManager *mmanager,unsigned char servo_id);
 unsigned char mmanager_is_servo_enabled(TMotionManager *mmanager,unsigned char servo_id);
-void mmanager_set_offset(TMotionManager *mmanager,unsigned char servo_id,char offset);
+static inline void mmanager_set_offset(TMotionManager *mmanager,unsigned char servo_id,char offset)
+{
+  if(servo_id<DYN_MANAGER_MAX_NUM_DEVICES)
+    mmanager->servo_values[servo_id].offset=offset;
+}
 void mmanager_add_module(TMotionManager *mmanager,struct TMotionModule *module);
 
 #ifdef __cplusplus
diff --git a/dynamixel_manager/include/modules/motion_manager_registers.h b/dynamixel_manager/include/modules/motion_manager_registers.h
index 02fbc9ed572a7d596bada1c73b517df5bb13815a..1d0bc4b1447149c7d54fc44965d395b2d0effda3 100644
--- a/dynamixel_manager/include/modules/motion_manager_registers.h
+++ b/dynamixel_manager/include/modules/motion_manager_registers.h
@@ -3,14 +3,24 @@
 
 #include "dyn_module_registers.h"
 
-#define RAM_MM_LENGTH                        (RAM_DYN_MODULE_LENGTH + 0)
+#define RAM_MM_LENGTH                        (4+DYN_MANAGER_MAX_NUM_DEVICES/2)
+
+#define MM_PRESENT_SERVOS_OFFSET             0
+#define MM_ENABLE_MODULE_OFFSET              4
+  #define MM_EVEN_SER_EN                     0x80
+  #define MM_EVEN_SER_MOD                    0x70
+  #define MM_ODD_SER_EN                      0x08
+  #define MM_ODD_SER_MOD                     0x07
 
 #define EEPROM_MM_LENGTH                     (DYN_MANAGER_MAX_NUM_DEVICES)
 
-#define MM_SERVO_OFFSET                      0
+#define MM_SERVO_OFFSET_OFFSET               0
 
-#define dyn_mm_eeprom_data(name,section_name,base_address) \
-unsigned short int name##_eeprom_data[] __attribute__ ((section (section_name)))={0,base_address+MM_SERVO_OFFSET};
+#define dyn_mm_eeprom_data(name,section_name,base_address,DEFAULT_PERIOD,...) \
+dyn_module_eeprom_data(name##_module,section_name,base_address,DEFAULT_PERIOD) \
+unsigned short int name##_eeprom_data[] __attribute__ ((section (section_name))) __attribute__ ((aligned (4)))={ \
+  __VA_ARGS__ \
+};
 
 #endif
 
diff --git a/dynamixel_manager/include/modules/motion_module.h b/dynamixel_manager/include/modules/motion_module.h
index 9498d5411c91ed6d61991c24e623ecb7966302ae..af07a7d31d89bd8abd16f83470cb0ffad9d42905 100644
--- a/dynamixel_manager/include/modules/motion_module.h
+++ b/dynamixel_manager/include/modules/motion_module.h
@@ -10,7 +10,7 @@ extern "C" {
 typedef struct TMotionModule{
   TModules id;
   TMotionManager *manager;
-  void (*set_period)(void *module,unsigned short int period_us);
+  void (*set_period)(void *module,unsigned short int period_ms);
   void (*set_module)(void *module,unsigned char servo_id);  
   void (*pre_process)(void *module);
   void (*post_process)(void *module);
diff --git a/dynamixel_manager/src/dyn_manager.c b/dynamixel_manager/src/dyn_manager.c
index 73db6b175604463e9a7c863b62610ea24b11530d..3e70b32b8c366ee66e1ec271ee40da58c3c4ebe9 100644
--- a/dynamixel_manager/src/dyn_manager.c
+++ b/dynamixel_manager/src/dyn_manager.c
@@ -18,20 +18,41 @@ extern unsigned char dyn_master_is_bulk_read_done(TDynamixelMaster *master,unsig
 typedef enum {start_single_ops,wait_single_ops,start_sync_ops,wait_sync_ops,start_bulk_ops,wait_bulk_ops,ops_done} dyn_manager_states_t;
 
 // private functions
+void dyn_manager_lock(TDynManager *manager)
+{
+  while(manager->lock==1);
+  manager->lock=1;
+}
+
+void dyn_manager_unlock(TDynManager *manager)
+{
+  manager->lock=0;
+}
+
+void dyn_manager_start_scan(TDynManager *manager)
+{
+  dyn_manager_stop(manager);
+  manager->memory->data[manager->ram_base_address+DYN_MANAGER_CONTROL_OFFSET]|=DYN_MANAGER_SCANNING;
+  scheduler_enable_channel(manager->scheduler,manager->sch_scan_ch);
+}
+
 void dyn_manager_write_cmd(TDynManager *module,unsigned short int address,unsigned short int length,unsigned char *data)
 {
-  unsigned short int uint16_value;
-  unsigned char *data_ptr;
+  unsigned short int eeprom_offset,ram_offset;
+
+  eeprom_offset=address-module->eeprom_base_address;
+  if(ram_in_window(module->eeprom_base_address+DYN_MANAGER_PERIOD_OFFSET,1,address,length))
+    dyn_manager_set_period(module,data[DYN_MANAGER_PERIOD_OFFSET-eeprom_offset]);
 
-  if(ram_in_window(DYN_MANAGER_PERIOD,2,address,length))
+  ram_offset=address-module->ram_base_address;
+  if(ram_in_range(module->ram_base_address+DYN_MANAGER_CONTROL_OFFSET,address,length))
   {
-    uint16_value=dyn_manager_get_period(module);
-    data_ptr=(unsigned char *)&uint16_value;
-    if(ram_in_range(DYN_MANAGER_PERIOD,address,length))
-      data_ptr[0]=data[DYN_MANAGER_PERIOD-address];
-    if(ram_in_range(DYN_MANAGER_PERIOD+1,address,length))
-      data_ptr[1]=data[DYN_MANAGER_PERIOD+1-address];
-    dyn_manager_set_period(module,uint16_value);
+    if(data[DYN_MANAGER_CONTROL_OFFSET-ram_offset]&DYN_MANAGER_START)
+      dyn_manager_start(module);
+    if(data[DYN_MANAGER_CONTROL_OFFSET-ram_offset]&DYN_MANAGER_STOP)
+      dyn_manager_stop(module);
+    if(data[DYN_MANAGER_CONTROL_OFFSET-ram_offset]&DYN_MANAGER_START_SCAN)
+      dyn_manager_start_scan(module);
   }
 }
 
@@ -62,7 +83,8 @@ TDynManagerOpCommon *dyn_manager_get_op_common(TDynManager *manager,unsigned cha
       default: return 0x00000000;
     } 
   }
-  else return 0x00000000;
+  else 
+    return 0x00000000;
 }
 
 OP_HANDLE *dyn_manager_get_free_op_handle(TDynManager *manager)
@@ -91,7 +113,7 @@ unsigned char dyn_manager_id_present(unsigned char num,unsigned char *ids,unsign
 
 void dyn_manager_delete_op_single_master(TDynManager *manager,unsigned char master_index,OP_HANDLE *op)
 {
-  unsigned char j,k,delete;
+  unsigned char j,k,del;
 
   if(op->op_index[master_index]!=0xFF)
   {
@@ -126,7 +148,7 @@ void dyn_manager_delete_op_single_master(TDynManager *manager,unsigned char mast
                                break;
       case DYN_MANAGER_SYNC: if(op->op_index[master_index]<(DYN_MANAGER_MAX_NUM_SYNC_OP-1))
                              {
-                               for(j=op->op_index[master_index];j<manager->operations[master_index].num_sync_op;j++)
+                               for(j=op->op_index[master_index];j<=manager->operations[master_index].num_sync_op;j++)
                                {
                                  manager->operations[master_index].sync_op[j].common.operation=manager->operations[master_index].sync_op[j+1].common.operation;
                                  manager->operations[master_index].sync_op[j].common.repetitions=manager->operations[master_index].sync_op[j+1].common.repetitions;
@@ -134,12 +156,12 @@ void dyn_manager_delete_op_single_master(TDynManager *manager,unsigned char mast
                                  manager->operations[master_index].sync_op[j].common.op_handle=manager->operations[master_index].sync_op[j+1].common.op_handle;
                                  manager->operations[master_index].sync_op[j].address=manager->operations[master_index].sync_op[j+1].address;
                                  manager->operations[master_index].sync_op[j].length=manager->operations[master_index].sync_op[j+1].length;
-                                 manager->operations[master_index].sync_op[j].num_devices=manager->operations[master_index].sync_op[j+1].num_devices;
                                  for(k=0;k<manager->operations[master_index].sync_op[j].num_devices;k++)
                                  {
                                    manager->operations[master_index].sync_op[j].ids[k]=manager->operations[master_index].sync_op[j+1].ids[k];
                                    manager->operations[master_index].sync_op[j].data[k]=manager->operations[master_index].sync_op[j+1].data[k];
                                  }
+                                 manager->operations[master_index].sync_op[j].num_devices=manager->operations[master_index].sync_op[j+1].num_devices;
                                }
                              }
                              else 
@@ -150,12 +172,12 @@ void dyn_manager_delete_op_single_master(TDynManager *manager,unsigned char mast
                                manager->operations[master_index].sync_op[op->op_index[master_index]].common.op_handle=0x00000000;
                                manager->operations[master_index].sync_op[op->op_index[master_index]].address=0x0000;
                                manager->operations[master_index].sync_op[op->op_index[master_index]].length=0x0000;
-                               manager->operations[master_index].sync_op[op->op_index[master_index]].num_devices=0x00;
                                for(k=0;k<manager->operations[master_index].sync_op[op->op_index[master_index]].num_devices;k++)
                                {
                                  manager->operations[master_index].sync_op[op->op_index[master_index]].ids[k]=0xFF;
                                  manager->operations[master_index].sync_op[op->op_index[master_index]].data[k]=0x00000000;
                                }
+                               manager->operations[master_index].sync_op[op->op_index[master_index]].num_devices=0x00;
                              }
                              manager->operations[master_index].num_sync_op--;
                              break;
@@ -167,7 +189,6 @@ void dyn_manager_delete_op_single_master(TDynManager *manager,unsigned char mast
                                  manager->operations[master_index].bulk_op[j].common.repetitions=manager->operations[master_index].bulk_op[j+1].common.repetitions;
                                  manager->operations[master_index].bulk_op[j].common.period_count=manager->operations[master_index].bulk_op[j+1].common.period_count;
                                  manager->operations[master_index].bulk_op[j].common.op_handle=manager->operations[master_index].bulk_op[j+1].common.op_handle;
-                                 manager->operations[master_index].bulk_op[j].num_devices=manager->operations[master_index].bulk_op[j+1].num_devices;
                                  for(k=0;k<manager->operations[master_index].bulk_op[j].num_devices;k++)
                                  {
                                    manager->operations[master_index].bulk_op[j].address[k]=manager->operations[master_index].bulk_op[j+1].address[k];
@@ -175,6 +196,7 @@ void dyn_manager_delete_op_single_master(TDynManager *manager,unsigned char mast
                                    manager->operations[master_index].bulk_op[j].ids[k]=manager->operations[master_index].bulk_op[j+1].ids[k];
                                    manager->operations[master_index].bulk_op[j].data[k]=manager->operations[master_index].bulk_op[j+1].data[k];
                                  }
+                                 manager->operations[master_index].bulk_op[j].num_devices=manager->operations[master_index].bulk_op[j+1].num_devices;
                                }
                              }
                              else
@@ -183,7 +205,6 @@ void dyn_manager_delete_op_single_master(TDynManager *manager,unsigned char mast
                                manager->operations[master_index].bulk_op[op->op_index[master_index]].common.repetitions=0x01;
                                manager->operations[master_index].bulk_op[op->op_index[master_index]].common.period_count=0x01;
                                manager->operations[master_index].bulk_op[op->op_index[master_index]].common.op_handle=0x00000000;
-                               manager->operations[master_index].bulk_op[op->op_index[master_index]].num_devices=0x00;
                                for(k=0;k<manager->operations[master_index].bulk_op[op->op_index[master_index]].num_devices;k++)
                                {
                                  manager->operations[master_index].bulk_op[op->op_index[master_index]].address[k]=0x0000;
@@ -191,6 +212,7 @@ void dyn_manager_delete_op_single_master(TDynManager *manager,unsigned char mast
                                  manager->operations[master_index].bulk_op[op->op_index[master_index]].ids[k]=0xFF;
                                  manager->operations[master_index].bulk_op[op->op_index[master_index]].data[k]=0x00000000;
                                }
+                               manager->operations[master_index].bulk_op[op->op_index[master_index]].num_devices=0x00;
                              }
                              manager->operations[master_index].num_bulk_op--;
                              break;
@@ -199,11 +221,11 @@ void dyn_manager_delete_op_single_master(TDynManager *manager,unsigned char mast
   else
     op->op_index[master_index]=0xFF;
   // remove handles
-  delete=0x01;
+  del=0x01;
   for(j=0;j<manager->num_masters;j++)
     if(op->op_index[j]!=0xFF)
-      delete=0x00;
-  if(delete==0x01)
+      del=0x00;
+  if(del==0x01)
   {
     op->op_type=no_op;
     manager->num_ops--;
@@ -211,7 +233,7 @@ void dyn_manager_delete_op_single_master(TDynManager *manager,unsigned char mast
 }
 
 // public functions
-unsigned char dyn_manager_init(TDynManager *manager,TMemory *memory,unsigned short int eeprom_base_address,unsigned short int ram_base_address)
+unsigned char dyn_manager_init(TDynManager *manager,TMemory *memory,TScheduler *scheduler,sched_channel_t loop_ch,sched_channel_t scan_ch,unsigned short int ram_base_address,unsigned short int eeprom_base_address)
 {
   unsigned char i,j,k;
 
@@ -281,9 +303,14 @@ unsigned char dyn_manager_init(TDynManager *manager,TMemory *memory,unsigned sho
     manager->op_handles[i].handle_index=i;
   }
   manager->num_ops=0x00;
-  /* initialize timer */
-  if(manager->init_timer!=0x00000000)
-    manager->init_timer();
+  manager->present_devices=0x00000000;
+  manager->lock=0;
+  /* initialize scheduler */
+  scheduler_set_channel(scheduler,loop_ch,(void(*)(void *))dyn_manager_loop,100,manager);
+  scheduler_set_channel_one_shot(scheduler,scan_ch,(void(*)(void *))dyn_manager_scan,100,manager);
+  manager->scheduler=scheduler;
+  manager->sch_loop_ch=loop_ch;
+  manager->sch_scan_ch=scan_ch;
 
   /* initialize memory module */
   mem_module_init(&manager->mem_module);
@@ -298,29 +325,36 @@ unsigned char dyn_manager_init(TDynManager *manager,TMemory *memory,unsigned sho
     return 0x00;
   manager->eeprom_base_address=eeprom_base_address;
   manager->ram_base_address=ram_base_address;
+  manager->memory=memory;
+  manager->running=0x00;
   
   return 0x01;
 }
 
-void dyn_manager_set_period(TDynManager *manager,unsigned short int period_us)
+void dyn_manager_set_period(TDynManager *manager,unsigned char period_ms)
 {
   unsigned char i;
 
-  if(manager->set_period!=0x00000000)
-  {
-    manager->set_period(period_us);
-    for(i=0;i<DYN_MANAGER_MAX_NUM_MODULES;i++)
-      if(manager->modules[i]!=0x00000000 && manager->modules[i]->set_period!=0x00000000)
-         manager->modules[i]->set_period(manager->modules[i]->data,period_us);
-    manager->period_us=period_us;
-    manager->memory->data[DYN_MANAGER_PERIOD]=period_us%256;
-    manager->memory->data[DYN_MANAGER_PERIOD+1]=period_us/256;
-  }
+  scheduler_change_period(manager->scheduler,manager->sch_loop_ch,period_ms);
+  for(i=0;i<DYN_MANAGER_MAX_NUM_MODULES;i++)
+    if(manager->modules[i]!=0x00000000 && manager->modules[i]->set_period!=0x00000000)
+       manager->modules[i]->set_period(manager->modules[i]->data,period_ms*manager->modules[i]->period_count);
+  manager->period_ms=period_ms;
+  manager->memory->data[manager->eeprom_base_address+DYN_MANAGER_PERIOD_OFFSET]=period_ms;
+}
+
+void dyn_manager_start(TDynManager *manager)
+{
+  scheduler_enable_channel(manager->scheduler,manager->sch_loop_ch);
+  manager->running=0x01;
+  manager->memory->data[manager->ram_base_address+DYN_MANAGER_CONTROL_OFFSET]|=DYN_MANAGER_RUNNING;
 }
 
-unsigned short int dyn_manager_get_period(TDynManager *manager)
+void dyn_manager_stop(TDynManager *manager)
 {
-  return manager->period_us;
+  scheduler_disable_channel(manager->scheduler,manager->sch_loop_ch);
+  manager->running=0x00;
+  manager->memory->data[manager->ram_base_address+DYN_MANAGER_CONTROL_OFFSET]&=(~DYN_MANAGER_RUNNING);
 }
 
 void dyn_manager_scan(TDynManager *manager)
@@ -329,6 +363,8 @@ void dyn_manager_scan(TDynManager *manager)
   unsigned char i,j,k,num=0;
   unsigned short int model;
 
+  manager->present_devices=0x00000000;
+  manager->num_devices=0;
   // scan all dynamixel buses
   for(i=0;i<manager->num_masters;i++)
   {
@@ -344,6 +380,7 @@ void dyn_manager_scan(TDynManager *manager)
         manager->devices[servo_ids[j]].model=model;
         manager->devices[servo_ids[j]].master_index=i;
         manager->num_devices++;
+        manager->present_devices|=(0x00000001<<servo_ids[j]);
         // pass the infor to each of the modules
         for(k=0;k<DYN_MANAGER_MAX_NUM_MODULES;k++)
           if(manager->modules[k]!=0x00000000)
@@ -352,10 +389,17 @@ void dyn_manager_scan(TDynManager *manager)
       // else ignore device
     }
   }
+  manager->memory->data[manager->ram_base_address+DYN_MANAGER_NUM_DEVICES_OFFSET]=manager->num_devices;
+  manager->memory->data[manager->ram_base_address+DYN_MANAGER_CONTROL_OFFSET]&=(~DYN_MANAGER_SCANNING);
+  manager->memory->data[manager->ram_base_address+DYN_MANAGER_PRESENT_DEVICES]=manager->present_devices&0x000000FF;
+  manager->memory->data[manager->ram_base_address+DYN_MANAGER_PRESENT_DEVICES+1]=(manager->present_devices>>8)&0x000000FF;
+  manager->memory->data[manager->ram_base_address+DYN_MANAGER_PRESENT_DEVICES+2]=(manager->present_devices>>16)&0x000000FF;
+  manager->memory->data[manager->ram_base_address+DYN_MANAGER_PRESENT_DEVICES+3]=(manager->present_devices>>24)&0x000000FF;
   // configure the operations
   for(i=0;i<manager->num_modules;i++)
     if(manager->modules[i]->setup!=0x00000000)
       manager->modules[i]->setup(manager->modules[i]->data);
+  manager->memory->data[manager->ram_base_address+DYN_MANAGER_CONTROL_OFFSET]&=(~DYN_MANAGER_SCANNING);
 }
 
 void dyn_manager_add_master(TDynManager *manager,TDynamixelMaster *master)
@@ -369,15 +413,10 @@ void dyn_manager_add_master(TDynManager *manager,TDynamixelMaster *master)
   {
     manager->masters[i]=master;
     manager->num_masters++;
-    manager->memory->data[DYN_MANAGER_NUM_MASTERS]++;
+    manager->memory->data[manager->ram_base_address+DYN_MANAGER_NUM_MASTERS_OFFSET]++;
   }
 }
 
-unsigned char dyn_manager_get_num_masters(TDynManager *manager)
-{
-  return manager->num_masters;
-}
-
 TDynamixelMaster *dyn_manager_get_device_master(TDynManager *manager,unsigned char device_id)
 {
   if(dyn_manager_check_id(manager,device_id)!=0xFF)
@@ -386,11 +425,6 @@ TDynamixelMaster *dyn_manager_get_device_master(TDynManager *manager,unsigned ch
     return 0x00000000;
 }
 
-unsigned short int dyn_manager_get_device_model(TDynManager *manager,unsigned char device_id)
-{
-  return manager->devices[device_id].model;
-}
-
 void dyn_manager_add_module(TDynManager *manager,TDynModule *module)
 {
   unsigned char i;
@@ -403,15 +437,11 @@ void dyn_manager_add_module(TDynManager *manager,TDynModule *module)
     manager->modules[i]=module;
     manager->num_modules++;
     module->manager=manager;
-    manager->memory->data[DYN_MANAGER_NUM_MODULES]++;
+    manager->memory->data[manager->ram_base_address+DYN_MANAGER_NUM_MODULES_OFFSET]++;
+    manager->modules[i]->set_period(manager->modules[i]->data,manager->period_ms*manager->modules[i]->period_count);
   }
 }
 
-unsigned char dyn_manager_get_num_modules(TDynManager *manager)
-{
-  return manager->num_modules;
-}
-
 void dyn_manager_delete_op(TDynManager *manager,OP_HANDLE *op)
 {
   unsigned char i;
@@ -488,19 +518,29 @@ OP_HANDLE *dyn_manager_single_op_new(TDynManager *manager,unsigned char mode,uns
   TDynManagerSingleOp *current_op;
   OP_HANDLE *op_handle;
 
+  dyn_manager_lock(manager);
   if((master_index=dyn_manager_check_id(manager,id))==0xFF)
+  {
+    dyn_manager_unlock(manager);
     return 0x00000000;
+  }
   if((op_handle=dyn_manager_get_free_op_handle(manager))==0x00000000)
+  {
+    dyn_manager_unlock(manager);
     return 0x00000000;
+  }
   if(mode==DYN_MANAGER_READ || mode==DYN_MANAGER_WRITE)
-    op_handle->op_type=DYN_MANAGER_SINGLE|mode;
+    op_handle->op_type=(op_type_t)(DYN_MANAGER_SINGLE|mode);
   else
+  {
+    dyn_manager_unlock(manager);
     return 0x00000000;
+  }
   current_op_index=manager->operations[master_index].num_single_op;
   if(current_op_index<DYN_MANAGER_MAX_NUM_SINGLE_OP)
   {
     current_op=&manager->operations[master_index].single_op[current_op_index];
-    current_op->common.operation=DYN_MANAGER_SINGLE|mode;
+    current_op->common.operation=(op_type_t)(DYN_MANAGER_SINGLE|mode);
     current_op->common.op_handle=op_handle;
     current_op->id=id;
     current_op->address=address;
@@ -513,8 +553,11 @@ OP_HANDLE *dyn_manager_single_op_new(TDynManager *manager,unsigned char mode,uns
   else
   {
     op_handle->op_type=no_op;
+    dyn_manager_unlock(manager);
     return 0x00000000;
   }
+  dyn_manager_unlock(manager);
+  
   return op_handle;
 }
 
@@ -522,44 +565,52 @@ void dyn_manager_single_op_change_id(TDynManager *manager,OP_HANDLE *op,unsigned
 {
   unsigned char i;
 
+  dyn_manager_lock(manager);
   for(i=0;i<manager->num_masters;i++)
   {
     if(op->op_index[i]!=0xFF)
       manager->operations[i].single_op[op->op_index[i]].id=id;
   }
+  dyn_manager_unlock(manager);
 }
 
 void dyn_manager_single_op_change_address(TDynManager *manager,OP_HANDLE *op,unsigned short int address)
 {
   unsigned char i;
 
+  dyn_manager_lock(manager);
   for(i=0;i<manager->num_masters;i++)
   {
     if(op->op_index[i]!=0xFF)
       manager->operations[i].single_op[op->op_index[i]].address=address;
   }
+  dyn_manager_unlock(manager);
 }
 
 void dyn_manager_single_op_change_length(TDynManager *manager,OP_HANDLE *op,unsigned short int length)
 {
   unsigned char i;
 
+  dyn_manager_lock(manager);
   for(i=0;i<manager->num_masters;i++)
   {
     if(op->op_index[i]!=0xFF)
       manager->operations[i].single_op[op->op_index[i]].length=length;
   }
+  dyn_manager_unlock(manager);
 }
 
 void dyn_manager_single_op_change_data(TDynManager *manager,OP_HANDLE *op,unsigned char *data)
 {
   unsigned char i;
 
+  dyn_manager_lock(manager);
   for(i=0;i<manager->num_masters;i++)
   {
     if(op->op_index[i]!=0xFF)
       manager->operations[i].single_op[op->op_index[i]].data=data;
   }
+  dyn_manager_unlock(manager);
 }
 
 // sync operation functions
@@ -569,17 +620,25 @@ OP_HANDLE *dyn_manager_sync_op_new(TDynManager *manager,unsigned char mode,unsig
   TDynManagerSyncOp *current_op;
   OP_HANDLE *op_handle;
 
+  dyn_manager_lock(manager);
   if((op_handle=dyn_manager_get_free_op_handle(manager))==0x00000000)
+  {
+    dyn_manager_unlock(manager);
     return 0x00000000;
+  }
   if(mode==DYN_MANAGER_READ || mode==DYN_MANAGER_WRITE)
-    op_handle->op_type=DYN_MANAGER_SYNC|mode;
+    op_handle->op_type=(op_type_t)(DYN_MANAGER_SYNC|mode);
   else
+  {
+    dyn_manager_unlock(manager);
     return 0x00000000;
+  }
   for(i=0;i<num;i++)
   {
     if((master_index=dyn_manager_check_id(manager,ids[i]))==0xFF)
     {
       op_handle->op_type=no_op;
+      dyn_manager_unlock(manager);
       return 0x00000000;
     }
     if(op_handle->op_index[master_index]==0xFF)
@@ -591,7 +650,7 @@ OP_HANDLE *dyn_manager_sync_op_new(TDynManager *manager,unsigned char mode,unsig
         if(dyn_manager_id_present(current_op->num_devices,current_op->ids,ids[i])==0x00)
         {
           op_handle->op_index[master_index]=current_op_index;
-          current_op->common.operation=DYN_MANAGER_SYNC|mode;
+          current_op->common.operation=(op_type_t)(DYN_MANAGER_SYNC|mode);
           current_op->common.op_handle=op_handle;
           current_op->address=address;
           current_op->length=length;
@@ -604,6 +663,7 @@ OP_HANDLE *dyn_manager_sync_op_new(TDynManager *manager,unsigned char mode,unsig
       else
       {
         op_handle->op_type=no_op;
+        dyn_manager_unlock(manager);
         return 0x00000000;
       }
     }
@@ -620,6 +680,7 @@ OP_HANDLE *dyn_manager_sync_op_new(TDynManager *manager,unsigned char mode,unsig
     }
   }
   manager->num_ops++;
+  dyn_manager_unlock(manager);
   return op_handle;
 }
 
@@ -628,6 +689,7 @@ void dyn_manager_sync_op_add_devices(TDynManager *manager,OP_HANDLE *op,unsigned
   TDynManagerSyncOp *current_op;
   unsigned char i,j;
 
+  dyn_manager_lock(manager);
   for(i=0;i<manager->num_masters;i++)
   {
     if(op->op_index[i]!=0xFF)
@@ -647,6 +709,7 @@ void dyn_manager_sync_op_add_devices(TDynManager *manager,OP_HANDLE *op,unsigned
       }
     }
   }
+  dyn_manager_unlock(manager);
 }
 
 void dyn_manager_sync_op_remove_devices(TDynManager *manager,OP_HANDLE *op,unsigned char num,unsigned char *ids)
@@ -654,6 +717,7 @@ void dyn_manager_sync_op_remove_devices(TDynManager *manager,OP_HANDLE *op,unsig
   TDynManagerSyncOp *current_op;
   unsigned char i,j,k,device_index;
 
+  dyn_manager_lock(manager);
   for(i=0;i<manager->num_masters;i++)
   {
     if(op->op_index[i]!=0xFF)
@@ -683,28 +747,33 @@ void dyn_manager_sync_op_remove_devices(TDynManager *manager,OP_HANDLE *op,unsig
         dyn_manager_delete_op_single_master(manager,i,op);
     }
   }
+  dyn_manager_unlock(manager);
 }
 
 void dyn_manager_sync_op_change_address(TDynManager *manager,OP_HANDLE *op,unsigned short int address)
 {
   unsigned char i;
 
+  dyn_manager_lock(manager);
   for(i=0;i<manager->num_masters;i++)
   {
     if(op->op_index[i]!=0xFF)
       manager->operations[i].sync_op[op->op_index[i]].address=address;
   }
+  dyn_manager_unlock(manager);
 }
 
 void dyn_manager_sync_op_change_length(TDynManager *manager,OP_HANDLE *op,unsigned short int length)
 {
   unsigned char i;
 
+  dyn_manager_lock(manager);
   for(i=0;i<manager->num_masters;i++)
   {
     if(op->op_index[i]!=0xFF)
       manager->operations[i].sync_op[op->op_index[i]].length=length;
   }
+  dyn_manager_unlock(manager);
 }
 
 void dyn_manager_sync_op_change_data(TDynManager *manager,OP_HANDLE *op,unsigned char num,unsigned char *ids,unsigned char * const data[])
@@ -712,6 +781,7 @@ void dyn_manager_sync_op_change_data(TDynManager *manager,OP_HANDLE *op,unsigned
   TDynManagerSyncOp *current_op;
   unsigned char i,j,device_index;
 
+  dyn_manager_lock(manager);
   for(i=0;i<manager->num_masters;i++)
   {
     if(op->op_index[i]!=0xFF)
@@ -724,6 +794,7 @@ void dyn_manager_sync_op_change_data(TDynManager *manager,OP_HANDLE *op,unsigned
       }
     }
   }
+  dyn_manager_unlock(manager);
 }
 
 // bulk operation functions
@@ -733,17 +804,25 @@ OP_HANDLE *dyn_manager_bulk_op_new(TDynManager *manager,unsigned char mode,unsig
   TDynManagerBulkOp *current_op;
   OP_HANDLE *op_handle;
 
+  dyn_manager_lock(manager);
   if((op_handle=dyn_manager_get_free_op_handle(manager))==0x00000000)
+  {
+    dyn_manager_unlock(manager);
     return 0x00000000;
+  }
   if(mode==DYN_MANAGER_READ || mode==DYN_MANAGER_WRITE)
-    op_handle->op_type=DYN_MANAGER_BULK|mode;
+    op_handle->op_type=(op_type_t)(DYN_MANAGER_BULK|mode);
   else
+  {
+    dyn_manager_unlock(manager);
     return 0x00000000;
+  }
   for(i=0;i<num;i++)
   {
     if((master_index=dyn_manager_check_id(manager,ids[i]))==0xFF)
     {
       op_handle->op_type=no_op;
+      dyn_manager_unlock(manager);
       return 0x00000000;
     }
     if(op_handle->op_index[master_index]==0xFF)
@@ -755,7 +834,7 @@ OP_HANDLE *dyn_manager_bulk_op_new(TDynManager *manager,unsigned char mode,unsig
         if(dyn_manager_id_present(current_op->num_devices,current_op->ids,ids[i])==0x00)
         {
           op_handle->op_index[master_index]=current_op_index;
-          current_op->common.operation=DYN_MANAGER_BULK|mode;
+          current_op->common.operation=(op_type_t)(DYN_MANAGER_BULK|mode);
           current_op->common.op_handle=op_handle;
           current_op->address[current_op->num_devices]=address[i];
           current_op->length[current_op->num_devices]=length[i];
@@ -768,6 +847,7 @@ OP_HANDLE *dyn_manager_bulk_op_new(TDynManager *manager,unsigned char mode,unsig
       else
       {
         op_handle->op_type=no_op;
+        dyn_manager_unlock(manager);
         return 0x00000000;
       }
     }
@@ -786,6 +866,7 @@ OP_HANDLE *dyn_manager_bulk_op_new(TDynManager *manager,unsigned char mode,unsig
     }
   }
   manager->num_ops++;
+  dyn_manager_unlock(manager);
   return op_handle;
 }
 
@@ -794,6 +875,7 @@ void dyn_manager_bulk_op_add_devices(TDynManager *manager,OP_HANDLE *op,unsigned
   TDynManagerBulkOp *current_op;
   unsigned char i,j;
 
+  dyn_manager_lock(manager);
   for(i=0;i<manager->num_masters;i++)
   {
     if(op->op_index[i]!=0xFF)
@@ -815,6 +897,7 @@ void dyn_manager_bulk_op_add_devices(TDynManager *manager,OP_HANDLE *op,unsigned
       }
     }
   }
+  dyn_manager_unlock(manager);
 }
 
 void dyn_manager_bulk_op_remove_devices(TDynManager *manager,OP_HANDLE *op,unsigned char num,unsigned char *ids)
@@ -822,6 +905,7 @@ void dyn_manager_bulk_op_remove_devices(TDynManager *manager,OP_HANDLE *op,unsig
   TDynManagerBulkOp *current_op;
   unsigned char i,j,k,device_index;
 
+  dyn_manager_lock(manager);
   for(i=0;i<manager->num_masters;i++)
   {
     if(op->op_index[i]!=0xFF)
@@ -855,6 +939,7 @@ void dyn_manager_bulk_op_remove_devices(TDynManager *manager,OP_HANDLE *op,unsig
         dyn_manager_delete_op_single_master(manager,i,op);
     }
   }
+  dyn_manager_unlock(manager);
 }
 
 void dyn_manager_bulk_op_change_address(TDynManager *manager,OP_HANDLE *op,unsigned char num,unsigned char *ids,unsigned short int *address)
@@ -862,6 +947,7 @@ void dyn_manager_bulk_op_change_address(TDynManager *manager,OP_HANDLE *op,unsig
   TDynManagerBulkOp *current_op;
   unsigned char i,j,device_index;
 
+  dyn_manager_lock(manager);
   for(i=0;i<manager->num_masters;i++)
   {
     if(op->op_index[i]!=0xFF)
@@ -874,6 +960,7 @@ void dyn_manager_bulk_op_change_address(TDynManager *manager,OP_HANDLE *op,unsig
       }
     }
   }
+  dyn_manager_unlock(manager);
 }
 
 void dyn_manager_bulk_op_change_length(TDynManager *manager,OP_HANDLE *op,unsigned char num,unsigned char *ids,unsigned short int *length)
@@ -881,6 +968,7 @@ void dyn_manager_bulk_op_change_length(TDynManager *manager,OP_HANDLE *op,unsign
   TDynManagerBulkOp *current_op;
   unsigned char i,j,device_index;
 
+  dyn_manager_lock(manager);
   for(i=0;i<manager->num_masters;i++)
   {
     if(op->op_index[i]!=0xFF)
@@ -893,6 +981,7 @@ void dyn_manager_bulk_op_change_length(TDynManager *manager,OP_HANDLE *op,unsign
       }
     }
   }
+  dyn_manager_unlock(manager);
 }
 
 void dyn_manager_bulk_op_change_data(TDynManager *manager,OP_HANDLE *op,unsigned char num,unsigned char *ids,unsigned char * const data[])
@@ -900,6 +989,7 @@ void dyn_manager_bulk_op_change_data(TDynManager *manager,OP_HANDLE *op,unsigned
   TDynManagerBulkOp *current_op;
   unsigned char i,j,device_index;
 
+  dyn_manager_lock(manager);
   for(i=0;i<manager->num_masters;i++)
   {
     if(op->op_index[i]!=0xFF)
@@ -912,6 +1002,7 @@ void dyn_manager_bulk_op_change_data(TDynManager *manager,OP_HANDLE *op,unsigned
       }
     }
   }
+  dyn_manager_unlock(manager);
 }
 
 void dyn_manager_loop(TDynManager *manager)
@@ -924,7 +1015,7 @@ void dyn_manager_loop(TDynManager *manager)
   TDynManagerSingleOp *single_op[DYN_MANAGER_MAX_NUM_MASTERS];
   TDynManagerSyncOp *sync_op[DYN_MANAGER_MAX_NUM_MASTERS];
   TDynManagerBulkOp *bulk_op[DYN_MANAGER_MAX_NUM_MASTERS];
-  static unsigned char modules_period_count[DYN_MANAGER_MAX_NUM_MASTERS]={0};
+  static unsigned char modules_period_count[DYN_MANAGER_MAX_NUM_MODULES]={0};
   static unsigned char single_op_period_count[DYN_MANAGER_MAX_NUM_SINGLE_OP]={0};
   static unsigned char sync_op_period_count[DYN_MANAGER_MAX_NUM_SINGLE_OP]={0};
   static unsigned char bulk_op_period_count[DYN_MANAGER_MAX_NUM_SINGLE_OP]={0};
@@ -948,11 +1039,13 @@ void dyn_manager_loop(TDynManager *manager)
       {
         if(manager->modules[i]->pre_process!=0x00000000)
           manager->modules[i]->pre_process(manager->modules[i]->data);
+        modules_period_count[i]=0;
       }
     }
   }
 
   // send all the commands
+  dyn_manager_lock(manager);
   do{
     for(i=0;i<manager->num_masters;i++)
     {
@@ -1083,6 +1176,7 @@ void dyn_manager_loop(TDynManager *manager)
       }
     } 
   }while(loop_done>0);
+  dyn_manager_unlock(manager);
 
   // execute the pre_process functions for all modules
   for(i=0;i<manager->num_modules;i++)
diff --git a/dynamixel_manager/src/dyn_module.c b/dynamixel_manager/src/dyn_module.c
index 4207dee7a4b61ba1383b94fe7d4d4b9441326fe2..949fe66af2017bf01bc7ed029dfadd6953da41f3 100644
--- a/dynamixel_manager/src/dyn_module.c
+++ b/dynamixel_manager/src/dyn_module.c
@@ -1,6 +1,25 @@
 #include "dyn_module.h"
+#include "dyn_module_registers.h"
+#include "ram.h"
 
-unsigned char dyn_module_init(TDynModule *module)
+// private functions
+void dyn_module_write_cmd(TDynModule *module,unsigned short int address,unsigned short int length,unsigned char *data)
+{
+  unsigned short int eeprom_offset;
+
+  eeprom_offset=address-module->eeprom_base_address;
+  if(ram_in_window(module->eeprom_base_address+DYN_MODULE_PERIOD_OFFSET,1,address,length))
+    dyn_module_set_period(module,data[DYN_MODULE_PERIOD_OFFSET-eeprom_offset]);
+  ram_write_table(module->memory,address,length,data);
+}
+
+void dyn_module_read_cmd(TDynModule *module,unsigned short int address,unsigned short int length,unsigned char *data)
+{
+  ram_read_table(module->memory,address,length,data);
+}
+
+// public functions
+unsigned char dyn_module_init(TDynModule *module,TMemory *memory,unsigned short int ram_base_address,unsigned short int eeprom_base_address)
 {
   unsigned char i;
 
@@ -11,31 +30,31 @@ unsigned char dyn_module_init(TDynModule *module)
     module->assigned_ids[i]=0x00;
   module->num_assigned_ids=0x00;
   module->period_count=0x00;
-  module->enabled=0x00;
+  module->enabled=0x01;
   module->add_device=0x00000000;
+  module->set_period=0x00000000;
   module->setup=0x00000000;
   module->pre_process=0x00000000;
   module->post_process=0x00000000;
   module->data=0x00000000;
+  /* initialize memory module */
+  mem_module_init(&module->mem_module);
+  module->mem_module.data=module;
+  module->mem_module.write_cmd=(void(*)(void *,unsigned short int, unsigned short int,unsigned char *))dyn_module_write_cmd;
+  module->mem_module.read_cmd=(void(*)(void *,unsigned short int, unsigned short int,unsigned char *))dyn_module_read_cmd;
+  if(!mem_module_add_ram_segment(&module->mem_module,ram_base_address,RAM_DYN_MODULE_LENGTH))
+    return 0x00;
+  if(!mem_module_add_eeprom_segment(&module->mem_module,eeprom_base_address,EEPROM_DYN_MODULE_LENGTH))
+    return 0x00;
+  if(!mem_add_module(memory,&module->mem_module))
+    return 0x00;
+  module->eeprom_base_address=eeprom_base_address;
+  module->ram_base_address=ram_base_address;
+  module->memory=memory;
 
   return 0x01;
 }
 
-void dyn_module_enable(TDynModule *module)
-{
-  module->enabled=0x01;
-}
-
-void dyn_module_disable(TDynModule *module)
-{
-  module->enabled=0x00;
-}
-
-unsigned char dyn_module_is_enabled(TDynModule *module)
-{
-  return module->enabled;
-}
-
 void dyn_module_add_model(TDynModule *module,unsigned short int model)
 {
   unsigned char i;
@@ -50,11 +69,6 @@ void dyn_module_add_model(TDynModule *module,unsigned short int model)
   }
 }
 
-unsigned char dyn_module_get_num_models(TDynModule *module)
-{
-  return module->num_models;
-}
-
 void dyn_module_add_device(TDynModule *module,unsigned char id, unsigned short int model)
 {
   unsigned char i;
@@ -72,12 +86,7 @@ void dyn_module_add_device(TDynModule *module,unsigned char id, unsigned short i
   }
 }
 
-unsigned char dyn_module_get_num_assigned_devices(TDynModule *module)
-{
-  return module->num_assigned_ids;
-}
-
-unsigned char dyn_moudle_device_is_assigned(TDynModule *module,unsigned char id)
+unsigned char dyn_module_device_is_assigned(TDynModule *module,unsigned char id)
 {
   if(id<DYN_MANAGER_MAX_NUM_DEVICES)
     return module->assigned_ids[id];
@@ -88,14 +97,8 @@ unsigned char dyn_moudle_device_is_assigned(TDynModule *module,unsigned char id)
 void dyn_module_set_period(TDynModule *module,unsigned char period)
 {
   if(period==0x00)
-    module->period_count=0x01;
-  else
-    module->period_count=period;
-}
-
-unsigned char dyn_module_get_period(TDynModule *module)
-{
-  return module->period_count;
+    period=0x01;
+  module->period_count=period;
+  if(module->set_period!=0x00000000)
+    module->set_period(module->data,period*module->manager->period_ms);
 }
-
-
diff --git a/dynamixel_manager/src/modules/action.c b/dynamixel_manager/src/modules/action.c
index ea816ab70fd8b5fb941a6d98c1ecd37825016141..e901e01264cd3153a919c00899412317c73b4373 100755
--- a/dynamixel_manager/src/modules/action.c
+++ b/dynamixel_manager/src/modules/action.c
@@ -1,43 +1,34 @@
 #include "action.h"
-#include "motion_pages.h"
+#include "action_mm_registers.h"
+#include "ram.h"
 
 #define SPEED_BASE_SCHEDULE 0x00
 #define TIME_BASE_SCHEDULE  0x0A
 
-// private variables
-typedef enum {ACTION_PRE,ACTION_MAIN,ACTION_POST,ACTION_PAUSE} action_states;
-TMotionModule action_module;
+// private functions
+void action_write_cmd(TActionMModule *module,unsigned short int address,unsigned short int length,unsigned char *data)
+{
+  unsigned int ram_offset;
 
-TPage action_next_page;
-TPage action_current_page;
-unsigned char action_current_step_index;
-unsigned char action_current_page_index;
-// angle variables
-long long int action_moving_angles[PAGE_MAX_NUM_SERVOS];// fixed point 48|16 format
-long long int action_start_angles[PAGE_MAX_NUM_SERVOS];// fixed point 48|16 format
-// speed variables
-long long int action_start_speed[PAGE_MAX_NUM_SERVOS];// fixed point 48|16 format
-long long int action_main_speed[PAGE_MAX_NUM_SERVOS];// fixed point 48|16 format
-// control variables
-unsigned char action_end,action_stop;
-unsigned char action_zero_speed_finish[PAGE_MAX_NUM_SERVOS];
-unsigned char action_next_index;
-unsigned char action_running;
-// time variables (in time units (7.8 ms each time unit))
-long long int action_total_time;// fixed point 48|16 format
-long long int action_pre_time;// fixed point 48|16 format
-long long int action_main_time;// fixed point 48|16 format
-long long int action_step_time;// fixed point 48|16 format
-long long int action_pause_time;// fixed point 48|16 format
-long long int action_current_time;// fixed point 48|16 format
-long long int action_section_time;// fixed point 48|16 format
-long long int action_period;
+  ram_offset=address-module->ram_base_address;
+  if(ram_in_range(module->ram_base_address+ACTION_MM_CONTROL_OFFSET,address,length))
+  {
+    if(data[ACTION_MM_CONTROL_OFFSET-ram_offset]&ACTION_MM_START)
+      action_start_page(module);
+    if(data[ACTION_MM_CONTROL_OFFSET-ram_offset]&ACTION_MM_STOP)
+      action_stop_page(module);
+  }
+  if(ram_in_range(module->ram_base_address+ACTION_MM_PAGE_OFFSET,address,length))// load the page identifier 
+    action_load_page(module,data[ACTION_MM_PAGE_OFFSET-ram_offset]);
+}
 
-// private functions
-void action_load_next_step(void)
+void action_read_cmd(TActionMModule *module,unsigned short int address,unsigned short int length,unsigned char *data)
+{
+  ram_read_table(module->memory,address,length,data);
+}
+
+void action_load_next_step(TActionMModule *action)
 {
-  // page and step information
-  static char num_repetitions=0;
   // angle variables
   short int next_angle;// information from the flash memory (fixed point 9|7 format)
   long long int max_angle;// fixed point format 48|16 format
@@ -56,178 +47,181 @@ void action_load_next_step(void)
   // control information
   unsigned char i=0;
 
-  action_current_step_index++;
-  if(action_current_step_index>=action_current_page.header.stepnum)// the last step has been executed
+  action->current_step_index++;
+  if(action->current_step_index>=action->current_page.header.stepnum)// the last step has been executed
   {
-    if(action_current_page.header.stepnum==1)
+    if(action->current_page.header.stepnum==1)
     {
-      if(action_stop)
-        action_next_index=action_current_page.header.exit;
+      if(action->stop)
+        action->next_index=action->current_page.header.exit;
       else
       {
-        num_repetitions--;
-        if(num_repetitions>0)
-          action_next_index=action_current_page_index;
+        action->num_repetitions--;
+        if(action->num_repetitions>0)
+          action->next_index=action->current_page_index;
         else
-          action_next_index=action_current_page.header.next;
+          action->next_index=action->current_page.header.next;
       }
-      if(action_next_index==0)
-        action_end=0x01;
+      if(action->next_index==0)
+        action->end=0x01;
       else
       {
-        if(action_next_index!=action_current_page_index)
+        if(action->next_index!=action->current_page_index)
         {
-          pages_get_page(action_next_index,&action_next_page);
-          if(!pages_check_checksum(&action_next_page))
-            action_end=0x01;
+          pages_get_page(action->next_index,&action->next_page);
+          if(!pages_check_checksum(&action->next_page))
+            action->end=0x01;
         }
-        if(action_next_page.header.repeat==0 || action_next_page.header.stepnum==0)
-          action_end=0x01;
+        if(action->next_page.header.repeat==0 || action->next_page.header.stepnum==0)
+          action->end=0x01;
       }
     }
-    pages_copy_page(&action_next_page,&action_current_page);// make the next page active
-    if(action_current_page_index!=action_next_index)
-      num_repetitions=action_current_page.header.repeat;
-    action_current_step_index=0;
-    action_current_page_index=action_next_index;
+    pages_copy_page(&action->next_page,&action->current_page);// make the next page active
+    if(action->current_page_index!=action->next_index)
+      action->num_repetitions=action->current_page.header.repeat;
+    action->current_step_index=0;
+    action->current_page_index=action->next_index;
   }
-  else if(action_current_step_index==action_current_page.header.stepnum-1)// it is the last step
+  else if(action->current_step_index==action->current_page.header.stepnum-1)// it is the last step
   {
-    if(action_stop)
-      action_next_index=action_current_page.header.exit;
+    if(action->stop)
+      action->next_index=action->current_page.header.exit;
     else
     {
-      num_repetitions--;
-      if(num_repetitions>0)
-        action_next_index=action_current_page_index;
+      action->num_repetitions--;
+      if(action->num_repetitions>0)
+        action->next_index=action->current_page_index;
       else
-        action_next_index=action_current_page.header.next;
+        action->next_index=action->current_page.header.next;
     }
-    if(action_next_index==0)
-      action_end=0x01;
+    if(action->next_index==0)
+      action->end=0x01;
     else
     {
-      if(action_next_index!=action_current_page_index)
+      if(action->next_index!=action->current_page_index)
       {
-        pages_get_page(action_next_index,&action_next_page);
-        if(!pages_check_checksum(&action_next_page))
-          action_end=0x01;
+        pages_get_page(action->next_index,&action->next_page);
+        if(!pages_check_checksum(&action->next_page))
+          action->end=0x01;
       }
-      if(action_next_page.header.repeat==0 || action_next_page.header.stepnum==0)
-        action_end=0x01;
+      if(action->next_page.header.repeat==0 || action->next_page.header.stepnum==0)
+        action->end=0x01;
     }
   }
   // compute trajectory
-  action_pause_time=(action_current_page.steps[action_current_step_index].pause*action_current_page.header.speed)>>5;
-  action_pause_time=action_pause_time<<9;
-  action_step_time=(action_current_page.steps[action_current_step_index].time*action_current_page.header.speed)>>5;
-  action_step_time=action_step_time<<9;
-  if(action_step_time<action_period)
-    action_step_time=action_period;// 0.078 in 16|16 format
+  action->pause_time=(action->current_page.steps[action->current_step_index].pause*action->current_page.header.speed)>>5;
+  action->pause_time=action->pause_time<<9;
+  action->step_time=(action->current_page.steps[action->current_step_index].time*action->current_page.header.speed)>>5;
+  action->step_time=action->step_time<<9;
+  if(action->step_time<action->period)
+    action->step_time=action->period;// 0.078 in 16|16 format
   max_angle=0;
   for(i=0;i<PAGE_MAX_NUM_SERVOS;i++)
   {
-    if(mmanager_get_module(action_module.manager,i)==MM_ACTION)
+    if(mmanager_get_module(action->mmodule.manager,i)==MM_ACTION)
     {
-      angle=action_current_page.steps[action_current_step_index].position[i];
+      angle=action->current_page.steps[action->current_step_index].position[i];
       if(angle==0x5A00)// bigger than 180
-        target_angles=action_module.manager->servo_values[i].target_angle;
+        target_angles=action->mmodule.manager->servo_values[i].target_angle;
       else
         target_angles=angle<<9;
-      action_moving_angles[i]=target_angles-action_module.manager->servo_values[i].target_angle;
-      if(action_end)
+      action->moving_angles[i]=target_angles-action->mmodule.manager->servo_values[i].target_angle;
+      if(action->end)
         next_angles=target_angles;
       else
       {
-        if(action_current_step_index==action_current_page.header.stepnum-1)
-          next_angle=action_next_page.steps[0].position[i];
+        if(action->current_step_index==action->current_page.header.stepnum-1)
+          next_angle=action->next_page.steps[0].position[i];
         else
-          next_angle=action_current_page.steps[action_current_step_index+1].position[i];
+          next_angle=action->current_page.steps[action->current_step_index+1].position[i];
         if(next_angle==0x5A00)
           next_angles=target_angles;
         else
           next_angles=next_angle<<9;
       }
       // check changes in direction
-      if(((action_module.manager->servo_values[i].target_angle < target_angles) && (target_angles < next_angles)) ||
-         ((action_module.manager->servo_values[i].target_angle > target_angles) && (target_angles > next_angles)))
+      if(((action->mmodule.manager->servo_values[i].target_angle < target_angles) && (target_angles < next_angles)) ||
+         ((action->mmodule.manager->servo_values[i].target_angle > target_angles) && (target_angles > next_angles)))
         dir_change=0x00;
       else
         dir_change=0x01;
       // check the type of ending
-      if(dir_change || action_pause_time>0 || action_end)
-        action_zero_speed_finish[i]=0x01;
+      if(dir_change || action->pause_time>0 || action->end)
+        action->zero_speed_finish[i]=0x01;
       else
-        action_zero_speed_finish[i]=0x00;
+        action->zero_speed_finish[i]=0x00;
       // find the maximum angle of motion in speed base schedule
-      if(action_current_page.header.schedule==SPEED_BASE_SCHEDULE)// speed base schedule
+      if(action->current_page.header.schedule==SPEED_BASE_SCHEDULE)// speed base schedule
       {
         // fer el valor absolut
-        if(action_moving_angles[i]<0)
-          tmp_angle=-action_moving_angles[i];
+        if(action->moving_angles[i]<0)
+          tmp_angle=-action->moving_angles[i];
         else
-          tmp_angle=action_moving_angles[i];
+          tmp_angle=action->moving_angles[i];
         if(tmp_angle>max_angle)
           max_angle=tmp_angle;
       }
-      action_module.manager->servo_values[i].cw_compliance=(1<<(action_current_page.header.slope[i]&0x0F));
-      action_module.manager->servo_values[i].ccw_compliance=(1<<((action_current_page.header.slope[i]&0xF0)>>4));
+      action->mmodule.manager->servo_values[i].cw_compliance=(1<<(action->current_page.header.slope[i]&0x0F));
+      action->mmodule.manager->servo_values[i].ccw_compliance=(1<<((action->current_page.header.slope[i]&0xF0)>>4));
     }
   }
-  if(action_current_page.header.schedule==SPEED_BASE_SCHEDULE)
-    action_step_time=(max_angle*256)/(action_current_page.steps[action_current_step_index].time*720);
-  accel_time_num=action_current_page.header.accel;
+  if(action->current_page.header.schedule==SPEED_BASE_SCHEDULE)
+    action->step_time=(max_angle*256)/(action->current_page.steps[action->current_step_index].time*720);
+  accel_time_num=action->current_page.header.accel;
   accel_time_num=accel_time_num<<9;
-  if(action_step_time<=(accel_time_num<<1))
+  if(action->step_time<=(accel_time_num<<1))
   {
-    if(action_step_time==0)
+    if(action->step_time==0)
       accel_time_num=0;
     else
     {
-      accel_time_num=(action_step_time-action_period)>>1;
+      accel_time_num=(action->step_time-action->period)>>1;
       if(accel_time_num==0)
-        action_step_time=0;
+        action->step_time=0;
     }
   }
-  action_total_time=action_step_time;
-  action_pre_time=accel_time_num;
-  action_main_time=action_total_time-action_pre_time;
-  non_zero_speed_divider=(action_pre_time>>1)+action_main_time;
-  if(non_zero_speed_divider<action_period)
-    non_zero_speed_divider=action_period;
-  zero_speed_divider=action_main_time;
-  if(zero_speed_divider<action_period)
-    zero_speed_divider=action_period;
+  action->total_time=action->step_time;
+  action->pre_time=accel_time_num;
+  action->main_time=action->total_time-action->pre_time;
+  non_zero_speed_divider=(action->pre_time>>1)+action->main_time;
+  if(non_zero_speed_divider<action->period)
+    non_zero_speed_divider=action->period;
+  zero_speed_divider=action->main_time;
+  if(zero_speed_divider<action->period)
+    zero_speed_divider=action->period;
   for(i=0;i<PAGE_MAX_NUM_SERVOS;i++)
   {
-    if(mmanager_get_module(action_module.manager,i)==MM_ACTION)
+    if(mmanager_get_module(action->mmodule.manager,i)==MM_ACTION)
     {
-      action_pre_time_initial_speed_angle=(action_start_speed[i]*action_pre_time)>>1;
-      moving_angle=action_moving_angles[i]<<16;
-      if(action_zero_speed_finish[i])
-        action_main_speed[i]=(moving_angle-action_pre_time_initial_speed_angle)/zero_speed_divider;
+      action_pre_time_initial_speed_angle=(action->start_speed[i]*action->pre_time)>>1;
+      moving_angle=action->moving_angles[i]<<16;
+      if(action->zero_speed_finish[i])
+        action->main_speed[i]=(moving_angle-action_pre_time_initial_speed_angle)/zero_speed_divider;
       else
-        action_main_speed[i]=(moving_angle-action_pre_time_initial_speed_angle)/non_zero_speed_divider;
-//      if((action_main_speed[i]>>16)>info.max_speed)
-//        action_main_speed[i]=(info.max_speed*65536);
-//      else if((action_main_speed[i]>>16)<-info.max_speed)
-//        action_main_speed[i]=-(info.max_speed*65536);
+        action->main_speed[i]=(moving_angle-action_pre_time_initial_speed_angle)/non_zero_speed_divider;
+//      if((action->main_speed[i]>>16)>info.max_speed)
+//        action->main_speed[i]=(info.max_speed*65536);
+//      else if((action->main_speed[i]>>16)<-info.max_speed)
+//        action->main_speed[i]=-(info.max_speed*65536);
     }
   }
 }
 
-void action_finish(void)
+void action_finish(TActionMModule *action)
 {
   // set the internal state machine to the idle state
-  action_end=0x00;
+  action->end=0x00;
   // change the internal state 
-  action_running=0x00;
+  action->running=0x00;
+  action->memory->data[action->ram_base_address+ACTION_MM_CONTROL_OFFSET]&=(~ACTION_MM_RUNNING);
 }
 
-void action_set_period(void *module,unsigned short int period_us)
+void action_set_period(void *module,unsigned short int period_ms)
 {
+  TActionMModule *action=(TActionMModule *)module;
+
   // load the current period 
-  action_period=(period_us<<16)/1000000;
+  action->period=(period_ms<<16)/1000;
 }
 
 void action_set_module(void *module,unsigned char servo_id)
@@ -237,221 +231,214 @@ void action_set_module(void *module,unsigned char servo_id)
 
 void action_pre_process(void *module)
 {
+  TActionMModule *action=(TActionMModule *)module;
   unsigned char i;
-  // angle variables 
-  static long long int accel_angles[PAGE_MAX_NUM_SERVOS];// fixed point 48|16 format
-  static long long int main_angles[PAGE_MAX_NUM_SERVOS];// fixed point 48|16 format
-  // speed variables (in controller units)
-  static long long int current_speed[PAGE_MAX_NUM_SERVOS]={0};// fixed point 48|16 format
-  long long int delta_speed;
-  // control variables 
-  static action_states state=ACTION_PAUSE;
 
-  if(action_running==0x01)
+  if(action->running==0x01)
   {
-    action_current_time+=action_period;
-    switch(state)
+    action->current_time+=action->period;
+    switch(action->state)
     {
-      case ACTION_PRE: if(action_current_time>action_section_time)
+      case ACTION_PRE: if(action->current_time>action->section_time)
                        {
                          for(i=0;i<PAGE_MAX_NUM_SERVOS;i++)
                          {
-                           if(mmanager_get_module(action_module.manager,i)==MM_ACTION)
+                           if(mmanager_get_module(action->mmodule.manager,i)==MM_ACTION)
                            {
                              /* the last segment of the pre section */
-                             delta_speed=(action_main_speed[i]-action_start_speed[i]);
-                             current_speed[i]=action_start_speed[i]+delta_speed;
-                             accel_angles[i]=(action_start_speed[i]*action_section_time+((delta_speed*action_section_time)>>1))>>16;
-                             action_module.manager->servo_values[i].target_angle=action_start_angles[i]+accel_angles[i];
+                             action->delta_speed=(action->main_speed[i]-action->start_speed[i]);
+                             action->current_speed[i]=action->start_speed[i]+action->delta_speed;
+                             action->accel_angles[i]=(action->start_speed[i]*action->section_time+((action->delta_speed*action->section_time)>>1))>>16;
+                             action->mmodule.manager->servo_values[i].target_angle=action->start_angles[i]+action->accel_angles[i];
                              /* update of the state */
-                             if(!action_zero_speed_finish[i])
+                             if(!action->zero_speed_finish[i])
                              {
-                               if((action_step_time-action_pre_time)==0)
-                                 main_angles[i]=0;
+                               if((action->step_time-action->pre_time)==0)
+                                 action->main_angles[i]=0;
                                else
-                                 main_angles[i]=((action_moving_angles[i]-accel_angles[i])*(action_step_time-(action_pre_time<<1)))/(action_step_time-action_pre_time);
-                               action_start_angles[i]=action_module.manager->servo_values[i].target_angle;
+                                 action->main_angles[i]=((action->moving_angles[i]-action->accel_angles[i])*(action->step_time-(action->pre_time<<1)))/(action->step_time-action->pre_time);
+                               action->start_angles[i]=action->mmodule.manager->servo_values[i].target_angle;
                              }
                              else
                              {
-                               main_angles[i]=action_moving_angles[i]-accel_angles[i]-(((action_main_speed[i]*action_pre_time)>>1)>>16);
-                               action_start_angles[i]=action_module.manager->servo_values[i].target_angle;
+                               action->main_angles[i]=action->moving_angles[i]-action->accel_angles[i]-(((action->main_speed[i]*action->pre_time)>>1)>>16);
+                               action->start_angles[i]=action->mmodule.manager->servo_values[i].target_angle;
                              }
                              /* the first step of the main section */
-                             action_module.manager->servo_values[i].target_angle=action_start_angles[i]+(main_angles[i]*(action_current_time-action_section_time))/(action_step_time-(action_pre_time<<1));
-                             current_speed[i]=action_main_speed[i];
+                             action->mmodule.manager->servo_values[i].target_angle=action->start_angles[i]+(action->main_angles[i]*(action->current_time-action->section_time))/(action->step_time-(action->pre_time<<1));
+                             action->current_speed[i]=action->main_speed[i];
                            }
                          }
-                         action_current_time=action_current_time-action_section_time;
-                         action_section_time=action_step_time-(action_pre_time<<1);
-                         state=ACTION_MAIN;
+                         action->current_time=action->current_time-action->section_time;
+                         action->section_time=action->step_time-(action->pre_time<<1);
+                         action->state=ACTION_MAIN;
                        }
                        else
                        {
                          for(i=0;i<PAGE_MAX_NUM_SERVOS;i++)
                          {
-                           if(mmanager_get_module(action_module.manager,i)==MM_ACTION)
+                           if(mmanager_get_module(action->mmodule.manager,i)==MM_ACTION)
                            {
-                             delta_speed=((action_main_speed[i]-action_start_speed[i])*action_current_time)/action_section_time;
-                             current_speed[i]=action_start_speed[i]+delta_speed;
-                             accel_angles[i]=((action_start_speed[i]*action_current_time)+((delta_speed*action_current_time)>>1))>>16;
-                             action_module.manager->servo_values[i].target_angle=action_start_angles[i]+accel_angles[i];
+                             action->delta_speed=((action->main_speed[i]-action->start_speed[i])*action->current_time)/action->section_time;
+                             action->current_speed[i]=action->start_speed[i]+action->delta_speed;
+                             action->accel_angles[i]=((action->start_speed[i]*action->current_time)+((action->delta_speed*action->current_time)>>1))>>16;
+                             action->mmodule.manager->servo_values[i].target_angle=action->start_angles[i]+action->accel_angles[i];
                            }
                          }
-                         state=ACTION_PRE;
+                         action->state=ACTION_PRE;
                        }
                        break;
-      case ACTION_MAIN: if(action_current_time>action_section_time)
+      case ACTION_MAIN: if(action->current_time>action->section_time)
                         {
                           for(i=0;i<PAGE_MAX_NUM_SERVOS;i++)
                           {
-                            if(mmanager_get_module(action_module.manager,i)==MM_ACTION)
+                            if(mmanager_get_module(action->mmodule.manager,i)==MM_ACTION)
                             {
                               /* last segment of the main section */
-                              action_module.manager->servo_values[i].target_angle=action_start_angles[i]+main_angles[i];
-                              current_speed[i]=action_main_speed[i];
+                              action->mmodule.manager->servo_values[i].target_angle=action->start_angles[i]+action->main_angles[i];
+                              action->current_speed[i]=action->main_speed[i];
                               /* update state */
-                              action_start_angles[i]=action_module.manager->servo_values[i].target_angle;
-                              main_angles[i]=action_moving_angles[i]-main_angles[i]-accel_angles[i];
+                              action->start_angles[i]=action->mmodule.manager->servo_values[i].target_angle;
+                              action->main_angles[i]=action->moving_angles[i]-action->main_angles[i]-action->accel_angles[i];
                               /* first segment of the post section */
-                              if(action_zero_speed_finish[i])
+                              if(action->zero_speed_finish[i])
                               {
-                                delta_speed=((0.0-action_main_speed[i])*(action_current_time-action_section_time))/action_pre_time;
-                                current_speed[i]=action_main_speed[i]+delta_speed;
-                                action_module.manager->servo_values[i].target_angle=action_start_angles[i]+(((action_main_speed[i]*(action_current_time-action_section_time))+((delta_speed*(action_current_time-action_section_time))>>1))>>16);
+                                action->delta_speed=((0.0-action->main_speed[i])*(action->current_time-action->section_time))/action->pre_time;
+                                action->current_speed[i]=action->main_speed[i]+action->delta_speed;
+                                action->mmodule.manager->servo_values[i].target_angle=action->start_angles[i]+(((action->main_speed[i]*(action->current_time-action->section_time))+((action->delta_speed*(action->current_time-action->section_time))>>1))>>16);
                               }
                               else
                               {
-                                action_module.manager->servo_values[i].target_angle=action_start_angles[i]+((main_angles[i]*(action_current_time-action_section_time))/action_pre_time);
-                                current_speed[i]=action_main_speed[i];
+                                action->mmodule.manager->servo_values[i].target_angle=action->start_angles[i]+((action->main_angles[i]*(action->current_time-action->section_time))/action->pre_time);
+                                action->current_speed[i]=action->main_speed[i];
                               }
                             }
                           }
-                          action_current_time=action_current_time-action_section_time;
-                          action_section_time=action_pre_time;
-                          state=ACTION_POST;
+                          action->current_time=action->current_time-action->section_time;
+                          action->section_time=action->pre_time;
+                          action->state=ACTION_POST;
                         }
                         else
                         {
                           for(i=0;i<PAGE_MAX_NUM_SERVOS;i++)
                           {
-                            if(mmanager_get_module(action_module.manager,i)==MM_ACTION)
+                            if(mmanager_get_module(action->mmodule.manager,i)==MM_ACTION)
                             {
-                              action_module.manager->servo_values[i].target_angle=action_start_angles[i]+(main_angles[i]*action_current_time)/action_section_time;
-                              current_speed[i]=action_main_speed[i];
+                              action->mmodule.manager->servo_values[i].target_angle=action->start_angles[i]+(action->main_angles[i]*action->current_time)/action->section_time;
+                              action->current_speed[i]=action->main_speed[i];
                             }
                           }
-                          state=ACTION_MAIN;
+                          action->state=ACTION_MAIN;
                         }
                         break;
-      case ACTION_POST: if(action_current_time>action_section_time)
+      case ACTION_POST: if(action->current_time>action->section_time)
                         {
                           for(i=0;i<PAGE_MAX_NUM_SERVOS;i++)
                           {
-                            if(mmanager_get_module(action_module.manager,i)==MM_ACTION)
+                            if(mmanager_get_module(action->mmodule.manager,i)==MM_ACTION)
                             {
                               /* last segment of the post section */
-                              if(action_zero_speed_finish[i])
+                              if(action->zero_speed_finish[i])
                               {
-                                delta_speed=-action_main_speed[i];
-                                current_speed[i]=action_main_speed[i]+delta_speed;
-                                action_module.manager->servo_values[i].target_angle=action_start_angles[i]+(((action_main_speed[i]*action_section_time)+((delta_speed*action_section_time)>>1))>>16);
+                                action->delta_speed=-action->main_speed[i];
+                                action->current_speed[i]=action->main_speed[i]+action->delta_speed;
+                                action->mmodule.manager->servo_values[i].target_angle=action->start_angles[i]+(((action->main_speed[i]*action->section_time)+((action->delta_speed*action->section_time)>>1))>>16);
                               }
                               else
                               {
-                                action_module.manager->servo_values[i].target_angle=action_start_angles[i]+main_angles[i];
-                                current_speed[i]=action_main_speed[i];
+                                action->mmodule.manager->servo_values[i].target_angle=action->start_angles[i]+action->main_angles[i];
+                                action->current_speed[i]=action->main_speed[i];
                               }
                               /* update state */
-                              action_start_angles[i]=action_module.manager->servo_values[i].target_angle;
-                              action_start_speed[i]=current_speed[i];
+                              action->start_angles[i]=action->mmodule.manager->servo_values[i].target_angle;
+                              action->start_speed[i]=action->current_speed[i];
                             }
                           }
                           /* load the next step */
-                          if(action_pause_time==0)
+                          if(action->pause_time==0)
                           {
-                            if(action_end)
+                            if(action->end)
                             {
-                              state=ACTION_PAUSE;
-                              action_finish();
+                              action->state=ACTION_PAUSE;
+                              action_finish(action);
                             }
                             else
                             {
-                              action_load_next_step();
+                              action_load_next_step(action);
                               /* first step of the next section */
                               for(i=0;i<PAGE_MAX_NUM_SERVOS;i++)
                               {
-                                if(mmanager_get_module(action_module.manager,i)==MM_ACTION)
+                                if(mmanager_get_module(action->mmodule.manager,i)==MM_ACTION)
                                 {
-                                  delta_speed=((action_main_speed[i]-action_start_speed[i])*(action_current_time-action_section_time))/action_pre_time;
-                                  current_speed[i]=action_start_speed[i]+delta_speed;
-                                  accel_angles[i]=(((action_start_speed[i]*(action_current_time-action_section_time))+((delta_speed*(action_current_time-action_section_time))>>1))>>16);
-                                  action_module.manager->servo_values[i].target_angle=action_start_angles[i]+accel_angles[i];
+                                  action->delta_speed=((action->main_speed[i]-action->start_speed[i])*(action->current_time-action->section_time))/action->pre_time;
+                                  action->current_speed[i]=action->start_speed[i]+action->delta_speed;
+                                  action->accel_angles[i]=(((action->start_speed[i]*(action->current_time-action->section_time))+((action->delta_speed*(action->current_time-action->section_time))>>1))>>16);
+                                  action->mmodule.manager->servo_values[i].target_angle=action->start_angles[i]+action->accel_angles[i];
                                 }
                               }
-                              action_current_time=action_current_time-action_section_time;
-                              action_section_time=action_pre_time;
-                              state=ACTION_PRE;
+                              action->current_time=action->current_time-action->section_time;
+                              action->section_time=action->pre_time;
+                              action->state=ACTION_PRE;
                             }
                           }
                           else
                           {
-                            action_current_time=action_current_time-action_section_time;
-                            action_section_time=action_pause_time;
-                            state=ACTION_PAUSE;
+                            action->current_time=action->current_time-action->section_time;
+                            action->section_time=action->pause_time;
+                            action->state=ACTION_PAUSE;
                           }
                         }
                         else
                         {
                           for(i=0;i<PAGE_MAX_NUM_SERVOS;i++)
                           {
-                            if(mmanager_get_module(action_module.manager,i)==MM_ACTION)
+                            if(mmanager_get_module(action->mmodule.manager,i)==MM_ACTION)
                             {
-                              if(action_zero_speed_finish[i])
+                              if(action->zero_speed_finish[i])
                               {
-                                delta_speed=((0.0-action_main_speed[i])*action_current_time)/action_section_time;
-                                current_speed[i]=action_main_speed[i]+delta_speed;
-                                action_module.manager->servo_values[i].target_angle=action_start_angles[i]+(((action_main_speed[i]*action_current_time)+((delta_speed*action_current_time)>>1))>>16);
+                                action->delta_speed=((0.0-action->main_speed[i])*action->current_time)/action->section_time;
+                                action->current_speed[i]=action->main_speed[i]+action->delta_speed;
+                                action->mmodule.manager->servo_values[i].target_angle=action->start_angles[i]+(((action->main_speed[i]*action->current_time)+((action->delta_speed*action->current_time)>>1))>>16);
                               }
                               else
                               {
-                                action_module.manager->servo_values[i].target_angle=action_start_angles[i]+(main_angles[i]*action_current_time)/action_section_time;
-                                current_speed[i]=action_main_speed[i];
+                                action->mmodule.manager->servo_values[i].target_angle=action->start_angles[i]+(action->main_angles[i]*action->current_time)/action->section_time;
+                                action->current_speed[i]=action->main_speed[i];
                               }
                             }
                           }
-                          state=ACTION_POST;
+                          action->state=ACTION_POST;
                         }
                         break;
-      case ACTION_PAUSE: if(action_current_time>action_section_time)
+      case ACTION_PAUSE: if(action->current_time>action->section_time)
                          {
-                           if(action_end)
+                           if(action->end)
                            {
-                             state=ACTION_PAUSE;
-                             action_finish();
+                             action->state=ACTION_PAUSE;
+                             action_finish(action);
                            }
                            else
                            {
                              // find next page to execute
-                             action_load_next_step();
+                             action_load_next_step(action);
                              /* first step of the next section */
                              for(i=0;i<PAGE_MAX_NUM_SERVOS;i++)
                              {
-                               if(mmanager_get_module(action_module.manager,i)==MM_ACTION)
+                               if(mmanager_get_module(action->mmodule.manager,i)==MM_ACTION)
                                {
-                                 delta_speed=((action_main_speed[i]-action_start_speed[i])*(action_current_time-action_section_time))/action_pre_time;
-                                 current_speed[i]=action_start_speed[i]+delta_speed;
-                                 accel_angles[i]=(((action_start_speed[i]*(action_current_time-action_section_time))+((delta_speed*(action_current_time-action_section_time))>>1))>>16);
-                                 action_module.manager->servo_values[i].target_angle=action_start_angles[i]+accel_angles[i];
+                                 action->delta_speed=((action->main_speed[i]-action->start_speed[i])*(action->current_time-action->section_time))/action->pre_time;
+                                 action->current_speed[i]=action->start_speed[i]+action->delta_speed;
+                                 action->accel_angles[i]=(((action->start_speed[i]*(action->current_time-action->section_time))+((action->delta_speed*(action->current_time-action->section_time))>>1))>>16);
+                                 action->mmodule.manager->servo_values[i].target_angle=action->start_angles[i]+action->accel_angles[i];
                                }
                              }
-                             action_current_time=action_current_time-action_section_time;
-                             action_section_time=action_pre_time;
-                             state=ACTION_PRE;
+                             action->current_time=action->current_time-action->section_time;
+                             action->section_time=action->pre_time;
+                             action->state=ACTION_PRE;
                            }
                          }
                          else// pause section still active
-                           state=ACTION_PAUSE;
+                           action->state=ACTION_PAUSE;
                          break;
       default: break;
     }
@@ -459,98 +446,116 @@ void action_pre_process(void *module)
 }
 
 // public functions
-void action_init(void)
+unsigned char action_init(TActionMModule *action,TMemory *memory,unsigned short int ram_base_address)
 {
   unsigned char i;
 
   /* initialize the motion module */
-  mmodule_init(&action_module);
-  action_module.id=MM_ACTION;
-  action_module.set_period=action_set_period;
-  action_module.set_module=action_set_module;
-  action_module.pre_process=action_pre_process;
+  mmodule_init(&action->mmodule);
+  action->mmodule.id=MM_ACTION;
+  action->mmodule.set_period=action_set_period;
+  action->mmodule.set_module=action_set_module;
+  action->mmodule.pre_process=action_pre_process;
+  action->mmodule.data=action;
 
   // init manager_current_angles with the current position of the servos
   for(i=0;i<PAGE_MAX_NUM_SERVOS;i++)
   {
     // angle variables
-    action_moving_angles[i]=0;// fixed point 48|16 format
-    action_start_angles[i]=0;
+    action->moving_angles[i]=0;// fixed point 48|16 format
+    action->start_angles[i]=0;
     // speed variables
-    action_start_speed[i]=0;// fixed point 48|16 format
-    action_main_speed[i]=0;// fixed point 48|16 format
+    action->start_speed[i]=0;// fixed point 48|16 format
+    action->main_speed[i]=0;// fixed point 48|16 format
     // control variables
-    action_zero_speed_finish[i]=0x00;
+    action->zero_speed_finish[i]=0x00;
+    action->current_speed[i]=0;
   }
   // clear the contents of the next page
-  pages_clear_page(&action_next_page);
-  pages_clear_page(&action_current_page);
-  action_current_page_index=0;
-  action_current_step_index=-1;
+  pages_clear_page(&action->next_page);
+  pages_clear_page(&action->current_page);
+  action->current_page_index=0;
+  action->current_step_index=-1;
   // control variables
-  action_end=0x00;
-  action_stop=0x00;
-  action_running=0x00;
-  action_next_index=0;
+  action->end=0x00;
+  action->stop=0x00;
+  action->running=0x00;
+  action->next_index=0;
   // time variables (in time units (7.8 ms each time unit))
-  action_total_time=0;// fixed point 48|16 format
-  action_pre_time=0;// fixed point 48|16 format
-  action_main_time=0;// fixed point 48|16 format
-  action_step_time=0;// fixed point 48|16 format
-  action_pause_time=0;// fixed point 48|16 format
-  action_current_time=0;// fixed point 48|16 format
-  action_section_time=0;// fixed point 48|16 format
-  action_period=(DYN_MANAGER_DEFAULT_PERIOD_US<<16)/1000000;
+  action->total_time=0;// fixed point 48|16 format
+  action->pre_time=0;// fixed point 48|16 format
+  action->main_time=0;// fixed point 48|16 format
+  action->step_time=0;// fixed point 48|16 format
+  action->pause_time=0;// fixed point 48|16 format
+  action->current_time=0;// fixed point 48|16 format
+  action->section_time=0;// fixed point 48|16 format
+  action->state=ACTION_PAUSE;
+  action->num_repetitions=0;
+  //action_period=(DYN_MANAGER_DEFAULT_PERIOD_US<<16)/1000000;
+  mem_module_init(&action->mem_module);
+  action->mem_module.data=action;
+  action->mem_module.write_cmd=(void(*)(void *,unsigned short int, unsigned short int,unsigned char *))action_write_cmd;
+  action->mem_module.read_cmd=(void(*)(void *,unsigned short int, unsigned short int,unsigned char *))action_read_cmd;
+  if(!mem_module_add_ram_segment(&action->mem_module,ram_base_address,RAM_ACTION_MM_LENGTH))
+    return 0x00;
+  if(!mem_add_module(memory,&action->mem_module))
+    return 0x00;
+  action->ram_base_address=ram_base_address;
+  action->memory=memory;
+  
+  return 0x01;
 }
 
-TMotionModule *action_get_module(void)
+TMotionModule *action_get_module(TActionMModule *action)
 {
-  return &action_module;
+  return &action->mmodule;
 }
 
-unsigned char action_load_page(unsigned char page_id)
+unsigned char action_load_page(TActionMModule *action,unsigned char page_id)
 {
-  action_next_index=page_id;
-  pages_get_page(action_next_index,&action_current_page);
-  pages_get_page(action_current_page.header.next,&action_next_page);
-  if(!pages_check_checksum(&action_current_page))
+  action->next_index=page_id;
+  pages_get_page(action->next_index,&action->current_page);
+  pages_get_page(action->current_page.header.next,&action->next_page);
+  if(!pages_check_checksum(&action->current_page))
     return 0x00;
-  if(!pages_check_checksum(&action_next_page))
+  if(!pages_check_checksum(&action->next_page))
     return 0x00;
+  action->memory->data[action->ram_base_address+ACTION_MM_PAGE_OFFSET]=page_id;
 
   return 0x01;
 }
 
-void action_start_page(void)
+void action_start_page(TActionMModule *action)
 {
   unsigned char i;
 
   for(i=0;i<PAGE_MAX_NUM_SERVOS;i++)
-    action_start_angles[i]=action_module.manager->servo_values[i].target_angle;
-  action_stop=0x00;
-  action_current_time=0;
-  action_section_time=0; 
-  action_current_step_index=-1;
+    action->start_angles[i]=action->mmodule.manager->servo_values[i].target_angle;
+  action->stop=0x00;
+  action->current_time=0;
+  action->section_time=0; 
+  action->current_step_index=-1;
   /* clear the interrupt flag */
-  action_running=0x01;
+  action->running=0x01;
+  action->memory->data[action->ram_base_address+ACTION_MM_CONTROL_OFFSET]|=ACTION_MM_RUNNING;
 }
 
-void action_stop_page(void)
+void action_stop_page(TActionMModule *action)
 {
-  action_stop=0x01;
+  action->stop=0x01;
 }
 
-unsigned char action_is_running(void)
+unsigned char action_is_running(TActionMModule *action)
 {
-  return action_running;
+  return action->running;
 }
 
-unsigned char action_get_current_page(void)
+unsigned char action_get_current_page(TActionMModule *action)
 {
-  return action_current_page_index;
+  return action->current_page_index;
 }
 
-unsigned char action_get_current_step(void)
+unsigned char action_get_current_step(TActionMModule *action)
 {
-  return action_current_step_index;
+  return action->current_step_index;
 }
diff --git a/dynamixel_manager/src/modules/dyn_servos.c b/dynamixel_manager/src/modules/dyn_servos.c
new file mode 100644
index 0000000000000000000000000000000000000000..4a7ba4a90f29903fa52bbd3bf4fb2dce2b9396ff
--- /dev/null
+++ b/dynamixel_manager/src/modules/dyn_servos.c
@@ -0,0 +1,291 @@
+#include "dyn_servos.h"
+
+TDynReg ax_reg[NUM_REG]={// Info
+                         {0x0000,2,1},
+                         {0xFFFF,0,0},
+                         {0x0002,1,1},
+                         {0x0003,1,1},
+                         {0x0004,1,1},
+                         {0x0005,1,1},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0x0010,1,1},
+                         // Configuration
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0x0006,2,1},
+                         {0x0008,2,1},
+                         {0x000B,1,1},
+                         {0x000C,1,1},
+                         {0x000D,1,1},
+                         {0x000E,2,1},
+                         {0x0022,2,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         // Status
+                         {0x0011,1,1},
+                         {0x0012,1,1},
+                         {0x0019,1,0},
+                         {0xFFFF,0,0},
+                         {0x002E,1,0},
+                         {0xFFFF,0,0},
+                         {0x002F,1,0},
+                         {0x002C,1,0},
+                         {0xFFFF,0,0},
+                         // Control 
+                         {0x0018,1,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0x001A,1,0},
+                         {0x001B,1,0},
+                         {0x001C,1,0},
+                         {0x001D,1,0},
+                         {0x0030,2,0},
+                         // Set point
+                         {0x001E,2,0},
+                         {0x0020,2,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         // Feedback
+                         {0x0024,2,0},
+                         {0x0026,2,0},
+                         {0x0028,2,0},
+                         {0x002A,1,0},
+                         {0x002B,1,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0}};
+
+TDynReg mx_1_0_reg[NUM_REG]={// Info
+                         {0x0000,2,1},
+                         {0xFFFF,0,0},
+                         {0x0002,1,1},
+                         {0x0003,1,1},
+                         {0x0004,1,1},
+                         {0x0005,1,1},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0x0010,1,1},
+                         // Configuration
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0x0006,2,1},
+                         {0x0008,2,1},
+                         {0x000B,1,1},
+                         {0x000C,1,1},
+                         {0x000D,1,1},
+                         {0x000E,2,1},
+                         {0x0022,2,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0x0020,2,0},
+                         {0x0014,2,1},
+                         {0x0016,1,1},
+                         // Status
+                         {0x0011,1,1},
+                         {0x0012,1,1},
+                         {0x0019,1,0},
+                         {0xFFFF,0,0},
+                         {0x002E,1,0},
+                         {0xFFFF,0,0},
+                         {0x002F,1,0},
+                         {0x002C,1,0},
+                         {0xFFFF,0,0},
+                         // Control 
+                         {0x0018,1,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0x001C,1,0},
+                         {0x001B,1,0},
+                         {0x001A,1,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0x0030,2,0},
+                         // Set point
+                         {0x001E,2,0},
+                         {0x0020,2,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0x0049,1,0},
+                         {0xFFFF,0,0},
+                         // Feedback
+                         {0x0024,2,0},
+                         {0x0026,2,0},
+                         {0x0028,2,0},
+                         {0x002A,1,0},
+                         {0x002B,1,0},
+                         {0xFFFF,0,0},
+                         {0x0032,2,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0}};
+
+TDynReg xl_reg[NUM_REG]={// Info
+                         {0x0000,2,1},
+                         {0xFFFF,0,0},
+                         {0x0002,1,1},
+                         {0x0003,1,1},
+                         {0x0004,1,1},
+                         {0x0005,1,1},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0x0011,1,1},
+                         // Configuration
+                         {0xFFFF,0,0},
+                         {0x000B,1,1},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0x0006,2,1},
+                         {0x0008,2,1},
+                         {0x000C,1,1},
+                         {0x000D,1,1},
+                         {0x000E,1,1},
+                         {0x000F,2,1},
+                         {0x0023,2,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         // Status
+                         {0x0012,1,1},
+                         {0x0012,1,1},
+                         {0x0019,1,0},
+                         {0xFFFF,0,0},
+                         {0x0031,1,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0x002F,1,0},
+                         {0x0032,1,0},
+                         // Control 
+                         {0x0018,1,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0x001D,1,0},
+                         {0x001C,1,0},
+                         {0x001B,1,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0x0033,2,0},
+                         // Set point
+                         {0x001E,2,0},
+                         {0x0020,2,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0x0049,1,0},
+                         {0xFFFF,0,0},
+                         // Feedback
+                         {0x0025,2,0},
+                         {0x0027,2,0},
+                         {0x0029,2,0},
+                         {0x002D,1,0},
+                         {0x002E,1,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0}};
+
+TDynReg mx_2_0_reg[NUM_REG]={// Info
+                         {0x0000,2,1},
+                         {0x0002,4,1},
+                         {0x0006,1,1},
+                         {0x0007,1,1},
+                         {0x0008,1,1},
+                         {0x0009,1,1},
+                         {0x000C,1,1},
+                         {0x000D,1,1},
+                         {0x0044,1,0},
+                         // Configuration
+                         {0x000A,1,1},
+                         {0x000B,1,1},
+                         {0x0014,4,1},
+                         {0x0018,4,1},
+                         {0x0034,4,1},
+                         {0x0030,4,1},
+                         {0x001F,1,1},
+                         {0x0022,2,1},
+                         {0x0020,2,1},
+                         {0x0024,2,1},
+                         {0xFFFF,0,0},
+                         {0x0026,2,1},
+                         {0xFFFF,0,0},
+                         {0x002C,4,1},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         // Status
+                         {0x003F,1,1},
+                         {0x003F,1,1},
+                         {0x0041,1,0},
+                         {0x0062,1,0},
+                         {0x007A,1,0},
+                         {0x007B,1,0},
+                         {0xFFFF,0,0},
+                         {0x0045,1,0},
+                         {0x0046,1,0},
+                         // Control 
+                         {0x0040,1,0},
+                         {0x004C,2,0},
+                         {0x004E,2,0},
+                         {0x0054,2,0},
+                         {0x0052,2,0},
+                         {0x0050,2,0},
+                         {0x0058,2,0},
+                         {0x005A,2,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         {0xFFFF,0,0},
+                         // Set point
+                         {0x0074,4,0},
+                         {0x0068,4,0},
+                         {0x0064,2,0},
+                         {0x0066,2,0},
+                         {0x006C,4,0},
+                         {0x0070,4,0},
+                         // Feedback
+                         {0x0084,4,0},
+                         {0x0080,4,0},
+                         {0x007E,2,0},
+                         {0x0090,2,0},
+                         {0x0092,1,0},
+                         {0x007C,2,0},
+                         {0x0078,2,0},
+                         {0x0088,5,0},
+                         {0x008C,4,0}};
+
+TServoConfig servo_data[NUM_SERVO_MODELS]={
+//model | enc_res | gear | max_angle | center_angle | max_speed | cw_limit | ccw_limit | registers | pid | protocol
+{300    , 1023    , 32   , 300<<7    , 150<<7       , 324       , 0        , 300<<7    , ax_reg    , 0   , 1},
+{12     , 1023    , 254  , 300<<7    , 150<<7       , 354       , 0        , 300<<7    , ax_reg    , 0   , 1},
+{18     , 1023    , 254  , 300<<7    , 150<<7       , 582       , 0        , 300<<7    , ax_reg    , 0   , 1},
+{360    , 4095    , 32   , 360<<7    , 180<<7       , 2820      , 0        , 360<<7    , mx_1_0_reg, 1   , 1},
+{29     , 4095    , 193  , 360<<7    , 180<<7       , 330       , 0        , 360<<7    , mx_1_0_reg, 1   , 1},
+{310    , 4095    , 200  , 360<<7    , 180<<7       , 378       , 0        , 360<<7    , mx_1_0_reg, 1   , 1},
+{320    , 4095    , 225  , 360<<7    , 180<<7       , 270       , 0        , 360<<7    , mx_1_0_reg, 1   , 1},
+{30     , 4095    , 193  , 360<<7    , 180<<7       , 378       , 0        , 360<<7    , mx_2_0_reg, 1   , 2},
+{311    , 4095    , 200  , 360<<7    , 180<<7       , 378       , 0        , 360<<7    , mx_2_0_reg, 1   , 2},
+{321    , 4095    , 225  , 360<<7    , 180<<7       , 270       , 0        , 360<<7    , mx_2_0_reg, 1   , 2},
+{350    , 1023    , 238  , 300<<7    , 150<<7       , 684       , 0        , 300<<7    , xl_reg    , 1   , 2}};
diff --git a/dynamixel_manager/src/modules/motion_manager.c b/dynamixel_manager/src/modules/motion_manager.c
index 9c8c7dc992e7f8098e6ab3ba4c4c4fcedf20625f..3e5a676b5384bb71abd3ce4386a210ebcd3c3742 100644
--- a/dynamixel_manager/src/modules/motion_manager.c
+++ b/dynamixel_manager/src/modules/motion_manager.c
@@ -1,32 +1,83 @@
 #include "motion_manager.h"
+#include "motion_manager_registers.h"
 #include "motion_module.h"
-#include "dyn_devices.h"
-#include "dyn_servos.h"
-
-/* private variables */
-uint16_t mm_eeprom_data[] __attribute__ ((section (".eeprom")))={DEFAULT_ADC_PERIOD,ADC_PERIOD};
+#include "ram.h"
 
 /* private functions */
+void mmanager_read_register(TMotionManager *mmanager,unsigned char id,TDynReg *reg,unsigned int *value)
+{
+  unsigned char reg_value[4]={0};
+
+  if(reg->address!=0xFFFF)
+  {
+    dyn_master_read_table(dyn_manager_get_device_master(mmanager->dyn_module.manager,id),id,reg->address,reg->size,reg_value);
+    if(reg->size==1)
+      (*value)=reg_value[0];
+    else if(reg->size==2)
+      (*value)=reg_value[0]+(reg_value[1]<<8);
+    else if(reg->size==4)
+      (*value)=reg_value[0]+(reg_value[1]<<8)+(reg_value[2]<<16)+(reg_value[3]<<24);
+  }
+}
+
+void mmanager_write_register(TMotionManager *mmanager,unsigned char id,TDynReg *reg,unsigned int value)
+{
+}
+
 void mmanager_read_cmd(void *module,unsigned short int address,unsigned short int length,unsigned char *data)
 {
+  TMotionManager *manager=(TMotionManager *)module;
 
+  ram_read_table(manager->memory,address,length,data);
 }
 
 void mmanager_write_cmd(void *module,unsigned short int address,unsigned short int length,unsigned char *data)
 {
+  TMotionManager *manager=(TMotionManager *)module;
+  unsigned short int eeprom_offset,ram_offset,i,j;
+  unsigned char byte_value,mod;
 
+  eeprom_offset=address-manager->eeprom_base_address;
+  if(ram_in_window(manager->eeprom_base_address+MM_SERVO_OFFSET_OFFSET,DYN_MANAGER_MAX_NUM_DEVICES,address,length))
+  {
+    for(i=0;i<DYN_MANAGER_MAX_NUM_DEVICES;i++)
+    {
+      if(ram_in_range(manager->eeprom_base_address+MM_SERVO_OFFSET_OFFSET+i,address,length))
+        mmanager_set_offset(manager,i,(signed char)(data[MM_SERVO_OFFSET_OFFSET-eeprom_offset+i]));
+    }
+  }
+  ram_offset=address-manager->ram_base_address;
+  if(ram_in_window(manager->ram_base_address+MM_ENABLE_MODULE_OFFSET,DYN_MANAGER_MAX_NUM_DEVICES/2,address,length))
+  {
+    for(i=0,j=0;i<DYN_MANAGER_MAX_NUM_DEVICES/2;i++,j+=2)
+    {
+      if(ram_in_range(manager->ram_base_address+MM_ENABLE_MODULE_OFFSET+i,address,length))
+      {
+        byte_value=data[MM_ENABLE_MODULE_OFFSET-ram_offset+i];
+        if(byte_value&MM_EVEN_SER_EN) mmanager_enable_servo(manager,j);
+        else mmanager_disable_servo(manager,j);
+        mod=(byte_value&MM_EVEN_SER_MOD)>>4;
+        mmanager_set_module(manager,j,(TModules)mod);
+        if(byte_value&MM_ODD_SER_EN) mmanager_enable_servo(manager,j+1);
+        else mmanager_disable_servo(manager,j+1);
+        mod=byte_value&MM_ODD_SER_MOD;
+        mmanager_set_module(manager,j+1,(TModules)mod);
+      }
+    }
+  }
+  ram_write_table(manager->memory,address,length,data);
 }
 
 unsigned short int mmanager_angle_to_value(TMotionManager *mmanager,unsigned char servo_id,short int angle);
 inline unsigned short int mmanager_angle_to_value(TMotionManager *mmanager,unsigned char servo_id,short int angle)
 {
-  return ((angle+mmanager->servo_configs[servo_id].center_angle)*mmanager->servo_configs[servo_id].encoder_resolution)/mmanager->servo_configs[servo_id].max_angle;
+  return ((angle+mmanager->servo_configs[servo_id]->center_angle)*mmanager->servo_configs[servo_id]->encoder_resolution)/mmanager->servo_configs[servo_id]->max_angle;
 }
 
 short int mmanager_value_to_angle(TMotionManager *mmanager,unsigned char servo_id,unsigned short int value);
 inline short int mmanager_value_to_angle(TMotionManager *mmanager,unsigned char servo_id,unsigned short int value)
 {
-  return (((short int)((value*mmanager->servo_configs[servo_id].max_angle)/mmanager->servo_configs[servo_id].encoder_resolution))-mmanager->servo_configs[servo_id].center_angle);
+  return (((short int)((value*mmanager->servo_configs[servo_id]->max_angle)/mmanager->servo_configs[servo_id]->encoder_resolution))-mmanager->servo_configs[servo_id]->center_angle);
 }
 
 void mmanager_compute_targets(TMotionManager *mmanager)
@@ -64,129 +115,29 @@ void mmanager_compute_angles(TMotionManager *mmanager)
 
 void mmanager_add_device(TMotionManager *mmanager,unsigned char id,unsigned short int model)
 {
-  unsigned short int cw_value,ccw_value;
+  unsigned int cw_value,ccw_value;
+  unsigned char i;
 
   if(id<DYN_MANAGER_MAX_NUM_DEVICES)
   {
-    switch(model)
-    {
-      case SERVO_DX113: mmanager->servo_configs[id].encoder_resolution=1023;
-                        mmanager->servo_configs[id].gear_ratio=193;
-                        mmanager->servo_configs[id].max_angle=300<<7;
-                        mmanager->servo_configs[id].center_angle=150<<7;
-                        mmanager->servo_configs[id].max_speed=324;
-                        break;
-      case SERVO_DX116: mmanager->servo_configs[id].encoder_resolution=1023;
-                        mmanager->servo_configs[id].gear_ratio=143;
-                        mmanager->servo_configs[id].max_angle=300<<7;
-                        mmanager->servo_configs[id].center_angle=150<<7;
-                        mmanager->servo_configs[id].max_speed=354;
-                        break;
-      case SERVO_DX117: mmanager->servo_configs[id].encoder_resolution=1023;
-                        mmanager->servo_configs[id].gear_ratio=193;
-                        mmanager->servo_configs[id].max_angle=300<<7;
-                        mmanager->servo_configs[id].center_angle=150<<7;
-                        mmanager->servo_configs[id].max_speed=510;
-                        break;
-      case SERVO_AX12A: mmanager->servo_configs[id].encoder_resolution=1023;
-                        mmanager->servo_configs[id].gear_ratio=254;
-                        mmanager->servo_configs[id].max_angle=300<<7;
-                        mmanager->servo_configs[id].center_angle=150<<7;
-                        mmanager->servo_configs[id].max_speed=354;
-                        break;
-      case SERVO_AX12W: mmanager->servo_configs[id].encoder_resolution=1023;
-                        mmanager->servo_configs[id].gear_ratio=32;
-                        mmanager->servo_configs[id].max_angle=300<<7;
-                        mmanager->servo_configs[id].center_angle=150<<7;
-                        mmanager->servo_configs[id].max_speed=2830;
-                        break;
-      case SERVO_AX18A: mmanager->servo_configs[id].encoder_resolution=1023;
-                        mmanager->servo_configs[id].gear_ratio=254;
-                        mmanager->servo_configs[id].max_angle=300<<7;
-                        mmanager->servo_configs[id].center_angle=150<<7;
-                        mmanager->servo_configs[id].max_speed=582;
-                        break;
-      case SERVO_RX10: mmanager->servo_configs[id].encoder_resolution=1023;
-                       mmanager->servo_configs[id].gear_ratio=193;
-                       mmanager->servo_configs[id].max_angle=300<<7;
-                       mmanager->servo_configs[id].center_angle=150<<7;
-                       mmanager->servo_configs[id].max_speed=324;
-                       break;
-      case SERVO_MX12W: mmanager->servo_configs[id].encoder_resolution=4095;
-                        mmanager->servo_configs[id].gear_ratio=32;
-                        mmanager->servo_configs[id].max_angle=360<<7;
-                        mmanager->servo_configs[id].center_angle=180<<7;
-                        mmanager->servo_configs[id].max_speed=2820;
-                        break;
-      case SERVO_MX28: mmanager->servo_configs[id].encoder_resolution=4095;
-                       mmanager->servo_configs[id].gear_ratio=193;
-                       mmanager->servo_configs[id].max_angle=360<<7;
-                       mmanager->servo_configs[id].center_angle=180<<7;
-                       mmanager->servo_configs[id].max_speed=330;
-                       break;
-      case SERVO_RX24F: mmanager->servo_configs[id].encoder_resolution=1023;
-                        mmanager->servo_configs[id].gear_ratio=193;
-                        mmanager->servo_configs[id].max_angle=300<<7;
-                        mmanager->servo_configs[id].center_angle=150<<7;
-                        mmanager->servo_configs[id].max_speed=756;
-                        break;
-      case SERVO_RX28: mmanager->servo_configs[id].encoder_resolution=1023;
-                       mmanager->servo_configs[id].gear_ratio=193;
-                       mmanager->servo_configs[id].max_angle=300<<7;
-                       mmanager->servo_configs[id].center_angle=150<<7;
-                       mmanager->servo_configs[id].max_speed=402;
-                       break;
-      case SERVO_RX64: mmanager->servo_configs[id].encoder_resolution=1023;
-                       mmanager->servo_configs[id].gear_ratio=200;
-                       mmanager->servo_configs[id].max_angle=300<<7;
-                       mmanager->servo_configs[id].center_angle=150<<7;
-                       mmanager->servo_configs[id].max_speed=294;
-                       break;
-      case SERVO_MX64: mmanager->servo_configs[id].encoder_resolution=4095;
-                       mmanager->servo_configs[id].gear_ratio=200;
-                       mmanager->servo_configs[id].max_angle=360<<7;
-                       mmanager->servo_configs[id].center_angle=180<<7;
-                       mmanager->servo_configs[id].max_speed=378;
-                       break;
-      case SERVO_EX106: mmanager->servo_configs[id].encoder_resolution=1023;
-                        mmanager->servo_configs[id].gear_ratio=184;
-                        mmanager->servo_configs[id].max_angle=250<<7;
-                        mmanager->servo_configs[id].center_angle=125<<7;
-                        mmanager->servo_configs[id].max_speed=414;
-                        break;
-      case SERVO_MX106: mmanager->servo_configs[id].encoder_resolution=4095;
-                        mmanager->servo_configs[id].gear_ratio=225;
-                        mmanager->servo_configs[id].max_angle=360<<7;
-                        mmanager->servo_configs[id].center_angle=180<<7;
-                        mmanager->servo_configs[id].max_speed=270;
-                        break;
-      case SERVO_XL320: mmanager->servo_configs[id].encoder_resolution=1023;
-                        mmanager->servo_configs[id].gear_ratio=238;
-                        mmanager->servo_configs[id].max_angle=300<<7;
-                        mmanager->servo_configs[id].center_angle=150<<7;
-                        mmanager->servo_configs[id].max_speed=684;
-                        break;
-      default: break;
-    }
-    // get the servo's current position
-    if(model==SERVO_XL320)
-    {
-      dyn_master_read_word(dyn_manager_get_device_master(mmanager->dyn_module.manager,id),id,XL_PRESENT_POSITION_L,&mmanager->servo_values[id].current_value);
-      dyn_master_read_word(dyn_manager_get_device_master(mmanager->dyn_module.manager,id),id,XL_CW_ANGLE_LIMIT_L,&cw_value);
-      dyn_master_read_word(dyn_manager_get_device_master(mmanager->dyn_module.manager,id),id,XL_CCW_ANGLE_LIMIT_L,&ccw_value);
-    }
-    else
-    {
-      dyn_master_read_word(dyn_manager_get_device_master(mmanager->dyn_module.manager,id),id,P_PRESENT_POSITION_L,&mmanager->servo_values[id].current_value);
-      dyn_master_read_word(dyn_manager_get_device_master(mmanager->dyn_module.manager,id),id,P_CW_ANGLE_LIMIT_L,&cw_value);
-      dyn_master_read_word(dyn_manager_get_device_master(mmanager->dyn_module.manager,id),id,P_CCW_ANGLE_LIMIT_L,&ccw_value);
-    }
+    for(i=0;i<NUM_SERVO_MODELS;i++)
+    if(model==servo_data[i].model)
+      mmanager->servo_configs[id]=&servo_data[i];
+
+    mmanager_read_register(mmanager,id,&mmanager->servo_configs[id]->registers[current_pos],&mmanager->servo_values[id].current_value);
+    mmanager_read_register(mmanager,id,&mmanager->servo_configs[id]->registers[min_angle_limit],&cw_value);
+    mmanager_read_register(mmanager,id,&mmanager->servo_configs[id]->registers[max_angle_limit],&ccw_value);
     mmanager->servo_values[id].target_value=mmanager->servo_values[id].current_value;
     mmanager->servo_values[id].current_angle=(mmanager_value_to_angle(mmanager,id,mmanager->servo_values[id].current_value)<<9);
     mmanager->servo_values[id].target_angle=mmanager->servo_values[id].current_angle;
     // read the servo limits
-    mmanager->servo_configs[id].cw_angle_limit=(mmanager_value_to_angle(mmanager,id,cw_value)<<9);
-    mmanager->servo_configs[id].ccw_angle_limit=(mmanager_value_to_angle(mmanager,id,ccw_value)<<9);
+    mmanager->servo_configs[id]->cw_angle_limit=(mmanager_value_to_angle(mmanager,id,cw_value)<<9);
+    mmanager->servo_configs[id]->ccw_angle_limit=(mmanager_value_to_angle(mmanager,id,ccw_value)<<9);
+    mmanager->present_servos|=(0x00000001<<id);
+    mmanager->memory->data[mmanager->ram_base_address+MM_PRESENT_SERVOS_OFFSET]=mmanager->present_servos&0x000000FF;
+    mmanager->memory->data[mmanager->ram_base_address+MM_PRESENT_SERVOS_OFFSET+1]=(mmanager->present_servos>>8)&0x000000FF;
+    mmanager->memory->data[mmanager->ram_base_address+MM_PRESENT_SERVOS_OFFSET+2]=(mmanager->present_servos>>16)&0x000000FF;
+    mmanager->memory->data[mmanager->ram_base_address+MM_PRESENT_SERVOS_OFFSET+3]=(mmanager->present_servos>>24)&0x000000FF;
   }
 }
 
@@ -196,55 +147,98 @@ void mmanager_setup(TMotionManager *mmanager)
   unsigned char ids[DYN_MANAGER_MAX_NUM_DEVICES];
   unsigned short int address[DYN_MANAGER_MAX_NUM_DEVICES];
   unsigned short int length[DYN_MANAGER_MAX_NUM_DEVICES];
-  unsigned char i,num=0;
+  unsigned char i,num=0,first=1;
+  unsigned short int start_address=0;
 
   // initialize the motion operation
   for(i=0;i<DYN_MANAGER_MAX_NUM_DEVICES;i++)
   {
     if(mmanager->dyn_module.assigned_ids[i]==0x01)
     {
-      data[num]=&mmanager->servo_values[i].cw_compliance;
-      ids[num]=i;
-      num++;
+      if(mmanager->servo_configs[i]->protocol_ver==1)
+      {
+        data[num]=&mmanager->servo_values[i].cw_compliance;
+        ids[num]=i;
+        num++;
+        if(first==1)
+        {
+          first=0;
+          if(mmanager->servo_configs[i]->pid==1)
+            start_address=mmanager->servo_configs[i]->registers[pos_pid_p].address;
+          else
+            start_address=mmanager->servo_configs[i]->registers[cw_comp_slope].address;
+        }
+      }
+    }
+  }
+  if(num>0)
+  {
+    if(mmanager->motion_op[0]!=0x00000000)
+      dyn_manager_delete_op(mmanager->dyn_module.manager,mmanager->motion_op[0]);
+    mmanager->motion_op[0]=dyn_manager_sync_op_new(mmanager->dyn_module.manager,DYN_MANAGER_WRITE,num,ids,start_address,4,(unsigned char * const*)&data);
+  }
+  num=0;
+  for(i=0;i<DYN_MANAGER_MAX_NUM_DEVICES;i++)
+  {
+    if(mmanager->dyn_module.assigned_ids[i]==0x01)
+    {
+      if(mmanager->servo_configs[i]->protocol_ver==2)
+      {
+        data[num]=(unsigned char *)&mmanager->servo_values[i].target_value;
+        ids[num]=i;
+        num++;
+        if(first==1)
+        {
+          first=0;
+          start_address=mmanager->servo_configs[i]->registers[goal_pos].address;
+        }
+      }
     }
   }
-  mmanager->motion_op=dyn_manager_sync_op_new(mmanager->dyn_module.manager,DYN_MANAGER_WRITE,num,ids,P_CW_COMPLIANCE_SLOPE,4,(unsigned char * const*)&data);
+  if(num>0)
+  {
+    if(mmanager->motion_op[1]!=0x00000000)
+      dyn_manager_delete_op(mmanager->dyn_module.manager,mmanager->motion_op[1]);
+    mmanager->motion_op[1]=dyn_manager_sync_op_new(mmanager->dyn_module.manager,DYN_MANAGER_WRITE,num,ids,start_address,2,(unsigned char * const*)&data);
+  }
   /* create a feedback operation with the servos that support bulk read */
   num=0;
   for(i=0;i<DYN_MANAGER_MAX_NUM_DEVICES;i++)
   {
     if(mmanager->dyn_module.assigned_ids[i]==0x01)
     {
-      if(HAS_BULK_READ(dyn_manager_get_device_model(mmanager->dyn_module.manager,i)))
+      if(mmanager->servo_configs[i]->protocol_ver==2)
       {
-        if(dyn_manager_get_device_model(mmanager->dyn_module.manager,i)==SERVO_XL320)
-          address[num]=XL_PRESENT_POSITION_L;
-        else
-          address[num]=P_PRESENT_POSITION_L;
+        address[num]=mmanager->servo_configs[i]->registers[current_pos].address;
         data[num]=(unsigned char *)&mmanager->servo_values[i].current_value;
-        length[num]=2;
+        length[num]=mmanager->servo_configs[i]->registers[current_pos].size;
         ids[num]=i;
         num++;
       }
     }
   }
-  mmanager->feedback_op=dyn_manager_bulk_op_new(mmanager->dyn_module.manager,DYN_MANAGER_READ,num,ids,address,length,(unsigned char * const*)data);
+  if(num>0)
+  {
+    if(mmanager->feedback_op[0]!=0x00000000)
+      dyn_manager_delete_op(mmanager->dyn_module.manager,mmanager->feedback_op[0]);
+    mmanager->feedback_op[0]=dyn_manager_bulk_op_new(mmanager->dyn_module.manager,DYN_MANAGER_READ,num,ids,address,length,(unsigned char * const*)data);
+  }
 }
 
-void mmanager_set_period(TMotionManager *mmanager,unsigned short int period_us)
+void mmanager_set_period(TMotionManager *mmanager,unsigned short period_ms)
 {
   unsigned char i;
 
-  for(i=0;i<MAX_NUM_MOTION_MODULES;i++)
-    if(mmanager->modules[i]->set_period!=0x00000000)
-      mmanager->modules[i]->set_period(mmanager->modules[i]->data,period_us*mmanager->dyn_module.period_count);
+  for(i=0;i<MM_MAX_NUM_MOTION_MODULES;i++)
+    if(mmanager->modules[i]!=0x00000000 && mmanager->modules[i]->set_period!=0x00000000)
+      mmanager->modules[i]->set_period(mmanager->modules[i]->data,period_ms);
 }
 
 void mmanager_pre_process(TMotionManager *mmanager)
 {
   unsigned char i;
 
-  for(i=0;i<MAX_NUM_MOTION_MODULES;i++)
+  for(i=0;i<MM_MAX_NUM_MOTION_MODULES;i++)
   {
     if(mmanager->modules[i]!=0x00000000 && mmanager->modules[i]->pre_process!=0x00000000)
       mmanager->modules[i]->pre_process(mmanager->modules[i]->data);
@@ -259,7 +253,7 @@ void mmanager_post_process(TMotionManager *mmanager)
 
   /* transform the current values to angles */
   mmanager_compute_angles(mmanager);
-  for(i=0;i<MAX_NUM_MOTION_MODULES;i++)
+  for(i=0;i<MM_MAX_NUM_MOTION_MODULES;i++)
   {
     if(mmanager->modules[i]!=0x00000000 && mmanager->modules[i]->post_process!=0x00000000)
       mmanager->modules[i]->post_process(mmanager->modules[i]->data);
@@ -267,29 +261,15 @@ void mmanager_post_process(TMotionManager *mmanager)
 }
 
 /* public functions */
-unsigned char mmanager_init(TMotionManager *mmanager,TMemory *memory)
+unsigned char mmanager_init(TMotionManager *mmanager,TMemory *memory,unsigned short int ram_base_address,unsigned short int eeprom_base_address)
 {
   unsigned char i;
 
   /* initialize the base module */
-  dyn_module_init(&mmanager->dyn_module);
+  dyn_module_init(&mmanager->dyn_module,memory,ram_base_address,eeprom_base_address);
   /* add all known servo models */
-  dyn_module_add_model(&mmanager->dyn_module,SERVO_DX113);
-  dyn_module_add_model(&mmanager->dyn_module,SERVO_DX116);
-  dyn_module_add_model(&mmanager->dyn_module,SERVO_DX117);
-  dyn_module_add_model(&mmanager->dyn_module,SERVO_AX12A);
-  dyn_module_add_model(&mmanager->dyn_module,SERVO_AX12W);
-  dyn_module_add_model(&mmanager->dyn_module,SERVO_AX18A);
-  dyn_module_add_model(&mmanager->dyn_module,SERVO_RX10);
-  dyn_module_add_model(&mmanager->dyn_module,SERVO_MX12W);
-  dyn_module_add_model(&mmanager->dyn_module,SERVO_MX28);
-  dyn_module_add_model(&mmanager->dyn_module,SERVO_RX24F);
-  dyn_module_add_model(&mmanager->dyn_module,SERVO_RX28);
-  dyn_module_add_model(&mmanager->dyn_module,SERVO_RX64);
-  dyn_module_add_model(&mmanager->dyn_module,SERVO_MX64);
-  dyn_module_add_model(&mmanager->dyn_module,SERVO_EX106);
-  dyn_module_add_model(&mmanager->dyn_module,SERVO_MX106);
-  dyn_module_add_model(&mmanager->dyn_module,SERVO_XL320);
+  for(i=0;i<NUM_SERVO_MODELS;i++)
+    dyn_module_add_model(&mmanager->dyn_module,servo_data[i].model);
   mmanager->dyn_module.data=mmanager;
   mmanager->dyn_module.add_device=(void (*)(void *,unsigned char,unsigned short int))mmanager_add_device;
   mmanager->dyn_module.setup=(void (*)(void *))mmanager_setup;
@@ -300,19 +280,12 @@ unsigned char mmanager_init(TMotionManager *mmanager,TMemory *memory)
   mmanager->balance_enabled=0x00;
   mmanager->num_modules=0x00;
   /* initialize motion module base attributes */
-  for(i=0;i<MAX_NUM_MOTION_MODULES;i++)
+  for(i=0;i<MM_MAX_NUM_MOTION_MODULES;i++)
     mmanager->modules[i]=0x00000000;
   for(i=0;i<DYN_MANAGER_MAX_NUM_DEVICES;i++)
   {
     /* servo configuration */
-    mmanager->servo_configs[i].model=0x0000;
-    mmanager->servo_configs[i].encoder_resolution=0x0000;
-    mmanager->servo_configs[i].gear_ratio=0x00;
-    mmanager->servo_configs[i].max_angle=0x0000;
-    mmanager->servo_configs[i].center_angle=0x0000;
-    mmanager->servo_configs[i].max_speed=0x0000;
-    mmanager->servo_configs[i].cw_angle_limit=0;
-    mmanager->servo_configs[i].ccw_angle_limit=0;
+    mmanager->servo_configs[i]=0x00000000;
     /* servo values */
     mmanager->servo_values[i].cw_compliance=0x00;
     mmanager->servo_values[i].ccw_compliance=0x00;
@@ -325,46 +298,33 @@ unsigned char mmanager_init(TMotionManager *mmanager,TMemory *memory)
     mmanager->servo_values[i].offset=0x00;
   }
   mmanager->enable_op=0x00000000;
-  mmanager->motion_op=0x00000000;
-  mmanager->feedback_op=0x00000000;
+  mmanager->motion_op[0]=0x00000000;
+  mmanager->motion_op[1]=0x00000000;
+  mmanager->feedback_op[0]=0x00000000;
+  mmanager->feedback_op[1]=0x00000000;
   mmanager->balance=0x00000000;
+  mmanager->present_servos=0x00000000;
 
   /* initialize memory module */
-  mem_module_init(&manager->mem_module);
-  manager->mem_module.data=manager;
-  manager->mem_module.write_cmd=mmanager_write_cmd;
-  manager->mem_module.read_cmd=mmanager_read_cmd;
-  if(!mem_module_add_ram_segment(&manager->mem_module,RAM_MM_BASE_ADDRESS,RAM_MM_LENGTH))
+  mem_module_init(&mmanager->mem_module);
+  mmanager->mem_module.data=mmanager;
+  mmanager->mem_module.write_cmd=mmanager_write_cmd;
+  mmanager->mem_module.read_cmd=mmanager_read_cmd;
+  if(!mem_module_add_ram_segment(&mmanager->mem_module,ram_base_address+RAM_DYN_MODULE_LENGTH,RAM_MM_LENGTH))
     return 0x00;
-  if(!mem_module_add_eeprom_segment(&manager->mem_module,EEPROM_MM_BASE_ADDRESS,EEPROM_MM_LENGTH))
+  mmanager->ram_base_address=ram_base_address+RAM_DYN_MODULE_LENGTH;
+  if(!mem_module_add_eeprom_segment(&mmanager->mem_module,eeprom_base_address+EEPROM_DYN_MODULE_LENGTH,EEPROM_MM_LENGTH))
     return 0x00;
-  if(!mem_add_module(memory,&manager->mem_module))
+  mmanager->eeprom_base_address=eeprom_base_address+EEPROM_DYN_MODULE_LENGTH;
+  if(!mem_add_module(memory,&mmanager->mem_module))
     return 0x00;
+  mmanager->memory=memory;
+  for(i=0;i<DYN_MANAGER_MAX_NUM_DEVICES/2;i++)
+    mmanager->memory->data[ram_base_address+MM_ENABLE_MODULE_OFFSET+i]=0x77;
 
   return 0x01;
 }
 
-TDynModule *mmanager_get_dyn_module(TMotionManager *mmanager)
-{
-  return &mmanager->dyn_module;
-}
-
-void mmanager_enable_balance(TMotionManager *mmanager)
-{
-  if(mmanager->balance!=0x00000000)
-    mmanager->balance_enabled=0x01;
-}
-
-void mmanager_disable_balance(TMotionManager *mmanager)
-{
-  mmanager->balance_enabled=0x00;
-}
-
-unsigned char mmanager_is_balance_enabled(TMotionManager *mmanager)
-{
-  return mmanager->balance_enabled;
-}
-
 void mmanager_set_module(TMotionManager *mmanager,unsigned char servo_id,TModules module)
 {
   if(servo_id<DYN_MANAGER_MAX_NUM_DEVICES)
@@ -394,13 +354,16 @@ void mmanager_enable_servo(TMotionManager *mmanager,unsigned char servo_id)
   {
     mmanager->servo_values[servo_id].enabled=0x01;
     /* add an operation to enable the servo */
-    if(mmanager->enable_op==0x00000000 || mmanager->enable_op->op_type==no_op)
+    if(mmanager->servo_configs[servo_id]!=0x00000000)
     {
-      mmanager->enable_op=dyn_manager_sync_op_new(mmanager->dyn_module.manager,DYN_MANAGER_WRITE,1,&servo_id,P_TORQUE_ENABLE,1,&data);
-      dyn_manager_set_op_repetitions(mmanager->dyn_module.manager,mmanager->enable_op,1);
+      if(mmanager->enable_op==0x00000000 || mmanager->enable_op->op_type==no_op)
+      {
+        mmanager->enable_op=dyn_manager_sync_op_new(mmanager->dyn_module.manager,DYN_MANAGER_WRITE,1,&servo_id,mmanager->servo_configs[servo_id]->registers[torque_en].address,1,&data);
+        dyn_manager_set_op_repetitions(mmanager->dyn_module.manager,mmanager->enable_op,1);
+      }
+      else
+        dyn_manager_sync_op_add_devices(mmanager->dyn_module.manager,mmanager->enable_op,1,&servo_id,&data);
     }
-    else
-      dyn_manager_sync_op_add_devices(mmanager->dyn_module.manager,mmanager->enable_op,1,&servo_id,&data);
   }
 }
 
@@ -412,13 +375,16 @@ void mmanager_disable_servo(TMotionManager *mmanager,unsigned char servo_id)
   {
     mmanager->servo_values[servo_id].enabled=0x00;
     /* add an operation to enable the servo */
-    if(mmanager->enable_op==0x00000000 || mmanager->enable_op->op_type==no_op)
+    if(mmanager->servo_configs[servo_id]!=0x00000000)
     {
-      mmanager->enable_op=dyn_manager_sync_op_new(mmanager->dyn_module.manager,DYN_MANAGER_WRITE,1,&servo_id,P_TORQUE_ENABLE,1,&data);
-      dyn_manager_set_op_repetitions(mmanager->dyn_module.manager,mmanager->enable_op,1);
+      if(mmanager->enable_op==0x00000000 || mmanager->enable_op->op_type==no_op)
+      {
+        mmanager->enable_op=dyn_manager_sync_op_new(mmanager->dyn_module.manager,DYN_MANAGER_WRITE,1,&servo_id,mmanager->servo_configs[servo_id]->registers[torque_en].address,1,&data);
+        dyn_manager_set_op_repetitions(mmanager->dyn_module.manager,mmanager->enable_op,1);
+      }
+      else
+        dyn_manager_sync_op_add_devices(mmanager->dyn_module.manager,mmanager->enable_op,1,&servo_id,&data);
     }
-    else
-      dyn_manager_sync_op_add_devices(mmanager->dyn_module.manager,mmanager->enable_op,1,&servo_id,&data);
   }
 }
 
@@ -430,12 +396,6 @@ unsigned char mmanager_is_servo_enabled(TMotionManager *mmanager,unsigned char s
     return 0x00;
 }
 
-void mmanager_set_offset(TMotionManager *mmanager,unsigned char servo_id,char offset)
-{
-  if(servo_id<DYN_MANAGER_MAX_NUM_DEVICES)
-    mmanager->servo_values[servo_id].offset=offset;
-}
-
 void mmanager_add_module(TMotionManager *mmanager,TMotionModule *module)
 {
   if(module->id!=MM_NONE)
diff --git a/dynamixel_manager/src/modules/motion_pages.c b/dynamixel_manager/src/modules/motion_pages.c
index bf4f7d8a10551d3545493e0aa698a5088e136666..34bec5e5cb174d3825a84f1d76b7fcb25c88fad5 100755
--- a/dynamixel_manager/src/modules/motion_pages.c
+++ b/dynamixel_manager/src/modules/motion_pages.c
@@ -42,4 +42,4 @@ inline unsigned char pages_get_slope(TPage *page,unsigned char servo_id)
   return 0x01<<(page->header.slope[servo_id]&0x0F);
 }
 
-TPage motion_pages[MAX_PAGES] __attribute__ ((section (".pages"))) __attribute__((weak)) ;
+TPage motion_pages[MAX_PAGES] __attribute__ ((section (".pages"))) __attribute__((weak));
diff --git a/dynamixel_manager/test/Makefile b/dynamixel_manager/test/Makefile
index 5ebaf504ae096678463832ddd32da27cbd77bb57..76bfa2cd86f2ccf8ed4898b663537f42595ef0eb 100755
--- a/dynamixel_manager/test/Makefile
+++ b/dynamixel_manager/test/Makefile
@@ -7,10 +7,14 @@ TARGET_FILES+=$(wildcard ../src/modules/*.c)
 TARGET_FILES+=$(wildcard ../src/*.c)
 TARGET_FILES+=$(wildcard ../../utils/src/*.c)
 TARGET_FILES+=$(wildcard ../../comm/src/*.c)
+TARGET_FILES+=$(wildcard ../../memory/src/*.c)
+TARGET_FILES+=$(wildcard ../../scheduler/src/*.c)
 BUILD_PATH=build
 BIN_PATH=bin
 
-INCLUDE_DIRS = -I../include -I../include/modules -I../../utils/include -I../../comm/include -I../../dynamixel_base/include
+INCLUDE_DIRS = -I../include -I../include/modules -I../../utils/include -I../../comm/include -I ../../memory/include -I../../dynamixel_base/include -I../../scheduler/include
+
+MACROS = -DMAX_DYN_MASTER_TX_BUFFER_LEN=256 -DMAX_DYN_MASTER_RX_BUFFER_LEN=256 -DDYN_MANAGER_MAX_NUM_MASTERS=4 -DDYN_MANAGER_MAX_NUM_MODULES=8 -DDYN_MANAGER_MAX_NUM_DEVICES=32 -DDYN_MANAGER_MAX_NUM_SINGLE_OP=16 -DDYN_MANAGER_MAX_NUM_SYNC_OP=4 -DDYN_MANAGER_MAX_NUM_BULK_OP=4 -DMODULE_MAX_NUM_MODELS=32 -DMM_MAX_NUM_MOTION_MODULES=8 -DEEPROM_SIZE=64 -DRAM_SIZE=1024
 
 CC = gcc
 
@@ -26,19 +30,25 @@ make_dirs:
 	mkdir -p $(BIN_PATH)
 
 $(BUILD_PATH)/%.o: %.c
-	$(CC) -c -g $(INCLUDE_DIRS) -o $@ $<
+	$(CC) -c -g $(INCLUDE_DIRS) $(MACROS) -o $@ $<
 
 $(BUILD_PATH)/%.o: ../src/%.c
-	$(CC) -c -g $(INCLUDE_DIRS) -o $@ $<
+	$(CC) -c -g $(INCLUDE_DIRS) $(MACROS) -o $@ $<
 
 $(BUILD_PATH)/%.o: ../src/modules/%.c
-	$(CC) -c -g $(INCLUDE_DIRS) -o $@ $<
+	$(CC) -c -g $(INCLUDE_DIRS) $(MACROS) -o $@ $<
 
 $(BUILD_PATH)/%.o: ../../utils/src/%.c
-	$(CC) -c -g $(INCLUDE_DIRS) -o $@ $<
+	$(CC) -c -g $(INCLUDE_DIRS) $(MACROS) -o $@ $<
 
 $(BUILD_PATH)/%.o: ../../comm/src/%.c
-	$(CC) -c -g $(INCLUDE_DIRS) -o $@ $<
+	$(CC) -c -g $(INCLUDE_DIRS) $(MACROS) -o $@ $<
+
+$(BUILD_PATH)/%.o: ../../memory/src/%.c
+	$(CC) -c -g $(INCLUDE_DIRS) $(MACROS) -o $@ $<
+
+$(BUILD_PATH)/%.o: ../../scheduler/src/%.c
+	$(CC) -c -g $(INCLUDE_DIRS) $(MACROS) -o $@ $<
 
 $(OUT_FILE): make_dirs $(TEST_OBJS) 
 	$(CC) -g $(TEST_OBJS) -lpthread --output $@
diff --git a/dynamixel_manager/test/dyn_man_test.c b/dynamixel_manager/test/dyn_man_test.c
index ccaf642ef95ed60437a0632979739dd30f405b56..db11313e2cf84aef072d3d9b6a63202ac44fba79 100644
--- a/dynamixel_manager/test/dyn_man_test.c
+++ b/dynamixel_manager/test/dyn_man_test.c
@@ -6,10 +6,15 @@
 #include "motion_manager.h"
 #include "action.h"
 #include "dyn_servos.h"
+#include "scheduler.h"
 
 TDynamixelMaster dyn_master1;
 TDynamixelMaster dyn_master2;
 TDynManager manager;
+TMemory memory;
+TScheduler scheduler;
+
+unsigned int SystemCoreClock=168000000;
 
 // timer functions
 unsigned long long int time_get_counts(void)
@@ -92,6 +97,12 @@ void dyn_master_scan(TDynamixelMaster *master,unsigned char *num,unsigned char *
   }
 }
 
+unsigned char dyn_master_read_table(TDynamixelMaster *master,unsigned char id,unsigned short int address,unsigned short int length,unsigned char *data)
+{
+  if(length==2)
+    dyn_master_read_word(master,id,address,(unsigned short int *)data);
+}
+
 unsigned char dyn_master_read_word(TDynamixelMaster *master,unsigned char id,unsigned short int address,unsigned short int *data)
 {
   if(master==&dyn_master1)
@@ -137,11 +148,11 @@ unsigned char dyn_master_read_word(TDynamixelMaster *master,unsigned char id,uns
 
 unsigned char dyn_master_start_read_table(TDynamixelMaster *master,unsigned char id,unsigned short int address,unsigned short int length,unsigned char *data)
 {
-  if(master==&dyn_master1)
-    printf("Master 1\n");
-  else
-    printf("Master 2\n");
-  printf("  read operation to servo %d at address %d with length %d\n",id,address,length);
+//  if(master==&dyn_master1)
+//    printf("Master 1\n");
+//  else
+//    printf("Master 2\n");
+//  printf("  read operation to servo %d at address %d with length %d\n",id,address,length);
 
   return DYN_SUCCESS;
 }
@@ -155,14 +166,14 @@ unsigned char dyn_master_start_write_table(TDynamixelMaster *master,unsigned cha
 {
   unsigned short int i;
 
-  if(master==&dyn_master1)
-    printf("Master 1\n");
-  else
-    printf("Master 2\n");
-  printf("  write operation to servo %d at address %d with length %d\n",id,address,length);
-  printf("  data:\n");
-  for(i=0;i<length;i++)
-    printf("    0x%x\n",data[i]);
+//  if(master==&dyn_master1)
+//    printf("Master 1\n");
+//  else
+//    printf("Master 2\n");
+//  printf("  write operation to servo %d at address %d with length %d\n",id,address,length);
+//  printf("  data:\n");
+//  for(i=0;i<length;i++)
+//    printf("    0x%x\n",data[i]);
 
   return DYN_SUCCESS;
 }
@@ -176,23 +187,23 @@ unsigned char dyn_master_start_sync_write(TDynamixelMaster *master,unsigned char
 {
   unsigned short int i,j;
 
-  if(master==&dyn_master1)
-    printf("Master 1\n");
-  else
-    printf("Master 2\n");
-  printf("  sync write operation at address %d with length %d\n",address,length);
-  for(j=0;j<num;j++)
-  {
-    printf("  servo %d data:\n",ids[j]);
-    for(i=0;i<length;i++)
-      printf("    0x%x\n",data[j][i]);
-  }
-/*  if(master==&dyn_master1 && address==P_CW_COMPLIANCE_SLOPE && length==4)
+//  if(master==&dyn_master1)
+//    printf("Master 1\n");
+//  else
+//    printf("Master 2\n");
+//  printf("  sync write operation at address %d with length %d\n",address,length);
+//  for(j=0;j<num;j++)
+//  {
+//    printf("  servo %d data:\n",ids[j]);
+//    for(i=0;i<length;i++)
+//      printf("    0x%x\n",data[j][i]);
+//  }
+  if(master==&dyn_master1 && address==ax_reg[cw_comp_slope].address && length==4)
   {
     for(i=0;i<num;i++)
       printf("%d,",data[i][2]+(data[i][3]<<8));
     printf("\n");
-  }*/
+  }
 
   return DYN_SUCCESS;
 }
@@ -206,13 +217,13 @@ unsigned char dyn_master_start_sync_read(TDynamixelMaster *master,unsigned char
 {
   unsigned short int i;
 
-  if(master==&dyn_master1)
-    printf("Master 1\n");
-  else
-    printf("Master 2\n");
-  printf("  sync read operation at address %d with length %d for servos:\n",address,length);
-  for(i=0;i<num;i++)
-    printf("  servo %d:\n",ids[i]);
+//  if(master==&dyn_master1)
+//    printf("Master 1\n");
+//  else
+//    printf("Master 2\n");
+//  printf("  sync read operation at address %d with length %d for servos:\n",address,length);
+//  for(i=0;i<num;i++)
+//    printf("  servo %d:\n",ids[i]);
 
   return DYN_SUCCESS;
 }
@@ -226,17 +237,17 @@ unsigned char dyn_master_start_bulk_write(TDynamixelMaster *master,unsigned char
 {
   unsigned short int i,j;
 
-  if(master==&dyn_master1)
-    printf("Master 1\n");
-  else
-    printf("Master 2\n");
-  printf("  bulk write operation:\n");
-  for(j=0;j<num;j++)
-  {
-    printf("  servo %d at address %d with length %d and data:\n",ids[j],address[j],length[j]);
-    for(i=0;i<length[j];i++)
-      printf("    0x%x\n",data[j][i]);
-  }
+//  if(master==&dyn_master1)
+//    printf("Master 1\n");
+//  else
+//    printf("Master 2\n");
+//  printf("  bulk write operation:\n");
+//  for(j=0;j<num;j++)
+//  {
+//    printf("  servo %d at address %d with length %d and data:\n",ids[j],address[j],length[j]);
+//    for(i=0;i<length[j];i++)
+//      printf("    0x%x\n",data[j][i]);
+//  }
 
   return DYN_SUCCESS;
 }
@@ -250,13 +261,13 @@ unsigned char dyn_master_start_bulk_read(TDynamixelMaster *master,unsigned char
 {
   unsigned short int i,j;
 
-  if(master==&dyn_master1)
-    printf("Master 1\n");
-  else
-    printf("Master 2\n");
-  printf("  bulk read operation:\n");
-  for(j=0;j<num;j++)
-    printf("  servo %d at address %d with length %d\n",ids[j],address[j],length[j]);
+//  if(master==&dyn_master1)
+//    printf("Master 1\n");
+//  else
+//    printf("Master 2\n");
+//  printf("  bulk read operation:\n");
+//  for(j=0;j<num;j++)
+//    printf("  servo %d at address %d with length %d\n",ids[j],address[j],length[j]);
 
   return DYN_SUCCESS;
 }
@@ -270,18 +281,14 @@ int main(void)
 {
   int i;
   TMotionManager mmanager;
+  TActionMModule action;
   TTime dyn_master1_timer; 
   TComm dyn_master1_comm;
   TTime dyn_master2_timer; 
   TComm dyn_master2_comm;
 
-  // init modules
-  mmanager_init(&mmanager);
-  action_init();
-  mmanager_add_module(&mmanager,action_get_module());
-  dyn_module_set_period(mmanager_get_dyn_module(&mmanager),1);
-  dyn_module_enable(mmanager_get_dyn_module(&mmanager));
-  
+  scheduler_init(&scheduler,1,100);
+
   // init masters
   time_init(&dyn_master1_timer,time_get_counts_per_us(),time_get_counts);
   comm_init(&dyn_master1_comm,0x01,&dyn_master1_timer);
@@ -290,10 +297,17 @@ int main(void)
   comm_init(&dyn_master2_comm,0x01,&dyn_master2_timer);
   dyn_master_init(&dyn_master2,&dyn_master2_comm,DYN_VER2);
 
-  dyn_manager_init(&manager);
+  dyn_manager_init(&manager,&memory,&scheduler,SCHED_CH1,0,64);
+  dyn_manager_set_period(&manager,14);
   dyn_manager_add_master(&manager,&dyn_master1);
   dyn_manager_add_master(&manager,&dyn_master2);
+  // init modules
+  mmanager_init(&mmanager,&memory,16,128);
+  action_init(&action,&memory,256);
+  mmanager_add_module(&mmanager,action_get_module(&action));
   dyn_manager_add_module(&manager,mmanager_get_dyn_module(&mmanager));
+  dyn_module_set_period(mmanager_get_dyn_module(&mmanager),1);
+  dyn_module_enable(mmanager_get_dyn_module(&mmanager));
   dyn_manager_scan(&manager);
 
   /* enable all servos and assign them to the ACTION module */
@@ -303,12 +317,12 @@ int main(void)
     mmanager_enable_servo(&mmanager,i);
   }
   /* load and start a page */
-  if(action_load_page(9))
-    action_start_page(); 
+  if(action_load_page(&action,7))
+    action_start_page(&action); 
 
-  for(i=0;i<10;i++)
+  for(i=0;i<100;i++)
   {
-    printf("***** Iteration %d *****\n",i);
+//    printf("***** Iteration %d *****\n",i);
     dyn_manager_loop(&manager);
   }
 }
diff --git a/memory/include/memory.h b/memory/include/memory.h
index 7eec4003a4352025704b164f72c58ec60afd538e..9e26965f60f8333c2002cda835427478d06717af 100644
--- a/memory/include/memory.h
+++ b/memory/include/memory.h
@@ -19,7 +19,6 @@ typedef struct
 {
   unsigned char num_mem_modules;
   TMemModule *mem_modules[MAX_NUM_MEM_MODULES];
-  unsigned char device_id;
   unsigned short int (*eeprom_write_data)(unsigned short int address,unsigned short int data);
   unsigned short int (*eeprom_read_data)(unsigned short int address,unsigned short int *data);
   unsigned char data[RAM_SIZE];
@@ -27,7 +26,7 @@ typedef struct
   unsigned char total_ram;
 }TMemory;
 
-void mem_init(TMemory *memory,unsigned char device_id);
+void mem_init(TMemory *memory);
 void mem_initialize_data(TMemory *memory);
 unsigned char mem_add_module(TMemory *memory, TMemModule *module);
 void mem_do_write(TMemory *memory,unsigned short int start_address,unsigned short int length,unsigned char *data);
diff --git a/memory/include/ram.h b/memory/include/ram.h
index ef2325be11b6a051e479edb100e92ec326d1f876..2b6696a7820622e7025238d5e9ec6efed3eac4b0 100644
--- a/memory/include/ram.h
+++ b/memory/include/ram.h
@@ -14,11 +14,11 @@ extern "C" {
 #define      RAM_BAD_ACCESS   -4
 
 unsigned char ram_init(TMemory *memory);
-inline void ram_read_byte(TMemory *memory,unsigned short int address, unsigned char *data)
+static inline void ram_read_byte(TMemory *memory,unsigned short int address, unsigned char *data)
 {
   (*data)=memory->data[address];
 }
-inline void ram_read_word(TMemory *memory,unsigned short int address, unsigned short int *data)
+static inline void ram_read_word(TMemory *memory,unsigned short int address, unsigned short int *data)
 {
   (*data)=memory->data[address];
   (*data)+=memory->data[address+1]*256;
@@ -29,7 +29,7 @@ unsigned char ram_clear_bit(TMemory *memory,unsigned short int address, unsigned
 unsigned char ram_write_byte(TMemory *memory,unsigned short int address, unsigned char data);
 unsigned char ram_write_word(TMemory *memory,unsigned short int address, unsigned short int data);
 unsigned char ram_write_table(TMemory *memory,unsigned short int address, unsigned short int length,unsigned char *data);
-inline unsigned char ram_in_range(unsigned short int reg,unsigned short int address,unsigned short int length)
+static inline unsigned char ram_in_range(unsigned short int reg,unsigned short int address,unsigned short int length)
 {
   if(reg>=address && reg<(address+length))
     return 0x01;
diff --git a/memory/src/memory.c b/memory/src/memory.c
index af30fbf36f18d9c31e08b50fa672aa12e2b4cf57..a2c9e59c2fdc9d6df8736b5f27c3460dae4ef171 100644
--- a/memory/src/memory.c
+++ b/memory/src/memory.c
@@ -17,7 +17,7 @@ unsigned char mem_in_window(unsigned short int mem_start_address,unsigned short
 }
 
 /* public functions */
-void mem_init(TMemory *memory,unsigned char device_id)
+void mem_init(TMemory *memory)
 {
   unsigned char i;
 
@@ -26,7 +26,6 @@ void mem_init(TMemory *memory,unsigned char device_id)
     memory->mem_modules[i]=0x00000000;
   memory->eeprom_write_data=0x00000000;
   memory->eeprom_read_data=0x00000000;
-  memory->device_id=device_id;
 
   /* initialize internal variables */
   memory->total_eeprom=0;
@@ -45,7 +44,7 @@ void mem_initialize_data(TMemory *memory)
   {
     for(i=0;i<EEPROM_SIZE;i++)
     {
-      if(memory->eeprom_read_data((memory->device_id<<8)+i,&data))
+      if(memory->eeprom_read_data(i,&data))
         eeprom_data[i]=0x00;
       else
         eeprom_data[i]=data&0x00FF;
@@ -192,7 +191,7 @@ void mem_do_write(TMemory *memory,unsigned short int start_address,unsigned shor
           mem_module->write_cmd(mem_module->data,actual_address,actual_length,&data[actual_address-start_address]);
         if(memory->eeprom_write_data!=0x00000000)
           for(k=actual_address;k<(actual_address+actual_length);k++)
-            memory->eeprom_write_data((memory->device_id<<8)+k,data[k-start_address]);
+            memory->eeprom_write_data(k,data[k-start_address]);
       }
     }
   }
diff --git a/scheduler/include/scheduler.h b/scheduler/include/scheduler.h
index 0effa946db7e27abd75e62ddef208306c0f7b5f1..40b835104285c1c424fd69d12353fc00fb5b77f0 100644
--- a/scheduler/include/scheduler.h
+++ b/scheduler/include/scheduler.h
@@ -32,6 +32,7 @@ typedef struct{
   unsigned char period_ms;
   unsigned int pulse;
   unsigned char enabled;
+  unsigned char one_shot;
   void *data;
 }TSchedulerChannel;
 
@@ -48,8 +49,10 @@ void scheduler_init(TScheduler *scheduler,unsigned char num_channels, unsigned s
 void scheduler_interrupt(TScheduler *scheduler,sched_channel_t channel_id);
 unsigned short int scheduler_get_pulse(TScheduler *scheduler, sched_channel_t channel_id);
 void scheduler_set_channel(TScheduler *scheduler,sched_channel_t channel_id, void (*function)(void *data), unsigned char period_ms,void *data);
+void scheduler_set_channel_one_shot(TScheduler *scheduler,sched_channel_t channel_id, void (*function)(void *data), unsigned char delay_ms,void *data);
 void scheduler_enable_channel(TScheduler *scheduler,sched_channel_t channel_id);
 void scheduler_change_period(TScheduler *scheduler,sched_channel_t channel_id,unsigned char period_ms);
+void scheduler_change_delay(TScheduler *scheduler,sched_channel_t channel_id,unsigned char delay_ms);
 void scheduler_disable_channel(TScheduler *scheduler,sched_channel_t channel_id);
 
 #ifdef __cplusplus
diff --git a/scheduler/src/scheduler.c b/scheduler/src/scheduler.c
index d4f420decf26a9cba28e4f6439e294d40fbfd79c..a7501520384d9cd7af5c2fb34c72ddd4f947052c 100644
--- a/scheduler/src/scheduler.c
+++ b/scheduler/src/scheduler.c
@@ -29,6 +29,7 @@ void scheduler_init(TScheduler *scheduler,unsigned char num_channels, unsigned s
     scheduler->channels[i].function=0x00000000;
     scheduler->channels[i].period_ms=0;
     scheduler->channels[i].enabled=0x00;
+    scheduler->channels[i].one_shot=0x00;
   }
   scheduler->num_channels=num_channels;
   scheduler->prescaler=prescaler;
@@ -41,10 +42,19 @@ void scheduler_interrupt(TScheduler *scheduler,sched_channel_t channel_id)
 {
   if(channel_id<scheduler->num_channels)
   {
-    if(scheduler->set_pulse!=0x00000000)
-      scheduler->set_pulse(scheduler_get_channel(channel_id),scheduler->channels[channel_id].pulse,0x01);
-    if(scheduler->channels[channel_id].function!=0x00000000)
-      scheduler->channels[channel_id].function(scheduler->channels[channel_id].data);
+    if(scheduler->channels[channel_id].one_shot==0x00)
+    {
+      if(scheduler->set_pulse!=0x00000000)
+        scheduler->set_pulse(scheduler_get_channel(channel_id),scheduler->channels[channel_id].pulse,0x01);
+      if(scheduler->channels[channel_id].function!=0x00000000)
+        scheduler->channels[channel_id].function(scheduler->channels[channel_id].data);
+    }
+    else
+    {
+      if(scheduler->channels[channel_id].function!=0x00000000)
+        scheduler->channels[channel_id].function(scheduler->channels[channel_id].data);
+      scheduler_disable_channel(scheduler,channel_id);
+    }
   }
 }
 
@@ -62,6 +72,25 @@ void scheduler_set_channel(TScheduler *scheduler,sched_channel_t channel_id, voi
     scheduler->channels[channel_id].period_ms=period_ms;
     scheduler->channels[channel_id].pulse=scheduler_ms_to_pulse(scheduler,period_ms);
     scheduler->channels[channel_id].data=data;
+    scheduler->channels[channel_id].one_shot=0x00;
+  }
+}
+
+void scheduler_set_channel_one_shot(TScheduler *scheduler,sched_channel_t channel_id, void (*function)(void *data), unsigned char delay_ms,void *data)
+{
+  if(channel_id<scheduler->num_channels)
+  {
+    if(scheduler->channels[channel_id].enabled==0x01)
+    {
+      if(scheduler->stop!=0x00000000)
+        scheduler->stop(channel_id);
+      scheduler->channels[channel_id].enabled=0x00;
+    }
+    scheduler->channels[channel_id].function=function;
+    scheduler->channels[channel_id].period_ms=delay_ms;
+    scheduler->channels[channel_id].pulse=scheduler_ms_to_pulse(scheduler,delay_ms);
+    scheduler->channels[channel_id].data=data;
+    scheduler->channels[channel_id].one_shot=0x01;
   }
 }
 
@@ -83,7 +112,25 @@ void scheduler_enable_channel(TScheduler *scheduler,sched_channel_t channel_id)
 void scheduler_change_period(TScheduler *scheduler,sched_channel_t channel_id,unsigned char period_ms)
 {
   if(channel_id<scheduler->num_channels)
-    scheduler->channels[channel_id].period_ms=period_ms;
+  {
+    if(scheduler->channels[channel_id].one_shot==0x00)
+    {
+      scheduler->channels[channel_id].period_ms=period_ms;
+      scheduler->channels[channel_id].pulse=scheduler_ms_to_pulse(scheduler,period_ms);
+    }
+  }
+}
+
+void scheduler_change_delay(TScheduler *scheduler,sched_channel_t channel_id,unsigned char delay_ms)
+{
+  if(channel_id<scheduler->num_channels)
+  {
+    if(scheduler->channels[channel_id].one_shot==0x01)
+    {
+      scheduler->channels[channel_id].period_ms=delay_ms;
+      scheduler->channels[channel_id].pulse=scheduler_ms_to_pulse(scheduler,delay_ms);
+    }
+  }
 }
 
 void scheduler_disable_channel(TScheduler *scheduler,sched_channel_t channel_id)