diff --git a/Makefile b/Makefile
index 6e70113ac0619acc80e1990f9ebc4a9718c73085..ffe548d0b9f8e95c3feee3b8a11615f0f06003f1 100755
--- a/Makefile
+++ b/Makefile
@@ -9,6 +9,7 @@ TARGET_FILES+=src/stm32f4xx_hal_msp.c
 TARGET_FILES+=src/gpio.c
 TARGET_FILES+=src/eeprom.c
 TARGET_FILES+=src/ram.c
+TARGET_FILES+=src/adc_dma.c
 TARGET_FILES+=src/bioloid_time.c
 TARGET_FILES+=src/bioloid_dyn_slave.c
 TARGET_FILES+=src/bioloid_dyn_master_sensors.c
@@ -70,6 +71,8 @@ TARGET_FILES+=$(HAL_PATH)/src/stm32f4xx_hal_flash_ex.c
 TARGET_FILES+=$(HAL_PATH)/src/stm32f4xx_hal_dma.c
 TARGET_FILES+=$(HAL_PATH)/src/stm32f4xx_hal.c
 TARGET_FILES+=$(HAL_PATH)/src/stm32f4xx_hal_uart.c
+TARGET_FILES+=$(HAL_PATH)/src/stm32f4xx_hal_adc.c
+TARGET_FILES+=$(HAL_PATH)/src/stm32f4xx_hal_adc_ex.c
 
 TARGET_FILES+=$(USART_PATH)/src/usart3.c
 TARGET_FILES+=$(USART_PATH)/src/usart2.c
diff --git a/include/adc_dma.h b/include/adc_dma.h
index 05699e454d72613ae80b01356927b9f66267f39d..2999be465858f1d2b489991449107781aa647bd4 100644
--- a/include/adc_dma.h
+++ b/include/adc_dma.h
@@ -5,10 +5,12 @@
 extern "C" {
 #endif
 
-#include "stm32f4xx.h"
+#include "stm32f4xx_hal.h"
 
 void adc_init(void);
-uint16_t adc_get_temperature(void);
+void adc_start(void);
+void adc_set_period(uint8_t period_ms);
+void adc_stop(void);
 
 #ifdef __cplusplus
 }
diff --git a/include/bioloid_registers.h b/include/bioloid_registers.h
index c18bb7d75d894c644b1df97e7d1a1b1fe63f8c8d..751a4430e99506b00cb1e2b03617a9cb97d9286e 100644
--- a/include/bioloid_registers.h
+++ b/include/bioloid_registers.h
@@ -46,6 +46,25 @@ typedef enum {
                                           //       |       |       |       | interrupt flag | enable interrupt | value | internally used
   BIOLOID_MODE_PB_CNTRL           = 0x2F, // bit 7 | bit 6 | bit 5 | bit 4 |     bit 3      |       bit 2      | bit 1 |      bit 0
                                           //       |       |       |       | interrupt flag | enable interrupt | value | internally used
+  BIOLOID_ADC_CNTRL               = 0x30, // bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0
+                                          //       |       |       |       |       |       |       | Enable
+  BIOLOID_ADC_PERIOD              = 0x31,
+  BIOLOID_ADC_CH1_L               = 0x32,
+  BIOLOID_ADC_CH1_H               = 0x33,
+  BIOLOID_ADC_CH2_L               = 0x34,
+  BIOLOID_ADC_CH2_H               = 0x35,
+  BIOLOID_ADC_CH3_L               = 0x36,
+  BIOLOID_ADC_CH3_H               = 0x37,
+  BIOLOID_ADC_CH4_L               = 0x38,
+  BIOLOID_ADC_CH4_H               = 0x39,
+  BIOLOID_ADC_TEMP_L              = 0x3A,
+  BIOLOID_ADC_TEMP_H              = 0x3B,
+  BIOLOID_ADC_CH6_L               = 0x3C,
+  BIOLOID_ADC_CH6_H               = 0x3D,
+  BIOLOID_ADC_VREF_L              = 0x3E,
+  BIOLOID_ADC_VREF_H              = 0x3F,
+  BIOLOID_ADC_CH8_L               = 0x40,
+  BIOLOID_ADC_CH8_H               = 0x41
 } bioloid_registers;
 
 #define      GPIO_BASE_ADDRESS    0x20
diff --git a/src/adc_dma.c b/src/adc_dma.c
index 19a70aaa2a82ab8a8194a83765c07b2e29f8c6bc..6ee1685d2bea9ff9c1f7c40cc3482a539c98fc87 100644
--- a/src/adc_dma.c
+++ b/src/adc_dma.c
@@ -1,145 +1,370 @@
 #include "adc_dma.h"
 #include "ram.h"
  
-#define ADC1_CH1           ADC_Channel_TempSensor
-#define ADC1_CH2           ADC_Channel_8
-#define ADC1_CH3           ADC_Channel_10
-#define ADC1_CH4           ADC_Channel_12
-
-#define ADC2_CH1           ADC_Channel_14
-#define ADC2_CH2           ADC_Channel_9
-#define ADC2_CH3           ADC_Channel_11
-#define ADC2_CH4           ADC_Channel_13
-
-#define ADC1_CH2_PIN       GPIO_Pin_8
-#define ADC1_CH2_PORT      GPIOB
-#define ADC1_CH2_PORT_CLK  RCC_AHB1Periph_GPIOB
-#define ADC1_CH3_PIN       GPIO_Pin_0
-#define ADC1_CH3_PORT      GPIOC
-#define ADC1_CH3_PORT_CLK  RCC_AHB1Periph_GPIOC
-#define ADC1_CH4_PIN       GPIO_Pin_2
-#define ADC1_CH4_PORT      GPIOC
-#define ADC1_CH4_PORT_CLK  RCC_AHB1Periph_GPIOC
-
-#define ADC2_CH1_PIN       GPIO_Pin_4
-#define ADC2_CH1_PORT      GPIOC
-#define ADC2_CH1_PORT_CLK  RCC_AHB1Periph_GPIOC
-#define ADC2_CH2_PIN       GPIO_Pin_1
-#define ADC2_CH2_PORT      GPIOB
-#define ADC2_CH2_PORT_CLK  RCC_AHB1Periph_GPIOB
-#define ADC2_CH3_PIN       GPIO_Pin_1
-#define ADC2_CH3_PORT      GPIOC
-#define ADC2_CH3_PORT_CLK  RCC_AHB1Periph_GPIOC
-#define ADC2_CH4_PIN       GPIO_Pin_3
-#define ADC2_CH4_PORT      GPIOC
-#define ADC2_CH4_PORT_CLK  RCC_AHB1Periph_GPIOC
-
-#define ADC_CCR_ADDRESS    ((uint32_t)0x40012308)
+#define ADC1_CH1                    ADC_CHANNEL_6
+#define ADC1_CH2                    ADC_CHANNEL_8
+#define ADC1_CH3                    ADC_CHANNEL_TEMPSENSOR
+#define ADC1_CH4                    ADC_CHANNEL_VREFINT
+
+#define ADC2_CH1                    ADC_CHANNEL_7
+#define ADC2_CH2                    ADC_CHANNEL_9
+#define ADC2_CH3                    ADC_CHANNEL_14
+#define ADC2_CH4                    ADC_CHANNEL_15
+
+#define ADC1_CH1_PIN                GPIO_PIN_6
+#define ADC1_CH1_PORT               GPIOA
+#define ADC1_CH1_ENABLE_PORT_CLK    __HAL_RCC_GPIOA_CLK_ENABLE()
+#define ADC1_CH2_PIN                GPIO_PIN_0
+#define ADC1_CH2_PORT               GPIOB
+#define ADC1_CH2_ENABLE_PORT_CLK    __HAL_RCC_GPIOB_CLK_ENABLE()
+#define ADC1_ENABLE_CLK             __ADC1_CLK_ENABLE()
+
+#define ADC2_CH1_PIN                GPIO_PIN_7
+#define ADC2_CH1_PORT               GPIOA
+#define ADC2_CH1_ENABLE_PORT_CLK    __HAL_RCC_GPIOA_CLK_ENABLE()
+#define ADC2_CH2_PIN                GPIO_PIN_1
+#define ADC2_CH2_PORT               GPIOB
+#define ADC2_CH2_ENABLE_PORT_CLK    __HAL_RCC_GPIOB_CLK_ENABLE()
+#define ADC2_CH3_PIN                GPIO_PIN_4
+#define ADC2_CH3_PORT               GPIOC
+#define ADC2_CH3_ENABLE_PORT_CLK    __HAL_RCC_GPIOC_CLK_ENABLE()
+#define ADC2_CH4_PIN                GPIO_PIN_5
+#define ADC2_CH4_PORT               GPIOC
+#define ADC2_CH4_ENABLE_PORT_CLK    __HAL_RCC_GPIOC_CLK_ENABLE()
+#define ADC2_ENABLE_CLK             __ADC2_CLK_ENABLE()
+
+#define ADC_DMA_CHANNEL             DMA_CHANNEL_0
+#define ADC_DMA_STREAM              DMA2_Stream0
+#define ADC_DMA_IRQn                DMA2_Stream0_IRQn
+#define ADC_DMA_IRQHandler          DMA2_Stream0_IRQHandler
+#define ADC_ENABLE_DMA_CLK          __HAL_RCC_DMA2_CLK_ENABLE()
+
+#define ADC_TIMER                   TIM4
+#define ENABLE_ADC_TIMER_CLK        __HAL_RCC_TIM4_CLK_ENABLE()
+#define ADC_TIMER_IRQn              TIM4_IRQn
+#define ADC_TIMER_IRQHandler        TIM4_IRQHandler
+
+// temperature conversion functions
+#define TEMP_V25                    0.76// ADC voltage at 25 degrees in V
+#define TEMP_INV_SLOPE              400.0// ADC slope in mV/degree
+
+// general voltage conversion
+#define VOLTAGE_DELTA               0.000805664
+#define VOLTAGE_GAIN                1.529411765
 
 // private variables
