Page 1 of 8
Introduction
For Christmas I got a Baofeng UV5R radio, which is a real cheep ($40) ham radio. Since I did not have a ham license, I started by simply programming it to be a police scanner. However, I soon got bored of just listening around and wanted to see what can be done with this radio. Since its a 4W radio, I thought it would be cool to try and send serial data over a few miles. After searching around a bit, I found that it can be programmed with an open source program called
CHIRP. I was originally hoping that I could change the firmware, but after looking at the CHIRP code I realized that you can only program the channels in the radio, and a few settings. I even attempted to write a simple python script (derived from the chirp program), to see if other commands are available, but with no success. Since the
schematics were available, I thought I could just try to interface with the cpu directly.
#Python program for Simple uv5r interface derived from CHIRP
import struct
import time
import serial
from chirp import chirp_common, errors, util, directory, memmap
UV5R_MODEL_291 = "\x01\xBB\xFF\x20\x12\x07\x25"
def _read_block(ser, start, size):
msg = struct.pack(">BHB", ord("S"), start, size)
ser.write(msg)
answer = ser.read(4)
if len(answer) != 4:
raise errors.RadioError("Radio refused to send block 0x%04x" % start)
cmd, addr, length = struct.unpack(">BHB", answer)
if cmd != ord("X") or addr != start or length != size:
print "Invalid answer for block 0x%04x:" % start
print "CMD: %s ADDR: %04x SIZE: %02x" % (cmd, addr, length)
raise errors.RadioError("Unknown response from radio")
chunk = ser.read(0x40)
if not chunk:
raise errors.RadioError("Radio did not send block 0x%04x" % start)
elif len(chunk) != size:
print "Chunk length was 0x%04i" % len(chunk)
raise errors.RadioError("Radio sent incomplete block 0x%04x" % start)
ser.write("\x06")
ack = ser.read(1)
if ack != "\x06":
raise errors.RadioError("Radio refused to send block 0x%04x" % start)
return chunk
ser = serial.Serial(port="/dev/ttyUSB0", baudrate=9600, timeout=0.5)
ser.setTimeout(1)
ser.write(UV5R_MODEL_291)
ack = ser.read(1)
ser.write("\x02")
ident = ser.read(8)
print "Ident:\n%s" % util.hexprint(ident)
ser.write("\x06")
ack = ser.read(1)
print "Ack %s" % util.hexprint(ack);
data = ""
for i in range(0, 0x8192, 0x40):
data += _read_block(ser, i, 0x40)
print "Data:\n%s" % util.hexprint(data)