将Python连接到Arduino困难

时间:2020-10-03 20:09:43

标签: python arduino

# Python + Arduino-based Radar Plotter
#
# ** Works with any motor that outputs angular rotation
# ** and with any distance sensor (HC-SR04, VL53L0x,LIDAR)
#
import numpy as np
import matplotlib

matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
import serial, sys, glob
import serial.tools.list_ports



ports = list(serial.tools.list_ports.comports())
for p in ports:
    print (p)

# Find Arudino ports, select one, then start communication with it
############################################
#
def port_search():
    if sys.platform.startswith('win'):  # Windows
        ports = ['COM{0:1.0f}'.format(ii) for ii in range(1, 256)]
        print ("Gay")
    else:
        raise EnvironmentError('Machine Not pyserial Compatible')

    arduinos = []
    for port in ports:  # loop through to determine if accessible
        if len(port.split('Bluetooth')) > 1:
            print("GI")
            continue

        try:
            ser = serial.Serial(port)
            ser.close()
            arduinos.append(port)  # if we can open it, consider it an arduino
            print ("GF")
        except (OSError, serial.SerialException):
            print("GH")
            pass
    return arduinos


arduino_ports = port_search()
ser = serial.Serial()# match baud on Arduino
ser.port = arduino_ports[0]
ser.baudrate = 9600
ser.flush()  # clear the port
#
############################################
# Start the interactive plotting tool and
# plot 180 degrees with dummy data to start
############################################
#
fig = plt.figure(facecolor='k')
win = fig.canvas.manager.window  # figure window
screen_res = win.wm_maxsize()  # used for window formatting later
dpi = 150.0  # figure resolution
fig.set_dpi(dpi)  # set figure resolution

# polar plot attributes and initial conditions
ax = fig.add_subplot(111, polar=True, facecolor='#006d70')
ax.set_position([-0.05, -0.05, 1.1, 1.05])
r_max = 100.0  # can change this based on range of sensor
ax.set_ylim([0.0, r_max])  # range of distances to show
ax.set_xlim([0.0, np.pi])  # limited by the servo span (0-180 deg)
ax.tick_params(axis='both', colors='w')
ax.grid(color='w', alpha=0.5)  # grid color
ax.set_rticks(np.linspace(0.0, r_max, 5))  # show 5 different distances
ax.set_thetagrids(np.linspace(0.0, 180.0, 10))  # show 10 angles
angles = np.arange(0, 181, 1)  # 0 - 180 degrees
theta = angles * (np.pi / 180.0)  # to radians
dists = np.ones((len(angles),))  # dummy distances until real data comes in
pols, = ax.plot([], linestyle='', marker='o', markerfacecolor='w',
                markeredgecolor='#EFEFEF', markeredgewidth=1.0,
                markersize=10.0, alpha=0.9)  # dots for radar points
line1, = ax.plot([], color='w', linewidth=4.0)  # sweeping arm plot

# figure presentation adjustments
fig.set_size_inches(0.96 * (screen_res[0] / dpi), 0.96 * (screen_res[1] / dpi))
plot_res = fig.get_window_extent().bounds  # window extent for centering
win.wm_geometry('+{0:1.0f}+{1:1.0f}'. \
                format((screen_res[0] / 2.0) - (plot_res[2] / 2.0),
                       (screen_res[1] / 2.0) - (plot_res[3] / 2.0)))  # centering plot
fig.canvas.toolbar.pack_forget()  # remove toolbar for clean presentation
fig.canvas.set_window_title('Arduino Radar')

fig.canvas.draw()  # draw before loop
axbackground = fig.canvas.copy_from_bbox(ax.bbox)  # background to keep during loop


############################################
# button event to stop program
############################################

def stop_event(event):
    global stop_bool
    stop_bool = 1


prog_stop_ax = fig.add_axes([0.85, 0.025, 0.125, 0.05])
pstop = Button(prog_stop_ax, 'Stop Program', color='#FCFCFC', hovercolor='w')
pstop.on_clicked(stop_event)


# button to close window
def close_event(event):
    global stop_bool, close_bool
    if stop_bool:
        plt.close('all')
    stop_bool = 1
    close_bool = 1