+ADC_HandleTypeDef hadc1;
+ADC_HandleTypeDef hadc2;
+DMA_HandleTypeDef hdma_adc1; 
+TIM_HandleTypeDef ADC_TIM_Handle;
+
+uint32_t adc_data[4];// temporal buffer to store ADC data before conversion
+uint16_t adc_period_ms;
+
+// private functions
+uint16_t adc_convert_temperature(uint16_t value)
+{
+  float conv_value;
+
+  conv_value=(value*VOLTAGE_DELTA-TEMP_V25)*TEMP_INV_SLOPE+25.0;
+
+  return conv_value*(1<<10);// fixed point format 6 | 10
+}
+
+uint16_t adc_convert_vrefint(uint16_t value)
+{
+  float conv_value;
+
+  conv_value=value*VOLTAGE_DELTA;
+
+  return conv_value*(1<<12);
+}
+
+uint16_t adc_convert_voltage(uint16_t value)
+{
+  float conv_value;
+
+  conv_value=value*VOLTAGE_DELTA*VOLTAGE_GAIN;
+
+  return conv_value*(1<<12);
+}
 
 // interrupt handlers
+void ADC_TIMER_IRQHandler(void)
+{
+  uint32_t capture;
+
+  if(__HAL_TIM_GET_FLAG(&ADC_TIM_Handle, TIM_FLAG_CC4) != RESET)
+  {
+    if(__HAL_TIM_GET_IT_SOURCE(&ADC_TIM_Handle, TIM_IT_CC4) !=RESET)
+    {
+      __HAL_TIM_CLEAR_IT(&ADC_TIM_Handle, TIM_IT_CC4);
+      capture = HAL_TIM_ReadCapturedValue(&ADC_TIM_Handle, TIM_CHANNEL_4);
+      __HAL_TIM_SET_COMPARE(&ADC_TIM_Handle, TIM_CHANNEL_4, (capture + adc_period_ms));
+    }
+  }
+  /* TIM Update event */
+  if(__HAL_TIM_GET_FLAG(&ADC_TIM_Handle, TIM_FLAG_UPDATE) != RESET)
+    if(__HAL_TIM_GET_IT_SOURCE(&ADC_TIM_Handle, TIM_IT_UPDATE) !=RESET)
+      __HAL_TIM_CLEAR_IT(&ADC_TIM_Handle, TIM_IT_UPDATE);
+  /* TIM Break input event */
+  if(__HAL_TIM_GET_FLAG(&ADC_TIM_Handle, TIM_FLAG_BREAK) != RESET)
+    if(__HAL_TIM_GET_IT_SOURCE(&ADC_TIM_Handle, TIM_IT_BREAK) !=RESET)
+      __HAL_TIM_CLEAR_IT(&ADC_TIM_Handle, TIM_IT_BREAK);
+  /* TIM Trigger detection event */
+  if(__HAL_TIM_GET_FLAG(&ADC_TIM_Handle, TIM_FLAG_TRIGGER) != RESET)
+    if(__HAL_TIM_GET_IT_SOURCE(&ADC_TIM_Handle, TIM_IT_TRIGGER) !=RESET)
+      __HAL_TIM_CLEAR_IT(&ADC_TIM_Handle, TIM_IT_TRIGGER);
+  /* TIM commutation event */
+  if(__HAL_TIM_GET_FLAG(&ADC_TIM_Handle, TIM_FLAG_COM) != RESET)
+    if(__HAL_TIM_GET_IT_SOURCE(&ADC_TIM_Handle, TIM_IT_COM) !=RESET)
+      __HAL_TIM_CLEAR_IT(&ADC_TIM_Handle, TIM_FLAG_COM);
+}
+
+void ADC_DMA_IRQHandler(void)
+{
+  uint16_t value;
+
+  /* Transfer Error Interrupt management ***************************************/
+  if(__HAL_DMA_GET_FLAG(&hdma_adc1, __HAL_DMA_GET_TE_FLAG_INDEX(&hdma_adc1)) != RESET)
+    if(__HAL_DMA_GET_IT_SOURCE(&hdma_adc1, DMA_IT_TE) != RESET)
+      __HAL_DMA_CLEAR_FLAG(&hdma_adc1, __HAL_DMA_GET_TE_FLAG_INDEX(&hdma_adc1));
+  /* FIFO Error Interrupt management ******************************************/
+  if(__HAL_DMA_GET_FLAG(&hdma_adc1, __HAL_DMA_GET_FE_FLAG_INDEX(&hdma_adc1)) != RESET)
+    if(__HAL_DMA_GET_IT_SOURCE(&hdma_adc1, DMA_IT_FE) != RESET)
+      __HAL_DMA_CLEAR_FLAG(&hdma_adc1, __HAL_DMA_GET_FE_FLAG_INDEX(&hdma_adc1));
+  /* Direct Mode Error Interrupt management ***********************************/
+  if(__HAL_DMA_GET_FLAG(&hdma_adc1, __HAL_DMA_GET_DME_FLAG_INDEX(&hdma_adc1)) != RESET)
+    if(__HAL_DMA_GET_IT_SOURCE(&hdma_adc1, DMA_IT_DME) != RESET)
+      __HAL_DMA_CLEAR_FLAG(&hdma_adc1, __HAL_DMA_GET_DME_FLAG_INDEX(&hdma_adc1));
+  /* Half Transfer Complete Interrupt management ******************************/
+  if(__HAL_DMA_GET_FLAG(&hdma_adc1, __HAL_DMA_GET_HT_FLAG_INDEX(&hdma_adc1)) != RESET)
+    if(__HAL_DMA_GET_IT_SOURCE(&hdma_adc1, DMA_IT_HT) != RESET)
+      __HAL_DMA_CLEAR_FLAG(&hdma_adc1, __HAL_DMA_GET_HT_FLAG_INDEX(&hdma_adc1));
+  /* Transfer Complete Interrupt management ***********************************/
+  if(__HAL_DMA_GET_FLAG(&hdma_adc1, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_adc1)) != RESET)
+    if(__HAL_DMA_GET_IT_SOURCE(&hdma_adc1, DMA_IT_TC) != RESET)
+    {
+      __HAL_DMA_CLEAR_FLAG(&hdma_adc1, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_adc1));
+      value=adc_convert_voltage(adc_data[0]&0x0000FFFF);
+      ram_data[BIOLOID_ADC_CH1_L]=value%256;
+      ram_data[BIOLOID_ADC_CH1_H]=value/256;
+      value=adc_convert_voltage((adc_data[0]&0xFFFF0000)>>16);
+      ram_data[BIOLOID_ADC_CH2_L]=value%256;
+      ram_data[BIOLOID_ADC_CH2_H]=value/256;
+      value=adc_convert_voltage(adc_data[1]&0x0000FFFF);
+      ram_data[BIOLOID_ADC_CH3_L]=value%256;
+      ram_data[BIOLOID_ADC_CH3_H]=value/256;
+      value=adc_convert_voltage((adc_data[1]&0xFFFF0000)>>16);
+      ram_data[BIOLOID_ADC_CH4_L]=value%256;
+      ram_data[BIOLOID_ADC_CH4_H]=value/256;
+      value=adc_convert_temperature(adc_data[2]&0x0000FFFF);
+      ram_data[BIOLOID_ADC_TEMP_L]=value%256;
+      ram_data[BIOLOID_ADC_TEMP_H]=value/256;
+      value=adc_convert_voltage((adc_data[2]&0xFFFF0000)>>16);
+      ram_data[BIOLOID_ADC_CH6_L]=value%256;
+      ram_data[BIOLOID_ADC_CH6_H]=value/256;
+      value=adc_convert_vrefint(adc_data[3]&0x0000FFFF);
+      ram_data[BIOLOID_ADC_VREF_L]=value%256;
+      ram_data[BIOLOID_ADC_VREF_H]=value/256;
+      value=adc_convert_voltage((adc_data[3]&0xFFFF0000)>>16);
+      ram_data[BIOLOID_ADC_CH8_L]=value%256;
+      ram_data[BIOLOID_ADC_CH8_H]=value/256;
+    }
+}
 
 // public functions
 void adc_init(void)
 {
-  ADC_CommonInitTypeDef ADC_CommonInitStructure;
-  ADC_InitTypeDef ADC_InitStructure;
-  GPIO_InitTypeDef GPIO_InitStructure;
-  DMA_InitTypeDef DMA_InitStructure;
+  GPIO_InitTypeDef GPIO_InitStruct; 	
+  ADC_MultiModeTypeDef multimode;
+  ADC_ChannelConfTypeDef sConfig;
+  TIM_ClockConfigTypeDef sClockSourceConfig;
+  TIM_MasterConfigTypeDef sMasterConfig;
+  TIM_OC_InitTypeDef TIM_OCInitStructure;
+  uint32_t capture;
+
+  /* initialize the internal variables */
+  adc_period_ms=840;// equivalent to 10 ms
+  ram_data[BIOLOID_ADC_PERIOD]=84;
 
   /* enable clocks */
-  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
-  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
-  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);
-  RCC_AHB1PeriphClockCmd(ADC1_CH2_PORT_CLK | ADC1_CH3_PORT_CLK | ADC1_CH4_PORT_CLK, ENABLE);
-  RCC_AHB1PeriphClockCmd(ADC2_CH1_PORT_CLK | ADC2_CH2_PORT_CLK | ADC2_CH3_PORT_CLK | ADC2_CH4_PORT_CLK, ENABLE);
-
-  /* DMA Config */
-  DMA_InitStructure.DMA_Channel = DMA_Channel_0;
-  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ram_data[50];
-  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_CCR_ADDRESS;
-  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
-  DMA_InitStructure.DMA_BufferSize = 4;
-  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
-  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
-  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
-  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
-  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
-  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
-  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
-  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
-  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
-  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
-  DMA_Init(DMA2_Stream0, &DMA_InitStructure);
-
-  /* DMA2_Stream0 enable */
-  DMA_Cmd(DMA2_Stream0, ENABLE);
+  ADC1_CH1_ENABLE_PORT_CLK;
+  ADC1_CH2_ENABLE_PORT_CLK;
+  ADC2_CH1_ENABLE_PORT_CLK;
+  ADC2_CH2_ENABLE_PORT_CLK;
+  ADC2_CH3_ENABLE_PORT_CLK;
+  ADC2_CH4_ENABLE_PORT_CLK;
+
+  ADC_ENABLE_DMA_CLK;
+
+  ADC1_ENABLE_CLK;
+  /* configure ADC1 */
+  hadc1.Instance = ADC1;
+  hadc1.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV8;
+  hadc1.Init.Resolution = ADC_RESOLUTION12b;
+  hadc1.Init.ScanConvMode = ENABLE;
+  hadc1.Init.ContinuousConvMode = DISABLE;// because it is triggered by a timer
+  hadc1.Init.DiscontinuousConvMode = DISABLE;
+  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING;
+  hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T4_CC4;
+  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
+  hadc1.Init.NbrOfConversion = 4;
+  hadc1.Init.DMAContinuousRequests = ENABLE;
+  hadc1.Init.EOCSelection = EOC_SEQ_CONV;
+  HAL_ADC_Init(&hadc1);
+
+  multimode.Mode = ADC_DUALMODE_REGSIMULT;
+  multimode.DMAAccessMode = ADC_DMAACCESSMODE_2;
+  multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_20CYCLES;
+  HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode);
+
+  /* configure ADC1 channels */
+  sConfig.Channel = ADC1_CH1;
+  sConfig.Rank = 1;
+  sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
+  HAL_ADC_ConfigChannel(&hadc1, &sConfig);
+
+  sConfig.Channel = ADC1_CH2;
+  sConfig.Rank = 2;
+  HAL_ADC_ConfigChannel(&hadc1, &sConfig);
+
+  sConfig.Channel = ADC1_CH3;
+  sConfig.Rank = 3;
+  HAL_ADC_ConfigChannel(&hadc1, &sConfig);
+
+  sConfig.Channel = ADC1_CH4;
+  sConfig.Rank = 4;
+  HAL_ADC_ConfigChannel(&hadc1, &sConfig);
 
   /* configure GPIO */
