Energy harvesting mobile robot. Developed at Institute of Systems and Robotics — University of Coimbra.
Fork of ISR_Mini-explorer by
Diff: robot.h
- Revision:
- 0:15a30802e719
- Child:
- 1:8569ac717e68
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/robot.h Thu Feb 02 12:21:11 2017 +0000 @@ -0,0 +1,1027 @@ +/** @file */ +//AUTOR: Fernando Pais +//MAIL: ferpais2508@gmail.com +//DATA: 6/6/2016 +// VERSÃO 6.4.0 +// +//Alterações: Problema de compatibilidade entre encoder e infravermelho resolvido +// Odometria actualizada automaticamente +// Valor da bateria verificado na inicialização +// Motores movem-se de 0 a 1000 para melhor difrenciação +// + +//#include "mbed.h" +//#include "init.h" +//#define _USE_MATH_DEFINES +# define M_PI 3.14159265358979323846 /* pi */ +#include <math.h> +#include <string.h> +#include "VCNL40x0.h" +#include "nRF24L01P.h" + +void Odometria(); + +// classes adicionais +nRF24L01P my_nrf24l01p(PTD2, PTD3, PTD1, PTC13, PTC12, PTA13); +VCNL40x0 VCNL40x0_Device (PTC9, PTC8, VCNL40x0_ADDRESS); +Timeout timeout; + +Serial pc(PTE0,PTE1); +I2C i2c(PTC9,PTC8); +I2C i2c1(PTC11,PTC10); + +// Variables needed by the lib +unsigned int ProxiValue=0; +short int prev_R=0; +short int prev_L=0; +long int total_R=0; +long int total_L=0; +long int ticks2d=0; +long int ticks2e=0; +float X=20; +float Y=20; +float AtractX = 0; +float AtractY = 0; +float theta=0; +int sensor_left=0; +int sensor_front=0; +int sensor_right=0; +short int flag=0; +int IRobot=0; +int JRobot=0; + +//SAIDAS DIGITAIS (normal) +DigitalOut q_pha_mot_rig (PTE4,0); //Phase Motor Right +DigitalOut q_sleep_mot_rig (PTE3,0); //Nano Sleep Motor Right +DigitalOut q_pha_mot_lef (PTA17,0); //Phase Motor Left +DigitalOut q_sleep_mot_lef (PTB11,0); //Nano Sleep Motor Left +DigitalOut q_pow_ena_i2c_p (PTE2,0); //Power Enable i2c FET P (0- enable 1-disable) +DigitalOut q_pow_ena_mic_p (PTA14,0); //Power enable Micro FET P (0- enable 1-disable) +DigitalOut q_pow_as5600_n (PTC6,1); //AS5600 Power MOSFET N (1- enable 0-disable) +DigitalOut q_pow_as5600_p (PTC5,0); //AS5600 Power MOSFET P (0- enable 1-disable) +DigitalOut q_pow_spi (PTC4,0); //SPI Power MOSFET P (0- enable 1-disable) +DigitalOut q_ena_mppt (PTC0,0); //Enable MPPT Control (0- enable 1-disable) +DigitalOut q_boost_ps (PTC7,1); //Boost Power Save (1- enable 0-disable) +DigitalOut q_tca9548_reset (PTC3,1); //Reset TCA9548 (1- enable 0-disable) +DigitalOut power_36khz (PTD0,0); //Power enable pic12f - 36khz (0- enable 1-disable) + + +// ******************************************************************** +// ******************************************************************** +//DEFINIÇÃO DE ENTRADAS E SAIDAS DO ROBOT +//ENTRADAS DIGITAIS (normal input) +DigitalIn i_enc_dir_rig (PTB8); //Encoder Right Direction +DigitalIn i_enc_dir_lef (PTB9); //Encoder Left Direction +DigitalIn i_micro_sd_det (PTC16); //MICRO SD Card Detect +DigitalIn i_mppt_fail (PTE5); //Fail MPPT Signal +DigitalIn i_usb_volt (PTB10); //USB Voltage detect +DigitalIn i_sup_cap_est (PTB19); //Supercap State Charger +DigitalIn i_li_ion_est (PTB18); //Li-ion State Charger + + +// ******************************************************************** +//ENTRADAS DIGITAIS (external interrupt) +InterruptIn i_int_mpu9250 (PTA15); //Interrupt MPU9250 +InterruptIn i_int_isl29125 (PTA16); //Interrupt ISL29125 Color S. +InterruptIn i_mic_f_l (PTD7); //Interrupt Comp Micro F L +InterruptIn i_mic_f_r (PTD6); //Interrupt Comp Micro F R +InterruptIn i_mic_r_c (PTD5); //Interrupt Comp Micro R C + + +// ******************************************************************** +//ENTRADAS ANALOGICAS +AnalogIn a_enc_rig (PTC2); //Encoder Left Output_AS_MR +AnalogIn a_enc_lef (PTC1); //Encoder Right Output_AS_ML +AnalogIn a_mic_f_l (PTB0); //Analog microphone F L +AnalogIn a_mic_f_r (PTB1); //Analog microphone F R +AnalogIn a_mic_r_c (PTB2); //Analog microphone R C +AnalogIn a_temp_bat (PTB3); //Temperature Battery + + +// ******************************************************************** + +//PWM OR DIGITAL OUTPUT NORMAL +//DigitalOut q_led_whi (PTE29); //Led white pwm +DigitalOut q_led_red_fro (PTA4); //Led Red Front +DigitalOut q_led_gre_fro (PTA5); //Led Green Front +DigitalOut q_led_blu_fro (PTA12); //Led Blue Front +DigitalOut q_led_red_rea (PTD4); //Led Red Rear +DigitalOut q_led_gre_rea (PTA1); //Led Green Rear +DigitalOut q_led_blu_rea (PTA2); //Led Blue Rear + + +//SAIDAS DIGITAIS (pwm) +PwmOut pwm_mot_rig (PTE20); //PWM Enable Motor Right +PwmOut pwm_mot_lef (PTE31); //PWM Enable Motor Left +PwmOut pwm_buzzer (PTE21); //Buzzer PWM +PwmOut pwm_led_whi (PTE29); //Led white pwm + +// ******************************************************************** +//SAIDAS ANALOGICAS +AnalogOut dac_comp_mic (PTE30); //Dac_Comparator MIC + + +/* Powers up all the VCNL4020. */ +void init_Infrared() +{ + VCNL40x0_Device.SetCurrent (20); // Set current to 200mA +} + +/** + * Selects the wich infrared to comunicate. + * + * @param ch - Infrared to read (1..5) + */ +void tca9548_select_ch(char ch) +{ + char ch_f[1]; + char addr=0xE0; + + if(ch==0) + ch_f[0]=1; + + if(ch>=1) + ch_f[0]=1<<ch; + + i2c.start(); + i2c.write(addr,ch_f,1); + i2c.stop(); +} + + +/** + * Get ADC value of the chosen infrared. + * + * @param ch - Infrared to read (1..5) + * + * Note: for the values of ch it reads (0-right, ... ,4-left, 5-back) + */ +long int read_Infrared(char ch) // 0-direita 4-esquerda 5-tras +{ + tca9548_select_ch(ch); + VCNL40x0_Device.ReadProxiOnDemand (&ProxiValue); // read prox value on demand + + return ProxiValue; +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////// MOTOR /////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////// + +// Calculo do Duty tem de ser revisto, o motor aguenta 6 V e o max definido aqui ronda os 4.2 V +// consultar pag 39 e 95 + +/** + * Sets speed and direction of the left motor. + * + * @param Dir - Direction of movement, 0 for back, or 1 for fron + * @param Speed - Percentage of speed of the motor (1..100) + * + * Note: Because of differences in the motors they need to be calibrated, test the robot going front and back + * at different speeds and see if it makes a straigth line + */ +void leftMotor(short int Dir,short int Speed) +{ + float Duty; + + if(Dir==1) { + q_pha_mot_lef=0; //Andar em frente + if(Speed>1000) //limite de segurança + Speed=1000; + if(Speed>0) { + Duty=Speed*.082 +35; // 35 = minimo para o motor rodar + q_sleep_mot_lef=1; //Nano Sleep Motor Left + pwm_mot_lef.pulsewidth_us(Duty*5); + } else { + q_sleep_mot_lef=0; + } + } + if(Dir==0) { + q_pha_mot_lef=1; //Andar para tras + + if(Speed>1000) //limite de segurança + Speed=1000; + if(Speed>0) { + Duty=Speed*.082 +35; // 35 = minimo para o motor rodar + q_sleep_mot_lef=1; //Nano Sleep Motor Left + pwm_mot_lef.pulsewidth_us(Duty*5); + } else { + q_sleep_mot_lef=0; + } + } +} + + +/** + * Sets speed and direction of the right motor. + * + * @param Dir - Direction of movement, 0 for back, or 1 for fron + * @param Speed - Percentage of speed of the motor (1..100) + * + * Note: Because of differences in the motors they need to be calibrated, test the robot going front and back + * at different speeds and see if it makes a straigth line + */ +void rightMotor(short int Dir,short int Speed) +{ + float Duty; + + if(Dir==1) { + q_pha_mot_rig=0; //Andar em frente + + if(Speed>1000) //limite de segurança + Speed=1000; + if(Speed>0) { + Duty=Speed*.082 +35; // 35 = minimo para o motor rodar + q_sleep_mot_rig=1; //Nano Sleep Motor Right + pwm_mot_rig.pulsewidth_us(Duty*5); + } else { + q_sleep_mot_rig=0; + } + } + if(Dir==0) { + q_pha_mot_rig=1; //Andar para tras + + + if(Speed>1000) //limite de segurança + Speed=1000; + if(Speed>0) { + Duty=Speed*.082 +35; // 35 = minimo para o motor rodar + q_sleep_mot_rig=1; //Nano Sleep Motor Right + pwm_mot_rig.pulsewidth_us(Duty*5); + } else { + q_sleep_mot_rig=0; + } + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////// ENCODER /////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Reads Position of left magnetic encoder. + * + * @return The absolute position of the left wheel encoder (0..4095) + */ +long int read_L_encoder() +{ + + char data_r_2[5]; + + i2c.start(); + i2c.write(0x6C); + i2c.write(0x0C); + i2c.read(0x6D,data_r_2,4,0); + i2c.stop(); + + short int val1=data_r_2[0]; + short int val2=data_r_2[1]; + val1=(val1&0xf)*256; + long int final=(val2+val1); + + return final; +} + + +/** + * Reads Position of right magnetic encoder. + * + * @return The absolute position of the right wheel encoder (0..4095) + */ +long int read_R_encoder() +{ + + char data_r_2[5]; + + i2c1.start(); + i2c1.write(0x6C); + i2c1.write(0x0C); + i2c1.read(0x6D,data_r_2,4,0); + i2c1.stop(); + + short int val1=data_r_2[0]; + short int val2=data_r_2[1]; + val1=(val1&0xf)*256; + long int final=(val2+val1); + + return final; +} + + +/** + * Calculates and returns the value of the right "incremental" encoder. + * + * @return The value of "tics" of the right encoder since it was initialized + */ +long int incremental_R_encoder() +{ + short int next_R=read_R_encoder(); // Reads curent value of the encoder + short int dif=next_R-prev_R; // Calculates the diference from last reading + + if(dif>3000) { // Going back and pass zero + total_R=total_R-4096+dif; + } + if(dif<3000&&dif>0) { // Going front + total_R=total_R+dif; + } + if(dif<-3000) { // Going front and pass zero + total_R=total_R+4096+dif; + } + if(dif>-3000&&dif<0) { // going back + total_R=total_R+dif; + } + prev_R=next_R; // Sets last reading for next iteration + + return total_R; +} + + +/** + * Calculates and returns the value of the left "incremental" encoder. + * + * @return The value of "tics" of the left encoder since it was initialized + */ +long int incremental_L_encoder() +{ + short int next_L=read_L_encoder(); // Reads curent value of the encoder + short int dif=-next_L+prev_L; // Calculates the diference from last reading + + if(dif>3000) { // Going back and pass zero + total_L=total_L-4096+dif; + } + if(dif<3000&&dif>0) { // Going front + total_L=total_L+dif; + } + if(dif<-3000) { // Going front and pass zero + total_L=total_L+4096+dif; + } + if(dif>-3000&&dif<0) { // going back + total_L=total_L+dif; + } + prev_L=next_L; // Sets last reading for next iteration + + return total_L; +} + + +/** + * Calculate the value of both encoder "incremental" every 10 ms. + */ +void timer_event() //10ms interrupt +{ + timeout.attach(&timer_event,0.01); + if(flag==0) { + incremental_R_encoder(); + incremental_L_encoder(); + } + Odometria(); + + return; +} + + +/** + * Set the initial position for the "incremental" enconder and "starts" them. + */ +void initEncoders() +{ + prev_R=read_R_encoder(); + prev_L=read_L_encoder(); + timeout.attach(&timer_event,0.01); +} + + +/** + * Returns to the user the value of the right "incremental" encoder. + * + * @return The value of "tics" of the right encoder since it was initialized + */ +long int R_encoder() +{ + wait(0.0001); + + return total_R; +} + +/** + * Returns to the user the value of the right "incremental" encoder. + * + * @return The value of "tics" of the right encoder since it was initialized + */ +long int L_encoder() +{ + wait(0.0001); + + return total_L; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////// BATTERY /////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Reads adc of the battery. + * + * @param addr - Address to read + * @return The voltage of the batery + */ +long int read16_mcp3424(char addr) +{ + char data[4]; + i2c1.start(); + i2c1.read(addr,data,3); + i2c1.stop(); + + return(((data[0]&127)*256)+data[1]); +} + +/** + * Reads adc of the battery. + * + * @param n_bits - Resolution of measure + * @param ch - Chose value to read, if voltage or current of solar or batery + * @param gain - + * @param addr - Address to write to + */ +void write_mcp3424(int n_bits, int ch, int gain, char addr) //chanel 1-4 write -> 0xD0 +{ + + int chanel_end=(ch-1)<<5; //shift left + char n_bits_end=0; + + if(n_bits==12) { + n_bits_end=0; + } else if(n_bits==14) { + n_bits_end=1; + } else if(n_bits==16) { + n_bits_end=2; + } else { + n_bits_end=3; + } + n_bits_end=n_bits_end<<2; //shift left + + char data[1]; + data[0]= (char)chanel_end | (char)n_bits_end | (char)(gain-1) | 128; + i2c1.start(); + i2c1.write(addr,data,1); + i2c1.stop(); +} + + +/** + * Reads adc of the battery. + * + * @return The voltage of the batery + */ +float value_of_Batery() +{ + float R1=75000.0; + float R2=39200.0; + float R3=178000.0; + float Gain=1.0; + write_mcp3424(16,3,1,0xd8); + float cha3_v2=read16_mcp3424(0xd9); //read voltage + float Vin_v_battery=(((cha3_v2*2.048)/32767))/Gain; + float Vin_b_v_battery=(-((-Vin_v_battery)*(R1*R2 + R1*R3 + R2*R3))/(R1*R2)); + Vin_b_v_battery=(Vin_b_v_battery-0.0)*1.00268; + + return Vin_b_v_battery; +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////// RF COMUNICATION /////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////// + + +/** + * Initializes the NRF24 module for comunication. + * + * Note: if the module is broken or badly connected this init will cause the code to stop, + * if all these messages don't appear thats the case + */ +void config_init_nrf() +{ + my_nrf24l01p.powerUp(); // powers module + my_nrf24l01p.setRfFrequency (2400); // channel 0 (2400-0 ... 2516-116) + my_nrf24l01p.setTransferSize(10); // number of bytes to be transfer + my_nrf24l01p.setCrcWidth(8); + my_nrf24l01p.enableAutoAcknowledge(NRF24L01P_PIPE_P0); // pipe where data transfer occurs (0..6) + pc.printf( "nRF24L01+ Frequency : %d MHz\r\n", my_nrf24l01p.getRfFrequency() ); + pc.printf( "nRF24L01+ Data Rate : %d kbps\r\n", my_nrf24l01p.getAirDataRate() ); + pc.printf( "nRF24L01+ TX Address : 0x%010llX\r\n", my_nrf24l01p.getTxAddress() ); + pc.printf( "nRF24L01+ RX Address : 0x%010llX\r\n", my_nrf24l01p.getRxAddress() ); + pc.printf( "nRF24L01+ CrC Width : %d CrC\r\n", my_nrf24l01p.getCrcWidth() ); + pc.printf( "nRF24L01+ TransferSize : %d Paket Size\r\n", my_nrf24l01p.getTransferSize () ); + my_nrf24l01p.setReceiveMode(); + my_nrf24l01p.enable(); + pc.printf( "Setup complete, Starting While loop\r\n"); +} + + +/** + * Receives a number from the Arduino. + * + * @return The value send by the arduino + */ +double receiveValue(void) +{ + char temp[4]; + double Val; + bool ok=0; + my_nrf24l01p.setTransferSize(4); + my_nrf24l01p.setReceiveMode(); + my_nrf24l01p.enable(); + do { + if(my_nrf24l01p.readable(NRF24L01P_PIPE_P0)) { + ok = my_nrf24l01p.read( NRF24L01P_PIPE_P0,temp, 4); + } + } while(ok==0); + + //transformation of temp to convert to original value + if(temp[0]==0) // if first elemente is 0 then its negative + Val = double(-(int(temp[1])+int(temp[2])*255+int(temp[3])*255*255)); + else // else its positive + Val = double(int(temp[1])+int(temp[2])*255+int(temp[3])*255*255); + + return Val; +} + + +/** + * Sends a number to the Arduino + * + * @param Value - number to be sent to the Arduino + */ +void sendValue(long int Value) +{ + bool ok=0; // comunication sucess, o if failed 1 if sucessfull + // double math=Value/65025; // temporary variable save results + int zero=1; // 1 byte, ( - ) if 0 ( + ) if 1 + int one=0; // 2 byte (0..255), multiplied by 1 + int two=0; // 3 byte (0..255), multiplied by 255 + int three=0; // 4 byte (0..255), multiplied by 255*255 + +//transformation of Value to send correctly through pipe + if (Value<0) { + zero=0; + Value=abs(Value); + } + // Value=abs(Value); + + double math=Value/65025; // temporary variable save results + + if(math<1) { + math=Value/255; + if(math<1) { + two=0; + one=Value; + } else { + two=(int)math; + one=Value % 255; + } + } else { + three=(int)math; + math=Value/255; + if(math<1) { + two=0; + one=Value; + } else { + two=(int)math; + one=Value % 255; + } + } + char temp[4]= {(int)zero,(int)one,(int)two,(int)three}; + + // Apagar depois de testar mais vezes + // pc.printf("1 inidice...%i...\r", temp[0]); + // pc.printf("2 inidice...%i...\r", temp[1]); + // pc.printf("3 inidice...%i...\r", temp[2]); + // pc.printf("4 inidice...%i...\r", temp[3]); + + my_nrf24l01p.setTransferSize(4); + my_nrf24l01p.setTransmitMode(); + my_nrf24l01p.enable(); + do { + ok = my_nrf24l01p.write( NRF24L01P_PIPE_P0,temp, 4); + if(ok==1) + pc.printf("Done.....%i...\r", Value); + else { + pc.printf("Failed\r"); + wait(1); + } + } while(ok==0); +} + +/** + * Sends matrix to arduino. + * + * @param matrix - Matrix of numbers to send [0..255] + * @param row - Number of rows + * @param column - Number of columns + */ +void sendMatrix(int (*matrix)[18],int row , int column) +{ + short ok=0; + short int i =0; + short int j=0; + short int byte=0; + int members=column*row; + char message[32]= {0}; + pc.printf("J ...%d... \r",members); + + my_nrf24l01p.setTransferSize(32); + my_nrf24l01p.setTransmitMode(); + my_nrf24l01p.enable(); + + do { + int* point = matrix[j]; + + do { + message[byte]= point[i]; + if (byte==31 || (i+1)*(j+1)==members) { + + do { + ok = my_nrf24l01p.write( NRF24L01P_PIPE_P0,message, 32); + if(ok==0) + wait(1); + + } while(ok==0); + + byte=-1; + } + + byte++; + i++; + + } while(i<column); + + i=0; + j++; + } while(j<row); + +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////// Sonar //////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////// +// Commands of operation with ultrasonic module + +// WRITE OPTION: +// ENABLE DC DC CONVERTER - 0x0C; +// DISABLE DC DC CONVERTER - 0x0B; +// START MEASURE LEFT SENSOR - 0x0A; +// START MEASURE FRONT SENSOR - 0x09; +// START MEASURE RIGHT SENSOR - 0x08; +// SENSORS ALWAYS MEASURE ON - 0x07; +// SENSORS ALWAYS MEASURE OFF - 0x06; + +// READ OPTION: +// GET MEASURE OF LEFT SENSOR - 0x05; +// GET MEASURE OF FRONT SENSOR - 0x04; +// GET MEASURE OF IGHT SENSOR - 0x03; +// GET STATUS SENSORS ALWAYS MEASURE - 0x02; +// GET STATUS DC DC CONVERTER - 0x01; + +void enable_dc_dc_boost() +{ + char data[1]; + data[0]= 0x0C; + wait_ms(1); + i2c1.start(); + i2c1.write(0x30,data,1); + i2c1.stop(); + i2c1.start(); + i2c1.write(0x30,data,1); + i2c1.stop(); +} + + +void disable_dc_dc_boost() +{ + char data[1]; + data[0]= 0x0B; + wait_ms(1); + i2c1.start(); + i2c1.write(0x30,data,1); + i2c1.stop(); +} + + +void start_read_left_sensor() +{ + char data[1]; + data[0]= 0x0A; + wait_ms(1); + i2c1.start(); + i2c1.write(0x30,data,1); + i2c1.stop(); +} + + +void start_read_front_sensor() +{ + char data[1]; + data[0]= 0x09; + wait_ms(1); + i2c1.start(); + i2c1.write(0x30,data,1); + i2c1.stop(); +} + + +void start_read_right_sensor() +{ + char data[1]; + data[0]= 0x08; + wait_ms(1); + i2c1.start(); + i2c1.write(0x30,data,1); + i2c1.stop(); +} + + +void measure_always_on() // left, front, right +{ + char data[1]; + data[0]= 0x07; + wait_ms(1); + i2c1.start(); + i2c1.write(0x30,data,1); + i2c1.stop(); +} + + +void measure_always_off() +{ + char data[1]; + data[0]= 0x06; + wait_ms(1); + i2c1.start(); + i2c1.write(0x30,data,1); + i2c1.stop(); +} + +/** + * Returns left sensor value + */ +static unsigned int get_distance_left_sensor() +{ + + static char data_r[3]; + static unsigned int aux; + flag=1; + + data_r[0]= 0x05; + wait_ms(1); + i2c1.start(); + i2c1.write(0x30,data_r,1); + i2c1.stop(); + wait_ms(10); + i2c1.start(); + i2c1.read(0x31,data_r,2,0); + i2c1.stop(); + + aux=(data_r[0]*256)+data_r[1]; + flag=0; + return aux; + // sensor_left=aux; + // pc.printf("\nDistance Left Sensor: %u mm",aux); //0 - 2500mm + +} + + +/** + * Returns front sensor value + */ +static unsigned int get_distance_front_sensor() +{ + + static char data_r[3]; + static unsigned int aux; + flag=1; + data_r[0]= 0x04; + wait_ms(1); + i2c1.start(); + i2c1.write(0x30,data_r,1); + i2c1.stop(); + wait_ms(10); + i2c1.start(); + i2c1.read(0x31,data_r,2,0); + i2c1.stop(); + + aux=(data_r[0]*256)+data_r[1]; + flag=0; + return aux; + // sensor_front=aux; + // pc.printf("\nDistance Front Sensor: %u mm",aux); //0 - 2500mm + +} + + +/** + * Returns right sensor value + */ +static unsigned int get_distance_right_sensor() +{ + + static char data_r[3]; + static unsigned int aux; + flag=1; + + data_r[0]= 0x03; + wait_ms(1); + i2c1.start(); + i2c1.write(0x30,data_r,1); + i2c1.stop(); + wait_ms(10); + i2c1.start(); + i2c1.read(0x31,data_r,2,0); + i2c1.stop(); + + aux=(data_r[0]*256)+data_r[1]; + flag=0; + return aux; + // sensor_right=aux; + // pc.printf("\nDistance Right Sensor: %u \r",aux); //0 - 2500mm + +} + + +void get_status_always_measure() +{ + + static char data_r[3]; + static unsigned int aux; + + data_r[0]= 0x02; + wait_ms(1); + i2c1.start(); + i2c1.write(0x30,data_r,1); + i2c1.stop(); + wait_ms(10); + i2c1.start(); + i2c1.read(0x31,data_r,2,0); + i2c1.stop(); + + aux=data_r[0]; + pc.printf("\nStatus of read always on/off: %u ",aux); //0 (off) - 1 (on) + +} + + +void get_status_dcdc_converter() +{ + + static char data_r[3]; + static unsigned int aux; + + data_r[0]= 0x01; + wait_ms(1); + i2c1.start(); + i2c1.write(0x30,data_r,1); + i2c1.stop(); + wait_ms(10); + i2c1.start(); + i2c1.read(0x31,data_r,2,0); + i2c1.stop(); + + aux=data_r[0]; + pc.printf("\nStatus of DC/DC Converter: %u ",aux); //0 (off) - 1 (on) + +} + + +/////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////// MISC. //////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////// + + +/** + * Initializes the necessary robot pins + */ +void init_robot_pins() +{ + + //SAIDAS DIGITAIS (normal) + //q_pha_mot_rig=0; //Phase Motor Right + //q_sleep_mot_rig=0; //Nano Sleep Motor Right + //q_pha_mot_lef=0; //Phase Motor Left + //q_sleep_mot_lef=0; //Nano Sleep Motor Left + //q_pow_ena_i2c_p=0; //Power Enable i2c FET P + //q_pow_ena_mic_p=0; //Power enable Micro FET P + //q_pow_as5600_n=1; //AS5600 Power MOSFET N + //q_pow_as5600_p=0; //AS5600 Power MOSFET P + //q_pow_spi=0; //SPI Power MOSFET P + //q_ena_mppt=0; //Enable MPPT Control + //q_boost_ps=1; //Boost Power Save + //q_tca9548_reset=1; //Reset TCA9548 + + //SAIDAS DIGITAIS (normal) + q_pha_mot_rig=0; //Phase Motor Right + q_sleep_mot_rig=0; //Nano Sleep Motor Right + q_pha_mot_lef=0; //Phase Motor Left + q_sleep_mot_lef=0; //Nano Sleep Motor Left + + q_pow_ena_i2c_p=0; //Power Enable i2c FET P + q_pow_ena_mic_p=0; //Power enable Micro FET P + q_pow_as5600_p=0; //AS5600 Power MOSFET P + // q_pow_spi=0; //SPI Power MOSFET P + q_pow_as5600_n=1; //AS5600 Power MOSFET N + + + q_ena_mppt=0; //Enable MPPT Control + q_boost_ps=1; //Boost Power Save + q_tca9548_reset=1; //Reset TCA9548 + + //Leds caso seja saida digital: + q_led_red_fro=1; //Led Red Front (led off) + q_led_gre_fro=1; //Led Green Front (led off) + q_led_blu_fro=1; //Led Blue Front (led off) + q_led_red_rea=1; //Led Red Rear (led off) + q_led_gre_rea=1; //Led Green Rear (led off) + q_led_blu_rea=1; //Led Blue Rear (led off)r + + +//******************************************************************** + //SAIDAS DIGITAIS (pwm) + //PWM Enable Motor Right + pwm_mot_rig.period_us(500); + pwm_mot_rig.pulsewidth_us(0); + + //PWM Enable Motor Left + pwm_mot_lef.period_us(500); + pwm_mot_lef.pulsewidth_us(0); + + //Buzzer PWM + pwm_buzzer.period_us(500); + pwm_buzzer.pulsewidth_us(0); + + //LED white + pwm_led_whi.period_us(500); + pwm_led_whi.pulsewidth_us(0); + +} + + +/** + * Initializes all the pins and all the modules necessary + */ +void initRobot(void) +{ + init_robot_pins(); + enable_dc_dc_boost(); + init_Infrared(); + initEncoders(); + config_init_nrf(); + enable_dc_dc_boost(); + wait_ms(100); //wait for read wait(>=150ms); + measure_always_on(); + float value = value_of_Batery(); + pc.printf("Initialization Successful \n\r"); + pc.printf("Battery level: %f \n\r",value); + if(value < 3.0) { + pc.printf(" WARNING: BATTERY NEEDS CHARGING "); + } + + // float level = value_of_Batery(); + // sendValue(int(level*100)); + +} + + +//////////////////////////////////////////////////// + +/** + * Updates the position and orientation of the robot based on the data from the encoders + * + * Note: Needs to be calibrated for each robot, in this case the radius of the whells is 3.55 + * and the distance between them is 7.4 + */ +void Odometria() +{ + long int ticks1d=R_encoder(); + long int ticks1e=L_encoder(); + + long int D_ticks=ticks1d - ticks2d; + long int E_ticks=ticks1e - ticks2e; + + ticks2d=ticks1d; + ticks2e=ticks1e; + + float D_cm= (float)D_ticks*((3.25*3.1415)/4096); + float L_cm= (float)E_ticks*((3.25*3.1415)/4096); + + float CM=(D_cm + L_cm)/2; + + theta +=(D_cm - L_cm)/7.18; + + theta = atan2(sin(theta), cos(theta)); + + // meter entre 0 + + X += CM*cos(theta); + Y += CM*sin(theta); + +} \ No newline at end of file