SparkFun Forums 

Where electronics enthusiasts find answers.

All things pertaining to wireless and RF links
By ICAC210
#68627
I am sending data from PIC18F to my XBee using USART at 9600 Baud rate (2% error), my host radio is connected to PC and i am monitoring in XCTU terminal. The problem is the receiving data is off for some reason. When I send 0x00, in the terminal I see F0 F8 F8 F0... in random order. Is "F" just a header since it is always there? Also, I am getting 8s instead of 0s, is it because the error in my baud rate? Ex. 0000 becomes 1000? Should I try to change to a different baud rate to reduce the error? Any idea is appreciated. I am sending data continuasouly.
By ICAC210
#68633
I found out that the reason i get "F" at front each time is because of the idle (bit high for USART). For some reason, the radio is capturing the idle bits and giving me false data? How do you synchronize the two?
By stevech
#68644
ICAC210 wrote:I found out that the reason i get "F" at front each time is because of the idle (bit high for USART). For some reason, the radio is capturing the idle bits and giving me false data? How do you synchronize the two?
If your baud rate is in error by up to 2%, try to reduce that. Better crystal or lower baud rate.

Framing errors happen if the transmitting UART sends a constant stream with no time gaps between characters. So now and then, or ever character, assure there's a 2 character (2 x (8 + 2 bits) ) period of time that there's no data flowing.

On the XBee side, if you are streaming a lot of data, you must use flow control: either XON/XOFF or RTS/CTS so that the sending UART stops if the XBee's buffer fills. That's quite a few bytes. The XBee uses 802.15.4 and that limits to 108 or so bytes per wireless data frame, after which there's a delay waiting for an ACK. X number of 108 byte frames are buffered in RAM in the XBee, hence the need for flow control.

The receiving XBee can overrun the receiving UART if, say, it's a pokey PIC that doesn't keep up. Maybe the PIC sends each byte to an LCD and that's slow, or some such. Or the receiving PIC doesn't do interrupt driven buffered UART receive as it must. Flow control issue here too, on the receive side.
By ICAC210
#68670
stevech wrote:
ICAC210 wrote:I found out that the reason i get "F" at front each time is because of the idle (bit high for USART). For some reason, the radio is capturing the idle bits and giving me false data? How do you synchronize the two?
If your baud rate is in error by up to 2%, try to reduce that. Better crystal or lower baud rate.

Framing errors happen if the transmitting UART sends a constant stream with no time gaps between characters. So now and then, or ever character, assure there's a 2 character (2 x (8 + 2 bits) ) period of time that there's no data flowing.

On the XBee side, if you are streaming a lot of data, you must use flow control: either XON/XOFF or RTS/CTS so that the sending UART stops if the XBee's buffer fills. That's quite a few bytes. The XBee uses 802.15.4 and that limits to 108 or so bytes per wireless data frame, after which there's a delay waiting for an ACK. X number of 108 byte frames are buffered in RAM in the XBee, hence the need for flow control.

The receiving XBee can overrun the receiving UART if, say, it's a pokey PIC that doesn't keep up. Maybe the PIC sends each byte to an LCD and that's slow, or some such. Or the receiving PIC doesn't do interrupt driven buffered UART receive as it must. Flow control issue here too, on the receive side.
Thanks for the reply. What is the best way to delay the transmitting for 16 bits in the code? I actually tried sending just one time but still, the receiving data is incorrect.
By ICAC210
#68682
Here is my sending code
SPBRG = 0b00011111; //decimal 31 to set baud rate to 9600, clock=20MHz
RCSTAbits.SPEN = 1;
TXSTAbits.SYNC = 0;
TXSTAbits.TXEN = 1;
BAUDCONBITS.TXCKP = 0;

data[2] = 0xCC;
while (1)
UARTWrite(&data[2]);


void UARTWrite(unsigned char* xbee)
{
TXREG = *xbee;
}
By stevech
#68694
ICAC210 wrote:Here is my sending code
SPBRG = 0b00011111; //decimal 31 to set baud rate to 9600, clock=20MHz
RCSTAbits.SPEN = 1;
TXSTAbits.SYNC = 0;
TXSTAbits.TXEN = 1;
BAUDCONBITS.TXCKP = 0;

data[2] = 0xCC;
while (1)
UARTWrite(&data[2]);


void UARTWrite(unsigned char* xbee)
{
TXREG = *xbee;
}
where's the code that loops until the UART TX buffer is ready for another byte? Or waits for a TX buffer empty interrupt?
By ICAC210
#68701
stevech wrote:
ICAC210 wrote:Here is my sending code
SPBRG = 0b00011111; //decimal 31 to set baud rate to 9600, clock=20MHz
RCSTAbits.SPEN = 1;
TXSTAbits.SYNC = 0;
TXSTAbits.TXEN = 1;
BAUDCONBITS.TXCKP = 0;

