物理家庭自动化接口
组件和用品
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
![]() |
| × | 1 | |||
| × | 1 | ||||
| × | 7 |
关于这个项目




请参阅下面的两个视频,以快速了解该项目。
界面传达信息并允许用户控制事物。大多数家庭自动化平台依赖于“虚拟界面”。你拿出一部智能手机,打开应用程序,看看你家发生了什么,然后开灯和关灯。当您离开时,这可以正常工作。但是查看虚拟表示并解析显示器上的信息需要工作。它需要专注,并且感觉不直观。
我想做一个“物理界面”——一个小模型房子,它在物理上模仿我想知道的关于我真实房子的事情。所以当车库门打开时,我希望模型上的车库门也打开。这个样板房可以放在我的咖啡桌上,我可以看一眼,看看车库门有没有在睡觉前打开。或者我可以把它放在我工作的办公桌上,通过 VPN 连接到我的家。上班的时候,我可以看一眼,看看前门是否一直开着。这个物理界面可以像我制作的一样富有创意或实用。

因此,在以下步骤中,我将
- 建造一个样板房,以显示诸如门位置、能源使用情况以及灯是否亮着等信息。
- 使用 Open Energy Monitor Arduino 库构建能源监测器,并将能源使用信息提供给样板房和 OpenHAB
- 提供几种将门/窗位置发送到样板房的方法。展示如何在 DIY 家庭自动化系统中使用 Wink Hub 和 Wink“Tripper”接触传感器数据。
- 使用 Wink 和 Arduino 执行输出,例如打开/关闭实际车库门或打开和关闭灯。
模型屋有一些伺服器和 LED 连接到 Arduino 控制器。该控制器订阅指示门位置和能源使用情况的 MQTT 消息,并相应地启动伺服系统。与指示灯是打开还是关闭的 LED 的想法相同。有几个选项可用于将此传感器信息发送到 MQTT 代理,因此我将在后面的步骤中详细说明。中间是一个运行 MQTT 代理(Mosquitto)和 OpenHAB 的 Raspberry Pi。虽然运行样板房不需要OpenHAB,但需要为智能手机应用程序提供接口,并允许远程监控和驱动。仅仅因为我想要一个物理接口并不意味着我准备放弃虚拟接口。
样板房也有两个按钮。其中一个按钮可以打开/关闭 zigbee 灯泡。另一个按钮打开和关闭车库门(在真正的房子上)。
第 1 部分:房屋建造
1) 建造样板房
2) 控制选项、接线和代码
第 2 部分:输入(传感器)
3) 传感器:能量监测
4)传感器:DIY传感器节点选项
5) 传感器:Wink Hub &Tripper 接触式传感器
第 3 部分:输出
6) 灯
7) 车库门开启器
第 1 步:样板房建造














我不希望这一步成为规定性的。我对艺术和手工艺非常成熟,所以我将展示我如何建造我的样板房。你会想要把它建造得像你自己的住所,并反映你关心的事情。这里有很大的创造力空间。此图中的某些组件(如电流互感器)将在后续步骤中使用。
组件 :
- (1) 盒子。这取决于你有多大和什么比例。
- (3) Tower Pro SG90 伺服 http://www.dx.com/p/towerpro-sg90-9g-mini-servo-w...
- (2) 小铰链 http://www.homedepot.com/p/Stanley-National-Hardw...
- (一些)粘合剂材料。我使用了 3M 挂钩的双面胶。
- Arduino Yun 或 Arduino Uno,带以太网屏蔽。
- 按钮http://www.radioshack.com/mini-spst-1-5-amp-moment...
- 房子周围的东西
屋顶
我剪下盒子的一个侧盖并将其连接到另一个(仍然连接的)侧盖上以形成一个屋顶。我用一个小盒子为直角提供了一个结构,后来用乐高积木更好地支撑它。您可能可以使用房子周围的任何东西来制作这个直角。


门/窗
切出要展示的门的孔。用双面胶在门上固定一两个铰链,然后固定在房子上。我知道,没什么特别的,所以可以随意利用你在房子周围的东西即兴创作。我用的是 3M 双面泡棉胶,那种带挂钩的。我还使用这些泡沫胶条来安装伺服电机。对于车库门,伺服电机臂将车库门推开,重力关闭车库门。对于前门,我需要在铰链门上系上一根绳子,以便伺服臂可以打开门。你看到的黄色乐高积木用来抵消铰链的伺服。

