xyphro / UsbGpib

Versatile, cheap and portable USB to GPIB converter (USBTMC class based)
MIT License
289 stars 51 forks source link

gpib adapter stops responding when script runs twice for setting firmware parameters #58

Open dazz100 opened 8 months ago

dazz100 commented 8 months ago

Hi I have encountered a problem where re-running a simple script causes the gpib firmware to time out and stop responding to commands. This occurs when the same simple script is run more than once. The script sets up the gpib adapter firmware, then reads the frequency once. That is all it does.

I have an adapter that is plugged into an Electro-Metrics Interference Analyser model EMC-30. It can be viewed here: https://www.eevblog.com/forum/testgear/electro-metrics-em-30-emc-receiver/
Basically it is a 1980's over-engineered radio receiver. Probably me and no-one else is trying to run gpib with it. It has a very basic, but adequate gpib command set. There are features that can only be controlled via gpib.

The EMC-30 was available with optional PC software that ran with the gpib. For that reason, I am reasonably confident the gpib firmware works but I could be wrong.

I am writing short scripts to test each command. There is no "ID" command or auto-ID feature. I can read the set frequency.

This is the output when the script succeeds:

D:\darren\My Documents\Electronics\Electro-Metrics EMC-30\GPIB_Test>python EMC30_gpib_rd_STATUS.py
###### Simple GPIB test for emc30
# Executes read STATUS

# Show the list of Resources
('USB0::0x03EB::0x2065::GPIB_15_24238323232351C01171::INSTR', 'ASRL1::INSTR')
# Opening the emc30

Set Auto ID = off
Set Line Feed = on
Save settings to eeprom
Read emc-30 status
4
0.11617

The script runs to completion and outputs the band (4) and the frequency (0.11617MHz) exactly as expected. The script works.

This is the output when the exact same script fails:

D:\darren\My Documents\Electronics\Electro-Metrics EMC-30\GPIB_Test>python EMC30_gpib_rd_STATUS.py
###### Simple GPIB test for emc30
# Executes read STATUS

# Show the list of Resources
('USB0::0x03EB::0x2065::GPIB_15_24238323232351C01171::INSTR', 'ASRL1::INSTR')
# Opening the emc30

Set Auto ID = off
Set Line Feed = on
Save settings to eeprom
Traceback (most recent call last):
  File "D:\darren\My Documents\Electronics\Electro-Metrics EMC-30\GPIB_Test\EMC30_gpib_rd_STATUS.py", line 49, in <module>
    emc30.write('!term store')
  File "G:\Programs\Python310\Lib\site-packages\pyvisa\resources\messagebased.py", line 196, in write
    count = self.write_raw(message.encode(enco))
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "G:\Programs\Python310\Lib\site-packages\pyvisa\resources\messagebased.py", line 156, in write_raw
    return self.visalib.write(self.session, message)[0]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "G:\Programs\Python310\Lib\site-packages\pyvisa\ctwrapper\functions.py", line 2795, in write
    ret = library.viWrite(session, data, len(data), byref(return_count))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "G:\Programs\Python310\Lib\site-packages\pyvisa\ctwrapper\highlevel.py", line 226, in _return_handler
    return self.handle_return_value(session, ret_value)  # type: ignore
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "G:\Programs\Python310\Lib\site-packages\pyvisa\highlevel.py", line 251, in handle_return_value
    raise errors.VisaIOError(rv)
pyvisa.errors.VisaIOError: VI_ERROR_TMO (-1073807339): Timeout expired before operation completed.

The script always fails when an attempt is made to save the parameters to eeprom. This happens before any attempt is made to communicate (send commands) to the emc-30. It never gets to the part of the script that sends the frequency read (FR) command. It is for this reason that I suspect a bug with the firmware. I suspect is is related to the save to eeprom part of the code.

I can reproduce the bug by running the test script twice. I can clear the problem by switching off the emc-30 for about 15 seconds and then switch on power.

My test script is below. This should work with any instrument by changing the "FR" command to something else (eg. "ID")

# EMC30 simple READ FREQUENCY command test
# ver 0.1 date 13 Mar 24
# The purpose of this script is to read the frequency

import pyvisa
import time
from timeit import default_timer as timer
# CMD commands to run
# D:
# cd \My Documents\Electronics\Electro-Metrics EMC-30\GPIB_Test
# python EMC30_gpib_rd_FREQ.py

# User Editable Variables
pause = 1       # Edit this.  This is the pause from the end of one query to the next.  
                # It is the time taken for the instrument to be ready for the next query.

# ID string for adapter 0:  'USB0::0x03EB::0x2065::GPIB_23_24238323232351C01171::INSTR'
# unique for each adapter

print("###### Simple GPIB test for emc30")
print("# Executes read FR")
print()
print("# Show the list of Resources")
rm = pyvisa.ResourceManager()
print(rm.list_resources())

print("# Opening the emc30")
# Resource = GPIB-usb adapter 0.  Different for each adapter.

emc30 = rm.open_resource('USB0::0x03EB::0x2065::GPIB_15_24238323232351C01171::INSTR', send_end=False,)
print()
time.sleep(pause)

print("Set Auto ID = off")
emc30.control_in(0xa1, 0x40, 0, 0, 1);                    # no autoid, 
emc30.write('!autoid off')
time.sleep(pause)

print("Set Line Feed = on")
emc30.control_in(0xa1, 0x40, 0, 0, 1); # set read termination to LF
emc30.write('!term lf')
time.sleep(pause)

print("Save settings to eeprom")  #this section is where a timeout occurs. 
emc30.control_in(0xa1, 0x40, 0, 0, 1); # Save readtermination setting in eeprom (non volatile)
emc30.write('!term store')
time.sleep(pause)

emc30.write_termination = '\r\n'
emc30.read_termination = '\n'
emc30.timeout = 1000         #sets 1s timeout for the meter after the read

print("Read emc-30 status")
print(emc30.write("FR") )   #Write the frequency read command
print(emc30.read())           # read the band and frequency

#emc30.clear()
rm.close()

Is there something I can do the help analyse and troubleshoot this issue?

Dazz

dazz100 commented 8 months ago

Hi Some further tests point to the following statements being the source of the issue:

print("Save settings to eeprom")
emc30.control_in(0xa1, 0x40, 0, 0, 1);    # Save readtermination setting in eeprom (non volatile)
emc30.write('!term store')
time.sleep(pause)

Also, unplugging the adapter from the PC, and plugging back in again allows the script to run normally. Cycling power on the emc-30 is not necessary. This indicates the receiver is OK and probably not the cause of the issue.

xyphro commented 8 months ago

Hi Dazz,

So when you remove term store it works multiple times after each other as intended? Can you confirm? This would ease my bugfixing.

Best regards,

Kai Ps: Can you set write termination to "" right after connecting to the instrument and try it again? Suspicion is that the residual CRLF added by pyvisa might make the firmware hang. I tested it only with eoi termination, so this is my strong root cause suspicion. Easy to fix for me if this is the case.

xyphro commented 8 months ago

Btw: Thanks for this excellent quality style of issue description!

xyphro commented 8 months ago

TestAndMeasurement_Dazz&Maurice.zip

In case my suspicion is true and your experiments turn out to confirm this. Then this might be the fix.

I cannot test this today, but can try during the week. But I don't want to block you from getting a potential bugfix.

Best regards,

Kai

dazz100 commented 8 months ago

Hi The No.1 adapter is effectively bricked at present. I can't rule out a hardware fault.

I switched to a No.2 adapter. This one programs correctly. No error messages. I ran the following program to return the resource ID:

# EMC30 Select antenna test
import pyvisa
print("# Show the list of Resources")
rm = pyvisa.ResourceManager()
print(rm.list_resources())

exit()

The response was:

D:\My Documents\Electronics\Electro-Metrics EMC-30\GPIB_Test>python EMC30_gpib_select_antenna.py
Simple GPIB test to select antenna switch and antenna
# Show the list of Resources
('ASRL1::INSTR',)

No returned resource ID.
The red LED is flashing slow with the EMC-30 powered on. When I switch off power to the EMC-30, the red LED flashes fast. My current hypothesis is that adapter No.2 has a hardware fault that is not reading one of the gpib control lines from the EMC-30. I need to study the code to figure out what signal the adapter is looking for, to go from slow flash LED to steady on.

If others see or don't see the same symptoms, that would help identify whether this is a hardware/software fault. Dazz