Full Duplex Serial Tx/Rx with XBee

I can successfully Tx from a Propeller to a PC with XBees in between. I can also Tx from one Propeller to a second Propeller with XBees in between, but the Rx data is not right. I have been searching and reading everything I can find and I feel like the answer is obvious, but I'm missing something.

Setups are identical for both Propellers: 2 buttons to incr/decr a variable, a serial LCD display, and an XBee.

When both bootup the value of the variable is displayed correctly. The variable on the Rx Propeller incr/decr correctly when it's local buttons are pushed. However, the variable on the Rx side jumps from it's starting value to 48 or 57 and then incr/decr between 48 and 57 when the buttons are pushed on the Tx side. I know communication is occuring, but the data is garbled.

Tx Propeller Code:
CON

_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000

TX = 2 'Tx pin for display
BAUD = 9_600 'Display BAUD

UpButton = 1 'Button changes the frequency up
DownButton = 0 'Button changes the frequency down

XB_Rx = 14 'XBee DOUT Data coming in from XBee
XB_Tx = 13 'XBee DIN Data going out of XBee
XB_Baud = 9600 'Baud for XBee


OBJ

LCD : "FullDuplexSerial.spin"
XB : "FullDuplexSerial.spin"

VAR
long Stack[40], Stack1[40]
byte number

PUB Main

LCD.start(TX, TX, %1000, BAUD) 'Initialize comms for display
waitcnt(10000 + cnt) 'Pause for FullDuplexSerial.spin to initialize
LCD.tx(12) 'Clear Display
waitcnt(10000 + cnt) 'Pause for Clear Display Command
LCD.tx(17) 'Turn On LCD Backlight
LCD.tx(22) 'Turn Display on with No Cursor and No Blink

XB.start(XB_Rx, XB_Tx, 0, XB_Baud) 'Initialize comms for XBee
waitcnt(10000 + cnt) 'Pause for XB to initialize

cognew (Check, @Stack) 'Cog to check button state
cognew (Display, @Stack1) 'Cog for display

number := 10 'Initial value

dira[UpButton] := 0 'Set Buttons as INPUT
dira[DownButton] := 0

outa[UpButton] := 1 'Set Buttons HIGH because buttons pulls LOW
outa[DownButton] := 1


PUB Display

repeat
LCD.tx(12) 'Clear Display
waitcnt(10000 + cnt) 'Pause for Clear Display Command
LCD.str(String("Number: "))
LCD.Dec(number)
waitcnt(clkfreq/10 + cnt)

PUB Check 'Check if a button is pressed

repeat
if ina[UpButton] == 0 'Increase number
waitcnt(clkfreq/20 + cnt)
if ina[UpButton] == 0
number++
XB.Dec(number)
waitcnt(clkfreq + cnt)

if ina[DownButton] == 0 'Decrease number
waitcnt(clkfreq/20 + cnt)
if ina[DownButton] == 0
number--
XB.Dec(number)
waitcnt(clkfreq + cnt)


Rx Propeller Code:
CON

_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000

TX = 2 'Tx pin for display
BAUD = 9_600 'Display BAUD

UpButton = 1 'Button changes the frequency up
DownButton = 0 'Button changes the frequency down

XB_Rx = 14 'XBee DOUT Data coming in from XBee
XB_Tx = 13 'XBee DIN Data going out of XBee
XB_Baud = 9600 'Baud for XBee


OBJ

LCD : "FullDuplexSerial.spin"
XB : "FullDuplexSerial.spin"

VAR
long Stack[40], Stack1[40], Stack2[40]
byte number

PUB Main

LCD.start(TX, TX, %1000, BAUD) 'Initialize comms for display
waitcnt(10000 + cnt) 'Pause for FullDuplexSerial.spin to initialize
LCD.tx(12) 'Clear Display
waitcnt(10000 + cnt) 'Pause for Clear Display Command
LCD.tx(17) 'Turn On LCD Backlight
LCD.tx(22) 'Turn Display on with No Cursor and No Blink

XB.start(XB_Rx, XB_Tx, 0, XB_Baud) 'Initialize comms for XBee
waitcnt(10000 + cnt) 'Pause for XB to initialize

cognew (Check, @Stack) 'Cog to check button state
cognew (Display, @Stack1) 'Cog for display
cognew (XBee, @Stack2) 'Cog for XBee

number := 20 'Initial value

dira[UpButton] := 0 'Set Buttons as INPUT
dira[DownButton] := 0

outa[UpButton] := 1 'Set Buttons HIGH because buttons pulls LOW
outa[DownButton] := 1


PUB Display

repeat
LCD.tx(12) 'Clear Display
waitcnt(10000 + cnt) 'Pause for Clear Display Command
LCD.str(String("Number: "))
LCD.Dec(number)
waitcnt(clkfreq/10 + cnt)

PUB Check 'Check if a button is pressed

repeat
if ina[UpButton] == 0 'Increase number
waitcnt(clkfreq/20 + cnt)
if ina[UpButton] == 0
number++
waitcnt(clkfreq + cnt)

if ina[DownButton] == 0 'Decrease number
waitcnt(clkfreq/20 + cnt)
if ina[DownButton] == 0
number--
waitcnt(clkfreq + cnt)

PUB XBee

repeat
number := XB.Rx ' Rx data from XBee

Comments

  • Bot,
    Your coding seems quite minimal on the Xbee side and you have not mentioned how the Xbees are configured, so it is difficult to troubleshoot.
    I used the comprehensive coding, data flow and configuration from examples in Martin Hebel's "Getting started with Xbee" tutorial, then pared my coding back when I was confident on the Xbee interface.
  • XBees are as-is right out of the box. I just need to move a byte or two of data when I push a button. Surely, those with experience could show me in minutes??
  • XBees -- right out of the box -- are not linked. You need to configure them (as was pointed out in the post above).
    Jon McPhalen
    Hollywood, CA
    It's Jon or JonnyMac -- please do not call me Jonny.
  • Failure is not an option...it's bundled with the software.
  • Hex 48 - 57 are the ascii characters for zero to 9, so it is likely the ascii character is being substituted for the hex values 0 - 9 somwhere in your code.
    In science there is no authority. There is only experiment.
    Life is unpredictable. Eat dessert first.
  • I went with XBee_Object instead of FullDuplexSerial. Used XB.Dec(number) followed by XB.CR on the Tx side and XB.RxDec on the Rx side. Works great now. I ignored the CR command previously because it was never required when talking to a PC terminal. I incorrectly figured it was for larger data sets.

    This all works for byte sized chunks. How do I move numbers larger than a byte?

  • JonnyMac wrote: »
    XBees -- right out of the box -- are not linked. You need to configure them (as was pointed out in the post above).

    Not quite, the default from Digi is that both the destination address (DH:DL) and the receive address (MY) are set to zero, so they can communicate in transparent mode right out of the box. Good until you want more capabilities and a fancier network. Assuming this is a 802.15.4 XBee.
  • @Botulism
    When you include code, it helps if you enclose it in code brackets (The letter "C" on the formatting bar). Then it will retain the Spin indentations. Is the following the way it is, so it increments and decrements at 1 second intervals as long as you hold down the button?
    repeat
       if ina[UpButton] == 0 'Increase number
          waitcnt(clkfreq/20 + cnt)
       if ina[UpButton] == 0
          number++
          XB.Dec(number)
          waitcnt(clkfreq + cnt)
    
       if ina[DownButton] == 0 'Decrease number
          waitcnt(clkfreq/20 + cnt)
       if ina[DownButton] == 0
          number--
          XB.Dec(number)
          waitcnt(clkfreq + cnt)
    

    That should be good for big numbers as well as bytes.

  • Thanks! I knew the formatting would be something simple I overlooked.
    Yes, it incr/decr every second.
    Apparently, I have never displayed a number larger than 3 digits in length to the Parallax display - https://www.parallax.com/product/27977. The moment I get to 4 digits the display just shows 255. There a command I'm missing? Looking at FullDuplexSerial and it doesn't appear to be limited by this. Is it the display? The examples I can find never go above 3 digits.
  • Helps if my Byte becomes a Word!
Sign In or Register to comment.