能量计
没有什么花哨。只需剪下一个箭头状的东西并将其连接到伺服臂上即可。剪下一个看起来有点像灌木的形状并用千瓦刻度标记,然后将伺服电机摩擦安装到盒子上,中间有灌木。

在能耗舵机上方,我贴了一个红色的 LED。
我还有两个按钮来控制灯和车库门。这些是瞬时按钮。按钮的外侧带有螺母,以将其固定在纸板箱壁上。另一侧是用于焊接电线的金属触点。


第 2 步:房屋建造 - 电线和代码



接线
这是接线图。我把盒子里面的接线弄得一团糟。如果您只想知道哪些电线在哪些引脚上:
- 状态引脚 LED:7
- 发光指示灯:4个
- 舵机 1(前门):3
- 伺服 2(车库门):5
- Servo 3(能量使用灌木):6
- 按钮 1(开/关灯):8
- 按钮 2(车库门打开/关闭):9
控制器选项
您可以使用自己喜欢的和手头上的东西。一个更便宜(20 美元)的选择是使用 Arduino Uno 克隆和以太网屏蔽。我从那开始,但这将我束缚在以太网电缆上。所以我把它换成了 Arduino Yun(65 美元)。贵得多,但也给了我使用 wifi 的自由。 Yun真的很容易使用。你基本上:
- 通过以太网将云连接到您的路由器
- 导航到Yun的网页
- 在路由器上设置密码和静态 IP
- 下载云草图
下面附上 Arduino Uno 和 Arduino Yun 的草图。它们非常相似,除了在 Yun 中使用的以太网桥之外,您几乎可以将 Yun 代码复制到 Uno。切换到Yun后,我添加了两个控制按钮。因此,Uno 草图没有这些按钮。
第一步中的视频展示了 Arduino Yun。这是使用 Uno 和以太网屏蔽的视频。制作这个视频时,我还没有安装这两个按钮,但其他一切都一样。
//www.youtube.com/embed/7i6McpbU3Gs
第 3 步:传感器:能量监控器








现在我们有一个能够显示能源使用情况的物理界面,我们需要构建一个传感器节点来读取房屋的能源消耗并将该消耗发布到 MQTT 代理。有几种方法可以做到这一点。我正在使用 Arduino Yun。这是最简单的方法,但不是最便宜的。如果需要,您可以使用 Arduino Uno、以太网扩展板和无线路由器来充当 wifi 桥接器。或者,您可以使用带有 Open Energy Monitor 包的 Pi。我只讲云法。


我正在使用 ebay 的 7 美元电流互感器。您可以在此处找到 Yhdc SCT-013-000 的 100A 版本。按照上面的接线图接线,并在这一步的底部上传Arduino Yun的草图。请务必使用您的 MQTT 代理 IP 地址修改代码。 Open Energy Monitor 库的这个页面是一个很好的参考。这是理想的组件值。
- 负载电阻 =33 ohm
- 分压电阻 =10k ohm
- 电容器 =10uF
我的能量监视器的图片与电路图并不真正匹配,因为我手头没有那些确切的组件。我不得不并联使用两个 68 欧姆的电阻器,因为我没有 33 欧姆的负载电阻器。而且我的整流电路没有10uF的电容,所以我用了两个22uF的电容代替。串联等效电容足够接近。
将电流互感器连接到您房屋的输入相之一。我只有一个 100A 变压器,所以我只监控其中一个相位。最终,我想要更多的变压器来监控输入电源的另一端以及分支电路。使用实际的安培计,我的 DIY 设置总是在不同安培读数的安培计上读取 1 安培(见上图 5)。减去额外的放大器非常简单。


OpenHAB
既然我们有数据进来,我们不妨也把它显示在 OpenHAB 上,以便可以绘制数据。这是相关的 OpenHAB 配置。


