衡阳派盒市场营销有限公司

電子發燒友App

硬聲App

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示
電子發燒友網>電子資料下載>電子資料>支持物聯網種植系統的構建

支持物聯網種植系統的構建

2023-06-15 | zip | 0.00 MB | 次下載 | 免費

資料介紹

描述

概述

種植植物的寧靜和清新是從城市生活的喧囂中解脫出來的。然而,我們有時會因為生活中的煩惱而無法好好照顧這些美麗的植物。不過不用擔心,智能室內花園是自動種植的完美解決方案。即使我們不在家,它也能照料我們的植物。

在這個項目中,我們將一個普通的室內花園改造為一個功能齊全且支持物聯網的種植系統。

功能

您可以使室內花園在適度的預算內具有以下功能。

  • 使用應用程序進行遠程控制和數據監控。
  • 監測溫度和濕度、光照強度、土壤濕度和水位。
  • 自動補光、加濕、加熱、換氣、澆水、水箱加水。

完成原型后,選擇一個亞克力盒子來裝飾你的花園。

邏輯

我們將功能劃分為更小的構建塊,如下圖所示。

?
pYYBAGNom2WAdfBDAAOu21cVE7g769.png
?

腳步

第 1 步:原型

程序一:修改主控板

使用涂鴉智能APP實現遠程控制,我們使用涂鴉WB3S網絡模塊作為主控。涂鴉三明治 Wi-Fi SoC 主控板(WB3S)幫助您快速實現各種智能硬件原型。該板只有一個 ADC 端口,因此我們使用 4 通道模擬多路復用器RS2255來擴展更多模擬通道。

?
pYYBAGNom2iAAIMjAAEherTt-VM125.png
?
poYBAGNom2uALhf2AAGS0hxY1Ac107.png
?

RS2255 提供對三個模擬通道的訪問,分別表示為 A1、A2 和 A3。

  • 模擬頻道

電路圖顯示,要讀取 A1、A2 和 A3 上的值,嵌入式系統必須首先讀取 ADC 值。PWM0 和 PWM1 輸出控制 RS2255,這與 ADC 如何連接到模擬通道有關。見下表:

pYYBAGNom3CAI2FUAAASk5MVUnA388.png
?

程序 2:檢測光強度

使用BH1750傳感器檢測光強度。BH1750 是一款使用 I2C 進行通信的數字環境光傳感器。BH1750FVI 是用于 I2C 總線接口的數字環境光傳感器 IC。它可以精確測量高達 65535 lx 的光的 LUX 值。BH1750如下圖:

?
poYBAGNom3KAdrnlAAAxG7-TIGE608.png
?
  • BH1750的電路圖:
?
poYBAGNom3SAK6mGAACfEh8Ek0M809.png
?

引腳配置:

  • VCC:3-5V 電源輸入
  • GND:電源地
  • SCL:I2C 時鐘引腳
  • SDA:I2C 數據引腳
  • ADDR:地址引腳
  • BH1750的電路圖:
  • 引腳配置:

程序 3:測量溫度和濕度

使用SHT21濕度和溫度傳感器測量環境溫度和濕度。SHT21經過全面校準,具有低功耗和出色的長期穩定性。它使用 I2C 協議進行通信。

注意:如果 SHT21 傳感器不可用,您可以使用HTU21D傳感器替代。

poYBAGNom3eAHP2XAAC9Z9IUz-E901.png
?
  • SHT21的電路圖:
?
poYBAGNom3mASJlGAABxqfnSrpk723.png
?
  • VCC:3.3V電源輸入
  • GND:電源地
  • SCL:I2C 時鐘引腳
  • SDA:I2C 數據引腳
  • SHT21的電路圖:
  • 引腳配置:

程序 4:測量土壤水分

使用土壤濕度傳感器測量土壤的含水量。表面鍍鎳,感應面積大,可提高導電性,防止與土壤接觸生銹的問題。該傳感器提供模擬和數字輸出。數字輸出簡單,而模擬輸出更準確。您可以借助傳感器板上的電位器(藍色)調整傳感器的靈敏度。傳感器使用 LM393 比較器將土壤濕度水平與預設閾值進行比較。

pYYBAGNom36AJaALAAClS0ydbzo862.png
?
  • 土壤濕度傳感器電路圖:
?
poYBAGNom4GANM3tAAEZRENc6Kk706.png
?
  • 引腳配置:VCC:3.3-5V 電源輸入GND:電源地D0:數字輸出A0:模擬輸出

程序 5:測量水箱水位

使用水位傳感器測量水箱中的水深。水位傳感器具有高性能和低功耗的靈敏度。它可以很容易地將水量轉換為模擬信號,輸出值可以被微處理器識別,從而實現水位報警。

poYBAGNom4OAPFcAAABJX6-K1Zg523.png
?
  • 水位傳感器電路圖:
?
poYBAGNom4WAMPF9AABc3sMuRII072.png
?
  • 引腳配置:+:3-5V電源輸入-:電源地S:模擬輸出

程序 6:補光

使用室內花園上的 LED 植物燈補光。生長燈由2835顆LED燈珠組成。共有114顆珠子,分暖白、紅、藍、遠紅外四個波段,每個波段的比例為25:9:2:2。

為了實現蔬菜以及花卉和水果的兩種生長模式,兩個 PWM 輸出控制光譜。一個控制藍光,另一個控制暖白光、紅光和遠紅外光。

poYBAGNom4uAYi3cAAO-2PYbGiw084.png
?
  • 蔬菜種植方式:

植物燈板提供暖白光、紅光、藍光和遠紅外光。頻譜報告如下:

pYYBAGNom5CAHQhhAAPxHjGIngw868.png
?
poYBAGNom5SAKzCWAAMp7HdtErM991.png
?
  • 花果種植模式:

植物燈板提供暖白光、紅光和遠紅外光。頻譜報告如下:

poYBAGNom52AeMh2AARdwLY4uxw974.png
?
pYYBAGNom6KAWTc4AANqnPbIIF4297.png
?
  • 引腳配置:12V:12V電源輸入PON:PWM輸入1 RON:PWM輸入2 GND:電源地

注意藍光只能在其他PWM信號輸出時進行調節。如果您沒有植物燈板,您可以使用兩個 PWM 輸出交替控制 LED 燈條。

程序 7:噴涂

使用 1 通道繼電器模塊來控制 5V 霧化器模塊。造霧器芯片的工作頻率為 108 kHz。第八針可用于監測水位,實現低水位切斷,防止霧化盤缺水。

pYYBAGNom6SAVtrHAABXym8jHv4499.png
?
  • 制霧器模塊電路圖:
?
pYYBAGNom6iAUvqsAAC3DmZjntc143.png
?
  • 引腳配置:紅線:5V黑線:GND

程序 8:加熱

使用1路繼電器模塊控制75W遠紅外線燈泡。紅外線燈泡具有熱效率高、遇水防爆、傳熱快、散熱快等特點。重要的是,它可以在潮濕的環境中有效地工作。您可以根據需要使用冷卻風扇。

poYBAGNom6uAdFpyAABPKj9b8Mw284.png
?

(可選)冷卻風扇:使用安裝在室內花園中的冷卻風扇(12V DC 0.18A)。風扇和紅外線燈泡通過220V AC轉12V DC電源變壓器并聯,由繼電器模塊控制。

pYYBAGNom7GAABJ3AARFPPewQ1U965.png
?

程序 9:通風

使用1路繼電器模塊控制兩個高速冷卻風扇(12V 0.5A)。通風可以降低環境溫度和濕度,從而為植物授粉。

poYBAGNom7WAFdw0AAGK0JaOqTw650.png
?

程序 10:加注水箱

使用 1 通道繼電器模塊控制 12V 水泵。您可以根據需要選擇供水或將水泵改為12V水電磁閥。

  • 功率:24W
  • 流量:5升/分鐘
  • 進水壓力:0.48 MPa
poYBAGNom7mAZE0IAAEECNi1FB4228.png
?

程序 11:水

使用 1 通道繼電器模塊控制兩個 12V DC 隔膜泵。水被泵送并施用于土壤。

pYYBAGNom7uAF7_kAAAhtadbN9M848.png
?

程序 12:我們為什么要使用繼電器模塊?

繼電器模塊通常用于切換使用比大多數微控制器可以處理的電壓更高的電壓的設備。

您可以使用兩個1路繼電器模塊和一個4路繼電器模塊來實現自動噴灑、加熱、水箱加水、通風和澆水。

  • 1通道繼電器模塊
poYBAGNom76AUyIlAABpgN6vWWQ891.png
?
  • 4通道繼電器模塊
poYBAGNom8KAJb3WAADBH6uwtFw928.png
?
  • 繼電器引腳
poYBAGNom8WAfGiiAAA5ON0xWtE766.png
?

程序 13:選擇室內花園

選擇一個簡單的傳統室內花園進行改造。

我們準備了一個傳統的室內花園,配有種植燈板和大型土壤容器。

pYYBAGNom8iAJkRFAAMEjjNuSVs402.png
?

這個花園有以下功能:

poYBAGNom8uARxpnAAFu7meBOjY296.png
?

程序 14:花園供電

花園需要四種電源,即220V AC、12V DC、5V DC和3.3V DC。為此,我們使用以下解決方案:

  • 220V AC:來自 220V/50 Hz 電網的電源。
poYBAGNom9GANcEnAABP8YQC6ks391.png
?
  • 12V DC:將 S-120-12 開關電源連接到 220V AC 電網。
?
pYYBAGNom9SAOtGiAAAjK2wrJZQ187.png
?

12V散熱風扇與紅外線燈泡相連。紅外燈泡連接到 220V 交流電源。隔離開關電源模塊 (12V 400 mA) 為冷卻風扇產生 12V DC。

pYYBAGNom9eAYTxlAAAcwL-2JL0410.png
?
  • 5V DC:為繼電器模塊和超聲波霧化器供電。
?
pYYBAGNom9qARKf-AABNAijUdY4912.png
?

模塊規格

  • 輸入電壓:9V–36V DC
  • 輸出電壓:5.2V/5A/25W
  • 輸入不同的電壓會輸出不同的功率:
  • 9–24V DC,輸出 5.2V/6A/30W。
  • 24–32V DC,輸出 5.2V/5A/25W。
  • 32-36V DC,輸出 5.2V/3.5A/18W。

3.3V DC:涂鴉三明治DC-DC電源板供電。此電源板配備雙電源插孔,可接受 12V DC 或 5V DC 電源。

  • 12V DC輸入時,兩顆SY8012B芯片工作,為板上其他元件提供12V、5V、3.3V DC供電
poYBAGNom92Ae_bXAABwK19cKto209.png
?

步驟 15:設計亞克力盒子

我們使用 Adob??e AutoCAD 設計了一個亞克力盒子。注意事項:

  • 鍋大小
  • 組件尺寸和布局
  • 固定孔位
  • 接線用螺絲孔

下圖顯示了組件布局供您參考。您可以修改和重新設計以滿足您的需求。下載 2D 圖紙

  • 正視圖:
pYYBAGNom-CAD-c9AABef6cQREk973.png
?
  • 后視圖:
poYBAGNom-KAOUx3AADNcaEdowk027.png
?

第 2 步:組裝

程序1:準備材料

準備以下組件和用品。

poYBAGNom-WAZDpZAABzIEGA4_4395.png
?
pYYBAGNom-eASQ8YAAByRaEAByY834.png
?
pYYBAGNom-2AVumfAAB5nQ5Q9uk092.png
?
pYYBAGNom_CAUzlaAAArpDR792o956.png
?

程序2:組裝亞克力盒

根據圖紙切割亞克力板。用粘合劑組裝丙烯酸組件。

pYYBAGNom_eAG9DqAAIVTHlII0s481.png
?

程序 3:接線

下載接線圖。

?
pYYBAGNonFKAfFVuABftyTi1QVo524.png
?

程序 4:安裝組件

注意事項:

  • 組件位置。
  • 上排風口用于進風口,下排風口用于出風口。
  • 電線使用和長度。
  • 光傳感器位置。

程序5:制作霧化器

  • 找一個帶蓋的瓶子。
pYYBAGNonFeAMJ_iAAIiDItPKjc812.png
?
  • 固定脫脂棉。

在蓋子上鉆一個直徑合適的孔來固定脫脂棉。放一些沙子或小石頭固定棉花的底部。

poYBAGNonGCALZopAAO00mrBQOM134.png
?
  • 將水位感應線通過蓋子孔插入瓶子。
pYYBAGNonGKAWqUIAAA-YNVbehU641.png
?
  • 修復霧化器。

1.如圖所示將造霧器放在蓋子上。

poYBAGNonGiAVkSAAAC5qliBkjs428.png
?

2. 重新擰上蓋子,但不要太緊。否則無法產生霧氣。如果沒有瓶子,您可以用熱膠固定霧化器。

poYBAGNonGuAYkLEAAHLrC5caYg072.png
?

程序 6:完成組裝

將組件放入盒子中并整理電線。

?
poYBAGNonHCAGgxQAAoegY3RMCk954.jpg
?
?
pYYBAGNonHSABVmCAAIVXDwrSWU567.jpg
?

第 3 步:創建

進行涂鴉 OS 開發,需要在涂??鴉IoT 平臺上創建一個室內花園產品,然后獲取 SDK。該產品代表了智慧花園的所有物聯網功能,包括產品授權和配置,構建了花園與涂鴉物聯網平臺的通信。本節介紹如何在涂鴉物聯網平臺上打造智能室內花園。有關詳細信息,請參閱創建產品。

?
pYYBAGNomXaAGxuSAABiWTVrJ_s934.png
?
  • 找到自定義函數并單擊創建函數。設置自定義函數的屬性。
  • 要設置溫度和濕度范圍,請添加四個整數數據點 (DP),即Max Temp 、Min Temp 、Max HumidityMin Humidity 。
  • 要將水箱水位的數據傳輸到云端,請添加水箱水位的整數DP
  • 要控制生長光色,請添加Light Color的枚舉 DP 。
  • 要在預定和自動補光之間切換,請添加Fill Light的布爾 DP 。
  • 登錄涂鴉物聯網平臺,點擊創建。
  • 選擇小家電>植物種植者。
  • 單擊自定義解決方案>植物種植者輸入產品名稱,協議類型選擇WiFi+藍牙,點擊頁面下方的創建產品。
  • 創建標準函數中,選擇開關、當前溫度、當前濕度、倒計時、剩余時間故障。
  • (可選)要實現智能花園的非標準功能,需要自定義一些功能。
  • 完成功能定義后,點擊設備面板選擇喜歡的應用控制面板。建議選擇適合您的調試需要的調試面板。

您已完成在涂鴉 IoT 平臺上創建產品。它已準備好進行嵌入式系統開發。

第 4 步:代碼

嵌入式代碼基于 BK7231 芯片組,使用涂鴉通用 Wi-Fi SDK 開發。您可以從涂鴉 GitHub 倉庫拉取的 demo 例程中獲取環境變量,也可以下載包含 SDK 環境變量的 demo 例程。我們通過方法 1 獲取 SDK。

程序 1:進入申請

克隆存儲庫以在您的計算機上創建本地副本。打開apps存儲演示代碼的文件夾。在這個文件夾中,新建一個文件夾,命名bk7231t_plant_grow_mach_demo為存放demo相關的源文件、頭文件、編譯文件。

如果您是第一次接觸 BK7231 開發,我們建議您文件夾中分別找到tuya_device.c并將它們復制到這個新創建的文件夾中。tuya_device.hsrcincludebk7231t_bl0937_1_plug_demo

打開tuya_device.c并找到該device_init功能。

OPERATE_RET device_init(VOID)
{
OPERATE_RET op_ret = OPRT_OK;
TY_IOT_CBS_S wf_cbs = {
status_changed_cb,\
gw_ug_inform_cb,\
gw_reset_cb,\
dev_obj_dp_cb,\
dev_raw_dp_cb,\
dev_dp_query_cb,\
NULL,
};
op_ret = tuya_iot_wf_soc_dev_init_param(hw_get_wifi_mode(),WF_START_SMART_FIRST,\
&wf_cbs,NULL,PRODECT_KEY,DEV_SW_VERSION);
if(OPRT_OK != op_ret) {
PR_ERR("tuya_iot_wf_soc_dev_init_param error,err_num:%d",op_ret);
return op_ret;
}
op_ret = tuya_iot_reg_get_wf_nw_stat_cb(wf_nw_status_cb);
if(OPRT_OK != op_ret) {
PR_ERR("tuya_iot_reg_get_wf_nw_stat_cb is error,err_num:%d",op_ret);
return op_ret;
}
op_ret= app_dltj_init(APP_DLTJ_NORMAL);
if(OPRT_OK != op_ret) {
PR_ERR("dltj init err!");
return op_ret;
}
op_ret = app_switch_init(APP_SW_MODE_NORMAL);
if(op_ret != OPRT_OK) {
return op_ret;
}
return op_ret;
}

在 BK7231T 芯片組的開發環境中,device_init函數是應用程序代碼的入口。設備上電時,BK7231T適配層運行初始化代碼,然后調用該函數初始化應用層。該函數處理以下內容:

  • 調用tuya_iot_wf_soc_dev_init_param()SDK初始化配置工作模式和配對模式,注冊回調函數,保存固件密鑰和PID。
TY_IOT_CBS_S wf_cbs = {
status_changed_cb,\
gw_ug_inform_cb,\
gw_reset_cb,\
dev_obj_dp_cb,\
dev_raw_dp_cb,\
dev_dp_query_cb,\
NULL,
};
op_ret = tuya_iot_wf_soc_dev_init_param(hw_get_wifi_mode(),WF_START_SMART_FIRST,\
&wf_cbs,NULL,PRODECT_KEY,DEV_SW_VERSION);
if(OPRT_OK != op_ret) {
PR_ERR("tuya_iot_wf_soc_dev_init_param error,err_num:%d",op_ret);
return op_ret;
} op_ret = tuya_iot_reg_get_wf_nw_stat_cb(wf_nw_status_cb);
if(OPRT_OK != op_ret) {
    PR_ERR("tuya_iot_reg_get_wf_nw_stat_cb is error,err_num:%d",op_ret);
    return op_ret;
}
op_ret= app_dltj_init(APP_DLTJ_NORMAL);
if(OPRT_OK != op_ret) {
PR_ERR("dltj init err!");
return op_ret;
}
op_ret = app_switch_init(APP_SW_MODE_NORMAL);
if(op_ret != OPRT_OK) {
return op_ret;
}
  • 調用tuya_iot_reg_get_wf_nw_stat_cb()注冊設備網絡狀態回調。
op_ret = tuya_iot_reg_get_wf_nw_stat_cb(wf_nw_status_cb);
if(OPRT_OK != op_ret) {
    PR_ERR("tuya_iot_reg_get_wf_nw_stat_cb is error,err_num:%d",op_ret);
    return op_ret;
}
  • 在應用層調用初始化函數。
op_ret= app_dltj_init(APP_DLTJ_NORMAL);
if(OPRT_OK != op_ret) {
    PR_ERR("dltj init err!");
    return op_ret;
}

op_ret = app_switch_init(APP_SW_MODE_NORMAL);
if(op_ret != OPRT_OK) {
    return op_ret;
}

因為tuya_device.c是借用了另一個demo,所以我們需要為這個demo實現一個應用初始化函數。創建app_plant.c及其頭文件并實現app_plant_init()device_init.

程序 2:應用程序架構

