Go Down

Topic: Problèmes avec librairie xbee (Read 566 times) previous topic - next topic

hppp

Salut à tous,

Je sais pas si il y a des utilisateurs de la librairie xbee dans le coins mais j'ai des petits problèmes.

Je fais un programme sur l'arduino pour envoyer à intervalle régulié des données. Je veux aussi pouvoir contrôler la fréquence d'envoie des données en lui envoyant le paramètre par xbee.

j'ai donc fait ce code qui dans un premier temps réception la fréquence d'envoie sous la forme de "tmp:3600" pour 3600ms et je l'enregistre dans la variable "temps_envoie2"

Mais mon premier problème c'est que je reçois dans la première boucle "tmp:hello" au lieu de "tmp:" ... donc je ne rentre pas dans la condition.

quand je commente la ligne 74 "ZBTxRequest zbTx = ZBTxRequest(addr64, payload, sizeof(payload));" j'ai la bonne valeur "tmp:" mais il ne rentre pas non plus dans la condition.

Auriez vous une idée? je ne sais pas si je suis très claire?

Merci

voilà mon code :

Code: [Select]
#include <XBee.h>

XBee xbee = XBee();
ZBRxResponse zbRx = ZBRxResponse();

long temps;
long temps_envoie=5000;
long temps_envoie2=5000;

void setup () {
  delay(1000);
  xbee.begin(9600);

}

void loop ()
{

//uint8_t payload[] = { 0, 0, 0, 0, 0 };
char data[6];
char type[4];
char temps2[3];
char apiid[3];

  // 1. This will read any data that is available:
 
  xbee.readPacket();

  // 2. Now, to check if a packet was received:
  if (xbee.getResponse().isAvailable())
  {
    apiid[0]=xbee.getResponse().getApiId();
    Serial.print("api id : ");
    Serial.println(xbee.getResponse().getApiId(), HEX);
    if (xbee.getResponse().getApiId() == ZB_RX_RESPONSE)
    {
      xbee.getResponse().getZBRxResponse(zbRx);
     
      for (int i = 0; i < 4; i++)
      {
         type[i]=zbRx.getData(i);
     }
     Serial.print("-");
     Serial.print(type);
     Serial.println("-");
     
     if (type=="tmp:")
     {
       int j=0;
      for (int i = 4; i < zbRx.getDataLength(); i++)
      {
         temps2[j]=zbRx.getData(i);
         j++;
     }
     Serial.println();
     Serial.println(temps2);
     temps_envoie2=strtoul( temps2, NULL, 10 );
     Serial.print("new : ");
     Serial.println(temps_envoie2);
     //temps=temps2+0;
     //zbRx.getDataLength()
      }
    }
  }
 
      if((millis() - temps) > temps_envoie)
        {
          XBeeAddress64 addr64 = XBeeAddress64(0x0013a200, 0x4062A169);

          ZBTxStatusResponse txStatus = ZBTxStatusResponse();

          uint8_t payload[] = { 'h', 'e', 'l', 'l', 'o' };

          ZBTxRequest zbTx = ZBTxRequest(addr64, payload, sizeof(payload));
         
         //xbee.send(zbTx);
         Serial.println();
          temps = millis();
          Serial.println(temps_envoie2);
          Serial.flush();
        }
}

bkd974


Bonjour,

Je bosse sur un projet avec Xbee et après quelques recherches j'ai abandonné l'idée de travailler avec les API et la bibliothèque.
Si il s'agit de communication entre 2 arduino une liaison série software (ou hardware sur Mega2560) fait largement l'affaire.
Si un des Xbee est "standalone" il faut alors programmer l'attribution de ses pins DIO. Un excellent tuto ici : http://jeromeabel.net/ressources/xbee-arduino

Ci-dessous un bref résumé de ma méthode  :

Code: [Select]

// Ici liaison série hardware sur Mega2560
// pin 16  ---> vers convertisseur 5v/3.3v --> Xbee Rx
// pin 17 <--- Xbee Tx (convertisseur de niveau pas obligatoire mais conseillé!)


// Programmation initiale du module Xbee neuf
// à faire juste une fois puis ce bout de code peut être occulté
// Ici c'est fait par programme arduino mais c'est aussi réalisable par des softs genre Cool_term