项目定义
编号 itm_smarthome_energy_amps "能量 (amps) [%.1f]" {mqtt="<[mymosquitto:2853:state:default]"}
编号 itm_smarthome_energy_watts "能量 (瓦特) [ %.1f]" {mqtt="<[mymosquitto:2852:state:default]"}
站点地图
Text label="Energy" icon="firstfloor"
{Frame label="Energy Usage" { Text item=itm_smarthome_energy_amps
Text item=itm_smarthome_energy_watts
Chart item=itm_smarthome_energy_watts period=h refresh=5000 } //帧能耗
}//Text label="Energy"
坚持
由于我们使用图表,我们需要为能源使用定义某种持久性策略。 RRD4J 最容易使用,所以这里是我对“/openhab/configurations/persistence/rrd4j.persist”的内容。
Strategies {
// 对于 rrd 图表,我们需要一个 cron 策略 everyMinute :"0 * * * * ?"}Items { DemoSwitch,NoOfLights,Window_GF_Toilet,Heating* :strategy =everyChange, everyMinute, restoreOnStartup // 让我们只将温度值存储在 rrd Temperature*,Weather_Chart* :strategy =everyMinute, restoreOnStartup itm_smarthome_energy_watts :strategy =everyUpdate}
能量监控屏幕


第 4 步:传感器:DIY 无线传感器节点

无线开/关传感器有几个选项。
在我之前的一个项目中,我使用 5 美元的无线收发器通过 MQTT 网关发送传感器数据。我仍在使用这个项目将车库门状态获取到 OpenHAB,在演示视频中,这实际上是模型房屋的车库门如何反映我的实际车库门状态。如果要使用,可以在这一步找到详细的代码和电路。这有点难看,但它在车库里,没人可能注意到。
还有一个光传感器,我用它来指示灯是否一直亮着。这也来自此步骤中详述的先前的 Instructable。它是 Uber 传感器的一部分,它使用光电阻器将亮度信息无线发送回 OpenHAB。在这种情况下,我只是订阅了指示亮度级别的 MQTT 主题。

我还制作了一个电池供电的簧片开关传感器,它使用与之前的 Instructable 相同的无线收发器和网关。然而,它不是很好看。出于审美原因,我真的不能在室内门或窗户上使用它。因此,为了解决这个问题,我使用了 Wink 外观更好的消费级簧片开关传感器。这将引导我们进行下一步。


第 5 步:传感器:Wink Hub



我在这篇博文中偶然发现了一位早期 Wink Hub 用户的博客文章,他找到了一种方法来 root 集线器以获得对 PHP 漏洞的访问。此漏洞允许您运行“aprontest”实用程序来控制与 Wink Hub 配对的事物。使用这种方法,我已经能够从 OpenHAB 界面控制灯光。
生根 Wink Hub 的最有趣的好处是它为您提供 本地 无需访问 Wink 服务器即可控制灯光和传感器状态。 Wink Hub 和 Wink API 始终需要访问 Internet 来联系 Wink 服务器以进行照明控制或获取传感器状态。现在,利用这个 PHP 漏洞,照明和传感器操作可以保留在您的本地 LAN 中。太好了。

我在这一步的底部包含了一个 PHP 脚本。如果您无法打开此文件,请尝试此链接。该脚本在 Raspberry Pi 上运行并轮询 Wink Hub 以了解两个 Wink Tripper 簧片开关的状态。此状态通过 REST API 发送到 OpenHAB。然后 OpenHAB 将发布这些门位置的 MQTT 主题。然后,模型房屋的控制器通过订阅这些门位置主题来打开或关闭门。
此步骤中附加的三个 OpenHAB 配置文件(项目、站点地图和规则)是使一切正常工作所必需的。它们定义了轮询脚本通过 REST 接口与之交互的联系人项目。还有一个通过 OpenHAB 控制 zigbee 灯泡的示例脚本。
//www.youtube.com/embed/tWKPcBOn1KM
脚本和配置文件。
第 6 步:输出:灯光


由于我介绍了配置文件的顺序,前面的步骤几乎提供了通过物理接口和 OpenHAB 接口控制“连接的灯泡”所需的一切。灯可以是 Wink 集线器支持的任何灯。目前,我已经使用 Cree Connected Bulb 和 GE Wink 灯对此进行了测试。两者都按预期工作。我只想把这个视频放在这里,更好地展示光传感器和按钮如何控制智能灯泡。
//www.youtube.com/embed/KSDUEfro3Vo第 7 步:输出:车库门开启器






步骤 5 中提供的配置文件包括控制车库门所需的大多数 OpenHAB 项目。但是你仍然需要一些东西来实际打开和关闭车库门。为此,我正在修改以前的 Instructable 的部分内容。我用这些组件制作了一个车库门开启器:
- Arduino 克隆(10 美元)
- 以太网屏蔽(7 美元)
- 簧片继电器 ($2)
- 备用车库门遥控器(22 美元)
Arduino 通过打开和关闭干触点来控制簧片继电器。备用车库门开启器的按钮连接在簧片继电器上的干触点上。将 Arduino 的引脚 5 和 GND 连接到簧片继电器的两个线圈引脚(两个外部引脚),将内部继电器引脚连接到车库门遥控器上的按钮。
Arduino 订阅 MQTT 主题并等待打开/关闭命令。当它看到这个话题时,它会瞬间激活干簧继电器,关闭备用车库门遥控器上的“按钮”。 Arduino 草图附在下面。此外,将“garage_monitor_rules.txt”添加到您的规则文件中。除了步骤 5 中附加的规则之外,这也是必需的。如果您不使用我使用的超声波传感器方法,则这是您需要更改以适应您的修改的部分。
//www.youtube.com/embed/CqbRosfqM3c如果您的车库门非常安静,或者您希望在车库门打开时在房子的另一部分播放某种音频通知,则上面添加的规则可以播放音频文件。您可以在大约 30 分钟后的第一个视频演示中听到它。
//www.youtube.com/embed/pdKfJtnpNzs
第 8 步:其他想法

在这个项目中做出的决定反映了我熟悉的工具、我手头的部件以及我希望事情如何工作的优先事项。您可能拥有一组不同的工具,并且您拥有不同的现成可用的硬件组件。对于家庭自动化的工作方式,您可能也有不同的想法。
使用 MQTT 和 OpenHAB 时有很大的灵活性,您不需要完全按照我所做的去做。用于控制模型房屋的控制器可以是某种类型的 Arduino、Raspberry Pi,甚至是 Sparkcore。 DIY 传感器可以是 Arduino 或独立的 ESP8266。唯一的限制是传感器数据需要以某种方式发布到 MQTT 代理。如果您在 OpenHAB 安装中有 USB Z-wave 棒,您可以将 OpenHAB 用作 Z-wave 到 MQTT 的桥接器,并利用 Z-wave 传感器进行门感应。
甚至 Wink 打开/关闭传感器也可以采用不同的方式。如果您没有root Wink Hub,您可以使用Wink API 获取传感器状态并将其发布到OpenHAB,或者直接通过MQTT 发布。这需要使用 Wink 服务器,但它消除了 root 集线器的约束。
所以,有很多方法可以做不同的事情。我倾向于使用最小公分母的硬件,因此使用 Arduino 和纸板箱。
代码
- smarthome_yun.ino
- smarthome_ethernet.ino
- energy_monitor_yun.ino
smarthome_yun.ino纯文本
// Eric Tsai// 2015-04-13// Arduino Yun 用于控制物理智能家居接口的代码// 修改MQTT 主题名称以匹配您的用途// 修改MQTT 代理IP 地址//new yun includes#include#include #include //使用以太网屏蔽时旧的以太网包含/*#include #include #include */#include //Ethernet shield setup/*IPAddress ip(192, 168, 2, 36);byte mac[] ={ 0x90, 0xA2, 0xDA, 0x0D, 0x43, 0x13 };byte server[ ] ={ 192, 168, 1, 101 };EthernetClient ethClient;PubSubClient client(server, 1883, callback, ethClient);*/unsigned long keepalivetime=0;unsigned long MQTT_reconnect=0;//使用yunclient桥接网络YunClient yun; //相当于ethernet clientPubSubClient client("192.168.1.101", 1883, callback, yun);bool conn_ok;//使用LED指示MQTT连接状态.int ledPin =4; //指示灯 onint statusPin =7; //指示MQTT连接状态//伺服控制intservo1Pin =3; //前门伺服2Pin =5; //车库门伺服3Pin =6; //能量使用表Servo Servo1; //门伺服舵机2; //车库门伺服伺服3; //energyint button1 =8; //前门上的按钮int button2 =9; //车库门上的按钮//伺服操作:servosintservo1_target =5的目标位置; //门,关闭伺服2_目标=5; //车库,封闭的servo3_target =180; //能量,180是“0”瓦,电机安装向后intservo1_pos_cur=5;intservo2_pos_cur=5;intservo3_pos_cur=180; // 180 是“0”瓦特,电机安装向后intservo1Opened =5;intservo1Closed =130;intservo2Opened =5;intservo2Closed =150;unsigned longservo1_time =0;unsigned longservo2_time =0;unsigned longservo3_time =0;/ /debounce on 按钮,所以你不会垃圾邮件 publishunsigned long button1_db =0;unsigned long button2_db =0;int button=0;int callback_flag =0;char buff_message[12];//--------- -------------------------------------------------- ----// MQTT回调//在这里对MQTT消息做出反应//-------------------------------- -------------------------------void callback(char* topic, byte* payload, unsigned int length) { //转换主题到 int。 int mytopic =atoi(主题); //Serial.print(mytopic); //将payload转换为int payload[length] ='\0'; //添加一行 return 以便 atof 可以正确解析 float mymsg =atof( (const char *) payload); //led if (mytopic ==2822) { if (mymsg ==1) { digitalWrite(ledPin, HIGH); } if (mymsg ==0) { digitalWrite(ledPin, LOW); } } //servo 1, front door if (mytopic ==2832) { if (mymsg ==1) //opened { //Serial.println("servo1 opens");伺服1_目标=伺服1打开; } if (mymsg ==0) //closed { //Serial.println("servo1 closed");伺服1_目标=伺服1关闭; } //Serial.println(servo1_target); } /* //第二个车库门信号“关闭”=关闭=发送1“打开”=打开=发送0*///伺服2,车库门 if (mytopic ==2842) { if (mymsg ==1) / /打开{伺服2_目标=伺服2打开; } if (mymsg ==0) //关闭{servo2_target =servo2Closed; } //callback_flag=1; //servo3_target =mymsg; } //servo 3, energy meter if (mytopic ==2852) { //message =watts //绑定瓦特到米最大和最小 if (mymsg> 6000) { mymsg =6000; } if (mymsg <0) { mymsg =0; } //bias meter from 180 degrees to 0 degrees //180 deg to 0 deg =0 watt to 6000 watts, for example //set max watts to what makes sense for you. servo3_target =180-((1-((6000-mymsg)/6000))*180)-25; callback_flag=1; }}//end callbackvoid setup() { pinMode(ledPin, OUTPUT); //LED indicating light on pinMode(statusPin, OUTPUT); pinMode(button1, INPUT_PULLUP); //use pull-up resistor, invert logic pinMode(button2, INPUT_PULLUP); //use pull-up resistor, invert logic digitalWrite(ledPin, HIGH); //yun bridge Bridge.begin(); //connect to MQTT broker client.connect("yun smarthome"); client.publish("watch", "Smart Home Connected!"); keepalivetime=millis(); //Wire.onReceive (receiveEvent); MQTT_reconnect =millis(); //client.subscribe("#"); //test subscribe client.subscribe("2822"); //LED client.subscribe("2832"); //servo 1 topic client.subscribe("2842"); //servo 2 topic client.subscribe("2852"); //servo 3 topic digitalWrite(ledPin, LOW); //servo servo1.attach(servo1Pin); servo1.write(90); servo2.attach(servo2Pin); servo2.write(90); servo3.attach(servo3Pin); servo3.write(5);} // end of setupvoid loop() { client.loop(); //MQTT processing needs this to run //For servo positioning, don't want to move too fast. //Must crawl from current position to target position //but also avoid using "delay" cmd, that just freezes up microcontroller //servo 1 if ((millis() - servo1_time)> 20) { if (servo1_pos_cur> servo1_target) { servo1_pos_cur =servo1_pos_cur - 1; } if (servo1_pos_cur 20) { if (servo2_pos_cur> servo2_target) { servo2_pos_cur =servo2_pos_cur - 1; } if (servo2_pos_cur 20) { if (servo3_pos_cur> servo3_target) { servo3_pos_cur =servo3_pos_cur - 1; } if (servo3_pos_cur 3000) || (button1_db> millis())) { button1_db=millis(); client.publish("2862", "button1 yaya"); } } //button 2 button=digitalRead(button2); if (button==0) //inverted logic { if ( ((millis() - button2_db)>3000) || (button2_db> millis())) { button2_db=millis(); client.publish("2872", "button2 yaya"); } } //check network connection to MQTT broker every 60 seconds. //reconnect if no longer connected if ((millis() - MQTT_reconnect)> 60000) { conn_ok =client.connected(); if (conn_ok==1) { digitalWrite(statusPin, HIGH); //Serial.println("MQTT connected OK"); } else { digitalWrite(statusPin, LOW); //Serial.println("MQTT NOT connected OK"); } //no connection, reconnect if (conn_ok ==0) { client.disconnect();延迟(5000); while (client.connect("smarthouse") !=1) { digitalWrite(statusPin, LOW); //Serial.println("Error connecting to MQTT"); delay(4000); } digitalWrite(statusPin, HIGH); } //Serial.println("reconnected to MQTT"); MQTT_reconnect =millis(); client.publish("watch","smart home heartbeat!"); }//end Mosquitto connection check} // end of loop
smarthome_ethernet.inoPlain text
// Eric Tsai// 2015-04-1// Arduino Uno w/ Ethernet, code for controlling physical smart home interface// Modify MQTT topic names to match your use// Modify MQTT broker IP address#include#include #include #include //Ethernetbyte mac[] ={ 0x90, 0xA2, 0xDA, 0x0D, 0x43, 0x13 };byte server[] ={ 192, 168, 1, 101 };EthernetClient ethClient;PubSubClient client(server, 1883, callback, ethClient);unsigned long keepalivetime=0;unsigned long MQTT_reconnect=0;bool conn_ok;//use LED for indicating MQTT connection status.int ledPin =4; //indicate lights onint statusPin =7; //indicate MQTT conn status//servo controlint servo1Pin =3; //front doorint servo2Pin =5; //garage doorint servo3Pin =6; //energy usage meterServo servo1; //doorServo servo2; //garage doorServo servo3; //energy//servo operation:target positions for servosint servo1_target =5; //door, closedint servo2_target =5; //garage, closedint servo3_target =180; //energy, 180 is "0" watts, motor mounted backwardsint servo1_pos_cur =5;int servo2_pos_cur =5;int servo3_pos_cur =180; // 180 is "0" watts, motor mounted backwardsint servo1Opened =5;int servo1Closed =120;int servo2Opened =5;int servo2Closed =150;unsigned long servo1_time =0;unsigned long servo2_time =0;unsigned long servo3_time =0;//---------------------------------------------------------------// MQTT call back// react to MQTT messages here//---------------------------------------------------------------void callback(char* topic, byte* payload, unsigned int length) { Serial.println("received MQTT"); //convert topic to int. int mytopic =atoi (topic); //Serial.print(mytopic); //convert payload to int payload[length] ='\0'; //add a line return so atof can parse correctly float mymsg =atof( (const char *) payload); //print MQTT message Serial.println(""); Serial.print("("); Serial.print(mytopic); Serial.print(", "); Serial.print(mymsg); Serial.println(")"); //led if (mytopic ==2822) { if (mymsg ==1) { digitalWrite(ledPin, HIGH); } if (mymsg ==0) { digitalWrite(ledPin, LOW); } } //servo 1, front door if (mytopic ==2832) { if (mymsg ==1) //opened { Serial.println("servo1 opened"); servo1_target =servo1Opened; } if (mymsg ==0) //closed { Serial.println("servo1 closed"); servo1_target =servo1Closed; } Serial.println(servo1_target); } /* //second garage door signal "closed" =off =send 1 "open" =on =send 0 */ //servo 2, garage door if (mytopic ==2842) { if (mymsg ==1) //opened { servo2_target =servo2Opened; } if (mymsg ==0) //closed { servo2_target =servo2Closed; } } //servo 3, energy meter if (mytopic ==2852) { //message =watts //error check if (mymsg> 6000) { mymsg =6000; } if (mymsg <0) { mymsg =0; } //bias meter from 180 degrees to 0 degrees //180 deg to 0 deg =0 watt to 6000 watts, for example //set max watts to what makes sense for you. servo3_target =180-((1-((6000-mymsg)/6000))*180); //servo3_target =mymsg; }}//end callbackvoid setup() { //ethernet //Ethernet.begin(mac, ip); //Wire.begin (MY_ADDRESS); Serial.begin (9600); Serial.println("starting"); pinMode(ledPin, OUTPUT); //LED indicating light on pinMode(statusPin, OUTPUT); digitalWrite(ledPin, HIGH); //wait for IP address while (Ethernet.begin(mac) !=1) { Serial.println("Error getting IP address via DHCP, trying again...");延迟(5000); } Serial.println("ethernet OK"); keepalivetime=millis(); while (client.connect("smarthouse") !=1) { Serial.println("Error connecting to MQTT"); //delay(3000); delay(4000); } MQTT_reconnect =millis(); Serial.println("setup complete"); client.publish("smarthouse","hello world"); //test publish //client.subscribe("#"); //test subscribe client.subscribe("2822"); //LED client.subscribe("2832"); //servo 1 topic client.subscribe("2842"); //servo 2 topic client.subscribe("2852"); //servo 2 topic digitalWrite(ledPin, LOW); //servo servo1.attach(servo1Pin); servo1.write(90); servo2.attach(servo2Pin); servo2.write(90); servo3.attach(servo3Pin); servo3.write(5);} // end of setupvoid loop() { client.loop(); //MQTT processing needs this to run //For servo positioning, don't want to move too fast. //Must crawl from current position to target position //but also avoid using "delay" cmd, that just freezes up microcontroller //servo 1 if ((millis() - servo1_time)> 20) { if (servo1_pos_cur> servo1_target) { servo1_pos_cur =servo1_pos_cur - 1; } if (servo1_pos_cur 20) { if (servo2_pos_cur> servo2_target) { servo2_pos_cur =servo2_pos_cur - 1; } if (servo2_pos_cur 20) { if (servo3_pos_cur> servo3_target) { servo3_pos_cur =servo3_pos_cur - 1; } if (servo3_pos_cur 60000) { conn_ok =client.connected(); if (conn_ok==1) { digitalWrite(statusPin, HIGH); Serial.println("MQTT connected OK"); } else { digitalWrite(statusPin, LOW); Serial.println("MQTT NOT connected OK"); } //no connection, reconnect if (conn_ok ==0) { client.disconnect();延迟(5000); while (client.connect("smarthouse") !=1) { digitalWrite(statusPin, LOW); Serial.println("Error connecting to MQTT"); delay(4000); } digitalWrite(statusPin, HIGH); } //Serial.println("reconnected to MQTT"); MQTT_reconnect =millis(); client.publish("smarthouse","heartbeat every minute!"); }//end Mosquitto connection check} // end of loop
energy_monitor_yun.inoPlain text
/*Eric Tsai2015-04-22Arduino Yun code for publishing energy use to MQTT brokerModify the "PubSubClient client" for your broker IP address*/#include#include #include #include "EmonLib.h" // OpenEnergy Monitor project libraryint LED =3;EnergyMonitor emon1; // open energy monitorunsigned long MQTT_reconnect=0;unsigned long read_energy=0;double Irms;bool conn_ok;YunClient yun; //equivalent of ethernet client//really shouldn't need call back, but just in case it's needed.void callback(char* topic, byte* payload, unsigned int length) { digitalWrite(LED, HIGH); // turn the LED on (HIGH is the voltage level) delay(500); // wait for a second digitalWrite(LED, LOW); // turn the LED off by making the voltage LOW}//use yunclient to bridge to networkPubSubClient client("192.168.1.101", 1883, callback, yun);//**********************************************************************void setup(){ // initialize digital pin 13 as an output. pinMode(LED,输出); digitalWrite(LED, HIGH); // turn the LED on (HIGH is the voltage level) delay(1000); // wait for a second digitalWrite(LED, LOW); // turn the LED off by making the voltage LOW Bridge.begin(); client.connect("yun_energy"); client.publish("watch", "Energy Monitor Connected!"); client.subscribe("yun_energy"); digitalWrite(LED, HIGH); // turn the LED on (HIGH is the voltage level) delay(3000); // wait for a second digitalWrite(LED, LOW); // turn the LED off by making the voltage LOW emon1.current(5, 60); // Current:input pin, calibration.}//**********************************************************************void loop(){ char buff_message[12]; //message buffer for MQTT publish float value; client.loop(); //run this every loop to maintain MQTT connection Irms =emon1.calcIrms(1480); // Calculate Irms only, 1480 means read Irms. //publish current every 10 seconds. if (millis() - read_energy> 10000) { //amps value =Irms; dtostrf (value, 4, 5, buff_message); client.publish("2853", buff_message); read_energy =millis(); //watts value =Irms*115; dtostrf (value, 4, 5, buff_message); client.publish("2852", buff_message); } //maintain MQTT connection if ((millis() - MQTT_reconnect)> 60000) { conn_ok =client.connected(); if (conn_ok==1) { digitalWrite(LED, HIGH); } else { digitalWrite(LED, LOW); } //no connection, reconnect if (conn_ok ==0) { client.disconnect();延迟(5000); while (client.connect("yun_energy") !=1) { delay(4000); } digitalWrite(LED, HIGH); client.publish("watch", "Energy Monitor reconnected"); } MQTT_reconnect =millis(); }//end Mosquitto connection check }
示意图



制造工艺