1

I have a Timer Swing of 15 seconds, which sends packets through my Coordinator API (XBee S2) to up to 20 Routers AT. And I am receiving all my packets through a SerialPortEvent (I'm using RXTXcomm.jar library), every packet I received I store in a Buffer ArrayList. Are they two different threads? I still have the main GUI going on.

So, my question is: what the best way to send and receive packet to/from multiple XBee modules? I think about two alternatives, make a for-loop to send unicast packet to every module (up to 20), after that, verifying my buffer receptor if I get any response. I currently using this approach, but sometimes I lose packets, maybe because XBee is halfduplex and I am receiving at same time of sending?

The another alternative is send a unicast packet and wait a response for each one. In that case, what would be the timeout response I should wait in order to not delay my timer swing (15 seconds). Should I increase this 15 seconds?

EDIT:

My current timeout is 300 ms for the ACK and 450 ms for the response

Renato Pereira
  • 834
  • 2
  • 9
  • 22
  • _Don't_ sleep on the EDT; _do_ see `SwingWorker` in [*Concurrency in Swing*](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/). – trashgod Jul 08 '14 at 14:52
  • I didn't insert Thread.Sleep(300) or Thread.Sleep(450). My timeout represents the amount of time I am checking the serial buffer – Renato Pereira Jul 08 '14 at 15:18

3 Answers3

2

Make use of the Transmit Status packet from the XBee, informing you of whether a packet was received at the radio layer on each router. If the router ACK at the application layer doesn't contain any additional information, you can potentially eliminate it to reduce network traffic.

You should be OK sending each frame to the routers and keeping track of which ones ACK, then resend frames that weren't acknowledged in the first pass. You should be OK as long as you're using hardware flow control on the coordinator to monitor the status of the XBee module's serial buffer. If the XBee drops CTS, you need to stop sending bytes immediately.

The XBee communicates with the host with full duplex, but only one radio on the network can send at a time (similar to Ethernet). The XBee module will manage inbound/outbound packets.

Finally, make sure your hosts communicate with the XBee modules at 115,200 bps (or faster). Using the default of 9600 bps is inefficient and increases the time it will take for a host to acknowledge packets.

tomlogic
  • 11,489
  • 3
  • 33
  • 59
  • Thanks @tomlogic, your response is really helpful. I just didn't understand very well your third paragraph. Can you please explain it again? I don't know how Ethernet works. Thanks! – Renato Pereira Jul 09 '14 at 14:07
  • Actually, 802.15.4 and 802.11 (Wi-Fi) use [CSMA/CA](http://en.wikipedia.org/wiki/CSMA/CA) (Carrier sense multiple access with collision avoidance) where "nodes attempt to avoid collisions by transmitting only when the channel is sensed to be 'idle'." Ethernet (802.3) uses [CSMA/CD](http://en.wikipedia.org/wiki/Carrier_sense_multiple_access_with_collision_detection) (Carrier sense multiple access with collision detection). – tomlogic Jul 10 '14 at 16:14
1

SwingWorker is the best way to handle this. Perform all serial port access in the worker's doInBackground() implementation, publish() interim results and process() the results on the EDT. A related example is examined here. If need be, you can manage multiple workers, as shown here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
0

Synchronize your send method and avoid sending packets too close in time.

This worked for me using this library

    <dependency>
        <groupId>com.rapplogic</groupId>
        <artifactId>xbee-api</artifactId>
        <version>0.9</version>
    </dependency>