ENIB 2023 : accélérocube : Différence entre versions

De Les Fabriques du Ponant
Aller à : navigation, rechercher
(Page créée avec « ==photo de l'équipe== 600px ==Que fait ce projet ? == ==Liste des composants== * composant 1 * composant 2 * ... ==Code== <pre... »)
 
(Catégories)
 
(2 révisions intermédiaires par 2 utilisateurs non affichées)
Ligne 1 : Ligne 1 :
  
==photo de l'équipe==
+
==photo du projet==
 
[[Fichier:IMG 20230118 111934988.jpg|600px]]
 
[[Fichier:IMG 20230118 111934988.jpg|600px]]
  
 
==Que fait ce projet ? ==
 
==Que fait ce projet ? ==
 +
Cube qui éclaire une ampoule si posé vers le haut
  
 
==Liste des composants==
 
==Liste des composants==
 
+
*ampoule
* composant 1
+
*accéléromètre
* composant 2
+
*bois
* ...
+
*vis
 +
*pinces croco
 +
*batterie
 +
*carte arduino
  
 
==Code==
 
==Code==
 
<pre>
 
<pre>
ici je pose mon code documenté !
+
#include <Wire.h>
 +
const int MPU_addr=0x3F;
 +
int gyro_x, gyro_y, gyro_z;
 +
long gyro_x_cal, gyro_y_cal, gyro_z_cal;
 +
boolean set_gyro_angles;
 +
 +
long acc_x, acc_y, acc_z, acc_total_vector;
 +
float angle_roll_acc, angle_pitch_acc;
 +
 +
float angle_pitch, angle_roll;
 +
int angle_pitch_buffer, angle_roll_buffer;
 +
float angle_pitch_output, angle_roll_output;
 +
int diceNum;
 +
 
 +
long loop_timer;
 +
int temp;
 +
 +
 
 +
void setup() {
 +
 
 +
  Wire.begin();
 +
  setup_mpu_6050_registers();
 +
  for (int cal_int = 0; cal_int < 1000 ; cal_int ++){                 
 +
    read_mpu_6050_data();
 +
    //Add the gyro x offset to the gyro_x_cal variable                                           
 +
    gyro_x_cal += gyro_x;
 +
    //Add the gyro y offset to the gyro_y_cal variable                                             
 +
    gyro_y_cal += gyro_y;
 +
    //Add the gyro z offset to the gyro_z_cal variable                                           
 +
    gyro_z_cal += gyro_z;
 +
    //Delay 3us to have 250Hz for-loop                                           
 +
    delay(3);                                                         
 +
  }
 +
  gyro_x_cal /= 1000;                                               
 +
  gyro_y_cal /= 1000;                                               
 +
  gyro_z_cal /= 1000;
 +
  Serial.begin(115200);
 +
  loop_timer = micros();                                             
 +
 
 +
}
 +
 
 +
void loop() {
 +
  // Get data from MPU-6050
 +
  read_mpu_6050_data();
 +
   
 +
  //Subtract the offset values from the raw gyro values
 +
  gyro_x -= gyro_x_cal;                                               
 +
  gyro_y -= gyro_y_cal;                                               
 +
  gyro_z -= gyro_z_cal;                                               
 +
       
 +
  //Gyro angle calculations . Note 0.0000611 = 1 / (250Hz x 65.5)
 +
 
 +
  //Calculate the traveled pitch angle and add this to the angle_pitch variable
 +
  angle_pitch += gyro_x * 0.0000611; 
 +
  //Calculate the traveled roll angle and add this to the angle_roll variable
 +
  //0.000001066 = 0.0000611 * (3.142(PI) / 180degr) The Arduino sin function is in radians                               
 +
  angle_roll += gyro_y * 0.0000611;
 +
                                   
 +
  //If the IMU has yawed transfer the roll angle to the pitch angle
 +
  angle_pitch += angle_roll * sin(gyro_z * 0.000001066);
 +
  //If the IMU has yawed transfer the pitch angle to the roll angle             
 +
  angle_roll -= angle_pitch * sin(gyro_z * 0.000001066);             
 +
 
 +
  //Accelerometer angle calculations
 +
 
 +
  //Calculate the total accelerometer vector
 +
  acc_total_vector = sqrt((acc_x*acc_x)+(acc_y*acc_y)+(acc_z*acc_z));
 +
 
 +
  //57.296 = 1 / (3.142 / 180) The Arduino asin function is in radians
 +
  //Calculate the pitch angle
 +
  angle_pitch_acc = asin((float)acc_y/acc_total_vector)* 57.296;
 +
  //Calculate the roll angle     
 +
  angle_roll_acc = asin((float)acc_x/acc_total_vector)* -57.296;     
 +
 
 +
  //Accelerometer calibration value for pitch
 +
  angle_pitch_acc -= 0.0;
 +
  //Accelerometer calibration value for roll                                             
 +
  angle_roll_acc -= 0.0;                                             
 +
  if(set_gyro_angles){
 +
 
 +
  //If the IMU has been running
 +
  //Correct the drift of the gyro pitch angle with the accelerometer pitch angle                     
 +
    angle_pitch = angle_pitch * 0.9996 + angle_pitch_acc * 0.0004;
 +
    //Correct the drift of the gyro roll angle with the accelerometer roll angle   
 +
    angle_roll = angle_roll * 0.9996 + angle_roll_acc * 0.0004;       
 +
  }
 +
  else{
 +
    //IMU has just started 
 +
    //Set the gyro pitch angle equal to the accelerometer pitch angle                                                         
 +
    angle_pitch = angle_pitch_acc;
 +
    //Set the gyro roll angle equal to the accelerometer roll angle                                     
 +
    angle_roll = angle_roll_acc;
 +
    //Set the IMU started flag                                     
 +
    set_gyro_angles = true;                                           
 +
  }
 +
 
 +
  //To dampen the pitch and roll angles a complementary filter is used
 +
  //Take 90% of the output pitch value and add 10% of the raw pitch value
 +
  angle_pitch_output = angle_pitch_output * 0.9 + angle_pitch * 0.1;
 +
  //Take 90% of the output roll value and add 10% of the raw roll value
 +
  angle_roll_output = angle_roll_output * 0.9 + angle_roll * 0.1;
 +
  //Wait until the loop_timer reaches 4000us (250Hz) before starting the next loop 
 +
 
 +
  // Print to Serial Monitor 
 +
  //Serial.print(" | Angle  = "); Serial.println(angle_pitch_output);
 +
 
 +
 
 +
  // Check Angle for Level LEDs
 +
 
 +
    if (angle_pitch_output < -2.01) {
 +
    // Turn on Level LED
 +
    digitalWrite(levelLED_neg1, HIGH);
 +
    digitalWrite(levelLED_neg0, LOW);
 +
    digitalWrite(levelLED_level, LOW);
 +
    digitalWrite(levelLED_pos0, LOW);
 +
    digitalWrite(levelLED_pos1, LOW);
 +
   
 +
    } else if ((angle_pitch_output > -2.00) && (angle_pitch_output < -1.01)) {
 +
    // Turn on Level LED
 +
    digitalWrite(levelLED_neg1, LOW);
 +
    digitalWrite(levelLED_neg0, HIGH);
 +
    digitalWrite(levelLED_level, LOW);
 +
    digitalWrite(levelLED_pos0, LOW);
 +
    digitalWrite(levelLED_pos1, LOW);
 +
   
 +
    } else if ((angle_pitch_output < 1.00) && (angle_pitch_output > -1.00)) {
 +
    // Turn on Level LED
 +
    digitalWrite(levelLED_neg1, LOW);
 +
    digitalWrite(levelLED_neg0, LOW);
 +
    digitalWrite(levelLED_level, HIGH);
 +
    digitalWrite(levelLED_pos0, LOW);
 +
    digitalWrite(levelLED_pos1, LOW);
 +
   
 +
    } else if ((angle_pitch_output > 1.01) && (angle_pitch_output < 2.00)) {
 +
    // Turn on Level LED
 +
    digitalWrite(levelLED_neg1, LOW);
 +
    digitalWrite(levelLED_neg0, LOW);
 +
    digitalWrite(levelLED_level, LOW);
 +
    digitalWrite(levelLED_pos0, HIGH);
 +
    digitalWrite(levelLED_pos1, LOW);
 +
   
 +
    } else if (angle_pitch_output > 2.01) {
 +
    // Turn on Level LED
 +
    digitalWrite(levelLED_neg1, LOW);
 +
    digitalWrite(levelLED_neg0, LOW);
 +
    digitalWrite(levelLED_level, LOW);
 +
    digitalWrite(levelLED_pos0, LOW);
 +
    digitalWrite(levelLED_pos1, HIGH);
 +
   
 +
    } 
 +
  }
 +
 
 +
 +
while(micros() - loop_timer < 4000);
 +
//Reset the loop timer                               
 +
loop_timer = micros();
 +
 
 +
}
 +
 +
