亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

使用 SmartThings ThingShield 构建 IR 桥

组件和用品

Arduino UNO
× 1
适用于 Arduino 的 SmartThings 扩展板
× 1
红外发光 LED
× 1
红外接收二极管
× 1
100 欧姆电阻(可选)
× 1

关于这个项目

简介

当连接到 SmartThings 云时,一个简单的电视遥控器能够进行更多的频道切换。该项目的零件数量很少,可立即获得回报,是探索该平台的好方法。

Arduino 和 ThingShield 的背景

SmartThings ThingShield 使使用 Arduino 构建 SmartThings 原型变得容易。屏蔽直接连接到通过 Zigbee 协议链接到 SmartThings 集线器的 UNO。屏蔽上的开关允许人们在使用引脚 0,1 或 2,3 与 Arduino 通信之间进行选择。 ThingShield 已保留使用引脚 6。

有关 Arudino 入门的更多信息:http://arduino.cc/en/Guide/Introduction

第 1 步:您需要

  • (x1) SmartThings Arduino ThingShield
  • (x1) Arduino Uno
  • (x1) 红外接收器
  • (x1) 红外发光 LED
  • (x1) 100 欧姆电阻器(可选)


第 2 步:下载 IR 库

该项目依赖于由 Ken Shirriff 开发的出色的 Arduino 库。 https://github.com/shirriff/Arduino-IRremote

以通常的方式安装库 Arduino 库。

http://arduino.cc/en/Guide/Libraries

安装后,我们需要修改 IRRemoteInt.h 以使用引脚 9 上的计时器。在此示例中,我们使用引脚 3 与 ThingShield 进行通信。


第 3 步:Arduino 草图

接下来,将草图上传到您的 Arduino 板(请参阅代码部分)。


第 4 步:构建

构建简单明了。首先将 ThingShield 连接到 Arduino 的顶部。虽然下图中只显示了 Arduino,但引脚位置与附加的屏蔽相同。

对于 IR 接收器,将相应的引脚连接到地和 5V。然后将数据引脚连接到 Arduino 引脚 11。将 IR 发射 LED 连接到引脚 9 和接地。在此设计中 100 欧姆电阻器是可选的,因为 LED 可能会处理来自 Arduino 的最大电流,因为它会快速闪烁以发送信号。一直开着,同样的电流很可能会烧坏LED。


第 5 步:创建自定义 SmartThings 设备类型

在 SmartThings IDE 中,我们接下来为我们的 ThingShield 创建一个新的设备类型。

进入“我的设备类型”部分,点击右侧的“新建智能设备”。

创建一个新的 SmartDevice 需要两个步骤。首先,在顶部为新设备类型命名“Ir Bridge”。请注意,稍后我们将在 SmartApp 代码中引用我们 SmartDevice 的名称。

我们需要定义设备的属性(变量)和命令(功能)。在本教程中,我们将为两个可编程按钮和一个录制按钮创建属性和命令。添加显示的每个属性和命令。选择“创建”以继续对设备进行编码。

接下来,将设备定义复制到 IDE 的代码窗口中(请参阅代码部分)。单击顶部的“保存”按钮,然后单击“发布”以使您可以使用该设备。


第 6 步:将 ThingShield 更新为您的新设备类型

如果尚未设置,请确保将 ThingShield 添加到 SmartThings 中心。要配对设备,请将 ThingShield 连接到您的 Arudino 并为其供电。按住盾牌上的“开关”按钮 6 秒钟。使用 SmartThings 智能手机应用程序,选择添加按钮。再按一次物理“开关”按钮,您应该会看到集线器识别 ThingShield。

返回,在 IDE 中,通过单击主屏幕上的“设备”导航到您的 Arduino ThingShield。从列表中选择您的设备,然后单击页面底部的“编辑”按钮。从“类型”下拉菜单中,选择您创建的新 SmartDevice 类型。当您稍后需要选择设备时,为设备提供有意义的标签名称会很有帮助。点击更新将设备设置为您的新设备类型。

