Society of Robots - Robot Forum

Electronics => Electronics => Topic started by: Admin on October 30, 2007, 12:48:49 PM

Title: UART error rate?
Post by: Admin on October 30, 2007, 12:48:49 PM
I am running an ATmega644 at 1Mhz and doing wireless serial communication with the Easy Radio.

Currently I am running it at 19200 baud, but would like to increase it to the max the Easy Radio can handle, 38400. I think I'm having buffer overflow problems because data gets jumbled if I rprintf() too often.

So looking at the 644 datasheet, it says I will get an error rate of -18.6% for 38400 at 1Mhz. I understand that this error results from rounding I think . . . but how does that affect me? Will data be lost often?


And as a side note, apparently Easy Radio released some software to make the baud configuration easier:
http://www.robotshop.ca/software/easy-radio-software-v2_03.zip
(if anyone was interested)
Title: Re: UART error rate?
Post by: bens on October 30, 2007, 01:27:10 PM
Section 17.8.3 (page 179) of the mega644 datasheet gives a fairly detailed explanation of baud rate errors and their effects.  The maximum recommended rate error when sending eight-bit (+parity) characters is +/-2%.  An 18% baud rate error is just way too high; the receiver and transmitter will not be able to stay synchronized.

error = (closest match baud rate / baud rate) - 1

UBRR = (f_osc / 16 / baud rate) - 1 = (1 MHz / 16 / 38,400) - 1 = .62 (approximately 1)
closest match baud rate = f_osc / 16 / (UBRR + 1) = 1 MHz / 16 / (1 + 1) = 31,250 bps

You are sending/receiving data at 31,250 bps while the other side is receiving/sending data at 38,400 bps.  This rate discrepency is just too much for the mega644's UART hardware.

Running at 19,200 baud will give you an error of 8.5%, which is still significantly higher than the recommended max error and will probably result in scattered frame errors.
Title: Re: UART error rate?
Post by: bens on October 30, 2007, 01:41:03 PM
I should also note that if you set the U2X (double speed) bit of the UCSR0A register, you can achieve a baud rate that's within 8.5% of 38,400 bps.  The only drawback is that the UART hardware is even more senstive to baud rate errors when running in double-speed mode (max recommended error for 8-bit chars in 2x-speed mode is +/-1.5%).
Title: Re: UART error rate?
Post by: Admin on October 30, 2007, 01:48:57 PM
hmmmm all it did at 38400 is just spit out random characters . . . unless I did something wrong, it just wasn't working . . .

But it works perfectly fine at 19200, minus that buffer issue . . . if I do too many rprintf's within a certain period of time is just prints out:
2525252525252525252525252525

when it should be:
255 255 255 255 73 73 88 10
(those numbers change a lot)

