嵌入式系统 阿里 Haas EDU 开发记录

警告
本文最后更新于 2021-11-28,文中内容可能已过时。

嵌入式系统 阿里 Haas EDU 开发记录

笔者所学物联网专业,有一门课是嵌入式系统。我们的嵌入式老师以个人名义为我们提供了阿里的Haas EDU教育开发版用于嵌入式系统实验课。并且留了一些任务给我们。本文记录相关流程供学习经验。

这块板子默认烧录的是 HaaS EDU K1教育开发案例合集。开源地址:https://gitee.com/alios-things/eduk1_demo

系统是AliOS Things 3.3,内核 rhino,硬件名 Haas EDU K1 。

创建好之后就是这样了。

https://cdn.ftls.xyz/images/2021/11/1.jpg
正面照
https://cdn.ftls.xyz/images/2021/11/2.jpg
背面照
  1. 需要 Vscode 和 C/C++ Extension Pack 插件。
  2. 安装 haas-studio v1.0.24,安装之后会跳出 aos-tools 的安装提示。同样也是一键安装。

状态栏可以看到编译,烧录等

https://cdn.ftls.xyz/images/2021/11/haas/haas1.png
安装好插件之后

笔者是在原HaaS EDU K1教育开发案例合集基础之上进行开发的,实际上也只是调用封装好的东西。

https://cdn.ftls.xyz/images/2021/11/haas/haas2.png
创建教育开发案例合集项目
https://cdn.ftls.xyz/images/2021/11/haas/haas3.png
教育开发案例合集目录
https://cdn.ftls.xyz/images/2021/11/haas/haas4.png
用户代码目录solutions,红色是上云用的

第一次创建项目大约需要 5min。然后点击 VSCode 下面状态栏的编译。第一次编译大约需要 5min。编译之后这个文件夹大约 1G 左右。 编译成功后大概这样:

1
2
3
4
5
6
7
8
cp -f ../release_bin/pub_otp.bin ../write_flash_tool/ota_bin/
cp -f ../release_bin/pub_otp.bin ../write_flash_gui/ota_bin/
all files done.
run external script success
Run script 'python "C:\Users\icer\Desktop\lab3\hardware\chip\haas1000\release/auto_build_tool/build_bin.py"  --target="C:\Users\icer\Desktop\lab3\solutions\lab3\aos.bin"  ' success
scons: done building targets.
AOS SDK Done
Build takes 0 Minutes 45 Seconds. 
https://cdn.ftls.xyz/images/2021/11/haas/haas6.png
编译之后

电脑需要装一个 cp210x.drivers 驱动。连接开发板到电脑,选择对应的串口,baudrate选择1500000,如果选错了可以修改配置文件。这些配置文件位于 .vscode 文件夹。然后点击 Vscode 状态栏的烧录,就可以看到大约 1700kb 的文件烧录进入了单片机。这时候单片机会显示一个出厂测试页面,会提示你按下K1,K2,K3, K4 , K1&K2 进行各种测试。看到这个测试说明我们的程序烧录成功了。

首先我们想要看到是HaaS EDU K1教育开发案例合集的图片中的各种功能。这时候我们需要关闭测试模式。

solutions\lab3\maintask.c 增加一行

1
#define ENABLE_FACTORY_TEST 0

然后我们就能看到HaaS EDU K1教育开发案例合集提供的案例了。也就是出厂自带的程序。

我们可以看到,官方样例中每一个页面都是一个程序。这时,我们要添加自己的页面程序。

打开solutions\lab3\k1_apps文件夹。然后创建solutions\lab3\k1_apps\test3文件夹。创建两个文件 test3.ctest3.h。修改 solutions\lab3\k1_apps\menu.c。这里的代码我都会贴在最后。

https://cdn.ftls.xyz/images/2021/11/haas/haas5.png
创建test3

所需要的代码
test3.c
test3.h
menu.c

代码变量说明:tem 温度 ,hum 湿度 ,xyz[3] 六轴传感器传出数据。

https://cdn.ftls.xyz/images/2021/11/3.jpg
正常显示数据和传感器信息

创建文件之后,一定要修改solutions\lab3\package.yaml的source_file。 增加代码

1
2
3
4
5
6
source_file:
<略>
  - "k1_apps/test3/test3.c"
  - "k1_apps/test4/test4.c"
  - "data_model_basic_demo.c"
  <略>

实验效果如下。

六轴传感器传的是 float 类型,显示不下于是强转为 short 类型。

目前效果不是很好,六轴传感器显示需要先运行官方陀螺仪示例之后才可以正常显示。待修复此特性。

点击 VScode 状态栏的串口,选择对应的串口,选择1500000。这时候连接开发板并且开机能够看到一堆文字闪过。等待文字稳定后按下回车,能看到(ash:/data)#。这时候我们就可以输入CLI命令了。 输入netmgr -t wifi -c ssid password就可以配网了。ssid替换为WIFI网络名,password替换为WIFI密码。

1
2
3
4
[  44.975]<I>eduk1_demo aos_task_delete test3_task
[  44.976]<I>eduk1_demo aos_task_new homepage_task

(ash:/data)#netmgr -t wifi -c ssid password

配网之后开发板主页面会显示IP右上角会显示WIFI图标。还能看到 IP。

https://cdn.ftls.xyz/images/2021/11/4.jpg
配网WIFI

基于HaaS EDU K1教育开发案例合集Wi-Fi设备连接阿里云示例。复制Wi-Fi设备连接阿里云示例下的 data_model_basic_demo.c 到 lab3\solutions\lab3\data_model_basic_demo.c。

修改三元组为自己设备的三元组,具体步骤键Wi-Fi设备连接阿里云示例 4.2 软件实现

修改data_model_basic_demo.c内的demo_main()为demo_main2()。

为了让这段程序在连接WIFI后运行,修改solutions\lab3\app_start.c,代码后面有。主要修改 wifi_event_cb 。

被修改的代码:
app_start.c

为了上传传感器数据,为data_model_basic_demo.c增加头文件

1
2
3
4
5
// 传感器数据
#include "drv_temp_humi_si_si7006.h"
#include "drv_temp_humi_sensylink_cht8305.h"
#include "drv_acc_gyro_inv_mpu6050.h"
#include "drv_acc_gyro_qst_qmi8610.h"

修改data_model_basic_demo.c主循环上传温湿度传感器和六轴传感器数据,abc 为计数,temp 温度,hump 湿度,xyz为六轴传感器数据。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
short int abc = 0;
    float temp, hump,xyz[3];
    uint8_t info[30];
    /* 主循环进入休眠 */
    cht8305_init();
    FisImu_init();
    while (1) {
        if(abc>=100) { abc=0;}
        FisImu_read_acc_xyz(xyz);
        cht8305_getTempHumidity(&hump, &temp);
        /* TODO: 以下代码演示了简单的属性上报和事件上报, 用户可取消注释观察演示效果 */        
        sprintf(info, "{\"LightSwitch\": %d,\"tem\": %.1f,\"hum\": %.1f,\"rax\": %d,\"ray\": %d,\"raz\": %d}", abc,temp,hump,(short)xyz[0],(short)xyz[1],(short)xyz[2]);
        demo_send_property_post(dm_handle, info);
        demo_send_event_post(dm_handle, "Error", "{\"ErrorCode\": 0}");

        abc+=1;

        aos_msleep(10000);
    }

连接WIFI成功后,数据就可以上云了。在日志服务选择刚刚创建的设备就可以看到是否成功了,其次在也可以查看设备是否在线查看是否上云成功。

https://cdn.ftls.xyz/images/2021/11/haas/haas8.png
上云日志
https://cdn.ftls.xyz/images/2021/11/haas/haas9.png
云平台收到的传感器信息

阿里云在产品栏目,功能定义,编辑草稿,可以定义物模型。阿里云物联网平台会匹配demo_send_property_post里的tem,hum,rax,ray,raz 等信息。编辑物模型之后,方便了后续的开发。

https://cdn.ftls.xyz/images/2021/11/haas/haas7.png
物模型

创建文件之后,一定要修改solutions\lab3\package.yaml的source_file。 增加代码

1
2
3
4
source_file:
<略>
  - "data_model_basic_demo.c"
  <略>

增加

HaaS EDU K1快速开始

Python轻应用开发手册

HaaS EDU K1 学习路径图(从新手到专家)

一站式开发工具HaaS Studio使用说明

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "test3.h"
#include "drv_temp_humi_si_si7006.h"
#include "drv_temp_humi_sensylink_cht8305.h"
#include "drv_acc_gyro_inv_mpu6050.h"
#include "drv_acc_gyro_qst_qmi8610.h"
#include "../menu.h"
// mqtt 头文件
#include "aiot_state_api.h"
#include "aiot_sysdep_api.h"
#include "aiot_mqtt_api.h"

