0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

一种多传感器数据融合的智能鱼缸系统设计

RTThread物联网操作系统 来源:RTThread物联网操作系统 作者:2345vor 2022-08-11 10:43 次阅读

摘 要

当今社会生活中对观赏鱼的饲养已经成为了一种潮流,目前人们开始追求更加便捷的饲养方式而且保证其存活率。新一代的家居设计以拥有丰富实用的补氧、换水、杀菌和温控功能、更加人性化的设计,而受到大众的青睐。本文基于鱼缸的智能化需求,提出了一款多传感器数据融合的智能鱼缸,采用RA6M4单片机和onenet物联网平台,对多个传感器的信息进行融合和互补来管理鱼缸以及感知水环境。用户利用电脑本地端、网页客户端或手机APP(还在开发测试中)实现对智能鱼缸的水温、气压、光照强度等传感采集,实现补氧气、蜂鸣器提示和杀菌的本地控制、室外异地远程控制及各传感器根据实际环境自动调节执行器的工作状态。

引言

本研究的智能鱼缸系统是属于智能家居的一个具体产品。鱼缸是大众家庭中比较常见的一种饲养鱼类的容器,但它的实际意义不仅仅是一个鱼缸、而是家庭中的一道风景。鱼缸中新鲜快活的鱼儿、娓娓动人的小虾、碧波荡漾的水草、浮浮沉沉的浮萍,十分巧妙地将水环境生态系统的美景融合在一个鱼缸中,形成了一幅动静相宜的画卷。

目前,国内市场上有许多功能不一致的产品,其中大多数是非智能,单一恒温控制、增氧、照明系统。如果一套多功能鱼缸无法智能控制多个功能模块和单个设备,则使用起来会很不灵活且效率低下,并且整体性能无法提高。

因此,针对这一系列问题提化了一种多传感器数据融合的智能鱼缸系统。首先对智能鱼缸系统进行总体设计,其次分别介绍系统的硬件设计和软件选择。硬件设计介绍了控制器、传感器、执行器以及电源的设计方案;软件设计包含多传感器数据融合与执行器协同系统、本地监控系统和物联网远程监控系统。其中多传感器首先采用均值滤波得到智能鱼缸的水体温度、水面气压、缸外温度,光照强度等数据,将鱼缸的水体温度和水面气压进行模糊逻辑推理,模糊控制水泵的工作状态进而调整补氧气速率;将鱼缸的缸外温度和光照强度也进行模糊逻辑推理,模糊控制水泵的工作状态进而调整补氧气速率。后期将项目的系统硬件与软件进行结合,经过多次测试,预计实现水循环、蜂鸣器提示和光照控制的功能,并实现移动终端的远程实时控制。该设计通过多传感器数据融合进行水泵和紫外线灯模糊控制,不仅仅是对于家用鱼缸的管理与改进,还对于类似的智能家居产品的研究与生产有较高的实用价值。

1、总体设计

本系统以RA6M4芯片作为系统主控,并围绕其设计了一系列外围电路。系统通过由多种组件函数库完成RT-Thread Studio 项目工程搭建,对使用 I2CADC、PWM 、UART通信协议的各类外设模块进行控制。同时通过 MQTT 协议发布主题订阅主题方式接入onenet物联网平台,以实现通过物联网对系统进行远程监测以及后期控制。系统结构框图如图 1 所示,以RA6M4为主控,通过间接或直接的方式对外围电路、外围模块进行控制。电源、控制器、执行器、传感器、鱼缸共同构成系统的硬件监测执行部分,通讯中的电脑端、手机端、中移互联云平台为软件交互部分。

68a08abc-18a8-11ed-ba43-dac502259ad0.png

图 1 系统结构框图

2、硬件设计

硬件部分由控制器、传感器、执行器、电源以及鱼缸组成。硬件原理图如下,

68c95046-18a8-11ed-ba43-dac502259ad0.png

项目工程见立创EDAIntelligent 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的性价比更高。

68e16afa-18a8-11ed-ba43-dac502259ad0.png

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

 1#include"bmp180.h"
 2#include"bmp180_sample.h"
 3/*
 4*Copyright(c)2020panrui 5*
 6*SPDX-License-Identifier:Apache-2.0
 7*
 8*ChangeLogs:
 9*DateAuthorNotes
10*2020-03-12panruithefirstversion
11*/
12#include
13#include
14#include"sensor.h"
15#include"bsp_api.h"
16rt_device_tbaro_dev=RT_NULL,temp_dev=RT_NULL;
17structrt_sensor_databaro_data,temp_data;
18rt_size_tres0=0,res1=1;
19rt_uint8_tchip_id;
20voidread_baro_entry(void)
21{
22baro_dev=rt_device_find("baro_bmp180");
23if(baro_dev==RT_NULL)
24{
25rt_kprintf("notfoundbaro_bmp180device
");
26return;
27}
28if(rt_device_open(baro_dev,RT_DEVICE_FLAG_RDONLY)!=RT_EOK)
29{
30rt_kprintf("openbaro_180failed
");
31return;
32}
33temp_dev=rt_device_find("temp_bmp180");
34if(temp_dev==RT_NULL)
35{
36rt_kprintf("notfoundtemp_bmp180device
");
37return;
38}
39if(rt_device_open(temp_dev,RT_DEVICE_FLAG_RDONLY)!=RT_EOK)
40{
41rt_kprintf("opentemp_bmp180failed
");
42return;
43}
44rt_device_control(baro_dev,RT_SENSOR_CTRL_SET_ODR,(void*)(1));/*1Hzread*/
45rt_device_control(temp_dev,RT_SENSOR_CTRL_SET_ODR,(void*)(1));/*1Hzread*/
46rt_device_control(temp_dev,RT_SENSOR_CTRL_GET_ID,(void*)&chip_id);
47rt_kprintf("bmp180chipID[0x%X]
",chip_id);
48}
49unsignedchar*bmp_read(void)
50{
51staticunsignedcharbmp[2];
52res0=rt_device_read(baro_dev,0,&baro_data,1);
53res0=rt_device_read(temp_dev,0,&temp_data,1);
54if(res0==0||res1==0)
55{
56rt_kprintf("readdatafailed!resultis%d,%d
",res0,res1);
57rt_device_close(baro_dev);
58rt_device_close(temp_dev);
59}
60bmp[0]=baro_data.data.baro/1000;
61bmp[1]=temp_data.data.temp/10-44;
62rt_kprintf("baro[%dPa],temp[%d.%dC],timestamp[%d]
",baro_data.data.baro,
63temp_data.data.temp/10-44,temp_data.data.temp%10,
64temp_data.timestamp);
65returnbmp;
66}
67intrt_hw_bmp180_port(void)
68{
69structrt_sensor_configcfg;
70cfg.intf.dev_name="i2c1";/*i2cbus*/
71cfg.intf.user_data=(void*)0x77;/*i2cslaveaddr*/
72rt_hw_bmp180_init("bmp180",&cfg);/*bmp180*/
73read_baro_entry();
74returnRT_EOK;
75}
76INIT_COMPONENT_EXPORT(rt_hw_bmp180_port);

bmp180_sample.h

 1/*
 2
 3*Copyright(c)2006-2021,RT-ThreadDevelopmentTeam
 4
 5*
 6
 7*SPDX-License-Identifier:Apache-2.0
 8
 9*
10
11*ChangeLogs:
12
13*DateAuthorNotes
14
15*2022-07-25Asusthefirstversion
16
17*/
18
19#ifndef_BMP180_SAMPLE_H_
20
21#define_BMP180_SAMPLE_H_
22
23voidread_baro_entry(void);
24
25unsignedchar*bmp_read(void);
26
27intrt_hw_bmp180_port(void);
28
29#endif/*PACKAGES_BMP180_LATEST_BMP180_SAMPLE_H_*/

DHT11温湿度传感器

DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有可靠性与卓越的长期稳定性,成本低、相对湿度和温度测量、快响应、抗干扰能力强、信号传输距离长、数字信号输出、精确校准。传感器包括一个电容式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。使用方法见Renesas RA6M4开发板之DHT11温湿度读取】

修改接口代码:

dhtxx_sample.c

 1
 2
 3#include
 4#include
 5#include
 6#include"dhtxx_sample.h"
 7#include"dhtxx.h"
 8#include"bsp_api.h"
 9#include
10#include
11#defineDATA_PINBSP_IO_PORT_01_PIN_02//dht温湿度端口定义
12/*cat_dhtxxsensordatabydynamic*/
13rt_uint8_t*cat_dhtxx(void)
14{
15staticrt_uint8_tdht[2];
16dht_device_tsensor=dht_create(DATA_PIN);
17if(dht_read(sensor)){
18rt_int32_ttemp=dht_get_temperature(sensor);
19rt_int32_thumi=dht_get_humidity(sensor);
20rt_kprintf("Temp:%d.%d'C,Humi:%d'%
",temp/10-2,temp%10,humi/10);
21dht[0]=temp/10-4,dht[1]=humi/10;
22}
23else{
24rt_kprintf("Readdhtsensorfailed.
");
25}
26rt_thread_mdelay(100);
27dht_delete(sensor);
28returndht;
29}
30//#ifdefFINSH_USING_MSH
31//MSH_CMD_EXPORT(cat_dhtxx,readdhtxxhumidityandtemperature);
32//#endif

dhtxx_sample.h

1#ifndef_DHTXX_SAMPLE_H_
2#define_DHTXX_SAMPLE_H_
3rt_uint8_t*cat_dhtxx(void);
4#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

 1#include"adc.h"
 2#defineADC_NAME"adc0"/*ADC设备名称*/
 3#defineLM35_ADC_CHANNEL0/*LM35_ADC水体温度通道*/
 4#definelight_ADC_CHANNEL1/*light_ADC光敏通道*/
 5#defineREFER_VOLTAGE330/*参考电压3.3V,数据精度乘以100保留2位小数*/
 6#defineCONVERT_BITS(1<< 12) /*转换位数为12位*/
 7rt_adc_device_tadc_dev;/*adc设备句柄*/
 8rt_err_tret=RT_EOK;
 9intadc_Initiation(void)
10{
11rt_err_tret=RT_EOK;
12/*查找设备*/
13adc_dev=(rt_adc_device_t)rt_device_find(ADC_NAME);
14if(adc_dev==RT_NULL)
15{
16rt_kprintf("adcsamplerunfailed!can'tfind%sdevice!
",ADC_NAME);
17ret=RT_ERROR;
18}
19else
20{
21rt_kprintf("rt_sensorfind%sdeviceinitsuccess!
",ADC_NAME);
22}
23returnret;
24}
25rt_uint8_t*adc_read()
26{
27rt_int16_tLM35=0,light=0;
28staticrt_uint8_tadc[2],adc_value[4],max=5;
29for(intvar=0;var< max; ++var) {
30/*使能设备*/
31ret=rt_adc_enable(adc_dev,LM35_ADC_CHANNEL);
32ret=rt_adc_enable(adc_dev,light_ADC_CHANNEL);
33rt_thread_mdelay(var);
34/*1读取采样值*/
35LM35=LM35+rt_adc_read(adc_dev,LM35_ADC_CHANNEL);
36rt_thread_mdelay(var);
37/*2读取采样值*/
38light=light+rt_adc_read(adc_dev,light_ADC_CHANNEL);
39/*关闭通道*/
40ret=rt_adc_disable(adc_dev,LM35_ADC_CHANNEL);
41ret=rt_adc_disable(adc_dev,light_ADC_CHANNEL);
42rt_thread_mdelay(50);
43}
44LM35=LM35/max,light=light/max;
45//rt_kprintf("theLM35is:%d
",LM35);
46/*转换为对应温度值*/
47LM35=LM35*(REFER_VOLTAGE/40.96);//转化为温度
48adc_value[0]=LM35/100-22;
49adc_value[1]=LM35%100;
50rt_kprintf("thevoltageis:%d.%02d`C
",adc_value[0],adc_value[1]);
51//rt_kprintf("thelightis:%d
",light);
52/*转换为对应电压值*/
53light=light*REFER_VOLTAGE/CONVERT_BITS;
54adc_value[2]=light/100;
55adc_value[3]=light%100;
56rt_kprintf("thevoltageis:%d.%02dlx
",adc_value[2],adc_value[3]);
57adc[0]=LM35/100-22;
58adc[1]=light;
59returnadc;
60}
61INIT_APP_EXPORT(adc_Initiation);

adc.h

1#ifndef_ADC_H_
2#define_ADC_H_
3#include
4#include
5#include
6#include
7intadc_Initiation(void);
8rt_uint8_t*adc_read();
9#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"

#definePWM_DEV_NAME"pwm8"/*PWM设备UV灯名称*/

#definePWM2_DEV_NAME"pwm7"/*PWM设备水泵名称*/

#definePWM_DEV_CHANNEL0/*PWM通道*/

#defineperiod500000/*周期为0.5ms,单位为纳秒us*/

structrt_device_pwm*pwm_dev;/*PWM设备句柄*/

structrt_device_pwm*pwm2_dev;/*PWM2设备句柄*/

intpwm_Initiation(void)

{

rt_err_trt_err=RT_EOK;

rt_uint16_tpulse=0;/*初始使能为零*/

/*查找UV灯设备*/

pwm_dev=(structrt_device_pwm*)rt_device_find(PWM_DEV_NAME);

if(pwm_dev==RT_NULL)

{

rt_kprintf("pwmsamplerunfailed!can'tfind%sdevice!
",PWM_DEV_NAME);

rt_err=RT_NULL;

}

else{

rt_kprintf("rt_sensorfind%sdeviceinitsuccess!
",PWM_DEV_NAME);

}

/*查找水泵设备*/

pwm2_dev=(structrt_device_pwm*)rt_device_find(PWM2_DEV_NAME);

if(pwm2_dev==RT_NULL)

{

rt_kprintf("pwmsamplerunfailed!can'tfind%sdevice!
",PWM2_DEV_NAME);

rt_err=RT_NULL;

}

else{

rt_kprintf("rt_sensorfind%sdeviceinitsuccess!
",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);

returnrt_err;

}

/*a,b范围在0~10*/

voidpwm_action(rt_uint8_ta,rt_uint8_tb)

{

if(a>=10){

a=10;

}

elseif(a<=0){

a=0;

}

if(b>=10){

b=10;

}

elseif(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

1#ifndef_PWMLED_H_
2#define_PWMLED_H_
3#include
4#include"hal_data.h"
5#include
6intpwm_Initiation(void);
7voidpwm_action(rt_uint8_ta,rt_uint8_tb);
8#endif/*_PWMLED_H_*/

  • OLED显示屏

本模块选用的是0.96寸OLED显示屏,通讯采用IIC协议,采用能实时显示水体温度、缸外温度、外界气压和光照强度数值,此模块是由RA6M4用户按键来触发响应(5S后熄屏),默认状态不显示。使用方法见【Renesas RA6M4开发板之I2C驱动ssd1306 OLED屏幕】

  • 蜂鸣器

采用TMB09A03型 DC3V 有源蜂鸣器,属于有源连续声。此模块采用普通GPIO输出控制,当传感器达到一定的阈值会在本地提醒用户执行相关操作,达到交互使用的效果。使用方法见【Renesas RA6M4开发板之按键和LED的GPIO】

https://oss-club.rt-thread.org/uploads/20220806/da39a3ee5e6b4b0d3255bfef95601890afd80709.png

t为对应的使用时间,结合实验分析,各参数如下表:

6aa85196-18a8-11ed-ba43-dac502259ad0.png

每天大约需要消耗60焦耳的电能(估算),因此采用18650电池USB供电,电源供电采用四节18650锂电池2000mA和太阳能电池板搭配。系统搭配UPS不间断供电系统,该供电系统通过监测18650锂电池的电压,如果光伏发电使锂电池达到3.7V,则不启动USB供电,反而言之。

太阳能电池板,采用5V200mA单晶太阳能板三片并联发电,太阳能电池板白天通过环境光给电池充电和系统供电。可以有效缓解18650锂电池供电需求。

2.5 鱼缸

本次实验采用市面常用的意品宠物用品专营店的240型高清热弯中小型桌面鱼缸,采用汽车级浮法玻璃工艺,使透光率达到92%。整体构成仿生态循环过滤,模拟大自然水流环境,循环净水,鱼缸结构如图2。尺寸是240mm170mm285mm,盛水容积大约8升。

3、软件设计

软件设计包括多传感器数据融合与执行器协同系统、本地监控系统和物联网远程监控系统,其中RA6M4软件架构如下。

6ae2ddd4-18a8-11ed-ba43-dac502259ad0.png

本项目软件架构主要采用上图所示的三个线程完成,其中:

CMD_Theard线程:负责完成传感器数据和执行器数据采集矫正;

LM_Theard线程:负责系统中传感器数据和执行器数据采集,通过拼接自定义串口协议,采用Uart串口通讯实现上下位机的联动;

Onenet_Theard线程:负责系统中传感器数据和执行器数据采集,通过esp8266上报到Onenet平台,以及云端数据下发解析执行等功能。

3.1 多传感器数据融合与执行器协同系统

其中多传感器首先采用卡尔曼滤波得到智能鱼缸的水体温度、水面气压、光照强度数据,将鱼缸的水体温度和水面气压进行模糊逻辑推理,模糊控制水泵的工作状态。

3.1.1 均值滤波

系统获取的传感器数据通常不能够直接供应用使用(存在噪声干扰:低频噪声或高频噪声),一般通过一种或者多种滤波算法结合,对原始数据进行滤波处理,在保证滤波后数据实时性要求的前提下,获取相对稳定无噪声的数据用于实际的应用系统。

6af94f60-18a8-11ed-ba43-dac502259ad0.png

平均滤波,取一定数量的原始数据,进行累加后取平均,从而获取较稳定的输出数据,主要滤除原始数据中的高频噪声。为了减少电源供电扰动主动放弃第一次采样,累加后续5次数据平均。

3.1.2 模糊控制

模糊控制结构如图3所示, 以鱼缸环境传感器数据处理的结果作为输入值, 一般包括:大气压强、温度、湿度、光照强度等;模糊控制输出用于执行器, 如水泵、加热设备、UV紫外线灯等。

6b2df06c-18a8-11ed-ba43-dac502259ad0.png

图 3 模糊控制结构

由于多输出的模糊控制算法过于复杂, 因此可利用模糊控制器的解耦特性, 将模糊控制系统分解为多个单输出的子系统,系统模糊控制如表1所示。例如可根据温度和气压控制水泵的打开时间, 本文将以此为例设计模糊控制器。

表 1 系统模糊控制

6b5f350a-18a8-11ed-ba43-dac502259ad0.png

输入主参输入副参输出结果

缸外温度气压水泵工作时间

缸内温度光照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所示:

6b71ff50-18a8-11ed-ba43-dac502259ad0.png

图 4 温度的范围域和隶属度函数曲线

根据前期调查,一般春季武汉市的气压为100000pa~101000pa, 定义输入量气压的基本论域为[100000, 101000]。定义5个模糊子集 (NB、NS、ZO、PS、PB) 和高斯型隶属度函数, 其中σ取值为125, NB、NS、ZO、PS、PB隶属度函数中均值x取值分别为100000、100250、100500、100750、101000。因此气压的范围域和隶属度函数曲线如图5所示:

6ba4a284-18a8-11ed-ba43-dac502259ad0.png

图 5 气压的范围域和隶属度函数曲线

水循环的每次水泵开启时间一般为0~20分钟, 定义输出量水循环时间基本论域为[0, 20]。分为5个模糊子集:关闭(NB)稍短(NS)中等(ZO)稍长(PS)长(PB),定义三角型隶属度函数,因此水循环时间的范围域和隶属度函数曲线如图6所示

6bced6b2-18a8-11ed-ba43-dac502259ad0.png

图 6 水循环时间的范围域和隶属度函数曲线

采用“if Temp and Pres then Motor”形式的模糊推理方法, 其中Temp、Temp为输入模糊子集, Motor为输出模糊子集。根据实践调试经验得出表2所示模糊控制规则表, 又称模糊关系矩阵, 共25条控制规则:

表 2 模糊控制规则表

6becba56-18a8-11ed-ba43-dac502259ad0.png

系统采用Mamdani模糊推理法, 本设计采用重心法, 即取模糊隶属度函数曲线与坐标围成面积的重心作为最终输出值。

6c24a4ca-18a8-11ed-ba43-dac502259ad0.png

使用Matlab的Fuzzy Logic工具箱进行系统仿真, 观察系统输入输出。例如取温度Temp=10℃、气压Pres=100500pa, 则输出的水循环时间Motor=3.14min,给定输入经模糊规则推理输出如图7所示:

6c462b22-18a8-11ed-ba43-dac502259ad0.png

图 7 给定输入经模糊规则推理输出

系统仿真输出曲面如图8所示, 输出曲面总体光滑, 稳定可靠, 可将养殖环境参数控制在最佳值附近。

6c708462-18a8-11ed-ba43-dac502259ad0.png

图 8 系统仿真输出曲面

近似函数代替为:

6c982080-18a8-11ed-ba43-dac502259ad0.png

3.2 本地监控系统

用户可以实时本地观察鱼缸状态,OLED显示器会事件型滚动屏幕,休眠状态是屏幕熄屏,因此休眠时间将远大于滚动显示时间以达到节能效果。OLED显示器滚动屏幕时将采集的传感器数据、执行器状态数据和电池电压数据实时动态显示。本地端设计了直接控制方式,优先级为1级,根据当前鱼缸环境的实际情况,个性化调节鱼缸的水泵、光照等,实现智能鱼缸的精准控制。

3.3 物联网远程监控系统

本文的智能鱼缸系统接入onenet物联网云平台,以实现物联网远程控制。采用onenet库与接口函数,并通过手机 APP 或手机语音的方式来实现远程操作。利用公有云服务进行数据传输,进而对其进行远程操控,使鱼缸能够作为智能家居被用户使用。

4 系统测试

4.1 本地端测试

采用Uart0实现本地端串口通讯,串口通讯分为接收协议和发送协议,上位机采用Serial Studio,使用方法见:

【Renesas RA6M4开发板之Serial studio串口交互】]

https://oss-club.rt-thread.org/uploads/20220806/da39a3ee5e6b4b0d3255bfef95601890afd80709.png

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->helloRT-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_sampleuart2

*命令解释:命令第二个参数是要使用的串口设备名称,为空则使用默认的串口设备

*程序功能:通过串口uart2输出字符串"helloRT-Thread!",并通过串口uart2输入一串字符(不定长),再通过数据解析后,使用控制台显示有效数据。

*/

#include"uart.h"

#defineLED3_PINBSP_IO_PORT_01_PIN_06

#definebuzzer_PINBSP_IO_PORT_04_PIN_03//蜂鸣器定义

#defineSAMPLE_UART_NAME"uart0"

#defineDATA_CMD_END'
'/*结束位设置为
,即回车符*/

#defineONE_DATA_MAXLEN12/*不定长数据的最大长度*/

/*用于接收消息的信号量*/

staticstructrt_semaphorerx_sem;

staticrt_device_tserial;

/*接收数据回调函数*/

staticrt_err_tuart_rx_ind(rt_device_tdev,rt_size_tsize)

{

/*串口接收到数据后产生中断,调用此回调函数,然后发送接收信号量*/

if(size>0)

{

rt_sem_release(&rx_sem);

}

returnRT_EOK;

}

staticcharuart_sample_get_char(void)

{

charch;

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);

}

returnch;

}

/*数据解析线程*/

staticvoidcontrol_thread_entry(void)

{

charch;

chardata[ONE_DATA_MAXLEN];

staticchari=0;

unsignedchar*adc_value,*bmp_value;

while(1)

{

ch=uart_sample_get_char();

if(ch==DATA_CMD_END)

{

data[i++]='';

rt_kprintf("data=0x");//CMDuart7打印uart0接收16进制数

for(intvar=0;var< ONE_DATA_MAXLEN-1;++var){

rt_kprintf("%x",data[var]);

}

rt_kprintf("
");

rt_thread_mdelay(1);

if(data[0]==0x5a&&data[10]==0xa5){//校验头部和尾部

if(data[4]==0x00){//保持命令

rt_kprintf("Keepon
");

}

elseif(data[4]==0x01){//修改命令//操作LED灯亮

rt_kprintf("Action
");

rt_pin_write(LED3_PIN,data[5]);//蜂鸣器操作相反

pwm_action(data[2],data[3]);//灯和水泵

rt_pin_write(buzzer_PIN,data[1]);//蜂鸣器操作相反

}

elseif(data[4]==0x02){

rt_kprintf("Automatic
");

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("datainputIllegal!pleaseinput:5A0000000101000B0000A5
",data);

}

rt_device_write(serial,0,&data,sizeof(data));//uart0打印接收指令

for(intvar=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串口输出线程*/

voidserial_thread_entry(rt_uint8_ta,rt_uint8_tb)

{

unsignedchar*adc_value,gpio_value[2],*bmp_value,*dht_value,pwm_value[2];

charstr1[45];

charHeadByte[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,"*/
");

rt_device_write(serial,0,str1,sizeof(str1));

rt_thread_mdelay(500);

}

staticintuart_data_sample(intargc,char*argv[])

{

rt_err_tret=RT_EOK;

charuart_name[RT_NAME_MAX];

charstr[]="helloRT-Thread!
";

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%sfailed!
",uart_name);

returnRT_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_tcontrol_thread=rt_thread_create("control",(void(*)(void*parameter))control_thread_entry,RT_NULL,1024,30,10);

rt_thread_tcontrol_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;

}

returnret;

}

/*导出到msh命令列表中*/

//MSH_CMD_EXPORT(uart_data_sample,uartdevicesample);

INIT_APP_EXPORT(uart_data_sample);

uart.h



/*

*Copyright(c)2006-2021,RT-ThreadDevelopmentTeam

*

*SPDX-License-Identifier:Apache-2.0

*

*ChangeLogs:

*DateAuthorNotes

*2022-07-25Asusthefirstversion

*/

#ifndef_UART_H_

#define_UART_H_

#include"hal_data.h"

#include

#include

#include

#include

#include"pwmled.h"

#include"adc.h"

#include"bmp180_sample.h"

#include"dhtxx_sample.h"

//staticrt_err_tuart_rx_ind(rt_device_tdev,rt_size_tsize);

//staticcharuart_sample_get_char(void);

//staticvoidcontrol_thread_entry(void);

voidserial_thread_entry(rt_uint8_ta,rt_uint8_tb);

//staticintuart_data_sample(intargc,char*argv[]);

#endif/*SRC_UART_H_*/

16进制指令:

部分效果图:

水泵工作状态

4.2 情况说明:

由于本人从7月25号困在中高风险区,电脑和硬件28号到,并且在实验室是可以连接wifi,由于条件有限,我所处管控区没有wifi,设备连接手机热点是无法登入onenet,因此暂时还没试验完,后期会补充onenet平台。

4.3 附件

代码地址: (请点击文末阅读原文至原文获取)

5、结语

首先感谢瑞萨和RTT官方给了我们DIY爱好者提供第二次测评。【基于RT-Thread+RA6M4的智能鱼缸系统设计之鱼我所欲也】只是个人在业余时间中一个不太完整的构想,虽然当前市面上以及有非常多的同类产品,但是二次开发易用性和扩展度与之相形见绌。

RT-Thread作为国内嵌入式系统生态的领跑者,对产品的快速原型开发有很强的支持,至于产品的稳健性还需尔后完善。因此第一次测评开发板,这个开发过程让我映像深刻,社区问答基本在专业伙伴协助下可以解决90%,更多是需要自身对C++基本语法掌握使用得当(强烈建议完善相关适配C++语言文档,那么RT-Thread愈加强大和健壮)。

本文利用RA6M4开发板、ESP8266、onenet平台构建了智能鱼缸系统,并开发了多传感器数据融合与执行器协同系统,将鱼缸的水体温度和水面气压进行模糊逻辑推理,模糊控制水泵的工作状态,克服了传统鱼缸缺乏反馈环节和调节环节的缺陷。该系统可通过传感器获得水温、气压、光照强度和视频流等数据实时鱼缸并由显示器或物联网平台反馈给用户。该智能鱼缸系统的功能全面、成本低廉、操作简便,易于推广应用,可创造较大市场价值。

由于时间短、本人知识水平有限等因素,该系统的研究设计中还是存在一些不足之处。本系统为了完成远程控制的功能,使用了onenet平台来进行数据的传输与存储,该云平台为商业平台,本系统对于用户数据的私密性保护存在一定的缺陷,需耍进一步提高对传输数据的加密保护。

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 传感器
    +关注

    关注

    2550

    文章

    51014

    浏览量

    752993
  • 单片机
    +关注

    关注

    6034

    文章

    44552

    浏览量

    634464
  • 智能家居
    +关注

    关注

    1928

    文章

    9552

    浏览量

    184879
  • RT-Thread
    +关注

    关注

    31

    文章

    1285

    浏览量

    40069

原文标题:基于RT-Thread+RA6M4的智能鱼缸系统设计之鱼我所欲也

文章出处:【微信号:RTThread,微信公众号:RTThread物联网操作系统】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    [分享]传感器数据融合理论及应用

    本帖最后由 srxh 于 2015-12-7 23:19 编辑 讲传感器数据融合技术,可参考下,拓展我们的系统构架、优化
    发表于 12-07 22:52

    基于传感器数据融合智能机器人设计

      本系统所设计的机器人的主要任务是在未知环境下依靠传感器信息,运用D-S数据融合算法,提供与环境有关的关于
    发表于 11-01 15:08

    深度解析传感器信息融合技术

    ,而且也综合处理了其它信息源的数据来提高整个传感器系统智能化。传感器
    发表于 11-07 10:53

    传感器信息融合技术解析

    传感器相互协同操作的优势,而且也综合处理了其它信息源的数据来提高整个传感器系统智能化。
    发表于 11-07 11:06

    仿生四足机器人中传感器信息融合的应用有哪些

    传感器信息融合技术综合了概率统计、信号处理、人工智能、控制理论等多个学科的最新科研成果,为机器人精确、全面、实时地感知各种复杂的、动态的、不确定的未知环境提供了
    发表于 08-18 07:43

    基于GP的传感器数据融合诊断与恢复

    本论文主要是研究遗传编程( GP) 在传感器故障的数据融合诊断与恢复中的应用,即用一种全新的数据
    发表于 06-30 08:48 15次下载

    传感器数据融合系统

    介绍传感器数据融合的模型和基本方法及在智能传感器中的应用。中文还给出个
    发表于 07-06 09:20 31次下载

    传感器异步航迹融合算法与仿真

    针对分布式传感器数据融合系统,提出了一种
    发表于 08-07 09:47 12次下载

    一种改进的智能传感器数据融合方法

    本文提出了一种利用模糊集理论和证据理论的智能传感器数据融合方法,其主要思路为:结合智能
    发表于 12-14 16:51 24次下载

    基于模糊逻辑的传感器数据融合方法研究

    针对当前工业环境下温湿度采集和传感器数据融合的特点和需求,文章提出了一种基于模糊逻辑的
    发表于 12-26 11:48 9次下载

    一种改进的传感器加权融合算法

    一种改进的传感器加权融合算法  引言   传感器
    发表于 12-12 10:32 2235次阅读

    一种改进的传感器信息融合算法

    一种改进的传感器信息融合算法_夏菽兰
    发表于 01-03 15:24 0次下载

    基于传感器数据融合智能火灾监控系统设计_郭冰陶

    基于传感器数据融合智能火灾监控系统设计_郭冰陶
    发表于 01-30 23:17 4次下载

    一种异质传感器的异步量测融合算法验证

    本文从建立伪量测方程的角度,提出了一种异质传感器的异步量测融合算法,该算法是通过在融合中心建立伪量测方程使各
    发表于 04-30 14:25 1583次阅读
    <b class='flag-5'>一种</b>异质<b class='flag-5'>多</b><b class='flag-5'>传感器</b>的异步量测<b class='flag-5'>融合</b>算法验证

    一种稳健的传感器数据融合方法

    本文介绍了一种稳健的传感器数据融合方法。传感器
    发表于 07-31 16:17 1次下载