PDA

View Full Version : FSK demodulator in firmware



HenrikOlsson
- 6th October 2025, 18:07
I have what looks to be a 1.6/3.2kHz FSK signal that I'd like to demodulate to a bitstream using a suitable PIC.
It's a two wire system with bursts of the FSK signal riding on top of the DC supply, so no carrier like with radio.

Never dealt with FSK signal before so asking if anyone has done anything like this using PBP?


I'm thinking of using the ZeroCrossingDetector peripheral together with a timer or two. Either just polling the ZCD Out bit and start/stop the timer(s) or possibly tie it in to the timer gate or go the interrupt route. Being such a low frequency signal I think polling will be more than adequate to get started.

The goal, for now, is "just" to get the signal into a digital bitstream that I can then capture with a logic analyzer. I know this is analog domain stuff, PLL's and such but when all you've got is a hammer (PBP in this case)....

Ioannis
- 6th October 2025, 18:48
Although it is a low frequency, still a zero cross happens every 156.2 usec for the 3.2KHz signal.

Will the pic be fast enough to process that signal? I am sure ZCD and timers will be enough, but then you have to do some work in less than that period.

Ioannis

HenrikOlsson
- 6th October 2025, 20:42
Plenty fast, I'd say.
At 32MHz an instruction cycle is 125ns. That's ~1250 cycles between zero crossings.

I'm not trying to interpret/decode the data, just demodulate the signal.
Every other zero crossing, grab timer value, do some comparison, flip a bit (or not), reset/restart timer. My gut feeling says we should be able to do that in less than 100 instructions - even with PBP compiled code but we'll see.

What's "bothering me" is the fact the line is idle for extended periods of time meaning there's no zero crossing and timer will overflow/wrap around. I'll need to detect that.

richard
- 7th October 2025, 00:01
there are some good ideas here
https://www.romanblack.com/DTMF/DTMF_alg.htm

HenrikOlsson
- 11th October 2025, 05:55
Thanks Richard,
I had actually read Romans article but, thankfully, my signal never shows two simultanouse tones - it's always one or the other which makes it easier.

I started with ZCD module but due to the nature of the signal I could not get reliable results (worked fine with waveform generator feeding it a symetric signal but I was unsucessfull in removing the DC-bias from the actual signal so had to abandon ZCD). Once again goes to show that simulations or even half-assed hardware tests doesn't (always) cut it.

Currently using a comparator with FVR at 2.048V to one input and the signal to the other. Comparator output drives TMR1 gate. TMR1 gate interrupt flag is used to signal "end of measurement". Pushing TMR1 values into an array, resetting TMR0 each time. When TMR0 overflows the line has been idle for 4ms which is my end of frame indicator.

/Henrik.

richard
- 11th October 2025, 06:35
i have zero experience with zcd module but reading the blurb it seems to bias the pin to about 0.7 ish volts. the signal is applied through a suitable R, so that when the signal goes negative the bias is removed and a crossing is detected. if your input never goes negative its not going to work afaics. the comparator is the next best choice. you also might be able to drive the timer gate directly through a voltage divider if the modulation is deep enough

HenrikOlsson
- 11th October 2025, 08:43
Yeah, never used ZCD before either, looked to be the perfect solution for this and a good excuse to play with it.

Problem with the ZCD and my signal is that the bus idles at 35VDC for "long" periods of time and swings +0/-6V from there, not +/-3V around 35VDC.

I figured I'd just slap a capacitor in series to remove the DC-bias and that did put "idle" at GND but then the resulting signal swings between GND and -6V instead of +/-3V so still no zero crossing. Adding a pullup outside of the series resistor sort of helped but made the zero crossing drift "upwards" during the "message". All in all it just didn't work relaibly.

Posted on EEVBlog on how to properly remove the DC-bias and was shot down in flames for selecting the ZCD for this application - which I guess was in order since it did in fact not work :-)

Comparator solution seems to work fine at the moment (these things now even has switchable hysteresis built in) but it has the drawback of being absolute level. For now it'll have to do, this is just an experiment at the moment.

Unfortunately I don't have the device providing the REAL signal so I kind of have to emulate/test as best as I can.

Thanks!

Ioannis
- 11th October 2025, 14:11
if you drive a voltage divider after the dc blocking capacitor? You will have a predefined dc level to consider as "0 volts" for the comparator I guess.

Ioannis

richard
- 12th October 2025, 02:20
looks feasible in simulations

9999

HenrikOlsson
- 12th October 2025, 15:07
Thanks Richard, appreciate the effort but (always a but)....

Problem with the ZCD and my signal is that the bus idles at 35VDC for "long" periods of time and swings +0/-6V from there, not +/-3V around 35VDC.
If I'm not reading the sim setup wrong (which I might) you have a +/-3V signal sitting on a DC-bias of 32V when, in reality, it is a +0/-6V signal sitting at that 32VDC bias (or 35 but it doesn't matter).

Try keeping that 32VDC bias but have the signal only swing down from there, and then make bursts, 25 cycles followed by 5 seconds of silence. What happens then?

Also, and I'm not sure this matters but I think so, it doesn't look like Protues is simulating the true behaviour of the ZCD-pin. If it did you wouldn't be able to measure a signal there (which looks to be Ch. C on the scope) because as long as you have the correct (enough) series impedance the ZCD-peripheral will drive the input pin to a voltage of zero. Weather the signal is above or below GND is determined by if the internal current source or current sink is active.

/Henrik.

richard
- 13th October 2025, 04:43
i'm guessing the signal is impressed on to the power line in a "balanced" phantom cailho style. i don't know how to simulate that or how to extract it properly either in any simple way with proteus .

it doesn't look like Protues is simulating the true behaviour of the ZCD-pin
entirely possible, i never fully trust that it is fully realistic. it does however look like the zcd would work with an unbalanced ac signal provided the offset and magnitude are adjusted suitably.
zcd is NOT particularly useful for your project since it cannot drive a timer gate directly or be a capture source

HenrikOlsson
- 13th October 2025, 05:36
zcd is NOT particularly useful for your project since it cannot drive a timer gate directly or be a capture source
Oh, but it can. I guess it might depend on the specific device but on the 18F57Q43 I happened to use it certainly could.

richard
- 13th October 2025, 05:48
more fully.
zcd is NOT particularly useful for this project since it cannot drive a timer gate directly or be a capture source for any of the pic chips that my crusty old version of proteus can simulate