close_ax = fig.add_axes([0.025, 0.025, 0.125, 0.05])
close_but = Button(close_ax, 'Close Plot', color='#FCFCFC', hovercolor='w')
close_but.on_clicked(close_event)

fig.show()

############################################
# inifinite loop, constantly updating the
# 180deg radar with incoming Arduino data
############################################
#
start_word, stop_bool, close_bool = False, False, False
while True:
    try:
        if stop_bool: # stops program
            fig.canvas.toolbar.pack_configure() # show toolbar
            if close_bool: # closes radar window
                plt.close('all')
            break
        ser_bytes = ser.readline() # read Arduino serial data
        decoded_bytes = ser_bytes.decode('utf-8') # decode data to utf-8
        data = (decoded_bytes.replace('\r','')).replace('\n','')
        print ("137")

        if start_word:
            for ii in data.split(','):
                continue
            vals = float(ii)
            print ("11")
            if len(vals)<2:
                print ("141")
                continue
            angle,dist = vals # separate into angle and distance
            if dist > r_max:
                dist = 0.0 # measuring more than r_max, it's likely inaccurate
                print ("145")
            dists[int(angle)] = dist

            if angle % 5 ==0: # update every 5 degrees
                print ("148")
                pols.set_data(theta,dists)
                fig.canvas.restore_region(axbackground)
                ax.draw_artist(pols)

                line1.set_data(np.repeat((angle*(np.pi/180.0)),2),
                   np.linspace(0.0,r_max,2))
                ax.draw_artist(line1)

                fig.canvas.blit(ax.bbox) # replot only data
                fig.canvas.flush_events() # flush for next plot
        else:
            if data =='Radar Start': # start word on Arduino
                start_word = True # wait for Arduino to output start word
                print('Radar Starting...')
                print ("10")
            else:
                continue



    except KeyboardInterrupt:
        plt.close('all')
        print('Keyboard Interrupt')
        break

此代码是假设将我编写的Arduino代码连接到上面的python代码。 但是我遇到两个错误。 打开串行监视器时。我得到的错误是:

回溯(最近通话最近): 文件“”,第1行,位于 运行文件中的文件“ C:\ Program Files \ JetBrains \ PyCharm Community Edition 2020.2.2 \ plugins \ python-ce \ helpers \ pydev_pydev_bundle \ pydev_umd.py”,第197行 pydev_imports.execfile(filename,global_vars,local_vars)#执行脚本 execfile中的文件“ C:\ Program Files \ JetBrains \ PyCharm Community Edition 2020.2.2 \ plugins \ python-ce \ helpers \ pydev_pydev_imps_pydev_execfile.py”,第18行 exec(compile(contents +“ \ n”,file,'exec'),glob,loc) 文件“ C:/ Users /(删除我的名字)/PycharmProjects/pythonProject/main.py”,第50行,在 ser.port = arduino_ports [0] IndexError:列表索引超出范围

当串行监视器关闭时。

回溯(最近通话最近): 文件“”,第1行,位于 文件“ C:\ Program Files \ JetBrains \ PyCharm Community Edition 2020.2.2 \ plugins \ python-ce \ helpers \ pydev_pydev_bundle \ pydev_umd.py”在运行文件pydev_imports.execfile(filename,global_vars,local_vars)中的第197行脚本

exec文件中第18行的文件“ C:\ Program Files \ JetBrains \ PyCharm Community Edition 2020.2.2 \ plugins \ python-ce \ helpers \ pydev_pydev_imps_pydev_execfile.py” exec(compile(contents +“ \ n”,file,'exec'),glob,loc)

文件“ C:/ Users /(已删除名称)/PycharmProjects/pythonProject/main.py”,第52行,在 ser.flush()#清除端口

文件“ C:\ Users(删除了我的名字)\ PycharmProjects \ pythonProject \ venv \ lib \ site-packages \ serial \ serialwin32.py”,第343行,刷新 而self.out_waiting: 文件“ C:\ Users(删除了我的名字)\ PycharmProjects \ pythonProject \ venv \ lib \ site-packages \ serial \ serialwin32.py”,第445行,在out_waiting中 引发SerialException(“ ClearCommError失败({!r})”。format(ctypes.WinError()))

serial.serialutil.SerialException:ClearCommError失败(OSError(9,'句柄无效。',None,6))

目前我不确定该怎么办。

0 个答案:

没有答案