Pages: [1]   Go Down
Author Topic: strange bug printing data from xbee packet  (Read 955 times)
0 Members and 1 Guest are viewing this topic.
uk
Offline Offline
Newbie
*
Karma: 0
Posts: 30
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
Code:
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:
Code:
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:

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

it prints this:

Code:
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.
Logged

uk
Offline Offline
Newbie
*
Karma: 0
Posts: 30
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 551
Posts: 46257
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.

Quote
I have a coordinator which is sending out regular heartbeat broadcast packets
But, I'm not going to show you that code.

Quote
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.

Code:
  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:
Code:
/**
* 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.

Quote
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?
Logged

uk
Offline Offline
Newbie
*
Karma: 0
Posts: 30
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

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)
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 551
Posts: 46257
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

uk
Offline Offline
Newbie
*
Karma: 0
Posts: 30
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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. :-)

* xbee_beacon_transmitter.pde (7.44 KB - downloaded 4 times.)
* xbee_beacon_receiver.pde (9.64 KB - downloaded 5 times.)
Logged

uk
Offline Offline
Newbie
*
Karma: 0
Posts: 30
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

* xbee_beacon_receiver.pde (8.83 KB - downloaded 5 times.)
* xbee_beacon_transmitter.pde (5.56 KB - downloaded 5 times.)
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 551
Posts: 46257
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm confused.
Quote
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.
Logged

uk
Offline Offline
Newbie
*
Karma: 0
Posts: 30
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I didn't realise that was the way it worked. I've been using a makefile from http://ed.am/dev/make/arduino-mk 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.
Logged

uk
Offline Offline
Newbie
*
Karma: 0
Posts: 30
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Pages: [1]   Go Up
Jump to: