8393浏览
查看: 8393|回复: 12

Intel IoT 物联网大赛 - Zoo团队- 智能灌溉系统

[复制链接]
hi,Everybody,不好意思,来晚了,但是今天还没有过去不是?就当做一个睡前的故事看看吧。
我们这次组团参加了蘑菇云与Innospace还有intel一起举办的一场基于Edison开发板的物联网大赛,结局是没有得到奖,不过没有关系,还是很开心的,兔子(队长),MKK(孙坚,主力外形设计师和实施工程师,土木工程师还有机械电子工程师,还有杨栋,正觉,skip,金立彦,box,王工,我们的队伍阵营还是很强大的,就是大家第一天都不知道做什么好,大家商量了好久。。。直到第二天上午早饭后,我们决定做一个智能灌溉系统。
智能灌溉系统???WTF? 我从来没有种过花花草草,你让我做灌溉系统?农业系统?期初我的内心是纠结的,是无奈的,可惜我看到那些SEEED套件的传感器后,觉得能做花花草草的灌溉系统已经是很奢侈的事情了。幸亏有DFrobot的套件撑场面。。。好吧,这不是广告。
无意中看了一眼时钟,23:34了,距离今天过去还有二十几分钟了,还是进入主题吧。
智能灌溉系统主要是想解决有的同志在家养花养草,忘记浇水导致花儿就这么早谢了。。;P。又TM跑题了,言归正传!
这个灌溉系统分为这么几个部分:
1. 数据采集传感器:  土壤干湿度传感器(DF套件里有)
2. 继电器(MKK的拿手绝活) 继电器,我们称之为Relay,就是允许通过低电平的电平信号来控制的开关模块,例如,你想用Arduino控制家里的点灯,arduino的引脚是低电平的,而家里是220V的致死电压,那么用继电器就很安全了。。。
3. 不知道怎么称呼:水泵? 蠕动泵?离心泵? 反正是一个马达带着转,能够泵水的装置,建议用养鱼的潜水泵,更加静音,这个泵跑起来和你的小赛车的噪音差不多。。。
4. 最后的大杀(keng)器(die)出现了! 就是Edison 开发板。说实话,很多人说edison是个坑爹货,说Yocto linux发行版各种坑,我觉得,其实也不是那么坑,其实基于linux内核的发行版里面,Edison的这块板子还是很不错的,至少wifi的稳定性,还有系统本身的稳定性都还是可圈可点的,比起香蕉派(bananaPi)这个坑爹板来说,好了不知道多少倍了!
另外,我太喜欢Edison上面跑OpenCV了,速度稳定而暴力,各种稳定没得说,好吧,最后还是觉得我的树莓派更好!
5.一个盛水的饭盒。。。饭盒。。。饭盒。。。我的队友们,你TMD在逗我?这么牛逼的比赛你给我带两个乐扣乐扣盒子做产品????我也是醉了。。。当我看到乐扣盒子的时候,我就知道我们肯定败了。。。因为评委里面有个搞艺术的Rex啊!你们~~哎。。。。
6. 还有一个非常非常关键的部件: 就是DF的I/O扩展板,没有它,基本啥都做不了了,有了这块扩展板,接驳设备也就15秒。

是不是已经看不下去了?哈哈,干货在此!
我们的创意思路是: 土壤干湿度传感器在花盆里面感受湿度的变化,据MKK的不完全统计,这个值的变化区间是在0~3000之间发生变化,当0出现的时候,就是水漫金山了,许仙哥你今天湿了没有?当3000的时候,干燥的土壤就开始”要你命三千了“,然后不是说要上云端么?不上云端怎么体现物联网?联网?联网?
好的,联网传什么数据呢?
当然在颜值统治世界的今天,自拍图片才是王道。所以就有了如下的技术硬植入:
1. Smartnode 对接微信端控制(1小时速成) 网址:www.smartnode.io 你值得拥有。
2. 阿里云端的一个存储照片的地方,这里是我的个人博客的后台,也是用wordpress搭建的一个小站。存储照片的后端用python的tornado模块实现了图片上传。地址:www.yoyojacky.com:9002
3. OpenCV 拍照并通过Edison本地的第一个shell脚本上传代码到我的个人博客后台的一个storage目录,并通过html页面展示出来,就这么简单。
上一张调试过程中的图片:
Intel IoT 物联网大赛 - Zoo团队- 智能灌溉系统图1

这里在测试照片的效果。
Intel IoT 物联网大赛 - Zoo团队- 智能灌溉系统图2

然后,我们开放了源码:
Intel IoT 物联网大赛 - Zoo团队- 智能灌溉系统图3

代码虽然很多bug,但是相信你们可以改得更好。。。
Github地址: https://github.com/yoyojacky/Edisoniot
Intel IoT 物联网大赛 - Zoo团队- 智能灌溉系统图4
上面的内容为smartnode上面的拖拽连线图,很像mind+的那种方式,非常简单方便。推荐初学者用起来,很赞!
Intel IoT 物联网大赛 - Zoo团队- 智能灌溉系统图6
首先,你得有一盆不怕水的植物,这个是兔子不知道从哪里找来的不怕水的水草,因为无数测试,它早已湿透。。
Intel IoT 物联网大赛 - Zoo团队- 智能灌溉系统图7
结构非常简单,两个乐扣饭盒,一块压合板,然后几根螺丝钉,加上一个土壤传感器,一个离心泵,两根4mm水管,一个Edison开发板,一个DF I/O扩展板,接上电源,然后就可以进行浇花行动了。基本上,一般的小白喜欢看的就是我上面写的这些,大牛工程师们可能要看细节了。好吧,先展示一下我们队友给你们看看。然后上代码。
Intel IoT 物联网大赛 - Zoo团队- 智能灌溉系统图5
——++——————+++——+++——————+++————————+++——————————————+++——————————
代码开始:
C语言Opencv抓图代码:
[mw_shl_code=cpp,true]#include <stdio.h>
#include <iostream>
#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/video/background_segm.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/legacy/legacy.hpp"
#include "opencv2/video/tracking.hpp"
#include "opencv2/photo/photo.hpp"

using namespace std;

extern "C" void take_photo(char *str);
void take_photo(char *str)
{
    IplImage *frame = NULL;
    int num = 0;
    int key;
    CvCapture *input_camera = cvCaptureFromCAM(0);
    frame = cvQueryFrame(input_camera);
    while(frame != NULL)
    {
        num++;
/
        frame = cvQueryFrame(input_camera);
        if(num == 20)
        {
            cvSaveImage(str,frame);
            break;

        }
    }
    cvReleaseCapture(&input_camera);
}[/mw_shl_code]

+++++++++++++++++++++++++++++++++++
然后是main.c
[mw_shl_code=c,true]#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>

#include <mraa/gpio.h>

int sensor_state = 0;

void *take_photo_thread (void *args){
    for(;;){
        if(sensor_state >= 500 ){
            char str[25];
            sprintf(str,"%d.jpg",(int) time((time_t*)NULL));
            take_photo(str);
            sleep (1);
            char command[100];
            sprintf (command, "upload.sh %s", str);
            system (command);
        }
        sleep(1);
    }
}

int main(int argc, char** argv)
{
    mraa_gpio_context sensor_gpio = NULL;

    sensor_gpio = mraa_gpio_init(5);

    if (sensor_gpio == NULL) {
        fprintf(stdout, "Could not initilaize sensor_gpio\n");
        return 1;
    }

    mraa_gpio_dir(sensor_gpio, MRAA_GPIO_IN);

    pthread_t t;
    pthread_create(&t,NULL,take_photo_thread,NULL);

    for (;;) {
        if( sensor_state != mraa_gpio_read(sensor_gpio)) {
            sensor_state = !sensor_state;
            printf("%d\n",sensor_state);
            sleep(1);
        }
    }
   
    return 0;
}[/mw_shl_code]

代码非常简单,基本都是例程,大牛不要吐槽哈!下面是Makefile,随意取用。☺️
[mw_shl_code=c,true]GCC_MRAA_FLAG=-lmraa -lpthread
GXX_OPENCV_FLAG=-lopencv_core -lopencv_highgui -lopencv_video -lopencv_calib3d -lopencv_contrib -lopencv_stitching -lopencv_superres -lopencv_legacy -lopencv_nonfree -lopencv_videostab -lopencv_gpu -lopencv_photo -lopencv_flann -lopencv_features2d -lopencv_ml -lopencv_imgproc -lopencv_objdetect

build: main.o mycam.o
        gcc main.o mycam.o -lstdc++ $(GXX_OPENCV_FLAG) $(GCC_MRAA_FLAG) -o main

run: build
        ./main

main.o: main.c
        gcc -c $(GCC_MRAA_FLAG) main.c

mycam.o: mycam.cpp
        g++ -c $(GXX_OPENCV_FLAG) mycam.cpp
clean:
        -rm main *~ *.o *.png[/mw_shl_code]

往服务器上上传的代码:
[mw_shl_code=bash,true]
#!/bin/bash
for i in `ls *.png |xargs`
do
curl -sT $i http://www.yoyojacky.com:9001
sleep 1
if [ $? -eq 0 ];then
rm -rf $i
else
echo "upload failue."
fi
done[/mw_shl_code]

简单粗暴~~~哈哈
然后服务器端的配置,就要安装改centos的源,然后安装nginx,然后安装python 的pip,更新pip,然后安装python进程管理工具supervisor还有web框架tornado,tornado的东西可以问问夏力维,小伙子python还是很牛逼的。哈哈
另外,这里发放一个干货,就是陈昊兄弟在开放夜问的问题,如何在Edison上让程序开机自动运行。
这里说一下linux启动过程,以下内容来自:http://blog.chinaunix.net/uid-26495963-id-3066282.html ,chinaUnix,学习linux或者unix在这里没错。
启动第一步--加载BIOS
当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它。这是因为BIOS中包含了CPU的相关信息、设备启动顺序信息、硬盘信息、内存信息、时钟信息、PnP特性等等。在此之后,计算机心里就有谱了,知道应该去读取哪个硬件设备了。

启动第二步--读取MBR
众所周知,硬盘上第0磁道第一个扇区被称为MBR,也就是Master Boot Record,即主引导记录,它的大小是512字节,别看地方不大,可里面却存放了预启动信息、分区表信息。
系统找到BIOS所指定的硬盘的MBR后,就会将其复制到0×7c00地址所在的物理内存中。其实被复制到物理内存的内容就是Boot Loader,而具体到你的电脑,那就是lilo或者grub了。

启动第三步--Boot Loader
Boot Loader 就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核做好一切准备
Boot Loader有若干种,其中Grub、Lilo和spfdisk是常见的Loader。
我们以Grub为例来讲解吧,毕竟用lilo和spfdisk的人并不多。
系统读取内存中的grub配置信息(一般为menu.lst或grub.lst),并依照此配置信息来启动不同的操作系统。

启动第四步--加载内核
根据grub设定的内核映像所在路径,系统读取内存映像,并进行解压缩操作。此时,屏幕一般会输出“Uncompressing Linux”的提示。当解压缩内核完成后,屏幕输出“OK, booting the kernel”。
系统将解压后的内核放置在内存之中,并调用start_kernel()函数来启动一系列的初始化函数并初始化各种设备,完成Linux核心环境的建立。至此,Linux内核已经建立起来了,基于Linux的程序应该可以正常运行了。

启动第五步--用户层init依据inittab文件来设定运行等级
内核被加载后,第一个运行的程序便是/sbin/init,该文件会读取/etc/inittab文件,并依据此文件来进行初始化工作。
其实/etc/inittab文件最主要的作用就是设定Linux的运行等级,其设定形式是“:id:5:initdefault:”,这就表明Linux需要运行在等级5上。Linux的运行等级设定如下:
0:关机
1:单用户模式
2:无网络支持的多用户模式
3:有网络支持的多用户模式
4:保留,未使用
5:有网络支持有X-Window支持的多用户模式
6:重新引导系统,即重启
关于/etc/inittab文件的学问,其实还有很多

启动第六步--init进程执行rc.sysinit
在设定了运行等级后,Linux系统执行的第一个用户层文件就是/etc/rc.d/rc.sysinit脚本程序,它做的工作非常多,包括设定PATH、设定网络配置(/etc/sysconfig/network)、启动swap分区、设定/proc等等。如果你有兴趣,可以到/etc/rc.d中查看一下rc.sysinit文件,里面的脚本够你看几天的

启动第七步--启动内核模块
具体是依据/etc/modules.conf文件或/etc/modules.d目录下的文件来装载内核模块。

启动第八步--执行不同运行级别的脚本程序
根据运行级别的不同,系统会运行rc0.d到rc6.d中的相应的脚本程序,来完成相应的初始化工作和启动相应的服务。

启动第九步--执行/etc/rc.d/rc.local
你如果打开了此文件,里面有一句话,读过之后,你就会对此命令的作用一目了然:
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don’t
# want to do the full Sys V style init stuff.
rc.local就是在一切初始化工作后,Linux留给用户进行个性化的地方。你可以把你想设置和启动的东西放到这里。

启动第十步--执行/bin/login程序,进入登录状态
此时,系统已经进入到了等待用户输入username和password的时候了,你已经可以用自己的帐号登入系统了。:)
===
漫长的启动过程结束了,一切都清静了…
====================
好,轮到我来了,那么到这里,大家已经应该知道了kernel加载完成后,启动系统调用的第一个程序就是init,也就是为什么我们linux上关机可以用init 0, 重启可以用init 6
如果你用C写了一个二进制文件,或者用shell,python等脚本语言写了脚本,那么就放在/etc/init.d/目录下面,命名成你想要的名称即可,我的upload.sh 我可以放入/etc/init.d/upload
这里不用加后缀也可以,因为在linux环境下,后缀名称就是为了方便照顾windows用户的习惯,我们其实可以不用扩展名的。
这里注意,注意,注意一下,你们说的Edison的坑来了。
先前的edison 的yocto版本1.6 里面,在/etc 里没有init.d 文件夹,自己创建一个就好,用mkdir -p  /etc/init.d ,而最新的yocto 版本 1.6.1里面是含有 init.d 文件的,不知道的就找不到了吧?)
:Q
我的upload中的内容:
[mw_shl_code=bash,true]#!/bin/bash
for i in `ls *.png |xargs`
do
curl -sT $i http://www.yoyojacky.com:9001
sleep 1
if [ $? -eq 0 ];then
rm -rf $i
else
echo "upload failue."
fi
done[/mw_shl_code]
记住要赋予可执行的权限
chmod +x /etc/init.d/upload
在 /etc/init.d 文件夹下执行
update-rc.d upload defaults 95 (启动顺序95)
然后开机就会自动启动了。是不是非常简单?
然后要删除开机自动启动就执行:
update-rc.d   -f  upload   remove
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
好了,到此我的帖子也结束了,我是骑驴玩儿漂移,一个专注技术和开源硬件的胖纸,欢迎大家拍砖灌水!
有机会去蘑菇云分享树莓派的心得,谢谢大家!
感谢蘑菇云提供我这个机会在此絮叨我们的项目,也感谢我的团队伙伴们,没有因为我的技术low,代码烂而抛弃我,义无反顾的收留了我。
感谢CCTV,一直没有给我称为网红的机会,感谢@juice,@ash 以及所有创客朋友们给我带来的启发和激励~
:lol

