嵌入式开发板RS485多节点串口编程——关节力矩传感器数据读取

2023-05-16

嵌入式开发板RS485多节点串口编程——关节力矩传感器数据读取

最近学业繁忙,主要是准备找工作,有一段时间没分享了,今天给大家分享一下我最近利用TI AM4376开发板RS485串口读取两个关节力矩传感器的数据,我们这个关节力矩传感器用在外骨骼机器人上。后面我也会将我最近找工作的经历分享给大家,主要包括笔试、面试的准备,希望能给正在准备找工作的应届生一些帮助。

一、RS485通信协议原理

之前面试国电南京自动化时,面试官就问了有关串口和总线通信协议的问题,所以如果你是打算找嵌入式相关的工作,这方面一定要准备充分。今天我们先详细介绍一下RS485的通信协议。

1、RS485与RS232的异同

首先是逻辑电平的不同,RS232的逻辑正电平是-3-15,逻辑负电平为+3+15,而RS485的逻辑正电平+2+6V,,负电平在-2-6V,和RS232是相反的。

其次是工作方式不同,RS232是全双工,发送和接收可以同时进行,而RS485是半双工,发送和接收不能同时进行。

2、RS485可以挂载多少个节点

RS485可以外接最多32个设备,CAN可以外接110个节点,传统RS232只允许一对一的通信,不过利用modbus协议可以外接多个设备,

二、关节力矩传感器

1、通讯机制

在RS485总线通讯网络中,上级系统为主设备(调度端),各力矩传感器为从设备(被调度端)。采用轮询应答通讯机制,即:由主设备向从设备发送命令帧,从设备收到与其ID相对应的指令后才能进行响应,并向主设备发送当前工作状态数据。从设备在没有收到主设备数据帧或ID不符的情况下维持当前状态不变。默认id:01

各力矩传感器的超时判断时间为主设备发出指令后0.5ms。

2、写设备地址

因为我们要与两个设备节点通信,所以要区分两个出厂设备,通过写设备地址通信协议,改变关节力矩传感器的设备地址,这样我们以后发送数据和接收数据的时候就会以设备地址为校验,01设备只接收地址位为01的数据,02设备只接收地址位位02的数据。

下表展示的就是写地址指令,我们只需要修改第八个字节,即设置地址字节,一个设备设置为01,也就是默认的,另一个设置成02,这样就区分了两个设备。

字节 序号信号名称字长数据类型内容备注
1帧头8位无符号整型AAH
2帧头8位无符号整型BBH
3帧头8位无符号整型CCH
4帧头8位无符号整型DDH
5命令标识8位无符号整型01H01H工作指令
6数据长度8位无符号整型0EH1个字节
7传感器地址8位无符号整型[0,FFH]原始设备ID
8设置地址8位无符号整型[0,FFH]更新后设备ID
9CRC16校验8位无符号整型[0,FFH]CRC16高位
10CRC16校验8位无符号整型[0,FFH]CRC16低位
11帧尾8位无符号整型DDH
12帧尾8位无符号整型CCH
13帧尾8位无符号整型BBH
14帧尾8位无符号整型AAH

3、力矩值读取

下表为力矩值读取协议:

字节序号信号名称字长数据类型内容备注
1帧头8位无符号整型AAH
2帧头8位无符号整型BBH
3帧头8位无符号整型CCH
4帧头8位无符号整型DDH
5指令字8位无符号整型03H03H—读取力矩值
6数据长度8位无符号整型0EH1个字节
7设备ID8位无符号整型[0,FFH]
8保留位8位无符号整型[0,00H]保留
9CRC校验8位无符号整型[0,FFH]CRC16高位
10CRC校验8位无符号整型[0,FFH]CRC16低位
11帧尾8位无符号整型DDH
12帧尾8位无符号整型CCH
13帧尾8位无符号整型BBH
14帧尾8位无符号整型AAH

根据上面我们设置的地址,我们要下发的指令即为:

	static char byteSend1[14];
    static char byteSend2[14];
	byteSend1[0] = 0xAA;
	byteSend1[1] = 0xBB;
	byteSend1[2] = 0xCC;
	byteSend1[3] = 0xDD;
	byteSend1[4] = 0x03;
	byteSend1[5] = 0x0E;
	byteSend1[6] = 0x01;//关节1设备地址
	byteSend1[7] = 0;
    byteSend1[8] = 0xAE;
    byteSend1[9] = 0xB3;
    byteSend1[10] = 0xDD;
    byteSend1[11] = 0xCC;
    byteSend1[12] = 0xBB;
    byteSend1[13] = 0xAA;

	byteSend2[0] = 0xAA;
	byteSend2[1] = 0xBB;
	byteSend2[2] = 0xCC;
	byteSend2[3] = 0xDD;
	byteSend2[4] = 0x03;
	byteSend2[5] = 0x0E;
	byteSend2[6] = 0x02;//关节2设备地址
	byteSend2[7] = 0;
    byteSend2[8] = 0xA4;
    byteSend2[9] = 0xB3;
    byteSend2[10] = 0xDD;
    byteSend2[11] = 0xCC;
    byteSend2[12] = 0xBB;
    byteSend2[13] = 0xAA;

4、力矩传感器数据读取

下表为力矩传感器返回的数据格式:

字节 序号信号名称标识字长数据类型内容单位LSB****接口当量备注
8~9传感器数据SNS_data16位有符号浮点数(保留一位小数)[-300,300]Nm0.01传感器输出范围为-300.0~300.0Nm

举例:传感器返回数据:AA BB CC DD 33 0F 01 09 23 64 DD CC BB AA。AA BB CC DD帧头;0F 数据长度4位,为33 01 23 09;33读取力矩成功;01为传感器ID;09 23为力矩数据,高位在前低位在后,16位整形表示为0923H,转换为10进制为2339/10,力矩值为233.9Nm。传感器数据为F756时,高位在前低位在后,16位整形表示为F756H,转换为10进制为-2217/10,力矩值为-221.7Nm。

三、测试程序

因为整个代码比较多,这里我只将主程序中的指令下发和接收贴上来,完整的代码我会放在公众号中:河边小乌龟爬,回复<关节力矩传感器数据读取>即可获取。

这里为了为了清楚的表示下发和接收过程,我没有写成函数接口的形式,按照代码的可读性来说,这样的代码可读性较差,优化就交给你们了。

	while (1)
	{
		while(flag == 0 && flag1 == 0){
			if(i > 13){
				flag = 1;
				i = 0;
				break;
			}
			context = byteSend[i];
			iRet = write(fd, &context, sizeof(context));
			i++;
		}
		bzero(r_buf, 15);
		while(flag == 1&& flag1 == 0){
			//读传感器发送过来的数据,并解析处理
			if(j > 14){
				flag = 0;
                j = 0;
                flag1 = 1;
				break;
			}
			iRet = read(fd, &readtext, sizeof(readtext));
			r_buf[j] = readtext;
			//printf("read:%02x\n", r_buf[j]);
			j++;
                                                
		}
        usleep(10000);
        while(flag == 0 && flag1 == 1){
			if(i > 13){
				flag = 1;
				i = 0;
				break;
			}
			context = byteSend2[i];
			iRet = write(fd, &context, sizeof(context));
			i++;
		}
		bzero(r_buf2, 15);
		while(flag == 1&& flag1 == 1){
			//读传感器发送过来的数据,并解析处理
			if(j > 14){
				flag = 0;
                j = 0;
                flag1 = 0;
				break;
			}
			iRet = read(fd, &readtext, sizeof(readtext));
			r_buf2[j] = readtext;
			//printf("read:%02x\n", r_buf[j]);
			j++;                                     
		}
		if(r_buf[0] == 0xAA && r_buf[1] == 0xBB){
			printf("this joint 1 POS:%7.3f\n", ((float)((r_buf[7]<<8) | r_buf[8])/100));		
		}
		if(r_buf2[0] == 0xAA && r_buf2[1] == 0xBB){
			printf("this joint 2 POS:%7.3f\n", ((float)((r_buf2[7]<<8) | r_buf2[8])/100));		
		}
	}

在ubantu中编译程序并下载到开发板中:

image-20220612143058057

运行结果如下:

image-20220612143257604

完整源码我放在公众号河边小乌龟爬中了,需要的自取,回复<关节力矩传感器数据读取>即可获得。

我是河边小乌龟爬,学习嵌入式软件开发路上的一名小学生,欢迎大家相互交流哇。公众号:河边小乌龟爬。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

嵌入式开发板RS485多节点串口编程——关节力矩传感器数据读取 的相关文章

  • STM32中使用printf打印串口数据

    STM32使用printf打印串口 摘要 该方法适用于 STM32 xff0c 实现了使用 printf 等标准 C 流函数输出数据的办法 xff0c 极大的减少了输出串口数据时所需要做的数据处理 实现原理 在 C 库中 xff0c pri
  • 尺取法(图文解析、初学推荐)

    文章目录 最少连续页 xff08 poj3320 xff09 分析题意第一步 xff1a 找第一个满足条件区间第二步 xff1a 开始将左端边界向右移 xff0c 达到 缩小 区间 减少连续页的目的 归纳总结代码 尺取法 xff1a 顾名思
  • 第九届蓝桥杯——倍数问题(数论、枚举)

    倍数问题 众所周知 xff0c 小葱同学擅长计算 xff0c 尤其擅长计算一个数是否是另外一个数的倍数 但小葱 只擅长两个数的情况 xff0c 当有很多个数之后就会比较苦恼 现在小葱给了你 n 个数 xff0c 希望你 从这 n 个数中找到
  • 基于Python OpenCV的车牌识别(一)————车牌定位

    一开始本想基于OpenCV原理编写定位程序的 xff0c 但发现效果并不是特别理想 xff0c 只能识别我处理的那张图片的车牌 xff0c 在使用其他图片识别的时候失误非常多 xff0c 几乎识别不到车牌 xff0c 下面附上识别的代码和效
  • 计算机网络——尝试SMTP交互(邮件发送)

    前言 本文通过 Windows 命令提示符 xff08 cmd xff09 实现邮件发送 第一步 xff1a 打开 Windows Telnet Client 功能 打开控制面板 点击程序 点击启动或关闭 Windows 功能 将 Teln
  • 离散数学:推理规则

    推理规则解释说明前提引入规则可以在证明的任何时候引入前提结论引入规则在证明的任何时候 xff0c 已证明的结论都可以作为后续证明的前提置换规则在证明的任何时候 xff0c 命题公式中的任何子命题公式都可以用与之等价的命题公式置换假言推理规则
  • 离散数学:谓词逻辑命题符号化

    个体词 个体常项或个体常元 xff1a 使用 x y z 表示个体变项或个体变元 xff1a 使用 a b c 表示个体域或论域 xff1a 个体变元的取值全总个体域 xff1a 宇宙件一切事物 谓词 概念 xff1a 表示个体性质或彼此之
  • 离散数学:主范式(主析取范式、主合取范式)

    求解主析取范式 主合取范式方法 1 真值表法 在表中列出变元值的全部可能 查表判断命题 命题结果真 xff0c 变元值对应主析取范式 命题结果假 xff0c 变元值对应主合取范式 2 等值演算法 命题化简 蕴涵等值式 xff1a A B A
  • Camera:双摄基本原理

    基本概念 基线 xff1a 两镜头的间距 景深 xff1a 画面清晰范围 xff0c 景深小 浅 背景虚化 xff0c 景深大背景清晰 影响景深的三个因素 xff1a 光圈 xff08 反比 xff0c 光圈越大景深越小 xff09 焦距
  • Linux:Hello World 模块

    前言 Linux 系统为应用程序提供了功能强大且容易扩展的 API xff0c 但在某些情况下 xff0c 这还远远不够 与硬件交互或进行需要访问系统中特权信息的操作时 xff0c 就需要一个内核模块 下面从 Hello World 模块来
  • 基础算法题 —— 计算字符串的编辑距离(动态规划)

    题解 在题目所求的编辑距离是指字符串 a 转换成字符串 b 所需最小的操作步骤 a i 61 b j 时 xff0c 要使 a i 61 61 b j 可使用的操作步骤如下 xff1a a i 可替换成 b j 字符串 a 下标为 i 的位
  • Matlab —— 02 基本操作与矩阵输入

    一 基本操作 1 help 功能 xff1a 便于快速了解指令的使用 ex 查询 pi 的简明介绍 Question 通过 matlab 计算出下列算式结果 Answer 1 2 或 xff08 3 xff09 xff08 4 xff09
  • Matlab —— 03结构化程式与自定义函数

    Script writing 新建脚本编辑界面 编辑测试文档 运行节 将整个框架划分为多个小节运行 xff0c 便于进行 Debug 设置断点 检查变量数值 方法一 xff1a 工作区内检查 方法二 xff1a 鼠标滑到变量位置 Struc
  • [unity] NavMesh 寻路 贴边走的问题 优化。

    NavMesh 寻路出来后 xff0c 角色走路很多时候贴着地图的边缘走 xff0c 很别扭 网上找了一个类似的问题 xff1a http www manew com thread 94163 1 1 html 里面方案 也挺适合我们的情况
  • 网易云ncm文件转mp3

    本人卖了一个ipod nano6 xff0c 帮买家导些歌 xff0c 结果用网易云下下来一堆ncm文件 xff0c 一脸懵逼 xff0c 因为ipod只能放mp3文件 上网查了一下ncm文件 xff0c 只能在会员有效期内放这个歌 于是上
  • catkin_make编译时fatal error: ###_msgs/***.h: 没有那个文件或目录

    h是头文件 xff0c 头文件 xff0c 就是一些定义和声明 xff0c 注意是定义 xff08 算是API接口吧 xff09 xff0c 编译时先加载这些头文件 xff0c 加载好了后主程序才能调用这些定义 那出现这种错误就是编译该程序
  • Theta* : 基于网格的任意角度寻路

    原文地址 xff08 科学上网 xff09 xff1a https arxiv org ftp arxiv papers 1401 1401 3843 pdf 1 简介 在本文中 xff0c 我们将研究一种机器人技术或视频游戏中使用的路径规
  • deepsort之YOLO系列目标跟踪及其他功能

    文章目录 一 ID switch是什么 xff1f 二 deepsort框架二 deepsort需要的模型1 目标检测器2 目标跟踪器 一 ID switch是什么 xff1f 跟踪问题中最重要的就是数据关联 xff08 data asso
  • PX4软件在环仿真注意点

    注 xff1a 最新内容参考PX4 user guide 点击此处 PX4下载指定版本代码和刷固件的三种方式 点击此处 PX4sitl固件编译方法 点击此处 PX4开发指南 点击此处 PX4无人机仿真 Gazebo 点击此处 px4仿真 知
  • cmake:生成动态链接库并使用

    已知 库函数的源文件名字叫hello c xff0c 库函数的头文件名字叫hello h xff0c 生成的动态链接库函数的名称叫libhello so xff0c 目标是在 hello install文件夹下安装这个库 xff0c 以便后

随机推荐

  • 算法:皇后问题

    问题 国际象棋中的皇后 xff0c 可以横向 纵向 斜向移动 如何在一个NXN的棋盘上放置N个皇后 xff0c 使得任意两个皇后都不在同一条横线 竖线 斜线方向上 xff1f 举个栗子 xff0c 下图的绿色格子是一个皇后在棋盘上的 封锁范
  • OpenCV+Python二维码条形码识别

    先上源码 xff0c github地址 xff1a https github com DerrickRose25 Opencv QRcode recognition 环境 xff1a Pycharm Python3 7 在pycharm里安
  • Onvif协议:实现Probe命令来进行设备发现(discover)

    在onvif协议对接中 xff0c 首先要明确服务器和客户端的身份 服务器 xff1a 通常是你要对接的其他厂家的数字摄像头 xff08 IPC xff09 客户端 xff1a 通常是对接的ipc的设备程序 xff0c 安防业内多称 xff
  • Linux C/C++编程:Udp组播(多播)

    Udp多播简介 概叙 单播用于两个主机之间单对单的通信广播用于一个主机对整个局域网上所有主机上的数据通信单播和广播是两个极端 xff0c 要么对一个主机进行通信 xff0c 要么对整个局域网的主机进行通信实际情况下 xff0c 经常需要对一
  • cmake:同一目录下多个源文件

    此文为 xff1a 轻松入门cmake系列教程前文为 xff1a cmake xff1a Hello cmake 接下来进入稍微复杂的例子 xff1a 在同一个目录下有多个源文件 第一个实验 实践 在之前的目录下添加2个文件 xff0c t
  • cmake:string

    字符串操作 概要 Search span class token operator and span Replace span class token function string span span class token punctu
  • 性能:你知道并发用户数应该怎么算吗

    我们知道 xff0c 一个性能测试中 xff0c 往往会有各种各样的指标 xff0c 比如TPS RPS QPS HPS CPM等 我们在实际工作的时候 xff0c 应该对这些概念有统一的认识 建议使用TPS作为关键的性能指标 另外 xff
  • C/C++面试:手写智能指针类

    shared ptr原理 shared ptr实际上是对裸指针进行了一层封装 xff0c 成员变量除了裸指针之外 xff0c 还有一个引用计数 xff0c 它记录裸指针被引用的次数 xff08 有多少个shared ptr指向这同一个裸指针
  • golang:http.request

    request 表示由服务器接收或由客户端发送的HTTP请求 xff0c 例如客户端 client 在发送各种请求时 xff0c 需要先新建一个请求对象 xff0c 然后调用一些请求的方法开始自定义一些配置 xff0c 服务端监听到该请求便
  • git:smartgit

    下载安装smartgit 下载 xff1a https www syntevo com smartgit download 终端下操作 xff1a 执行命令 xff1a tar xvf smartgit tar gz 执行命令 xff1a
  • golang:如何在proto3中用上golang对应的interface{}类型

    首先 xff0c 我希望所有golang中用于http请求响应的结构 xff0c 都使用proto3来定义 麻烦的是 xff0c 有的情况下某个字段的类型可能是动态的 xff0c 对应的JSON类型可能是number string bool
  • 如何计算icmp校验和

    前几天看到大佬写的一篇关于icmp远控后门文章 xff0c 对icmp协议充满了激情 xff0c 通过查阅资料了解相关所需的知识 xff0c 实现整个程序首先要了解imcp包请求与回复 xff0c 在整个请求中最先就涉及到icmp包的构造
  • 作为一个自动化本科生到底应该学些什么(讲讲个人经历和感受)

    2019 6 26日深夜 晚上在床上准备休息 xff0c 一个同跟我聊天说自己大学荒废了 xff0c 突然有很多感想想写一写 我觉得自己大学也是得过且过地过着的 xff0c 不过虽然充满艰辛和不满意 xff0c 但还是挺充实的 先自我介绍一
  • 嵌入式项目实战——基于QT的视频监控系统设计(一)

    嵌入式项目实战 基于QT的视频监控系统设计 xff08 一 xff09 这个五一因为疫情 xff0c 只能待在家里 xff0c 想了想不如将我之前做的一个小的嵌入式的练习项目分享出来 xff0c 供入门嵌入式的同学们学习 基于QT的视频监控
  • 嵌入式项目实战——基于QT的视频监控系统设计(三)

    嵌入式项目实战 基于QT的视频监控系统设计 xff08 三 xff09 进入到五一假期第三天 xff0c 继续我们的项目 本来五一假期还是想好好休息一下的 xff0c 因为最近学习的状态不太好 xff0c 刷题都没有思路了 xff0c 但是
  • 嵌入式开发板RS485协议串口编程——角度传感器数据读取

    嵌入式开发板RS485协议串口编程 倾角传感器数据读取 之前分享过一篇嵌入式操作系统开发板中的串口编程 光敏电阻数据读取 xff0c 是基于TTL协议的串口编程 xff0c 本节主要讲述基于RS485协议的串口编程 xff0c 掌握了这两种
  • 嵌入式开发板CAN通信编程——伺服电机驱动

    嵌入式开发板CAN通信编程 伺服电机驱动 在实际的嵌入式项目开发过程中 xff0c 若不涉及上位机与开发板的通信传输数据 xff0c 那最关键的无非就是两个内容 xff0c 读取传感器的数据并处理 xff0c 驱动硬件设备工作 传感器数据的
  • 嵌入式字符设备驱动——ULN2003步进电机驱动程序实现

    嵌入式字符设备驱动 ULN2003步进电机驱动程序实现 之前分享了字符设备驱动程序的实现 hello驱动 xff0c 是不涉及硬件操作的 xff0c 我说过要给大家分享一篇涉及硬件操作的字符设备驱动程序的实现 xff0c 今天周末休息 xf
  • Linux多进程间通信——共享内存实现

    Linux多进程间通信 共享内存实现 又到了每周分享时刻 xff0c 这周我要分享的是关于Linux中进程间通信问题 xff0c 这对于底层程序的实现至关重要 xff0c 进程间通信方式主要包括管程 共享内存 消息传递 套接字这几种方式 x
  • 嵌入式开发板RS485多节点串口编程——关节力矩传感器数据读取

    嵌入式开发板RS485多节点串口编程 关节力矩传感器数据读取 最近学业繁忙 xff0c 主要是准备找工作 xff0c 有一段时间没分享了 xff0c 今天给大家分享一下我最近利用TI AM4376开发板RS485串口读取两个关节力矩传感器的