diff --git a/controllers/include/cm510_cfg.h b/controllers/include/cm510_cfg.h
index 0b2b730ac12bbc37fba3455238aed9fe85a1d636..54775760f91b5cbe79d46f74d6f9c4660d71a6be 100644
--- a/controllers/include/cm510_cfg.h
+++ b/controllers/include/cm510_cfg.h
@@ -20,7 +20,7 @@
 #define SERIAL_CONSOLE_MAX_BUFFER_LEN           128
 
 // motion configuration parameters
-#define MANAGER_MAX_NUM_SERVOS                  18 
+#define MANAGER_MAX_NUM_SERVOS                  32 
 #define MANAGER_MISSING_SERVOS_ALARM_NOTE       NOTE_SOL
 #define MANAGER_MISSING_SERVOS_ALARM_TIME_ON    10
 #define MANAGER_MISSING_SERVOS_ALARM_TIME_OFF   100
diff --git a/controllers/src/cm510.c b/controllers/src/cm510.c
index 91769ecf9738f9afe7052993a456bb43cf3fd200..16612ed2edf70c225e86a7808a6e29daf7121158 100755
--- a/controllers/src/cm510.c
+++ b/controllers/src/cm510.c
@@ -50,6 +50,7 @@ int16_t main(void)
   uint8_t num_servos;
 
   init_cm510();
+  turn_led_off(LED_BAT);
   sei();
   _delay_ms(2000);
   /* call the user initialization function */
diff --git a/dyn_devices/src/exp_board/exp_board.c b/dyn_devices/src/exp_board/exp_board.c
index 5098889252e8bd11cf961db10a02c720031371f0..f4df041c21ed4b96d523966776fa3c6a79c795b0 100755
--- a/dyn_devices/src/exp_board/exp_board.c
+++ b/dyn_devices/src/exp_board/exp_board.c
@@ -81,6 +81,8 @@ uint8_t exp_board_init(uint8_t board_id)
         exp_board_dac_present=0x00;
         exp_board_uart_usb_present=0x01;
       }
+      // read the number pf PWM servos
+      dyn_master_read_byte(exp_board_id,NUM_PWM_SERVOS,&exp_board_num_servos);
       return 0x00;
     } 
     else
@@ -89,10 +91,10 @@ uint8_t exp_board_init(uint8_t board_id)
       exp_board_uart_ttl_present=0x00;
       exp_board_pwm_present=0x00;
       exp_board_uart_usb_present=0x00;
+      // read the number pf PWM servos
+      dyn_master_read_byte(exp_board_id,NUM_PWM_SERVOS,&exp_board_num_servos);
       return 0xFF;
     }
