.: robotitaly.NET :. - la community italiana sulla robotica  

Vai indietro   .: robotitaly.NET :. - la community italiana sulla robotica > Robotica > XBee's

XBee's Gli XBee sono in moduli di comunicazione wireless standard ZigBee della Maxstream/Digi

Rispondi
 
Strumenti della discussione Modalità di visualizzazione
  #1  
Vecchio 01-28-2013, 02:34 PM
michelef87 michelef87 non è collegato
Nuovo Roboter
 
Registrato dal: Jan 2013
Messaggi: 8
Exclamation Problemi broadcast in rete xbee S2 "a stella"

Salve,

Sto sviluppando un progetto per controllare delle luci da remoto, tramite un software sviluppato da me in python. Le luci verranno controllate da un numero di 3-6 (non so ancora di preciso quanti ne serviranno) arduino, collocati in varie posizioni, che si occuperanno di gestire vari effetti. Una comunicazione diretta via cavo sarà impossibile, quindi pensavo di avvalermi dei moduli xbee con una configurazione "a stella", che vedrebbe il pc collegato ad un xbee coordinator impostato con gli indirizzi di destinazione in broadcast (DH: 0 DL: FFFF); mentre gli altri ricevitori verranno impostati come router o end device.

Ho già sviluppato il software per il pc, e lo sketch per l'arcuino, e collegandoli direttamente tramite seriale funziona tutto perfettamente, così ho ordinato 2 moduli Xbee serie 2 (XB24-ZB) per effettuare i primi test sulla comunicazione wireless.

Ho la necessità che la comunicazione tra il pc ed i vari ricevitori avvenga il più rapidamente possibile, con delle performance simili alla comunicazione seriale.

Purtroppo però ho avuto una spiacevole sorpresa. Ovvero impostando il coordinator in modalità AT, con indirizzi DH e DL impostati in broadcast (0 ed FFFF), l'invio dei dati era veramente poco performante, con pause anche di 3-5 secondi nella trasmissione. Invece il modulo end device, impostato con gli indirizzi DH E DL del coordinator, riceveva regolarmente i dati in modo rapido.
La presenza di questo problema mi è stato confermato anche da google, così seguendo i vari consigli letti qua e là e leggendo i vari datasheet, sono passato alla modalità API (Zigbee, AP settato a 2).
Ora nel mio software di gestione ho inserito l'indirizzo dei ricevitori a cui i pacchetti vanno inviati, ed ho aggiunto le librerie apposite per sfruttare la modalità API.
Purtroppo però quando invio più di 3 pacchetti contemporaneamente, la trasmissione inizia ad esser di nuovo rallentata: il buffer dell'usb inizia a riempirsi e subentra un certo ritardo nella consegna dei pacchetti ai ricevitori, e questo mi causa un brutto effetto quando devo accendere più luci contemporaneamente, o comunque inviare più effetti nel giro di pochi istanti.

Come posso rendere la comunicazione tra l'xbee coordinatore e gli xbee ricevitori più performante? Ho provato ad alzare il baudrate, ma non ho avuto un effetto risolutore. Preciso che i comandi inviati dal pc agli arcuino pesano appena un paio di byte.
Inoltre non vorrei che aggiungendo altri moduli alla rete, le performance diminuissero ulteriormente.

Sono riuscito ad ottenere delle performance pari al collegamento seriale, solo impostando i moduli in modalità "p2p" in transparent mode. Purtroppo però a me la configurazione p2p non va bene, perché come dicevo, mi servono più ricevitori, non uno solo.

Mi servirebbe qualche consiglio prima di spendere soldi inutilmente per gli altri moduli che potrebbero rivelarsi inadatti…
Non avevo previsto che gli xbee S2 avessero questo tipo di problemi, o forse sbaglio io qualcosa, visto che sono molto complessi…

Forse almeno il modulo che fa da coordinator dovrei prenderlo del tipo "pro"? O forse i moduli della serie 1 sono più performanti in questo tipo di situazioni? Sono pensieri buttati lì, spero in qualche esperto mi possa consigliare al riguardo.

Grazie in anticipo!
Rispondi quotando
  #2  
Vecchio 01-29-2013, 07:17 AM
L'avatar di Emanuele Terrasi
Emanuele Terrasi Emanuele Terrasi non è collegato
Roboter Graduato
 
Registrato dal: Dec 2009
residenza: Palermo
Messaggi: 492
Blog Entries: 15
predefinito

