亲,“电路城”已合并升级到更全、更大、更强的「新与非网」。点击查看「新与非网」

本网页已闲置超过3分钟,按键盘任意键或点击空白处,即可回到网页

利用Alexa和物联网云控制你的电视

发布时间:2022-11-01
分享到:

利用Alexa和物联网云控制你的电视

发布时间:2022-11-01
分享到:

本文将教你让电视学习如何使用Arduino IoT Cloud和Amazon Alexa切换频道,调整音量和打开或关闭任何电视。

介绍

Arduino IoT云
Arduino IoT Cloud是一个平台,可以让任何人轻松构建物联网连接对象。为了使用Alexa控制我们的电视,我们还将使用官方Arduino Alexa 。

第一部分:如何控制电视机
控制任何一种电视最简单的方法,就是把我们当成它自己的遥控红外控制器。为了做到这一点,我们必须监听遥控器将发送的信号,捕获数据,并用我们的Arduino板模仿它。一旦电路组装好,我们就把这张草图上传到黑板上。它将把远程按钮按下所产生的红外信号转换为无符号整数数组。让我们将遥控器对准我们制作的Arduino IR接收器,并按下以下按钮:

  • 电源/待机
  • 频道从1到9
  • 音量加
  • 音量减
  • 频道上
  • 频道下

我们将看到通过串行监视器传入的值,报告为rawData。现在让我们将它们记录到一个文本文件中,并为每个列表分配自己的数组名(chan1、chan2等等)。以下值仅供参考,由三星电视遥控器生成。

CHANNEL 1
unsigned int chan1[67] = {4450,4500, 550,1700, 500,1700, 550,1700, 550,550, 550,600, 500,600, 550,550, 550,600, 500,1700, 550,1700, 550,1700, 500,600, 500,600, 550,550, 550,600, 500,600, 550,550, 550,600, 500,1700, 550,600, 500,600, 550,550, 550,600, 500,600, 550,1700, 500,1700, 550,600, 500,1700, 550,1700, 550,1700, 500,1700, 550,1700, 500};
CHANNEL 2
unsigned int chan2[67] = {4500,4500, 550,1700, 500,1700, 550,1700, 550,550, 550,550, 550,600, 500,600, 550,600, 500,1700, 550,1700, 500,1700, 550,600, 500,600, 550,550, 550,600, 500,600, 550,1700, 500,600, 550,1700, 500,600, 550,550, 550,600, 500,600, 550,550, 550,650, 450,1700, 550,600, 500,1700, 550,1700, 500,1700, 550,1700, 550,1700, 500};
CHANNEL 3
unsigned int chan3[67] = {4500,4500, 500,1700, 550,1700, 550,1700, 500,600, 550,550, 550,600, 500,600, 550,550, 550,1700, 500,1700, 550,1700, 550,550, 550,600, 500,600, 550,550, 550,600, 500,600, 550,1700, 500,1700, 550,600, 550,550, 550,550, 550,600, 550,550, 550,1700, 500,600, 550,550, 550,1700, 550,1650, 550,1700, 550,1700, 500,1700, 600};
CHANNEL 4
unsigned int chan4[67] = {4450,4450, 550,1700, 550,1700, 500,1700, 550,600, 500,600, 550,550, 600,550, 500,600, 550,1700, 500,1700, 550,1700, 550,550, 550,600, 500,600, 550,550, 550,600, 500,600, 550,550, 550,600, 500,1700, 550,600, 500,600, 550,550, 550,600, 500,1700, 550,1700, 550,1700, 500,600, 550,1700, 500,1700, 550,1700, 550,1700, 500}; 
CHANNEL 5
unsigned int chan5[67] = {4500,4500, 500,1700, 550,1700, 550,1700, 550,550, 550,550, 550,550, 600,550, 550,550, 550,1700, 550,1650, 550,1700, 550,550, 550,600, 500,600, 550,550, 550,600, 500,1700, 550,600, 500,600, 550,1700, 500,600, 550,550, 550,600, 550,550, 550,550, 550,1700, 550,1700, 500,600, 550,1700, 500,1700, 550,1700, 550,1700, 500}; 
CHANNEL 6
unsigned int chan6[67] = {4500,4500, 550,1650, 550,1700, 550,1700, 500,600, 550,550, 550,600, 500,600, 500,600, 550,1700, 500,1700, 550,1700, 550,550, 600,550, 500,600, 550,550, 600,550, 550,550, 550,1700, 500,600, 550,1700, 500,600, 550,550, 550,600, 500,600, 550,1700, 500,600, 550,1700, 500,600, 550,1650, 600,1650, 550,1700, 550,1650, 600}; 
CHANNEL 7
unsigned int chan7[67] = {4500,4500, 550,1700, 500,1700, 550,1750, 500,550, 550,600, 500,650, 500,550, 550,550, 550,1750, 500,1700, 500,1700, 550,650, 450,650, 500,550, 550,600, 500,650, 500,550, 550,600, 500,1700, 550,1750, 500,600, 500,550, 550,600, 500,650, 500,1750, 450,1700, 550,600, 500,650, 500,1700, 500,1700, 550,1750, 500,1700, 500}; 
CHANNEL 8
unsigned int chan8[67] = {4450,4550, 500,1700, 550,1700, 550,1650, 550,600, 500,600, 550,550, 550,600, 500,600, 550,1700, 500,1700, 550,1700, 550,550, 550,600, 500,600, 550,550, 550,600, 500,1700, 550,600, 500,1700, 550,1700, 500,600, 550,550, 550,650, 450,600, 550,550, 550,1700, 550,550, 550,600, 500,1700, 550,1700, 550,1700, 500,1700, 550}; 
CHANNEL 9
unsigned int chan9[67] = {4450,4500, 550,1700, 550,1700, 500,1700, 550,600, 500,600, 550,550, 550,600, 500,600, 550,1700, 500,1700, 550,1700, 500,600, 550,550, 550,600, 500,600, 550,550, 550,600, 500,1700, 550,1700, 550,1700, 500,600, 550,550, 550,550, 550,600, 500,1700, 550,600, 500,600, 550,550, 550,1700, 550,1700, 500,1700, 550,1700, 550}; 
VOLUME UP
unsigned int volUp[67] = {4500,4500, 550,1700, 500,1750, 500,1700, 550,600, 500,600, 500,600, 550,550, 550,600, 500,1700, 550,1700, 550,1700, 500,650, 450,600, 550,600, 500,650, 450,650, 500,1700, 500,1750, 500,1750, 500,550, 550,600, 500,650, 500,550, 550,600, 500,650, 500,600, 500,600, 500,1700, 550,1750, 450,1750, 500,1700, 550,1700, 500}; 
VOLUME DOWN
unsigned int volDown[67] = {4450,4550, 500,1700, 550,1700, 550,1650, 550,600, 550,550, 550,600, 500,600, 500,600, 550,1700, 500,1700, 550,1700, 550,550, 550,600, 500,600, 550,550, 550,600, 500,1700, 550,1700, 550,600, 500,1700, 550,600, 500,600, 500,600, 550,550, 550,600, 500,650, 500,1700, 500,650, 500,1700, 500,1750, 500,1700, 550,1700, 500}; 
CHANNEL UP
unsigned int chanUp[67] = {4500,4450, 550,1700, 550,1650, 550,1700, 550,550, 550,600, 550,550, 550,550, 600,550, 550,1650, 550,1700, 550,1650, 600,550, 550,550, 550,600, 500,600, 550,550, 550,550, 550,1700, 550,550, 600,550, 550,1650, 550,600, 550,550, 550,550, 550,1700, 550,550, 550,1700, 550,1700, 550,550, 550,1650, 600,1650, 550,1700, 550}; 
CHANNEL DOWN
unsigned int chanDown[67] = {4500,4450, 600,1650, 550,1700, 550,1650, 550,600, 550,550, 550,550, 550,600, 500,600, 550,1700, 500,1700, 550,1700, 550,550, 550,600, 550,550, 550,550, 550,550, 600,550, 550,550, 550,600, 500,600, 550,1650, 600,550, 550,550, 550,550, 600,1650, 550,1700, 500,1700, 600,1650, 550,550, 600,1650, 550,1700, 500,1700, 550};

