Fabrication d'un inclinomètre

Ici vous pouvez trouver des infos sur les accessoires dédiés aux SV650 & SV1000 N/S
( Tête de fouche, sabot, selle, pot, etc... )
watoubilly
Pilote 50 cm3
Pilote 50 cm3
Messages : 52
Enregistré le : jeu. 22 oct., 2020 19:52

Fabrication d'un inclinomètre

Message par watoubilly »

Je lance ce topic pour partager avec vous un projet que je suis en train de commencer : la fabrication d'un inclinomètre autonome.
Je pars d'un projet existant à base d'Arduino et d'un accéléromètre.

. La première étape est de reproduire l'électronique et adapter le code:
J'ai repris le schéma de câblage tel quel avec un ArduinoUno qui trainait dans un tiroir.
Pour le code j'ai fait quelques modifications pour n'avoir que des info utiles et conserver le maximum atteint de chaque coté ainsi que la valeur actuelle de l'angle.

Image

. La deuxième étape est de fabriquer un shield pour l'Arduino plutôt que d'utiliser une platine d'essaie.
Image

. La troisième étape est de fabriquer les boitiers pour mettre l'électronique:
Je suis en train de faire 2 boitiers différents car le LCD sera sur le tableau de bord du SV tandis que le capteur d'angle sera dans la bulle.
Image

Voici le résultat une fois imprimé
Image

A présent je suis en train de faire le boitier pour le capteur d'angle.
watoubilly
Pilote 50 cm3
Pilote 50 cm3
Messages : 52
Enregistré le : jeu. 22 oct., 2020 19:52

Fabrication d'un inclinomètre

Message par watoubilly »

Mis en position ça donne ça :
Image
Xavier06
Pilote 250 cm3
Pilote 250 cm3
Messages : 976
Enregistré le : dim. 19 août, 2018 16:24
Moto : SV1000S K3

Fabrication d'un inclinomètre

Message par Xavier06 »

watoubilly a écrit : lun. 11 janv., 2021 10:55 Je pars d'un projet existant à base d'Arduino et d'un accéléromètre.
avec un accéléromètre comme capteur, tu n'auras pas la mesure de l'angle de la moto par rapport à la verticale en virage
watoubilly
Pilote 50 cm3
Pilote 50 cm3
Messages : 52
Enregistré le : jeu. 22 oct., 2020 19:52

Fabrication d'un inclinomètre

Message par watoubilly »

Tu as raison Xavier j'ai fait mes recherches et il faut combiner un gyroscope. Mais aucun soucis j'ai trouvé un autre composant qui inclue les 2 et qui parle en I2C donc je n'aurai que le shield a recâbler.
watoubilly
Pilote 50 cm3
Pilote 50 cm3
Messages : 52
Enregistré le : jeu. 22 oct., 2020 19:52

Fabrication d'un inclinomètre

Message par watoubilly »

Xavier06 a écrit : lun. 11 janv., 2021 13:38
watoubilly a écrit : lun. 11 janv., 2021 10:55 Je pars d'un projet existant à base d'Arduino et d'un accéléromètre.
avec un accéléromètre comme capteur, tu n'auras pas la mesure de l'angle de la moto par rapport à la verticale en virage
J'aurais quand même l'angle sur la béquille. :hehe:
Avatar du membre
nico97410
Pilote Grand Prix
Pilote Grand Prix
Messages : 7072
Enregistré le : lun. 25 mars, 2013 13:56
Moto : Ex-SV650S 06' - VFR 750 RC36-II 96' - VFR748RR
Localisation : Ile de la Réunion

Fabrication d'un inclinomètre

Message par nico97410 »

A l’époque j’avais des berryIMU qui avait gyro+accéléromètre, et je crois bien que ça communiquer en i2c
Océ a écrit : Parce que Nico m’a rempli
watoubilly
Pilote 50 cm3
Pilote 50 cm3
Messages : 52
Enregistré le : jeu. 22 oct., 2020 19:52

Fabrication d'un inclinomètre

Message par watoubilly »

Merci Nico pour l'info. Je suis toujours en phase d'impression 3D pour le deuxième boitier en attendant un équivalent de ton berryIMU avec gyroscope et accéléromètre.
watoubilly
Pilote 50 cm3
Pilote 50 cm3
Messages : 52
Enregistré le : jeu. 22 oct., 2020 19:52

Fabrication d'un inclinomètre

Message par watoubilly »

Bon je confirme que l'accéléromètre seul ne fonctionne pas.
Mon premier proto de boitier est ok donc prochaine étape prototypage avec accéléromètre et gyro.
Personne n'a jamais fait ce type de montage j'ai vu des début mais jamais de fin. Vous avez un truc a me dire ? :snif:
Avatar du membre
PEagle
Pilote Grand Prix
Pilote Grand Prix
Messages : 5767
Enregistré le : sam. 09 oct., 2010 19:54
Moto : KawaTM Zx6r K7 orange

Fabrication d'un inclinomètre

Message par PEagle »

Je réfléchis aux maths qu'il va y avoir derrière, ça va pas être vraiment simple.
Ton gyroscope va dériver, ce ne sera pas aussi marqué que sur les avions (15° par heure à cause de la rotation de la terre) mais tu vas vite avoir de l'erreur et tu ne pourras pas le recaler facilement lorsque tu roules.
Le calage à vide, il te faudra un zéro et il sera pas forcément facile à aller chercher si tu veux quelque chose au degré près. (Tu peux le caler t'assurer de mettre ta moto sur un support horizontal, noter l'angle de la moto sur la béquille, faire un bouton pour le remettre à 0 et l'associer à l'angle de ta béquille, mais ce sera mal calibré dès que ta moto sur béquille ne sera pas sur un sol plat.)

C'est ce que je vois vite fait comme ça qu'il faudra prendre en compte. Ensuite à voir, si la dérive est vraiment mineure, une fois calibré, tu sera tranquille.
A reçu 26 :tusors:
Image
watoubilly
Pilote 50 cm3
Pilote 50 cm3
Messages : 52
Enregistré le : jeu. 22 oct., 2020 19:52

Fabrication d'un inclinomètre

Message par watoubilly »

Le montage en volant est OK avec un code qui semble fonctionner (insensible au secouage contrairement au montage précédent sans gyroscope). Pour le moment j'ai angle instantané et angle max pour le pitch et le roll par contre je vois pas trop à quoi peut servir le roll sauf pour les weelings et stopies. :mrgreen: Mais en SV c'est interdit askip.

Comme tu dis PEagle je vais ajouter un bouton pour recalibrer le zéro au cas où je change le boitier de place et surtout pour faire un RAZ des stats de max détecté. Appuie court RAZ de stats, appuie long recalibrage.
watoubilly
Pilote 50 cm3
Pilote 50 cm3
Messages : 52
Enregistré le : jeu. 22 oct., 2020 19:52

Fabrication d'un inclinomètre

Message par watoubilly »

Tout est terminé mais impossible de tester grandeur nature il neige.
Je vous ferai un tuto si vous êtes intéressé.
watoubilly
Pilote 50 cm3
Pilote 50 cm3
Messages : 52
Enregistré le : jeu. 22 oct., 2020 19:52

Fabrication d'un inclinomètre

Message par watoubilly »

Petit tour effectué, c'est un échec ! D'après la littérature il manque quelque chose en plus pour faire un inclinomètre pour moto. Par contre pour du franchissement en 4x4 c'est parfait.

Je vous met le code:

Code : Tout sélectionner

#include <EEPROM.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h> 

#define DEBUG_SERIAL

                  
// -- CONSTANTS --

//Digital input
const int DI_PUSH_BUTTON = 2;

//Display
const int LCD_I2C_ADDRESS = 0x27;
const int LCD_CHAR_PER_LINE = 16;
const int LCD_LINES = 2;

//Accelerometer and gyroscope
const int MPU6050_I2C_ADDRESS = 0x68;

