Fm transmitter in software


65 posts   Page 1 of 3   1, 2, 3
by mikerr » Mon Dec 10, 2012 10:31 pm
This is really cool:

FM transmitter entirely in software:

http://www.icrobotics.co.uk/wiki/index. ... ransmitter

Just a Pi and a 20cm wire connected to a gpio pin.
Got a Pi Camera? View it in my android app - Raspicam Remote ! No software required on the pi
User avatar
Posts: 1231
Joined: Thu Jan 12, 2012 12:46 pm
Location: NorthWest, UK
by jackokring » Mon Dec 10, 2012 10:56 pm
Drum and base fans everywhere will replace a certain FM channel, which was good and went pants.
Pi=B256R0USB CL4SD8GB Raspbian Stock. https://sites.google.com/site/rubikcompression/strictly-long https://dl.dropboxusercontent.com/u/1615413/Own%20Work/Leptronics.pdf https://groups.google.com/forum/#!topic/comp.compression/t22ct_BKi9w
User avatar
Posts: 784
Joined: Tue Jul 31, 2012 8:27 am
Location: London, UK
by BrianW » Mon Dec 10, 2012 11:35 pm
I've just tried this out. I'm amazed that it works, but it does.

I was transmitting to my phone's FM receiver, only a few centimetres from the Pi. It didn't even need the aerial on GPIO4.

More than a metre or so away, another station on that frequency comes back. Given the likelihood of harmonics, it's perhaps best that the range is severely limited.
Posts: 77
Joined: Sun Jul 29, 2012 9:03 pm
by redhawk » Mon Dec 10, 2012 11:47 pm
It works but the range is pretty bad around 20cm not 100meters as indicated in that link.
Even my frequency counter with direct link was having a hard time locking onto the signal.

Richard S.
Last edited by redhawk on Mon Dec 10, 2012 11:52 pm, edited 1 time in total.
User avatar
Posts: 3519
Joined: Sun Mar 04, 2012 2:13 pm
Location: ::1
by ksangeelee » Mon Dec 10, 2012 11:51 pm
Brilliantly inventive.

So, a novel solution to the question 'what's my IP address?' - an FM radio broadcast. Perhaps followed by an contrived anecdote or an annoying jingle.
Posts: 193
Joined: Sun Dec 25, 2011 5:25 pm
Location: Edinburgh, UK
by redhawk » Tue Dec 11, 2012 12:30 am
Okay ignore my previous post I had the antenna connected to the wrong GPIO pin. :roll:

Image

I think this circuit exhibits some harmonic distortion my frequency counter was showing 300MHz to start with until I constructed a simple RF filter using an S18 toko coil and capacitor. :)

I wonder if the code could be modified to produce PSK encoded signals??

Richard S.
Last edited by redhawk on Tue Dec 11, 2012 12:37 am, edited 1 time in total.
User avatar
Posts: 3519
Joined: Sun Mar 04, 2012 2:13 pm
Location: ::1
by joan » Tue Dec 11, 2012 12:36 am
Interesting idea. How would it be used though? You can buy legal tuned 434MHz receiever/transmitter pairs for less than £4.
User avatar
Posts: 5708
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK
by mikerr » Tue Dec 11, 2012 10:05 am
ksangeelee wrote:Brilliantly inventive.

So, a novel solution to the question 'what's my IP address?' - an FM radio broadcast. Perhaps followed by an contrived anecdote or an annoying jingle.


Have your Pi continuously speak kernel log messages on its own FM station, just by piping log into text2speech (e.g. festival)
Got a Pi Camera? View it in my android app - Raspicam Remote ! No software required on the pi
User avatar
Posts: 1231
Joined: Thu Jan 12, 2012 12:46 pm
Location: NorthWest, UK
by JonnyBoats » Tue Dec 11, 2012 8:20 pm
Obviously this works for a frequency of 100 MHz. Has anyone tried other frequencies? I am curious what frequency range works.
Posts: 4
Joined: Tue Dec 11, 2012 6:46 am
by redhawk » Tue Dec 11, 2012 8:57 pm
The C source won't compile: gcc -lm -std=c99 pifm.c as instructed in fact it shows no error message at all (using Rasbian Wheezy).

Any here know what's wrong??

