Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python 3 #16

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 46 additions & 47 deletions OscScreenGrabLAN.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#!/usr/bin/env python
#!/usr/bin/env python3

from telnetlib_receive_all import Telnet
from Rigol_functions import *
import time
from PIL import Image
import StringIO
import io
import sys
import os
import platform
Expand Down Expand Up @@ -74,35 +74,35 @@


def print_help():
print
print "Usage:"
print " " + "python " + script_name + " png|bmp|csv [oscilloscope_IP [save_path]]"
print
print "Usage examples:"
print " " + "python " + script_name + " png"
print " " + "python " + script_name + " csv 192.168.1.3"
print
print "The following usage cases are not yet implemented:"
print " " + "python " + script_name + " bmp 192.168.1.3 my_place_for_captures"
print
print "This program captures either the waveform or the whole screen"
print " of a Rigol DS1000Z series oscilloscope, then save it on the computer"
print " as a CSV, PNG or BMP file with a timestamp in the file name."
print
print " The program is using LXI protocol, so the computer"
print " must have LAN connection with the oscilloscope."
print " USB and/or GPIB connections are not used by this software."
print
print " No VISA, IVI or Rigol drivers are needed."
print
print()
print("Usage:")
print(" " + "python " + script_name + " png|bmp|csv [oscilloscope_IP [save_path]]")
print()
print("Usage examples:")
print(" " + "python " + script_name + " png")
print(" " + "python " + script_name + " csv 192.168.1.3")
print()
print("The following usage cases are not yet implemented:")
print(" " + "python " + script_name + " bmp 192.168.1.3 my_place_for_captures")
print()
print("This program captures either the waveform or the whole screen")
print(" of a Rigol DS1000Z series oscilloscope, then save it on the computer")
print(" as a CSV, PNG or BMP file with a timestamp in the file name.")
print()
print(" The program is using LXI protocol, so the computer")
print(" must have LAN connection with the oscilloscope.")
print(" USB and/or GPIB connections are not used by this software.")
print()
print(" No VISA, IVI or Rigol drivers are needed.")
print()

# Read/verify file type
if len(sys.argv) <= 1:
print_help()
sys.exit("Warning - wrong command line parameters.")
elif sys.argv[1].lower() not in ["png", "bmp", "csv"]:
print_help()
print "This file type is not supported: ", sys.argv[1]
print("This file type is not supported: ", sys.argv[1])
sys.exit("ERROR")

file_format = sys.argv[1].lower()
Expand All @@ -118,10 +118,10 @@ def print_help():
response = os.system("ping -c 1 " + IP_DS1104Z + " > /dev/null")

if response != 0:
print
print "WARNING! No response pinging " + IP_DS1104Z
print "Check network cables and settings."
print "You should be able to ping the oscilloscope."
print()
print("WARNING! No response pinging " + IP_DS1104Z)
print("Check network cables and settings.")
print("You should be able to ping the oscilloscope.")

# Open a modified telnet session
# The default telnetlib drops 0x00 characters,
Expand All @@ -131,40 +131,39 @@ def print_help():

# Check if instrument is set to accept LAN commands
if instrument_id == "command error":
print "Instrument reply:", instrument_id
print "Check the oscilloscope settings."
print "Utility -> IO Setting -> RemoteIO -> LAN must be ON"
print("Instrument reply:", instrument_id)
print("Check the oscilloscope settings.")
print("Utility -> IO Setting -> RemoteIO -> LAN must be ON")
sys.exit("ERROR")

# Check if instrument is indeed a Rigol DS1000Z series
id_fields = instrument_id.split(",")
if (id_fields[company] != "RIGOL TECHNOLOGIES") or \
(id_fields[model][:3] != "DS1") or (id_fields[model][-1] != "Z"):
print "Found instrument model", "'" + id_fields[model] + "'", "from", "'" + id_fields[company] + "'"
print "WARNING: No Rigol from series DS1000Z found at", IP_DS1104Z
print
typed = raw_input("ARE YOU SURE YOU WANT TO CONTINUE? (No/Yes):")
print("Found instrument model", "'" + id_fields[model] + "'", "from", "'" + id_fields[company] + "'")
print("WARNING: No Rigol from series DS1000Z found at", IP_DS1104Z)
print()
typed = input("ARE YOU SURE YOU WANT TO CONTINUE? (No/Yes):")
if typed != 'Yes':
sys.exit('Nothing done. Bye!')

print "Instrument ID:",
print instrument_id
print("Instrument ID:", instrument_id)

# Prepare filename as C:\MODEL_SERIAL_YYYY-MM-DD_HH.MM.SS
timestamp = time.strftime("%Y-%m-%d_%H.%M.%S", time.localtime())
filename = path_to_save + id_fields[model] + "_" + id_fields[serial] + "_" + timestamp

if file_format in ["png", "bmp"]:
# Ask for an oscilloscope display print screen
print "Receiving screen capture..."
buff = command(tn, ":DISP:DATA?")
print("Receiving screen capture...")
buff = command_bin(tn, ":DISP:DATA?")

