日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

【基于RT-Thread+RA6M4的智能鱼缸系统设计之鱼我所欲也】

發布時間:2024/3/12 windows 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【基于RT-Thread+RA6M4的智能鱼缸系统设计之鱼我所欲也】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【基于RT-Thread+RA6M4的智能魚缸系統設計之魚我所欲也】

  • 摘 要:
  • 0 引言
  • 1. 總體設計
  • 2. 硬件設計
    • 2.1 控制器
    • 2.2 傳感器
    • 2.3 執行器
    • 2.4 電源
    • 2.5 魚缸
  • 3 軟件設計
    • 3.1 多傳感器數據融合與執行器協同系統
      • 3.1.1 均值濾波
      • 3.1.2 模糊控制
    • 3.2 本地監控系統
    • 3.3 物聯網遠程監控系統
  • 4 系統測試
    • 4.1 本地端測試
      • 4.1.1 接收協議
      • 4.1.2 傳輸協議
    • 4.2 情況說明:
    • 4.3 附件
  • 5 結語

摘 要:

當今社會生活中對觀賞魚的飼養已經成為了一種潮流,目前人們開始追求更加便捷的飼養方式而且保證其存活率。新一代的家居設計以擁有豐富實用的補氧、換水、殺菌和溫控功能、更加人性化的設計,而受到大眾的青睞。本文基于魚缸的智能化需求,提出了一款多傳感器數據融合的智能魚缸,采用RA6M4單片機和onenet物聯網平臺,對多個傳感器的信息進行融合和互補來管理魚缸以及感知水環境。用戶利用電腦本地端、網頁客戶端或手機APP(還在開發測試中)實現對智能魚缸的水溫、氣壓、光照強度等傳感采集,實現補氧氣、蜂鳴器提示和殺菌的本地控制、室外異地遠程控制及各傳感器根據實際環境自動調節執行器的工作狀態。

0 引言

本研究的智能魚缸系統是屬于智能家居的一個具體產品。魚缸是大眾家庭中比較常見的一種飼養魚類的容器,但它的實際意義不僅僅是一個魚缸、而是家庭中的一道風景。魚缸中新鮮快活的魚兒、娓娓動人的小蝦、碧波蕩漾的水草、浮浮沉沉的浮萍,十分巧妙地將水環境生態系統的美景融合在一個魚缸中,形成了一幅動靜相宜的畫卷。

目前,國內市場上有許多功能不一致的產品,其中大多數是非智能,單一恒溫控制、增氧、照明系統。如果一套多功能魚缸無法智能控制多個功能模塊和單個設備,則使用起來會很不靈活且效率低下,并且整體性能無法提高。
因此,針對這一系列問題提化了一種多傳感器數據融合的智能魚缸系統。首先對智能魚缸系統進行總體設計,其次分別介紹系統的硬件設計和軟件選擇。硬件設計介紹了控制器、傳感器、執行器以及電源的設計方案;軟件設計包含多傳感器數據融合與執行器協同系統、本地監控系統和物聯網遠程監控系統。其中多傳感器首先采用均值濾波得到智能魚缸的水體溫度、水面氣壓、缸外溫度,光照強度等數據,將魚缸的水體溫度和水面氣壓進行模糊邏輯推理,模糊控制水泵的工作狀態進而調整補氧氣速率;將魚缸的缸外溫度和光照強度也進行模糊邏輯推理,模糊控制水泵的工作狀態進而調整補氧氣速率。后期將項目的系統硬件與軟件進行結合,經過多次測試,預計實現水循環、蜂鳴器提示和光照控制的功能,并實現移動終端的遠程實時控制。該設計通過多傳感器數據融合進行水泵和紫外線燈模糊控制,不僅僅是對于家用魚缸的管理與改進,還對于類似的智能家居產品的研究與生產有較高的實用價值。

1. 總體設計

本系統以RA6M4芯片作為系統主控,并圍繞其設計了一系列外圍電路。系統通過由多種組件函數庫完成RT-Thread Studio 項目工程搭建,對使用 I2C、ADC、PWM 、UART等通信協議的各類外設模塊進行控制。同時通過 MQTT 協議發布主題訂閱主題方式接入onenet物聯網平臺,以實現通過物聯網對系統進行遠程監測以及后期控制。系統結構框圖如圖 1 所示,以RA6M4為主控,通過間接或直接的方式對外圍電路、外圍模塊進行控制。電源、控制器、執行器、傳感器、魚缸共同構成系統的硬件監測執行部分,通訊中的電腦端、手機端、中移互聯云平臺為軟件交互部分。

圖 1 系統結構框圖

2. 硬件設計

硬件部分由控制器、傳感器、執行器、電源以及魚缸組成。硬件原理圖如下

項目工程見立創EDA:Intelligent fish tank system

2.1 控制器

控制器選用RA6M4單片機,RA6M4配合RT-Thread Studio 編程而不用51單片機或者STM32單片機,主頻高達200MHz, 采用Arm Cortex?-M33 內核,IO口全部引出,采用MOS管輸出穩定且可承載一定功率,8路UART串口,10路PWM,還設計了Arduino UNO板載接口,可通過WiFi接入網絡來智能控制執行器,讓使用者更好地進行人機交互,使用起來更加方便。RA6M4性能強而且功率低,對比相同性能的主控板,RA6M4的性價比更高。

Renesas RA6M4開發板環境配置參照:【基于 RT-Thread Studio的CPK-RA6M4 開發板環境搭建】

2.2 傳感器