请注意,将来发布自定义设备类型的更新时,您需要回来确认您的物理设备在发布更新后是否仍与正确的设备类型相关联。


第 7 步:编写 SmartThings 应用

我们在项目中还有一段代码——SmartApp 本身。导航到“My SmartApps”并单击右侧的按钮启动“New SmartApp”。为其命名、描述和类别(“我的应用程序”)。点击“创建”继续编写应用程序。

复制 smartApp 代码(请参阅代码部分)。选择“保存”,然后单击“发布”,使 SmartApp 在您的 Smartthings iOS 或 Android(即将推出)应用上可用。

请注意,我们通过名称将 SmartDevice 类型引用为“IrBridge”,而没有我们最初在名称“Ir Bridge”中使用的原始空格:

输入“irDevice”、“device.IrBridge”

该行允许我们仅显示“Ir Bridge”类型的设备作为在 SmartApp 中选择的选项。使用的 camelCasing 非常具体:在智能应用程序中引用设备类型时,名称中的空格会被删除。空格后面的第一个字符和字符都大写。其他的都是小写的,不管原来的大写。


第 8 步:启用 SmartApp

在 SmartThings 智能手机应用程序中,将新 SmartApp 与我们的新 IR 设备相关联,然后选择您想要控制的开关。然后点击“安装”。

要对应用程序中的每个按钮进行编程,请通过单击磁贴角落的齿轮转到磁贴详细信息。选择大的录音按钮——它会变成红色,表示您处于录音模式。然后单击要控制的图块(播放/暂停或 B)——它会变成黄色。将遥控器对准 ThingShield,然后按下您想要学习的按钮。 ThingShield 现在会将该代码发送到 SmartThings 云,并将其与您在 SmartApp 中选择的按钮相关联。新编程的按钮会变成绿色,录制按钮会变回白色。

下次按下遥控器上的按钮时,您将切换与 SmartApp 中的按钮关联的开关。

代码

  • Arduino 草图
  • 设备定义
  • 智能应用代码
