CANopen协议开发梳理总结笔记教程

0、提醒

        CANOpen使用时,需要清楚什么是大端和小端,这对于CANOpen数据发送及解析时,有很大的帮助。且学习开发CANOpen时,需要具备一定的CAN基础。

1、CANOpen协议介绍

①、什么是CANOpen协议

        CANOpen协议是一种架构在控制局域网络(Controller Area Network, CAN)上的高层通信协议,它广泛应用于工业自动化、机械工程和汽车电子等领域。CANOpen协议通过对象字典、服务数据对象(SDO)、过程数据对象(PDO)等机制,为机器人、运动控制、过程控制、楼宇自动化、交通运输等行业提供了一种标准化的通信解决方案。

        CANOpen协议的标准由非营利组织CiA(CAN in Automation)进行起草、审核及维护工作。

        CANOpen协议本身是一个单一的标准,它定义了设备间的通信协议和接口规范。

        CANOpen协议支持从10kbps到1Mbps的波特率,具体包括10k、20k、50k、125k、250k、500k、800k和1Mbps。

        简单来说,CANOpen协议是一个基于CAN协议的的一个应用层协议。

②、CANOpen协议的特性

        开放性:CANOpen是一个公开的标准,任何公司都可以使用它来开发产品,无需支付许可费用。

        网络管理:CANOpen协议定义了网络管理功能,如节点自诊断、网络监控等,使得网络维护更加方便。

        对象字典:CANOpen使用对象字典来描述设备的功能和状态,使得设备之间的通信更加标准化。

        服务:CANOpen定义了一系列的服务,如NMT(Network Management)、TPDO(Time-Triggered Protocol Data Object)、RPDO(Real-Time Protocol Data Object)等,以满足不同的应用需求。

        PDO(Process Data Object):PDO是CANOpen中用于快速传输过程数据的数据对象,可以实时地传输控制和状态信息。

        SDO(Service Data Object):SDO用于访问设备的对象字典,可以读取或写入设备的状态和配置信息。

        紧急消息:CANOpen还定义了紧急消息,用于在发生严重故障时立即通知网络中的其他设备。

        心跳消息:心跳消息用于监测网络中设备的运行状态,如果一段时间内没有收到某个设备的心跳消息,网络管理系统会认为该设备已经离线。

        CANOpen常用缩写

③、CANOpen协议应用场景

        在CANOpen协议中,对于不同类型的CANopen 设备和应用场景分别有不同的子协议,如CiA301、CiA401、CiA402、CiA421、CiA423、CiA424、CiA426、CiA430、CiA433等众多子协议构成了CANopen协议。

2、CANOpen字典

        CANOpen字典(Object Dictionary, OD)是CANopen协议的核心组成部分,它是一个有序的对象组,用于描述CANopen节点的所有参数,包括通讯数据的存放位置。

        CANOpen字典的结构由索引和子索引组成:

        索引:每个对象采用一个16位的索引值来寻址,范围在0x0000到0xFFFF之间。

        子索引:在某些索引下,为了访问数据结构中的单个元素,定义了一个8位的子索引,范围是0x00到0xFF之间。

        CANOpen的SDO模式下的数据传输时,也是按如下格式进行发送和接收。其中字典中的部分索引可能没有子索引。

3、CANOpen通信

        CANOpen通信有两种模式,分别是SDO通信、和PDO通信,如下图所示为CANOpen通信的设备模型图。

①、SDO通信

        SDO 全称为服务数据对象,其通过对象索引和子索引与CANOpen字典建立联系,通过SDO可以读取对象数据,在允许的情况下,也可以修改写入对象数据。

        SDO 传输方式遵循客户端—服务器模式(CS),即一应一答方式。由 CAN 总线网络中的 SDO 客户端发起,SDO 服务器作出应答。

        SDO 传输报文由COB-ID数据段组成,数据段采用小端模式,即低位在前,高位在后排列。所有的 SDO 报文数据段都必须是 8 个字节。

        SDO发送数据的COB-ID都是0x600+节点ID

        SDO接收数据的COB-ID都是0x580+节点ID

SDO读数据报文格式

SDO写数据报文格式

②、PDO通信

        PDO 全称为 过程数据对象, 其用来传输实时的数据,是 CANopen 中最主要的数据传输方式。通过SDO配置PDO后,可以实现设备端的数据周期性自动上传到服务器,也可以实现控制发送的数据小于8字节,由于PDO发送的数据无返回,因此可以极大的提升数据传输速度。

        按照接收与发送的不同,PDO又分为TPDO和RPDO,其中RPDO用于服务器给设备端发送控制数据TPDO为设备端周期性上传数据到服务器

        PDO 的传输遵循的是生产者消费者模型,即 CAN 总线网络中生产者产生的 TPDO 可根据COB-ID 由网络上一个或者多个消费者 RPDO 接收。每个PDO由通信参数和映射参数共同决定最终传输的方式及内容。

        如下是所使用的电机控制器中实现 PDO 的传输的4 个 RPDO 和4 个 TPDO。注意,不同控制器的PDO数量可能不一致,需要根据实际产品进行手册参考。

        PDO使用时,需要进行映射配置操作,如下所示为PDO映射操作的流程图。

        因PDO映射内容较多,因此将在下一篇博客中详细介绍PDO映射操作。

3、CANOpen应用

①、设置CiA402模式

        发送:601 2B 02 20 01 00 00 00 00 (设置为 CiA402 模式)

//2B 02 20 01 00 00 00 00   (CiA402 模式)
#define WRITE_2_BYTE        0x2B
#define WRITE_60_CTRL_PARAM 0x2002
#define CTRL_MODE_SELECT    0x01
#define CIA402_MODE         0x00//将数据按规定填充到CAN的8字节数据区
char data[8] = { 0 };
data[0] = WRITE_2_BYTE;
data[1] = WRITE_60_CTRL_PARAM & 0xFF;
data[2] = WRITE_60_CTRL_PARAM >> 8 & 0xFF;
data[3] = CTRL_MODE_SELECT;
data[4] = CIA402_MODE;serve_motor_send_data(0x601, data);
//成功会返回数据:60 02 20 01 00 00 00 00 

②、循环同步位置模式

        发送:601 2F 60 60 00 08 00 00 00 (循环同步位置模式)

//2F 60 60 00 08 00 00 00 (循环同步位置模式)
#define WRITE_1_BYTE         0x2F   
#define WRITE_60_RUN_MODE    0x6060
#define CYCLIC_SYNC_POS_MODE 0x08//将数据按规定填充到CAN的8字节数据区
char data[8] = {0};   
data[0] = WRITE_1_BYTE;
data[1] = WRITE_60_RUN_MODE & 0xFF;
data[2] = WRITE_60_RUN_MODE >> 8 & 0xFF;
data[3] = 0x00;
data[4] = CYCLIC_SYNC_POS_MODE;serve_motor_send_data(0x601, data);
//成功会返回数据: 60 60 60 00 00 00 00 00 

③、电机准备

        发送: 601 2B 40 60 00 06 00 00 00 (设置 6040h为 0x6, 使电机准备)

//2B 40 60 00 06 00 00 00
#define WRITE_2_BYTE           0x2B
#define WRITE_60_CTRL_STATE    0x6040
#define MOTOR_READY            0x06//将数据按规定填充到CAN的8字节数据区
char data[8] = { 0 };
data[0] = WRITE_2_BYTE;
data[1] = WRITE_60_CTRL_STATE & 0xFF;
data[2] = WRITE_60_CTRL_STATE >> 8 & 0xFF;
data[3] = 0x00;
data[4] = MOTOR_READY;servo_motor_send_data(0x601, data);
//正常会返回数据:60 40 60 00 00 00 00 00 

③、电机锁轴使能

        发送: 601 2B 40 60 00 0F 00 00 00 (设置 6040h为 0xF, 使电机使能)

//2B 40 60 00 0F 00 00 00
#define WRITE_2_BYTE          0x2B
#define WRITE_60_CTRL_STATE   0x6040 
#define MOTOR_ENABLE          0x7F//将数据按规定填充到CAN的8字节数据区
char data[8] = { 0 };
data[0] = WRITE_2_BYTE;
data[1] = WRITE_60_CTRL_STATE & 0xFF;
data[2] = WRITE_60_CTRL_STATE >> 8 & 0xFF;
data[3] = 0x00;
data[4] = MOTOR_ENABLE;servo_motor_send_data(0x601, data);
//正常会返回数据:60 40 60 00 00 00 00 00 

④、电机松轴失能

        发送: 601 2B 40 60 00 07 00 00 00 (设置 6040h为 0x7, 使电机失能)

//2B 40 60 00 07 00 00 00
#define WRITE_2_BYTE           0x2B
#define WRITE_60_CTRL_STATE    0x6040    
#define MOTOR_DISABLE          0x07//将数据按规定填充到CAN的8字节数据区
char data[8] = { 0 };
data[0] = WRITE_2_BYTE;
data[1] = WRITE_60_CTRL_STATE & 0xFF;
data[2] = WRITE_60_CTRL_STATE >> 8 & 0xFF;
data[3] = 0x00;
data[4] = MOTOR_DISABLE;servo_motor_send_data(0x601, data);
//正常会返回数据:60 40 60 00 00 00 00 00 

⑤、设置电机目标位置

        发送: 601 23 7A 60 00 10 27 00 00 (设置目标位置 607Ah为 10000)

//目标位置    :   23 7A 60 00 10 27 00 00 (设置 607Ah为 10000)
#define WRITE_4_BYTE         0x23   
#define WRITE_60_POSITION    0x607Aint pos = 90;//90度
int pos_pulse = (int)(pos * 10000.0 / 360);//数值单位转换(角度值数据转换为脉冲)
char data[8] = { 0 };//将数据按规定填充到CAN的8字节数据区
data[0] = WRITE_4_BYTE;
data[1] = WRITE_60_POSITION & 0xFF;
data[2] = WRITE_60_POSITION >> 8 & 0xFF;
data[3] = 0x00;
data[4] = pos_pulse & 0xFF;
data[5] = pos_pulse >> 8 & 0xFF;
data[6] = pos_pulse >> 16 & 0xFF;
data[7] = pos_pulse >> 24 & 0xFF;servo_motor_send_data(0x601, data);
//正常会返回到数据
//例如:60 7A 60 00 00 00 00 00 

⑥、读取电机实际位置

        发送:601 40 63 60 00 00 00 00 00

#define READ_60_CMD      0x40
#define READ_60_POSITION 0x6063//将数据按规定填充到CAN的8字节数据区
char data[8] = { 0 };
data[0] = READ_60_CMD;
data[1] = READ_60_POSITION & 0xFF;
data[2] = READ_60_POSITION >> 8 & 0xFF;servo_motor_send_data(0x601, data);
//正常会返回到读取到的位置数据
//例如:43 63 60 00 F1 2D C0 01 

⑦、读取电机实际速度

        发送:601 40 6C 60 00 00 00 00 00

//40 6C 60 00 00 00 00 00
#define READ_60_CMD    0x40
#define READ_60_SPEED  0x606C//将数据按规定填充到CAN的8字节数据区
char data[8] = { 0 };
data[0] = READ_60_CMD;
data[1] = READ_60_SPEED & 0xFF;
data[2] = READ_60_SPEED >> 8 & 0xFF;servo_motor_send_data(0x601, data);
//正常会返回到读取到的速度数据
//例如:43 6C 60 00 7C F6 FF FF 

⑧、读取电机实际电流

        发送:601 40 78 60 00 00 00 00 00

