Skip to content

Instantly share code, notes, and snippets.

@cosmonaut
Created October 3, 2015 08:43
Show Gist options
  • Select an option

  • Save cosmonaut/459047ae66c18aca50a0 to your computer and use it in GitHub Desktop.

Select an option

Save cosmonaut/459047ae66c18aca50a0 to your computer and use it in GitHub Desktop.
Script to grab screenshot from HP 54506B oscilloscope with Galvant USB/GPIB adapter.
#!/usr/bin/python
import sys
import serial
import time
import numpy as np
import matplotlib.pyplot as mp
import matplotlib.cm as cm
#48 bytes rows (384 pixels)
#74 bytes cols (592 pixels)
ROW_LEN = 74
COL_LEN = 48
# 6 byte row frame thing
FRAME_LEN = 6
# Read data from the scope
def hp_read(s, term = '\r', timeout = 3000):
if (s.isOpen() == False):
return((False, "Serial device closed..."))
msg = bytes(0)
for i in range(timeout):
n = s.inWaiting()
if (n > 0):
msg += s.read(n)
if (msg[-1] == term):
break
time.sleep(0.001)
if (msg != ''):
return((True, msg))
else:
return((False, "timeout?"))
def save_shot(data, fname):
# Row sync pattern
pattern = bytes([0x1b, 0x2a, 0x62, 0x37, 0x34, 0x57])
# image buffer
im = np.zeros((384, 592), dtype = np.uint8)
# track row and col number
row = 0
#col = 0
temp = 0
# index
ind = 0
while (True):
# Find row sync frame
ind = data.find(pattern, ind)
if (ind == -1):
# quit if no frames left
break
# move past the sync to only plot actual image
ind += FRAME_LEN
# convert row of bytes into bits...
temp = data[ind:ind+ROW_LEN]
# Loop over bytes in row
for i in range(ROW_LEN):
# Reverse the byte order, not sure why HP54506B is like this but it is...
rbyte = int('{:08b}'.format(temp[i])[::-1], 2)
# Loop over bits in byte
for j in range(8):
mask = 1 << j
if (mask & rbyte):
im[row, (i*8)+j] = 1
row += 1
fig = mp.figure(frameon = False, figsize=(6.42,4.34), dpi = 100)
ax = fig.add_subplot(111)
ax.imshow(im, interpolation = 'none', cmap = cm.binary)
ax.set_axis_off()
ax.set_frame_on(False)
# Put a 0.25" border on the raw scope image
fig.subplots_adjust(left=0.03894080996884735,
bottom=0.0576,
right=0.9610591900311527,
top=0.9424,
wspace=0.0,
hspace=0.0)
# For debugging size stuff...
# bbox = fig.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
# width, height = bbox.width*fig.dpi, bbox.height*fig.dpi
# print(fig.dpi)
# print(bbox.width, bbox.height)
# print(width, height)
fig.savefig(fname, pad_inches = 0)
def main(dev_name, gpib_addr, fname):
gpib_addr = int(gpib_addr)
if ((gpib_addr < 0) or (gpib_addr > 30)):
print("GPIB address must be between 0 and 30")
print("Got address: %s" % str(gpib_addr))
s = serial.Serial(dev_name,
460800,
bytesize = serial.EIGHTBITS,
stopbits = serial.STOPBITS_ONE,
parity = serial.PARITY_NONE)
s.flushInput()
# Turn off auto mode
s.write("++auto 0\n".encode())
# Check version...
s.write("++ver\n".encode())
time.sleep(0.02)
n = s.inWaiting()
msg = s.read(n)
print("Galvant GPIB USB: %s" % msg)
# Turn debug on for hardware test
s.write("++debug 1\n".encode())
time.sleep(0.02)
# Set long timeout (54506)
s.write("++read_tmo_ms 3000\n".encode())
time.sleep(0.02)
# Set \n as outgoing and incoming terminator
s.write("++eos 2\n".encode())
time.sleep(0.02)
# Set GPIB address
ga = str(gpib_addr)
s.write(bytearray("++addr " + ga + "\n", 'ascii'))
time.sleep(0.1)
# Remote mode
s.write("++loc\n".encode())
time.sleep(0.02)
s.write(":HARDCOPY:LENG 11\n".encode())
time.sleep(0.02)
s.write(":HARDCOPY:LENG?\n".encode())
s.write("++read eoi\n".encode())
time.sleep(0.1)
err, m = hp_read(s, term = 13, timeout = 1000)
if (err):
print(m)
else:
print("Error:")
print(m)
s.write(":HARDCOPY:MODE PRINT\n".encode())
time.sleep(0.02)
s.write(":HARDCOPY:MODE?\n".encode())
s.write("++read eoi\n".encode())
time.sleep(0.1)
err, m = hp_read(s, term = 13, timeout = 1000)
if (err):
print(m)
else:
print("Error:")
print(m)
print("printing... \n\n")
time.sleep(0.2)
s.write(":PRIN?\n".encode())
s.write("++read eoi\n".encode())
data = bytes(0)
err, m = hp_read(s, term = 13, timeout = 3000)
if (err):
data += m
if (m[-1] == 13):
print("Hardcopy retrieved...\n")
else:
print("Error:")
print(m)
#save_shot(data, "screenshot.pdf")
save_shot(data, fname)
# Return control to front panel
s.write("++loc\n".encode())
time.sleep(0.1)
# close serial port
s.close()
if __name__ == '__main__':
if (len(sys.argv) > 3):
main(sys.argv[1], sys.argv[2], sys.argv[3])
else:
print("Usage: python hp54506b_sc.py <usb_device_name> <gpib_address> <screen capture filename>")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment