diff --git a/communications/Makefile b/communications/Makefile
index a2382b4cbf8c7873331f76ee4ba386823dce806e..cd714da6eb59cc665f3559b63d0fa3035d3048ca 100644
--- a/communications/Makefile
+++ b/communications/Makefile
@@ -20,7 +20,7 @@ ARFLAGS=rsc
 
 .PHONY: show_banner all
 
-all: show_banner $(PROJECT).a examples
+all: show_banner $(PROJECT).a 
 
 show_banner:
 	@echo "------------------------------------------------------";
diff --git a/communications/include/comm_cfg.h b/communications/include/comm_cfg.h
new file mode 100644
index 0000000000000000000000000000000000000000..454edd881749c3ab5c5fa892726b6ca083a13006
--- /dev/null
+++ b/communications/include/comm_cfg.h
@@ -0,0 +1,24 @@
+#ifndef _COMM_CFG_H
+#define _COMM_CFG_H
+
+#ifndef DYN_MASTER_MAX_TX_BUFFER_LEN
+  #define DYN_MASTER_MAX_TX_BUFFER_LEN            128
+#endif
+
+#ifndef DYN_MASTER_MAX_RX_BUFFER_LEN
+  #define DYN_MASTER_MAX_RX_BUFFER_LEN            128
+#endif
+
+#ifndef DYN_MASTER_DEFAULT_BAUDRATE
+  #define DYN_MASTER_DEFAULT_BAUDRATE             1000000
+#endif
+
+#ifndef DYN_MASTER_DEFAULT_TIMEOUT_US
+  #define DYN_MASTER_DEFAULT_TIMEOUT_US           10000
+#endif
+
+#ifndef SERIAL_CONSOLE_MAX_BUFFER_LEN
+  #define SERIAL_CONSOLE_MAX_BUFFER_LEN           128
+#endif
+
+#endif
diff --git a/communications/include/dynamixel_master.h b/communications/include/dynamixel_master.h
index 9e1bf8198b121d50845c112b57a5e8075dcab59b..9fa62737f3c26e3e75d2bfbc888cc93d2524dd66 100644
--- a/communications/include/dynamixel_master.h
+++ b/communications/include/dynamixel_master.h
@@ -3,14 +3,6 @@
 
 #include "dynamixel.h"
 
-#ifndef MAX_DYN_MASTER_TX_BUFFER_LEN
-  #define       MAX_DYN_MASTER_TX_BUFFER_LEN      128
-#endif
-
-#ifndef MAX_DYN_MASTER_RX_BUFFER_LEN
-  #define       MAX_DYN_MASTER_RX_BUFFER_LEN      128
-#endif
-
 /* public functions */
 void dyn_master_init(void);
 void dyn_master_set_rx_timeout(uint16_t timeout_ms);
diff --git a/communications/include/serial_console.h b/communications/include/serial_console.h
index eb0dcebd55867d57d3ba7e4f2eb3af48d3821e69..2624cfa550762791faee2eec945068763002ddb4 100644
--- a/communications/include/serial_console.h
+++ b/communications/include/serial_console.h
@@ -4,8 +4,6 @@
 #include <avr/io.h>
 #include <avr/interrupt.h>
 
-#define SERIAL_CONSOLE_BUFFER    128
-
 void serial_console_init(uint32_t baudrate);
 
 #endif
diff --git a/communications/src/dynamixel_master.c b/communications/src/dynamixel_master.c
index f44efa6dcbea8cc8b43c9f695719a990dbf22b9f..c1b445ac1b8fc594fa0d31aba5c2a31e909c09a3 100644
--- a/communications/src/dynamixel_master.c
+++ b/communications/src/dynamixel_master.c
@@ -1,10 +1,11 @@
+#include "comm_cfg.h"
 #include "dynamixel_master.h"
 
 /* private variables */
-uint8_t dyn_master_tx_buffer[MAX_DYN_MASTER_TX_BUFFER_LEN];
+uint8_t dyn_master_tx_buffer[DYN_MASTER_MAX_TX_BUFFER_LEN];
 uint8_t dyn_master_sent_bytes;
 volatile uint8_t dyn_master_sent_done;
-uint8_t dyn_master_rx_buffer[MAX_DYN_MASTER_RX_BUFFER_LEN];
+uint8_t dyn_master_rx_buffer[DYN_MASTER_MAX_RX_BUFFER_LEN];
 uint8_t dyn_master_received_bytes;
 volatile uint8_t dyn_master_packet_ready;
 return_level_t dyn_master_return_level;
@@ -204,10 +205,10 @@ void dyn_master_init(void)
   // bit3: stop bit(0 = stop bit 1, 1 = stop bit 2)
   // bit2,bit1: data size(11 = 8bit)
   UCSR0C = 0b00000110;
-  dyn_master_set_baudrate((uint32_t)1000000);
+  dyn_master_set_baudrate((uint32_t)DYN_MASTER_DEFAULT_BAUDRATE);
 
   /* initialize the timeout timer */
-  dyn_master_rx_timeout_us=10000;
+  dyn_master_rx_timeout_us=DYN_MASTER_DEFAULT_TIMEOUT_US;
   TCCR0A=0x00;// normal mode, output disabled on both channels
   TCCR0B=0x00;// normal mode, prescaler 0 (timer disabled)
   TIMSK0=0x00;// all interrupts disabled
diff --git a/communications/src/serial_console.c b/communications/src/serial_console.c
index 55496d5348b7332987f5199d55d46dea5ae1a972..7842eb7d91bf8866bd014625a7a30f234339bbfd 100644
--- a/communications/src/serial_console.c
+++ b/communications/src/serial_console.c
@@ -1,8 +1,9 @@
+#include "comm_cfg.h"
 #include "serial_console.h"
 #include <stdio.h>
 
 /* private variables */
-volatile uint8_t serial_console_buffer[SERIAL_CONSOLE_BUFFER];
+volatile uint8_t serial_console_buffer[SERIAL_CONSOLE_MAX_BUFFER_LEN];
 volatile uint8_t serial_console_read_ptr;
 volatile uint8_t serial_console_write_ptr;
 volatile uint8_t serial_console_num_data;
@@ -11,10 +12,10 @@ static FILE *device;
 /* interrupt handlers */
 SIGNAL(USART1_RX_vect)
 {
-  if(serial_console_num_data<SERIAL_CONSOLE_BUFFER)
+  if(serial_console_num_data<SERIAL_CONSOLE_MAX_BUFFER_LEN)
   {
     serial_console_buffer[serial_console_write_ptr]=UDR1;
-    serial_console_write_ptr=(serial_console_write_ptr+1)%SERIAL_CONSOLE_BUFFER;
+    serial_console_write_ptr=(serial_console_write_ptr+1)%SERIAL_CONSOLE_MAX_BUFFER_LEN;
     serial_console_num_data++;
   }
 }
@@ -49,7 +50,7 @@ int serial_console_getchar(FILE *dev)
 
   while(serial_console_num_data==0);
   rx=serial_console_buffer[serial_console_read_ptr];
-  serial_console_read_ptr=(serial_console_read_ptr+1)%SERIAL_CONSOLE_BUFFER;
+  serial_console_read_ptr=(serial_console_read_ptr+1)%SERIAL_CONSOLE_MAX_BUFFER_LEN;
   serial_console_num_data--;
   if(rx=='\r')
     rx='\n';
diff --git a/controllers/Makefile b/controllers/Makefile
index 3afb4f27ee39fbe6e3ab24d166bf02aaa26da68e..1c0c8bca77ce8044316e1d248b82b8849706f9f4 100755
--- a/controllers/Makefile
+++ b/controllers/Makefile
@@ -1,19 +1,22 @@
 #AVR-GCC  Makefile
 
 PROJECT=libcontrollers
-SOURCES=src/cm510/cm510.c src/cm510/gpio.c src/cm510/adc.c src/cm510/buzzer.c
+SOURCES=src/cm510.c src/gpio.c src/adc.c src/buzzer.c src/user_time.c
 OBJS=$(SOURCES:.c=.o)
 SRC_DIR=./src/ 
 BIN_DIR=./build/
 LIB_DIR=./lib/
+DEV_DIR=../dyn_devices/
 COMM_DIR=../communications/
+MAN_DIR=../motion/
+CONT_DIR=./
 CC=avr-gcc
 OBJCOPY=avr-ar
 MMCU=atmega2561
 
-INC_DIRS=-I./include/ -I$(COMM_DIR)include
+INC_DIRS=-I$(CONT_DIR)include/ -I$(COMM_DIR)include -I$(DEV_DIR)include -I$(MAN_DIR)include
 
-LIBS=$(COMM_DIR)lib/libcomm.a
+LIBS=$(COMM_DIR)lib/libcomm.a $(DEV_DIR)lib/libdyn_devices.a $(MAN_DIR)lib/libmotion_manager.a
 
 CFLAGS=-mmcu=$(MMCU) -Wall -O3 -DF_CPU=16000000UL -gdwarf-2 -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wstrict-prototypes
 
@@ -21,7 +24,7 @@ ARFLAGS=rsc
 
 .PHONY: all show_banner clean
 
-all: show_banner communications dyn_devices $(PROJECT).a examples
+all: show_banner communications dyn_devices motion_manager $(PROJECT).a
 
 show_banner:
 	@echo "------------------------------------------------------";
@@ -47,8 +50,14 @@ communications:
 dyn_devices:
 	$(MAKE) -C ../dyn_devices
 
+motion_manager:
+	$(MAKE) -C ../motion
+
 examples: 
 	$(MAKE) -C src/examples
+	$(MAKE) -C ../communications examples
+	$(MAKE) -C ../dyn_devices examples
+	$(MAKE) -C ../motion examples
 
 download: 
 	$(MAKE) -C src/examples download
@@ -59,3 +68,4 @@ clean:
 	$(MAKE) -C src/examples clean
 	$(MAKE) -C ../communications clean
 	$(MAKE) -C ../dyn_devices clean
+	$(MAKE) -C ../motion clean
diff --git a/controllers/include/adc.h b/controllers/include/adc.h
index 6235d1d444005372af713495d616ba701e31bcf3..a5b45094cf4da6a4d3b5f3280aeef76c3c175a63 100644
--- a/controllers/include/adc.h
+++ b/controllers/include/adc.h
@@ -7,10 +7,6 @@
 // ADC channel identifiers
 typedef enum {ADC_VCC=0,ADC_PORT_1=1,ADC_PORT_2=2,ADC_PORT_3=3,ADC_PORT_4=4,ADC_PORT_5=5,ADC_PORT_6=6} adc_t;
 #define         NUM_ADC               7
-// number of samples to average
-#define         ADC_MAX_NUM_SAMPLES   16
-#define         ADC_SAMPLE_PERIOD_MS  10
-#define         ADC_VOLTAGE_ALARM_TH  559
 
 /**
  * \brief Function to initialize the ADC module
diff --git a/controllers/include/cm510.h b/controllers/include/cm510.h
index dd87e115ab575d2c88763bf97ba10b898b270dd1..4eba4049da0918f60c711a7d96bf024224668b1c 100755
--- a/controllers/include/cm510.h
+++ b/controllers/include/cm510.h
@@ -18,6 +18,15 @@
 #ifndef _CM510_H
 #define _CM510_H
 
+#include "cont_cfg.h"
+#include "motion_cfg.h"
+#include "comm_cfg.h"
+#include "gpio.h"
+#include "adc.h"
+#include "buzzer.h"
+#include "motion_manager.h"
+#include "user_time.h"
+
 // general interface
 /**
  * \brief Function to initialize all the cm510 modules
diff --git a/controllers/include/cm510_cfg.h b/controllers/include/cm510_cfg.h
new file mode 100644
index 0000000000000000000000000000000000000000..e46833f4107bd561f7ab31449eb09f2758ac060b
--- /dev/null
+++ b/controllers/include/cm510_cfg.h
@@ -0,0 +1,41 @@
+#ifndef _CM510_CFG_H
+#define _CM510_CFG_H
+
+#include "buzzer.h"
+
+// controller configuration parameters
+#define ADC_MAX_NUM_SAMPLES                     16
+#define ADC_SAMPLE_PERIOD_MS                    10
+#define ADC_VOLTAGE_ALARM_TH                    559
+#define ADC_VOLTAGE_ALARM_WINDOW                20
+#define ADC_VOLTAGE_ALARM_NOTE                  NOTE_LA
+#define ADC_VOLTAGE_ALARM_TIME_ON               30
+#define ADC_VOLTAGE_ALARM_TIME_OFF              30
+
+// communication configuration parameters
+#define DYN_MASTER_MAX_TX_BUFFER_LEN            128
+#define DYN_MASTER_MAX_RX_BUFFER_LEN            128
+#define DYN_MASTER_DEFAULT_BAUDRATE             1000000
+#define DYN_MASTER_DEFAULT_TIMEOUT_US           10000
+#define SERIAL_CONSOLE_MAX_BUFFER_LEN           128
+
+// motion configuration parameters
+#define MANAGER_MAX_NUM_SERVOS                  18
+#define MANAGER_MISSING_SERVOS_ALARM_NOTE       NOTE_SOL
+#define MANAGER_MISSING_SERVOS_ALARM_TIME_ON    10
+#define MANAGER_MISSING_SERVOS_ALARM_TIME_OFF   100
+#define BALANCE_GYRO_CAL_NUM_SAMPLES            10
+#define BALANCE_GYRO_X_CHANNEL                  3
+#define BALANCE_GYRO_Y_CHANNEL                  4
+#define BALANCE_GYRO_CAL_FAILED_ALARM_NOTE      NOTE_SOL
+#define BALANCE_GYRO_CAL_FAILED_ALARM_TIME_ON   10
+#define BALANCE_GYRO_CAL_FAILED_ALARM_TIME_OFF  100
+#define BALANCE_MAX_CAL_GYRO_ERROR              20.0
+#define BALANCE_FORWARD_FALL_THD_VALUE          (-200)
+#define BALANCE_BACKWARD_FALL_THD_VALUE         200
+#define BALANCE_KNEE_GAIN                       (4.0/54.0)
+#define BALANCE_ANKLE_ROLL_GAIN                 (4.0/18.0)
+#define BALANCE_HIP_PITCH_GAIN                  (4.0/20.0)
+#define BALANCE_ANKLE_PITCH_GAIN                (4.0/40.0)
+
+#endif
diff --git a/controllers/include/cont_cfg.h b/controllers/include/cont_cfg.h
new file mode 100644
index 0000000000000000000000000000000000000000..985b7b9a4e2abfc84c834cdcba1f249ac229ad84
--- /dev/null
+++ b/controllers/include/cont_cfg.h
@@ -0,0 +1,35 @@
+#ifndef _CONT_CFG_H
+#define _CONT_CFG_H
+
+#include "buzzer.h"
+
+// number of samples to average
+#ifndef ADC_MAX_NUM_SAMPLES
+  #define ADC_MAX_NUM_SAMPLES         16
+#endif
+
+#ifndef ADC_SAMPLE_PERIOD_MS
+  #define ADC_SAMPLE_PERIOD_MS        10
+#endif 
+
+#ifndef ADC_VOLTAGE_ALARM_TH
+  #define ADC_VOLTAGE_ALARM_TH        559
+#endif
+
+#ifndef ADC_VOLTAGE_ALARM_WINDOW      
+  #define ADC_VOLTAGE_ALARM_WINDOW    20
+#endif
+
+#ifndef ADC_VOLTAGE_ALARM_NOTE
+  #define ADC_VOLTAGE_ALARM_NOTE      NOTE_LA
+#endif
+
+#ifndef ADC_VOLTAGE_ALARM_TIME_ON
+  #define ADC_VOLTAGE_ALARM_TIME_ON   30
+#endif
+
+#ifndef ADC_VOLTAGE_ALARM_TIME_OFF
+  #define ADC_VOLTAGE_ALARM_TIME_OFF  30
+#endif
+
+#endif
diff --git a/controllers/include/user_time.h b/controllers/include/user_time.h
new file mode 100644
index 0000000000000000000000000000000000000000..ab080482202830d0982cb083051b1ee26e623483
--- /dev/null
+++ b/controllers/include/user_time.h
@@ -0,0 +1,15 @@
+#ifndef _USER_TIME_H
+#define _USER_TIME_H
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+
+/* public functions */
+void init_user_time(void);
+void user_time_set_period(uint16_t period_ms);
+void user_time_set_one_time(uint16_t time_ms);
+uint8_t user_time_is_period_done(void);
+uint8_t user_time_is_done(void);
+void user_time_stop(void);
+
+#endif
diff --git a/controllers/src/cm510/adc.c b/controllers/src/adc.c
similarity index 84%
rename from controllers/src/cm510/adc.c
rename to controllers/src/adc.c
index f5899c044773fe0b5acf9c8c5e0c9a4c3a3a8fc1..be4e5efc8944cddb57337f488729b31ff71b683d 100644
--- a/controllers/src/cm510/adc.c
+++ b/controllers/src/adc.c
@@ -1,5 +1,5 @@
+#include "cm510_cfg.h"
 #include "adc.h"
-#include "gpio.h"
 #include "buzzer.h"
 #include <util/delay.h>
 
@@ -14,6 +14,7 @@ volatile uint16_t adc_values[NUM_ADC];
 volatile uint16_t adc_avg_values[NUM_ADC];
 volatile uint8_t adc_current_ch;
 volatile uint8_t adc_current_sample;
+volatile uint8_t adc_voltage_alarm;
 
 /* private functions */
 void adc_set_channel(uint8_t ch_id)
@@ -94,15 +95,21 @@ void adc_loop(void)
       {
 //        voltage_mv=((uint32_t)data*(uint32_t)5000*(uint32_t)133)/((uint16_t)1024*(uint16_t)33);
         // compare with hysteresis
-        if(buzzer_is_playing_alarm())
+        if(adc_voltage_alarm==0x01)
         {
-          if(data>=(ADC_VOLTAGE_ALARM_TH+20))// voltage under 11 V
+          if(data>=(ADC_VOLTAGE_ALARM_TH+ADC_VOLTAGE_ALARM_WINDOW))// voltage under 11 V
+          {
             buzzer_stop_alarm();
+            adc_voltage_alarm=0x00;
+          }
         }
         else
         {
-          if(data<(ADC_VOLTAGE_ALARM_TH-20))// voltage under 11 V
+          if(data<(ADC_VOLTAGE_ALARM_TH-ADC_VOLTAGE_ALARM_WINDOW))// voltage under 11 V
+          {
             buzzer_start_alarm(NOTE_LA,30,30);
+            adc_voltage_alarm=0x01;
+          }
         }
       }
       adc_current_ch=(adc_current_ch+1)%NUM_ADC;
@@ -114,7 +121,7 @@ void adc_loop(void)
 /* public functions */
 void init_adc(void)
 {
-  uint8_t i=0;
+  uint8_t i=0,j=0;
 
   ADCSRA=(1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);// enable ADC set prescaler 1/128
                                                                   // disable auto trigger, interrupts disabled
@@ -127,9 +134,16 @@ void init_adc(void)
   DDRA  = 0xFC;
   PORTA = 0xFC;// all sensors disabled
 
+  // initialize internal sample variables to 12V to avoid initial voltage alarm
   for(i=0;i<NUM_ADC;i++)
-    adc_values[i]=0x0000;
+  {
+    adc_values[i]=0x0266;//equivalent to 12 V
+    adc_avg_values[i]=0x0266;//equivalent to 12 V
+    for(j=0;j<ADC_MAX_NUM_SAMPLES;j++)
+      adc_ch_data[i][j]=0x0266;
+  }
   adc_current_ch=0;
+  adc_voltage_alarm=0x00;
 
   // configure the timer 2 to perform periodic conversions (1 ms period)
   TCCR2A=(1<<WGM21);// CTC mode, no output
diff --git a/controllers/src/cm510/buzzer.c b/controllers/src/buzzer.c
similarity index 90%
rename from controllers/src/cm510/buzzer.c
rename to controllers/src/buzzer.c
index 0222db063d5f7ac3b3d83c9ed4baec120118e8d9..115cd534a008eb8e8198e3d11f7cd0465bee8f8b 100644
--- a/controllers/src/cm510/buzzer.c
+++ b/controllers/src/buzzer.c
@@ -68,22 +68,6 @@ void buzzer_loop(void)
   }
 }
 
