【智能草缸-哔哩哔哩】 https://b23.tv/Pxea9NK
很早之前就想要实现一个全自动控制的草缸,当时是19年刚研究生入学,正好在本科毕业的暑假时间,有在培训机构教学Micro bit的硬件编程,所以当时基于scrach 图形化编程,利用手头的Micro bit套件搭过一版的草缸自动控制系统,做了一个桌面微缸(缸体沐野微缸)。
之后也将这一套系统搬到了30方缸上,养水草也取得了很不错的效果
但是慢慢的,问题也暴露了出来,例如scrach编程的代码不是很利于维护,一些底层的功能没办法开发,一些模块还未能支持,microbit平台的成本太高不利于复刻,以及很少出现但是确实会有的代码跑飞了的问题(天知道是啥情况,突然一下子就整个卡住了,OLED屏幕不刷新了,平均两个月会碰到一次,可能是时序错误?)
因此,实现一套低成本,高拓展性,利于开发维护,并且能长时间稳定运行的自动控制系统的想法愈发强烈。本项目就此应运而生,在2022年春节期间,基本完成了整体的代码设计,(本人代码水平奇烂,且有差不多三年没碰代码了,各位大佬轻喷)并在之后完成了剩下的苦力活儿(捣鼓缸,捣鼓草)。目前基本上开缸完成,有心思来和大家分享一下我的整套想法,希望可以借此抛砖引玉,集思广益,望各位大佬多多提出意见。大家有能力的也可以复刻一下,只希望不要用于商业目的。
目前基本完成了各种草缸需要的功能,下文会详细介绍。之后的发展方向有以下几点:1.提高集成度,确定元器件并制作pcb,但是这会牺牲一定的拓展性;2.之后可能采用ESP32的mcu来进行联网,这样不仅仅可以记录草缸的数据,还能省去RTC模块(直接联网获取时间);3.有余力的话整个手机控制界面(这个估计很远了,水平有限);4.想办法整合一下电源接口,因为各模块供电电压不同,目前使用了15V,5V,36V的直流电压,以及220V交流电压,要是可以的话希望还能再缩减一下,最好可以集成多电压输出的隔离电源模块;5.目前的控制系统占最大体积的是继电器模块,不知有什么好的小体积的平替,不要和我说固态继电器,这玩意儿输出端只有两个口,我需要三口的输出,也就是要有个常闭口(保证鲁棒性);6.目前并没有上自动喂食,因为草缸基本养的灯鱼,食量很小,饲料也很小,需要精确控制粉料给的量,丝杆加步进电机可以做到这一点,之前自己也尝试做过,但是太丑了,做机械结构又不是我的强项,这个还是得用3D打印来比较合适。7.目前按键还没怎么整明白,就像在2.10节说的那样,希望能实现按一下暂停10分钟,按两下暂停20分钟,以此类推,这样方便之后加双氧水控藻(一般关过滤1小时),但是我代码一直实现不了,希望评论区有高人指点!
资料下载链接:
所有用到的库,以及主程序都在内,内附pdf说明文档,也就是本文余下的内容,建议看pdf,排版更加舒服一些。
基于Arduino的自动鱼缸控制系统-单片机文档类资源-CSDN下载
基于Arduino的草缸自动控制系统
作者 | 沉底的鱼。。 |
|
完成日期 | 2022年3月27日 |
摘 要
【摘要】
本文提出了一种水草缸的自动控制系统,旨在自动维持水草缸各项指标,以适应其中水草以及鱼只的生存所需。本系统目前已经实现了RTC实时时钟,模拟自然光,自动CO2添加,水温检测及基于时间的自动调温,水位监测及自动加水,正弦波造浪,电子除藻,喂食暂停水泵,OLED显示鱼缸各指标等功能。因鱼只较小也较少,喂食需要精确控制饲料的量,暂未实现自动喂食功能。经过一次在小鱼缸上的实验,确保了各个功能安全可靠,将系统用在了30*30*30的中型寝室鱼缸上。并且目前已经经过测试完全可以实现在寒假无人值守时的鱼缸的自动运行。
【关键词】草缸;自动控制;水草;鱼缸。
日常生活中,我们多少都爱装扮一下自己工作生活的环境,小盆栽或是小鱼缸除了美化我们的环境外也已然成为许多人自我调节以及心理舒压的妙招。其中草缸因其独特的创造性造景和生态气息是最受大众欢迎的一类。草缸即是以水草为主题的水族缸,一般以热带淡水为主,着重于水草造景,搭配小型鱼只以获得整体生态系统。大多数流行天然造景,通常为了保持草缸生态系统的长期稳定,需要特别注重草缸的灯照、肥料、二氧化碳含量、水质等,以及所有对水草生长条件的维护。
这些条件每一项都较为繁杂,若是全部依靠人工控制的话自然需要消耗大量的时间和精力去照看,若是遇上出差等长期在外的情况则更是无法亲自照料。为此我们设计了这一整体草缸控制系统,使其能够自动控制光照、温度等重要的参数,使得整个生态系统能够不受外界环境的干扰,尽可能的模仿最适合其生长的自然界的生存环境,同时也解放了原本需要照顾它的人力。拥有这样一个系统,能够使你轻松的享受美好生活,不必顾虑许多。
本次设计中,我们主要使用Arduino开发板结合各类传感器对草缸内的光照、温度、湿度、CO2浓度等参数进行较为精确的控制,并结合OLED显示屏对其内部的这些参数进行直观的显示,以对草缸进行良好的自动控制并创建与用户的人性化交互。
图 1草缸整体效果图
图 2 上版本基于microbit开发的控制系统的不同时期整体效果图
本系统拥有时钟基准,可以根据需要设置白昼时间(例如假设本系统设置为8点~18点为白天)。可以根据需要基于时间设置每个时刻的加热温度(白天和黑夜的温差有利于植物生长)。
在8点,白天开始,温度开始回升,灯光在8点这一小时内由0变化到255亮度等级。
风扇打开,将LED的热量带走,防止LED烧坏,增加了灯具的寿命。
CO2的电磁阀打开,通过气体细化器进入草缸溶于水中,供给给水草进行光合作用。
在18点,黑夜开始,温度开始下降,CO2电磁阀关闭。灯光在18点这一小时内由255变化到0亮度等级,在灯熄灭后,水泵关闭。
同时每隔一定时间就会检测空气温湿度,鱼缸水温水位,并在OLED屏幕上显示,鱼缸水温水位信息还会反馈,进行加热棒加温,水泵补水。
图 3 控制系统整体
图 4 开缸整体图2022.3.27
Arduino nano开发版引脚定义如下图 5,开发板拥有丰富的数字模拟接口资源,有6路ADC,有6路PWM波输出,同时集成了I2C总线接口。值得注意的是A4 A5口被用作I2C通信,数字口2,3可用作外部中断,同时默认的PWM波输出频率在大约1000赫兹左右。
图 5 nano 引脚图
2.2 RTC时钟基准
本实验中所用的时钟芯片为DS1307,是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.0V~5.5V。采用I2C总线与主控板进行通信以获取实时的时钟,拥有单独的供电,掉电时钟不会清0。在本系统中可以用串口通信辅助烧录的方式任意设置当前时间。
本系统只要烧录就会自动读取系统时间作为RTC初始时间。但也支持任意设定时间,只需要改变全局变量,并且在设置温度时需要将ide串口打开,设置波特率115200并且输入大写的S即可。
水温控制是一项很关键的功能,草缸内的动植物都需要适当的温度才能保证基本的生理活动。传统的加热棒,温控原理是利用双金属簧片的热胀冷缩原理来控制开关,大体能保证鱼缸在一恒定温度,但是显而易见,抗疲劳性低,可靠性低,离水立刻工作不正常。因而近年来电子温控加热棒迅速崛起,但是售价较高,很多人依旧会选择便宜的前者。但是这两种加热棒都只能设置一个固定温度,不能做到如自然环境中的白天黑夜有一定温差。同时,面对有时候比较反常的天气气温大起大落,也需要制冷风扇对鱼缸进行适当的降温,因此有一套能进行升温与降温的水温自动控制系统很有必要。
另外模拟自然温度对动物植物都有很多好处,可以促进很多鱼类的发情繁殖;可以使水草在白天光合作用积累的有机物在夜晚呼吸作用消耗的更少,促进生长,开花。还可以使得红色水草发色更加艳丽。如果要将这一切变得可控,根据时间基准随意设置对应温度,那么水温信息的采集和反馈就是必要的。
水温信息的采集原理详见附录A,在这里就不再详细赘述。本项目使用到了2路的NTC温度探头,这2路温度探头都可以单独采样当前环境温度,并且可以将这2路的数据放在一起进行分析使得最后获得的温度数据具有更高的鲁棒性,在系统设计上排除了许多煮鱼或者冻鱼的可能性。
在代码设计中temp 1即为第一路温度传感器收集到的温度,temp 2即为第2度温度传感器收集到的温度,diffTEMP即为差分温度,是将2路传感器采集的信号做差取得的一个更加精确的温度数,在理论上可以达到小数点后有效位数为2位的温度数据十分的精确。
水温信息采集代码中设计了4种报错:第一种报错为温度探头1报错,这可能是由于温度探头1探头松动或者是连接线松动导致的报错;第2种报错为温度探头2报错,这可能是由于温度探头2探头松动或者是连接线松动导致的报错;第3种报错为温度探头12报错,这可能是由于2个探头都松动或者2个探头的连接线都松动导致的报错;第4种报错为温度差过大报错,这是由于2个温度探头读取到的温度数据差别过大可能是由于某个温度探头脱离了水面,使得一个温度探头测的是水温一个温度探头测的是室温导致的报错。这4种报错都有方法可以修正到正确的温度同时报错会激发Error指示程序。
本项目中设置了白天的开始和结束时间,并且设置了白天和晚上的温度。实际上水温信息的设置就是利用这四个变量实现的一个平滑过渡的温度设置。具体方案为,设置白天的中间时刻为最高水温,即为白天的温度;入夜的中间时刻为最低水温,即为夜晚的温度;其他时刻的水温做线性变化,呈现三角波的形式。这样可以最大限度地保证水温均匀变化并且模拟自然环境,且可以人为地创造温差。当前设定温度为全局变量SetNowTemp,每十分钟变化一次。
本系统可以分别设置白天与夜间的水温,可以同时使用加热棒和降温风扇来控制水温在不同时间段达到设定的值。
采用一路继电器控制一定功率的加热棒的开合,并非功率控制。采用1路继电器控制一定功率的风扇的开合(若采用功率控制会出现一定问题详见附录B)。利用继电器的吸合断开来控制温度。
若仅仅简单地考虑测量温度高于设定温度时断开,测量温度低于设定温度时吸合,则会在水温达到设定温度附近时频繁的吸合断开,极大的降低继电器寿命,继电器频繁吸合断开也会产生噪音。
解决方案是采用类似施密特触发器的方式,设置了一定的回差温度,具体工作方式如图 6所示
图 6 具有回差温度的温度信息反馈
以加热为例设置白天加热温度为25度,回差温度为0.3度(回差温度可任意设置),现在水温为20摄氏度。工作模式便是打开加热棒开始加温直到水温变为25.3度,停止加温,直到水温缓慢变为24.7度,再次开启加温直到水温到25.3度停止加温,如此进行一个循环。
但是要同时实现升温降温的话就会出现问题,当打开加热棒开始加温直到水温变为25.3度时刻,风扇也会开始工作,因此改为工作模式便是打开加热棒开始加温直到水温变为25.3度,停止加温,直到水温缓慢变为24.9度,停止加温,直到水温自然变化到25.3度开启风扇,或者降温到24.7度再开启加温。
设置的白天以及晚上基准温度会实时显示在屏幕上,当加热或是降温开始工作时在OLED显示屏上也会显示工作状态。
在夏天最热的时候,当风扇已经无力支持降温时(单风扇大约降温3度),就要采用半导体制冷方案,如图 7,采用两片优质12706制冷片,以及两个AMD纯铜散热器(一定要买底部面积是4*4cm的电脑散热器),实测可以搭配风扇,在室温29.1度的情况下,将30方缸水温降到21.9度,如图 8所示。
图 7 半导体制冷方案
图 8 实际制冷效果
本系统最好搭配空气温度采集这样的话当出现错误情况4的时候就可以有一个基准来判断是哪个探头暴露在空气中因此改用另一个温度探头的信号。在之前的项目中使用过DHT11模块该模块可以同时采集空气的温湿度十分的好用。本次设计没有安上,注意代码错误4时是直接和25度拿来当空气温度,大家有兴趣可以加装。但是个人觉得,如果不是玩雨林缸,不是很有必要。
采用大功率MOS管压控电流源来达到模拟自然光的目的,完成的功能为在白天开始的那一个小时内,灯的亮度从0变化到255亮度等级,之后保持恒定,在夜晚开始的那一个小时内,灯的亮度从255变化到0亮度等级,之后恒定。
图 9 大功率MOS管开关驱动模块
采用双MOS并联输出,内阻低电流大,满足了LED驱动的需求,通过改变MOS管的栅极电压来控制漏级电流从而达到控制灯亮度的目的。值得一提的是电源必须采用电压源,不然静态工作点不合适,MOS管并未工作在饱和区,会发热严重。同时使用这个模块的好处就是可以单独控制灯的供电,如果使用4路的mos管控制那么必须这4路用电器的供电电压是一致的,我采用的是50瓦的AT3灯珠,需要用30伏的电压源单独供电,因此我采用了这个模块。
2.5.2 LED风冷散热
为了延长LED寿命,减少光衰,良好的散热是必要的,本系统采用了一个废弃电脑的CPU散热。因此在LED工作的白昼时间打开风扇,用以散热,实际上发现12v的风扇用5v供电就完全可以压住灯的热量,还比较静音。使用一路继电器就可以简单地完成这项功能。
图 10 灯具及散热器
电子除藻器是利用电解水的副产物,尤其是游离态的自由基来杀灭藻类的孢子和各种病原菌的装置。核心就是电解水,需要找到惰性电极以及合适的电压才能产生细密的电解水气泡均匀分散到鱼缸内。本系统采用镍铬铁合金作为电极,利用pwm波功率控制,基本上预防了藻类和病原体的爆发。
电子除藻器采用1路功率控制,工作间隔时间可调可以设置为每X分钟工作1分钟,工作功率可调可以在白天和夜里分别设置它的功率。
图 11 电子除藻电解电极
图 12 浮球开关
简单直接的控制方案是采用如图 12的浮球开关,内部有干簧管,可以实现随着水位变化而通断,本项目最后采用了这种更加可靠而且简单的方案。
因此监测水位可以使用一路GPIO口读取传感器数字量简单完成。
后续我了解到可以利用电容变化检测水位变化,这就是淘宝卖的非接触式水位计的原理,这个也很好用,我手头有一个数字式的触摸传感器模块,测试过后发现可行,但是还是建议大家使用模拟的模块,自己来处理数据,因为我发现我手头的数字式的触摸传感器模块不够灵敏,可能是因为电容变化的量比较小导致的。
本项目并不打算将自动补水系统的开启与关闭用继电器完成而是简单地将此开关与水泵串联接到12伏电源上。因为这个开关本身就是一个闭环的控制系统因此单片机可以读取水泵的工作状态而不需要控制水泵的工作状态,这样的话即使单片机本身出现问题例如供电断开,也不影响自动补水功能的实现。
更好的做法是把自动补水系统连在继电器的常通端口上,只有检测到水位异常才会主动断开使之停止工作,这样的设计更加鲁棒。
采用一路继电器控制的隔膜泵吸水,无需潜入水中或者安装止逆阀。当检测水位低于阈值时工作,直到浮球开关重新断开为止。
图 13 隔膜泵
2.8 CO2添加
利用自制的CO2发生装置利用小苏打和柠檬酸反应生成CO2。气体发生装置如下
图 14气体发生装置
采用一路继电器控制的直流微型常闭式电磁气阀。在白天时间打开,在夜晚时间关闭,目前加气的气量并不能实现自动控制,仍需手动调节。同时在使用过程中发现二氧化碳极易溶于水,因此在关闭气体阀的时候水会通过管子逆流而上因此设置为每一个小时的第一分钟打开电子阀平衡内外气压防止水流随管子逆流而上。
图 15 直流微型常闭式电磁气阀、止逆阀、CO2细化头
以上是之前的co2方案,现在换上了钢瓶了,钢瓶出气气压很稳定,真香。控制钢瓶电磁阀即可。
在海缸中经常会用到造浪功能,利用水泵产生不规律的水流使得营养物质以及碎屑均匀地送到鱼缸的各个角落。本系统中集成了正弦波造浪功能,指的是系统造浪强度随时间的变化是一个正弦波图形。本系统有3个可以自己设置的变量:最大正弦波强度;正弦波周期;以及白天和晚上造浪的强度差。使用1路PWM波控制功率输出。
喂食按钮的功能非常的朴素就是有一个按钮按下以后会让鱼缸水泵停止工作一段时间,停止工作的一段时间可以自行设置,精确到秒。
利用1路继电器控制水泵平时将水泵连接在继电器的常闭端,因此即使单片机没有正常供电,水泵也可以正常工作。在喂食按钮被按下后利用继电器将水泵电路断开一定时间以后再将水泵电路接回。
后续希望做出的功能,按一下暂停10分钟,按两下暂停20分钟,以此类推,这样方便之后加双氧水控藻(一般关过滤1小时),但是我代码一直实现不了,希望评论区有高人指点!
2.11 OLED屏幕显示
显示采用了I2C通信的0.96英寸的OLED模块,因为内容较多,采用滚动显示各项数据,每三秒滚动一次。如下图所示,各项参数意义如下:
图 16 显示页面1
图16 显示页面1中,第一排显示的为日期和时间,Dayime为白天时间;lightlevel为当前亮度等级;algae_remove维电子除藻器功率等级。
图 17 显示页面2
图17 显示页面2中,water为当前水体温度;T为设定的白天和晚上的最高,最低温度;now为目前应该加热或降温达到的温度;heat和cool为加热制冷指示符,0是没开启,1是开启。如果有温度报错会在最后1排显示报错的具体内容。
图 18 显示页面3
图18 显示页面3中CO2 Time指的是二氧化碳开启的时间,后面会显示open或者Close指的是目前二氧化碳阀门的开启状态,SinWavelevel指的是目前正弦波造浪的强度等级,feedTime指的是喂食按钮按下后水泵关停的时间后面的open或closed指的是水泵的状态。
本自动控制系统有一定代码量,为了程序的结构清晰,大量采用函数
总体代码见附录
本文设计的草缸自动控制系统基本达到预期目标,已经稳定运行一年多表现良好,待测试完成可以考虑再添加功能,或者考虑大规模的例如鱼房整体的自动化控制,需要独立控制多口鱼缸,届时可能会使用编译码器,来节省IO口。兴趣是最好的老师,结合自身兴趣和所学专业,往往事半功倍。
1.提高集成度,确定元器件并制作pcb,但是这会牺牲一定的拓展性;
2.之后可能采用ESP32的mcu来进行联网,这样不仅仅可以记录草缸的数据,还能省去RTC模块(直接联网获取时间);
3.有余力的话整个手机控制界面(这个估计很远了,水平有限);
4.想办法整合一下电源接口,因为各模块供电电压不同,目前使用了15V,5V,36V的直流电压,以及220V交流电压,要是可以的话希望还能再缩减一下,最好可以集成多电压输出的隔离电源模块;
5.目前的控制系统占最大体积的是继电器模块,不知有什么好的小体积的平替,不要和我说固态继电器,这玩意儿输出端只有两个口,我需要三口的输出,也就是要有个常闭口(保证鲁棒性);
6.目前并没有上自动喂食,因为草缸基本养的灯鱼,食量很小,饲料也很小,需要精确控制粉料给的量,丝杆加步进电机可以做到这一点,之前自己也尝试做过,但是太丑了,做机械结构又不是我的强项,这个还是得用3D打印来比较合适。
7.目前按键还没怎么整明白,就像在2.10节说的那样,希望能实现按一下暂停10分钟,按两下暂停20分钟,以此类推,这样方便之后加双氧水控藻(一般关过滤1小时),但是我代码一直实现不了,希望评论区有高人指点!
附录A 水温采集原理
以下原理说明是在之前为另一个项目所撰写当时的项目是3.3伏系统,本项目的电源电压是5伏,除了电源电压不同之外其他原理都相同。
图 19水温传感器
采用图 19水温传感器,NTC 10K热敏电阻,在室温25℃时电阻值为10K欧姆,该热敏电阻温度与电阻值的关系由厂家提供,如图 20所示。
图 20 热敏电阻温度与电阻值的关系图
可以看到有明显的非线性,因此试图用线性拟合是极其不准确的,因此我们要找到消除非线性的方法,利用电阻来消除传感器的非线性就是常用的手段,结构如图 21。
图 21 单电阻-单热敏电阻的采样电路
可以得到在A点接入ADC,得到的读数为
![]() | (1) |
图 22温度与ADC采样理论值与线性拟合值关系
可以看到线性度显著提升,但是输入信号动态范围比较小只有约0.4v的动态范围,利用率不足40%,AD转换的精度较低。由于本实验中利用的是10位ADC转换器,故AD转换的相对分辨率可达0.0977%,即在满量程为3.3V时,分辨率可达3.223mV/LSB。在本例中,整体的数据精度可认为是ADC电压转化精度以及ADC温度转化精度两部分之和。可认为ADC电压转换的理论精度用其量化误差来表示即,量化单位为时,最大量化误差为
,理论精度达0.04%。
而在ADC温度转化过程中,利用最小二乘法,进行线性拟合,最后得到的最小的离差的平方和计算公式如下
![]() | (2) |
计算得出离差的平方和结果为141.28。
这样的结构简单,稳定,提高了线性度,但是ADC的动态范围太小,在实际在使用过程中温度精度约在0.2度,可能是由于NTC温敏电阻固有的5%误差导致,以及在使用过程中鱼缸水位会下降若NTC温敏电阻探头高于水面会造成测温一直不准,加热棒持续工作,导致“煮鱼”,为了解决这一系列问题, 提出了下面的新的结构。
图 23 双电阻-双热敏电阻的采样电路
利用了两路采样电路的类电桥结构,但是电阻和热敏电阻位置相反。在A,B点接入ADC,得到的读数差值为
![]() | (3) |
可以看到在A、B点的读数之和为在
,
时,读数之和为1,对应ADC采样值和为1024,这就提供了一个校验的简单方式,如果出现有任意一个温度探头脱离水面,或者线路接触不良等问题时,
,对应的ADC采样值之和就会与1024偏差很远就可以判断电路工作异常,进而进行报警以及利用空气温度来判断哪个温度探头脱离水面,进而采用另一个温敏电阻,利用单电阻采样电路来计算温度。这样大大降低了“煮鱼”的概率。
图 24 温度与ADC采样差值采样理论值与线性拟合值关系
计算得出离差的平方和结果为565.12,线性度并未再度提升,但是输入动态范围提升了一倍。
计算温度的算法如下,先用厂家给出的热敏电阻整数温度时电阻值计算得到整数温度的ADC理论采样值的差值,用列表将每个整数温度下的ADC理论采样值的差值保存下来,每次采样得到ADC实际采样值的差值后,与列表中的实际值比较,确定整数温度区间之后,再在这一度的范围内线性拟合,得到小数点后一位的值。
例如某次采样得到ADC实际采样值的差值为55,与列表中的值对比发现22℃时的理论采样值的差值为68, 23℃时的理论采样值的差值为45,因此确定了温度范围在22~23℃之间,再线性拟合(55-45)/(68-45)=0.43就得到了小数部分,保留一位小数,对应的温度即为22.4℃。
附录B 快速PWM信号
如果有细心的小伙伴就会发现为什么你的制冷风扇不用功率控制?这是由单片机的本身的硬件限制导致的。Arduino的pwm波默认的频率在1000赫兹左右用这样的信号控制风扇的电源电压会让风扇产生啸叫,直观感受就是非常的吵。利用比较高的频率如30K赫兹或者比较低的频率如30赫兹的PWM波来控制风扇就不会产生这样的问题。因此我们需要改变PWM的频率才能解决这个问题,在代码中一定有细心的小伙伴们发现了我有一个init_fastPWM()函数并未使用,这个函数就是用来调节PWM的频率的它可以调节数字口3的PWM波频率,但是它的代价就是11口就被占用不能使用了我个人认为这样的设计比较鸡肋。而且风扇作为制冷本身功率就比较的弱,没有必要再去调节它的功率,有需要的小伙伴可以自己尝试着去使用一下。