用小安派 DSL做天氣站
用戶分享DIY
前言
小安派-DSL(AiPi-DSL) 是安信可開源團隊專門為Ai-M61-32S設計的一款屏幕驅動開發板,支持2.8/3.5寸等30Pin SPI顯示屏、2.4寸及1.28寸等18Pin SPI顯示屏。
小安派-DSL目前已測試通過的有3.5寸電容觸摸屏(GC9307)、2.4寸電容觸摸屏(GC9307)、1.28寸圓形電容觸摸屏(GC9A01)。
這次采用小安派 dsl 板子,屏幕為 2.4 寸 320 *240 分辨率屏幕,外接 sht30 溫濕度傳感器,做一個天氣站。
01
主要功能
時間顯示(已完成)
天氣顯示(已完成)
溫濕度顯示(已完成)
wifi 密碼保存(已完成)
b 站粉絲數顯示(已完成)
U 盤模擬設置(已完成)
電腦性能顯示(已完成)
web server(已完成)
自動息屏(放棄)
微信小程序接入(放棄)
溫濕度 mqtt 上報(放棄)
02
方案進度
由于筆者接觸小安派時間較短,可能只能實現部分功能,目前完成logo界面設計,ttf 矢量字體顯示及U盤模擬功能。電腦性能上位機開發 80%(wpf 實在太占用資源類,先湊合用),基本功能已完善:
初步完成界面布局及 wifi 掃描和連接
完成時間獲取更新
獲取心知天氣完成
完成 https 獲取 b 站粉絲數
sht30 溫濕度傳感器調試完成
添加 pwm 亮度調節
完善多界面管理
性能監控調試完成
03
功能說明
軟件說明
所有信息保存在 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;
主要為四個任務: (1)用于刷新 lvgl 界面 (2)用于管理 Wi-Fi (3)為定時器任務,定時更新 sys_info 中的信息內容 (4)用于接收電腦發送的監控信息并進行處理
時間更新
連接到 Wi-Fi 獲取并 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 的程序優化,所以暫時只能將就使用。 接著是下位機,小安派連接 Wi-Fi 后開啟 tcp_server,然后監聽 8124 端口,上位機連接成功后,會首先發送 pc 信息,包括CPU型號,GPU型號,采用 json 字符串的格式發送。然后上位機定時向小安派發送內存、CPU、GPU、網速相關信息,小安派將其解析并更新UI。
尚未解決的問題
嗶哩嗶哩賬戶ID及天氣地址代碼固化在代碼中,需要更改源碼,之后將會使用 web server 功能,通過 post 修改上述參數,將相應參數保存至文件。
04
05
軟件代碼
代碼放在 gitlab :
https://gitee.com/wangpeng25/desktop-ornaments
-
溫濕度傳感器
+關注
關注
5文章
581瀏覽量
35797 -
開發板
+關注
關注
25文章
5110瀏覽量
97896 -
電容觸摸屏
+關注
關注
1文章
78瀏覽量
22145
原文標題:用小安派 DSL做一個天氣站
文章出處:【微信號:安信可科技,微信公眾號:安信可科技】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論