基于Chappie-II的二次开发日志-1

出于个人兴趣决定在原Forairaaaaa/Chappie-II的基础上进行个性化修改和部分特殊功能的实现,本文主要包括:

  • 开发环境配置
  • 系统逻辑简读
  • 设置页面menu实现

注:仅为随笔,不建议做任何技术参考

1. 环境配置

1.1 WSL+VScode+PIO

因为习惯了将开发环境集成在wsl中,然后用vscode连接后使用,所以本次依然是WSL+VScode这一套。由于原工程就是PIO工程,曾经也用过vscode上的PIO插件,所以不多做赘述。
PIO安装与使用可参考在vscode 中用PlatformIO开发-CSDN博客
其中需要注意的是程序的烧录等操作依赖USB连接,而wsl并不会像宿主机一样轻松识别使用USB设备,所以需要使用USB/IP 开源项目 usbipd-win来实现开发板与开发环境的连接,方法可以参考连接 USB 设备 | Microsoft Learn
但因为程序烧录时有上电操作,所以连接会断开,需要手动使用usbipd attach --wsl --busid <busid>来连接一下。如果嫌麻烦可以写个脚本。

1.2 文件树和依赖库

1.2.1 文件树

Chappie-II/Firmware
├── default_16MB.csv
├── lib
│   ├── arduinoFFT
│   ├── ESP32-BLE-Gamepad
│   ├── FastLED
│   ├── LovyanGFX
│   ├── lv_conf.h
│   ├── lvgl
│   ├── NimBLE-Arduino
│   └── README
├── platformio.ini
├── src
    ├── ChappieBsp
    ├── ChappieUI
    └── main.cpp

1.2.2 下载依赖

git submodule init
git submodule update
cd lib
git clone https://github.com/lovyan03/LovyanGFX.git
git clone -b v8.3.5 https://github.com/lvgl/lvgl.git
git clone https://github.com/FastLED/FastLED.git
git clone https://github.com/lemmingDev/ESP32-BLE-Gamepad.git
git clone https://github.com/h2zero/NimBLE-Arduino.git
git clone --branch 1.6.2 https://github.com/kosme/arduinoFFT.git 

注意,使用高于1.6.2版本的arduinoFFT会出现报错。

2. 系统逻辑简读

2.1 系统启动

#include "Arduino.h"
#include "ChappieUI/ChappieUI.h"

CHAPPIEUI ChappieUI;
/**
 * @brief 系统初始化并启动App_Launcher
 */
void setup()
{
    ChappieUI.begin();
}

/**
 * @brief 刷新App_Launcher以获得实时信息
 */
void loop()
{
    ChappieUI.update();
    delay(5);
}

系统功能以APP为单位体现,包括此处的App_Launcher本身也是App。轮询App和系统状态实现App的启动和退出。
此处App_Launcher的功能包括:

  • void App_Launcher::onCreate():App_Launcher的创建
  • void App_Launcher::onDestroy():App_Launcher的退出,以加载lvgl主屏幕并销毁Launcher screen实现
  • void App_Launcher::updateDeviceStatus():响应按键A、B一个电源键一个home键
  • void App_Launcher::updateAppManage():App状态管理,包括onCreateisRunningonDestroy三种状态。可以看到App被退出也就是onDestroy状态,会默认创建App_Launcher,实现退出返回主页的效果。且在App默认框架中要求返回Appname,与AppRegister中已注册的App对应,实现查询和访问。

2.2 App_Settings简读

App_Settings是系统中的”设置“app,可以看到其通过WIFI实现时间的同步

