CANopen协议【SDO】
SDO:
SDO是读写单个寄存器。主要用于配置伺服驱动器参数。
1 收发功能:
//public unsafe struct VCI_CAN_OBJ //CAN数据帧 【单帧对象】//{// public uint ID;// 帧ID。 【11bit】数据右对齐。 详情请参照: 《8.附件1: ID对齐方式.pdf》说明文档。// public uint TimeStamp; //设备接收到某一帧的时间标识。 时间标示从CAN卡上电开始计时,计时单位为0.1ms。// public byte TimeFlag; //时间标识,为1时TimeStamp有效// public byte SendType; //发送帧类型。=0时为正常发送(发送失败会自动重发,重发超时时间为4秒, 4秒内没有发出则取消);=1时为单次发送// public byte RemoteFlag; //是否是远程帧【RTR】。 =0时为数据帧, =1时为远程帧(数据段空)。// public byte ExternFlag; //是否是扩展帧。 =0时为标准帧(11位ID), =1时为扩展帧(29位ID)。// public byte DataLen; //数据长度 DLC (<=8),即CAN帧Data有几个字节。约束了后面Data[8]中的有效字节。// public fixed byte Data[8]; //如DataLen定义为3,即Data[0]、 Data[1]、 Data[2]是有效的。// public fixed byte Reserved[3];//系统保留。//}
unsafe public int Get_Receive(ref VCI_CAN_OBJ[] obj){//===1 等待加载=================DelaySecond(0.005);//5ms // USB速度3~5ms//===2 接口接收=================object obj2 = new object();//对象int num = Help_rtx.RXs(ref obj2);// can.get_Receive(CAN_DeviceType, CAN_ind, CAN1, ref obj[0], 2000, 50);if (num < 1) return 0;// 空退//===3 取出帧,并且分发=========obj = (VCI_CAN_OBJ[])obj2;//====3界面显示=================// 分发数据帧,UI层显示if (Wt_get != null){// 数组是引用类型VCI_CAN_OBJ[] uiObj = new VCI_CAN_OBJ[num];uiObj = obj;UIshow(num, uiObj);// //COB - ID Byte 0:1 Byte 2 Byte 3:7// //0x080 + Node - ID 应急错误代码 错误寄存器(1001H) 厂商指定区域// //byte0~1: 8120 【0x603F】// // 应急错误代码// // 0000H 无错误// // 8110H CAN 溢出// // 8120H 错误被动模式(0411)// // 8130H 寿命保护/ 心跳错误// // 8140H 被迫离线恢复故障// // 8141H 被迫离线// // 8150H 发送 COB - ID 冲突// // 8210H PDO 长度错误未处理// // 8220H PDO 超过长度// //byte2: 11// // (1001H)位定义// // Bit0:generic error 一般错误// // Bit1:current 电流// // Bit2:voltage 电压 (04)// // Bit3:temperature 温度// // Bit4:通讯// // Bit5:协议402错误// // Bit6:保留// // Bit7:伺服厂家// //————————————————// //版权声明:本文为CSDN博主「cfqq1989」的原创文章,遵循CC 4.0 BY - SA版权协议,转载请附上原文出处链接及本声明。// //原文链接:https://blog.csdn.net/cfqq1989/article/details/128308808//}// EMCY:故障(从站故障)80h + 从站//if (item.ID > 0x700 && item.ID < (0x700 + 127)) //从站状态//{// if (Wt_get!=null)// {// NMTslave slave=(NMTslave)p[0];// string sta = Enum.GetName(typeof(NMTslave), slave);// //string str = $"从站:{item.ID - 0x700}状态{p[0].ToString("X2")}; ";// string str = $"从站:{item.ID - 0x700}_{sta}; ";// Wt_get(null, str);// }//}}return num;}/// <summary>/// 【1 4 8】DLC长度,帧id,数据包64bit【小端】/// </summary>/// <param name="DLC"></param>/// <param name="CANid"></param>/// <param name="byte8"></param>/// <returns></returns>/// <exception cref="Exception"></exception>public bool Set_Send(Byte DLC, UInt32 CANid, Int64 byte8)// 1 4 8{//int hand = 0x88;// 设备:USR-CANET200//int cobid = 0x12345678;// 11bit或29bit//Int64 byte8 = 0x0011223344556677;//wait_dataRX数据池();//can.send(hand8, cobid, byte8);//wait_dataRX数据池();if (DLC > 8) DLC = 8;// <=8string cmd = madeCode((byte)DLC, (UInt32)CANid, byte8);// Code编码 "08 00000602 2B 5021 00 00000000"if (Help_rtx.TXs(cmd)==1)// 接口功能 "08000006022B50210000000000" // 单帧 13字节( 1 4 8 在接口解码发送){return true;}else throw new Exception("发送失败。检查主站硬件状态(是否开启?)!");//return false;}
2 SDO功能码:
void SDO(Region_Type regtype, UInt16 reg, Byte son, Int32 value)// 1操作类型,2寄存器编号,3子索引,4参数值{// SDO操作 600h+//========================================================// 准备发送Byte by0 = (Byte)regtype;//1 操作码【u8】UInt16 by1 = (UInt16)reg;//2 寄存器【u16】Byte by2 = (Byte)son;//3 子索引【u8】Int64 by3 = (Int32)value;//4设定值【u32】// b0 b1b2 b3 b4b5b6b7Byte8 = by0 + (by1 << 8) + (by2 << 24) + (by3 << 32); // 23 2000 00 11223344 Set_Send(0x08, 0x600 + Address, Byte8);// 40 2000 00 11223344}
3 SDO读:
读的数据帧发出后,伺服回帧包含【寄存器数据类型】【寄存器值】
这里 寄存器数据类型 需要标记,因为写寄存器时需要用到 【寄存器数据类型】
public enum Region_Type : byte{读 = 0x40, // 回帧0x60成功成功 = 0x60,失败 = 0x80,写b8 = 0x2F,写b16 = 0x2B,写b24 = 0x27,写b32 = 0x23,//寄存器bitb8 = 0x4F,//回帧:4F 寄存器有效长度 8bitb16 = 0x4B,b24 = 0x47,b32 = 0x43}
/// <summary>/// 【读】寄存器/// </summary>/// <param name="reg"></param>/// <param name="son"></param>/// <returns></returns>unsafe public Int32 SDO(UInt16 reg, Byte son)// 【读】寄存器,子索引【0x0000~0xFFFF】{// 读busy = true;//===1 get_数据类型=============//===2 get_Value===================SDO(Region_Type.读, reg, son, 0);//读//===2 get_帧===================#region get_ValueVCI_CAN_OBJ[] obj = new VCI_CAN_OBJ[2000];// 创芯科技CAN分析仪最大支持2000帧接收,广成10239帧Rx13 = new byte[13];// 提取数据帧DelaySecond(0.010);//10ms // USB速度3~5msint num = Get_Receive(ref obj);busy = false;if (num > 0)// 数据帧{for (int i = num - 1; i >= 0; i--){if (obj[i].ID == 0x580 + Address && obj[i].Data[0] != 0x60)// SDO 600h+的回信【580h+】{// 580h+从站地址 回帧//=====580h 寄存器类型====================Rx13[5] = obj[i].Data[0];// 2001.00=50000; // 4B,01 20,00, 50 C3 00 00 // // u16寄存器Rx13[6] = obj[i].Data[1];// 寄存器4B(b16位) 2001-00= 0x 0000C350Rx13[7] = obj[i].Data[2];// u8子索引Rx13[8] = obj[i].Data[3];// int32数据值Rx13[9] = obj[i].Data[4];// 小端Rx13[10] = obj[i].Data[5];Rx13[11] = obj[i].Data[6];Rx13[12] = obj[i].Data[7];//=====2======================//VCI_CAN_OBJ one = obj[i]; //break;}// SDO应答帧(580h+)}}else{Region_Obj = 0x80;// 故障return -1;}// 回帧结果Region_Obj = Rx13[5];// 标记: b8 = 0x4F, b16 = 0x4B, b24 = 0x47, b32 = 0x43 //0x6040是16bitint value = get_Value_U32(Rx13);// 解析 43,4060,00,0000 0000// 日志====================================if (Region_Obj < 0x43 | Region_Obj > 0x4F)// u8~32 读取失败 // 参考 enum region_Type //| Region_Type>(int)region_Type.b32{// 0x05030000 80 string error = getError(value, reg, son, -1); // 故障码,寄存器,子,值if (Wt_get != null){Wt_get(new byte[] { 0x00 }, "读取寄存器错误:" + error);}// throw new Exception("读取错误:" + error);// 提前终止}//错误else{//成功return value;}//正确#endregionreturn -1;}
4 SDO写:
unsafe public bool SDO(UInt16 reg, Byte son, Int32 value)//【写】{// 写busy = true;//===1 get寄存器数据类型=============Int32 data = SDO(reg, son);//读//===2 set_Value=====================if (Region_Obj >= 0x43 || Region_Obj <= 0x4F){SDO((Region_Type)Region_Obj - 0x20, reg, son, value);}else { return false; }//===2 get_帧===================#region get_ValueVCI_CAN_OBJ[] obj = new VCI_CAN_OBJ[2000];// 创芯科技CAN分析仪最大支持2000帧接收,广成10239帧Rx13 = new byte[13];// 提取数据帧DelaySecond(0.010);//10ms // USB速度3~5msint num = Get_Receive(ref obj);busy = false;if (num > 0)// 数据帧{for (int i = num - 1; i >= 0; i--){if (obj[i].ID == 0x580 + Address && obj[i].Data[0] == 0x60)// SDO 600h+的回信【580h+】{// 580h+从站地址 回帧return true;}// SDO应答帧(580h+)}}#endregionRegion_Obj = 0x80;// 故障return false;}
相关文章:
CANopen协议【SDO】
SDO: SDO是读写单个寄存器。主要用于配置伺服驱动器参数。 1 收发功能: //public unsafe struct VCI_CAN_OBJ //CAN数据帧 【单帧对象】//{// public uint ID;// 帧ID。 【11bit】数据右对齐。 详情请参照: 《8.附件1࿱…...
9-什么是迭代器,生成器,装饰器、django的信号用过吗?如何用,干过什么、什么是深拷贝,什么是浅拷贝,如何使用、slice操作符和list构造函数
1 什么是迭代器,生成器,装饰器 2 django的信号用过吗?如何用,干过什么 3 什么是深拷贝,什么是浅拷贝,如何使用 3.1 浅拷贝 3.2 深拷贝 3.3 扩展(slice操作符和list构造函数) 1 什么是迭代器,生成…...
RabbitMQ之发送者(生产者)可靠性
文章目录 前言一、生产者重试机制二、生产者确认机制实现生产者确认(1)定义ReturnCallback(2)定义ConfirmCallback 总结 前言 生产者重试机制、生产者确认机制。 一、生产者重试机制 问题:生产者发送消息时࿰…...
乐得瑞LDR6020 VR串流线方案:实现同时充电传输视频信号
VR(Virtual Reality),俗称虚拟现实技术,是一项具有巨大潜力的技术创新,正在以惊人的速度改变我们的生活方式和体验,利用专门设计的设备,如头戴式显示器(VR头盔)、手柄、定…...
【libGDX】Mesh纹理贴图
1 前言 纹理贴图的本质是将图片的纹理坐标与模型的顶点坐标建立一一映射关系。纹理坐标的 x、y 轴正方向分别朝右和朝下,如下。 2 纹理贴图 本节将使用 Mesh、ShaderProgram、Shader 实现纹理贴图,OpenGL ES 的实现见博客 → 纹理贴图。 DesktopLauncher…...
基线扫描tomcat安全加固-检查是否支持HTTPS等加密协议
背景:基线扫描时,docker镜像中的tomcat在检查是否支持HTTPS等加密协议这一项上未通过。 思路:先通过JDK自带的keytool工具生成证书,再从tomcat的server.xml配置文件中增加配置。 我不确定不同版本的JDK生成的证书是否可以通用&a…...
基于 STM32F7 和神经网络的实时人脸特征提取与匹配算法实现
本文讨论了如何使用 STM32F7 和神经网络模型来实现实时人脸特征提取与匹配算法。首先介绍了 STM32F7 的硬件和软件特点,然后讨论了人脸特征提取和匹配算法的基本原理。接下来,我们将重点讨论如何在 STM32F7 上实现基于神经网络的人脸特征提取与匹配算法&…...
Android笔记(十四):JetPack Compose中附带效应(一)
在Android应用中可以通过定义可组合函数来搭建应用界面。应用界面的更新往往是与可组合函数内部定义的状态值相关联的。当界面的状态值发生变更,会导致应用界面进行更新。在Android笔记(九):Compose组件的状态,对Compo…...
【web】Fastapi自动生成接口文档(Swagger、ReDoc )
简介 FastAPI是流行的Python web框架,适用于开发高吞吐量API和微服务(直接支持异步编程) FastAPI的优势之一:通过提供高级抽象和自动数据模型转换,简化请求数据的处理(用户不需要手动处理原始请求数据&am…...
竞赛选题 题目:基于FP-Growth的新闻挖掘算法系统的设计与实现
文章目录 0 前言1 项目背景2 算法架构3 FP-Growth算法原理3.1 FP树3.2 算法过程3.3 算法实现3.3.1 构建FP树 3.4 从FP树中挖掘频繁项集 4 系统设计展示5 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 基于FP-Growth的新闻挖掘算法系统的设计与实现…...
188. 股票买卖问题(交易次数为任意正整数)
题目 题解 class Solution:def maxProfit(self, k: int, prices: List[int]) -> int:N len(prices)# 定义状态:dp[i][j][k]表示在第i天,有j次交易机会,持有或不持有的最大利润dp [[[0 for i in range(2)] for j in range(k1)] for m in range(N)]f…...
Typescript怎样对URL参数进行编码?
URL中的参数需要进行编码(URL encoding)是为了确保传输的参数不包含特殊字符,同时确保数据的可靠性和安全性。 特殊字符如空格、&、?等在URL中有特殊含义,如果直接包含在参数值中,可能会导致解析错误或者安全问题…...
AndroidStudio2022.3.1 Patch3使用国内下载源加速
记录一下这个版本的as在使用国内下载源加速碰到的诸多问题。 一、gradle-8.0-bin.zip下载慢 编辑项目文件夹/gradle/wrapper/gradle-wrapper.properties,文件内容改为如下: #Fri Nov 24 18:50:06 CST 2023 distributionBaseGRADLE_USER_HOME distribu…...
Go语言的学习笔记2——Go语言源文件的结构布局
用一个只有main函数的go文件来简单说一下Go语言的源文件结构布局,主要分为包名、引入的包和具体函数。下边是main.go示例代码: package mainimport "fmt"func main() { fmt.Println("hello, world") }package main就是表明这个文件…...
python给视频增加字幕
python给视频增加字幕 安装所需库 在开始之前,我们需要安装一些Python库。主要使用到的库如下: moviepy:用于处理视频和音频的库。 pydub:用于处理音频的库。 speech_recognition:用于语音识别的库。 首先࿰…...
相机设置参数:黑电平(Black Level)详解和示例
本文通过原理和示例对相机设置参数“黑电平”进行讲解,以帮助大家理解和使用。 原理 相机中黑电平原理是将电平增大,可以显示更多暗区细节,可能会损失一些亮区,但图像更多的关注暗区,获取完图像信息再减掉。只是为了…...
Mac Ubuntu双系统解决WiFi和WiFi 5G网络不可用问题
文章目录 设备信息1. Ubuntu WiFi不可用解决方式查看Mac的网卡型号根据网卡型号搜索获取到的解决方法查看WiFi名字问题参考链接 2. 解决WiFi重启后失效问题打开终端创建.sh脚本文件编辑脚本文件复制粘贴脚本修改脚本权限创建并编辑systemd service文件复制粘贴下文到systemd se…...
数据分析基础之《matplotlib(2)—折线图》
一、折线图绘制与保存图片 1、matplotlib.pyplot模块 matplotlib.pyplot包含了一系列类似于matlab的画图函数。它的函数作用于当前图形(figure)的当前坐标系(axes) import matplotlib.pyplot as plt 2、折线图绘制与显示 展示城…...
Rust语言入门教程(三) - 函数与模块系统
函数 函数的定义 根据Rust的格式规范,函数名的格式应遵从蛇形命名法,即是用小写字母以及下划线组成,如: fn do_stuff(){ }Rust并不要求函数定义的位置必须在调用它之前,所以如果你习惯于把main函数放在最前面的话&a…...
ubuntu22.04 arrch64版在线安装java环境
脚本 #安装java#!/bin/bashif type -p java; thenecho "Java has been installed."else#2.Installed Java , must install wgetwget -c https://repo.huaweicloud.com/java/jdk/8u151-b12/jdk-8u151-linux-arm64-vfp-hflt.tar.gz;tar -zxvf ./jdk-8u151-linux-arm6…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
