1、背景介绍
XR806开源鸿蒙开发板是一款基于华为鸿蒙操作系统的开源硬件平台,具有高度的可定制性和丰富的接口资源。近年来,随着人工智能和机器人技术的快速发展,四足仿生机器人成为了一个备受关注的研究领域。四足仿生机器人具有稳定的行走能力、较高的负载能力、适应复杂环境等优点,在救援、服务、娱乐等领域具有广泛的应用前景。因此,基于XR806开发板设计一个四足仿生机器人是很有意义的项目。
2、硬件介绍
机器人身上有 12 个舵机,一个机器腿接 3 个舵机,连接到一个 pca9685 舵机驱动上,舵机驱动通过 I2C 与 XR806 通信,XR806 有两个 I2C 接口,我主要是用第 1 个 (B14, B15),通过控制 PCA9685 上的寄存器来简介控制舵机。
pca9685 参数:
I2C 接口,支持高达 16 路 PWM 输出,每路 12 位分辨率 (4096 级);
内置 25MHz 晶振,可不连接外部晶振,也可以连接外部晶振,最大 50MHz;
支持 2.3V-5.5V 电压,最大耐压值 5.5V, 逻辑电平 3.3V;
具有上电复位,以及软件复位等功能。
引脚图示:
3、软件介绍
3.1pca的初始化设计
首先要进行 i2c 初始化:
i2c_init(i2c_id);
导入相关库:
#include "driver/chip/hal_i2c.h"
#define i2c_id 1 # 使用第1个i2c
i2c 初始化函数:
void i2c_init(unsigned int id){
I2C_InitParam initParam;
initParam.addrMode = I2C_ADDR_MODE_7BIT;
initParam.clockFreq = 40000;
if (HAL_I2C_Init(id, &initParam) != HAL_OK) {
printf("i2c init fail!\n");
while(1);
} else {
printf("i2c init success!\n");
}
}
主要是调用 HAL_I2C_Init 函数对第 1 个 i2c 接口进行初始化。
初始化 pca9685:
pca9685_init(60);
pca9685_init 函数:
void pca9685_init(float hz) {
pca_write(pca_mode1, 0x0);
pca_setfreq(hz);
OS_MSleep(500);
}
3.2pca的具体操作
pca9685 写寄存器
void pca_write(uint8_t reg_addr, uint8_t data) { uint8_t buf[1]; buf[0] = data; HAL_I2C_Master_Transmit_Mem_IT(i2c_id, pca_adrr, reg_addr, I2C_MEMADDR_SIZE_8BIT, buf, 1); }
pca9685 读寄存器
`uint8_t pca_read(uint8_t reg_addr) { uint8_t buf[1]; HAL_I2C_Master_Receive_Mem_IT(i2c_id, pca_adrr, reg_addr, I2C_MEMADDR_SIZE_8BIT, buf, 1); return buf[0]; }`
pca9685 设置频率
void pca_setfreq(float freq) { uint8_t prescale,old_mode,new_mode; double prescaleval; freq *= 0.92; prescaleval = 25000000; prescaleval /= 4096; prescaleval /= freq; prescaleval -= 1; prescale =(uint8_t)(prescaleval + 0.5f); old_mode = pca_read(pca_mode1); new_mode = (old_mode & 0x7F) | 0x10; pca_write(pca_mode1, new_mode); pca_write(pca_pre, prescale); pca_write(pca_mode1, old_mode); OS_MSleep(2); pca_write(pca_mode1, old_mode | 0xa1); }
3.3pca中关于pwm的设定
核心代码段展示如下:
#include <stdio.h> #include "ohos_init.h" #include "kernel/os/os.h" // #include "iot_i2c.h" #include "driver/chip/hal_i2c.h" #include "iot_errno.h" #include "math.h" #define i2c_id 1 #define pca_adrr 0x40 // pca9685设备地址 #define pca_mode1 0x0 #define pca_pre 0xFE #define LED0_ON_L 0x6 #define LED0_ON_H 0x7 #define LED0_OFF_L 0x8 #define LED0_OFF_H 0x9 static OS_Thread_t g_main_thread; void pca_write(uint8_t reg_addr, uint8_t data) { uint8_t buf[1]; buf[0] = data; HAL_I2C_Master_Transmit_Mem_IT(i2c_id, pca_adrr, reg_addr, I2C_MEMADDR_SIZE_8BIT, buf, 1); } uint8_t pca_read(uint8_t reg_addr) { uint8_t buf[1]; HAL_I2C_Master_Receive_Mem_IT(i2c_id, pca_adrr, reg_addr, I2C_MEMADDR_SIZE_8BIT, buf, 1); return buf[0]; } void pca_setfreq(float freq) { uint8_t prescale,old_mode,new_mode; double prescaleval; freq *= 0.92; prescaleval = 25000000; prescaleval /= 4096; prescaleval /= freq; prescaleval -= 1; prescale =(uint8_t)(prescaleval + 0.5f); old_mode = pca_read(pca_mode1); new_mode = (old_mode & 0x7F) | 0x10; pca_write(pca_mode1, new_mode); pca_write(pca_pre, prescale); pca_write(pca_mode1, old_mode); OS_MSleep(2); pca_write(pca_mode1, old_mode | 0xa1); } void pca_setpwm(uint8_t num, uint32_t on, uint32_t off) { pca_write(LED0_ON_L+4*num,on); pca_write(LED0_ON_H+4*num,on>>8); pca_write(LED0_OFF_L+4*num,off); pca_write(LED0_OFF_H+4*num,off>>8); } void pca9685_init(float hz) { pca_write(pca_mode1, 0x0); pca_setfreq(hz); OS_MSleep(500); } void pca_rotate(uint8_t num,uint8_t angle) { uint32_t off=0; off=floor(angle * 2 + angle / 5 + 158); pca_setpwm(num, 0, off); } void i2c_init(unsigned int id){ I2C_InitParam initParam; initParam.addrMode = I2C_ADDR_MODE_7BIT; initParam.clockFreq = 40000; if (HAL_I2C_Init(id, &initParam) != HAL_OK) { printf("i2c init fail!\n"); while(1); } else { printf("i2c init success!\n"); } } static void MainThread(void *arg) { uint8_t i = 0; i2c_init(i2c_id); pca9685_init(60); printf("i2c and pca9685 init done.\n"); while(1){ pca_rotate(0, 0); OS_MSleep(1000); pca_rotate(0, 180); OS_MSleep(1000); } } void PCAMain(void) { printf("PCA9685 Motor Start.\n"); if (OS_ThreadCreate(&g_main_thread, "MainThread", MainThread, NULL, OS_THREAD_PRIO_APP, 10 * 1024) != OS_OK) { printf("[ERR] Create MainThread Failed\n"); } } SYS_RUN(PCAMain);
4、实物展示
5、总结
通过本次设计,我们了解了基于XR806开源鸿蒙开发板的四足仿生机器人的设计和实现过程。在硬件选型方面,我们选择了合适的处理器、传感器、执行器和电源等部件,实现了对机器人主要功能的支持。在软件设计方面,我们基于华为鸿蒙操作系统开发了相应的控制和感知算法,实现了对机器人的精确控制和环境感知。通过这个项目,我们不仅学习了四足仿生机器人的相关知识,还掌握了XR806开发板的使用方法和相关算法的开发。未来,我们可以进一步优化机器人的性能和应用场景,实现更广泛的应用和发展。