Arduino 草图C/C++
//************************************************* ********************************/// @file/// @brief//// Arduino SmartThings IR Shield/ /***************************************************** ****************************#include  //由于一些奇怪的有线语言链接器需要设置TODO,应该我们将整个库吸收到 smartthings#include #include //*************************** ****************************************************** // 引脚定义 | | | | | | | | | | | | | | | | | | | | | | | | | | | | |// VVVVVVVVVVVVVVVVVVVVVVVVVVVV//*********************************************** **********************************#define PIN_LED 13#define PIN_RECV 11#define PIN_THING_RX 3#define PIN_THING_TX 2 //**************************************************** *****************************// 全局变量 | | | | | | | | | | | | | | | | | | | | | | | | | | | | |// VVVVVVVVVVVVVVVVVVVVVVVVVVVV//*********************************************** **************************************SmartThingsCallout_t messageCallout; // 调用函数 forward decalationSmartThings smartthing(PIN_THING_RX, PIN_THING_TX, messageCallout); // 构造函数 isDebugEnabled; // 在这个例子中启用或禁用调试int stateLED; //状态跟踪LEDIRrecv的最后设置值irrecv(PIN_RECV);IRsend irsend;decode_results results;//*************************** ****************************************************** // API 函数 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |// VVVVVVVVVVVVVVVVVVVVV VVVVVVVV//*********************************************** **********************************void setup(){ // 设置全局变量的默认状态 isDebugEnabled =true;状态 LED =0; // 匹配下面设置的硬件引脚状态 // 设置硬件引脚 pinMode(PIN_LED, OUTPUT); // 定义 PIN_LED 作为输出 digitalWrite(PIN_LED, LOW); // 将值设置为 LOW (off) 以匹配 stateLED=0 if (isDebugEnabled) { // 设置调试串口 Serial.begin(9600); // 设置串口,波特率为 9600 Serial.println("setup.."); // 打印出 'setup..' 在开始时 }irrecv.enableIRIn(); // 启动接收器}//************************************************ ************************************void loop(){ // 运行智能逻辑 smartthing.run(); if (irrecv.decode(&results)) { blue();简历.resume(); // 接收下一个值 Serial.println(results.value, HEX); //转储(&结果); //示例:smartthing.send("HEX,XXXCODE");字符串 irCmd; if (results.decode_type ==NEC) { irCmd =String(results.value, HEX) + "," + "NEC" + String(results.bits, DEC) + ":" + String(results.value, HEX); } else if (results.decode_type ==SONY) { irCmd =String(results.value, HEX) + "," + "SNY" + String(results.bits, DEC) + ":" + String(results.value,十六进制); } else if (results.decode_type ==RC5) { irCmd =String(results.value, HEX) + "," + "RC5" + String(results.bits, DEC) + ":" + String(results.value,十六进制); } else if (results.decode_type ==RC6) { irCmd =String(results.value, HEX) + "," + "RC6" + String(results.bits, DEC) + ":" + String(results.value,十六进制); } else { irCmd =String(results.value, HEX) + "," + "RAW" + String(results.bits, DEC) + ":"; Serial.println(irCmd); smartthing.send(irCmd); irCmd =""; }}//**************************************************** ********************************void messageCallout(String message){ smartthing.shieldSetLED(0, 0, 0); // 如果启用了调试,则打印出接收到的消息 if (isDebugEnabled) { Serial.print("Rx:'");串行打印(消息); Serial.println("' "); } String type =message.substring(0,3); int startCode =message.indexOf(':'); String lenStr =message.substring(3,startCode); String codeStr =message.substring(startCode + 1);无符号长代码; //将十六进制字符串转换为长无符号 if(type !="RAW") code =stringToNum(codeStr,16); //不适用于RAW int len =stringToNum(lenStr,10); //对于每种类型 - NEC、SON、PAN、JVC、RC5、RC6 等...前 3 个 if(type =="NEC") { Serial.println("NEC-SEND"); Serial.println(len); Serial.println(code,HEX); irsend.sendNEC(code,len); ircv.enableIRIn(); } else if(type =="SNY") { irsend.sendSony(code,len); ircv.enableIRIn(); } else if(type =="RC5") { irsend.sendRC5(code,len); ircv.enableIRIn(); } else if(type =="RC6") { irsend.sendRC6(code,len); ircv.enableIRIn(); } }// 转储出 decode_results 结构。// 在 IRrecv::decode()// void * 之后调用它以解决编译器问题//void dump(void *v) {// decode_results *results =(decode_results *) vvoid dump(decode_results *results) { int count =results->rawlen; if (results->decode_type ==UNKNOWN) { Serial.print("Unknown encoding:"); } else if (results->decode_type ==NEC) { Serial.print("Decoded NEC:"); } else if (results->decode_type ==SONY) { Serial.print("解码的索尼:"); } else if (results->decode_type ==RC5) { Serial.print("Decoded RC5:"); } else if (results->decode_type ==RC6) { Serial.print("Decoded RC6:"); } else if (results->decode_type ==PANASONIC) { Serial.print("Decoded PANASONIC - Address:"); Serial.print(results->panasonicAddress,HEX); Serial.print(" 值:"); } else if (results->decode_type ==JVC) { Serial.print("Decoded JVC:"); Serial.print(results->value, HEX); Serial.print(" ("); Serial.print(results->bits, DEC); Serial.println("bits)"); Serial.print("Raw("); Serial.print(count, DEC); Serial.print("):"); for (int i =0; i rawbuf[i]*USECPERTICK, DEC); } else { Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC); Serial.print(" "); } Serial.println("");}//**************************************** ****************************************// 局部函数 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |// VVVVVVVVVVVVVVVVVVVVV VVVVVVVV//*********************************************** ********************************** unsigned long stringToNum(String s, int base) //10为十进制, 16 十六进制{ unsigned long i =0;无符号长值 =0;无符号长位置 =s.length();字符 c;无符号长符号 =1; for(i; i ='0' &&c <='9') //0 到 9 { value +=( c - '0') * exponent(base,place); } else if (c>='A' &&((c - 'A' + 10) ='a' &&(c - 'a' + 10)  
设备定义Groovy
/** * Smart Ir * * Author:[email protected] * Date:2013-03-06 */metadata { // 模拟器元数据模拟器{} // UI tile 定义tile { standardTile("recStatus", "device.recStatus", width:2, height:2, canChangeIcon:true, canChangeBackground:true) { state "off", label:'record', action:"record", backgroundColor:"#ffffff" state "on" , label:'record', action:"record", backgroundColor:"#ff0000" } //这是一个二级磁贴 //set, unset, prog - green, white, yellow standardTile("buttonA", "device.buttonAStatus" ", width:1, height:1, canChangeIcon:true, canChangeBackground:true) { state "unset", label:'', action:"buttonA", icon:"st.custom.buttons.play-pause", backgroundColor :"#cccccc" //灰色状态 "prog", label:'', action:"buttonA", icon:"st.custom.buttons.play-pause", backgroundColor:"#FDE910" //黄色状态 "set ", label:'', action:"buttonA", icon:"st.custom.buttons.play-pause", backgroundColor:"#79b821" //green } //set, unset, prog - green, white, y ellow standardTile("buttonB", "device.buttonBStatus", width:1, height:1, canChangeIcon:true, canChangeBackground:true) { state "unset", label:'', action:"buttonB", icon:"st .custom.buttons.b", backgroundColor:"#cccccc" //灰色状态 "prog", label:'', action:"buttonB", icon:"st.custom.buttons.b", backgroundColor:"#FDE910 " //黄色状态 "set", label:'', action:"buttonB", icon:"st.custom.buttons.b", backgroundColor:"#79b821" //green } //可能的主图块 main ([ "buttonA","buttonB"]) //这是一个多图块详细信息的数组 (["recStatus","buttonA","buttonB"]) }}// 解析传入的设备消息以生成事件def parse(String description) { log.trace "parse:" def value =zigbee.parse(description)?.text def codeParts =value.split(/,/) log.trace "code:${codeParts[0]}" //[0]是十六进制,[1]是[1]的重发,前三个字符是类型,后面是代码 if(device.currentValue("recStatus") =="on") //在记录模式{ log .trace “记录已启用” if(device.cur rentValue("lastButton") !="") { log.trace "last button is active" def buttonStatus ="${device.currentValue("lastButton")}Status"; def buttonHex ="${device.currentValue("lastButton")}Hex"; def buttonCode ="${device.currentValue("lastButton")}Code"; def result =[ createEvent(name:buttonStatus, value:"set", isStateChange:true) //把按钮变成绿色 ,createEvent(name:buttonHex, value:codeParts[0], isStateChange:true) //存储代码, createEvent(name:buttonCode, value:codeParts[1], isStateChange:true) //存储代码 ,createEvent(name:"recStatus", value:"off", isStateChange:true) ,createEvent(name:"lastButton", value:"", isStateChange:true) //重置最后一个按钮 ] return result } else{ log.trace "no button selected" } } else { //if not //检查是否匹配任何按钮 if(codeParts[ 0] ==device.currentValue("buttonAHex")) { //发送一个与buttonA相关的事件 def result =createEvent(name:"button", value:"A",isStateChange:true) log.debug "Parse returned $ {result?.descriptionText}" return result } else if(codeParts[0] ==device.currentValue("buttonBHex")) { //发送与buttonB相关的事件 def result =createEvent(name:"button", value:"B", isStateChange:true ) log.debug "解析返回 ${result?.descriptionText}" ret urn result } } def result =createEvent(name:null, value:"") return result}def record(){ //进入记录模式 log.debug "RecordMode changes from ${device.currentValue("recStatus")}" clearLast() //清除最后一个按钮 //将属性切换为开/关 if(device.currentValue("recStatus") =="on") { sendEvent(name:"recStatus", value:"off", isStateChange:true ) //瓷砖颜色变为白色 } else { sendEvent(name:"recStatus", value:"on", isStateChange:true) //瓷砖颜色变为红色 }}def buttonA(){ log.debug "ButtonA press" if(device.currentValue("recStatus") =="on") //如果在记录模式,设置要编程的按钮 { clearLast() log.debug "Put buttonA in programming mode" //设置 lastTile 属性为 tileA // 变成黄色 sendEvent(name:"buttonAStatus", value:"prog", isStateChange:true) sendEvent(name:"lastButton", value:"buttonA", isStateChange:true) } else if(device.currentValue(" buttonAStatus") =="set") //如果设置了,发送存储的代码 { log.debug "Send buttonA Code" //发送发射器的远程代码 zigbee.smartShield(text:"${device.currentValue("buttonACode")}").format() } else { log.debug "button 当前为 ${device.currentValue("buttonAStatus")} " }}def buttonB(){ clearLast() log.debug "ButtonB press" if(device.currentValue("recStatus") =="on") //如果在记录模式,设置按钮被编程 { log.debug "Put button in Programming mode" //设置lastTile属性为tileA //把它变成黄色 sendEvent(name:"buttonBStatus", value:"prog", isStateChange:true) sendEvent(name:"lastButton", value:"buttonB ", isStateChange:true) } else if(device.currentValue("buttonBStatus") =="set") //如果设置了,发送存储的代码 { log.debug "Send buttonB Code" //发送远程代码到发射器 zigbee.smartShield(text:"${device.currentValue("buttonBCode")}").format() } else if(device.currentValue("buttonBStatus") =="unset") { log.debug "button当前未设置" }}def clearLast(){ if(device.currentValue("lastButton") !="") { sendEvent(name:"${device.current Value("lastButton")}", value:"unset", isStateChange:true) sendEvent(name:"lastButton", value:"", isStateChange:true) }}
smartApp 代码Groovy
/** * IR 接收器 * * 作者:[email protected] * 日期:2013-03-31 */preferences { section("Pick an IR device...") { input "irDevice", "device .IrBridge" } section("Button A 打开或关闭..."){ input "switch1", "capability.switch", title:"This light", required:false } section("Button B 打开或关闭..."){ input "switch2", "capability.switch", title:"This light", required:false } }def installed() { log.debug "Installed with settings:${settings}" subscribe(irDevice , "button.B", handleB) subscribe(irDevice, "button.A",handleA)}def updated() { log.debug "Updated with settings:${settings}" unsubscribe() subscribe(irDevice, "button. B", handleB) subscribe(irDevice, "button.A",handleA)}def handleA(evt) { log.debug "收到按钮 A" if (switch1.currentValue("switch") =="on") { switch1 .off() } else { switch1.on() }}def handleB(evt) { log.debug "收到按钮 B" if (switch2.currentValue("switch") =="on") { switch2.off() } else { switch2.on() }}

制造工艺

  1. 使用 Raspberry Pi 和 Python 构建机器人
  2. 使用 Raspberry Pi 构建赛格威
  3. 如何处理数据?!
  4. 用 Arduino 捕捉水滴
  5. 使用 K30 传感器监测二氧化碳
  6. 聋盲通信与 1Sheeld/Arduino
  7. 使用 Arduino 控制硬币接收器
  8. Arduino 带蓝牙控制 LED!
  9. 使用 Arduino Cloud 随时随地了解您家的温度!
  10. 使用 MAX30100 可穿戴脉搏传感器和 Arduino
  11. 使用 Nextion Display 构建 Fridgeye 应用程序
  12. 通过智能自动化打造员工体验的未来