python和arduino串口通信_关于python和matlab,python和Arduino通信总结_weixin_39804620的博客-程序员秘密

技术标签: python和arduino串口通信  

最近一段时间主要都是在忙于课题收尾阶段,涉及到很多平台验证问题,在这中间必不可少的环节就是解决不同软件硬件之间的通讯问题了。我的课题主要是围绕python来做的,目前涉及到的就是python和matlab,以及python和Arduino之间的问题了。本文主要是为了记录自己在过程中遇到的一些问题,以及解决方法。

1.软件安装问题。

(1)用于安装实时软件的电脑装的是XP系统,只支持python2.7及以下的版本。如果安装python3以上的版本,均无法安装使用。

(2)XP系统只支持Anaconda2,不支持以上的版本,如果安装新的版本,就会报错:fail to create menu一类的ERROR,当时试了很多遍呀,心态血炸,还好最终调过来了呀TT

(3)关于python在cmd窗口进行安装库

现在很多库都是在pip18.1的版本下才能安装的,但是系统自带的又是怕pip8.1.1版本的,所以很多库如果不更新pip的话是无法进行安装使用的。又一个问题来了,如果你用的是anaconda,就会知道anaconda的导航里面是有很多的库直接就能安装的,但是有一个坑就是很多库的版本都相对比较老了。你在这个导航里面是找不到pip的最新版本的。这时候的解决方案就是通过命令窗口对pip进行更新(前提是电脑要联网),

打开cmd串口,输入以下指令,就可以把pip直接升级到最新版本。

更新:python -m pip install --upgrade pip

查看当前函数库版本,cmd窗口输入以下指令:

pip list

如果更新到制定版本,cmd窗口输入以下指令:

pip install --upgrade <库的名字>==指定版本

如果更新到最新版本,cmd窗口输入以下指令:

pip install --upgrade +<库的名字>

卸载库,cmd窗口输入以下指令:

pip uninstall + <库的名字>

2.安装好了环境才能开始操作呀,接下来就是matlab和python之间的通信。matlab和python之间并没有可以进行直接通讯的接口,所以只有通过别的途径找到一个桥梁来让他们之间建立起通讯。恰好TPC通讯协议就可以满足两者之间通讯的需求。其中也遇到过几个问题:

(1)怎么才能建立连接?

必须要有相同的IP地址和端口号,IP地址怎么获得,可以通过命令窗口获得,但是我是直接通过以下来获取的:

import socket

IP= socket.gethostbyname(socket.gethostname())

端口号我是任意取得,可以正常运行。

(2)建立起TCP通讯,就会有Client端和Sever端,不要把这个搞混淆了。其中Client端是客户端,是发送请求或者说是发送指令的,客户端是接收指令的。

客户端和服务端之间有一个操作顺序的问题,如果是先打开客户端的话,是无法找到连接的。因为服务端才是你数据要去的地方,也可以说是通讯的启动方是Sever端,信息的发起点是Client。

(3)端口被占用的问题

当你运行一次通讯程序后,必须要停掉程序,或者是将Port口关闭,否则在开始新的程序的时候是一定会被占用的。

(4)python和matlab双方的发送和接收的函数

python:

import numpyas np

import socket

IP= socket.gethostbyname(socket.gethostname())# 服务器端可以写"localhost",可以为空字符串"",可以为本机IP地址

print(IP)

port= 80 # 端口号

Tpc_sever= socket.socket(socket.AF_INET, socket.SOCK_STREAM)

Tpc_sever.bind((IP, port))#绑定Ip和端口

Tpc_sever.listen(1)

print('listen at port :', port)

conn, addr= Tpc_sever.accept()

print('connected by', addr)

while True:

data_string= str((conn.recv(100000000)))#接收数据

data_split= data_string.strip(' ').split(' ')#将一整段的字符串进行分割

data_filter_None= list(filter(None,data_split))#将空的字符串删去

data_dig= list(map(lambda x: float(x),data_filter_None))#将字符转换为浮点型

Info= np.array(data_dig).reshape([1,-1])

