Teensy Convolution SDR (Software Defined Radio)

Hi,

I would like to share a modular PCB made by EA7GIB for the great Franz's TeensySDR based on the ready made ADC and DAC modules. There are a QSD+filter PCB and a R820T2, MSI001/MSI2500 aditional pcbs being tested atm too.

Source code:

MSI001 TeensySDR fork source code version (uses soft spi port at pins 1,2,3 to control msi001 ... it might be merged with main source soon): https://github.com/gmtii/teensySDR
MSI001 breakout PCB Kicad sources for TeensySDR https://github.com/gmtii/Prototipo-MSI001
R820T2+Si5351 version: https://github.com/gmtii/Prototipo-R820T2

Frontend TeensySDR modular pcb gerbers: https://github.com/gmtii/TeensySDR_PCB/raw/master/FRONTAL_TEENSY.zip


EYvTNnGXgAE5UGC.jpg
1cc3fdfa-8bac-49b5-8f21-fc566e2459ae.jpg
ef99af62-868f-4970-847a-df3a93e9a39b.jpg
0c644886-0f54-410e-9ede-cd83abfa7673.jpg
8f7c4bac-ac1c-4cbf-bd3e-a53b8f174b35.jpg

Back PCB QSD+si5351 + 4 switched BPF from 0 to 30 mhz.

0c04fc78-4b23-4a34-ace4-05e1ae427119.jpg
3201aaf4-f6ef-4d7d-a08e-4bc2364566cd.jpg
028fa14d-18cc-4b75-9d9d-0decfa288764.jpg

MSI001 PCB breakouts:

ae8a2037-b399-4607-b648-da70b96b542e.jpg
e3250cb5-5ce9-4851-8bc5-c19debedf796.jpg

Some videos: https://twitter.com/ea7gib

Best regards.
 
Last edited:
Hi Esteban,

that looks really great! And it will be a great help for anyone trying to build a Teensy Convolution SDR (or any other QSD-based SDR).

I am really curious about the Msi001 performance and would love to build an SDR based on that chip. However, I have not yet understood which version you have built/tested and whether the version with the built-in ADC/USB adapter (Msi2500) is already running with Teensy 4.0 or whether it is intended for a different application. (Not to speak about the interesting RT820T2 ;-))

Could you explain a little more how these different options work and which of them you have tested / plan to test with Teensy 4.0 ?

73 de Frank DD4WH
 
Hello all together,

But for me it is not really clear yet if this is the right way for the SNR indicator implementation.
I will be very grateful for some tips and hints :).
Hi Tisho
What exactly are you trying to measure? SNR depends on the bandwidth of the signal so is a different calculation for NFM, SSB, AM, WFM etc.
 
Hi WH7U,

I came to the same conclusion after some reading :)
Afterwords I got the idea to work around the Calculatedbm() function.
If I understand it correct there the half of the work is done (based on the bandwidth, gain and the attenuation the "signal level" is determined), what is left it is to determine the "noise level".
To keep is simple what I did was to determine the size of the actual passband. Based on this size I sum half of this size just before the pasband and half after the passband.
For example my actual bandwidth it is from 3MHz to 3,005Mhz (passband 5kHz, half it is 2.5kHz ), there as usual it is calculated the actual dBm.
From 2,9975MHz to 3MHz (2,5kHz) and from 3,005 to 3,0075 (2,5kHz) I do sum all FFT_spec_old[c]. This sum later on I use to calculate the "noise floor"

And on the end I do: SNR = Signal - Noise

Here is basicaly what i did (hopefully more understandable:) )
Code:
//Preparation for SNR - Tisho
  float signal_db_raw=0;
  float noise_db_raw;
  float signal_db=0;
  float noise_db=0;
  float static snr_old;

  int SNR_SignalRange = (int)Ubin-(int)Lbin;        // what is the actual signal range (pasband) in bin
  int SNR_Noise_L_range = Lbin-SNR_SignalRange/2;   //half of the signal range (in bin) before the pasband
  int SNR_Noise_H_range = Ubin+SNR_SignalRange/2;   //half of the signal range (in bin) after the pasband
  
   for (int c = SNR_Noise_L_range; c <= (int)Lbin-1; c++)   // sum up the values for noise floor measurment of all bins before the pasband
      noise_db_raw = noise_db_raw + FFT_spec_old[c];
       
   for (int c = (int)Ubin+1; c <= SNR_Noise_H_range; c++)   // sum up the values for noise floor measurment of all bins after the pasband
      noise_db_raw = noise_db_raw + FFT_spec_old[c];
