9.舵机状态读取¶
注意事项:
|
9.1.API¶
9.1.1.读取参数¶
函数原型
// 读取数据
FSUS_STATUS FSUS_ReadData(Usart_DataTypeDef *usart, uint8_t servoId, uint8_t address, uint8_t *value, uint8_t *size);
usart
舵机控制对应的串口数据对象Usart_DataTypeDef
servoId
舵机的IDaddress
只读参数或自定义参数地址value
读取到的数据存放指针size
读取到的数据的长度存放指针
使用示例
uint8_t servoId = 0; // 连接在转接板上的总线伺服舵机ID号
uint8_t value;
uint8_t dataSize;
statusCode = FSUS_ReadData(servoUsart, servoId, FSUS_PARAM_SERVO_STATUS, (uint8_t *)&value, &dataSize);
if (statusCode == FSUS_STATUS_SUCCESS)
{
// 舵机工作状态标志位
// BIT[0] - 执行指令置1,执行完成后清零。
// BIT[1] - 执行指令错误置1,在下次正确执行后清零。
// BIT[2] - 堵转错误置1,解除堵转后清零。
// BIT[3] - 电压过高置1,电压恢复正常后清零。
// BIT[4] - 电压过低置1,电压恢复正常后清零。
// BIT[5] - 电流错误置1,电流恢复正常后清零。
// BIT[6] - 功率错误置1,功率恢复正常后清零。
// BIT[7] - 温度错误置1,温度恢复正常后清零。
if ((value >> 3) & 0x01)
printf("read sucess, voltage too high\r\n");
if ((value >> 4) & 0x01)
printf("read sucess, voltage too low\r\n");
}
9.1.2.写入自定义参数¶
推荐使用上位机写入自定义参数。 |
函数原型
// 写入数据
FSUS_STATUS FSUS_WriteData(Usart_DataTypeDef *usart, uint8_t servoId, uint8_t address, uint8_t *value, uint8_t size);
usart
舵机控制对应的串口数据对象Usart_DataTypeDef
servoId
舵机的IDaddress
自定义参数地址value
写入的数据存放指针size
写入的数据的长度
使用示例
uint8_t servoId = 0; // 连接在转接板上的总线伺服舵机ID号
float angleLimitLow = -90.0; // 舵机角度下限设定值
value = (int16_t)(angleLimitLow*10); // 舵机角度下限 转换单位为0.1度
statusCode = FSUS_WriteData(servoUsart, servoId, FSUS_PARAM_ANGLE_LIMIT_LOW, (uint8_t *)&value, 2);
9.1.3.重置舵机自定义参数¶
函数原型
usart
舵机控制对应的串口数据对象Usart_DataTypeDef
servoId
舵机的ID
使用示例
9.2.例程¶
STM32F103_SDK下载链接:SDK for STM32F103
9.2.1.读取舵机参数(温度、功率、工作状态)¶
功能简介
读取舵机的实时状态,并且给出了判断工作状态异常的示例
- 电压
- 电流
- 功率
- 温度
- 工作状态标志位
// 舵机工作状态标志位
// BIT[0] - 执行指令置1,执行完成后清零。
// BIT[1] - 执行指令错误置1,在下次正确执行后清零。
// BIT[2] - 堵转错误置1,解除堵转后清零。
// BIT[3] - 电压过高置1,电压恢复正常后清零。
// BIT[4] - 电压过低置1,电压恢复正常后清零。
// BIT[5] - 电流错误置1,电流恢复正常后清零。
// BIT[6] - 功率错误置1,功率恢复正常后清零。
// BIT[7] - 温度错误置1,温度恢复正常后清零。
源代码
/***************************************************
* 读取舵机参数
***************************************************/
#include "stm32f10x.h"
#include "usart.h"
#include "sys_tick.h"
#include "fashion_star_uart_servo.h"
#include "math.h"
// 使用串口1作为舵机控制的端口
// <接线说明>
// STM32F103 PA9(Tx) <----> 总线伺服舵机转接板 Rx
// STM32F103 PA10(Rx) <----> 总线伺服舵机转接板 Tx
// STM32F103 GND <----> 总线伺服舵机转接板 GND
// STM32F103 V5 <----> 总线伺服舵机转接板 5V
// <注意事项>
// 使用前确保已设置usart.h里面的USART1_ENABLE为1
// 设置完成之后, 将下行取消注释
Usart_DataTypeDef *servoUsart = &usart1;
// 使用串口2作为日志输出的端口
// <接线说明>
// STM32F103 PA2(Tx) <----> USB转TTL Rx
// STM32F103 PA3(Rx) <----> USB转TTL Tx
// STM32F103 GND <----> USB转TTL GND
// STM32F103 V5 <----> USB转TTL 5V (可选)
// <注意事项>
// 使用前确保已设置usart.h里面的USART2_ENABLE为1
Usart_DataTypeDef *loggingUsart = &usart2;
// 重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
while ((loggingUsart->pUSARTx->SR & 0X40) == 0)
{
}
/* 发送一个字节数据到串口 */
USART_SendData(loggingUsart->pUSARTx, (uint8_t)ch);
/* 等待发送完毕 */
// while (USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET);
return (ch);
}
uint8_t servoId = 0; // 连接在转接板上的总线伺服舵机ID号
FSUS_STATUS statusCode; // 状态码
int main(void)
{
// 嘀嗒定时器初始化
SysTick_Init();
// 串口初始化
Usart_Init();
// 读取用户自定义数据
// 数据表里面的数据字节长度一般为1个字节/2个字节/4个字节
// 查阅通信协议可知,舵机角度上限的数据类型是有符号短整型(UShort, 对应STM32里面的int16_t),长度为2个字节
// 所以这里设置value的数据类型为int16_t
int16_t value;
uint8_t dataSize;
// 传参数的时候, 要将value的指针强行转换为uint8_t
// 读取电压
statusCode = FSUS_ReadData(servoUsart, servoId, FSUS_PARAM_VOLTAGE, (uint8_t *)&value, &dataSize);
printf("read ID: %d\r\n", servoId);
if (statusCode == FSUS_STATUS_SUCCESS)
{
printf("read sucess, voltage: %d mV\r\n", value);
}
else
{
printf("fail\r\n");
}
// 读取电流
statusCode = FSUS_ReadData(servoUsart, servoId, FSUS_PARAM_CURRENT, (uint8_t *)&value, &dataSize);
if (statusCode == FSUS_STATUS_SUCCESS)
{
printf("read sucess, current: %d mA\r\n", value);
}
else
{
printf("fail\r\n");
}
// 读取功率
statusCode = FSUS_ReadData(servoUsart, servoId, FSUS_PARAM_POWER, (uint8_t *)&value, &dataSize);
if (statusCode == FSUS_STATUS_SUCCESS)
{
printf("read sucess, power: %d mW\r\n", value);
}
else
{
printf("fail\r\n");
}
// 读取温度
statusCode = FSUS_ReadData(servoUsart, servoId, FSUS_PARAM_TEMPRATURE, (uint8_t *)&value, &dataSize);
if (statusCode == FSUS_STATUS_SUCCESS)
{
double temperature, temp;
temp = (double)value;
temperature = 1 / (log(temp / (4096.0f - temp)) / 3435.0f + 1 / (273.15 + 25)) - 273.15;
printf("read sucess, temperature: %f\r\n", temperature);
}
else
{
printf("fail\r\n");
}
// 读取工作状态
statusCode = FSUS_ReadData(servoUsart, servoId, FSUS_PARAM_SERVO_STATUS, (uint8_t *)&value, &dataSize);
if (statusCode == FSUS_STATUS_SUCCESS)
{
// 舵机工作状态标志位
// BIT[0] - 执行指令置1,执行完成后清零。
// BIT[1] - 执行指令错误置1,在下次正确执行后清零。
// BIT[2] - 堵转错误置1,解除堵转后清零。
// BIT[3] - 电压过高置1,电压恢复正常后清零。
// BIT[4] - 电压过低置1,电压恢复正常后清零。
// BIT[5] - 电流错误置1,电流恢复正常后清零。
// BIT[6] - 功率错误置1,功率恢复正常后清零。
// BIT[7] - 温度错误置1,温度恢复正常后清零。
if ((value >> 3) & 0x01)
printf("read sucess, voltage too high\r\n");
if ((value >> 4) & 0x01)
printf("read sucess, voltage too low\r\n");
}
else
{
printf("fail\r\n");
}
printf("================================= \r\n");
// 死循环
while (1)
;
}
输出日志
read ID: 0 //舵机ID
read sucess, VOLTAG: 8905 mV //当前电压
read sucess, CURRENT: 0 mA //当前电流
read sucess, POWER: 0 mW //当前功率
read sucess, temperature: 32.240993 //当前温度
read sucess, VOLTAGE too high //如果当前电压超过舵机参数设置的舵机高压保护值,可以读到标志位
=================================
附表1 - 只读参数表¶
address | 参数 名称 (en) | 参数 名称 (cn) | 字节 类型 | 字节 长度 | 说明 | 单位 |
---|---|---|---|---|---|---|
1 | voltage | 舵机电压 | uint16_t | 2 | mV | |
2 | current | 舵机电流 | uint16_t | 2 | mA | |
3 | power | 舵机功率 | uint16_t | 2 | mW | |
4 | temprature | 舵机温度 | uint16_t | 2 | ADC | |
5 | servo_status | 舵机工作状态 | uint8_t | 1 | BIT[0] - 执行指令置1,执行完成后清零。 BIT[1] - 执行指令错误置1,在下次正确执行后清零。 BIT[2] - 堵转错误置1,解除堵转后清零。 BIT[3] - 电压过高置1,电压恢复正常后清零。 BIT[4] - 电压过低置1,电压恢复正常后清零。 BIT[5] - 电流错误置1,电流恢复正常后清零。 BIT[6] - 功率错误置1,功率恢复正常后清零。 BIT[7] - 温度错误置1,温度恢复正常后清零。 | |
6 | servo_type | 舵机型号 | uint16_t | 2 | ||
7 | firmware_version | 舵机固件版本 | uint16_t | 2 | ||
8 | serial_number | 舵机序列号 | uint32_t | 4 | 舵机序列号(serial_number)并不是舵机ID,它是舵机的唯一识别符。 |
附表2 - 自定义参数表¶
address | 参数 名称 (en) | 参数 名称 (cn) | 字节 类型 | 字节 长度 | 说明 | 单位 |
---|---|---|---|---|---|---|
32 | <预留> | uint8_t | ||||
33 | response_switch | 响应开关 | uint8_t | 1 | 0 - 舵机控制指令执行可以被中断,新的指令覆盖旧的指令,无反馈数据 1 - 舵机控制指令不可以被中断,指令执行结束之后发送反馈数据 | |
34 | servo_id | 舵机ID | uint8_t | 1 | 舵机的ID号初始默认设置为0。修改此值可以修改舵机的ID号 | |
35 | <预留> | uint8_t | ||||
36 | baudrate | 波特率选项 | uint8_t | 1 | 1 - 9600 2 - 19200 3 - 38400 4 - 57600 5 - 115200 6 - 250000 7 - 500000 8 - 1000000 | |
37 | stall_protect_mode | 舵机堵转保护模式 | uint8_t | 1 | 0 - 将舵机功率降低到功率上限 1 - 释放舵机锁力(舵机卸力) | |
38 | stall_power_limit | 舵机堵转功率上限 | uint16_t | 2 | mW | |
39 | over_volt_low | 舵机电压下限 | uint16_t | 2 | mV | |
40 | over_volt_high | 舵机电压上限 | uint16_t | 2 | mV | |
41 | over_temprature | 温度上限 | uint16_t | 2 | 见附表3 | ADC |
42 | over_power | 功率上限 | uint16_t | 2 | mW | |
43 | over_current | 电流上限 | uint16_t | 2 | mA | |
44 | accel_switch | 加速度处理开关 | uint8_t | 1 | 舵机目前必须设置启用加速度处理,即只能设置0x01这个选项。 | |
45 | <预留> | uint8_t | 1 | |||
46 | po_lock_switch | 舵机上电锁力开关 | uint8_t | 1 | 0 - 上电舵机释放锁力 1 - 上电舵机保持锁力 | |
47 | wb_lock_switch | 轮式刹车锁力开关 | uint8_t | 1 | 0 - 停止时释放舵机锁力 1 - 停止时保持舵机锁力 | |
48 | angle_limit_switch | 角度限制开关 | uint8_t | 1 | 0 - 关闭角度限制 1 - 开启角度限制 | |
49 | soft_start_switch | 上电首次缓慢执行 | uint8_t | 1 | 0 - 关闭上电首次缓慢执行 1 - 开启上电首次缓慢执行 | |
50 | soft_start_time | 上电首次执行时间 | uint16_t | 2 | ms | |
51 | angle_limit_high | 舵机角度上限 | int16_t | 2 | 0.1度 | |
52 | angle_limit_low | 舵机角度下限 | int16_t | 2 | 0.1度 | |
53 | angle_mid_offset | 舵机中位角度偏移 | int16_t | 2 | 0.1度 |
附表3 - 温度ADC值转换表¶
温度为ADC值,需要进行转换。
以下为50-79℃ 温度/ADC参照表。
温度(℃) | ADC | 温度(℃) | ADC | 温度(℃) | ADC |
---|---|---|---|---|---|
50 | 1191 | 60 | 941 | 70 | 741 |
51 | 1164 | 61 | 918 | 71 | 723 |
52 | 1137 | 62 | 897 | 72 | 706 |
53 | 1110 | 63 | 876 | 73 | 689 |
54 | 1085 | 64 | 855 | 74 | 673 |
55 | 1059 | 65 | 835 | 75 | 657 |
56 | 1034 | 66 | 815 | 76 | 642 |
57 | 1010 | 67 | 796 | 77 | 627 |
58 | 986 | 68 | 777 | 78 | 612 |
59 | 963 | 69 | 759 | 79 | 598 |