A measuring instrument (Ahlborn ALMEMO 2690) connected via RS232 works with pyvisa & plotly Dash (tested simplified python code examples used):
import pyvisa
from pyvisa.constants import StopBits, Parity
import time
from dash import Dash, html, dcc, callback, Output, Input
rm = pyvisa.ResourceManager('@py')
# Ahlborn ALMEMO 2690 over RS232 @ 115200 bd 8N1
measuring_instrument = rm.open_resource('ASRL/dev/ttyS0::INSTR', baud_rate=115200, data_bits=8, parity=Parity.none, stop_bits=StopBits.one)
measuring_instrument.read_termination = '' # required character(s), see manual of measuring_instrument: none required for RS232
measuring_instrument.write_termination = '' # required character(s), see manual of measuring_instrument: none required
measuring_instrument.write('f1G02') # init_string, see manual of measuring_instrument
timer1 = time.time() # time.time() uses float in seconds: 1 = 1 s
cycle_time = 0.5 # measurement cycle time, given in seconds as float value
cycle_time_ms = int(cycle_time * 1000) # measurement cycle time, given in milliseconds (integer)
app = Dash(__name__)
app.layout = html.Div(
html.Div([
dcc.Interval(
id='interval',
interval = cycle_time_ms, #measurement cycle time, given in milliseconds (integer)
n_intervals = 0
),
html.Div(id='measurement_instrument_output'),
])
)
@app.callback(
Output(component_id='measurement_instrument_output', component_property='children'),
[Input(component_id='interval', component_property='n_intervals')]
)
def update(n_intervals):
measuring_instrument.flush(pyvisa.constants.BufferOperation.discard_read_buffer) # clearing read_buffer, required
measuring_instrument.write('S1') # send_string, see manual of measuring_instrument
time.sleep(0.02) # depends on instrument transfer speed
value0 = measuring_instrument.read(encoding='iso-8859-15') # value0 = send_string, should be neglected
value1 = measuring_instrument.read(encoding='iso-8859-15') # value1 = response_string, required
return (value1)
if __name__ == '__main__':
app.run_server(debug=True)
If connection of this measuring instrument is switched to ethernet it works with pyvisa and without Dash:
import pyvisa
import time
rm = pyvisa.ResourceManager('@py')
# Ahlborn ALMEMO 2690 over ethernet @ TCP/IP 192.168.0.240:10001
measuring_instrument = rm.open_resource('TCPIP::192.168.0.240::10001::SOCKET') # TCPIP::192.168.0.240::INSTR doesn't work!
measuring_instrument.read_termination = '\n' # required character(s), see manual of measuring_instrument: \n required for ethernet
measuring_instrument.write_termination = '' # required character(s), see manual of measuring_instrument: none required
measuring_instrument.write('f1G02') # init_string, see manual of measuring_instrument
timer1 = time.time() # time.time() uses float in seconds: 1 = 1 s
cycle_time = 0.5 # measurement cycle time, given in seconds as float value
while True:
timer2 = time.time()
diff = timer2 - timer1
if diff >= cycle_time:
timer1 = time.time()
measuring_instrument.flush(pyvisa.constants.BufferOperation.discard_read_buffer) # clearing read_buffer, required
measuring_instrument.write('S1') # send_string, see manual of measuring_instrument
time.sleep(0.02) # depends on instrument transfer speed
value0 = measuring_instrument.read(encoding='iso-8859-15') # value0 = send_string, should be neglected
value1 = measuring_instrument.read(encoding='iso-8859-15') # value1 = response_string, required
print(value1)
But it doesn’t work if Dash is added to pyvisa with use of TCPIP SOCKET:
import pyvisa
import time
from dash import Dash, html, dcc, callback, Output, Input
rm = pyvisa.ResourceManager('@py')
# Ahlborn ALMEMO 2690 over ethernet @ TCP/IP 192.168.0.240:10001
measuring_instrument = rm.open_resource('TCPIP::192.168.0.240::10001::SOCKET') # TCPIP::192.168.0.240::INSTR doesn't work!
measuring_instrument.read_termination = '\n' # required character(s), see manual of measuring_instrument: \n required for ethernet
measuring_instrument.write_termination = '' # required character(s), see manual of measuring_instrument: none required
measuring_instrument.write('f1G02') # init_string, see manual of measuring_instrument
timer1 = time.time() # time.time() uses float in seconds: 1 = 1 s
cycle_time = 0.5 # measurement cycle time, given in seconds as float value
cycle_time_ms = int(cycle_time * 1000) # measurement cycle time, given in milliseconds (integer)
app = Dash(__name__)
app.layout = html.Div(
html.Div([
dcc.Interval(
id='interval',
interval = cycle_time_ms, #measurement cycle time, given in milliseconds (integer)
n_intervals = 0
),
html.Div(id='measurement_instrument_output'),
])
)
@app.callback(
Output(component_id='measurement_instrument_output', component_property='children'),
[Input(component_id='interval', component_property='n_intervals')]
)
def update(n_intervals):
measuring_instrument.flush(pyvisa.constants.BufferOperation.discard_read_buffer) # clearing read_buffer, required
measuring_instrument.write('S1') # send_string, see manual of measuring_instrument
time.sleep(0.02) # depends on instrument transfer speed
value0 = measuring_instrument.read(encoding='iso-8859-15') # value0 = send_string, should be neglected
value1 = measuring_instrument.read(encoding='iso-8859-15') # value1 = response_string, required
return (value1)
if __name__ == '__main__':
app.run_server(debug=True)
Console shows error output:
Dash is running on http://127.0.0.1:8050/
- Serving Flask app ‘pyVISA-example12’
- Debug mode: on
Traceback (most recent call last):
File “/home/user/testing/pyVISA-example12.py”, line 10, in
measuring_instrument.write(‘f1G02’) # init_string, see manual of measuring_instrument
File “/home/user/.local/lib/python3.9/site-packages/pyvisa/resources/messagebased.py”, line 197, in write
count = self.write_raw(message.encode(enco))
File “/home/user/.local/lib/python3.9/site-packages/pyvisa/resources/messagebased.py”, line 157, in write_raw
return self.visalib.write(self.session, message)[0]
File “/home/user/.local/lib/python3.9/site-packages/pyvisa_py/highlevel.py”, line 543, in write
written, status_code = self.sessions[session].write(data)
File “/home/user/.local/lib/python3.9/site-packages/pyvisa_py/tcpip.py”, line 1246, in write
size = self.interface.send(block)
ConnectionRefusedError: [Errno 111] Connection refused
Tests with “tcpdump port 10001”:
Sucessfully running with pyvisa and without plotly Dash (second code example) gives tcpdump output like this:
18:13:12.213717 IP pc-008.ffi.52140 > localhost.10001: Flags [S], seq 1288963231, win 32120, options [mss 1460,sackOK,TS val 2662383994 ecr 0,nop,wscale 7], length 0
18:13:12.213921 IP localhost.10001 > pc-008.ffi.52140: Flags [S.], seq 109609790, ack 1288963232, win 2047, options [mss 1400], length 0
18:13:12.213935 IP pc-008.ffi.52140 > localhost.10001: Flags [.], ack 1, win 32120, length 0
18:13:12.213985 IP pc-008.ffi.52140 > localhost.10001: Flags [P.], seq 1:6, ack 1, win 32120, length 5
18:13:12.225047 IP localhost.10001 > pc-008.ffi.52140: Flags [.], ack 6, win 2047, length 0
18:13:12.246031 IP localhost.10001 > pc-008.ffi.52140: Flags [P.], seq 1:46, ack 6, win 2047, length 45
18:13:12.246035 IP pc-008.ffi.52140 > localhost.10001: Flags [.], ack 46, win 32075, length 0
18:13:12.814168 IP pc-008.ffi.52140 > localhost.10001: Flags [P.], seq 6:8, ack 46, win 32075, length 2
18:13:12.818130 IP localhost.10001 > pc-008.ffi.52140: Flags [P.], seq 46:50, ack 8, win 2047, length 4
18:13:12.818137 IP pc-008.ffi.52140 > localhost.10001: Flags [.], ack 50, win 32071, length 0
18:13:12.838996 IP localhost.10001 > pc-008.ffi.52140: Flags [P.], seq 50:86, ack 8, win 2047, length 36
18:13:12.839003 IP pc-008.ffi.52140 > localhost.10001: Flags [.], ack 86, win 32035, length 0
18:13:13.314131 IP pc-008.ffi.52140 > localhost.10001: Flags [P.], seq 8:10, ack 86, win 32035, length 2
18:13:13.318094 IP localhost.10001 > pc-008.ffi.52140: Flags [P.], seq 86:90, ack 10, win 2047, length 4
18:13:13.318101 IP pc-008.ffi.52140 > localhost.10001: Flags [.], ack 90, win 32031, length 0
Failing with pyvisa and with plotly Dash (third code example) gives tcpdump output like this:
18:13:41.013417 IP pc-008.ffi.46106 > localhost.10001: Flags [S], seq 1702851283, win 32120, options [mss 1460,sackOK,TS val 2662412794 ecr 0,nop,wscale 7], length 0
18:13:41.013622 IP localhost.10001 > pc-008.ffi.46106: Flags [S.], seq 119103457, ack 1702851284, win 2047, options [mss 1400], length 0
18:13:41.013636 IP pc-008.ffi.46106 > localhost.10001: Flags [.], ack 1, win 32120, length 0
18:13:41.013691 IP pc-008.ffi.46106 > localhost.10001: Flags [P.], seq 1:6, ack 1, win 32120, length 5
18:13:41.024431 IP localhost.10001 > pc-008.ffi.46106: Flags [.], ack 6, win 2047, length 0
18:13:41.045419 IP localhost.10001 > pc-008.ffi.46106: Flags [P.], seq 1:46, ack 6, win 2047, length 45
18:13:41.045427 IP pc-008.ffi.46106 > localhost.10001: Flags [.], ack 46, win 32075, length 0
18:13:41.438377 IP pc-008.ffi.46116 > localhost.10001: Flags [S], seq 391207644, win 32120, options [mss 1460,sackOK,TS val 2662413218 ecr 0,nop,wscale 7], length 0
18:13:41.438663 IP localhost.10001 > pc-008.ffi.46116: Flags [R.], seq 0, ack 391207645, win 0, length 0
18:13:41.499507 IP pc-008.ffi.46106 > localhost.10001: Flags [R.], seq 6, ack 46, win 32075, length 0
Presence of plotly Dash results in a second try with a SYN packet that is responded with two RST packets. This seems to be the problem and how can it be solved?