Im working on a Visible light communication project. Its a simplex transmitter receiver setup using an LED to send data to a photodiode receiver. Im thinking of ways to encode the data for transmission and was wondering how exactly i would implement a Frequency Modulation setup. I know the basic concept of FM but dont understand how the receiver perceives these shifts in frequency(wouldnt it take a few cycles of high/low to even calculate frequency, and if so wouldnt this be a limit to max bitrate). Ill be using an arduino board to interpret the received signal. How would I go about using FM to send data from an LED to a receiver and decodw that information?
There are several ways to detect FM.
Today, this is generally done with a PLL (phase-locked loop). It's a voltage-controlled oscillator in a feedback loop. Via feedback, the voltage into the voltage-controlled oscillator is adjusted so that its output matches the input signal. This control voltage is the FM-demodulated signal.
In past days, other techniques were used, like ratio detectors. If the carrier is slow enough, you can use digital techniques to outright measure the time between zero crossings, or the number of zero crossings in a particular interval. Think of a low-pass and high-pass filter adjusted so that they both attenuate the carrier frequency equally. Any change in the carrier frequency will cause a relative difference in the amplitudes. There are more methods. Look up "FM demodulation".
You seem to wish for a high bit rate, using a low carrier frequency, when you suggest that few cycles should encode each bit. One extreme form of FM (or frequency-shift-keying FSK) is Manchester encoding (see its wiki page). In this encoding scheme, one could say that one of two frequencies are possible:
- a string of "1's" encode to one cycle of the "carrier" per bit
- a string of "0's" encode to one cycle of the "carrier" per bit
- a string of alternating "010101..." encode to one-half cycle per bit.
This modulation scheme can also be described as a form of phase-shift-keying. It can be decoded by looking for and locking to a bit-transition (both positive and negative bit transitions should be equally lockable). At the beginning of a transmission, a string of "01010101..." is sent, allowing the receiver to find and lock onto those edges. A phase-locked loop is helpful to clean up noisy edges. A phase-locked loop also provides edge memory, where it anticipates the time span to the next lockable edge. It is possible to use your Arduino's timer function to implement an appropriate software locking loop, provided your serial bit rate is not too high (too involved to describe here).
Noise that can be interpreted as a bit transition will seriously disrupt decoding, so this method should not be used to extract a weak signal from noise. In this case, having many carrier cycles spanning each transmitted bit allows filtering to reduce errors caused by noise. Now you're into more classic "FM" or "PM".