Bonjour,
Je suis actuellement en terminale S-SI et pour mon projet de PPE je dois commander à distance un bras robotisé grâce à un nunchuk de wii. J'ai choisi d'utiliser pour cela deux cartes arduino, une relier au nunchuk qui doit lire les valeurs de l'accéléromètre du nunchuk et les envoyer à l'autre par l'intermédiaire d'un module xbee sur chaque carte, la seconde carte doit lire les valeurs envoyées par la première pour contrôler 3 servomoteur. Chaque servomoteur lisant les valeurs d'un seul axe de l'accéléromètre.
Je rencontre un problème lorsque j'essaye de faire communiquer les 2 cartes. De plus j'aimerais utiliser l'accéléromètre tel qu'un inclinomètre parce que je n'arrive pas à lier chaque servomoteur à une seule valeur chacun, par exemple lorsque je bouge le nunchuk sur un axe, plusieurs servomoteurs bougent au lieux d'un seul. Voici le code que j'utilise:
émetteur: carte arduino1 + nunchuk + module xbee1
#include <Servo.h>;
#include <Wire.h>;
// Doit être ajusté en fonction de chaque nunchuck
#define ZEROX 530
#define ZEROY 530
#define ZEROZ 530
// adresse I2C du nunchuck
#define WII_NUNCHUK_I2C_ADDRESS 0x52
// définition d'une variable Servo
// définition d'une variable counter
int counter;
// définition d'un tableau de données
uint8_t data[6];
void setup()
{
Serial.begin(115200);
// initialisation du nunchuck
Wire.begin();
Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
Wire.write(0xF0);
Wire.write(0x55);
Wire.endTransmission();
Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
Wire.write(0xFB);
Wire.write(0x00);
Wire.endTransmission();
}
void loop()
{
// on demande 6 octets au nunchuck
Wire.requestFrom(WII_NUNCHUK_I2C_ADDRESS, 6);
counter = 0;
// tant qu'il y a des données
while(Wire.available())
{
// on récupère les données
data[counter++] = Wire.read();
}
// on réinitialise le nunchuck pour la prochaine demande
Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
Wire.write(0x00);
Wire.endTransmission();
if(counter >= 5)
{
// on extrait les données
// dans mon exemple j'utilise uniquement les données d'accélération sur l'axe Y
double accelX = ((data[2] << 2) + ((data[5] >> 2) & 0x03) - ZEROX);
double accelY = ((data[3] << 2) + ((data[5] >> 4) & 0x03) - ZEROY);
double accelZ = ((data[4] << 2) + ((data[5] >> 6) & 0x03) - ZEROZ);
// on limite la valeur entre -180 et 180
int value = constrain(accelY, -180, 180);
// on mappe cette valeur pour le servomoteur soit entre 0 et 180
value = map(value, -180, 180, 0, 180);
Serial.println(value);
delay(15);
}
}
Récepteur: carte arduino 2 + servo + module xbee 2
#include <Servo.h>
Servo servomoteur;
int value;
void setup()
{
Serial.begin(115200);
servomoteur.attach(9);
}
void loop()
{
while(Serial.available() == 0);
int data = Serial.read() - '0';
servomoteur.write(value);
Serial.flush();
}
Salut, je suppose que ton xbee est relier au rx tx de ta carte, pour le coup je vois aucune initialisation de com série particulière dans tes prog (serial.begin d'origine n'est peut être pas redirigé vers les sorties que tu utilisent ) donc l'erreur peut être la, tout comme elle peut être dans le fait que tu à mal câblé, liste nous ton matériel et ton câblage et on pourra te dire ce qu'il en est.
Ps: pour le câblage fait un schéma c'est plus simple
Je suis désolé j'avais répondu mercredi mais je crois que cela n'a pas fonctionner. Donc pour le rx et le tx du xbee je ne peux pas vous en dire plus car le xbee shield se branche sur toute les entrées analogiques, sur rx, tx, et sur quelques sorties :
Salut, bon sa fait un moment que sa traîne et on avance pas, j'ai regardé sur le net un peut le câblage et j'ai jamais vue un truc aussi mal documenté, on sais même pas ou finissent réellement ces deux pine, si tu pouvait regarder directement sur la carte ce qui est relier aux pins RX et TX sa aiderai
Ok je pourrais vous répondre mercredi parce qu'il faut que je récupère la carte au lycée. Merci de votre aide, sinon est ce que vous avait déjà utilisé le module xbee pour une application similaire ?
J'ai pas trouvé à quoi étaient branchés le RX et le TX mais en tout cas je peut vous dire que ce programme fonctionne:
#define potPin 0
#define ledPin 9
int inByte = -1;
char inString[6];
int stringPos = 0;
int lastValue = 0;
void setup()
{
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop()
{
inByte = Serial.read();
//Envoie une nouvelle valeur seulement si elle diffère de la précédente d'au moins 5 afin de ne pas saturer le réseau
int potVal = analogRead(potPin);
if( abs(potVal - lastValue) > 5)
{
Serial.println(potVal);
lastValue = potVal;
}
//Si une donnée numérique est dispoible, la mémoriser
if((inByte >= '0') && (inByte <= '9')){
inString[stringPos] = inByte;
stringPos ++;
}
//Si un caractère de fin de ligne est détecté, traiter la chaîne et écrire la valeur sur la sortie qui commande la LED puis remettre la chaîne à zero
if(inByte == '\r'){
int brightness = atoi(inString); //Convertit la chaîne en entier
//Réduction de la plage d'entrée de 0-1023 à 0-255
brightness = map(brightness, 0, 1023, 0, 255);
analogWrite(ledPin, brightness);
//Remise à zéro de la chaîne de caractères
for (int c = 0; c < stringPos; c++){
inString[c] = 0;
}
stringPos = 0;
}
}
Par contre je n'arrive toujours pas à controler un servo grace au nunchuk en liaison xbee, voila ou j'en suis:
Carte avec le nunchuk et le xbee:
#include <Wire.h>
// Doit être ajusté en fonction de chaque nunchuck
#define ZEROX 512
#define ZEROY 512
#define ZEROZ 512
// adresse I2C du nunchuck
#define WII_NUNCHUK_I2C_ADDRESS 0x52
// définition d'une variable Servo
// définition d'une variable counter
int counter;
int value1;
int value2;
int value3;
// définition d'un tableau de données
uint8_t data[6];
void setup()
{
Serial.begin(9600);
// initialisation du nunchuck
Wire.begin();
Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
Wire.write(0xF0);
Wire.write(0x55);
Wire.endTransmission();
Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
Wire.write(0xFB);
Wire.write(0x00);
Wire.endTransmission();
}
void loop()
{
// on demande 6 octets au nunchuck
Wire.requestFrom(WII_NUNCHUK_I2C_ADDRESS, 6);
counter = 0;
// tant qu'il y a des données
while(Wire.available())
{
// on récupère les données
data[counter++] = Wire.read();
}
// on réinitialise le nunchuck pour la prochaine demande
Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
Wire.write(0x00);
Wire.endTransmission();
if(counter >= 5)
{
// on extrait les données
// j'utilise uniquement les données d'accélération sur l'axe X, Y et Z
double accelX = ((data[2] << 2) + ((data[5] >> 2) & 0x03) - ZEROX);
double accelY = ((data[3] << 2) + ((data[5] >> 4) & 0x03) - ZEROY);
double accelZ = ((data[4] << 2) + ((data[5] >> 6) & 0x03) - ZEROZ);
// on limite la valeur entre -180 et 180
int value1 = constrain(accelY, -180, 180);
// on mappe ces valeurs pour que les servomoteur soit entre 0 et 180
value1 = map(value1, -180, 180, 0, 180);
// on envoie la valeur à la 2eme carte
Serial.println(value1);
Serial.println();
delay (100);
}
}