傳感器由各個具體功能模塊構成:BMP180氣壓溫度傳感器、DHT11溫濕度傳感器、LM35溫度傳感器和光敏電阻光照傳感器。

  • BMP180氣壓溫度傳感器

BMP180是一款高精度、小體積、低能耗的壓力溫度傳感器,可以應用在移動設備中;BMP180采用強大的8-pin陶瓷無引線芯片承載(LCC)超薄封裝,可以通過I2C總線直接與各種微處理器相連。為模糊控制水泵的制氧速率提供輸入外界氣壓和外界溫度兩變量。使用方法見【Renesas RA6M4開發板之I2C讀取BMP180氣壓溫度】
修改接口代碼:
bmp180_sample.c

#include "bmp180.h" #include "bmp180_sample.h"/** Copyright (c) 2020 panrui <https://github.com/Prry/rtt-bmp180>** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date Author Notes* 2020-03-12 panrui the first version*/#include <rtthread.h> #include <rtdevice.h> #include "sensor.h" #include "bsp_api.h" rt_device_t baro_dev = RT_NULL, temp_dev = RT_NULL; struct rt_sensor_data baro_data,temp_data; rt_size_t res0 = 0, res1 = 1; rt_uint8_t chip_id; void read_baro_entry(void) {baro_dev = rt_device_find("baro_bmp180");if (baro_dev == RT_NULL){rt_kprintf("not found baro_bmp180 device\r\n");return;}if (rt_device_open(baro_dev, RT_DEVICE_FLAG_RDONLY) != RT_EOK){rt_kprintf("open baro_180 failed\r\n");return;}temp_dev = rt_device_find("temp_bmp180");if (temp_dev == RT_NULL){rt_kprintf("not found temp_bmp180 device\r\n");return;}if (rt_device_open(temp_dev, RT_DEVICE_FLAG_RDONLY) != RT_EOK){rt_kprintf("open temp_bmp180 failed\r\n");return;}rt_device_control(baro_dev, RT_SENSOR_CTRL_SET_ODR, (void *)(1));/* 1Hz read */rt_device_control(temp_dev, RT_SENSOR_CTRL_SET_ODR, (void *)(1));/* 1Hz read */rt_device_control(temp_dev, RT_SENSOR_CTRL_GET_ID, (void*)&chip_id);rt_kprintf("bmp180 chip ID [0x%X]\n", chip_id); } unsigned char *bmp_read(void) {static unsigned char bmp[2];res0 = rt_device_read(baro_dev, 0, &baro_data, 1);res0 = rt_device_read(temp_dev, 0, &temp_data, 1);if (res0==0 || res1==0){rt_kprintf("read data failed! result is %d,%d\n", res0, res1);rt_device_close(baro_dev);rt_device_close(temp_dev);}bmp[0]=baro_data.data.baro/1000;bmp[1]=temp_data.data.temp/10-44;rt_kprintf("baro[%dPa],temp[%d.%dC],timestamp[%d]\r\n", baro_data.data.baro,temp_data.data.temp/10-44, temp_data.data.temp%10,temp_data.timestamp);return bmp; }int rt_hw_bmp180_port(void) {struct rt_sensor_config cfg;cfg.intf.dev_name = "i2c1"; /* i2c bus */cfg.intf.user_data = (void *)0x77; /* i2c slave addr */rt_hw_bmp180_init("bmp180", &cfg); /* bmp180 */read_baro_entry();return RT_EOK; } INIT_COMPONENT_EXPORT(rt_hw_bmp180_port);

bmp180_sample.h

/** Copyright (c) 2006-2021, RT-Thread Development Team** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date Author Notes* 2022-07-25 Asus the first version*/ #ifndef _BMP180_SAMPLE_H_ #define _BMP180_SAMPLE_H_void read_baro_entry(void); unsigned char *bmp_read(void); int rt_hw_bmp180_port(void);#endif /* PACKAGES_BMP180_LATEST_BMP180_SAMPLE_H_ */
  • DHT11溫濕度傳感器

DHT11數字溫濕度傳感器是一款含有已校準數字信號輸出的溫濕度復合傳感器。它應用專用的數字模塊采集技術和溫濕度傳感技術,確保產品具有可靠性與卓越的長期穩定性,成本低、相對濕度和溫度測量、快響應、抗干擾能力強、信號傳輸距離長、數字信號輸出、精確校準。傳感器包括一個電容式感濕元件和一個NTC測溫元件,并與一個高性能8位單片機相連接。使用方法見【Renesas RA6M4開發板之DHT11溫濕度讀取】
修改接口代碼:
dhtxx_sample.c

#include <rtthread.h> #include <rtdevice.h> #include <board.h> #include "dhtxx_sample.h" #include "dhtxx.h" #include "bsp_api.h" #include <stdio.h> #include <string.h>#define DATA_PIN BSP_IO_PORT_01_PIN_02//dht溫濕度端口定義/* cat_dhtxx sensor data by dynamic */ rt_uint8_t *cat_dhtxx(void) {static rt_uint8_t dht[2];dht_device_t sensor = dht_create(DATA_PIN);if(dht_read(sensor)) {rt_int32_t temp = dht_get_temperature(sensor);rt_int32_t humi = dht_get_humidity(sensor);rt_kprintf("Temp: %d.%d 'C, Humi: %d '% \n", temp/10-2, temp%10, humi/10);dht[0] = temp/10-4,dht[1] = humi/10;}else {rt_kprintf("Read dht sensor failed.\n");}rt_thread_mdelay(100);dht_delete(sensor);return dht; }//#ifdef FINSH_USING_MSH //MSH_CMD_EXPORT(cat_dhtxx, read dhtxx humidity and temperature); //#endif

dhtxx_sample.h

#ifndef _DHTXX_SAMPLE_H_ #define _DHTXX_SAMPLE_H_rt_uint8_t *cat_dhtxx(void);#endif /* PACKAGES_DHTXX_LATEST_EXAMPLES_DHTXX_SAMPLE_H_ */
  • LM35溫度傳感器

    LM35線性溫度傳感器是一種得到廣泛使用的溫度傳感器,工作溫度范圍較大,模塊適用于許多特殊場合,測量溫度范圍為0℃~100℃,輸出電壓與溫度成正比線性關系,0°C時輸出為0V,溫度每上升1℃,輸出電壓增加10mV,LM35線性溫度傳感器使用ADC讀取 (需要校準),可以非常容易地實現與環境溫度感知相關的互動效果。本實驗將LM35傳感器建議封裝使其可以穩定讀取水體溫度,使用方法見【Renesas RA6M4開發板之Arduino六路ADC采樣】

  • 光敏電阻光照傳感器

    光敏電阻是用硫化鎘或硒化鎘等半導體材料制成的特殊電阻器,其工作原理是基于內光電效應。光照愈強,阻值就愈低,隨著光照強度的升高,電阻值迅速降低,亮電阻值可小至1KΩ以下。光敏電阻對光線十分敏感,其在無光照時,呈高阻狀態,暗電阻一般可達1.5MΩ,使用ADC讀取 (需要校準)。使用方法見【Renesas RA6M4開發板之Arduino六路ADC采樣】
    兩個ADC接口代碼
    adc.c

#include"adc.h" #define ADC_NAME "adc0" /* ADC 設 備 名 稱 */ #define LM35_ADC_CHANNEL 0 /* LM35_ADC水體溫度通 道 */ #define light_ADC_CHANNEL 1 /* light_ADC光敏通 道 */ #define REFER_VOLTAGE 330 /* 參 考 電 壓 3.3V,數 據 精 度 乘 以100保 留2位 小 數*/ #define CONVERT_BITS (1 << 12) /* 轉 換 位 數 為12位 */ rt_adc_device_t adc_dev; /* adc設備句柄 */ rt_err_t ret = RT_EOK; int adc_Initiation(void) {rt_err_t ret = RT_EOK;/* 查 找 設 備 */adc_dev = (rt_adc_device_t)rt_device_find(ADC_NAME);if (adc_dev == RT_NULL){rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_NAME);ret = RT_ERROR;}else{rt_kprintf("rt_sensor find %s device init success!\n", ADC_NAME);}return ret; } rt_uint8_t *adc_read() {rt_int16_t LM35=0,light=0;static rt_uint8_t adc[2], adc_value[4], max = 5;for (int var = 0; var < max; ++var) {/* 使 能 設 備 */ret = rt_adc_enable(adc_dev, LM35_ADC_CHANNEL);ret = rt_adc_enable(adc_dev, light_ADC_CHANNEL);rt_thread_mdelay(var);/* 1讀 取 采 樣 值 */LM35 = LM35+ rt_adc_read(adc_dev, LM35_ADC_CHANNEL);rt_thread_mdelay(var);/* 2讀 取 采 樣 值 */light = light + rt_adc_read(adc_dev, light_ADC_CHANNEL);/* 關 閉 通 道 */ret = rt_adc_disable(adc_dev, LM35_ADC_CHANNEL);ret = rt_adc_disable(adc_dev, light_ADC_CHANNEL);rt_thread_mdelay(50);}LM35 = LM35/max,light = light/max; // rt_kprintf("the LM35 is :%d \n", LM35);/* 轉 換 為 對 應 溫 度 值 */LM35 = LM35*(REFER_VOLTAGE/40.96); //轉化為溫度adc_value[0] = LM35 / 100-22;adc_value[1] = LM35 % 100;rt_kprintf("the voltage is :%d.%02d `C\n", adc_value[0], adc_value[1]); // rt_kprintf("the light is :%d \n", light);/* 轉 換 為 對 應 電 壓 值 */light = light * REFER_VOLTAGE / CONVERT_BITS;adc_value[2] = light /100;adc_value[3] = light %100;rt_kprintf("the voltage is :%d.%02d lx\n", adc_value[2], adc_value[3]);adc[0] = LM35/100-22;adc[1] = light;return adc; } INIT_APP_EXPORT(adc_Initiation);

adc.h

#ifndef _ADC_H_ #define _ADC_H_ #include <rtthread.h> #include <rtdevice.h> #include <stdio.h> #include <stdlib.h> int adc_Initiation(void); rt_uint8_t *adc_read();#endif /* _ADC_H_ */

2.3 執行器

結合魚缸實際需求,執行器包括水泵、UV殺菌燈、OLED顯示屏和蜂鳴器。

  • 水泵

    USB魚缸養魚氧氣泵,超靜音打氧機小型增氧機家用增氧泵釣魚專用,控制方式采用PWM輸出,將USB接口連接MX1919,通過MX1919驅動器控制增氧效果,需要大增氧時滿功率運行,不需要增氧時關閉氣泵,中間過渡可以通過氣壓和溫度進行傳感器數據融合實現模糊控制。使用方法見【Renesas RA6M4開發板之兩路PWM驅動】
  • UV殺菌燈

    采用5W魚缸UV殺菌燈180°遮光板,控制方式采用PWM輸出,避免漏光直射對眼睛和魚兒造成不可逆的傷害不透光才能更安全;隨意調整遮光板角度。本次實驗采用六顆紫色LED代替,同樣使用MX1919另外一路輸出,使用方法見【Renesas RA6M4開發板之兩路PWM驅動】
    兩路PWM接口代碼

