角度编码器 ST-3806-15-RS
在 两轴机械臂+机械爪整体控制板设计与机械爪控制调试 双轴机械臂的控制中,使用了基于 BH38旋转编码器初步测试 作为两个关节的运动角度测量,但是由于BH38传感器采用了MODBUS协议,所使用的串口波特率(19200)无法改变,致使解读读取的时间大约是10ms(具体读取信号波形参见 BH60绝对位置编码器测试 ),这对于机械臂运动动态调整造成了困难。
在 闭环步进电机平顺控制算法: 42HS48EIS,57HS 对于角度读取的时间延迟采用了补偿的方法,虽然有一定的效果,但是还是没有被彻底解决控制的平顺问题。
下面测试ST-3806-15-RS角度传感器,希望解决以下问题:
- 能够将角度读取的时间缩短到1ms左右;
- 角度的分辨率提高到15bit。
■ 编码器ST-3806-15-RS
- 编码器的基本资料参加: ST-3806系列单圈编码器 说明书 。
- 对于编码器的测试参见: ST-3806系列单圈编码器 测试说明 。
1.基本信息
- 型号:ST-3806-15-RS
- 工作电压:DC5-24V
- 接口定义:
红/RD | 黑/BK | 绿/GN | 黄/YE | 白/WH |
---|---|---|---|---|
+5~24V | 0V | 485A+ | 485B- | SET |
- 出品公司:上海默马科技有限公司
▲ 角度编码器 ST-3806-15-RS
01测试电路板设计
对于博文中 基于STC8H1K28的双轴机械臂驱动模块 的模块进行修正。在传感器接口处增加一个管脚(设置SET),形成新的传感器读写模块。
下面对应的电路板设计和软件设计。
1. SCH和PCB1
▲ #zxhn 01测试电路设计
2.软件工程文件2
单片机的软件工程文件采用与基于STC8H1K28的双轴机械臂驱动模块相同的工程文件进行测试。但是由于原来的模块中存在着旧的代码,程序体积过大,所以建立新的测试软件3。
02软件初步调试
1.设置UART2波特率
//------------------------------------------------------------------------------
void SetUART2Baud(unsigned long lnBaud) {unsigned long lnNumber;unsigned int nNumber;lnNumber = OSC_FREQUENCY;lnNumber /= lnBaud * 4;nNumber = 0xffff - (unsigned int)lnNumber;T2H = nNumber >> 8;T2L = nNumber & 0xff;
}
下面是SetUART2Baud(9600)对应的TXD2的波形。
▲ 波特率=9600的波形
2.ST3806子函数
(1) 设置ST3806波特率
else IFARG0("sb115200") {printf("Set ST3806 baud 115200:\r\n");ON(ST3806_SET1_PIN);WaitTime(3000);OFF(ST3806_SET1_PIN);WaitTime(1000);SetUART2Baud(9600);ucRet = ST3806SetBaud115200();printf("Set Result: %bd\r\n", ucRet);SetUART2Baud(115200);
请注意,在前面设置波特率前,设置SET管脚为高电平3秒钟,以保证ST3806被初始化为缺省的9600波特率。
如下是在115200下读写485总线波形。时间长度大约是2.2ms.
▲ 读取数据的485总线波形
(2) 读取ST3806角度
ST3806的角度值是在寄存器地址00(0x00),前后两个字节(高端字节在前)表示了一个15bit的角度值。
//------------------------------------------------------------------------------
unsigned int ST3806Buffer2Number(void) {unsigned int nNumber;nNumber = g_ucST3806Buffer[3];nNumber = (nNumber << 8) + g_ucST3806Buffer[4];return nNumber;
}//------------------------------------------------------------------------------
unsigned int ST3806ReadNumber(unsigned char ucChannel) {ST3806SetChannel(ucChannel);ST3806ReadData2Buffer();return ST3806Buffer2Number();
}
在读取时间上,ST3806返回数据的时刻具有某种随机性。这一点在控制方面需要谨慎。
▲ 读取时间的不确定性
在快速读取的时候,这种结果的返回抖动则更加的明显。结果的抖动时间前后大约1.5ms左右。
▲ 在快速读取的时候,这种结果返回的抖动更加明显
03C51代码
/*
**==============================================================================
** ST3806.C: -- by Dr. ZhuoQing, 2020-09-14
**
**==============================================================================
*/#include "C51BASIC.H"
#include "STC8H.H"//------------------------------------------------------------------------------
#define ST3806_GLOBALS 1 // Define the global variables
#include "ST3806.H"//------------------------------------------------------------------------------//------------------------------------------------------------------------------
void ST3806Init(unsigned char ucAddress) {OFF(ST3806_DIR1_PIN);PM_PP(ST3806_DIR1_PIN);OFF(ST3806_DIR2_PIN);PM_PP(ST3806_DIR2_PIN);OFF(ST3806_SET1_PIN);PM_PP(ST3806_SET1_PIN);OFF(ST3806_SET2_PIN);PM_PP(ST3806_SET2_PIN);g_ucST3806Address = ucAddress; g_ucST3806Channel = ST3806_CHANNEL_1;
}//------------------------------------------------------------------------------
void ST3806SetChannel(unsigned char ucChannel) {g_ucST3806Channel = ucChannel;OFF(ST3806_DIR1_PIN);OFF(ST3806_DIR2_PIN);
}void ST3806DirON(void) {if(g_ucST3806Channel == ST3806_CHANNEL_1) {OFF(ST3806_DIR2_PIN);ON(ST3806_DIR1_PIN);} else {OFF(ST3806_DIR1_PIN);ON(ST3806_DIR2_PIN); }}void ST3806DirOFF(void) {OFF(ST3806_DIR2_PIN);OFF(ST3806_DIR1_PIN);
}//------------------------------------------------------------------------------
unsigned int ModbusCRC(unsigned char * pByte, int nLength) {unsigned int nCRC;unsigned int i;unsigned char ucByte, j;nCRC = 0xffff;for(i = 0; i < nLength; i ++) {ucByte = *(pByte + i);nCRC ^= (unsigned int)ucByte;for(j = 0; j < 8; j ++) {if((nCRC & 0x1) != 0) {nCRC >>= 1;nCRC ^= 0xA001;} else nCRC >>= 1;} }return nCRC;
}//------------------------------------------------------------------------------
void ST3806AppendCRC(unsigned char ucLength) {unsigned int nCRC;nCRC = ModbusCRC(g_ucST3806Buffer, ucLength);g_ucST3806Buffer[ucLength + 1] = (unsigned char)(nCRC >> 8);g_ucST3806Buffer[ucLength] = (unsigned char)nCRC;
}//------------------------------------------------------------------------------
void ST3806SendBuffer(unsigned char ucLength) {unsigned char i;ST3806AppendCRC(ucLength);ST3806DirON();for(i = 0; i < ucLength + 2; i ++) {UART2SendChar(g_ucST3806Buffer[i]);}ST3806DirOFF();UART2_CLEAR;}//------------------------------------------------------------------------------
unsigned char ST3806SetBaud115200(void) {unsigned char i, c;g_ucST3806Buffer[0] = g_ucST3806Address;g_ucST3806Buffer[1] = 0x10;g_ucST3806Buffer[2] = 0x0;g_ucST3806Buffer[3] = 0x3;g_ucST3806Buffer[4] = 0x0;g_ucST3806Buffer[5] = 0x1;g_ucST3806Buffer[6] = 0x2;g_ucST3806Buffer[7] = 0x0;g_ucST3806Buffer[8] = 0x5;ST3806SendBuffer(9);for(i = 0; i < 100; i ++) {if(UART2ReceChar(&c) == 0) break;}if(i < 100)g_ucST3806Buffer[0] = c;else return 1;
/* for(i = 1; i < 8; i ++) {if(UART2ReceChar(&c)) return 10+i;g_ucST3806Buffer[i] = c;}
*/ return 0;
}//------------------------------------------------------------------------------
unsigned char ST3806ReadData2Buffer(void) {unsigned char i, c;g_ucST3806Buffer[0] = g_ucST3806Address;g_ucST3806Buffer[1] = 0x3;g_ucST3806Buffer[2] = 0x0;g_ucST3806Buffer[3] = 0x0;g_ucST3806Buffer[4] = 0x0;g_ucST3806Buffer[5] = 0x1;ST3806SendBuffer(6);g_ucST3806Buffer[3] = 0x0;g_ucST3806Buffer[4] = 0x0;g_ucST3806Buffer[5] = 0x0;g_ucST3806Buffer[6] = 0x0;for(i = 0; i < 10; i ++) {if(UART2ReceChar(&c) == 0) break;}if(i < 10)g_ucST3806Buffer[0] = c;else return 1;for(i = 1; i < 9; i ++) {if(UART2ReceChar(&c)) return 1;g_ucST3806Buffer[i] = c;}return 0;}//------------------------------------------------------------------------------
unsigned char ST3806ReadConfig2Buffer(void) {unsigned char i, c;g_ucST3806Buffer[0] = g_ucST3806Address;g_ucST3806Buffer[1] = 0x3;g_ucST3806Buffer[2] = 0x0;g_ucST3806Buffer[3] = 0x0;g_ucST3806Buffer[4] = 0x0;g_ucST3806Buffer[5] = 0x3;ST3806SendBuffer(6);for(i = 0; i < 10; i ++) {if(UART2ReceChar(&c) == 0) break;}if(i < 10)g_ucST3806Buffer[0] = c;else return 1;for(i = 1; i < 11; i ++) {if(UART2ReceChar(&c)) return 1;g_ucST3806Buffer[i] = c;}return 0;
}//------------------------------------------------------------------------------
unsigned int ST3806Buffer2Number(void) {unsigned int nNumber;nNumber = g_ucST3806Buffer[3];nNumber = (nNumber << 8) + g_ucST3806Buffer[4];return nNumber;
}//------------------------------------------------------------------------------
unsigned int ST3806ReadNumber(unsigned char ucChannel) {ST3806SetChannel(ucChannel);ST3806ReadData2Buffer();return ST3806Buffer2Number();
}//==============================================================================
// END OF THE FILE : ST3806.C
//------------------------------------------------------------------------------
/*
**==============================================================================
** ST3806.H: -- by Dr. ZhuoQing, 2020-09-14
**
** Description:
**
**==============================================================================
*/
#ifndef __ST3806__
#define __ST3806__
//------------------------------------------------------------------------------
#ifdef ST3806_GLOBALS#define ST3806_EXT
#else#define ST3806_EXT extern
#endif // ST3806_GLOBALS
//------------------------------------------------------------------------------
//==============================================================================//------------------------------------------------------------------------------//------------------------------------------------------------------------------
#define ST3806_ADDRESS 1
#define ST3806_DIR1_PIN 1, 2
#define ST3806_DIR2_PIN 1, 3
#define ST3806_SET1_PIN 2, 4
#define ST3806_SET2_PIN 2, 3 //==============================================================================
void ST3806Init(unsigned char ucAddress); // ucAddress: Default is 1#define ST3806_CHANNEL_1 0
#define ST3860_CHANNEL_2 1ST3806_EXT unsigned char g_ucST3806Channel;
void ST3806SetChannel(unsigned char ucChannel);
void ST3806DirON(void);
void ST3806DirOFF(void);//------------------------------------------------------------------------------
#define ST3806_BUFFER 16ST3806_EXT unsigned char xdata g_ucST3806Buffer[ST3806_BUFFER];
ST3806_EXT unsigned char xdata g_ucST3806Address;unsigned int ModbusCRC(unsigned char * pByte, int nLength);
void ST3806AppendCRC(unsigned char ucLength);//------------------------------------------------------------------------------
void ST3806SendCharBuffer(unsigned char ucLength);unsigned char ST3806ReadData2Buffer(void);
unsigned char ST3806ReadConfig2Buffer(void);unsigned int ST3806Buffer2Number(void);//------------------------------------------------------------------------------
unsigned int ST3806ReadNumber(unsigned char ucChannel); // Return about 2ms(&115200bps)unsigned char ST3806SetBaud115200(void);//==============================================================================
// END OF THE FILE : ST3806.H
//------------------------------------------------------------------------------
#endif // __ST3806__
※ 附录
■ 相关文献链接:
- 两轴机械臂+机械爪整体控制板设计与机械爪控制调试
- BH38旋转编码器初步测试
- BH60绝对位置编码器测试
- 闭环步进电机平顺控制算法: 42HS48EIS,57HS
- ST-3806系列单圈编码器 说明书
- ST-3806系列单圈编码器 测试说明
- 基于STC8H1K28的双轴机械臂驱动模块:步进电机42HS348E,BH32角度传感器
设计AD工程文件:AD\XQWF\2020\机械臂\CNT2AXESCLAWSTC8H.SchDoc ↩︎
单片机软件工程文件:C51\STC\Project\XQWF\2020\STC8H2AXES\STC8H2AXES.uvproj ↩︎
新建的测试C51工程文件:C51\STC\Project\XQWF\2020\TestST3806\TestST3806.uvproj ↩︎
角度编码器 ST-3806-15-RS相关推荐
- 微型角度编码器 : KYTB-1503-1024
简 介: 通过ESP32 对于KYTB角度编码器进行测试,初步验证了KYTB的基本功能.由于ESP32的端口中断具有最大上限频率,通过实验测量到这个频率大约为26kHz. 关键词: 角度编码器,KYT ...
- pwm控制舵机转动角度程序_Mixly 第15课 舵机的使用
第15课 舵机的使用 舵机的旋转不像普通电机那样只是转圈圈,它可以根据你的指令旋转到0至180度之间的任意角度然后精准的停下来.舵机的转动的角度是通过调节PWM(脉冲宽度调制)信号的占空比来实现的. ...
- 海德汉角度编码器RCN727F与替代型号RCN8390F参数对比
广州希洛登自动控制技术有限公司 海德汉圆光栅尺编码器RCN727F是 fanuc系统专用的绝对式编码器 Fanuc02串口孔径有60和100mm2种 电缆有0.5米.1米.3米.5米几大类 精度是2角 ...
- HM编码器代码阅读(15)——帧间预测之AMVP模式(三)xGetBlkBits函数
GetBlkBits函数的主要功能是计算使用某种PU划分模式的时候,该种模式占用的比特数 Void TEncSearch::xGetBlkBits( PartSize eCUMode, Bool bP ...
- 计算编码器零点电角度偏移量
编码器零点电角度偏移量 同步电机的控制,转子的位置是必要的反馈.电机的磁极的换向,控制的是电角度. 编码器的安装和电角度,存在误差. 机械角度的反馈,在多极对数时,需要做一个电角度的转换,进入控制的转 ...
- rs=st.executeQuery(sql);报错
rs=st.executeQuery(sql);一直是红色显示无法解析Statement中的方法excuteQuery package com.dao;import com.Utils.JDBCUti ...
- ST-3806系列单圈编码器 说明书
▲ 角度编码器 ST-3806-15-RS https://item.taobao.com/item.htm?spm=a1z09.2.0.0.745e2e8dPZ3LXR&id=5928237 ...
- 【机器人】从机械臂示教器导出编码器数据到U盘中的操作步骤
工业机器人 注:这里针对我使用的工业机械臂CRP1410,不同机器人操作方式不完全相同 Question:当机械臂按照运动指令运动后,如何将运动过程中的编码器数据导出到U盘进而在计算机中进行处理呢? ...
- 步进电机基础(6.2)-步进电机的特性测量方法-动态特性的测量法和步距角度精度的测量
步进电机基础(6.2)-步进电机的特性测量方法-动态特性的测量法和步距角度精度的测量 前言 基本信息 前言说明 6.2 动态特性的测量法 1 . 滑轮平衡法 2 . 磁滞制动法 3 . 利用扭力棒转矩 ...
最新文章
- python的requests模块功能_《Python数据可视化编程实战》—— 1.7 安装requests模块-阿里云开发者社区...
- 为什么我们不应该使用过多的线程
- python 正整数 连续多个数之和_vijos - P1302连续自然数和 (公式推导 + python)
- python字符串和List:索引值以 0 为开始值,-1 为从末尾的开始位置;值和位置的区别哦...
- 编程不仅是写代码!?
- 接口进阶 java 1614956772
- Java Protected 解读
- void main(){char str[] = “\tab\n\014\\\“;printf(“%d“,strlen(str))}
- spark记录(7)SparkCore的调优之数据倾斜调优
- 区块链 共识算法 分类
- Decorator设计模式(装饰)
- SC-GlowTTS论文阅读
- 喜讯 | 哈特公寓荣誉获最佳新锐公寓奖
- 基于lerna重构Concis组件库
- [ ERROR ] Suite ‘Test1‘ contains no tests matching tag ‘run‘ and matching name ‘Test1.test2‘ in suit
- 下载文件、根据链接生成二维码
- win10中文字符乱码解决方案
- 输出一句英文话语中的单词数量
- Struts2框架简单入门
- 御剑系列扫描工具(五款)下载
热门文章
- [转]为什么程序员总是写糟糕的代码?这3个原因
- iOS开发网络篇—GET请求和POST请求
- 排除hotnews主题内容页面上的热点图片推荐里的分类-hotnews主题top_hot.php
- EFMVC - ASP.NET MVC 3 and Entity Framework 4.1 Code First 项目介绍
- 在.NET 3.5 平台上使用LINQ to SQL创建三层/多层Web应用系统 (Part 1)
- Python3.5模块‘OS’‘sys’
- webstrom常用键
- 开发人员学Linux(4):使用JMeter对网站和数据库进行压力测试
- 使用JDBC进行批处理
- MyEclipse设置JSP页面默认编码方式