應用程序代碼分三層實現。

  • 底層有傳感器驅動代碼和封裝傳感器初始化和數據采集接口。
  • 第二層有部分控制邏輯代碼,調用傳感器驅動接口來實現各個組件的控制邏輯。該層封裝了輪詢數據處理的接口。
  • 第一層創建應用任務調用第二層接口,處理DP數據傳輸,接受解析。

app_plant.c實現第一層。

  • app_plant_init()調用二層封裝的設備初始化接口,創建應用任務。
OPERATE_RET app_plant_init(IN APP_PLANT_MODE mode)
{
    OPERATE_RET op_ret = OPRT_OK;

    if(APP_PLANT_NORMAL == mode) {
        
        // Initialize I/O, sensors, PWM, and more
        plant_device_init();
        
        // Create data collection tasks for I2C sensors
        xTaskCreate(sensor_data_get_iic_theard,"thread_data_get_iic",512,NULL,TRD_PRIO_3,NULL);

        // Create data collection tasks for ADC sensors
        xTaskCreate(sensor_data_get_adc_theard,"thread_data_get_adc",512,NULL,TRD_PRIO_4,NULL);

        // Create data processing tasks
        xTaskCreate(sensor_data_deal_theard,"thread_data_deal",512,NULL,TRD_PRIO_4,NULL);

        // Create scheduled tasks for DP data reporting
        xTaskCreate(sensor_data_report_theard,"thread_data_report",512,NULL,TRD_PRIO_4,NULL);
    }else {
        // Non-production test mode
    }

    return op_ret;
}
  • app_report_all_dp_status()報告所有 DP 數據:
VOID app_report_all_dp_status(VOID)
{
    OPERATE_RET op_ret = OPRT_OK;

    INT_T dp_cnt = 0;
    dp_cnt = 12;

    TY_OBJ_DP_S *dp_arr = (TY_OBJ_DP_S *)Malloc(dp_cnt*SIZEOF(TY_OBJ_DP_S));
    if(NULL == dp_arr) {
        PR_ERR("malloc failed");
        return;
    }

    memset(dp_arr, 0, dp_cnt*SIZEOF(TY_OBJ_DP_S));

    dp_arr[0].dpid = DPID_SWITCH_P;
    dp_arr[0].type = PROP_BOOL;
    dp_arr[0].time_stamp = 0;
    dp_arr[0].value.dp_value = plant_ctrl_data.Switch;
    ......
    
    op_ret = dev_report_dp_json_async(NULL,dp_arr,dp_cnt);
    Free(dp_arr);
    if(OPRT_OK != op_ret) {
        PR_ERR("dev_report_dp_json_async relay_config data error,err_num",op_ret);
    }

    PR_DEBUG("dp_query report_all_dp_data");
    return;
}
  • 任務功能。

在任務中,plant_get_iic_sensor_data()、plant_get_adc_sensor_data()、plant_ctrl_handle()plant_ctrl_all_off()被循環調用。這些接口來自第二層并在plant_control.c.

STATIC VOID sensor_data_get_iic_theard(PVOID_T pArg)
{   
    while(1) {

        PR_DEBUG("plant_get_i2c_sensor_data");
        vTaskDelay(TASKDELAY_SEC);

        if(TRUE == plant_ctrl_data.Switch) {    
            plant_get_iic_sensor_data();
        }
        
    }
}

STATIC VOID sensor_data_get_adc_theard(PVOID_T pArg)
{   
    while(1) {

        PR_DEBUG("plant_get_adc_sensor_data");
        vTaskDelay(TASKDELAY_SEC*2);

        if(TRUE == plant_ctrl_data.Switch) {
            plant_get_adc_sensor_data();
        }
        
    }
}

STATIC VOID sensor_data_deal_theard(PVOID_T pArg)
{   
    while(1) {
        vTaskDelay(TASKDELAY_SEC);

        if(TRUE == plant_ctrl_data.Switch) {
            plant_ctrl_handle();
        }else {
            plant_ctrl_all_off();
        }
        
    }

}

STATIC VOID sensor_data_report_theard(PVOID_T pArg)
{   
    while(1) {
        vTaskDelay(TASKDELAY_SEC*5);
        app_report_all_dp_status();
    }

}
  • deal_dp_proc()根據DP ID處理接收到的DP數據。
VOID deal_dp_proc(IN CONST TY_OBJ_DP_S *root)
{
    UCHAR_T dpid;

    dpid = root->dpid;
    PR_DEBUG("dpid:%d",dpid);
    
    switch (dpid) {
    
    case DPID_SWITCH_P:
        PR_DEBUG("set switch:%d",root->value.dp_bool);
        plant_ctrl_data.Switch = root->value.dp_bool;
        break;
        
    case DPID_PUMP:
        PR_DEBUG("set pump:%d",root->value.dp_bool);
        plant_ctrl_data.Pump = root->value.dp_bool;
        break;
        
        ......
        
    default:
        break;
    }

    return;

}

我們已經構建了應用程序架構。接下來,我們需要在第二層實現接口,這些接口放在plant_control.c. 以下程序描述了溫度和濕度、光照和土壤濕度方面的控制邏輯。

程序 3:溫度和濕度

要控制溫度和濕度,首先我們必須收集數據。SHT21 傳感器收集溫度和濕度數據。它使用 I2C 協議進行通信。我們根據SHT21 技術手冊編寫傳感器驅動程序代碼。驅動代碼完成后,我們封裝了傳感器初始化、數據采集、數據轉換的接口。

所有 SHT21 驅動程序和外部接口均以sht21.c. 封裝的外部接口從plant_control.c.

1.tuya_sht21_init(sht21_init_t* param)初始化傳感器。request 參數是一個指向結構的指針,該結構包含有關 SDA 和 SCL I/O 引腳和分辨率的信息。

typedef struct 
{
    UCHAR_T SDA_PIN;            ///< SDA pin
    UCHAR_T SCL_PIN;            ///< SCL pin
    sht21_resolution_t RESOLUTION;   
}sht21_init_t;

2.定義結構變量plant_control.c并調用plant_device_init()以初始化傳感器。

#define IIC_SDA_PIN                         (6)
#define IIC_SCL_PIN                         (7)

STATIC sht21_init_t sht21_int_param = {IIC_SDA_PIN, IIC_SCL_PIN, SHT2x_RES_10_13BIT};

VOID plant_device_init(VOID)
{

    // SHT21 IIC driver init 
    tuya_sht21_init(&sht21_int_param);
    
}