-  GPIO_InitStructure.GPIO_Pin = ADC1_CH2_PIN | ADC2_CH2_PIN;
-  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
-  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
-  GPIO_Init(ADC1_CH2_PORT, &GPIO_InitStructure);
-
-  GPIO_InitStructure.GPIO_Pin = ADC1_CH3_PIN | ADC1_CH4_PIN | ADC2_CH1_PIN | ADC2_CH3_PIN | ADC2_CH4_PIN;
-  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
-  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
-  GPIO_Init(ADC2_CH1_PORT, &GPIO_InitStructure);
-
-  /* ADC Common Init */
-  ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult;
-  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;
-  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_2;
-  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
-  ADC_CommonInit(&ADC_CommonInitStructure);
-
-  /* ADC1 configuration */
-  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
-  ADC_InitStructure.ADC_ScanConvMode = ENABLE;
-  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
-  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
-  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
-  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
-  ADC_InitStructure.ADC_NbrOfConversion = 4;
-  ADC_Init(ADC1, &ADC_InitStructure);
-
-  /* ADC1 regular channels 10, 11 configuration */
-  ADC_RegularChannelConfig(ADC1, ADC1_CH1, 1, ADC_SampleTime_480Cycles);
-  ADC_RegularChannelConfig(ADC1, ADC1_CH2, 2, ADC_SampleTime_480Cycles);
-  ADC_RegularChannelConfig(ADC1, ADC1_CH3, 3, ADC_SampleTime_480Cycles);
-  ADC_RegularChannelConfig(ADC1, ADC1_CH4, 4, ADC_SampleTime_480Cycles);
-
-  /* ADC1 configuration */
-  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
-  ADC_InitStructure.ADC_ScanConvMode = ENABLE;
-  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
-  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
-  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
-  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
-  ADC_InitStructure.ADC_NbrOfConversion = 4;
-  ADC_Init(ADC2, &ADC_InitStructure);
-
-  /* ADC1 regular channels 10, 11 configuration */
-  ADC_RegularChannelConfig(ADC2, ADC2_CH1, 1, ADC_SampleTime_480Cycles);
-  ADC_RegularChannelConfig(ADC2, ADC2_CH2, 2, ADC_SampleTime_480Cycles);
-  ADC_RegularChannelConfig(ADC2, ADC2_CH3, 3, ADC_SampleTime_480Cycles);
-  ADC_RegularChannelConfig(ADC2, ADC2_CH4, 4, ADC_SampleTime_480Cycles);
-
-  /* Enable DMA request after last transfer (Multi-ADC mode) */
-  ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
-
-  /* Enable ADC1 */
-  ADC_Cmd(ADC1, ENABLE);
-
-  /* Enable ADC2 */
-  ADC_Cmd(ADC2, ENABLE);
-
-  /* Start ADC1 Software Conversion */
-  ADC_SoftwareStartConv(ADC1);
+  GPIO_InitStruct.Pin = ADC1_CH1_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  HAL_GPIO_Init(ADC1_CH1_PORT, &GPIO_InitStruct);
+  GPIO_InitStruct.Pin = ADC1_CH2_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  HAL_GPIO_Init(ADC1_CH2_PORT, &GPIO_InitStruct);
+
+  ADC2_ENABLE_CLK;
+  /* configure ADC1 */
+  hadc2.Instance = ADC2;
+  hadc2.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV8;
+  hadc2.Init.Resolution = ADC_RESOLUTION12b;
+  hadc2.Init.ScanConvMode = ENABLE;
+  hadc2.Init.ContinuousConvMode = DISABLE;// because it is triggered by a timer
+  hadc2.Init.DiscontinuousConvMode = DISABLE;
+  hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
+  hadc2.Init.NbrOfConversion = 4;
+  hadc2.Init.DMAContinuousRequests = ENABLE;
+  hadc2.Init.EOCSelection = EOC_SEQ_CONV;
+  HAL_ADC_Init(&hadc2);
+
+  multimode.Mode = ADC_DUALMODE_REGSIMULT;
+  multimode.DMAAccessMode = ADC_DMAACCESSMODE_2;
+  multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_20CYCLES;
+  HAL_ADCEx_MultiModeConfigChannel(&hadc2, &multimode);
+
+  /* configure ADC2 channels */
+  sConfig.Channel = ADC2_CH1;
+  sConfig.Rank = 1;
+  sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
+  HAL_ADC_ConfigChannel(&hadc2, &sConfig);
+
+  sConfig.Channel = ADC2_CH2;
+  sConfig.Rank = 2;
+  HAL_ADC_ConfigChannel(&hadc2, &sConfig);
+
+  sConfig.Channel = ADC2_CH3;
+  sConfig.Rank = 3;
+  HAL_ADC_ConfigChannel(&hadc2, &sConfig);
+
+  sConfig.Channel = ADC2_CH4;
+  sConfig.Rank = 4;
+  HAL_ADC_ConfigChannel(&hadc2, &sConfig);
+
+  /* configure GPIO */
+  GPIO_InitStruct.Pin = ADC2_CH1_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  HAL_GPIO_Init(ADC2_CH1_PORT, &GPIO_InitStruct);
+  GPIO_InitStruct.Pin = ADC2_CH2_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  HAL_GPIO_Init(ADC2_CH2_PORT, &GPIO_InitStruct);
+  GPIO_InitStruct.Pin = ADC2_CH3_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  HAL_GPIO_Init(ADC2_CH3_PORT, &GPIO_InitStruct);
+  GPIO_InitStruct.Pin = ADC2_CH4_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  HAL_GPIO_Init(ADC2_CH4_PORT, &GPIO_InitStruct);
+
+  /* initialize DMA */
+  hdma_adc1.Instance = DMA2_Stream0;
+  hdma_adc1.Init.Channel = DMA_CHANNEL_0;
+  hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
+  hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
+  hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
+  hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
+  hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
+  hdma_adc1.Init.Mode = DMA_CIRCULAR;
+  hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
+  hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+  HAL_DMA_Init(&hdma_adc1);
+
+  __HAL_LINKDMA(&hadc1,DMA_Handle,hdma_adc1);
+
+  HAL_NVIC_SetPriority(ADC_DMA_IRQn, 3, 1);
+  HAL_NVIC_EnableIRQ(ADC_DMA_IRQn);
+
+  /* configure the timer to generate the internal trigger */
+  ENABLE_ADC_TIMER_CLK;
+  ADC_TIM_Handle.Instance=ADC_TIMER;
+  ADC_TIM_Handle.Init.Period = 0xFFFF;
+  ADC_TIM_Handle.Init.Prescaler = 1000;
+  ADC_TIM_Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
+  ADC_TIM_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
+  HAL_NVIC_SetPriority(ADC_TIMER_IRQn, 3, 1);
+  HAL_NVIC_EnableIRQ(ADC_TIMER_IRQn);
+  /* use the internal clock */
+  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
+  HAL_TIM_ConfigClockSource(&ADC_TIM_Handle, &sClockSourceConfig);
+  HAL_TIM_OC_Init(&ADC_TIM_Handle);
+  /* disable master/slave mode */
+  sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC4REF;
+  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
+  HAL_TIMEx_MasterConfigSynchronization(&ADC_TIM_Handle, &sMasterConfig);
+  /* configure ouptut counter channel 4 */
+  TIM_OCInitStructure.OCMode = TIM_OCMODE_TOGGLE;
+  TIM_OCInitStructure.OCPolarity = TIM_OCPOLARITY_HIGH;
+  TIM_OCInitStructure.OCFastMode = TIM_OCFAST_DISABLE;
+  capture = HAL_TIM_ReadCapturedValue(&ADC_TIM_Handle, TIM_CHANNEL_4);
+  TIM_OCInitStructure.Pulse = capture+adc_period_ms;
+  HAL_TIM_OC_ConfigChannel(&ADC_TIM_Handle, &TIM_OCInitStructure,TIM_CHANNEL_4);
+
+  /* start ADC operation */
+  HAL_ADC_Start(&hadc2);
+  HAL_ADCEx_MultiModeStart_DMA(&hadc1,adc_data,4);
+  adc_start();
 }
 
-uint16_t adc_get_temperature(void)
+void adc_start(void)
 {
-  return 0x0000;
+  ram_data[BIOLOID_ADC_CNTRL]|=0x01;
+  HAL_TIM_OC_Start_IT(&ADC_TIM_Handle, TIM_CHANNEL_4);
 }
+
+void adc_set_period(uint8_t period_ms)
+{
+  adc_period_ms=period_ms*84;
+}
+
+void adc_stop(void)
+{
+  ram_data[BIOLOID_ADC_CNTRL]&=0xFE;
+  HAL_TIM_OC_Stop_IT(&ADC_TIM_Handle, TIM_CHANNEL_4);
+}
+
diff --git a/src/bioloid_dyn_master_sensors.c b/src/bioloid_dyn_master_sensors.c
index 783f116c17276b6485735206372ba3758a7dae24..ff619e83fd9ab862e97fbc157b756b3723287c6a 100755
--- a/src/bioloid_dyn_master_sensors.c
+++ b/src/bioloid_dyn_master_sensors.c
@@ -75,9 +75,4 @@ void bioloid_dyn_master_sensors_init(void)
   dyn_master_init(&bioloid_dyn_master_sensors,&bioloid_dyn_master_sensors_comm);
   bioloid_dyn_master_sensors.set_rx_mode=bioloid_dyn_master_sensors_set_rx_mode;
   bioloid_dyn_master_sensors.set_tx_mode=bioloid_dyn_master_sensors_set_tx_mode;
-
-  if(dyn_master_ping(&bioloid_dyn_master_sensors,0xC0)==DYN_SUCCESS)
-    gpio_set_led(RXD_LED); 
-  else
-    gpio_clear_led(RXD_LED);
 }
diff --git a/src/bioloid_stm32.c b/src/bioloid_stm32.c
index 8c9688988924eb475345fd6bf33728f666450102..2b36940662c74c346e0ede9cd009caed0ea6c80c 100644
--- a/src/bioloid_stm32.c
+++ b/src/bioloid_stm32.c
@@ -2,6 +2,7 @@
 #include "gpio.h"
 #include "eeprom.h"
 #include "ram.h"
+#include "adc_dma.h"
 #include "bioloid_time.h"
 #include "bioloid_dyn_slave.h"
 #include "bioloid_dyn_master_sensors.h"
@@ -15,6 +16,8 @@ int32_t main(void)
   EE_Init();
   /* initialize the ram module */
   ram_init();  
+  /* initialize the ADC module */
+  adc_init();
   /* initialize the time module */
   bioloid_time_init();
   /* initialize the dynamixel slave interface */