static void xTaskOne(void *xTask1)
{
    while (1)
    {
        uint8_t i = 0;
        WiFi.mode(WIFI_AP_STA);
        WiFi.begin();
        while (WiFi.status() != WL_CONNECTED)
	    { //这里是阻塞程序,直到连接成功
            vTaskDelay(100);
            i++;  
            if(i == 100)
            {
                //vTaskDelete(NULL);
                break;//等待10秒,若未连接,则退出联网
            }
        }
        i = 0;
        if(WiFi.status() != WL_CONNECTED)
        {       
            WiFi.beginSmartConfig();
        }
        if(WiFi.status() != WL_CONNECTED)
        {
            while (!WiFi.smartConfigDone()) 
            { 
                delay(500);
                i++;  
                if(i == 200)
                {
                    WiFi.disconnect();
                    vTaskDelete(NULL);//等待25秒,若仍未配网,则注销线程
                }
            }
            i = 0;
            vTaskDelay(100);
            while (WiFi.status() != WL_CONNECTED) 
            { 
                vTaskDelay(100);
                i++;  
                if(i == 100)
                {
                    WiFi.disconnect();
                    vTaskDelete(NULL);
                } 
            }
        }
    	http.begin("http://quan.suning.com/getSysTime.do"); //HTTP begin
    	int httpCode = http.GET();
        if (httpCode > 0)
        {
            // httpCode will be negative on error
            if (httpCode == HTTP_CODE_OK) // 收到正确的内容
            {
            String resBuff = http.getString();
            char *pEnd;
            char charArray[100];
            char str [30];
            resBuff.toCharArray(charArray, 61);
            for(i=0;i<=15;i++){str[i]=charArray[i+46];}

            int nums[6];
            extract_ints(str, nums, 6);

            rtc_date.year = nums[0];
            rtc_date.month = nums[1];
            rtc_date.date = nums[2];
            rtc_time.hours = nums[3];
            rtc_time.minutes = nums[4];
            rtc_time.seconds = nums[5]+1;//补偿数据处理的时间            
            uint16_t y = nums[0];
            uint8_t m = nums[1];
            uint8_t d = nums[2];
            if(m<3)
            {
                m+=12;
                y-=1;
            }
            rtc_date.weekDay=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%7;
            device->Rtc.setDate(&rtc_date);
            device->Rtc.setTime(&rtc_time);
            }
        }
        http.end();
        WiFi.disconnect();
        vTaskDelete(NULL);
    }
}

WIFI的连接使用了官方的smartconfig方法,还没进行测试。剩下的功能则是画了一个圆弧ui,不知道作何用处的。

3. menu实现

基础例程和调用lvgl库的版本进行初始修改(函数功能和名称发生了改变)
具体的显示效果等下次有时间和回调函数一起完成,尝试把原有的Wifi同步时间的功能显示在menu中。

   /**
     * @brief 设置界面的多级菜单
     * @author K0maru3
     */
    void App_Settings_menu(void)
    {
        /*Create a menu object*/
        lv_obj_t * menu = lv_menu_create(lv_scr_act());
        lv_obj_set_size(menu, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL));
        lv_obj_center(menu);

        lv_obj_t * cont;
        lv_obj_t * label;

        /*Create a sub page*/
        lv_obj_t * sub_page = lv_menu_page_create(menu, NULL);

        cont = lv_menu_cont_create(sub_page);
        label = lv_label_create(cont);
        lv_label_set_text(label, "Hello, I am hiding here");

        /*Create a main page*/
        lv_obj_t * main_page = lv_menu_page_create(menu, NULL);

        cont = lv_menu_cont_create(main_page);
        label = lv_label_create(cont);
        lv_label_set_text(label, "Item 1");

        cont = lv_menu_cont_create(main_page);
        label = lv_label_create(cont);
        lv_label_set_text(label, "Item 2");

        cont = lv_menu_cont_create(main_page);
        label = lv_label_create(cont);
        lv_label_set_text(label, "Item 3 (Click me!)");
        lv_menu_set_load_page_event(menu, cont, sub_page);

        lv_menu_set_page(menu, main_page);
    }

本文作者:k0maru3

本文链接:https://www.cnblogs.com/k0maru3/p/18522773

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   K0maru  阅读(52)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起