void setup_mpu_6050_registers(){
 +
 +
  //Activate the MPU-6050
 +
 
 +
  //Start communicating with the MPU-6050
 +
  Wire.beginTransmission(0x68);
 +
  //Send the requested starting register                                     
 +
  Wire.write(0x6B); 
 +
  //Set the requested starting register                                                 
 +
  Wire.write(0x00);
 +
  //End the transmission                                                   
 +
  Wire.endTransmission();
 +
                                             
 +
  //Configure the accelerometer (+/-8g)
 +
 
 +
  //Start communicating with the MPU-6050
 +
  Wire.beginTransmission(0x68);
 +
  //Send the requested starting register                                     
 +
  Wire.write(0x1C); 
 +
  //Set the requested starting register                                               
 +
  Wire.write(0x10);
 +
  //End the transmission                                                 
 +
  Wire.endTransmission();
 +
                                             
 +
  //Configure the gyro (500dps full scale)
 +
 
 +
  //Start communicating with the MPU-6050
 +
  Wire.beginTransmission(0x68);
 +
  //Send the requested starting register                                       
 +
  Wire.write(0x1B);
 +
  //Set the requested starting register                                                   
 +
  Wire.write(0x08);
 +
  //End the transmission                                                 
 +
  Wire.endTransmission();
 +
                                             
 +
}
 +
 +
 +
