Ce composant a pour but de m'aider à définir la position d'un robot. Voir la doc sur Sparkfun. Il mesure la gravité et son orientation.
Une video d'explication sur les accéléromètres est disponible ici.
Le branchement est le suivant :
MMA7361 - Arduino
VCC - 3.3V
GND - GND
XOUT - A0
YOUT - A1
ZOUT - A2
SLP - 3.3V
L'alimentation 3.3V de l'entrée GSEL permet de passer de la précision 1.5G à 6G.
Processing
Afin de visualiser les mesures de l'accéléromètre je me suis intéressé au logiciel Processing. Il ressemble au logiciel Arduino et est dédié à la programmation graphique via du Java.
Voir le site officiel Processing.
Voir le tutorial de communication entre Arduino et Processing.
Site en français concernant Processing.
Visualisation graphique des valeurs d'accélération
Ci-dessus les valeurs brutes X, Y et Z de l'accéléromètre sont affichées sous forme de graphe. En-dessous, utilisation de ces valeurs pour agir sur un cube virtuel.
Programme Arduino
void setup() {
analogReference(EXTERNAL);
Serial.begin(9600);
}
void loop() {
int xValue = analogRead(A0);
int yValue = analogRead(A1);
int zValue = analogRead(A2);
Serial.print(xValue);
Serial.print(",");
Serial.print(yValue);
Serial.print(",");
Serial.print(zValue);
Serial.println(",");
}
Programme Processing Graphe
import processing.serial.*;
Serial myPort;
int xPos = 1;
void setup () {
size(1200, 300);
println(Serial.list());
myPort = new Serial(this, Serial.list()[1], 9600);
myPort.bufferUntil('\n');
background(0);
}
void draw () {
}
void serialEvent (Serial myPort) {
float inByte;
String inString = myPort.readStringUntil('\n');
if (inString != null) {
String[] tokens = inString.split(",");
if (tokens.length == 4) {
inString = trim(inString);
// rouge
inByte = int(tokens[0]);
inByte = map(inByte, 0, 1023, 0, height);
stroke(255,0,0);
line(xPos, height, xPos, height - inByte);
// vert
inByte = int(tokens[1]);
inByte = map(inByte, 0, 1023, 0, height);
stroke(0,255,0);
line(xPos+400, height, xPos+400, height - inByte);
// bleu
inByte = int(tokens[2]);
inByte = map(inByte, 0, 1023, 0, height);
stroke(0,0,255);
line(xPos+800, height, xPos+800, height - inByte);
if (xPos >= 400) {
xPos = 0;
background(0);
} else {
xPos++;
}
}
}
}
Programme Processing 3D
import processing.serial.*;
Serial myPort;
float xMag, yMag = 0;
int xMin = 1024;
int yMin = 1024;
int zMin = 1024;
int xMax = 0;
int yMax = 0;
int zMax = 0;
void setup()
{
size(640, 360, P3D);
noStroke();
colorMode(RGB, 1);
println(Serial.list());
myPort = new Serial(this, Serial.list()[1], 9600);
myPort.bufferUntil('\n');
}
void draw()
{
background(0.5);
pushMatrix();
translate(width/2, height/2, -30);
rotateX(-xMag);
rotateZ(yMag);
scale(90);
beginShape(QUADS);
fill(1, 0, 0); vertex(-1, 0.5, 1);
fill(1, 0, 0); vertex( 1, 0.5, 1);
fill(1, 0, 0); vertex( 1, -0.5, 1);
fill(1, 0, 0); vertex(-1, -0.5, 1);
fill(0, 1, 0); vertex( 1, 0.5, 1);
fill(0, 1, 0); vertex( 1, 0.5, -1);
fill(0, 1, 0); vertex( 1, -0.5, -1);
fill(0, 1, 0); vertex( 1, -0.5, 1);
fill(1, 0, 0); vertex( 1, 0.5, -1);
fill(1, 0, 0); vertex(-1, 0.5, -1);
fill(1, 0, 0); vertex(-1, -0.5, -1);
fill(1, 0, 0); vertex( 1, -0.5, -1);
fill(0, 1, 0); vertex(-1, 0.5, -1);
fill(0, 1, 0); vertex(-1, 0.5, 1);
fill(0, 1, 0); vertex(-1, -0.5, 1);
fill(0, 1, 0); vertex(-1, -0.5, -1);
fill(0, 0, 1); vertex(-1, 0.5, -1);
fill(0, 0, 1); vertex( 1, 0.5, -1);
fill(0, 0, 1); vertex( 1, 0.5, 1);
fill(0, 0, 1); vertex(-1, 0.5, 1);
fill(0, 0, 1); vertex(-1, -0.5, -1);
fill(0, 0, 1); vertex( 1, -0.5, -1);
fill(0, 0, 1); vertex( 1, -0.5, 1);
fill(0, 0, 1); vertex(-1, -0.5, 1);
endShape();
popMatrix();
}
void serialEvent (Serial myPort) {
int xValue;
int yValue;
String inString = myPort.readStringUntil('\n');
if (inString != null) {
String[] tokens = inString.split(",");
if(tokens.length == 4) {
xValue = int(tokens[0]);
if (xValue > xMax) xMax = xValue;
if (xValue < xMin) xMin = xValue;
xValue = int(map(xValue,xMin,xMax,-90,90));
if (abs(xValue) > 6) { // pour éviter le tremblement du au bruit
xMag = xValue * PI / 180.0;
}
yValue = int(tokens[1]);
if (yValue > yMax) yMax = yValue;
if (yValue < yMin) yMin = yValue;
yValue = int(map(yValue,xMin,xMax,-90,90));
if (abs(yValue) > 6) { // pour éviter le tremblement du au bruit
yMag = yValue * PI / 180.0;
}
}
}
}
Bonjour,
RépondreSupprimerje suis très intéresse par ton projet sur arduino, y'aurait-il un moyen de te contacter ?
Salut,
RépondreSupprimerque veux tu savoir de plus sur ce projet ?
Seb
Je voudrais, si c'est possible, que tu m'aides à arriver à le réaliser également.
RépondreSupprimerJe n'arrive pas à récupérer les données de l'accéléromètre pour les transmettrent sur la arduino et arriver a un rendu tel que le tien
Merci d'avoir pris le temps de me répondre.
Finalement après m'y être investi toute la journée, j'ai réussi à récupérer les données ...
RépondreSupprimerSubsiste un problème .. l'affichage. Les données n'arrivent pas suffisamment vite pour que le cube ou les courbes apparaissent et bougent instantanément. Problème de delay ? de débits ? Augmenter le baud ?
Merci de l'attention que tu me portes.
En fait les données sont envoyées sur le port série Serial (RX et TX) http://arduino.cc/en/Reference/Serial. Le débit est de 9600 par défaut. Sur le arduino, ne met pas de délai, afin des les données soient envoyées à chaque boucle. Sur la partie processing, la fonction serialEvent est appelé à chaque réception d'un évènement. Peut être que a peut poser un problème si cette fonction est trop longue à s'exécuté. Essaye de voir quelle partie du traitement est chronophage. Il n'y a pas de raison que tu n'obtienne pas le même résultat.
RépondreSupprimerBonjour, merci de votre réponse qui nous à permis de voir, que le contrôle de flux était activé et il nous prenait un maximum de débit.
RépondreSupprimerPourrait tu me donner ton mail afin que je puisse te soumettre une idée de programme ?
J'aimerai en effet, faire apparaitre sur le programmes aux trois courbes, les variations en fonctions de x, y et de z ! Sur celui que tu as crée, seul x entre en compte non ? Pourrais tu m'aider afin d'obtenir un résultat probant ?
Bien cordialement,
Salut, tu peux m'envoyer des mails à sebaplus@yahoo.fr ou continuer à discuter directement sur les commentaires du blog.
RépondreSupprimerEn fait, sur mon projet j'utilise les 3 axes x,y,z dans les 2 cas d'affichage. Sur les graphes, il s'agit des 3 couleurs différentes.
Salut,
RépondreSupprimerj'ai travaillé sur une autre utilisation de l'accéléromètre. Tu peux la retrouver sur mon dernier post : http://sebarduino.blogspot.com/2012/03/servo.html
Bonjour,
RépondreSupprimerce serait bien de mettre un flush() dans le sketch à la fin de chaque ligne. Sinon, j'ai l'impression que le programme fait des mesures plus vite qu'il ne peut les transmettre et le résultat n'est pas optimal. (Mieux encore serait de commander la saisie et/ou de faire du contrôle de flux mais là, cela compliquerait l'exemple dont la simplicité même est l'intérêt principal) -- xof
Je suis d'accord que les mesures sont beaucoup plus rapides que le transfert avec Serial. Mais les deux actions, se faisant l'une après l'autre, ça ne pose pas vraiment de problème dans ce cas. Si les données devaient être traitées sur le module Arduino, il faudrait effectivement gérer le Serial différemment.
RépondreSupprimerBonjour, est-il possible et utile d'amplifier le signal de x,y,z avec des composants du marché, afin d'avoir plus de précision de mesure? Je n'ai pas encore tout à fait compris l'intérêt de la fonction accelero.setSensitivity(HIGH) ou LOW...
RépondreSupprimer