data[2] = 0xCC;
while (1)
UARTWrite(&data[2]);


void UARTWrite(unsigned char* xbee)
{
TXREG = *xbee;
}
where's the code that loops until the UART TX buffer is ready for another byte? Or waits for a TX buffer empty interrupt?

I used another while loop with UARTWrite inside and I am reading values from accelerometer within the loop. This causes some delay in the UART transmission (u can see the idle 1 bit a lot longer in oscilliscope), but how do I make sure that the TX buffer is emptied before I send out another byte? Do i need to use CTS?
Another thing, I hook up the another side of XBee (not USB explorer), to observe the scope at RX. The problem is my TX (sending) and RX (receiving) do not match on the oscilliscope. RX seems to be the same even when I change the sending data. I think this is why I am seeing wrong data at the XCTU terminal. Whatever going into the sending Xbee should be the same coming out of receiving Xbee, correct?
By ICAC210
#68719
Hi,

This is very strange. I change the code so that it only transmit once to XCTU, but it's still reading the wrong data!! I tried to send 1F and I see F3 at the terminal? This means its not the flow control that was causing the problem. I checked the UART pin on the oscilliscope and it is correctly showing 1F into the TX of Xbee, but for some reason, it is not receiving right. Any ideas?
My baud rate has to be correct if the two devices are communicating, right?

TXREG = 0x11;
while (1);

I don't need to send any header for the data I am sending, right?
By stevech
#68720
ICAC210 wrote:
stevech wrote:
ICAC210 wrote:Here is my sending code
SPBRG = 0b00011111; //decimal 31 to set baud rate to 9600, clock=20MHz
RCSTAbits.SPEN = 1;
TXSTAbits.SYNC = 0;
TXSTAbits.TXEN = 1;
BAUDCONBITS.TXCKP = 0;

data[2] = 0xCC;
while (1)
UARTWrite(&data[2]);


void UARTWrite(unsigned char* xbee)
{
TXREG = *xbee;
}
where's the code that loops until the UART TX buffer is ready for another byte? Or waits for a TX buffer empty interrupt?

I used another while loop with UARTWrite inside and I am reading values from accelerometer within the loop. This causes some delay in the UART transmission (u can see the idle 1 bit a lot longer in oscilliscope), but how do I make sure that the TX buffer is emptied before I send out another byte? Do i need to use CTS?
Another thing, I hook up the another side of XBee (not USB explorer), to observe the scope at RX. The problem is my TX (sending) and RX (receiving) do not match on the oscilliscope. RX seems to be the same even when I change the sending data. I think this is why I am seeing wrong data at the XCTU terminal. Whatever going into the sending Xbee should be the same coming out of receiving Xbee, correct?
You must have code to check if the transmit UART buffer has room to accept the next character. You cannot just jam byte in without first checking, or using interrupts to indicate "more data please". Read the microprocessor application notes, look at others' examples.

Analogy: You are stuffing apples in the basket while wearing a blindfold - by not checking the right UART status bit.
By ICAC210
#68725
stevech wrote:
ICAC210 wrote:
stevech wrote: where's the code that loops until the UART TX buffer is ready for another byte? Or waits for a TX buffer empty interrupt?

I used another while loop with UARTWrite inside and I am reading values from accelerometer within the loop. This causes some delay in the UART transmission (u can see the idle 1 bit a lot longer in oscilliscope), but how do I make sure that the TX buffer is emptied before I send out another byte? Do i need to use CTS?
Another thing, I hook up the another side of XBee (not USB explorer), to observe the scope at RX. The problem is my TX (sending) and RX (receiving) do not match on the oscilliscope. RX seems to be the same even when I change the sending data. I think this is why I am seeing wrong data at the XCTU terminal. Whatever going into the sending Xbee should be the same coming out of receiving Xbee, correct?
You must have code to check if the transmit UART buffer has room to accept the next character. You cannot just jam byte in without first checking, or using interrupts to indicate "more data please". Read the microprocessor application notes, look at others' examples.

Analogy: You are stuffing apples in the basket while wearing a blindfold - by not checking the right UART status bit.
Hi, I understand what you are saying. But why is it that when I send only 1 byte of data, the receiving is still incorrect? I just tried to send data from the XCTU to Xbee/PIC, the RX looks good on the oscilliscope, but when I read from RCREG register, it is not reading what it suppose to be. I am writing the RCREG to eeprom memory to see it. Is there any specific way to read RCREG? I don't understand how is it that the data entering the PIC is not the same as the one i store in data memory. Could it be my baud rate?

data[0] = RCREG;
ee_write_byte(0, data[0])

"0" is the eeprom address
By ICAC210
#68734
stevech wrote:
ICAC210 wrote:
stevech wrote: where's the code that loops until the UART TX buffer is ready for another byte? Or waits for a TX buffer empty interrupt?