3.初始化后,傳感器可以提供環境溫度和濕度值。因為花園需要連續的環境參數,所以必須相應地調用獲取傳感數據的接口。在上述過程中,任務函數app_plant.c之一plant_get_iic_sensor_data()plant_control.c. 因此,我們需要調用傳感器數據采集接口tuya_sht21_measure()和計算接口tuya_sht21_cal_RH()。這兩個接口的參數都是枚舉值,用來獲取溫度或濕度。

VOID plant_get_iic_sensor_data(VOID)
{

    SHORT_T hum;
    SHORT_T temp;

    tuya_sht21_init(&sht21_int_param);

    hum = tuya_sht21_measure(HUMIDITY);
    device_data.humidity = tuya_sht21_cal_RH(hum);
    
    if(device_data.humidity > 0){ // Remove invalid humidity values less than 0
        plant_report_data.Humidity_current = (UCHAR_T)device_data.humidity;
        PR_NOTICE("humidity = %d",plant_report_data.Humidity_current);
    }

    temp = tuya_sht21_measure(TEMP);
    device_data.temperature = tuya_sht21_cal_temperature(temp);
    plant_report_data.Temp_current = (UCHAR_T)device_data.temperature;
    PR_NOTICE("tempre = %d",plant_report_data.Temp_current);
}

4.將環境溫度和濕度與閾值進行比較。我們在涂鴉 IoT 平臺上創建了最高最低溫度和濕度的四個 DP ,因此我們可以通過應用設置閾值并通過云端發送到設備。處理DP數據中deal_dp_proc()函數。app_plant.c

VOID deal_dp_proc(IN CONST TY_OBJ_DP_S *root)
{
    UCHAR_T dpid;

    dpid = root->dpid;
    PR_DEBUG("dpid:%d",dpid);
    
    switch (dpid) {

    ......
    
    case DPID_TEMP_MAX:
        PR_DEBUG("set temp max:%d",root->value.dp_value);
        plant_ctrl_data.Temp_max = root->value.dp_value;
        break;
    
    case DPID_HUMIDITY_MAX:
        PR_DEBUG("set humidity max:%d",root->value.dp_value);
        plant_ctrl_data.Humidity_max = root->value.dp_value;
        break;
    
    case DPID_TEMP_MIN:
        PR_DEBUG("set temp min:%d",root->value.dp_value);
        plant_ctrl_data.Temp_min = root->value.dp_value;
        break;

    case DPID_HUMIDITY_MIN:
        PR_DEBUG("set humidity min:%d",root->value.dp_value);
        plant_ctrl_data.Humidity_min = root->value.dp_value;
        break;
    ......
    
    default:
        break;
    }

    return;

}

5.創建數據比較和I/O設備控制任務app_plant.c。它在循環中調用plant_ctrl_handle()函數。plant.control.c所有控制邏輯都在 中指定plant_ctrl_handle()。為了調節溫度和濕度,我們使用了霧化器、紅外線燈泡和冷卻風扇,它們通過繼電器模塊打開/關閉。tuya_gpio_inout_set()此 SDK 中封裝的接口和tuya_gpio_write()接口控制 I/O 輸出。代碼如下:

#define HUMIDIFIER_PORT                     (24)
#define HUMIDIFIER_LEVEL                    LOW

#define HEATING_ROD_PORT                    (20)
#define HEATING_ROD_LEVEL                   LOW

#define COOL_DOWN_FAN_PORT                  (21)
#define COOL_DOWN_FAN_LEVEL                 LOW

STATIC VOID __ctrl_gpio_init(CONST TY_GPIO_PORT_E port, CONST BOOL_T high)
{
    // Set I/O pin to output mode
    tuya_gpio_inout_set(port, FALSE);
    // Set I/O level
    tuya_gpio_write(port, high);
}

VOID plant_device_init(VOID)
{
    // SHT21 IIC driver init 
    tuya_sht21_init(&sht21_int_param);

    // gpio init
    __ctrl_gpio_init(HUMIDIFIER_PORT, HUMIDIFIER_LEVEL);

    __ctrl_gpio_init(COOL_DOWN_FAN_PORT, COOL_DOWN_FAN_LEVEL);  

    __ctrl_gpio_init(HEATING_ROD_PORT, HEATING_ROD_LEVEL);

}

STATIC VOID __passive_ctrl_module_temp_humidity(VOID)
{   
    if(device_data.humidity < plant_ctrl_data.Humidity_min) {
        tuya_gpio_write(HUMIDIFIER_PORT, !HUMIDIFIER_LEVEL);
    }else {
        tuya_gpio_write(HUMIDIFIER_PORT, HUMIDIFIER_LEVEL);
    }

    if(device_data.temperature < plant_ctrl_data.Temp_min) {
        tuya_gpio_write(HEATING_ROD_PORT, !HEATING_ROD_LEVEL);
    }else {
        tuya_gpio_write(HEATING_ROD_PORT, HEATING_ROD_LEVEL);
    }

    if((device_data.temperature > plant_ctrl_data.Temp_max)||(device_data.humidity > plant_ctrl_data.Humidity_max)) {
        tuya_gpio_write(COOL_DOWN_FAN_PORT,!COOL_DOWN_FAN_LEVEL);
    }else {
        tuya_gpio_write(COOL_DOWN_FAN_PORT,COOL_DOWN_FAN_LEVEL);
    }
    
}

VOID plant_ctrl_handle(VOID)
{   
    PR_DEBUG("enter ctrl handle");

    __passive_ctrl_module_temp_humidity();
    
}

程序 4:燈光控制

BH1750 光傳感器使用 I2C 協議進行通信。我們根據BH1750 數據表編寫傳感器驅動程序代碼驅動代碼完成后,我們封裝了傳感器初始化和數據采集的接口。所有 BH1750 驅動程序和外部接口均以bh1750.c. 封裝的外部接口從plant_control.c.

1.tuya_bh1750_init(sht21_init_t* param)初始化傳感器。request 參數是一個指向包含有關 SDA 和 SCL I/O 管腳信息的結構的指針。

typedef struct 
{
    UCHAR_T SDA_PIN;            ///< SDA pin
    UCHAR_T SCL_PIN;            ///< SCL pin 
}bh1750_init_t;

2.定義結構變量plant_control.c并調用plant_device_init()以初始化傳感器。

#define IIC_SDA_PIN                         (6)
#define IIC_SCL_PIN                         (7)

STATIC bh1750_init_t bh1750_int_param = {IIC_SDA_PIN, IIC_SCL_PIN};

VOID plant_device_init(VOID)
{
......
    // SHT21 IIC driver init 
    tuya_bh1750_init(&bh1750_int_param);
......
}

