Papilio FM transmitter

Problem

edit

Transmitting signals is part of Software Defined Radio (SDR). The goal here is to build a simple FM transmitter using a Papilio and then explore what is possible from there. Perhaps change the pitch of the sound of the beeps as the signal is being transmitted.

Conceive

edit

This project is to take a previously done project with a spartan 6 lx9 *FM Transmitter and make it work on a spartan 3E XC3S250E. The software has modified to send an SOS signal using two different tones.

Design

edit

The idea is to build square pulses of different widths and then string them together to create a frequency. Two frequencies are necessary: tone 1, tone 2. If they are in the MHz region then an FM radio should be able to hear them if placed close to the radio. The carrier frequency selected by the radio will be subtracted from the frequency of the two tones to generate sound out of the speakers.

Implement

edit

The circuit was implemented using the following code which is a slightly modified version of the starting point code above. It produces an SOS type of signal in two different tones.

Modified FM Radio VHDL Code
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity fm_xmit is
    Port ( CLKIN_IN : in  STD_LOGIC;
           antenna : out  STD_LOGIC);
end fm_xmit;

architecture Behavioral of fm_xmit is
   component clocking
   port ( CLKIN_IN  : in  std_logic;
         CLKFX_OUT : out std_logic
   );
   end component;
   
	
   signal CLKFX_OUT            : std_logic;
   signal shift_ctr         : unsigned (4 downto 0) := (others => '0');
   signal phase_accumulator : unsigned (31 downto 0) := (others => '0');
   signal beep_counter      : unsigned (19 downto 0):= (others => '0');-- gives a 305Hz beep signal
   signal message           : std_logic_vector(33 downto 0) := "1010100011101110111000101010000000";
   signal pitch             : std_logic_vector(33 downto 0) :="1010100000000000000000101010000000";


begin
  antenna <= std_logic(phase_accumulator(31));
  
 fast_clock : clocking port map (
      CLKIN_IN => CLKIN_IN,
      CLKFX_OUT => CLKFX_OUT
   );  
  
   process(CLKFX_OUT)
   begin
      if rising_edge(CLKFX_OUT) then
         if beep_counter = x"FFFFF" then
            if shift_ctr = "00000" then
               message <= message(0) & message(33 downto 1);
               pitch   <= pitch(0) & pitch(33 downto 1);
				end if;
            shift_ctr <= shift_ctr + 1;
         end if;      
         
         -- The constants are calculated as (desired freq)/320Mhz*2^32
         if message(0) = '1' then
            if beep_counter(19) = '1' and pitch(0) ='0' then
               phase_accumulator <= phase_accumulator + 1222381325; -- gives a 91075kHz signal               
            else
               phase_accumulator <= phase_accumulator + 1220381325; -- gives 90925kHz signal
            end if;
         else 
            phase_accumulator <= phase_accumulator + 1221381325; -- gives 91000kHz signal
         end if;
         
         beep_counter <= beep_counter+1;
      end if;
   end process;
end Behavioral;

The radio is not a normal. A normal radio tunes at 89.9, 90.1, 90.3 but not in between. This radio tunes to all channels inbetween. This made it easier to find the optimum channel ... by searching. Can see that the demonstration video below that it was done at 91.2 MHz which is not a normal FM channel. It is exactly in the middle of two commercial broadcast FM channels: 91.1 and 91.3 MHz.

Demo

edit

video

Next Steps

edit
  • Do the math and figure out what 91.2 Mghz is the best carrier frequency of the two tones generated.
  • Build external circuit to create a band pass filter centered on 91.2 MHz within a 100KHz band.
  • Add the logicstart megawing and use the switches to switch to different frequencies, and display the frequencies being used on the LED's.