Quote:
Originariamente inviata da michelef87 Visualizza il messaggio
Sono riuscito ad ottenere delle performance pari al collegamento seriale, solo impostando i moduli in modalità "p2p" in transparent mode. Purtroppo però a me la configurazione p2p non va bene, perché come dicevo, mi servono più ricevitori, non uno solo.
Non so praticamente nulla di connessioni e mi azzardo a fare una domanda stupidissima: non potresti avere dei ricevitori eguali, aggiungere al messaggio un byte di selezione ed affidare al programma il compito di ignorare i messaggi rivolti ad altri? Forse la trasmissione è bidirezionale e si bloccherebbe?

Ultima modifica di Emanuele Terrasi; 01-29-2013 a 07:19 AM
Rispondi quotando
  #3  
Vecchio 01-29-2013, 07:37 AM
L'avatar di astrobeed
astrobeed astrobeed non è collegato
Moderator
 
Registrato dal: Mar 2006
residenza: Roma
Messaggi: 2,133
Blog Entries: 1
predefinito

Quote:
Originariamente inviata da michelef87 Visualizza il messaggio
Non avevo previsto che gli xbee S2 avessero questo tipo di problemi, o forse sbaglio io qualcosa, visto che sono molto complessi…
Il problema che citi non è reale, è vero che ci sono delle latenze per la propagazione dei pacchetti in un network, però sono tempi di millisecondi e non di secondi.
Sicuramente il problema è nel tuo software e non nei moduli Xbee.
Rispondi quotando
  #4  
Vecchio 01-29-2013, 01:45 PM
michelef87 michelef87 non è collegato
Nuovo Roboter
 
Registrato dal: Jan 2013
Messaggi: 8
predefinito

Grazie per le risposte!

@emanuele: In modalità transparent mode avrebbe funzionato così: il coordinator invia il pacchetto a tutti i ricevitori e gli arduino erano in grado di eseguire solo comandi che li interessavano (tramite appunto un bit apposito inserito nel pacchetto).
Ora in API mode ho comunque questa possibilità, ovvero di inviare i pacchetti a tutta la lista di indirizzi noti, ma tuttavia a questo punto sarebbe più corretto già a livello di trasmissione inviare i pacchetti solo verso i ricevitori interessati dal comando, risparmiando banda.

@astrobeed: Il problema dei *secondi* di latenza l'ho riscontrato in AT mode, e solo dal coordinator (impostato in broadcast) verso il router/end device. Mentre dal router/end device, impostato con gli indirizzi DL e DH del coordinator, la trasmissione è veloce come se fosse via cavo.
Impostando entrambi in API mode, la trasmissione è *nettamente* migliorata, diventando accettabile. Tuttavia quando i pacchetti sono più di 3-4 inviati contemporaneamente, "all'occhio" si nota un lieve delay. Ho fatto un test di flooding di 1000 pacchetti inviati in 17 secondi, e la trasmissione si conclude con circa 5-6 secondi di ritardo.
Questo non avveniva impostando gli xbee in AT mode P2P. In questa modalità la connessione aveva una performance pari al collegamento via cavo. Ed è quello a cui vorrei arrivare anche in una configurazione "a stella".

Pomeriggio vedo di postare qualche riga di codice e qualche test sui delay, in modo da poter ragionare su dei dati effettivi, e non "ad occhio".
Rispondi quotando
  #5  
Vecchio 01-29-2013, 10:48 PM
michelef87 michelef87 non è collegato
Nuovo Roboter
 
Registrato dal: Jan 2013
Messaggi: 8
predefinito

Allora, ho scoperto una cosa interessante. In python se invio il comando e basta, senza "leggere" la notifica di invio che ritorna dall'xbee, la latenza cala di molto.

I settaggi degli xbee sono i seguenti:
Coordinator:
XB24-ZB - ZIGBEE COORDINATOR API - 21A7
Impostazioni: tutto default, tranne AP:2

End-Device:
XB24-ZB ZIGBEE END DEVICE API - 29A7
Impostazioni tutto default, tranne:
AP:2
DL: indirizzo low del coordinator
DH: indirizzo hight del coordinator

Il codice di invio dei pacchetti che ho usato è questo:

codice:
#! /usr/bin/python

import time
from datetime import datetime

import serial
from xbee import XBee, ZigBee

PORT = '/dev/ttyUSB0'
BAUD_RATE = 9600

# Open serial port
ser = serial.Serial(PORT, BAUD_RATE, bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=1, rtscts=1, dsrdtr=1)  #abilito il flow control per evitare che il buffer dell'xbee si saturi e che alcuni dati vadano persi