Richard S.
User avatar
Posts: 3519
Joined: Sun Mar 04, 2012 2:13 pm
Location: ::1
by joan » Tue Dec 11, 2012 9:13 pm
Compiles/links OK for me. Default executable is in a.out.
User avatar
Posts: 5708
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK
by CurlyNinja_ » Tue Dec 11, 2012 10:02 pm
I cannot seem to transmit audio, the radio just goes silent when I run the script?
Posts: 1
Joined: Tue Dec 11, 2012 10:00 pm
by redhawk » Tue Dec 11, 2012 10:13 pm
I messed up the source code that's why it wasn't compiling. :lol:
I set the frequency output to 99MHz as stated in the documentation using the value of 0x50CF (just how this equates to 5.050505 decimal I'm still a little bit puzzled).

Sadly the results were very disappointing, while it did in fact transmit on 99MHz there was massive harmonic distortion throughout the FM / Airband: (79, 84, 89, 94, 99, 104, 107.5, 109, 114, 119, 124.1, 129.1)MHz
For some reason the PI seems to work best at 100MHz with very little harmonic distortion unfortunately this classes with Classic FM already transmitting on 100.1MHz

I'm going to experiment with different frequencies and see which works best I’m not happy that the PI could leak audio broadcasts into the FM Airband region.

Richard S.
User avatar
Posts: 3519
Joined: Sun Mar 04, 2012 2:13 pm
Location: ::1
by redhawk » Tue Dec 11, 2012 11:53 pm
As far as I can tell the FM transmitter only works best if 500MHz is divided by a whole integer number if you divide by fractions this causes serious harmonic distortions.
I suspect that this is the result of timing instabilities but I cannot be certain, perhaps someone with in-depth knowledge of the PI hardware could explain it away.
In a nutshell there are only a few stable frequencies to choose from: 71.4, 83.4, 100 and 125MHz which are more or less inaccessible without a multi-band or modded FM radio.

Personally I'm sticking with my trusty USB FM transmitter dongle at least it can tune between 76 and 108MHz and in perfect stereo.

Richard S.
User avatar
Posts: 3519
Joined: Sun Mar 04, 2012 2:13 pm
Location: ::1
by BrianW » Wed Dec 12, 2012 12:15 pm
redhawk wrote:using the value of 0x50CF (just how this equates to 5.050505 decimal I'm still a little bit puzzled).
Essentially, it's 0x5000 divided by 0x1000. The last three digits are the fractional value. Just like if you divided 5050 by 1000, you'd get 5 and 50 thousandths (5.050), by dividing 0x50cf by 0x1000, you get 5 and 207 four-thousand-and-ninety-sixths:

5+207/4096 = 5.05053

If you have 'bc' on your Pi, it's easy enough to calculate
Code: Select all
scale=5
ibase=16
50CF/1000
5.05053
It's not quite 5.050505, but it's as close as you can get. 500/(5+207/4096) = 98.999MHz
Posts: 77
Joined: Sun Jul 29, 2012 9:03 pm
by dom » Wed Dec 12, 2012 12:52 pm
redhawk wrote:As far as I can tell the FM transmitter only works best if 500MHz is divided by a whole integer number if you divide by fractions this causes serious harmonic distortions.
I suspect that this is the result of timing instabilities but I cannot be certain, perhaps someone with in-depth knowledge of the PI hardware could explain it away.
In a nutshell there are only a few stable frequencies to choose from: 71.4, 83.4, 100 and 125MHz which are more or less inaccessible without a multi-band or modded FM radio.

Personally I'm sticking with my trusty USB FM transmitter dongle at least it can tune between 76 and 108MHz and in perfect stereo.

Richard S.


You could play with the MASH bits. E.g. change:
struct GPCTL setupword = {6/*SRC*/, 1, 0, 0, 0, 1,0x5a};
to
struct GPCTL setupword = {6/*SRC*/, 1, 0, 0, 0, 3,0x5a};
(valid settings are 0,1,2,3 and I believe 3 adds more noise to the fractional divide, so spreading the harmonics)
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4032
Joined: Wed Aug 17, 2011 7:41 pm
Location: Cambridge
by Yggdrasil » Wed Dec 12, 2012 2:19 pm
Just a note to the wave files: I has to use bitrate 22050, not 44100, to generate some other playable files. I.E.
Code: Select all
sox "$1" -c 1 -r 22050 "$2"


A really nice project! The quality is low, but probably I need a better antenna to gain some quality improvements.
Posts: 132
Joined: Sun Aug 26, 2012 8:45 pm
by Danbert » Thu Dec 13, 2012 2:18 pm
dom wrote:You could play with the MASH bits. E.g. change:
struct GPCTL setupword = {6/*SRC*/, 1, 0, 0, 0, 1,0x5a};
to
struct GPCTL setupword = {6/*SRC*/, 1, 0, 0, 0, 3,0x5a};
(valid settings are 0,1,2,3 and I believe 3 adds more noise to the fractional divide, so spreading the harmonics)


Dom:
The data sheet says about the MASH module that the "user must ensure that the module is not exposed to frequencies higher than 25MHz"

Have I misunderstood, or would using MASH on frequencies of around 100MHz be a Bad Thing?
Posts: 17
Joined: Mon Dec 05, 2011 2:52 pm
by dom » Thu Dec 13, 2012 4:28 pm
Danbert wrote:The data sheet says about the MASH module that the "user must ensure that the module is not exposed to frequencies higher than 25MHz"

Have I misunderstood, or would using MASH on frequencies of around 100MHz be a Bad Thing?


Spoken to Terry who designed the clock manager (and is quite impressed with this):

"Ok, there is no 25MHz limit, I don't know where that has come from.

They are getting a 500MHz clock from the PLL. That is the clock input to the MASH divider. The MASH divider can actually run at 750MHz, such is the genius of its design :)

BTW we only have MASH on the clocks on the clocks controlled by the CM_GP0CTL, CM_GP1CTL, CM_PWMCTL, CM_PCMCTL, PM_SLIMCTL. I assume they are using GP0 or GP1.

The divisor can be set to 2.000 - 4095.999 (actually it is 12 bit integer and 12 bit fractional part) so I don't understand why they say the divided clock is limited to 100.025 - 99.975.

The output of the MASH divider is designed to run at 125MHz. We spec the PWM & PCM to be max 25MHz but they are actually designed for 125MHz. I mention this because it is the only place we have a 25MHz spec. I doubt they are actually using PWM or PCM."

So. Enabling MASH=3 on a ~100MHz clock should be fine.
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4032
Joined: Wed Aug 17, 2011 7:41 pm
Location: Cambridge
by Danbert » Thu Dec 13, 2012 5:36 pm
Hi Dom,
That's great news, thank you!

dom wrote:The divisor can be set to 2.000 - 4095.999 (actually it is 12 bit integer and 12 bit fractional part) so I don't understand why they say the divided clock is limited to 100.025 - 99.975.

This is the FM deviation which their code applies to the audio - an audio frame with the maximum value will be modulated at 100.025MHz and an audio frame with the minimum value will be modulated at 99.975MHz.

Is there any way to check what the PLL is set to from software? I want to adapt this code to work in the amateur radio bands, but don't want it to be transmitting out of band if somebody has over/underclocked their Pi.

Dan
Posts: 17
Joined: Mon Dec 05, 2011 2:52 pm
by redhawk » Thu Dec 13, 2012 6:02 pm
Would it be possible modify the code to take more than one argument something like $1 = frequency and $2 = wav file name.
I find it really tedious to have to keep editing the source, compiling the source and then executing it every time I want to test a different frequency offset.

Also once the transmitter is activated how can it be turned off??

Richard S.
User avatar
Posts: 3519
Joined: Sun Mar 04, 2012 2:13 pm
Location: ::1
by Danbert » Fri Dec 14, 2012 11:10 am
redhawk wrote:Would it be possible modify the code to take more than one argument something like $1 = frequency and $2 = wav file name.


In main(), do something like:
Code: Select all
      #define PLLDFREQ 500000000
      int freq = atoi(argv[1]);   // Convert the first argument from a string to an int
      float divisor = (float)PLLDFREQ/freq;
      int divisor_code = divisor * (1 << 12);  // The lower 12 bits of the divisor register are the fractional part

and a few other changes (the filename is now in argv[2] and you'll have to pass divisor_code as a parameter to modulate()) should be a good start.

Also once the transmitter is activated how can it be turned off??


If I've understood the datasheet right, clear the enable bit which you should be able to do by doing:
Code: Select all
void tx_off()
{
    CLRBIT(CM_GP0CTL, 4);
}


I've not tested either of these changes yet so I might be wrong.

Dan
Posts: 17
Joined: Mon Dec 05, 2011 2:52 pm
by dom » Fri Dec 14, 2012 11:37 am
Danbert wrote:Hi Dom,Is there any way to check what the PLL is set to from software? I want to adapt this code to work in the amateur radio bands, but don't want it to be transmitting out of band if somebody has over/underclocked their Pi.

PLLD is always 500MHz, whatever overclock settings are used (overlocking changes PLLC).
(Actually PLLD is 2GHz, but there is a initial divide by 4 present, before the fractional divisor).
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4032
Joined: Wed Aug 17, 2011 7:41 pm
Location: Cambridge
by rgh » Sun Dec 16, 2012 6:07 pm
Here's a version I've written that uses DMA and so improves quality and reduces CPU use from 100% to about 1.6% :-)

I'm pasting this text from the source so people don't blame me if it eats their Pi:

* NOTE: THIS CODE MAY WELL CRASH YOUR PI, TRASH YOUR FILE SYSTEMS, AND
* POTENTIALLY EVEN DAMAGE YOUR HARDWARE. THIS IS BECAUSE IT STARTS UP THE DMA
* CONTROLLER USING MEMORY OWNED BY A USER PROCESS. IF THAT USER PROCESS EXITS
* WITHOUT STOPPING THE DMA CONTROLLER, ALL HELL COULD BREAK LOOSE AS THE
* MEMORY GETS REALLOCATED TO OTHER PROCESSES WHILE THE DMA CONTROLLER IS STILL
* USING IT. I HAVE ATTEMPTED TO MINIMISE ANY RISK BY CATCHING SIGNALS AND
* RESETTING THE DMA CONTROLLER BEFORE EXITING, BUT YOU HAVE BEEN WARNED. I
* ACCEPT NO LIABILITY OR RESPONSIBILITY FOR ANYTHING THAT HAPPENS AS A RESULT
* OF YOU RUNNING THIS CODE. IF IT BREAKS, YOU GET TO KEEP ALL THE PIECES.


Richard
Attachments
PiFmDma-20121216.tgz
(4.92 KiB) Downloaded 584 times
Posts: 220
Joined: Fri Nov 25, 2011 3:53 pm
by joan » Sun Dec 16, 2012 6:16 pm
Excellent work!
User avatar
Posts: 5708
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK