家园防线 | 斐乐的手敲大型庭院物联网灌溉系统(持续更新)

#Why IoT?

我住在乡下,除却鸟语花香之外,就是有许多需要手工完成的农活。
我是挺喜欢田园生活的,但是有些时候如果要出去玩,家里的菜地、院子就会没有人管,很不自由,如果请邻居来浇水,一次2、30块一年也是一大笔钱。加上我家树种的比较密集,完成一次充分的浇水工作可能需要两个小时以上。
代号家园防线,名字源自于国际知名光头杰森斯坦森的电影《HomeFront》,为啥取这个名字呢?因为工作对象是家园,英文单词也是以我的简拼HF开头🤡


接下来开始讲故事

如果你想看我的具体代码和实现细节,请跳过这一部分

在暑假的这段时间里我本来想写一个关于大学的回忆录的,但是后来由于时间匆忙写了一些些就没写了,以后还是要补上。如果你想粗略了解大学的时候干了什么事情的话,可以看看这个微平《浙警院封面人物:斐乐仔你的生活由你定义》
为啥要说到这个微平呢,主要是以为在这个微平里面的第一张合照,那是董教授给我们上的《物联网概论》这门课,虽然是系部为了给我们补学分而开设的课程,但是我毫无偏袒的认为:这绝对是ZJPC最有水平、最有价值、最有趣的课程之一。(图为ESP32和两块古早设备Arduino uno)

请添加图片描述

上课不久老师发给我们人手一块ESP8266,让我们用Blink示例代码让他闪烁,过程很简单,插线、导入文件、烧录,简简单单几步,ESP8266上面自带的LED就闪烁了起来。别看小小的一个LED灯,在那个时候我差不多是这样的:
在这里插入图片描述
一瞬间,很多东西都jb说的通了,比如说电风扇怎么做,自动开关的插线板怎么做,空调怎么做,董大师,我悟了。我要给家里开发一个自动化的物联网灌溉系统。
后来的课程具体我就不做赘述了,这门课程是真的好,而且也很感谢我的队友小民哥,小民哥吃苦耐劳,在结课作业里负责了论文和PPT的制作,我只要负责写代码和上台讲解就好了,选择一个好队友真的很重要。


现在开始具体制作

1.选定功能

我们的功能主要有以下几个:
洗车、手动自动模式切换、土壤湿度检测(保证闭环)、设备工作状态提示、重启设备等功能。
大致思路有两个:一是自动控制,二是物联网,人可以轻松查看以及控制
我们可以从我后续的手机APP上管窥一下具体的功能。(手机快没电了giao,图片为未连接系统时的app。)手机app

2.水路设计、设备挑选

1.我把院子切分成为了五个部分(即五个水路),分别进行浇水灌溉
在这里插入图片描述
五个部分分别的树木负责数为50、30+T、40、40、T
(T指的是灌木丛和低矮植被、蔬菜、果树等,需要另外计算水力消耗)
2.水路搭建
水路大概就像是这样:首先过滤器先把水泵抽上来的池塘杂质给过滤掉(保证我的滴灌不会被堵住)在这里插入图片描述

然后按照划分区域一片一片地进行浇水:通过控制器配合电磁阀实现,这样设计的原因是为了降低水泵在流量动力方面的要求事实上后来发现还是得把水泵给换了。
在这里插入图片描述
浇水的部分分为主通水管和毛细管,主管送水,毛细管负责浇水的最后一公里,给喷水的小红帽供水。(这里是后来运行时拍的,把头向右弯可以看到原图)
在这里插入图片描述
管道铺设这个活真的是有点累,详情可以咨询我衣服上的盐在这里插入图片描述
3.我采用的水泵是一台古早的自吸式水泵,已经服役七八年了,做这个系统真的和考古一样。
在这里插入图片描述
说到这台水泵,别看他破破烂烂,经过我的计算,现在它的流量仍然有1200L/h,七八年过去了只下降了300L(额定1500),十分坚挺,拆下来装在小船上说不定以也可以继续驱动,也许这就是传说中的亦可赛艇吧。
但是虽然是1200,我还是忽略了一个问题----我选用的16mm滴灌管最大流量是1000,否则会吃不消。我向来都是搏一搏类型的,认为1200也无所谓。
结果是这样的:我设计的这个系统不是传统意义上的水路传输,而是在传输的过程中不断地把水播撒到外面:类似一个y=1/x(第一象限),水压在不断地减小。。。
在这里插入图片描述
In fact,我是在水路的第一次运行后才发现这个问题,越到后面小红帽的出水越小。。。在和家里人汇报了这个事情之后,我决定买一个新的水泵,我就喜欢大大大,流量也得大,水也多。终于有机会淘汰这个伊拉克老兵了。
4.控制器选择了外星人技术ESP32,不错不错,味道好极了
在这里插入图片描述