# Create API object
xbee = ZigBee(ser,escaped=True)

DEST_ADDR_LONG = "\x00\x13\xA2\x00\x40\x9C\x91\xA5"

# Continuously read and print packets
while True:
    try:
        print "send data"
	tstart = datetime.now()
        xbee.send("tx",data="321\n",dest_addr_long=DEST_ADDR_LONG,dest_addr="\xff\xfe")
        response = xbee.wait_read_frame()
        xbee.send("tx",data="322\n",dest_addr_long=DEST_ADDR_LONG,dest_addr="\xff\xfe")
        response = xbee.wait_read_frame()
        xbee.send("tx",data="323\n",dest_addr_long=DEST_ADDR_LONG,dest_addr="\xff\xfe")
        response = xbee.wait_read_frame()
        xbee.send("tx",data="324\n",dest_addr_long=DEST_ADDR_LONG,dest_addr="\xff\xfe")
        response = xbee.wait_read_frame()
        xbee.send("tx",data="325\n",dest_addr_long=DEST_ADDR_LONG,dest_addr="\xff\xfe")
        response = xbee.wait_read_frame()
	tend = datetime.now()
	print tend - tstart
	time.sleep(1)
    except KeyboardInterrupt:
        break
        
ser.close()
Ho misurato l'intervallo di tempo impiegato dalla libreria python ad inviare il pacchetto, ed a ricevere la notifica, e il risultato è questo:

codice:
0:00:00.368380
send data
0:00:00.372380
send data
0:00:00.369378
send data
0:00:00.369506
send data
0:00:00.367380
send data
0:00:00.370503
Poi ho riprovato a togliere la parte xbee.wait_read_frame():

codice:
#! /usr/bin/python

import time
from datetime import datetime

import serial
from xbee import XBee, ZigBee


PORT = '/dev/ttyUSB0'
BAUD_RATE = 9600

# Open serial port
ser = serial.Serial(PORT, BAUD_RATE, bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=1, rtscts=1, dsrdtr=1)  #abilito il flow control per evitare che il buffer dell'xbee si saturi e che alcuni dati vadano persi

# Create API object
xbee = ZigBee(ser,escaped=True)

DEST_ADDR_LONG = "\x00\x13\xA2\x00\x40\x9C\x91\xA5"

# Continuously read and print packets
while True:
    try:
        print "send data"
	tstart = datetime.now()
        xbee.send("tx",data="321\n",dest_addr_long=DEST_ADDR_LONG,dest_addr="\xff\xfe")
        xbee.send("tx",data="322\n",dest_addr_long=DEST_ADDR_LONG,dest_addr="\xff\xfe")
        xbee.send("tx",data="323\n",dest_addr_long=DEST_ADDR_LONG,dest_addr="\xff\xfe")
        xbee.send("tx",data="324\n",dest_addr_long=DEST_ADDR_LONG,dest_addr="\xff\xfe")
        xbee.send("tx",data="325\n",dest_addr_long=DEST_ADDR_LONG,dest_addr="\xff\xfe")
	tend = datetime.now()
	print tend - tstart
	time.sleep(1)
    except KeyboardInterrupt:
        break
        
ser.close()
e il delay è calato un bel po', almeno sulla carta:

codice:
0:00:00.000178
send data
0:00:00.000166
send data
0:00:00.000167
send data
0:00:00.000167
send data
0:00:00.000168
send data
0:00:00.000168
send data
0:00:00.000176
Disattivando la lettura del frame di risposta "all'occhio" un lieve miglioramento si nota, ma non è ancora ai livelli di una connessione via cavo, o alla modalità "p2p". Ad ogni modo piano piano ci si sta arrivando... almeno pare

Poi ho letto che che momento di invio del pacchetto in modalità api sarebbe meglio mettere l'indirizzo "short" a 16 bit, e non lasciarlo "FF FE". Proverò anche questo.

Altri consigli/prove/idee? Grazie in anticipo!
Rispondi quotando
  #6  
Vecchio 01-29-2013, 11:03 PM
michelef87 michelef87 non è collegato
Nuovo Roboter
 
Registrato dal: Jan 2013
Messaggi: 8
predefinito

Ho provato ad aggiungere l'indirizzo a 16bit corretto, ma fermo restando quanto detto sopra, i tempi sono gli stessi...
Rispondi quotando
  #7  
Vecchio 01-30-2013, 12:25 AM
michelef87 michelef87 non è collegato
Nuovo Roboter
 
Registrato dal: Jan 2013
Messaggi: 8
predefinito

