Monday, October 22, 2012

Monitoring My XBee Network

In the previous post <link> I wrote about how I discovered broadcast mode can cause problems as you increase the number of nodes.  That led to a method of monitoring each node to see what it was actually doing, and by watching each of them in turn, seeing how the traffic patterns work out.

Well, I left it kind of up-in-the-air on exactly how I did it.  Basically, I used the examples that Akiba of Freaklabs released for various functions and created a sniffer of sorts.  This is necessary because the XBee only sends out the serial port data intended for the particular radio module you're plugged into.  That's what makes broadcast mode so useful, you can see all the traffic and chase problems.  With a Freakduino Chibi board, you can monitor all the devices on your network at once, but that is way too much information to try to wade through.  By setting the Chibi board to promiscuous mode and then writing code to filter by address, you can watch any node in the network to see what is going on with that particular device.  This makes it possible to see its traffic even though you aren't using an XBee.

Here's the code I came up with:

The Arduino Sketch
/*
This sketch enables promiscuous mode on the Freakduino boards and then
filters by device address to watch a particular node.

I had to change the buffer size in the chibi library for promiscuous mode
because, being set to 1024 with another buffer for the packet to be manipulated
caused the board to run out of RAM.  Just go into the chibi library and
find the receive buffer in chb_buf.h and set it to what you want.  I used the
value 500, and it seems to work fine

Before using this sketch, also go into the chibiUsrCfg.h file and
enable promiscuous mode. To do this, change the definition:

#define CHIBI_PROMISCUOUS 0
to
#define CHIBI_PROMISCUOUS 1

When not using promiscuous mode, disable this setting by changing
it back to 0.
*/

#include <chibi.h>
#include <avr/pgmspace.h>
#include <MemoryFree.h>

/*
Addresses of devices in my network
                    Long     Short
Garage Controller 407A 38AF  A019
Power Monitor     4031 566B  CD6B
Controller        4055 B0A6  97FA
Status Display    406F B6B5  9BE8
Pool Controller   4079 B2BD  9370
Temp1             406F 7FAC  1B1E
House Clock       4055 B094  0
Acid Pump         406F B7AF  7D58
*/
char *deviceName[] = {"Garage Controller",
                       "Power Monitor",
                       "Controller",
                       "Status Display",
                       "Pool Controller",
                       "Temp1",
                       "House Clock",
                       "Acid Pump"};
uint16_t deviceAddress[] = {0xA019,
                         0xCD6B,
                         0x97FA,
                         0x9BE8,
                         0x9370,
                         0x1B1E,
                         0x0,
                         0x7D58};
uint16_t listenTo;
byte Pbuf[500];
char Dbuf[50];
int longest = 0;

void showMem(){
  strcpy_P(Dbuf,PSTR("Mem = "));
  Serial.print(Dbuf);
  Serial.println(freeMemory());
}

/**************************************************************************/
// Initialize
/**************************************************************************/
void setup()
{
  // Init the chibi stack
  Serial.begin(115200);
  chibiInit();
  strcpy_P(Dbuf,PSTR("\n\r***************I'm alive**************"));
  Serial.println(Dbuf);
  unsigned int choice = 0;
  Serial.println("Pick a device to listen to");
  for(int i = 0; i < sizeof(deviceName)/sizeof(deviceName[0]); i++){
    Serial.print((char)(i + 'A'));
    Serial.print(" - ");
    Serial.println(deviceName[i]);
  }
  Serial.print("> ");
  // this only accepts a single character for the device choice.
  // that's because the chibi board runs at 8MHz on the internal clock and
  // internal clocks aren't accurate.  This means the higher baud rates sometimes
  // have problems.  When I worked on this I couldn't get the board to accept more
  // than one character correctly at baud rates over 57K.  Works fine at 9600,
  // but I want to output the data far faster than that.
  while(1){
    if(Serial.available() != 0){
      char c = Serial.read();
      Serial.write(c);
      Serial.println();
      choice = toupper(c) - 'A';
      if (choice < sizeof(deviceName)/sizeof(deviceName[0]))
        break;
      else {
        Serial.println(" oops, try again");
        Serial.print("> ");
      }
    }
  }
  listenTo = deviceAddress[choice];
  strcpy_P(Dbuf,PSTR("Starting Radio, Result = "));
  Serial.print(Dbuf);
  Serial.println(chibiSetChannel(12),DEC);
  strcpy_P(Dbuf,PSTR("Listening to "));
  Serial.print(Dbuf);
  Serial.print(deviceName[choice]);
  strcpy_P(Dbuf,PSTR(" at address "));
  Serial.print(Dbuf);
  Serial.println(listenTo, HEX);
  showMem();
}

/**************************************************************************/
// Loop
/**************************************************************************/
void loop()
{
  // Check if any data was received from the radio. If so, then handle it.
  if (chibiDataRcvd() == true)
  {
    int len;
    uint16_t senderAddress;
 
    // send the raw data out the serial port in binary format
    len = chibiGetData(Pbuf);
    if (len > longest)
      longest = len;
    senderAddress = chibiGetSrcAddr();
    if (senderAddress == listenTo && len > 0){
      strcpy_P(Dbuf,PSTR("From: "));
      Serial.print(Dbuf);
      Serial.print(senderAddress,HEX);
      strcpy_P(Dbuf,PSTR(" Len: "));
      Serial.print(Dbuf);
      Serial.print(len);
      strcpy_P(Dbuf,PSTR(" Longest: "));
      Serial.print(Dbuf);
      Serial.println(longest);
      for (int i= 0; i < len; i++){
        uint8_t nibble = (uint8_t) (Pbuf[i] >> 4);
        if (nibble <= 9)
          Serial.write(nibble + 0x30);
        else
          Serial.write(nibble + 0x37);
     
        nibble = (uint8_t) (Pbuf[i] & 0x0F);
        if (nibble <= 9)
          Serial.write(nibble + 0x30);
        else
          Serial.write(nibble + 0x37);
        Serial.print(' ');
      }
      Serial.println();
      for (int i= 0; i < len; i++){
        uint8_t nibble = (uint8_t) (Pbuf[i] >> 4);
        Serial.write(' ');
        if (iscntrl(Pbuf[i]))
          Serial.write(' ');
        else
          Serial.write(Pbuf[i]);
        Serial.write(' ');
      }
      Serial.println();
    }
  }
}


A couple of things to keep in mind.  The Chibi board is only running at 8 Mhz, so it can't keep up with unlimited traffic flying through the air at 250Kb forever.  If you spend too much time in the code checking and decoding, you'll miss packets.  The Chibi library sets a buffer size of 1024 to handle packets being received to help with this, but you'll have to reduce this size because the MCU only has 2K of ram to begin with.  I point this out in the code.  The maximum size of a packet is 127 bytes, so make your parsing buffer longer than that.  I print the maximum packet length in the code above, and have never seen a packet larger, so it appears the library is working fine for separating the packets.  I also put a routine in the code to monitor  memory usage.  Use this to keep track so you don't run out with the various buffers and such.

Here's a sample of the output using the serial monitor from the Arduino IDE:


It doesn't wrap around, but that could be easily added.  I just use the scroll bar on the bottom to move around.  I output the hex values as well as the ascii so I can recognize the various packets as well as decode the binary portions of the data.

So, as your network grows, or you have problems right off the bat, consider this combination of things as a possible tool to help you get past it.  Of course, you're welcome to grab the code and modify it to your particular network and need for monitoring.

