当前位置:   article > 正文

【硬件控制】5. Pico使用串口与电脑通信

pico使用串口与电脑通信

前几节都是在讲树莓派与外部的元件通信,本节来讲树莓派如何与电脑通信

本篇文章会教大家开发一个这样的上位机软件,用来和Pico通信,文章较长,耐心看完

先看一下树莓派Pico的引脚图吧

我们可以看到上面有UART的引脚,UART又分为TX和RX

UART是串口的一种,可以用来通信,包括单片机和电脑,单片机和单片机,单片机和其它带串口的外设

UART是全双工的,也就是说发送的发送的同时可以接收数据,UART需要三根线,一根TX(发送),一根RX(接收)和一根GND(共地)


串口模块:

现在的电脑都不带串口了,我们需要一个USB转串口模块来给电脑增加串口能力

如图所示:

网上很容易买到这样的USB转串口模块,只需几块钱,用的是CH340芯片

这个模块一头插电脑,另一头的引脚可以通过杜邦线连接Pico或其它单片机,这些引脚上面都要标注,别插错就可以了

买到模块后找店家要一个驱动,安装驱动后,可以测试下模块是否正常工作,将模块插入电脑,设备管理器里面出现新的串口设备说明驱动安装成功

然后使用一根杜邦线将TXD脚和RXD脚连接起来,这样这个模块发送的数据就会被自己接收到了

连接完成后,打开串口调试助手

里面选择自己的串口号,点击打开,同时将接收区设置中的十六进制显示去掉

在下面的输入窗口中输入数据,点击发送,上面的接收窗口就能收到相同的数据了,说明串口模块工作正常


Pico连接串口:

1号脚是串口的TX

2号脚是串口的RX

3号脚是GND,也要用到

这三个脚接到USB转串口模块的对应引脚上

TX接RX,RX接TX,GND接模块的GND(需要共地才能通信)

连接完成后给Pico编写串口通信代码:

  1. import time
  2. from machine import UART, Pin
  3. led = Pin(25, Pin.OUT)
  4. uart = UART(0, baudrate=9600, bits=8, stop=1)
  5. while True:
  6. led.toggle()
  7. time.sleep(1)
  8. uart.write('hello-world\n')

首先引入UART包,然后初始化一个uart对象

uart需要设置几个参数

第一个是串口号,设置为0代表用Pico上的第一个串口

baudrate设置串口通信的波特率

bits设置通信的数据位为8位

stop设置停止位为1位

代码写完上传到Pico中

然后打开串口助手工具

串口设置要和Pico中的配置保持一致,比如波特率写9600,两边都要写9600

然后打开串口,就能源源不断收到Pico发送的数据了

然后我们来通过Python写一个小工具,用来代替串口调试助手 读取串口数据

Python提供了一个串口操作的包,pyserial

需要先安装这个包

pip install pyserial

然后编写代码,操作串口

  1. import serial
  2. com = serial.Serial("COM4", 9600)
  3. if com.isOpen():
  4. print("打开串口成功")
  5. print(com.name)
  6. try:
  7. while True:
  8. read_data = com.read()
  9. if read_data:
  10. print(read_data)
  11. except:
  12. print('err')
  13. finally:
  14. com.close()
  15. else:
  16. print("打开串口失败")

代码写完后,将串口调试助手的串口操作关闭掉,运行上面的Python脚本,也能源源不断输出Pico发送的数据了


上位机程序:

最后来编写一个上位机程序控制Pico

上位机是一个运行在电脑或手机上的程序,可以操作单片机

我们编写一个Python界面程序来给Pico发送指令,Pico收到指令后执行开灯或者关灯操作

使用PySimpleGui来编写界面

需要先安装包

pip install PySimpleGUI

然后编写如下代码:

  1. import PySimpleGUI as sg
  2. import serial
  3. from serial.rfc2217 import Serial
  4. from serial.tools import list_ports
  5. def get_com_list():
  6. """
  7. 获取串口列表
  8. :return:
  9. """
  10. ports = list_ports.comports(include_links=False)
  11. return [port.device for port in ports]
  12. def get_baudrates_list():
  13. """
  14. 获取波特率列表
  15. :return:
  16. """
  17. return [item for item in Serial.BAUDRATES]
  18. if __name__ == '__main__':
  19. com_list = get_com_list()
  20. baudrates_list = get_baudrates_list()
  21. com: serial.Serial = None
  22. layout = [[sg.Text('通过按钮控制Pico点亮/熄灭LED')],
  23. [sg.HorizontalSeparator()],
  24. [sg.Text('串口:'), sg.InputCombo(com_list, readonly=True, key='com'),
  25. sg.Button('刷新', key='refresh_com_list')],
  26. [sg.Text('波特率:'), sg.InputCombo(baudrates_list, readonly=True, default_value=115200, key='baudrates')],
  27. [sg.Button('打开串口', key='open_serial'), sg.Button('关闭串口', key='close_serial')],
  28. [sg.HorizontalSeparator()],
  29. [sg.Button('开灯', key='open_led'), sg.Button('关灯', key='close_led')]]
  30. window = sg.Window('Pico上位机程序v1.0', layout, size=(300, 200))
  31. while True:
  32. event, values = window.read()
  33. if event == sg.WIN_CLOSED:
  34. break
  35. elif event == 'refresh_com_list':
  36. # 刷新串口列表
  37. com_list = get_com_list()
  38. window['com'].update(values=com_list)
  39. elif event == 'open_serial':
  40. # 打开串口
  41. selected_com = values['com']
  42. selected_baudrates = values['baudrates']
  43. if not selected_com:
  44. sg.Popup('请选择串口')
  45. elif not selected_baudrates:
  46. sg.Popup('请选择波特率')
  47. else:
  48. if not com:
  49. print(f'open serial: {selected_com}')
  50. com = serial.Serial(selected_com, int(selected_baudrates))
  51. elif event == 'close_serial':
  52. # 关闭串口
  53. if com and com.isOpen():
  54. print('close serial')
  55. com.close()
  56. com = None
  57. elif event == 'open_led':
  58. if com and com.isOpen():
  59. print('send open led command')
  60. com.write(b'open_led\n')
  61. elif event == 'close_led':
  62. if com and com.isOpen():
  63. print('send close led command')
  64. com.write(b'close_led\n')
  65. window.close()

上面这段代码会创建这样的窗口:

可以下拉选择串口,然后设置波特率,打开串口后就能发送指令了

这里定义了两个指令

开灯:

open_led\n

关灯:

close_led\n

这两个指令会通过串口发送到Pico设备,Pico收到后判断指令然后执行相应的动作

Pico的代码如下:

  1. import time
  2. from machine import UART, Pin
  3. led = Pin(25, Pin.OUT)
  4. uart = UART(0, baudrate=115200, bits=8, parity=None, stop=1)
  5. uart.write('pico started!\n')
  6. while True:
  7. time.sleep(1)
  8. if uart.any():
  9. command = uart.readline()
  10. if not command:
  11. continue
  12. command_str = command.decode()
  13. uart.write('recv-{}\n'.format(command_str))
  14. if command_str.startswith('open_led'):
  15. led.value(1)
  16. elif command_str.startswith('close_led'):
  17. led.value(0)

循环接收串口消息,收到后判断是否为定义的指令

然后执行相应的动作

以上就是一个简单的单片机与上位机通信的案例,大家可以稍加改造完成自己的控制功能

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/492054
推荐阅读
相关标签
  

闽ICP备14008679号