本文概述
本ESP8266 Arduino教程的目的是熟悉在芯片上使用Arduino的嵌入式编程, 该芯片因其在IoT领域的可访问性和易用性而在制造商社区(和一般开发人员)中变得非常流行。本教程还通过非官方的” hack”使我们与Alexa交涉, 让Alexa在家里进行投标(此技术并非用于生产, 仅用于家庭演示)。在家尝试, 但不要在工作。
这项技术的优点在于, 我们可以在自己的房屋中使用它, 使Alexa几乎可以使几乎所有用电运行的东西实现自动化。另外, 我们还可以深入了解Arduino的嵌入式编程, 这项技能如今在主流程序员中可能并不常见。最后, 我们开始使用流行的ESP8266芯片, 这是”自己动手”的最爱。这是一个了不起的小芯片, 具有运行各种功能的能力, 并且内置了该项目需要的内置Wifi芯片。这将使Alexa设备和芯片直接相互通信。
只是Alexa编程的一些背景知识:Alexa”技能”编程模型的工作方式如下:
- 你与Alexa交谈。
- Alexa会将你的语音一直传回到亚马逊的云。
- 语音命令被路由到Alexa”技能”(在亚马逊云中运行的程序)。
Alexa的”技能”接管了命令的处理;通常, 它会导致将响应发送回Alexa设备, 从而使用户对响应说一些话。对于Alexa IoT, 该命令将路由到亚马逊云上的”设备影子”, 最终导致响应发送到你家中的其他设备。我们正在绕过所有黑客攻击。我们想让Alexa设备直接与我们家庭内部的ESP8266芯片通信, 而无需将任何数据发送到云端并返回。我们希望Alexa仅在家庭wifi网络内部和内部直接向ESP8266发送请求。
我们的hack并不是真正的秘密。我们将使ESP8266″模仿” Wemo Belkin, 这是一种具有Amazon特殊许可的设备, 允许它直接与Alexa设备进行通信, 而绕开了上述所有Amazon Cloud通信。
我们的ESP8266假装是Wemo, 享有直接从Alexa接收命令的特权。
ESP8266 Arduino教程的基本计划
- 在ESP8266上侦听Alexa设备, 以在本地wifi网络上发送探针以查找兼容的设备, 然后通过说”我是Wemo”来回应这些探针。
- 一旦被Alexa设备信任, 请侦听来自该设备的其他命令。通过通过红外线发射器发送红外线代码并打开/关闭电视来处理它们。
硬体需求
要完成本教程, 你将需要自己获得一些物品, 所有这些物品都很容易获得。
- 任何Alexa设备。我已经使用Alexa Dot开发了本教程。本教程可以与Echo模拟器一起使用吗?它可能! (但是我还没有测试过)。如果你喜欢冒险(或节俭), 请尝试一下。 Alexa设备需要零花钱, 但是免费使用Echosim。
- ESP8266芯片。在撰写本文时, 它们的成本仅为几美元。你可以在Ebay或几乎任何库存充足的硬件商店上购买它们。
- IR(红外)二极管。你需要将其连接到ESP8266芯片, 这需要你自己做。对于这个项目, 我们只需要发送功能;我们不在乎接收IR。确保将二极管连接到GND并输出0, 本教程才能正常工作。 (如果你采用其他任何方式, 也可以, 但你还必须负责相应地修改教程代码。此链接可能会对你有所帮助。请注意, 由于ESP8266上使用的编号方式, 引脚0可能会被标记为” D3″。
- 一个串行适配器, 一侧为USB(可插入你的开发计算机), 另一侧为ESP8266芯片。
- 你知道用户名和密码的本地wifi网络。
ESP8266连接到适配器, 在Echo Dot旁边
带红外二极管的ESP8266
Arduino软件工具
- Arduino IDE。有适用于所有主要操作系统的版本, 包括Windows。本教程是在Ubuntu版本上开发的, 但是我也已经在Windows上安装并使用了Arduino, 没有问题。
- 用于Arduino的ESP8266开发库。
- 司机。幸运的是, 适配器的驱动程序很可能是即插即用的, 因此不需要其他驱动程序。
设置一切
- 安装Arduino IDE。
- 使用Boards Manager安装ESP8266库。
要使用Boards Manager安装ESP8266库:
- 在Arduino IDE中, 打开文件->首选项。
- 在”其他委员会管理器URL”中输入以下URL:http://arduino.esp8266.com/stable/package_esp8266com_index.json
- 点击确定
转到董事会管理器(工具->董事会:[当前董事会]->董事会管理器)。
在”过滤器”文本框中, 键入” ESP8266″。
现在, 你已经添加了其他板管理器, 应该会获得” esp8266″的条目。选择它, 然后单击”安装”。
- 请稍等-下载所有内容都需要一些时间。
- 重新启动你的Arduino IDE。
- 打开”工具”->”开发板”:这次, 向下滚动到” Generic ESP8266 Module”并选择它。
添加第三方库
Arduino提供了许多不同的方法来将外部库添加到你的项目中, 或称其为” Sketch”。为了使事情尽可能简单, 在本教程中, 我们将以最快的速度进行说明, 即简单地复制文件夹。为了使本教程正常工作, 我们将需要添加两个外部库:IRemoteESP8266和https://github.com/me-no-dev/ESPAsyncTCP。
- 在GitHub中的教程代码中, 找到”库”目录。
- 在Arduino的根安装目录(例如C:\ Program Files \ Arduino)中, 找到”库”子目录。
- 将IRemoteESP8266目录从教程的”库”目录复制到Arduino的”库”目录。
- 将ESPAsyncTCP目录从教程的”库”目录复制到Arduino的”库”目录。
- 重新启动Arduino IDE。
现在, 该项目中包含用于IR传输和异步TCP的库。
设定值
下图显示了典型设置, 这些设置适用于我和我的硬件, 但可能因每个用户而异。你可以尝试以下设置, 但有可能可能必须根据特定的芯片和适配器进行调整。例如, 我的是nodemcu, 所以我不得不将重置方法从” ck”(默认)更改为” nodemcu”。另外, 将”调试端口”设置为”串行”, 以便可以使用串行调试器。我的是非常典型的设置, 因此你可以将我的设置用作基础。我只是说如果你要弄乱它们以使编译和刷新过程正常工作, 请不要感到惊讶。
使用ESP8266 Hello World验证设置
Arduino项目以.ino文件开头。 .ino文件定义了两个输入点:设置和循环。对于我们的” hello world”, 我们将在ESP8266上稍作点灯, 以验证我们的代码是否有效。
//SET TO MATCH YOUR HARDWARE
#define SERIAL_BAUD_RATE 9600
#define LED_PIN 2
/*---------------------------------------*/
//Runs once, when device is powered on or code has just been flashed
void setup()
{
//if set wrong, your serial debugger will not be readable
Serial.begin(SERIAL_BAUD_RATE);
pinMode(LED_PIN, OUTPUT);
}
/*---------------------------------------*/
//Runs constantly
void loop()
{
digitalWrite(LED_PIN, LOW);
delay(1000);
digitalWrite(LED_PIN, HIGH);
delay(1000);
}
编译并刷新代码
如果到目前为止的设置是正确的, 那么编译和刷新是简单的步骤。要编译而不闪烁, 只需从Arduino菜单转到Sketch-> Verify / Compile。
要将代码刷新到芯片上并进行编译, 请从Arduino菜单中选择Sketch-> Upload。
如果刷新成功, 你将看到进度显示从0%变为100%, 在此期间, 芯片上的LED最有可能实际上会闪烁或闪烁。
要测试串行调试是否有效:
- 首先, 确保将调试端口设置为串行(工具->调试端口)。
- 代码完成闪烁到芯片后, 选择工具->串行监视器。
成功启动后, 串行调试器的输出:
太好了, 这样行得通;接下来, 我们要验证我们的IR输出。让我们通过红外发射器发送信号, 并验证信号是否通过。
我们将利用现有的Arduino IR库来帮助我们。 Arduino的一大优点是, 将库和模块捕捉进出非常容易。 C ++框架令人耳目一新!
只需按照Git repo的README文件中的说明进行操作即可在Arduino中安装。
此代码只是重复闪烁红外发射器。 IR是人眼看不见的, 但是有测试它的提示。运行此代码, 验证(通过调试器)该代码正在你的芯片上运行, 然后打开移动设备的相机。通过相机直接看红外二极管灯泡。如果它可以正常工作, 则应该可以看到灯泡已打开和关闭。你也可以使用任何可用的遥控器(例如, 标准电视遥控器)来尝试此操作。以下代码应使IR灯泡每0.5秒开始闪烁一次。实际上, 它会发送LG开/关命令, 因此实际上可能会在附近打开和关闭LG电视。
#include <IRremoteESP8266.h> // IR Library
IRsend* irSend; // infrared sender
//SET TO MATCH YOUR HARDWARE
#define SERIAL_BAUD_RATE 9600
//PIN 0 is D3 ON THE CHIP
#define IR_PIN 0
/*---------------------------------------*/
//Runs once, when device is powered on or code has just been flashed
void setup()
{
//if set wrong, your serial debugger will not be readable
Serial.begin(SERIAL_BAUD_RATE);
//initialize the IR
irSend = new IRsend(IR_PIN, true);
irSend->begin();
}
/*---------------------------------------*/
//Runs constantly
void loop()
{
irSend->sendNEC(0x20DF10EF, 32, 3);
delay(1000);
}
开始ESP8266教程
如果到目前为止一切正常, 我认为我们对基本设备和设置都可以正常运行感到满意, 并且我们准备开始本教程。
连接到Wifi
首先, 我们需要连接到本地wifi。下面的代码将尝试连接到Wifi, 并报告连接成功(通过串行调试器)。在代码示例中, 请不要忘记用你的wifi网络的用户名替换myWifiSsid的值, 并使用正确的密码替换myWifiPassword的值。
#include "debug.h" // Serial debugger printing
#include "WifiConnection.h" // Wifi connection // this file is part of my tutorial code
#include <IRremoteESP8266.h> // IR library
WifiConnection* wifi; // wifi connection
IRsend* irSend; // infrared sender
//SET YOUR WIFI CREDS
const char* myWifiSsid = "***";
const char* myWifiPassword = "*******";
//SET TO MATCH YOUR HARDWARE
#define SERIAL_BAUD_RATE 9600
//PIN 0 is D3 ON THE CHIP
#define IR_PIN 0
/*---------------------------------------*/
//Runs once, when device is powered on or code has just been flashed
void setup()
{
//if set wrong, your serial debugger will not be readable
Serial.begin(SERIAL_BAUD_RATE);
//initialize wifi connection
wifi = new WifiConnection(myWifiSsid, myWifiPassword);
wifi->begin();
//connect to wifi
if (wifi->connect())
{
debugPrint("Wifi Connected");
}
}
/*---------------------------------------*/
//Runs constantly
void loop()
{
}
运行Wemo服务器
连接的?好。现在, 我们来了解项目的重点:Wemo服务器。
我自己的Wemo模拟器包含在本教程的源文件中。现在, 你可以搜索Google并找到一个更简单的Wemo模拟器。你可以找到使用更少的代码编写的代码, 而且它易于理解。无论如何, 请随时进行检查, 试验, 编写自己的内容, 等等。这些都是使本教程成为你自己的一部分。
我的背后的原因是它使用了ESPAsyncTCP。为什么这样好?好吧, 在这种方法变得不可靠之前, 你可以使用ESP8266在ESP8266上运行的服务器(或设备)如此之多, 从某种意义上说, Alexa将开始丢失设备(找不到它们), 命令将被丢弃, 并且性能变慢。我发现通过使用ESPAsyncTCP库可以使此数字最大化。
如果没有它, 我发现在大约10到12台设备中爬入是不可靠的;有了它, 我发现该数字最多可以达到16。如果你想扩展本教程并探索芯片功能的极限, 我建议使用我的版本。如果你只是想了解一个简单的版本, 请随时在Google上搜索” wemo emulator Arduino”;你应该找到许多示例。
现在, 我们必须安装ESPAsyncTCP库。像安装IR库一样安装它;转到Git页面并按照说明进行操作。
该库也包含在我的esp8266 arduino示例代码中。这只是打开wifi连接, 侦听Alexa发现请求并通过返回”我是Wemo”响应进行处理的代码。
#include "debug.h" // Serial debugger printing
#include "WifiConnection.h" // Wifi connection
#include "Wemulator.h" // Our Wemo emulator
#include <IRremoteESP8266.h> // IR library
WifiConnection* wifi; // wifi connection
Wemulator* wemulator; // wemo emulator
IRsend* irSend; // infrared sender
//SET YOUR WIFI CREDS
const char* myWifiSsid = "***";
const char* myWifiPassword = "*******";
//SET TO MATCH YOUR HARDWARE
#define SERIAL_BAUD_RATE 9600
//PIN 0 is D3 ON THE CHIP
#define IR_PIN 0
/*---------------------------------------*/
//Runs once, when device is powered on or code has just been flashed
void setup()
{
//if set wrong, your serial debugger will not be readable
Serial.begin(SERIAL_BAUD_RATE);
//initialize wifi connection
wifi = new WifiConnection(myWifiSsid, myWifiPassword);
wifi->begin();
//initialize the IR
irSend = new IRsend(IR_PIN, false);
irSend->begin();
//initialize wemo emulator
wemulator = new Wemulator();
//connect to wifi
if (wifi->connect())
{
wemulator->begin();
//start the wemo emulator (it runs as a series of webservers)
wemulator->addDevice("tv", new WemoCallbackHandler(&commandReceived));
wemulator->addDevice("television", new WemoCallbackHandler(&commandReceived));
wemulator->addDevice("my tv", new WemoCallbackHandler(&commandReceived));
wemulator->addDevice("my television", new WemoCallbackHandler(&commandReceived));
}
}
/*---------------------------------------*/
//Runs constantly
void loop()
{
//let the wemulator listen for voice commands
if (wifi->isConnected)
{
wemulator->listen();
}
}
预测试
通过与Alexa一起运行, 测试目前为止的产品(WiFi和仿真器)。本教程假定你已在家里设置并安装了Alexa设备。
测试发现:
对Alexa说:” Alexa, 发现设备。”
这将导致Alexa在你的本地wifi网络上广播UDP请求, 扫描Wemos和其他兼容设备。该请求应在对wemulator-> listen()的调用中收到;在loop()函数中。依次将其路由到Wemulator的handleUDPPacket(*)方法。在nextUDPResponse()方法中发送响应。注意该响应的内容:
const char UDP_TEMPLATE[] PROGMEM =
"HTTP/1.1 200 OK\r\n"
"CACHE-CONTROL: max-age=86400\r\n"
"DATE: Sun, 20 Nov 2016 00:00:00 GMT\r\n"
"EXT:\r\n"
"LOCATION: http://%s:%d/setup.xml\r\n"
"OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
"01-NLS: %s\r\n"
"SERVER: Unspecified, UPnP/1.0, Unspecified\r\n"
"ST: urn:Belkin:device:**\r\n"
"USN: uuid:Socket-1_0-%s::urn:Belkin:device:**\r\n\r\n";
这是告诉Alexa”我是Wemo(贝尔金)的代码, 我该如何帮助你?”的代码Alexa收到此响应后, 便会知道并记住将来的智能家居命令可能会路由到此设备。
此时串行调试器的输出应如下图所示。完成发现后, Alexa会口头告诉你它已在网络上”发现[N]个设备”。
在setup()函数中, 请注意以下代码段:
new WemoCallbackHandler(&commandReceived)
这是我们将从Alexa捕获命令的回调。它的主体在WemoCallbackHandler.h(WemoCallbackHandler :: handleCallback)中定义。从Alexa捕获命令后, 就可以使用它来完成所需的操作。在此之前的几行中, 我们使用以下代码行设置了可以使用的命令:
wemulator->addDevice("tv");
wemulator->addDevice("television");
wemulator->addDevice("my tv");
wemulator->addDevice("my television");
因此, 这些是我们在芯片上运行的4个独立的”服务器”或侦听器。这样可以设置对Alexa说以下任何命令的能力:
Alexa, 打开电视Alexa, 关闭电视Alexa, 打开电视Alexa, 关闭电视Alexa, 打开我的电视Alexa, 关闭我的电视Alexa, 打开我的电视Alexa, 关闭我的电视
这就是我们将对其进行测试的方式。我们希望说任何这些命令都应该唤醒我们的代码并输入该回调, 我们可以在其中执行所需的操作。
添加IR命令
现在我们已经收到命令, 现在该是通过打开/关闭电视来处理它了。因此, 这一切-wifi, wemo仿真器和IR-都将放在一起。我的电视是LG, 因此我查找了打开/关闭的适当顺序, 并通过IR库的sendNEC功能(LG使用NEC协议)发送了该顺序。 IR编码/解码本身就是一个单独的主题, 其中消息是通过信号调制来编码的;这是非常精确的时间, 标记和空格的规范。每个制造商都倾向于使用其自己的专有协议来执行命令, 并且时序不同。这非常有趣, 你可以通过查看该IR库的源代码, 进行谷歌搜索等来进行更深入的研究。但是, 为了方便起见, IR库为我们提供了所有这些细节。
你的电视不是LG吗?只是谷歌正确的代码。这是Sony电视的命令(注意:未经测试):
irSend.sendSony(0xa90, 12);
如果你想自己动手做, 可以设置一个IR接收器, 将遥控器(或任何IR发射器)对准它, 并解码其发送的代码;但是, 那是另一本教程。
端到端测试
- 将Alexa放在可以听到你声音的任何地方。
- 将ESP8266和连接的红外二极管放在电视的遥控范围内。
- 说” Alexa, 发现设备”。等待它报告成功(它应该已经发现至少一台设备)。
- 说” Alexa, 打开电视”或” Alexa, 关闭电视”。
Alexa应该理解你的命令(作为智能家居命令, 不针对特定技能), 搜索用于处理该设备的本地设备, 然后将该命令发送到该设备(你的ESP8266)。你的设备应将其接收并将遥控器命令发送到电视。你可以通过手机摄像头查看二极管, 以确保其发光。
由于关闭电视的IR代码与打开电视的代码相同, 因此你发出命令”打开”还是”关闭”都没有关系。相同的代码, 并切换状态。如果电视关闭, 则应打开电视;如果电视打开, 则应关闭电视。
故障排除
你已连接到Wifi吗?
你是否在正确的变量值中输入了正确的用户名/密码?
//SET YOUR WIFI CREDS
const char* myWifiSsid = "***";
const char* myWifiPassword = "*******";
连接到Wifi时, 是否通过串行调试端口收到故障消息或任何错误?
你的Wifi是否已打开, 并且可以通过任何其他常规方式连接到它吗?
Alexa是否发现了你的设备?
当你说” Alexa, 发现设备”时, Alexa将发出发现设备的请求。
必须正确配置和设置Alexa, 并将其连接到与ESP8266相同的Wifi网络。
在Fauxmo.h中查看。参见函数Fauxmo :: handle()。这是ESP8266听到呼叫后将运行的第一个代码。放入调试消息以查看之后是否有任何代码
if (len > 0)
{
在跑。如果不是, 则说明没有收到命令。如果是, 则似乎正在接收命令, 但未正确处理。从那里按照代码查找问题所在。
你的网络上还有许多其他可发现的设备吗?太多会导致发现运行速度变慢, 甚至有时会失败。
你的设备收到命令了吗?
当你发出命令” Alexa, 打开电视”时, 执行应输入WemoCallbackHandler :: handleCallback处理程序(在WemoCallbackHandler.h文件中)。如果尚未执行此操作, 请尝试在其中输出一些调试消息, 以确保在发出命令时将其触发。另外, 在发出命令之前, 尝试说” Alexa, 发现设备”, 以确保Alexa知道你的设备。此步骤假定设备发现成功。
红外二极管发光吗?
如前所述, 当你认为设备应该发光时, 请将手机的摄像头对准它, 然后通过摄像头查看二极管。尽管在现实生活中你什么都看不到, 但是通过相机, 它应该像正常的灯光一样亮起并闪烁。如果看到此消息, 则表明它正在发射……某物。
红外信号是否反向?
你的IR二极管的接线方式可以使信号实质上反向。请谅解我, 因为我不是电子产品或接线人员, 但错误地连接二极管的结果将是默认情况下IR灯将打开, 但当IRSend库打算打开时将其关闭。它在。在这种情况下, 默认情况下, 在setup()代码运行之后, 但在其他任何事情发生之前, 你的红外灯应处于打开状态(可通过相机看到)。如果要注释掉loop()内的所有代码, 则应该看到它一直处于打开状态。
要更清楚地了解如何解决此问题, 请进入教程代码的library / IRemoteESP8266 / src文件夹。参见构造函数:
IRsend::IRsend(uint16_t IRsendPin, bool inverted) : IRpin(IRsendPin), periodOffset(PERIOD_OFFSET)
{
if (inverted)
{
outputOn = LOW;
outputOff = HIGH;
}
else
{
outputOn = HIGH;
outputOff = LOW;
}
}
我们所说的是”反向”参数和处理它的逻辑。如果你的接线颠倒了, 最简单的解决方案是在代码中做些小的改动以允许这样做(而不是重新接线……但是如果你愿意, 可以这样做)。只需在AlexaTvRemote.ino中更改此行:
//initialize the IR
irSend = new IRsend(IR_PIN, false);
to
//initialize the IR
irSend = new IRsend(IR_PIN, true);
你是否拥有正确的遥控器代码和命令?
如果其他一切似乎都没问题, 但电视没有服从, 则IR代码很可能有问题。在该IR库接口上尝试其他函数调用(例如sendLG, sendPanasonic, sendSharp等), 或确保你使用的函数与硬件相匹配。该库不太可能不支持你电视的硬件, 但我认为这在技术上是可行的。
确保你要发送的代码适合你的硬件。你可能需要在Google上进行一些挖掘才能找到合适的一个。如果所有其他方法均失败, 则始终可以选择在按下”电源”按钮时检测从工作遥控器发出的代码, 但这是不同的教程, 并且需要不同的硬件。
本文总结
希望一切都能为你解决。如果是这样(甚至可能不是这样), 那么这是一次在多个对象上同时割牙的好方法:
- Alexa
- 嵌入式编程
- ESP8266芯片
- Arduino IDE
当然, 当然, 你还可以通过语音命令打开/关闭电视, 这可能会带来一点便利。
为什么要骇客?
为什么这是黑客行为, 而不是Alexa基本API的一部分?在学习了如何发展我的第一个Alexa技能之后, 我真正想知道的就是”如何直接从Alexa向网络上的另一台设备发送命令?”令人遗憾的是, 亚马逊没有公开用于在Alexa设备与本地网络上的其他对象之间进行通信的完整API, 而没有经历”技能”或”智能家居”范式(其中所有内容都必须发送到AWS)在做任何事情之前), 但他们只是没有。
尝试进一步
尝试使用一套远程控制命令来更全面地控制电视, 例如更改频道和控制音量。通过查看你可以在一个ESP8266上监听多少个不同的命令来测试芯片的极限(提示:该数字几乎不破两位数, 无需进行一些非常聪明的编程)。如果你擅长使用硬件, 请尝试将其他设备直接连接到ESP8266芯片, 而不是通过IR控制其他设备;喜欢照明之类的。重塑wemo!
有关:
- 我如何制作功能齐全的Arduino气象站
- 使用ESP32音频采样
评论前必须登录!
注册