作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
本ESP8266 Arduino教程的目的是熟悉 Arduino嵌入式编程 在制造商社区(和一般的开发人员)中变得超级流行的芯片上 可访问性 以及在物联网领域的易用性. 本教程还让我们的手脏与亚莉克莎使用非官方的“黑客”,让亚莉克莎做我们的投标在家里(这种技术是不打算在生产中使用, 只适用于家庭示范). 在家里试试,但不要在工作中.
这项技术的美妙之处在于,我们可以在自己的家中使用它,让亚莉克莎几乎自动化任何用电的东西. 作为额外的奖励, 我们将深入了解Arduino的嵌入式编程, 这一技能在当今的主流程序员中可能并不常见. 最后,我们将与受欢迎的人一起工作 ESP8266芯片, a favorite among do-it-yourselfers; it’s an amazing little chip with ability to run all sorts of things, 内置了我们在这个项目中需要的Wifi芯片. 这将使亚莉克莎设备和芯片能够直接相互通信.
关于亚莉克莎编程的一些背景知识:亚莉克莎“技能”编程模型是这样工作的:
的 亚莉克莎 “skill” takes over h和ling of the comm和; normally it results in a response being sent back to the 亚莉克莎 device, 使它对用户作出回应. 以亚莉克莎物联网为例, 该命令被路由到亚马逊云上的“设备影子”, 这最终会导致响应被发送到您家中的其他设备. 我们用黑客绕过了所有这些. 我们想让亚莉克莎设备直接与我们的ESP8266芯片对话, 在我们的家里, 无需向云端发送任何信息,也无需返回. 我们希望亚莉克莎直接向我们的ESP8266发送请求, 只能在我们家的wifi网络内使用.
我们的黑客并不是什么秘密. 我们将使ESP8266“模拟”a Wemo贝尔金, 这款设备获得了亚马逊的特殊许可,可以直接与亚莉克莎设备进行通信, 绕过上面描述的所有亚马逊云通信.
假装自己是Wemo, 我们的ESP8266享有能够直接从亚莉克莎接收命令的特权.
要完成本教程, 你需要自己去买一些东西, 所有这些都很容易获得.
使用Boards Manager安装ESP8266库:
转至董事会经理(工具 -> Board: [current board] -> Boards Manager).
Arduino提供了许多不同的方法来将外部库添加到项目中, 或“草图,他们是这么说的. 让事情尽可能的简单, 对于本教程, 我们会用最快的速度解释, 哪一个是简单地复制文件夹. 我们需要为教程添加两个外部库: IRemoteESP8266 和 http://github.com/me-no-dev/ESPAsyncTCP.
现在项目中包含了用于IR传输和异步TCP的库.
下图显示了典型的设置,这些设置适用于我和我的硬件,但可能因每个用户而异. 您可以尝试下面的设置, 但是,您可能需要根据您的特定芯片和适配器来调整它们. 例如,我的是nodemcu,因此我必须将重置方法从“ck”(默认值)更改为“nodemcu”.此外,将“调试端口”设置为“serial”,以便您可以使用串行调试器. 我的是一个非常典型的设置, so you can use my settings as a base; I’m just saying don’t be surprised if you have to mess with them to get the compile 和 flash process to work.
Arduino项目从一个 .进气阀打开文件. 的 .每个文件定义了两个入口点:setup和loop. 对于我们的" hello world ", 我们要打开一盏灯, 在ESP8266上, 只是为了验证我们的代码是否有效.
//设置为匹配你的硬件
#define SERIAL_BAUD_RATE 9600
#定义LED_PIN
/*---------------------------------------*/
//运行一次,当设备上电或代码刚刚闪过
无效的设置()
{
//如果设置错误,你的串行调试器将不可读
串行.开始(SERIAL_BAUD_RATE);
pinMode (LED_PIN、输出);
}
/*---------------------------------------*/
/ /运行不断
无效循环()
{
digitalWrite (LED_PIN、低);
延迟(1000);
digitalWrite (LED_PIN、高);
延迟(1000);
}
如果到目前为止您的设置是正确的,编译和flash步骤很简单. 要编译而不闪烁,只需转到 Sk等h -> Verify/Compile 从Arduino菜单中.
若要将代码闪烁到芯片并进行编译,请选择 Sk等h -> Upload 从Arduino菜单中.
如果flash成功, 您将看到进度显示从0%变为100%, 在此期间,芯片上的LED很可能会闪烁或闪烁.
要测试串行调试是否工作:
串口调试器启动成功后的输出:
Great, so that works; next, we want to verify our IR output. 让我们通过红外发射器发送一个信号,并验证信号是否通过.
我们要利用现有的 Arduino IR库 来帮助我们. Arduino的一个伟大之处在于,它很容易将库和模块放入和取出. 对于c++框架来说非常令人耳目一新!
只需按照Git repo的README文件中的说明在Arduino中安装即可.
这个代码只是在红外发射器上反复闪烁. 红外线是人眼看不见的, but there’s a pro-tip for testing it; run this code, 验证(通过调试器)它是否在芯片上运行, 然后打开手机的摄像头. 直接看红外二极管灯泡 透过你的相机. 如果它是工作的,你应该看到灯泡明显地打开和关闭. 你也可以在任何工作的遥控器上尝试这个方法.g.(标准电视遥控器). 下面的代码将导致IR灯泡开始每0闪烁一次.5秒. 实际上它发送LG开/关命令, 所以如果你的LG电视在附近,它可能会打开或关闭它.
#include // IR Library
IRsend* irSend; // infrared sender
//设置为匹配你的硬件
#define SERIAL_BAUD_RATE 9600
//引脚0是芯片上的D3
#定义IR_PIN 0
/*---------------------------------------*/
//运行一次,当设备上电或代码刚刚闪过
无效的设置()
{
//如果设置错误,你的串行调试器将不可读
串行.开始(SERIAL_BAUD_RATE);
//初始化IR
irSend = new irSend (IR_PIN, true);
irSend->begin();
}
/*---------------------------------------*/
/ /运行不断
无效循环()
{
irSend->sendNEC(0x20DF10EF, 32, 3);
延迟(1000);
}
如果到目前为止一切顺利的话, 我想我们可以感到满意的是,我们的基本设备和装置都在工作, 我们已经准备好开始本教程的主要内容了.
首先,我们需要连接到本地wifi. 下面的代码将尝试连接到Wifi, 并报告连接成功(通过串行调试器). 在代码示例中, 不要忘记将mywiissid的值替换为您的wifi网络的用户名, 并用正确的密码替换myWifiPassword的值.
#包括“调试.//串行调试器打印
#包括“WifiConnection.// Wifi连接//这个文件是我的教程代码的一部分
#include // IR library
WifiConnection* wifi; // wifi connection
IRsend* irSend; // infrared sender
//设置wifi信号
const char* mywiwiid = "***";
const char* myWifiPassword = "*******";
//设置为匹配你的硬件
#define SERIAL_BAUD_RATE 9600
//引脚0是芯片上的D3
#定义IR_PIN 0
/*---------------------------------------*/
//运行一次,当设备上电或代码刚刚闪过
无效的设置()
{
//如果设置错误,你的串行调试器将不可读
串行.开始(SERIAL_BAUD_RATE);
//初始化wifi连接
wifi =新wifi连接(mywifiid, myWifiPassword);
wifi->begin();
//连接wifi
if (wifi->connect())
{
debugPrint(“无线连接”);
}
}
/*---------------------------------------*/
/ /运行不断
无效循环()
{
}
连接? 好. 现在我们进入项目的核心部分:Wemo服务器.
我自己的Wemo模拟器包含在本教程的源文件中. 现在,您可以搜索Google并找到一个更简单的Wemo模拟器. 你可以找到一个用更少的代码编写的,而且很容易理解. 无论如何,你可以自由地检查、实验、写你自己的文章等等. 这就是让本教程成为你自己的一部分.
我的原因是它使用了ESPAsyncTCP. 为什么这是好的? 好吧, 在ESP8266开始变得不可靠之前,您只能使用这种方法在ESP8266上运行这么多服务器(或设备), 从某种意义上说,亚莉克莎会开始丢失设备(而不是找到它们), 命令将被丢弃, 性能变慢. 我发现这个数字是通过使用ESPAsyncTCP库最大化的.
没有它, I’ve found unreliability to creep in at around 10-12 devices; with it, 我发现这个数字高达16个左右. 如果您想扩展本教程并探索芯片可以做的限制, 我建议使用我的版本. 如果你想看一个简单的版本,只是为了你自己的理解, feel free to search “wemo emulator Arduino” on Google; you should find a host of examples.
现在,我们要安装 ESPAsyncTCP图书馆. Install it just as we did the IR library; go to the Git page 和 follow the instructions.
这个库也包含在我的esp8266 arduino示例代码中. 这是打开wifi连接的代码, 监听亚莉克莎发现请求, 并通过返回“I am Wemo”响应来处理它.
#包括“调试.//串行调试器打印
#包括“WifiConnection.h”// Wifi连接
#包括“Wemulator.//我们的Wemo模拟器
#include // IR library
WifiConnection* wifi; // wifi connection
Wemulator* wemulator; // wemo emulator
IRsend* irSend; // infrared sender
//设置wifi信号
const char* mywiwiid = "***";
const char* myWifiPassword = "*******";
//设置为匹配你的硬件
#define SERIAL_BAUD_RATE 9600
//引脚0是芯片上的D3
#定义IR_PIN 0
/*---------------------------------------*/
//运行一次,当设备上电或代码刚刚闪过
无效的设置()
{
//如果设置错误,你的串行调试器将不可读
串行.开始(SERIAL_BAUD_RATE);
//初始化wifi连接
wifi =新wifi连接(mywifiid, myWifiPassword);
wifi->begin();
//初始化IR
irSend = new irSend (IR_PIN, false);
irSend->begin();
//初始化wemo模拟器
wemulator = new wemulator ();
//连接wifi
if (wifi->connect())
{
wemulator->begin();
//启动wemo仿真器(它作为一系列网络服务器运行)
wemulator->addDevice("tv", 新WemoCallbackH和ler (&comm和Received));
wemulator->addDevice("television", 新WemoCallbackH和ler (&comm和Received));
wemulator->addDevice("my tv", 新WemoCallbackH和ler (&comm和Received));
wemulator->addDevice("my television", 新WemoCallbackH和ler (&comm和Received));
}
}
/*---------------------------------------*/
/ /运行不断
无效循环()
{
//让wemulator监听语音命令
if (wifi->is连接)
{
wemulator->listen();
}
}
测试我们到目前为止(wifi和模拟器),通过运行它与亚莉克莎. 本教程假设您的亚莉克莎设备已设置并安装在家中.
测试发现:
对亚莉克莎说, “亚莉克莎,发现设备.”
这将导致亚莉克莎在本地wifi网络上广播UDP请求, 扫描Wemos和其他兼容设备. 这个请求应该在调用中被接收 wemulator->listen();
在循环()函数中. 这反过来将它路由到Wemulator的 h和leUDPPacket (*)
方法. 中发出响应 nextUDPResponse ()
方法. 请注意该答复的内容:
const char UDP_TEMPLATE[]程序=
“HTTP / 1.1 200 OK\r\n"
“cache - control:信息= 86400 \ r \ n”
"日期:2016年11月20日星期日00:00:00 GMT\r\n"
“EXT: \ r \ n”
“地点:http://%s: % d /设置.xml \ r \ n”
“选择:\”http://schemas.“.org/“/1/0/\"; ns=01\r\n"
“01-NLS: % s \ r \ n”
"SERVER: Unspecified, UPnP/1 ..0,不明\ r \ n”
“圣:urn:贝尔金:设备:* * \ r \ n”
“USN: uuid: Socket-1_0 - % s:: urn:贝尔金:装置:* * \ r \ n \ r \ n”;
这是告诉亚莉克莎“我是Wemo (Belkin),我能帮你什么吗??一旦亚莉克莎收到这个回复, 它知道并记住未来的智能家居命令可能会路由到这个设备.
此时串行调试器的输出应该如下图所示. 当发现结束时, 亚莉克莎会口头告诉你,它已经在你的网络上“发现了[N]台设备”.
在 设置()
函数,请注意下面的代码片段:
新WemoCallbackH和ler (&comm和Received)
这是我们将从亚莉克莎捕获命令的回调. 它的主体在WemoCallbackH和ler中定义.h (WemoCallbackH和ler:: h和leCallback). 一旦我们捕获了亚莉克莎的命令,我们就可以随心所欲地使用它. 在此之前的行中,我们设置了可能使用的命令,使用这些代码行:
wemulator->addDevice("tv");
wemulator->addDevice("television");
wemulator->addDevice("my tv");
wemulator->addDevice("my television");
这是我们在芯片上运行的4个独立的“服务器”或监听器. 这设置了对亚莉克莎说以下任何命令的能力:
亚莉克莎,打开电视 亚莉克莎,关掉电视 亚莉克莎,打开电视 亚莉克莎,关掉电视 亚莉克莎,打开我的电视 亚莉克莎,关掉我的电视 亚莉克莎,打开我的电视 亚莉克莎,关掉我的电视
这就是我们测试它的方法. 我们期望说这些命令中的任何一个都应该唤醒我们的代码并进入回调, 我们可以用它做我们想做的事吗.
现在我们收到了命令,是时候通过打开/关闭电视来处理它了. 所以这将是所有的东西——wifi, wemo模拟器和ir——都放在一起. 我的电视是LG的, 所以我查找了合适的打开/关闭顺序, 并通过我们IR库的sendNEC函数发送(LG使用NEC协议). 红外编码/解码本身是一个独立的主题, wherein a message is encoded in the modulation of a signal; it’s a specification of very precise timings, 标志着, 和空间. 每个制造商都倾向于使用自己专有的命令协议, 和 with different timings; it’s quite interesting, 您可以通过查看IR库的源代码进行更深入的研究, 谷歌等. 但是为了方便起见,所有这些细节都由我们的IR库来处理.
你的电视不是LG的? 只要谷歌正确的代码. 以下是索尼电视的命令(注意:未经测试):
irSend.sendSony (0 xa90, 12);
如果你真的想自己动手, 你可以设置一个红外接收器, 把你的遥控器(或任何红外发射器)对准它, 和 decode the codes that it’s sending; that’s a different tutorial, 虽然.
亚莉克莎应该理解你的命令(作为智能家居命令), 不是针对特定技能的), 请搜索本地设备来处理, 并将命令发送到设备(您的ESP8266). 您的设备应该接收到它并将远程控制命令发送到电视. 你可以通过手机摄像头查看你的二极管,以确保它在发光.
因为关掉电视的红外编码和打开电视的编码是一样的, 不管你是下“开”还是“关”的命令都没有关系.“这是相同的代码,它切换状态. 如果电视是关着的,它应该开着,如果开着,它应该关着.
您是否在正确的变量值中输入了正确的用户名/密码?
//设置wifi信号
const char* mywiwiid = "***";
const char* myWifiPassword = "*******";
您是否收到了失败消息, 或任何错误通过串行调试端口, 连接到Wifi时?
你的Wifi打开了吗?你可以通过其他普通方式连接吗?
当你说“亚莉克莎,发现设备”时,亚莉克莎就会发出发现设备的请求.”
您的亚莉克莎必须正确配置和设置,并连接到与ESP8266相同的Wifi网络.
看看Fauxmo.h. 参见函数Fauxmo::h和le(). 这是ESP8266听到调用后将运行的第一个代码. 放入调试消息,看看是否有任何代码
if (len > 0)
{
正在运行. 如果不是,则没有接收到该命令. 如果是,则似乎收到了命令,但没有正确处理. 按照代码查找问题所在.
在您的网络中有许多其他可发现的设备吗? 太多会导致发现运行得更慢,甚至有时会失败.
当你发出命令“亚莉克莎,打开我的电视”时,执行应该会进入你的 WemoCallbackH和ler: h和leCallback处理程序
(在WemoCallbackH和ler中.h文件). 如果你还没有这样做, 尝试在其中输出一些调试消息,以确保在发出命令时它被触发. 也, 试着通过说“亚莉克莎”来确保亚莉克莎知道你的设备, “发现设备”,然后再发出命令. 此步骤假设设备发现成功.
如前所述, 当你认为你的设备应该发出信号时, 将手机的摄像头对准它,通过摄像头观察二极管. 虽然在现实生活中你什么也看不见, 通过相机,它应该显示为一个正常的光点亮和闪烁. 如果你看到这个,那么它在发射…什么东西.
你的红外二极管可能以这样一种方式布线,信号本质上是反向的. 请容忍我的解释, 因为我不是搞电子或电线的, 但错误接线二极管的结果将是红外光将默认打开, 但当IRSend库打算打开它时,它会关闭. 如果是这种情况,默认情况下,您的红外线灯应该是亮的(通过相机可见) 设置()
代码运行,但在任何其他事情发生之前. 的所有代码都注释掉 循环()
,你应该会看到它一直亮着.
要更清楚地了解如何解决这个问题,请进入 库/ IRemoteESP8266 / src 教程代码文件夹. 参见构造函数:
IRsend::IRsend(int16_t IRsendPin, bool倒):IRpin(IRsendPin),
periodOffset (PERIOD_OFFSET)
{
如果(倒)
{
outputOn = LOW;
outputOff = HIGH;
}
其他的
{
outputOn = HIGH;
outputOff = LOW;
}
}
“反向”论证和处理它的逻辑就是我们要讨论的. 如果你的线路是反向的, 最简单的解决方案是在代码中做一个小的改变来允许这一点(而不是重新布线……当然,如果你喜欢的话,你可以这样做)。. 只需在亚莉克莎TvRemote中更改这一行.伊诺:
//初始化IR
irSend = new irSend (IR_PIN, false);
to
//初始化IR
irSend = new irSend (IR_PIN, true);
如果一切顺利的话, 但电视就是不听话, 很有可能是红外代码出了问题. 在该IR库接口上尝试不同的函数调用(例如.g., sendLG
, sendPanasonic
, sendSharp
等.),或者确保你使用的那个与你的硬件匹配. 你的电视硬件不受该库支持的可能性非常小, 但我想这在技术上是可行的.
确保您发送的代码是适合您的硬件的代码. 你可能需要在谷歌上做一些挖掘才能找到合适的. 如果一切都失败了, 总是可以选择检测从您的工作远程发出的代码, 当你按下电源按钮时——但这是一个不同的教程,需要不同的硬件.
希望你一切顺利. 如果是这样(即使不是), 这是一个很好的方法,可以让你同时掌握几个科目:
当然还有, 你可能有一点方便, 能够通过语音命令打开/关闭电视.
为什么这是一个黑客,而不是亚莉克莎的基本API的一部分? 在学习如何开发我的第一个亚莉克莎技能之后, 我真正想知道的是“我如何直接从亚莉克莎发送命令到网络上的另一台设备。?“很遗憾,亚马逊没有为亚莉克莎设备和本地网络上的其他对象之间的通信提供成熟的API, 无需经历“技能”或“智能家居”范式(其中所有内容都必须在执行任何操作之前发送到AWS)。, 但事实并非如此.
尝试一套远程控制命令来更全面地控制你的电视, 如改变频道和控制音量. 通过查看在一个ESP8266上可以监听多少不同的命令来测试芯片的极限(提示:这个数字几乎没有突破两位数), 没有一些非常聪明的程序). 如果你擅长使用硬件,那就试着控制其他设备 不 through IR, by wiring them directly to ESP8266芯片s; like lighting 和 such. 重塑女性!
物联网设备可以使用任何标准的服务器对服务器或客户端-服务器协议在网络上进行通信, 比如直接TCP, HTTP, TLS, 网络 sockets等. 他们还可以使用本地wifi,依靠UDP、TCP或其他协议. 物联网设备使用红外信号进行通信也并不罕见.
随着摩尔定律继续使计算能力变得便宜,它也将变得无处不在. 确实如此, 我们可以期待看到普通物体变得“聪明”或“有意识”,这确实是我们开始看到的. 程序员掌握这一点很重要,因为这清楚地表明了行业的发展方向.
Arduino是一个流行的开发平台,它弥合了硬件和软件之间的差距. 它无处不在,简单,并且可以在不同的硬件平台上使用. 物联网中流行的两个平台是ESP8266和ESP32. 利用这个标准的项目是Arduino项目.
物联网范式的全部要点是,一切都可能变得“智能”,因此成为物联网框架的一部分. 灯泡、咖啡机、电视等.,通常连接到物联网系统. 还有各种集线器和连接器,如Wemo贝尔金或亚马逊亚莉克莎产品.
世界级的文章,每周发一次.
世界级的文章,每周发一次.