第二部分:Arduino IoT云
从主Arduino IoT Cloud页面,我们将创建一个新事件,并为其分配一个有意义的名称。我们称它为TVRemoteController。然后我们将选择我们将要使用的板。对于本文,我们使用了Arduino Nano 33 IoT,但如果您有另一个兼容的板,也可以,只要记住,IR库的pinout和行为可能会改变。如果此时您无法看到您的板子,那么您可能已经跳过了我们上面提到的“入门”过程,如果是这种情况,请返回该过程。

完成之后,我们将向我们的东西添加一个属性,它将代表我们的电视机。在智能家居分类下,属性类型选择“TV”,设置为“读写”,在“更新”下选择“当值发生变化时”。

这里是我们的东西的属性视图在这里应该是这样的:

第三部分:Arduino网络编辑器
是时候点击“编辑草图”按钮了,它将带我们进入Web编辑器,在那里我们可以添加一些自定义代码到由IoT云自动生成的草图中。

首先我们必须包含的是Ken Shirriff的IR Remote库。

#include <IRremote.h>

然后,我们必须为通道设置一个二维数组,为所需的命令设置6个数组。如果您还记得,在第一部分中我们捕获了一些IR数据,现在我们将使用这些数据填充我们的数组

const unsigned int chan[9][67] = {
 {chan1},
 {chan2},
 {chan3},
 {chan4},
 {chan5},
 {chan6},
 {chan7},
 {chan8},
 {chan9}
};
const unsigned int volUp[67] = {...};  
const unsigned int volDown[67] = {...};
const unsigned int chanUp[67] = {...}; 
const unsigned int chanDown[67] = {...};
const unsigned int onoff[67] = {...};
const unsigned int mute[67] = {...};

