【电子DIY作品】+桌面助手+安信可产品+小安派dsl

[复制链接]
查看2609 | 回复23 | 2023-10-24 09:49:27 | 显示全部楼层 |阅读模式

本帖最后由 xiaoxiaoyudu 于 2024-1-4 09:13 编辑

本帖最后由 xiaoxiaoyudu 于 2024-1-4 09:07 编辑

本帖最后由 xiaoxiaoyudu 于 2023-12-17 13:04 编辑

桌面助手

1.主要功能

  • [x] 时间显示(已完成)
  • [x] 天气显示(已完成)
  • [x] 温湿度显示(已完成)
  • [x] wifi密码保存(已完成)
  • [x] b站粉丝数显示(已完成)
  • [x] U盘模拟设置(已完成)
  • [x] 电脑性能显示(已完成)
  • [x] web server(已完成)
  • [ ] 自动息屏(放弃)
  • [ ] 微信小程序接入(放弃)
  • [ ] 温湿度mqtt上报(放弃)

2.目前进度

由于接触小安派时间较短,可能只能实现部分功能,目前完成logo界面设计,ttf矢量字体显示及u盘模拟功能。电脑性能上位机开发80%(wpf实在太占用资源类,算了,先凑合用了,之后再改),基本功能以完善。

10.29 初步完成界面布局及wifi扫描和连接。 11.01 完成时间获取更新。 11.02 获取心知天气完成。 11.03 完成https获取b站粉丝数 11.04 sht30温湿度传感器调试完成 11.05 添加pwm亮度调节 11.14完善多界面管理 11.18性能监控调试完成

3.硬件说明

采用小安派dsl板子,屏幕为2.4寸320 *240分辨率屏幕,外接sht30温湿度传感器。

4.界面展示

gif.jpg

[b站视频]

<iframe src="https://player.bilibili.com/player.html?aid=278539119&bvid=BV1cw411K7mn&cid=1336618924&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>

5.功能说明

软件说明

所有信息保存在sys_info的结构体中,该结构体为全局变量,下图所示。

typedef struct
{
    union {
        uint32_t state;
        struct{
            uint32_t state_wifi : 2; // 0:未连接 ; 1:连接;2:断开连接
            uint32_t state_upan : 2; // 0:未开启 ; 1:连接;
        };
    };
    lv_obj_t *last_src;
    struct tm* timeinfo_t;
    uint8_t   backlight;
    blbl_follow_t blbl_info_t;
    weather_t weather[3];
    char * city;
    char * weather_key;
    wifi_info_t wifi;
    uint8_t brightness;
    sht30_t sht;
    pc_info_t pc;
    monitor_info_t *monitor;
} blbl_sys_t;

主要为四个任务,一个任务用于刷新lvgl界面,一个任务用于管理wifi,另一个任务为定时器任务,定时更新sys_info中的信息内容,最后一个任务用于接收电脑发送的监控信息并进行处理。

时间更新

在连接到wifi获取并ip地址时,采用http从网易api接口获取时间戳,保存时间戳信息,开启rtc计时,这里有一个小bug,官方提供的设置rtc函数不能设置计数值,只能从0开始计数。当前时间戳即为rtc时间+http获取的时间戳。然后通过localtime将时间戳转换为年月日。

struct bflb_device_s *rtc;
static uint64_t base_time;

void rtc_init(uint64_t timetemp)
{  
    rtc = bflb_device_get_by_name("rtc");
    //此函数,只能开启⏲
    bflb_rtc_set_time(rtc, BFLB_RTC_SEC2TIME(1));
    base_time = timetemp;
}

uint64_t rtc_get_time()
{
    return (BFLB_RTC_TIME2SEC(bflb_rtc_get_time(rtc)) + base_time);
}

void time_update()
{
    time_t time = rtc_get_time();
    localtime(&time);
}

天气显示

使用心知天气api,使用tcp模拟http请求,返回的为最近三日天气状态的json字符串,使用cjson对字符串进行解析,存储到系统变量sys_info中。

温度度显示