-void buzzer_start_alarm(note_t note, uint16_t on_time_100ms,uint16_t off_time_100ms)
-{
-  if(buzzer_playing_alarm==0x00)// the alram is not playing
-  {
-    if(buzzer_playing)// if the normal buzzer is playing, stop it.
-      buzzer_stop();
-    buzzer_playing_alarm=0x01;
-    buzzer_time_on_100ms=on_time_100ms;
-    buzzer_time_off_100ms=off_time_100ms;
-    buzzer_note=note;
-    // enable PWM output
-    TCCR1A&=(~(1<<COM1A0));
-    TCCR1A|=(1<<COM1A1);
-  }
-}
-
 void buzzer_stop_alarm(void)
 {
   if(buzzer_playing_alarm==0x01)
@@ -94,6 +78,27 @@ void buzzer_stop_alarm(void)
   }
 }
 
+void buzzer_start_alarm(note_t note, uint16_t on_time_100ms,uint16_t off_time_100ms)
+{
+  if(buzzer_playing_alarm)// the alram is not playing
+    buzzer_stop_alarm();
+  else if(buzzer_playing)// if the normal buzzer is playing, stop it.
+    buzzer_stop();
+  // set top count value
+  ICR1H = 0x00;
+  ICR1L = buzzer_note_freq[note];
+  // Set the compare value to half the period
+  OCR1AH = 0x00;
+  OCR1AL = buzzer_note_freq[note]>>1;
+  buzzer_time_on_100ms=on_time_100ms;
+  buzzer_time_off_100ms=off_time_100ms;
+  buzzer_note=note;
+  // enable PWM output
+  TCCR1A&=(~(1<<COM1A0));
+  TCCR1A|=(1<<COM1A1);
+  buzzer_playing_alarm=0x01;
+}
+
 /* public functions */
 void init_buzzer(void)
 {
diff --git a/controllers/src/cm510/cm510.c b/controllers/src/cm510.c
similarity index 83%
rename from controllers/src/cm510/cm510.c
rename to controllers/src/cm510.c
index 0b25730059316d7fff64f3498df39de48bba5edf..316ab01dded22f064b6e417654f27ecc27bafcc7 100755
--- a/controllers/src/cm510/cm510.c
+++ b/controllers/src/cm510.c
@@ -15,14 +15,12 @@
  *  along with iri-libbioloid.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "cm510.h"
-#include "gpio.h"
-#include "adc.h"
-#include "buzzer.h"
 #include <avr/io.h>
 #include <avr/interrupt.h>
 #include <inttypes.h>
 #include <util/delay.h>
+#include "cm510_cfg.h"
+#include "cm510.h"
 
 /* external user functions */
 extern void user_init(void);
@@ -32,6 +30,8 @@ extern void user_loop(void);
 extern void pushbuttons_loop(void);
 extern void adc_loop(void);
 extern void buzzer_loop(void);
+extern void manager_loop(void);
+extern void user_time_loop(void);
 
 // general interface
 void init_cm510(void)
@@ -40,20 +40,26 @@ void init_cm510(void)
   init_buttons();
   init_adc();
   init_buzzer();
+  init_user_time();
 }
 
 int16_t main(void)
 {
   init_cm510();
+  sei();
+  manager_init(MANAGER_MAX_NUM_SERVOS);
   /* call the user initialization function */
   user_init();
-  sei();
+  // turn BAT_LED on to indicate the initialization is done
+  turn_led_on(LED_BAT);
 
   while(1)
   {
     pushbuttons_loop();
     adc_loop();
     buzzer_loop();
+    manager_loop();
+    user_time_loop();
     user_loop();
   }
 }
diff --git a/controllers/src/examples/Makefile b/controllers/src/examples/Makefile
index fcb8394727c000908ba201b6c99d3beecbc45515..db83592ea8c4d3501365f3b0ed1bd8bc74b83a87 100644
--- a/controllers/src/examples/Makefile
+++ b/controllers/src/examples/Makefile
@@ -6,15 +6,17 @@ SOURCES=main.c
 
 OBJS=$(SOURCES:.c=.o)
 SRC_DIR=./src/
-CM510_DIR=../../lib
-COMM_DIR=../../../communications/lib
+DEV_DIR=../../../dyn_devices/
+COMM_DIR=../../../communications/
+MAN_DIR=../../../motion/
+CONT_DIR=../../
 CC=avr-gcc
 OBJCOPY=avr-objcopy
 MMCU=atmega2561
 
-INCLUDE_DIRS=-I../../include/ -I../../../communications/include
+INCLUDE_DIRS=-I$(CONT_DIR)include/ -I$(COMM_DIR)include -I$(MAN_DIR)include -I$(DEV_DIR)include
 
-LIBS=$(CM510_DIR)/libcontrollers.a $(COMM_DIR)/libcomm.a
+LIBS=$(CONT_DIR)lib/libcontrollers.a $(MAN_DIR)lib/libmotion_manager.a $(COMM_DIR)lib/libcomm.a $(DEV_DIR)lib/libdyn_devices.a
 
 CFLAGS=-mmcu=$(MMCU) -Wall -Os $(defines) -DF_CPU=16000000UL -gdwarf-2 -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wstrict-prototypes
 
diff --git a/controllers/src/examples/main.c b/controllers/src/examples/main.c
index a3a9ce57bc59b46b152cf0bff56b32bcd989ecf1..4100e66b48115655465d7626ab0504796eedee72 100755
--- a/controllers/src/examples/main.c
+++ b/controllers/src/examples/main.c
@@ -20,24 +20,27 @@
 #include "adc.h"
 #include "buzzer.h"
 #include "serial_console.h"
+#include "user_time.h"
 #include <stdio.h>
 #include <util/delay.h>
 
 void user_init(void)
 {
   serial_console_init(57600);
+  user_time_set_period(10);
 }
 
 void user_loop(void)
 {
+  if(user_time_is_period_done())
+  {
+    printf("Gyro X: %d\n",get_adc_avg_channel(ADC_PORT_3));
+    printf("Gyro Y: %d\n",get_adc_avg_channel(ADC_PORT_4));
+  }
   if(is_button_pressed(BTN_START))
     turn_led_on(LED_AUX);
   else
     turn_led_off(LED_AUX);
-//  if(get_adc_avg_channel(ADC_VCC)<512)
-//    turn_led_on(LED_PLAY);
-//  else
-//    turn_led_off(LED_PLAY);
   if(is_button_falling_edge(BTN_UP))
     buzzer_start(NOTE_SOL,30,30);
   else
@@ -45,5 +48,4 @@ void user_loop(void)
     if(is_button_falling_edge(BTN_DOWN))
       buzzer_stop();
   }
-  printf("loop\n");
 }
diff --git a/controllers/src/cm510/gpio.c b/controllers/src/gpio.c
similarity index 100%
rename from controllers/src/cm510/gpio.c
rename to controllers/src/gpio.c
diff --git a/controllers/src/user_time.c b/controllers/src/user_time.c
new file mode 100644
index 0000000000000000000000000000000000000000..90a29a408040df38c986d49bd3ea1a76e0badb42
--- /dev/null
+++ b/controllers/src/user_time.c
@@ -0,0 +1,126 @@
+#include "user_time.h"
+
+/* private variables */
+uint8_t user_time_single;
+uint16_t user_time_time;
+uint16_t user_time_period;
+volatile uint8_t user_time_done;
+volatile uint8_t user_time_period_done;
+
+/* private funcitons */
+void user_time_loop(void)
+{
+  static uint16_t count=0;
+
+  if(TIFR5&(1<<OCF5A))
+  {
+    TIFR5|=(1<<OCF5A);// clear any interrupt
+    TCNT5H=0x00;                   
+    TCNT5L=0x00;
+    if(user_time_single==0x01)
+    {
+      if(count==user_time_time)
+      {
+        count=0;
+        user_time_done=0x01;
+        TCCR5B&=0xF8;// disable timer 
+      }
+      else
+        count++;
+    }
+    else
+    {
+      if(count==user_time_period)
+      {
+        count=0;
+        user_time_period_done=0x01;
+      }
+      else
+        count++;
+    }
+  }
+}
+
+/* public functions */
+void init_user_time(void)
+{
+  // initialize timer3 for buzzer time control (100ms period)
+  TIMSK5=0x00;// disable all interrupts
+  TIFR5=0x2F;// clear any pending interrupt
+  TCNT5H=0x00;                   
+  TCNT5L=0x00;
+  // set PWM mode with ICR top-count (CTC mode)
+  TCCR5A=0x00;
+  TCCR5A&=~(1<<WGM50);
+  TCCR5A&=~(1<<WGM51);
+  TCCR5B=0x00;
+  TCCR5B|=(1<<WGM52);
+  TCCR5B&=~(1<<WGM53);
+  // clear output compare value A
+  OCR5AH=0x18;
+  OCR5AL=0x6A;
+  TCCR5B&=0xF8;// disable timer by default
+
+  /* initialize internal variables */
+  user_time_single=0x00;
+  user_time_time=0x00;
+  user_time_period=0x00;
+  user_time_done=0x00;
+  user_time_period_done=0x00;
+}
+
+void user_time_set_period(uint16_t period_ms)
+{
+  user_time_single=0x00;
+  user_time_period=period_ms/100;
+  user_time_period_done=0x00;
+  TCNT5H=0x00;                   
+  TCNT5L=0x00;
+  TIFR5=0x2F;// clear any pending interrupt
+  TCCR5B&=0xF8;// disable timer by default
+  TCCR5B|=0x04;
+}
+
+void user_time_set_one_time(uint16_t time_ms)
+{
+  user_time_single=0x01;
+  user_time_time=time_ms/100;
+  user_time_done=0x00;
+  TCNT5H=0x00;                   
+  TCNT5L=0x00;
+  TIFR5=0x2F;// clear any pending interrupt
+  TCCR5B&=0xF8;// disable timer by default
+  TCCR5B|=0x04;
+}
+
+uint8_t user_time_is_period_done(void)
+{
+  if(user_time_period_done==0x01)
+  {
+    user_time_period_done=0x00;
+    return 0x01;
+  }
+  else
+    return 0x00;
+}
+
+uint8_t user_time_is_done(void)
+{
+  if(user_time_done==0x01)
+  {
+    user_time_done=0x00;
+    return 0x01;
+  }
+  else
+    return 0x00;
+}
+
+void user_time_stop(void)
+{
+  TCCR5B&=0xF8;// disable timer 
+  TIFR5|=(1<<OCF5A);// clear any interrupt
+  TCNT5H=0x00;                   
+  TCNT5L=0x00;
+  user_time_period_done=0x00;  
+  user_time_done=0x00;  
+}
diff --git a/dyn_devices/Makefile b/dyn_devices/Makefile
index b7af2ae6f9ff4695a5df146b5336387cc0a1bb0f..44b6332e1d6be66947d0201478045048d607c92e 100755
--- a/dyn_devices/Makefile
+++ b/dyn_devices/Makefile
@@ -19,7 +19,7 @@ ARFLAGS=rsc
 
 .PHONY: all show_banner clean
 
