Searching \ for '[PIC] Better way to read a serial data stream?' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: massmind.org/techref/microchip/ios.htm?key=serial
Search entire site for: 'Better way to read a serial data stream?'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] Better way to read a serial data stream?'
2009\08\18@011954 by PicDude

flavicon
face

Hi all,

I intend to read a proprietary serial data stream from another product into
a spare PortA pin on a 16F pic.  Currently 8Mhz internal osc, but the PCB is
setup for a 3-pin resonator (20Mhz or other) resonator if necessary.

Essentially there is a relatively long idle period, followed by over 70
sequential data bits which are around 400ms long each, and at approx 1%
timing error from the sender.  This becomes fun because I don't have
interrupt-on-change on this pin, and trying to set a constant time for each
bit will be difficult because and error will accumulate over 70 bits.

So my plan is to generate Timer 2 interrupts every 50 to 100 ms looking for
the idle period, then end-of-idle transition, adjust the timer (PR2) to poll
in the middle as appropriate to capture the bit value, then adjust PR2 again
to end a few percent before the expected transition, and then poll in a loop
to accurately determine the edge/transition that marks the end of the bit
(the beginning of the bit).  The "few percent" will allow for all sources of
timing errors from the sender, receiver (pic) clock, etc.

Now the question -- since the pic is doing other things, the timer interrupt
that should be triggered a few percent before the end of the bit may get
delayed, so the few percent may change to 5 percent or more, and I could be
waiting for maybe over 100 clock cycles before returning from that
interrupt.  I hate doing that, and always try to keep my interrupt
processing as short as possible.  Is there another/better way to do this?

Cheers,
-Neil.

--
View this message in context: www.nabble.com/Better-way-to-read-a-serial-data-stream--tp25018655p25018655.html
Sent from the PIC - [PIC] mailing list archive at Nabble.com.

2009\08\18@012115 by PicDude

flavicon
face

Oops, this should be 400 us (*micro*seconds) long each.



PicDude wrote:
>
> ... over 70 sequential data bits which are around 400ms long each...
>

--
View this message in context: www.nabble.com/Better-way-to-read-a-serial-data-stream--tp25018655p25018667.html
Sent from the PIC - [PIC] mailing list archive at Nabble.com.

2009\08\18@032859 by Richard Prosser

picon face
2009/8/18 PicDude <spam_OUTpicdude2TakeThisOuTspamavn-tech.com>:
>
> Oops, this should be 400 us (*micro*seconds) long each.
>
>
>
> PicDude wrote:
>>
>> ... over 70 sequential data bits which are around 400ms long each...
>>
>
> --
> View this message in context: www.nabble.com/Better-way-to-read-a-serial-data-stream--tp25018655p25018667.html
> Sent from the PIC - [PIC] mailing list archive at Nabble.com.
>


Picdude.
I think you need to organise a system in which the errors don't
accumulate. I used  a method (many years ago) that maintained bit
synch  that may be useful. Trouble is it's a bit hard to explain.

Basically you sample twice per  period, once at the transition and
once at the anticipated midpoint. If the midpoint reading agrees with
the transition reading but the bit has changed from the previous bit
(midpoint), then you assume that you have sampled late and your clock
is a bit slow. Similarly, if the bit has changed, and so has the
reading since the transition, then you figure your local clock is fast
and adjust it slightly accordingly. Providing the adjustment is small,
you can retain lock in quite noisy environments - we were using a
radio link.