void read_mpu_6050_data(){
 +
 +
  //Read the raw gyro and accelerometer data
 +
 +
  //Start communicating with the MPU-6050                                         
 +
  Wire.beginTransmission(0x68); 
 +
  //Send the requested starting register                                     
 +
  Wire.write(0x3B);
 +
  //End the transmission                                                   
 +
  Wire.endTransmission();
 +
  //Request 14 bytes from the MPU-6050                                 
 +
  Wire.requestFrom(0x68,14);   
 +
  //Wait until all the bytes are received                                     
 +
  while(Wire.available() < 14);
 +
 
 +
  //Following statements left shift 8 bits, then bitwise OR. 
 +
  //Turns two 8-bit values into one 16-bit value                                     
 +
  acc_x = Wire.read()<<8|Wire.read();                                 
 +
  acc_y = Wire.read()<<8|Wire.read();                                 
 +
  acc_z = Wire.read()<<8|Wire.read();                                 
 +
  temp = Wire.read()<<8|Wire.read();                                 
 +
  gyro_x = Wire.read()<<8|Wire.read();                               
 +
  gyro_y = Wire.read()<<8|Wire.read();                               
 +
  gyro_z = Wire.read()<<8|Wire.read();                 
 +
 
 +
 
 +
}
 
</pre>
 
</pre>
  
Ligne 19 : Ligne 246 :
  
 
[[Catégorie:Enib2023]]
 
[[Catégorie:Enib2023]]
 +
 +
[[Catégorie:Arduino]]

Version actuelle datée du 15 janvier 2024 à 16:01

photo du projet

IMG 20230118 111934988.jpg

Que fait ce projet ?

Cube qui éclaire une ampoule si posé vers le haut

Liste des composants

  • ampoule
  • accéléromètre
  • bois
  • vis
  • pinces croco
  • batterie
  • carte arduino

Code

#include <Wire.h>
const int MPU_addr=0x3F;
int gyro_x, gyro_y, gyro_z;
long gyro_x_cal, gyro_y_cal, gyro_z_cal;
boolean set_gyro_angles;
 
long acc_x, acc_y, acc_z, acc_total_vector;
float angle_roll_acc, angle_pitch_acc;
 
float angle_pitch, angle_roll;
int angle_pitch_buffer, angle_roll_buffer;
float angle_pitch_output, angle_roll_output;
int diceNum;

