HP/Agilent 33120A Unable to send arbitrary waveform - Page 1
Forum section: electronics / testgear

author: veso266
author_rank: Newbie
timestamp: May 28, 2023, 05:40:41 pm
content: Hello there, I am trying to send arbitrary waveform into HP 33120A for the past few hours nowits just a simple sine wave, nothing specialHere is my sender programCode:import mathimport serialimport osimport timeLogFilePath = 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_amplitudeif amplitude_range == 0:return waveformmax_abs_amplitude = max(abs(max_amplitude), abs(min_amplitude))normalization_factor = 1.0 / max_abs_amplitudescaled_waveform = [value * normalization_factor for value in waveform]return scaled_waveformREAL_DEVICE = True#npnts = 8000 # Define number of ASCII points in waveformnpnts = 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 = 1waveform =  * npnts # Initialize waveform list# Open COM portif 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 buffersser.write(b"*CLS\r\n") # Clear any errors, that might acumulatedser.write(b"*IDN?\r\n") # Get and Show firmware revisionif REAL_DEVICE:resp = ser.readline().strip().decode()print("Firmware revision: "+resp)ser.write(b":SYST:REM\r\n") # Enable the remote RS-232 modeser.write(b"*RST\r\n") # Reset the function generatorser.write(b"FORM:BORD SWAP\r\n") # Swap data bytes (send LSB first)ser.write(b"FREQ 5\r\n") # Output frequency is 5 Hzser.write(b"OUTP:LOAD 50\r\n") # Output termination is 50 ohmsser.write(b"VOLT 1.3\r\n") # Output amplitude is 1.3 Vpp# Calculate data pointsprint("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 memoryprint("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 waveformscaled_waveform = scale_waveform(waveform)# Print the scaled waveform without exponent notationser.write(b"DATA VOLATILE, ")for i in range(npnts - 1):ser.write("{}, ".format(scaled_waveform).encode())ser.write("{}\r\n".format(scaled_waveform[npnts - 1]).encode())#Sleep a bit, just to get the instrument a chance to breathetime.sleep(1)ser.write(b"*OPC?\r\n") # Wait for download to completeif 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 itif 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 completeresp = ser.readline().strip().decode()time.sleep(1) #Sleep a bit, just to get the instrument a chance to process what we have thrown at itprint("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_SINser.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 arbser.write(b"VOLT:OFFS 0.7\r\n") # Offset is 0.7Vser.write(b"FREQ 5\r\n") # Output frequency is 5 Hz#Sleep a bit, just to get the instrument a chance to breathetime.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 itif 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 completeresp = ser.readline().strip().decode()time.sleep(1) #Sleep a bit, just to get the instrument a chance to process what we have thrown at itprint("Program did not complete, ERROR CODE: " + resp)if REAL_DEVICE:ser.write(b"SYST:ERR?\r\n") # Wait for download to completeresp = ser.readline().strip().decode()time.sleep(1) #Sleep a bit, just to get the instrument a chance to process what we have thrown at itif 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 modeprint("Good by")ser.close() # Close the COM portlogger.close()#If log file is empty, delete itemsif 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 8everything works finebut 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 itI mean, the manual says that I can send 16000 points into this device and my waveform can look like thisCode:Waveform Length: 8 to 16,000 pointsAmplitude resolution: 12 bits (including sign)Sample rate: 40 MSa / secNumber of points: 16,000thats sample rate of 16khz of signalSo not sure whats wrong, and why I cannot even send 16Hz signal to my generatorThanks for Anwsering and Best Regards

author: gslick
author_rank: Frequent Contributor
timestamp: May 29, 2023, 01:16:41 am
content: You probably need to make sure you are using a full hardware handshake null-modem cable, and enable DSR/DTR flow control. Otherwise you will overflow the input buffer on the 33120A.Code:ser = serial.Serial('COM30', 9600, dsrdtr=True)

author: veso266
author_rank: Newbie
timestamp: May 29, 2023, 11:58:06 am
content: Quote from: gslick on May 29, 2023, 01:16:41 amOh dammit, I never thought of that, I did try to enable Hardware flow control in HyperTerminal and it does work there just fine, but if I enable it inside python, I cannot comunicate with an instrumentI am using this some LogiLink serial usb converter:https://www.amazon.com/LogiLink-Adapter-USB-Seriell-UA0042A/dp/B00CBTE3T2which has Prolific PL2303TA chipset inside and according to its datasheet:https://cdn-shop.adafruit.com/datasheets/DS_PL2303TA_d20120504.pdfHardware flow control is supportedWhy does Hardware flow control work in HyperTerminal and not in Python?Also when trying Hercules program (which also shows you CTS/RTS lights) with Hardware flow control:https://www.hw-group.com/software/hercules-setup-utilityIt does appear to work:https://imgur.com/a/GZbf7gBThe device does respons and lights are onSo now I am realy confusedIs there any example in low level c or something like that, just to figure out if my adapter is at fault (because its realy wierd that some programs do appear to work, while others don't)