采用sht30温湿度传感器模块,i2c接口,bl618一共两组i2c,一组提供给屏幕的触摸ic,并且没有引出该io,故只能选用另一组i2c,根据芯片手册,貌似每个gpio均支持i2c复用,只不过只能复用scl或者sda其中一个。然后初始化gpio,复用i2c1,通过i2c初始化sht30,如下所示。

struct bflb_i2c_msg_s msgs;
    uint8_t subaddr[2] = { CMD_FETCH_DATA_H, CMD_FETCH_DATA_L};

    board_i2c1_gpio_init();

    i2c1 = bflb_device_get_by_name("i2c1");

    bflb_i2c_init(i2c1, 400000);

    msgs.addr = SHT30_WRITE_ADDR;
    msgs.flags = 0;
    msgs.buffer = subaddr;
    msgs.length = 2;

    bflb_i2c_transfer(i2c1, &msgs, 1);

然后便可以读出原始数据,经过处理,可以获得温湿度信息。

int sht30_get_value()
{
    unsigned char sht30_buf[6]={0}; 
    uint32_t date;
    int ret;
    struct bflb_i2c_msg_s msgs;
    //配置SHT30的寄存器
    msgs.addr = SHT30_WRITE_ADDR;
    msgs.flags = I2C_M_READ;
    msgs.buffer = sht30_buf;
    msgs.length = 6;

    bflb_i2c_transfer(i2c1, &msgs, 1);
    //校验读出来的数据,算法参考sht30 datasheet
    if( (!SHT3X_CheckCrc(sht30_buf,2,sht30_buf[2])) && (!SHT3X_CheckCrc(sht30_buf+3,2,sht30_buf[5])) )
    {
        ret = 0;//成功
        date=(sht30_buf[0]<<8|sht30_buf[1]);
        sys_info_t.sht.temp =(uint8_t) ( ((float)date *175)/65535 -50  );
        sys_info_t.sht.humi =(uint8_t)( ( (sht30_buf[3]*256) + (sht30_buf[4]) )*100/65535.0) ;
    }
    return ret;
}

b站粉丝数显示

在前两年,b站提供粉丝数获取的http接口,最近由于安全考虑,b站的http均不能使用,需要使用https发起请求。为了方便,这里只使用单向验证,不对服务器返回信息进行验证。

u盘模拟

官方提供了usb存储设备模拟的代码,但是是基于ram模拟的,一旦掉电,数据将会丢失。我们可以选用将数据存储到片上flash内,flash大小一共有8m,选用后4m作为文件管理系统。我们只需要实现读写flash的操作即可,即以下接口。需要注意的是经过测试,flash最小读写单位为4k,小于4k会出现问题。

void usbd_msc_get_cap(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
{
    *block_num = BLOCK_COUNT; //Pretend having so many buffer,not has actually.
    *block_size = BLOCK_SIZE;
}


int usbd_msc_sector_read(uint32_t sector, uint8_t *buffer, uint32_t length)
{
    if (sector < BLOCK_COUNT){
        bflb_flash_read(CONFIG_FLASH_USB_ADDRESS + sector*BLOCK_SIZE, buffer, length);
    }
    return 0;
}
int usbd_msc_sector_write(uint32_t sector, uint8_t *buffer, uint32_t length)
{
    if (sector < BLOCK_COUNT){
        bflb_flash_erase(CONFIG_FLASH_USB_ADDRESS + sector*BLOCK_SIZE,length);
        bflb_flash_write(CONFIG_FLASH_USB_ADDRESS + sector*BLOCK_SIZE, buffer, length);
    }
    return 0;
}

之后调用usb初始化,电脑便会识别到该设备,但是由于没有文件系统,系统会建议格式化u盘,建议不要使用window自带的格式化,将会格式化为fat16文件系统,在之后的gif显示中发现fat16文件系统读取gif文件并显示会卡住,而fat32文件系统则没有该问题。故使用第三方工具diskgenius格式化为fat32.

到此我们已经完成usb存储设备模拟,但是这个功能有什么用呢,当然是方便传输文件给程序使用,所有程序也要可以识别该文件系统,官方已经做了fatfs文件系统的移植,但是是基于sd卡的,将其改为基于flash的,同样也是只需要实现flash读写接口。

int fs_flash_read(BYTE *buff, LBA_t sector, UINT count)
{
    if(!count)
        return RES_PARERR;
    if(bflb_flash_read(FS_ADDR + sector*BLOCK_SIZE, buff, count * BLOCK_SIZE)){
        return RES_PARERR;
    }
    return 0;
}

int fs_flash_write(const BYTE *buff, LBA_t sector, UINT count)
{
    bflb_flash_erase(FS_ADDR + sector*BLOCK_SIZE,count);
    bflb_flash_write(FS_ADDR + sector*BLOCK_SIZE, (uint8_t *)buff, count * BLOCK_SIZE);
    return 0;
}

int fs_flash_ioctl(BYTE cmd, void *buff)
{
    switch (cmd) {
        // Get R/W sector size (WORD)
        case GET_SECTOR_SIZE:
            *(WORD *)buff = BLOCK_SIZE;
            break;

        // Get erase block size in unit of sector (DWORD)
        case GET_BLOCK_SIZE:
            *(DWORD *)buff = 1;
            break;

        case GET_SECTOR_COUNT:
            *(DWORD *)buff = 1024;
            break;

        case CTRL_SYNC:
            break;

        default:
            break;
    }

    return 0;
}

从usb模拟可知,我们将文件系统放到后4m的位置,如果我们将fatfs的地址也设置为4m的位置,将会发现,程序检测不到fat32文件系统,这是因为我们在用电脑格式化的时候,会在fat32文件系统前添加一段额外的表头信息,这段表头位于4m的位置,真正的fat32文件系统位于0x3f000处。具体为什么会这样,我也没有深入研究。 FS_ADDR (CONFIG_FLASH_USB_ADDRESS + 0x3F000) 至此,程序便可以直接访问fat32文件系统的文件。

电脑性能监控

电脑性能监控需要使用上位机不断的给小安派发送电脑相关信息,关于上位机的选择,首先先到的是使用ada64,但是发现,这个软件居然要几百块钱,于是便打算使用开源项目,这里使用的是OpenHardwareMonitor,一个电脑性能检测的开源项目,基于c#开发,提供dll动态链接库文件。然后是界面的设计,首先选择的是和OpenHardwareMonitor一样的框架winform,但受限于本人技术较菜,一些复杂功能无法实现,便选择使用wpf框架,wpf框架功能更加强大,但是问题在于使用wpf开发的程序占用资源过于庞大,本人又不太了解wpf的程序优化,所以暂时只能将就使用。

然后是下位机,小安派连接wifi后开启tcp_server,然后监听8124端口,上位机连接成功后,会首先发送pc信息,包括cpu型号,gpu型号,采用json字符串的格式发送。然后上位机定时向小安派发送内存,cpu,gpu,网速相关信息,小安派将其解析并更新ui。

尚未解决的问题

哔哩哔哩账户id及天气地址代码固化在代码中,需要更改源码,之后将会使用web server功能,通过post修改上述参数,将相应参数保存至文件。

源代码

代码放在gitlab上->https://gitee.com/wangpeng25/desktop-ornaments 跳转

本帖被以下淘专辑推荐:

回复

使用道具 举报

WangChong | 2023-10-24 10:10:45 | 显示全部楼层
大佬学习了
回复 支持 反对

使用道具 举报

496199544 | 2023-10-24 10:31:54 | 显示全部楼层
大佬学习了
回复 支持 反对

使用道具 举报

bzhou830 | 2023-10-24 13:27:39 | 显示全部楼层
大佬学习了
选择去发光,而不是被照亮
回复 支持 反对

使用道具 举报

Mr.Tail | 2023-10-24 13:47:41 | 显示全部楼层
期待大佬出作品呀!
回复 支持 反对

使用道具 举报

妖猊 | 2023-10-24 16:02:59 | 显示全部楼层
向大佬学习了
回复 支持 反对

使用道具 举报

iiv | 2023-10-24 21:47:42 | 显示全部楼层
大佬666
回复

使用道具 举报

jkernet | 2023-10-24 22:14:23 | 显示全部楼层
期待
回复

使用道具 举报

粉色小风扇 | 2023-10-25 15:25:08 | 显示全部楼层
厉害
回复

使用道具 举报

90956 | 2023-11-13 09:13:48 | 显示全部楼层
大佬学习了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则