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.
Dependents: ISR_Mini-explorer_Rangefinder
Fork of ISR_Mini-explorer by
robot.h
00001 /** @file */ 00002 00003 #include "mbed.h" 00004 #include <math.h> 00005 #include "VCNL40x0.h" 00006 #include "Radio.h" 00007 #include "Encoder.h" 00008 #include "Rangefinder.h" 00009 00010 I2C i2c(PTC9,PTC8); 00011 I2C i2c1(PTC11,PTC10); 00012 Mutex mutex_i2c0; 00013 Mutex mutex_i2c1; 00014 00015 float X=20; 00016 float Y=20; 00017 float THETA=0; 00018 Encoder esquerdo(&i2c, &mutex_i2c0, 0); 00019 Encoder direito(&i2c1, &mutex_i2c1, 1); 00020 Thread thread; 00021 00022 void odometry_thread() 00023 { 00024 float theta=0; 00025 long int ticks2d=0; 00026 long int ticks2e=0; 00027 00028 00029 00030 while (true) { 00031 esquerdo.incremental(); 00032 direito.incremental(); 00033 //------------------------------------------- 00034 long int ticks1d=direito.readIncrementalValue(); 00035 long int ticks1e=esquerdo.readIncrementalValue(); 00036 00037 long int D_ticks=ticks1d - ticks2d; 00038 long int E_ticks=ticks1e - ticks2e; 00039 00040 ticks2d=ticks1d; 00041 ticks2e=ticks1e; 00042 00043 float D_cm= (float)D_ticks*((3.25*3.1415)/4096); 00044 float L_cm= (float)E_ticks*((3.25*3.1415)/4096); 00045 00046 float CM=(D_cm + L_cm)/2; 00047 00048 theta +=(D_cm - L_cm)/7.18; 00049 00050 theta = atan2(sin(theta), cos(theta)); 00051 THETA = theta; 00052 00053 // meter entre 0 00054 00055 X += CM*cos(theta); 00056 Y += CM*sin(theta); 00057 //------------------------------------------- 00058 00059 Thread::wait(10); 00060 } 00061 } 00062 00063 // classes adicionais 00064 VCNL40x0 VCNL40x0_Device (PTC9, PTC8, VCNL40x0_ADDRESS); 00065 Serial pc(PTE0,PTE1); 00066 00067 00068 // Variables needed by the lib 00069 unsigned int ProxiValue=0; 00070 00071 //SAIDAS DIGITAIS (normal) 00072 DigitalOut q_pha_mot_rig (PTE4,0); //Phase Motor Right 00073 DigitalOut q_sleep_mot_rig (PTE3,0); //Nano Sleep Motor Right 00074 DigitalOut q_pha_mot_lef (PTA17,0); //Phase Motor Left 00075 DigitalOut q_sleep_mot_lef (PTB11,0); //Nano Sleep Motor Left 00076 DigitalOut q_pow_ena_i2c_p (PTE2,0); //Power Enable i2c FET P (0- enable 1-disable) 00077 DigitalOut q_pow_ena_mic_p (PTA14,0); //Power enable Micro FET P (0- enable 1-disable) 00078 DigitalOut q_pow_as5600_n (PTC6,1); //AS5600 Power MOSFET N (1- enable 0-disable) 00079 DigitalOut q_pow_as5600_p (PTC5,0); //AS5600 Power MOSFET P (0- enable 1-disable) 00080 DigitalOut q_pow_spi (PTC4,0); //SPI Power MOSFET P (0- enable 1-disable) 00081 DigitalOut q_ena_mppt (PTC0,0); //Enable MPPT Control (0- enable 1-disable) 00082 DigitalOut q_boost_ps (PTC7,1); //Boost Power Save (1- enable 0-disable) 00083 DigitalOut q_tca9548_reset (PTC3,1); //Reset TCA9548 (1- enable 0-disable) 00084 DigitalOut power_36khz (PTD0,0); //Power enable pic12f - 36khz (0- enable 1-disable) 00085 00086 00087 // ******************************************************************** 00088 // ******************************************************************** 00089 //DEFINIÇÃO DE ENTRADAS E SAIDAS DO ROBOT 00090 //ENTRADAS DIGITAIS (normal input) 00091 DigitalIn i_enc_dir_rig (PTB8); //Encoder Right Direction 00092 DigitalIn i_enc_dir_lef (PTB9); //Encoder Left Direction 00093 DigitalIn i_micro_sd_det (PTC16); //MICRO SD Card Detect 00094 DigitalIn i_mppt_fail (PTE5); //Fail MPPT Signal 00095 DigitalIn i_usb_volt (PTB10); //USB Voltage detect 00096 DigitalIn i_sup_cap_est (PTB19); //Supercap State Charger 00097 DigitalIn i_li_ion_est (PTB18); //Li-ion State Charger 00098 00099 00100 // ******************************************************************** 00101 //ENTRADAS DIGITAIS (external interrupt) 00102 InterruptIn i_int_mpu9250 (PTA15); //Interrupt MPU9250 00103 InterruptIn i_int_isl29125 (PTA16); //Interrupt ISL29125 Color S. 00104 InterruptIn i_mic_f_l (PTD7); //Interrupt Comp Micro F L 00105 InterruptIn i_mic_f_r (PTD6); //Interrupt Comp Micro F R 00106 InterruptIn i_mic_r_c (PTD5); //Interrupt Comp Micro R C 00107 00108 00109 // ******************************************************************** 00110 //ENTRADAS ANALOGICAS 00111 AnalogIn a_enc_rig (PTC2); //Encoder Left Output_AS_MR 00112 AnalogIn a_enc_lef (PTC1); //Encoder Right Output_AS_ML 00113 AnalogIn a_mic_f_l (PTB0); //Analog microphone F L 00114 AnalogIn a_mic_f_r (PTB1); //Analog microphone F R 00115 AnalogIn a_mic_r_c (PTB2); //Analog microphone R C 00116 AnalogIn a_temp_bat (PTB3); //Temperature Battery 00117 00118 00119 // ******************************************************************** 00120 00121 //PWM OR DIGITAL OUTPUT NORMAL 00122 //DigitalOut q_led_whi (PTE29); //Led white pwm 00123 DigitalOut q_led_red_fro (PTA4); //Led Red Front 00124 DigitalOut q_led_gre_fro (PTA5); //Led Green Front 00125 DigitalOut q_led_blu_fro (PTA12); //Led Blue Front 00126 DigitalOut q_led_red_rea (PTD4); //Led Red Rear 00127 DigitalOut q_led_gre_rea (PTA1); //Led Green Rear 00128 DigitalOut q_led_blu_rea (PTA2); //Led Blue Rear 00129 00130 //SAIDAS DIGITAIS (pwm) 00131 PwmOut pwm_mot_rig (PTE20); //PWM Enable Motor Right 00132 PwmOut pwm_mot_lef (PTE31); //PWM Enable Motor Left 00133 PwmOut pwm_buzzer (PTE21); //Buzzer PWM 00134 PwmOut pwm_led_whi (PTE29); //Led white pwm 00135 00136 // ******************************************************************** 00137 //SAIDAS ANALOGICAS 00138 AnalogOut dac_comp_mic (PTE30); //Dac_Comparator MIC 00139 00140 00141 00142 00143 /** 00144 * Selects the wich infrared to comunicate. 00145 * 00146 * @param ch - Infrared to read (1..5) 00147 */ 00148 void tca9548_select_ch(char ch) 00149 { 00150 char ch_f[1]; 00151 char addr=0xE0; 00152 00153 if(ch==0) 00154 ch_f[0]=1; 00155 00156 if(ch>=1) 00157 ch_f[0]=1<<ch; 00158 00159 mutex_i2c0.lock(); 00160 i2c.write(addr,ch_f,1); 00161 mutex_i2c0.unlock(); 00162 } 00163 00164 00165 00166 00167 00168 /* Powers up all the VCNL4020. */ 00169 void init_Infrared() 00170 { 00171 00172 for (int i=0; i<6;i++) 00173 { 00174 tca9548_select_ch(i); 00175 VCNL40x0_Device.SetCurrent (20); // Set current to 200mA 00176 } 00177 tca9548_select_ch(0); 00178 } 00179 00180 00181 /** 00182 * Get the distance from of the chosen infrared. 00183 * 00184 * @param ch - Infrared to read (0,1..5) 00185 * 00186 * Note: for the values of ch it reads (0-right, ... ,4-left, 5-back) 00187 */ 00188 float read_Infrared(char ch) // 0-direita 4-esquerda 5-tras 00189 { 00190 tca9548_select_ch(ch); 00191 VCNL40x0_Device.ReadProxiOnDemand (&ProxiValue); // read prox value on demand 00192 float aux =floor(pow((float)ProxiValue/15104.0,-0.57)*10.0)/10.0 ; 00193 return aux; 00194 //return ProxiValue; 00195 } 00196 00197 /////////////////////////////////////////////////////////////////////////////////////////////// 00198 /////////////////////////////////// MOTOR /////////////////////////////////////////// 00199 /////////////////////////////////////////////////////////////////////////////////////////////// 00200 00201 // Calculo do Duty tem de ser revisto, o motor aguenta 6 V e o max definido aqui ronda os 4.2 V 00202 // consultar pag 39 e 95 00203 00204 /** 00205 * Sets speed and direction of the left motor. 00206 * 00207 * @param Dir - Direction of movement, 0 for back, or 1 for fron 00208 * @param Speed - Percentage of speed of the motor (1..100) 00209 * 00210 * Note: Because of differences in the motors they need to be calibrated, test the robot going front and back 00211 * at different speeds and see if it makes a straigth line 00212 */ 00213 void leftMotor(short int Dir,short int Speed) 00214 { 00215 float Duty; 00216 00217 if(Dir==1) { 00218 q_pha_mot_lef=0; //Andar em frente 00219 if(Speed>1000) //limite de segurança 00220 Speed=1000; 00221 if(Speed>0) { 00222 Duty=Speed*.082 +35; // 35 = minimo para o motor rodar 00223 q_sleep_mot_lef=1; //Nano Sleep Motor Left 00224 pwm_mot_lef.pulsewidth_us(Duty*5); 00225 } else { 00226 q_sleep_mot_lef=0; 00227 } 00228 } 00229 if(Dir==0) { 00230 q_pha_mot_lef=1; //Andar para tras 00231 00232 if(Speed>1000) //limite de segurança 00233 Speed=1000; 00234 if(Speed>0) { 00235 Duty=Speed*.082 +35; // 35 = minimo para o motor rodar 00236 q_sleep_mot_lef=1; //Nano Sleep Motor Left 00237 pwm_mot_lef.pulsewidth_us(Duty*5); 00238 } else { 00239 q_sleep_mot_lef=0; 00240 } 00241 } 00242 } 00243 00244 00245 /** 00246 * Sets speed and direction of the right motor. 00247 * 00248 * @param Dir - Direction of movement, 0 for back, or 1 for fron 00249 * @param Speed - Percentage of speed of the motor (1..100) 00250 * 00251 * Note: Because of differences in the motors they need to be calibrated, test the robot going front and back 00252 * at different speeds and see if it makes a straigth line 00253 */ 00254 void rightMotor(short int Dir,short int Speed) 00255 { 00256 float Duty; 00257 00258 if(Dir==1) { 00259 q_pha_mot_rig=0; //Andar em frente 00260 00261 if(Speed>1000) //limite de segurança 00262 Speed=1000; 00263 if(Speed>0) { 00264 Duty=Speed*.082 +35; // 35 = minimo para o motor rodar 00265 q_sleep_mot_rig=1; //Nano Sleep Motor Right 00266 pwm_mot_rig.pulsewidth_us(Duty*5); 00267 } else { 00268 q_sleep_mot_rig=0; 00269 } 00270 } 00271 if(Dir==0) { 00272 q_pha_mot_rig=1; //Andar para tras 00273 00274 00275 if(Speed>1000) //limite de segurança 00276 Speed=1000; 00277 if(Speed>0) { 00278 Duty=Speed*.082 +35; // 35 = minimo para o motor rodar 00279 q_sleep_mot_rig=1; //Nano Sleep Motor Right 00280 pwm_mot_rig.pulsewidth_us(Duty*5); 00281 } else { 00282 q_sleep_mot_rig=0; 00283 } 00284 } 00285 } 00286 00287 00288 /////////////////////////////////////////////////////////////////////////////////////////////// 00289 /////////////////////////////////// BATTERY /////////////////////////////////////////// 00290 /////////////////////////////////////////////////////////////////////////////////////////////// 00291 00292 /** 00293 * Reads adc of the battery. 00294 * 00295 * @param addr - Address to read 00296 * @return The voltage of the baterry 00297 */ 00298 long int read16_mcp3424(char addr) 00299 { 00300 char data[4]; 00301 mutex_i2c1.lock(); 00302 i2c1.read(addr,data,3); 00303 mutex_i2c1.unlock(); 00304 return(((data[0]&127)*256)+data[1]); 00305 } 00306 00307 /** 00308 * Reads adc of the battery. 00309 * 00310 * @param n_bits - Resolution of measure 00311 * @param ch - Chose value to read, if voltage or current of solar or batery 00312 * @param gain - 00313 * @param addr - Address to write to 00314 */ 00315 void write_mcp3424(int n_bits, int ch, int gain, char addr) //chanel 1-4 write -> 0xD0 00316 { 00317 00318 int chanel_end=(ch-1)<<5; //shift left 00319 char n_bits_end=0; 00320 00321 if(n_bits==12) { 00322 n_bits_end=0; 00323 } else if(n_bits==14) { 00324 n_bits_end=1; 00325 } else if(n_bits==16) { 00326 n_bits_end=2; 00327 } else { 00328 n_bits_end=3; 00329 } 00330 n_bits_end=n_bits_end<<2; //shift left 00331 00332 char data[1]; 00333 data[0]= (char)chanel_end | (char)n_bits_end | (char)(gain-1) | 128; 00334 mutex_i2c1.lock(); 00335 i2c1.write(addr,data,1); 00336 mutex_i2c1.unlock(); 00337 } 00338 00339 00340 /** 00341 * Reads adc of the battery. 00342 * 00343 * @return The voltage of the batery 00344 */ 00345 float value_of_Batery() 00346 { 00347 float R1=75000.0; 00348 float R2=39200.0; 00349 float R3=178000.0; 00350 float Gain=1.0; 00351 write_mcp3424(16,3,1,0xd8); 00352 float cha3_v2=read16_mcp3424(0xd9); //read voltage 00353 float Vin_v_battery=(((cha3_v2*2.048)/32767))/Gain; 00354 float Vin_b_v_battery=(-((-Vin_v_battery)*(R1*R2 + R1*R3 + R2*R3))/(R1*R2)); 00355 Vin_b_v_battery=(Vin_b_v_battery-0.0)*1.00268; 00356 00357 return Vin_b_v_battery; 00358 } 00359 00360 /////////////////////////////////////////////////////////////////////////////////////////////// 00361 ////////////////////////////////// Sonar //////////////////////////////////////////// 00362 /////////////////////////////////////////////////////////////////////////////////////////////// 00363 // Commands of operation with ultrasonic module 00364 00365 // WRITE OPTION: 00366 // ENABLE DC DC CONVERTER - 0x0C; 00367 // DISABLE DC DC CONVERTER - 0x0B; 00368 // START MEASURE LEFT SENSOR - 0x0A; 00369 // START MEASURE FRONT SENSOR - 0x09; 00370 // START MEASURE RIGHT SENSOR - 0x08; 00371 // SENSORS ALWAYS MEASURE ON - 0x07; 00372 // SENSORS ALWAYS MEASURE OFF - 0x06; 00373 00374 // READ OPTION: 00375 // GET MEASURE OF LEFT SENSOR - 0x05; 00376 // GET MEASURE OF FRONT SENSOR - 0x04; 00377 // GET MEASURE OF IGHT SENSOR - 0x03; 00378 // GET STATUS SENSORS ALWAYS MEASURE - 0x02; 00379 // GET STATUS DC DC CONVERTER - 0x01; 00380 00381 void enable_dc_dc_boost() 00382 { 00383 char data[1]; 00384 data[0]= 0x0C; 00385 mutex_i2c1.lock(); 00386 i2c1.write(0x30,data,1); 00387 mutex_i2c1.unlock(); 00388 } 00389 00390 00391 void measure_always_on() // left, front, right 00392 { 00393 char data[1]; 00394 data[0]= 0x07; 00395 mutex_i2c1.lock(); 00396 i2c1.write(0x30,data,1); 00397 mutex_i2c1.unlock(); 00398 } 00399 00400 00401 /** 00402 * Returns left sensor value 00403 */ 00404 static unsigned int get_distance_left_sensor() 00405 { 00406 00407 static char data_r[3]; 00408 static unsigned int aux; 00409 00410 data_r[0]= 0x05; 00411 mutex_i2c1.lock(); 00412 i2c1.write(0x30,data_r,1); 00413 i2c1.read(0x31,data_r,2); 00414 mutex_i2c1.unlock(); 00415 00416 aux=(data_r[0]*256)+data_r[1]; 00417 00418 return aux; 00419 } 00420 00421 00422 /** 00423 * Returns front sensor value 00424 */ 00425 static unsigned int get_distance_front_sensor() 00426 { 00427 00428 static char data_r[3]; 00429 static unsigned int aux; 00430 00431 data_r[0]= 0x04; 00432 00433 mutex_i2c1.lock(); 00434 i2c1.write(0x30,data_r,1); 00435 i2c1.read(0x31,data_r,2); 00436 mutex_i2c1.unlock(); 00437 00438 aux=(data_r[0]*256)+data_r[1]; 00439 00440 return aux; 00441 00442 } 00443 00444 00445 /** 00446 * Returns right sensor value 00447 */ 00448 static unsigned int get_distance_right_sensor() 00449 { 00450 00451 static char data_r[3]; 00452 static unsigned int aux; 00453 00454 data_r[0]= 0x03; 00455 00456 mutex_i2c1.lock(); 00457 i2c1.write(0x30,data_r,1); 00458 i2c1.read(0x31,data_r,2,0); 00459 mutex_i2c1.unlock(); 00460 00461 aux=(data_r[0]*256)+data_r[1]; 00462 00463 return aux; 00464 00465 } 00466 00467 00468 00469 /////////////////////////////////////////////////////////////////////////////////////////////// 00470 ////////////////////////////////// MISC. //////////////////////////////////////////// 00471 /////////////////////////////////////////////////////////////////////////////////////////////// 00472 00473 00474 /** 00475 * Initializes the necessary robot pins 00476 */ 00477 void init_robot_pins() 00478 { 00479 00480 //SAIDAS DIGITAIS (normal) 00481 //q_pha_mot_rig=0; //Phase Motor Right 00482 //q_sleep_mot_rig=0; //Nano Sleep Motor Right 00483 //q_pha_mot_lef=0; //Phase Motor Left 00484 //q_sleep_mot_lef=0; //Nano Sleep Motor Left 00485 //q_pow_ena_i2c_p=0; //Power Enable i2c FET P 00486 //q_pow_ena_mic_p=0; //Power enable Micro FET P 00487 //q_pow_as5600_n=1; //AS5600 Power MOSFET N 00488 //q_pow_as5600_p=0; //AS5600 Power MOSFET P 00489 //q_pow_spi=0; //SPI Power MOSFET P 00490 //q_ena_mppt=0; //Enable MPPT Control 00491 //q_boost_ps=1; //Boost Power Save 00492 //q_tca9548_reset=1; //Reset TCA9548 00493 00494 //SAIDAS DIGITAIS (normal) 00495 q_pha_mot_rig=0; //Phase Motor Right 00496 q_sleep_mot_rig=0; //Nano Sleep Motor Right 00497 q_pha_mot_lef=0; //Phase Motor Left 00498 q_sleep_mot_lef=0; //Nano Sleep Motor Left 00499 00500 q_pow_ena_i2c_p=0; //Power Enable i2c FET P 00501 q_pow_ena_mic_p=0; //Power enable Micro FET P 00502 q_pow_as5600_p=0; //AS5600 Power MOSFET P 00503 // q_pow_spi=0; //SPI Power MOSFET P 00504 q_pow_as5600_n=1; //AS5600 Power MOSFET N 00505 00506 00507 q_ena_mppt=0; //Enable MPPT Control 00508 q_boost_ps=1; //Boost Power Save 00509 q_tca9548_reset=1; //Reset TCA9548 00510 00511 //Leds caso seja saida digital: 00512 q_led_red_fro=1; //Led Red Front (led off) 00513 q_led_gre_fro=1; //Led Green Front (led off) 00514 q_led_blu_fro=1; //Led Blue Front (led off) 00515 q_led_red_rea=1; //Led Red Rear (led off) 00516 q_led_gre_rea=1; //Led Green Rear (led off) 00517 q_led_blu_rea=1; //Led Blue Rear (led off)r 00518 00519 00520 //******************************************************************** 00521 //SAIDAS DIGITAIS (pwm) 00522 //PWM Enable Motor Right 00523 pwm_mot_rig.period_us(500); 00524 pwm_mot_rig.pulsewidth_us(0); 00525 00526 //PWM Enable Motor Left 00527 pwm_mot_lef.period_us(500); 00528 pwm_mot_lef.pulsewidth_us(0); 00529 00530 //Buzzer PWM 00531 pwm_buzzer.period_us(500); 00532 pwm_buzzer.pulsewidth_us(0); 00533 00534 00535 //LED white 00536 pwm_led_whi.period_us(500); 00537 pwm_led_whi.pulsewidth_us(0); 00538 00539 } 00540 00541 /** 00542 * Initializes all the pins and all the modules necessary 00543 * 00544 * @param channel - Which RF channel to comunicate on, 0-125. 00545 *\note If you are not using RF module put random number. 00546 * \warning Channel on Robot and Board has to be the same. 00547 */ 00548 void initRobot(int channel) 00549 { 00550 pc.printf("Battery level: \n\r"); 00551 init_nRF(channel); 00552 init_robot_pins(); 00553 00554 enable_dc_dc_boost(); 00555 wait_ms(100); //wait for read wait(>=150ms); 00556 enable_dc_dc_boost(); 00557 measure_always_on(); 00558 wait_ms(100); //wait for read wait(>=150ms); 00559 00560 init_Infrared(); 00561 00562 init_rangefinder(&i2c1, &mutex_i2c1); 00563 00564 00565 thread.start(odometry_thread); 00566 00567 float value = value_of_Batery(); 00568 00569 pc.printf("Initialization Successful \n\r"); 00570 pc.printf("Battery level: %f \n\r",value); 00571 if(value < 3.0) { 00572 pc.printf(" WARNING: BATTERY NEEDS CHARGING "); 00573 } 00574 // float level = value_of_Batery(); 00575 // sendValue(int(level*100)); 00576 00577 }
Generated on Fri Jul 15 2022 01:53:00 by
1.7.2
