Shop OBEX P1 Docs P2 Docs Learn Events
Xbee Discover radio node in the same Network — Parallax Forums

Xbee Discover radio node in the same Network

Hello! So far I'm loving the Xbee but I need help to write my own program. With the XCTU software I was able to communicate between 2 XBee Pro that are in the same Network (same channel). One is the "Coordinator" receiving data and the other is the "Router" sending "hello world" from a Stamp2. All works perfectly with the XCTU software. I created a project on Visual Studio 2022 (C# windows form). I was able to open the port successfully means the Xbee "Coordinator" is ready but how I add the other Xbee (router) that is not connected to the computer. You do this manually on the XCTU software by pressing "Discover radio node in the same Network". How do I add all the Xbee remote modules on Visual Studio C# code to be all communicating? I appreciate any help!

Comments

  • JonnyMacJonnyMac Posts: 8,973
    edited 2023-06-08 01:27

    Look up the Node Discovery command. It's an AT message that will cause XBees in the same Channel and PAN to respond (MAC, MY address, and Node ID). At Elite Laser Tag we use it to identify our taggers (guns) in a system. Fair warning: if there are other XBees in the same Channel and PAN but not part of your system, you could be fooled. We get around this by having the tagger program the NI field of the XBee with a string that identifies us and product type. For example, "ELTE-01" is a tagger, "ELTE-02" is a game box. It's not likely that another vendor is going to use those strings in their NI field.

  • Hi JonnyMac! Where is this Node Discovery command? Is something on the XTCU software or something I have to setup via code on my .Net project? Do you have any screenshot or examples I can look up ?

    Thanks

    @JonnyMac said:
    Look up the Node Discovery command. It's an API message that will cause XBees in the same Channel and PAN to respond (MAC, MY address, and Node ID). At Elite Laser Tag we use it to identify our taggers (guns) in a system. Fair warning: if there are other XBees in the same Channel and PAN but not part of your system, you could be fooled. We get around this by having the tagger program the NI field of the XBee with a string that identifies us and product type. For example, "ELTE-01" is a tagger, "ELTE-02" is a game box. It's not likely that another vendor is going to use those strings in their NI field.

  • JonnyMacJonnyMac Posts: 8,973
    edited 2023-06-08 02:08

    I edited my post to show you how you can create a command using the frames generator in XCTU. You need to send this sequence to the XBee, then get ready to receive.

    There is also a serial terminal in XCTU. I fired up a tagger and sent the ND command and monitored the response. There are actually two responses: the first (yellow highlight) is the tagger. The second (underline) is the message from the XBee telling you the ND scan period is complete.

  • XCTU is a very useful tool. I suggest you spend a lot of time with it to learn the ins-and-outs of XBee.

  • Luis_PLuis_P Posts: 246
    edited 2023-06-08 04:47

    @JonnyMac said:
    Look up the Node Discovery command. It's an AT message that will cause XBees in the same Channel and PAN to respond (MAC, MY address, and Node ID). At Elite Laser Tag we use it to identify our taggers (guns) in a system. Fair warning: if there are other XBees in the same Channel and PAN but not part of your system, you could be fooled. We get around this by having the tagger program the NI field of the XBee with a string that identifies us and product type. For example, "ELTE-01" is a tagger, "ELTE-02" is a game box. It's not likely that another vendor is going to use those strings in their NI field.

    Let's see if I understand. Are you saying if I send this command (7E 00 04 08 01 4E 44 64) from the BS2 that is connected to the XBEE remote module before I send the String EX: "hello world" the Master XBee connected to the computer will get the message? without having to discover the remotes modules? Or I'm confused?
    Remember I have 1 Xbee (Coordinator) USB to PC and 1 Xbee as remote connected to a BS2. The BS2 sends OUT "Hello World" and the Coordinators needs to receive that message.

  • JonnyMacJonnyMac Posts: 8,973
    edited 2023-06-08 05:02

    With one remote and one at the PC you should simply consider transparent mode -- Node Discovery is for locating devices within your network and there's not enough RAM in the BS2 to deal with that.

    While I would never use the XBee with a BS2, others have. This document is old and XCTU has been updated a lot, but it should be helpful.

    -- https://forums.parallax.com/uploads/attachments/47421/101790.pdf

  • Luis_PLuis_P Posts: 246
    edited 2023-06-09 00:07

    @JonnyMac
    Hi JonnyMac! you are a genius! everything works except I can't read the whole data. It just read some characters. I feel I'm really close to finish with this project. I just need to know why when I'm reading the serial port on C# only reading a few character. Maybe because I'm not sending the "ND scan period is complete" ? 7E 00 05 88 01 4E 44 00 E4 or something wrong on my code?

        private StringBuilder receivedData = new StringBuilder();
        public Form1()
        {
            InitializeComponent();
        }
    
        private void Form1_Load(object sender, EventArgs e)
        {
    
        }
    
         private void button2_Click(object sender, EventArgs e)
        {
             if (!serialPort1.IsOpen)
                try
            {
    
                //serialPort1.PortName = "COM5";
                serialPort1.BaudRate = 9600;
                serialPort1.DataBits = 8;
                serialPort1.Parity = Parity.None;
                serialPort1.StopBits = StopBits.One;
    
                serialPort1.Handshake = Handshake.None;
                serialPort1.RtsEnable = true;
                serialPort1.DtrEnable = true;
                serialPort1.ReadTimeout = 1000;            
                serialPort1.Open();
                serialPort1.DataReceived += DatareceivedHandler; // Add DataReceived Event Handler
    
                }
                catch (Exception Err)
                {
                    MessageBox.Show(Err.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
    
        }
    
       private void DatareceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
    
                string inData = serialPort1.ReadExisting();
                displayToWindow(inData);
    
        }
            private void displayToWindow(string inData)
        {
            BeginInvoke(new EventHandler(delegate
            {
                richTextBox1.AppendText(inData); //Encoding.ASCII.GetString(inData)
                richTextBox1.ScrollToCaret();
            }));
        }
    

    }

  • JonnyMacJonnyMac Posts: 8,973
    edited 2023-06-09 17:29

    Hi JonnyMac! you are a genius! everything works except I can't read the whole data.

    No, I just have a lot of experience with XBee at my employer. We have fields with more than 100 "taggers" in operation that are sending messages back to our scoring system.

    I don't code in C# and having only started working with serial for the PC using Xojo. Here's some things you'll understand once you've taken the time to study XBee docs (hint, hint).

    1) API Messages begin with $7E
    2) The byte that follows will always be $00 (MSB of payload length)
    3) The 3rd byte will be LSB of the payload length
    4) The payload is the 4th through penultimate bytes
    5) The last byte is the XBee checksum

    I highlighted the payload here. Note that the byte that precedes the payload indicates its length.

    This is how I receive an XBee message in the Propeller (if you can understand C#, Spin should be very simple).

    pub get_rx_frame(ms) : len | c, pb
    
    '' Receive XBee frame
    '' -- returns positive length if valid
    '' -- application must verify checksum
    
      if (ms =< 0)
        c := serial.rxcheck                                         ' anything waiting now?
      else
        c := serial.rxtime(ms)                                      ' wait with time-out
    
      if (c <> $7E)                                                 ' if not frame header
        return 0
    
      rxbuf[len++] := c                                             ' add to buffer
    
      c := serial.rxtime(1)                                         ' msb of payload bytes (0)
      if (c < 0)                                                     
        return 0                                                     
      else                                                           
        rxbuf[len++] := c                                            
    
      c := serial.rxtime(1)                                         ' lsb of payload bytes
      if (c < 0)                                                     
        return 0                                                     
      else                                                           
        rxbuf[len++] := c                                            
        pb := c                                                      
    
      repeat (pb+1)                                                 ' get payload bytes + checksum
        c := serial.rxtime(1)                                        
        if (c < 0)
          return 0
        else
          rxbuf[len++] := c
    

    You probably have to do things differently on the PC with serial events. Perhaps you need to keep a state variable vis-à-vis a message. Maybe it's 0 when no message is in process. When a $7E is received, the state would be set to 1 (receiving), the $7E would be buffered, and the buffer count (len in my code) set to 1. Note that after capturing the LSB of the payload length I use a loop to collect the rest of the message. While rare, the Propeller serial buffer could be holding multiple messages when this method is called. This design lets me extract one method at a time. I can check the serial buffer available() method to see if there's anything else to do.

    With the message fully buffered, you can verify the checksum. This is how I do it in Spin.

    pub calc_checksum(p_buf, len) : cs
    
      cs := $FF
      repeat len
        cs -= byte[p_buf++]
    
      return cs & $FF
    

    Note that the checksum is of the payload bytes only. This is how I use it in Spin

    pub validate_rx_frame | last
    
    '' Ensures that the last frame received is in fact valid
    
      last := rxbuf[2] + 3
    
      if (calc_checksum(@rxbuf[3], rxbuf[2]) == rxbuf[last])
        return true
      else
        return false
    

    The first line calculates the index of the last byte in the buffer. The checksum is calculated on the payload which starts at index 3 and is index 2 bytes long. The last byte in the buffer is the transmitted checksum.

  • @JonnyMac Problem solved! I was not getting all the data because the BS2 was sending Command "CLS" before sending the string I need, that will cause the screen to be clear. removing that fixed the problem:

    ' {$STAMP BS2}
    ' {$PBASIC 2.5}

    SELECT $STAMP

    #CASE BS2
    T9600 CON 84

    ENDSELECT

    Baud CON T9600

    Tx PIN 0
    Rx PIN 1 'NO CONNECTED

    '******************* Varaible Declarations***************
    Counter VAR Byte
    '********************************************************

    '**************Main Loop*********************************
    PAUSE 500
    SEROUT Tx, Baud, [ $7E, $00, $04, $08, $01, $4E, $44, $64] 'DISCOVERY NODE AT COMMAND
    PAUSE 200
    SEROUT Tx, Baud, ["1A1"] ' This is the data I need
    PAUSE 500 ' Pause

    END

  • JonnyMacJonnyMac Posts: 8,973
    edited 2023-06-11 23:01

    Why do you think you need the ND command? Your code makes not sense. When the ND is sent by an XBee, any other XBees in the network will respond to it, but you're not doing anything with the response -- you're just filling the XBee RX buffer.

    I, and others, have a lot of experience with XBee. What is your goal with the project?

  • Hey JonnyMac. Im not connecting XBEE DOUT to any pin on the BS2. The BS2 is only sending data, no receiving. Everything is working fine. Now Im going to connect “buttons” on the BS2 to be press and send string. Do you see anything wrong with this approach?

    @JonnyMac said:
    Remember... the ND command returns a lot of data if a device is found. The BS2 has 26 bytes of RAM. Even if you only have one device and it's not using the NI string, 30 bytes are going to come back -- you just can't buffer than with the BS2. IMO, the Stamp should be the slave; let the PC search for those nodes.

    And, again, if you just need a one-to-one relationship you can simplify things by using transparent mode (address your master node as 0, and your slave node as 1). Here's a cool deal: You can have multiple slave nodes with this concept as long as you have some kind of identifier in your message as to which device gets the command (I use 0 for all). The XBee sorts out multiple nodes with the same MY address under the hood.

  • JonnyMacJonnyMac Posts: 8,973
    edited 2023-06-12 15:19

    There is no need to use Node Discovery. If you setup your XBees for transparent mode it will act like a wired connection without the wires.

    https://www.digi.com/resources/documentation/Digidocs/90001942-13/concepts/c_transparent_mode_detailed.htm?tocpath=XBee transparent mode|XBee transparent mode in detail|_____0

  • @JonnyMac
    Thank you! very useful information. All Xbee's are happy and communicating! Moving on to finish the project now!

Sign In or Register to comment.