个人技术博客: http://www.yoyojacky.com/
欢迎互粉哈!晚安~

yoyojacky  初级技匠
 楼主|

发表于 2016-11-26 00:58:28

@陈昊 兄弟,你看了么?最后要@你的。
回复

使用道具 举报

yoyojacky  初级技匠
 楼主|

发表于 2016-11-26 01:05:06

我擦~果然没有人,都去啪啪啪了么?~~~;P
回复

使用道具 举报

Ash  管理员

发表于 2016-11-28 18:20:53

yoyojacky 发表于 2016-11-26 01:05
我擦~果然没有人,都去啪啪啪了么?~~~

双手打字 以示清白
回复

使用道具 举报

yoyojacky  初级技匠
 楼主|

发表于 2016-11-29 12:56:34

Ash 发表于 2016-11-28 18:20
双手打字 以示清白

时间已经过去这么久了。。。
回复

使用道具 举报

yoyojacky  初级技匠
 楼主|

发表于 2016-11-29 12:56:57

看来这个项目没几个人看啊。:'(
回复

使用道具 举报

吹口琴的钢铁侠  初级技匠

发表于 2016-11-30 10:08:45

看起来很难啊
回复

使用道具 举报

yoyojacky  初级技匠
 楼主|

发表于 2016-11-30 15:08:13

这个太简单,很少有人关注的说。。~
回复

使用道具 举报

王子麒  初级技师

发表于 2016-12-1 18:28:16

。。。。。。。
回复

使用道具 举报

iooops  中级技匠

发表于 2016-12-11 22:23:24

回复

使用道具 举报

Xpimach  见习技师

发表于 2017-1-5 14:32:55

哈哈哈哈
回复

使用道具 举报

砖头墙  初级技师

发表于 2017-1-6 21:24:20

叼                       牛                       膜拜大神
回复

使用道具 举报

yoyojacky  初级技匠
 楼主|

发表于 2017-1-10 11:17:23

这个太简单,参加比赛都被虐了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail