strange bug printing data from xbee packet

Hi,

I'm having trouble printing out numerical data from a packet sent over a couple of xbee radios. I have a coordinator which is sending out regular heartbeat broadcast packets, and a receiver which receives these packets and sends back a log packet to show what it's doing. I'm trying to work out why I can't get the log packets to print out correctly over software serial. I've reduced the problem to sending a character string "1234567890ABCDEF" from the receiver, and printing it out either as characters, or as decimal character codes, from the coordinator.

The relevant code on the transmitter looks like this:

char readLogPacket() {
  // wait for a log packet and print out the contents.
  //delay(10);
  //usb.print(".");
  xbee.readPacket();
  //usb.print("-");
  if (xbee.getResponse().isAvailable()) {
    // something arrived.
    //usb.println("ia");
    if (xbee.getResponse().getApiId() == ZB_RX_RESPONSE) {
      // it's a log packet.
      //usb.println("rx");
      xbee.getResponse().getZBRxResponse(rx);
      //usb.println("done");
      return 1;
    } else {
      // not an RX packet.
      return 0;
    }
  } else {
    return 0; // no packet.
  }
}

...

void loop() {
...
  unsigned char* rxPayload;
  unsigned char test;
...
  while (!readLogPacket() && tickNo < oldTicks + 2);
  if (tickNo < oldTicks + 2) {
    usb.print("unpack: ");
    rxPayload = (unsigned char*) rx.getData();
    for (unsigned char i = 0; i < 16; i++) {
      test = rxPayload[i];
      usb.print(test);
      usb.print(" ");
    }
    usb.println();
  }
...
}

In other words, it's waiting to receive the log packet, and if it doesn't time out waiting, it puts a copy of the pointer to the received packet payload into rxPayload, then goes through storing successive characters in 'test' and printing them out.

If I use the exact code above, the result is like this:

Tick: 4

Tick: 8

Tick: 12

Tick: 16

unpack: 49 0 22 0 6 115 0 0 0 1 8 202 1 4 4 8 

Tick: 20

unpack: 49 0 22 0 6 115 0 0 0 1 8 202 1 4 73 8 

Tick: 24

Whereas if I print the characters cast into 'char' instead of 'unsigned char', it prints as it should. I.e. if I change the code to:

...
    for (unsigned char i = 0; i < 16; i++) {
      test = rxPayload[i];
      usb.print((char)test);
      usb.print(" ");
    }
...

it prints this:

Tick: 4

Tick: 8

Tick: 12

Tick: 16

unpack: 1 2 3 4 5 6 7 8 9 0 A B C D E F 

Tick: 20

unpack: 1 2 3 4 5 6 7 8 9 0 A B C D E F 

Tick: 24

unpack: 1 2 3 4 5 6 7 8 9 0 A B C D E F 

Tick: 28

unpack: 1 2 3 4 5 6 7 8 9 0 A B C D E F

Another thing to add to my perplexity is that when I define the character string in the coordinator's code, and print it directly, it works fine both ways...

If anyone has any idea what is going on here, I'd really appreciate it, as I've been stuck on what looked at first sight like a simple problem (sending log packets) for several days now. The only thing I can guess is that it might be due to some compiler optimisation that I don't know about, but I may be wrong.

Thanks.

I've just tried moving the log packet print code to a separate function, and turning off compiler optimisation within that function ('#pragma GCC optimize("O0")'). This doesn't help.

I'm having trouble printing out numerical data from a packet sent over a couple of xbee radios.

It would be nice to know what kind.

I have a coordinator which is sending out regular heartbeat broadcast packets

But, I'm not going to show you that code.

The relevant code on the transmitter looks like this:

That may seem like the relevant code, but there are a lot of instances that we can only guess at what there are an instance of.

  unsigned char* rxPayload;
    rxPayload = (unsigned char*) rx.getData();

Why are you using unsigned char as the type?

Assuming (yes, I know that is dangerous) that rx is an instance of RxDataResponse, the getData() method that returns a pointer is defined:

	/**
	 * Returns the payload array.  This may be accessed from index 0 to getDataLength() - 1
	 */
	uint8_t* getData();

Casting is often safe enough, but using the correct type is almost always better.

Whereas if I print the characters cast into 'char' instead of 'unsigned char', it prints as it should.

So, what's the problem? Was the data on the other end char or unsigned char? What is the problem with using char as the data type on the receiver?

What cast did you use to put the character data into the uint_8 array to be sent?

Hi,

Next time I'll post the whole code - I just wanted to avoid doing that because it's a fairly long program, and the problem was just in printing out the received log packets.

rx is an instance of ZBRxResponse. I know that it's meant to be uint8_t. The first thing I tried was to do the cast at the end, in the usb.print function (I.e. usb.print((char)test); ), but I was trying casting the pointer to see if it worked any better.

The other thing I tried since I posted this was to print 'test' in both formats at once. I.e. using this code:

      usb.print((char)test);
      usb.print(",");
      usb.print(test);
      usb.print(" ");

If I do that, neither the characters nor the numerical values come out right, apart from the first character in the packet.

I have managed to find a workaround for this problem, which is to copy the bytes from the xbee receive buffer into another buffer before printing them. If I do it this way, they will print as characters or decimal ascii codes perfectly well.

Thanks,

andy (highfellow)

One more question, that would have been answered by posting all of the code. What is usb an instance of?

Does that class derive from Print?

Hi,

usb is an instance of SoftwareSerial (from arduino 1.0.1 - i.e. based on NewSoftSerial). The code I have working now is attached to this post. This is different from what I was posting before because I've done some more work this afternoon. xbee_beacon_transmitter.pde is on the coordinator, which is sending out regular (4 second) ticks to the device running xbee_beacon_receiver.pde. The receiver sends back log packets, which is the bit I was stuck on.

The idea of the code is for the receiver to sync its own clock as closely as possible to the clock on the transmitter, in period and phase. This part isn't working fully yet, but at least I can now debug it. The code which sends the heartbeat and log packets is now working fine as far as I can see.

cheers. :slight_smile:

xbee_beacon_transmitter.pde (7.44 KB)

xbee_beacon_receiver.pde (9.64 KB)

I've reposted those files with some commented code removed, to make it easier to read.

xbee_beacon_receiver.pde (8.83 KB)

xbee_beacon_transmitter.pde (5.56 KB)

I'm confused.

usb is an instance of SoftwareSerial (from arduino 1.0.1 - i.e. based on NewSoftSerial).

Yet, you have .pde files, indicating that you are not using Arduino 1.0.1.

Using 1.0.1 libraries in older versions of the IDE is hardly recommended practice.

I didn't realise that was the way it worked. I've been using a makefile from ::[ edam ]:: » Arduino Makefile to build my sketches, so I hadn't noticed that .pde isn't recognised by the new IDE (if that's the case). (Before I switched to this makefile, I was using the one that came with earlier releases of arduino).

I switched to arduino 1.0.1 (from the earlier version that came with ubuntu) because I was wondering if there was a bug in NewSoftSerial that had been fixed in the latest release.

I've just tried changing .pde to.ino, and the files still build OK. I can't confirm whether they are working because I left the boards at work.