Having to turn off UART continuous receive

Started by upand_at_them September 12, 2004
I have a program in my 16F88 that reads data from a GPS (through the
hardware UART), stores it in RAM, parses it, and then writes certain
items to an external EEPROM. What I've discovered, though, is that I
have to turn off continuous receive (CREN=0) before I do my
processing routine or it doesn't work.

Now, I can understand why this would be so in a software UART,
because the big delay caused by the processing routine would foul up
the ability to get back in time for the next start bit. But why
should this be the case for a hardware UART?

My main routine looks like this:
1) Wait 30 seconds (I notice the problem whether I have this or not)
2) Enable continuous receive
3) Get GPS data
4) Disable continuous receive
5) Process GPS data and store in EEPROM
6) Go to step 1

I've tried it without step 4, but it doesn't work.

Mike





----- Original Message -----
From: upand_at_them <>
To: <>
Sent: Sunday, September 12, 2004 6:01 PM
Subject: [piclist] Having to turn off UART continuous receive > I have a program in my 16F88 that reads data from a GPS (through the
> hardware UART), stores it in RAM, parses it, and then writes certain
> items to an external EEPROM. What I've discovered, though, is that I
> have to turn off continuous receive (CREN=0) before I do my
> processing routine or it doesn't work.
>
> Now, I can understand why this would be so in a software UART,
> because the big delay caused by the processing routine would foul up
> the ability to get back in time for the next start bit. But why
> should this be the case for a hardware UART?
>
> My main routine looks like this:
> 1) Wait 30 seconds (I notice the problem whether I have this or not)
> 2) Enable continuous receive
> 3) Get GPS data
> 4) Disable continuous receive
> 5) Process GPS data and store in EEPROM
> 6) Go to step 1
>
> I've tried it without step 4, but it doesn't work.
>
> Mike

I believe what you are seeing is the overrun error stopping further
receives. If I remember correctly you need to turn the receiver OFF then ON
again to clear the overrun error.

Regards
Sergio Masci

http://www.xcprod.com/titan/XCSB - optimising PIC compiler



Is your input routine interrupt driven? If not, there's your
problem. What you want to do is receive the chars as fast as they
come in via an interrupt routine and stick them in a circular
buffer - keep this code tight and FAST. Then your main code reads
chars out of the buffer and does whatever is necessary. In the long
haul, your processing of chars must be faster than the GPS or you
will overflow the buffer. The thing about these PICs is the lack of
memory makes building an adequate buffer very difficult. It should
probably be as large as 3 full sentences (one you are working on,
one in the buffer and one coming in) and that may exceed the RAM
space.

You may be able to use a much smaller buffer if your processing
(scanner) is very quick. The PICs don't have much memory but they
are fast. You should be able to process many thousands of chars per
second if the scanner is quick.

You could do some analysis in the interrupt routine and discard
unimportant parts of the sentence before putting the valuable stuff
in the buffer but that probably won't help the situation.

You need elasiticity - the incoming sentences are rigid and
asynchronous. I would build a sizable buffer (32 chars?) and then
have a flag that gets set (and an LED) if overflow ever occurs. I
would increase the size of the buffer or tighten up the processing
code until I never got an overflow and then double the size of the
buffer. You could probably keep a counter that retained the maximum
number of chars ever in the buffer.

You can find the logic for a circular buffer or queue as it is
sometimes called in "Fundamental Algorithms" by Knuth on page 241
equations 6a and 7a. There are many other references around but a
quick search of Google wasn't helpful.

