敢碰就报警的Arduino Yún系统

雷锋网  •  扫码分享
我是创始人李岩:很抱歉!给自己产品做个广告,点击进来看看。  

敢碰就报警的Arduino Yún系统

如果你想做一个报警系统,目的恐怕再明确不过了------你不想让孩子爬上橱柜或是冰箱偷东西吃,也不想其他人偷开你的锁柜。当然啦,可能你会想给偷吃食物的宠物拍张照片。或者,你想学学美剧《办公室》里Dwight Schrute所扮演的角色,看看是谁把同事的工作材料换成了果冻。那么问题来了,你该怎么做呢?

是的,你可以在橱柜/冰箱/锁柜里放上一个设备,一旦它监测到有动静,就会拍一张照片然后发送到你的电子邮件里。还有如果你会IFTTT(让互联网为你服务)的话,甚至可以自动把那些“小偷们”的照片发到社交媒体上,让全世界看看他们的脸。

首先,让我们先来欣赏一下小哥浮夸的演技:

这个报警系统项目,由一个运动传感器(PIR),一个摄像头,以及一个支持无线Wi-Fi连接设备组成。笔者选择了 Arduino  Yún,因为它非常易于使用,还能轻松配置无线Wi-Fi,而且如果你想换成RaspberryPi,也很容易。当然啦,如果你使用RaspberryPi的话,Wi-Fi配置可能会略微麻烦一些,因为它必须要连接到一台计算机上才能进行配置操作,而使用Arduino Yún就相对轻松多了,任何人都可以在上面直接配置。这个报警系统项目其实非常简单,即便你没有什么焊接/电气方面的技巧,也能在几分钟时间里轻松完成组装。废话不多说,赶紧来看看怎么做吧。

敢碰就报警的Arduino Yún系统

第一步 Arduino基本配置

首先,你需要配置自己的Arduino Yún网络设置,如果你按照教程一步步操作,其实非常简单。 点击查看教程.

完成配置之后,你需要测试Arduino的连接状况。打开浏览器,输入http://arduino.local,然后即能看到Arduino网页界面了。

如果一切操作正常,打开SSH会话。

$ sshroot@arduino.local

默认密码是:“arduino”。

然后,让我们来安装一些有用的软件包

$opkg update

$opkg install openssh-sftp-server

那么,为什么要安装“openssh-sftp-server”呢?因为这个软件包可以让你从Arduino上面轻松上传或下载文件。现在,你可以使用一个通用的SFTP客户端,比如filezilla,transmit,或是cyberduck等等,这样就不用输入麻烦的SCP命令来进行文件传输了。

然后,为了兼容Python,我们还需要安装一个SSL支持包(感谢sbkirby!)。因为在默认软件包里,并没有包含这个软件支持包。

$opkg update

$opkg install python-openssl

笔者墙裂推荐你可以在Arduino Yún上插一个SD卡(如果你有一个的话),Arduino Yún设备会自动分配文件路径,地址是mnt/sda1。

然后,我们要在Arduino Yún上面安装USB摄像头和USB声卡。

第二步  安装并测试USB摄像头

通过opkg套件管理系统,已经有支持Linino的UVC软件包了,因此安装摄像头可以说是非常简单的一个步骤。是需要通过ssh连接到Yún上面,然后输入:

$ opkg update

$ opkg install kmod-video-uvc

就可以了。

不过我们还需要一个可以拍照片的软件,笔者使用过一款容量极小,但又非常便于使用的拍照软件fswebcam,按照如下命令,安装即可。

$ opkg install fswebcam

第三步  拍摄你的第一张照片

首先要确保你使用了SD卡作为存储,否则Arduino内存会很快就被耗尽。好了,如果你正在使用SD存储卡的话,你应该已经能够看到它的安装路径地址了/mnt/sda1.如果你还没有使用,那么请将FAT32格式的SD卡插入到设备的SD卡插槽里面,并重启你的Arduino设备。

现在,请把摄像头插进设备的USB端口,然后输入:

$ cd /mnt/sda1

$ fswebcam test.png

如果一切正常的话,你现在就能拍摄自己的第一张照片啦!注意看看你的SD卡里的内容哦,:)

这意味着,现在我们可以通过Yún’s Bridge库,在自己的Arduino设备里面拍照片,按照下面这种操作方式就能实现:

Process.runShellCommand("fswebcam /mnt/sda1/test.png");

第四步  安装声卡

在Yún上打开一个ssh会话,然后输入:

$opkg install kmod-usb-audio

$opkg install madplay

完成安装之后,现在Arduino Yún设备就有了声卡支持了。笔者只尝试了下MP3格式的音乐播放,还没有自己录制一些音频,但是很快就会去尝试下!

如果想要测试一下声卡效果,其实也非常简单,你只需在SD卡里复制一个MP3音频文件,然后输入:

$cd /mnt/sda1

$madplay yoursound.mp3  

这意味着现在我们可以通过Yún’s Bridge库,在Arduino设备里面播放声音了,按照下面这种操作方式就能实现:  

Process.runShellCommand("madplay /mnt/sda1/test.mp3");

第五步  电子邮件脚本

现在,我们的监控设备可以拍照片并且支持播放声音….但是我们还想要更多功能!我们想让这款设备能通过电子邮件发送文件。

所以,我们该怎么做呢?答案其实非常简单….一个python脚本就能搞定!Arduino Yún整合了Temboo库,笔者想让这个监控系统更加具有兼容性,因此我们会使用一个非常简单的python脚本编码图像文件,并通过电子邮件发送出去。

笔者选择的电子邮箱是 Gmail ,但是这个代码脚本其实可以选择任何支持SMTP服务器的电子邮箱。

你可以创建一个新文件,称之为“sendemail.py”,然后把下面这段代码复制进去,

# coding=utf-8

# Copyright (C) 2014  Stefano Guglielmetti

# This program is free software: you can redistribute it and/or modify

# it under the terms of the GNU General Public License as published by

# the Free Software Foundation, either version 3 of the License, or

# (at your option) any later version.

# This program is distributed in the hope that it will be useful,

# but WITHOUT ANY WARRANTY; without even the implied warranty of

# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License

# along with this program. If not, see <http://www.gnu.org/licenses/>.

import smtplib, os, sys

from email.MIMEMultipart import MIMEMultipart

from email.MIMEBase import MIMEBase

from email.MIMEText import MIMEText

from email.Utils import COMMASPACE, formatdate

from email import Encoders

#From address, to address, subject and message body

from_address    = 'FROM_ADDRESS@EMAIL.COM'

to_address      = ['YOUR_ADDRESS@EMAIL.COM']

email_subject   = 'Alert!!! Zombies!!! Ahead!!!'

email_body      = 'A non dead intruder has been detected and needs to be eliminated!'

# Credentials (if needed)

username = 'EMAIL_LOGIN'

password = 'EMAIL_PASSWORD'

# The actual mail send

server = 'smtp.gmail.com:587'

def send_mail(send_from, send_to, subject, text, files=[], server="localhost"):

    assert type(send_to)==list

    assert type(files)==list

    msg = MIMEMultipart()

    msg['From'] = send_from

    msg['To'] = COMMASPACE.join(send_to)

    msg['Date'] = formatdate(localtime=True)

    msg['Subject'] = subject

    msg.attach( MIMEText(text) )

    for f in files:

        part = MIMEBase('application', "octet-stream")

        part.set_payload( open(f,"rb").read() )

        Encoders.encode_base64(part)

        part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(f))

        msg.attach(part)

    smtp = smtplib.SMTP(server)

    smtp.starttls()

    smtp.login(username,password)

    smtp.sendmail(send_from, send_to, msg.as_string())

    smtp.close()

send_mail(from_address, to_address, email_subject, email_body, [sys.argv[1]], server) #the first command line argument will be used as the image file name

现在,你需要把相关电子邮件设置做下改动,如下

#From address, to address, subject and message body

from_address    = 'FROM_ADDRESS@EMAIL.COM'

to_address      = ['YOUR_ADDRESS@EMAIL.COM']

email_subject   = 'Alert!!! Zombies!!! Ahead!!!'

email_body      = 'An undead intruder has been detected and needs to be eliminated!'  

# Credentials (if needed)

username = 'EMAIL_LOGIN'

password = 'EMAIL_PASSWORD'

# The actual mail send

server = 'smtp.gmail.com:587'

接下来,你可以通过SFTP(或是SCP,如果你喜欢的话)把这段脚本文件上传到Arduino Yún的SD卡里,然后再次打开SSH会话,输入下面这段命令:

$cd /mnt/sda1

$python sendemail.py test.png

几秒钟之后,你就会收到一封电子邮件,附件就是Arduino Yún拍摄的照片,是不是很神奇!

第六步  让我们搭设电路板!

别担心,这一个步骤其实也是非常简单的。你根本用不着焊接什么材料,所有部件都能靠组装完成。笔者使用了这款PIR传感器,是因为它即可靠,又方便使用。你可以参照下图来进行相关操作:

敢碰就报警的Arduino Yún系统

我们已经连上了这个PIR传感器。如果监控系统设备发现了一些动作,上面的LED灯就会打开。

第七步  现在是时候加上Arduino Sketch了