I need a higher data rate . . . looks like Ill need that darn crystal w/caps installed after all . . .
Title: Re: UART error rate?
Post by: bens on October 30, 2007, 02:20:21 PM
Right, at 38,400 bps your error is so large that bits start getting out of sync in the middle of a single byte (at least I expect that's what you'd find if you worked out the math).  The result is that a single transmitted byte would be interpreted incorrectly by the receiver.  At 19,200 bps, your error is such that transmissions will start getting out of sync after a few bytes (once again, you'd have to work out the math to see precisely when this would happen).  If you send one byte, pause, send another byte, pause, etc, you should be ok.  The problem will arise if you stream a large number of bytes without periodically pausing to allow the receiver and transmitter to resync.  Looking through the datasheet, you probably need to run at 9600 bps in double-speed asynchronous UART mode (error of .2%) if you want to be able to stream bytes as fast as possible over serial without eventually losing synchronization.  If you want sound serial communication at a higher baud, you probably need to have your AVR running faster than 1 MHz.

Out of curiosity, have you tried 38,400 bps with the UART set for double speed?  You might be able to packets a few bytes in length using that configuration without losing synchronization.
Title: Re: UART error rate?
Post by: Admin on October 30, 2007, 02:46:21 PM
Quote
If you send one byte, pause, send another byte, pause, etc, you should be ok.  The problem will arise if you stream a large number of bytes without periodically pausing to allow the receiver and transmitter to resync.
I am basically making a highspeed wireless datalogger . . . unfortunately the transmission is going too slow for what I need.

Quote
If you want sound serial communication at a higher baud, you probably need to have your AVR running faster than 1 MHz.
Yea thats why I mentioned getting a crystal . . .

Quote
Out of curiosity, have you tried 38,400 bps with the UART set for double speed?  You might be able to packets a few bytes in length using that configuration without losing synchronization.
I was thinking of this, but the Easy Radio datasheet (http://www.active-robots.com/products/radio-solutions/radio/er-datasheet-2.3-sept-05.pdf) mentions nothing on 'asynchronous,' just a list of a few possible baud rates.

I was playing around with what I was sending . . . I wanted to send information from 8 sensors simultaneously but that isn't working . . . but if I bring it down to 3 simultaneously it works fine. Ill then do the other sensors later . . . but the data is disconnected doing it this way . . .

I think Ill just get a crystal (doh!)
Title: Re: UART error rate?
Post by: dunk on October 30, 2007, 03:23:00 PM
so i haven't used my EasyRadio modules for a while but you have to set the baud rate on the EasyRadio module as well.

the EasyRadio modules have a microcontroller in them that takes incoming data, stores it in a buffer and transmits it asynchronously over a single radio channel. the microcontrollers in each module do all the complicated time slice negotiation involved.
that's how they handle 2 way traffic on one radio frequency.
with the firmware on my modules i think they defaulted to 19200 but that was user definable.

or as the datasheet puts it:
Quote
The Serial Data Input and Serial Data Output operate at the standard 19,200 Baud and the two handshake
lines provide optional flow control to and from the host. The Easy-Radio Transceiver can accept and transmit
up to 180 bytes of data, which it buffers internally before transmitting in an efficient over-air code format.

Any other Easy-Radio Transceiver within range that ?hears? the transmission will decode the message and
place the recovered data within a receive buffer that can then be unloaded to the receiving host for
processing and interpretation. Transmission and reception are bi-directional half duplex i.e. transmit OR
receive but not simultaneously.

what i can't remember (and am too tired to read the datasheet to find out) is whether the radios on the modules are limited to 19200 halfduplex even when the input speed of the module is set higher....
if that was the case you would have reached the limits of the EasyRadio modules.

do you need 2 way comms for this?
if not, simple RF modules might suit you better.

dunk.
Title: Re: UART error rate?
Post by: bens on October 30, 2007, 03:45:30 PM
Quote
Quote
If you want sound serial communication at a higher baud, you probably need to have your AVR running faster than 1 MHz.
Yea thats why I mentioned getting a crystal . . .
Can't you first just try to unprogram the CKDIV8 fuse and run your mega644 off its internal RC oscillator at 8 MHz?

Quote
I was thinking of this, but the Easy Radio datasheet (http://www.active-robots.com/products/radio-solutions/radio/er-datasheet-2.3-sept-05.pdf) mentions nothing on 'asynchronous,' just a list of a few possible baud rates.
"Asynchronous" just means you're not supplying a clock along with your serial transmission.  SPI is synchronous because the receiving device shares a clock line with the transmitting device, and this clock line maintains synchronization between the two.  Serial is typically used asynchronously (you configure the receiver to operate at a speed as close as possible to the transmitter, but there is no shared clock).  Your communication with the EasyRadio is asynchronous, so there'd be no harm in trying to set the U2X bit for double-speed operation.
Title: Re: UART error rate?
Post by: JonHylands on October 30, 2007, 07:35:44 PM
Can't you first just try to unprogram the CKDIV8 fuse and run your mega644 off its internal RC oscillator at 8 MHz?

That's how I run most of my ATmegaXXX chips - at 8 MHz, using the internal oscillator. You can easily do 38400 with it like that.

- Jon
Title: Re: UART error rate?
Post by: Admin on October 31, 2007, 07:16:04 AM
dunk, it says the max speed is 38400, but it can be reprogrammed to do any baud rate under that . . . I've managed to reprogram it before so its doable . . . hmmmm that gives me an idea - bens said my AVR is going at 31,250 bps so perhaps I can try to set the Easy Radio at that rate!!!

I have to demo it in like an hour so Ill wait until after lunch to try it (better not to break it until after the demo ;D).

I need 2 way comms because I want to do wireless boatloading of my AVR.

Quote
Can't you first just try to unprogram the CKDIV8 fuse and run your mega644 off its internal RC oscillator at 8 MHz?
Hmmmm I just looked into the fuses . . . apparently Im using 'Ext. Crystal Osc.; Frequency 8.0 [CKSEL=1111 SUT=11]' . . . and the 'Divide clock by 8 internally; [CKDIV8=0]' box is not checked . . . so does that mean I'm actually already operating at 8Mhz?
(sorry for the noob question)

Hmmm if thats so, then that means the error is actually only .2% . . . and doesn't explain those random characters . . .
Title: Re: UART error rate?
Post by: JonHylands on October 31, 2007, 08:35:28 AM
Unless you have an external crystal or resonator, you need to set it to "Int RC Osc 8 MHz" - I generally use the 65 ms startup version of that.

- Jon
Title: Re: UART error rate?
Post by: bens on October 31, 2007, 11:05:53 AM
Quote
Hmmmm I just looked into the fuses . . . apparently Im using 'Ext. Crystal Osc.; Frequency 8.0 [CKSEL=1111 SUT=11]' . . . and the 'Divide clock by 8 internally; [CKDIV8=0]' box is not checked . . . so does that mean I'm actually already operating at 8Mhz?
(sorry for the noob question)
Well that's weird...  If you have selected "Ext. Crystal Osc" and you're not actually using an external crystal oscillator, your AVR should not actually be functioning right now.  (I've temporarily killed several AVRs by accidentally setting their fuses for the wrong clock, so I have some experience with this.)  AVRs by default have their fuses set for internal RC oscillator divided by 8, so if you or someone else hasn't previously messed with the fuses, that's what your AVR should be set for.  My suspicion is that your reading was not really your AVR's fuse settings because you're getting what I get when I use AVR Studio to try to read the fuses of a non-existent mega644 (i.e. your low fuse byte, and probably your two other fuse bytes, is reading as 0xFF, which is completely unprogrammed).
Title: Re: UART error rate?
Post by: Admin on October 31, 2007, 11:27:48 AM
Hmmm appears I just found a small bug in AVR Studio . . . apparently the fuses don't show properly unless you scroll down with the AVR turned on the entire time . . . explains some of my confusion . . .

Anyway, the actual fuse checked is:
Int. RC Osc at 65ms

Nothing else is checked . . . so what frequency am I running at??? None of the Int RC fuses say 8Mhz.

And what does that 65ms mean?

(should I be reading the datasheet for this?)

Ive messed up a board from playing with fuses too . . . so Im not taking chances again . . . :P
Title: Re: UART error rate?
Post by: bens on October 31, 2007, 11:49:26 AM
So you're saying the "divide clock by 8 internally [CKDIV8=0]" box is unchecked?  If so, I'd say it sounds like you are running at 8 MHz, but that just raises more questions.  Specifically, how was your UART able to work at all if you were setting your baud by selecting UBRR values for a 1 MHz system clock?  If you're running at 1 MHz, you get ~38.4 kbps using UBRR = 1.  If you're running at 8 MHz with UBRR = 1, your baud is 250 kbps.  What I'm saying is, if you were able to successfully communicate using your UART at 19.2 kbps, whatever assumption you made about your clock speed could not have been off by a factor of 8 (unless you somehow made a mistake in your calculations that exactly canceled the mistake in your assumption, but that seems unlikely).  What value for UBRR were you using to achieve 19.2 kbps baud?

If you want to understand more about the clock settings, I suggest looking at the datasheet.  In a nutshell, the 65ms is an "additional delay from reset."  As the datasheet puts it, "the main purpose of the delay is to keep the AVR reset until it is supplied with minimum Vcc."  It also requires the oscillator to oscillate for a minimum number or cycles before the clock is considered stable.
Title: Re: UART error rate?
Post by: Admin on October 31, 2007, 12:17:26 PM
Let me better clarify what is going on in my setup . . .

Hyperterminal (set at 19200) is talking with my USB to Serial adaptor (configured for 19200 in the drivers) which is talking with my Easy Radio (defaults at 19200) which then wirelessly talks with my MCU (set to 19200).

My mcu is running avrlib, with uart.h, and this is what I have in the initial code setup:

Code: [Select]
uartInit();  // initialize the UART (serial port)
uartSetBaudRate(19200);

This works . . . if I change it to 38400 (just in my code) I only receive random characters.

Quote
So you're saying the "divide clock by 8 internally [CKDIV8=0]" box is unchecked?
correct . . . I think I just thought it was running at 1Mhz when it was actually 8Mhz . . . Im not a very good programmer as you can see :P


So ummm now that we know Im running at 8Mhz . . . gotta figure out why 38400 wasnt working . . . Ill toy around with it for awhile unless you guys got ideas?
Title: Re: UART error rate?
Post by: Admin on October 31, 2007, 12:46:15 PM
Im a moron!!!!!!!

Ok I just realized why it wasn't working . . . I was changing the baud for only one of my two transceivers!!!

<image of a hammer hitting me on the head>

Ok Im going to look into how to send serial commands to change the baud of the other remote unit, and Ill post again if I get confused or have a victory . . .
Title: Re: UART error rate?
Post by: bens on October 31, 2007, 12:53:55 PM
I was going to suggest you try bypassing the Easy Radio by connecting your USB to serial adapter directly to your AVR to see if the problems still persist, but it looks like you've probably figured things out.  Just out of curiosity, how does avrlib know the speed of your AVR's system clock?  Do you have a #define F_CPU somewhere above your #includes?
Title: Re: UART error rate?
Post by: Admin on October 31, 2007, 12:58:46 PM
yea in global.h I have this:
#define F_CPU        8000000

I did that like 4+ months ago and didn't really understand what I was doing . . . had entirely forgotten about it until you just reminded me . . .

<more hammers hitting my head>
Title: Re: UART error rate?
Post by: Admin on November 01, 2007, 01:01:18 PM
New problem . . .

I think I've managed to change the Easy Radio baud that is connected to my mcu by running this code:
Code: [Select]
//change Easy Radio baud to 38400
delay_cycles(65500);
rprintf("ER_CMD#U5");//ER_CMD#U4 for 19200, ER_CMD#U5 for 38400 maximum
delay_cycles(6550);
rprintf("ACK");
delay_cycles(6550);

(basically sending ER_CMD#U5 to the ER module followed by the ACK command ~20ms later changes baud)

Doing so results in me getting random characters, so I think it works. So then I go to change the baud on the other Easy Radio attached to my USB to serial adapter to sync them . . . But when I try to run the Easy Radio program I got to work earlier now only this error comes up:

Quote
Application Error
Exception EAccessVioloation in module ER V2_03.exe at 00000000. Access violation at address 00000000. Read of address 00000000.

Any idea what that means? Apparently its not that odd of an error (http://www.google.com/search?q=%22Exception+EAccessViolation%22&ie=utf-8&oe=utf-8&rls=org.mozilla:en-US:official&client=firefox-a).

The error occurs no matter the baud rate of the ER attached to my mcu . . .

So then I try to bypass that program and just send data.

But when I type or paste ER_CMD#U5 into hyperterminal, it doesn't change the baud of the ER attached to my USB/serial adapter . . . other ideas on how to do this?
Title: Re: UART error rate?
Post by: krich on November 01, 2007, 05:31:36 PM
No idea on the ER, but I've seen that Application Error a million times.  That is what's commonly called a Null Pointer Exception.  This happens when you try to reference a pointer that has not been assigned yet (i.e. its still set to null, which is 0x0) and the OS is saying, hold on a sec you are not allowed to reference memory at 0x0 and throws an Access Violation error.

In production software, that's called a bug.  It shouldn't happen, but it does occasionally.  Good error handling will prevent this kind of thing.  There is obviously something about your setup that the software designers didn't take into account and is messing with its mind.  Since it worked before, you might try rebooting, or backing out the changes you've made recently to the software/ER, or try uninstalling/installing the application/drivers (look for an update).
Title: Re: UART error rate?
Post by: Admin on November 02, 2007, 11:12:44 AM
Quote
Since it worked before, you might try rebooting, or backing out the changes you've made recently to the software/ER, or try uninstalling/installing the application/drivers (look for an update).
none of that worked . . . so I tried retracing my steps to how I got it to work the first time . . . and figured out this complex bug workaround that doesnt really make sense but works . . .

Ill post it for whoever needs it in the future . . . its really strange but its the only way I've gotten it to work . . .

(Im running the Easy Radio on com3 in hardware)

1) Tell hyperterminal to connect to COM3
2) Run the ER software
3) An error will come up saying com3 is in use, click OK
4) disconnect your hyperterminal connection
5) the RS232 Settings window will come up, set it to COM1, 19200 baud, data bits 8, stop bits 1, flow control NONE. note that I just said com1 - it makes no sense but if you use com3 it doesnt work!
6) push ok, the program should now have correctly loaded
7) now we swap it to com3 by going to file -> Change rs232 settings -> com3
8 ) to verify you did it right, in UART BAUD RATE dropdown select ER_CMD#U? (GetBAUD)
9) push Update, and you should see:
SENT:      ER_CMD#U?
RECEIVED:   ER_CMD#U4
(if you dont see RECEIVED that means you did something wrong)
10) select your desired baud rate and click update - you are done!