It looks a bit complicated but actually coded into quite a compact
block of assembler. ('6805 in the case in point)

Richard P

2009\08\18@034737 by Michael Rigby-Jones

flavicon
face


> -----Original Message-----
> From: .....piclist-bouncesKILLspamspam@spam@mit.edu [piclist-bouncesspamKILLspammit.edu] On
Behalf
{Quote hidden}

PCB
> is
> setup for a 3-pin resonator (20Mhz or other) resonator if necessary.
>
> Essentially there is a relatively long idle period, followed by over
70
> sequential data bits which are around 400ms long each, and at approx
1%
> timing error from the sender.  This becomes fun because I don't have
> interrupt-on-change on this pin,

Which pin are you using and which device?

=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================

2009\08\18@082113 by olin piclist

face picon face
PicDude wrote:
> I intend to read a proprietary serial data stream from another
> product into
> a spare PortA pin on a 16F pic.  Currently 8Mhz internal osc, but the
> PCB is
> setup for a 3-pin resonator (20Mhz or other) resonator if necessary.
>
> Essentially there is a relatively long idle period, followed by over
> 70
> sequential data bits which are around 400ms long each, and at approx
> 1%
> timing error from the sender.

Obviously this can't work.  Just from the sender's clock error alone you are
off by .7 bits in the middle of the last bit, with .5 bit time error being
the guaranteed to fail limit.  Any error in the receiving process adds to
this.  Either you got the specs wrong or some idiot designed a protocol that
can't be correctly received regardless of how much cleverness is applied in
the receiver.  If this is really NRZ encoding and the sender could send all
bits the same value, then you're screwed.

You can resync your clock on bit transitions, assuming these happen once
between bits and the bits are the same length.  Even though bit value
changes may not be guarantee within a particular time, you can still make
use of them when they do occur, and most likely they will occur often enough
in practise.

The easiest thing is to set up periodic interrupt and sample the input
signal there.  Fortunately your bit rate is very slow, so this interrupt
could every 10mS or more.  Even something as slow as 10mS still gives you 40
samples/bit.

Obviosly you watch for the start bit and start timing there, but you also
watch for transitions on the line and reset the clock to the middle between
two bits when you find one.  That resets any accumulated clock drift between
the sender and receiver on every bit value change.  The problem is that
these are not guaranteed to occur unless you haven't told us everything.

For extra credit, you not only reset the clock on input line transitions,
but also adjust your conception of a bit time a little.  After a few
messages, your PIC will have been trained on that sender, and subsequent
messages will work better, even with long sequences of the same bit value.

A easy way to do this is to keep a number that indicates how many samples
there are per bit.  This trick is to make this fixed point and keep some
fraction bits, like 8.  This allows making small changes in your assumed bit
period when edges are found.  I would adjust the bit period slowly, probably
by low pass filtering any new value into the in-use value with a couple of
poles and a low filter fraction.  The error between the sender's clock and
your clock shouldn't change much, and should change slowly when it does.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\08\18@152929 by William \Chops\ Westfield

face picon face

On Aug 18, 2009, at 5:22 AM, Olin Lathrop wrote:

>> Essentially there is a relatively long idle period, followed by  
>> over 70 sequential data bits which are around 400ms long each, and  
>> at approx 1% timing error from the sender.
>
> Obviously this can't work.

I agree with Olin.  This is where schemes other than NRZ come in (even  
just stop and start bits in async serial), and why they're needed...

BillW


2009\08\19@101126 by PicDude

flavicon
face


Richard Prosser wrote:
{Quote hidden}

> --

2009\08\19@121715 by Dave Tweed

face
flavicon
face
PicDude wrote:
> Let me clarify a few things, which I think will make a difference -- the
> bits start and end with a L-->H transition. The H-->L transition point
> between the start and end points of each bit varies, so the duty-cycle
> determines the bit value. This is not NRZ. Yes, bits are the same length.

In that case, you have a self-clocking code, which makes things a LOT
easier.

You just need to poll the data line with a period that is less than (with a
comfortable margin) the minimum interval between any pair of transitions.
For example, if the signal is 1/3 high, 2/3 low for a 0 and vice versa for
a 1, then sample at 4x the bit rate, or 100 us. The timing margin you
select should include any expected peak-to-peak jitter in the sampling that
might be due to interrupt latencies, etc.

To decode the data, simply look for groups samples consisting of contiguous
1s followed by contiguous 0s, and make your bit decision based on the
relative counts in each group. This can even be done in the ISR itself,
with little overhead.

-- Dave Tweed

2009\08\19@160119 by Richard Prosser

picon face
2009/8/20 PicDude <picdude2spamspam_OUTavn-tech.com>:
{Quote hidden}

>> -

2009\08\20@191439 by PicDude

flavicon
face

Okay, that seems like a surprisingly simple solution to this problem.  I'm
evaluating on paper for now, and can't see it working well with 4x the bit
rate, but 5x seems to work well... so far.  This is assuming minimal error
for now, but I'll try factoring in a few percent error to see how 5x would
handle it.  What's nice is that the ISR processing for this is indeed very
minimal, so a faster sample rate is fine.

FWIW, I've been able to re-work some of my other ISR code (mostly to
multiplex LED displays) to reduce interrupt latency by breaking it up into a
couple shorter calls.

Thanks,
-Neil.



Dave Tweed wrote:
{Quote hidden}

