diff --git a/src/bioloid_stm32.c b/src/bioloid_stm32.c
index 0c268d7020b3d13527d633aae1335c29066d8166..4270daee979620d6a44c806741293f78c1193df4 100644
--- a/src/bioloid_stm32.c
+++ b/src/bioloid_stm32.c
@@ -27,9 +27,15 @@ uint8_t read_operation(uint8_t address, uint8_t length, uint8_t *data)
   }
   else// RAM region
   {
+    return DYN_NO_ERROR;
   }
 }
 
+void test_gpio(void)
+{
+  gpio_toggle_led(NORTH_LED);
+}
+
 int32_t main(void)
 {
   uint8_t inst_packet[1024];
@@ -78,6 +84,8 @@ int32_t main(void)
   else
     GPIO_ResetBits(GPIOD,GPIO_Pin_14);
 
+  gpio_set_pushbutton_callback(NORTH_PB,test_gpio);
+
   while(1)                             /* main function does not return */
   {
     if(dyn_slave_is_packet_ready())// check if a new instruction packet has been received
diff --git a/src/gpio.c b/src/gpio.c
index 625c0a23dd646d4d4f8219923df81c6f5a127752..a5c60edecca04ef793dd0273c52e8bf6596773af 100644
--- a/src/gpio.c
+++ b/src/gpio.c
@@ -24,31 +24,43 @@
 #define PUSH_BUTTON1_PIN          GPIO_Pin_6                
 #define PUSH_BUTTON1_GPIO_PORT    GPIOE                       
 #define PUSH_BUTTON1_SOURCE       GPIO_PinSource6
+#define PUSH_BUTTON1_EXTI_PORT    EXTI_PortSourceGPIOE
+#define PUSH_BUTTON1_EXTI_PIN     EXTI_PinSource6
+#define PUSH_BUTTON1_EXTI_LINE    EXTI_Line6
 
 #define PUSH_BUTTON2_GPIO_CLK     RCC_AHB1Periph_GPIOC
 #define PUSH_BUTTON2_PIN          GPIO_Pin_13                
 #define PUSH_BUTTON2_GPIO_PORT    GPIOC                       
 #define PUSH_BUTTON2_SOURCE       GPIO_PinSource13
+#define PUSH_BUTTON2_EXTI_PORT    EXTI_PortSourceGPIOC
+#define PUSH_BUTTON2_EXTI_PIN     EXTI_PinSource13
+#define PUSH_BUTTON2_EXTI_LINE    EXTI_Line13
 
 #define PUSH_BUTTON3_GPIO_CLK     RCC_AHB1Periph_GPIOC
 #define PUSH_BUTTON3_PIN          GPIO_Pin_14                
 #define PUSH_BUTTON3_GPIO_PORT    GPIOC                       
 #define PUSH_BUTTON3_SOURCE       GPIO_PinSource14
+#define PUSH_BUTTON3_EXTI_PORT    EXTI_PortSourceGPIOC
+#define PUSH_BUTTON3_EXTI_PIN     EXTI_PinSource14
+#define PUSH_BUTTON3_EXTI_LINE    EXTI_Line14
 
 #define PUSH_BUTTON4_GPIO_CLK     RCC_AHB1Periph_GPIOC
 #define PUSH_BUTTON4_PIN          GPIO_Pin_15
 #define PUSH_BUTTON4_GPIO_PORT    GPIOC                       
 #define PUSH_BUTTON4_SOURCE       GPIO_PinSource15
+#define PUSH_BUTTON4_EXTI_PORT    EXTI_PortSourceGPIOC
+#define PUSH_BUTTON4_EXTI_PIN     EXTI_PinSource15
+#define PUSH_BUTTON4_EXTI_LINE    EXTI_Line15
 
 #define GPO_TIMER                 TIM2
 #define GPO_TIMER_CLK             RCC_APB1Periph_TIM2
 #define GPO_TIMER_IRQn            TIM2_IRQn
 #define GPO_TIMER_IRQHandler      TIM2_IRQHandler
 
-#define GPI_TIMER                 TIM3
-#define GPI_TIMER_CLK             RCC_APB1Periph_TIM3
-#define GPI_TIMER_IRQn            TIM3_IRQn
-#define GPI_TIMER_IRQHandler      TIM3_IRQHandler
+#define GPI_EXTI1_IRQn            EXTI9_5_IRQn
+#define GPI_EXTI1_IRQHandler      EXTI9_5_IRQHandler
+#define GPI_EXTI2_IRQn            EXTI15_10_IRQn
+#define GPI_EXTI2_IRQHandler      EXTI15_10_IRQHandler
 
 // private variables
 // LED blink periods
@@ -62,39 +74,40 @@ void (*south_pb_callback)(void);
 void (*east_pb_callback)(void);
 void (*west_pb_callback)(void);
 
-// IRQ hanfler functions
-void GPI_TIMER_IRQHandler(void)
+// IRQ handler functions
+void GPI_EXTI1_IRQHandler(void)
 {
-  uint16_t capture;
-  static uint8_t north_pb_last=Bit_SET,south_pb_last=Bit_SET,east_pb_last=Bit_SET,west_pb_last=Bit_SET;
-  uint8_t north_pb_new,south_pb_new,east_pb_new,west_pb_new;
+  if(EXTI_GetITStatus(PUSH_BUTTON1_EXTI_LINE) != RESET)
+  {
+    if(north_pb_callback!=0)  
+      north_pb_callback();
+    /* Clear the EXTI line 0 pending bit */
+    EXTI_ClearITPendingBit(PUSH_BUTTON1_EXTI_LINE);
+  }
+}
 
-  if(TIM_GetITStatus(GPI_TIMER, TIM_IT_CC1)!=RESET)
+void GPI_EXTI2_IRQHandler(void)
+{
+  if(EXTI_GetITStatus(PUSH_BUTTON2_EXTI_LINE) != RESET)
   {
-    TIM_ClearITPendingBit(GPI_TIMER,TIM_IT_CC1);
-    capture = TIM_GetCapture1(GPI_TIMER);
-    TIM_SetCompare1(GPI_TIMER, capture + 10);
-    /* check all the pushbuttons */
-    north_pb_new=GPIO_ReadInputDataBit(PUSH_BUTTON1_GPIO_PORT,PUSH_BUTTON1_PIN);
-    if(north_pb_last==Bit_SET && north_pb_new==Bit_RESET)
-      if(north_pb_callback!=0)  
-        north_pb_callback();
-    north_pb_last=north_pb_new;
-    south_pb_new=GPIO_ReadInputDataBit(PUSH_BUTTON2_GPIO_PORT,PUSH_BUTTON2_PIN);
-    if(south_pb_last==Bit_SET && south_pb_new==Bit_RESET)
-      if(south_pb_callback!=0)  
-        south_pb_callback();
-    south_pb_last=south_pb_new;
-    east_pb_new=GPIO_ReadInputDataBit(PUSH_BUTTON3_GPIO_PORT,PUSH_BUTTON3_PIN);
-    if(east_pb_last==Bit_SET && east_pb_new==Bit_RESET)
-      if(east_pb_callback!=0)  
-        east_pb_callback();
-    east_pb_last=east_pb_new;
-    west_pb_new=GPIO_ReadInputDataBit(PUSH_BUTTON4_GPIO_PORT,PUSH_BUTTON4_PIN);
-    if(west_pb_last==Bit_SET && west_pb_new==Bit_RESET)
-      if(west_pb_callback!=0)  
-        west_pb_callback();
-    west_pb_last=west_pb_new;
+    if(south_pb_callback!=0)  
+      south_pb_callback();
+    /* Clear the EXTI line 0 pending bit */
+    EXTI_ClearITPendingBit(PUSH_BUTTON2_EXTI_LINE);
+  }
+  if(EXTI_GetITStatus(PUSH_BUTTON3_EXTI_LINE) != RESET)
+  {
+    if(east_pb_callback!=0)  
+      east_pb_callback();
+    /* Clear the EXTI line 0 pending bit */
+    EXTI_ClearITPendingBit(PUSH_BUTTON3_EXTI_LINE);
+  }
+  if(EXTI_GetITStatus(PUSH_BUTTON4_EXTI_LINE) != RESET)
+  {
+    if(west_pb_callback!=0)  
+      west_pb_callback();
+    /* Clear the EXTI line 0 pending bit */
+    EXTI_ClearITPendingBit(PUSH_BUTTON4_EXTI_LINE);
   }
 }
 
@@ -137,15 +150,16 @@ void GPO_TIMER_IRQHandler(void)
 // public functions
 void gpio_init(void)
 {
-  GPIO_InitTypeDef  GPIO_InitStructure;
-  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
+  GPIO_InitTypeDef GPIO_InitStructure;
+  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
   NVIC_InitTypeDef NVIC_InitStructure;
-  TIM_OCInitTypeDef  TIM_OCInitStructure;
+  EXTI_InitTypeDef EXTI_InitStructure;
 
   /* enable clocks */
   RCC_AHB1PeriphClockCmd(LED1_GPIO_CLK | LED2_GPIO_CLK | LED3_GPIO_CLK | LED4_GPIO_CLK, ENABLE);
   RCC_AHB1PeriphClockCmd(PUSH_BUTTON1_GPIO_CLK | PUSH_BUTTON2_GPIO_CLK | PUSH_BUTTON3_GPIO_CLK | PUSH_BUTTON4_GPIO_CLK, ENABLE);
-  RCC_APB1PeriphClockCmd(GPO_TIMER_CLK | GPI_TIMER_CLK,ENABLE);
+  RCC_APB1PeriphClockCmd(GPO_TIMER_CLK,ENABLE);
+  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
 
   /* GPIO Configuration */
   GPIO_InitStructure.GPIO_Pin = LED1_PIN;
@@ -197,9 +211,6 @@ void gpio_init(void)
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);
 
-  NVIC_InitStructure.NVIC_IRQChannel = GPI_TIMER_IRQn;
-  NVIC_Init(&NVIC_InitStructure);
-
   /* LED's timer configuration */
   TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
   TIM_TimeBaseStructure.TIM_Prescaler = 0;
@@ -210,19 +221,30 @@ void gpio_init(void)
   TIM_PrescalerConfig(GPO_TIMER, 42000, TIM_PSCReloadMode_Immediate);
   TIM_SetClockDivision(GPO_TIMER,TIM_CKD_DIV2);
 
-  /* pushbutton timer configuration */
-  TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
-  TIM_TimeBaseStructure.TIM_Prescaler = 0;
-  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
-  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
-  TIM_TimeBaseInit(GPI_TIMER,&TIM_TimeBaseStructure);
-  TIM_Cmd(GPI_TIMER, ENABLE);
-  TIM_PrescalerConfig(GPI_TIMER, 42000, TIM_PSCReloadMode_Immediate);
-  TIM_SetClockDivision(GPI_TIMER,TIM_CKD_DIV2);
-  TIM_OCInitStructure.TIM_Pulse = 10;// 10 Hz
-  TIM_OC1Init(GPI_TIMER, &TIM_OCInitStructure);
-  TIM_OC1PreloadConfig(GPI_TIMER, TIM_OCPreload_Disable);
-  TIM_ITConfig(GPI_TIMER, TIM_IT_CC1, ENABLE);
+  /* Connect external interrupts */
+  SYSCFG_EXTILineConfig(PUSH_BUTTON1_EXTI_PORT,PUSH_BUTTON1_EXTI_PIN);
+  SYSCFG_EXTILineConfig(PUSH_BUTTON2_EXTI_PORT,PUSH_BUTTON2_EXTI_PIN);
+  SYSCFG_EXTILineConfig(PUSH_BUTTON3_EXTI_PORT,PUSH_BUTTON3_EXTI_PIN);
+  SYSCFG_EXTILineConfig(PUSH_BUTTON4_EXTI_PORT,PUSH_BUTTON4_EXTI_PIN);
+
+  /* configure external interrupts */
+  EXTI_InitStructure.EXTI_Line = PUSH_BUTTON1_EXTI_LINE | PUSH_BUTTON2_EXTI_LINE | PUSH_BUTTON3_EXTI_LINE | PUSH_BUTTON4_EXTI_LINE;
+  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
+  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
+  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
+  EXTI_Init(&EXTI_InitStructure);
+
+  NVIC_InitStructure.NVIC_IRQChannel = GPI_EXTI1_IRQn;
+  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
+  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
+  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+  NVIC_Init(&NVIC_InitStructure);
+
+  NVIC_InitStructure.NVIC_IRQChannel = GPI_EXTI2_IRQn;
+  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
+  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
+  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+  NVIC_Init(&NVIC_InitStructure);
 }
 
 void gpio_set_led(led_t led_id)
@@ -371,6 +393,8 @@ uint8_t gpio_is_pushbutton_pressed(pushbutton_t pb_id)
         return 0x00;
       break;
   }
+
+  return 0x00;
 }
 
 void gpio_set_pushbutton_callback(pushbutton_t pb_id,void (*callback)(void))