Lecture de données IMU et anémomètre avec une carte ARDUINO UNO

Bonjour,

Je dispose d’un IMU (Inertial Measurement System) 9DOF Sparkfun (http://www.sparkfun.com/products/9623; http://www.sparkfun.com/datasheets/Sensors/IMU/9DOF-Razor-v14.pdf), d’un anémomètre sonique Young model 81000 (http://www.campbellsci.ca/Catalogue/81000_Man.pdf) ainsi que d’une carte ARDUINO UNO.
Mon objectif est d’envoyer un programme à la carte pour pouvoir lire les données de l’IMU et de l’anémomètre simultanément.

Les données brutes en sortie de l’IMU sont de la forme : (Roll Pitch Yaw ?x ?y ?z AccX AccY AccZ MagX MagY MagZ)
48.78 1.62 81.41 -1.85 0.51 -0.87 -7.56 192.42 171.32 59 -725 -213
48.66 1.66 81.45 -2.56 1.07 -1.25 -5.56 195.42 169.32 60 -726 -214
48.42 1.61 81.50 -8.87 0.76 -0.54 -5.56 214.42 169.32 60 -726 -214
48.03 1.55 81.55 -22.15 0.62 -0.33 -5.56 215.42 170.32 60 -726 -214

Les données brutes en sortie de l’anémomètre sont de la forme : (Vx Vy Vz Température)
0.01 0.03 0.01 22.3
-0.01 0.01 0.02 22.4
0.03 0.02 0.03 21.8

. Comment puis-je récupérer ces données de type ‘char’ avec la carte ARDUINO UNO, sachant que je ne dispose que d’un seul port série (Tx, Rx).
. Est-il possible de créer un deuxième port série sur la carte ARDUINO ?
. Comment feriez-vous pour relier l’IMU à la carte, et l’anémomètre à la même carte, i.e. quel fil sur quelle broche ?
. Connaissez-vous un exemple de code qui aurait déjà permis de traiter ce problème ?

L’objectif étant à partir des données de l’IMU et de l’anémomètre, de pouvoir afficher sur le moniteur série les données sous cette forme :
(Roll Pitch Yaw ?x ?y ?z AccX AccY AccZ MagX MagY MagZ Vx Vy Vz Température)

Le principal problème réside essentiellement dans l’acquisition des données par la carte ARDUINO.

Dans l’attente de vous lire. Merci.

Boris

54050-sen-10010-300_pl.jpg

Bonjour,

J'ai aussi un imu 9dof de spakfun, de base il faudra le reprogrammer avec le firmware IMU (voir lien google code sur la page sparkfun).

Dans ton câblage prend la plus grande prudence ! L'IMU est en 3v3 et l'arduino en 5V, sur RX aucun probléme 3v3 -> 5v mais tx ne doit pas être cablé ! (5v -> 3v3 = BOOM !). Tu cable 3v3 arduino -> vcc IMU, tx imu -> rx arduino (ou rx softserial) et c'est tout.

Aprés niveau utilisation c'est pas compliquer chaque trame a une longueur max fixe (de mémoire je sais plus) donc tu fait un char buffer[TAILLE_MAX] que tu le remplis avec les donnée série au fur et à mesure, quand tu reçois le ! qui annonce une nouvelle trame tu stop le remplissage et tu parse les donnée acquise (!ANG:valeur,valeur,...).

Bonjour,

Merci de ta réponse. J'essayerai de faire un code avec cette librairie demain matin car ici en Nouvelle-Zélande c'est déjà la nuit. Pour l'utilisation de l'IMU, c'est assez simple, tu peux le brancher directement sur ton PC à l'aide d'un convertisseur USB/FTDI. Le code source que tu télécharge se trouve à cette adresse : http://code.google.com/p/sf9domahrs/downloads/list J'utilise la version 1_0 du code. Une fois téléchargé, tu peux lire et modifier le code à l'aide du logiciel ARDUINO. Tu le charges ensuite sur ton IMU et tu reçois sur le moniteur série les infos que tu as codées dans l'onglet 'OUTPUT'.

Les infos sur les angles et les vitesses de rotation sont assez bonnes et le programme permet de corriger le biais du gyroscope. En ce qui concerne l'accélération, c'est un peu moyen lorsque les accélérations sont faibles, car les signaux sont très bruités. Toutefois en utilisant un filtre de Kalman par exemple, on peut réussir a obtenir quelque chose d'un peut plus "lissé" et donc plus exploitable.

A plus Boris

Bonjour,

Merci pour les indications sur le câblage.
Le moniteur série ne pouvant être réglé que sur une seule vitesse, comment puis-je afficher les valeurs de l’IMU et de l’anémomètre sachant que leurs ports série respectifs ont des vitesses différentes ?
Pouvez-vous m’expliquer comment utiliser la fonction char buffer dans mon cas de figure ?

Mon programme peut-il commencer de la sorte ?

#include <NewSoftSerial.h>

NewSoftSerial IMU(0,1);
NewSoftSerial SONIC(2,3);

void setup()  
{
  Serial.begin(9600);
  IMU.begin(57600);
  SONIC.begin(38400);

  Serial.print("Roll Pitch Yaw Rx Ry Rz AccX AccY AccZ MagX MagY MagZ");
  Serial.print("\t");
  Serial.println("Vx Vy Vz Temperature");

  delay(100);
}

void loop()
{
      Serial.print((char)IMU.read());
      Serial.print("\t");
      Serial.print((char)SONIC.read());
}

Boris

Mauris:
Pouvez-vous m’expliquer comment utiliser la fonction char buffer dans mon cas de figure ?

J’ai fait un truc pour te donner des idée mais sans aucune garantie que ça marche directe :wink:
Fait pour le firmware 9DOF google-code de base sans la modif pour avoir les données brute.

#include <NewSoftSerial.h>

NewSoftSerial IMU(2,3);

char buffer[255];
char num[16];
char temp;
int index = 0;
int index2 = 0;

int roll, pitch, yaw;

void setup()  
{
  Serial.begin(9600);
  IMU.begin(57600);

  delay(100);
}

void loop()
{
  getDataFromIMU();
  parseDataFromIMU();
  Serial.print("ROLL");
  Serial.println(roll);
  Serial.print("PITCH");
  Serial.println(pitch);
  Serial.print("YAW");
  Serial.println(yaw);
}

void getDataFromIMU(){
  if(IMU.available() > 30){
    while(IMU.read() != '!');
    index = -1;
    IMU.read(); // A
    IMU.read(); // N
    IMU.read(); // G
    IMU.read(); // :
    while(temp != '\r'){
      temp = IMU.read();
      if(temp > 0)
        buffer[index++] = temp;
    }
    IMU.read(); // \n
    buffer[index++] = '\0';
  }
}

void parseDataFromIMU(){
  index = -1;
  index2 = -1;
  while(temp != ','){
    temp = buffer[index++];
    if(temp != '\0')
      num[index2++] = temp;
  }
  num[index2++] = '\0';
  roll = atoi(num);

  temp = 'A';
  index2 = -1;
  while(temp != ','){
    temp = buffer[index++];
    if(temp != '\0')
      num[index2++] = temp;
  }
  num[index2++] = '\0';
  pitch = atoi(num);

  temp = 'A';
  index2 = -1;
  while(temp != ','){
    temp = buffer[index++];
    if(temp != '\0')
      num[index2++] = temp;
  }
  num[index2++] = '\0';
  yaw = atoi(num);

}

Bonjour,

l’anémomètre est uniquement utilisé pour mesurer la vitesse du vent dans les 3 directions du repère lié au voilier.
L’IMU quand à lui sert à mesurer les accélérations générés par les mouvements du voilier (roulis, tangage, lacet, embardée, cavalement et pilonnement).
L’objectif étant qu’avec l’ensemble de ces données, je sois capable de mesurer les accélérations, d’en soustraire l’action de la gravité à l’aide des angles d’Euler (déduits des vitesses mesurées par le gyroscope) et enfin de soustraire les vitesses calculées à partir de l’accélération aux vitesses mesurées par l’anémomètre.
Ainsi je connaitrai le profil réel du vent apparent auquel est soumis le voilier lors d’une navigation.

En utilisant un hyperterminal, je suis capable d’obtenir au format *.txt les fichiers de données de l’IMU et de l’anémomètre.

Mon problème est que je voudrais centralisé tout le post-traitement de données sur la carte arduino, plutôt que sur Matlab comme je le fais en ce moment.

Pour l’instant je souhaiterai créer un port série pour lire les données de l’IMU et de l’anémomètre sur les broches digitales. J’ai essayé avec la librairie NewSoftSerial comme vous me l’aviez indiqué, mais cela ne fonctionne malheureusement pas.
J’ai testé les quelques lignes du simpliste programme en pièce jointe et le moniteur série parviens à afficher les valeurs fournis par l’IMU en ayant cablé Tx IMU → Rx Uno. Toutefois, cela a nécessité de réglé le port série de l’IMU à 9600 BAUD lui aussi.

Je ne parviens donc toujours pas à créer un nouveau port série.
Avez-vous d’autre tuyaux, ou d’autres pistes à explorer ?

Merci d’avance,
Boris