Hello there, I am trying to send arbitrary waveform into HP 33120A for the past few hours now
its just a simple sine wave, nothing special
Here is my sender program
import math
import serial
import os
import time
LogFilePath = os.path.dirname(os.path.realpath(__file__)) + "\\"
LogFile = LogFilePath + "log.txt"
logger = open(LogFile, "a")
def scale_waveform(waveform):
max_amplitude = max(waveform)
min_amplitude = min(waveform)
amplitude_range = max_amplitude - min_amplitude
if amplitude_range == 0:
return waveform
max_abs_amplitude = max(abs(max_amplitude), abs(min_amplitude))
normalization_factor = 1.0 / max_abs_amplitude
scaled_waveform = [value * normalization_factor for value in waveform]
return scaled_waveform
REAL_DEVICE = True
#npnts = 8000 # Define number of ASCII points in waveform
npnts = 8 # Define number of ASCII points in waveform (SampleRate {MIN=8Hz, MAX=16kHz)
NCYCLES = 4 # Define number of cycles (Frequency of the Sinewave (1Hz = 1 Cycle)
amplitudeGain = 1
waveform = [0] * npnts # Initialize waveform list
# Open COM port
if REAL_DEVICE:
ser = serial.Serial('COM30', 9600, stopbits=2)
else:
ser = serial.Serial('COM1', 9600)
#logger.write("test")
print("Connection successful at: {} {} {}N{}".format(ser.port, ser.baudrate, ser.bytesize, ser.stopbits))
ser.write(b"\r") # Clear any buffers
ser.write(b"*CLS\r\n") # Clear any errors, that might acumulated
ser.write(b"*IDN?\r\n") # Get and Show firmware revision
if REAL_DEVICE:
resp = ser.readline().strip().decode()
print("Firmware revision: "+resp)
ser.write(b":SYST:REM\r\n") # Enable the remote RS-232 mode
ser.write(b"*RST\r\n") # Reset the function generator
ser.write(b"FORM:BORD SWAP\r\n") # Swap data bytes (send LSB first)
ser.write(b"FREQ 5\r\n") # Output frequency is 5 Hz
ser.write(b"OUTP:LOAD 50\r\n") # Output termination is 50 ohms
ser.write(b"VOLT 1.3\r\n") # Output amplitude is 1.3 Vpp
# Calculate data points
print("Calculating Data Points...")
for i in range(1, npnts + 1):
waveform[i - 1] = math.sin(2 * math.pi * NCYCLES * i / npnts)# * amplitudeGain
# Download data points to volatile memory
print("Downloading Arb... with length: " + str(len(waveform)))
#logger.write("This will write into file named log.txt inside script directory")
#ser.write(b"DATA VOLATILE, 0,0,0,0,0,0,0,0")
#ser.write(b"DATA VOLATILE, 0.125,-0.25,0.375,-0.5,0.625,-0.75,0.875,-1")
# Scale the waveform
scaled_waveform = scale_waveform(waveform)
# Print the scaled waveform without exponent notation
ser.write(b"DATA VOLATILE, ")
for i in range(npnts - 1):
ser.write("{}, ".format(scaled_waveform[i]).encode())
ser.write("{}\r\n".format(scaled_waveform[npnts - 1]).encode())
#Sleep a bit, just to get the instrument a chance to breathe
time.sleep(1)
ser.write(b"*OPC?\r\n") # Wait for download to complete
if REAL_DEVICE:
resp = ser.readline().strip().decode()
#print(resp)
time.sleep(1) #Sleep a bit, just to get the instrument a chance to process what we have thrown at it
if resp == '1':
print("Download Complete")
ser.write(b'DISP:TEXT "WAVEFORM DL"\r\n')
else:
ser.write(b"SYST:ERR?\r\n") # Wait for download to complete
resp = ser.readline().strip().decode()
time.sleep(1) #Sleep a bit, just to get the instrument a chance to process what we have thrown at it
print("Download did not complete, ERROR CODE: " + resp)
#Don't abuse poor FLASH inside the device if you are only testing
#If you want to save your waveform permanantly you can uncomment this
#ser.write(b"DATA:COPY DAMP_SIN, VOLATILE\r\n") # Copy to non-volatile memory
#ser.write(b"FUNC:USER DAMP_SIN\r\n") # Select the active arb
#Usefull commands to delete/cat/select Waveforms already in FLASH
#List all uvailable Waveforms: DATA:CAT?
#Delete user Waveform: DATA:DEL DAMP_SIN
ser.write(b"FUNC:USER VOLATILE\r\n") # Select the recently downlowded Waveform (Comment this if you want to select already saved waveform)
ser.write(b"FUNC:SHAP USER\r\n") # Output the selected arb
ser.write(b"VOLT:OFFS 0.7\r\n") # Offset is 0.7V
ser.write(b"FREQ 5\r\n") # Output frequency is 5 Hz
#Sleep a bit, just to get the instrument a chance to breathe
time.sleep(1)
ser.write(b"*OPC?\r\n")
if REAL_DEVICE:
resp = ser.readline().strip().decode()
time.sleep(1) #Sleep a bit, just to get the instrument a chance to process what we have thrown at it
if resp == '1':
print("Program Complete")
ser.write(b'DISP:TEXT "WAVEFORM OK"\r\n')
else:
ser.write(b"SYST:ERR?\r\n") # Wait for download to complete
resp = ser.readline().strip().decode()
time.sleep(1) #Sleep a bit, just to get the instrument a chance to process what we have thrown at it
print("Program did not complete, ERROR CODE: " + resp)
if REAL_DEVICE:
ser.write(b"SYST:ERR?\r\n") # Wait for download to complete
resp = ser.readline().strip().decode()
time.sleep(1) #Sleep a bit, just to get the instrument a chance to process what we have thrown at it
if resp == '+0,"No error"':
print("Enjoy your waveform :)")
else:
print("Something is wrong, ERROR CODE: " + resp)
print("Just incase you forgot to press BLUE SHIFT button, to enable LOCAL mode again, I did that for you")
ser.write(b"SYSTEM:LOCAL\r\n") # Enable the remote RS-232 mode
print("Good by")
ser.close() # Close the COM port
logger.close()
#If log file is empty, delete items
if os.stat(LogFile).st_size == 0:
print("Empty file")
os.remove(LogFile)
if sinewave points (npnts) are small like the minimum you can send, like 8
everything works fine
but as soon as I increase number of points to something bigger like 16 then the instrument is throwing: +521,"Input buffer overflow"
I think my scaling function stops working at higher points, but not sure how to fix it
I mean, the manual says that I can send 16000 points into this device and my waveform can look like this
Waveform Length: 8 to 16,000 points
Amplitude resolution: 12 bits (including sign)
Sample rate: 40 MSa / sec
Number of points: 16,000
thats sample rate of 16khz of signal
So not sure whats wrong, and why I cannot even send 16Hz signal to my generator
Thanks for Anwsering and Best Regards