3.程序设计

1.物联网平台我选择了Tlink,采用TCP协议进行交互,我没有用移动的物联网平台是因为他们的网页卡的一,没有用MQTT协议是因为前期我看不懂,后期看懂了发现没必要(我要控制的只有一个设备,只需“物联网”,而无需“万物互联”)
2.我用的是Arduino语言,众所周知,Arduino是这样的

void setup()
{
  Serial.begin(9600);
  ......
}

void loop() {  
.....
}

但是想要实现定时任务,就需要做到让定时凌驾于loop()之上,做到循环的时候不改变时间设置的既有效果,更重要的是,要保证我与物联网平台的交互不断,我的设备要有实时的信息发送出去。
所以嘿嘿嘿,我创新了一波,把整个创新切分为了标志层、执行层和交互层,所有的工作都接线清晰,而不会导致loop()执行的时候的混乱不堪。在loop的末尾是很清晰的执行+传递信号,KISS原则,简单而有效
在loop的末尾是很清晰的执行+传递信号
至于最下方的标注不用delay(),用mills()的原因大家都懂的,防阻塞。
3.一个跨越loop()计时的方法(主要就是涉及flag们的设计和临界状态的判断)

if (hand_watering_flag == 1 || (auto_watering_flag == 1 && time2go())) //fixme:time2go可能需要再大一点;1.算好delay和time2go;2.做一个每天几次,或者上下午几次的东西
    {
        if (pump_working_flag == 1)
        {
            if (work_times > 1)
            {
                for (i = 0; i < length(working_solenoid_valve); i++)
                {
                    if ((4 - work_times) == i) //次数为5,电磁阀2、3工作;为4,1,3工作;以此类推. ps:index需要减一
                    {
                        working_solenoid_valve[i] = 0;
                    }
                    else
                    {
                        working_solenoid_valve[i] = 1;
                    }
                }
                // Serial.println(work_times);
                // Serial.println('else分界线');
            }
            else if (work_times == 1)
            {
                // Serial.println('1');
                for (i = 0; i < length(working_solenoid_valve); i++)
                {
                    // Serial.println("1");

                    working_solenoid_valve[i] = 0;
                }
                solenoid_valve4 = 1;
            }
            // mid_time = time_flag - mid_time; //fixme
            Serial.println(mid_time);
            if (time_flag > delaytime) //1秒 = 1000 毫秒
            {
                work_times = work_times - 1;
            }
            if (work_times == -1)
            {
                for (i = 0; i < length(working_solenoid_valve); i++)
                {
                    working_solenoid_valve[i] = 0;
                }
                solenoid_valve4 = 0;
                pump_working_flag = 0;
                hand_watering_flag = 0;
                // Serial.println('1');
                time_flag = 0;
                // Serial.println('1');
                mid_time = 0;
                // Serial.println('1');
            }
        }
    }

4.最后一个问题就是写代码的时候要仔细,总会出现一些奇奇怪怪的问题,有一次居然还提示我寄存器爆炸了。。无语子,看图找错误
在这里插入图片描述
5.由于我的代码实在是有点多(500行不到,说多不多),这里写不大下,我会在github上面发布,大家可以去看看。 Click here for Filagiao’s Github


持续更新,未完待续。后续还会介绍RS485和TTL电路传感器之间的交互等内容。。。加油,冯诺依曼保佑。

在这里插入图片描述
Enjoy your coding!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值