Skip to content

Instantly share code, notes, and snippets.

@matthewpalmer
Created January 18, 2015 22:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matthewpalmer/3bd07172c07eb8fcdae5 to your computer and use it in GitHub Desktop.
Save matthewpalmer/3bd07172c07eb8fcdae5 to your computer and use it in GitHub Desktop.
import Data.Complex
import Data.List
import Foreign.Marshal.Array
import RTLSDR
import FFT
import Plot
import Spectrum
bufSize = 512
sampleRate = 1280000
frequency = 433420000 -- ~100 MHz
calibrationError = 0
main = do
getSignal frequency
getSignal frequency = do
dev <- open 0
case dev of
Nothing -> putStrLn "Error opening device"
Just dev -> do
setSampleRate dev sampleRate
setCenterFreq dev frequency
setTunerGainMode dev False
resetBuffer dev
allocaArray bufSize $ \ptr -> do
res <- readSync dev ptr bufSize
case res of
False -> putStrLn "Error reading from device"
True -> do
res <- peekArray bufSize ptr
let complexes = map fromIntegral res
coeffs = fft complexes
-- First entry in the FFT coefficients is always garbage for some reason
spectrum = Spectrum.computeSpectrum (tail coeffs) (fromIntegral sampleRate)
absoluteSpectrum = absolutivize (fromIntegral frequency + calibrationError) spectrum
f = length coeffs
ms = map Data.Complex.magnitude coeffs
cfreq <- getFreqCorrection dev
--case cfreq of
--Just cfreq -> do
print $ "center: " ++ (show cfreq)
--print res
--print spectrum
--Plot.plot (spectrum) ("Centre: " ++ (show frequency) ++ "Hz") (show frequency ++ "-r.png")
Plot.plot (absoluteSpectrum) ("Centre: " ++ (show frequency) ++ "Hz") (show frequency ++ "-a.png")
putStr $ (show frequency) ++ "\t"
print $ sum ms
--print spectrum
close dev
getSignal (frequency {-+ 100000-})
-- Convert the computed spectrum to one with an x axis relative to our input frequency
--relativize :: Double -> [(Double, Double)] -> [(Double, Double)]
--relativize center readings =
-- numReadings = fromIntegral(length readings)
-- intervalSize = (fst $ head $ tail readings) - (fst $ head readings)
-- middleFreq = readings !! (numReadings / 2)
absolutivize :: Double -> [(Double, Double)] -> [(Double, Double)]
absolutivize center readings = zip absoluteFrequencies magnitudes
where absoluteFrequencies = map (+ center) offsets
magnitudes = map snd readings
frequencies = map fst readings
middleFrequency = frequencies !! (fromIntegral(length frequencies) `div` 2)
offsets = map (\x -> (-) x middleFrequency) frequencies
{-
If we have a collection of pairs like
[(0.0,429.7772578325535),(2500.0,885.4309962413882),(5000.0,287.8264854491852)]
and suppose our center frequency is 108MHz.
First, split the frequencies from the magnitudes.
frequencies = map fst pairs
magnitudes = map snd pairs
We get our intervalSize by the difference between the 1st and 2nd frequencies.
intervalSize = (head $ tail frequencies) - (head frequencies)
The middle element in frequencies maps to our absolute center (108MHz).
middleValue = pairs !! (length pairs / 2)
Then convert each pair into a + or - relative value from the middleValue, e.g.
[0.0, 2500.0, 5000.0] => offsets = [-2500.0, 0.0, +2500.0]
Finally, add these +/- values to the center frequency
map (+centerFrequency) offsets
-}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment