Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
MotHatLib.cpp
00001 #include "SysConfig.h" 00002 00003 //Number of on-board devices 00004 const int LED_NUM_MAX = 1; 00005 const int MOT_NUM_MAX = 4; 00006 const int SRV_NUM_MAX = 4; 00007 const int VMON_NUM_MAX = 4; 00008 00009 //The speed difference rate of left/right side motors when the vehicle turns head 00010 const int MOT_TURN_RATE = 4; 00011 00012 //Fixed PWM period of servos 00013 const int SRV_PERIOD_US = 20000; 00014 00015 //LEDs on mother board and daughter board 00016 //DigitalOut led_mb(LED1, 0); //Nucleo 00017 DigitalOut led_mb(PB_12, 1); //MOT HAT 00018 00019 //USART2 to PC for debug 00020 Serial uart_pc(SERIAL_TX, SERIAL_RX); 00021 SerialDummy uart_dummy; 00022 00023 //GPIO for L293DD motor direction control 00024 //Forward = 2b'01, Backward = 2b'10, Stop = 2b'00 00025 BusOut mot1_dir(PB_3, PA_11), mot2_dir(PA_15, PA_12), mot3_dir(PD_2, PC_12), mot4_dir(PB_6, PB_7); 00026 00027 //GPIO for motor velocimeter 00028 InterruptIn spd1_in(PF_6), spd2_in(PF_7), spd3_in(PF_5), spd4_in(PC_4); 00029 //GPIO for ultrasound rangefinder 00030 InterruptIn us1_echo(PC_10), us2_echo(PC_5); 00031 DigitalOut us1_trig(PC_11), us2_trig(PF_4); 00032 00033 //Timers for speed and distance counter 00034 Timer timer_spd, timer_us; 00035 00036 //Analog inputs for power voltage monitoring 00037 AnalogIn vin_bat(PC_0); //ADC1_CH10 00038 AnalogIn vin_12v(PC_1); //ADC1_CH11 00039 AnalogIn vin_5v(PC_2); //ADC1_CH12 00040 AnalogIn vin_3v3(PC_3); //ADC1_CH13 00041 00042 //TIM3 PWM channels 00043 PwmOut mot1_pwm(PB_5); //TIM3_CH2 00044 PwmOut mot2_pwm(PB_4); //TIM3_CH1 00045 PwmOut mot3_pwm(PB_0); //TIM3_CH3 00046 PwmOut mot4_pwm(PC_9); //TIM3_CH4 00047 00048 //TIM15 PWM channels 00049 PwmOut servo1_pwm(PB_14); //TIM15_CH1 00050 PwmOut servo2_pwm(PB_15); //TIM15_CH2 00051 //TIM16 PWM channels 00052 PwmOut servo3_pwm(PB_8); //TIM16_CH1 00053 //TIM17 PWM channels 00054 PwmOut servo4_pwm(PB_9); //TIM17_CH1 00055 00056 //Position calibration for servos 00057 //ServoCal[x][0] is -90 degrees, ServoCal[x][1] is +90 degrees 00058 const int ServoCal[][2] = {{1000, 2000}, {1000, 2000}, {1000, 2000}, {1000, 2000}}; 00059 00060 //Voltage division ratios 00061 const float VmonDivision[] = {0.1, 0.1, 0.5, 0.5}; 00062 00063 //Init board library 00064 //--> Success return 0 00065 int BoardLibInit(void) 00066 { 00067 //Init LED status 00068 LedOnAll(); 00069 00070 //Init debug UART 00071 uart_pc.baud(115200); 00072 00073 //Init DC motors 00074 Mot_Init(); 00075 00076 //Init servos 00077 Servo_Init(); 00078 00079 //Return 0 if success 00080 return 0; 00081 } 00082 00083 /*********************************************/ 00084 /* Voltage Monitor Functions */ 00085 /*********************************************/ 00086 float Vmon_ReadVolt(int channel) 00087 { 00088 switch(channel) 00089 { 00090 case 1: 00091 return vin_bat.read() * 3.3 / VmonDivision[channel - 1]; 00092 00093 case 2: 00094 return vin_12v.read() * 3.3 / VmonDivision[channel - 1]; 00095 00096 case 3: 00097 return vin_5v.read() * 3.3 / VmonDivision[channel - 1]; 00098 00099 case 4: 00100 return vin_3v3.read() * 3.3 / VmonDivision[channel - 1]; 00101 00102 default: 00103 return 0; 00104 } 00105 } 00106 00107 00108 /*********************************************/ 00109 /* DC Motor Control Functions */ 00110 /*********************************************/ 00111 //Init the PWM and direction of motors to STOP state 00112 void Mot_Init(void) 00113 { 00114 for(int motNum = 1; motNum <= MOT_NUM_MAX; motNum++) 00115 { 00116 Mot_PwmSetup(motNum, 1000, 0); //Freq = 1KHz, Speed = 0% 00117 Mot_SetDirection(motNum, 's'); //Direction = STOP 00118 } 00119 } 00120 00121 //Control the movement of vehicle 00122 //dir: forward = 'f', backward = 'b', stop = 's' 00123 //turn: left = 'l', right = 'r', fixed turning rate 00124 //speed: 0.0~1.0 (0~100%, 0.245 = 24.5%) 00125 void Mot_Ctrl(char dir, char turn, float speed) 00126 { 00127 if(speed < 0) 00128 speed = 0; 00129 if(speed > 1) 00130 speed = 1; 00131 00132 switch(turn) 00133 { 00134 case 'm': 00135 Mot_PwmWrite(1, speed); 00136 Mot_SetDirection(1, dir); 00137 Mot_PwmWrite(2, speed); 00138 Mot_SetDirection(2, dir); 00139 00140 if(MOT_NUM_MAX > 2) 00141 { 00142 Mot_PwmWrite(3, speed); 00143 Mot_SetDirection(3, dir); 00144 Mot_PwmWrite(4, speed); 00145 Mot_SetDirection(4, dir); 00146 } 00147 break; 00148 00149 case 'l': 00150 Mot_PwmWrite(1, speed / MOT_TURN_RATE); 00151 Mot_SetDirection(1, dir); 00152 Mot_PwmWrite(2, speed); 00153 Mot_SetDirection(2, dir); 00154 00155 if(MOT_NUM_MAX > 2) 00156 { 00157 Mot_PwmWrite(3, speed / MOT_TURN_RATE); 00158 Mot_SetDirection(3, dir); 00159 Mot_PwmWrite(4, speed); 00160 Mot_SetDirection(4, dir); 00161 } 00162 break; 00163 00164 case 'r': 00165 Mot_PwmWrite(1, speed); 00166 Mot_SetDirection(1, dir); 00167 Mot_PwmWrite(2, speed / MOT_TURN_RATE); 00168 Mot_SetDirection(2, dir); 00169 00170 if(MOT_NUM_MAX > 2) 00171 { 00172 Mot_PwmWrite(3, speed); 00173 Mot_SetDirection(3, dir); 00174 Mot_PwmWrite(4, speed / MOT_TURN_RATE); 00175 Mot_SetDirection(4, dir); 00176 } 00177 break; 00178 00179 case 's': 00180 for(int motNum = 1; motNum <= MOT_NUM_MAX; motNum++) 00181 { 00182 Mot_PwmWrite(motNum, 0); 00183 Mot_SetDirection(motNum, 's'); 00184 } 00185 break; 00186 } 00187 } 00188 00189 //channel: 1~4, period: us, duty: 0.0~1.0 (0.245 = 24.5%) 00190 void Mot_PwmSetup(int channel, int period, float duty) 00191 { 00192 if(duty < 0) 00193 duty = 0; 00194 else if(duty > 1) 00195 duty = 1; 00196 00197 switch(channel) 00198 { 00199 case 1: 00200 mot1_pwm.period_us(period); 00201 mot1_pwm = duty; 00202 break; 00203 case 2: 00204 mot2_pwm.period_us(period); 00205 mot2_pwm = duty; 00206 break; 00207 case 3: 00208 mot3_pwm.period_us(period); 00209 mot3_pwm = duty; 00210 break; 00211 case 4: 00212 mot4_pwm.period_us(period); 00213 mot4_pwm = duty; 00214 break; 00215 00216 default: 00217 break; 00218 } 00219 } 00220 00221 //channel: 1~4, duty: 0.0~1.0 (0.245 = 24.5%) 00222 void Mot_PwmWrite(int channel, float duty) 00223 { 00224 if(duty < 0) 00225 duty = 0; 00226 else if(duty > 1) 00227 duty = 1; 00228 00229 switch(channel) 00230 { 00231 //All channels in TIM3 share the same period 00232 case 1: 00233 mot1_pwm = duty; 00234 break; 00235 case 2: 00236 mot2_pwm = duty; 00237 break; 00238 case 3: 00239 mot3_pwm = duty; 00240 break; 00241 case 4: 00242 mot4_pwm = duty; 00243 break; 00244 00245 default: 00246 break; 00247 } 00248 } 00249 00250 //channel: 1~4, dir: forward = 'f', backward = 'b', stop = 's' 00251 void Mot_SetDirection(int channel, char dir) 00252 { 00253 switch(channel) 00254 { 00255 case 1: 00256 if(dir == 'f') 00257 mot1_dir = 0x1; 00258 else if(dir == 'b') 00259 mot1_dir = 0x2; 00260 else 00261 mot1_dir = 0x0; 00262 break; 00263 case 2: 00264 if(dir == 'f') 00265 mot2_dir = 0x1; 00266 else if(dir == 'b') 00267 mot2_dir = 0x2; 00268 else 00269 mot2_dir = 0x0; 00270 break; 00271 case 3: 00272 if(dir == 'f') 00273 mot3_dir = 0x1; 00274 else if(dir == 'b') 00275 mot3_dir = 0x2; 00276 else 00277 mot3_dir = 0x0; 00278 break; 00279 case 4: 00280 if(dir == 'f') 00281 mot4_dir = 0x1; 00282 else if(dir == 'b') 00283 mot4_dir = 0x2; 00284 else 00285 mot4_dir = 0x0; 00286 break; 00287 } 00288 } 00289 00290 /*********************************************/ 00291 /* Motor Velocimetoer Functions */ 00292 /*********************************************/ 00293 int MotSpdPulseTime[] = {0, 0, 0, 0}; 00294 int MotSpeed[] = {0, 0, 0, 0}; 00295 00296 void Mot_StartVelocimeter(void) 00297 { 00298 timer_spd.start(); 00299 00300 spd1_in.rise(&Mot_SpdPluseIntHandler1); 00301 spd2_in.rise(&Mot_SpdPluseIntHandler2); 00302 spd3_in.rise(&Mot_SpdPluseIntHandler3); 00303 spd4_in.rise(&Mot_SpdPluseIntHandler4); 00304 } 00305 00306 void Mot_StopVelocimeter(void) 00307 { 00308 spd1_in.disable_irq(); 00309 spd2_in.disable_irq(); 00310 spd3_in.disable_irq(); 00311 spd4_in.disable_irq(); 00312 00313 timer_spd.stop(); 00314 for(int i=1; i<=MOT_NUM_MAX; i++) 00315 MotSpdPulseTime[i-1] = 0; 00316 } 00317 00318 int Mot_GetSpeed(int channel) 00319 { 00320 if(channel < 1) 00321 channel = 1; 00322 else if(channel > MOT_NUM_MAX) 00323 channel = MOT_NUM_MAX; 00324 00325 return MotSpeed[channel - 1]; 00326 } 00327 00328 void Mot_SpdPluseIntHandler1(void) 00329 { 00330 int time = timer_spd.read_ms(); 00331 MotSpeed[0] = 3000 / (time - MotSpdPulseTime[0]); 00332 MotSpdPulseTime[0] = time; 00333 } 00334 00335 void Mot_SpdPluseIntHandler2(void) 00336 { 00337 int time = timer_spd.read_ms(); 00338 MotSpeed[1] = 3000 / (time - MotSpdPulseTime[1]); 00339 MotSpdPulseTime[1] = time; 00340 } 00341 00342 void Mot_SpdPluseIntHandler3(void) 00343 { 00344 int time = timer_spd.read_ms(); 00345 MotSpeed[2] = 3000 / (time - MotSpdPulseTime[2]); 00346 MotSpdPulseTime[2] = time; 00347 } 00348 00349 void Mot_SpdPluseIntHandler4(void) 00350 { 00351 int time = timer_spd.read_ms(); 00352 MotSpeed[3] = 3000 / (time - MotSpdPulseTime[3]); 00353 MotSpdPulseTime[3] = time; 00354 } 00355 00356 /*********************************************/ 00357 /* Servo Control Functions */ 00358 /*********************************************/ 00359 //Init the PWM and direction of motors to STOP state 00360 void Servo_Init(void) 00361 { 00362 for(int servoNum = 1; servoNum <= SRV_NUM_MAX; servoNum++) 00363 { 00364 Servo_SetAngle(servoNum, 0); 00365 } 00366 } 00367 00368 //channel: 1~4, angle: -90.0~+90.0 00369 void Servo_SetAngle(int channel, float angle) 00370 { 00371 if(channel > 0 && channel <= SRV_NUM_MAX) 00372 { 00373 int pulse = (int)((angle + 90.0) * (ServoCal[channel - 1][1] - ServoCal[channel-1][0]) / 180.0 + ServoCal[channel-1][0]); 00374 Servo_PwmWrite(channel, pulse); 00375 } 00376 } 00377 00378 //channel: 1~4, pulse_us: 0~20000us 00379 void Servo_PwmSetup(int channel, int pulse_us) 00380 { 00381 if(pulse_us < 0) 00382 pulse_us = 0; 00383 else if(pulse_us > 20000) 00384 pulse_us = 20000; 00385 00386 switch(channel) 00387 { 00388 case 1: 00389 servo1_pwm.period_us(SRV_PERIOD_US); 00390 servo1_pwm.pulsewidth_us(pulse_us); 00391 break; 00392 case 2: 00393 servo2_pwm.period_us(SRV_PERIOD_US); 00394 servo2_pwm.pulsewidth_us(pulse_us); 00395 break; 00396 case 3: 00397 servo3_pwm.period_us(SRV_PERIOD_US); 00398 servo3_pwm.pulsewidth_us(pulse_us); 00399 break; 00400 case 4: 00401 servo4_pwm.period_us(SRV_PERIOD_US); 00402 servo4_pwm.pulsewidth_us(pulse_us); 00403 break; 00404 00405 default: 00406 break; 00407 } 00408 } 00409 00410 //channel: 1~4, pulse_us: 0~20000us 00411 void Servo_PwmWrite(int channel, int pulse_us) 00412 { 00413 if(pulse_us < 0) 00414 pulse_us = 0; 00415 else if(pulse_us > 20000) 00416 pulse_us = 20000; 00417 00418 switch(channel) 00419 { 00420 //All channels in TIM3 share the same period 00421 case 1: 00422 servo1_pwm.pulsewidth_us(pulse_us); 00423 break; 00424 case 2: 00425 servo2_pwm.pulsewidth_us(pulse_us); 00426 break; 00427 case 3: 00428 servo3_pwm.pulsewidth_us(pulse_us); 00429 break; 00430 case 4: 00431 servo4_pwm.pulsewidth_us(pulse_us); 00432 break; 00433 00434 default: 00435 break; 00436 } 00437 } 00438 00439 /*********************************************/ 00440 /* Ultrasound Rangefinder Functions */ 00441 /*********************************************/ 00442 //xxx 00443 00444 00445 /*********************************************/ 00446 /* LED Control Functions */ 00447 /*********************************************/ 00448 void LedOn(int ch) 00449 { 00450 switch(ch) 00451 { 00452 case 0: 00453 led_mb = 0; 00454 break; 00455 00456 default: 00457 break; 00458 } 00459 } 00460 00461 void LedOff(int ch) 00462 { 00463 switch(ch) 00464 { 00465 case 0: 00466 led_mb = 1; 00467 break; 00468 00469 default: 00470 break; 00471 } 00472 } 00473 00474 void LedToggle(int ch) 00475 { 00476 switch(ch) 00477 { 00478 case 0: 00479 led_mb = !led_mb; 00480 break; 00481 00482 default: 00483 break; 00484 } 00485 } 00486 00487 void LedOnAll(void) 00488 { 00489 for(int ledNum = 0; ledNum < LED_NUM_MAX; ledNum++) 00490 LedOn(ledNum); 00491 } 00492 00493 void LedOffAll(void) 00494 { 00495 for(int ledNum = 0; ledNum < LED_NUM_MAX; ledNum++) 00496 LedOff(ledNum); 00497 }
Generated on Fri Jul 15 2022 01:55:45 by
1.7.2