-all: show_banner $(PROJECT).a examples
+all: show_banner communications $(PROJECT).a 
 
 show_banner:
 	@echo "------------------------------------------------------";
@@ -34,11 +34,14 @@ show_banner:
 	@echo "------------------------------------------------------";
 
 $(PROJECT).a: ${OBJS}
-	$(OBJCOPY) $(ARFLAGS) ${LIB_DIR}$(PROJECT).a $(LIBS) $(OBJS)
+	$(OBJCOPY) $(ARFLAGS) ${LIB_DIR}$(PROJECT).a $(OBJS)
 
 %.o: %.c 
 	$(CC) -c $(CFLAGS) $(INC_DIRS) -o $@ $<
 
+communications:
+	$(MAKE) -C $(COMM_DIR)
+
 examples:
 	$(MAKE) -C src/examples 
 
diff --git a/dyn_devices/src/examples/Makefile b/dyn_devices/src/examples/Makefile
index f5be84ed36e5399b332a24ba6b8abab7ce157c44..e47489236aa81efc8ff2c3bd7ba6d599ae7006d5 100755
--- a/dyn_devices/src/examples/Makefile
+++ b/dyn_devices/src/examples/Makefile
@@ -24,15 +24,21 @@ HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature
 
 .PHONY: all
 
-all: $(PROJECT).hex
+all: communications dyn_devices $(PROJECT).hex
 
 $(PROJECT).hex: $(PROJECT).elf
 	$(OBJCOPY) -O ihex $(HEX_FLASH_FLAGS)  $< $@
-$(PROJECT).elf: $(OBJS)
+$(PROJECT).elf: $(OBJS) $(COMM_DIR)lib/libcomm.a $(DEV_DIR)lib/libdyn_devices.a
 	$(CC) $(LDFLAGS) $(OBJS) $(LIB_DIRS) $(LIBS) -o $(PROJECT).elf
 %.o:%.c
 	$(CC) -c $(CFLAGS) $(INCLUDE_DIRS) -o $@ $<
 
+communications:
+	$(MAKE) -C $(COMM_DIR)
+
+dyn_devices:
+	$(MAKE) -C $(DEV_DIR)
+
 download: $(MAIN_OUT_HEX)
 	fw_downloader -d /dev/ttyUSB0 -f ./src/examples/comm_ex.hex -p new
 
diff --git a/motion/Makefile b/motion/Makefile
index c89f25848cd2d3d9898e1843e3b967c9f73ba641..a6372baf5b0addcfbf95247cdd79507d8e64509a 100755
--- a/motion/Makefile
+++ b/motion/Makefile
@@ -1,18 +1,19 @@
 PROJECT=libmotion_manager
-SOURCES=src/motion_manager.c src/action.c src/motion_pages.c
+SOURCES=src/motion_manager.c src/action.c src/motion_pages.c src/balance.c
 OBJS=$(SOURCES:.c=.o)
 SRC_DIR=./src/ 
 BIN_DIR=./build/
 LIB_DIR=./lib/
 COMM_DIR=../communications/
 DEV_DIR=../dyn_devices/
+CONT_DIR=../controllers/
 CC=avr-gcc
 OBJCOPY=avr-ar
 MMCU=atmega2561
 
-INC_DIRS=-I./include/ -I$(DEV_DIR)include/ -I$(COMM_DIR)include/
+INC_DIRS=-I./include/ -I$(DEV_DIR)include/ -I$(COMM_DIR)include/ -I$(CONT_DIR)include/
 
-LIBS=$(DEV_DIR)lib/libdyn_devices.a $(COMM_DIR)lib/libcomm.a 
+LIBS=$(COMM_DIR)lib/libcomm.a $(DEV_DIR)lib/libdyn_devices.a
 
 CFLAGS=-mmcu=$(MMCU) -Wall -O3 -DF_CPU=16000000UL -gdwarf-2 -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wstrict-prototypes
 
@@ -20,7 +21,7 @@ ARFLAGS= rsc
 
 .PHONY: all show_banner clean
 
-all: show_banner $(PROJECT).a
+all: show_banner communications dyn_devices $(PROJECT).a
 
 show_banner:
 	@echo "------------------------------------------------------";
@@ -36,11 +37,21 @@ show_banner:
 
 
 $(PROJECT).a: ${OBJS}
-	$(OBJCOPY) $(ARFLAGS) ${LDIR}$(PROJECT).a $(LIBS) $(OBJS)
+	$(OBJCOPY) $(ARFLAGS) ${LIB_DIR}$(PROJECT).a $(OBJS)
+
+communications:
+	$(MAKE) -C $(COMM_DIR)
+
+dyn_devices:
+	$(MAKE) -C $(DEV_DIR)
+
+examples:
+	$(MAKE) -C src/examples
 
 %.o: %.c 
 	$(CC) -c $(CFLAGS) ${INC_DIRS} -o $@ $<
 
 clean:
-	rm -f ${LDIR}$(PROJECT).a
+	rm -f ${LIB_DIR}$(PROJECT).a
 	rm -f $(OBJS) 
+	$(MAKE) -C src/examples clean
diff --git a/motion/include/action.h b/motion/include/action.h
index 549728d6745d48b1e7eaeb32fab03d9045a59000..929ad3fa569e85a042af698bd77a7e1e168f24ec 100644
--- a/motion/include/action.h
+++ b/motion/include/action.h
@@ -1,18 +1,10 @@
 #ifndef _ACTION_H
 #define _ACTION_H
 
-#include <inttypes.h>
-
-#define NUM_SERVOS 	18
-
 // basic motion interface
-void action_init(void);
 uint8_t action_set_page(uint8_t page_id);
 void action_start_page(void);
 void action_stop_page(void);
 uint8_t is_action_running(void);
 
-// motion manager interface
-void action_process(void);
-
 #endif
diff --git a/motion/include/balance.h b/motion/include/balance.h
new file mode 100644
index 0000000000000000000000000000000000000000..5c227eb00a2be42b38b8fcdd38541ed20935aced
--- /dev/null
+++ b/motion/include/balance.h
@@ -0,0 +1,50 @@
+#ifndef _BALANCE_H
+#define _BALANCE_H
+
+typedef enum {robot_standing,robot_face_down,robot_face_up} fallen_t;
+
+// public functions
+void balance_init(void);
+/**
+ * \brief Function to check if the robot has fallen to the ground
+ * 
+ * This function returns:
+ *   0x00 : if the robot is standing.
+ *   0x01 : if the robot has fallen face-to-ground 
+ *   0x02 : if the robot has fallen back-to-ground
+ * After reading the value, the internal state is automatically set
+ * back to 0x00
+ */
+fallen_t balance_robot_has_fallen(void);
+uint8_t balance_calibrate_gyro(void);
+/**
+ * \brief Function to enable the internal gyros
+ * 
+ * If the gyroscopes have been detected and calibrated in the init_motion() function,
+ * this function enbales them to be used. When enabled they perform two tasks: first
+ * balance the robot while moving to make it more stable and also detect when the 
+ * robot falls.
+ */
+void balance_enable_gyro(void);
+/**
+ * \brief Function to disable the internal gyros
+ *
+ * If the gyroscopes have been detected and calibrated in the init_motion() function,
+ * this function disales them. When disabled it is no longer possible to detect when 
+ * robot falls. gyro
+ *
+ * This function may be used to avoid cancelling the standing up action due to fast 
+ * motions associated with this motion. After the robot is standing up, the gyros may
+ * be enabled again.
+ */
+void balance_disable_gyro(void);
+/**
+ * \brief Function to check whether the gyros are enabled or not
+ *
+ * This function checks wether the gyros are currently enabled or not.
+ *
+ * \return 0x01 if the gyros are enabled and 0x00 otherwise.
+ */
+uint8_t balance_is_gyro_enabled(void);
+
+#endif
diff --git a/motion/include/motion_cfg.h b/motion/include/motion_cfg.h
new file mode 100644
index 0000000000000000000000000000000000000000..f96994c4cfcd0624ab272636e478ffeceefb09dd
--- /dev/null
+++ b/motion/include/motion_cfg.h
@@ -0,0 +1,74 @@
+#ifndef _MOTION_CFG_H
+#define _MOTION_CFG_H
+
+#include "buzzer.h"
+
+#ifndef MANAGER_MAX_NUM_SERVOS
+  #define MANAGER_MAX_NUM_SERVOS                  18
+#endif
+
+#ifndef MANAGER_MISSING_SERVOS_ALARM_NOTE
+  #define MANAGER_MISSING_SERVOS_ALARM_NOTE       NOTE_SOL
+#endif
+
+#ifndef MANAGER_MISSING_SERVOS_ALARM_TIME_ON
+  #define MANAGER_MISSING_SERVOS_ALARM_TIME_ON    10
+#endif
+
+#ifndef MANAGER_MISSING_SERVOS_ALARM_TIME_OFF
+  #define MANAGER_MISSING_SERVOS_ALARM_TIME_OFF   100
+#endif
+
+#ifndef BALANCE_GYRO_CAL_NUM_SAMPLES
+  #define BALANCE_GYRO_CAL_NUM_SAMPLES            10
+#endif 
+
+#ifndef BALANCE_GYRO_X_CHANNHEL
+  #define BALANCE_GYRO_X_CHANNEL                  3
+#endif 
+
+#ifndef BALANCE_GYRO_Y_CHANNEL
+  #define BALANCE_GYRO_Y_CHANNEL                  4
+#endif
+
+#ifndef BALANCE_GYRO_CAL_FAILED_ALARM_NOTE
+  #define BALANCE_GYRO_CAL_FAILED_ALARM_NOTE      NOTE_SOL
+#endif
+
+#ifndef BALANCE_GYRO_CAL_FAILED_ALARM_TIME_ON
+  #define BALANCE_GYRO_CAL_FAILED_ALARM_TIME_ON   10
+#endif
+
+#ifndef BALANCE_GYRO_CAL_FAILED_ALARM_TIME_OFF
+  #define BALANCE_GYRO_CAL_FAILED_ALARM_TIME_OFF  100
+#endif
+
+#ifndef BALANCE_MAX_CAL_GYRO_ERROR
+  #define BALANCE_MAX_CAL_GYRO_ERROR              20.0
+#endif
+
+#ifndef BALANCE_FORWARD_FALL_THD_VALUE
+  #define BALANCE_FORWARD_FALL_THD_VALUE          (-200)
+#endif
+
+#ifndef BALANCE_BACKWARD_FALL_THD_VALUE
+  #define BALANCE_BACKWARD_FALL_THD_VALUE         200
+#endif
+
+#ifndef BALANCE_KNEE_GAIN
+  #define BALANCE_KNEE_GAIN                       (4.0/54.0)
+#endif
+
+#ifndef BALANCE_ANKLE_ROLL_GAIN
+  #define BALANCE_ANKLE_ROLL_GAIN                 (4.0/18.0)
+#endif
+
+#ifndef BALANCE_HIP_PITCH_GAIN
+  #define BALANCE_HIP_PITCH_GAIN                  (4.0/20.0)
+#endif
+
+#ifndef BALANCE_ANKLE_PITCH_GAIN
+  #define BALANCE_ANKLE_PITCH_GAIN                (4.0/40.0)
+#endif
+
+#endif
diff --git a/motion/include/motion_manager.h b/motion/include/motion_manager.h
index 3a1ea88bdb7c748a4bb66fc45b51b313b1a4f192..29b0ee61b9c8905828b823f6c75135ba69be8682 100644
--- a/motion/include/motion_manager.h
+++ b/motion/include/motion_manager.h
@@ -2,15 +2,6 @@
 #define _MOTION_MANAGER_H
 
 #include <inttypes.h>