--- In , "upand_at_them" <upand_at_them@y...>
wrote:
> I have a program in my 16F88 that reads data from a GPS (through
the
> hardware UART), stores it in RAM, parses it, and then writes
certain
> items to an external EEPROM. What I've discovered, though, is
that I
> have to turn off continuous receive (CREN=0) before I do my
> processing routine or it doesn't work.
>
> Now, I can understand why this would be so in a software UART,
> because the big delay caused by the processing routine would foul
up
> the ability to get back in time for the next start bit. But why
> should this be the case for a hardware UART?
>
> My main routine looks like this:
> 1) Wait 30 seconds (I notice the problem whether I have this or
not)
> 2) Enable continuous receive
> 3) Get GPS data
> 4) Disable continuous receive
> 5) Process GPS data and store in EEPROM
> 6) Go to step 1
>
> I've tried it without step 4, but it doesn't work.
>
> Mike





Now that you and Sergio explained it, it makes sense. The overflow
error.

I guess I can leave my routine the way it is, since it does work, and
since what I'm doing is one of the solutions (turning receive off
then on). I might also try resetting the overflow error before my
input routine.

Thanks,
Mike
--- In , "rtstofer" <rstofer@p...> wrote:
>
> Is your input routine interrupt driven? If not, there's your
> problem. What you want to do is receive the chars as fast as they
> come in via an interrupt routine and stick them in a circular
> buffer - keep this code tight and FAST. Then your main code reads
> chars out of the buffer and does whatever is necessary. In the
long
> haul, your processing of chars must be faster than the GPS or you
> will overflow the buffer. The thing about these PICs is the lack
of
> memory makes building an adequate buffer very difficult. It should
> probably be as large as 3 full sentences (one you are working on,
> one in the buffer and one coming in) and that may exceed the RAM
> space.
>
> You may be able to use a much smaller buffer if your processing
> (scanner) is very quick. The PICs don't have much memory but they
> are fast. You should be able to process many thousands of chars
per
> second if the scanner is quick.
>
> You could do some analysis in the interrupt routine and discard
> unimportant parts of the sentence before putting the valuable stuff
> in the buffer but that probably won't help the situation.
>
> You need elasiticity - the incoming sentences are rigid and
> asynchronous. I would build a sizable buffer (32 chars?) and then
> have a flag that gets set (and an LED) if overflow ever occurs. I
> would increase the size of the buffer or tighten up the processing
> code until I never got an overflow and then double the size of the
> buffer. You could probably keep a counter that retained the
maximum
> number of chars ever in the buffer.
>
> You can find the logic for a circular buffer or queue as it is
> sometimes called in "Fundamental Algorithms" by Knuth on page 241
> equations 6a and 7a. There are many other references around but a
> quick search of Google wasn't helpful. >
>
> --- In , "upand_at_them"
<upand_at_them@y...>
> wrote:
> > I have a program in my 16F88 that reads data from a GPS (through
> the
> > hardware UART), stores it in RAM, parses it, and then writes
> certain
> > items to an external EEPROM. What I've discovered, though, is
> that I
> > have to turn off continuous receive (CREN=0) before I do my
> > processing routine or it doesn't work.
> >
> > Now, I can understand why this would be so in a software UART,
> > because the big delay caused by the processing routine would foul
> up
> > the ability to get back in time for the next start bit. But why
> > should this be the case for a hardware UART?
> >
> > My main routine looks like this:
> > 1) Wait 30 seconds (I notice the problem whether I have this or
> not)
> > 2) Enable continuous receive
> > 3) Get GPS data
> > 4) Disable continuous receive
> > 5) Process GPS data and store in EEPROM
> > 6) Go to step 1
> >
> > I've tried it without step 4, but it doesn't work.
> >
> > Mike






Sure, but turning it off and on means you may miss the next sentence
if you miss the lead-in character. If that's not a problem then
your solution will work.

I haven't found code that implements interrupt driven receive - it
isn't difficult but it has to be done properly. Do all the tests
for framing error, parity error, overflow and decide what to do with
invalid data. Skip the char? Skip the sentence? Either approach
has problems. What if it is just the next to the last char? The
first char? That type of thing will drive you nuts!

Do the sentences have a checksum? If so, the scanner can deal with
everything. The input routine just puts the GOOD chars in the queue
and lets the higher level code deal with missing chars. Maybe it
posts an error flag or puts an invalid char in the queue. The
scanner can see the error and scrap the entire sentence.

