[Top][All Lists]

## Re: [Discuss-gnuradio] CPM timing recovery

 From: Achilleas Anastasopoulos Subject: Re: [Discuss-gnuradio] CPM timing recovery Date: Tue, 05 Jun 2007 18:01:14 -0400 User-agent: Mozilla Thunderbird 1.0.2 (Windows/20050317)

```David,

```
one way to estimate the rate is to raise the CPM signal to an appropriate power in order to generate spectral lines that can be easily
```tracked.
```
The precise power is a function of the modulation index of your CPM modulation. Eg, if you are using full-response CPFSK with h=N/D (where N,D are relative primes) then you can raise your signal to the power D in order to generate spectral lines. I don't remember off the top off my head the exact frequency of these spectral lines but you can
```easily find out the relationship by simple experimentation.

BTW, are you using the cpm.py hierarchical block that is
on the trunk? If yes, I attach a simple python code that
demonstrates the spectral line generation for a 4-CPFSK
with h=1/2.

Achilleas
```
```#!/usr/bin/env python

from gnuradio import gr, gru, eng_notation, optfir
from gnuradio.wxgui import stdgui, fftsink, form
from optparse import OptionParser
from usrpm import usrp_dbid
import sys
import math
import wx
import random
import Numeric

class cpm_graph (stdgui.gui_flow_graph):
def __init__(self,frame,panel,vbox,argv):
stdgui.gui_flow_graph.__init__ (self,frame,panel,vbox,argv)

self.frame = frame
self.panel = panel

# TX
bit_rate = 10e3
bits_per_symbol=2;
samples_per_symbol = 8;
symbol_rate = bit_rate / bits_per_symbol
sample_rate = symbol_rate * samples_per_symbol

print bit_rate , symbol_rate , sample_rate

Kb = 102400
packet = [0]*Kb
for i in range(Kb):
packet[i] = random.randint(0, 1) # random bits
self.src = gr.vector_source_b(packet,True)

self.b2B = gr.unpacked_to_packed_bb(1,gr.GR_MSB_FIRST)

#self.mod_old = blks.gmsk_mod (self, samples_per_symbol,
bt=0.35,log=False )
self.mod_new = blks.cpm_mod (self,
samples_per_symbol=samples_per_symbol,
bits_per_symbol=bits_per_symbol,
h_numerator=1,
h_denominator=2,
cpm_type=0, # 0 = CPFSK
bt=0.35,
symbols_per_pulse=1,
#generic_taps=Numeric.ones(samples_per_symbol*1)/2.0,
verbose=True,
log=False)

self.nonl = gr.multiply_cc();

#self.fft_old = fftsink.fft_sink_c (self, panel, fft_size=512,
sample_rate=sample_rate,y_per_div=10,ref_level=0, fft_rate=5)
self.fft_new = fftsink.fft_sink_c (self, panel, fft_size=512,
sample_rate=sample_rate,y_per_div=4,ref_level=-10, fft_rate=5, average=True,
avg_alpha=0.01)
self.fft_new1 = fftsink.fft_sink_c (self, panel, fft_size=512,
sample_rate=sample_rate,y_per_div=4,ref_level=-10, fft_rate=5, average=True,
avg_alpha=0.01)

#self.connect (self.src,self.b2B,self.mod_old,self.fft_old)
#self.connect (self.b2B,self.mod_new,self.fft_new)
self.connect (self.src,self.b2B,self.mod_new,self.fft_new)
self.connect (self.mod_new,(self.nonl,0))
self.connect (self.mod_new,(self.nonl,1))
self.connect (self.nonl,self.fft_new1)

if __name__ == '__main__':
app = stdgui.stdapp (cpm_graph, "test CPM graph")
app.MainLoop ()
```