#  
# M.Mastrofini Example of Scope remote control using Python
#  July 2014 -  ver 1.0
#  example using direct commands and VBS commands
#  Wincom extension must be installed
#
import win32com.client #imports the pywin32 library
scope=win32com.client.Dispatch("LeCroy.ActiveDSOCtrl.1")  #creates instance of the ActiveDSO control
scope.MakeConnection("IP:127.0.0.1") #Connects to the oscilloscope.  Substitute your IP address
import re
import binascii
import functools
import numpy
import matplotlib.pyplot as plt
scope.WriteString("VBS 'app.Acquisition.C1.VerScale = 0.2'",1)
CMD="VBS "+"'app.Display.GridMode = " +'"Quad"'+"'"
print(CMD)
scope.WriteString(CMD,1)

value = "example of acquisition synchronization using *OPC?"
scope.WriteString("COMM_HEADER OFF",1)
scope.WriteString("COMM_FORMAT DEF9,Byte,BIN",1) # set scope to format header off and #word (2 bytes x sample) data transfer
#
#scope.WriteString("COMM_FORMAT OFF, BYTE, BIN",1) # set scope to format header off and word (1 bytes x sample) data transfer
#
# stop trigger and check if the scope is in stop mode
# during long acquisitions the scope may still be recording data
#
#scope.WriteString("TRMD STOP",1)
#value = ""
#scope.WriteString("TRMD?",1)
#value = scope.ReadString(80)
#while value != "STOP":
#    scope.WriteString("TRMD?",1)
#    value = scope.ReadString(80)
#print (value)
# Scope is now in idle mode
#scope.WriteString("TRMD SINGLE",1)
#scope.WriteString("TRMD?",1)
#value = "now scope is in " + scope.ReadString(80) + " trigger mode"
#print (value)
#value = ""
# Arming trigger and sedn wait command, in order to respond With 1 to *OPC? only when operation is completed
#scope.WriteString("ARM;WAIT",1)
#print ("scope armed, waiting for OPC ")
#while value != "1":
#    scope.WriteString("*OPC?",1)
##    value = scope.ReadString(1)
###print (" opc = " + value)
####print ( " scope has captured a waveform")
#value = " "
scope.WriteString("CFMT?",1)
value = scope.ReadString(80)
print (value)
scope.WriteString("VBS? 'return=app.Acquisition.C3.VerScale",1)
value = scope.ReadString(80)
print (value)
vertical_Scale= float(value)
scope.WriteString("VBS? 'return=app.Acquisition.Horizontal.HorScale",1)
value = scope.ReadString(80)
T= float(value)
print (T)
scope.WriteString("C3:WF? DAT1",1)
#read first 15 bytes, to determine how many bytes need to be transferred 
header = scope.ReadBinary(16)
print (header)
rlen = int(header[7:16]) 
print (rlen)
T0=-T*5
print (T0)
T1=T*5
print (T1)
#read from scope the waveform data
dataword = scope.ReadBinary(rlen)
rlen = rlen -2
print (rlen)
# converting the binary data to 8 bit integers because reading 1 byte per sample. Modify accordingly if reading 2 byte per sample
#assuming we have 500 horizontal pixels, so we have 250 max values and 250 min values to plot. we have to divide rlen in 250 segments
# setting segments to 2000, we assume 2000 horizontal pixels are available for plotting
segments = 2000
points_in_segment=int(rlen/(segments*2))
print (points_in_segment)
vector_to_plot =numpy.zeros(segments)
# A better algorithm can be found to make sure we have a number of points_in_segment
# which is an interg submultiple of the record length rlen
# N pixels available, N/2 for max and N/2 for min
for k in range(0,segments/2):
    subdata = dataword[(k)*points_in_segment:(k+1)*points_in_segment]
    subdata =  numpy.fromstring(subdata, dtype=numpy.int8)   
# in each segment search max and min value, and index of them in the vector
    Imax= numpy.argmax(subdata)
    Max = subdata[Imax]
    Imin= numpy.argmin(subdata)
    Min = subdata[Imin]
    #print (Max, Min)
# decide waht comes first in plot Min or Max
    if Imax > Imin:
        vector_to_plot[2*k]= Min
        vector_to_plot[2*k+1] =Max
    else:
        vector_to_plot[2*k]= Max
        vector_to_plot[2*k+1] =Min
        
    
#rescale vertical data to match vertical scale on scope        
vector_to_plot = vector_to_plot * vertical_Scale/30
x=numpy.arange(T0, T1, segments)# horizontal scale vector in uS -  a range in number of samples = segments
plt.ylim(-vertical_Scale*4,vertical_Scale*4)
plt.xlim(0, segments)
plt.plot(vector_to_plot)
plt.show()