--- In , "upand_at_them" <upand_at_them@y...>
wrote:
> Now that you and Sergio explained it, it makes sense. The
overflow
> error.
>
> I guess I can leave my routine the way it is, since it does work,
and
> since what I'm doing is one of the solutions (turning receive off
> then on). I might also try resetting the overflow error before my
> input routine.
>
> Thanks,
> Mike >
> --- In , "rtstofer" <rstofer@p...> wrote:
> >
> > Is your input routine interrupt driven? If not, there's your
> > problem. What you want to do is receive the chars as fast as
they
> > come in via an interrupt routine and stick them in a circular
> > buffer - keep this code tight and FAST. Then your main code
reads
> > chars out of the buffer and does whatever is necessary. In the
> long
> > haul, your processing of chars must be faster than the GPS or
you
> > will overflow the buffer. The thing about these PICs is the
lack
> of
> > memory makes building an adequate buffer very difficult. It
should
> > probably be as large as 3 full sentences (one you are working
on,
> > one in the buffer and one coming in) and that may exceed the RAM
> > space.
> >
> > You may be able to use a much smaller buffer if your processing
> > (scanner) is very quick. The PICs don't have much memory but
they
> > are fast. You should be able to process many thousands of chars
> per
> > second if the scanner is quick.
> >
> > You could do some analysis in the interrupt routine and discard
> > unimportant parts of the sentence before putting the valuable
stuff
> > in the buffer but that probably won't help the situation.
> >
> > You need elasiticity - the incoming sentences are rigid and
> > asynchronous. I would build a sizable buffer (32 chars?) and
then
> > have a flag that gets set (and an LED) if overflow ever occurs.
I
> > would increase the size of the buffer or tighten up the
processing
> > code until I never got an overflow and then double the size of
the
> > buffer. You could probably keep a counter that retained the
> maximum
> > number of chars ever in the buffer.
> >
> > You can find the logic for a circular buffer or queue as it is
> > sometimes called in "Fundamental Algorithms" by Knuth on page
241
> > equations 6a and 7a. There are many other references around but
a
> > quick search of Google wasn't helpful.
> >
> >
> >
> >
> > --- In , "upand_at_them"
> <upand_at_them@y...>
> > wrote:
> > > I have a program in my 16F88 that reads data from a GPS
(through
> > the
> > > hardware UART), stores it in RAM, parses it, and then writes
> > certain
> > > items to an external EEPROM. What I've discovered, though, is
> > that I
> > > have to turn off continuous receive (CREN=0) before I do my
> > > processing routine or it doesn't work.
> > >
> > > Now, I can understand why this would be so in a software UART,
> > > because the big delay caused by the processing routine would
foul
> > up
> > > the ability to get back in time for the next start bit. But
why
> > > should this be the case for a hardware UART?
> > >
> > > My main routine looks like this:
> > > 1) Wait 30 seconds (I notice the problem whether I have this
or
> > not)
> > > 2) Enable continuous receive
> > > 3) Get GPS data
> > > 4) Disable continuous receive
> > > 5) Process GPS data and store in EEPROM
> > > 6) Go to step 1
> > >
> > > I've tried it without step 4, but it doesn't work.
> > >
> > > Mike





Yeah, it's not a problem that I miss sentences. This is for a high-
altitude balloon and I'm only logging lat, lon, alt, etc. every 30
seconds.

Thanks.

Mike

