AVR SAME Decoding.

Go To Last Post
53 posts / 0 new

Pages

Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am trying to build an AVR NWS weather radio SAME message decoder.

I have been researching the SAME (specific area message encoding) system, and its AFSK with a 2083.3 Hz bit 1 tone, and a 1562.5 Hz space tone.

also it has a 520.83 bitrate.

im not quite sure how to make a UART to read a 520.83bps rate. the AFSK decoder to decode the tones into bits, i can handle that. its not knowing how to read in the bits into a 520.83bps UART.

once i read in the bits into SRAM, i can handle it from there also. its the UART and bit-bang timing that i dont quite understand.

any ideas?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

use 16MHz oscillator frequency and use
pre-divider=1920 in an AVR:

16MHz/16/1920=520.83333.. Bit/sec.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

First I don't knoow how SAME works.
to find the two tone you need to sample the two tones, either with a filter (goetchel is very simple) or just by timming zero crossings. So as I can see a 0 is 3 full periods and a 1 is four, that's simple but how does the header work ? (the start of a message) and do you need to syncronize on the bits or can it be done at the header only ?
I would get a .wav file on a PC and the see what is needed using a PC C compiler (or often I use excel because it's so easy to plot with).
I think you will need a interrupt at 2083.3*4 Hz.

I would send the message from a buffer at a least 1200 baud.

Jens

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

well getting the AFSK tones into 0s and 1s isnt hard. im going to use an AFSK decoder IC with bandpass filters.

but when it becomes its serial bitstream is where im going to have my problems.

im going to have my 520.83bps going to a port pin.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You do not use the UART. This is not async serial. It is a constant bit stream with no start or stop bits (section A.1.2). The header consists of 8 characters, every one being 0xAB. So, shift the bits into a shift register until you see that bit pattern and that syncs you to the frame. From then, on, shift 8 bits and read, shift 8 bits and read.

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ka7ehk wrote:
You do not use the UART. This is not async serial. It is a constant bit stream with no start or stop bits (section A.1.2). The header consists of 8 characters, every one being 0xAB. So, shift the bits into a shift register until you see that bit pattern and that syncs you to the frame. From then, on, shift 8 bits and read, shift 8 bits and read.

Jim

I know this thread is rather old, but I would like to pick back up on it again.

I'm not quite understanding what your saying, when you say shift until you see that bit pattern.

you have to shift at a certain speed? how would I calculate the speed at which to shift at? i know its 520.83bits per second, with a 1.92ms bit period.

only thing that comes to mind is shift one step, wait 1.92ms, shift another bit, and wait another 1.92ms.

I'm not exactly sure how to delay exactly 1.92ms.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I'm not exactly sure how to delay exactly 1.92ms.

Use a timer.

Also, search this site for "bit banging" to find discussions on a related technique. Those talk will probably be on decoding asynch serial (eg. RS-232) but the techniques will be usable in your case also even though the link protocol differs.

One thing to ponder is to sample at three times the data rate, and have a "majority vote" on each bit (or simply deem the decoding as bad if there is a minority vote).

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You set a timer that runs every 1.92ms

You sample things like you would do with a UART. i.e. having got started, you read half-way through a bit period.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can also consider using the excellent debouncing techniques mentioned elsewhere in this forum to get the bitstream into the AVR. Sampling at several times the expected bit rate as suggested above is one way.

Don't know the AFSK decoder you are using, but make sure the output is switching cleanly. If in doubt, use a Schmitt trigger to clean it up.

If you think education is expensive, try ignorance.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

another thing i stumbled upon is dividing a 1mhz crystal by 1920, and that gives the exact 520.83bps bitrate.

If i did this, i could use that division clock output to an interrupt pin, to read a bit each time that interrupt hits. wouldnt this work also? (im not familiar enough with math to figure out timers).

Im not sure exactly how to divide a 1mhz clock by this either. hehe. Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

the AFSK decoder have seperate outputs. one output is high if the mark tone is detected, and another output is high if the space tone is detected. so you have a 10 and 01 situation. if its 11 or 00 its noise and to be ignored.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The only thing that I have come up with is this:

AVR at 1Mhz. and a timer0 prescale at 8.

after 240 counts its at 520.83.

I'm not sure if my math is right, but i figured 1mhz / 8 is 125000, and i take this divide by 240 counts, its 520.83... So, im assuming this means, that i will hit count 240 exactly 520.83 times per second. (give or take the time required to reset the timer).

So, what do i do, reset the timer, wait until the count hits 240, then read the bit? shift it in, and then reset the counter, and wait again? Thanks.

your saying to read halfway in the bit, im not sure how exactly to do this.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Don't bother about dividing a clock yourself, configure a timer as a counter to output an interrupt every 1.92ms. You can just use a prescaler to get it within range, and modify the TOP value to fine tune to exactly your bit time.. You could also resync the timer everytime you catch a preamble, so you don't lose sync over time...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

only way i know how i could sync it, is as soon as i see a high bit, i start the timer, and stop it when i see the low bit, record and write the value to EEP or something.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

well if my math and thinking is correct, what i do know is if I use a 1mhz clock on the AVR, use timer0 with prescale of 8, the timer value will be at 240 approximately 1.92ms in. and it will hit 240 about 520.83 times per second. (plus or minus a few clocks to set/reset/clear timer).

And on a bit-bang you have to read half-bit times.

So the way i have it thought up is like this:

Wait 960uS. (about 120 timer value).

Read the bit, shift it.

Wait 1.92ms (about 240 timer value - time lost from reading/shifting bit so about 238).

Read next bit, shift it.

repeat cycle. after 8 bits shifted. check if AB. if not, then throw it out. and try again.

if AB, start SAME mode, and then store in RAM. increment RAM pointer, and bounce back to read subroutine to go read again.

I see where the timer would have to be adjusted because it takes time to crunch code to do stuff. so i have to trim off or add time to the timer when i go off and do stuff like shift the bits, save in ram, check and branch etc etc etc.

right?

but then again the timer is always counting no matter what your doing, so itll hit 120 or 240 or w/e your defined value is quicker. heck i dunno.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you attach a wav file with some known content, and assert with grand aplomb that we are all so stupid that we cant possibly decode the file within a week, you will have 3 or 4 guys submitting the results of their SAME decoder within hours. If you can cajole or somehow coax them into selling/loaning/giving you the c source to their program, you are all set.

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bobgardner wrote:
If you attach a wav file with some known content, and assert with grand aplomb that we are all so stupid that we cant possibly decode the file within a week, you will have 3 or 4 guys submitting the results of their SAME decoder within hours. If you can cajole or somehow coax them into selling/loaning/giving you the c source to their program, you are all set.

?? lol.. you just confused the heck outta me. hehe.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Can I just record it off a shortwave receiver? What freq?

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

no. SAME is broadcasted from the NWS weather radio network. the 162.xxx area of the band.

there is a sample file on wikipedia.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

techknight wrote:
The only thing that I have come up with is this:

AVR at 1Mhz. and a timer0 prescale at 8.

after 240 counts its at 520.83.

I'm not sure if my math is right, but i figured 1mhz / 8 is 125000, and i take this divide by 240 counts, its 520.83... So, im assuming this means, that i will hit count 240 exactly 520.83 times per second. (give or take the time required to reset the timer).

So, what do i do, reset the timer, wait until the count hits 240, then read the bit? shift it in, and then reset the counter, and wait again? Thanks.

your saying to read halfway in the bit, im not sure how exactly to do this.

Are you using a real Xtal or the internal OSC (witch isn't very precise)

/Bingo

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
your saying to read halfway in the bit, im not sure how exactly to do this.

If you read the bit while it is being changed you will get wrong data... If your interrupt triggers on the edge, add a half-bit delay before reading.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I dont have a 1mhz xtal, just the RC oscillator.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've been thinking about this all day. I THINK that i have it figured out. Wont actually know until i build the AFSK decoder and write some code to figure it out.

but what i have figured is this: with a 1mhz clock, each CPU cycle will take 1uS. Since the same message pre-amble begins with a first bit (LSB) of 1, that means i can use this to trigger an external interrupt.

so to read approximately 960us, i will have to set the timer to do this, but i have to subtract off the uS wasted by triggering the interrupt, and the clock time required to jump to the routine, and set up the timer, etc. etc etc. once i calculate that time, i can subtract it off my timer time and that way i can land in the middle of the first bit.

but each consecutive bit, i have to subtract off the time required to read the bit, and rotate my temp byte. plus the time required for the cpi instructions for my 8 bits, plus the cycles required to put each byte into sram, etc etc etc. I see where this is going to get complicated. Because if i dont have all this calculated out, then eventually i will loose time for each bit i read. it will slowly scoot outward from the middle of the bit until i cross-over and everything is offset by a bit.

But i figured i have 1920 clock cycles before i HAVE to read each proceeding bit. after the first half bit delay, minus code time. so i hope to keep things trimmed down enough, that i only waste about 10us or so before getting to read the bit. but if I'm in the middle, ive still got a couple hundred uS of "waste time" before i get into problems.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You could use a simple 8-bit serial to parallel shifter and supply it the bit clock, then you only have to read a full byte every 8 bits...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That bitrate is so slow that it you really don't need to worry about the time it takes to read in a bit value. Just use one of the AVR's timers to get your delays to poll the bits.

Math is cool.
jevinskie.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

UNiXWHoRe wrote:
You could use a simple 8-bit serial to parallel shifter and supply it the bit clock, then you only have to read a full byte every 8 bits...

but we go back into that 1mhz by 1920 divider discussion again. hehe ;)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How so? Just PWM the desired frequency for the clock rate... ;)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