const int MPU6050_REGISTER_ADDRESS_PWR_MGMT_1 = 0x6B;
const int MPU6050_REGISTER_ADDRESS_ACCEL_CONFIG = 0x1C;
const int MPU6050_REGISTER_ADDRESS_GYRO_CONFIG = 0x1B;

const int MPU6050_REGISTER_ADDRESS_ACCEL_XOUT_H = 0x3B;
const float MPU6050_ACCEL_LSB_SENSITIVITY = 16384.0;

const int MPU6050_REGISTER_ADDRESS_GYRO_XOUT_H = 0x43;
const float MPU6050_GYRO_LSB_SENSITIVITY = 131.0;

const int MPU6050_CALIBRATION_SAMPLE_COUNT = 200;

//Misc
const int MAX_ROLL = 75;
const int MAX_PITCH = 75;


// -- TYPES --
struct AccCorrectionOffset
{
  float X;
  float Y;  
};

struct GyroCorrectionOffset
{
  float X;
  float Y;
  float Z;
};


// -- VARIABLES --
//Raw values
static float g_accX, g_accY, g_accZ;     //Accelerometer values
static float g_gyroX, g_gyroY, g_gyroZ;  //Gyroscope values

//Temporary values
static float g_accAngleX, g_accAngleY = 0.0;
static float g_gyroAngleX, g_gyroAngleY, g_gyroAngleZ;
static float g_elapsedTime, g_currentTime, g_previousTime;

//Final values
static float g_roll, g_pitch, g_yaw;

//Statistics
static int g_statisticLeftRoll = 0;
static int g_statisticRightRoll = 0;
static int g_statisticLeftPitch = 0;
static int g_statisticRightPitch = 0;

static float g_accMinX, g_accMaxX;
static float g_accMinY, g_accMaxY;

//Correction values
static AccCorrectionOffset g_accCorrectionOffset;
static GyroCorrectionOffset g_gyroCorrectionOffset;

//Display 
static int g_updateDisplay = 0;
static int g_displayMode = 0;

//Lcd
LiquidCrystal_I2C g_lcd(LCD_I2C_ADDRESS, LCD_CHAR_PER_LINE, LCD_LINES);


// -- FUNCTIONS --

//Setup
void setup() 
{
#ifdef DEBUG_SERIAL  
  Serial.begin(19200);
#endif
  
  //LCD Display init
  g_lcd.init();
  g_lcd.backlight();

  //Push button init
  pinMode(DI_PUSH_BUTTON, INPUT_PULLUP);

  //MPU6050 init
  Wire.begin();
  Wire.beginTransmission(MPU6050_I2C_ADDRESS);
  Wire.write(MPU6050_REGISTER_ADDRESS_PWR_MGMT_1);
  Wire.write(0x00); // Make reset and use internal clock
  Wire.endTransmission(true);  
  delay(20);

  //Init corrections
  if(digitalRead(DI_PUSH_BUTTON) != LOW)  
  {//Read corrections saved in EEPROM for accelerometer and gyroscope
    int eeAddress = 0;  
    EEPROM.get( eeAddress, g_accCorrectionOffset);
    eeAddress = sizeof(AccCorrectionOffset);
    EEPROM.get( eeAddress, g_gyroCorrectionOffset);
  }
  else
  {//Enter in calibration mode
    g_lcd.clear();
    g_lcd.setCursor(0, 0);
    g_lcd.print("AUTO CALIBRATION");
    g_lcd.setCursor(0, 1);
    g_lcd.print("Don't move...");
    delay(2000); 

    //Start calibration
    AutoCalibrate();        

    //Save corrections in EEPROM
    int eeAddress = 0;  
    EEPROM.put( eeAddress, g_accCorrectionOffset);
    eeAddress = sizeof(AccCorrectionOffset);
    EEPROM.put( eeAddress, g_gyroCorrectionOffset);

    //Show details if keep button down
    if(digitalRead(DI_PUSH_BUTTON) == LOW)
    {
      g_lcd.clear();
      g_lcd.setCursor(0, 0);
      g_lcd.print("AX offset");
      g_lcd.setCursor(0, 1);
      g_lcd.print(g_accCorrectionOffset.X);
      delay(1500);
      
      g_lcd.clear();
      g_lcd.setCursor(0, 0);
      g_lcd.print("AY offset");
      g_lcd.setCursor(0, 1);
      g_lcd.print(g_accCorrectionOffset.Y);
      delay(1500);      
       
      g_lcd.clear();
      g_lcd.setCursor(0, 0);
      g_lcd.print("GX offset");
      g_lcd.setCursor(0, 1);
      g_lcd.print(g_gyroCorrectionOffset.X);
      delay(1500);   
          
      g_lcd.clear();
      g_lcd.setCursor(0, 0);
      g_lcd.print("GY offset");
      g_lcd.setCursor(0, 1);
      g_lcd.print(g_gyroCorrectionOffset.Y);
      delay(1500); 
           
      g_lcd.clear();
      g_lcd.setCursor(0, 0);
      g_lcd.print("GZ offset");
      g_lcd.setCursor(0, 1); 
      g_lcd.print(g_gyroCorrectionOffset.Z);
      delay(1500);      
    }
  }

  g_lcd.clear();
  g_lcd.setCursor(0, 0);
  g_lcd.print("  INCLINOMETER  ");
  g_lcd.setCursor(9, 1);
  g_lcd.print("V1.0");
      
  delay(3000);    
  DisplayMode();
}