MENU_COVER_TYP test3_cover = {MENU_COVER_NONE};
MENU_TASK_TYP  test3_tasks = {test3_init, test3_uninit};
MENU_TYP test3 = {"test3", &test3_cover, &test3_tasks, NULL, NULL};

static int running = 1;
// 定义三轴加速器的x,y,z
// 使用开发板为 k1c g_haasboard_is_k1c = 1
static short r_ax = 0, r_ay = 0, r_az = 0;

static aos_task_t test3_task_handle;

int test3_init(void)
{
    if (g_haasboard_is_k1c) {
        cht8305_init();
        FisImu_init();
        LOGI(EDU_TAG, "cht8305_init done\n");
        LOGI(EDU_TAG, "FisImu_init done\n");
    } else {
        si7006_init();
        MPU_Init();
        LOGI(EDU_TAG, "si7006_init done\n");
        LOGI(EDU_TAG, "MPU_Init done\n");
    }
    LOGI(EDU_TAG, "MPU_Init done\n");
    //
    OLED_Clear();
    
    OLED_Refresh_GRAM();
    running = 1;
    aos_task_new_ext(&test3_task_handle, "test3_task", test3_task, NULL, 1024, AOS_DEFAULT_APP_PRI);
    LOGI(EDU_TAG, "aos_task_delete test3_task\n");
    return 0;
}

void test3_task(void)
{
    float         temp, hump,xyz[3];
    uint8_t       temp_str[10];
    uint8_t       hump_str[10];
    uint8_t       info[10];
    uint8_t       six_str[30];
    uint8_t       six_info[10];
    unsigned char c = 0;


    while (running) {
        if (g_haasboard_is_k1c) {
            FisImu_read_acc_xyz(xyz);
            cht8305_getTempHumidity(&hump, &temp);
            strcpy(info,"cht8305:");
        } else {
            MPU_Get_Accelerometer(&r_ax, &r_ay, &r_az);
            si7006_getTempHumidity(&hump, &temp);
            strcpy(info,"si7006:");
        }



        sprintf(temp_str, "W:%5.1fC", temp);
        sprintf(hump_str, "S:%5.1f%%", hump);
        if(g_haasboard_is_k1c) {
            strcpy(six_info,"FisImu");
            // sprintf(six_str,"x:%2.1f,y:%2.1f,z:%2.1f",xyz[0],xyz[1],xyz[2]);
            sprintf(six_str,"x:%d,y:%d,z:%d",(short)xyz[0],(short)xyz[1],(short)xyz[2]);
            printf("FisIum: \n%f\n%f\n%f\n",xyz[0],xyz[1],xyz[2]);
        }
        else{
            strcpy(six_info,"MPU");
            sprintf(six_str,"x:%d,y:%d,z:%d",r_ax,r_ay,r_az);
            printf("MPU: \n%d\n%d\n%d\n",r_ax,r_ay,r_az);
        }

        // LOGD(EDU_TAG, "%s %s", temp_str, hump_str);

        // 绘制左右的图标
        OLED_Icon_Draw(2, 24, &icon_skip_left, 0);
        OLED_Icon_Draw(122, 24, &icon_skip_right, 0);

        OLED_Show_String(20, 5, info, 12, 1);
        OLED_Show_String(20, 20, temp_str, 12, 1);
        OLED_Show_String(20, 35, hump_str, 12, 1);
        OLED_Show_String(20, 50, six_str ,12,1);

        OLED_Refresh_GRAM();
        aos_msleep(500);
    }
    running = 1;
}

int test3_uninit(void)
{
    running = 0;

    while (!running) {
        aos_msleep(50);
    }
    if (g_haasboard_is_k1c) {
        cht8305_deinit();
        FisImu_deinit();
        LOGI(EDU_TAG, "cht8305_deinit done\n");
        LOGI(EDU_TAG, "FisImu_deinit done\n");
    } else {
        si7006_deinit();
        MPU_Deinit();
        LOGI(EDU_TAG, "si7006_deinit done\n");
        LOGI(EDU_TAG, "MPU_Deinit done\n");
    }

    aos_task_delete(&test3_task_handle);
    LOGI(EDU_TAG, "aos_task_delete test3_task\n");
    return 0;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#ifndef __TEST3_H__
#define __TEST3_H__

#include "../menu.h"

extern MENU_TYP test3;

int  test3_init(void);
int  test3_uninit(void);
void test3_task(void);

#endif
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdio.h>
#include <stdlib.h>

#include "aos/kernel.h"
#include "menu.h"

// 添加离自己最近的子级目录
#include "aircraftBattle/aircraftBattle.h"
#include "barometer/barometer.h"
#include "compass/compass.h"
#include "greedySnake/greedySnake.h"
#include "gyroscope/gyroscope.h"
#include "homepage/homepage.h"
#include "humiture/humiture.h"
#include "lightmeter/lightmeter.h"
#include "musicbox/musicbox.h"
#include "shakeshake/shakeshake.h"
#include "kws/kws.h"
// add path
#include "test3/test3.h"

#define KEY_CODE_BACK  (EDK_KEY_1 | EDK_KEY_2)
#define KEY_CODE_LEFT  EDK_KEY_1
#define KEY_CODE_RIGHT EDK_KEY_3
#define KEY_CODE_DOWN  EDK_KEY_4

MENU_TYP *Menus[] = {
    &homepage,&test3,
    &humiture, &gyroscope, &shakeshake,  &compass,        &barometer,
    &lightmeter, &musicbox,  &greedySnake, &aircraftBattle, &kws,
    
};
MENU_LIST_TYP MenuList = {Menus, sizeof(Menus)/sizeof(Menus[0])};

MENU_TYP *pCurMenu = NULL;
key_code_cb app_key_code_cb = NULL;
<>
余下没有修改
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
 */

#include "aos/init.h"
#include "board.h"
#include "k1_apps/menu.h"
#include <aos/errno.h>
#include <aos/kernel.h>
#include <k_api.h>
#include <stdio.h>
#include <stdlib.h>
#include <uservice/eventid.h>
// #include "drivers/lcd/st7789v/st7789v_vfs.h"
// #include "drivers/lcd/st7789v/st7789v.h"
#include "netmgr.h"


extern int board_test(void);
extern void vendor_cli_register_init(void);
extern int demo_main2(int argc, char *argv[]);
int g_haasboard_is_k1c = 0;

int bt_connected = 0;
int wifi_connected = 0;
int ip_got_finished = 0;
char eduk1_ip_addr[IPADDR_STR_LEN] = {0};

int demo_main(int argc, char *argv[])
{
    int ret = 0;

    while (1)
    {
        if (wifi_connected && !ip_got_finished)
        {
           ret = netmgr_wifi_get_ip_addr(&eduk1_ip_addr);

           if (ret ==0)
            ip_got_finished = 1;
        }
        aos_msleep(1000);
    }
}

static void entry_func(void *data)
{
    demo_main(0 , NULL);
}
static void entry_func2(void *data)
{
    demo_main2(0 , NULL);
}

static void wifi_event_cb(uint32_t event_id, const void *param, void *context)
{
    aos_task_t task;
    aos_status_t ret2;
    switch (event_id)
    {
        case EVENT_NETMGR_DHCP_SUCCESS:
            wifi_connected = 1;
            aos_task_new("link_dmeo", entry_func, NULL, 6*1024);
            ret2 = aos_task_create(&task, "linksdk_demo", entry_func2,
                          NULL, NULL, 6048, AOS_DEFAULT_APP_PRI, AOS_TASK_AUTORUN);
            if (ret2 < 0) {
                printf("create linksdk demo task failed, ret = %ld \r\n", ret2);
            }
            break;

        case EVENT_NETMGR_WIFI_DISCONNECTED:
            wifi_connected = 0;
            break;

        default:
            break;
    }
    return;
}
extern int haasedu_is_k1c();

int application_start(int argc, char **argv)
{
    int ret;

    aos_set_log_level(AOS_LL_INFO);
    event_service_init(NULL);

    netmgr_service_init(NULL);

    /*enable network auto reconnect*/
    netmgr_set_auto_reconnect(NULL, true);

    /*enable auto save wifi config*/
    netmgr_wifi_set_auto_save_ap(true);

    event_subscribe(EVENT_NETMGR_DHCP_SUCCESS, wifi_event_cb, NULL);

    g_haasboard_is_k1c = haasedu_is_k1c();
    sh1106_init();
    menu_init();

    ret = BleCfg_run();
    if (ret) {
        return ret;
    }

    aos_msleep(100);

    (void)BleCfg_recovery_wifi();
    (void)BleCfg_recovery_devinfo();

    return 0;
}

作者: 恐咖兵糖
版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 4.0 许可协议