matlab读取表格数据以固定周期通过串口发送
wptr33 2025-06-09 00:39 13 浏览
如题,这里对数据的处理对于熟悉matlab各函数操作的同学来讲,是常规操作,但对于matlab新手或只是想借用matlab工具将存于PC端文件中的数据通过串口发送出去的工程人员来说,由于对matlab软件比较陌生,实现各种功能所应该调用的函数没有头绪,所以还是比较麻烦的。这里先简单介绍实现这项操作过程中的几个步骤,然后贴出完整代码,供大家需要时查询。
这里主要以功能分以下步骤:
- matlab读取指定文件数据
- 不同类型数据转换为字节数据
- 固定时间间隔的实现
- 操作串口发送数据
matlab读取指定文件数据
这里介绍两种读取方式:选择读取和指定读取
- 选择读取
所谓选择读取即在m文件执行过程中由操作者自己选择要读取的文件,先上代码
clear all
%要操作的数据行数(从首行算起)
sym num ;
num=693;
%定义1列,num行数组变量
data_lat=zeros(1,num);
%选择读取文件数据
[FileName PathName]=uigetfile()
file=fullfile(PathName,FileName)
M=csvread(file);
%单独操作M矩阵的第一列1~num行数据
data_lat=M(1:num,1);
%画出读取的纬度数据,红色
plot(data_lat,'r');
上述代码的最终实现是选择文件读取其数据到M矩阵,并将数据的第一列的1~num行以红色画出图来。
代码执行后首先会弹出选择窗口,手动选定要操作的文件
注意这里可以自由选择不同路径下的文件,要操作的文件不一定在当前工作目录下。选择窗口的打开源于uigetfile()函数的执行,选择文件结束后函数返回被选择文件的路径和文件名
而后,fullfile()合成被选择文件的完整路径,并返回给file变量,最后通过csvread()函数将文件数据读取进来并形成M数据矩阵,如下原csv文件与M数据对比,原数据类型依次为
double/double/float/float/float/float
这里采用csvread()函数读取数据是因为笔者的原数据文件为.csv格式,需根据文件不同格式选择读取函数,如xlsread()函数
此外,matlab中数组和C语言的不同在于,没有0号元素,即没有0号下标的元素,都是从1号元素开始
- 指定读取
指定读取即在m文件中直接指定要读取文件的完整路径,在程序执行过程中无需再选择文件
clear all
%要操作的数据行数(从首行算起)
sym num ;
num=693;
%定义1列,num行数组变量
data_lat=zeros(1,num);
%选择读取文件数据
% [FileName PathName]=uigetfile()
% file=fullfile(PathName,FileName)
% M=csvread(file);
%指定读取文件数据
M=csvread('D:\study\matlab\uart\3926_vehicle_global_position_0.csv');
%单独操作M矩阵的第一列1~num行数据
data_lat=M(1:num,1);
%画出读取的纬度数据,红色
plot(data_lat,'r');
不同类型数据转换为字节数据
串口常规发送8位字节数据,这里不同类型数据只有按计算机存储规则先转换为字节发送给接收端,接收端再按相同的存储规则将字节数据转换为原数据类型以完成数据的传输,这里首先存在一个数据转换的问题
%整型int
i2ubuff=zeros(1,4);
i2ubuff=typecast(int(12345),'uint8');
%单精度浮点型float
f2ubuff=zeros(1,4);
f2ubuff=typecast(single(data_lon(i)),'uint8');
%双精度浮点型double
d2ubuff=zeros(1,8);
d2ubuff=typecast(double(data_lat(i)),'uint8');
‘=’左侧即为不同数据类型返回的无符号字节数组数据,这里还有要注意的一项是发送端和接收端的数据存储模式,也即大端、小端问题
固定时间间隔的实现
数据准备好之后,有时需要一股脑的将数据全部发送出去,有时又需要以固定的周期,定时一部分一部分的发送出去。后者的定时作用,在单片机上一般由定时器timer或滴答定时器等实现精准的时间把控,在matlab中则需要调用函数来实现
- 整秒定时
对于整秒时间间隔可以调用pause()函数,如定时3秒调用 pause(3) 即可实现
- 压秒级定时
当要实现的时间间隔单位低于秒级时,pause()函数就无能为力了,tic toc函数可以实现
% 延时200ms
tic
while toc < 0.2
end
tic执行时,会获取实时系统时间t0,toc则一直获取当前系统时间t1与t0的时间差,如上,当时间间隔大于或等于0.2时,程序会跳出while循环向下执行,否则会在while中等待,注意这种延时存在一定的精度误差
操作串口发送数据
由于只执行简单的串口操作,和单片机控制串口的操作很相似
- 指定端口,创建端口设备
s=serial('COM18');
- 设置串口属性
set(s,'BaudRate',115200,'parity','none','databits',8,'stopbits',1);
属性名字,紧跟要设置成的属性
- 打开串口
fopen(s);
- 发送数据
fwrite(s,sendbuff);
关闭串口,删除内存中串口设备对象,清除工作空间中串口设备对象
fclose(s);
delete(s);
clear s;
有时打开串口后,程序由于某种原因未能执行完毕,中途退出后,再次运行程序会显示打开串口错误,要打开的串口被占用,这是因为上次运行出错的程序未能正确关闭串口。此时有两种选择,一是关闭matlab软件,解除占用,但是打开matlab并等待就绪会占用很长一段时间,挺让人不耐烦的。二是在命令窗口运行下列函数,解除占用
%强行关闭串口
scoms=instrfindall;
stopasync(scoms);
fclose(scoms);
delete(scoms);
完整代码
最后贴出笔者的完整代码,该代码的实现是读取.csv数据以5hz的频率将数据按固定格式发送出去
%串口发送程序
%测试数据在excel表中列顺序:经度、纬度、高度、y轴(东)速度、x轴(北)速度、z轴(下)速度
clear all
%操作的每列数据行数,从第一行算起
sym num
num=693;
%中间数据
global sendbuff
global f2ubuff
global d2ubuff
global data_lat
global data_lon
global data_alt
global data_vy
global data_vx
global data_vz
sendbuff=zeros(1,48);
f2ubuff=zeros(1,4);
d2ubuff=zeros(1,8);
data_lat=zeros(1,num);
data_lon=zeros(1,num);
data_alt=zeros(1,num);
data_vy=zeros(1,num);
data_vx=zeros(1,num);
data_vz=zeros(1,num);
%获取日志数据
[FileName PathName]=uigetfile();
file=fullfile(PathName,FileName);
M=csvread(file);
data_lat=M(1:num,1);
data_lon=M(1:num,2);
data_alt=M(1:num,3);
data_vy=M(1:num,4);
data_vx=M(1:num,5);
data_vz=M(1:num,6);
%选定串口,创建串口设备对象
s=serial('COM18');
fclose(s);
%设置串口属性
set(s,'BaudRate',115200,'parity','none','databits',8,'stopbits',1);
%打开串口
fopen(s);
%固定字节
sendbuff(1)='#39;;
sendbuff(2)='E';
sendbuff(3)='X';
sendbuff(4)='Y';
sendbuff(5)='F';
sendbuff(6)=48;
sendbuff(7)=0;
sendbuff(8)=20;
sendbuff(9)=20;
sendbuff(42)=1;
sendbuff(43)=0;
sendbuff(44)=0;
sendbuff(45)=160;
sendbuff(46)=64;
sendbuff(47)=0;
sendbuff(48)=63;
for i=1:num
%纬度
d2ubuff=typecast(double(data_lat(i)),'uint8');
sendbuff(10)=d2ubuff(1);
sendbuff(11)=d2ubuff(2);
sendbuff(12)=d2ubuff(3);
sendbuff(13)=d2ubuff(4);
sendbuff(14)=d2ubuff(5);
sendbuff(15)=d2ubuff(6);
sendbuff(16)=d2ubuff(7);
sendbuff(17)=d2ubuff(8);
%经度
d2ubuff=typecast(double(data_lon(i)),'uint8');
sendbuff(18)=d2ubuff(1);
sendbuff(19)=d2ubuff(2);
sendbuff(20)=d2ubuff(3);
sendbuff(21)=d2ubuff(4);
sendbuff(22)=d2ubuff(5);
sendbuff(23)=d2ubuff(6);
sendbuff(24)=d2ubuff(7);
sendbuff(25)=d2ubuff(8);
%高度
f2ubuff=typecast(single(data_lon(i)),'uint8');
sendbuff(26)=f2ubuff(1);
sendbuff(27)=f2ubuff(2);
sendbuff(28)=f2ubuff(3);
sendbuff(29)=f2ubuff(4);
%vy
f2ubuff=typecast(single(data_vy(i)),'uint8');
sendbuff(30)=f2ubuff(1);
sendbuff(31)=f2ubuff(2);
sendbuff(32)=f2ubuff(3);
sendbuff(33)=f2ubuff(4);
%vx
f2ubuff=typecast(single(data_vx(i)),'uint8');
sendbuff(34)=f2ubuff(1);
sendbuff(35)=f2ubuff(2);
sendbuff(36)=f2ubuff(3);
sendbuff(37)=f2ubuff(4);
%vz
f2ubuff=typecast(single(data_vz(i)),'uint8');
sendbuff(38)=f2ubuff(1);
sendbuff(39)=f2ubuff(2);
sendbuff(40)=f2ubuff(3);
sendbuff(41)=f2ubuff(4);
fwrite(s,sendbuff);
% 延时200ms
tic
while toc < 0.2
end
end
%延时一段时间等待数据发送完毕再关闭串口,数据未发送完毕时,不能正常关闭串口
pause(3);
%关闭串口
fclose(s);
%删除内存中串口设备对象
delete(s);
%清除工作空间中串口设备对象
clear s;
相关推荐
- MySQL进阶五之自动读写分离mysql-proxy
-
自动读写分离目前,大量现网用户的业务场景中存在读多写少、业务负载无法预测等情况,在有大量读请求的应用场景下,单个实例可能无法承受读取压力,甚至会对业务产生影响。为了实现读取能力的弹性扩展,分担数据库压...
- 3分钟短文 | Laravel SQL筛选两个日期之间的记录,怎么写?
-
引言今天说一个细分的需求,在模型中,或者使用laravel提供的EloquentORM功能,构造查询语句时,返回位于两个指定的日期之间的条目。应该怎么写?本文通过几个例子,为大家梳理一下。学习时...
- 一文由浅入深带你完全掌握MySQL的锁机制原理与应用
-
本文将跟大家聊聊InnoDB的锁。本文比较长,包括一条SQL是如何加锁的,一些加锁规则、如何分析和解决死锁问题等内容,建议耐心读完,肯定对大家有帮助的。为什么需要加锁呢?...
- 验证Mysql中联合索引的最左匹配原则
-
后端面试中一定是必问mysql的,在以往的面试中好几个面试官都反馈我Mysql基础不行,今天来着重复习一下自己的弱点知识。在Mysql调优中索引优化又是非常重要的方法,不管公司的大小只要后端项目中用到...
- MySQL索引解析(联合索引/最左前缀/覆盖索引/索引下推)
-
目录1.索引基础...
- 你会看 MySQL 的执行计划(EXPLAIN)吗?
-
SQL执行太慢怎么办?我们通常会使用EXPLAIN命令来查看SQL的执行计划,然后根据执行计划找出问题所在并进行优化。用法简介...
- MySQL 从入门到精通(四)之索引结构
-
索引概述索引(index),是帮助MySQL高效获取数据的数据结构(有序),在数据之外,数据库系统还维护者满足特定查询算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构...
- mysql总结——面试中最常问到的知识点
-
mysql作为开源数据库中的榜一大哥,一直是面试官们考察的重中之重。今天,我们来总结一下mysql的知识点,供大家复习参照,看完这些知识点,再加上一些边角细节,基本上能够应付大多mysql相关面试了(...
- mysql总结——面试中最常问到的知识点(2)
-
首先我们回顾一下上篇内容,主要复习了索引,事务,锁,以及SQL优化的工具。本篇文章接着写后面的内容。性能优化索引优化,SQL中索引的相关优化主要有以下几个方面:最好是全匹配。如果是联合索引的话,遵循最...
- MySQL基础全知全解!超详细无废话!轻松上手~
-
本期内容提醒:全篇2300+字,篇幅较长,可搭配饭菜一同“食”用,全篇无废话(除了这句),干货满满,可收藏供后期反复观看。注:MySQL中语法不区分大小写,本篇中...
- 深入剖析 MySQL 中的锁机制原理_mysql 锁详解
-
在互联网软件开发领域,MySQL作为一款广泛应用的关系型数据库管理系统,其锁机制在保障数据一致性和实现并发控制方面扮演着举足轻重的角色。对于互联网软件开发人员而言,深入理解MySQL的锁机制原理...
- Java 与 MySQL 性能优化:MySQL分区表设计与性能优化全解析
-
引言在数据库管理领域,随着数据量的不断增长,如何高效地管理和操作数据成为了一个关键问题。MySQL分区表作为一种有效的数据管理技术,能够将大型表划分为多个更小、更易管理的分区,从而提升数据库的性能和可...
- MySQL基础篇:DQL数据查询操作_mysql 查
-
一、基础查询DQL基础查询语法SELECT字段列表FROM表名列表WHERE条件列表GROUPBY分组字段列表HAVING分组后条件列表ORDERBY排序字段列表LIMIT...
- MySql:索引的基本使用_mysql索引的使用和原理
-
一、索引基础概念1.什么是索引?索引是数据库表的特殊数据结构(通常是B+树),用于...
- 一周热门
-
-
C# 13 和 .NET 9 全知道 :13 使用 ASP.NET Core 构建网站 (1)
-
程序员的开源月刊《HelloGitHub》第 71 期
-
详细介绍一下Redis的Watch机制,可以利用Watch机制来做什么?
-
假如有100W个用户抢一张票,除了负载均衡办法,怎么支持高并发?
-
如何将AI助手接入微信(打开ai手机助手)
-
Java面试必考问题:什么是乐观锁与悲观锁
-
redission YYDS spring boot redission 使用
-
SparkSQL——DataFrame的创建与使用
-
一文带你了解Redis与Memcached? redis与memcached的区别
-
如何利用Redis进行事务处理呢? 如何利用redis进行事务处理呢英文
-
- 最近发表
- 标签列表
-
- git pull (33)
- git fetch (35)
- mysql insert (35)
- mysql distinct (37)
- concat_ws (36)
- java continue (36)
- jenkins官网 (37)
- mysql 子查询 (37)
- python元组 (33)
- mybatis 分页 (35)
- vba split (37)
- redis watch (34)
- python list sort (37)
- nvarchar2 (34)
- mysql not null (36)
- hmset (35)
- python telnet (35)
- python readlines() 方法 (36)
- munmap (35)
- docker network create (35)
- redis 集合 (37)
- python sftp (37)
- setpriority (34)
- c语言 switch (34)
- git commit (34)