This project has moved. For the latest updates, please go here.

Changing I/O State

Aug 12, 2013 at 5:51 PM
Hello, I am fairly new to programming, and have loved your libraries so far. I am having an issue figuring out how to toggle the state of an I/O pin on a remote xbee controller. I can discover all of the controllers just fine. Can I get some help as to were to start?
Thank you,
Coordinator
Aug 12, 2013 at 10:43 PM
I'm glad you like the library and i hope you will be able to use it for your project. First thing i recommend is trying to toggle your local XBee I/O and after that trying to do the same with a remote. If you use X-CTU software than you should know that changing I/O state requires changing its configuration and sending it to the device. What actualy happens is X-CTU sends AT commands that change what you set up in the application. You need to do the same in your application - send AT command. See AT commands aproporiate for your XBee and use it so change I/O configuration. If you succeed then you can send the same AT command to a remote XBee and you are set! If you are not familiar with the AT commands try reading module serial number on your own using AT commands. Report on your progress and maybe i will be able to help you along the way.
Aug 12, 2013 at 11:27 PM
Hello,
I am sorry, I should have provided a little more information. I have read the "Building Wireless Sensor Networks" by O'Reilly, and have learned the basic Hex command layouts. I am able to use your libraries to discover all of the devices on my network, and am using that to store my "Serial Numbers", "Network Addresses", and "Node Identifier". I am a little confused about now using that information with your library to toggle on and off an I/O port on a remote controller and eventuall sending data to a remote mcu. I was able to write another program that took the data that I stored in the database and was able to create the hex command to turn on and off I/O ports. If you could point me in the direction of what parts of the library I would use to build my hex packets that would be great. Let me know what other information you need from me.
Coordinator
Aug 13, 2013 at 6:27 AM
Did you use X-CTU software before? Do you know how to set your local XBee I/O port to desired state using that software and how to check if you indeed control the port?
Aug 13, 2013 at 6:45 AM
Edited Aug 13, 2013 at 6:48 AM
Yes I used the x-ctu to toggle it manually. Then I tested doing it through x-ctu remotely from another radio(worked great) Now I am working on doing it from a c# application. I can again control the port remotely by sending commands to it, and manually typing up the hex frames. It looked like your library can build the hex frame alot simpler to send the AT commands to the radios, I just am a little lost on using your library to create and send the AT command in my c# application. Again thank you for your patients and help! Sent from my iPhone
Coordinator
Aug 13, 2013 at 8:27 AM
Ok so you are on the right track. In your code since you are able to discover your nodes you have your XBeeApi class object working. Use Visual Studio Object Browser to see this class methods. You will find a series of Send methods that allow you to create a request frame:
public AtRequest Send(AtCmd atCommand, params byte[] value);
public AtRequest Send(Api.Wpan.AtCmd atCommand, params byte[] value);
public AtRequest Send(Api.Zigbee.AtCmd atCommand, params byte[] value);
The first method creates AT command that is common to all XBee modules. The second one is dedicated to Series 1 XBee (802.15.4) and the last one is for Series 2 XBee (Zigbee). As arguments you provide the command type and data you want to send with it. You can also use other Send method to create the request from raw bytes as you did with the hex frame before. In result you will get AtRequest class object. Two methods of this class will be useful to you:
public XBeeResponse GetResponse();
public IRequest To(XBeeAddress destination);
First one just send the request and returns the response. The second one sets the receiver of the request (you will send to your local XBee by default To() is not called). Basically the request class implements something called Fluent API (Google it if you hear it for the first time). Hope this helps.
Aug 22, 2013 at 3:47 AM
Edited Aug 22, 2013 at 3:48 AM
Thank you for your replies, they were very helpful. I have another question, I have been banging my head against the wall, and can't get it to work. Maybe you can give me some hints and idea. Like I said before I am can discover all of the devices from my software, store the addresses ect. I can also send my AT commands to the end devices. What I would like to do is press a button on my mcu, and have it send a message to my coordinator. (I can do this part, and receive the message perfectly in my program. I am using the listener. I can see the data just fine with the listener below, but am not sure how to see the address of the end device that sent the data. I know the format of the messages, so I know the address is somewhere, just can't figure out how to get it from the sender variable. I am sure it is just late, and it is something simple, but your help would be great!!
  public static void OnData(XBeeApi receiver, byte[] data, XBeeAddress sender)
        {
            var dataStr = new string(Encoding.UTF8.GetChars(data));
            
            Console.WriteLine(dataStr);
            StringBuilder hex = new StringBuilder(sender.Address.Length * 2);
            foreach (byte b in sender.Address)
            {
                hex.AppendFormat("{0:x2}", b);
                Console.WriteLine(b);
            }
        }
