2021愛智先行者—智慧燈光開關
2021愛智先行者—智慧燈光開關
既可以蹭熱度,水文章還有機會拿獎金,這我怎麼能錯過呢???立馬開始光速整活!
【本文正在參與"2021愛智先行者-徵文大賽"活動】https://mp.weixin.qq.com/s/I2s99dZpbP0QpMiKFneYJA
具體活動帖子可以參考以下連結:
大家有興趣的也可以一起參與呦,一等獎獎金有 1000 塊呢!
給朋友們的新手大禮包!
首先,發現有很多朋友初次使用愛智,這裡給大家分享一些我自己的使用心得和我自己做的小工具(絕對不是想拯救一下我那可悲的閱讀量!震聲!(▼皿▼#))。
目前我用得最多的,裝置與愛智互動的協議:
統一了 WiFi 和 ZigBee 上層使用的跨廠商發現與控制 DDC協議介紹_靈感桌面的部落格-CSDN部落格
我自己寫的愛智裝置開發的除錯小工具(很挫,還有BUG,但是勉強能用):
初次嘗試!在 Spirit 1 實現 DDC協議嗅探器_靈感桌面的部落格-CSDN部落格
我自己寫的一個用於裝置開發的 SDDC_SDK ,裝置開發會挺方便的(雖然能用,但是依然有BUG,歡迎大家幫我修BUG,大悲(ಥ_ಥ) ):
同人逼死官方系列!基於sddc 協議的SDK框架 sddc_sdk_lib 解析_靈感桌面的部落格-CSDN部落格
同人逼死官方系列!從 DDC 嗅探器到 sddc_sdk_lib 的資料解析_靈感桌面的部落格-CSDN部落格
我還做了很多奇奇怪怪的場景和 DEMO,我的財寶嗎?想要的話就給你,去找出來吧!我的一切都放在靈感桌面的祕密寶庫 !
以上程式碼全部是開源的(歡迎大家幫我修BUG),如果不會用 git 的朋友可以看看這篇文章:
簡單無腦,上手即用 - 手把手教你使用 智慧紅外溫度感測器程式碼以及依賴的 gitee 庫!_靈感桌面的部落格-CSDN部落格
怎麼樣?我是不是準備超級充分?還有是大家覺得有用的話麻煩給我點個贊吧!求求你們了,我讓室友給大家磕頭了!
這是正兒八經的前言
在幾個月前我在 從零開始的DIY智慧家居 - 基於 ESP32 的智慧光照感測器_靈感桌面的部落格-CSDN部落格 中埋了一個坑,現在我回來填坑了!這次就把遠端控燈的場景完成(偷偷告訴你們,我偷偷把坑挖更大了)。現在真的可以實現自動開關燈了!
硬體選擇
首先,就是翼輝的 邊緣計算機 Spirit 1 邊緣計算機,在這裡 Spirit 1 就相當於一個小伺服器,大部分的運算都在這裡完成。
遠端控制燈的裝置,我選擇了公牛的 遙控開關 進行改造,但是我發現這個開關好像是 lora 的,我沒整過 433MHz 模組,於是只能用繼電器硬上了。
這繼電器 挺好用的,5V就能驅動,3.3V就能觸發,體積也不大,板子加繼電器一共要0.13A的電流。
接線方面 開發板只要個繼電器連線就好(VCC-5V, GND-GND,T1-P14)。
程式碼解析
獲取程式碼
為了方便講解邏輯,我會打亂程式碼的順序可能還會進行裁剪,要是想直接拿程式碼跑的朋友可以直接去 靈感桌面的祕密寶庫 獲取程式碼,或者直接 clone:
https://gitee.com/inspiration-desktop/DEV-lib-arduino.git
下載或者 clone程式碼後這次用到的是這三個資料夾:
cjson:我移植的 cjson 庫,就是標準的 cjson 庫,放到 arduino 安裝目錄下的 libraries 資料夾裡,百度一下 cjson 的函式使用就行了。
libsddc:是我移植自官方的SDDC庫和自己寫的 SDK,也是放入 libraries 資料夾裡就行。裡面是 SDDC 協議的處理函式,我們不用管。
demo 資料夾裡面就是我們各種感測器的 demo 程式碼了:
紅圈的 SW_sddc_sdk_demo資料夾裡面就是我們程式碼,點進去就能看見 SW_sddc_sdk_demo.ino 檔案,雙擊檔案會自動啟動 arduino-IDE 開啟程式碼。在工具 -> 埠 選擇對應的 COM 口然後點選上傳就可以把程式碼燒錄到板子裡:
裝置控制命令:
通過 Spirit 1 的應用程式或者除錯工具 嗅探器 向感測器裝置傳送的命令:
觸發開關:
{
"method": "set",
"SW_ctrl": "button"
}
裝置和協議初始化流程:
基於官方 demo 寫的不需要做什麼修改,主要是裝置初始化,管腳配置,和協議初始化部分。
/*
* 初始化感測器
*/
void sensor_init()
{
pinMode(sign_pin, OUTPUT);
}
void setup() {
byte mac[6];
Serial.begin(115200);
Serial.setDebugOutput(true);
Serial.println();
// 初始化感測器
sensor_init();
// 清除一下按鍵狀態機的狀態
button.reset();
// 建立按鍵掃描執行緒,長按 IO0 按鍵,鬆開後ESP32 將會進入 SmartConfig 模式
sddc_printf("長按按鍵進入 Smartconfig...\n");
button.attachLongPressStop(esp_io0_key_task);
xTaskCreate(esp_tick_task, "button_tick", ESP_TASK_STACK_SIZE, NULL, ESP_TASK_PRIO, NULL);
// 啟動 WiFi 並且連線網路
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
// 獲取並列印 IP 地址
Serial.println("");
Serial.println("WiFi connected");
Serial.print("'ip :");
Serial.print(WiFi.localIP());
Serial.println("' to connect");
// sddc協議初始化
sddc_lib_main(&sys_cfg);
// 獲取並列印網絡卡 mac 地址
WiFi.macAddress(mac);
sddc_printf("MAC addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
mac[5], mac[4], mac[3], mac[2], mac[1], mac[0]);
// 使用網絡卡 mac 地址設定裝置唯一標識 UID
sddc_set_uid(G_sddc, mac);
}
void loop() {
// 執行 SDDC 協議迴圈
while (1)
{
sddc_printf("SDDC running...\n");
sddc_run(G_sddc);
sddc_printf("SDDC quit!\n");
}
// 銷燬 SDDC 協議
sddc_destroy(G_sddc);
}
配置裝置資訊
這部分程式碼可以配置 WiFi 名字和 WiFi 密碼,要使用的引腳,並且配置裝置在 Spirit 1 上顯示的資訊:
#define SDDC_CFG_PORT 680U // SDDC 協議使用的埠號
#define PIN_INPUT 0 // 選擇 IO0 進行控制
#define ESP_TASK_STACK_SIZE 4096
#define ESP_TASK_PRIO 25
static const int sign_pin = 14; // 開關控制引腳
static const char* ssid = "EOS-Tenda"; // WiFi 名
static const char* password = "1234567890"; // WiFi 密碼
OneButton button(PIN_INPUT, true);
/*
* 當前裝置的資訊定義
*/
DEV_INFO dev_info = {
.name = "燈光遙控開關",
.type = "light.rc",
.excl = SDDC_FALSE,
.desc = "ESP-32S",
.model = "IDDGYK01B",
.vendor = "inspiration-desktop",
};
/*
* 系統註冊物件匯聚
*/
SDDC_CONFIG_INFO sys_cfg = {
.token = "1234567890", // 裝置密碼
.devinfo = &dev_info,
.io_dev_reg = io_dev,
.io_dev_reg_num = ARRAY_SIZE(io_dev),
.num_dev_reg = num_dev,
.num_dev_reg_num = ARRAY_SIZE(num_dev),
.state_get_reg = dev_state_get_reg,
.state_get_reg_num = ARRAY_SIZE(dev_state_get_reg),
.dis_dev_reg = dis_dev,
.dis_dev_num = ARRAY_SIZE(dis_dev),
};
回撥函式註冊
這是收到命令後回撥函式註冊的位置,在這裡註冊的函式才能被 SDK 正確的呼叫,執行正確的動作。
具體 SDK 的解析可以參考 同人逼死官方系列!基於sddc 協議的SDK框架 sddc_sdk_lib 解析 和 同人逼死官方系列!從 DDC 嗅探器到 sddc_sdk_lib 的資料解析
/*
* 數字量裝置物件函式與處理方法註冊
*/
NUM_DEV_REGINFO num_dev[] = {
// {"set_num_demo", demo}, // 字串為輸入命令,demo為命令處理函式
};
/*
* 顯示裝置物件函式與處理方法註冊
*/
DIS_DEV_REGINFO dis_dev[] = {
// {"set_dis_demo", demo}, // 字串為輸入命令,demo為命令處理函式
};
/*
* IO裝置物件設定函式與處理方法註冊
*/
IO_DEV_REGINFO io_dev[] = {
// {"set_io_demo", demo}, // 字串為輸入命令,demo為命令處理函式
{"SW_ctrl", SW_ctrl},
};
/*
* 系統物件狀態獲取註冊
*/
DEV_STATE_GET dev_state_get_reg[] = {
// {"demo", DEV_NUM_TYPE, num_get_demo}, // demo為輸入命令,字串為命令處理函式
// {"demo", DEV_IO_TYPE, io_get_demo},
// {"demo", DEV_DISPLAY_TYPE, dis_get_demo},
};
資料獲取與上報流程
這裡是我們自己編寫的處理流程 ,可以根據你的需求自己更改,收到 set 或者 get 後根據前面的註冊的函式,進入對應的處理函式。
static void button_task(void *arg)
{
Serial.println("觸發");
delay(100);
digitalWrite(sign_pin, HIGH);
delay(100);
digitalWrite(sign_pin, LOW);
vTaskDelete(NULL);
}
/*
* 開關控制函式
*/
sddc_bool_t SW_ctrl(const char* value)
{
printf("進入開關控制函式\n");
// 不能在主迴圈裡面延時,所有單獨開一個執行緒模擬按鍵觸發
xTaskCreate(button_task, "button_task", ESP_TASK_STACK_SIZE, NULL, ESP_TASK_PRIO, NULL);
return SDDC_TRUE;
}
總結
就這?就這?我在開頭說了我在憋大招,當然不會這樣這點東西,這只是一個開胃菜。請大家敬請期待吧!
本文僅個人學習使用,如有錯誤,歡迎指正, ( ੭ ˙ᗜ˙ )੭謝謝老闆!