//Loop
void loop() 
{
  static int pushButtonDownCount;
  //RAZ statitics if push button down
  while(digitalRead(DI_PUSH_BUTTON) == LOW) 
  {   
    pushButtonDownCount++;
    delay(100);

    if(pushButtonDownCount > 20)
    {
      g_lcd.clear();    
      g_lcd.setCursor(0, 0);
      g_lcd.print("RESET ALL");
      delay(1500);     
      
      //Start RAZ
      ResetStatistics();

      pushButtonDownCount = 0;
    }
  }

  if(pushButtonDownCount > 0)
  {       
    if(++g_displayMode > 2)
      g_displayMode = 0;
    
    DisplayMode();
    
    pushButtonDownCount = 0;
  }
  
  //Read acceleromter data
  Wire.beginTransmission(MPU6050_I2C_ADDRESS);
  Wire.write(MPU6050_REGISTER_ADDRESS_ACCEL_XOUT_H);
  Wire.endTransmission(false);
  Wire.requestFrom(MPU6050_I2C_ADDRESS, 6, true); //Read 6 registers from ACCEL_XOUT_H (ACCEL_XOUT_H, ACCEL_XOUT_L, ACCEL_YOUT_H, ACCEL_YOUT_L, ACCEL_ZOUT_H, ACCEL_ZOUT_L)

  //For a range of +-2g, divide raw values by ACCEL_LSB_SENSITIVITY (according to the datasheet)  
  g_accX = (Wire.read() << 8 | Wire.read()) / MPU6050_ACCEL_LSB_SENSITIVITY;
  g_accY = (Wire.read() << 8 | Wire.read()) / MPU6050_ACCEL_LSB_SENSITIVITY;  
  g_accZ = (Wire.read() << 8 | Wire.read()) / MPU6050_ACCEL_LSB_SENSITIVITY;
  
  // Calculating Roll and Pitch from the accelerometer data
  g_accAngleX = (atan(g_accY / sqrt(pow(g_accX, 2) + pow(g_accZ, 2))) * 180 / PI) + g_accCorrectionOffset.X;
  g_accAngleY = (atan(-1 * g_accX / sqrt(pow(g_accY, 2) + pow(g_accZ, 2))) * 180 / PI) + g_accCorrectionOffset.Y;

  //Compute period from last acquisition
  g_previousTime = g_currentTime;        // Previous time is stored before the actual time read
  g_currentTime = millis();            // Current time actual time read
  g_elapsedTime = (g_currentTime - g_previousTime) / 1000; // Divide by 1000 to get seconds

  //Read gyroscope data
  Wire.beginTransmission(MPU6050_I2C_ADDRESS);
  Wire.write(MPU6050_REGISTER_ADDRESS_GYRO_XOUT_H);
  Wire.endTransmission(false);
  Wire.requestFrom(MPU6050_I2C_ADDRESS, 6, true); // Read 6 registers from GYRO_XOUT_H (GYRO_XOUT_H, GYRO_XOUT_L, GYRO_YOUT_H, GYRO_YOUT_L, GYRO_ZOUT_H, GYRO_ZOUT_L)

  //For a 250deg/s range, divide raw value by GYRO_LSB_SENSITIVITY (according to the datasheet)
  g_gyroX = (Wire.read() << 8 | Wire.read()) / MPU6050_GYRO_LSB_SENSITIVITY;
  g_gyroY = (Wire.read() << 8 | Wire.read()) / MPU6050_GYRO_LSB_SENSITIVITY;
  g_gyroZ = (Wire.read() << 8 | Wire.read()) / MPU6050_GYRO_LSB_SENSITIVITY;
  
  //Correct the outputs with the calculated error values
  g_gyroX = g_gyroX + g_gyroCorrectionOffset.X;
  g_gyroY = g_gyroY + g_gyroCorrectionOffset.Y;
  g_gyroZ = g_gyroZ + g_gyroCorrectionOffset.Z;
  
  //Currently the raw values are in degrees per seconds, deg/s, so we need to multiply by sendonds (s) to get the angle in degrees
  g_gyroAngleX = g_gyroAngleX + g_gyroX * g_elapsedTime; // deg/s * s = deg
  g_gyroAngleY = g_gyroAngleY + g_gyroY * g_elapsedTime;
  g_yaw =  g_yaw + g_gyroZ * g_elapsedTime;
  
  //Complementary filter - combine acceleromter and gyro angle values
  g_gyroAngleX = 0.96 * g_gyroAngleX + 0.04 * g_accAngleX;
  g_gyroAngleY = 0.96 * g_gyroAngleY + 0.04 * g_accAngleY;

  g_roll = g_gyroAngleX;
  g_pitch = g_gyroAngleY;

#ifdef DEBUG_SERIAL  
  // Print the values on the serial monitor
  Serial.print("accX=");
  Serial.print(g_accX);
  Serial.print("/accY=");
  Serial.print(g_accY);
  Serial.print("/accZ=");
  Serial.print(g_accZ);  
  Serial.print("    ");
  Serial.print("roll=");
  Serial.print(g_roll);
  Serial.print("/pitch=");
  Serial.print(g_pitch);
  Serial.print("/yaw=");
  Serial.println(g_yaw);
#endif

  UpdateStatistics();  

  g_updateDisplay++;
  if(g_updateDisplay >= 100)
  {//Do not display value eachtime to avoid LCD to blink
    g_updateDisplay = 0;
    switch(g_displayMode)
    {
      case 0:
        DisplayRollAndLinear();        
        break;
      case 1:        
        DisplayRollAndPitch();        
        break;
      case 2:        
        DisplayLinearAndCentrifugal();
        break;
    }
  }
}

