前言
小安派-DSL(AiPi-DSL) 是安信可開源團(tuán)隊(duì)專門為Ai-M61-32S設(shè)計(jì)的一款屏幕驅(qū)動(dòng)開發(fā)板,支持2.8/3.5寸等30Pin SPI顯示屏、2.4寸及1.28寸等18Pin SPI顯示屏。
小安派-DSL目前已測(cè)試通過的有3.5寸電容觸摸屏(GC9307)、2.4寸電容觸摸屏(GC9307)、1.28寸圓形電容觸摸屏(GC9A01)。
這次采用小安派 dsl 板子,屏幕為 2.4 寸 320 *240 分辨率屏幕,外接 sht30 溫濕度傳感器,做一個(gè)天氣站。
01、主要功能
時(shí)間顯示(已完成)
天氣顯示(已完成)
溫濕度顯示(已完成)
wifi 密碼保存(已完成)
b 站粉絲數(shù)顯示(已完成)
U 盤模擬設(shè)置(已完成)
電腦性能顯示(已完成)
web server(已完成)
自動(dòng)息屏(放棄)
微信小程序接入(放棄)
溫濕度 mqtt 上報(bào)(放棄)
02、方案進(jìn)度
由于筆者接觸小安派時(shí)間較短,可能只能實(shí)現(xiàn)部分功能,目前完成logo界面設(shè)計(jì),ttf 矢量字體顯示及U盤模擬功能。電腦性能上位機(jī)開發(fā) 80%(wpf 實(shí)在太占用資源類,先湊合用),基本功能已完善:
?初步完成界面布局及 wifi 掃描和連接
?完成時(shí)間獲取更新
?獲取心知天氣完成
?完成 https 獲取 b 站粉絲數(shù)
?sht30 溫濕度傳感器調(diào)試完成
?添加 pwm 亮度調(diào)節(jié)
?完善多界面管理
?性能監(jiān)控調(diào)試完成
03、功能說明
軟件說明
所有信息保存在 sys_info 的結(jié)構(gòu)體中,該結(jié)構(gòu)體為全局變量,下圖所示。
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;
主要為四個(gè)任務(wù):
(1)用于刷新 lvgl 界面
(2)用于管理 Wi-Fi
(3)為定時(shí)器任務(wù),定時(shí)更新 sys_info 中的信息內(nèi)容
(4)用于接收電腦發(fā)送的監(jiān)控信息并進(jìn)行處理
時(shí)間更新
連接到 Wi-Fi 獲取并 ip 地址時(shí),采用 http 從網(wǎng)易 api 接口獲取時(shí)間戳,保存時(shí)間戳信息,開啟 rtc 計(jì)時(shí),這里有一個(gè)小 bug,官方提供的設(shè)置 rtc 函數(shù)不能設(shè)置計(jì)數(shù)值,只能從 0 開始計(jì)數(shù)。當(dāng)前時(shí)間戳即為 rtc 時(shí)間 +http 獲取的時(shí)間戳。然后通過 localtime 將時(shí)間戳轉(zhuǎn)換為年月日。
struct bflb_device_s *rtc;
static uint64_t base_time;
void rtc_init(uint64_t timetemp)
{
rtc = bflb_device_get_by_name("rtc");
//此函數(shù),只能開啟?
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 請(qǐng)求,返回最近三日天氣狀態(tài)的 json 字符串,使用 cjson 對(duì)字符串進(jìn)行解析,存儲(chǔ)到系統(tǒng)變量 sys_info 中。
溫濕度時(shí)間顯示
采用 sht30 溫濕度傳感器模塊,i2c 接口,bl618 一共兩組 i2c,一組提供給屏幕的觸摸 ic,并且沒有引出該 io,故只能選用另一組 i2c,根據(jù)芯片手冊(cè),貌似每個(gè) gpio 均支持 i2c 復(fù)用,只不過只能復(fù)用 scl 或者其中一個(gè) sda 。然后初始化 gpio,復(fù)用 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);
然后便可以讀出原始數(shù)據(jù),經(jīng)過處理,可以獲得溫濕度信息。
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);
//校驗(yàn)讀出來的數(shù)據(jù),算法參考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 站粉絲數(shù)顯示
之前b 站提供粉絲數(shù)獲取的 http 接口,最近由于安全考慮,b 站的 http 均不能使用,需要使用 https 發(fā)起請(qǐng)求。為了方便,這里只使用單向驗(yàn)證,不對(duì)服務(wù)器返回信息進(jìn)行驗(yàn)證。
U盤模擬
官方提供了USB存儲(chǔ)設(shè)備模擬的代碼,但是是基于RAM模擬的,一旦掉電,數(shù)據(jù)將會(huì)丟失,可以選用將數(shù)據(jù)存儲(chǔ)到片上Flash 內(nèi),F(xiàn)lash 大小一共有 8M,選用后4M作為文件管理系統(tǒng)。只需要實(shí)現(xiàn)讀寫Flash 的操作即可,即以下接口。需要注意的是經(jīng)過測(cè)試,F(xiàn)lash最小讀寫單位為4K,小于4K會(huì)出現(xiàn)問題。
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;
}
之后調(diào)用USB初始化,電腦便會(huì)識(shí)別到該設(shè)備,但是由于沒有文件系統(tǒng),系統(tǒng)會(huì)建議格式化U盤,建議不要使用 Window 自帶的格式化,將會(huì)格式化為 fat16 文件系統(tǒng),在之后的 gif 顯示中發(fā)現(xiàn) fat16 文件系統(tǒng)讀取 gif 文件并顯示會(huì)卡住,而 fat32 文件系統(tǒng)則沒有該問題。故使用第三方工具 diskgenius 格式化為 fat32.
到此已經(jīng)完成USB存儲(chǔ)設(shè)備模擬,個(gè)功能有什么用?當(dāng)然是方便傳輸文件給程序使用,所有程序也要可以識(shí)別該文件系統(tǒng),官方已經(jīng)做了 FatFS 文件系統(tǒng)的移植,但是是基于SD卡的,將其改為基于 Flash 的,同樣也是只需要實(shí)現(xiàn) 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模擬可知,我們將文件系統(tǒng)放到后4M的位置,如果我們將FatFS的地址也設(shè)置為4M的位置,將會(huì)發(fā)現(xiàn),程序檢測(cè)不到Fat32文件系統(tǒng),這是因?yàn)樵谟秒娔X格式化的時(shí)候,會(huì)在Fat32文件系統(tǒng)前添加一段額外的表頭信息,這段表頭位于 4M的位置,真正的Fat32文件系統(tǒng)位于0x3f000處。具體為什么會(huì)這樣,筆者還沒有深入研究。
FS_ADDR (CONFIG_FLASH_USB_ADDRESS + 0x3F000)
至此,程序便可以直接訪問 Fat32 文件系統(tǒng)的文件。
電腦性能監(jiān)控
電腦性能監(jiān)控需要使用上位機(jī)不斷的給小安派發(fā)送電腦相關(guān)信息,關(guān)于上位機(jī)的選擇,首先先到的是使用 ada64,但是發(fā)現(xiàn),這個(gè)軟件居然要幾百塊錢,于是便打算使用開源項(xiàng)目,這里使用的是 OpenHardwareMonitor,一個(gè)電腦性能檢測(cè)的開源項(xiàng)目,基于 c#開發(fā),提供 dll 動(dòng)態(tài)鏈接庫文件。
然后是界面的設(shè)計(jì),首先選擇的是和 OpenHardwareMonitor 一樣的框架 Winform,但受限于本人技術(shù)較菜,一些復(fù)雜功能無法實(shí)現(xiàn),便選擇使用wpf 框架,wpf 框架功能更加強(qiáng)大,但是問題在于使用 wpf 開發(fā)的程序占用資源過于龐大,本人又不太了解 wpf 的程序優(yōu)化,所以暫時(shí)只能將就使用。
接著是下位機(jī),小安派連接 Wi-Fi 后開啟 tcp_server,然后監(jiān)聽 8124 端口,上位機(jī)連接成功后,會(huì)首先發(fā)送 pc 信息,包括CPU型號(hào),GPU型號(hào),采用 json 字符串的格式發(fā)送。然后上位機(jī)定時(shí)向小安派發(fā)送內(nèi)存、CPU、GPU、網(wǎng)速相關(guān)信息,小安派將其解析并更新UI。
尚未解決的問題
嗶哩嗶哩賬戶ID及天氣地址代碼固化在代碼中,需要更改源碼,之后將會(huì)使用 web server 功能,通過 post 修改上述參數(shù),將相應(yīng)參數(shù)保存至文件。
04、視頻演示
桌面助手_嗶哩嗶哩_bilibili?www.bilibili.com/video/BV1cw411K7mn/?spm_id_from=888.80997.embed_other.whitelist&t=85.12471&bvid=BV1cw411K7mn&vd_source=54c5db21948db2378659b7e8e42bafbf
05、軟件代碼
代碼放在 gitlab :https://link.zhihu.com/?target=https%3A//gitee.com/wangpeng25/desktop-ornaments
op-ornaments
審核編輯 黃宇
-
DSL
+關(guān)注
關(guān)注
2文章
59瀏覽量
38322 -
開發(fā)板
+關(guān)注
關(guān)注
25文章
5078瀏覽量
97671 -
電容觸摸屏
+關(guān)注
關(guān)注
1文章
78瀏覽量
22127
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論