long loop_timer;
int temp;
 

void setup() {
  
  Wire.begin();
  setup_mpu_6050_registers(); 
  for (int cal_int = 0; cal_int < 1000 ; cal_int ++){                  
    read_mpu_6050_data(); 
    //Add the gyro x offset to the gyro_x_cal variable                                            
    gyro_x_cal += gyro_x;
    //Add the gyro y offset to the gyro_y_cal variable                                              
    gyro_y_cal += gyro_y; 
    //Add the gyro z offset to the gyro_z_cal variable                                             
    gyro_z_cal += gyro_z; 
    //Delay 3us to have 250Hz for-loop                                             
    delay(3);                                                          
  }
  gyro_x_cal /= 1000;                                                 
  gyro_y_cal /= 1000;                                                 
  gyro_z_cal /= 1000;
  Serial.begin(115200);
  loop_timer = micros();                                               

}

void loop() {
  // Get data from MPU-6050
  read_mpu_6050_data();
     
  //Subtract the offset values from the raw gyro values
  gyro_x -= gyro_x_cal;                                                
  gyro_y -= gyro_y_cal;                                                
  gyro_z -= gyro_z_cal;                                                
         
  //Gyro angle calculations . Note 0.0000611 = 1 / (250Hz x 65.5)
  
  //Calculate the traveled pitch angle and add this to the angle_pitch variable
  angle_pitch += gyro_x * 0.0000611;  
  //Calculate the traveled roll angle and add this to the angle_roll variable
  //0.000001066 = 0.0000611 * (3.142(PI) / 180degr) The Arduino sin function is in radians                                
  angle_roll += gyro_y * 0.0000611; 
                                     
  //If the IMU has yawed transfer the roll angle to the pitch angle
  angle_pitch += angle_roll * sin(gyro_z * 0.000001066);
  //If the IMU has yawed transfer the pitch angle to the roll angle               
  angle_roll -= angle_pitch * sin(gyro_z * 0.000001066);               
  
  //Accelerometer angle calculations
  
  //Calculate the total accelerometer vector
  acc_total_vector = sqrt((acc_x*acc_x)+(acc_y*acc_y)+(acc_z*acc_z)); 
   
  //57.296 = 1 / (3.142 / 180) The Arduino asin function is in radians
  //Calculate the pitch angle
  angle_pitch_acc = asin((float)acc_y/acc_total_vector)* 57.296; 
  //Calculate the roll angle      
  angle_roll_acc = asin((float)acc_x/acc_total_vector)* -57.296;       
  
  //Accelerometer calibration value for pitch
  angle_pitch_acc -= 0.0;
  //Accelerometer calibration value for roll                                              
  angle_roll_acc -= 0.0;                                               
  if(set_gyro_angles){ 
  
  //If the IMU has been running 
  //Correct the drift of the gyro pitch angle with the accelerometer pitch angle                      
    angle_pitch = angle_pitch * 0.9996 + angle_pitch_acc * 0.0004; 
    //Correct the drift of the gyro roll angle with the accelerometer roll angle    
    angle_roll = angle_roll * 0.9996 + angle_roll_acc * 0.0004;        
  }
  else{ 
    //IMU has just started  
    //Set the gyro pitch angle equal to the accelerometer pitch angle                                                           
    angle_pitch = angle_pitch_acc;
    //Set the gyro roll angle equal to the accelerometer roll angle                                       
    angle_roll = angle_roll_acc;
    //Set the IMU started flag                                       
    set_gyro_angles = true;                                            
  }
  
  //To dampen the pitch and roll angles a complementary filter is used
  //Take 90% of the output pitch value and add 10% of the raw pitch value
  angle_pitch_output = angle_pitch_output * 0.9 + angle_pitch * 0.1; 
  //Take 90% of the output roll value and add 10% of the raw roll value 
  angle_roll_output = angle_roll_output * 0.9 + angle_roll * 0.1; 
  //Wait until the loop_timer reaches 4000us (250Hz) before starting the next loop  
  
  // Print to Serial Monitor   
  //Serial.print(" | Angle  = "); Serial.println(angle_pitch_output);
  
  
  // Check Angle for Level LEDs
  
    if (angle_pitch_output < -2.01) {
    // Turn on Level LED
    digitalWrite(levelLED_neg1, HIGH);
    digitalWrite(levelLED_neg0, LOW);
    digitalWrite(levelLED_level, LOW);
    digitalWrite(levelLED_pos0, LOW);
    digitalWrite(levelLED_pos1, LOW);
    
    } else if ((angle_pitch_output > -2.00) && (angle_pitch_output < -1.01)) {
    // Turn on Level LED
    digitalWrite(levelLED_neg1, LOW);
    digitalWrite(levelLED_neg0, HIGH);
    digitalWrite(levelLED_level, LOW);
    digitalWrite(levelLED_pos0, LOW);
    digitalWrite(levelLED_pos1, LOW);
    
    } else if ((angle_pitch_output < 1.00) && (angle_pitch_output > -1.00)) {
    // Turn on Level LED
    digitalWrite(levelLED_neg1, LOW);
    digitalWrite(levelLED_neg0, LOW);
    digitalWrite(levelLED_level, HIGH);
    digitalWrite(levelLED_pos0, LOW);
    digitalWrite(levelLED_pos1, LOW);
    
    } else if ((angle_pitch_output > 1.01) && (angle_pitch_output < 2.00)) {
    // Turn on Level LED
    digitalWrite(levelLED_neg1, LOW);
    digitalWrite(levelLED_neg0, LOW);
    digitalWrite(levelLED_level, LOW);
    digitalWrite(levelLED_pos0, HIGH);
    digitalWrite(levelLED_pos1, LOW);
    
    } else if (angle_pitch_output > 2.01) {
    // Turn on Level LED
    digitalWrite(levelLED_neg1, LOW);
    digitalWrite(levelLED_neg0, LOW);
    digitalWrite(levelLED_level, LOW);
    digitalWrite(levelLED_pos0, LOW);
    digitalWrite(levelLED_pos1, HIGH);
    
    }  
  }
  
 
 while(micros() - loop_timer < 4000); 
 //Reset the loop timer                                
 loop_timer = micros();
  
}
 