# Info = int(data)

print('recieved message:', Info)

# data = data.decode

# data = (conn.recv(1024)).decode() # 解码

# np.save('data.npy', data)

# Info = data

# if not Info:

# break

#下面的语句是用来返回值的,我们这里不需要返回值所以直接注释掉

# send = input('return:')

# conn.sendall(send.encode()) # 再编码发送

conn.close()

Tpc_sever.close()

matlab:

data = [oxyHb,deoxyHb,totalHb,switch_signal];

% 构造客户端tcpip对象

tcpipClient = tcpip('192.168.0.153',80,'NetworkRole','Client');%设置对象属性,A端的IP为192.168.123.30

set(tcpipClient,'OutputBufferSize',1000000000000); %设置缓存长度 经过验证一个double类型的数据数据栈据 8个缓存位,这个是设置发送的数据缓存 %并且这个设置的长度必须大于你要发送的数据的长度

set(tcpipClient,'InputBufferSize',1024); %设置缓存长度 这个是设置接收的数据缓存

set(tcpipClient,'Timeout',10); %设置连接时间为1分钟 %打开连接对象

fopen(tcpipClient);

ii=1;

% a = num2str(signal);

% fwrite(tcpipClient,a);

while(1)

% while(1)

% nBytes = get(tcpipClient,'BytesAvailable'); %这里得到的数据是接收到的所有缓存个数,比如说有N 个字符 的数据,那么这个大小就是 N

% if nBytes > 0

% break;

% end

% end

Data_Com = num2str(data(ii,:));

fwrite(tcpipClient,Data_Com);

nBytes_1(i)=nBytes;

disp(i) % 接收命令

receivedInstruction = fread(tcpipClient,nBytes,'int8');

disp(strcat('received instruction is: ',char(receivedInstruction'))); % 反馈数据

fwrite(tcpipClient,signal(i),'double');

numSent = get(tcpipClient,'valuesSent');

disp(strcat('Bytes of instruction is :',num2str(numSent)));

ii=ii+1;

pause(0.13)

end % 关闭和删除连接对象

fclose(tcpipClient);

delete(tcpipClient);

3.关于python和Arduino通讯

这个方法看了晚上帖子介绍的方法其实都比较多,但是呀,没办法呀,python2.7真的已经是被抛弃了呀,好多库函数已经都不能用了。所以只能委曲求全,用最原始的串口通讯的方法。

首先,要安装pyserial函数库。直接上代码了我就

import serial

import time

def To_arduino(key_command):

arduino = serial.Serial('COM5', baudrate=9600,timeout=1)

print(arduino.portstr) # check which port was really used

if (arduino.isOpen()):

print("打开成功")

else:

print("打开失败")

try:

arduino.write(str(key_command)) #写入命令,因为另一端接收数据的格式是字符串,所以要转换成字符串进行数据传输,虽然Arduino端有直接接收数字的函数,但是我几经测试,还是没成功,暂时放弃了

rev_data = arduino.readline() #接收Arduino返回数据

if rev_data == b'':

continue

else:

print(rev_data)

time.sleep(1)

except KeyboardInterrupt:

arduino.close() #不关掉串口的话,即使你的程序终止,你的串口还是被占用的

if __name__ == '__main__':

To_arduino(1)

Arduino端:

int Rev;

int Pin_Mark;

int Timekeep;

void setup() {

// put your setup code here, to run once:

Timekeep = 10;

pinMode(13,OUTPUT);

pinMode(2,OUTPUT);

pinMode(3,OUTPUT);

pinMode(4,OUTPUT);

pinMode(5,OUTPUT);

Serial.begin(9600);

// while(Serial.read()>= 0){};

Serial.setTimeout(1000); //串口超时 1000 毫秒

}

void loop()

{

// put your main code here, to run repeatedly:

if (Serial.available()> 0)

{

Rev = Serial.read(); #读取串口中数据

Pin_Mark = int(Rev)+2; #将字符转化为int型数据

Serial.write(Pin_Mark);

digitalWrite(Pin_Mark,HIGH); #将Pin_Mark引脚置为高电平

delay(Timekeep);

digitalWrite(Pin_Mark,LOW);#将Pin_Mark引脚置为低电平

}

}

这里必须要吐槽一下了,可能是很久没有跟硬件打交道了,对这种没有print的结果输出的调试起来感觉很麻烦呀,我压根就不知道你穿过来的是什么信号。想过用串口助手,Arduino也确实是有串口监测器,但是问题来了呀,你如果是打开串口检测器,那你这个端口就是在被占用的状态呀,你是不能在从python数据发送端利用端口进行数据传输了呀,所以说,调试起来果然还是有点麻烦,所以我又把发到Arduino的数据发送给了python进行数据打印。0.0

还有自己的一个误区,以为是必须要Arduino开发板的程序要在发送端的数据发送之前就要打开,而且也要和python的数据发送端同时运行,其实这是极端错误的。因为Arduino开发板只要你把程序烧写进去之后,只要连接端口就会立刻运行,并不需要去再进行额外的操作。只要你数据发送过来,就ok了。

啊啊啊啊啊,目前只能回忆起来这么多了,先写到这里0.0

回来补充一个很重要的关于和Arduino通信的一点就是Arduino的编程中,串口输入与输出都是针对ASCII码值的。比如你想得到一个97的数值,你需要输入字符‘a’,具才能在Serial.read()一段得到97这个数值。具体ASCII码需要查看以下链接:http://ascii.911cha.com/

关于Serial.write函数,理论上Serial.write('a') 与Serial.write(97) 应该相同,然而事实并非如此。实际测试中,发现Serial.write(97) 与Serial.write('97') 相同,可知Serial.write()函数中有代码专门对这种情况进行了处理,将数字隐式地转化成了字符串,使用户不用关心ASCII码,并尽量贴近于其他语言。然而缺点就是与Serial.read()的不统一。为什么不把Serial.read()也封装的通用一点呢?TT研究了好几个小时才研究出来。0.0

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_39804620/article/details/110048203

智能推荐

usb hub和usb device注册过程_xiaofengcanyue2013的博客-程序员秘密

A10的cpu有一个hub,也就是root hub,下边带有三个controller。其中第0个控制器具有otg功能,它的端点0支持最大64字节的控制传送,另外具有5个端点;控制器1、2只能作为host用,其下面最多能外接一个hub。如果控制器0作为device用,简称udc;如果作为host用,就和其他两个控制器一样简称hcd。     他们作为平台设备注册进内核,平台资源在drivers/

Hive学习(一)Hive的三种搭建方式_Hen_YA的博客-程序员秘密

Hive三种搭建方式一、Local本地(derby)元数据库derby与工具都是在本地只需将压缩包解压,在hive-site.xml做以下配置(将原信息删除)注:需要将hive-site.xml.template更名为hive-site.xmlmv hive-default.xml.template hive-site.xml&amp;amp;amp;amp;lt;?xml version=&amp;amp;amp;quot;1.0&amp;amp;amp;quot;?&amp;amp;amp;

CentOS7.6下Nginx配置Https_奕奕星空的博客-程序员秘密_centos7 nginx配置https

转自:river's blogCentOS7.6下Nginx安装请参考博文:阿里云CentOS7.6下安装Nginx现在为了网站更加安全,可以采用https访问,需要安装SSL证书,一般SSL证书都需要付费,但是也有免费的,我这里在阿里云申请了免费的DV证书。在 产品-&gt;安全-&gt;SSL证书 下可以选购免费的DV证书证书下载选择Nginx,会得到2个文件xxx_river106.cn.key, xxx_river106.cn.pem。配置Https前Ngin...

python如何关闭multiprocess_Python(29):Python程序中的进程操作(multiprocess.process)_weixin_39995351的博客-程序员秘密

一、multiprocess模块multiprocess不是一个模块而是python中一个操作、管理进程的包。子模块分为四个部分:创建进程部分(multiprocess.process)进程同步部分((multiprocess.Lock))进程池部分((multiprocess.Pool))进程之间数据共享(ThreadLocal、multiprocess.Queue、Pipes)二、multip...

gcc # 和 ##_June_Hou的博客-程序员秘密

#和##的用法1.'#' 用于转换字符串,可以是任意字符2.&quot;##&quot; 用于连接两边的符号,例如:a##b == ab, ab必须为一个为已声明变量; a##b() == ab(), ab()必须为一个已声明的函数.举例:#include &amp;lt;stdio.h&amp;gt;#define AAA(a)      #a      #define BBB(b,c)    b##c#defi...

C语言 递归实现顺序输出整数_Shuo..的博客-程序员秘密

题目描述本题要求实现一个函数,对一个整数进行按位顺序输出。函数接口定义:void printdigits( int n );函数printdigits应将n的每一位数字从高位到低位顺序打印出来,每位数字占一行。裁判测试程序样例:#include &lt;stdio.h&gt;void printdigits( int n );int main(){int n; scanf("...

随便推点

java实验4 发牌程序_是zg啊!的博客-程序员秘密_发牌程序java

题目类别: 实验关键字: 掌握Java数组、方法的基本定义内容要求:编写程序,项目名和类名均为PokerGame。实现功能:(1) 共有m幅扑克牌,每幅扑克牌不包括大王和小王共52张牌。(2) 可能有n个人参与扑克游戏,2&lt;=n&lt;=52。(3) 程序运行时输入扑克牌幅数m和人数n,然后所有牌分别依次分发给n个人。不能整除时,每个人的牌数可以不同,如3个人1幅牌,则第1个人18张,第2个和第3个人17张牌。(4) 发牌完成后按花色(顺序为黑桃、红心、草花、方块)和牌面大小输出每个

自适应滤波:维纳滤波器——LCMV及MVDR实现_weixin_33734785的博客-程序员秘密

作者:桂。时间:2017-03-24  06:52:36链接:http://www.cnblogs.com/xingshansi/p/6609317.html 声明:欢迎被转载,不过记得注明出处哦~ 【读书笔记03】前言西蒙.赫金的《自适应滤波器原理》第四版,上一篇看到维纳滤波基本形式:最优化问题,且无任何条件约束。这次看到有约束的部分,简单整理一下思路: ...

创建一项新的工程(Code Composer Studio 5.2)_tlsdhy的博客-程序员秘密

1.打开CCS5.2,新建一个工程。单击左上角工具栏Project,选择New ccs project.建立一个新的工程。在弹出的任务框project name 内填入工程名称2.在左方框内右击自己的工程名文件,选择最后的properties选项。在弹出的对话框内按照图示选择添加头文件路径单击OK完成添加。3.右键工程名选择“add Files”添加完后应有如下列表。4.在主操作栏编写完程序后右键...

OpenStack核心组件-keystone_weixin_30871293的博客-程序员秘密

1. Keystone介绍  keystone是OpenStack的组件之一,用于为OpenStack家族中的其它组件成员提供统一的认证服务,包括身份验证、令牌的发放和校验、服务列表、用户权限的定义等等。云环境中所有的服务之间的授权和认证都需要经过 keystone. 因此 keystone 是云平台中第一个即需要安装的服务。作为 OpenStack 的基础支持服务,Keystone 做下...

安装Teradata 数据库驱动_dqsweet的博客-程序员秘密_teradata驱动下载

Step to install the Teradata Client ODBC1. For installing the Teradata client you need to follow the following sequence for installing.2. First install Teradata TDGSS2. Then install Teredata T

canal小试牛刀第一篇:canal-server+kafka根据mysql binlog同步数据_凯丨的博客-程序员秘密_canal-server

1. 前情提要直接监听mysql的binlog同步数据可以对业务无侵入。数仓搭建必备利器。2. 准备工作了解canal-server了解kafka了解Canal Kafka了解mysql主从了解docker、docker-compose3. 配置相关mysql保存以下配置至./mysql/conf.d/slave.cnf[mysqld]log-bin=mysql-bin # 开启 binlogbinlog-format=ROW # 选择 ROW 模式server_id=1