//40 78 60 00 00 00 00 00
#define READ_60_CMD 0x40
#define READ_60_CURRENT 0x6078//将数据按规定填充到CAN的8字节数据区
char data[8] = { 0 };
data[0] = READ_60_CMD;
data[1] = READ_60_CURRENT & 0xFF;
data[2] = READ_60_CURRENT >> 8 & 0xFF;servo_motor_send_data(0x601, data);
//正常会返回到读取到的电流数据
//例如:4B 78 60 00 FC FF 00 00 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/40840.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于CLIP特征的多模态大模型中的视觉短板问题

【论文极速读】 基于CLIP特征的多模态大模型中的视觉短板问题 FesianXu 20240706 at Tencent WeChat search team 前言 今天读到篇CVPR 24’的论文 [1],讨论了常见的多模态大模型(大多都基于CLIP语义特征,以下简称为MLLM)中的视觉…

若依 / ruoyi-ui:执行yarn dev 报错 esnext.set.difference.v2.js in ./src/utils/index.js

一、报错信息 These dependencies were not found: * core-js/modules/esnext.set.difference.v2.js in ./src/utils/index.js * core-js/modules/esnext.set.intersection.v2.js in ./src/utils/index.js * core-js/modules/esnext.set.is-disjoint-from.v2.js in ./src/utils…

Python处理表格数据常用的 N+个操作

Python作为一种强大且易用的编程语言,其在数据处理方面表现尤为出色。特别是当我们面对大量的表格数据时,Python的各类库和工具可以极大地提高我们的工作效率。以下,我将详细介绍Python处理表格数据常用的操作。 首先,我们需要安…

2024.7.5总结

今晚的总结是在图书馆前的梯子上写的,我多次辗转,可能是我最后一次看看这个学校了,明天就要踏上回家的旅途了。还有半个月入职,干脆回家看看,毕竟,工作以后机会不多了。 下午的时候,用顺丰寄了…

复现YOLO_ORB_SLAM3_with_pointcloud_map项目记录

文章目录 1.环境问题2.遇到的问题2.1编译问题1 monotonic_clock2.2 associate.py2.3 associate.py问题 3.运行问题 1.环境问题 首先环境大家就按照github上的指定环境安装即可 环境怎么安装网上大把的资源,自己去找。 2.遇到的问题 2.1编译问题1 monotonic_cloc…

ASP.NET Core----基础学习01----HelloWorld---创建Blank空项目

文章目录 1. 创建新项目--方式一: blank2. 程序各文件介绍(Project name :ASP.Net_Blank)(1)launchSettings.json 启动方式的配置文件(2)appsettings.json 基础配置file参数的读取&a…

ChatGPT:SpringBoot解决跨域问题方法-手动设置请求头

ChatGPT:SpringBoot解决跨域问题方法-手动设置请求头 这里的设置响应头是为了发送请求方还是接收请求方 设置响应头是为了发送请求方。具体来说,添加 Access-Control-Allow-Origin 头部是为了告诉浏览器,哪些域名可以访问资源。当设置为 * 时…

Java求自然常数e的近似值(课堂实例1)

❤❤引言🎃🎃 ❤点关注编程梦想家(大学生版)-CSDN博客不迷路~~~~~~❤ 自然常数 𝑒e 是数学中一个非常重要的常数,约等于 2.71828,它在自然对数、复合利息计算等领域有着广泛的应用。本文将介绍如…

自动批量将阿里云盘文件发布成WordPress文章脚本源码(以RiPro主题为例含付费信息下载地址SEO等自动设置)源码

背景 很多资源下载站,付费资源下载站,付费内容查看等都可以用WordPress站点发布内容,这些站点一般会基于一个主题,付费信息作为文章附属的信息发布,底层存储在WP表里,比如日主题,子比主题等。 …

掌握IPython的`%%debug`:深入交互式调试的艺术