tuya_bh1750_get_bright_value()3.初始化完成后,調用BH1750數據采集接口plant_get_iic_sensor_data()獲取光照強度值。為保證光傳感器和溫濕度傳感器采集數據時通信穩定,plant_get_iic_sensor_data()輸入時只啟用其中一個傳感器。

VOID plant_get_iic_sensor_data(VOID)
{

    SHORT_T hum;
    SHORT_T temp;

    switch (IIC_SELECT_FLAG)
    {
    case 0:    
        tuya_sht21_init(&sht21_int_param);

        hum = tuya_sht21_measure(HUMIDITY);
        device_data.humidity = tuya_sht21_cal_RH(hum);
        if(device_data.humidity > 0){ // Remove invalid humidity values less than 0
            plant_report_data.Humidity_current = (UCHAR_T)device_data.humidity;
            PR_NOTICE("humidity = %d",plant_report_data.Humidity_current);
        }

        temp = tuya_sht21_measure(TEMP);
        device_data.temperature = tuya_sht21_cal_temperature(temp);
        plant_report_data.Temp_current = (UCHAR_T)device_data.temperature;
        PR_NOTICE("tempre = %d",plant_report_data.Temp_current);
        
        IIC_SELECT_FLAG = 1;

        break;
    case 1:    
        tuya_bh1750_init(&bh1750_int_param);

        device_data.light_intensity_value = tuya_bh1750_get_bright_value();
        PR_NOTICE("light_intensity_value = %d",device_data.light_intensity_value);
        
        IIC_SELECT_FLAG = 0;

        break;

    default:
        break;
    }

}

4.因為我們沒有創建一個DP來設置一個應用程序的光強度值,我們在代碼中設置了一個值。調整光亮度,使光傳感器采集的數據接近該值。我們還設置了一個誤差范圍,以避免在臨界點出現光閃爍。

#define ACCURACY                         (2000)  // Error range
#define light_value_set                  (12000) // Light intensity in lx unit

5.PWM輸出控制燈光亮度。PWM 初始化和輸出功能在plant_pwm.c. 初始化PWM in plant_device_init(),調用實現光控的接口plant_ctrl_handle()。

USER_PWM_DUTY_T user_pwm_duty = {0,0};

VOID plant_device_init(VOID)
{
    ......
    plant_pwm_init();
    ......
}

STATIC VOID __passive_ctrl_module_light(VOID)
{   
    if(IIC_SELECT_FLAG){ // If the I2C temperature and humidity sensor operates previously
        return;
    }

    if((TRUE == plant_ctrl_data.Auto_switch)) { // Automatic light filling is switched on
        USHORT_T current = device_data.light_intensity_value;
        USHORT_T set = light_value_set;

        if((current - set) > ACCURACY) { // Current light intensity is greater than the set value but not within the error range
            if((current - set) >= 200) {
                if(plant_ctrl_data.Bright_value >= 50)plant_ctrl_data.Bright_value -= 50;
            }else if((current - set) > 150) {
                if(plant_ctrl_data.Bright_value >= 20)plant_ctrl_data.Bright_value -= 20;
            }else {
                if(plant_ctrl_data.Bright_value >= 1)plant_ctrl_data.Bright_value--;
            }
        }else if((set - current) > ACCURACY) { // Current light intensity is less than the set value but not within the error range
            if((set - current) >= 200) {
                if(plant_ctrl_data.Bright_value <= 950)plant_ctrl_data.Bright_value += 50;
            }else if((set - current) > 150) {
                if(plant_ctrl_data.Bright_value <= 980)plant_ctrl_data.Bright_value += 20;
            }else {
                if(plant_ctrl_data.Bright_value <= 999)plant_ctrl_data.Bright_value++;
            }
        }
    } 
}

STATIC VOID __initiative_ctrl_module_light(VOID)
{   
    
    if(TRUE == plant_ctrl_data.Auto_switch) { // Automatic light filling is switched on
        PR_NOTICE("Ligth open !!!!");
        if(plant_ctrl_data.Light_color == red) { // Set light color to red
            user_pwm_duty.duty_red = plant_ctrl_data.Bright_value;
            user_pwm_duty.duty_blue = 0;
        }else if(plant_ctrl_data.Light_color == blue) { // Set light color to blue
            user_pwm_duty.duty_blue = plant_ctrl_data.Bright_value;
            user_pwm_duty.duty_red = 0;
        }else {
            user_pwm_duty.duty_blue = plant_ctrl_data.Bright_value;
            user_pwm_duty.duty_red = user_pwm_duty.duty_blue;
        }
        plant_pwm_set(&user_pwm_duty);
    }else { // Automatic light filling is switched off. Users manually schedule light filling.
        if(plant_ctrl_data.Light_color == red) {
            user_pwm_duty.duty_red = 1000;
            user_pwm_duty.duty_blue = 0;
        }else if(plant_ctrl_data.Light_color == blue) {
            user_pwm_duty.duty_blue = 1000;
            user_pwm_duty.duty_red = 0;
        }else {
            user_pwm_duty.duty_red = 1000;
            user_pwm_duty.duty_blue = 1000;
        }
        if((IsThisSysTimerRun(light_timer) == FALSE)&&(plant_ctrl_data.Countdown_set != cancel)) {
            light_flag_min = (USHORT_T)plant_ctrl_data.Countdown_set * 60;
            plant_pwm_set(&user_pwm_duty);
            sys_start_timer(light_timer,1000*60,TIMER_CYCLE);
        }else if(plant_ctrl_data.Countdown_set == cancel) {
            user_pwm_duty.duty_blue = 0;
            user_pwm_duty.duty_red = 0;
            plant_pwm_set(&user_pwm_duty);
            light_flag_min = 0;
            sys_stop_timer(light_timer);
        }else if(IsThisSysTimerRun(light_timer) == TRUE) {
            plant_pwm_set(&user_pwm_duty);
        }
        // Save timer's remaining time in minute
        plant_report_data.Countdown_left = light_flag_min;
    }
                                                                        
}

VOID plant_ctrl_handle(VOID)
{   
    ......
    __passive_ctrl_module_light();
    __initiative_ctrl_module_light();
}

程序 5:土壤水分

土壤濕度傳感器根據土壤電阻的變化輸出不同的模擬信號值。ADC 將來自傳感器的模擬信號轉換為數字信號,以監測水分的變化。

1.app_plant.c中,ADC采集任務循環調用plant_get_adc_sensor_data()。plant_control.c所有ADC采集相關的代碼都放在這個界面中:

