NUCLEO-F446RE ENCODER TIMER3 Y TIMER 2 HAL AND PWM. PID PARA UN PENDULO INVERTIDO CON 2 ENCODER DE CUADRATURA

Dependencies:   mbed-dev

Files at this revision

API Documentation at this revision

Comitter:
gereina
Date:
Sat May 21 04:17:35 2016 +0000
Commit message:
QEI_TIMER2_TIMER_3 OK; PWM MBED; PID

Changed in this revision

Encoder/Encoder.h Show annotated file Show diff for this revision Revisions of this file
Encoder/EncoderInit.cpp Show annotated file Show diff for this revision Revisions of this file
Encoder/EncoderMspInitF0.cpp Show annotated file Show diff for this revision Revisions of this file
Encoder/EncoderMspInitF1.cpp Show annotated file Show diff for this revision Revisions of this file
Encoder/EncoderMspInitF3.cpp Show annotated file Show diff for this revision Revisions of this file
Encoder/EncoderMspInitF4.cpp Show annotated file Show diff for this revision Revisions of this file
Encoder/EncoderMspInitL0.cpp Show annotated file Show diff for this revision Revisions of this file
Encoder/EncoderMspInitL1.cpp Show annotated file Show diff for this revision Revisions of this file
Encoder/EncoderMspInitL4.cpp Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-dev.lib Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Encoder/Encoder.h	Sat May 21 04:17:35 2016 +0000
@@ -0,0 +1,6 @@
+#ifndef ENCODER_H
+#define ENCODER_H
+
+void EncoderInit(TIM_Encoder_InitTypeDef * encoder, TIM_HandleTypeDef * timer, TIM_TypeDef * TIMx, uint32_t maxcount, uint32_t encmode);
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Encoder/EncoderInit.cpp	Sat May 21 04:17:35 2016 +0000
@@ -0,0 +1,35 @@
+#include "mbed.h"
+
+void EncoderInit(TIM_Encoder_InitTypeDef * encoder, TIM_HandleTypeDef * timer, TIM_TypeDef * TIMx, uint32_t maxcount, uint32_t encmode)
+{
+
+    timer->Instance = TIMx;
+    timer->Init.Period = maxcount;
+    timer->Init.CounterMode = TIM_COUNTERMODE_UP;
+    timer->Init.Prescaler = 0;
+    timer->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
+
+    encoder->EncoderMode = encmode;
+
+    encoder->IC1Filter = 0x0F;
+    encoder->IC1Polarity = TIM_INPUTCHANNELPOLARITY_RISING;
+    encoder->IC1Prescaler = TIM_ICPSC_DIV4;
+    encoder->IC1Selection = TIM_ICSELECTION_DIRECTTI;
+
+    encoder->IC2Filter = 0x0F;
+    encoder->IC2Polarity = TIM_INPUTCHANNELPOLARITY_FALLING;
+    encoder->IC2Prescaler = TIM_ICPSC_DIV4;
+    encoder->IC2Selection = TIM_ICSELECTION_DIRECTTI;
+
+
+    if (HAL_TIM_Encoder_Init(timer, encoder) != HAL_OK) {
+        printf("Couldn't Init Encoder\r\n");
+        while (1) {}
+    }
+
+    if(HAL_TIM_Encoder_Start(timer,TIM_CHANNEL_1)!=HAL_OK) {
+        printf("Couldn't Start Encoder\r\n");
+        while (1) {}
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Encoder/EncoderMspInitF0.cpp	Sat May 21 04:17:35 2016 +0000
@@ -0,0 +1,37 @@
+#include "mbed.h"
+/*
+ * HAL_TIM_Encoder_MspInit()
+ * Overrides the __weak function stub in stm32f0xx_hal_tim.h
+ *
+ * Edit the below for your preferred pin wiring & pullup/down
+ * I have encoder common at 3V3, using GPIO_PULLDOWN on inputs.
+ * Encoder A&B outputs connected directly to GPIOs.
+ *
+ * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00088500.pdf
+ * Table 11 has GPIO alternate function pinout mappings.
+ *
+ * TIM1_CH1: AF2 @ PA_8 - TIM1 used as system ticker under mbed, so unavailable
+ * TIM1_CH2: AF2 @ PA_9
+ *
+ * TIM3_CH1: AF1 @ PA_6, PB_4; AF0 @ PC_6*  *only for F030xC devices
+ * TIM3_CH2: AF1 @ PA_7, PB_5; AF0 @ PC_7*
+ *
+ */
+
+#ifdef TARGET_STM32F0
+void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim)
+{
+    GPIO_InitTypeDef GPIO_InitStruct;
+
+    if (htim->Instance == TIM3) { //PB_4 PB_5 = Nucleo D5 D4
+        __TIM3_CLK_ENABLE();
+        __GPIOB_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_5;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF1_TIM3;
+        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+    }
+}
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Encoder/EncoderMspInitF1.cpp	Sat May 21 04:17:35 2016 +0000
@@ -0,0 +1,74 @@
+#include "mbed.h"
+/*
+ * HAL_TIM_Encoder_MspInit()
+ * Overrides the __weak function stub in stm32f1xx_hal_tim.h
+ *
+ * Edit the below for your preferred pin wiring & pullup/down
+ * I have encoder common at 3V3, using GPIO_PULLDOWN on inputs.
+ * Encoder A&B outputs connected directly to GPIOs.
+ *
+ * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/CD00161566.pdf
+ * Table 5 has GPIO alternate function pinout mappings.
+ *
+ * TIM1_CH1: default PA_8, remap PE_9
+ * TIM1_CH2: default PA_9, remap PE_11
+ *
+ * TIM2_CH1: default PA_0 
+ * TIM2_CH2: default PA_1, remap PB_3
+ *
+ * TIM3_CH1: default PA_6, remap PB_4, PC_6
+ * TIM3_CH2: default PA_7, remap PB_5, PC_7
+ *
+ * TIM4_CH1: default PB_6, remap PD_12
+ * TIM4_CH2: default PB_7, remap PD_13
+ *
+ * NB one of these timers will be the employed by mbed as systick, unavailable as encoder.
+ */
+
+#ifdef TARGET_STM32F1
+void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim)
+{
+    GPIO_InitTypeDef GPIO_InitStruct;
+
+    if (htim->Instance == TIM1) { //PA8 PA9 = Nucleo D7 D8
+        __TIM1_CLK_ENABLE();
+        __GPIOA_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+//        GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
+        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+    }
+    else if (htim->Instance == TIM2) { //PA0 PA1 = Nucleo A0 A1
+        __TIM2_CLK_ENABLE();
+        __GPIOA_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+//        GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
+        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+    }
+    else if (htim->Instance == TIM3) { //PA6 PA7 = Nucleo D12 D11
+        __TIM3_CLK_ENABLE();
+        __GPIOA_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+//        GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
+        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+    }
+    else if (htim->Instance == TIM4) { // PB6 PB7 = Nucleo D10 MORPHO PB7
+        __TIM4_CLK_ENABLE();
+        __GPIOB_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+//        GPIO_InitStruct.Alternate = GPIO_AF2_TIM4;
+        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+    }
+}
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Encoder/EncoderMspInitF3.cpp	Sat May 21 04:17:35 2016 +0000
@@ -0,0 +1,82 @@
+#include "mbed.h"
+/*
+ * HAL_TIM_Encoder_MspInit()
+ * Overrides the __weak function stub in stm32f3xx_hal_tim.h
+ *
+ * Edit the below for your preferred pin wiring & pullup/down
+ * I have encoder common at 3V3, using GPIO_PULLDOWN on inputs.
+ * Encoder A&B outputs connected directly to GPIOs.
+ *
+ * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00093333.pdf
+ * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00097745.pdf
+ * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00133117.pdf
+ * Table 14 has GPIO alternate function pinout mappings.
+ *
+ * TIM1_CH1: AF2 @ PC_0, PE_9; AF6 @ PA_8
+ * TIM1_CH2: AF2 @ PC_1, PE_11; AF6 @ PA_9
+ *
+ * (TIM2_CH1: AF1 @ PA_0, PA_5, PA_15; AF2 @ PD_3)  TIM2 is the mbed system ticker, so unavailable as encoder.
+ * (TIM2_CH2: AF1 @ PA_1, PB_3; AF2 @ PD_4)
+ *
+ * TIM3_CH1: AF2 @ PA_6, PB_4, PC_6, PE_2           not for F302R8, OK @ F334R8
+ * TIM3_CH2: AF2 @ PA_4, PA_7, PB_5, PC_7, PE_3
+ *
+ * TIM4_CH1: AF2 @ PB_6, PD_12; AF10 @ PA_11        not for both F302R8 & F334R8
+ * TIM4_CH2: AF2 @ PB_7, PD_13; AF10 @ PA_12
+ *
+ */
+
+#ifdef TARGET_STM32F3
+
+void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim)
+{
+    GPIO_InitTypeDef GPIO_InitStruct;
+
+    if (htim->Instance == TIM1) { //PA8 PA9 = Nucleo D7 D8
+        __TIM1_CLK_ENABLE();
+        __GPIOA_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF6_TIM1;
+        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+    }
+#if 0 //TIM2 is the mbed system ticker
+    else if (htim->Instance == TIM2) { //PA0 PA1 = Nucleo A0 A1
+        __TIM2_CLK_ENABLE();
+        __GPIOA_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
+        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+    }
+#endif
+#if defined TARGET_STM32F334R8
+    else if (htim->Instance == TIM3) { //PB4 PB5 = Nucleo D5 D4
+        __TIM3_CLK_ENABLE();
+        __GPIOB_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_5;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
+        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+    }
+#endif
+#if 0
+    else if (htim->Instance == TIM4) { // PB6 PB7 = Nucleo D10 MORPHO_PB7
+        __TIM4_CLK_ENABLE();
+        __GPIOB_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF2_TIM4;
+        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+    }
+#endif
+}
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Encoder/EncoderMspInitF4.cpp	Sat May 21 04:17:35 2016 +0000
@@ -0,0 +1,102 @@
+#include "mbed.h"
+/*
+ * HAL_TIM_Encoder_MspInit()
+ * Overrides the __weak function stub in stm32f4xx_hal_tim.h
+ *
+ * Edit the below for your preferred pin wiring & pullup/down
+ * I have encoder common at 3V3, using GPIO_PULLDOWN on inputs.
+ * Encoder A&B outputs connected directly to GPIOs.
+ *
+ * www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00102166.pdf
+ * www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00141306.pdf
+ *
+ * TIM1_CH1: AF1 @ PA_8, PE_9 
+ * TIM1_CH2: AF1 @ PA_9, PE_11 
+ *
+ * TIM2_CH1: AF1 @ PA_0, PA_5, PA_15, PB_8*     *F446 only
+ * TIM2_CH2: AF1 @ PA_1, PB_3, PB_9*            *F446 only
+ *
+ * TIM3_CH1: AF2 @ PA_6, PB_4, PC_6
+ * TIM3_CH2: AF2 @ PA_7, PB_5, PC_7
+ *
+ * TIM4_CH1: AF2 @ PB_6, PD_12
+ * TIM4_CH2: AF2 @ PB_7, PD_13
+ *
+ * TIM5_CH1: AF2 @ PA_0*    *TIM5 used by mbed system ticker so unavailable
+ * TIM5_CH2: AF2 @ PA_1*
+ *
+ *
+ * Agrego el TIMER 8 tambien funciona 
+ * TIM8_CH1: AF3 @ PC_6
+ * TIM8_CH2: AF3 @ PC_7 
+ *
+ *
+ *
+ *
+ */
+
+#ifdef TARGET_STM32F4
+void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim)
+{
+    GPIO_InitTypeDef GPIO_InitStruct;
+
+    if (htim->Instance == TIM1) { //PA8 PA9 = Nucleo D7 D8
+        __TIM1_CLK_ENABLE();
+        __GPIOA_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
+        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+    }
+    else if (htim->Instance == TIM2) { //PA0 PA1 = Nucleo A0 A1 //USANDO ALTERNO PB8 Y PB 9 para el pololulu funcione
+        __TIM2_CLK_ENABLE();
+        __GPIOB_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
+        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+    }
+    else if (htim->Instance == TIM3) { //PB4 PB5 = Nucleo D5 D4
+        __TIM3_CLK_ENABLE();
+        __GPIOB_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_5;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
+        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+    }
+    else if (htim->Instance == TIM4) { // PB6 PB7 = Nucleo D10 MORPHO_PB7
+        __TIM4_CLK_ENABLE();
+        __GPIOB_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF2_TIM4;
+        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+    }
+     
+          
+     else if (htim->Instance == TIM8) { // PC7 PC8 =  D9  PC6
+        __TIM8_CLK_ENABLE();
+        __GPIOC_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF3_TIM8;
+        HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+    }    
+    
+    
+    
+    
+    
+    
+}
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Encoder/EncoderMspInitL0.cpp	Sat May 21 04:17:35 2016 +0000
@@ -0,0 +1,28 @@
+#include "mbed.h"
+/*
+ * HAL_TIM_Encoder_MspInit()
+ * Overrides the __weak function stub in stm32f4xx_hal_tim.h
+ *
+ * Edit the below for your preferred pin wiring & pullup/down
+ * I have encoder common at 3V3, using GPIO_PULLDOWN on inputs.
+ * Encoder A&B outputs connected directly to GPIOs.
+ *
+ */
+
+#ifdef TARGET_STM32L0
+void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim)
+{
+    GPIO_InitTypeDef GPIO_InitStruct;
+
+    if (htim->Instance == TIM2) { //PA0 PA1 = Nucleo A0 A1
+        __TIM2_CLK_ENABLE();
+        __GPIOA_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
+        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+    }
+}
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Encoder/EncoderMspInitL1.cpp	Sat May 21 04:17:35 2016 +0000
@@ -0,0 +1,63 @@
+#include "mbed.h"
+/*
+ * HAL_TIM_Encoder_MspInit()
+ * Overrides the __weak function stub in stm32l4xx_hal_tim.h
+ *
+ * Edit the below for your preferred pin wiring & pullup/down
+ * I have encoder common at 3V3, using GPIO_PULLDOWN on inputs.
+ * Encoder A&B outputs connected directly to GPIOs.
+ *
+ * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00098321.pdf
+ * Table 9 has GPIO alternate function pinout mappings.
+ *
+ * TIM2_CH1: AF1 @ PA_0, PA_5, PA_15, PE_9
+ * TIM2_CH2: AF1 @ PA_1, PB_3, PE_10
+ *
+ * TIM3_CH1: AF2 @ PA_6, PB_4, PC_6, PE_3
+ * TIM3_CH2: AF2 @ PA_7, PB_5, PC_7, PE_4
+ *
+ * TIM4_CH1: AF2 @ PB_6, PD_12
+ * TIM4_CH2: AF2 @ PB_7, PD_13
+ *
+ * TIM5_CH1: AF2 @ PA_0*    *TIM5 used by mbed system ticker so unavailable
+ * TIM5_CH2: AF2 @ PA_1*
+ *
+ */
+
+#ifdef TARGET_STM32L1
+void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim)
+{
+    GPIO_InitTypeDef GPIO_InitStruct;
+
+    if (htim->Instance == TIM2) { //PA0 PA1 = Nucleo A0 A1
+        __TIM2_CLK_ENABLE();
+        __GPIOA_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
+        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+    }
+    else if (htim->Instance == TIM3) { //PB4 PB5 = Nucleo D5 D4
+        __TIM3_CLK_ENABLE();
+        __GPIOB_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_5;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
+        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+    }
+    else if (htim->Instance == TIM4) { // PB6 PB7 = Nucleo D10 MORPHO_PB7
+        __TIM4_CLK_ENABLE();
+        __GPIOB_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF2_TIM4;
+        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+    }
+}
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Encoder/EncoderMspInitL4.cpp	Sat May 21 04:17:35 2016 +0000
@@ -0,0 +1,86 @@
+#include "mbed.h"
+/*
+ * HAL_TIM_Encoder_MspInit()
+ * Overrides the __weak function stub in stm32f4xx_hal_tim.h
+ *
+ * Edit the below for your preferred pin wiring & pullup/down
+ * I have encoder common at 3V3, using GPIO_PULLDOWN on inputs.
+ * Encoder A&B outputs connected directly to GPIOs.
+ *
+ * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00108832.pdf
+ * Table 15 has GPIOx AFx pinouts
+ *
+ * TIM1_CH1: AF1 @ PA8, PE9
+ * TIM1_CH2: AF1 @ PA9, PE11
+ *
+ * TIM2_CH1: AF1 @ PA0, PA5, PA15
+ * TIM2_CH2: AF1 @ PA1, PB3
+ *
+ * TIM3_CH1: AF2 @ PA6, PB4, PC6, PE3
+ * TIM3_CH2: AF2 @ PA7, PB5, PC7, PE4
+ *
+ * TIM4_CH1: AF2 @ PB6, PD12
+ * TIM4_CH2: AF2 @ PB7, PD13
+ *
+ * TIM5_CH1: AF2 @ PA0, PF6
+ * TIM5_CH2: AF2 @ PA1, PF7
+ *
+ */
+
+#ifdef TARGET_STM32L4
+void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim)
+{
+    GPIO_InitTypeDef GPIO_InitStruct;
+
+    if (htim->Instance == TIM1) {       //PA8 PA9 = Nucleo D7 D8
+        __TIM1_CLK_ENABLE();
+        __GPIOA_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
+        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+    }
+    else if (htim->Instance == TIM2) {  //PA0 PA1 = Nucleo A0 A1
+        __TIM2_CLK_ENABLE();
+        __GPIOA_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
+        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+    }
+    else if (htim->Instance == TIM3) {  //PB4 PB5 = Nucleo D5 D4
+        __TIM3_CLK_ENABLE();
+        __GPIOB_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_5;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
+        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+    }
+    else if (htim->Instance == TIM4) { // PB6 PB7 = Nucleo D10 MORPHO_PB7
+        __TIM4_CLK_ENABLE();
+        __GPIOB_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF2_TIM4;
+        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+    }
+    else if (htim->Instance == TIM5) { // here for completeness, mbed sytem timer uses this
+        __TIM5_CLK_ENABLE();
+        __GPIOA_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF2_TIM5;
+        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+    }
+}
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat May 21 04:17:35 2016 +0000
@@ -0,0 +1,564 @@
+/*PROYECTO DEL PENDULO INVERTIDO
+ * TARJETA= NUCLEO STM32F446
+   ENCODER EJE X PB_8 CH1  PB_9 CH2
+   ENCODER PENDULO PB_4 PB_5
+   
+   FIN DE CARRERA MOTOR IZQ = A1 
+   FIN DERECHA DER  = A0
+   
+   POLOLULU
+   
+   nD2 = D6
+   M1DIR=D7
+   M1PWM= D11 (TIMER 1)
+   NsF=D12
+   GND=D13
+   VCC=VCC
+ */   
+
+
+
+/*------------- THANKS DAVID LOWE FOR YOUR HELP-Your API/HAL use full ---------------------------------------
+ * Using STM32's counter peripherals to interface rotary encoders.
+ * Encoders are supported on F4xx's TIM1,2,3,4,5. TIM2 & TIM5 have 32bit count, others 16bit.
+ * Beware mbed uses TIM5 for system timer, SPI needs TIM1, others used for PWM.
+ * Check your platform's PeripheralPins.c & PeripheralNames.h if you need both PWM & encoders.
+ *
+ * Edit HAL_TIM_Encoder_MspInitFx.cpp to suit your mcu & board's available pinouts & pullups/downs.
+ *
+ * Thanks to:
+ * http://petoknm.wordpress.com/2015/01/05/rotary-encoder-and-stm32/
+ *
+ * References:
+ * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/user_manual/DM00122015.pdf
+ * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/reference_manual/DM00096844.pdf
+ * http://www.st.com/web/en/resource/technical/document/application_note/DM00042534.pdf
+ * http://www.st.com/web/en/resource/technical/document/datasheet/DM00102166.pdf
+ * 
+ * David Lowe Jan 2015
+ *
+ 
+ *Se complementa con el Timer 8 en la tarjeta nucleo
+ *Efectivamente el Timer 5 no se debe usar.
+ *Se Ajustaron los pines para la tarjeta para usar otros para los PWM
+  
+ */
+
+#include "mbed.h"
+#include "Encoder.h"
+
+
+/****************************ENCODER INICIALIZACION *************************/
+//STM mbed bug: these macros are MISSING from stm32f3xx_hal_tim.h
+#ifdef TARGET_STM32F3
+#define __HAL_TIM_GET_COUNTER(__HANDLE__) ((__HANDLE__)->Instance->CNT)
+#define __HAL_TIM_IS_TIM_COUNTING_DOWN(__HANDLE__)            (((__HANDLE__)->Instance->CR1 &(TIM_CR1_DIR)) == (TIM_CR1_DIR))
+#endif
+
+TIM_Encoder_InitTypeDef encoder2, encoder3, encoder4,encoder5, encoder8;
+TIM_HandleTypeDef  timer2,  timer3;
+
+/*************************************************************************/
+
+/*CONFIGURAMOS EL SHIELD DEL POLOLULU
+ Al coincidir con los pines del timer se modifica el codigo
+*/
+
+DigitalOut M1DIR(D7);
+PwmOut M1PWM(PA_7);
+//AnalogIn   M1FB(A0);
+
+//DigitalOut M2DIR(D8);
+//PwmOut M2PWM(D10);
+//DigitalIn  M2FB(A1);
+
+DigitalOut nD2(D6,1);
+DigitalIn nSF(D12);
+
+
+
+
+/***********PUERTO SERIAL*****************/
+
+Serial pc(SERIAL_TX, SERIAL_RX);
+
+
+/*VALORES POR DEFECTO*/
+
+float VEL=0.0;
+
+/*VALORES DE CONFIGURACION DE LOS PINES*/
+
+InterruptIn FINIZQR(A1);
+InterruptIn FINDERM(A0);
+//DigitalIn FINIZQR(D5);
+//DigitalIn FINDERM(D6);
+
+int alarma=0;
+DigitalOut INDICA(LED2);
+DigitalIn  INIT(PC_13);
+
+
+void toggle1(void); 
+void toggle2(void); 
+void inicializa(void);
+void centrar(void);
+
+/*-------------VARIABLES GLOBALES----------------------*/
+       
+    float X=0;
+    float POS=0;
+    float A=0;
+    float ANG=0;
+    float LIMIN=300;//SI no inicializa toca manual 220 
+    float LIMAX=7000;  //Si no inciializa toca 
+    
+    
+    float XMIN=0; //en las pruebas realizadas el 0 +200 pulsos
+    float XMAX=7200;; //en las pruebas aprox 7949
+    float MITAD=0;
+    int DATAPC=0;
+    int LEIDO=0;
+    
+    
+    
+/*------------------VARIABLES DEL PID Discreto--------------------------*/
+
+
+float uc0,yn0,en0,cn0,uc1,yn1,cn1,en1,yn2,cn2,en2,yn3,cn3,en3;
+    
+
+//Constantes
+
+float q0,q1,q2;
+
+/*-----------------PID DE PENDULO COMPLETO-------------------------------*/
+float PID_CODIGO(float MEDIDA,float SETPOINT,float DT);
+
+float KI;
+float KP;
+float KD; 
+float ERR;
+float PREVI_ERR;
+float INTEGRAL;
+float DERIVATIVO;
+
+float DESEADO=180;
+
+float TM=0.01;  // tiempo de muestreo
+
+
+float numero, cal_pwm;
+
+
+
+/*-------------------------------------------------PROGRAMA---------------------------------------------------------------*/
+
+int main()
+{
+ float SALIDAPID;
+ 
+ 
+ 
+ //inicializacion de las varibles   
+    yn0=0;
+    cn0=0;
+    en0=0;
+    yn1=0;
+    cn1=0;
+    en1=0;
+    yn2=0;
+    cn2=0;
+    en2=0;
+    yn3=0;
+    cn3=0;
+    en3=0;
+
+    q0=0.0510;
+    q1=-0.00102;
+    q2=0;
+
+    INTEGRAL=0.0;
+     KI=0.5;
+     KP=13;
+     KD=0.25; 
+     SALIDAPID=0.0;
+      
+    
+    
+    
+    //Configuramos el puerto de 96000 a 115200 para mayor velocidad
+    pc.baud(115200);    
+
+
+    //counting on both A&B inputs, 4 ticks per cycle, full 32-bit count
+    EncoderInit(&encoder2, &timer2, TIM2, 0xffffffff, TIM_ENCODERMODE_TI12);
+ 
+    //counting on both A&B inputs, 4 ticks per cycle, full 32-bit count
+    EncoderInit(&encoder3, &timer3, TIM3, 0xffff, TIM_ENCODERMODE_TI12);
+ 
+        int16_t count3=0;
+        int32_t count2=0;
+        //int8_t dir2, dir3;
+
+    M1PWM.period_ms(10.0); // set PWM period to 10 ms
+    
+     pc.printf("Listo iniciamos centrando el carro !\n");
+     wait(0.1);
+    
+    
+     inicializa();
+     centrar();
+     alarma=1;
+     
+     
+
+     pc.printf("Centre el pendulo y Presione reset para continuar \n\r");
+     //pc.printf("Press 'a' = aumentar, 'd' = disminuir   'i'=Izquierda 'o'=derecha 'r'=reset contadores 's'=para solo el PWM   \n\r");
+     char c ='s';
+     if (INIT==0){
+                
+            yn0=0;
+            cn0=0;
+            en0=0;
+            yn1=0;
+            cn1=0;
+            en1=0;
+            yn2=0;
+            cn2=0;
+            en2=0;
+            yn3=0;
+            cn3=0;
+            en3=0;
+            alarma=0;
+            VEL=0;
+            numero=0;
+            wait(0.5);               
+                }  
+       
+    
+    //Ciclo principal
+    while(1) {
+   
+
+     //----Deje habilitado la lectura del teclado para pruebas
+        if(pc.readable()==1) {
+               wait(0.1);
+               c = pc.getc();
+               pc.putc(c);
+        
+               
+                    if((c == 'a') && (VEL < 0.99)) {
+                             VEL += 0.01; 
+                             M1PWM = VEL; 
+                    }
+                    if((c == 'd') && (VEL > 0.01)) { 
+                        VEL -= 0.01; 
+                        M1PWM = VEL; 
+                    }
+                    if (c == 'i') {
+                    M1DIR=1; 
+                    }    
+                    if (c == 'o') {
+                    M1DIR=0; 
+                    }    
+                    if (c == 'r') {
+                    __HAL_TIM_SetCounter(&timer3, 0x0000);
+                    __HAL_TIM_SetCounter(&timer2, 0x00000000);
+                    }
+                    if (c == 's') {
+                    M1PWM = 0.0;
+                    }
+                                       
+                    c='0';       
+         }   
+        //----fin rutina de teclado
+        
+         INDICA=alarma;
+        
+          FINIZQR.rise(&toggle1);
+          FINDERM.rise(&toggle2);
+        
+        
+        //Rutina de lectura de los encoder timer2=X y Timer3 = Angulo
+        //X es de 100 huecos por revolucion = X4  400 pulsos por revolucion
+        //X es de 500 huecos por revolucuon = X4  2000 pulsos por revolucion
+        // X aproximado de 7950 +/10% por temas mecanicos de hay que sea variable el centro
+        // MITAD = 3757 depende de la ubicacion de los sensores ((MAX-220)-(MIN+220))/2
+        
+        //count2=TIM2->CNT;
+        //dir2=TIM2->CR1&TIM_CR1_DIR;
+        count2=__HAL_TIM_GET_COUNTER(&timer2);
+        //dir2 = __HAL_TIM_IS_TIM_COUNTING_DOWN(&timer2); //no se necesita para el calculo
+
+        //count3=TIM3->CNT;
+        //dir3=TIM3->CR1&TIM_CR1_DIR;
+        count3=__HAL_TIM_GET_COUNTER(&timer3);
+        //dir3 = __HAL_TIM_IS_TIM_COUNTING_DOWN(&timer3); //no se necesita para el calculo
+        
+        
+        
+
+       X=count2;//sensor de posicion 
+       A=count3;// sensor de angulo
+       
+       pc.printf("%6.0f %6.0f \t", X,A);
+        
+       if (INIT==0){
+                
+            yn0=0;
+            cn0=0;
+            en0=0;
+            yn1=0;
+            cn1=0;
+            en1=0;
+            yn2=0;
+            cn2=0;
+            en2=0;
+            yn3=0;
+            cn3=0;
+            en3=0;
+            alarma=0;
+            VEL=0;
+            numero=0;
+            wait(0.5);               
+                }
+                      
+    
+     //factor de conversion por longitud/pulsos (720mm/7949 =0.090577 mm* pulso  LTOTAL/PULSOS
+       POS=X*720/7949;
+       
+       
+       //factor de conversion grados vuelta/pulsos (360grados/2000 pulsos)=0.18   grados por pulso
+       ANG=A*0.18;
+       
+       pc.printf("POS: %6.3f  ANGULO:%6.3f \t", POS,ANG);
+    
+      
+        if(alarma==0){
+     
+        SALIDAPID=PID_CODIGO(ANG, DESEADO, TM);
+        
+        VEL=SALIDAPID;
+        
+                
+        //MAXIMO DE LA TARJETA   
+            
+            if (VEL>100) {        //Salida PID si es mayor que el MAX 
+                 VEL=99;
+            }                          
+            if (VEL<-100) {        //Salida PID si es mayor que el MAX 
+                 VEL=-99;
+            }                          
+            
+            if((VEL<=100)&&(VEL>=0)){
+                       VEL=VEL*1;                //Error es positivo entonces gire a la izquierda lado opuesto del motor
+                        M1DIR=0;
+                       } 
+            
+            if((VEL<0)&&(VEL>-100)){
+                       VEL=VEL*-1;                //Error es negativo entonces gire a la derecha lado opuesto del motor
+                        M1DIR=1;
+                       } 
+              
+                       
+            if (abs(VEL)<10){      //Salida PID si es menor que el MIN 
+                 VEL=1;                         
+             }
+                 
+        M1PWM=(float)VEL/100;//para controlar con las teclas por silas moscas 
+    
+        
+        }
+        pc.printf("PID = %f \t", SALIDAPID);    
+        pc.printf("REF:%6.2f ANG:%6.2f ERROR: %6.2f ACC:%6.2f  Itera: %.0f\t",DESEADO, ANG, ERR,VEL,numero);  
+        
+         
+        
+        
+        //pc.printf("El PWM %1.3f \t ",VEL); 
+        pc.printf("Alama: %i \n \r",alarma); 
+        
+        
+        
+        
+        
+        /*************************************************************************************************/
+        numero=numero+1;
+  
+  
+        /****seguridad***************/
+        if ((X+300)>=LIMAX){
+          VEL=0;
+          M1PWM=0;
+          alarma=1;
+        }
+        if ((X-300)<=LIMIN){
+          VEL=0.0;
+          M1PWM=0.0;
+          alarma=1;
+        }
+        
+        
+        
+        
+        
+    }
+}
+
+/*---------------------FUNCIONES-----------------------------------------------*/
+ 
+ /*---------------------INTERUPPCIONES------------------------------------------*/
+ 
+    void toggle1() {
+           wait(0.25); 
+           VEL = 0.0;
+           M1PWM = 0.0;
+           alarma=1;
+           pc.printf("ALARMA FINAL IZQUIERDA\n\r");
+    }
+    
+      void toggle2() {
+           wait(0.25); 
+           VEL = 0.0;
+           alarma=1;
+           M1PWM = 0.0;
+           pc.printf("ALARMA FINAL DERECHA\n\r");
+    }   
+    
+/*--------------------------------FUCIONES DE INICIALIZACION------------------------------*/
+
+
+void inicializa(){
+        pc.printf("Funcion de Inicializacion iniciada\n\r");
+           
+     M1PWM=0.1;
+     M1DIR=1;
+     while(FINDERM==0){
+         pc.printf("BUSCANCO DERECHA DEL MOTOR\n\r");
+          }
+         pc.printf("ENCONTRADA - REINICIANDO EL CONTADOR EN X\n\r");
+            __HAL_TIM_SetCounter(&timer2, 0x00000000);
+       
+     M1PWM=0.1;
+     M1DIR=0;
+          
+      while(FINIZQR==0){
+         pc.printf("BUSCANCO IZQUIERDA LADO OPUESTO\n\r");
+          }  
+       M1PWM=0;         
+       XMAX=__HAL_TIM_GET_COUNTER(&timer2);
+       M1PWM=0;
+       XMIN=0;
+       LIMIN=220;
+       LIMAX=XMAX-220;
+       MITAD=(LIMAX-LIMIN)/2; 
+       pc.printf("Fijando los limites XMIN+220 y XMAX-220 por seguridad, XMIN:%6.0f XMAX:%6.0f MITAD:%6.1f \n\r",XMIN, XMAX, MITAD);
+   
+    }
+
+void centrar(){
+     float error, pos;
+     int parada;
+     float itera;
+     parada=1;
+     itera=0;
+     pos=0;
+     error=0;
+     
+     float K1, K2, K3, uk;
+            
+     /*valores por defecto*/
+     //Kp=0.03;
+     //Ki=0;
+     //Kd=0;
+     
+     
+     /*parametros del PID discreto*/
+    // K1=Kp+(Ki/2)*Ts+(Kd/Ts);
+    // K2=-Kp+(Ki/2)*Ts-(2*Kd/Ts);
+    // K3=Kd/Ts;
+     
+     K1=0.19;
+     K2=0;
+     K3=0;
+     
+     
+     
+     pos=__HAL_TIM_GET_COUNTER(&timer2);
+     error=MITAD-pos;
+     
+     while(parada==1){
+ 
+            if (error>0){
+                        //Error es positivo entonces gire a la izquierda lado opuesto del motor
+                        M1DIR=0;
+                       } 
+            else if(error<=0){
+                        //Error es negativo entonces gire a la derecha hacia el motor
+                        M1DIR=1;
+                       } 
+            
+            pos=__HAL_TIM_GET_COUNTER(&timer2);
+            error=MITAD-pos;
+            
+            uk=error*K1;
+                    
+            
+             
+           pc.printf("BUSCA LA MITAD M:%6.0f P:%6.0f E:%6.1f Uk:%6.1f Itera:%6.0f\n\r",MITAD, pos, error,uk, itera);
+    
+            if (abs(uk)>100) {        //Salida  si es mayor que el MAX 
+                 uk=80;}                          
+                else if (abs(uk)<20){      //Salida  si es menor que el MIN 
+                uk=5;                         
+             }
+                 
+             M1PWM=(float)uk/100; //Accion de control mapeada a PWM; salida de la tarjeta.
+        
+               
+           
+            if (abs(error)<5){
+                parada=0;
+                }
+            if (itera>1000){
+                parada=0;
+                }
+     
+            itera++;
+       
+       }     
+       M1PWM=0.0;
+       pc.printf("ENCONTRADO  MITAD:%f  POS:%f  Error: %f Itera: %f\n\r",MITAD, pos, error, itera);    
+       
+
+}
+
+/******************************************PID*******************************************************/
+float PID_CODIGO(float MEDIDA,float SETPOINT,float DT){
+    float OUTPID;
+ 
+    ERR=SETPOINT-MEDIDA;
+    INTEGRAL=INTEGRAL+ERR*DT;
+    DERIVATIVO=(ERR-PREVI_ERR)/DT;
+    OUTPID=KP*ERR-KI*INTEGRAL+KD*DERIVATIVO;
+    PREVI_ERR=ERR;
+
+    //wait(DT);
+    return(OUTPID);
+   
+    
+    //previous_error = 0
+    //integral = 0 
+    //start:
+    //error = setpoint - measured_value
+    //integral = integral + error*dt
+    //derivative = (error - previous_error)/dt
+    //output = Kp*error + Ki*integral + Kd*derivative
+    //previous_error = error
+    //wait(dt)
+    //goto start
+
+    
+      
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-dev.lib	Sat May 21 04:17:35 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-dev/#9b334a45a8ff