I don't understand why it doesnt work if you don't do step 1 first, but somehow having your com port busy fixes it . . . ???

Ok back to getting the entire setup to 38400 . . . Ill post again if it finally works . . .
Title: Re: UART error rate?
Post by: Admin on November 02, 2007, 12:18:43 PM
It works! :D

A correction to the initialization code for my AVR:
Code: [Select]
/****************INITIALIZATIONS*******************/
//other stuff Im experimenting with for SoR
uartInit();  // initialize the UART (serial port)
uartSetBaudRate(19200);// set the baud rate of the UART for our debug/reporting output
rprintfInit(uartSendByte);// initialize rprintf system

rprintf("\r\nSystem Warming Up");

//change Easy Radio baud to 38400
delay_cycles(65500);
rprintf("ER_CMD#U5");//ER_CMD#U4 for 19200, ER_CMD#U5 for 38400 maximum
delay_cycles(6550);
rprintf("ACK");
delay_cycles(65500);
uartSetBaudRate(38400);
delay_cycles(5000);

An interesting side note . . . I changed the transceiver on the computer side to 38400, the USB/serial adapter to 38400, and hyperterminal to 38400, but left both the transceiver and uart on the mcu side at 19200 and it still worked!!! not sure why . . . ???

Anyway, the above code makes everything 38400 baud (including mcu and the mcu-side Easy Radio).

As soon as I really truly understand this UART stuff Ill write a tutorial on it for the $50 robot.
Title: Re: UART error rate?
Post by: Admin on November 02, 2007, 01:20:06 PM
problem - did more testing . . .

hmmmm so apparently even though I now have it running at 38400 baud, it still exhibits the same problem at 19200! :'(

I changed baud because my theory was that the uart couldn't keep up . . . let me give examples . . .

this is what I want to do:
Code: [Select]
update sensors();//adds values to t1, t2, r1, etc.
rprintf("%d %d %d %d %d %d %d %d \r\n",t1,t2,r1,r2,r4,r5,bk,TCNT0);
(it runs this line about 30 times/sec)
and this is the output:
2525252525252525252525252525

but if i dont update sensors (meaning they all default to zero except the timer), I get this output:
0 0 0 0 0 0 0 0 0 0 0 20
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 255
0 0 0 0 0 0 0 0 4
0 0 0 0 0 0 0 4
0 0 0 0 0 0 0 8
0 0 0 0 0 0 0 8
0 0 0 0 0 0 0 9
0 0 0 0 0 0 0 3

Thats a bit strange of an output, no?!


So then I try this code using fewer outputs:
Code: [Select]
update sensors();//adds values to t1, t2, r1, etc.
rprintf("%d %d %d %d \r\n",t1,t2,r1,TCNT0);
And get this correct output:
255 255 255 11
255 255 255 5
255 255 255 5
255 255 255 5
255 255 255 255
244 255 255 0
255 255 255 0
255 255 255 251