> --

2009\08\21@141255 by Dave Tweed

face
flavicon
face
PicDude wrote:
> Okay, that seems like a surprisingly simple solution to this problem.
> I'm evaluating on paper for now, and can't see it working well with 4x
> the bit rate, but 5x seems to work well... so far. This is assuming
> minimal error for now, but I'll try factoring in a few percent error
> to see how 5x would handle it. What's nice is that the ISR processing
> for this is indeed very minimal, so a faster sample rate is fine.

Like I said, the interval depends on the exact characteristics of the data
you're trying to decode.

Actully, I misspoke. Suppose the data is high for 40% of the bit interval
for a zero, and 60% for a one. In that case, you'd need to sample with a
period that is less than -- with some margin -- 20% of the bit interval in
order to reliably resolve the difference.

-- Dave Tweed


'[PIC] Better way to read a serial data stream?'
2009\09\02@075451 by Bob Axtell
face picon face
I would drop the internal RC clock and use a ceramic resonator or
crystal instead. Otherwise you will be driven to despair by timing
errors,

I'd sample at least 4x per bit if possible then nudge the centerline
slightly. Timer2 and PR2 will work, I've done it. With a good clock.

--Bob

On Fri, Aug 21, 2009 at 11:12 AM, Dave Tweed<KILLspampicKILLspamspamdtweed.com> wrote:
{Quote hidden}

> -

2009\09\02@083345 by Dave Tweed

face
flavicon
face
Bob Axtell wrote:
{Quote hidden}

I think you missed the point of the scheme I'm outlining. It doesn't
require the sampling clock to be synchronized with the data at all.
The only requirement is that the sampling period be less than the time
intervals you're trying to resolve, with sufficient margin based on
things like CPU clock accuracy and sampling jitter.

-- Dave Tweed

2009\09\12@143815 by PicDude

flavicon
face

Hmmm... no, I wasn't thinking that (that it has to be synchronized).  FWIW, I
got this working, but I get occasional errors if the sampling period is any
higher than 1/9th the period of the data.  I suspect that most of this is
due to latency from other interrupt routines in the code.  It's not a
problem for now, as there's no other significant processing in the code, but
I'm cleaning up (and breaking up) some of that other code now.  Thanks.

Cheers,
-Neil.




Dave Tweed wrote:
>
> I think you missed the point of the scheme I'm outlining. It doesn't
> require the sampling clock to be synchronized with the data at all.
> The only requirement is that the sampling period be less than the time
> intervals you're trying to resolve, with sufficient margin based on
> things like CPU clock accuracy and sampling jitter.
>
> -- Dave Tweed
>

--
View this message in context: www.nabble.com/Better-way-to-read-a-serial-data-stream--tp25018655p25417060.html
Sent from the PIC - [PIC] mailing list archive at Nabble.com.


'[PIC] Better way to read a serial data stream?'
2009\10\14@055241 by Alan B. Pearce
face picon face
>So my plan is to generate Timer 2 interrupts every 50 to 100 ms
>looking for the idle period, then end-of-idle transition, adjust
>the timer (PR2) to poll in the middle as appropriate to capture
>the bit value, then adjust PR2 again to end a few percent before
>the expected transition, and then poll in a loop to accurately
>determine the edge/transition that marks the end of the bit (the
>beginning of the bit).  The "few percent" will allow for all
>sources of timing errors from the sender, receiver (pic) clock, etc.
>
>Now the question -- since the pic is doing other things, the timer
>interrupt that should be triggered a few percent before the end of
>the bit may get delayed, so the few percent may change to 5 percent
>or more, and I could be waiting for maybe over 100 clock cycles
>before returning from that interrupt.  I hate doing that, and always
>try to keep my interrupt processing as short as possible.
>Is there another/better way to do this?

Right, sorry to be so late replying, but I have been away for 9 weeks
looking after my ailing father.

My response is to refer you to the M6800 Applications manual that was
printed around the late 1970s. Someone posted a link here to a downloadable
PDF copy when I mentioned this some time in the past, so check the archives.

My reason for mentioning it is that they do a scheme something like you are
suggesting, to read a barcode wand for UPC codes, which is hand scanned
across the barcode, so has to deal with variable speed scans, as well as
widely different scan rates. Should give you some good ideas on what you
need to do to get good results every time.

More... (looser matching)
- Last day of these posts
- In 2009 , 2010 only
- Today
- New search...