Also would I be able to see the 64 and 16 bit addresses of the sender?
Aug 23, 2013 at 5:14 AM
Still banging my head against the wall. Any help would be greatly appreciated!
Aug 23, 2013 at 5:30 AM
I have worked on this wonder API before. What I see here is that in OnData event you can only get the payload. The sender device information will not be here.
If you want that then you need to get the XbeeResponse which gets generated by this API.

And For this kind of work you need to forget Ondata event and hook up with Listner, here is the code have a look at it.

public class MyListener : IPacketListener
{
    public IList<XbeeResponsePacket> AllPacket = new List<XbeeResponsePacket>();

    public void ProcessPacket(XBeeResponse packet)
    {

        // This will write a packet for every incoming frame
        if (packet.GetType().Name == "RxResponse")
        {
            XbeeResponsePacket resPacket = new XbeeResponsePacket();

            //Console.WriteLine("<- {0} {1}", packet.GetType().Name, packet);
            Type type = packet.GetType();
            var payloadval = type.GetProperty("Payload").GetValue(packet, null);
            var SourceSerialNumber = type.GetProperty("SourceSerial").GetValue(packet, null);
            var SourceAddress16Bit = type.GetProperty("SourceAddress").GetValue(packet, null);

            resPacket.Payload = (byte[])payloadval;
            resPacket.SourceSerialNumber = SourceSerialNumber.ToString();
            resPacket.SourceAddress16Bit = SourceAddress16Bit.ToString();
            AllPacket.Add(resPacket);
        }
    }

    public XBeeResponse[] GetPackets(int timeout)
    {
        throw new NotSupportedException();
    }

    public bool Finished { get { return false; } }

}

I hope this will help you.
Aug 23, 2013 at 4:33 PM
You are the man! That worked great! Thank you!! I will post complete working code in a little bit.
Aug 24, 2013 at 3:31 AM
Edited Aug 24, 2013 at 4:38 AM
Ok, one more question. So lets say I use the same code you had. When my listener receives the information I can break out everything the way I need to, but want to know if there is a way, or the best way to reply to the node that I just received the information from.

For example:
public class MyListener : IPacketListener
{
   

    public void ProcessPacket(XBeeResponse packet)
    {

        // This will write a packet for every incoming frame
        if (packet.GetType().Name == "RxResponse")
        {
           

            //Console.WriteLine("<- {0} {1}", packet.GetType().Name, packet);
            Type type = packet.GetType();
            var payloadval = type.GetProperty("Payload").GetValue(packet, null);
            var SourceSerialNumber = type.GetProperty("SourceSerial").GetValue(packet, null);
            var SourceAddress16Bit = type.GetProperty("SourceAddress").GetValue(packet, null);

            var payload = (byte[])payloadval;
            var Source_Serial = SourceSerialNumber.ToString();
            var Source_Network_Address = SourceAddress16Bit.ToString();

           
             //Respond to source node here. I tried setting up nodeinformation with the serial number and network address but get an error saying that it can't because the object does not exist.??


        }
    }

    public XBeeResponse[] GetPackets(int timeout)
    {
        throw new NotSupportedException();
    }

    public bool Finished { get { return false; } }
Aug 24, 2013 at 7:46 AM
You need to pass xBee Object to listener class and then get the node and then send a xbee request to node.

But I think its not the right place to do this kind of work here.

remember single responsibility principle.

So once you have all the packet in hand then somewhere loop though them and send Acknowledgements.

To look at Acknowledgements just Remove this line " if (packet.GetType().Name == "RxResponse") " and enable this line

//Console.WriteLine("<- {0} {1}", packet.GetType().Name, packet);

Then you will see the Acknowledgements Coming in.

You can try sending them.
Aug 26, 2013 at 3:53 PM
TechSavy, thank you again. You gave me some great direction. And, of course I have one more question. I am creating a nodeinfo object with the data I have collected using the above code. I can write the Serial address to the object just fine (I am giving it a string value and it converts it). But I am unable to populate the Network Address. I was wanting to give it the network address as well to help minimize overhead on the network trying to search for it. If I manually type in the network address (ie. 0x0DF3), it works great. But no matter if I try to convert it to a byte array, or to int32 I can't get it to work programatically. Any help would be apprenticed.
Coordinator
Aug 26, 2013 at 8:46 PM
Edited Aug 27, 2013 at 8:04 AM
Guys, why are you butchering this library :) Take a look at this and tell me why are you doing what you are doing
        public void ProcessPacket(XBeeResponse packet)
        {
            Console.WriteLine("<- {0} {1}", packet.GetType().Name, packet);

            if (packet is RxResponse)
            {
                var rxResponse = packet as RxResponse;
                var payload = rxResponse.Payload;
                var sourceSerial = rxResponse.SourceSerial.ToString();
                var sourceNetworkAddress = rxResponse.SourceAddress.ToString();

                // assuming that your XBeeApi object is accessable 
                // via static property on Program class
                var nodeInfo = new NodeInfo(sourceSerial, sourceNetworkAddress);
                Program.Xbee.Send("Hello").To(nodeInfo).NoResponse();
            }
        }
Aug 26, 2013 at 9:37 PM
It can not find a reference to "RxResponse". I am using Visual Studio 2012. I have added the Xbee.pc project as a reference for my project. I also added the Gadgeteers project, and that didn't change anything. I did see RXresponse in the xbee_42 project, but am unable to add this project using Visual Studio 2012, 2010, or 2008? Any ideas?
Coordinator
Aug 26, 2013 at 10:10 PM
There are two version of this class depending on type of XBee module you are using. Assuming you are using the Series 2 modules (Zigbee) you need to add this
using NETMF.OpenSource.XBee.Api.Zigbee;
Aug 26, 2013 at 10:53 PM
Edited Aug 26, 2013 at 10:54 PM
Man, can't believe I missed that. I have implemented this cleaner method that you provided above, but I still have the exact same problem.
var nodeInfo = new NodeInfo(sourceSerial, sourceNetworkAddress);
Gives an error saying ," The best overloaded method match for 'NETMF.OpenSource.Xbee.Api.Common.NodeInfo.NodeInfo(NETMF.OpenSource.XBee.Api.XBeeAddress64, NETMF.OpenSource.Xbee.Api.XBeeAddress16)' has some invalid arguments."

So to see were the invalid argument was I tried this:
NodeInfo ni = new NodeInfo();
                ni.SerialNumber = new XBeeAddress64(sourceSerial);
                ni.NetworkAddress = new XBeeAddress16(rxResponse.SourceAddress);
and
 NodeInfo ni = new NodeInfo();
                ni.SerialNumber = new XBeeAddress64(sourceSerial);
                ni.NetworkAddress = new XBeeAddress16(sourceNetworkAddress);
And get the same error only for the "Network Address. Any ideas?
Coordinator
Aug 27, 2013 at 8:08 AM
Edited Aug 27, 2013 at 8:08 AM
I wrote my sample code in notepad so don't take everything as is. NodeInfo constructor is accepting XBeeAddress64 and XBeeAddress16 as arguments and you are providing two string arguments instead. I suggest you start using Resharper it will make your life easier.