PWM the desired frequency..... hmm..... i thought PWM adjusts the pulse-width, not frequency?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You have control over both frequency and duty cycle with PWM. There is no rule that says the PWM has to change over time, you are perfectly free to use it to generate a 50% duty cycle clock of some given frequency.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

im going to have to study the data sheet some more to figure out how to adjust frequency aside from the prescaler.

I'm going to go ahead and build the AFSK decoder once my parts arrive for the active BPF. and scope the output. I will get back with you all once i do this. hehe. If people think that im "begging for code" I'm not. im simply trying to understand some things. I basically read what you were saying, and tried to interpret it, and posted what i thought was my understanding. I didnt really get any comments on it, so i figured what i posted math/timer was was correct.

But im going to build the AFSK decoder, and build a simple atmel circuit, and write a program that detects for AB only. and light an LED if AB detected. since SAME data varies in length, and its all ascii data, the incomming data should NEVER be $00 at any given point in time. so i can just keep feeding in data to keep things short and sweet, until i encounter $00. once i tst for 00, i exit. then perform the breakdown of data manipulation.

Thanks all.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What I would do is stick something like a 74HC164 shifter on the serial input, clock it from the AVR using a PWM. Only thing you have to do now is keep track of how many bits are on the shifter, find a way to synchronize the clock you supply to the shifter, and read/clear the shifter when necessary...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think I can do it all in sw by sampling the waveform and doing an fft. I have the bits and pieces in different programs.. the fft, the sw uart... just need to cutnpaste em together.... anybody have a test waveform for an acceptance test?

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bobgardner wrote:
I think I can do it all in sw by sampling the waveform and doing an fft. I have the bits and pieces in different programs.. the fft, the sw uart... just need to cutnpaste em together.... anybody have a test waveform for an acceptance test?

I've attached a SAME message that I generated in software a few years ago. To decode it, a FFT would be silly. It would be better and faster to use the Goertzel algorithm to bin the bits into either 2083.3 Hz (1) or 1562.5 Hz (0).

Wikipedia also has a SAME message, probably a recording: http://commons.wikimedia.org/wik...

Attachment(s): 

Math is cool.
jevinskie.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ok guys im back.

I built a test circuit, and wrote some test code.

I attached the code.

But of course, as i knew it, I have some sort of a problem. its not reading properly.

I sent a SAME message out the sound card to the device that is encoded to say this:

Encoded message:
00000000 ABAB ABAB ABAB ABAB ABAB ABAB ABAB ABAB ................
00000010 5A43 5A43 2D45 4153 2D52 5754 2D30 3132 ZCZC-EAS-RWT-012
00000020 3035 372D 3031 3230 3831 2D30 3132 3130 057-012081-01210
00000030 312D 3031 3231 3033 2D30 3132 3131 352B 1-012103-012115+
00000040 3030 3330 2D32 3738 3034 3135 2D57 5453 0030-2780415-WTS
00000050 502F 5456 2D00 0000 0000 0000 0000 0000 P/TV-...........

But i get this:

00000000 AA51 FC03 FC2F D02F DA15 EA17 E03F C17A .Q..././.....?.z
00000010 A990 287F 03FC 17A8 BFE5 0AF5 07C0 FF00 ..(.............
00000020 F38C D3F2 7E03 FC3F 809F 9E09 EE0F C07F ....~..?........
00000030 83E0 3BC8 30FF 04F8 1F60 9F7D 02F5 1780 ..;.0....`.}....
00000040 FF00 F0D2 32C8 3F00 FE07 986F 2C4A F60B ....2.?....o,J..
00000050 E06F 40FB FF07 0000 0000 0000 0000 0000 .o@.............

any ideas

Attachment(s): 

Last Edited: Sat. Jun 28, 2008 - 04:55 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Apart of decoding the bytes, you need a good syncronisation, since there is no stat and stop bit.
However, there is a stop bit (eight bit = 0) that can help you. So, you should use every transition 0 - 1 or 1 - 0 to keep in synchronisation.
Don't mix the voting way to establish if a bit is 0 or one with the synchronisation procedure. There are different things, with some interactions.
If you use interupts, is easyer, if not, I would use a sample rate at least three times of 520.83Hz if not to implement a sort of PLL.

Gelu.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

angelu wrote:
Apart of decoding the bytes, you need a good syncronisation, since there is no stat and stop bit.
However, there is a stop bit (eight bit = 0) that can help you. So, you should use every transition 0 - 1 or 1 - 0 to keep in synchronisation.
Don't mix the voting way to establish if a bit is 0 or one with the synchronisation procedure. There are different things, with some interactions.
If you use interupts, is easyer, if not, I would use a sample rate at least three times of 520.83Hz if not to implement a sort of PLL.

Gelu.

you lost me.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, i played with my timer settings a little bit.

I dropped the timer value in my first delay to about 60, and dropped my second delay to 237. if the second delay is 238 or 236 i get pure garbage.

but with these settings, i get this now:

00000000 80AB ABAB ABAB FBFF 5654 5454 5454 54F4 ........VTTTTTT.
00000010 5A43 5A43 2D45 4153 0D00 0080 D2CF CECD ZCZC-EAS........
00000020 EFFF FFFF FFFF 3F30 3800 0000 0000 0000 ......?08.......
00000030 98D6 FFFF FFFF FFFF EF67 E706 0000 0000 .........g......
00000040 1898 1998 16FD FFE7 E765 6765 69D4 F52F .........egei../
00000050 A817 2AAB 96FF 1F00 0000 0000 0000 0000 ..*.............

So it at least is now getting some good data. it sort of oscillates between garbage, and good and garbage again. But as stated previously in this thread, it might have something to do with the internal 1mhz RC oscillator. so i will have to most likely break down and get a crystal.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well for one you are using the internal RC oscillator.. You are doomed from the start there, no way to keep any reasonable timing margin with it... I'm sure you must have a 3.6864MHz xtal with two caps lying around somewhere... ;) Will also make your UART comms error-free

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Few things:

Quote:

IDLETOP:
cpi flags, $01
brne idletop

cli

lets say, INT0 will triger when PC is at 'cpi flags, $01'. Since you read all 256 * 8 bits inside the INT0 ISR, when you exit IST the int0 flag will be set 100%; so, after PC go back to the next instruction, instead to go to CLI, will execute INTo ISR again, reading another set of data and writing it on the same EEPROM location. You need to disable INT0 at the begining of the ISR.

Quote:

Wait:
in temp2, TCNT0
cpi temp2, $78 brlo wait

and

Quote:

Wait2:
in temp2, TCNT0 cpi temp2, $F0 brlo wait2

You scan TCNT0, compare, branch - you lose not one microsecond, but many. These delays are acumulating, pushing you more and more out of fase, and in the end you will lose bits, not only microseconds. You need to use CTC for example and let the timer to rol over by it self.

Quote:

ReadBit:
in temp, PIND bst TEMP, 2 lsr BYTE
bld BYTE, 7

I see you read only one bit, and not both, as you said before. You can not check those two impossible situations 00 and 11 reading only one bit.

Even if you fix these isues, you will not be able to read properly.
If you use an quartz osccilator, and starting in a good phase, maybe have chances to read properly.
To be sure you not miss something, you need synchronisation in phase AND in frequency. This kind of transmission is worst than manchester or serial (232).

Gelu.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

used an 8mhz crystal and a 64 prescaler. changed the timing a little bit on both the half-bit and bit timer. and it decoded just fine! only on one same file though. I have a few others including the one you posted it only decodes garbage.

The same file on WIKI is the only one that decodes properly.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just a thought, but if you are decoding from audio make sure you use a file in fixed bitrate and no compression... Most audio compression schemes are lossy, and slight pitch changes can occur, leading to your bandpass filter discarding the signal partly for example if it is too strict... I can *hear* the pitch difference between the OGG-Vorbis compressed file on wikipedia and the WAV file posted above... I would use the WAV file as base if I was you... ;)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

angelu wrote:
Few things:

Quote:

IDLETOP:
cpi flags, $01
brne idletop

cli

lets say, INT0 will triger when PC is at 'cpi flags, $01'. Since you read all 256 * 8 bits inside the INT0 ISR, when you exit IST the int0 flag will be set 100%; so, after PC go back to the next instruction, instead to go to CLI, will execute INTo ISR again, reading another set of data and writing it on the same EEPROM location. You need to disable INT0 at the begining of the ISR.

Quote:

Wait:
in temp2, TCNT0
cpi temp2, $78 brlo wait

and

Quote:

Wait2:
in temp2, TCNT0 cpi temp2, $F0 brlo wait2

You scan TCNT0, compare, branch - you lose not one microsecond, but many. These delays are acumulating, pushing you more and more out of fase, and in the end you will lose bits, not only microseconds. You need to use CTC for example and let the timer to rol over by it self.

Quote:

ReadBit:
in temp, PIND bst TEMP, 2 lsr BYTE
bld BYTE, 7

I see you read only one bit, and not both, as you said before. You can not check those two impossible situations 00 and 11 reading only one bit.

Even if you fix these isues, you will not be able to read properly.
If you use an quartz osccilator, and starting in a good phase, maybe have chances to read properly.
To be sure you not miss something, you need synchronisation in phase AND in frequency. This kind of transmission is worst than manchester or serial (232).

Gelu.

I didnt understand the AFSK decoder schematic very well. so the 01 10 11 00 is no longer valid.

its just a single bit at INT0.

and CTC, what is that and how do you use it?

as far as shifting out of phase, i dont know how to do it any other way. not smart enough i guess.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

UNiXWHoRe wrote:
Just a thought, but if you are decoding from audio make sure you use a file in fixed bitrate and no compression... Most audio compression schemes are lossy, and slight pitch changes can occur, leading to your bandpass filter discarding the signal partly for example if it is too strict... I can *hear* the pitch difference between the OGG-Vorbis compressed file on wikipedia and the WAV file posted above... I would use the WAV file as base if I was you... ;)

yea i converted the ogg over to 16 bit microsoft PCM mono wav.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But even then the losses occured in the original OGG conversion will stay present in the final PCM... Original recording would have to be PCM mono (or left channel from a stereo file) for a good source... Also if you are playing the audio through your sound card, make sure all EQ's are flat...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

techknight, here people sometimes have problem with USART. One concern is the quality of the RC osccilator, and many recomandations are to use an external quartz cristal. Remeber, it is about transmiting/reciving usualy eight bits of data, start and stop, so a total of 10 bits, cos after 10 bits, another synchronisation take place. In contrast, you try to handle 256 * 8 = 2048 bits using only one time synchronisation. I think you realise the difference.

I don't know how young / old you are, if you remember those old black and white TVs.
One of the problem sometime was with the vertical synchronisation. In time, the receptor lose the ability to synchronize the osccilator with the transmiting station signal. And I remember, I didn't understand at that time too much, but I took a screwdriver, and tryed to 'repair' the TV, adjusting the natural frequency of the osccilator turning a potentiometer left and right, thinking I will solve the problem. The image was either runing up or runing down.
Eh, you are now exactly in the same situation, trying to change the uC frequency, prescaler, timer0, etc. Will just not work.

Gelu.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

whelp i don't know any other way to do it. sorry.. guess i'm just not smart enough. theres NOTHING there to synchronize to except the preamble. I don't know how to sync a preamble. ive never done it before and i just don't know how. but after the preamb, you get data. and it could drift off that data and your screwed. no clock pulse to go by. it sucks. I am using an 8mhz crystal now with a timer0 prescaler of 64

no, i aint that old. hehe. im pretty young still. just out of my teens.

The wave file posted in this thread i cant get it to decode properly at all. the only thing i can get to decode is the ogg. no matter how much i change the timer0 compare timing, i cant get it right.

I either get D5s for my preamble, or i get 2As for my preamble.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

and when you point out whats wrong with my code earlier in the thread, you explained what the problem is, out of phase, etc, but you don't explain how to fix it. I cant magically figure out how to fix something that i don't understand well enough.

and you mention terms like CTC and stuff like that, I don't know what that means. hehe.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The only thing that i know how to do is maybe when the high bit comes in, trigger the interrupt, and start the timer. stop the timer when it goes back to zero. and record that value. thats the only way i know how to do it. but the thing that sucks is theres 2 1s at the beginning. instead of just 101010101

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What uC do you use ?

Gelu.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ATmega8 with 8mhz crystal.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The core of the program should be like this:

- set INT0 or 1 for pin change. Connect one of those two lines to the INT pin.
u can use on rising edge or falling edge, but wil loose half of synchronisation events.

- set TC0 for CTC (clear on compare - see data sheet)
- set OCR to 240 - the bit rate
- do not activate interrupts for TC0 yet

INT0 ISR:

if is the first INT0 event, set TCNT to 120 and activate TC OCR interrupt

if not:

if your last value was 01, read the port for example 20 times, and expect to have at least 12-15 readings of 10. If so, consider you just detected a new transition. If no, ignore the event.
the same, if your last value was 10, read the port for example 20 times, and expect to have at least 12-15 readings of 01. If so, consider you just detected a new transition. If no, ignore the event.
Don't update the data now.
In case of valid detection, read the timer. If the timer is greater than for example 80 or less than for example 160, just set TCNT to half (120). If not, hmm, will be a problem. You can play with these values (80 - 120)
Don't forget to clear INT0 flag just before to exit INT0 ISR.

OCR ISR:
just read the data and store it accordingly
after you finish reading all data, disable interrupts, or ignore the events.

Main program:

try first to catch the patern 0xAB in order to be synchronized at byte level, assuming in this moment you are synchronized at bit level.
The first INT0 event can be fake.
When you get something different than 0xAB, you can count the bytes.

Good luck.

Gelu.

Pages