//Function  
void AutoCalibrate()
{     
  static float AccX, AccY, AccZ = 0.0;
  static float GyroX, GyroY, GyroZ = 0.0;

  static float AccErrorX, AccErrorY = 0.0;
  static float GyroErrorX, GyroErrorY, GyroErrorZ = 0.0;

  //Read accelerometer values X times
  int sample  = 0;
  while (sample < MPU6050_CALIBRATION_SAMPLE_COUNT) 
  {
    Wire.beginTransmission(MPU6050_I2C_ADDRESS);
    Wire.write(MPU6050_REGISTER_ADDRESS_ACCEL_XOUT_H);
    Wire.endTransmission(false);
    Wire.requestFrom(MPU6050_I2C_ADDRESS, 6, true);
    
    AccX = (Wire.read() << 8 | Wire.read()) / MPU6050_ACCEL_LSB_SENSITIVITY;
    AccY = (Wire.read() << 8 | Wire.read()) / MPU6050_ACCEL_LSB_SENSITIVITY;  
    AccZ = (Wire.read() << 8 | Wire.read()) / MPU6050_ACCEL_LSB_SENSITIVITY;
    
    //Sum all readings
    AccErrorX = AccErrorX + ((atan((AccY) / sqrt(pow((AccX), 2) + pow((AccZ), 2))) * 180 / PI));
    AccErrorY = AccErrorY + ((atan(-1 * (AccX) / sqrt(pow((AccY), 2) + pow((AccZ), 2))) * 180 / PI));
    sample++;
  }
  
  AccErrorX = AccErrorX / MPU6050_CALIBRATION_SAMPLE_COUNT;
  AccErrorY = AccErrorY / MPU6050_CALIBRATION_SAMPLE_COUNT;  
  
  //Read gyroscope values X times
  sample = 0;
  while (sample < MPU6050_CALIBRATION_SAMPLE_COUNT) 
  {
    Wire.beginTransmission(MPU6050_I2C_ADDRESS);
    Wire.write(MPU6050_REGISTER_ADDRESS_GYRO_XOUT_H);
    Wire.endTransmission(false);
    Wire.requestFrom(MPU6050_I2C_ADDRESS, 6, true);
       
    GyroX = Wire.read() << 8 | Wire.read();
    GyroY = Wire.read() << 8 | Wire.read();
    GyroZ = Wire.read() << 8 | Wire.read();
    // Sum all readings
    GyroErrorX = GyroErrorX + (GyroX / MPU6050_GYRO_LSB_SENSITIVITY);
    GyroErrorY = GyroErrorY + (GyroY / MPU6050_GYRO_LSB_SENSITIVITY);
    GyroErrorZ = GyroErrorZ + (GyroZ / MPU6050_GYRO_LSB_SENSITIVITY);
    sample++;
  }
  
  GyroErrorX = GyroErrorX / MPU6050_CALIBRATION_SAMPLE_COUNT;
  GyroErrorY = GyroErrorY / MPU6050_CALIBRATION_SAMPLE_COUNT;
  GyroErrorZ = GyroErrorZ / MPU6050_CALIBRATION_SAMPLE_COUNT;

  g_accCorrectionOffset.X = AccErrorX * -1;
  g_accCorrectionOffset.Y = AccErrorY * -1;

  g_gyroCorrectionOffset.X = GyroErrorX * -1;
  g_gyroCorrectionOffset.Y = GyroErrorY * -1;
  g_gyroCorrectionOffset.Z = GyroErrorZ * -1;    

#ifdef DEBUG_SERIAL
  // Print the error values on the Serial Monitor
  Serial.print("AccErrorX: ");
  Serial.println(AccErrorX);
  Serial.print("AccErrorY: ");
  Serial.println(AccErrorY);
  Serial.print("GyroErrorX: ");
  Serial.println(GyroErrorX);
  Serial.print("GyroErrorY: ");
  Serial.println(GyroErrorY);
  Serial.print("GyroErrorZ: ");
  Serial.println(GyroErrorZ);   
#endif  
}

void ResetStatistics()
{
  g_statisticLeftRoll = 0;    
  g_statisticRightRoll = 0;
  g_statisticLeftPitch = 0;
  g_statisticRightPitch = 0;   

  g_accMinX = 0;
  g_accMaxX = 0;
  g_accMinY = 0;
  g_accMaxY = 0;
}

void UpdateStatistics()
{  
  if(g_roll < g_statisticLeftRoll)
  {
    g_statisticLeftRoll = g_roll;
  }
  else if(g_roll > g_statisticRightRoll)
  {
    g_statisticRightRoll = g_roll;
  }

  if(g_pitch < g_statisticLeftPitch)
  {
    g_statisticLeftPitch = g_pitch;
  }
  else if(g_pitch > g_statisticRightPitch)
  {
    g_statisticRightPitch = g_pitch;
  }

  if(g_accX < g_accMinX)
    g_accMinX = g_accX;
  else if(g_accX > g_accMaxX)
    g_accMaxX = g_accX;

  if(g_accY < g_accMinY)
    g_accMinY = g_accY;
  else if(g_accY > g_accMaxY)
    g_accMaxY = g_accY;  
    
}


//Display
void DisplayMode()
{    
  switch(g_displayMode)
  {
    case 0:
      g_lcd.clear();    
      g_lcd.setCursor(0, 0);
      g_lcd.print("ROLL");
      g_lcd.setCursor(0, 1);
      g_lcd.print("& LINEAR");
      delay(1000);     
    break;
    case 1:
      g_lcd.clear();    
      g_lcd.setCursor(0, 0);
      g_lcd.print("ROLL");
      g_lcd.setCursor(0, 1);
      g_lcd.print("& PITCH");
      delay(1000);     
    break;
    case 2:
      g_lcd.clear();    
      g_lcd.setCursor(0, 0);
      g_lcd.print("LINEAR");
      g_lcd.setCursor(0, 1);
      g_lcd.print("& CENTRIFUGAL");
      delay(1000);     
    break;    
  }    
}
void DisplayRollAndPitch() 
{
  int roll = g_roll;
  int pitch = g_pitch;
  
  roll = abs(roll);
  if(roll > MAX_ROLL)
    roll = MAX_ROLL;
    
  pitch = abs(pitch);
  if(pitch > MAX_PITCH)
    pitch = MAX_PITCH;         

  int statisticLeftRoll = abs(g_statisticLeftRoll);
  if(statisticLeftRoll > MAX_ROLL)
    statisticLeftRoll = MAX_ROLL;
   
  int statisticRightRoll = abs(g_statisticRightRoll);
  if(statisticRightRoll > MAX_ROLL)
    statisticRightRoll = MAX_ROLL;

  int statisticLeftPitch = abs(g_statisticLeftPitch);
  if(statisticLeftPitch > MAX_PITCH)
    statisticLeftPitch = MAX_PITCH;
    
  int statisticRightPitch = abs(g_statisticRightPitch);    
  if(statisticRightPitch > MAX_PITCH)
    statisticRightPitch = MAX_PITCH;

  char buffer[3];
    
  g_lcd.clear();
  g_lcd.setCursor(0, 0);
  g_lcd.print("R:");
  snprintf(buffer,sizeof(buffer), "%d", roll);
  g_lcd.print(buffer);
  g_lcd.print((char)223);

  g_lcd.setCursor(11, 0);
  snprintf(buffer,sizeof(buffer), "%02d", statisticLeftRoll);
  g_lcd.print(buffer);  
  g_lcd.print("/");
  snprintf(buffer,sizeof(buffer), "%02d", statisticRightRoll);
  g_lcd.print(buffer);  

  g_lcd.setCursor(0, 1);
  g_lcd.print("P:");
  snprintf(buffer,sizeof(buffer), "%d", pitch);
  g_lcd.print(buffer);
  g_lcd.print((char)223);   

  g_lcd.setCursor(11, 1);
  snprintf(buffer,sizeof(buffer), "%02d", statisticLeftPitch);
  g_lcd.print(buffer);  
  g_lcd.print("/");
  snprintf(buffer,sizeof(buffer), "%02d", statisticRightPitch);
  g_lcd.print(buffer);  
}
void DisplayLinearAndCentrifugal()
{    
  g_lcd.clear();
  g_lcd.setCursor(0, 0);
  g_lcd.print("L:");

  if(g_accX < 0)
    g_lcd.setCursor(2, 0);
  else
    g_lcd.setCursor(3, 0);
  
  g_lcd.print(g_accX, 1);
  g_lcd.print("g");

  g_lcd.setCursor(8, 0);
  g_lcd.print(g_accMinX,1);  
  g_lcd.print("/"); 
  g_lcd.print(g_accMaxX,1);  

  g_lcd.setCursor(0, 1);
  g_lcd.print("C:");

  if(g_accY < 0)
    g_lcd.setCursor(2, 1);
  else
    g_lcd.setCursor(3, 1);
  
  g_lcd.print(g_accY, 1);
  g_lcd.print("g");

  g_lcd.setCursor(8, 1);
  g_lcd.print(g_accMinY,1);  
  g_lcd.print("/"); 
  g_lcd.print(g_accMaxY,1); 
}
void DisplayRollAndLinear()
{
  g_lcd.clear();
  int roll = g_roll;
 
  roll = abs(roll);
  if(roll > MAX_ROLL)
    roll = MAX_ROLL;
    
  int statisticLeftRoll = abs(g_statisticLeftRoll);
  if(statisticLeftRoll > MAX_ROLL)
    statisticLeftRoll = MAX_ROLL;
   
  int statisticRightRoll = abs(g_statisticRightRoll);
  if(statisticRightRoll > MAX_ROLL)
    statisticRightRoll = MAX_ROLL;
 
  char buffer[3];
    
  g_lcd.clear();
  g_lcd.setCursor(0, 0);
  g_lcd.print("R: ");
  snprintf(buffer,sizeof(buffer), "%d", roll);
  g_lcd.print(buffer);
  g_lcd.print((char)223);

  g_lcd.setCursor(11, 0);
  snprintf(buffer,sizeof(buffer), "%02d", statisticLeftRoll);
  g_lcd.print(buffer);  
  g_lcd.print("/");
  snprintf(buffer,sizeof(buffer), "%02d", statisticRightRoll);
  g_lcd.print(buffer);  

  g_lcd.setCursor(0, 1);
  g_lcd.print("L:");

  if(g_accX < 0)
    g_lcd.setCursor(2, 1);
  else
    g_lcd.setCursor(3, 1);
  
  g_lcd.print(g_accX, 1);
  g_lcd.print("g");

  g_lcd.setCursor(8, 1);
  g_lcd.print(g_accMinX,1);  
  g_lcd.print("/"); 
  g_lcd.print(g_accMaxX,1); 
}
Ceux qui veulent aller plus loin je pense que la piste est celle ci
https://bitbucket.org/cinqlair/mpu9250/ ... ckAHRS.cpp

++
Avatar du membre
PEagle
Pilote Grand Prix
Pilote Grand Prix
Messages : 5767
Enregistré le : sam. 09 oct., 2010 19:54
Moto : KawaTM Zx6r K7 orange

Fabrication d'un inclinomètre

Message par PEagle »

Echec, c'est à dire, il te fait quoi ?
A reçu 26 :tusors:
Image
watoubilly
Pilote 50 cm3
Pilote 50 cm3
Messages : 52
Enregistré le : jeu. 22 oct., 2020 19:52

Fabrication d'un inclinomètre

Message par watoubilly »

J'ai peut être parlé un peu vite, j'ai des mauvaises valeurs d'angle mais j'arrive en buté sur l'accélération donc normale que le roll et le pitch est faux puisque je fais du filtrage qui utilise l'accélération.

Avec mon SV650 j'ai une accélération supérieure à 2G. ;) Je vais changer l'échelle de mesure pour ne plus arriver en limite et je retesterai.
D'après tes recherches tu vois un truc pas bon toi ?

A noter qu'en statique (pas sur une moto) tout est OK enfin comme avec l'accéléromètre seul.

EDIT: Petit test dans le garage à l'accélération j'ai 2.7G et un roll qui monte pas tt seul.
Je testerai sur route demain si j'ai le temps.
Avatar du membre
PEagle
Pilote Grand Prix
Pilote Grand Prix
Messages : 5767
Enregistré le : sam. 09 oct., 2010 19:54
Moto : KawaTM Zx6r K7 orange

Fabrication d'un inclinomètre

Message par PEagle »

Je n'ai pas regardé le code, ça fait très longtemps que je n'ai pas codé et je ne crois pas connaitre celui la.
Par contre, pourquoi utiliser l'accéléromètre? Teste d'abord avec le gyro et vois comment il dérive, tu pourra voir après comment faire si la dérive est grande.
A reçu 26 :tusors:
Image
Répondre