Anyone with ideas?
Title: Re: UART error rate?
Post by: bens on November 02, 2007, 06:32:43 PM
How does rprintf work?  I assume it buffers the data and passes it on to the UART as the UART buffers have room?  If so, how big is your rprintf buffer?  If things work for short packets of data but not for long packets, it makes me suspicious that you have a buffer problem (either your buffer is too small to hold the data for a single long rprintf call, or, more likely, you're trying to print data faster than your UART can transmit it).  Are you sure you're not actually trying to print faster than 30 times per second?  At the very least you can figure out what your packet-length limit is by just transmitting hardcoded values, increasing the number of transmitted bytes until things start failing.

Also, it could help if you try transmitting something like "abcdefghi...".  That way, the result of the transition might give you more insight into the nature of the failure.
Title: Re: UART error rate?
Post by: dunk on November 03, 2007, 07:49:44 AM
from the datasheet:
Quote
The Easy-Radio Transceiver can accept and transmit up to 180 bytes of data, which it buffers internally before transmitting in an efficient over-air code format.
so the Easy-Radio module is not transmitting data at the same speed you are sending it at.
it appears you are not filling up the 180 bytes buffer but i suspect its some other timing issue.
have you tried monitoring the "Busy" pin while you are sending data to the ER module?
try only sending data when the "Busy" pin is low.

dunk.
Title: Re: UART error rate?
Post by: Admin on November 05, 2007, 03:26:27 PM
Hmmmm so its still not making sense to me . . . like if it was a buffer problem, wouldn't at least the first packet of info get through?

I mean, I am getting this: 2525252525252
Instead of this: 0 0 0 0 0 0 0 42525252525252

Anyway, so Im trying Dunks idea, and here is the code:
Code: [Select]
while(PORT_IS_ON(PORTC,7)){};//allow data to only transmit when pin is low
rprintf("%d %d %d %d %d %d %d %d \r\n",t1,t2,r1,r2,r4,r5,bk,elapsed_time);//buffer overflow?

Notice I removed the timer, so its not that either . . . Anyway, its still printing 2525252525 with that code. Just for fun I change it to PORT_IS_OFF, and it just stays stuck in the while loop forever . . . So I figure maybe I'm initializing my port wrong?

DDRC = 0x7F;//set C7 to input with other pins as outputs
(busy pin 4 is connected to C7 - did I do this right?! do I maybe need to set pull-up resistors?)

In case I did it right, I scoped up the busy pin 4 with my new oscilloscope for more clues . . . attached is the plot, with the waveform measured at ~12Hz (+/- .6Hz). Not sure if that helps though . . .

Quote
Also, it could help if you try transmitting something like "abcdefghi...".  That way, the result of the transition might give you more insight into the nature of the failure.
Ok I added this code in the beginning:
Code: [Select]
rprintf("\r\nSystem Warming Up");

//let system stabelize for X time
for(i=0;i<=8;i++) // 65500*1.003/234*8 = 2.2 seconds
{
delay_cycles(65500);//~280 milliseconds
rprintf(".");
}

rprintf("\r\nabcdefghijklmnopqrstuvwxyz1234");

//same as above rprintf of output data code goes here//

And this is the output I got:

System Warming Up........ 247
252525252525252525252525252525252525

Quote
Are you sure you're not actually trying to print faster than 30 times per second?
I just scoped it and my function has a frequency of 23Hz, so its actually fewer than 30 . . .

Another theory I have is that maybe its a avrlib problem? Going through uart.h I found this:
Code: [Select]
// buffer memory allocation defines
// buffer sizes
#ifndef UART_TX_BUFFER_SIZE
//! Number of bytes for uart transmit buffer.
/// Do not change this value in uart.h, but rather override
/// it with the desired value defined in your project's global.h
#define UART_TX_BUFFER_SIZE 0x0040
I don't really understand it but does it ring bells for anyone?

 ??? ??? ???
Title: Re: UART error rate?
Post by: bens on November 05, 2007, 03:49:32 PM
So just to clarify, approximately how many total bytes are you attempting to send with each transmission cycle?  It looks like avrlib is limiting you to a 64-byte transmit buffer (you aren't overriding this UART_TX_BUFFER_SIZE value in your project's global.h file, are you?).  I still recommend you see what the output is when you send a less-repetitive sequence of bytes, such as "abcde...".
Title: Re: UART error rate?
Post by: Admin on November 05, 2007, 04:22:53 PM
ran another test . . . this might give more clues . . .

First I ran this code:
Code: [Select]
rprintf("\r\nabcdef");
rprintf("\r\n123456");
rprintf("\r\nabcdef");
//followed by data output code

and got this output:
252525252525252525252525252525252525

Then I ran this code, just adding delays:
Code: [Select]
rprintf("\r\nabcdef");
delay_cycles(6550);
rprintf("\r\n123456");
delay_cycles(6550);
rprintf("\r\nabcdef");
delay_cycles(6550);
//followed by data output code

and got this output:
abcdef
123456
abcdef252525252525252525252525


bens, just in case that didn't bypass your questions . . .
Quote
you aren't overriding this UART_TX_BUFFER_SIZE value in your project's global.h file, are you?
nope

Quote
I still recommend you see what the output is when you send a less-repetitive sequence of bytes, such as "abcde..."
I thought I did this . . . what do you mean exactly? Can you give me some code for it?

Quote
approximately how many total bytes are you attempting to send with each transmission cycle?
hmmmm no idea on how to check that . . . rprintf is magic to me unfortunately . . . all my code snippets above are real code . . .
Title: Re: UART error rate?
Post by: bens on November 05, 2007, 10:03:13 PM

Quote
I still recommend you see what the output is when you send a less-repetitive sequence of bytes, such as "abcde..."
I thought I did this . . . what do you mean exactly? Can you give me some code for it?
Sorry, this is just my being retard and not fully reading your previous post.

At this point I'm really not sure what's going on, mainly because I've never used rprintf or Easy Radio.  If I were in your shoes I think I'd probably try to simplify things down to the basics to get at what's failing.  For example, make a program that just uses rprintf to transmit a single fixed byte sequence to hyperterm.  Increase the length of of the byte sequence until it fails and observe what happens when at the moment you cross the failure threshold.
Title: Re: UART error rate?
Post by: Admin on November 06, 2007, 09:11:26 AM
Quote
For example, make a program that just uses rprintf to transmit a single fixed byte sequence to hyperterm.  Increase the length of of the byte sequence until it fails and observe what happens when at the moment you cross the failure threshold.
Ok so I wrote a program that does this:
Code: [Select]
delay_cycles(30000);
rprintf("\r\n12345678901234567890123456789012345678901234567");
delay_cycles(30000);
rprintf("\r\n123456789012345678901234567890123456789012345678");
delay_cycles(30000);
rprintf("\r\n1234567890123456789012345678901234567890123456789");
delay_cycles(30000);
rprintf("\r\n12345678901234567890123456789012345678901234567890");
delay_cycles(30000);
rprintf("\r\n123456789012345678901234567890123456789012345678901");
delay_cycles(30000);
rprintf("\r\n1234567890123456789012345678901234567890123456789012");
delay_cycles(30000);
rprintf("\r\n12345678901234567890123456789012345678901234567890123");
delay_cycles(30000);
rprintf("\r\n123456789012345678901234567890123456789012345678901234");
delay_cycles(30000);
rprintf("\r\n1234567890123456789012345678901234567890123456789012345");
delay_cycles(30000);
rprintf("\r\n12345678901234567890123456789012345678901234567890123456");
delay_cycles(30000);
rprintf("\r\n123456789012345678901234567890123456789012345678901234567");
delay_cycles(30000);

and this is the output:
12345678901234567890123456789012345678901234567
123456789012345678901234567890123456789012345678
1234567890123456789012345678901234567890123456789
12345678901234567890123456789012345678901234567890
123456789012345678901234567890123456789012345678901
1234567890123456789012345678901234567890123456789012
12345678901234567890123456789012345678901234567890123
123456789012345678901234567890123456789012345678901234
1234567890123456789012345678901234567890123456789012345
12345678901234567890123456789012345678901234567890123456
123456789012345678901234567890123456789012345678901234567

As you can see, it just kept going and never failed . . . it only fails if I set the delay too short. The longer the data I output, the longer the delay needs to be. If the delay was ever too short, it will just start doing 25252525 at that point in the output.

This just leads me to believe that I'm sending data faster than it can be transmitted by the Easy Radio . . . but still not sure if its a uart problem or an Easy Radio problem.

I think I know why my while loop for the busy line wasn't working (assuming my port initialization is correct). It doesn't go above 3.5V (see attached chart in previous post (http://www.societyofrobots.com/robotforum/index.php?topic=2250.msg15278#msg15278)), which is probably too low to trigger a digital port high, right? I couldn't find the minimum voltage for a logic 1 in the ATmega644 datasheet :-\


So to test dunks theory, I used an analog pin . . . I used this code and deleted all the delays:
Code: [Select]
while(a2dConvert8bit(3) > 128){};//allow data to only transmit when pin is low
//output code goes here
and it works!
The problem is that this while loop still takes a while, slowing down my whole datalogger to be too slow at 18.5Hz . . . I want around 30 . . . :-\
Title: Re: UART error rate?
Post by: bens on November 06, 2007, 12:16:26 PM
You could try to remove Easy Radio from the picture to see if the problem still occurs.  At any rate, if the Easy Radio's busy pin is only letting you send data at 18.5Hz, that would seem to confirm that you were sending the Easy Radio data before it was ready for it.  So now the next question is, can you increase the loop speed of your data logger by transmitting fewer bytes?  For example, maybe you should send your sensor values as numbers, not as ascii decimal (or at least send them as ascii hex).

The mega644 datasheet (page 315, section 26.2 - DC Characteristics) says that the minimum input high voltage on an I/O line is .6Vcc, so if your AVR is at 5 V, they guarantee that the I/O line will read high from 3 to 5.5 V.
Title: Re: UART error rate?
Post by: dunk on November 06, 2007, 03:53:15 PM
hi Admin,
looks like the Easy Radio modules are the bottle neck all right.

what about using simple single direction radio modules? get 2 pairs on different channels.
providing you only have 2 nodes this way you could transmit in both directions simultaneously on different channels without having to pause transmission to allow data to flow in the other direction.

alternatively, you could check out http://www.zigbee.org/en/index.asp (http://www.zigbee.org/en/index.asp) modules.
i haven't used them but maybe they allow for higher data transmission rates?

dunk.
Title: Re: UART error rate?
Post by: Admin on November 06, 2007, 04:04:21 PM
Quote
You could try to remove Easy Radio from the picture to see if the problem still occurs.
doh! got to rewire some stuff then . . . I got some bluetooth stuff I can hook it up to, just lazy to resolder stuff . . . Ill try with software for a bit longer because my final project cannot use bluetooth - this datalogger will be underwater and bluetooth doesn't transmit very far in that situation . . . Im operating at 400Mhz right now, and thats still a bit too high (lower the better for underwater). Dunk, this is why I wont be able to use the XBee (http://www.maxstream.net/products/xbee/xbee-oem-rf-module-zigbee.php) because it also operates at a too high 2.4Ghz.

Quote
For example, maybe you should send your sensor values as numbers, not as ascii decimal (or at least send them as ascii hex).
hmmmm I've been trying to understand and pick apart this rprintf stuff, not much success yet . . . still working on it . . . I blame my mechE-ness for my slow programming skills . . . Ill toy with it for awhile . . . anyone have code to do this that they can send me?

Quote
The mega644 datasheet (page 315, section 26.2 - DC Characteristics) says that the minimum input high voltage on an I/O line is .6Vcc, so if your AVR is at 5 V, they guarantee that the I/O line will read high from 3 to 5.5 V.
man I feel dumb, I stared at that page for like 20+ minutes until it made sense . . . All I saw was .6Vcc and I couldn't figure out where you got 3V from . . . till I realized it was .6 X Vcc =3V . . . bllaaaahhh

Quote
what about using simple single direction radio modules? get 2 pairs on different channels.
Well, I rarely have data flow the other direction, mostly just for bootloading . . . does the transceiver stop transmitting to check for receive data occasionally?
Title: Re: UART error rate?
Post by: 4u_allie on November 06, 2007, 04:27:39 PM
   Okay, So this is my Input and Output chart for my robot: Anybody can use it if theirs doesn't work:
  
 DEC.   BINARY             TURN                          OUTPUT                                         OPERATION
           8 4 2 1    HRT    HLT  SRT   SLT       FW REV                 SPEED
                                                           R           F        SLO   MED   FAS   STO        
 o        0 0 0 0     0       0       0      0       1          0          0       0       0       1             RSTO
  1       0 0 0 1     0       0       0      0       1          0          1       0       0       0             RSLO
  2       0 0 1 0     1       0       0      0       1          0          1       0       0       0             RHRT
  3       0 0 1 1     0       0       0      0       1          0          0       1       0       0             RMED
  4       0 1 0 0     0       1       0      0       1          0          1       0       0       0             RHLT
  5       0 1 0 1     0       0       1      0       1          0          0       1       0       0             RSRT
  6       0 1 1 0     0       0       0      1       1          0          0       1       0       0             RSLT
  7       0 1 1 1     0       0       0      0       1          0          0       0       1       0             RFAS
  8       1 0 0 0     0       0       0      0       1          1          0       0       0       1             FSTO
  9       1 0 0 1     0       0       0      0       0          1          1       0       0       0             FSLO
  10     1 0 1 0     1       0       0      0       0          1          1       0       0       0             FHRT
  11     1 0 1 1     0       0       0      0       0          0          1       0       1       0             FMED
  12     1 1 0 0     0       1       0      0       0          1          1       0       0       0             FHLT
  13     1 1 0 1     0       0       1      0       0          1          0       1       0       0             FSRT
  14     1 1 1 0     0       0       0      1       0          1          0       1       0       0             FSLT
  15     1 1 1 1     0       0       0      0       0          1          0       0       1       0             FFAS
                        
Title: Re: UART error rate?
Post by: dunk on November 06, 2007, 04:44:55 PM
Quote
anyone have code to do this that they can send me?

if i don't need all the features of printf i generally just send bytes straight to the UART like this:

Code: [Select]
void uartSendByte(char  data)
        {
         while (!(UCSRA & (1<<UDRE)))             // ensure UART has finished sending last byte.
                {
                wdt_reset();
                }
        UDR = data;                                        // put data in UART output register.

        return;
        }

easy peasy.

dunk.
Title: Re: UART error rate?
Post by: Admin on November 18, 2007, 08:14:57 PM
another question . . .

in the error rate charts, what is the difference between U2Xn=0 and U2Xn=1? The latter sometimes has a lower error rate . . .
Title: Re: UART error rate?
Post by: bens on November 18, 2007, 09:12:02 PM
Setting the U2X register bit causes the UART to run at double speed, which can sometimes make it possible for you to achieve baud rates closer to standard values.  If you take a look at the formulas for calculating baud rate from the value of the UBRR (baud rate) register, the error rates should make sense.

U2X = 0 => baud rate = Fosc / 16 / (UBRR + 1)
U2X = 1 => baud rate = Fosc / 8 / (UBRR + 1)

Error arises from the fact that Fosc is usually not a standard UART frequency, so the baud rate you when you divide Fosc by some number isn't going to be a standard UART frequency.
Title: Re: UART error rate?
Post by: Admin on January 18, 2008, 02:54:15 PM
This problem has come back to haunt me . . .
http://www.societyofrobots.com/robotforum/index.php?topic=2880.msg21085#msg21085

Its breaking my bootloader :(

Perhaps if I use cts and rts on the EasyRadio that might fix stuff?

I'm going to contact the Easy Radio people right now to see what they think . . .
Title: Re: UART error rate?
Post by: rgcustodio on January 18, 2008, 05:03:36 PM
Hello Admin,

i've been reading the ER datasheet and the previous posts. here are some comments and ideas that might be able to start some new discussion.

i'm assuming here you're using the ERx00TRS modules. these are the transceiver variety, and hopefully the 2nd generation version. i'm assuming you are communicating to your ER enabled robot/system with, obviously, an ER enable PC. the ER might be connected to a USB-RS232 converter or a dedicated RS232 on your PC. i also assume that the software that you are using to transfer/download the "application" is FBOOT17.EXE. wheew too many assumptions!

all page references refer to the ER data sheet.

1) on page 12, End of Data Delay, is your code implementing this delay?
i don't think the downloader you are using knows this, so it might just be streaming data continuously. this would work if your wired since the connection is more stable, ie less erroneous packets, and you have no transfer overhead!
for an ER radio connection, according to page 12, there's a 13.2ms of overhead for each packet (this occurs even if you just transfer one character) so for example you are streaming data, the buffer gets full and the ER transmit, but while transmitting (before the 13.2ms is over!) you begin writing to the ER again, you risk destroying the data in the buffer that is currently being transmitted.

2) on page 12, Buffer Size, i hope you're buffering or sending your data in chunks/blocks that are 180-bytes or less in length.
i assume the 180 buffer is used for both Tx and Rx, since the ER is half-duplex only and there are those warnings of buffer corruption strewn all over the ER's data sheet.
do you still remember the UART_TX_BUFFER_SIZE that you posted? maybe you can try increasing that to 128 to closely match the ER's buffer size.

3) the ER is only half-duplex!
did i mentioned this already? you risk destroying the contents of the receive buffers if you try to send anything through the air while the ER is still receiving (again, based on the data sheet).

4) use Busy Output (CTS) and Host Ready Input (RTS) pins on the ER, as you've mentioned
this will be additional coding and probably additional traces/wires on your board. this could be extra work but incorporating CTS/RTS to your solution to 1 and 2 above is the best solution.