//Calculate SNR Tisho
  signal_db = dbm;      //as signal level use alredy calculated dbm
  noise_db = dbm_calibration + bands[current_band].gainCorrection + (float32_t)RF_attenuation + slope * log10f_fast(noise_db_raw) +       //for the noise level calculate the same way as dbm
  cons - (float32_t)bands[current_band].RFgain * 1.5;                                                               //just out of the pasband (the same amount of bins)

  snr = snr_old + ((signal_db - noise_db) - snr_old)/6;     //LPF filter SNR 
  if(snr < 0)
    snr = 0;
  snr_old = snr;

Any improvement proposals are welcomed :)
 
Hi Tisho,
What you can do in a simple S/N calculation is to take the signal in the passband, say the signal you are interested in is at 1MHz and is 1 kHz wide. Add all the FFT bins from .9995 MHz to 1.0005 MHz and divide by the number of bins; this is your "signal" level. Then look next to your signal (hopefully no other signal is there). Say look between 1.001 MHz and 1.002 MHz and add those bins (and divide by the number of bins) and this is your "noise" level. The ratio between those two numbers is the SNR of that received signal. The problem is that there may be another signal in the 1.001 MHz to 1.002 MHz location.
I think this is what you were trying to say above but you are looking on both sides of the signal. That works too but gives you twice the chance of catching a signal that you don't want. And this is why you divide by the number of FFT bins - it lets you use a different number of bins for your signal and your noise and still get a correct ratio. But I would put a little space between the signal and the noise because the signal will splatter over into the adjacent space in the FFT due to windowing effects.
In the FM broadcast band, this calculation is easier because you know where all the stations are located. You can do an FFT of all the station locations, and take the lowest number and use that as your noise measurement.
In a band like one of the ham bands there are signals randomly all over the place. So if you are looking at 5 kHz wide signals, just chop the band (or a portion of the band) into 5 kHz segments, add the bins in each segment, then find the one with the lowest sum and use this as your noise. This technique works pretty well even if the band is fairly crowded. There is usually one 5 kHz segment that is empty.
Hope this helps.
Bill
 
Hi Frank,

Measured sensitivity is about -110 dbm@7.2mhz. Will measure other frequences asap. I honestly think it works much better than a QSD and as bonus it has the expanded receive range.

Sorry for the confusion...We made a simple breakout msi001 pcb and a experimental versión with a msi2500, so one could use the board with teensySDR or attached to a PC.

Anyway, next pic will be the 'final' version: msi001 with separate inputs for every band and different antennas... rf switching and one antenna port is planned for the next revision.

8bdc5505-39a5-413b-a880-5f78427d37e2.jpg

The source code has to be modified to:

- The frequency is direct and not multiplied by the QSD factor, e.g. 4x. Then all the tuning functions, frequency ranges, bands, etc. have to be modified.
- The msi001 handling functions have been put into separate files: msi001.ino and msi001.h
- msi001 is controlled by SPI port; A software SPI port needs to be enabled. In the code I have used pins 1,2,3 for the cs, clk and dat signals.
- Menu 1 has been modified to add 4 functions that control the gain of the tuner, IF, mixer and LNA for V / UHF. By the way, it would be very interesting to use the msi001's gain with the TeensySDR's gain function.

I'll be glad to send a msi001 pcb to you :D.

Regards,

Esteban EA8DGL.

Hi Esteban,

that looks really great! And it will be a great help for anyone trying to build a Teensy Convolution SDR (or any other QSD-based SDR).

I am really curious about the Msi001 performance and would love to build an SDR based on that chip. However, I have not yet understood which version you have built/tested and whether the version with the built-in ADC/USB adapter (Msi2500) is already running with Teensy 4.0 or whether it is intended for a different application. (Not to speak about the interesting RT820T2 ;-))

Could you explain a little more how these different options work and which of them you have tested / plan to test with Teensy 4.0 ?

73 de Frank DD4WH
 
Last edited:
Hi Les,
I determined that the 100nF capacities on the output of the mixer need to be replaced with 5nF capacitors for WFM. It looks like they should be 50nF for narrow modes also -I still need to model this to be sure of the values. I can probably do this today. And the output transformers need to be removed. I am planning to build a little audio amp to add because the output level of the QRP board is low but I am using a loop antenna so it may be okay with a larger antenna.
There is a decision here because very low RF frequencies could overlap with WFM baseband audio. If you want WFM you may need to give up receiver frequencies down at the extreme low end. And I am not sure about the filter in the ADC. I have on my list to look at the code and see what the LPF frequency is. With opening up the receiver audio bandwidth we need to make sure there is a low pass filter on the output of the receiver or input of the ADC or there will be alias problems. I expect that this is built into the DAC but I haven’t checked. You probably know.
I am working on putting my radio back together in a more permanent form with some shielding and power supply conditioning to try and get the ADC audio input noise down as low as possible. I expect we can use all the bits of the ADC with careful construction and shielding.
 
Here is a frequency sweep with 5 nF capacitors replacing the 100 nF capacitors C3, C4, C5, and C6. The sweep is from 0 to 250 kHz. I think this is about the right value for WFM reception with the QRP Labs receiver.
0-250kHz_5nF.png
 
Last edited:
And here is a frequency sweep from 0 to 500 Hz with the 5 nF capacitors. This shows that the low frequency audio still goes down below 100 Hz.
View attachment 20438

So this shows that the 5 nF capacitors will work fine for WFM. The transformers TR1 and TR2 will also need to be removed and the I and Q signals can be taken off of C1 and C2 respectively. Otherwise, the QRP Labs receiver is all set for WFM reception. I have not tried it yet.
 
Last edited:
It looks like they should be 50 nF for narrow modes also -I still need to model this to be sure of the values.
I was wrong about this. The 100 nF capacitors are fine for the narrow modes. The frequency response is fine out past 5 kHz. Attached is a plot from 0 to 5 kHz with 100 nF capacitors.
View attachment 20439
 
Hi Frank,

Measured sensitivity is about -110 dbm@7.2mhz. Will measure other frequences asap. I honestly think it works much better than a QSD and as bonus it has the expanded receive range.

Sorry for the confusion...We made a simple breakout msi001 pcb and a experimental versión with a msi2500, so one could use the board with teensySDR or attached to a PC.

Anyway, next pic will be the 'final' version: msi001 with separate inputs for every band and different antennas... rf switching and one antenna port is planned for the next revision.

View attachment 20366

The source code has to be modified to:

- The frequency is direct and not multiplied by the QSD factor, e.g. 4x. Then all the tuning functions, frequency ranges, bands, etc. have to be modified.
- The msi001 handling functions have been put into separate files: msi001.ino and msi001.h
- msi001 is controlled by SPI port; A software SPI port needs to be enabled. In the code I have used pins 1,2,3 for the cs, clk and dat signals.
- Menu 1 has been modified to add 4 functions that control the gain of the tuner, IF, mixer and LNA for V / UHF. By the way, it would be very interesting to use the msi001's gain with the TeensySDR's gain function.

I'll be glad to send a msi001 pcb to you :D.

Regards,

Esteban EA8DGL.

Hi Esteban,

thanks for the information!

How did you measure sensitivity? And which bandwidth/demodulator did you use? Standard sensitivity measures are usually made in SSB with very narrow 500Hz bandwidth. If I adjust my bandwidth to this figure, I get about 128dBm on the display with antenna input connected to 50 Ohms with my conventional Teensy QSD-based Convolution SDR.

The PCB looks great and does not seem to have too many components. Yes, I would be very interested, I will send you a PM.

The changes in the software do not sound too complex and I would be willing to integrate them into the Software, if you allow. A pull request would be most comfortable ;-).

Yes, that should be quite easy to use the RF gain setting in the menu to allow setting the gain in the MSI001.

Sounds very exciting!

All the best,

Frank
 
Hi WH7U,

very interesting simulations and figures! However, I do not understand your scaling of the axes very well. Is the y-axis linearly scaled? Would be good to see a dB scale. And x-axis is frequency in MHz? But why did you only show the part from zero to 25kHz?

There is also a formula to calculate the -3dB-bandwidth established by Youngblood 2002 in his seminal paper series. [it is eq8 in paper 1]

https://github.com/DD4WH/Teensy-ConvolutionSDR/wiki/Links-&-Resources