VOID plant_get_adc_sensor_data(VOID)
{   // Control switch analog chip to select soil moisture channel
    rs2255_channel_checkout(SOIL_MOISTURE_SENSOR_PORT);
        
    tuya_hal_adc_init(&tuya_adc);
    tuya_hal_adc_value_get(TEMP_ADC_DATA_LEN, &device_data.soil_humidity);
    PR_NOTICE("soil_humidity = %d",device_data.soil_humidity);

    tuya_hal_adc_finalize(&tuya_adc);

}

2.當土壤水分值低于閾值時,水泵開始運行并為植物供水。調用自動澆水接口plant_ctrl_handle()

  • 變量使水泵有一個休息間隔,以避免植物澆水過多ADD_WATER_COUNT。ADD_WATER_READY
STATIC VOID __passive_ctrl_module_soil_humidity(VOID)
{   
    if(device_data.soil_humidity > plant_ctrl_data.Soil_humidity_threshold) { 

        if(ADD_WATER_READY) { 

            tuya_gpio_write(WATER_VALVE_PORT, !WATER_VALVE_LEVEL);

            ADD_WATER_COUNT++;
            if(ADD_WATER_COUNT > 5) {
                ADD_WATER_READY = 0;
            }

        } else{

            tuya_gpio_write(WATER_VALVE_PORT, WATER_VALVE_LEVEL);
            ADD_WATER_COUNT++;
            if(ADD_WATER_COUNT >15) {
                ADD_WATER_READY = 1;
                ADD_WATER_COUNT = 0;
            }

        }
    }else {

        ADD_WATER_READY = 1;
        ADD_WATER_COUNT = 0;
        tuya_gpio_write(WATER_VALVE_PORT, WATER_VALVE_LEVEL);

    }
}

VOID plant_ctrl_handle(VOID)
{   
    ......
    __passive_ctrl_module_soil_humidity();
    ......
}

程序 6:水箱

水泵用于從水箱抽水并向工廠供水。當水位下降時,需要另一個水泵為水箱供水。水位傳感器根據電阻產生輸出電壓,通過測量我們可以確定水位。我們需要使用 ADC 讀取這個模擬電壓并將其轉換為數字值。

1.rs2255_init()用于初始化模擬開關芯片。RS2255 與 SDA 和 SCL 引腳共享相同的 I/O,因此初始化在 ADC 數據采集開始時運行,這與其他 I2C 傳感器初始化相同。

VOID plant_get_adc_sensor_data(VOID)
{
    rs2255_init();

    switch (ADC_SELECT_FLAG)
    {
    case 0:    

        rs2255_channel_checkout(WATER_SENSOR_PORT);
        tuya_hal_adc_init(&tuya_adc);
        tuya_hal_adc_value_get(TEMP_ADC_DATA_LEN, &device_data.water_tank_value);
        PR_NOTICE("water_tank_value = %d",device_data.water_tank_value);

        ADC_SELECT_FLAG = 1;

        break;
    case 1:    
        
        rs2255_channel_checkout(SOIL_MOISTURE_SENSOR_PORT);
        tuya_hal_adc_init(&tuya_adc);
        tuya_hal_adc_value_get(TEMP_ADC_DATA_LEN, &device_data.soil_humidity);
        PR_NOTICE("soil_humidity = %d",device_data.soil_humidity);

        ADC_SELECT_FLAG = 0;

        break;

    default:
        break;
    }
    
    tuya_hal_adc_finalize(&tuya_adc);

}

2.調用plant_ctrl_handle()實現水箱水位控制。

#define WATER_PUMP_PORT                     (22)
#define WATER_PUMP_LEVEL                    LOW

STATIC VOID __initiative_ctrl_module_pump(VOID)
{   
    // Convert water level sensor value into remaining water level percentage for data transmission
    if(device_data.water_tank_value < 1700) {
        plant_report_data.Water_remain = 10;
    }else if(device_data.water_tank_value < 2500) {
        plant_report_data.Water_remain = 25;
    }else if(device_data.water_tank_value < 2700) {
        plant_report_data.Water_remain = 50;
    }else if(device_data.water_tank_value < 2900) {
        plant_report_data.Water_remain = 75;
    }else if(device_data.water_tank_value >= 3000) {
        plant_report_data.Water_remain = 100;
    }

    if(TRUE == plant_ctrl_data.Pump){ // If water pump is switched on
        PR_NOTICE("water pump open !!!!");
        tuya_gpio_write(WATER_PUMP_PORT,!WATER_PUMP_LEVEL);
    }else {
        tuya_gpio_write(WATER_PUMP_PORT,WATER_PUMP_LEVEL);
    }
    if(device_data.water_tank_value >= 3000) { // When the water level approaches the threshold, the water pump is switched off
        PR_NOTICE("water tank is full !!!!");
        tuya_gpio_write(WATER_PUMP_PORT,WATER_PUMP_LEVEL);
        plant_ctrl_data.Pump = FALSE;
    }
                                                                    
}

VOID plant_ctrl_handle(VOID)
{   
    ......
    __initiative_ctrl_module_pump();
    ......
}

現在,我們已經完成了編碼部分。用APP上的調試面板測試DP數據傳輸后,我們就可以進行固件編譯了。

程序 7:編譯和燒錄

Linux 終端中,運行build_app.sh腳本來編譯固件。生成的固件位于apps> APP_PATH>output中。

  • 命令格式:
build_app.sh /home/share/samba/ci/ty_iot_wf_bt_sdk_bk7231t$ sudo sh build_app.sh apps/bk7231t_plant_grow_mach_demo bk7231t_plant_grow_mach_demo 1.0.0
  • 命令示例:
/home/share/samba/ci/ty_iot_wf_bt_sdk_bk7231t$ sudo sh build_app.sh apps/bk7231t_plant_grow_mach_demo bk7231t_plant_grow_mach_demo 1.0.0
  • 下圖顯示成功返回。
poYBAGNomYaAKb8ZAAHQ8-a4huI824.png
?

?

將固件燒錄到模塊后,我們開始進行功能調試。有關刻錄和授權的更多信息,請參閱刻錄和授權 WB 系列模塊。

第 5 步:調試

一旦模塊被授權,我們將手機連接到 Wi-Fi 網絡,打開藍牙,按照說明對花園進行配對。然后,我們可以用應用程序控制花園。在本項目中,我們使用涂鴉智能 App 作為控制終端。有不同的應用程序選項。有關詳細信息,請參閱應用程序開發。

調試過程如下:

程序 1:預定和自動補光

  • 打開花園并設置倒計時。

?

pYYBAGNonIGAct_qAABLKGV8mZY390.png
?

?

pYYBAGNonIqAapkRAAK1JGk9sLM415.png
?

?

2.設置燈光顏色,生長燈板相應改變顏色。

?

pYYBAGNonI6AObkQAALMN6vhZSc153.png
?

?

3.當倒計時設置為取消時,植物燈板將關閉。

4.開啟自動補光后,燈光亮度會不斷增加,直到達到預設值。

程序二:溫濕度控制

1.可以在涂鴉智能APP上查看當前環境溫度和濕度。

?

pYYBAGNonJCAB82lAABAFpJRPes330.png
?

?

2.如果您設置的最小濕度大于當前濕度,霧化器將啟動。當環境濕度超過最小值時,制霧器將停止。

?

pYYBAGNonJWAHjhjAAMhxAz1cCk103.png
?

?

3.如果您設置的最低溫度高于當前溫度,紅外線燈泡將打開。當環境溫度超過最小值時,紅外燈泡將停止。

4.以同樣的方式測試最高溫度和濕度,并觀察冷卻風扇是否相應運行。這個風扇可以對空氣進行除濕和冷卻。

程序 3:加注水箱

1.可查看水箱水位剩余水百分比。

2.在涂鴉智能APP開啟Pump ,開啟水泵。

?

?

pYYBAGNonJeAUBsQAABGBxUYzOY139.png
?

?

poYBAGNonJyAcsotAAD3ZNcvzTo292.png
?

?

1:通風繼電器模塊

2:噴涂繼電器模塊

3:補水箱繼電器模塊

?

3.將水位傳感器放入杯中,加水至銅線完全沒入。您會發現水泵停止并且應用程序上的Pump恢復。

?

pYYBAGNonJ-AdHAMAAIST79UUi4961.png
?

?

4.水箱水位變為100。

?

poYBAGNonKSAMaanAAAmELbputM549.png
?

?

程序 4:自動澆水

  • 當您打開花園時,用于澆水的水泵將持續運行。

?

poYBAGNonKaAYuFIAAC440iATqY131.png
?

?

  • 4:澆水繼電器模塊
  • 5:加熱繼電器模塊

2.將土壤濕度傳感器放入水中,模擬土壤濕度達到閾值的情況。你會發現水泵停止。

?
poYBAGNonLGARtssABGAhS5Fs4U105.png
?

概括

恭喜!您已成功構建智能室內花園的原型。依托涂鴉物聯網平臺,您可以快速輕松地從零開始構建各種智能原型。


下載該資料的人也在下載 下載該資料的人還在閱讀
更多 >

評論

查看更多

下載排行

本周

  1. 1A7159和A7139射頻芯片的資料免費下載
  2. 0.20 MB   |  55次下載  |  5 積分
  3. 2PIC12F629/675 數據手冊免費下載
  4. 2.38 MB   |  36次下載  |  5 積分
  5. 3PIC16F716 數據手冊免費下載
  6. 2.35 MB   |  18次下載  |  5 積分
  7. 4dsPIC33EDV64MC205電機控制開發板用戶指南
  8. 5.78MB   |  8次下載  |  免費
  9. 5STC15系列常用寄存器匯總免費下載
  10. 1.60 MB   |  7次下載  |  5 積分
  11. 6模擬電路仿真實現
  12. 2.94MB   |  4次下載  |  免費
  13. 7PCB圖繪制實例操作
  14. 2.92MB   |  2次下載  |  免費
  15. 8零死角玩轉STM32F103—指南者
  16. 26.78 MB   |  1次下載  |  1 積分

本月

  1. 1ADI高性能電源管理解決方案
  2. 2.43 MB   |  452次下載  |  免費
  3. 2免費開源CC3D飛控資料(電路圖&PCB源文件、BOM、
  4. 5.67 MB   |  141次下載  |  1 積分
  5. 3基于STM32單片機智能手環心率計步器體溫顯示設計
  6. 0.10 MB   |  137次下載  |  免費
  7. 4A7159和A7139射頻芯片的資料免費下載
  8. 0.20 MB   |  55次下載  |  5 積分
  9. 5PIC12F629/675 數據手冊免費下載
  10. 2.38 MB   |  36次下載  |  5 積分
  11. 6如何正確測試電源的紋波
  12. 0.36 MB   |  19次下載  |  免費
  13. 7PIC16F716 數據手冊免費下載
  14. 2.35 MB   |  18次下載  |  5 積分
  15. 8Q/SQR E8-4-2024乘用車電子電器零部件及子系統EMC試驗方法及要求
  16. 1.97 MB   |  8次下載  |  10 積分

總榜

  1. 1matlab軟件下載入口
  2. 未知  |  935121次下載  |  10 積分
  3. 2開源硬件-PMP21529.1-4 開關降壓/升壓雙向直流/直流轉換器 PCB layout 設計
  4. 1.48MB  |  420062次下載  |  10 積分
  5. 3Altium DXP2002下載入口
  6. 未知  |  233088次下載  |  10 積分
  7. 4電路仿真軟件multisim 10.0免費下載
  8. 340992  |  191367次下載  |  10 積分
  9. 5十天學會AVR單片機與C語言視頻教程 下載
  10. 158M  |  183335次下載  |  10 積分
  11. 6labview8.5下載
  12. 未知  |  81581次下載  |  10 積分
  13. 7Keil工具MDK-Arm免費下載
  14. 0.02 MB  |  73810次下載  |  10 積分
  15. 8LabVIEW 8.6下載
  16. 未知  |  65988次下載  |  10 積分
博九网| 百家乐官网游戏类型| 百家乐官网大眼仔用法| 皇冠百家乐官网的玩法技巧和规则 | 百家乐官网博彩资讯论坛| 百家乐官网统计软件| 索雷尔百家乐的玩法技巧和规则| 德州扑克发牌| 百家乐官网网站赌博| 百家乐透视用设备| 888百家乐的玩法技巧和规则| 线上老虎机| 励骏会百家乐官网的玩法技巧和规则 | 大发888娱乐场下载专区| 网上百家乐官网真的假的| 百家乐视频挖坑| 大发888登陆| 网上百家乐官网真的假的| 百家乐水晶筹码| 皇冠| 网上百家乐官网公| 大发888老虎机平台| 百家乐官网网投注| 金盾百家乐网址| 仪陇县| 百家乐官网秘籍下注法| 大发888优惠红利代码| 百家乐官网赌场博彩赌场网| 下载百家乐的玩法技巧和规则 | 英皇百家乐官网的玩法技巧和规则| 诸子百家乐的玩法技巧和规则| 波音百家乐官网游戏| 百家乐信誉平台开户| 环球娱乐城| 百家乐最低下注| 速博国际| 百家乐怎么对冲打| 顶旺娱乐| 百家乐网上最好网站| 湛江市| 百家乐高手怎么下注|