#Why IoT?
我住在乡下,除却鸟语花香 之外,就是有许多需要手工完成的农活。 我是挺喜欢田园生活的,但是有些时候如果要出去玩,家里的菜地、院子就会没有人管,很不自由,如果请邻居来浇水,一次2、30块一年也是一大笔钱。加上我家树种的比较密集 ,完成一次充分的浇水工作可能需要两个小时以上。 代号家园防线,名字源自于国际知名光头杰森斯坦森的电影《HomeFront》,为啥取这个名字呢?因为工作对象是家园,英文单词也是以我的简拼HF开头 🤡
接下来开始讲故事
如果你想看我的具体代码和实现细节,请跳过这一部分
在暑假的这段时间里我本来想写一个关于大学的回忆录的,但是后来由于时间匆忙写了一些些就没写了,以后还是要补上。如果你想粗略了解大学的时候干了什么事情的话,可以看看这个微平《浙警院封面人物:斐乐仔你的生活由你定义》 为啥要说到这个微平呢,主要是以为在这个微平里面的第一张合照,那是董教授给我们上的《物联网概论》这门课,虽然是系部为了给我们补学分而开设的课程,但是我毫无偏袒的认为:这绝对是ZJPC最有水平、最有价值、最有趣的课程之一 。(图为ESP32和两块古早设备Arduino uno)
上课不久老师发给我们人手一块ESP8266,让我们用Blink示例代码让他闪烁,过程很简单,插线、导入文件、烧录,简简单单几步,ESP8266上面自带的LED就闪烁了起来。别看小小的一个LED灯,在那个时候我差不多是这样的: 一瞬间,很多东西都jb说的通了,比如说电风扇怎么做,自动开关的插线板怎么做,空调怎么做,董大师,我悟了 。我要给家里开发一个自动化的物联网灌溉系统。 后来的课程具体我就不做赘述了,这门课程是真的好,而且也很感谢我的队友小民哥,小民哥吃苦耐劳,在结课作业里负责了论文和PPT的制作,我只要负责写代码和上台讲解就好了,选择一个好队友真的很重要。
现在开始具体制作
1.选定功能
我们的功能主要有以下几个: 洗车、手动自动模式切换、土壤湿度检测(保证闭环)、设备工作状态提示、重启设备等功能。 大致思路有两个:一是自动控制,二是物联网,人可以轻松查看以及控制 我们可以从我后续的手机APP 上管窥一下具体的功能。(手机快没电了giao,图片为未连接系统时的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原则,简单而有效 。 至于最下方的标注不用delay(),用mills()的原因大家都懂的,防阻塞。 3.一个跨越loop()计时的方法(主要就是涉及flag们的设计和临界状态的判断)
if (hand_watering_flag == 1 || (auto_watering_flag == 1 && time2go()))
{
if (pump_working_flag == 1)
{
if (work_times > 1)
{
for (i = 0; i < length(working_solenoid_valve); i++)
{
if ((4 - work_times) == i)
{
working_solenoid_valve[i] = 0;
}
else
{
working_solenoid_valve[i] = 1;
}
}
}
else if (work_times == 1)
{
for (i = 0; i < length(working_solenoid_valve); i++)
{
working_solenoid_valve[i] = 0;
}
solenoid_valve4 = 1;
}
Serial.println(mid_time);
if (time_flag > delaytime)
{
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;
time_flag = 0;
mid_time = 0;
}
}
}
4.最后一个问题就是写代码的时候要仔细,总会出现一些奇奇怪怪的问题,有一次居然还提示我寄存器爆炸了。。无语子,看图找错误 5.由于我的代码实在是有点多(500行不到,说多不多),这里写不大下,我会在github上面发布,大家可以去看看。 Click here for Filagiao’s Github
持续更新,未完待续。后续还会介绍RS485和TTL电路传感器之间的交互等内容。。。加油,冯诺依曼保佑。
Enjoy your coding!
|