27 comments:

  1. Many thanks, I have been struggling with XBee in API mode for weeks. This really helped me make progress. Also a great blog that this gadget gal enjoyed reading.

    Chris



    ReplyDelete
  2. I almost gave up on XBees when I first started using them. Then, something clicked and they started working for me. That's one reason why I started blogging about them. They are really cool little tools, but only once you start getting them to actually talk to one another. If you haven't already, take a look at the posts on the Arduino XBee library. Now that the library supports the another serial port (either software or hardware), it makes a nice interface to the devices.

    ReplyDelete
  3. I just ordered a chibi for sniffing my network (thanks for all of the xbee ideas,examples and help) and upon looking into the chb_buf.h file to change the buffer size it already takes care of changing the buffer size for you. It's set to 768 if in promiscuous mode so I don't think there is a need for that step anymore. The file was updated 3 months ago so I'm assuming that they went in and took care of the problem you were having. Just trying to give a little back
    Dave

    ReplyDelete
  4. Thank you very much. The next person that reads this will save some time...or me when I make changes to it.

    ReplyDelete
  5. Could you post a link to where you learned about strcpy_P & PSTR? I've been having a look around and there seems to be a bit of conflicting and confusing views and usage of strings being stored in program memory, to the point where someone is giving out instructions on changing code in a library to make it work.

    ReplyDelete
  6. I came across it by messing with the code in the arduino playground. However, they put a relatively new page up that has more examples at:

    http://playground.arduino.cc/Main/Printf

    There's stuff in there that I haven't played with yet.

    ReplyDelete
  7. This comment has been removed by the author.

    ReplyDelete
  8. try this bit of code out to help you with reading multiple characters. I use numbers but I'm sure it can be easily adapted to work with characters

    [CODE]
    // function reads user input and converts input array to an integer

    char read_array[4]; // array to store user input in menu make any size you want
    // Serial.flush(); used to clear the Rx buffer but doesn't work in 1.0.
    // I do this so that if the user accidentally enters something before they
    // are prompted to it won't be read.
    Serial.println("Whatever your table is."); // print user prompt
    while(Serial.available() > 0) // if buffer isn't clear
    Serial.read(); // clear it
    while (Serial.available() == 0); // wait here for user input
    //while(Serial.available() <= sizeof(read_array) - 1); // or wait for buffer to fill
    for (int i = 0; i <= sizeof(read_array); i++){
    read_array[i] = Serial.read(); // read incoming data into array
    delay(10); // breathe
    }
    int choice = atoi(read_array); // array to int
    // work some magic with choice!
    [CODE]

    ReplyDelete
    Replies
    1. Thank you. What baud rate are you using on the serial port? I'll give this a try in a week or two; I'm up to my neck in another project that is eating me alive right now.

      Delete
  9. I usually use 57600 but lately I've been running 115200. the datasheet for the 328p says that 57600 is the fastest with the lowest error rate which is why I started using it. I haven't had any issues with 115200 but I've been working with native serial ports and 16MHz so I don't know how it will respond using softSerial and/or 8MHz. I've also looked up .printf and now I'm wrapping all of my display text with F(); serial.print(F("Hello World")); It saves a ton of memory (I now use 328p where I needed a Mega2650 before). I haven't played around with it a lot but I haven't noticed any bugs that have come up from storing strings in flash.
    Cheers!

    ReplyDelete
    Replies
    1. I remember when I discovered that strings ate up most of my memory. From then on, my project size dropped a bunch. Watch out for the String datatype and various stream operations too. They eat memory at run time and can kill an Arduino. Scout around here for the little memory routine that I use and include it as needed. I use the heck out of it.

      Delete
  10. I worked on some quick code that lets you enter a string of characters into the serial monitor and it will get saved as an array. Does anyone know how to then take the array that was just made and turn it into a string and place it inside of another array? The thought is; you have your array that holds the names of all your nodes, well say you want to rename one of the nodes but while the program is running and not just through re-uploading the code with a different name.
    [CODE]
    byte numOfElem = 20;
    char readName[numOfElem] = {}; // character array
    Serial.print(F("Enter Name (Cannot Be Greater Than 20 Characters: "));
    while (Serial.available() > 0){ // if there is junk in the serial inbox
    Serial.read(); // read it out
    }
    while(Serial.available() == 0); // wait for user input
    byte i = 0;
    while(Serial.available()){
    readName[i] = Serial.read(); // place character into array
    Serial.print(readName[i]); // debug
    i++;
    }
    Serial.println();
    Serial.print(readName);
    [CODE]

    ReplyDelete
    Replies
    1. To turn it into a 'c' string, just put a null at the end. Right after the loop just stick the null in. To copy from one array to another , you can then use strcpy(). If you want to you could simple set the array to 0 first by using memset() to clear it all. Be sure to allow for an extra character at the end.

      Delete
  11. Ok I think I got this all figured out. remember this is a code snippet! this could possibly work great for a network that shuts down and then needs to find 16 bit network addresses again. Next I want to work on getting the chibi to print out to a display of some sort, not sure if I'll have enough memory for a lot of data to be displayed thinking a receipt printer might work better, but it could work for individual events and then the chibi could be a truly stand alone system monitor.
    thanks for the patience and support Dave!
    [CODE]
    byte numOfElem = 20;
    char readName[numOfElem] = {}; // character array
    Serial.print(F("Enter Name (Cannot Be Greater Than 20 Characters: "));
    while (Serial.available() > 0){ // if there is junk in the serial inbox
    Serial.read(); // read it out
    }
    while(Serial.available() == 0); // wait for user input
    byte i = 0;
    while(Serial.available()){
    readName[i] = Serial.read(); // place character into array
    Serial.print(readName[i]); // debug
    i++;
    }
    readName[i] = 0x00; // add null character
    Serial.println();
    Serial.print(readName);

    strncpy(deviceName[j], readname, sizeof(deviceName[j]); // copies readName to deviceName[j] address and will not allow readName to write past the memory allocation of deviceName[j]
    [CODE]

    ReplyDelete
    Replies
    1. I knew you'd get it working. Isn't it fun when you do something cool like that?

      Delete
  12. Sure is dude! Now I just have to get some free time to stitch all of these ideas together... and get my sous-vide working so that I can control the temperature of 10 gallons of water.
    My boss found this set of machine code (on the web somewhere) and it will return how many bytes of SRAM are free, and it doesn't require a library. I personally have no idea what's going on I've been just copying and pasting :/
    [CODE]
    // this function returns the number of bytes currently free in SRAM
    int freemem(){
    extern int __heap_start, *__brkval;
    int v;
    return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
    } // end int freemem()...
    [CODE]

    I noticed that in your serial monitor print out of each packet that there isn't a very strict repetition of protocol bytes. Also the XBee start byte never shows up. I'm not sure why this is.

    ReplyDelete
    Replies
    1. That code is the same as the c code to get the memory left. It'll run a tiny bit faster, but that doesn't really matter if it isn't run very often. You need to save time in stuff that is executed a lot, not something that is executed once in a while. But, it's cool; I'd use it just ... because.

      The start byte '7e' is tucked in there by the the XBee itself. It doesn't really exist over the air. That's one thing you'll have to get used to, the stuff over the air isn't exactly what is output over the serial port. If you have relay hops, you'll start to notice the packets getting longer as they move along. They carry the addresses of each forwarding device. It's kind of cool watching it, but I got tired of it and just started looking at the stuff that I needed to fix a particular problem.

      Nowadays I use it to see what's actually going on. I thought about changing the code a bit to just strip out the things I need for presentation and leave the other stuff out. Haven't had enough ambition to do it though.

      Delete
  13. This comment has been removed by the author.

    ReplyDelete
  14. Ok so I got the Chibi up and running and it was really simple, pretty much plug and play I had to change it promiscuous 1 like you say. I did modify your code a little bit because I want to look at everything that's going on (this helps to see if other stuff is broadcasting on the same channel). I didn't change any of the channels on the XBee network. On the Chibi I set it to channel 15 b/c Dave did and b/c that's the only channel that worked for my network (default is 11). This is the sketch I run and it should work for anyone that just wants to take a peek at their own:
    [CODE]
    /*
    Taken from code @ desert-home.com, thanks Dave!

    Before using this sketch, also go into the chibiUsrCfg.h file and
    enable promiscuous mode. To do this, change the definition:

    #define CHIBI_PROMISCUOUS 0
    to
    #define CHIBI_PROMISCUOUS 1

    When not using promiscuous mode, disable this setting by changing
    it back to 0.
    */

    #include
    #include
    #include

    int longest = 0;
    byte Pbuf[768]; // max buffer size of Chibi so shouldn't need to be bigger
    char *deviceName[] = {"Coordinator", "Router1", "Router2", "Router3"};
    unsigned int deviceAddr[] = { 0x0000, 0x3DAA, 0x7557, 0x9646};

    // this function returns the number of bytes currently free in SRAM
    int freeMem(){
    extern int __heap_start, *__brkval;
    int v;
    return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
    } // end int freemem()...


    /**************************************************************************/
    // Initialize
    /**************************************************************************/
    void setup()
    {
    // Init the chibi stack
    Serial.begin(57600);
    chibiInit();
    chibiSetChannel(15); // set channel to 2425 MHz
    Serial.print(F("\n\r***************I'm alive************** \n"));
    Serial.print(F("Init Program Mem = "));
    Serial.print(freeMem());
    Serial.println();
    }

    /**************************************************************************/
    // Loop
    /**************************************************************************/
    void loop(){
    // Check if any data was received from the radio. If so, then handle it.
    if (chibiDataRcvd() == true){
    int len;
    byte flag;
    uint16_t senderAddr;
    // send the raw data out the serial port in binary format
    len = chibiGetData(Pbuf);
    if (len > longest)
    longest = len;
    senderAddr = chibiGetSrcAddr(); // get address
    for(int i = 0; i < 4; i++){
    if(senderAddr == deviceAddr[i]){ // find device name
    Serial.print(F("From: "));
    Serial.print(deviceName[i]);
    Serial.print(F(" Address = "));
    Serial.print(deviceAddr[i], HEX);
    }
    }
    Serial.print(F(" Len: "));
    Serial.print(len);
    Serial.print(F(" Longest: "));
    Serial.print(longest);
    Serial.print(F(" Free Mem = "));
    Serial.println(freeMem());
    for (int i= len; i >= 0; i--){
    if (Pbuf[i]<0x10) // adds leading zero if necessary
    Serial.print("0");
    Serial.print(Pbuf[i], HEX);
    Serial.print(" ");
    }
    Serial.println();
    }
    }
    watching what goes on when data is sent and just the idle chatter really helps me understand whats going on. It almost makes me want to write a chibiXBeeArduino library so it is even easier to understand what all of the chatter is without having to freeze-frame and look up what all of the bytes code for, but I have way too many projects on my desk, in my basement, out on Lake Michigan, you get the idea. Enjoy all!
    Cheers

    ReplyDelete
    Replies
    1. Good job. If you want to preserve it, get a program off the web call putty. It's a really sophisticated terminal program that can grab the stuff as it comes in and save it to a log file. You'll stumble around a bit getting used to it because it has about a million option and configurations.

      Trust me, it's worth the effort. I use it a lot for this kind of thing since the stuff flies by a whole lot faster than I can read.

      Delete
  15. Hello Dave
    Can I throw a question at you on XBee?
    I have a small network of Series 2 XBees, mainly doing temperatures and counting utility meter pulses. There is one coordinator sitting with a Mega 2560, three routers and some end devices working in sleep mode with pin wake.
    Most of the time it works well, but now and again, the pulse XBees will drop a pulse probably due to a transmission problem. I would like to try another approach. Instead of sending each pulse as a digital change, I thought it might be better to count the pulses at the end devices, then periodically send the accumulated count value to the coordinator. This is going to involve possibly a sleeping Arduino at the end device to do the counting. So instead of the Hall sensor or whatever being connected to the XBee, it would connect to the Arduino, and the XBee would serve simply as the trasmission device. Another though is to get the coordinator Mega to send a request to the remote Arduino/XBee (end device) and request it sends the data.
    All of this would be a complete departure to how I am working now so before I start on what could be a waste of time, your advice would be appreciated.
    Up until now, I have been doing all my own packet parsing etc., but you use the XBee Arduino library by Andrew Rapp. I've started looking at it and noticed that it uses SoftwareSerial. You suggest using the "new" softwareserial by Paul Stoffregen, which I presume is AltSoftwareSerial. Should I change and include AltSoftwareSerial? I'm a bit confused on this and also where XBee.h comes into it. The Arduino XBee (ARapp) library I have refers to modifications by Paul S and others, so I presume it is the latest version.
    I appreciate that the Mega has other Serial ports, and eventually I will use these instead of software serial, but the sketch is very, very long. So I thought I would just set up a separate Arduino>XBee>XBee>Arduino pairing to see if the data (count) transmission works better than the digital change (XBee) method.
    Thanks from the UK

    ReplyDelete
    Replies
    1. The ONLY time I use software serial is when there is only one serial port on the device. When you have a real serial port, use it. If you've got your heart set on using a Mega, use the real serial port. It's not that software serial is bad or hard to use, it's that the buffering and such is much better using hardware.

      Sending a transmission per pulse can lead to a LOT of traffic and lost transmissions, so I see your problem.

      I use arduinos to gather information, store it, then forward it to something that reports a lot. I even construct the packets into something I can read so I don't have to count bytes and convert from hex when I monitor things. It lowers the traffic a lot and gives me something I can watch when the inevitable problems happen.

      Andrew's Library is great, and yes, it has been modified to work really well with software serial, but you don't have to use software serial. I works well with hardware also. I modified Andrew's library to include two of the XBee messages that he originally didn't include. That library is on github if you want it.

      Somewhere on this blog I included my first experiences with the library, you can use that as an example to get you going. The idea of setting up a little separate network is a good one. That's the way I did it to test using the library originally.

      Delete
  16. Hello Dave
    Thanks for getting back so promptly - I can see you keep busy.
    I use the Mega simply because the main sketch is now >50k, so long since wouldn't fit on a 328. I'm in the process of changing or adding a new Serial instance right now to try on the Mega. I buy the Mega as a clone from Elegoo so it's cheap to use. Sometime, time permitting; I would like to try some of the more powerful boards like the Feather MO (Cortex).
    Adding an Arduino at the end devices (and routers) is something I have been putting off mainly down to the additional complexity of sleeping, but it would certainly ease a lot of problems. Handling a pulse is harder than it looks, especially with mechanical meters like the water meter where the dial magnet can stop right over the Hall sensor - I have been using CMOS logic to create a distinct pulse, but an MCU would be easier. The main transmission problems occur with the electrity meter where the pulses are relatively fast, but slow compared to XBee capability, but I am already dividing down the pulses on a Nano, and dropouts still happen - I find it happens when something else barges in like another meter. Storing on the Arduino would allow multiple transmissions of the data to make sure it gets through. Incidentally, I do use software serial with GPS which does generate a lot of transmissions, but no problems so far. I have a remote GPS antenna on a roof and use a pair of XBees in AT mode to transmit the data back to the house.
    I’ll take a look at your blog in more detail and GitHub.
    There is a lot of activity with people using the ESP boards now, but the XBees are still dependable and XCTU saves a lot of messing about.
    I was reading your bits on the rattlers. I'm plagued by rats from a neighbouring property and envy you having a 22 handgun. Loading up an airgun can take too long sometimes
    Best wishes

    ReplyDelete
    Replies
    1. Hint, subsonic rounds and a water bottle (empty) over the barrel doesn't get too loud. Also, there are CO2 airguns that can rapid fire; they waste the gas cartridge if you store it though. Just a thought.

      Delete
  17. Hi Dave!

    I'm finishing my final year in electronics engineering at the moment and this blog has really helped me in my thesis. I do have one question though.

    My group and I plan on setting up network that consists of end devices, routers, and a coordinator. One of our objectives is to see the route each packet takes to the coordinator. I tried Wireshark and a sniffer to do this, but not only will it not cover the entire network, our adviser told us that sniffing the traffic isn't going to be enough to prove that the packets did take the route they did.

    My next idea was to connect the router XBees to their own Arduino Unos and have the Uno log the data that the routers receive into a micro SD Card. I tried to use the code in the part 1 of the "Using the XBee Library" part of the blog and I realized that while the Uno can tell if the router got data before passing it on, it isn't a Zigbee Receive packet, so I tried to edit the code to just print the frame that the router got regardless of what kind of packet it is.

    This is the code I eventually ended up with.

    #include
    #include
    #include
    #include

    File IntermediateCapture;

    XBee xbee = XBee();
    XBeeResponse response = XBeeResponse();
    ZBRxResponse rx = ZBRxResponse();


    #define ssRX 2
    #define ssTX 3
    SoftwareSerial nss(ssRX, ssTX);

    void print32Bits(uint32_t dw)
    {
    print16Bits(dw >> 16);
    print16Bits(dw & 0xFFFF);
    }

    void print16Bits(uint16_t w)
    {
    print8Bits(w >> 8);
    print8Bits(w & 0x00FF);
    }

    void print8Bits(byte c)
    {
    uint8_t nibble = (c >> 4);
    if (nibble <= 9)
    IntermediateCapture.write(nibble + 0x30);
    else
    IntermediateCapture.write(nibble + 0x37);

    nibble = (uint8_t) (c & 0x0F);
    if (nibble <= 9)
    IntermediateCapture.write(nibble + 0x30);
    else
    IntermediateCapture.write(nibble + 0x37);
    }

    void setup()
    {
    Serial.begin(9600);
    nss.begin(9600);
    xbee.setSerial(nss);
    SD.begin(10);
    }

    void loop()
    {
    xbee.readPacket();
    if (xbee.getResponse().isAvailable())
    {
    IntermediateCapture = SD.open("xbeelog.txt", FILE_WRITE);
    if (IntermediateCapture)
    {
    IntermediateCapture.print(" Frame: ");
    for (int i = 0; i < xbee.getResponse().getFrameDataLength(); i++)
    {
    print8Bits(xbee.getResponse().getFrameData()[i]);
    IntermediateCapture.print(' ');
    }
    IntermediateCapture.println();
    IntermediateCapture.close();
    }
    }
    }

    To test this, I set up a simple network consisting of a coordinator, router, and end device. I connected the coordinator to my laptop and watched the packets it received using XCTU. I stopped the test after the coordinator received 252 Receive Packets.

    The problem with the code I pasted above is that it only logged two frames, and the frames that were saved in the SD Card were literally only:
    00
    02

    Is it even possible to log the packets received by a router using Arduino Uno?

    ReplyDelete
    Replies
    1. I don't think there's a way to capture the routing information as it operates with an XBee.

      These little devices' big selling point is that they DO NOT have a promiscuous mode where they let you see all the traffic. The packets between XBees that route and forward are invisible to the guy that is passing data between them.

      You can direct the traffic yourself through the various devices, but that doesn't help for your project.

      I'm curious why your advisor says Wireshark can't prove where the packets went on their way around the network. That's pretty much its purpose for some people.

      Also, I don't understand why you can't cover the entire network with wireshark. You can always use multiple instances of Wireshark running on a machine placed where it can see whatever you want, combine the output and trace it that way.

      Having the hardware might be a problem in your environment though.

      Delete
    2. It's been a while since our last meeting but I don't think I asked why it Wireshark wasn't enough.

      As for not being able to cover the entire network, I only have one laptop to use. I guess I can capture the traffic from one route then save the capture file before moving to another route. For the purpose of determining the route that each packet takes, that should be enough right?

      Also, thank you so much for replying. I'm at my wit's end regarding this issue and it's nice that I'm getting some clarifications.

      Delete