expectedBuffLen = expected_buff_bytes(buff)
# Just in case the transfer did not complete in the expected time, read the remaining 'buff' chunks
while len(buff) < expectedBuffLen:
logging.warning("Received LESS data then expected! (" +
str(len(buff)) + " out of " + str(expectedBuffLen) + " expected 'buff' bytes.)")
tmp = tn.read_until("\n", smallWait)
tmp = tn.read_until(b"\n", smallWait)
if len(tmp) == 0:
break
buff += tmp
Expand All @@ -181,16 +180,16 @@ def print_help():
buff = buff[tmcHeaderLen: tmcHeaderLen+expectedDataLen]

# Save as PNG or BMP according to file_format
im = Image.open(StringIO.StringIO(buff))
im = Image.open(io.BytesIO(buff))
im.save(filename + "." + file_format, file_format)
print "Saved file:", "'" + filename + "." + file_format + "'"
print("Saved file:", "'" + filename + "." + file_format + "'")

# TODO: Change WAV:FORM from ASC to BYTE
elif file_format == "csv":
# Put the scope in STOP mode - for the moment, deal with it by manually stopping the scope
# TODO: Add command line switch and code logic for 1200 vs ALL memory data points
# tn.write("stop")
# response = tn.read_until("\n", 1)
# response = tn.read_until(b"\n", 1)

# Scan for displayed channels
chanList = []
Expand All @@ -214,7 +213,7 @@ def print_help():

# for each active channel
for channel in chanList:
print
print()

# Set WAVE parameters
command(tn, ":WAV:SOUR " + channel)
Expand All @@ -226,15 +225,15 @@ def print_help():
command(tn, ":WAV:STOP 1200")

buff = ""
print "Data from channel '" + str(channel) + "', points " + str(1) + "-" + str(1200) + ": Receiving..."
print("Data from channel '" + str(channel) + "', points " + str(1) + "-" + str(1200) + ": Receiving...")
buffChunk = command(tn, ":WAV:DATA?")

# Just in case the transfer did not complete in the expected time
while buffChunk[-1] != "\n":
logging.warning("The data transfer did not complete in the expected time of " +
str(smallWait) + " second(s).")

tmp = tn.read_until("\n", smallWait)
tmp = tn.read_until(b"\n", smallWait)
if len(tmp) == 0:
break
buffChunk += tmp
Expand Down Expand Up @@ -278,6 +277,6 @@ def print_help():
scr_file.write(csv_buff)
scr_file.close()

print "Saved file:", "'" + filename + "." + file_format + "'"
print("Saved file:", "'" + filename + "." + file_format + "'")

tn.close()
33 changes: 25 additions & 8 deletions Rigol_functions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pip
import pkg_resources
import sys
import logging

Expand All @@ -8,7 +8,7 @@
def log_running_python_versions():
logging.info("Python version: " + str(sys.version) + ", " + str(sys.version_info)) # () required in Python 3.

installed_packages = pip.get_installed_distributions()
installed_packages = pkg_resources.working_set
installed_packages_list = sorted(["%s==%s" % (i.key, i.version) for i in installed_packages])
logging.info("Installed Python modules: " + str(installed_packages_list))

Expand All @@ -18,29 +18,46 @@ def command(tn, scpi):
answer_wait_s = 1
response = ""
while response != "1\n":
tn.write("*OPC?\n") # previous operation(s) has completed ?
tn.write(b"*OPC?\n") # previous operation(s) has completed ?
logging.info("Send SCPI: *OPC? # May I send a command? 1==yes")
response = tn.read_until("\n", 1) # wait max 1s for an answer
response = tn.read_until(b"\n", 1).decode() # wait max 1s for an answer
logging.info("Received response: " + response)

tn.write(scpi + "\n")
tn.write(scpi.encode() + b"\n")
logging.info("Sent SCPI: " + scpi)
response = tn.read_until("\n", answer_wait_s)
response = tn.read_until(b"\n", answer_wait_s).decode()
logging.info("Received response: " + response)
return response


def command_bin(tn, scpi):
logging.info("SCPI to be sent: " + scpi)
answer_wait_s = 1
response = b""
while response != b"1\n":
tn.write(b"*OPC?\n") # previous operation(s) has completed ?
logging.info("Send SCPI: *OPC? # May I send a command? 1==yes")
response = tn.read_until(b"\n", 1) # wait max 1s for an answer
logging.info("Received response: " + repr(response))

tn.write(scpi.encode() + b"\n")
logging.info("Sent SCPI: " + scpi)
response = tn.read_until(b"\n", answer_wait_s)
logging.info("Received response: " + repr(response))
return response


# first TMC byte is '#'
# second is '0'..'9', and tells how many of the next ASCII chars
# should be converted into an integer.
# The integer will be the length of the data stream (in bytes)
# after all the data bytes, the last char is '\n'
def tmc_header_bytes(buff):
return 2 + int(buff[1])
return 2 + int(buff[1:2].decode())


def expected_data_bytes(buff):
return int(buff[2:tmc_header_bytes(buff)])
return int(buff[2:tmc_header_bytes(buff)].decode())


def expected_buff_bytes(buff):
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading