2

OpenHarmony有氧拳击之设备端开发-开源基础软件社区-51CTO.COM

 2 years ago
source link: https://ost.51cto.com/posts/16219
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

OpenHarmony有氧拳击之设备端开发 精华

OpenHarmony有氧拳击之设备端开发
一、简介
在一个风和日丽,阳光明媚的下午,码农们都像往常一样正在专注地码代码。突然前面的小哥哥站起来,手握开发板,来回出拳。这是怎么回事?

原来这是一款拳击互动游戏,本文将带你一同解开其中的奥秘。开发者从中不仅能体验到学习知识的愉悦,还能享受到健身的乐趣。依托OpenAtom OpenHarmony(以下简称“OpenHarmony”)3.2 Beta1操作系统,样例分为应用端和设备端两部分。本文主要介绍设备端的实现,后续会分享应用端的开发。

设备端:采用小熊派BearPi-HM Nano(Hi3861)开发板,处理加速度计传感器数据。

应用端:采用润和DAYU200(RK3568)开发板,主要处理显示及音效。

如下图,左侧为设备端,右侧为应用端:开发者手握设备端小熊派开发板,观察屏幕,根据应用端APP显示,在指定的时间完成挥拳动作;挥拳信息经无线传递到应用端,应用端APP对挥拳时机有相应的计分规则,最后统计出总分。

OpenHarmony有氧拳击之设备端开发-开源基础软件社区

二、原理
相比正常状态下,挥拳动作会引起手臂较大的加速度变化。根据这个特征,我们使用BearPi-HM_Nano开发板的扩展模块E53_SC2,它内部集成了MPU6050传感器,能够读取加速度的大小。

做挥拳动作实验,统计数据,得到挥拳时加速度的阈值。程序执行时,把实时的数据与阈值进行比较,判断是否触发了挥拳动作。再经过无线通信,实时把数据发送到应用端。

三、加速度计传感器使用说明
设备端的开发关键在对加速度计传感器的使用,主要涉及两点:1、重力加速度g的理解;2、如何把MPU6050寄存器的数据转化为有单位的数据?

1、样例使用的加速度传感器是MPU6050,它有±2g、±4g、±8g和±16g四个量程可以选择。一个g是指一个重力加速度,代表9.8米/秒²大小。举个例子:假如设备从高处掉落,其加速计测量到的加速度将为0g,因为传感器没有受到力的挤压,处在失重状态;假如设备水平放在桌面上,则加速计测量出的加速度为1g(9.8米/秒²),我们可以理解为受到1g的压力;

2、MPU6050采用16位的ADC采样。16位的ADC采样是什么意思?举个例子:如果量程选择(通过寄存器选择)是±2g,16位的ADC采样,表示的含义是用65536(即2的16次方)种情况去表达-2到+2g的情况。如下datasheet截图显示,AFS_SEL=0,表示±2g量程,当数据寄存器的数据为16384,对应表示受到1g的力。例如:数据寄存器读取到的值为X,对应受到的力的大小为Y,则Y=X/16384,单位是g。

OpenHarmony有氧拳击之设备端开发-开源基础软件社区

四、代码解析
设备端代码主要分为两个线程:1、传感器数据处理线程;2、TCP通信线程;它们之间通过事件的方式进行同步通信。

1、传感器数据处理线程主要函数说明:

//E53_SC2模块MPU6050传感器数据处理主要流程
static void DataHandleTask(void)
{
    uint8_t ret;
    ret = E53SC2Init();//MPU6050传感器初始化及配置,配置为+—8g量程
    if (ret != 0) {
        printf("E53_SC2 Init failed!\r\n");
        return;
    }
    while (1)  {
        ret = E53SC2ReadData(&data);//MPU6050传感器寄存器数据读取
        if (ret != 0)  {
            printf("E53_SC2 Read Data!\r\n");
            return;
        }
        AccDataHandle(&data);//MPU6050传感器数据处理,转化为单位为g的数据
        if (myCaldata.Accel[ACCEL_X_AXIS] < 0) {
            myCaldata.Accel[ACCEL_X_AXIS] = myCaldata.Accel[ACCEL_X_AXIS] * -1.0; 
        }
        if (myCaldata.Accel[ACCEL_Y_AXIS] < 0) {
            myCaldata.Accel[ACCEL_Y_AXIS] = myCaldata.Accel[ACCEL_Y_AXIS] * -1.0; 
        }
        if (myCaldata.Accel[ACCEL_Z_AXIS] < 0) {
            myCaldata.Accel[ACCEL_Z_AXIS] = myCaldata.Accel[ACCEL_Z_AXIS] * -1.0; 
        }
        //判断实时数据是否大于拳击阈值Boxing_ACC,大于则设置事件
       if (myCaldata.Accel[ACCEL_X_AXIS] > Boxing_ACC ||                          myCaldata.Accel[ACCEL_Y_AXIS] > Boxing_ACC || myCaldata.Accel[ACCEL_Z_AXIS] > Boxing_ACC) {
            printf("MPU set flg\r\n");
            osEventFlagsSet(g_eventFlagsId, FLAGS_MSK1);//触发拳击事件
        }
        usleep(Delay_10ms);
    }
}
#define MAX_POS_NUM 32767
#define LSB 4096.0
//MPU6050传感器数据处理,转化为单位为g的数据
int AccDataHandle(E53SC2Data *dat)
{    //量程为+-8g,所以分辨率为4096
    if (dat->Accel[ACCEL_X_AXIS] <  MAX_POS_NUM) {
        myCaldata.Accel[ACCEL_X_AXIS] = dat->Accel[ACCEL_X_AXIS]/LSB;
    } else {
        myCaldata.Accel[ACCEL_X_AXIS] =(-1)* (dat->Accel[ACCEL_X_AXIS]-MAX_POS_NUM)/LSB;
    }
    if (dat->Accel[ACCEL_Y_AXIS] <  MAX_POS_NUM) {
        myCaldata.Accel[ACCEL_Y_AXIS] = dat->Accel[ACCEL_Y_AXIS]/LSB;
    } else {
        myCaldata.Accel[ACCEL_Y_AXIS] = (-1)*(dat->Accel[ACCEL_Y_AXIS]-MAX_POS_NUM)/LSB;
    }
    if (dat->Accel[ACCEL_Z_AXIS] <  MAX_POS_NUM) {
        myCaldata.Accel[ACCEL_Z_AXIS] = dat->Accel[ACCEL_Z_AXIS]/LSB;
    } else {
        myCaldata.Accel[ACCEL_Z_AXIS] =(-1)*(dat->Accel[ACCEL_Z_AXIS]-                   MAX_POS_NUM)/LSB;
    }
return 0;
}

2、TCP通信线程主要函数说明:

在本样例的网络通信中,小熊派BearPi-HM Nano(Hi3861)开发板作为客户端,润和DAYU200(RK3568)开发板作为服务端。它们之间采用TCP机制通信。

如下代码:建立好TCP通信后,常规状态下通信线程处在阻塞态,当拳击事件触发后,则会发送信息给服务端:

static void TCPClientTask(void)
{
    // 在sock_fd 进行监听,在 new_fd 接收新的链接
    int sock_fd;
    uint32_t flags;
    struct sockaddr_in send_addr;   // 服务器的地址信息
    socklen_t addr_length = sizeof(send_addr);
    char recvBuf[recvLen];
    memset(recvBuf, '\0', sizeof(recvBuf));
    // 连接Wifi
    WifiConnect(CONFIG_WIFI_SSID, CONFIG_WIFI_PWD); 
    // 创建socket
    if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("create socket failed!\r\n");
        exit(1);
    }
    // 初始化预连接的服务端地址
    send_addr.sin_family = AF_INET;
    send_addr.sin_port = htons(CONFIG_SERVER_PORT);
    send_addr.sin_addr.s_addr = inet_addr(CONFIG_SERVER_IP);
    addr_length = sizeof(send_addr);
    //连接
    connect(sock_fd,(struct sockaddr *)&send_addr, addr_length);
    printf("TCPClient connect success\r\n");


    while (1) {
        memset(recvBuf, '\0', sizeof(recvBuf));
  //等待事件是否触发
        flags = osEventFlagsWait(g_eventFlagsId, FLAGS_MSK1, osFlagsWaitAny, osWaitForever);
        printf("TCP get flag\r\n");
        sprintf(sendbuf,"right\r\n");
        send(sock_fd, sendbuf, strlen(sendbuf), 0);//tcp发出触发信息
        // 线程休眠一段时间
        usleep(Delay_100ms);//100ms
    }
    closesocket(sock_fd);
}