在Arduino IDE上复制下面这段代码,然后上传到你的Yún上:

 * Switches a LED, takes a picture and sends it via email

 * according to the state of the sensors output pin.

 * Determines the beginning and end of continuous motion sequences.

 *

 * @author: Stefano Guglielmetti / stefano (at) mikamai (dot) com / http://jeko.net

 * @date:   feb 5, 2014  

 *

 * based on the example by Kristian Gohlke / krigoo (_) gmail (_) com / http://krx.at

 * http://playground.arduino.cc/Code/PIRsense

 *

 * stefano guglielmetti (cleft) 2014 

 *

 * released under a creative commons "Attribution-NonCommercial-ShareAlike 2.0" license

 * http://creativecommons.org/licenses/by-nc-sa/2.0/de/

 *

 *

 * The Parallax PIR Sensor is an easy to use digital infrared motion sensor module. 

 * (http://www.parallax.com/detail.asp?product_id=555-28027)

 *

 * The sensor's output pin goes to HIGH if motion is present.

 * However, even if motion is present it goes to LOW from time to time, 

 * which might give the impression no motion is present. 

 * This program deals with this issue by ignoring LOW-phases shorter than a given time, 

 * assuming continuous motion is present during these phases.

 *  

 */

#include <Bridge.h>

/////////////////////////////

//VARS

//the time we give the sensor to calibrate (10-60 secs according to the datasheet)

int calibrationTime = 10;        

//the time when the sensor outputs a low impulse

long unsigned int lowIn;         

//the amount of milliseconds the sensor has to be low 

//before we assume all motion has stopped

long unsigned int pause = 5000;  

boolean lockLow = true;

boolean takeLowTime;  

int pirPin = 6;    //the digital pin connected to the PIR sensor's output

int ledPin = 13;

Process p;

String imageName;

/////////////////////////////

//SETUP

void setup(){

  Bridge.begin();

  Serial.begin(9600);

  pinMode(pirPin, INPUT);

  pinMode(ledPin, OUTPUT);

  digitalWrite(pirPin, LOW);

  //give the sensor some time to calibrate

  Serial.print("calibrating sensor ");

  for(int i = 0; i < calibrationTime; i++){

    Serial.print(".");

    delay(1000);

  }

  Serial.println(" done");

  Serial.println("SENSOR ACTIVE");

  delay(50);

}

 

////////////////////////////

//LOOP

void loop(){

  if(digitalRead(pirPin) == HIGH){

    digitalWrite(ledPin, HIGH);   //the led visualizes the sensors output pin state

    if(lockLow){  

      //makes sure we wait for a transition to LOW before any further output is made:

      lockLow = false;            

      Serial.println("---");

      Serial.print("motion detected at ");

      Serial.print(millis()/1000);

      Serial.println(" sec"); 

      imageName = uniqueFileName("png"); //generate a new, uniqe file name

      p.runShellCommand("fswebcam /mnt/sda1/" + imageName); //takes the picture

      while(p.running()); //wait till the process ends

      p.runShellCommand("madplay /mnt/sda1/sounds/sirena.mp3"); //play the siren sound

      while(p.running()); //wait till the process ends

      p.runShellCommand("python /mnt/sda1/sendemail.py /mnt/sda1/" + imageName); //sends the picture via email

      while(p.running()); //wait till the process ends

      delay(50);

    }         

    takeLowTime = true;

  }

  if(digitalRead(pirPin) == LOW){       

    digitalWrite(ledPin, LOW);  //the led visualizes the sensors output pin state

    if(takeLowTime){

      lowIn = millis();          //save the time of the transition from high to LOW

      takeLowTime = false;       //make sure this is only done at the start of a LOW phase

    }

    //if the sensor is low for more than the given pause, 

    //we assume that no more motion is going to happen

    if(!lockLow && millis() - lowIn > pause){  

      //makes sure this block of code is only executed again after 

      //a new motion sequence has been detected

      lockLow = true;                        

      Serial.print("motion ended at ");      //output

      Serial.print((millis() - pause)/1000);

      Serial.println(" sec");

      delay(50);

    }

  }

}

 

 

/* A simple function to generate unique timestamp based filenames */

String uniqueFileName(String ext){

  String filename = "";

  p.runShellCommand("date +%s");

  while(p.running()); 

  while (p.available()>0) {

    char c = p.read();

    filename += c;

  }  

  filename.trim();

  filename += "." + ext;

 

  return filename;

}  

十秒钟之后(校准时间),就将开始工作,并拍摄照片了!!!

一切搞定!下面这张照片,就是组装完成后的效果图。 在GitHub上 ,有这个项目的详细文档。

敢碰就报警的Arduino Yún系统

 via  makezine

关注硬创邦微信号(leiphone_bang),加入全球创客马拉松主群(群号:259592983),参与我们的互动讨论,获得最新比赛信息~

敢碰就报警的Arduino Yún系统

随意打赏

提交建议
微信扫一扫,分享给好友吧。