Xiaohai Li
/
RPi_MOT_HAT
Raspberry Pi MOT HAT Based on STM32F030R8. The clock needs to be changed to 8MHz after export.
Embed:
(wiki syntax)
Show/hide line numbers
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