百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

Arduino读光栅数据

bigegpt 2024-09-16 12:28 10 浏览

最近在工作中,需要使用光栅尺,但是之前的程序是电气工程师通过PLC控制,然后使用需要使用modbus协议去读取结果,使用相当的不智能,优化的话,那位电气工程师已经离职,没人接手。

为了更好的使用这个光栅尺,我决定自己来优化一下。PLC开发不太懂,但没事,我手头有个空闲的ESP32C3,使用MCU去读个脉冲信号,我觉得问题不大。

在拿到光栅尺,我看了下规格:精度1um,TTL信号输出,一个脉冲的计数为4um,接口为DB9,当然接线与传统的RS232串口定义完全不一样。

这里接线就不做过多的描述,毕竟设备不一样,光栅尺的输出信号分为了A/B/Z,然后我们来看下光栅的A/B信号:



这时候有使用arduino玩过编码器,一看就知道,这不就是编码器,于是顺手把USB逻辑分析仪拿出来,运动一下光栅,看下数据波形,一个波形的时间大约在3-400ms。

于是arduino的开发就简单了,两个pin脚中断触发,然后读编码器一般计数就行了。为了让使用过程中能实现自动上报数据,于是我增加了一个pin脚中断,在上升或者下降触发的时候能自动把计数数据发到串口,这样在到达我需要测试数据的时候,ESP32C3能把数据自动上报。

所以arduino的代码我设计为3块:

1、中断计数、中断上报;

2、串口协议生成;

3、串口数据通讯。

既然已经有了单片机程序,那上位机也必不可少,那就直接简单点,使用C#进行数据开发。

那就直接开发,使用arduino开发虽然不能深入了解单片机的开发精髓,但是我们要的是能拿来直接用。

中断定义:

const int A_pin = 1; // 定义A管脚引脚号

const int B_pin = 2; // 定义B管脚引脚号

const int P_pin = 3;

const int interruptPinA = digitalPinToInterrupt(A_pin);

const int interruptPinB = digitalPinToInterrupt(B_pin);

const int interruptPinP = digitalPinToInterrupt(P_pin);


在初始化中增加代码:

// 设置中断回调函数

attachInterrupt(interruptPinA, countPulseA, CHANGE);

attachInterrupt(interruptPinB, countPulseB, CHANGE);

attachInterrupt(interruptPinP, countPulseP, CHANGE);

中断函数关键代码:

A脚中断部分:

// 在A脉冲中寻找上升沿信号,若A编码器引脚为高电平,

// 若B编码器引脚为低电平,Counter计数+1,否则-1

if (digitalRead(A_pin) == HIGH) {

if (digitalRead(B_pin) == LOW) {

count = count + 1;

}

else {

count = count - 1;

}

}

else // 在A脉冲中寻找下降沿信号

{

if (digitalRead(B_pin) == HIGH) {

count = count + 1;

}

else {

count = count - 1;

}

}

B脚中断部分:

// 在B脉冲中寻找上升沿信号

if (digitalRead(B_pin) == HIGH)

{

if (digitalRead(A_pin) == HIGH) {

count = count + 1;

}

else {

count = count - 1;

}

}

else {


if (digitalRead(A_pin) == LOW) {

count = count + 1;

}

else {

count = count - 1;

}

}

P脚就是自动发送串口数据,协议是自己定义的就不具体描述,基本协议思路:

定义好协议的帧头、流水号、数据长度、数据位、数据内容、校验位以及帧尾,这样基本不会有问题。至于校验,简单的就是累加、或者直接使用现成的校验方式,比如CRC16等。

上位机就简单的使用C#进行数据收发,我选择使用winform进行编写。

当前.net的版本较多,既然支持的直接使用推荐的.net8.0,在.net8.0的环境中是没有serialport控件,需要使用nuget来获取system.io.ports控件:



功能就简洁点,直接获取串口,然后直接读数据内容:



至于功能就基于serialport控件:

搜索本地串口:

cb_comname.Items.Clear();

cb_comname.Items.AddRange(SerialPort.GetPortNames());

if (cb_comname.Items.Count > 0)

{

cb_comname.SelectedIndex = 0;

}

打开串口:


try

{

sp.PortName = comname;

sp.BaudRate = bs;

sp.Open();

isok = sp.IsOpen;

}

catch (Exception ex)

{

MessageBox.Show(ex.Message);

}

数据收发:


sp.DataReceived += Sp_DataReceived;

处理事件的函数内容:

int len=sp.BytesToRead;

if (len > 0)

{

byte[] buf=new byte[len];

sp.Read(buf, 0, len);

//处理数据

}

顺便使用了closexml来保存记录的光栅数据,使用起来相当完美,有时间再录制一个视频。

相关推荐

最全的MySQL总结,助你向阿里“开炮”(面试题+笔记+思维图)

前言作为一名编程人员,对MySQL一定不会陌生,尤其是互联网行业,对MySQL的使用是比较多的。对于求职者来说,MySQL又是面试中一定会问到的重点,很多人拥有大厂梦,却因为MySQL败下阵来。实际上...

Redis数据库从入门到精通(redis数据库设计)

目录一、常见的非关系型数据库NOSQL分类二、了解Redis三、Redis的单节点安装教程四、Redis的常用命令1、Help帮助命令2、SET命令3、过期命令4、查找键命令5、操作键命令6、GET命...

netcore 急速接入第三方登录,不看后悔

新年新气象,趁着新年的喜庆,肝了十来天,终于发了第一版,希望大家喜欢。如果有不喜欢看文字的童鞋,可以直接看下面的地址体验一下:https://oauthlogin.net/前言此次带来得这个小项目是...

精选 30 个 C++ 面试题(含解析)(c++面试题和答案汇总)

大家好,我是柠檬哥,专注编程知识分享。欢迎关注@程序员柠檬橙,编程路上不迷路,私信发送以下关键字获取编程资源:发送1024打包下载10个G编程资源学习资料发送001获取阿里大神LeetCode...

Oracle 12c系列(一)|多租户容器数据库

作者杨禹航出品沃趣技术Oracle12.1发布至今已有多年,但国内Oracle12C的用户并不多,随着12.2在去年的发布,选择安装Oracle12c的客户量明显增加,在接下来的几年中,Or...

flutter系列之:UI layout简介(flutter-ui-nice)

简介对于一个前端框架来说,除了各个组件之外,最重要的就是将这些组件进行连接的布局了。布局的英文名叫做layout,就是用来描述如何将组件进行摆放的一个约束。在flutter中,基本上所有的对象都是wi...

Flutter 分页功能表格控件(flutter 列表)

老孟导读:前2天有读者问到是否有带分页功能的表格控件,今天分页功能的表格控件详细解析来来。PaginatedDataTablePaginatedDataTable是一个带分页功能的DataTable,...

Flutter | 使用BottomNavigationBar快速构建底部导航

平时我们在使用app时经常会看到底部导航栏,而在flutter中它的实现也较为简单.需要用到的组件:BottomNavigationBar导航栏的主体BottomNavigationBarI...

Android中的数据库和本地存储在Flutter中是怎样实现的

如何使用SharedPreferences?在Android中,你可以使用SharedPreferencesAPI来存储少量的键值对。在Flutter中,使用Shared_Pref...

Flet,一个Flutter应用的实用Python库!

▼Flet:用Python轻松构建跨平台应用!在纷繁复杂的Python框架中,Flet宛如一缕清风,为开发者带来极致的跨平台应用开发体验。它用最简单的Python代码,帮你实现移动端、桌面端...

flutter系列之:做一个图像滤镜(flutter photo)

简介很多时候,我们需要一些特效功能,比如给图片做个滤镜什么的,如果是h5页面,那么我们可以很容易的通过css滤镜来实现这个功能。那么如果在flutter中,如果要实现这样的滤镜功能应该怎么处理呢?一起...

flutter软件开发笔记20-flutter web开发

flutterweb开发优势比较多,采用统一的语言,就能开发不同类型的软件,在web开发中,特别是后台式软件中,相比传统的html5开发,更高效,有点像c++编程的方式,把web设计出来了。一...

Flutter实战-请求封装(五)之设置抓包Proxy

用了两年的flutter,有了一些心得,不虚头巴脑,只求实战有用,以供学习或使用flutter的小伙伴参考,学习尚浅,如有不正确的地方还望各路大神指正,以免误人子弟,在此拜谢~(原创不易,转发请标注来...

为什么不在 Flutter 中使用全局变量来管理状态

我相信没有人用全局变量来管理Flutter应用程序的状态。毫无疑问,我们的Flutter应用程序需要状态管理包或Flutter的基本小部件(例如InheritedWidget或St...

Flutter 攻略(Dart基本数据类型,变量 整理 2)

代码运行从main方法开始voidmain(){print("hellodart");}变量与常量var声明变量未初始化变量为nullvarc;//未初始化print(c)...