understanding 1, 2, 3 above is very important. If you continuously stream data over the air without the End of Data Delay, you'll be writing over the ER's buffers which will cause loss of data. blocking the data you are sending will also maximize the throughput of your ER since you will be trying to use up most of ER's 180-byte buffer before transmitting, and minimizing the overhead caused by the transmission delay. but everything will be in vain if 4 is not implemented.

try to find the "Easy-Radio Software Guide" mentioned in the data sheet, it might be helpful.

btw, a disclaimer, i don't have any actual experience working with the ER! so all this assumptions and theories could be totally rubbish :)

Seriously, I hope this helps!
Title: Re: UART error rate?
Post by: DomoArigato on January 18, 2008, 09:17:53 PM
Hey admin, I have the BlueSmirf working on my AVR.  Everything is working great at 38.4k baud rate.  If BlueSmirf will work for you it was pretty simple to get up and going.  I can even connect to it with my phone.  I'm using it for data logging on my computer.  I'd be glad to give you my serial code I use with it.  It ran like 50$.
Title: Re: UART error rate?
Post by: Admin on January 22, 2008, 09:32:10 AM
I feel really bad for causing a double post (http://www.societyofrobots.com/robotforum/index.php?topic=2880.msg21232#msg21232) . . . I had no idea that the two different problems were related . . .

A quick recap of my situation . . . The reason why I needed the Easy Radio module is because it is the lowest frequency transceiver I could find on the market. Why do I want 400MHz? Well, because it's for my robot fish - meaning underwater. Water absorbs more RF at higher frequencies, so to improve range, I need to use lower frequencies - avoiding bluetooth and zigbee and such that use 2.5GHz . . .

I'm really not sure if I should just call defeat, or try to reverse engineer that bootloader written in assembly . . . I spent like 6 months working on an underwater wireless bootloader - a key selling point for my underwater robot . . . but I might just be better off if I change mission parameters . . . I'll think about this for a bit and talk with my group on it too for tomorrow's meeting . . .

I'm thinking I should keep the Easy Radio to transmit data, and also have bluetooth on it so I can reprogram without constantly opening up my waterproof seals . . . I'd have to take the robot out of the water to do this, but alas probably still easier than my other options . . .

Unless you guys know another transceiver that works on a low frequency without a buffer issue?


Anyway, I emailed the guy who makes the Easy Radio modules and says two important things:
1) confirms what you said, rgcustodio
2) says he is making a new Easy Radio version with much more ram