--- In , "rtstofer" <rstofer@p...> wrote:
>
> Sure, but turning it off and on means you may miss the next
sentence
> if you miss the lead-in character. If that's not a problem then
> your solution will work.
>
> I haven't found code that implements interrupt driven receive - it
> isn't difficult but it has to be done properly. Do all the tests
> for framing error, parity error, overflow and decide what to do
with
> invalid data. Skip the char? Skip the sentence? Either approach
> has problems. What if it is just the next to the last char? The
> first char? That type of thing will drive you nuts!
>
> Do the sentences have a checksum? If so, the scanner can deal with
> everything. The input routine just puts the GOOD chars in the
queue
> and lets the higher level code deal with missing chars. Maybe it
> posts an error flag or puts an invalid char in the queue. The
> scanner can see the error and scrap the entire sentence.
>
> --- In , "upand_at_them"
<upand_at_them@y...>
> wrote:
> > Now that you and Sergio explained it, it makes sense. The
> overflow
> > error.
> >
> > I guess I can leave my routine the way it is, since it does work,
> and
> > since what I'm doing is one of the solutions (turning receive off
> > then on). I might also try resetting the overflow error before
my
> > input routine.
> >
> > Thanks,
> > Mike
> >
> >
> >
> > --- In , "rtstofer" <rstofer@p...> wrote:
> > >
> > > Is your input routine interrupt driven? If not, there's your
> > > problem. What you want to do is receive the chars as fast as
> they
> > > come in via an interrupt routine and stick them in a circular
> > > buffer - keep this code tight and FAST. Then your main code
> reads
> > > chars out of the buffer and does whatever is necessary. In the
> > long
> > > haul, your processing of chars must be faster than the GPS or
> you
> > > will overflow the buffer. The thing about these PICs is the
> lack
> > of
> > > memory makes building an adequate buffer very difficult. It
> should
> > > probably be as large as 3 full sentences (one you are working
> on,
> > > one in the buffer and one coming in) and that may exceed the
RAM
> > > space.
> > >
> > > You may be able to use a much smaller buffer if your processing
> > > (scanner) is very quick. The PICs don't have much memory but
> they
> > > are fast. You should be able to process many thousands of
chars
> > per
> > > second if the scanner is quick.
> > >
> > > You could do some analysis in the interrupt routine and discard
> > > unimportant parts of the sentence before putting the valuable
> stuff
> > > in the buffer but that probably won't help the situation.
> > >
> > > You need elasiticity - the incoming sentences are rigid and
> > > asynchronous. I would build a sizable buffer (32 chars?) and
> then
> > > have a flag that gets set (and an LED) if overflow ever
occurs.
> I
> > > would increase the size of the buffer or tighten up the
> processing
> > > code until I never got an overflow and then double the size of
> the
> > > buffer. You could probably keep a counter that retained the
> > maximum
> > > number of chars ever in the buffer.
> > >
> > > You can find the logic for a circular buffer or queue as it is
> > > sometimes called in "Fundamental Algorithms" by Knuth on page
> 241
> > > equations 6a and 7a. There are many other references around
but
> a
> > > quick search of Google wasn't helpful.
> > >
> > >
> > >
> > >
> > > --- In , "upand_at_them"
> > <upand_at_them@y...>
> > > wrote:
> > > > I have a program in my 16F88 that reads data from a GPS
> (through
> > > the
> > > > hardware UART), stores it in RAM, parses it, and then writes
> > > certain
> > > > items to an external EEPROM. What I've discovered, though,
is
> > > that I
> > > > have to turn off continuous receive (CREN=0) before I do my
> > > > processing routine or it doesn't work.
> > > >
> > > > Now, I can understand why this would be so in a software
UART,
> > > > because the big delay caused by the processing routine would
> foul
> > > up
> > > > the ability to get back in time for the next start bit. But
> why
> > > > should this be the case for a hardware UART?
> > > >
> > > > My main routine looks like this:
> > > > 1) Wait 30 seconds (I notice the problem whether I have this
> or
> > > not)
> > > > 2) Enable continuous receive
> > > > 3) Get GPS data
> > > > 4) Disable continuous receive
> > > > 5) Process GPS data and store in EEPROM
> > > > 6) Go to step 1
> > > >
> > > > I've tried it without step 4, but it doesn't work.
> > > >
> > > > Mike