I used another while loop with UARTWrite inside and I am reading values from accelerometer within the loop. This causes some delay in the UART transmission (u can see the idle 1 bit a lot longer in oscilliscope), but how do I make sure that the TX buffer is emptied before I send out another byte? Do i need to use CTS?
Another thing, I hook up the another side of XBee (not USB explorer), to observe the scope at RX. The problem is my TX (sending) and RX (receiving) do not match on the oscilliscope. RX seems to be the same even when I change the sending data. I think this is why I am seeing wrong data at the XCTU terminal. Whatever going into the sending Xbee should be the same coming out of receiving Xbee, correct?
You must have code to check if the transmit UART buffer has room to accept the next character. You cannot just jam byte in without first checking, or using interrupts to indicate "more data please". Read the microprocessor application notes, look at others' examples.

Analogy: You are stuffing apples in the basket while wearing a blindfold - by not checking the right UART status bit.
Would this work? I configured to enable CTS flow control for Xbee, and in my pic code,

while (1)
{
if (CTS ==0)
TXREG = 0x55;
}
By ICAC210
#68772
I figured out the problem, finally. My baud rate was at 19200 going into XBee, not 9600.

I have a question, if i have 3 xbee sending data to my host xbee, do i have to operate in API mode? Would transparent mode work? If so, how does the host xbee distinguish which data is from which xbee?
By stevech
#68824
ICAC210 wrote:I figured out the problem, finally. My baud rate was at 19200 going into XBee, not 9600.

I have a question, if i have 3 xbee sending data to my host xbee, do i have to operate in API mode? Would transparent mode work? If so, how does the host xbee distinguish which data is from which xbee?
OK on the wrong baud rate. But you still need code to loop until the UART has room for a byte. You can skip doing that ONLY if your program sends bytes no more often than the time to send one byte, at the chosen baud rate. At 9600baud, that's about 1mSec per byte.

On the question above... no, the 3 XBees can set DL = the address of the "host" Xbee as you say. The 802.15.4 mode has destination addresses you can set at run time using AT commands in your program, if you do the +++ escape with same kind of timing you do with the keyboard.

Also, as I recall, the coordinator in a non-ZigBee network is address 0, so if any XBee addresses its data to 0, it'll go to that node. Also, an all ones destination address is a broadcast - all nodes get the packet, and based on the contents, can ignore or process. Note though, that broadcast packets have no error correction in the MAC layer - you must detect garbled and lost messages in your application with broadcast addresses. Or ignore errors and rely on repeated redundant transmissions or some such.
By ICAC210
#68867
stevech wrote:
ICAC210 wrote:I figured out the problem, finally. My baud rate was at 19200 going into XBee, not 9600.

I have a question, if i have 3 xbee sending data to my host xbee, do i have to operate in API mode? Would transparent mode work? If so, how does the host xbee distinguish which data is from which xbee?
OK on the wrong baud rate. But you still need code to loop until the UART has room for a byte. You can skip doing that ONLY if your program sends bytes no more often than the time to send one byte, at the chosen baud rate. At 9600baud, that's about 1mSec per byte.

On the question above... no, the 3 XBees can set DL = the address of the "host" Xbee as you say. The 802.15.4 mode has destination addresses you can set at run time using AT commands in your program, if you do the +++ escape with same kind of timing you do with the keyboard.

Also, as I recall, the coordinator in a non-ZigBee network is address 0, so if any XBee addresses its data to 0, it'll go to that node. Also, an all ones destination address is a broadcast - all nodes get the packet, and based on the contents, can ignore or process. Note though, that broadcast packets have no error correction in the MAC layer - you must detect garbled and lost messages in your application with broadcast addresses. Or ignore errors and rely on repeated redundant transmissions or some such.
Thanks for the reply.
I am working on the CTS/RTS right now since I am sending continuous streaming data.
This is the psuedo i have gathered so far, can you see if i am on the right track?
1) Check TRMT... If full, do nothing. If empty, goto 2
2) Check CTS... If busy, do nothing. If clear, load TXREG and goto 3
3) TRMT will now show "full." Wait (do nothing) until it shows "empty."
4) Set a timer for some reasonable period for the XBEE to respond, say 10mS
5) Check CTS... if busy, the byte is done, you can now repeat the main loop. If clear, the XBEE hasn't processed the new byte yet...
6) ...so check the timer... If expired, the XBEE didn't receive the byte. Either reset the serial port or go back to 1 and try resending the byte

Do i need to check TXIF (TXREG)? also, what is the best way to set a timer for delay? Would Nop(); works? Thanks.
By stevech
#68902
I'm of the ARM and AVR religions - I left PICs behind long ago.

But example code for using the UART should be in many examples from MIcrochip and user forums.

Of course, you must actually connect RTS/CTS between the PIC and the radio, and of the correct polarity.