Lee_cnQxtG · 2023年10月24日 · 山西

[XR806开发板试用]基于XR806开源鸿蒙开发板的四足仿生机器人

1、背景介绍

XR806开源鸿蒙开发板是一款基于华为鸿蒙操作系统的开源硬件平台,具有高度的可定制性和丰富的接口资源。近年来,随着人工智能和机器人技术的快速发展,四足仿生机器人成为了一个备受关注的研究领域。四足仿生机器人具有稳定的行走能力、较高的负载能力、适应复杂环境等优点,在救援、服务、娱乐等领域具有广泛的应用前景。因此,基于XR806开发板设计一个四足仿生机器人是很有意义的项目。
image.png

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;
具有上电复位,以及软件复位等功能。
引脚图示:
image.png

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的具体操作

  1. 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);
    }
  2. 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];
    }`
  3. 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、实物展示

    image.png

    5、总结

    通过本次设计,我们了解了基于XR806开源鸿蒙开发板的四足仿生机器人的设计和实现过程。在硬件选型方面,我们选择了合适的处理器、传感器、执行器和电源等部件,实现了对机器人主要功能的支持。在软件设计方面,我们基于华为鸿蒙操作系统开发了相应的控制和感知算法,实现了对机器人的精确控制和环境感知。通过这个项目,我们不仅学习了四足仿生机器人的相关知识,还掌握了XR806开发板的使用方法和相关算法的开发。未来,我们可以进一步优化机器人的性能和应用场景,实现更广泛的应用和发展。

推荐阅读
关注数
13823
内容数
139
全志XR806开发板相关的知识介绍以及应用专栏。
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息