Hi Everybody,
For a project I’m working on, I’m connected to an IMU sensor through my computer’s USB port. I’m using pyserial to read in the data. I’m able to successfully run and print the data to my console when I change the BooleanSwitch from off to on, however, I haven’t figured out a way yet to shut it off. Here is my question:
- How would I properly stop reading the data and close the serial connection once the switch goes from True to False?
I’m including some code to help clarify what it is I’m doing:
boolean_switch_serial_read.py
import dash
import dash_daq as daq
import dash_html_components as html
from dash.dependencies import Input, Output
import time
import serial_read
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
daq.BooleanSwitch(
id='my-boolean-switch',
on=False
),
html.Div(id='boolean-switch-output'),
html.Button(id='button',n_clicks=0,style={'display': 'none'}),
html.Div(id='dummy-div',style={'display':'none'})
])
@app.callback(
[Output('boolean-switch-output', 'children'),
Output('button','n_clicks')],
[Input('my-boolean-switch', 'on')])
def update_output(on):
if on:
n=1
else:
n=0
output_string = 'The switch is {}.'.format(on)
return (output_string,n)
@app.callback(
Output('dummy-div','children'),
[Input('button','n_clicks')]
)
def read_serial_data(n):
try:
if n==0:
raise KeyboardInterrupt
serial_read.save_serial_data('data/test3.csv','foo',n)
return None
except:
raise dash.exceptions.PreventUpdate
if __name__ == '__main__':
app.run_server(debug=True)
serial_read.py
import serial
import time
import csv
def save_serial_data(fn,port,n):
filename = fn
com_port = '/dev/cu.usbserial-DB00X8WD'
with serial.Serial(com_port, 115200, timeout=0, parity=serial.PARITY_NONE, rtscts=0) as ser: # this needs to match Arduino settings
ser.flushInput()
line = []
with open(filename, 'w+', newline='') as myfile:
wr = csv.writer(myfile)
wr.writerow('6666')
t = time.time()
print("The button value being passed is {}".format(n))
flag=True
while flag:
try:
for c in ser.read().decode('utf-8'):
line.append(c)
if c == "\n":
newline = ''.join(line)
newline4 = newline[0:len(newline) - 3]
res = [float(idx) for idx in newline4.split(',')]
t_elapsed = time.time() - t
t_elapsed = float("{:.4f}".format(t_elapsed))
wr.writerow([t_elapsed] + res)
print([t_elapsed] + res)
line = []
break
except Exception as e:
print("Keyboard Interrupt")
print(e)
ser.close()
flag = False
print(flag)
ser.close()
One observation I made is that it seems my code will stop reading the data once I toggle the switch from on to off back to on again, which doesn’t completely make sense to me. I think one of my issues is that I’m not properly closing the serial connection before I open up a new connection. Here is the exception error I’m getting:
The button value being passed is 1
Keyboard Interrupt
read failed: device reports readiness to read but returned no data (device disconnected or multiple access on port?)
If anybody has some ideas how to resolve this issue, I’d really appreciate any suggestions. Thanks!!
Ben