BW = 1 / (PI * 4 * 50 Ohms * Cs) [four times 50 Ohms, because each sampling cap samples one quarter of the duty cycle into 50 Ohms of input impedance]

Cs is the value of the sampling capacitors that you use. [I use 10^-9 for nano]

So, for

Cs == 100nF --> BW = 15.9kHz

Cs == 4.7nF --> BW = 338.6kHz

Cs == 10.0nF --> BW = 159.1kHz

This is the -3dB-bandwidth, so voltage will have fallen to 50% below that frequency. So, I see some discrepancies comparing with your figures. But maybe my equation is wrong, or I misinterpreted the 4 * 50 Ohms?

All the best 73s,

Frank DD4WH
 
Hi WH7U, thanks for the exhaustive answer on the capacitors for the receiver board. Once my receiver board turns up, will try to values you're suggesting and report back.
br, Les.
 
Ok, maybe Nyquist plays no role here... I/Q are not signals as usual.

Nyquist always plays a role ;-).
We are using two ADCs with 256ksps each and we digitize I AND Q, so the resulting bandwidth is 2 x Nyquist == 256kHz bandwidth.

That is the reason why we can display a full 256kHz spectrum with two ADCs running @256ksps each.

@Les, @WH7U: there is one thing to remember: we are using an IF frequency in the digital domain, which is equal to one quarter of the sampling frequency of the ADC.

So, if you use 96ksps sample rate, the IF is 24kHz (the audio baseband is at the IF, NOT at the baseband of the displayed spectrum). And you have to add your desired audio bandwidth to that. So, the QSD should be able to pass a bandwidth of about 30kHz without loss, if you are searching for the ideal QSD detector bandwidth and the ideal sampling cap values.

For other sample rates you use, you can easily calculate your desired QSD bandwidth, if you account for the IF at one quarter of the sample rate.

However, for WFM demodulation, it is different: there we choose the baseband signal and demodulate FM directly without an IF.
 