Quote
Hello John,
Well that forum post took some digesting, but the latest comments from 'rgcustodio' were pretty much there.
To understand your timing issues (provided you no longer have BAUD issues) you need to understand the process the modules go through to send and receive data.
The ER4/900 modules (02 versions) use a PIC which is limited in its internal RAM to 384 bytes. Therefore, each process (upload to module, transmit over air, receive over air and download to target) uses the SAME 180 Byte buffer, and can only do one operation at a time.
Therefore before sending the next set of data, you need to give enough time for the overair comms to complete AND the target to receive the downloaded data. (The timing for a packet of data is in the datasheet.)
The data rate over air is a constant, and does not relate to your RS232 BAUD rate. This enables two end points with different BAUD rates to connect together without conversion.
To operate the quickest, you could start uploading to the transmitting end at a time where the 'bytes to send' = 'bytes still being delivered'.
(If that makes sense)
FYI, I am close to completion of the 900MHz 03 version of the modules. These now use an ATMEL MEGA168, which has allowed me to use independent buffers for all functions. This means that Upload/Download/Transmit or Upload/Download/Receive can be done simultaneously.
This is a massive step forward to easyRadio efficiency. I am also adding features to allow deliver DURING over air reception, but as this involves a change to the over air protocol, it will be software switched and would not be understood by an 02 module.

