Xbee Communication is causing Teensy to halt

Status
Not open for further replies.

ahpuck

Member
Hello,

I'm having a relatively curious issue with a custom PCB that I use. It has a Teensy 3.2 and an XBee S2C. I was experiencing an issue where anytime any of my code resulted in an xbee.send(), the program would come to a stop.

Initially I thought this behavior was due to a buggy I2C bus so using an InterruptTimer I added a second chunk of code that checked to see if a variable in the main loop was being incremented and if it stopped getting incremented it would trigger a software emulated restart (via a CPU_RESTART define). I ended up still having the program halting issue, so I kept digging and found it was the xbee.send method that was causing the teensy to halt and not the I2C bus. I removed the interrupt timing code and still came to the conclusion that the xbee.send method was causing issues (just to be doubly sure). After more chipping away at it, I figured out that if I increased the Xbee baudrate to 38400 this issue goes away. I don't want to go much above 38400 as I end up with a lot of bad packets at 57600 or 115200 (which also seems strange).

Does anyone have any insight into why xbee.send at low baudrates would cause this problem? I'm happy to provide relevant code chunks if needed.

Initial XBee baudrate was 9600.

New XBee baudrate is 38400.
 
Sorry, I have not had any issues using Xbees in the past. Although I mainly only used Series 1 using simple input and output to Serial ports.

As mentioned at the top of each forum posting. Really can not help much without more information, like a sample program showing the issue, What libraries if any you are using. What is hooked up to what...
 
So my setup is as follows:

Hardware
Teensy 3.2
Xbee S2C
Pin Mapping
Using Serial1 on Teensy to connect to Xbee. (Pin 0 for TX and Pin 1 for RX)
The Xbee also is connected to:
Teensy Reset via DIO4
Teensy Program via DIO0
Teensy Pin 17 via A11 (

Example code:
Code:
#include "Arduino.h"
#include "Xbee.h"

// The period, in msec, of the check thread.  Configured into the IntervalTimer.
const int lockupCheckPeriodMilliseconds = 25;
// Lock-up detection counter.  Stops getting incremented if the main loop hangs
volatile boolean  lockupCheckEnabled = false;
volatile uint32_t lockupCount;
volatile uint32_t previousLockupCount;
volatile uint32_t realtimeCount;

void realTimeHandler();
int main(){
  Serial.begin(115200);
  Serial.printf("Compiled on %s %s\n", __DATE__, __TIME__);

  lockupCount         = 0;
  previousLockupCount = 99999;
  realtimeCount       = 0;
  
  // object to handle receiving xbee messages
  XbeeRxStream             xbeeRxStream   = XbeeRxStream();
  // object to handle sending xbee messages
  XbeeTxStream             xbeeTxStream   = XbeeTxStream();

  IntervalTimer interruptTimer;
  // Hardware timer for our real-time interrupt driven process
  interruptTimer.begin(realTimeHandler, lockupCheckPeriodMilliseconds * 1000);

  // enable check thread
  lockupCheckEnabled = true;
  while (1) {
    digitalWrite(TEENSY_ONBOARD_LED_PIN, HIGH);
    // check if an rx packet is avaiable
    xbeeRxStream.receive();

    if (!xbeeRxStream.isEmpty()) {
      XbeeRxPacket xbeeRxPacket = xbeeRxStream.getRxPacket();
      // packet handling code is here
    }
      // checks to see if I have any packets queued for transmission
      if (!xbeeTxStream.isQueueEmpty()) {
      Serial.println("XbeeTxStream Tranmitting");
      xbeeTxStream.transmit();
    } 
    lockupCount++;
    digitalWrite(TEENSY_ONBOARD_LED_PIN, LOW);
  }
}
// realtime loop that checks for lockup in the main thread
void realTimeHandler(){
  if ((realtimeCount++ % (1000 / 5)) == 0) {
    Serial.printf("realTimeHandler() actual %d previous %d realtime %d\n", lockupCount, previousLockupCount, realtimeCount);
  }
  if (lockupCheckEnabled) {
    // Look to see if the main thread has hung (e.g. on an I2C bus failure)
    if ((realtimeCount++ % (1000 / 5)) == 1) {
      Serial.println("realTimeHandler() lockupCheck");
    }
    if (lockupCount == previousLockupCount) {
      Serial.printf(" restarting actual %d previous %d realtime %d\n", lockupCount, previousLockupCount, realtimeCount);
      // Restart during normal operation
      TeensyConfigCommand teensyHandler = TeensyConfigCommand(globalConfig);
      teensyHandler.handle(TeensyEvent::RESTART);
      teensyHandler.handle();
    }
    previousLockupCount = lockupCount;
  }
}

Then here's the relevant section of my transmit code. XbeeStream holds the Xbee Library object that gets shared with both XbeeRxStream and XbeeTxStream. XbeeRxStream has a similar constructor.

Code:
XbeeTxStream::XbeeTxStream() : XbeeStream(){
  Serial1.begin(XBEE_BAUDRATE);
  xbee.setSerial(Serial1);
}

bool XbeeTxStream::transmit(){
  // TODO (AHP) add repeating functionality
  XbeeTxPacket txPacket;

  if (_txPacketQueue->size() > 0) {
    // Serial.printf("Queue Size %d\n", _txPacketQueue->size());
    txPacket = _txPacketQueue->get(0);
  }
  transmit(&txPacket);
  // after send remove the first object
  _txPacketQueue->shift();
  // clear queue if empty just in case
  if (_txPacketQueue->size() == 0) {
    _txPacketQueue->clear();
  }
  if (_txPacketQueue->size() > 0) {
    // still more packets to transmit
    return false;
  } else {
    // buffer is clear
    return true;
  }
}

bool XbeeTxStream::transmit(XbeeTxPacket* packet){
  Serial.printf("XbeeTxStream    Destination Address: 0x%04x Source Address 0x%04x\n", packet->destinationAddress, config->myXbee.address);
  Serial.print("XbeeTxStream    ");
  for (int i = 0; i < MAX_XBEE_BYTES; i++) {
    Serial.printf("0x%02x ", packet->txPacket[i]);
  }
  Tx16Request txRequest;
  if (packet->destinationAddress == XBEE_BROADCAST_ADDRESS) {
    txRequest = Tx16Request(0xFFFF, packet->txPacket, MAX_XBEE_BYTES);
  } else {
    // txRequest = Tx16Request(packet->destinationAddress, packet->txPacket, MAX_XBEE_BYTES);
    txRequest = Tx16Request(0xFFFF, packet->txPacket, MAX_XBEE_BYTES);
  }

  xbee.send(txRequest);
  Serial.printf("XbeeTxStream    Sending Single Packet to 0x%04x\n", packet->destinationAddress);
  return 0;
}
bool XbeeTxStream::isQueueEmpty(){
  return _txPacketQueue->size() == 0;
}

I
 
Status
Not open for further replies.
Back
Top