pwmled.c

#include "pwmled.h"#define PWM_DEV_NAME "pwm8" /* PWM設備UV燈名稱 */ #define PWM2_DEV_NAME "pwm7" /* PWM設備水泵名稱 */ #define PWM_DEV_CHANNEL 0 /* PWM通道 */ #define period 500000 /* 周期為0.5ms,單位為納秒us */ struct rt_device_pwm *pwm_dev; /* PWM設備句柄 */ struct rt_device_pwm *pwm2_dev; /* PWM2設備句柄 */ int pwm_Initiation(void) {rt_err_t rt_err = RT_EOK;rt_uint16_t pulse = 0; /* 初始使能為零 *//* 查找UV燈設備 */pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME);if (pwm_dev == RT_NULL){rt_kprintf("pwm sample run failed! can't find %s device!\n", PWM_DEV_NAME);rt_err = RT_NULL;}else {rt_kprintf("rt_sensor find %s device init success!\n", PWM_DEV_NAME);}/* 查找水泵設備 */pwm2_dev = (struct rt_device_pwm *)rt_device_find(PWM2_DEV_NAME);if (pwm2_dev == RT_NULL){rt_kprintf("pwm sample run failed! can't find %s device!\n", PWM2_DEV_NAME);rt_err = RT_NULL;}else {rt_kprintf("rt_sensor find %s device init success!\n", PWM2_DEV_NAME);}/* 設置PWM周期和脈沖寬度默認值 */rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL, period, pulse);/* 使能設備 */rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL);rt_pwm_enable(pwm2_dev, PWM_DEV_CHANNEL);return rt_err; } /*a,b范圍在0~10*/ void pwm_action(rt_uint8_t a,rt_uint8_t b) {if (a>=10) {a=10;}else if (a<=0) {a=0;}if (b>=10) {b=10;}else if (b<=5) {b=0;}if (a==0&&b==0) {rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, 0);//UV燈rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL, period, 0);//水泵} else {rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, period*0.1*a);//UV燈rt_pwm_set(pwm2_dev, PWM_DEV_CHANNEL, period, period*0.7+period*0.03*b);//水泵} } INIT_APP_EXPORT(pwm_Initiation);

pwmled.h

#ifndef _PWMLED_H_ #define _PWMLED_H_ #include <rtthread.h> #include "hal_data.h" #include <rtdevice.h>int pwm_Initiation(void); void pwm_action(rt_uint8_t a,rt_uint8_t b);#endif /* _PWMLED_H_ */
  • OLED顯示屏

本模塊選用的是0.96寸OLED顯示屏,通訊采用IIC協議,采用能實時顯示水體溫度、缸外溫度、外界氣壓和光照強度數值,此模塊是由RA6M4用戶按鍵來觸發響應(5S后熄屏),默認狀態不顯示。使用方法見【Renesas RA6M4開發板之I2C驅動ssd1306 OLED屏幕】

  • 蜂鳴器

采用TMB09A03型 DC3V 有源蜂鳴器,屬于有源連續聲。此模塊采用普通GPIO輸出控制,當傳感器達到一定的閾值會在本地提醒用戶執行相關操作,達到交互使用的效果。使用方法見【Renesas RA6M4開發板之按鍵和LED的GPIO】

2.4 電源

結合魚缸日常供電需求,每天整體電控系統所需能量表達式如下;
Q=QL+QP+QCQ=Q_L+Q_P+Q_CQ=QL?+QP?+QC?
其中QLQ_LQL?是UV殺菌燈每天消耗的能量;QPQ_PQP?是水泵每天消耗的能量;QCQ_CQC?是控制器和其他傳感器、執行器等每天消耗的能量。

t為對應的使用時間,結合實驗分析,各參數如下表:

每天大約需要消耗60焦耳的電能(估算),因此采用18650電池USB供電,電源供電采用四節18650鋰電池2000mA和太陽能電池板搭配。系統搭配UPS不間斷供電系統,該供電系統通過監測18650鋰電池的電壓,如果光伏發電使鋰電池達到3.7V,則不啟動USB供電,反而言之。
太陽能電池板,采用5V200mA單晶太陽能板三片并聯發電,太陽能電池板白天通過環境光給電池充電和系統供電??梢杂行Ь徑?8650鋰電池供電需求。

2.5 魚缸

本次實驗采用市面常用的意品寵物用品專營店的240型高清熱彎中小型桌面魚缸,采用汽車級浮法玻璃工藝,使透光率達到92%。整體構成仿生態循環過濾,模擬大自然水流環境,循環凈水,魚缸結構如圖2。尺寸是240mm170mm285mm,盛水容積大約8升。

圖 2 魚缸結構

3 軟件設計

軟件設計包括多傳感器數據融合與執行器協同系統、本地監控系統和物聯網遠程監控系統,其中RA6M4軟件架構如下。

本項目軟件架構主要采用上圖所示的三個線程完成,其中:
CMD_Theard線程:負責完成傳感器數據和執行器數據采集矯正;
LM_Theard線程:負責系統中傳感器數據和執行器數據采集,通過拼接自定義串口協議,采用Uart串口通訊實現上下位機的聯動;
Onenet_Theard線程:負責系統中傳感器數據和執行器數據采集,通過esp8266上報到Onenet平臺,以及云端數據下發解析執行等功能。

