• 基于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)

     1 import serial
     2 
     3 
     4 serialPort = "COM4"  # 串口
     5 baudRate = 9600  # 波特率
     6 ser = serial.Serial(serialPort, baudRate, timeout=0.5)
     7 print("参数设置:串口=%s ,波特率=%d" % (serialPort, baudRate))
     8 
     9 
    10 while 1:
    11     str = ser.readline()
    12     print(str)
    13 
    14 ser.close()

    然后是Arduino端代码

    1 void setup(){
    2   Serial.begin(9600);
    3 }
    4 void loop(){
    5   Serial.print("Hello,World!
    ");
    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的电阻

    有了上面的基础

    我就直接贴代码了

    附带详细注释哦

     1 void setup(){
     2   Serial.begin(9600);
     3   pinMode(13, OUTPUT);//设置13号端口作为输出端口
     4   digitalWrite(13,HIGH);//让灯开始时亮
     5 }
     6 char var;
     7 void loop(){
     8   while(Serial.available()>0)//当有信号的时候
     9   {
    10     var=Serial.read();
    11     if(var=='0')//传过来的是0
    12       digitalWrite(13,LOW);
    13     if(var=='1')//传过来的是1
    14      digitalWrite(13,HIGH);
    15   }
    16 }

    python端口

    此处python接口采用serial中的write函数来向串口中写入数据

    注意一下输入的一定要是ASCII字符

    否则Arduino接口无法读出的

     1 # -*- coding: utf-8 -*-
     2 import serial
     3 
     4 serialPort = "COM4"  # 串口
     5 baudRate = 9600  # 波特率
     6 ser = serial.Serial(serialPort, baudRate, timeout=0.5)
     7 print("参数设置:串口=%s ,波特率=%d" % (serialPort, baudRate))
     8 
     9 demo1=b"0"#将0转换为ASCII码方便发送
    10 demo2=b"1"#同理
    11 while 1:
    12     c=input('请输入指令:')
    13     c=ord(c)#将c转换为UTF-8标准数字
    14     if(c==48):
    15         ser.write(demo1)#ser.write在于向串口中写入数据
    16     if(c==49):
    17         ser.write(demo2)

    运行结果如下:

    图8 输入0时关闭

    图 9 输入1时打开

    ------------------------------------------------------------------------------------------------------------------------------------------------------

    几点注意事项:

    1.接口不一定统一

    2.其中函数笔者是依据自己理解来描述的,如果有问题的话希望各位大佬不要喷

    3.Arduino真是太好玩了

    如果各位大佬觉得笔者这篇写的还算可以的话欢迎打赏哦

    2018-12-31  01:26:53  Author:Lance Yu

  • 相关阅读:
    yii2 批量插入
    yii2 ArrayHelper的19个函数+使用实例+功能详解
    thinkphp phpexcel
    yii2 ActiveForm beforeSubmit用法
    YII2项目常用技能知识总结
    Redis 的 fields 遇到的问题
    spring boot +mybatis+druid 多数据源配置
    简单使用shell 自动打包,发布项目 脚本
    cmpp 短信平台
    mysql workbench 导出表结构
  • 原文地址:https://www.cnblogs.com/lanceyu/p/10201236.html
Copyright © 2020-2023  润新知