然后让我们设置IR库和所需的频率(对于这种应用程序,它将始终是38KHz)

IRsend irsend;
const int freq = 38;

我们还需要一个函数来发送IR命令并闪烁内置LED(在这个阶段主要用于调试目的)。所使用的延迟值将取决于电视机的制造和型号,所以如果没有按照预期工作(错误的命令或没有收到命令),请尝试改动调整它。

void sendIR(const unsigned int buf[]) {
 digitalWrite(LED_BUILTIN, HIGH);
 irsend.sendRaw(buf, 67, freq);
 delay(300);
 digitalWrite(LED_BUILTIN, LOW);
}

最后一步是用一些自定义代码完成生成的回调onTvChange(),以便在Alexa命令改变电视属性时发送IR命令。例如,如果音量增加了,我们必须虚拟地按下音量上升按钮,如果通道设置为7,我们必须发送通道7按钮的序列,以此类推。

void onTvChange() {
 Serial.println("==================");
 Serial.println("Switch:"+String(tv.getSwitch()));
 Serial.println("Volume:"+String(tv.getVolume()));
 Serial.println("Channel:"+String(tv.getChannel()));
 Serial.println("Mute:"+String(tv.getMute()));
 Serial.println("==================");
 if (first){
     prevSwitch = tv.getSwitch();
     prevVolume = tv.getVolume();
     prevChannel = tv.getChannel();
     prevMute = tv.getMute();
     first = false;
     return;
 } 
 // Volume changed
 if (tv.getVolume() > prevVolume) {
   tv.setMute(false);
   prevMute = false;
   for (int k = prevVolume + 1 ; k<=tv.getVolume(); k++) {
     sendIR(volUp);
     Serial.println("Volume requested:"+String(tv.getVolume())+" Set:"+String(k));  
   }
   prevVolume = tv.getVolume();
 }
 else if (tv.getVolume() < prevVolume) {
   tv.setMute(false);
   prevMute = false;
   for (int k = prevVolume - 1; k>=tv.getVolume(); k--) {
     sendIR(volDown);
     Serial.println("Volume changed:"+String(tv.getVolume())+" Set:"+String(k));  
   }
   prevVolume = tv.getVolume();
 }
 // Mute changed
 if (tv.getMute() != prevMute && tv.getMute()) {
   prevMute = tv.getMute();
   sendIR(mute);
   Serial.println("Mute changed:"+String(tv.getMute()));
 }
 else if (tv.getMute() != prevMute && !tv.getMute()) {
   prevMute = tv.getMute();
   sendIR(mute);
   Serial.println("Mute changed:"+String(tv.getMute()));
 }
 // Channel changed
 if (tv.getChannel() != prevChannel) {
   int newChannel = tv.getChannel();
   if (newChannel > 0 && newChannel < 10) {
     sendIR(chan[newChannel-1]);
   } else if (newChannel > 9) {
     if (newChannel > prevChannel) {
       for (int ch = prevChannel; ch < newChannel; ch++) {
         sendIR(chanUp);
         Serial.println("Chan requested:"+String(newChannel)+" Set:"+String(ch));  
       }  
     } else if (newChannel < prevChannel) {
         for (int ch = prevChannel; ch > newChannel; ch--) {
           sendIR(chanDown);
           Serial.println("Chan requested:"+String(newChannel)+" Set:"+String(ch));  
         }
     }
   }
   prevChannel = newChannel;
   Serial.println("Channel changed:"+String(tv.getChannel()));
 }
 // On/Off changed
 if (tv.getSwitch() != prevSwitch) {
   prevSwitch = tv.getSwitch();
   if (tv.getSwitch()) {
     sendIR(chan[6]);
   } else {
     sendIR(onoff);
   }
   Serial.println("Switch changed:"+String(tv.getSwitch()));
 }

第四部分:Amazon Alexa
我们现在需要亚马逊Alexa应用程序,它可以从苹果应用程序商店或谷歌Play商店下载。安装完成后,使用现有帐户登录或创建一个新帐户。

让我们通过安装Arduino Alexa Skill并配置它访问和控制我们的电视的必要步骤。我们将按照下面的图像顺序查看所有必需的步骤。

我们完成了,现在是时候用语音控制我们的电视发出一些指令了:

“Alexa,把电视音量开大点。”
“Alexa,静音电视”或“Alexa,取消静音电视”。
“Alexa,下一个电视频道。”

希望你能用Alexa和物联网云玩得开心。

如果您对此项目有任何想法、意见或问题,请在下方留言。

以上内容翻译自网络,原作者:Ubi de Feo,如涉及侵权,可联系删除。

加入微信技术交流群

技术交流,职业进阶

关注与非网服务号

获取电子工程师福利

加入电路城 QQ 交流群

与技术大牛交朋友

讨论