3.1 多傳感器數據融合與執行器協同系統

其中多傳感器首先采用卡爾曼濾波得到智能魚缸的水體溫度、水面氣壓、光照強度數據,將魚缸的水體溫度和水面氣壓進行模糊邏輯推理,模糊控制水泵的工作狀態。

3.1.1 均值濾波

系統獲取的傳感器數據通常不能夠直接供應用使用(存在噪聲干擾:低頻噪聲或高頻噪聲),一般通過一種或者多種濾波算法結合,對原始數據進行濾波處理,在保證濾波后數據實時性要求的前提下,獲取相對穩定無噪聲的數據用于實際的應用系統。

平均濾波,取一定數量的原始數據,進行累加后取平均,從而獲取較穩定的輸出數據,主要濾除原始數據中的高頻噪聲。為了減少電源供電擾動主動放棄第一次采樣,累加后續5次數據平均。

3.1.2 模糊控制

模糊控制結構如圖3所示, 以魚缸環境傳感器數據處理的結果作為輸入值, 一般包括:大氣壓強、溫度、濕度、光照強度等;模糊控制輸出用于執行器, 如水泵、加熱設備、UV紫外線燈等。


圖 3 模糊控制結構
由于多輸出的模糊控制算法過于復雜, 因此可利用模糊控制器的解耦特性, 將模糊控制系統分解為多個單輸出的子系統,系統模糊控制如表1所示。例如可根據溫度和氣壓控制水泵的打開時間, 本文將以此為例設計模糊控制器。
表 1 系統模糊控制

輸入主參輸入副參輸出結果
缸外溫度氣壓水泵工作時間
缸內溫度光照UV燈工作時間

假想實驗環境:室內的溫度為0℃30℃,而魚缸水體溫度在0℃20℃,定義輸入量溫度的基本論域為[0, 20]。

定義5個模糊子集(NB、NS、ZO、PS、PB) 和高斯型隸屬度函數,其中σ取值為2, NB、NS、ZO、PS、PB隸屬度函數中均值x取值分別為0、5、10、15、20。因此溫度的范圍域和隸屬度函數曲線如圖4所示:

圖 4 溫度的范圍域和隸屬度函數曲線
根據前期調查,一般春季武漢市的氣壓為100000pa~101000pa, 定義輸入量氣壓的基本論域為[100000, 101000]。定義5個模糊子集 (NB、NS、ZO、PS、PB) 和高斯型隸屬度函數, 其中σ取值為125, NB、NS、ZO、PS、PB隸屬度函數中均值x取值分別為100000、100250、100500、100750、101000。因此氣壓的范圍域和隸屬度函數曲線如圖5所示:

圖 5 氣壓的范圍域和隸屬度函數曲線
水循環的每次水泵開啟時間一般為0~20分鐘, 定義輸出量水循環時間基本論域為[0, 20]。分為5個模糊子集:關閉(NB)稍短(NS)中等(ZO)稍長(PS)長(PB),定義三角型隸屬度函數,因此水循環時間的范圍域和隸屬度函數曲線如圖6所示

圖 6 水循環時間的范圍域和隸屬度函數曲線
采用“if Temp and Pres then Motor”形式的模糊推理方法, 其中Temp、Temp為輸入模糊子集, Motor為輸出模糊子集。根據實踐調試經驗得出表2所示模糊控制規則表, 又稱模糊關系矩陣, 共25條控制規則:
表 2 模糊控制規則表

系統采用Mamdani模糊推理法, 本設計采用重心法, 即取模糊隸屬度函數曲線與坐標圍成面積的重心作為最終輸出值。


使用Matlab的Fuzzy Logic工具箱進行系統仿真, 觀察系統輸入輸出。例如取溫度Temp=10℃、氣壓Pres=100500pa, 則輸出的水循環時間Motor=3.14min,給定輸入經模糊規則推理輸出如圖7所示:

圖 7 給定輸入經模糊規則推理輸出
系統仿真輸出曲面如圖8所示, 輸出曲面總體光滑, 穩定可靠, 可將養殖環境參數控制在最佳值附近。

圖 8 系統仿真輸出曲面
近似函數代替為:

3.2 本地監控系統

用戶可以實時本地觀察魚缸狀態,OLED顯示器會事件型滾動屏幕,休眠狀態是屏幕熄屏,因此休眠時間將遠大于滾動顯示時間以達到節能效果。OLED顯示器滾動屏幕時將采集的傳感器數據、執行器狀態數據和電池電壓數據實時動態顯示。本地端設計了直接控制方式,優先級為1級,根據當前魚缸環境的實際情況,個性化調節魚缸的水泵、光照等,實現智能魚缸的精準控制。

3.3 物聯網遠程監控系統

本文的智能魚缸系統接入onenet物聯網云平臺,以實現物聯網遠程控制。采用onenet庫與接口函數,并通過手機 APP 或手機語音的方式來實現遠程操作。利用公有云服務進行數據傳輸,進而對其進行遠程操控,使魚缸能夠作為智能家居被用戶使用。

4 系統測試

4.1 本地端測試

采用Uart0實現本地端串口通訊,串口通訊分為接收協議和發送協議,上位機采用Serial Studio,使用方法見:【Renesas RA6M4開發板之Serial studio串口交互】

4.1.1 接收協議

根據實際要求,確定通信協議傳輸格式。

名稱16進制大小
Head0x5a1字節
Buzzer0x00/0x011字節
UVLED0x00~0x0a1字節
Moter0x00~0x0a1字節
Command0x00~0x021字節
LED30x00/0x011字節
Data0x00~0xff3字節
Num0x0b1字節
Verify0xa51字節