void setup_mpu_6050_registers(){
 
  //Activate the MPU-6050
  
  //Start communicating with the MPU-6050
  Wire.beginTransmission(0x68); 
  //Send the requested starting register                                       
  Wire.write(0x6B);  
  //Set the requested starting register                                                  
  Wire.write(0x00);
  //End the transmission                                                    
  Wire.endTransmission(); 
                                              
  //Configure the accelerometer (+/-8g)
  
  //Start communicating with the MPU-6050
  Wire.beginTransmission(0x68); 
  //Send the requested starting register                                       
  Wire.write(0x1C);   
  //Set the requested starting register                                                 
  Wire.write(0x10); 
  //End the transmission                                                   
  Wire.endTransmission(); 
                                              
  //Configure the gyro (500dps full scale)
  
  //Start communicating with the MPU-6050
  Wire.beginTransmission(0x68);
  //Send the requested starting register                                        
  Wire.write(0x1B);
  //Set the requested starting register                                                    
  Wire.write(0x08); 
  //End the transmission                                                  
  Wire.endTransmission(); 
                                              
}
 
 
void read_mpu_6050_data(){ 
 
  //Read the raw gyro and accelerometer data
 
  //Start communicating with the MPU-6050                                          
  Wire.beginTransmission(0x68);  
  //Send the requested starting register                                      
  Wire.write(0x3B);
  //End the transmission                                                    
  Wire.endTransmission(); 
  //Request 14 bytes from the MPU-6050                                  
  Wire.requestFrom(0x68,14);    
  //Wait until all the bytes are received                                       
  while(Wire.available() < 14);
  
  //Following statements left shift 8 bits, then bitwise OR.  
  //Turns two 8-bit values into one 16-bit value                                       
  acc_x = Wire.read()<<8|Wire.read();                                  
  acc_y = Wire.read()<<8|Wire.read();                                  
  acc_z = Wire.read()<<8|Wire.read();                                  
  temp = Wire.read()<<8|Wire.read();                                   
  gyro_x = Wire.read()<<8|Wire.read();                                 
  gyro_y = Wire.read()<<8|Wire.read();                                 
  gyro_z = Wire.read()<<8|Wire.read();                  

  
}

Catégories