基于Arduino和python的串口通信和上位机控制
引言
经常的时候我们要实现两个代码之间的通信,比如说两个不同不同人写的代码要对接,例如将python指令控制Arduino控件的开关,此处使用串口通信是非常方便的,下面笔者将结合自己踩过的坑来讲述下自己的学习经历。
首先是挑战杯审报的一个项目,即采用机器学习模型分类数据,结合Arduino的压力传感器模块,而机器学习大多采取python,数据无法做到实时传输,最后放弃了。
图1 压力传感器模型
然后是python需要通过Arduino的北斗模块获取位置数据,这个也需要做两个代码之间的通信。
当时的我被这两个问题卡了好久也没有想到解决方案
感觉像是很复杂又完全没有思路
后来查阅大量资料终于得到解决
此处大概有两个重要的环节:串口通信和上位机控制
在说之前我们先要了解一下串行接口
伟大的百度百科告诉我们:
串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方式的扩展接口。串行接口 (Serial Interface) 是指数据一位一位地顺序传送,其特点是通信线路简单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线),从而大大降低了成本,特别适用于远距离通信,但传送速度较慢。
(传送速度较慢这个。。。)
(反正我们就传个几KB的数据,慢就慢吧)
(手动微笑)
串口通信
打开我们的Arduino编译器,可以看到有一个选择板子所在的端口的选项
图2 Arduino编译器的端口
像此处写的COM4就是指的是Arduino开发板所在的串口,如果需要通过Arudino来上传代码到开发板上所需要使用的就是这个串口来与Arduino开发板进行通信
用过的人都知道Arduino有一个串口监视器(图右上角)和一个Serial.print()函数
图3 串口监视器的位置
如果我们使用Serial.print()函数的话,传过来的数据就能够成功的在串口监视器上显示出来
图4 Serial.print()函数结合串口监视器的描述
那么我们需要思考一个问题:
既然传过来的数据能够用Arduino来看
那么其他的软件如果能够打开的话效果就会非常好
由此我们就需要做串口通信的问题啦
--------------------------------------------------------------------------------------------------------------------------------------------------
知识链接:其实Arduino主要起到的仅仅只有一个编译的作用,这个串口监视只是它的副业。。
--------------------------------------------------------------------------------------------------------------------------------------------------
一、设置串口
此处我们采用python打开这个串口以实现串口通信
编译器使用pyCharm
首先安装pyserial
图5 安装pyserial
(万能的pip install真好用)
pyserial的作用在于提供一个从串口读取信息的接口
现在我们已经拥有串口通信的基础了
赶紧把包导进来(注意使用import serial而不是import pyserial)
这里介绍一个基本函数serial.Serial(a,b,c)来设置一个串口
a为一个字符串代表串口的位置(如COM3)
b为一个数字代表波特率
(值得注意的是Arduino中Serial.begin()所设定的东西一定要求与你读到的波特率相同)
c为超时的时间,单位为s
初始化如图所示
图6 串口设置与初始化
此处的意义是打开一个名字叫COM1的串口,以9600波特率,0.5秒作为超时
二、读取信息
采用readline函数以读取一列数据
由于此处我们定义的变量是ser
所以下面也同样使用ser
即ser.readline()函数
下面贴出代码:
首先是python端代码
图7 python端代码和运行结果(由于此处我是COM4串口就设置的是COM4)
import serial
serialPort = "COM4" # 串口
baudRate = 9600 # 波特率
ser = serial.Serial(serialPort, baudRate, timeout=0.5)
print("参数设置:串口=%s ,波特率=%d" % (serialPort, baudRate))
while 1:
str = ser.readline()
print(str)
ser.close()
然后是Arduino端代码
1 void setup(){
2 Serial.begin(9600);
3 }
4 void loop(){
5 Serial.print("Hello,World!\n");
6 }
至此
Arduino端向python端传输数据已经完成
上位机控制
由于Arduino的控制很有可能需要其他代码传送运行结果给它
所以上位机对于Arduino的控制也是十分有意义的
利用上位机的控制
我们能够实现代码直接控制开关的结果
例如输入一个数然后开关打开灯亮
此处我们就采用这个作为Model
一、Arduino函数介绍
此处要介绍三个新的函数Serial.read() Serial.available() pinMode()
1.Serial.read()
这个函数的作用在于从COM接口读取一个字节的数据
2.Serial.available()
这个函数的作用在于查看COM接口是否有数据读入
3.pinMode((串口号),OUTPUT) 将一个端口设置为输出口
有了这两个函数过后接下来会简单很多
二、接口实现
Arduino端口
我们需要实现以下功能:
1.灯原来亮
2.按下0后灯灭
3.按下1后灯亮
首先我们需要向Arduino芯片内写入代码
但有一点需要注意
如果要将二极管LED直接接到接口上的话只能接13号接口
因为13号接口自带正好适合LED的电阻
有了上面的基础
我就直接贴代码了
附带详细注释哦
void setup(){
Serial.begin(9600);
pinMode(13, OUTPUT);//设置13号端口作为输出端口
digitalWrite(13,HIGH);//让灯开始时亮
}
char var;
void loop(){
while(Serial.available()>0)//当有信号的时候
{
var=Serial.read();
if(var=='0')//传过来的是0
digitalWrite(13,LOW);
if(var=='1')//传过来的是1
digitalWrite(13,HIGH);
}
}
python端口
此处python接口采用serial中的write函数来向串口中写入数据
注意一下输入的一定要是ASCII字符
否则Arduino接口无法读出的
# -*- coding: utf-8 -*-
import serial
serialPort = "COM4" # 串口
baudRate = 9600 # 波特率
ser = serial.Serial(serialPort, baudRate, timeout=0.5)
print("参数设置:串口=%s ,波特率=%d" % (serialPort, baudRate))
demo1=b"0"#将0转换为ASCII码方便发送
demo2=b"1"#同理
while 1:
c=input('请输入指令:')
c=ord(c)#将c转换为UTF-8标准数字
if(c==48):
ser.write(demo1)#ser.write在于向串口中写入数据
if(c==49):
ser.write(demo2)
------------------------------------------------------------------------------------------------------------------------------------------------------
几点注意事项:
1.接口不一定统一
2.其中函数笔者是依据自己理解来描述的,如果有问题的话希望各位大佬不要喷
3.Arduino真是太好玩了