Serial2.begin(9600); // Tout module Xbee est en ATBD3 par défaut càd 9600bds
while( !Serial2.find("OK") ) Serial2.print("+++");  // Passe le Xbee en mode "AT COMMAND"
Serial2.print("ATRE\r");  // remet le Xbee en mode "usine"
Serial2.print("ATBD6\r"); // Passe le Xbee en 57600 bauds
Serial2.print("ATID1234\r"); // Renomme le réseau (ici en "1234")
Serial2.print("ATMY1\r"); // Adresse courte du Xbee local
Serial2.print("ATDL2\r"); // Adresse courte du Xbee distant
Serial2.print("ATIR14\r"); // taux d'échantillonnage
Serial2.print("ATIT5\r"); // nombre d'échantillons
Serial2.print("ATIU0\r"); // les I/O (pins DIO) sont autonomes et ne passent pas par l'UART
Serial2.print("ATIAFFFF\r"); // le module xbee local peut recevoir des I/O provenant de tout autre module distant (sinon faire ATIAn)
Serial2.print("ATICFF\r"); // Ecoute et transmet tout changement d'état des DIO0 à DIO7
Serial2.print("ATD0 4\r"); // met le DIO0 en OUTPUT LOW
Serial2.print("ATD1 5\r"); // met le DIO1 en OUTPUT HIGH
Serial2.print("ATD2 3\r"); // met le DIO2 en INPUT
Serial2.print("ATWR\r"); // Ecrit toutes ces modifications dans la mémoire du module
Serial2.print("ATCN\r"); // quitte le mode "COMMAND"
// Cette programmation prend plusieurs secondes. Il n'est pas conseillé de la faire systématiquement à chaque lancement de l'arduino.
// a partir de ce moment ce module "1" est opérationnel à 57600 sur le réseau "1234"... sauf plantage il est programmé "à vie"...

// Puis utilisation normale du module
Serial2.begin(57600);
Serial2.setTimeout(10);


A partir de cet instant tu as deux possibilités de communication simultanées et "transparentes" :
- L'UART et le transfert classique de données série bidirectionnel entre les deux xbee/arduino
- Les 8 DIO (dont 2 PWM maxi) - Ces DIO devant être connectés physiquement via des convertisseurs de niveau 5/3.3v. Assez pratique pour déclencher des interruptions sur un arduino distant. A noter qu'un arduino distant n'a pas lieu d'être si les I/O du Xbee suffisent à relever des capteurs ou actionner des dispositifs 3.3v.

PS: Hors mis le branchement électrique  Pin_arduino <---> DIO_Xbee, je n'ai pas trouvé le moyen de déclencher les DIO par programme. A la rigueur, on en a pas besoin...

Exemple de prise de contact entre PIERRE et PAUL, deux Xbee/Arduino :


Code: [Select]
// ----------------   Côté PIERRE
Serial2.begin(57600);
Serial2.setTimeout(10);
while( !Serial2.find("iciPAUL") ) {
Serial2.print("iciPIERRE");
delay(2000); // pas la peine de saturer le port série
}
// si on est ici c'est que PAUL est ONLINE
while ( Serial2.find("iciPAUL") ); // ca vide le buffer


// ----------------   Côté PAUL
Serial2.begin(57600);
Serial2.setTimeout(10);
while( !Serial2.find("iciPIERRE") ) {
Serial2.print("iciPAUL");
delay(2000);
}
// si on est ici c'est que PIERRE est ONLINE
while ( Serial2.find("iciPIERRE") ); // ca vide le buffer






hppp

Salut, merci de ton aide.

Mais j'ai un petit problème, j'ai 4 modules Xbee et 3 arduino qui doivent communiquer ensemble et un pc qui doit aussi donner des ordres donc le mode API est obligatoire pour moi.

J'arrive très bien à recevoir en mode API des données et à les traiter, j'arrive très bien à en envoyer, mais j'arrive pas à faire les 2 en même temps ... enfin, recevoir des données, faire des traitements sur des données et renvoyer une pseudo réponde ou renvoyer un code erreur pour prévenir l'autre que tous c'est bien passé.

bkd974


Oups! ça se complique un petit peu alors :-)

Je n'ai pas encore approfondi la question des réseaux Xbee de plus de 2 points. Mais il faudra bien que je m'y mette...

Tu as quoi comme module Xbee ? Série1, Série2 ? Quoi comme Arduino ?

Série2
Protocole ZigBee pour des montage de réseaux complexes en maillage comportant coordinateurs, routeurs et end-device. Mais là, je ne suis pas qualifié...

Série1
Protocole 802.15.4 çàd Point-à-Point. Au grand maximum tu peux monter ton réseau en "étoile". Dans ton cas, 3 Xbee "end-device" communiquent avec un "coordinateur" central. Les "end-device" ne communiquent alors pas entre eux directement d'où l'intérêt de "programmer" les ATMY et ATDL. Avec les Série1 pas d'obligation de travailler avec les API.

Si ça peut t'aider :
- coordinateur : http://wiki.ed-win.net/index.php/Cr%C3%A9er_son_coordinateur_XBee
- end-device : http://wiki.ed-win.net/index.php/Cr%C3%A9er_un_End-Device_XBee

Je suivrais tes expériences de près...

Go Up