Passando invece ai ricevitori, ho messo questo codice sull'arduino, allo scopo di misurare il delay tra la ricezione dei diversi pacchetti.

codice:
#include <XBee.h>

unsigned long initime; //variabile per il calcolo del delay

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

void setup() {
  xbee.begin(9600);
  initime = millis();
}

void loop() {

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

  // 2. Now, to check if a packet was received: 
  if (xbee.getResponse().isAvailable()) {
    if (xbee.getResponse().getApiId() == ZB_RX_RESPONSE) {
      xbee.getResponse().getZBRxResponse(zbRx);

      Serial.println("Dal pacchetto precedente: ");
      Serial.println(millis() - initime);  //calcolo il delay e lo scrivo in seriale
      Serial.println("\n");
      initime = millis();  //Salvo il tempo, per calcolare il delay del prossimo pacchetto
    }
  }
}

Il risultato in seriale è il seguente:

codice:
Dal pacchetto precedente: 
840


Dal pacchetto precedente: 
30


Dal pacchetto precedente: 
31


Dal pacchetto precedente: 
31


Dal pacchetto precedente: 
30
In media il ritardo di ricezione dei pacchetti si attesta attorno ai 29-32 ms, che sono troppi per quello che serve a me (30ms x ad esempio 5 pacchetti = 150ms, ed è un ritardo che l'occhio riesce a notare).

Ho la speranza di far scendere il delay sotto ai 30ms? Già 10-15ms sarebbe un traguardo nettamente soddisfacente.
Rispondi quotando
  #8  
Vecchio 01-30-2013, 08:21 AM
L'avatar di max_robot
max_robot max_robot non è collegato
Roboter Graduato
 
Registrato dal: Sep 2008
Messaggi: 458
predefinito

Quote:
In python se invio il comando e basta, senza "leggere" la notifica di invio che ritorna dall'xbee, la latenza cala di molto.
Questo porterebbe a farmi credere che ci sia un tempo minimo nella funzione di ricezione della stringa seriale in lettura. In molte librerie seriali che ho utilizzato sotto linux spesso viene definito un tempo di attesa per i pacchetti in ingresso, si passa all'informazione successiva solo nel caso in cui il pacchetto arriva nell'intervallo temporale o quando scade l'intervallo stesso.

Max
__________________
il pericolo del passato era che gli uomini potessero diventare schiavi, il pericolo del futuro è che possano diventare robot (e. fromm)
Rispondi quotando
  #9  
Vecchio 01-30-2013, 12:42 PM
michelef87 michelef87 non è collegato
Nuovo Roboter
 
Registrato dal: Jan 2013
Messaggi: 8
predefinito

Bhè, posso disattivare la lettura dei pacchetti in ingresso, attivandola solo quando serve, se questo causa problemi di velocità.

Quindi secondo te quei 30 ms di delay sono definiti dalla libreria stessa?
Rispondi quotando
  #10  
Vecchio 01-30-2013, 01:23 PM
L'avatar di max_robot
max_robot max_robot non è collegato
Roboter Graduato
 
Registrato dal: Sep 2008
Messaggi: 458
predefinito

Quote:
Quindi secondo te quei 30 ms di delay sono definiti dalla libreria stessa?
Questo è quello che mi viene in mente basandomi su quanto riportato da te.
La cosa che non capisco è per quale motivo rimanga in attesa per ogni byte ricevuto, in questo modo è più che normale che si accumuli un certo delay dato dalla somma dei tempi d'attesa di ogni dato ricevuto; in genere si crea un buffer nel quale vengono incapsulati i diversi byte ed una volta che il buffer è pieno si passa ad analizzare i dati ricevuti.
Prova a dare un'occhiata alla libreria che utilizzi nella sezione dedicata alla ricezione dei dati.

Max
__________________
il pericolo del passato era che gli uomini potessero diventare schiavi, il pericolo del futuro è che possano diventare robot (e. fromm)
Rispondi quotando
Rispondi

Segnalibri

Strumenti della discussione
Modalità di visualizzazione

Regole d'invio
Non puoi inserire discussioni
Non puoi inserire repliche
Non puoi inserire allegati
Non puoi modificare i tuoi messaggi

BB code è attivo
Le smilie sono attive
Il codice IMG è attivo
il codice HTML è disattivato

Salto del forum


Tutti gli orari sono GMT. Attualmente sono le 12:05 PM.


Powered by vBulletin versione 3.8.7
Copyright ©: 2000 - 2018, Jelsoft Enterprises Ltd.