Wobbulator, RF Network Analyzer
I recently found an interesting measuring project wobbulator with the Raspberry Pi computer from Tom Herbison, a HF Network Analyzer. It consists of the following elements:
Raspberry Pi computer for control and graphic output.
DDS generator module AD9850 with new output filter from DL5FA
- Adafruit Raspberri Pi proto board
AD8307 Logarithmic Amplifier (RF detector)
A/D converter with I2C (TWI) connection to the Raspberry Pi
For the Hardware Input/Output handling see RaspberryPiIOLibrary
A similar project Poor Ham's Scalar Network Analyzer (PHSNA) with an Arduino UNO as controller and PC for graphics is developed on Yahoo, see at Links. The graphic user interface and the use of the low cost Raspberry Pi computer I like more, than the Arduino - Excel setup.
Unfortunately the dynamic range of the wobbulator was not so good (about 52 dB). So, I tried to improve that, to about 65 dB. After several tries I came very close (60 dB) to that target.
Because the first hardware design of the wobbulator was more for qualitative measurements, I adopted some design improvements from the PHSNA group, and made my own PCB's (Printed Circuit Board), in order to combine the best of the two projects.
Now, after 8 month of work with some throwbacks, it looks like, that the project is successfully finished.
Because of the AD8307 Logarithmic Amplifier, the A/D converter just needs a 10 bit resolution, so I decided from the viewpoint of cost and size to use an Arduino Pro Mini controller module. The alternative, an ATtiny85-20 works in principle, but not reliable.
A PCB (size: 70 x 45 mm) brings together:
The 26 pin flat cable connector from the Raspberry Pi with +3.3 and +5 V supply.
The 6 pin connector (2.54 mm raster) from the DDS-Generator.
The 6 + 2 pin connector (2.54 mm raster) to hold the Arduino Pro Mini board (A/D converter).
Logamp (Logarithmic Amplifier) parts with the BNC connector.
For the schematic please see the picture on the right (click to expand), for printing download the PDF file.
To make your own PCB (double sided, thickness 0.5 mm) I will attach the Eagle6 files:
- Power Supply specialties for AD8307:
- If you supply with 3.3 V only, then it is difficult to measure up to 0 dBm.
- On one IC I had to supply with 5.2 V, in order to reach down to -72 dBm at open input.
A/D converter, software Arduino Pro Mini
The basic A/D converter and I2C communication software was developed with an Arduino Nano 3 module, with the Arduino IDE and then ported to the Arduino Pro Mini. The Analog/Digital Converter software (Arduino version 1.0.5) can be downloaded here. Also the Python3 test program for the Raspberry Pi. Usually you can buy the Arduino Pro Mini in the +5 V version (clock = 16 MHz). I run this board with 3.3 V only, in order to have a better A/D resolution and a more stable reference voltage. The maximum clock frequency with 3.3 V supply should be 13 MHz, but it works also with 16 MHz at room temperature (4 mA supply current).
For debugging the tool Bus Pirate 3 (firmware version 6.1) is use, with program CoolTerm.app (Mac OS) and 115000 baud, no handshake. When you see the prompt HiZ> hit "i" for information, and "m" for the modes.
For programming the module please see at AVRArduinoProMini.
The communication with the Raspberry Pi is made via I2C/TWI bus.
- Slave address: 5 (master: 0x0A = write, 0x0B = read, Address 0 - 4 are reserved)
The tests were sniffed with the Bus Pirate 3 from Links, see:
Legend: + = ACK, - = NACK, [ = Start bit, ] = Stop bit [0x0A+0x03+][0x0B+0x01+0xE8-] send A/D channel 3, get analog value 0x200 = 488
The oscilloscope picture (click on enlarge) on the right shows the I2C timing, Data: [0x0A+0x03+], upper trace = SDA, lower trace = SCL). The I2C clock was 100 KHz, the ATmega328 clock was 16 MHz.
A/D converter, software Attiny85-20
Because of the AD8307 Logarithmic Amplifier the A/D converter just needs a 10 bit resolution, I decided from the viewpoint of cost and size to try an Atmel ATtiny85-20 micro controller. This works in principle, but not reliable. I will just explain what is the reason of the problem.
The CPU clock rate was set to 8 MHz, the I2C clock 40 KHz. Because the clock pulses are created by software, the timing is not very accurate, see the oscilloscope picture (click to enlarge) on the right (Data: [0x0A+0x03+], upper trace = SDA, lower trace = SCL). The clock stretching from the slave is 50 to 100 us.
Workaround: the slave stretches the clock only at the end/directly after an I2C-read-ACK-phase (after reading ACK/NACK), but then by more than 0.5 clock periods.
In order to make it easier to analyze the problem by digital scope, you can add series resistors in the I2C bus lines. When the Raspberry Pi pull-up resistor are 1k8, then a value of 390R would be good. Then you see at the "0" level, who is pulling the bus down.
The communication with the Raspberry Pi is made via I2C/TWI bus.
- Slave address: 5 (master: 0x0A = write, 0x0B = read, Address 0 - 4 are reserved)
The tests were sniffed with the Bus Pirate 3 (firmware version 6.1) from Links, see:
Legend: + = ACK, - = NACK, [ = Start bit, ] = Stop bit [0x0A+0x03+][0x0B+0x02+0x00-] send A/D channel 3, get analog value 0x200 = 512
In order to avoid I2C bus speed problems, the I2C clock rate was reduced from 100 KHz to 40 KHz:
http://www.noiseisgood.co.nz/debugging-the-wm8731-adcdac-with-a-bus-pirate/ # To check your i2c bus baudrate : $ sudo cat /sys/module/i2c_bcm2708/parameters/baudrate 100000 # edit a new file $ sudo nano /etc/modprobe.d/custom.conf options i2c_bcm2708 baudrate=40000 $ sudo reboot $ sudo cat /sys/module/i2c_bcm2708/parameters/baudrate 40000
RF amplitude measurement
In order to have a large dynamic range in measuring the Radio Frequency amplitude coming back from the DUT (Device Under Test), a logarithmic amplifier AD8307 was selected (about 88 db dynamic range). In order to use the full dynamic range of the logarithmic amplifier from +16 dBm (4.0 Vpp at 50 Ohm) to -72 dBm (0.159 mVpp at 50 Ohm) the input level should be accordingly. The definition for 0 dBm is 1 mW (0.63 Vpp at 50 Ohm). I always tell Vpeak-to-peak because most of the time those voltages are measured with an oscilloscope.
The output level of the DDS-Generator therefore should be adopted close to the +16 dBm. While the supply voltage is 5 V, the output current of the DDS-Generator is set via RSET = 3k9 to 10.24 mA. The output of the DDS generator got a symmetric 1:1 transformer and a new low pass filter, see Filter_AD9850_from_DL5FA. With a load resistance of about 50 Ohm the output voltage is maximum 0.63 Vpp, hence 0 dBm at 50 Ohm. Maybe a 3 dB level increase is needed to reach the 0 dBm level, see here for a simple modification.
The input impedance of the logarithmic amplifier is 50 Ohm and the input connection a BNC plug.
Raspberry Pi, hardware
The first prototype had all modules together on the proto board, see the picture on the right. The I/O port from the Raspberry Pi are fed via 26 pin flat cable to a half size proto board, price about 6.50 EUR, see Links. On one side on top the DDS-Generator AD9850 is plugged via a 10 pin connector. Because the control signals of the DDS-Generator are inputs only, the DDS-Generator can be operated with +5 V, while the Raspberry Pi works with +3.3 V. While the Logic 1 level at 5 V supply is specified with a minimum of 3.5 V (70% of supply voltage), it works in reality. With a specified input current of maximum 12 uA the Logic 1 level from GPIO is nearly the same as the supply voltage of 3.3 V. For more details, please see at the Links.
On the other side on top a self made PCB (printed circuit board) is plugged via a 6 pin connector, which holds the Arduino Pro Mini module, the logarithmic amplifier AD8307 and 2 BNC plugs. The upper side side of the PCB is a ground plane for shielding. It shows up, that the 50 Ohm input resistance of the logarithmic amplifier together with very short wires needs no further shielding.
While the evaluation it shows up, that the DDS-Generator produces a lot of RF noise. If you want to have a larger dynamic range of the amplitude, the DDS-Generator must be housed in a metal box and shielded, see the picture on the right. All signals and the +5 V supply are fed through 1 nF capacitors in the wall of the box. Inside the box a 1 mH choke (0.7 Ohm) is inserted in the +5 V supply.
The AD9850 DDS-Generator modules from China are probably so cheap, because the low pass filter was not designed well. There are several proposals to improve that, see AmateurRadioDDSgenerator. I designed my own filter and it works good, for details see Filter_AD9850_from_DL5FA.
Finally, after removing some hardware bugs (cold soldering, bad capacitor, etc.) I put all the modules in a housing Teko D13 (WxHxL 150 x 54 x 135 mm, reichelt.de 4.25 EUR). This housing was selected because of the easy handling and low cost.
For easier mounting and as a ground plane a copper plated epoxy board 105 x 120 mm was screwed onto the already provided posts inside the housing (copper side up). The metal housing is soldered at 2 points to the base plate, distance to the wall = 15 mm. The logamp PCB is mounted on 3 screws M2.5 x 8 mm, which are mounted from underneath of the base plate. Two nuts (3.2 mm) are used for the spacing of the logamp PCB. The back side of the PCB is soldered with a piece of copper foil or 3 thick wires to the ground plane.
Because there is already a cutout in the backside of the housing, I extended the cutout so the BNC plugs seats well, see the picture on the right. The upper half of the housing fits without modification.
The flat cable to the Raspberry Pi is routed over the side wall, and cutout over the width of the flat cable by about 1 mm, allowing the housing to close without gap.
The original front plate, transparent red plastic, is just used to close the open front side of the housing.
Raspberry Pi, software
- Update 2015-12-12 Raspbian Jessie 2015-11-21
The Wobbulator software can be downloaded (ZIP file) from the github archive, see Links.
For the I2C/TWI interface bus you need a driver library , see Links. The quick2wire-gpio-admin software can be downloaded as a ZIP file from the github archive, into the new Install folder.
Unfortunately the GPIO library needs root rights to work. There is also a GPIO library which does not need that, but it is about 10 times slower, please see here for details.
For installation of the libraries and tools do:
# install documentation tool $ sudo apt-get install pandoc # tools to install $ sudo apt-get install python-pip $ sudo apt-get install python-virtualenv $ mkdir Install $ cd Install # install GPIO/I2C library # Download the I2C driver quick2wire-gpio-admin $ wget https://github.com/quick2wire/quick2wire-gpio-admin/archive/master.zip $ unzip master.zip # Rename $ mv master.zip quick2wire/quick2wire-gpio-admin.zip $ cd quick2wire-gpio-admin-master $ make $ sudo make install # check for good installation $ man gpio-admin # Install GPIO/I2C Python3 library $ wget https://github.com/quick2wire/quick2wire-python-api/archive/master.zip $ unzip master.zip # Rename $ mv master.zip quickwire-python-api.zip # setup group $ sudo adduser $USER i2c # logout and login again, to activate the group assignment or reboot later # check for function (24(BCM) = 18(pi_header_1) = 5(pins) = DATA) $ gpio-admin export 24 $ cat /sys/class/gpio/gpio24/value 0 # set gpio24 output to "1" $ echo out > /sys/class/gpio/gpio24/direction $ echo 1 > /sys/class/gpio/gpio24/value $ cat /sys/class/gpio/gpio24/value 1 # shut off pin $ gpio-admin unexport 24 # install i2cdetect $ sudo apt-get install i2c-tools
New Jessy method for I2C enabling:
$ sudo raspi-config # select in the menu "Advanced Options" # select in the menu "A7 I2C Enable/Disable automatic loading" # Answer "yes" to "Would you like the ARM I2C interface to be enabled?" # Info: The ARM I2C interface will be enabled after a reboot" # Answer "yes" to "Would you like the I2C kernel module to be loaded by default?" # Exit the program # Do a reboot
Old method for I2C enabling:
# edit file /etc/modprobe.d/raspi-blacklist.conf # Quick2wire software library needs it 2013-12-09 RR #blacklist spi-bcm2708 #blacklist i2c-bcm2708 # edit file /etc/modules # add line i2c-dev $ sudo reboot
Check the I2C interface:
# check for i2c device descriptor $ ls /dev/i2* crw-rw---T 1 root i2c 89, 0 Dez 9 18:14 /dev/i2c-0 crw-rw---T 1 root i2c 89, 1 Dez 9 18:14 /dev/i2c-1 # check for modules $ lsmod Module Size Used by i2c_dev 5620 0 snd_bcm2835 15846 0 snd_pcm 77560 1 snd_bcm2835 snd_seq 53329 0 snd_timer 19998 2 snd_pcm,snd_seq snd_seq_device 6438 1 snd_seq snd 58447 5 snd_bcm2835,snd_timer,snd_pcm,snd_seq,snd_seq_device snd_page_alloc 5145 1 snd_pcm spidev 5224 0 leds_gpio 2235 0 led_class 3562 1 leds_gpio spi_bcm2708 4510 0 i2c_bcm2708 3759 0 $ sudo i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- 05 -- -- -- -- -- -- -- -- -- -- ....
In order to have the path of the library folder accessible to Python3, the environment variable PYTHONPATH can be setup with the path of the Quick2Wire library. But this works since Raspbian 2015-11-21 only.
# link Quick2Wire-API (i2c) library to Python # edit /home/pi/.bashrc # add # for I2C use export QUICK2WIRE_API_HOME=/home/pi/Install/quick2wire-python-api-master export PYTHONPATH=$PYTHONPATH:$QUICK2WIRE_API_HOME # logout and login again, to activate the environment
For Raspbian 2014-01-07 the environment variable PYTHONPATH does not work together with sudo. I could not find out why, my solution 1 is to copy the folder quick2wire to the Python3.2 folder dist-packages, or solution 2 to add the path of the Quick2Wire library directly in the program wobbulator.py.
# Error message: ImportError: No module named quick2wire.i2c # solution 1 # found the path from "IDLE3/File/Path Browser" # copy folder quick2wire-python-api-master/quick2wire to /usr/local/lib/python3.2/dist-packages/ # solution 2 # Edit wobbulator.py import sys # setup the path according to your local installation sys.path.append('/home/pi/Install/quick2wire-python-api-master') #import quick2wire i2c module import quick2wire.i2c as i2c
In order to start the program wobbulator.py from the command line the first line must be a shebang line, see also Links:
- #!/usr/bin/env python3
# change path to folder $ cd /home/pi/Install/wobbulator # Start programm from the terminal command line # since Raspian 2015-11-21 $ python3 wobbulator2.6.3.py # for old Rapian $ sudo ./wobbulator2.6.3.py
Changes to wobbulator.py
After some improvements of the original software I am using now version 2.6.3 with some patches.
Shebang - the first line should tell where the the Python interpreter is.
- A/D Converter with an ATmega328 (Arduino Pro Mini)
Because of the different A/D converter the I2C routine must be changes. For easier scaling, i converted the binary value 0 - 1023 to Volt 0 - 3.3 V.
# for function sleep import time, sys #define address for ADC chip, Arduino mini adc_address = 0x05 # Function to get reading from ADC def getadcreading(address): bus.transaction(i2c.writing_bytes(0x05, 0x03)) time.sleep(.001) avhigh, avlow = bus.transaction(i2c.reading(address,2)) t = (avhigh << 8) | avlow # Uref = 3.32 V / 1023 (10 Bit) = 308 -> scale in Volt return (t / 308)
Show a vertical amplitude scaling (ampdivlabel) of 10dB/div in the graph.
I think for filter measurement a relative dB value is more important than an absolute dB value.
canvas.create_rectangle(1, 1, 500, 500) ampdivlabel = Label(frame, text='10dB/div') ampdivlabel.grid(row=0, column=6)
- The dB scaling was changed to span +20 / -80 dB, and 100 pixel per 10 dB
startV = float(-80) stopV = float(20) vN = startV + 100/gain
- Reading the ADC is different:
bias = (getadcreading(chip, address) + getadcreading(chip, address))/2 #<< changed afa reading = getadcreading(chip) #includes triggering adc << added afa
- Scale the vertical amplitude value to 10dB/div:
# AD8307 (5 V supply) 23mV/dB, span 0.27 - 2.23 V, *185 = 10 dB/div y = int(500 + 25 - (reading * 185))
- change title line:
root.wm_title('RPi Wobbulator v2.6.3RR, use "scrot -s -d 4" for window shot')
screen shot: In order make a screen shot of the graph, open a second tab in the Terminal window. Then type scrot -s -d 4 ENTER. The parameter -d 4 (delay 4 s) is needed, to bring via a mouse click the graph window back in the foreground, because usually the Terminal window overlaps.
The patched program is provided for download.
The setup and use of VNC (Virtual Network Computing) is described on page VNC server
Measurements and conclusion
With the Arduino Pro Mega as an Analog to Digital converter I had to modify the main Python program, but now it works in principle, see screen-shot on the right. The 290 steps are measured in about 1.3 seconds, what I think is a good time.
The test object is a Murata 10.7 MHz dual ceramic filter SFW-10.7MA with the data:
- Bandwidth @6 dB: 250 KHz
- Bandwidht @40 dB: 400 KHz
- Impedance at input and output: 300 Ohm
In the picture (Graph) to the right you will see 3 traces in blue.
- Upper trace: a short between input and output.
Center trace: a Murata 10.7 MHz ceramic filter SFW-10.7MA, for details see Links
- Lower trace: Open input (absolute 0.27 V, about -73 dBm).
I wanted to check the dB linearity of the logarithmic amplifier in 10 dB steps from 0 to -60 dBm. While measuring I found out, that the 0 dB attenuation was compressed, because of the 3.3 V supply.
In order to improve that, I changed to a 5 V supply. Now the linearity looked better.
Originally you have a practical dynamic amplitude range with about 60 dB, even if the logarithmic amplifier has a maximum dynamic range of about 88 dB.
Considering the actual RF output level at the DDS-Generator of 0 dBm, the possible dynamic range could be 70 dB (open input). The missing 10 dB are coming from noise, because the logarithmic amplifier is sensitive up to 900 MHz. I could not found out how to improve that.
The printed circuit board of the logarithmic amplifier had a ground shield on one side, with some contacting to the wire side. It is important to keep the wires at the front end short.
To get a clean signal, the noisy DDS-Generator must be put in a metal box. All control signals and the power supply got 1 nF pass through capacitors and a ferrite pearl. The +5 V inside got a choke with 1 mH.
Poor Hams Scalar Network Analyzer is a very similar project to the Wobbulator, but depends on MS Windows Excel and more comfortable PLX-DAQ (Data Acquisition for Excel with serial link) from company parallax, see at Links. The RF generator is the same. For level measuring a logarithmic amplifier (AD8307) from project Power meter is used.
The main computing is done with an Arduino UNO module (CPU Atmel ATmega328). It is also possible to use a cheaper (Ebay, about $7) and smaller Arduino Nano 3.0 module.
The normal operation is to make a frequency sweep with a Terminal Program (Win32 - PuTTY) and copy and paste the data block into a text file with extension .csv (comma separated value). This text file can be imported into a spreadsheet (MS Excel, LibreOffice, OpenOffice) and converted into a diagram. This is a lot of handling.
In order to make it more comfortable, you can use the free Data Acquisition Program PLX-DAQ to automate that time consuming process, see picture on the right (click to enlarge). Yes, it works, but in the long run you will get problems. The Program PLX-DAQ is very nice made, but from the year 2007 and it looks, that it is no longer maintained. In my test I used Win7-32 SP1 and MS Excel 2002 SP3. While in the data acquisition test spreadsheet PLX-DAQ.xls the link to the ActiveX program selmaDAQ_Ver2.ocx works fine, in the application spreadsheet PMSNAb4r2.xls the link to the ActiveX Program could not be established (VBA runtime error 464). A workaround is, to load first the test spreadsheet and then the application program into Excel. This also works running Win7-32 in a virtualbox (ver. 4.3.6).
The Arduino UNO software SimpleSNA_WA5BDU_1r9_rev2r62.zip can be downloaded from the Yahoo group PHSNA (Files), but you have to be a member of this group.
The project description is in the files:
- Simple Scalar Network Analyzer Instructions v1r10.pdf
- Simple Scalar Network Analyzer Overview v1r11.pdf
Terminal Program PuTTY
Because the mentioned Terminal Program Term232 is not very intelligent, I choose PuTTY to use PuTTY, download windows installer. For use with PHSNA a few parameter changes are necessary or usefull:
- Category: Session - Connection type: Serial
- Category: Session - Serial Line: e.g. COM4
- Category: Session - Speed: 9600
- Category: Terminal - Local echo: Force on
- Category: Terminal - Local line editing: Force on
- Category: Window: Colours - mark at: Use system colours
- Category: Window: Lines of scrollback - default is 2000
Category: Session: Saved Sessions - name e.g. Arduino_COM4_9600 - then Save
How to use the clipboard:
- Copy to clipboard: mark the text with the mouse + left button, and it is in the clipboard
- Paste from clipboard: key SHIFT + Insert
When you start PuTTY next time, just double click left on session name, e.g. Arduino_COM4_9600.
The basic operation is to use a Terminal Program, e.g. PuTTY on Windows, or any other comparable one on other operating systems (Mac OS X - CoolTerm.app, Linux - PuTTY) to talk to the Arduino UNO. See the main menu:
Retrieved: slope = 0.18700 intercept = -85.00 DDS is running on: 7040000 Hz AD9850 mode Simple SNA by Jim Giammanco, N5IB, and Jerry Haigwood, W5JH Version 2.62 on 21 Nov 2013, 01-04-2013 Nick, WA5BDU_1r9 Select: 1 - SNA Function 2 - Generator Function 3 - Calibrate DDS 4 - Determine or enter AD8307 constants 5 - Set start-up frequency 6 - Change start-up mode to PLX (Excel) 7 - Test and characterize crystal 8 - Toggle AD9850/AD9851 modes 9 - Re-display menu Choice:
Unfortunately editing is not possible. Mistyping usually ends in a reset of the Arduino UNO.
This is a tricky business. In order to calibrate the analog measurement value of the RF level, you have to dig in the software. In program eeprom_i_o.ino you can find the definition for the slope:
# line 39 serialprintln_P(PSTR("Enter slope (decimal number dBm / count): "));
The parameter calculation slope/intercept you can find in program misc_functions.ino:
// Power Meter Calibration - Conversion of ADC counts to dBm // the equations below convert the raw output (pin 4) of the AD8307 to dBm // for a raw, unamplified AD8307: assuming 0.025 V per dBm, and 0 V corresponds to -84 dBm, // so 0 dBm is 2.1 V, and +10 dBm is 2.35V // // but most 8307 meters would have a buffer amp with some gain so that +10 dBm will be about 5 V // to accomodate that amplifier the parameters below would have to be recalculated... // think y = mx + b, you have to determine the slope y in dBm per volt (e.eg. 18.8) // and the intercept in dBm correcponding to zero volts, e.g. -84 // // v_dBm = -84 + ((40*CH0_ADC_counts)/1023.0)*AREF; // generic transfer function for raw, unamplified AD8307 output
Arduino ATmega328 A/D converter resolution is 10 bit -> 1023 steps.
- AREF is in the original setup calibrated to 5.0V, in my case 4.8V from USB supply.
slope dBm/count in my case, AD8307 raw output: 4.8 V / 1023 / 0.025 V = 0.187
intercept in my case: estimated to -85 dBm
Once you have optimized (lowest voltage from AD8307 with open input) your hardware with low pass filters, chokes, bypass capacitors and shielding, it make sense to do a calibration of the logarithmic amplifier AD8307 with calibrated attenuators. For details, please read this conversation
Frequency Sweep with PLX-DAQ
After finding the previous mentioned workaround for using the software PLX-DAQ, you could enter in cells L2-L4:
- Lower limit frequency for the sweep [KHz]
- Upper limit frequency for the sweep [KHz]
- step, frenquency [Hz]
Then you click on Connect of the PLX-DAQ control window. The measurement values are read in from the serial link to the Arduino UNO and inserted into the spreadsheet at the proper place, see the picture.
It has a side effect, that this mode of operation (PLX-DAQ) is then stored in the EEPROM of the Arduino UNO. Next time, you connect to the Arduion UNO with a terminal program, you have to wait for about 30 seconds to enter the menu mode.
PHSNA - Poor Hams Scalar Network Analyzer
Setup Putty for Windows Terminal emulation for a SSH network connection.
http://www.hobbytronics.co.uk/raspberry-pi-ssh Raspberry Pi SSH Login without Monitor
Setup VNC Virtual Network Computing
Mikrocontroller.net, Deutsch Raspberry Pi Erklärungen
List of pages in this category:
-- RudolfReuter 2013-12-09 15:54:41