CW Transmitter



A real CW morse code ham transmitter is more than just the turning on and off of a carrier. You have to have shaping to limit the rise and fall times of the carrier or you will generate key-clicks and annoy other operators up and down the band. Here we generate a DC signal and key it with a hand-key wired to an I/O pin on the usrp. The keyed DC is run thru a lowpass fir_filter with a relatively low sampling rate (currently 50kS/s), mixed with an RF carrier (15Khz) and then an interpolating fir_filter to get a sampling rate suitable for the USRP (2MS/s).

2mS/div:


#!/usr/bin/env python
#

from gnuradio import gr
from gnuradio import usrp
from gnuradio import audio
import time
import sys

def build_graph (ampl):

    usrp_interp = 64
    usrp_duc = 7100e3
    sink = usrp.sink_c (0, usrp_interp)
    print "requesting: ", usrp_duc, "hz"
    sink.set_tx_freq(0, usrp_duc)
    actual_freq = sink.tx_freq(0)
    print "got ", actual_freq, "hz"
    df = sink.dac_freq()
    print "DAC Freq: ", df
    sink.set_nchannels(1)
    sink.set_mux(0x98)

    hi_sample_rate = 2000000
    sample_rate = 50000
    rf_lo = 19.4e3	# carrier point - 7100 + 15Khz, 40m novice cw
    rf_ampl = 10e3

    fg = gr.flow_graph ()


    dc_src = gr.sig_source_f(sample_rate,gr.GR_CONST_WAVE,1,1,0)
    key_mix = gr.multiply_const_ff(ampl)

    click_filter_coeffs = gr.firdes.low_pass (1,sample_rate,1e3,500,gr.firdes.WIN_HAMMING)
    click_filter = gr.fir_filter_fff(1,click_filter_coeffs)

    carrier = gr.sig_source_f(sample_rate,gr.GR_COS_WAVE,rf_lo,rf_ampl,0)
    carrier_mix = gr.multiply_ff()

    interp_filter_coeffs = gr.firdes.low_pass (1,hi_sample_rate,25e3,5e3,gr.firdes.WIN_HAMMING)
    interp_filter = gr.interp_fir_filter_fff(40,interp_filter_coeffs)

    hilbert = gr.hilbert_fc(197)

    fg.connect(dc_src, key_mix)
    fg.connect(key_mix, click_filter)
    fg.connect(click_filter, (carrier_mix,0))
    fg.connect(carrier, (carrier_mix, 1))
    fg.connect(carrier_mix, interp_filter)
    fg.connect(interp_filter, hilbert)
    fg.connect(hilbert, sink)

    return fg, key_mix, sink

def main ():

    ampl = 0
    fg = build_graph (ampl)
    ampl = 1
    fg[0].start ()


    while 1:
	fg[1].set_k((~fg[2].read_io(0)&1)*ampl)

if __name__ == '__main__':
    main ()