五、代码构建、编译及烧录
1、OpenHarmony 3.2 Beta1源码下载,地址参考文章结尾处链接;

2、在源码根目录下的vendor目录下,新建team_x文件夹;

3、把boxing文件夹,拷贝到team_x目录下,如下图所示:OpenHarmony有氧拳击之设备端开发-开源基础软件社区

4、在源码目录下,输入hb set,然后选择当前文件路径,即输入.(点),然后通过方向键选取team_x下的boxing,如下图:

OpenHarmony有氧拳击之设备端开发-开源基础软件社区

5、输入hb build -f,开始编译,编译成功后,会在根目录下的out/bearpi_hm_nano/boxing目录生成Hi3861_wifiiot_app_allinone.bin,如下图:

OpenHarmony有氧拳击之设备端开发-开源基础软件社区
OpenHarmony有氧拳击之设备端开发-开源基础软件社区

6、用HiBurn工具烧录程序,烧录参考链接在文章结尾处;

烧录成功后,可以本地验证项目是否成功:

1、电脑端使用网络调试助手软件,建立TCP服务端,电脑端建立服务端需要注意以下几点:

(1)电脑与BearPi-HM Nano开发板连入同一个Wi-Fi热点,如图:电脑与开发板都连入热点"YYYYYY";

(2)BearPi-HM Nano开发板程序设置的IP,电脑的IP,网络调试助手服务端的IP,三者保持一致,如下图"192.168.1.100";

(3)点击网络调试助手的"连接"按钮,即先启动服务端。

OpenHarmony有氧拳击之设备端开发-开源基础软件社区

2、BearPi-HM Nano开发板串口接入电脑,设置波特率为115200;

3、复位BearPi-HM Nano开发板,复位后,串口会打印Wi-Fi连接成功、TCP连接成功等信息,如下图(右侧);

4、手握开发板,尝试出拳(即挥动开发板)。能看到网络助手的TCP服务端窗口,成功接收到同步挥拳信息“right”,如下图(左侧):

OpenHarmony有氧拳击之设备端开发-开源基础软件社区

六、总结
本文主要讲述了拳击互动游戏中,关于设备端的开发,使用小熊派BearPi-HM Nano(Hi3861)开发板硬件,在小熊派相关基础例程上做了二次开发。本设备端开发,使用了OpenHarmony的线程、事件、GPIO、IIC、TCP通信等相关基础知识,再结合加速度计传感器的使用,实现与应用端同步交互的功能。

本样例是OpenHarmony知识体系工作组(相关链接在文章末尾)为广大开发者分享的样例。知识体系工作组结合日常生活,给开发者规划了各种场景的Demo样例,如智能家居场景、影音娱乐场景、运动健康场景等;欢迎广大开发者一同参与OpenHarmony的开发,更加完善样例,相互学习,相互进步。

七、参考连接
本样例代码下载链接:

https://gitee.com/openharmony-sig/knowledge_demo_entainment/tree/master/dev/team_x/boxing

OpenHarmony知识体系共建开发仓:

https://gitee.com/openharmony-sig/knowledge/blob/master/docs/co-construct_demos/README_zh.md

OpenHarmony学习路径:

https://growing.openharmony.cn/mainPlay/learnPath

小熊派BearPi-HM Nano开发板学习路径:

https://growing.openharmony.cn/mainPlay/learnPathMaps?id=19

https://gitee.com/bearpi/bearpi-hm_nano/tree/master

润和DAYU200(RK3568)开发板介绍:

https://gitee.com/hihope_iot/docs/blob/master/HiHope_DAYU200/docs/README.md

https://growing.openharmony.cn/mainPlay/learnPathMaps?id=27

OpenHarmony有氧拳击之设备端开发-开源基础软件社区

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK