我使用Arduino通过I2C与传感器通信。从传感器获取数据后,Arduino通过串行通信将其输出为字符串。字符串看起来像这样:
"-3.46,-8.4,4.64,7.5,35.3,4.32,-9.0,\r\n"
然后我使用Python来读取传入的数据,将其分段(丢弃\r\n
),然后通过matplotlib.animation
实时显示用户选择的数据集。在我的计算机上使用脚本时,它工作正常,但在尝试在另一台计算机上使用它时,我收到一个Tkinter回调异常错误。
Python脚本:
port = 'com4' # Configure which port the Arduino is connected to.
baud = 19200 # Configure baud rate
ind = 0 # Determine which data point you want displayed on the graph. [0-6]
import numpy as np
from matplotlib.lines import Line2D
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import serial
import time
import re
import xlwt
if serial.Serial(port,baud).is_open:
serial.Serial(port,baud).close()
ser = serial.Serial(port,baud,timeout=1)
ser.reset_input_buffer()
ser.readline()
class Scope(object):
def __init__(self, ax, maxt=4, dt=0.04):
self.ax = ax
self.dt = dt
self.maxt = maxt
self.tdata = [-dt]
self.ydata = [0]
self.line = Line2D(self.tdata, self.ydata)
self.ax.add_line(self.line)
self.ax.set_ylim(yMin, yMax)
self.ax.set_xlim(0, self.maxt)
def update(self, y):
lastt = self.tdata[-1]
if lastt > self.tdata[0] + self.maxt: # reset the arrays
self.tdata = [self.tdata[-1]]
self.ydata = [self.ydata[-1]]
self.ax.set_xlim(self.tdata[0], self.tdata[0] + self.maxt)
self.ax.figure.canvas.draw()
t = self.tdata[-1] + self.dt
self.tdata.append(t)
tArray.append(t)
self.ydata.append(y)
self.line.set_data(self.tdata, self.ydata)
return self.line,
def emitter():
while True:
val = ser.readline()
allData = val.split(",")
yArray.append(allData[:-1]) # discarding return line characters from the serial read.
yield allData[ind]
fig, ax = plt.subplots()
scope = Scope(ax)
# pass a generator in "emitter" to produce data for the update func
ani = animation.FuncAnimation(fig, scope.update, emitter, interval=10,blit=True)
plt.show()
print yArray
错误讯息:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1542, in __call__
return self.func(*args)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 592, in callit
func(*args)
File "C:\Python27\lib\site-packages\matplotlib\backends\_backend_tk.py", line 88, in _on_timer
TimerBase._on_timer(self)
File "C:\Python27\lib\site-packages\matplotlib\backend_bases.py", line 1373, in _on_timer
ret = func(*args, **kwargs)
File "C:\Python27\lib\site-packages\matplotlib\animation.py", line 1481, in _step
still_going = Animation._step(self, *args)
File "C:\Python27\lib\site-packages\matplotlib\animation.py", line 1217, in _step
self._draw_next_frame(framedata, self._blit)
File "C:\Python27\lib\site-packages\matplotlib\animation.py", line 1237, in _draw_next_frame
self._post_draw(framedata, blit)
File "C:\Python27\lib\site-packages\matplotlib\animation.py", line 1260, in _post_draw
self._blit_draw(self._drawn_artists, self._blit_cache)
File "C:\Python27\lib\site-packages\matplotlib\animation.py", line 1275, in _blit_draw
a.axes.draw_artist(a)
File "C:\Python27\lib\site-packages\matplotlib\axes\_base.py", line 2622, in draw_artist
a.draw(self._cachedRenderer)
File "C:\Python27\lib\site-packages\matplotlib\artist.py", line 55, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "C:\Python27\lib\site-packages\matplotlib\lines.py", line 738, in draw
self.recache()
File "C:\Python27\lib\site-packages\matplotlib\lines.py", line 656, in recache
yconv = self.convert_yunits(self._yorig)
File "C:\Python27\lib\site-packages\matplotlib\artist.py", line 200, in convert_yunits
return ax.yaxis.convert_units(y)
File "C:\Python27\lib\site-packages\matplotlib\axis.py", line 1526, in convert_units
ret = self.converter.convert(x, self.units, self)
File "C:\Python27\lib\site-packages\matplotlib\category.py", line 65, in convert
unit.update(values)
AttributeError: 'NoneType' object has no attribute 'update'
我已将其指向if
中的scope.update
声明,具体为:
self.tdata = [self.tdata[-1]]
self.ydata = [self.ydata[-1]]
因为在评论这些行时,程序会继续运行(虽然没有意义,因为它没有更新图表)。
在工作系统上运行python --version && pip freeze
会导致:
Python 2.7.13
appdirs==1.4.3
certifi==2018.1.18
chardet==3.0.4
configobj==5.0.6
cycler==0.10.0
Cython==0.28
decorator==4.0.11
enum34==1.1.6
et-xmlfile==1.0.1
functools32==3.2.3.post2
future==0.16.0
idna==2.6
ipython-genutils==0.2.0
iso8601==0.1.12
jdcal==1.3
matplotlib==2.0.2
mpltools==0.2.0
mpmath==0.19
nose==1.3.7
numpy==1.13.0rc1+mkl
openpyxl==2.4.7
packaging==16.8
panda==0.3.1
pandas==0.22.0
patsy==0.5.0
pyparsing==2.2.0
pyperclip==1.5.27
pyserial==3.4
python-dateutil==2.6.0
pytz==2017.2
PyVISA==1.8
pywin32==221
PyYAML==3.12
requests==2.18.4
scikit-learn==0.19.1
scipy==0.19.0
seaborn==0.8.1
six==1.10.0
sklearn==0.0
sympy==1.0
traitlets==4.3.2
urllib3==1.22
vispy==0.5.3
xlwt==1.3.0
... 非工作系统:
Python 2.7.13
backports.functools-lru-cache==1.5
cycler==0.10.0
et-xmlfile==1.0.1
jdcal==1.3
kiwisolver==1.0.1
matplotlib==2.2.2
numpy==1.13.1
openpyxl==2.4.8
pyparsing==2.2.0
pyserial==3.4
python-dateutil==2.7.2
pytz==2018.4
six==1.11.0
xlwt==1.3.0
答案 0 :(得分:1)
<强>解决!强>
通过将非工作计算机的matplotlib
版本从2.2.2
恢复为2.0.2
,问题就会消退。虽然这解决了这个问题,但我不确定这个问题背后的根本原因是什么。
答案 1 :(得分:0)
我在尝试对完全相同的异常回调进行故障排除时遇到了该线程。我发现问题是由matplotlib函数引起的,该函数用于包含类似字符串对象的更新图。也许这是matplotlib中某个地方的错误,但是我已经通过在附加到ydata数组之前将y值转换为int来解决了它。对于您的代码,我的实现是:self.ydata.append(int(y))
也许float可以像ImportanceOfBeingErnest所建议的那样工作