If you need any help just ask. If you send me your bootloader code, I could take a look for you as well.
The new 03 module also contains a bootloader for flash upgrades which will include (once I have written it) and overair upgrade facility from the eval software.
Oh yes... Eval software... I wrote it, and it is a bit buggy on the comms. This is because it was written on Borland C++ Builder and unlike MS Visual Studio, they did not provide a serialPort class. I therefore had to write my own, but it hits a couple of cross thread problems and dies a death. The faster the machine, the worse it gets... I think!.
Anyway, also about to be uploaded to the server, is the new eval software, which solves all these issues and adds a bit of transparency to how to understand the modules better. (Not written the help file yet though.. doh!)
Well... that's about it.
You can contact me through any of the means on the signature right at the bottom of this email.
Kind Regards
David Schmider
Title: Re: UART error rate?
Post by: dunk on January 22, 2008, 09:50:39 AM
Quote
Unless you guys know another transceiver that works on a low frequency without a buffer issue?
so i know this solution is not ideal but have you considered using 2 one way radio links on separate frequencies?
each one way RF link will obviously not have the buffering issues you are experiencing.
use one pair of RF modules in each direction.

to be honest i'm not sure if you will need to separate the aerials by some distance to stop cross interference or if it will Just Work....

i actually have some of these modules sitting in my bits box that i intended using this way in a long range wireless project but i never did start building that one....
let me know how you get on if you try playing with this.

i suppose you could also keep your existing EasyRadio modules and use another single direction RF link for the bootloader....


dunk.
Title: Re: UART error rate?
Post by: rgcustodio on January 22, 2008, 10:26:52 AM
Quote
I'm really not sure if I should just call defeat, or try to reverse engineer that bootloader written in assembly . . .
it's not defeat yet!

you could probably rewrite an open source C bootloader to fix the problem in software [oooh seems awfully familiar ;)] you've got 4Kb of bootblock to use, that is if your user application isn't using up all of the flash. if you could code tightly and conservatively your bootloader should fit 4k or less.
Title: Re: UART error rate?
Post by: Admin on January 22, 2008, 10:32:06 AM
Quote
so i know this solution is not ideal but have you considered using 2 one way radio links on separate frequencies?
I just asked David (the ER guy) if this was a good idea and he said "Two modules wouldn't help".

But he volunteered to look into modifying the bootloader for me :)

I think he just got a loyal customer and perhaps a tutorial supporting his product ::)


Quote
you could probably rewrite an open source C bootloader to fix the problem in software [oooh seems awfully familiar Wink] you've got 4Kb of bootblock to use, that is if your user application isn't using up all of the flash. if you could code tightly and conservatively your bootloader should fit 4k or less.
you have waaaaayyyy too much undeserved faith in my programming skills :o
Title: Re: UART error rate?
Post by: dunk on January 22, 2008, 11:05:33 AM
Quote
I just asked David (the ER guy) if this was a good idea and he said "Two modules wouldn't help".
i don't mean 2 ER modules.
i think the ER modules all have buffers built in.
regular RF modules do not.
i mean 2 pairs of plain RF modules, one in each direction. 2 separate frequencies. no delay between transmit time and receive time.

the only thing i can think that would stop that working is RF interference between the 2.
i'll be traveling most of the rest of this week but next time i'm at home i'll experiment and report back.


dunk.