Got my own board working... it collected dust for some month.
I had the Elektor-Board so far. Oh my.. what a difference! Did'nt know how much better a front-end can be :)
(I'm new to this stuff)

It took some time (and patches....)
20200603_204118.jpg
It uses a Breakout-board for the SI5351, a Potatoe 7474, Potatoe 3253, 2 x INA163, 4.7nF I/Q capacitors, 0.8mm PCB, 12V from a rechargable battery.

I'm still waiting for delivery of an other transformator.

I'll do a new board revision to get rid of the pacthes in the next weeks.
 
Hi WH7U,

very interesting simulations and figures! However, I do not understand your scaling of the axes very well. Is the y-axis linearly scaled? Would be good to see a dB scale. And x-axis is frequency in MHz? But why did you only show the part from zero to 25kHz?

There is also a formula to calculate the -3dB-bandwidth established by Youngblood 2002 in his seminal paper series. [it is eq8 in paper 1]

https://github.com/DD4WH/Teensy-ConvolutionSDR/wiki/Links-&-Resources

BW = 1 / (PI * 4 * 50 Ohms * Cs) [four times 50 Ohms, because each sampling cap samples one quarter of the duty cycle into 50 Ohms of input impedance]

Cs is the value of the sampling capacitors that you use. [I use 10^-9 for nano]

So, for

Cs == 100nF --> BW = 15.9kHz

Cs == 4.7nF --> BW = 338.6kHz

Cs == 10.0nF --> BW = 159.1kHz

This is the -3dB-bandwidth, so voltage will have fallen to 50% below that frequency. So, I see some discrepancies comparing with your figures. But maybe my equation is wrong, or I misinterpreted the 4 * 50 Ohms?

All the best 73s,

Frank DD4WH

I did a bad job of explaining those figures. They were fairly quick and dirty - I was just trying to determine the right capacitors for the audio response. The y-axis is amplitude in volts at the audio output port (I and Q) and the x-axis is time in seconds. I did a frequency sweep from 0 to some value. I did this by feeding a 4 MHz signal into the local oscillator (LO) port and a 20mV sweep into the antenna port. The sweep went from 1 MHz to 1 MHz plus whatever I said in the plot - say 250 kHz. So the sweep went from 1 MHz to 1.250 MHz in this case.
Knowing the frequency is tough when on a time plot, so I plotted a number of milliseconds that was similar to the frequency of the linear sweep. This way, say at 0.025 seconds you can sort of figure that the end of the plot is a baseband (audio) frequency of 250 kHz and at 0.01 seconds, that is where the sweep was 100 kHz. I can redo them with actual units that make more sense if it helps.
I was not aware of those formulas (I admit to not having read any of the reference material). I am an electronics engineer so know only enough to be dangerous here. I understand filters and Fourier transforms and DSP and what not and am using this project to learn about SDRs and all this cool stuff you guys are doing.
The plots should not be taken as gospel. Your formulas look dead-on. I was looking for less than 3 dB at the upper frequency. This is a very simple model whose purpose was to determine the right value for the caps. The reason that my results differ is likely that I included the input transformer and the op-amps etc. As the old saying goes "all models are wrong, but some are useful". I didn't spend the time to make sure the transformer resistance was exactly right. I did put the correct specs in for the op-amps though. Anyhow, there is room for improvement but I was only trying to figure out the frequency response of the audio. I also wanted to confirm that if I changed the capacitors from 100 nF to 5 nF that I wouldn't sacrifice reception at 136 kHz which I want to experiment with (it still works great at that frequency).
I don't understand your 2X Nyquist explanation. All ADCs will alias if there is an input signal greater than 1/2 the sample rate. They still work fine, they just have all sorts of artifacts in the digitized signal.
And I was not aware of the IF frequency. That improves performance quite a bit due to eliminating the 1/f^2 noise in direct conversion. I need to dig through your code and understand better what is going on before I start making bold statements.
I will attach a snapshot of the model so you can see what parts are included. Like I said, it is pretty quick and dirty.
QRPLabsModel.jpg
73,
Bill
 
Got my own board working... it collected dust for some month.
I had the Elektor-Board so far. Oh my.. what a difference! Did'nt know how much better a front-end can be :)
(I'm new to this stuff)

Congratulations Frank! That is a nice looking board. It is ALL about the front end when you are talking about receiver performance. But then you have to have all the cool filters and decoders to make use of it. Did you make that board? It looks like you have a bunch of filters on it down at the bottom.

Bill
 
The main circuitry is very similar to that used in the SDR-1000.

These are empty solder pads, which are actually intended for filters.
But I chose the wrong size, the filters probably cannot be realized in this size. This will have to wait until the 2nd revision. ;)
 
I was not aware of those formulas (I admit to not having read any of the reference material). [...]
I don't understand your 2X Nyquist explanation. All ADCs will alias if there is an input signal greater than 1/2 the sample rate. They still work fine, they just have all sorts of artifacts in the digitized signal.
I have to read a lot, because as a biologist many of this electronics / DSP stuff only becomes clear to me by reading the references :).

As far as I understand it, by using one ADC for the I signal and another ADC for the Q signal [as an example both use 256ksps sample rate], we have 128kHz of alias-free bandwidth on the positive side of the frequency spectrum and 128kHz of alias-free bandwidth on the negative frequency spectrum, because we have complex signals here. So, in total, if we put together the negative and positive part of the spectrum for the spectrum display, this gives in total 256kHz of alias-free bandwidth, although we are using 256ksps sample rate. Not sure whether that makes sense ;-). I also have a reference for this: https://www.dsprelated.com/showarticle/192.php [scroll down to "quadrature-sampling scheme", under figure 18]

Oh, and if you are interested in very low receive frequencies, I can confirm that I have received CW signals of the famous SAQ alternator from Sweden on 17.2kHz VLF with my QSD frontend.
The input transformer will probably be the limiting part for reception on VLF, use a lot of ferrite :). I have 73 ferrite as the transformer core material, 43 is probably not that good at low frequencies.
 
Last edited:
Got my own board working... it collected dust for some month.
I had the Elektor-Board so far. Oh my.. what a difference! Did'nt know how much better a front-end can be :)

Congratulations! Very nice!

I think the filters can be built with SMD components. Use good (and expensive) NP0 capacitors.
The coils are more critical, those with high Q are bigger and cost more . . . Bob Larkin made some very good sugestions for that [http://www.janbob.com/electron/FilterBP1/FiltBP1.html], and you could also ask for samples at Coilcraft.
 
Thank you. :)



WH7U, DD4WH: Do you think it is possible to use analog switches to switch the gain resitors (Rg) on the INA163 ? Four, or even two steps, controllable by the Teensy would be fine.
 
Last edited:
Back
Top