Basic DC motor control test, rpm feedback by simple impulse signal, PID speed control.
Dependencies: FastPWM mbed FastIO MODSERIAL
Diff: main.cpp
- Revision:
- 8:5ce5fe1ce503
- Parent:
- 7:1aba48efb1c3
- Child:
- 10:c28d133a1408
diff -r 1aba48efb1c3 -r 5ce5fe1ce503 main.cpp --- a/main.cpp Wed Mar 28 09:32:05 2018 +0000 +++ b/main.cpp Wed Mar 28 13:18:59 2018 +0000 @@ -1,21 +1,35 @@ +/** + * @brief Basic DC motor control test, rpm feedback by simple impulse signal, PID speed control. + * @file main.cpp + * @author Jan Tetour <jan.tetour@gmail.com> + * + * Test application for STM32F4 for small DC motor control. Main specifications: + * - DC motor controlled by PWM + * - Motor driver used L298N + * - RPM evaluated via simple impulse sensor + * - Speed (RPM) controlled by PID controller + */ + #include "mbed.h" + #include "FastPWM.h" #include "FastIO.h" + #include "PID.h" +// Define MODSERIAL buffer sizes #define MODSERIAL_DEFAULT_RX_BUFFER_SIZE 16 #define MODSERIAL_DEFAULT_TX_BUFFER_SIZE 64 #include "MODSERIAL.h" -#define IMPULSE_SENSOR_R_PIN (PA_9) -#define PWM_OUT_R_PIN (PA_6) +// Pin defintions +#define IMPULSE_SENSOR_R_PIN (PA_9) +#define PWM_OUT_R_PIN (PA_6) -//------------------------------------ -// Hyperterminal configuration -// 9600 bauds, 8-bit data, no parity -//------------------------------------ +// Serial port definitions MODSERIAL pcLink(SERIAL_TX, SERIAL_RX); +// Tasks timming definitions static const us_timestamp_t periodImpSens = 125000; // 125 msec static const us_timestamp_t periodLEDBlink = 100000; // 100 msec static const us_timestamp_t periodPWMWrite = 250000; // 250 msec @@ -28,31 +42,41 @@ static us_timestamp_t tStamp = 0; +static Timer myTimer; + +// RPM Sensor module level variables static unsigned int uiImpSens = 0U; static unsigned int uiImpSensTemp = 0U; static int iImpSensLastState = 0; -static float fPwmDuty = 0.0; + +// PWM Generator module level variables +static float fPwmDuty = 0.0f; + +// RPM Controller module level variables static float fRPMSetpoint = 0.0f; -static void setup(void); +// LOCAL MODULE VARIABLES +// I/O pins related +FastPWM mypwm(PWM_OUT_R_PIN); +FastIn<IMPULSE_SENSOR_R_PIN> pinImpulseSensorIn; +FastIn<USER_BUTTON> pinUserButtonIn; +DigitalOut myled(LED1); + +// Controllers +PID pid_RPM_Right_motor(1.0f, 0.0f, 0.0f, (((float)periodPWMWrite)/1000000.0f)); + +// LOCAL FUNCTION DECLARATIONS +// Task worker functions static void tskImpSens(void); static void tskLEDBlink(void); static void tskPWMWrite(void); static void tskRPMSetpoint(void); static void tskBackground(void); -FastPWM mypwm(PWM_OUT_R_PIN); - -FastIn<IMPULSE_SENSOR_R_PIN> pinImpulseSensorIn; -FastIn<USER_BUTTON> pinUserButtonIn; +// Inititalization +static void setup(void); -PID pid_RPM_Right_motor(1.0f, 0.0f, 0.0f, (((float)periodPWMWrite)/1000000.0f)); - -DigitalOut myled(LED1); - -Timer myTimer; - - +// Task management functions static inline void DO_TASK(us_timestamp_t tskPeriod, us_timestamp_t &tskTimer, us_timestamp_t timeStamp, void (*tskFunction)(void)) { if (tskPeriod < (timeStamp - tskTimer)) @@ -67,7 +91,7 @@ (*tskFunction)(); } - +// Main function definition int main(void) { setup(); @@ -86,6 +110,8 @@ } +// LOCAL MODULE DEFINITIONS +// Initialization void setup(void) { pcLink.baud(115200); @@ -110,19 +136,38 @@ pid_RPM_Right_motor.setSetPoint(0.0f); } +// Task worker functions definitions +/** + * @brief RPM calculation. + * @note Needs refactoring to implement #ifdef for 2 different implementation (with/without PID). + * + * Stores impulse count per measurement period and clears impulse counter. + */ void tskImpSens(void) { uiImpSens = uiImpSensTemp; uiImpSensTemp = 0U; - pcLink.printf("IMP: %u imp. \r", uiImpSens); + // pcLink.printf("IMP: %u imp. \r", uiImpSens); } +/** + * @brief User LED flashing. + * + * Implements User LED flashing. + */ void tskLEDBlink(void) { myled = !myled; } +/** + * @brief Writes new duty cycle value into PWM generator. + * @note Needs refactoring to implement #ifdef for 2 different implementation (with/without PID). + * @warning Not finished. + * + * Calculates new dyty cycle and writes the value into PWM generator. + */ void tskPWMWrite(void) { // fPwmDuty = fPwmDuty + 0.1; @@ -145,6 +190,12 @@ // pcLink.printf("\r\nPWM: %.2f %% \r\n", mypwm.read() * 100); } +/** + * @brief Implementation of periodic change of RPM Setpoint. Simulates setpoint changes to asses dynamic behaviour. + * @note For test purposes. + * + * Increases Setpoint value step by step with every invocation. + */ void tskRPMSetpoint(void) { fRPMSetpoint += 10.0f; @@ -156,6 +207,14 @@ pid_RPM_Right_motor.setSetPoint(fRPMSetpoint); } +/** + * @brief Implementation of background task. Periodically called from main loop without delay. + * @note These actions are candidates for refactoring to event based implementation. + * @warning Initial implementation. Simple and easy. + * + * This function implements actions, which needs to be processed with high priority. + * Is intended to be called in every pass of main loop. + */ void tskBackground(void) { // Impulse sensor - pulse counting @@ -165,4 +224,4 @@ iImpSensLastState = iTemp; uiImpSensTemp++; } -} \ No newline at end of file +}