ouais ok

Dependents:   roboticLab_withclass_3_July

Fork of ISR_Mini-explorer by ISR UC

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers robot.h Source File

robot.h

Go to the documentation of this file.
00001 /** @file */
00002 //AUTOR: Fernando Pais
00003 //MAIL:  ferpais2508@gmail.com
00004 //DATA: 6/6/2016
00005 // VERSÃO 6.4.0
00006 //
00007 //Alterações: Problema de compatibilidade entre encoder e infravermelho resolvido
00008 //            Odometria actualizada automaticamente
00009 //            Valor da bateria verificado na inicialização
00010 //            Motores movem-se de 0 a 1000 para melhor difrenciação
00011 //
00012 
00013 //#include "mbed.h"
00014 //#include "init.h"
00015 //#define _USE_MATH_DEFINES
00016 # define M_PI           3.14159265358979323846  /* pi */
00017 #include <math.h>
00018 #include <string.h>
00019 #include "VCNL40x0.h"
00020 #include "nRF24L01P.h "
00021 
00022 void Odometria();
00023 void OdometriaKalman(float* R_cm, float* L_cm);
00024 
00025 // classes adicionais
00026 nRF24L01P my_nrf24l01p(PTD2, PTD3, PTD1, PTC13, PTC12, PTA13);
00027 VCNL40x0 VCNL40x0_Device (PTC9, PTC8, VCNL40x0_ADDRESS);
00028 Timeout timeout;
00029 
00030 Serial pc(PTE0,PTE1);
00031 I2C i2c(PTC9,PTC8);
00032 I2C i2c1(PTC11,PTC10);
00033 
00034 // Variables needed by the lib
00035 unsigned int  ProxiValue=0;
00036 short int prev_R=0;
00037 short int prev_L=0;
00038 long int total_R=0;
00039 long int total_L=0;
00040 long int ticks2d=0;
00041 long int ticks2e=0;
00042 float X=20;
00043 float Y=20;
00044 float AtractX = 0;
00045 float AtractY = 0;
00046 float theta=0;
00047 int sensor_left=0;
00048 int sensor_front=0;
00049 int sensor_right=0;
00050 short int flag=0;
00051 int IRobot=0;
00052 int JRobot=0;
00053 
00054 //SAIDAS DIGITAIS (normal)
00055 DigitalOut  q_pha_mot_rig       (PTE4,0);     //Phase Motor Right
00056 DigitalOut  q_sleep_mot_rig     (PTE3,0);     //Nano Sleep Motor Right
00057 DigitalOut  q_pha_mot_lef       (PTA17,0);    //Phase Motor Left
00058 DigitalOut  q_sleep_mot_lef     (PTB11,0);    //Nano Sleep Motor Left
00059 DigitalOut  q_pow_ena_i2c_p     (PTE2,0);     //Power Enable i2c FET P (0- enable 1-disable)
00060 DigitalOut  q_pow_ena_mic_p     (PTA14,0);    //Power enable Micro FET P (0- enable 1-disable)
00061 DigitalOut  q_pow_as5600_n      (PTC6,1);     //AS5600 Power MOSFET N (1- enable 0-disable)
00062 DigitalOut  q_pow_as5600_p      (PTC5,0);     //AS5600 Power MOSFET P (0- enable 1-disable)
00063 DigitalOut  q_pow_spi           (PTC4,0);     //SPI Power MOSFET P (0- enable 1-disable)
00064 DigitalOut  q_ena_mppt          (PTC0,0);     //Enable MPPT Control (0- enable 1-disable)
00065 DigitalOut  q_boost_ps          (PTC7,1);     //Boost Power Save (1- enable 0-disable)
00066 DigitalOut  q_tca9548_reset     (PTC3,1);     //Reset TCA9548 (1- enable 0-disable)
00067 DigitalOut  power_36khz         (PTD0,0);     //Power enable pic12f - 36khz (0- enable 1-disable)
00068 
00069 
00070 // ********************************************************************
00071 // ********************************************************************
00072 //DEFINIÇÃO DE ENTRADAS E SAIDAS DO ROBOT
00073 //ENTRADAS DIGITAIS (normal input)
00074 DigitalIn   i_enc_dir_rig       (PTB8);     //Encoder Right Direction
00075 DigitalIn   i_enc_dir_lef       (PTB9);     //Encoder Left Direction
00076 DigitalIn   i_micro_sd_det      (PTC16);    //MICRO SD Card Detect
00077 DigitalIn   i_mppt_fail         (PTE5);     //Fail MPPT Signal
00078 DigitalIn   i_usb_volt          (PTB10);    //USB Voltage detect
00079 DigitalIn   i_sup_cap_est       (PTB19);    //Supercap State Charger
00080 DigitalIn   i_li_ion_est        (PTB18);    //Li-ion State Charger
00081 
00082 
00083 // ********************************************************************
00084 //ENTRADAS DIGITAIS (external interrupt)
00085 InterruptIn i_int_mpu9250       (PTA15);    //Interrupt MPU9250
00086 InterruptIn i_int_isl29125      (PTA16);    //Interrupt ISL29125 Color S.
00087 InterruptIn i_mic_f_l           (PTD7);     //Interrupt Comp Micro F L
00088 InterruptIn i_mic_f_r           (PTD6);     //Interrupt Comp Micro F R
00089 InterruptIn i_mic_r_c           (PTD5);     //Interrupt Comp Micro R C
00090 
00091 
00092 // ********************************************************************
00093 //ENTRADAS ANALOGICAS
00094 AnalogIn    a_enc_rig           (PTC2);     //Encoder Left Output_AS_MR
00095 AnalogIn    a_enc_lef           (PTC1);     //Encoder Right Output_AS_ML
00096 AnalogIn    a_mic_f_l           (PTB0);     //Analog microphone F L
00097 AnalogIn    a_mic_f_r           (PTB1);     //Analog microphone F R
00098 AnalogIn    a_mic_r_c           (PTB2);     //Analog microphone R C
00099 AnalogIn    a_temp_bat          (PTB3);     //Temperature Battery
00100 
00101 
00102 // ********************************************************************
00103 
00104 //PWM OR DIGITAL OUTPUT NORMAL
00105 //DigitalOut    q_led_whi         (PTE29);    //Led white pwm
00106 DigitalOut    q_led_red_fro     (PTA4);     //Led Red Front
00107 DigitalOut    q_led_gre_fro     (PTA5);     //Led Green Front
00108 DigitalOut    q_led_blu_fro     (PTA12);    //Led Blue Front
00109 DigitalOut    q_led_red_rea     (PTD4);     //Led Red Rear
00110 DigitalOut    q_led_gre_rea     (PTA1);     //Led Green Rear
00111 DigitalOut    q_led_blu_rea     (PTA2);     //Led Blue Rear
00112 
00113 
00114 //SAIDAS DIGITAIS (pwm)
00115 PwmOut      pwm_mot_rig         (PTE20);    //PWM Enable Motor Right
00116 PwmOut      pwm_mot_lef         (PTE31);    //PWM Enable Motor Left
00117 PwmOut      pwm_buzzer          (PTE21);    //Buzzer PWM
00118 PwmOut      pwm_led_whi         (PTE29);    //Led white pwm
00119 
00120 // ********************************************************************
00121 //SAIDAS ANALOGICAS
00122 AnalogOut   dac_comp_mic        (PTE30);        //Dac_Comparator MIC
00123 
00124 
00125 /* Powers up all the VCNL4020. */
00126 void init_Infrared()
00127 {
00128     VCNL40x0_Device.SetCurrent (20);     // Set current to 200mA
00129 }
00130 
00131 /**
00132  * Selects the wich infrared to comunicate.
00133  *
00134  * @param ch - Infrared to read (1..5)
00135  */
00136 void tca9548_select_ch(char ch)
00137 {
00138     char ch_f[1];
00139     char addr=0xE0;
00140 
00141     if(ch==0)
00142         ch_f[0]=1;
00143 
00144     if(ch>=1)
00145         ch_f[0]=1<<ch;
00146 
00147     i2c.start();
00148     i2c.write(addr,ch_f,1);
00149     i2c.stop();
00150 }
00151 
00152 
00153 /**
00154  * Get ADC value of the chosen infrared.
00155  *
00156  * @param ch - Infrared to read (1..5)
00157  *
00158  * Note: for the values of ch it reads (0-right, ... ,4-left, 5-back)
00159  */
00160 long int read_Infrared(char ch) // 0-direita 4-esquerda 5-tras
00161 {
00162     tca9548_select_ch(ch);
00163     VCNL40x0_Device.ReadProxiOnDemand (&ProxiValue);    // read prox value on demand
00164 
00165     return ProxiValue;
00166 }
00167 
00168 ///////////////////////////////////////////////////////////////////////////////////////////////
00169 ///////////////////////////////////     MOTOR       ///////////////////////////////////////////
00170 ///////////////////////////////////////////////////////////////////////////////////////////////
00171 
00172 // Calculo do Duty tem de ser revisto, o motor aguenta 6 V e o max definido aqui ronda os 4.2 V
00173 // consultar pag 39 e 95
00174 
00175 /**
00176  * Sets speed and direction of the left motor.
00177  *
00178  * @param Dir - Direction of movement, 0 for back, or 1 for fron
00179  * @param Speed - Percentage of speed of the motor (1..100)
00180  *
00181  * Note: Because of differences in the motors they need to be calibrated, test the robot going front and back
00182  *  at different speeds and see if it makes a straigth line
00183  */
00184 void leftMotor(short int Dir,short int Speed)
00185 {
00186     float Duty;
00187 
00188     if(Dir==1) {
00189         q_pha_mot_lef=0;            //Andar em frente
00190         if(Speed>1000)                   //limite de segurança
00191             Speed=1000;
00192         if(Speed>0) {
00193             Duty=Speed*.082 +35;         // 35 = minimo para o motor rodar
00194             q_sleep_mot_lef=1;          //Nano Sleep Motor Left
00195             pwm_mot_lef.pulsewidth_us(Duty*5);
00196         } else {
00197             q_sleep_mot_lef=0;
00198         }
00199     }
00200     if(Dir==0) {
00201         q_pha_mot_lef=1;            //Andar para tras
00202 
00203         if(Speed>1000)                   //limite de segurança
00204             Speed=1000;
00205         if(Speed>0) {
00206             Duty=Speed*.082 +35;         // 35 = minimo para o motor rodar
00207             q_sleep_mot_lef=1;          //Nano Sleep Motor Left
00208             pwm_mot_lef.pulsewidth_us(Duty*5);
00209         } else {
00210             q_sleep_mot_lef=0;
00211         }
00212     }
00213 }
00214 
00215 
00216 /**
00217  * Sets speed and direction of the right motor.
00218  *
00219  * @param Dir - Direction of movement, 0 for back, or 1 for fron
00220  * @param Speed - Percentage of speed of the motor (1..100)
00221  *
00222  * Note: Because of differences in the motors they need to be calibrated, test the robot going front and back
00223  *  at different speeds and see if it makes a straigth line
00224  */
00225 void rightMotor(short int Dir,short int Speed)
00226 {
00227     float Duty;
00228 
00229     if(Dir==1) {
00230         q_pha_mot_rig=0;            //Andar em frente
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_rig=1;          //Nano Sleep Motor Right
00237             pwm_mot_rig.pulsewidth_us(Duty*5);
00238         } else {
00239             q_sleep_mot_rig=0;
00240         }
00241     }
00242     if(Dir==0) {
00243         q_pha_mot_rig=1;            //Andar para tras
00244 
00245 
00246         if(Speed>1000)                   //limite de segurança
00247             Speed=1000;
00248         if(Speed>0) {
00249             Duty=Speed*.082 +35;         // 35 = minimo para o motor rodar
00250             q_sleep_mot_rig=1;          //Nano Sleep Motor Right
00251             pwm_mot_rig.pulsewidth_us(Duty*5);
00252         } else {
00253             q_sleep_mot_rig=0;
00254         }
00255     }
00256 }
00257 
00258 
00259 ///////////////////////////////////////////////////////////////////////////////////////////////
00260 ///////////////////////////////////     ENCODER     ///////////////////////////////////////////
00261 ///////////////////////////////////////////////////////////////////////////////////////////////
00262 
00263 /**
00264  * Reads Position of left magnetic encoder.
00265  *
00266  * @return The absolute position of the left wheel encoder (0..4095)
00267  */
00268 long int read_L_encoder()
00269 {
00270 
00271     char data_r_2[5];
00272 
00273     i2c.start();
00274     i2c.write(0x6C);
00275     i2c.write(0x0C);
00276     i2c.read(0x6D,data_r_2,4,0);
00277     i2c.stop();
00278 
00279     short int val1=data_r_2[0];
00280     short int val2=data_r_2[1];
00281     val1=(val1&0xf)*256;
00282     long int final=(val2+val1);
00283 
00284     return  final;
00285 }
00286 
00287 
00288 /**
00289  * Reads Position of right magnetic encoder.
00290  *
00291  * @return The absolute position of the right wheel encoder (0..4095)
00292  */
00293 long int read_R_encoder()
00294 {
00295 
00296     char data_r_2[5];
00297 
00298     i2c1.start();
00299     i2c1.write(0x6C);
00300     i2c1.write(0x0C);
00301     i2c1.read(0x6D,data_r_2,4,0);
00302     i2c1.stop();
00303 
00304     short int val1=data_r_2[0];
00305     short int val2=data_r_2[1];
00306     val1=(val1&0xf)*256;
00307     long int final=(val2+val1);
00308 
00309     return  final;
00310 }
00311 
00312 
00313 /**
00314  * Calculates and returns the value of the  right "incremental" encoder.
00315  *
00316  * @return The value of "tics" of the right encoder since it was initialized
00317  */
00318 long int incremental_R_encoder()
00319 {
00320     short int next_R=read_R_encoder(); // Reads curent value of the encoder
00321     short int dif=next_R-prev_R;       // Calculates the diference from last reading
00322 
00323     if(dif>3000) {                     // Going back and pass zero
00324         total_R=total_R-4096+dif;
00325     }
00326     if(dif<3000&&dif>0) {              // Going front
00327         total_R=total_R+dif;
00328     }
00329     if(dif<-3000) {                    // Going front and pass zero
00330         total_R=total_R+4096+dif;
00331     }
00332     if(dif>-3000&&dif<0) {             // going back
00333         total_R=total_R+dif;
00334     }
00335     prev_R=next_R;                     // Sets last reading for next iteration
00336 
00337     return  total_R;
00338 }
00339 
00340 
00341 /**
00342  * Calculates and returns the value of the  left "incremental" encoder.
00343  *
00344  * @return The value of "tics" of the left encoder since it was initialized
00345  */
00346 long int incremental_L_encoder()
00347 {
00348     short int next_L=read_L_encoder(); // Reads curent value of the encoder
00349     short int dif=-next_L+prev_L;      // Calculates the diference from last reading
00350 
00351     if(dif>3000) {                     // Going back and pass zero
00352         total_L=total_L-4096+dif;
00353     }
00354     if(dif<3000&&dif>0) {              // Going front
00355         total_L=total_L+dif;
00356     }
00357     if(dif<-3000) {                    // Going front and pass zero
00358         total_L=total_L+4096+dif;
00359     }
00360     if(dif>-3000&&dif<0) {             // going back
00361         total_L=total_L+dif;
00362     }
00363     prev_L=next_L;                     // Sets last reading for next iteration
00364 
00365     return  total_L;
00366 }
00367 
00368 
00369 /**
00370  * Calculate the value of both encoder "incremental" every 10 ms.
00371  */
00372 void timer_event()  //10ms interrupt
00373 {
00374     timeout.attach(&timer_event,0.01);
00375     if(flag==0) {
00376         incremental_R_encoder();
00377         incremental_L_encoder();
00378     }
00379     Odometria();
00380 
00381     return;
00382 }
00383 
00384 
00385 /**
00386  * Set the initial position for the "incremental" enconder and "starts" them.
00387  */
00388 void initEncoders()
00389 {
00390     prev_R=read_R_encoder();
00391     prev_L=read_L_encoder();
00392     timeout.attach(&timer_event,0.01);
00393 }
00394 
00395 
00396 /**
00397  * Returns to the user the value of the right "incremental" encoder.
00398  *
00399  * @return The value of "tics" of the right encoder since it was initialized
00400  */
00401 long int R_encoder()
00402 {
00403     wait(0.0001);
00404 
00405     return total_R;
00406 }
00407 
00408 /**
00409  * Returns to the user the value of the right "incremental" encoder.
00410  *
00411  * @return The value of "tics" of the right encoder since it was initialized
00412  */
00413 long int L_encoder()
00414 {
00415     wait(0.0001);
00416 
00417     return total_L;
00418 }
00419 
00420 
00421 ///////////////////////////////////////////////////////////////////////////////////////////////
00422 ///////////////////////////////////     BATTERY     ///////////////////////////////////////////
00423 ///////////////////////////////////////////////////////////////////////////////////////////////
00424 
00425 /**
00426  * Reads adc of the battery.
00427  *
00428  * @param addr - Address to read
00429  * @return The voltage of the batery
00430  */
00431 long int read16_mcp3424(char addr)
00432 {
00433     char data[4];
00434     i2c1.start();
00435     i2c1.read(addr,data,3);
00436     i2c1.stop();
00437 
00438     return(((data[0]&127)*256)+data[1]);
00439 }
00440 
00441 /**
00442  * Reads adc of the battery.
00443  *
00444  * @param n_bits - Resolution of measure
00445  * @param ch - Chose value to read, if voltage or current of solar or batery
00446  * @param gain -
00447  * @param addr - Address to write to
00448  */
00449 void write_mcp3424(int n_bits, int  ch, int gain, char  addr)  //chanel 1-4    write -> 0xD0
00450 {
00451 
00452     int chanel_end=(ch-1)<<5; //shift left
00453     char n_bits_end=0;
00454 
00455     if(n_bits==12) {
00456         n_bits_end=0;
00457     } else if(n_bits==14) {
00458         n_bits_end=1;
00459     } else if(n_bits==16) {
00460         n_bits_end=2;
00461     } else {
00462         n_bits_end=3;
00463     }
00464     n_bits_end=n_bits_end<<2; //shift left
00465 
00466     char data[1];
00467     data[0]= (char)chanel_end | (char)n_bits_end | (char)(gain-1) | 128;
00468     i2c1.start();
00469     i2c1.write(addr,data,1);
00470     i2c1.stop();
00471 }
00472 
00473 
00474 /**
00475  * Reads adc of the battery.
00476  *
00477  * @return The voltage of the batery
00478  */
00479 float value_of_Batery()
00480 {
00481     float   R1=75000.0;
00482     float   R2=39200.0;
00483     float   R3=178000.0;
00484     float   Gain=1.0;
00485     write_mcp3424(16,3,1,0xd8);
00486     float cha3_v2=read16_mcp3424(0xd9); //read  voltage
00487     float Vin_v_battery=(((cha3_v2*2.048)/32767))/Gain;
00488     float Vin_b_v_battery=(-((-Vin_v_battery)*(R1*R2 + R1*R3 + R2*R3))/(R1*R2));
00489     Vin_b_v_battery=(Vin_b_v_battery-0.0)*1.00268;
00490 
00491     return Vin_b_v_battery;
00492 }
00493 
00494 ///////////////////////////////////////////////////////////////////////////////////////////////
00495 ///////////////////////////////     RF COMUNICATION     ///////////////////////////////////////
00496 ///////////////////////////////////////////////////////////////////////////////////////////////
00497 
00498 
00499 /**
00500  * Initializes the NRF24 module for comunication.
00501  *
00502  * Note: if the module is broken or badly connected this init will cause the code to stop,
00503  *  if all these messages don't appear thats the case
00504  */
00505 void config_init_nrf()
00506 {
00507     my_nrf24l01p.powerUp(); // powers module
00508     my_nrf24l01p.setRfFrequency (2400); // channel 0 (2400-0 ... 2516-116)
00509     my_nrf24l01p.setTransferSize(10);   // number of bytes to be transfer
00510     my_nrf24l01p.setCrcWidth(8);
00511     my_nrf24l01p.enableAutoAcknowledge(NRF24L01P_PIPE_P0); // pipe where data transfer occurs (0..6)
00512     pc.printf( "nRF24L01+ Frequency    : %d MHz\r\n",  my_nrf24l01p.getRfFrequency() );
00513     pc.printf( "nRF24L01+ Data Rate    : %d kbps\r\n", my_nrf24l01p.getAirDataRate() );
00514     pc.printf( "nRF24L01+ TX Address   : 0x%010llX\r\n", my_nrf24l01p.getTxAddress() );
00515     pc.printf( "nRF24L01+ RX Address   : 0x%010llX\r\n", my_nrf24l01p.getRxAddress() );
00516     pc.printf( "nRF24L01+ CrC Width    : %d CrC\r\n", my_nrf24l01p.getCrcWidth() );
00517     pc.printf( "nRF24L01+ TransferSize : %d Paket Size\r\n", my_nrf24l01p.getTransferSize () );
00518     my_nrf24l01p.setReceiveMode();
00519     my_nrf24l01p.enable();
00520     pc.printf( "Setup complete, Starting While loop\r\n");
00521 }
00522 
00523 
00524 /**
00525  * Receives a number from the Arduino.
00526  *
00527  * @return The value send by the arduino
00528  */
00529 double receiveValue(void)
00530 {
00531     char temp[4];
00532     double Val;
00533     bool ok=0;
00534     my_nrf24l01p.setTransferSize(4);
00535     my_nrf24l01p.setReceiveMode();
00536     my_nrf24l01p.enable();
00537     do {
00538         if(my_nrf24l01p.readable(NRF24L01P_PIPE_P0)) {
00539             ok = my_nrf24l01p.read( NRF24L01P_PIPE_P0,temp, 4);
00540         }
00541     } while(ok==0);
00542 
00543     //transformation of temp to convert to original value
00544     if(temp[0]==0) // if first elemente is 0 then its negative
00545         Val = double(-(int(temp[1])+int(temp[2])*255+int(temp[3])*255*255));
00546     else // else its positive
00547         Val = double(int(temp[1])+int(temp[2])*255+int(temp[3])*255*255);
00548 
00549     return Val;
00550 }
00551 
00552 
00553 /**
00554  * Sends a number to the Arduino
00555  *
00556  * @param Value - number to be sent to the Arduino
00557  */
00558 void sendValue(long int Value)
00559 {
00560     bool ok=0;  // comunication sucess, o if failed 1 if sucessfull
00561     // double math=Value/65025; // temporary variable save results
00562     int zero=1;  // 1 byte, ( - ) if 0 ( + ) if 1
00563     int one=0;   // 2 byte (0..255), multiplied by 1
00564     int two=0;   // 3 byte (0..255), multiplied by 255
00565     int three=0; // 4 byte (0..255), multiplied by 255*255
00566 
00567 //transformation of Value to send correctly through pipe
00568     if (Value<0) {
00569         zero=0;
00570         Value=abs(Value);
00571     }
00572     //  Value=abs(Value);
00573 
00574     double math=Value/65025; // temporary variable save results
00575 
00576     if(math<1) {
00577         math=Value/255;
00578         if(math<1) {
00579             two=0;
00580             one=Value;
00581         } else {
00582             two=(int)math;
00583             one=Value % 255;
00584         }
00585     } else {
00586         three=(int)math;
00587         math=Value/255;
00588         if(math<1) {
00589             two=0;
00590             one=Value;
00591         } else {
00592             two=(int)math;
00593             one=Value % 255;
00594         }
00595     }
00596     char temp[4]= {(int)zero,(int)one,(int)two,(int)three};
00597 
00598     // Apagar depois de testar mais vezes
00599     // pc.printf("1 inidice...%i...\r", temp[0]);
00600     // pc.printf("2 inidice...%i...\r", temp[1]);
00601     // pc.printf("3 inidice...%i...\r", temp[2]);
00602     // pc.printf("4 inidice...%i...\r", temp[3]);
00603 
00604     my_nrf24l01p.setTransferSize(4);
00605     my_nrf24l01p.setTransmitMode();
00606     my_nrf24l01p.enable();
00607     do {
00608         ok = my_nrf24l01p.write( NRF24L01P_PIPE_P0,temp, 4);
00609         if(ok==1)
00610             pc.printf("Done.....%i...\r", Value);
00611         else {
00612             pc.printf("Failed\r");
00613             wait(1);
00614         }
00615     } while(ok==0);
00616 }
00617 
00618 /**
00619  *  Sends matrix to arduino.
00620  *
00621  * @param matrix - Matrix of numbers to send [0..255]
00622  * @param row - Number of rows
00623  * @param column - Number of columns
00624  */
00625 void sendMatrix(int (*matrix)[18],int row , int column)
00626 {
00627     short ok=0;
00628     short int i =0;
00629     short int j=0;
00630     short int byte=0;
00631     int members=column*row;
00632     char message[32]= {0};
00633     pc.printf("J ...%d... \r",members);
00634 
00635     my_nrf24l01p.setTransferSize(32);
00636     my_nrf24l01p.setTransmitMode();
00637     my_nrf24l01p.enable();
00638 
00639     do {
00640         int* point = matrix[j];
00641 
00642         do {
00643             message[byte]= point[i];
00644             if (byte==31 || (i+1)*(j+1)==members) {
00645 
00646                 do {
00647                     ok = my_nrf24l01p.write( NRF24L01P_PIPE_P0,message, 32);
00648                     if(ok==0)
00649                         wait(1);
00650 
00651                 } while(ok==0);
00652 
00653                 byte=-1;
00654             }
00655 
00656             byte++;
00657             i++;
00658 
00659         } while(i<column);
00660 
00661         i=0;
00662         j++;
00663     } while(j<row);
00664 
00665 }
00666 
00667 ///////////////////////////////////////////////////////////////////////////////////////////////
00668 //////////////////////////////////      Sonar     ////////////////////////////////////////////
00669 ///////////////////////////////////////////////////////////////////////////////////////////////
00670 //      Commands of operation with ultrasonic module
00671 
00672 //    WRITE OPTION:
00673 //        ENABLE DC DC CONVERTER          - 0x0C;
00674 //        DISABLE DC DC CONVERTER         - 0x0B;
00675 //        START MEASURE LEFT SENSOR       - 0x0A;
00676 //        START MEASURE FRONT SENSOR      - 0x09;
00677 //        START MEASURE RIGHT SENSOR      - 0x08;
00678 //        SENSORS ALWAYS MEASURE ON       - 0x07;
00679 //        SENSORS ALWAYS MEASURE OFF      - 0x06;
00680 
00681 // READ OPTION:
00682 //        GET MEASURE OF LEFT SENSOR          - 0x05;
00683 //        GET MEASURE OF FRONT SENSOR         - 0x04;
00684 //        GET MEASURE OF IGHT SENSOR          - 0x03;
00685 //        GET STATUS SENSORS ALWAYS MEASURE   - 0x02;
00686 //        GET STATUS DC DC CONVERTER          - 0x01;
00687 
00688 void enable_dc_dc_boost()
00689 {
00690     char data[1];
00691     data[0]= 0x0C;
00692     wait_ms(1);
00693     i2c1.start();
00694     i2c1.write(0x30,data,1);
00695     i2c1.stop();
00696     i2c1.start();
00697     i2c1.write(0x30,data,1);
00698     i2c1.stop();
00699 }
00700 
00701 
00702 void disable_dc_dc_boost()
00703 {
00704     char data[1];
00705     data[0]= 0x0B;
00706     wait_ms(1);
00707     i2c1.start();
00708     i2c1.write(0x30,data,1);
00709     i2c1.stop();
00710 }
00711 
00712 
00713 void start_read_left_sensor()
00714 {
00715     char data[1];
00716     data[0]= 0x0A;
00717     wait_ms(1);
00718     i2c1.start();
00719     i2c1.write(0x30,data,1);
00720     i2c1.stop();
00721 }
00722 
00723 
00724 void start_read_front_sensor()
00725 {
00726     char data[1];
00727     data[0]= 0x09;
00728     wait_ms(1);
00729     i2c1.start();
00730     i2c1.write(0x30,data,1);
00731     i2c1.stop();
00732 }
00733 
00734 
00735 void start_read_right_sensor()
00736 {
00737     char data[1];
00738     data[0]= 0x08;
00739     wait_ms(1);
00740     i2c1.start();
00741     i2c1.write(0x30,data,1);
00742     i2c1.stop();
00743 }
00744 
00745 
00746 void measure_always_on()  // left, front, right
00747 {
00748     char data[1];
00749     data[0]= 0x07;
00750     wait_ms(1);
00751     i2c1.start();
00752     i2c1.write(0x30,data,1);
00753     i2c1.stop();
00754 }
00755 
00756 
00757 void measure_always_off()
00758 {
00759     char data[1];
00760     data[0]= 0x06;
00761     wait_ms(1);
00762     i2c1.start();
00763     i2c1.write(0x30,data,1);
00764     i2c1.stop();
00765 }
00766 
00767 /**
00768  * Returns left sensor value
00769  */
00770 static unsigned int get_distance_left_sensor()
00771 {
00772 
00773     static char data_r[3];
00774     static unsigned int aux;
00775     flag=1;
00776 
00777     data_r[0]= 0x05;
00778     wait_ms(1);
00779     i2c1.start();
00780     i2c1.write(0x30,data_r,1);
00781     i2c1.stop();
00782     wait_ms(10);
00783     i2c1.start();
00784     i2c1.read(0x31,data_r,2,0);
00785     i2c1.stop();
00786 
00787     aux=(data_r[0]*256)+data_r[1];
00788     flag=0;
00789     return aux;
00790     // sensor_left=aux;
00791     // pc.printf("\nDistance Left Sensor: %u mm",aux); //0 - 2500mm
00792 
00793 }
00794 
00795 
00796 /**
00797  * Returns front sensor value
00798  */
00799 static unsigned int get_distance_front_sensor()
00800 {
00801 
00802     static char data_r[3];
00803     static unsigned int aux;
00804     flag=1;
00805     data_r[0]= 0x04;
00806     wait_ms(1);
00807     i2c1.start();
00808     i2c1.write(0x30,data_r,1);
00809     i2c1.stop();
00810     wait_ms(10);
00811     i2c1.start();
00812     i2c1.read(0x31,data_r,2,0);
00813     i2c1.stop();
00814 
00815     aux=(data_r[0]*256)+data_r[1];
00816     flag=0;
00817     return aux;
00818     // sensor_front=aux;
00819     // pc.printf("\nDistance Front Sensor: %u mm",aux); //0 - 2500mm
00820 
00821 }
00822 
00823 
00824 /**
00825  * Returns right sensor value
00826  */
00827 static unsigned int get_distance_right_sensor()
00828 {
00829 
00830     static char data_r[3];
00831     static unsigned int aux;
00832     flag=1;
00833 
00834     data_r[0]= 0x03;
00835     wait_ms(1);
00836     i2c1.start();
00837     i2c1.write(0x30,data_r,1);
00838     i2c1.stop();
00839     wait_ms(10);
00840     i2c1.start();
00841     i2c1.read(0x31,data_r,2,0);
00842     i2c1.stop();
00843 
00844     aux=(data_r[0]*256)+data_r[1];
00845     flag=0;
00846     return aux;
00847     // sensor_right=aux;
00848     // pc.printf("\nDistance Right Sensor: %u \r",aux); //0 - 2500mm
00849 
00850 }
00851 
00852 
00853 void get_status_always_measure()
00854 {
00855 
00856     static char data_r[3];
00857     static unsigned int aux;
00858 
00859     data_r[0]= 0x02;
00860     wait_ms(1);
00861     i2c1.start();
00862     i2c1.write(0x30,data_r,1);
00863     i2c1.stop();
00864     wait_ms(10);
00865     i2c1.start();
00866     i2c1.read(0x31,data_r,2,0);
00867     i2c1.stop();
00868 
00869     aux=data_r[0];
00870     pc.printf("\nStatus of read always on/off: %u ",aux); //0 (off) - 1 (on)
00871 
00872 }
00873 
00874 
00875 void get_status_dcdc_converter()
00876 {
00877 
00878     static char data_r[3];
00879     static unsigned int aux;
00880 
00881     data_r[0]= 0x01;
00882     wait_ms(1);
00883     i2c1.start();
00884     i2c1.write(0x30,data_r,1);
00885     i2c1.stop();
00886     wait_ms(10);
00887     i2c1.start();
00888     i2c1.read(0x31,data_r,2,0);
00889     i2c1.stop();
00890 
00891     aux=data_r[0];
00892     pc.printf("\nStatus of DC/DC Converter: %u ",aux); //0 (off) - 1 (on)
00893 
00894 }
00895 
00896 
00897 ///////////////////////////////////////////////////////////////////////////////////////////////
00898 //////////////////////////////////      MISC.      ////////////////////////////////////////////
00899 ///////////////////////////////////////////////////////////////////////////////////////////////
00900 
00901 
00902 /**
00903  * Initializes the necessary robot pins
00904  */
00905 void init_robot_pins()
00906 {
00907 
00908     //SAIDAS DIGITAIS (normal)
00909     //q_pha_mot_rig=0;            //Phase Motor Right
00910     //q_sleep_mot_rig=0;          //Nano Sleep Motor Right
00911     //q_pha_mot_lef=0;            //Phase Motor Left
00912     //q_sleep_mot_lef=0;          //Nano Sleep Motor Left
00913     //q_pow_ena_i2c_p=0;          //Power Enable i2c FET P
00914     //q_pow_ena_mic_p=0;          //Power enable Micro FET P
00915     //q_pow_as5600_n=1;           //AS5600 Power MOSFET N
00916     //q_pow_as5600_p=0;           //AS5600 Power MOSFET P
00917     //q_pow_spi=0;                //SPI Power MOSFET P
00918     //q_ena_mppt=0;               //Enable MPPT Control
00919     //q_boost_ps=1;               //Boost Power Save
00920     //q_tca9548_reset=1;          //Reset TCA9548
00921 
00922     //SAIDAS DIGITAIS (normal)
00923     q_pha_mot_rig=0;            //Phase Motor Right
00924     q_sleep_mot_rig=0;          //Nano Sleep Motor Right
00925     q_pha_mot_lef=0;            //Phase Motor Left
00926     q_sleep_mot_lef=0;          //Nano Sleep Motor Left
00927 
00928     q_pow_ena_i2c_p=0;         //Power Enable i2c FET P
00929     q_pow_ena_mic_p=0;          //Power enable Micro FET P
00930     q_pow_as5600_p=0;           //AS5600 Power MOSFET P
00931     // q_pow_spi=0;                //SPI Power MOSFET P
00932     q_pow_as5600_n=1;           //AS5600 Power MOSFET N
00933 
00934 
00935     q_ena_mppt=0;               //Enable MPPT Control
00936     q_boost_ps=1;               //Boost Power Save
00937     q_tca9548_reset=1;          //Reset TCA9548
00938 
00939     //Leds caso seja saida digital:
00940     q_led_red_fro=1;          //Led Red Front (led off)
00941     q_led_gre_fro=1;          //Led Green Front (led off)
00942     q_led_blu_fro=1;          //Led Blue Front (led off)
00943     q_led_red_rea=1;          //Led Red Rear (led off)
00944     q_led_gre_rea=1;          //Led Green Rear (led off)
00945     q_led_blu_rea=1;          //Led Blue Rear (led off)r
00946 
00947 
00948 //********************************************************************
00949     //SAIDAS DIGITAIS (pwm)
00950     //PWM Enable Motor Right
00951     pwm_mot_rig.period_us(500);
00952     pwm_mot_rig.pulsewidth_us(0);
00953 
00954     //PWM Enable Motor Left
00955     pwm_mot_lef.period_us(500);
00956     pwm_mot_lef.pulsewidth_us(0);
00957 
00958     //Buzzer PWM
00959     pwm_buzzer.period_us(500);
00960     pwm_buzzer.pulsewidth_us(0);
00961 
00962     //LED white
00963     pwm_led_whi.period_us(500);
00964     pwm_led_whi.pulsewidth_us(0);
00965 
00966 }
00967 
00968 
00969 /**
00970  * Initializes all the pins and all the modules necessary
00971  */
00972 void initRobot(void)
00973 {
00974     init_robot_pins();
00975     enable_dc_dc_boost();
00976     init_Infrared();
00977     initEncoders();
00978     config_init_nrf();
00979     enable_dc_dc_boost();
00980     wait_ms(100); //wait for read wait(>=150ms);
00981     measure_always_on();
00982     float value = value_of_Batery();
00983     pc.printf("Initialization Successful \n\r");
00984     pc.printf("Battery level: %f \n\r",value);
00985     if(value < 3.0) {
00986         pc.printf(" WARNING: BATTERY NEEDS CHARGING ");
00987     }
00988 
00989     // float level = value_of_Batery();
00990     // sendValue(int(level*100));
00991 
00992 }
00993 
00994 
00995 ////////////////////////////////////////////////////
00996 
00997 /**
00998  * Updates the position and orientation of the robot based on the data from the encoders
00999  *
01000  * Note: Needs to be calibrated for each robot, in this case the radius of the whells is 3.55
01001  * and the distance between them is 7.4
01002  */
01003 void Odometria()
01004 {
01005     long int ticks1d=R_encoder();
01006     long int ticks1e=L_encoder();
01007     //pc.printf("\r\nticks1d:%f",ticks1d);
01008     //pc.printf("\r\nticks1e:%f",ticks1d);
01009     long int D_ticks=ticks1d - ticks2d;
01010     long int E_ticks=ticks1e - ticks2e;
01011     //pc.printf("\r\nD_ticks:%f",D_ticks);
01012     //pc.printf("\r\nE_ticks:%f",E_ticks);
01013     ticks2d=ticks1d;
01014     ticks2e=ticks1e;
01015 
01016     float D_cm= (float)D_ticks*((3.25*3.1415)/4096);
01017     float L_cm= (float)E_ticks*((3.25*3.1415)/4096);
01018     //pc.printf("\r\nD_cm:%f",D_cm);
01019     //pc.printf("\r\nL_cm:%f",L_cm);
01020     float CM=(D_cm + L_cm)/2;
01021 
01022     //pc.printf("\r\nCM:%f",CM);
01023     theta +=(D_cm - L_cm)/7.18;
01024     theta = atan2(sin(theta), cos(theta));
01025 
01026     // meter entre 0
01027     X += CM*cos(theta);
01028     Y += CM*sin(theta);
01029 
01030 }
01031 
01032 void OdometriaKalman(float* R_cm, float* L_cm)
01033 {
01034     long int ticks1d=R_encoder();
01035     long int ticks1e=L_encoder();
01036 
01037     long int D_ticks=ticks1d - ticks2d;
01038     long int E_ticks=ticks1e - ticks2e;
01039 
01040     ticks2d=ticks1d;
01041     ticks2e=ticks1e;
01042 
01043     float D_cm= (float)D_ticks*((3.25*3.1415)/4096);
01044     float E_cm= (float)E_ticks*((3.25*3.1415)/4096);
01045 
01046     float CM=(D_cm + E_cm)/2;
01047 
01048     theta +=(D_cm - E_cm)/7.18;
01049 
01050     theta = atan2(sin(theta), cos(theta));
01051 
01052     // meter entre 0
01053 
01054     X += CM*cos(theta);
01055     Y += CM*sin(theta);
01056 
01057     *R_cm= D_cm;
01058     *L_cm= E_cm;
01059 }