-#include "motion_pages.h"
-
-#define       MANAGER_MAX_NUM_SERVOS         20
-#define       GYRO_CAL_NUM_SAMPLES           10
-#define       X_GYRO_CHANNEL                  3
-#define       Y_GYRO_CHANNEL                  4
-
-extern TPage action_next_page;
-extern TPage action_current_page;
 
 // servo information structure
 typedef struct{
@@ -23,57 +14,7 @@ typedef struct{
   uint8_t ccw_slope;
 }TServoInfo;
 
-int16_t servo_offsets[MANAGER_MAX_NUM_SERVOS];
-
 // public functions
-void manager_init(uint8_t num_servos);
-void manager_set_index_value(uint8_t servo_id, uint16_t value);
-void manager_set_servo_value(uint8_t servo_id, uint16_t value);
-uint16_t manager_get_index_value(uint8_t servo_id);
-uint16_t manager_get_servo_value(uint8_t servo_id);
-void manager_set_servo_slopes(uint8_t servo_id, uint8_t slope);
-
-/**
- * \brief Function to check if the robot has fallen to the ground
- * 
- * This function returns:
- *   0x00 : if the robot is standing.
- *   0x01 : if the robot has fallen face-to-ground 
- *   0x02 : if the robot has fallen back-to-ground
- * After reading the value, the internal state is automatically set
- * back to 0x00
- */
-uint8_t manager_check_robot_fallen(void);
+uint8_t manager_init(uint8_t num_servos);
 
-// gyro interface
-uint8_t manager_calibrate_gyro(void);
-/**
- * \brief Function to enable the internal gyros
- * 
- * If the gyroscopes have been detected and calibrated in the init_motion() function,
- * this function enbales them to be used. When enabled they perform two tasks: first
- * balance the robot while moving to make it more stable and also detect when the 
- * robot falls.
- */
-void manager_enable_gyro(void);
-/**
- * \brief Function to disable the internal gyros
- *
- * If the gyroscopes have been detected and calibrated in the init_motion() function,
- * this function disales them. When disabled it is no longer possible to detect when 
- * robot falls. gyro
- *
- * This function may be used to avoid cancelling the standing up action due to fast 
- * motions associated with this motion. After the robot is standing up, the gyros may
- * be enabled again.
- */
-void manager_disable_gyro(void);
-/**
- * \brief Function to check whether the gyros are enabled or not
- *
- * This function checks wether the gyros are currently enabled or not.
- *
- * \return 0x01 if the gyros are enabled and 0x00 otherwise.
- */
-uint8_t manager_is_gyro_enabled(void);
 #endif
diff --git a/motion/src/action.c b/motion/src/action.c
index 4cd742e9d92ddf8dd892d85b7dff595a37388967..5452f9ad1b777c6a1dc7959ae7c1617f14a7a46b 100644
--- a/motion/src/action.c
+++ b/motion/src/action.c
@@ -1,12 +1,9 @@
-#include "action.h"
-#include "dyn_servos.h"
-#include "motion_pages.h"
-#include "motion_manager.h"
 #include <avr/io.h>
 #include <avr/interrupt.h>
 #include <util/delay.h>
-#include "cm510.h"
-
+#include "motion_cfg.h"
+#include "action.h"
+#include "motion_pages.h"
 
 /**************************************
  * Section             /----\
@@ -23,6 +20,12 @@ typedef enum{ ZERO_FINISH, NONE_ZERO_FINISH} TStopMode;
 #define       TIME_BASE_SCHEDULE       0x0a
 #define       INVALID_BIT_MASK         0x4000
 
+// external functions
+extern uint16_t manager_get_index_value(uint8_t servo_id);
+extern uint16_t manager_get_servo_value(uint8_t servo_id);
+extern void manager_set_servo_value(uint8_t servo_id, uint16_t value);
+extern void manager_set_servo_slopes(uint8_t servo_id, uint8_t slope);
+
 // private variables
 uint8_t action_finished;
 uint8_t action_stop;
@@ -71,10 +74,7 @@ uint8_t action_set_page(uint8_t page_id)
 
   error=load_page_info(page_id,&action_current_page);
   if(error==0)
-  {
-    //ram_write_byte(CM730_ACTION_NUMBER,page_id);
     action_current_index=page_id;
-  }
   return error;
 }
 
@@ -90,9 +90,8 @@ void action_start_page(void)
   action_step_count = 0;
   bPlayRepeatCount = action_current_page.header.repeat;
   action_next_index = 0x00;
-  
 
-  for( i=1; i<=NUM_SERVOS; i++ )
+  for( i=1; i<=MANAGER_MAX_NUM_SERVOS; i++ )
   {
       wpTargetAngle1024[i] = manager_get_index_value(i);
       ipLastOutSpeed1024[i] = 0;
@@ -100,16 +99,11 @@ void action_start_page(void)
       ipGoalSpeed1024[i] = 0;
   }
   action_is_running=0x01;
-  //ram_write_byte(CM730_ACTION_STATUS,0x01);
-  //ram_set_bit(CM730_ACTION_CONTROL,0x00);
-  //ram_clear_bit(CM730_ACTION_CONTROL,0x01);
 }
 
 void action_stop_page(void)
 {
   action_stop=0x01;
-  //ram_clear_bit(CM730_ACTION_CONTROL,0x00);
-  //ram_set_bit(CM730_ACTION_CONTROL,0x01);
 }
 
 uint8_t is_action_running(void)
@@ -132,7 +126,6 @@ void action_process(void)
   int64_t lStartSpeed1024_PreTime_256T;
   int64_t lMovingAngle_Speed1024Scale_256T_2T;
   int64_t lDivider1,lDivider2;
-  uint16_t wMaxAngle1024;
   uint16_t wMaxSpeed256;
   uint16_t wPrevTargetAngle; // Start position
   uint16_t wCurrentTargetAngle; // Target position
@@ -147,7 +140,7 @@ void action_process(void)
   {
     wUnitTimeCount = 0;
 
-    for(bID=1;bID<=NUM_SERVOS;bID++)
+    for(bID=1;bID<=MANAGER_MAX_NUM_SERVOS;bID++)
     {
       wpStartAngle1024[bID] = manager_get_servo_value(bID);
       ipLastOutSpeed1024[bID] = ipGoalSpeed1024[bID];
@@ -158,9 +151,9 @@ void action_process(void)
     {
       // MAIN Section Áغñ
       bSection = MAIN_SECTION;
-      turn_led_off(LED_TxD);
+//      turn_led_off(LED_TxD);
       wUnitTimeNum =  wUnitTimeTotalNum - (wAccelStep << 1);
-      for(bID=1;bID<=NUM_SERVOS;bID++)
+      for(bID=1;bID<=MANAGER_MAX_NUM_SERVOS;bID++)
       {
         if( bpFinishType[bID] == NONE_ZERO_FINISH )
         {
@@ -177,10 +170,10 @@ void action_process(void)
     {
       // POST Section Áغñ
       bSection = POST_SECTION;
-      turn_led_off(LED_TxD);
+//      turn_led_off(LED_TxD);
       wUnitTimeNum = wAccelStep;
 
-      for(bID=1;bID<=NUM_SERVOS;bID++)
+      for(bID=1;bID<=MANAGER_MAX_NUM_SERVOS;bID++)
       {
         ipMainAngle1024[bID] = ipMovingAngle1024[bID] - ipMainAngle1024[bID] - ipAccelAngle1024[bID];
       }
@@ -191,22 +184,22 @@ void action_process(void)
       if( wPauseTime )
       {
         bSection = PAUSE_SECTION;
-        turn_led_off(LED_TxD);
+//        turn_led_off(LED_TxD);
         wUnitTimeNum = wPauseTime;
       }
       else
       {
         bSection = PRE_SECTION;
-        turn_led_on(LED_TxD);
+//        turn_led_on(LED_TxD);
       }
     }
     else if( bSection == PAUSE_SECTION )
     {
       // PRE Section Áغñ
       bSection = PRE_SECTION;
-      turn_led_on(LED_TxD);
+//      turn_led_on(LED_TxD);
 
-      for(bID=1;bID<=NUM_SERVOS;bID++)
+      for(bID=1;bID<=MANAGER_MAX_NUM_SERVOS;bID++)
       {
         ipLastOutSpeed1024[bID] = 0;
       }
@@ -273,7 +266,7 @@ void action_process(void)
         //  wMaxAngle1024 = 0;
 
       ////////// Jointº° ÆÄ¶ó¹ÌÅÍ °è»ê
-      for(bID=1;bID<=NUM_SERVOS;bID++)
+      for(bID=1;bID<=MANAGER_MAX_NUM_SERVOS;bID++)
       {
           // ÀÌÀü, ÇöÀç, ¹Ì·¡¸¦ ¹ÙÅÁÀ¸·Î ±ËÀûÀ» °è»ê
           ipAccelAngle1024[bID] = 0;
@@ -366,7 +359,7 @@ void action_process(void)
 
       if(lDivider2 == 0)
         lDivider2 = 1;
-      for(bID=1;bID<=NUM_SERVOS;bID++)
+      for(bID=1;bID<=MANAGER_MAX_NUM_SERVOS;bID++)
       {
           lStartSpeed1024_PreTime_256T = (long)ipLastOutSpeed1024[bID] * ulPreSectionTime256T; //  *300/1024 * 1024/720 * 256 * 2
           lMovingAngle_Speed1024Scale_256T_2T = (((long)ipMovingAngle1024[bID]) * 2560L) / 12;
@@ -389,11 +382,11 @@ void action_process(void)
     wUnitTimeCount++;
     if( bSection == PAUSE_SECTION )
     {
-      toggle_led(LED_AUX);
+//      toggle_led(LED_AUX);
     }
     else
     {
-      for(bID=1;bID<=NUM_SERVOS;bID++)
+      for(bID=1;bID<=MANAGER_MAX_NUM_SERVOS;bID++)
       {
         if( ipMovingAngle1024[bID] == 0 )
           manager_set_servo_value(bID,wpStartAngle1024[bID]);
diff --git a/motion/src/balance.c b/motion/src/balance.c
new file mode 100644
index 0000000000000000000000000000000000000000..d7461ef0fca2bfb56269050ca5a558a5045ec857
--- /dev/null
+++ b/motion/src/balance.c
@@ -0,0 +1,141 @@
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <util/delay.h>
+#include "motion_cfg.h"
+#include "balance.h"
+#include "adc.h"
+#include "buzzer.h"
+
+// external functions
+extern void buzzer_start_alarm(note_t note,uint16_t on_time_100ms,uint16_t off_time_100ms);
+extern void buzzer_stop_alarm(void);
+
+// private variables
+uint16_t balance_x_gyro_center;
+uint16_t balance_y_gyro_center;
+uint8_t balance_gyro_calibrated;
+uint8_t balance_enabled;
+uint8_t balance_robot_fallen_state;
+int16_t balance_offsets[MANAGER_MAX_NUM_SERVOS];
+
+// private functions
+void balance_loop(void)
+{
+  int16_t gyro_x=0;
+  int16_t gyro_y=0;
+
+  if(balance_enabled == 0x01 && balance_gyro_calibrated == 0x01)
+  {
+    // get x,y gyroscope
+    gyro_x=get_adc_channel(BALANCE_GYRO_X_CHANNEL)-balance_x_gyro_center;
+    gyro_y=get_adc_channel(BALANCE_GYRO_Y_CHANNEL)-balance_y_gyro_center;
+
+    if(gyro_x > BALANCE_BACKWARD_FALL_THD_VALUE)
+      balance_robot_fallen_state = robot_face_up;
+    else if(gyro_x < BALANCE_FORWARD_FALL_THD_VALUE)
+      balance_robot_fallen_state = robot_face_down;
+
+    float x_error1,x_error2,y_error1,y_error2;
+    x_error1=gyro_x*BALANCE_KNEE_GAIN;//4.0/54.0;
+    x_error2=gyro_x*BALANCE_ANKLE_ROLL_GAIN;//4.0/18.0;
+    y_error1=gyro_y*BALANCE_HIP_PITCH_GAIN;//4.0/20.0;
+    y_error2=gyro_y*BALANCE_ANKLE_PITCH_GAIN;//4.0/40.0;
+
+    balance_offsets[8] = (uint16_t)y_error1;
+    balance_offsets[9] = (uint16_t)y_error1;
+    balance_offsets[12] = (uint16_t)x_error1;//-1.0;
+    balance_offsets[13] = (uint16_t)-x_error1;//+1.0;
+    balance_offsets[14] = (uint16_t)+x_error2;
+    balance_offsets[15] = (uint16_t)-x_error2;
+    balance_offsets[16] = (uint16_t)-y_error2;
+    balance_offsets[17] = (uint16_t)-y_error2;
+  }
+}
+
+int16_t balance_get_offset(uint8_t index)
+{
+  return balance_offsets[index];
+}
+
+void balance_get_all_offsets(int16_t **offsets)
+{
+  *offsets=&balance_offsets[0];
+}
+
+// public functions
+void balance_init(void)
+{
+  uint8_t i;
+
+  balance_x_gyro_center=0;
+  balance_y_gyro_center=0;
+  balance_gyro_calibrated=0x00;
+  balance_enabled=0x00;
+  balance_robot_fallen_state=robot_standing;
+  for(i=0;i<MANAGER_MAX_NUM_SERVOS;i++)
+    balance_offsets[i]=0;
+}
+
+uint8_t balance_robot_has_fallen(void)
+{
+  uint8_t state = balance_robot_fallen_state;
+  balance_robot_fallen_state = robot_standing;
+  return state;
+}
+
+uint8_t balance_calibrate_gyro(void)
+{
+  uint16_t x_gyro_values[BALANCE_GYRO_CAL_NUM_SAMPLES];
+  uint16_t y_gyro_values[BALANCE_GYRO_CAL_NUM_SAMPLES];
+  float x_gyro_average=0.0,y_gyro_average=0.0,std_x=0.0,std_y=0.0;
+  uint8_t i=0;
+
+  balance_x_gyro_center=0;
+  balance_y_gyro_center=0;
+  for(i=0;i<BALANCE_GYRO_CAL_NUM_SAMPLES;i++)
+  {
+    _delay_ms(50);
+    x_gyro_values[i]=get_adc_channel(BALANCE_GYRO_X_CHANNEL); 
+    y_gyro_values[i]=get_adc_channel(BALANCE_GYRO_Y_CHANNEL); 
+    x_gyro_average+=x_gyro_values[i];
+    y_gyro_average+=y_gyro_values[i];
+  }  
+  x_gyro_average/=(float)BALANCE_GYRO_CAL_NUM_SAMPLES;
+  y_gyro_average/=(float)BALANCE_GYRO_CAL_NUM_SAMPLES;
+  // compute the standard deviation
+  for(i=0;i<BALANCE_GYRO_CAL_NUM_SAMPLES;i++)
+  {
+    std_x+=(x_gyro_values[i]-x_gyro_average)*(x_gyro_values[i]-x_gyro_average);
+    std_y+=(y_gyro_values[i]-y_gyro_average)*(y_gyro_values[i]-y_gyro_average);
+  }
+  std_x=sqrt(std_x/BALANCE_GYRO_CAL_NUM_SAMPLES);
+  std_y=sqrt(std_y/BALANCE_GYRO_CAL_NUM_SAMPLES);
+  if(std_x<BALANCE_MAX_CAL_GYRO_ERROR && std_y<BALANCE_MAX_CAL_GYRO_ERROR)
+  {
+    balance_gyro_calibrated=0x01;
+    balance_x_gyro_center=(uint16_t)x_gyro_average;
+    balance_y_gyro_center=(uint16_t)y_gyro_average;
+  }
+  else
+  {
+    buzzer_start_alarm(BALANCE_GYRO_CAL_FAILED_ALARM_NOTE,BALANCE_GYRO_CAL_FAILED_ALARM_TIME_ON,BALANCE_GYRO_CAL_FAILED_ALARM_TIME_OFF);
+    return 0x00;
+  }
+  buzzer_stop_alarm();
+  return 0x01;
+}
+
+void balance_enable(void)
+{
+  balance_enabled=0x01;
+}
+
+void balance_disable(void)
+{
+  balance_enabled=0x00;
+}
+
+uint8_t balance_is_enabled(void)
+{
+  return balance_enabled;
+}
diff --git a/motion/src/examples/Makefile b/motion/src/examples/Makefile
index 63e7191ae722f8bba643d837c64e842202220a4c..6b50b49effa4336102f6b86be4556fea9f5fa6af 100644
--- a/motion/src/examples/Makefile
+++ b/motion/src/examples/Makefile
@@ -1,80 +1,55 @@
-ROBOTIS_C_DIR =../../../robotis_lib
+PROJECT=manager_ex
+########################################################
+# afegir tots els fitxers que s'han de compilar aquí
+########################################################
+SOURCES=main.c
 
-ifdef ROBOTIS_C_DIR
-    ROBOTIS_C_DIR_FOUND=true
-else
-    ROBOTIS_C_DIR_FOUND=false
-endif
-
-PROJECT=example
-SOURCES=main.c 
 OBJS=$(SOURCES:.c=.o)
-SDIR=../../src/ 
-IDIR=../../include/
-BDIR=../../build/
-LDIR=../../lib/
+SRC_DIR=./src/
+DEV_DIR=../../../dyn_devices/
+COMM_DIR=../../../communications/
+CONT_DIR=../../../controllers/
+MAN_DIR=../../
 CC=avr-gcc
-OBJCOPY=avr-ar rsc
+OBJCOPY=avr-objcopy
 MMCU=atmega2561
-CONTLIB=../../../controllers/lib/
-SERVLIB=../../../dyn_devices/lib/
-ROBOTISLIB=$(ROBOTIS_C_DIR)/lib/
 
-ROBOTIS_INCLUDE_DIR=$(ROBOTIS_C_DIR)/include/
+LIBS=$(CONT_DIR)lib/libcontrollers.a $(MAN_DIR)lib/libmotion_manager.a $(COMM_DIR)lib/libcomm.a $(DEV_DIR)lib/libdyn_devices.a
 
-SERVOS_INCLUDE_DIR=../../../dyn_devices/include/
+INCLUDE_DIRS=-I$(DEV_DIR)include -I$(COMM_DIR)include -I$(CONT_DIR)include -I$(MAN_DIR)include
 
-CONTROLLER_INCLUDE_DIR=../../../controllers/include/
+CFLAGS=-mmcu=$(MMCU) -Wall -Os $(defines) -DF_CPU=16000000UL -gdwarf-2 -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wstrict-prototypes
 
-CFLAGS=-mmcu=$(MMCU) -Wall -O3 -DF_CPU=16000000UL -gdwarf-2 -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wstrict-prototypes
+LDFLAGS=-mmcu=$(MMCU) -Wl,-Map=$(PROJECT).map -DF_CPU=16000000UL
 
-.PHONY: all check_robotis_c show_banner clean
+HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature
 
-all: check_robotis_c show_banner $(PROJECT).elf $(PROJECT).hex
+.PHONY: all
 
-check_robotis_c:
-	@if ! $(ROBOTIS_C_DIR_FOUND); then                                                 \
-	    echo " IMPORTANT !!! ";                                                        \
-	    echo " ROBOTIS_C_DIR variable is not set! The software won't compile";         \
-	    echo " unless you specify the path to Robotis embedded C software.";           \
-	    echo "";                                                                       \
-	    echo " You should:";                                                           \
-	    echo "   1. Edit the makefile, at the begging set up ROBOTIS_C_DIR";           \
-	    echo "   2. Use the variable with make: make ROBOTIS_C_DIR=path-to-bioloid-c"; \
-	    echo "";                                                                       \
-	    echo " Beware of:";                                                            \
-	    echo "   1. Do not use '(' in the directory name (as it comes from robotis) "; \
-	    echo "   2. Absolute path is preferred to avoid problems with submake calls"; \
-	    exit 2;                                                                        \
-	fi
+all: communications dyn_devices controllers motion_manager $(PROJECT).hex
 
-	@if [ ! -d $(ROBOTIS_C_DIR) ]; then                                                  \
-	   echo " ! ROBOTIS_C_DIR is pointing to a non existant directory. Please fix it.";  \
-	   exit 2;                                                                           \
-	fi
+$(PROJECT).hex: $(PROJECT).elf
+	$(OBJCOPY) -O ihex $(HEX_FLASH_FLAGS)  $< $@
+$(PROJECT).elf: $(OBJS)
+	$(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $(PROJECT).elf
+%.o:%.c
+	$(CC) -c $(CFLAGS) $(INCLUDE_DIRS) -o $@ $<
 
-show_banner:
-	@echo "------------------------------------------------------";
-	@echo "       _____                                          ";
-	@echo "      /  _  \                                         ";
-	@echo "      | |_| |               The Humanoid Lab          ";
-	@echo "  ____\_____/____                                     ";
-	@echo " /               \    http://apollo.upc.es/humanoide/ ";
-	@echo "/   _         _   \                                   ";
-	@echo "|  | |       | |  |            $(PROJECT)             ";
-	@echo "|  | |       | |  |                                   ";
-	@echo "------------------------------------------------------";
+communications:
+	$(MAKE) -C $(COMM_DIR)
 
+dyn_devices:
+	$(MAKE) -C $(DEV_DIR)
 
-$(PROJECT).elf: ${OBJS}
-	$(CC) -g -mmcu=$(MMCU) -o ${LDIR}$(PROJECT).elf $(OBJS) -L $(LDIR) -l motion_manager -L $(CONTLIB) -l controllers -L $(SERVLIB) -l dyn_devices -L $(ROBOTISLIB) -l dynamixel -L $(ROBOTISLIB) -l serial
+controllers:
+	$(MAKE) -C $(CONT_DIR)
 
-$(PROJECT).hex: $(PROJECT).elf
-	avr-objcopy -O ihex $(LDIR)$(PROJECT).elf $(PROJECT).hex 
+motion_manager:
+	$(MAKE) -C $(MAN_DIR)
 
-%.o: %.c 
-	$(CC) -c $(CFLAGS) -I$(IDIR) -I${ROBOTIS_INCLUDE_DIR} -I${SERVOS_INCLUDE_DIR} -I${CONTROLLER_INCLUDE_DIR} -o $@ $<
+download: $(MAIN_OUT_HEX)
+	fw_downloader -d /dev/ttyUSB0 -f ./src/examples/comm_ex.hex -p new
 
 clean:
-	rm -f ${LDIR}$(PROJECT).a
-	rm -f $(OBJS) 
+	-rm $(PROJECT).*
+	-rm $(OBJS)
diff --git a/motion/src/examples/main.c b/motion/src/examples/main.c
index 3a50003e54f89fc451dccd8f42ae6746c1a085a7..eef8267f38155f31e8159cd195e9e5588f6f0118 100644
--- a/motion/src/examples/main.c
+++ b/motion/src/examples/main.c
@@ -1,65 +1,38 @@
+#include <util/delay.h>
+#include <stdio.h>
+#include "motion_cfg.h"
 #include "motion_manager.h"
 #include "action.h"
 #include "cm510.h"
-#include <util/delay.h>
-#include <stdio.h>
-#include "exp_board.h"
-#include "exp_board_reg.h"
-#include "serial.h"
-
+#include "gpio.h"
+#include "serial_console.h"
 
-int main(void)
+void user_init(void)
 {
-	int n_servos = 18;
-	init_cm510(ASYNC);
-
-  manager_init(n_servos);
-
-  int exp_board_ad_4, exp_board_ad_5, gyro_x, gyro_y;
-
-  //serial_initialize(57600);
-  exp_board_init(192);
-
-
-  action_init();
-	action_set_page(1);
-	action_start_page();
-	_delay_ms(2000);
+  serial_console_init(57600);
+}
 
-	if(manager_calibrate_gyro())
-	{
-		manager_enable_gyro();
-	  action_set_page(3);
-	  action_start_page();	
+void user_loop(void)
+{
+  if(is_button_falling_edge(BTN_UP))
+  {
+    if(is_action_running()==0x00)
+    {
+      printf("start action\n");
+      action_set_page(3);
+      action_start_page();
+    }
   }
-  
-  exp_board_ad_4 = get_adc_avg_channel(ADC4);
-  while(exp_board_ad_4 < 400)
+  else
   {
-  	exp_board_ad_4 = get_adc_avg_channel(ADC4);
-  	//printf("exp_board_ad_4: %d\n",exp_board_ad_4);		
-  	_delay_ms(50);
+    if(is_button_falling_edge(BTN_DOWN))
+    {
+      if(is_action_running())
+      {
+        printf("stop action\n");
+        action_stop_page();
+      }
+    }
   }
-  //printf("stop");	
-	action_stop_page();
-
-	//while(is_action_running())	
-	action_set_page(1);
-	action_start_page();
-
-	//_delay_ms(1000);
-	//action_set_page(32);
-	//action_start_page();
-	
-	while(1) {
-    //exp_board_ad_4 = get_adc_avg_channel(ADC4);
-    //printf("exp_board_ad_4: %d\n",exp_board_ad_4);		
-
-    //exp_board_ad_5 = get_adc_avg_channel(ADC5);
-    //printf("exp_board_ad_5: %d\n\n",exp_board_ad_5);		
-		//turn_led_on(LED_PROGRAM);
-		//action_process();
-		//turn_led_off(LED_PROGRAM);
-		//_delay_ms(500);
-	}
 }
+
diff --git a/motion/src/motion_manager.c b/motion/src/motion_manager.c
index 5c435f671797a38464a9d84730c9812b714a06e0..129c42640172f9cb1f5ee4b3f45df1d6bcf474c6 100644
--- a/motion/src/motion_manager.c
+++ b/motion/src/motion_manager.c
@@ -1,26 +1,30 @@
-#include "motion_manager.h"
 #include <avr/io.h>
 #include <avr/interrupt.h>
 #include <util/delay.h>
+#include "motion_cfg.h"
+#include "motion_manager.h"
+#include "motion_pages.h"
 #include "dynamixel_master.h"
 #include "dyn_servos.h"
 #include "dyn_servos_reg.h"
 #include "action.h"
+#include "balance.h"
 #include "buzzer.h"
+#include "gpio.h"
 
 // external functions
 extern void buzzer_start_alarm(note_t note,uint16_t on_time_100ms,uint16_t off_time_100ms);
 extern void buzzer_stop_alarm(void);
+extern void balance_loop(void);
+extern void balance_get_all_offsets(int16_t **offsets);
+extern void action_init(void);
+extern void action_process(void);
 
 // private variables
 uint8_t manager_num_servos;
 TServoInfo manager_servos[MANAGER_MAX_NUM_SERVOS];
-
-// gyroscope private variables
-uint16_t x_gyro_center;
-uint16_t y_gyro_center;
-uint8_t gyro_enabled;
-uint8_t robot_fallen_state;
+extern TPage action_next_page;
+extern TPage action_current_page;
 
 typedef struct
 {
@@ -34,18 +38,38 @@ dyn_send_data data[MANAGER_MAX_NUM_SERVOS];
 TWriteData packets[MANAGER_MAX_NUM_SERVOS];
 
 // private functions
-void manager_loop(void)
+void manager_timer_init(void)
 {
-//  turn_led_on(LED_PROGRAM); //debug
-
-  // call the action process
-  action_process(); //action_ready
-  // balance the robot
-  manager_balance();
-  // send the motion commands to the servos
-  manager_send_motion_command();
+  // initialize timer4 for buzzer time control (7.8ms period)
+  TIMSK4=0x00;// disable all interrupts
+  TIFR4=0x2F;// clear any pending interrupt
+  TCNT4H=0x00;                   
+  TCNT4L=0x00;
+  // set PWM mode with ICR top-count (CTC mode)
+  TCCR4A=0x00;
+  TCCR4A&=~(1<<WGM40);
+  TCCR4A&=~(1<<WGM41);
+  TCCR4B=0x00;
+  TCCR4B|=(1<<WGM42);
+  TCCR4B&=~(1<<WGM43);
+  // clear output compare value A
+  OCR4AH=0x3D;
+  OCR4AL=0x08;
+  TCCR4B&=0xF8;// set the prescaler to 8
+  TCCR4B|=0x02;
+}
 
-//  turn_led_off(LED_PROGRAM); //debug
+uint8_t manager_period_done(void)
+{
+  if(TIFR4&(1<<OCF4A))
+  {
+    TIFR4|=(1<<OCF4A);// clear any interrupt
+    TCNT4H=0x00;                   
+    TCNT4L=0x00;
+    return 0x01;
+  }
+  else
+    return 0x00;
 }
 
 void manager_send_motion_command(void) 
@@ -53,12 +77,14 @@ void manager_send_motion_command(void)
   uint8_t *pdata;
   uint8_t i;
   uint16_t target_pos;
+  int16_t *offsets;
 
-  ppacket = (uint8_t *)data;
+  pdata = (uint8_t *)data;
   
+  balance_get_all_offsets(&offsets);
   for(i=0;i<manager_num_servos;i++) 
   {
-    target_pos = manager_servos[i].current_value + servo_offsets[i];
+    target_pos = manager_servos[i].current_value + offsets[i];
     pdata[i*4+2] = target_pos&0xFF;
     pdata[i*4+3] = (target_pos>>8)&0xFF;
 
@@ -72,42 +98,10 @@ void manager_send_motion_command(void)
     else 
       pdata[i*4+1] = 1<<(0x0F&manager_servos[i].ccw_slope);
 
-    packets[i].data=(uint8_t *)&data[i];
-  }
-  dyn_master_sync_write(manager_num_servos,servo_ids,CW_COMP_SLOPE,4,packets); 
-}
-
-void manager_balance(void)
-{
-  int16_t gyro_x=0;
-  int16_t gyro_y=0;
-
-  if(gyro_enabled == 0x01)
-  {
-    // get x,y gyroscope
-//    gyro_x=get_adc_channel(X_GYRO_CHANNEL)-x_gyro_center;
-//    gyro_y=get_adc_channel(Y_GYRO_CHANNEL)-y_gyro_center;
-
-    if(gyro_x > 200)
-      robot_fallen_state = 0x02;
-    else if(gyro_x < -200)
-      robot_fallen_state = 0x01;
-
-    float x_error1,x_error2,y_error1,y_error2;
-    x_error1=gyro_x*4.0/54.0;
-    x_error2=gyro_x*4.0/18.0;
-    y_error1=gyro_y*4.0/20.0;
-    y_error2=gyro_y*4.0/40.0;
-
-    servo_offsets[8] = (uint16_t)y_error1;
-    servo_offsets[9] = (uint16_t)y_error1;
-    servo_offsets[12] = (uint16_t)x_error1;//-1.0;
-    servo_offsets[13] = (uint16_t)-x_error1;//+1.0;
-    servo_offsets[14] = (uint16_t)+x_error2;
-    servo_offsets[15] = (uint16_t)-x_error2;
-    servo_offsets[16] = (uint16_t)-y_error2;
-    servo_offsets[17] = (uint16_t)-y_error2;
+    packets[i].data_addr=(uint8_t *)&data[i];
   }
+  if(manager_num_servos>0)
+    dyn_master_sync_write(manager_num_servos,servo_ids,CW_COMP_SLOPE,4,packets); 
 }
 
 void manager_get_current_position(void)
@@ -133,6 +127,11 @@ void manager_set_servo_slopes(uint8_t servo_id, uint8_t slope)
   }
 }
 
+void manager_set_index_value(uint8_t servo_id, uint16_t value)
+{
+  manager_servos[servo_id].current_value=value;
+}
+
 void manager_set_servo_value(uint8_t servo_id, uint16_t value)
 {
   uint8_t i;
@@ -147,11 +146,6 @@ void manager_set_servo_value(uint8_t servo_id, uint16_t value)
   }
 }
 
-void manager_set_index_value(uint8_t servo_id, uint16_t value)
-{
-  manager_servos[servo_id].current_value=value;
-}
-
 uint16_t manager_get_index_value(uint8_t servo_id)
 {
   return manager_servos[servo_id-1].current_value;
@@ -168,24 +162,23 @@ uint16_t manager_get_servo_value(uint8_t servo_id)
   return 2048;
 }
 
-void manager_timer_init(void)
-{
-
-}
-
-uint8_t manager_period_done(void)
+void manager_loop(void)
 {
-
+  if(manager_period_done()==0x01)
+  {
+    // call the action process
+    action_process(); //action_ready
+    // balance the robot
+    balance_loop();
+    // send the motion commands to the servos
+    manager_send_motion_command();
+  }
 }
 
 // public functions
-void manager_init(uint8_t num_servos)
+uint8_t manager_init(uint8_t num_servos)
 {
   uint8_t i;
-  uint8_t found_servos;
-
-  /* initialize private variables */
-  robot_fallen_state = 0x00;
 
   // enable power to the servos
   dyn_master_init();
@@ -194,13 +187,14 @@ void manager_init(uint8_t num_servos)
   /* scan the bus for all available servos */
   dyn_master_scan(&manager_num_servos,servo_ids);
   if(num_servos != manager_num_servos)
-    buzzer_start_alarm(NOTE_SOL,1000,10000);
+    buzzer_start_alarm(MANAGER_MISSING_SERVOS_ALARM_NOTE,MANAGER_MISSING_SERVOS_ALARM_TIME_ON,MANAGER_MISSING_SERVOS_ALARM_TIME_OFF);
+  else
+    buzzer_stop_alarm();
 
   for(i=0;i<manager_num_servos;i++)
   {
     //set_target_speed(i+1,0);
-    servo_offsets[i] = 0;
-    enable_servo(i+1);
+    enable_servo(servo_ids[i]);
     manager_servos[i].id=servo_ids[i];
     manager_servos[i].max_value=1023;
     manager_servos[i].min_value=0;
@@ -210,74 +204,11 @@ void manager_init(uint8_t num_servos)
 
   /* initialize the period timer */
   manager_timer_init();
-}
-
-uint8_t manager_check_robot_fallen(void)
-{
-  uint8_t state = robot_fallen_state;
-  robot_fallen_state = 0x00;
-  return state;
-}
-
-uint8_t manager_calibrate_gyro(void)
-{
-  uint16_t x_gyro_values[GYRO_CAL_NUM_SAMPLES];
-  uint16_t y_gyro_values[GYRO_CAL_NUM_SAMPLES];
-  float x_gyro_average=0.0,y_gyro_average=0.0,std_x=0.0,std_y=0.0;
-  uint8_t calibrated=0x00;
-  uint8_t i=0,count=0;
+  /* initialize the action module */
+  action_init();
 
-  x_gyro_center=0;
-  y_gyro_center=0;
-  while(!calibrated)
-  {
-    for(i=0;i<GYRO_CAL_NUM_SAMPLES;i++)
-    {
-      _delay_ms(50);
-//      x_gyro_values[i]=get_adc_channel(X_GYRO_CHANNEL); 
-//      y_gyro_values[i]=get_adc_channel(Y_GYRO_CHANNEL); 
-      x_gyro_average+=x_gyro_values[i];
-      y_gyro_average+=y_gyro_values[i];
-    }  
-    x_gyro_average/=(float)GYRO_CAL_NUM_SAMPLES;
-    y_gyro_average/=(float)GYRO_CAL_NUM_SAMPLES;
-    // compute the standard deviation
-    for(i=0;i<GYRO_CAL_NUM_SAMPLES;i++)
-    {
-      std_x+=(x_gyro_values[i]-x_gyro_average)*(x_gyro_values[i]-x_gyro_average);
-      std_y+=(y_gyro_values[i]-y_gyro_average)*(y_gyro_values[i]-y_gyro_average);
-    }
-    std_x=sqrt(std_x/GYRO_CAL_NUM_SAMPLES);
-    std_y=sqrt(std_y/GYRO_CAL_NUM_SAMPLES);
-    if(std_x<20.0 && std_y<20.0)
-    {
-      calibrated=0x01;
-      x_gyro_center=(uint16_t)x_gyro_average;
-      y_gyro_center=(uint16_t)y_gyro_average;
-    }
-    else
-    {
-      count++;
-      if(count==5)
-        return 0x00;
-    }
-  }
   return 0x01;
 }
 
-void manager_enable_gyro(void)
-{
-  gyro_enabled=0x01;
-}
-
-void manager_disable_gyro(void)
-{
-  gyro_enabled=0x00;
-}
-
-uint8_t manager_is_gyro_enabled(void)
-{
-  return gyro_enabled;
-}
 
 
diff --git a/motion/src/motion_pages.c b/motion/src/motion_pages.c
index c8641f9e46af6e56dca137118ca738206b6f0e7c..3b53c1e3538c87ef5189423388d693b7d7f81263 100644
--- a/motion/src/motion_pages.c
+++ b/motion/src/motion_pages.c
@@ -1,14 +1,14 @@
 #include "motion_pages.h"
-#include "cm510.h"
 
-void pages_get_page(uint8_t page_id,TPage *page) {
-	uint8_t i=0;
-	uint8_t *ppage = (uint8_t *)page;
-	TPage *base_page = &((TPage *)PAGE_BASE_ADDR)[page_id];
-  
+void pages_get_page(uint8_t page_id,TPage *page) 
+{
+  uint8_t i=0;
+  uint8_t *ppage = (uint8_t *)page;
+  TPage *base_page = &((TPage *)PAGE_BASE_ADDR)[page_id];
+
   for(i=0;i<sizeof(TPage);i++) {
-		ppage[i]= pgm_read_byte_far((uint8_t *)base_page+i);
-	}
+    ppage[i]= pgm_read_byte_far((uint8_t *)base_page+i);
+  }
 }
 
 uint8_t pages_check_checksum(TPage *page)
@@ -40,24 +40,18 @@ void pages_copy_page(TPage *src,TPage *dst)
     ((uint8_t *)dst)[i]=((volatile uint8_t *)src)[i];
 }
 
-
-uint8_t load_page_info(uint8_t page_id,TPage *page) {
-//	uint8_t *start_address;
-//	uint16_t i;
-
-//	start_address=(uint8_t *)POSE_BASE_ADR+(0x200*page_id);
-
-//	for(i=0;i<0x200;i++) (((uint8_t *)page)[i])=pgm_read_byte(start_address+i);
+uint8_t load_page_info(uint8_t page_id,TPage *page) 
+{
   uint32_t i=0;
   uint8_t *ppage = (uint8_t *)page;
-//  TPage *base_page = (TPage *)PAGE_BASE_ADDR;
 
-  for(i=0;i<sizeof(TPage);i++) {
+  for(i=0;i<sizeof(TPage);i++) 
     ppage[i]= pgm_read_byte_far((uint32_t)PAGE_BASE_ADDR+(uint32_t)(sizeof(TPage)*page_id)+i);
-//    ppage[i]= pgm_read_byte_far( &(base_page[page_id])+i);
-  }
-	if(pages_check_checksum(page)==0) return 0;
-	else return -1;
+  
+  if(pages_check_checksum(page)==0) 
+    return 0;
+  else 
+    return -1;
 }