From sigrok
Jump to: navigation, search
BG7TBL case.jpg
Status planned
Frequency (user) 138MHz-4.4GHz
Waveforms sine (fixed)
Amplitude ? V
Connectivity USB

The BG7TBL USB RF Signal Generator is a PC-based function generator. It has no external controls, requiring a USB connection to a computer.

Software to run this hardware can be found here

This device can be bought on ebay for ca $65. Search for "138MHz-4.4GHz". There is a version with the ADF4351 instead that will give you more range (35MHz-4.4GHz).




Baud 57600, 8n1

The protocol is binary serial based.

Query firmware

  • Send 0x8f+"v"

The answer should be in hex:

  • 77

Where the returned byte is the firmware version, 0x77 = 119 = 'w'.


import serial

ser = serial.Serial('/dev/ttyUSB0', 57600, timeout=1) # Linux first FTDI
ser.write("\x8f" + "v")
print("version is " +

Signal generator

Setting frequency

To set a frequency send:

  • 0x8f

Then f and then the frequency divided by 10 with leading zeroes. For example this is the payload for 400MHz.

  • 400 000 000 / 10
  • f040000000
import sys, serial

ser = serial.Serial('/dev/ttyUSB0', 57600, timeout=1) # Linux first FTDI
# sys.argv[1] is frequency in Herz
cmd = "\x8f" + "f" + '{:09d}'.format(int(sys.argv[1])/10)

Spectrum analyzer

The protocol is briefly described in the source code here:

Here is a minimal code for an 'x' sweep (the protocol is described in chapter 6 of ). The device sends back the expected number of bytes but it seems I have to divide the frequency by 10... (?).

import sys, serial, struct

start_frequency = 100000000    # FM band
increment       = 20000
steps           = 2000
# 'x' sweep (writing the command returns (4 * steps) bytes (what is it, I don't know)
cmd = "\x8f" + "x" + '{:09d}{:08d}{:04d}'.format(start_frequency/10, increment, steps)
ser = serial.Serial('/dev/ttyUSB0', 57600, timeout=100) # Linux first FTDI
rsp = * steps)
if len(rsp) < (4 * steps):
	sys.stderr.write("Warning : Did not read enough measures! Try increasing the timeout\n")
	steps = len(rsp)/4    # adapt to the number of measures read
val_tab = struct.unpack_from("<" + "h"*2*steps, rsp) # 2 * steps 'little endian shorts'
for i in range(0, steps):
	print(val_tab[2*i])	# channel A (A and B are interleaved)