开源硬件领域有两大法宝,树莓派和Arduino,如果你手上正好有这两样东西,那么恭喜你,接下来你可以极为简单的构建一个家庭监控系统。本篇文章将指导您完成每一步骤,确保你不会遇到问题。介绍首先,肯定有工程师会有疑问,为什么要将树莓派和Arduino一起使用?树莓派具有适用于简单布尔任务(开或关)和读取一些低端温度传感器的GPIO,这样就够了吗?没有!对于更复杂的系统,我们需要使用微控制器来完成繁重的工作,比如Arduino,它具有带多个通道的ADC(模数转换器),PWM(脉冲宽度调制)通道和非常精确的时序。例如,如果您想测量房屋的电能消耗,您需要一个电流互感器和一个基本电路,它将输出你可以使用ADC测量的电压。如果你想输出介于1和0之间的东西,比如可以产生像呼吸灯一样效果的LED,就可以使用PWM输出。最后,如果您需要具有非常精确定时的设备(如PID系统,多路复用LED阵列或控制步进电机),则需要一个微控制器。在本文的例子中,我们将使用ArduinoUno作为微控制器。BOM和硬件原框图对于此项目,您将需要以下内容:ArduinoUno(如果你愿意,可以使用不同的Arduino产品)树莓派(同样,树莓派的任何产品都可以)树莓派电源(针对最新的树莓派3B+,最好配上一个额外的电源)安装了Raspbian系统的SD卡(RaspbianLite也可以)传感器和Arduino的其它模块(取决于你想要实现什么功能)ArduinoIDE,Raspbian,C/C++,HTML和javascript的基础知识(其实只需了解C/C++,那就足够了。)硬件原理框图并不复杂,取决于您想要实现的功能。在这个例子中,我使用了温度/湿度传感器和LED。Arduino代码为简单起见,这里仅展示如何从DHT11传感器读取温度和湿度以及如何远程闪烁LED。数据通过串口以9600的波特率发送。在主函数中,我们读取串口并检查收到的内容。如果我们收到字符串“thl”,则意味着我们需要通过串口从传感器发送数据。为了使此功能正常工作,我们使用while循环并反复发送数据,直到我们收到“ok”以知道数据已到达服务器。如果我们收到字符串“led”,我们只是闪烁LED。在这里你可以添加你想要的任何函数和字符串——只需记住使用“thl”发送数据。你需要知道的是这里我们以JavaScriptObjectNotation(JSON)形式发送数据。JavaScriptObjectNotation是一种用于传输数据对象的开源格式。我们使用这个是因为我们可以使用javascript在main.html文件中轻松使用这些数据。要使用它,我们需要一个名为ArduinoJson的库,您可以在这里下载。函数“send_data()”顾名思义:它以JSON格式通过串口发送数据。要添加数据,您只需在此函数中添加一行,如下所示:root["name_of_data"]=function_that_return_data();“function_that_return_data()”如下所示:intfunction_that_return_data(){intdata;//insertcodethatreadsdatafromasensorandattributesthevaluetovariable'data'return(data);}这就是Arduino部分的全部内容。下面你可以看到我用DHT11传感器和LED为这个特殊情况编写的确切代码。#include"ArduinoJson.h"#include"dht.h"dhtDHT;//givenametoyourDHTsensor#defineDHT11_PINA0//PinforDHT11data#defineLED_PINA1//PINforLEDvoidsetup(){Serial.begin(9600);}voidloop(){Stringstr;str=Serial.readString();//Readserialstr.toLowerCase();//Converttolowercaseif(str=="thl")do{str=Serial.readString();//Readtheserialagainsend_data();//Callsenddatafunction}while(str!="ok");//Continuetosenddatauntilwereceivean"ok"if(str=="led"){digitalWrite(LED_PIN,HIGH);//turntheLEDon(HIGHisthevoltagelevel)delay(1000);//waitforaseconddigitalWrite(LED_PIN,LOW);//turntheLEDoffbymakingthevoltageLOW}}voidsend_data(){StaticJsonBufferjsonBuffer;JsonObject&root=jsonBuffer.createObject();root["temp"]=get_temperature();root["humidity"]=get_humidity();root.printTo(Serial);Serial.println();}intget_temperature()//functionthatreturnthetemperatureasaninteger{inttemperature;DHT.read11(DHT11_PIN);temperature=DHT.temperature;return(temperature);}intget_humidity()//functionthatreturnthetemperatureasaninteger{inthumidity;DHT.read11(DHT11_PIN);humidity=DHT.humidity;return(humidity);}在树莓派上设置Web服务器我们将使用树莓派作为使用NGINX的Web服务器,下面是完成此步骤的过程以及所需的其他组件(如PHP)。这里先来解释一些基础知识。首先,您需要在树莓派上安装Raspbian系统,可以将键盘和显示器连接到树莓派并且上电,或者熟练的朋友也可以通过SSH进行操作。无论使用哪种方法,请记住所有命令都需要以root身份运行,否则你将收到权限错误,这可以通过在前面写“sudo”来完成。Let'sgo!!!首先,更新存储库和包。如果您不熟悉Linux,那我告诉你,它的作用是更新安装包(应用程序)的位置,然后更新它们。sudoapt-getupdatesudoapt-getupgrade安装NGINX,PHP和git。询问时,输入“y”并按Enter键。sudoapt-getinstallnginxphp5-fpmgit而后需要更改默认的NGINX目录并使其与PHP一起使用。cd/etc/nginxsudonanosites-enabled/default下面是修改完成后的代码。server{listen80;##listenforipv4;thislineisdefaultandimpliedlisten[::]:80default_serveripv6only=on;##listenforipv6root/var/www;indexindex.htmlindex.php;#Makesiteaccessiblefromhttp://localhost/server_name_;location/{indexindex.htmlindex.php;#Firstattempttoserverequestasfile,thenas#directory,thenfallbacktotheCMS.try_files$uri$uri/index.html;}location/doc/{alias/usr/share/doc/;autoindexon;allow127.0.0.1;allow::1;denyall;}location~\.php${fastcgi_split_path_info^(.+\.php)(/.+)$;fastcgi_passunix:/var/run/php5-fpm.sock;fastcgi_indexindex.php;includefastcgi.conf;}}修改完成重启NGINX。sudoservicenginxrestart要测试是不是一切正常,可以创建一个PHP测试页面。cd/var/wwwsudonanotest.php并将其放入test.php文件中:phpinfo();?>现在定位到Raspberry-Pi-Ip-Address/test.php(例如:192.168.0.2/test.php)。如果你看到一个包含PHP信息的页面,如下所示,那么它可以正常工作,继续下一步。如果它不起作用,那么再次阅读这部分并检查你是否做错了。最后一步是输入此代码以允许用户www-data(NGINX使用的用户)访问串行端口。sudousermod-a-Gdialoutwww-data在此之后,再重启一次。网站文件到这里其实差不多已经完成了。现在只需将文件下载到树莓派上并根据需要进行编辑。您可以手动下载文件并将它们放入/var/www,或者您可以执行以下命令并自动从github下载它们:cd/var/wwwsudogitclonehttps://github.com/alexonaci/Paranoid/tree/AAC有了这些文件,我们先来看看是些什么内容。/img文件夹:包含缩略图和索引页面的背景图像ArduinoCode.ino:包含Arduino草图的文件PhpSerial.php:PHP库,允许我们使用PHP通过串口与Uno进行通信Style.css:页面的CSSMain.html:包含javascript,按钮和可视数据的最重要的页面Relay.php:启动与Arduino通信的文件下面将解释如何添加项目。要添加新按钮,只需添加以下行:On/OffThumbnail_Image是要用作缩略图的图像的路径(请记住将其放在/img文件夹中)。Name_action是您要为按钮选择的名称。您可以在此处查看可以使用的按钮类型。定位到文件的底部,您可以在其中看到“$(”#led-button“)行。单击(blinkLED);”并在下面添加:$("#Name_action").click(Function_Name);在它上面,添加与它相关的功能:functionFunction_Name(){$.get(url+"Parameter")}“参数”是按下按钮时将通过串口发送到Arduino的字符串。它需要与sketch内的函数相关联,这个在文章上面部分的“ArduinoCode”中讨论过。要在屏幕上添加一个新项目,该项目将显示Arduino发送的值,如传感器数据,请添加以下类型的项目:Display_data:其中“Display_data”是将出现在数据之前的名称,例如“temperature:”,而DataID是标识符。还记得当我说我们将收到JSON数据时吗?这是它派上用场的地方。搜索“getLuminosityTemperatureHumidity()”函数,并在其末尾添加:$("#DataID").html(parsedJSON.name_of_data);其中“name_of_data”是您为Arduino代码部分中的数据选择的字符串。有一个函数会每隔10秒调用一次这个函数,就是这样。setInterval(getLuminosityTemperatureHumidity,10000);如果你愿意,可以更改时间。另外,我也解释一下relay.php脚本是如何工作的?每次像“getLuminosityTemperatureHumidity()”这样的函数调用时它都会打开。为了工作,它使用PhpSerial库。以“$serial->”开头的前8行是建立与Arduino的串行连接。注意!每次执行此脚本时,Arduino都将重置。如果您不希望发生这种情况,只需将一个10uF电容与负极引脚连接到GND,将正极引脚连接到RESET。“sleep(2);”需要一行,因为Arduino在我们打开串行连接的最初几刻没有响应。之后,我们将通过GET方法接收的参数“$_GET[”command“]”发送到Arduino,如果该命令是“thl”,我们从微控制器读取输入数据。收到数据后,我们发送“确定”并返回数据,如此而已。下面是你项目应遵循的操作方式:调试如果你遇到问题,例如没有接收数据,最简单的开始调试的地方就在你的浏览器中。使用Chrome来获取这些说明:只需按F12,转到网络选项卡,单击,按F5刷新并单击“relay.php?command=thl”。如果一切正常,数据应如下面的屏幕截图所示:最后,希望你们喜欢这个项目。