[PROJET GYROPODE] Robot équilibriste : Magellan !
Débuté par Esprit, janv. 01 2011 06:43
160 réponses à ce sujet
#101
Posté 23 mars 2011 - 11:36
Voici un lien qui pourra peut etre t'aider pour lire les valeurs de tes capteurs : http://www.varesano.net/blog/fabio/my-first-6-dof-imu-sensors-fusion-implementation-adxl345-itg3200-arduino-and-processing
Sinon j'ai bien aimé le "-Déco, leds, engrenages pour faire steampunk,... : A FAIRE.. "
C'est aussi un truc que j'ai dans mes projets a chaque fois, faire de la déco, mais ca passe à la trappe à tous les coup faute de temps :D
Sinon j'ai bien aimé le "-Déco, leds, engrenages pour faire steampunk,... : A FAIRE.. "
C'est aussi un truc que j'ai dans mes projets a chaque fois, faire de la déco, mais ca passe à la trappe à tous les coup faute de temps :D
#102
Posté 24 mars 2011 - 07:43
J'ai regardé les explications sur ton lien, j'ai téléchargé son code et j'ai essayé. Déjà c'est cool, le code se compile sans erreurs.
Quand je regarde le terminal de communication, ça me donne :
f:182DD43D,f:0BB7BA3D,f:EE8C7D3F,f:3C470A44,f:C4B85F42,f:6666E641,f:F89D30BF,f:9C332E3F,f:D0DC7C3E,f:636C2244,f:0C1C8C42,f:023529BF,f:19B52B3F,f:F44BAC3E,
f:D516D63D,f:7745AB3D,f:19B27D3F,f:3C470A44,f:C4B85F42,f:6666E641,f:7137F2BE,f:1B9C303F,f:07470CBF,f:8F331144,f:9A750043,f:8641F9BE,f:201A3C3F,f:B0D6F1BE,
f:5313753D,f:A352EC3D,f:04D47D3F,f:3C470A44,f:C4B85F42,f:6666E641,f:676F023F,f:E499EEBD,f:0A405ABF,f:6091FE43,f:16C83B43,f:D79D0F3F,f:19F2E9BD,f:A4E451BF,
...[/size]
Euh... Et au départ, ça défilait super vite, il n'y avait pas de tempo dans son programme.
Mais j'ai un peu de mal à voir à quoi tout ça correspond.
Dans le code, il met :
serialPrintFloatArr(Gyro_ds, 3);
serialPrintFloatArr(RwGyro, 3);
serialPrintFloatArr(Awz, 2);
serialPrintFloatArr(RwEst, 3);
Serial.println();[/code]
Bon, il y a de l'avancement !
J'arrive à avoir des trucs qui viennent apparemment de l'accéléromètre et du gyroscope, chose que je n'arrivais pas à faire auparavant.
Il reste à comprendre ce que je reçois et à le rendre utilisable... :tare:
Quand je regarde le terminal de communication, ça me donne :
f:182DD43D,f:0BB7BA3D,f:EE8C7D3F,f:3C470A44,f:C4B85F42,f:6666E641,f:F89D30BF,f:9C332E3F,f:D0DC7C3E,f:636C2244,f:0C1C8C42,f:023529BF,f:19B52B3F,f:F44BAC3E,
f:D516D63D,f:7745AB3D,f:19B27D3F,f:3C470A44,f:C4B85F42,f:6666E641,f:7137F2BE,f:1B9C303F,f:07470CBF,f:8F331144,f:9A750043,f:8641F9BE,f:201A3C3F,f:B0D6F1BE,
f:5313753D,f:A352EC3D,f:04D47D3F,f:3C470A44,f:C4B85F42,f:6666E641,f:676F023F,f:E499EEBD,f:0A405ABF,f:6091FE43,f:16C83B43,f:D79D0F3F,f:19F2E9BD,f:A4E451BF,
...[/size]
Euh... Et au départ, ça défilait super vite, il n'y avait pas de tempo dans son programme.
Mais j'ai un peu de mal à voir à quoi tout ça correspond.
Dans le code, il met :
serialPrintFloatArr(Gyro_ds, 3);
serialPrintFloatArr(RwGyro, 3);
serialPrintFloatArr(Awz, 2);
serialPrintFloatArr(RwEst, 3);
Serial.println();[/code]
Bon, il y a de l'avancement !
J'arrive à avoir des trucs qui viennent apparemment de l'accéléromètre et du gyroscope, chose que je n'arrivais pas à faire auparavant.
Il reste à comprendre ce que je reçois et à le rendre utilisable... :tare:
#103
Posté 24 mars 2011 - 08:19
Bon moi qui pensais voir Magellan se balader dans la foule a Caprica3, c'est raté apparemment ! ^^
Content que tu progresses avec tes capteurs ;)
C'est sacrément moche les valeurs que ca te sort en tout cas :D
Je pense que les 3 premieres valeurs sont x, y, z de l'accelerometre (mais en hexa a chaque fois) les 3 suivant x, y, z du gyro etc...
Voila dans l'ordre ce que ca te sort :
float RwAcc[3]; //projection of normalized gravitation force vector on x/y/z axis, as measured by accelerometer (3 valeurs)
float Gyro_ds[3]; //Gyro readings (3 valeurs)
float RwGyro[3]; //Rw obtained from last estimated value and gyro movement (3 valeurs)
float Awz[2]; //angles between projection of R on XZ/YZ plane and Z axis (deg) (2 valeurs)
float RwEst[3]; // ?? l'estime de quelque chose je suppose :p (3 valeurs)
Si tu veux afficher quelque chose de plus lisible pour l'etre humain, modifies la fonction "serialFloatPrint" en faisant juste un Serial.print(f);
Content que tu progresses avec tes capteurs ;)
C'est sacrément moche les valeurs que ca te sort en tout cas :D
Je pense que les 3 premieres valeurs sont x, y, z de l'accelerometre (mais en hexa a chaque fois) les 3 suivant x, y, z du gyro etc...
Voila dans l'ordre ce que ca te sort :
float RwAcc[3]; //projection of normalized gravitation force vector on x/y/z axis, as measured by accelerometer (3 valeurs)
float Gyro_ds[3]; //Gyro readings (3 valeurs)
float RwGyro[3]; //Rw obtained from last estimated value and gyro movement (3 valeurs)
float Awz[2]; //angles between projection of R on XZ/YZ plane and Z axis (deg) (2 valeurs)
float RwEst[3]; // ?? l'estime de quelque chose je suppose :p (3 valeurs)
Si tu veux afficher quelque chose de plus lisible pour l'etre humain, modifies la fonction "serialFloatPrint" en faisant juste un Serial.print(f);
#108
Posté 25 mars 2011 - 01:08
J'ai commencé à essayer de remettre en forme tous les petits bouts de codes que j'ai accumulé.
Je veux faire une librairie par capteur. Donc trois librairies à faire/refaire. Le but étant d'uniformiser un peu mes différentes sources et arriver à quelque chose de plus facilement utilisable.
Suite au prochain épisode. ;)
Je veux faire une librairie par capteur. Donc trois librairies à faire/refaire. Le but étant d'uniformiser un peu mes différentes sources et arriver à quelque chose de plus facilement utilisable.
Suite au prochain épisode. ;)
#114
Posté 29 mars 2011 - 09:36
Bon, je me bats avec l'accéléromètre pour qu'il m'affiche une valeur en "g" ou en "mg".
Je sais que sa précision est de 4mg/LSB et qu'il me renvoie une valeur sur deux byte avec 10 bits utiles.
Je me base sur le code qui se trouve sur le site Code Young.
Voici le code :
Je sais que sa précision est de 4mg/LSB et qu'il me renvoie une valeur sur deux byte avec 10 bits utiles.
Je me base sur le code qui se trouve sur le site Code Young.
Voici le code :
#define DEVICE (0x53) //ADXL345 device address
#define TO_READ (6) //num of bytes we are going to read each time (two bytes for each axis)
byte buff[TO_READ] ; //6 bytes buffer for saving data read from the device
char str[512]; //string buffer to transform data before sending it to the serial port
void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial for output
//Turning on the ADXL345
writeTo(DEVICE, 0x2D, 0);
writeTo(DEVICE, 0x2D, 16);
writeTo(DEVICE, 0x2D, 8);
}
void loop()
{
int regAddress = 0x32; //first axis-acceleration-data register on the ADXL345
int x, y, z;
readFrom(DEVICE, regAddress, TO_READ, buff); //read the acceleration data from the ADXL345
//each axis reading comes in 10 bit resolution, ie 2 bytes. Least Significat Byte first!!
//thus we are converting both bytes in to one int
x = (((int)buff[1]) << 8) | buff[0];
y = (((int)buff[3])<< 8) | buff[2];
z = (((int)buff[5]) << 8) | buff[4];
//we send the x y z values as a string to the serial port
sprintf(str, "%d %d %d", x, y, z);
Serial.print(str);
Serial.print(10, BYTE);
//It appears that delay is needed in order not to clog the port
delay(15);
}
//---------------- Functions
//Writes val to address register on device
void writeTo(int device, byte address, byte val) {
Wire.beginTransmission(device); //start transmission to device
Wire.send(address); // send register address
Wire.send(val); // send value to write
Wire.endTransmission(); //end transmission
}
//reads num bytes starting from address register on device in to buff array
void readFrom(int device, byte address, int num, byte buff[]) {
Wire.beginTransmission(device); //start transmission to device
Wire.send(address); //sends address to read from
Wire.endTransmission(); //end transmission
Wire.beginTransmission(device); //start transmission to device
Wire.requestFrom(device, num); // request 6 bytes from device
int i = 0;
while(Wire.available()) //device may send less than requested (abnormal)
{
buff[i] = Wire.receive(); // receive a byte
i++;
}
Wire.endTransmission(); //end transmission
}[/code]
Il me renvoie donc une valeur binaire du genre : "xxxxxx 01 00 10 11 10". Cette valeur est retransformée en valeur décimale et j'affiche quelque chose entre -512 et 512, si je ne me trompe pas.
Là où ça se corse, c'est que je voudrais afficher cette valeur en "g" ou "mg".
(Je sais, il y a un code où ça marchait... Ben je le retrouve plus !!! :( )
Je cherche sur le net mais si vous avez une solution, je suis preneur.
#115
Posté 29 mars 2011 - 09:41
[quote"Esprit"]
(Je sais, il y a un code où ça marchait... Ben je le retrouve plus !!! :( )
[/quote]
Bah bravo c'etait bien la peine de faire joujou avec le code a Caprica :D
Le code qui marchait venait du lien que je t'avais donné et on avait modifié juste les printfloat pour que ca renvoit des valeurs lisible.
Sinon, logiquement la valeur que tu obtiens, tu la multiplie par 4, et tu obtiens la valeur en mg (donc de -2g a +2g apparemment).
(Je sais, il y a un code où ça marchait... Ben je le retrouve plus !!! :( )
[/quote]
Bah bravo c'etait bien la peine de faire joujou avec le code a Caprica :D
Le code qui marchait venait du lien que je t'avais donné et on avait modifié juste les printfloat pour que ca renvoit des valeurs lisible.
Sinon, logiquement la valeur que tu obtiens, tu la multiplie par 4, et tu obtiens la valeur en mg (donc de -2g a +2g apparemment).
#116
Posté 29 mars 2011 - 09:50
Oulà, je vais aller me coucher moi... Plus capable de faire fois 4...
J'essayais d'afficher en g et donc un truc du genre "0,84g" et je n'ai pas réussis à afficher en float.
Mais en mg, c'est vrai que c'est bien plus simple. Il faut que j'arrête d'essayer de me prendre la tête. :D
Le code modifié :
z = (((int)buff[5]) << 8) | buff[4];
x = x*4;
y = y*4;
z = z*4;
//we send the x y z values as a string to the serial port
sprintf(str, "x : %dmg; y : %dmg; z : %dmg", x, y, z);
Serial.print(str);
Serial.print(10, BYTE);[/code]
[Edit : J'oubliais. Effectivement c'est +-2g pour l'instant. Le capteur peut aller jusqu'à +-16g mais par défaut c'est +-2g. ;)
J'essayais d'afficher en g et donc un truc du genre "0,84g" et je n'ai pas réussis à afficher en float.
Mais en mg, c'est vrai que c'est bien plus simple. Il faut que j'arrête d'essayer de me prendre la tête. :D
Le code modifié :
y = (((int)buff[3])<< 8) | buff[2];
z = (((int)buff[5]) << 8) | buff[4];
x = x*4;
y = y*4;
z = z*4;
//we send the x y z values as a string to the serial port
sprintf(str, "x : %dmg; y : %dmg; z : %dmg", x, y, z);
Serial.print(str);
Serial.print(10, BYTE);[/code]
[Edit : J'oubliais. Effectivement c'est +-2g pour l'instant. Le capteur peut aller jusqu'à +-16g mais par défaut c'est +-2g. ;)
#119
Posté 30 mars 2011 - 09:33
Bon, l'accéléromètre marche et le magnétomètre me renvoient quelque chose de valable. Je n'ai pas encore transformé ses résultats en valeurs utilisables mais c'est un détail...
Par contre, le gyroscope ne marche pas.
Lui, il me renvoie les mêmes valeurs, quoi que je fasse...
Voici le code :
Par contre, le gyroscope ne marche pas.
Lui, il me renvoie les mêmes valeurs, quoi que je fasse...
Voici le code :
// I2C library, gyroscope
#define GYRO_ADDR 0x69 // gyro address, binary = 11101001 when AD0 is connected to Vcc (see schematics of your breakout board)
#define SMPLRT_DIV 0x15
#define DLPF_FS 0x16
#define INT_CFG 0x17
#define PWR_MGM 0x3E
#define TO_READ 8 // 2 bytes for each axis x, y, z
// offsets are chip specific.
int offx = 120;
int offy = 20;
int offz = 93;
//initializes the gyroscope
void initGyro()
{
/*****************************************
* ITG 3200
* power management set to:
* clock select = internal oscillator
* no reset, no sleep mode
* no standby mode
* sample rate to = 125Hz
* parameter to +/- 2000 degrees/sec
* low pass filter = 5Hz
* no interrupt
******************************************/
writeTo(GYRO_ADDR, PWR_MGM, 0x00);
writeTo(GYRO_ADDR, SMPLRT_DIV, 0x07); // EB, 50, 80, 7F, DE, 23, 20, FF
writeTo(GYRO_ADDR, DLPF_FS, 0x1E); // +/- 2000 dgrs/sec, 1KHz, 1E, 19
writeTo(GYRO_ADDR, INT_CFG, 0x00);
}
void getGyroscopeData()
{
/**************************************
Gyro ITG-3200 I2C
registers:
temp MSB = 1B, temp LSB = 1C
x axis MSB = 1D, x axis LSB = 1E
y axis MSB = 1F, y axis LSB = 20
z axis MSB = 21, z axis LSB = 22
*************************************/
int regAddress = 0x1B;
int temp, x, y, z;
byte buff[TO_READ];
char str[50]; // 50 should be enough to store all the data from the gyro
readFrom(GYRO_ADDR, regAddress, TO_READ, buff); //read the gyro data from the ITG3200
temp = (buff[0] << 8) | buff[1];
x = ((buff[2] << 8) | buff[3]) + offx;
y = ((buff[4] << 8) | buff[5]) + offy;
z = ((buff[6] << 8) | buff[7]) + offz;
//we send the x y z values as a string to the serial port
sprintf(str, "t : %d;\t x : %d;\t y : %d;\t z : %d", temp, x, y, z);
Serial.print(str);
Serial.print(10, BYTE);
}
void setup()
{
Serial.begin(9600);
Wire.begin();
initGyro();
}
void loop()
{
getGyroscopeData();
delay(1000);
}
//---------------- Functions
//Writes val to address register on device
void writeTo(int device, byte address, byte val) {
Wire.beginTransmission(device); //start transmission to device
Wire.send(address); // send register address
Wire.send(val); // send value to write
Wire.endTransmission(); //end transmission
}
//reads num bytes starting from address register on device in to buff array
void readFrom(int device, byte address, int num, byte buff[]) {
Wire.beginTransmission(device); //start transmission to device
Wire.send(address); //sends address to read from
Wire.endTransmission(); //end transmission
Wire.beginTransmission(device); //start transmission to device
Wire.requestFrom(device, num); // request 6 bytes from device
int i = 0;
while(Wire.available()) //device may send less than requested (abnormal)
{
buff[i] = Wire.receive(); // receive a byte
i++;
}
Wire.endTransmission(); //end transmission
}
[/code]
J'ai vu qu'il allait chercher les "Data Output" à partir du registre 0x1B. De là, il va prendre 8 bytes d'informations. (température, x, y et z, chacun sur deux bytes). Donc il balaie de 0x1B à 0x22. Jusque là, d'accord. Il stocke tout ça dans les buffer (de buff[0] à buff[7]).
C'est quoi le "offx" ?
Il y a ça dans le code, un peu plus haut :
int offx = 120;
int offy = 20;
int offz = 93;[/code]
Mais ça ne me dit pas ce que c'est...
Bref, je patauge.
Une idée de pourquoi il me renvoie toujours les mêmes valeurs ?
J'ai un jour fait une erreur, j'ai branché le capteur sur le 5V au lieu du 3,3V... J'espère que je n'ai pas grillé le gyroscope...
Normalement ça devrait aller, j'ai lu sur le site de Sparkfun que ça ne devrait pas poser problèmes mais quand même... :(
[Edit :
Voilà ce que me renvoie le gyroscope :
t : -2089; x : -16337; y : 8114; z : 16076
J'ai éteint, rebranché, réenvoyé le code, ... Rien ne change, mêmes valeurs... :(
[Edit2 :
J'ai changé de local, du coup les valeurs ont changées... Mais après, ça ne change plus. J'ai redébranché, réenvoyé le code, ... Pareil.
t : 23862; x : 13745; y : -9675; z : -3395
J'ai trouvé le premier capteur de local... :D
Et sinon, j'ai vérifié sur le schéma fonctionnel de l'IMU. Il y a un régulateur Vcc>3,3V. Donc il ne devrait y avoir aucun problème pour le fait que j'aie mis du 5V dessus.
#120
Posté 30 mars 2011 - 01:12
L'offset, c'est le décalage du capteur par rapport a 0, en gros, de par l’imprécision de la conception, le capteur "a froid" et immobile te renverrais des valeurs différente de 0. donc, on calibre l'engin en ajoutant le décalage ( pratiquement fixe ) observé en 0.
Répondre à ce sujet
1 utilisateur(s) li(sen)t ce sujet
0 members, 1 guests, 0 anonymous users