Capture the display of a Rigol DS1000Z series oscilloscope by LAN using LXI SCPI commands
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

OscScreenGrabLAN.py 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. __author__ = 'RoGeorge'
  2. #
  3. # TODO: Port for Linux
  4. # TODO: Add command line parameters for IP, file path and file format
  5. # TODO: Add GUI
  6. # TODO: Add browse and custom filename selection
  7. # TODO: Create executable distributions
  8. # TODO: Use git, upload to GitHub
  9. #
  10. import telnetlib_receive_all
  11. import time
  12. import Image
  13. import StringIO
  14. import sys
  15. import os
  16. # Update the next lines for your own default settings:
  17. path_to_save = ""
  18. save_format = "PNG"
  19. IP_DS1104Z = "192.168.1.3"
  20. # Port used by Rigol LXI protocol
  21. port = 5555
  22. # Check parameters
  23. script_name = os.path.basename(sys.argv[0])
  24. # Print usage
  25. print
  26. print "Usage:"
  27. print " " + script_name + " [oscilloscope_IP [save_path [PNG | BMP]]]"
  28. print
  29. print "Usage examples:"
  30. print " " + script_name
  31. print " " + script_name + " 192.168.1.3"
  32. print " " + script_name + " 192.168.1.3 my_place_for_osc_captures"
  33. print " " + script_name + " 192.168.1.3 my_place_for_osc_captures BMP"
  34. print
  35. print "This program capture the image displayed"
  36. print " by a Rigol DS1000Z series oscilloscope, then save it on the computer"
  37. print " as a PNG or BMP file with a timestamp in the file name."
  38. print
  39. print " The program is using LXI protocol, so the computer"
  40. print " must have LAN connection with the oscilloscope."
  41. print " USB and/or GPIB connections are not used by this software."
  42. print
  43. print " No VISA, IVI or Rigol drivers are needed."
  44. print
  45. # Create/check if 'path' exists
  46. # Check network response (ping)
  47. response = os.system("ping -n 1 " + IP_DS1104Z + " > nul")
  48. if response != 0:
  49. print
  50. print "No response pinging " + IP_DS1104Z
  51. print "Check network cables and settings."
  52. print "You should be able to ping the oscilloscope."
  53. # Open a modified telnet session
  54. # The default telnetlib drops 0x00 characters,
  55. # so a modified library 'telnetlib_receive_all' is used instead
  56. tn = telnetlib_receive_all.Telnet(IP_DS1104Z, port)
  57. tn.write("*idn?") # ask for instrument ID
  58. instrument_id = tn.read_until("\n", 1)
  59. # Check if instrument is set to accept LAN commands
  60. if instrument_id == "command error":
  61. print instrument_id
  62. print "Check the oscilloscope settings."
  63. print "Utility -> IO Setting -> RemoteIO -> LAN must be ON"
  64. sys.exit("ERROR")
  65. # Check if instrument is indeed a Rigol DS1000Z series
  66. id_fields = instrument_id.split(",")
  67. if (id_fields[0] != "RIGOL TECHNOLOGIES") or \
  68. ((id_fields[1][:3] != "DS1") and (id_fields[1][-1] != "Z")):
  69. print
  70. print "ERROR: No Rigol from series DS1000Z found at ", IP_DS1104Z
  71. sys.exit("ERROR")
  72. print "Instrument ID:"
  73. print instrument_id
  74. # Prepare filename as C:\MODEL_SERIAL_YYYY-MM-DD_HH.MM.SS
  75. timestamp = time.strftime("%Y-%m-%d_%H.%M.%S", time.localtime())
  76. filename = path_to_save + id_fields[1] + "_" + id_fields[2] + "_" + timestamp
  77. # Ask for an oscilloscope display print screen
  78. tn.write("display:data?")
  79. print "Receiving..."
  80. buff = tn.read_until("\n", 10)
  81. # Just in case the transfer did not complete in 10 seconds
  82. while len(buff) < 1152068:
  83. tmp = tn.read_until("\n", 1)
  84. if len(tmp) == 0:
  85. break
  86. buff += tmp
  87. # Strip TMC Blockheader and last 3 bytes
  88. buff = buff[11:-3]
  89. # Save as PNG
  90. im = Image.open(StringIO.StringIO(buff))
  91. im.save(filename + ".png", "PNG")
  92. print "Saved file:", filename + ".png"
  93. # Save as BMP
  94. # scr_file = open(filename + ".bmp", "wb")
  95. # scr_file.write(buff)
  96. # scr_file.close()
  97. tn.close()
  98. # The code after this line was only for debugging purposes.
  99. # It prints the BMP header params, which are always the same.
  100. #
  101. # def print_hex(prt_buff):
  102. # print "(",
  103. # for c in prt_buff:
  104. # print hex(ord(c)),
  105. # print ")"
  106. #
  107. #
  108. # def print_dec(prt_buff):
  109. # n = 0
  110. # for c in reversed(prt_buff):
  111. # n = 256 * n + ord(c)
  112. # print n,
  113. #
  114. #
  115. # def prt_dec_hex(prt_buff):
  116. # print_dec(prt_buff)
  117. # print_hex(prt_buff)
  118. #
  119. #
  120. # def print_next_as(description, nr_of_bytes):
  121. # print description + " " * (50 - len(description)),
  122. # prt_dec_hex(buff[print_next_as.offset:print_next_as.offset+nr_of_bytes])
  123. # print_next_as.offset += nr_of_bytes
  124. # print_next_as.offset = 2
  125. #
  126. #
  127. # print
  128. # print "BMP header"
  129. # print "----------"
  130. # print "Header type: ", buff[0:2],
  131. # print_hex(buff[0:2])
  132. # print_next_as("BMP size in bytes:", 4)
  133. # print_next_as("reserved 2 bytes:", 2)
  134. # print_next_as("reserved 2 bytes:", 2)
  135. # print_next_as("Offset for BMP start of pixels array:", 4)
  136. # print
  137. # print "DIB header"
  138. # print "----------"
  139. # print_next_as("Number of DIB header bytes:", 4)
  140. # print_next_as("Image width (in pixels):", 4)
  141. # print_next_as("Image height (in pixels):", 4)
  142. # print_next_as("Number of color planes:", 4)
  143. # print_next_as("Number of bits per pixel:", 2)
  144. # print_next_as("Compression type used:", 4)
  145. # print_next_as("Size of the raw bitmap data (including padding):", 4)
  146. # print_next_as("Horizontal print resolution (pixels/meter):", 4)
  147. # print_next_as("Vertical print resolution (pixels/meter):", 4)
  148. # print_next_as("Number of colors in palette:", 4)
  149. # print_next_as("Important colors (0 means all):", 4)
  150. # print_next_as("First pixel (BGR):", 3)