IPython是一个功能丰富的交互式Python解释器,它为Python开发者提供了许多便捷的功能,其中之一就是%%debug魔法命令。%%debug是IPython提供的一种快速进入调试模式的方法,它允许用户在代码执行出错时立即开始调试,而无需单独启动调…

Apache Seata tcc 模块源码分析

本文来自 Apache Seata官方文档,欢迎访问官网,查看更多深度文章。 本文来自 Apache Seata官方文档,欢迎访问官网,查看更多深度文章。 一 .导读 spring 模块分析中讲到,Seata 的 spring 模块会对涉及到分布式业务的 b…

《梦醒蝶飞:释放Excel函数与公式的力量》9.2 FV函数

9.2 FV函数 FV函数是Excel中用于计算投资或贷款在若干期后的未来值的函数。它是一个非常实用的财务函数,能够帮助我们快速计算投资的最终价值或贷款的期末余额。 9.2.1 函数简介 FV函数用于计算基于定期固定支付和固定利率的投资或贷款的未来值。未来值是指在一定…

cs224n作业3 代码及运行结果

代码里要求用pytorch1.0.0版本,其实不用也可以的。 【删掉run.py里的assert(torch.version “1.0.0”)即可】 代码里面也有提示让你实现什么,弄懂代码什么意思基本就可以了,看多了感觉大框架都大差不差。多看多练慢慢来,加油&am…

中英双语介绍美国的州:阿肯色州(Arkansas)

中文版 阿肯色州简介 阿肯色州(Arkansas)位于美国南部,以其多样的自然景观、丰富的文化遗产和不断发展的经济而闻名。以下是对阿肯色州的详细介绍,包括其地理位置、人口、经济、教育、文化和主要城市。 地理位置 阿肯色州东临…

文件、文本阅读与重定向、路径与理解指令——linux指令学习(一)

前言:本节内容标题虽然为指令,但是并不只是讲指令, 更多的是和指令相关的一些原理性的东西。 如果友友只想要查一查某个指令的用法, 很抱歉, 本节不是那种带有字典性质的文章。但是如果友友是想要来学习的,…

PD虚拟机怎么联网?PD虚拟机安装Win11无法上网 pd虚拟机连不上网怎么解决 mac安装windows虚拟机教程

PD虚拟机既可以联网使用,也可以单机使用。如需将PD虚拟机联网,可以共享Mac原生系统的网络,其使用体验与真实系统无异。本文会详细讲解PD虚拟机如何联网,并会进一步解决PD虚拟机安装Win10无法上网的问题。 如果有网络相关问题的小伙…

游戏服务器搭建选VPS还是专用服务器?

游戏服务器搭建选VPS,VPS能够提供控制、性能和稳定性。它不仅仅是让游戏保持活力。它有助于减少延迟问题,增强您的游戏体验。 想象一下:你正沉浸在一场游戏中。 胜利在望。突然,屏幕卡住——服务器延迟。 很崩溃,对…

C语言实现【程序设计与实践】实验三:自动售货机

声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 附上c版http://t.csdnimg.cn/BbDSL https://blog.csdn.net/As_sBomb/article/details/105485940 实验三:自动售货机 题目: 图所示为简易自动售货…

1493. 删掉一个元素以后全为 1 的最长子数组

1493. 删掉一个元素以后全为 1 的最长子数组 题目链接&#xff1a;1493. 删掉一个元素以后全为 1 的最长子数组 代码如下&#xff1a; class Solution { public://滑动窗口int longestSubarray(vector<int>& nums){int res 0;int count 0;//记录碰到0的个数int …

【MYSQL】事务隔离级别以及InnerDB底层实现

事务隔离级别 读未提交&#xff08;Read Uncommitted&#xff09; 允许事务读取其他事务未提交的数据&#xff0c;可能会导致脏读。 读已提交&#xff08;Read Committed&#xff09; 一个事务只能看见已经提交的事务所做的更改&#xff0c;可以避免脏读&#xff0c;但可能…