-    // read the number pf PWM servos
-    dyn_master_read_byte(exp_board_id,NUM_PWM_SERVOS,&exp_board_num_servos);
   }
   else
   {
diff --git a/examples/pan_tilt/Makefile b/examples/pan_tilt/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..419086620880f1f6fae04368489a249b5993be73
--- /dev/null
+++ b/examples/pan_tilt/Makefile
@@ -0,0 +1,57 @@
+PROJECT=pan_tilt
+########################################################
+# afegir tots els fitxers que s'han de compilar aquí
+########################################################
+SOURCES=pan_tilt.c 
+
+OBJS=$(SOURCES:.c=.o)
+SRC_DIR=./
+DEV_DIR=../../dyn_devices/
+COMM_DIR=../../communications/
+CONT_DIR=../../controllers/
+MAN_DIR=../../motion/
+CC=avr-gcc
+OBJCOPY=avr-objcopy
+MMCU=atmega2561
+
+LIBS=$(MAN_DIR)lib/libmotion_manager.a $(CONT_DIR)lib/libcontrollers.a $(COMM_DIR)lib/libcomm.a $(DEV_DIR)lib/libdyn_devices.a
+
+INCLUDE_DIRS=-I$(DEV_DIR)include -I$(COMM_DIR)include -I$(CONT_DIR)include -I$(MAN_DIR)include -I../movements
+
+CFLAGS=-mmcu=$(MMCU) -Wall -Os $(defines) -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
+
+HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature
+
+.PHONY: all
+
+all: communications dyn_devices controllers motion_manager $(PROJECT).hex
+
+$(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 $@ $<
+
+communications:
+	$(MAKE) -C $(COMM_DIR)
+
+dyn_devices:
+	$(MAKE) -C $(DEV_DIR)
+
+controllers:
+	$(MAKE) -C $(CONT_DIR)
+
+motion_manager:
+	$(MAKE) -C $(MAN_DIR)
+
+download: $(MAIN_OUT_HEX)
+	fw_downloader -d /dev/ttyUSB0 -f ./$(PROJECT).hex -p cm510
+
+clean:
+	-rm $(PROJECT).map
+	-rm $(PROJECT).hex
+	-rm $(PROJECT).elf
+	-rm $(OBJS)
diff --git a/examples/pan_tilt/pan_tilt.c b/examples/pan_tilt/pan_tilt.c
new file mode 100644
index 0000000000000000000000000000000000000000..8b3ec676826bace4fdcb945b2a3f3c96445eddec
--- /dev/null
+++ b/examples/pan_tilt/pan_tilt.c
@@ -0,0 +1,88 @@
+#include <util/delay.h>
+#include <stdio.h>
+#include "cm510.h"
+#include "balance.h"
+#include "exp_board.h"
+#include "pan_tilt.h"
+
+typedef enum {wait_start,wait_cmd,wait_pan_left,wait_pan_right,wait_tilt_up,wait_tilt_down} main_states;
+
+#define PAN_SERVO_ID    19
+#define TILT_SERVO_ID   20
+
+void user_init(void)
+{
+  serial_console_init(57600);
+  balance_init();
+  balance_calibrate_gyro();
+  balance_enable_gyro();
+  user_time_set_period(100);
+  pan_tilt_init(PAN_SERVO_ID,TILT_SERVO_ID);
+}
+
+void user_loop(void)
+{
+  static main_states state=wait_start;
+
+  if(user_time_is_period_done())
+  {
+    switch(state)
+    {
+      case wait_start: if(is_button_rising_edge(BTN_START))
+                       {
+                         action_set_page(31);
+                         action_start_page();
+                         state=wait_cmd;
+                       }
+                       else
+                         state=wait_start;
+                       break;
+      case wait_cmd: if(is_button_rising_edge(BTN_LEFT))
+                     {
+                       pan_set_speed(10);
+                       pan_move_angle(70);
+                       state=wait_pan_left;
+                     }
+                     else if(is_button_rising_edge(BTN_RIGHT))
+                     {
+                       pan_set_speed(200);
+                       pan_move_angle(-70);
+                       state=wait_pan_right;
+                     } 
+                     else if(is_button_rising_edge(BTN_UP))
+                     {
+                       tilt_set_speed(10);
+                       tilt_move_angle(70);
+                       state=wait_tilt_up;
+                     } 
+                     else if(is_button_rising_edge(BTN_DOWN))
+                     {
+                       tilt_set_speed(200);
+                       tilt_move_angle(-70);
+                       state=wait_tilt_down;
+                     } 
+                     break;
+      case wait_pan_left: if(pan_is_moving())
+                            state=wait_pan_left;
+                          else
+                            state=wait_cmd;
+                          break; 
+      case wait_pan_right: if(pan_is_moving())
+                             state=wait_pan_right;
+                           else
+                             state=wait_cmd;
+                           break;
+      case wait_tilt_up: if(tilt_is_moving())
+                           state=wait_tilt_up;
+                         else
+                           state=wait_cmd;
+                         break;
+      case wait_tilt_down: if(tilt_is_moving())
+                             state=wait_tilt_down;
+                           else
+                             state=wait_cmd;
+                           break;
+    }
+  }
+}
+
diff --git a/motion/Makefile b/motion/Makefile
index 5b1a7eebcbb7df4fc7c92336a70a9c94bd683f90..2b667ac1a44b2ab3f87f261801e7016b9601c6d8 100755
--- a/motion/Makefile
+++ b/motion/Makefile
@@ -1,5 +1,5 @@
 PROJECT=libmotion_manager
-SOURCES=src/motion_manager.c src/action.c src/motion_pages.c src/balance.c
+SOURCES=src/motion_manager.c src/action.c src/motion_pages.c src/balance.c src/pan_tilt.c
 OBJS=$(SOURCES:.c=.o)
 SRC_DIR=./src/ 
 BIN_DIR=./build/
diff --git a/motion/include/motion_cfg.h b/motion/include/motion_cfg.h
index 399c1cfc097bb9e6204769b0af55e9dc6930495a..0440e64c64301544b029bb5b779867790189d5ce 100644
--- a/motion/include/motion_cfg.h
+++ b/motion/include/motion_cfg.h
@@ -4,7 +4,7 @@
 #include "buzzer.h"
 
 #ifndef MANAGER_MAX_NUM_SERVOS
-  #define MANAGER_MAX_NUM_SERVOS                  18
+  #define MANAGER_MAX_NUM_SERVOS                  32
 #endif
 
 #ifndef MANAGER_MISSING_SERVOS_ALARM_NOTE
diff --git a/motion/include/motion_manager.h b/motion/include/motion_manager.h
index 32f7ff0e5e63eca3db6345e9582f319a9c3ee906..5f4e43172e70a64fa0995dd77ce72dc0cd17c454 100644
--- a/motion/include/motion_manager.h
+++ b/motion/include/motion_manager.h
@@ -11,12 +11,14 @@ typedef enum {MM_NONE=0,MM_ACTION=1,MM_JOINTS=2} mm_module_t;
 
 // servo information structure
 typedef struct{
+  uint16_t angle;
   uint16_t max_value;
   uint16_t min_value;
   uint16_t center_value;
   uint16_t current_value;
-  uint8_t cc_slope;
-  uint8_t ccw_slope;
+  uint16_t cw_limit;
+  uint16_t ccw_limit;
+  uint8_t slope;
   mm_module_t module;
 }TServoInfo;
 
diff --git a/motion/include/pan_tilt.h b/motion/include/pan_tilt.h
index 8ec19866066cc131b7fb70969c80f801cd5c43b4..8623da4d24d35ca6a290daa144e9e6465cbb492c 100644
--- a/motion/include/pan_tilt.h
+++ b/motion/include/pan_tilt.h
@@ -1,13 +1,28 @@
 #ifndef PAN_TILT_H
 #define PAN_TILT_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <avr/io.h>
+
 // public functions
-void pan_tilt_init(void);
-void pan_tilt_set_angles(int8_t pan_angle,uint8_t titl_angle);
-void pan_set_angle(int8_t pan_angle);
+void pan_tilt_init(uint8_t pan_id,uint8_t tilt_id);
+void pan_tilt_move_angles(int8_t pan_angle,uint8_t titl_angle);
+void pan_move_angle(int8_t pan_angle);
 void pan_set_speed(uint8_t pan_speed);
-void tilt_set_angle(int8_t tilt_angle);
-void tilt_set_speed(int8_t tilt_speed);
+void pan_stop(void);
+uint8_t pan_is_moving(void);
+void tilt_move_angle(int8_t tilt_angle);
+void tilt_set_speed(uint8_t tilt_speed);
+void tilt_stop(void);
+uint8_t tilt_is_moving(void);
+
 void pan_tilt_process(void);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
diff --git a/motion/src/action.c b/motion/src/action.c
index 25c3ef1b2516093e040a5d50baf0bb7425c6ee2d..6029311220afbc1930d940bfbbb1ad8b71d54a0e 100644
--- a/motion/src/action.c
+++ b/motion/src/action.c
@@ -22,11 +22,9 @@ 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_servo_value(uint8_t servo_id);
-extern mm_module_t manager_get_servo_module(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);
+// external variables
+extern uint8_t manager_num_servos;
+extern TServoInfo manager_servos[MANAGER_MAX_NUM_SERVOS];
 
 // private variables
 uint8_t action_finished;
@@ -61,7 +59,6 @@ uint8_t action_is_running;
 // public functions
 void action_init(void)
 {
-  //ram_write_byte(CM730_ACTION_STATUS,0x00);
   action_finished=0x00;
   action_stop=0x00;
   action_next_index=0xFF;
@@ -93,11 +90,11 @@ void action_start_page(void)
   bPlayRepeatCount = action_current_page.header.repeat;
   action_next_index = 0x00;
 
-  for(i=1;i<=MANAGER_MAX_NUM_SERVOS;i++)
+  for(i=0;i<MANAGER_MAX_NUM_SERVOS;i++)
   {
-    if(manager_get_servo_module(i)==MM_ACTION)
+    if(manager_servos[i].module==MM_ACTION)
     {
-      wpTargetAngle1024[i] = manager_get_servo_value(i);
+      wpTargetAngle1024[i] = manager_servos[i].current_value;
       ipLastOutSpeed1024[i] = 0;
       ipMovingAngle1024[i] = 0;
       ipGoalSpeed1024[i] = 0;
@@ -147,9 +144,9 @@ void action_process(void)
 
     for(bID=0;bID<MANAGER_MAX_NUM_SERVOS;bID++)
     {
-      if(manager_get_servo_module(bID)==MM_ACTION)
+      if(manager_servos[bID].module==MM_ACTION)
       {
-        wpStartAngle1024[bID] = manager_get_servo_value(bID);
+        wpStartAngle1024[bID] = manager_servos[bID].current_value;
         ipLastOutSpeed1024[bID] = ipGoalSpeed1024[bID];
       }
     }
@@ -162,7 +159,7 @@ void action_process(void)
       wUnitTimeNum =  wUnitTimeTotalNum - (wAccelStep << 1);
       for(bID=0;bID<MANAGER_MAX_NUM_SERVOS;bID++)
       {
-        if(manager_get_servo_module(bID)==MM_ACTION)
+        if(manager_servos[bID].module==MM_ACTION)
         {
           if( bpFinishType[bID] == NONE_ZERO_FINISH )
           {
@@ -183,7 +180,7 @@ void action_process(void)
       wUnitTimeNum = wAccelStep;
 
       for(bID=0;bID<MANAGER_MAX_NUM_SERVOS;bID++)
-        if(manager_get_servo_module(bID)==MM_ACTION)
+        if(manager_servos[bID].module==MM_ACTION)
           ipMainAngle1024[bID] = ipMovingAngle1024[bID] - ipMainAngle1024[bID] - ipAccelAngle1024[bID];
     }
     else if( bSection == POST_SECTION )
@@ -205,7 +202,7 @@ void action_process(void)
       bSection = PRE_SECTION;
 
       for(bID=0;bID<MANAGER_MAX_NUM_SERVOS;bID++)
-        if(manager_get_servo_module(bID)==MM_ACTION)
+        if(manager_servos[bID].module==MM_ACTION)
           ipLastOutSpeed1024[bID] = 0;
     }
 
@@ -270,7 +267,7 @@ void action_process(void)
       ////////// Jointº° ÆÄ¶ó¹ÌÅÍ °è»ê
       for(bID=0;bID<MANAGER_MAX_NUM_SERVOS;bID++)
       {
-        if(manager_get_servo_module(bID)==MM_ACTION)
+        if(manager_servos[bID].module==MM_ACTION)
         {
           // ÀÌÀü, ÇöÀç, ¹Ì·¡¸¦ ¹ÙÅÁÀ¸·Î ±ËÀûÀ» °è»ê
           ipAccelAngle1024[bID] = 0;
@@ -366,7 +363,7 @@ void action_process(void)
         lDivider2 = 1;
       for(bID=0;bID<MANAGER_MAX_NUM_SERVOS;bID++)
       {
-        if(manager_get_servo_module(bID)==MM_ACTION)
+        if(manager_servos[bID].module==MM_ACTION)
         {
           lStartSpeed1024_PreTime_256T = (long)ipLastOutSpeed1024[bID] * ulPreSectionTime256T; //  *300/1024 * 1024/720 * 256 * 2
           lMovingAngle_Speed1024Scale_256T_2T = (((long)ipMovingAngle1024[bID]) * 2560L) / 12;
@@ -395,10 +392,10 @@ void action_process(void)
     {
       for(bID=0;bID<MANAGER_MAX_NUM_SERVOS;bID++)
       {
-        if(manager_get_servo_module(bID)==MM_ACTION)
+        if(manager_servos[bID].module==MM_ACTION)
         {
           if( ipMovingAngle1024[bID] == 0 )
-            manager_set_servo_value(bID,wpStartAngle1024[bID]);
+            manager_servos[bID].current_value=wpStartAngle1024[bID];
           else
           {
             if( bSection == PRE_SECTION )
@@ -406,11 +403,11 @@ void action_process(void)
               iSpeedN = (short)(((long)(ipMainSpeed1024[bID] - ipLastOutSpeed1024[bID]) * wUnitTimeCount) / wUnitTimeNum);
               ipGoalSpeed1024[bID] = ipLastOutSpeed1024[bID] + iSpeedN;
               ipAccelAngle1024[bID] =  (short)((((long)(ipLastOutSpeed1024[bID] + (iSpeedN >> 1)) * wUnitTimeCount * 144) / 15) >> 9);
-              manager_set_servo_value(bID,wpStartAngle1024[bID] + ipAccelAngle1024[bID]);
+              manager_servos[bID].current_value=wpStartAngle1024[bID] + ipAccelAngle1024[bID];
             }
             else if( bSection == MAIN_SECTION )
             {
-              manager_set_servo_value(bID,wpStartAngle1024[bID] + (short int)(((long)(ipMainAngle1024[bID])*wUnitTimeCount) / wUnitTimeNum));
+              manager_servos[bID].current_value=wpStartAngle1024[bID] + (short int)(((long)(ipMainAngle1024[bID])*wUnitTimeCount) / wUnitTimeNum);
               ipGoalSpeed1024[bID] = ipMainSpeed1024[bID];
             }
             else // POST_SECTION
@@ -418,7 +415,7 @@ void action_process(void)
               if( wUnitTimeCount == (wUnitTimeNum-1) )
               {
                 // ½ºÅÜ ¸¶Áö¸· ¿ÀÂ÷¸¦ ÁÙÀ̱âÀ§ÇØ ±×³É ¸ñÇ¥ À§Ä¡ °ªÀ» »ç¿ë
-                manager_set_servo_value(bID,wpTargetAngle1024[bID]);
+                manager_servos[bID].current_value=wpTargetAngle1024[bID];
               }
               else
               {
@@ -426,20 +423,20 @@ void action_process(void)
                 {
                   iSpeedN = (short int)(((long)(0 - ipLastOutSpeed1024[bID]) * wUnitTimeCount) / wUnitTimeNum);
                   ipGoalSpeed1024[bID] = ipLastOutSpeed1024[bID] + iSpeedN;
-                  manager_set_servo_value(bID,wpStartAngle1024[bID] +  (short)((((long)(ipLastOutSpeed1024[bID] + (iSpeedN>>1)) * wUnitTimeCount * 144) / 15) >> 9));
+                  manager_servos[bID].current_value=wpStartAngle1024[bID] +  (short)((((long)(ipLastOutSpeed1024[bID] + (iSpeedN>>1)) * wUnitTimeCount * 144) / 15) >> 9);
                 }
                 else // NONE_ZERO_FINISH
                 {
                   // MAIN Section°ú µ¿ÀÏÇÏ°Ô ÀÛµ¿-µ¿ÀÏ
                   // step¿¡¼­ ¾î¶²¼­º¸´Â °¡°í ¾î¶² ¼­º¸´Â ¼­¾ßÇÏ´Â »óȲÀÌ ¹ß»ýÇÒ ¼ö ÀÖÀ¸¹Ç·Î ÀÌ·¸°Ô ÇÒ ¼ö¹Û¿¡ ¾øÀ½
-                  manager_set_servo_value(bID,wpStartAngle1024[bID] + (short int)(((long)(ipMainAngle1024[bID]) * wUnitTimeCount) / wUnitTimeNum));
+                  manager_servos[bID].current_value=wpStartAngle1024[bID] + (short int)(((long)(ipMainAngle1024[bID]) * wUnitTimeCount) / wUnitTimeNum);
                   ipGoalSpeed1024[bID] = ipMainSpeed1024[bID];
                 }
               }
             }
           }
           //set slopes
-          manager_set_servo_slopes(bID, action_current_page.header.slope[bID]);
+          manager_servos[bID].slope=action_current_page.header.slope[bID];
         }
       }
     }
diff --git a/motion/src/motion_manager.c b/motion/src/motion_manager.c
index d9735b5d3258a112bac9f12c23f573c2a6d00554..53084cb906f797585bd28fe9863443c096252cac 100644
--- a/motion/src/motion_manager.c
+++ b/motion/src/motion_manager.c
@@ -31,7 +31,7 @@ extern TActionPage action_current_page;
 
 typedef struct
 {
-  uint8_t cc_slope;
+  uint8_t cw_slope;
   uint8_t ccw_slope;
   uint16_t position;
 }dyn_send_data;
@@ -93,15 +93,16 @@ void manager_send_motion_command(void)
       pdata[num*4+2] = target_pos&0xFF;
       pdata[num*4+3] = (target_pos>>8)&0xFF;
 
-      if(manager_servos[i].cc_slope == 0) 
+      if(manager_servos[i].slope == 0) 
+      {
         pdata[num*4] = 32;
-      else 
-        pdata[num*4] = 1<<(0x0F&manager_servos[i].cc_slope);
-
-      if(manager_servos[i].ccw_slope == 0)
         pdata[num*4+1] = 32;
+      }
       else 
-        pdata[num*4+1] = 1<<(0x0F&manager_servos[i].ccw_slope);
+      {
+        pdata[num*4] = 1<<(0x0F&manager_servos[i].slope);
+        pdata[num*4+1] = 1<<(0x0F&manager_servos[i].slope);
+      }
 
       packets[num].data_addr=(uint8_t *)&data[num];
       num++;
@@ -111,19 +112,14 @@ void manager_send_motion_command(void)
     dyn_master_sync_write(manager_num_servos,servo_ids,CW_COMP_SLOPE,4,packets); 
 }
 
-void manager_get_current_position(void)
+void manager_set_servo_slope(uint8_t servo_id, uint8_t slope)
 {
-  uint8_t i;
-
-  for(i=0;i<MANAGER_MAX_NUM_SERVOS;i++)
-    if(manager_servos[i].module!=MM_NONE)
-      manager_servos[i].current_value=get_current_position(i);
+  manager_servos[servo_id].slope=slope;
 }
 
-void manager_set_servo_slopes(uint8_t servo_id, uint8_t slope)
-{
-  manager_servos[servo_id].cc_slope=slope;
-  manager_servos[servo_id].ccw_slope=slope;
+uint8_t manager_get_servo_slope(uint8_t servo_id)
+{ 
+  return manager_servos[servo_id].slope;
 }
 
 void manager_set_servo_value(uint8_t servo_id, uint16_t value)
@@ -141,6 +137,15 @@ mm_module_t manager_get_servo_module(uint8_t servo_id)
   return manager_servos[servo_id].module;
 }
 
+uint8_t manager_get_cw_servo_limit(uint8_t servo_id)
+{
+  return manager_servos[servo_id].cw_limit;
+}
+
+uint8_t manager_get_ccw_servo_limit(uint8_t servo_id)
+{
+  return manager_servos[servo_id].ccw_limit;
+}
 void manager_loop(void)
 {
   if(manager_period_done()==0x01)
@@ -174,11 +179,15 @@ uint8_t manager_init(uint8_t num_servos)
   /* initialize by default the information for all servos */
   for(i=0;i<num;i++)
   {
+    manager_servos[i].angle=0;
     manager_servos[i].max_value=0;
     manager_servos[i].min_value=0;
     manager_servos[i].center_value=0;
     manager_servos[i].current_value=0;
     manager_servos[i].module=MM_NONE;
+    manager_servos[i].slope=32;
+    manager_servos[i].cw_limit=0;
+    manager_servos[i].ccw_limit=0;
   }
 
   /* scan the bus for all available servos */
@@ -192,21 +201,27 @@ uint8_t manager_init(uint8_t num_servos)
     if(model==0x000C || model==0x012C)// standard AX-12 or AX12W
     {
       enable_servo(id);
+      manager_servos[id].angle=300;
       manager_servos[id].max_value=1023;
       manager_servos[id].min_value=0;
       manager_servos[id].center_value=512;
       manager_servos[id].current_value=get_current_position(id);
+      get_angle_limits(id,&manager_servos[i].cw_limit,&manager_servos[id].ccw_limit);
       manager_servos[id].module=MM_ACTION;
+      manager_servos[id].slope=32;
       manager_num_servos++;
     }
     else if(model==0x0C00)// Emmulated servos from the expansion board pan&tilt servos
     {
       enable_servo(id);
+      manager_servos[id].angle=300;
       manager_servos[id].max_value=1023;
       manager_servos[id].min_value=0;
       manager_servos[id].center_value=512;
       manager_servos[id].current_value=get_current_position(id);
+      get_angle_limits(id,&manager_servos[i].cw_limit,&manager_servos[id].ccw_limit);
       manager_servos[id].module=MM_JOINTS;
+      manager_servos[id].slope=32;
       manager_num_servos++;
     }
   } 
diff --git a/motion/src/pan_tilt.c b/motion/src/pan_tilt.c
index a79e2fe96732526234218130d5ef55c10de06ee1..66f1ab55340aaec90197d597d212c5e1403d2075 100644
--- a/motion/src/pan_tilt.c
+++ b/motion/src/pan_tilt.c
@@ -1,51 +1,209 @@
 #include "pan_tilt.h"
+#include "motion_cfg.h"
+#include "motion_manager.h"
 
-// external functions
-extern uint16_t manager_get_servo_value(uint8_t servo_id);
-extern mm_module_t manager_get_servo_module(uint8_t servo_id);
-extern void manager_set_servo_value(uint8_t servo_id, uint16_t value);
+// external variables
+extern uint8_t manager_num_servos;
+extern TServoInfo manager_servos[MANAGER_MAX_NUM_SERVOS];
 
 // private variables
-uint16_t pan_angle;
-uint16_t pan_speed;
+// pan variables
+uint32_t pan_target_angle;
+uint32_t pan_target_speed;
+uint32_t pan_current_angle;
+uint8_t pan_stoping;
+uint8_t pan_moving;
 uint8_t pan_servo_id;
-uint16_t tilt_angle;
-uint16_t tilt_speed;
+// tilt variables
+uint32_t tilt_target_angle;
+uint32_t tilt_target_speed;
+uint32_t tilt_current_angle;
+uint8_t tilt_stoping;
+uint8_t tilt_moving;
 uint8_t tilt_servo_id;
 
 // public functions
 void pan_tilt_init(uint8_t pan_id,uint8_t tilt_id)
 {
+  // set serov ID's
   pan_servo_id=pan_id;
   tilt_servo_id=tilt_id;
+  /* initialize pan variables */
+  pan_target_angle=manager_servos[pan_servo_id].current_value<<7;
+  pan_target_speed=0;
+  pan_current_angle=manager_servos[pan_servo_id].current_value<<7;
+  pan_stoping=0x00;
+  pan_moving=0x00;
+  /* initialize tilt variables */
+  tilt_target_angle=manager_servos[tilt_servo_id].current_value<<7;
+  tilt_target_speed=0;
+  tilt_current_angle=manager_servos[tilt_servo_id].current_value<<7;
+  tilt_stoping=0x00;
+  tilt_moving=0x00;
 }
 
-void pan_tilt_set_angles(int8_t pan_angle,uint8_t titl_angle)
+void pan_tilt_move_angles(int8_t pan_angle,uint8_t tilt_angle)
 {
-
+  pan_move_angle(pan_angle);
+  tilt_move_angle(tilt_angle);
 }
 
-void pan_set_angle(int8_t pan_angle)
+void pan_move_angle(int8_t pan_angle)
 {
-
+  if(pan_servo_id!=0xFF)
+  {
+    if(pan_target_speed==0)
+    {
+      pan_target_angle=manager_servos[pan_servo_id].current_value<<7;
+      pan_current_angle=manager_servos[pan_servo_id].current_value<<7;
+      pan_moving=0x00;
+    }
+    else
+    {
+      pan_current_angle=manager_servos[pan_servo_id].current_value<<7;
+      pan_target_angle=((uint32_t)(((int32_t)pan_angle*(int32_t)manager_servos[pan_servo_id].max_value)/((int32_t)manager_servos[pan_servo_id].angle))+(uint32_t)manager_servos[pan_servo_id].center_value);
+      if(pan_target_angle>manager_servos[pan_servo_id].ccw_limit)
+        pan_target_angle=manager_servos[pan_servo_id].ccw_limit;
+      else if(pan_target_angle<manager_servos[pan_servo_id].cw_limit)
+        pan_target_angle=manager_servos[pan_servo_id].cw_limit;
+      pan_target_angle=pan_target_angle<<7;
+      pan_moving=0x01;
+    }
+  }
 }
 
 void pan_set_speed(uint8_t pan_speed)
 {
+  pan_target_speed=(((uint32_t)pan_speed*(uint32_t)manager_servos[pan_servo_id].max_value)/((uint32_t)manager_servos[pan_servo_id].angle));
+}
 
+void pan_stop(void)
+{
+  pan_stoping=0x01;
 }
 
-void tilt_set_angle(int8_t tilt_angle)
+uint8_t pan_is_moving(void)
 {
+  return pan_moving;
+}
 
+void tilt_move_angle(int8_t tilt_angle)
+{
+  if(tilt_servo_id!=0xFF)
+  {
+    if(tilt_target_speed==0)
+    {
+      tilt_target_angle=manager_servos[tilt_servo_id].current_value<<7;
+      tilt_current_angle=manager_servos[tilt_servo_id].current_value<<7;
+      tilt_moving=0x00;
+    }
+    else
+    {
+      tilt_current_angle=manager_servos[tilt_servo_id].current_value<<7;
+      tilt_target_angle=(((int32_t)tilt_angle*(int32_t)manager_servos[tilt_servo_id].max_value)/((int32_t)manager_servos[tilt_servo_id].angle))+manager_servos[tilt_servo_id].center_value;
+      if(tilt_target_angle>manager_servos[tilt_servo_id].ccw_limit)
+        tilt_target_angle=manager_servos[tilt_servo_id].ccw_limit;
+      else if(tilt_target_angle<manager_servos[tilt_servo_id].cw_limit)
+        tilt_target_angle=manager_servos[tilt_servo_id].cw_limit;
+      tilt_target_angle=tilt_target_angle<<7;
+      tilt_moving=0x01;
+    }
+  }
 }
 
-void tilt_set_speed(int8_t tilt_speed)
+void tilt_set_speed(uint8_t tilt_speed)
 {
+  tilt_target_speed=(((uint32_t)tilt_speed*(uint32_t)manager_servos[tilt_servo_id].max_value)/((uint32_t)manager_servos[tilt_servo_id].angle));
+}
 
+void tilt_stop(void)
+{
+  tilt_stoping=0x01;
+}
+
+uint8_t tilt_is_moving(void)
+{
+  return tilt_moving;
 }
 
 void pan_tilt_process(void)
 {
-  
+  // pan control
+  if(pan_stoping==0x01)
+  {
+    pan_target_angle=manager_servos[pan_servo_id].current_value<<7;
+    pan_current_angle=manager_servos[pan_servo_id].current_value<<7;
+    pan_target_speed=0;
+    pan_moving=0x00;
+    pan_stoping=0x00;
+  }
+  else
+  {
+    if(pan_current_angle<pan_target_angle)
+    {
+      pan_current_angle+=pan_target_speed;
+      if(pan_current_angle>=pan_target_angle)
+      {
+        pan_current_angle=pan_target_angle;
+        pan_moving=0x00;
+      }
+    }
+    else if(pan_current_angle>pan_target_angle)
+    {
+      if(pan_current_angle<pan_target_speed)
+      {
+        pan_current_angle=pan_target_angle;
+        pan_moving=0x00;
+      }
+      else
+      {
+        pan_current_angle-=pan_target_speed;
+        if(pan_current_angle<=pan_target_angle)
+        {
+          pan_current_angle=pan_target_angle;
+         pan_moving=0x00;
+        }
+      }
+    }
+  }
+  manager_servos[pan_servo_id].current_value=(pan_current_angle>>7);
+  // tilt control
+  if(tilt_stoping==0x01)
+  {
+    tilt_target_angle=manager_servos[tilt_servo_id].current_value;
+    tilt_current_angle=manager_servos[tilt_servo_id].current_value;
+    tilt_target_speed=0;
+    tilt_moving=0x00;
+    tilt_stoping=0x00;
+  }
+  else
+  {
+    if(tilt_current_angle<tilt_target_angle)
+    {
+      tilt_current_angle+=tilt_target_speed;
+      if(tilt_current_angle>=tilt_target_angle)
+      {
+        tilt_current_angle=tilt_target_angle;
+        tilt_moving=0x00;
+      }
+    }
+    else if(tilt_current_angle>tilt_target_angle)
+    {
+      if(tilt_current_angle<tilt_target_speed)
+      { 
+        tilt_current_angle=tilt_target_angle;
+        tilt_moving=0x00;
+      }  
+      else
+      {
+        tilt_current_angle-=tilt_target_speed;
+        if(tilt_current_angle<=tilt_target_angle)
+        {
+          tilt_current_angle=tilt_target_angle;
+          tilt_moving=0x00;
+        }  
+      }
+    }  
+  }
+  manager_servos[tilt_servo_id].current_value=(tilt_current_angle>>7);
 }