通信協議格式:

  • Head : 協議頭部,標記一幀傳輸的開始(自定義字節數);
  • Buzzer:蜂鳴器操作數;
  • UVLED:紫外線LED燈操作數;
  • Moter:水泵操作數;
  • Command:需要傳輸的控制命令,可以定義成結構體形式(自定義字節數),0x00保持,0x01手動修改,0x02自動控制;
  • LED3:板載LED3操作數;
  • Data:需要傳輸的數據,不管什么類型,都轉換成16進制進行傳輸(自定義字節數);
  • Num:需要傳輸的數據(自定義字節數),此數據長度為11字節,換算16進制為0x0b;
  • Verify:校驗(自定義字節數),常采用CRC校驗,和校驗,奇偶校驗,異或校驗等。
    • 5A 01 00 00 01 01 00 00 00 0B A5 開燈
    • 5A 01 00 00 01 00 00 00 00 0B A5 關燈
    • 5A 00 00 00 01 00 00 00 00 0B A5 蜂鳴器打開
    • 5A 00 0a 00 01 00 00 00 00 0B A5 UV燈打開
    • 5A 00 00 00 02 01 00 00 00 0B A5 自動

    具體查看數據解析線程函數control_thread_entry

    4.1.2 傳輸協議

    傳輸協議采用一串字符編碼,其中包含幀頭,分隔符,幀尾

    名稱標記
    幀頭/*KAANSATQRO,
    分隔符,
    幀尾*/

    中間監測魚缸數據依次為:水體溫度(LM35),光照強度,警報(蜂鳴器),板載LED3,外部大氣壓(BMP180),外部溫度1(BMP180),外部溫度2(DHT11),外部濕度(DHT11),UV燈(PWM1),水泵增氧機(PWM2)

    具體查看數據解析線程函數serial_thread_entry

    Serial Studio傳感器映射部分參數配置

    Serial Studio的Json映射文件

    {"frameEnd": "*/","frameStart": "/*KAANSATQRO,","groups": [{"datasets": [{"alarm": 0,"fft": false,"fftSamples": 1024,"graph": true,"led": false,"log": false,"max": 0,"min": 0,"title": "水體溫度(LM35)","units": "℃","value": "%1","widget": "gauge"},{"alarm": 0,"fft": false,"fftSamples": 1024,"graph": true,"led": false,"log": false,"max": 0,"min": 0,"title": "光照強度","units": "Lux","value": "%2","widget": ""},{"alarm": 0,"fft": false,"fftSamples": 1024,"graph": false,"led": true,"log": false,"max": 0,"min": 0,"title": "警報(蜂鳴器)","units": "bool","value": "%3","widget": ""},{"alarm": 0,"fft": false,"fftSamples": 1024,"graph": false,"led": true,"log": false,"max": 0,"min": 0,"title": "板載LED3","units": "bool","value": "%4","widget": ""},{"alarm": 0,"fft": false,"fftSamples": 1024,"graph": true,"led": false,"log": false,"max": 0,"min": 0,"title": "外部大氣壓(BMP180)","units": "KPa","value": "%5","widget": ""},{"alarm": 0,"fft": false,"fftSamples": 1024,"graph": true,"led": false,"log": false,"max": 0,"min": 0,"title": "外部溫度1(BMP180)","units": "℃","value": "%6","widget": "gauge"},{"alarm": 0,"fft": false,"fftSamples": 1024,"graph": true,"led": false,"log": false,"max": 0,"min": 0,"title": "外部溫度2(DHT11)","units": "℃","value": "%7","widget": "gauge"},{"alarm": 0,"fft": false,"fftSamples": 1024,"graph": true,"led": false,"log": false,"max": 0,"min": 0,"title": "外部濕度(DHT11)","units": "%","value": "%8","widget": "gauge"},{"alarm": 0,"fft": false,"fftSamples": 1024,"graph": true,"led": false,"log": false,"max": 0,"min": 0,"title": "UV燈(PWM1)","units": "%","value": "%9","widget": ""},{"alarm": 0,"fft": false,"fftSamples": 1024,"graph": true,"led": false,"log": false,"max": 0,"min": 0,"title": "水泵增氧機(PWM2)","units": "%","value": "%10","widget": ""}],"title": "智能魚缸監測系統","widget": ""}],"separator": ",","title": "test" }

    打印效果:

    11:42:35.098 -> hello RT-Thread! 11:42:35.586 -> /*KAANSATQRO,25,134,1,0,82,25,0,0,0,0*/ 11:42:37.005 -> /*KAANSATQRO,25,138,1,0,97,25,26,79,0,0*/ 11:42:38.426 -> /*KAANSATQRO,24,138,1,0,97,25,26,80,0,0*/ 11:42:39.833 -> /*KAANSATQRO,25,138,1,0,97,25,26,80,0,0*/ 11:42:41.256 -> /*KAANSATQRO,24,138,1,0,97,25,26,80,0,0*/ 11:42:42.678 -> /*KAANSATQRO,24,138,1,0,97,25,26,80,0,0*/ 11:42:44.081 -> /*KAANSATQRO,24,138,1,0,97,25,26,80,0,0*/ 11:42:45.496 -> /*KAANSATQRO,25,138,1,0,97,25,26,80,0,0*/ 11:42:46.919 -> /*KAANSATQRO,25,138,1,0,97,25,26,80,0,0*/ 11:42:48.332 -> /*KAANSATQRO,24,138,1,0,97,25,26,80,0,0*/ 11:42:49.750 -> /*KAANSATQRO,26,138,1,0,97,25,26,80,0,0*/ 11:42:51.160 -> /*KAANSATQRO,25,138,1,0,97,25,26,80,0,0*/ 11:42:52.573 -> /*KAANSATQRO,25,138,1,0,97,25,26,80,0,0*/

    本地端接口代碼:
    uart.c

    /** 程序清單:這是一個串口設備接收不定長數據的示例代碼* 例程導出了 uart_dma_sample 命令到控制終端* 命令調用格式:uart_dma_sample uart2* 命令解釋:命令第二個參數是要使用的串口設備名稱,為空則使用默認的串口設備* 程序功能:通過串口 uart2 輸出字符串"hello RT-Thread!",并通過串口 uart2 輸入一串字符(不定長),再通過數據解析后,使用控制臺顯示有效數據。 */#include"uart.h" #define LED3_PIN BSP_IO_PORT_01_PIN_06 #define buzzer_PIN BSP_IO_PORT_04_PIN_03//蜂鳴器定義 #define SAMPLE_UART_NAME "uart0" #define DATA_CMD_END '\r' /* 結束位設置為 \r,即回車符 */ #define ONE_DATA_MAXLEN 12 /* 不定長數據的最大長度 *//* 用于接收消息的信號量 */ static struct rt_semaphore rx_sem; static rt_device_t serial;/* 接收數據回調函數 */ static rt_err_t uart_rx_ind(rt_device_t dev, rt_size_t size) {/* 串口接收到數據后產生中斷,調用此回調函數,然后發送接收信號量 */if (size > 0){rt_sem_release(&rx_sem);}return RT_EOK; }static char uart_sample_get_char(void) {char ch;while (rt_device_read(serial, 0, &ch, 1) == 0){rt_sem_control(&rx_sem, RT_IPC_CMD_RESET, RT_NULL);rt_sem_take(&rx_sem, RT_WAITING_FOREVER);}return ch; } /* 數據解析線程 */ static void control_thread_entry(void) {char ch;char data[ONE_DATA_MAXLEN];static char i = 0;unsigned char *adc_value, *bmp_value;while (1){ch = uart_sample_get_char();if(ch == DATA_CMD_END){data[i++] = '\0';rt_kprintf("data= 0x");//CMD uart7打印 uart0接收16進制數for (int var = 0; var < ONE_DATA_MAXLEN-1; ++var) {rt_kprintf("%x",data[var]);}rt_kprintf("\r\n");rt_thread_mdelay(1);if (data[0]==0x5a&&data[10]==0xa5) {//校驗頭部和尾部if (data[4]==0x00) {//保持命令rt_kprintf("Keep on \r\n");}else if (data[4]==0x01) {//修改命令//操作LED燈亮rt_kprintf("Action \r\n");rt_pin_write(LED3_PIN, data[5]);//蜂鳴器操作相反pwm_action(data[2],data[3]);//燈和水泵rt_pin_write(buzzer_PIN, data[1]);//蜂鳴器操作相反}else if (data[4]==0x02) {rt_kprintf("Automatic \r\n");adc_value = adc_read();bmp_value = bmp_read();data[2] = 10*adc_value[0]/35*(330-adc_value[1])/330;//水泵data[3] = 10*adc_value[0]/30*(101-bmp_value[0])/5;//水泵pwm_action(data[2],data[3]);//燈和水泵}}else {//校驗識別,返回數據不合法rt_kprintf("data input Illegal ! please input :5A 00 00 00 01 01 00 0B 00 00 A5 \r\n",data);}rt_device_write(serial, 0, &data, sizeof(data));//uart0打印接收指令for (int var = 0; var < sizeof(data); ++var) {data[var] = 0x00;}//數組清零i = 0;//重新獲取continue;}i = (i >= ONE_DATA_MAXLEN-1) ? ONE_DATA_MAXLEN-1 : i;data[i++] = ch;} }/*uart0串口輸出線程*/ void serial_thread_entry(rt_uint8_t a,rt_uint8_t b) {unsigned char *adc_value, gpio_value[2], *bmp_value, *dht_value, pwm_value[2];char str1[45];char HeadByte[45] ="/*KAANSATQRO";adc_value = adc_read();gpio_value[0] = rt_pin_read(buzzer_PIN),gpio_value[1] = rt_pin_read(LED3_PIN);bmp_value = bmp_read();dht_value = cat_dhtxx();pwm_value[0] = a,pwm_value[1] = b;rt_sprintf(str1, "%s,%d,%d", HeadByte, adc_value[0],adc_value[1]);rt_sprintf(str1, "%s,%d,%d", str1,gpio_value[0],gpio_value[1]);rt_sprintf(str1, "%s,%d,%d", str1,bmp_value[0],bmp_value[1]);rt_sprintf(str1, "%s,%d,%d", str1,dht_value[0],dht_value[1]);rt_sprintf(str1, "%s,%d,%d", str1,pwm_value[0],pwm_value[1]);rt_sprintf(str1, "%s%s", str1,"*/ \r\n");rt_device_write(serial, 0, str1, sizeof(str1) );rt_thread_mdelay(500); }static int uart_data_sample(int argc, char *argv[]) {rt_err_t ret = RT_EOK;char uart_name[RT_NAME_MAX];char str[] = "hello RT-Thread!\r\n";if (argc == 2){rt_strncpy(uart_name, argv[1], RT_NAME_MAX);}else{rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX);}/* 查找系統中的串口設備 */serial = rt_device_find(uart_name);if (!serial){rt_kprintf("find %s failed!\n", uart_name);return RT_ERROR;}/* 初始化信號量 */rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);/* 以中斷接收及輪詢發送模式打開串口設備 */rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);/* 設置接收回調函數 */rt_device_set_rx_indicate(serial, uart_rx_ind);/* 發送字符串 */rt_device_write(serial, 0, str, (sizeof(str) - 1));/* 創建 control_thread 線程 */ // rt_thread_t control_thread = rt_thread_create("control", (void (*)(void *parameter))control_thread_entry, RT_NULL, 1024, 30, 10);rt_thread_t control_thread = rt_thread_create("control", (void (*)(void *parameter))control_thread_entry, RT_NULL, 1024, 25, 10);/* 創建成功則啟動線程 */if (control_thread != RT_NULL){rt_thread_startup(control_thread);}else{ret = RT_ERROR;}return ret; }/* 導出到 msh 命令列表中 */ //MSH_CMD_EXPORT(uart_data_sample, uart device sample); INIT_APP_EXPORT(uart_data_sample);

    uart.h

    /** Copyright (c) 2006-2021, RT-Thread Development Team** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date Author Notes* 2022-07-25 Asus the first version*/ #ifndef _UART_H_ #define _UART_H_#include "hal_data.h" #include <rtthread.h> #include <rtdevice.h> #include <stdio.h> #include <string.h> #include "pwmled.h" #include "adc.h" #include "bmp180_sample.h" #include "dhtxx_sample.h" //static rt_err_t uart_rx_ind(rt_device_t dev, rt_size_t size); //static char uart_sample_get_char(void); //static void control_thread_entry(void); void serial_thread_entry(rt_uint8_t a,rt_uint8_t b); //static int uart_data_sample(int argc, char *argv[]); #endif /* SRC_UART_H_ */

    16進制指令:

    • 5A 01 00 00 01 01 00 00 00 0B A5 開燈
    • 5A 01 00 00 01 00 00 00 00 0B A5 關燈
    • 5A 00 00 00 01 00 00 00 00 0B A5 蜂鳴器打開
    • 5A 00 0a 00 01 00 00 00 00 0B A5 UV燈打開
    • 5A 00 00 00 02 01 00 00 00 0B A5 自動
      部分效果圖:

      水泵工作狀態

    4.2 情況說明:

    由于本人從7月25號困在中高風險區,電腦和硬件28號到,并且在實驗室是可以連接wifi,由于條件有限,我所處管控區沒有wifi,設備連接手機熱點是無法登入onenet,因此暫時還沒試驗完,后期會補充onenet平臺。

    4.3 附件

    代碼地址:

    • 上位機監控代碼
    • Onenet平臺完整代碼

    視頻地址:

    • 【基于RT-Thread+RA6M4的智能魚缸系統之魚我所欲也】硬件設計調試一
    • 【基于RT-Thread+RA6M4的智能魚缸系統之魚我所欲也】硬件設計調試二
    • 演示

    5 結語

    • 首先感謝瑞薩和RTT官方給了我們DIY愛好者提供第二次測評????!净赗T-Thread+RA6M4的智能魚缸系統設計之魚我所欲也】只是個人在業余時間中一個不太完整的構想,雖然當前市面上以及有非常多的同類產品,但是二次開發易用性和擴展度與之相形見絀🤣🤣🤣。
    • RT-Thread作為國內嵌入式系統生態的領跑者,對產品的快速原型開發有很強的支持,至于產品的穩健性還需爾后完善。因此第一次測評開發板,這個開發過程讓我映像深刻,社區問答基本在專業伙伴協助下可以解決90%🎉🎉🎉,更多是需要自身對C++基本語法掌握使用得當(強烈建議完善相關適配C++語言文檔,那么RT-Thread愈加強大和健壯🎏🎏🎏)。
    • 本文利用RA6M4開發板、ESP8266、onenet平臺構建了智能魚缸系統,并開發了多傳感器數據融合與執行器協同系統,將魚缸的水體溫度和水面氣壓進行模糊邏輯推理,模糊控制水泵的工作狀態,克服了傳統魚缸缺乏反饋環節和調節環節的缺陷🌼🌼🌼。該系統可通過傳感器獲得水溫、氣壓、光照強度和視頻流等數據實時魚缸并由顯示器或物聯網平臺反饋給用戶。該智能魚缸系統的功能全面、成本低廉、操作簡便,易于推廣應用,可創造較大市場價值。
    • 由于時間短、本人知識水平有限等因素,該系統的研究設計中還是存在一些不足之處。本系統為了完成遠程控制的功能,使用了onenet平臺來進行數據的傳輸與存儲,該云平臺為商業平臺,本系統對于用戶數據的私密性保護存在一定的缺陷,需耍進一步提高對傳輸數據的加密保護😀😀😀。

    參考文獻:

    • 基于RT-Thread+RA6M4上傳onenet云平臺
    • 基于RT-Thread+RA6M4的智能安防系統
    • 自定義串口通信協議(16進制)
    • 【Renesas RA6M4開發板之按鍵和LED的GPIO】
    • 【Renesas RA6M4開發板之Arduino六路ADC采樣】
    • 【Renesas RA6M4開發板之兩路PWM驅動】
    • 【Renesas RA6M4開發板之I2C讀取BMP180氣壓溫度】
    • 【Renesas RA6M4開發板之Serial studio串口交互】

    總結

    以上是生活随笔為你收集整理的【基于RT-Thread+RA6M4的智能鱼缸系统设计之鱼我所欲也】的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。