Construcción de un puente de infrarrojos con SmartThings ThingShield
Componentes y suministros
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
Acerca de este proyecto
Introducción
Un simple control remoto de TV es capaz de cambiar de canal mucho más cuando se conecta a la nube SmartThings. Con una pequeña cantidad de piezas y una recompensa inmediata, el proyecto es una buena forma de explorar la plataforma.
Información sobre Arduino y ThingShield
SmartThings ThingShield facilita la construcción de prototipos de SmartThings usando Arduino. El escudo se conecta directamente al enlace UNO con el concentrador SmartThings a través del protocolo Zigbee. Un interruptor en el escudo permite elegir entre usar los pines 0,1 o 2,3 para comunicarse con el Arduino. ThingShield ya se reserva el uso del pin 6.
Para obtener más información sobre cómo comenzar con Arudino:http://arduino.cc/en/Guide/Introduction
Paso 1:necesitará
- (x1) SmartThings Arduino ThingShield
- (x1) Arduino Uno
- (x1) Receptor de infrarrojos
- (x1) LED de emisión de infrarrojos
- (x1) Resistencia de 100 ohmios (opcional)
Paso 2:descargue la biblioteca de infrarrojos
El proyecto depende de una maravillosa biblioteca Arduino desarrollada por Ken Shirriff. https://github.com/shirriff/Arduino-IRremote
Instale la biblioteca Arduino de la manera habitual.
http://arduino.cc/en/Guide/Libraries
Una vez instalado, necesitamos modificar IRRemoteInt.h para usar el temporizador en el pin 9. En este ejemplo, usamos el pin 3 para la comunicación con ThingShield.
Paso 3:Arduino Sketch
A continuación, cargue el boceto en su placa Arduino (consulte la sección de códigos).
Paso 4:la compilación
La construcción es simple y directa. Primero conecte el ThingShield en la parte superior del Arduino. Aunque solo se muestra el Arduino en el diagrama a continuación, la ubicación de los pines es la misma con el protector adjunto.
Para el receptor de infrarrojos, conecte los pines correspondientes a tierra y 5V. Luego, conecte el pin de datos al pin 11 de Arduino. Conecte el LED emisor de infrarrojos al pin 9 y a tierra. La resistencia de 100 ohmios es opcional en este diseño, ya que el LED probablemente puede manejar la corriente máxima del Arduino, ya que parpadea rápidamente para enviar señales. Si se deja encendido continuamente, la misma corriente probablemente quemaría el LED.
Paso 5:Creación de un tipo de dispositivo SmartThings personalizado
En SmartThings IDE, a continuación creamos un nuevo tipo de dispositivo para nuestro ThingShield.
Vaya a la sección "Mis tipos de dispositivo", haga clic en "Nuevo dispositivo inteligente" a la derecha.
La creación de un nuevo SmartDevice requiere dos pasos. Primero, asigne un nombre al nuevo tipo de dispositivo en la parte superior "Ir Bridge". Tenga en cuenta que haremos referencia al nombre de nuestro SmartDevice en nuestro código de SmartApp más adelante.
Necesitamos definir los Atributos (variables) y Comandos (funciones) del dispositivo. Para este tutorial, crearemos los atributos y comandos para dos botones programables y un botón de grabación. Agregue cada uno de los atributos y comandos que se muestran. Seleccione "Crear" para continuar codificando el dispositivo.
A continuación, copie la definición del dispositivo en la ventana de código del IDE (consulte la sección de código). Haga clic en el botón "Guardar" en la parte superior y luego haga clic en "Publicar" para que el dispositivo esté disponible para usted.
Paso 6:Actualización de ThingShield a su nuevo tipo de dispositivo
Asegúrese de agregar su ThingShield a su hub SmartThings si aún no está configurado. Para emparejar el dispositivo, conecte ThingShield a su Arudino y enciéndalo. Mantenga presionado el botón "Cambiar" en el escudo durante 6 segundos. Con la aplicación para teléfonos inteligentes SmartThings, seleccione el botón Agregar. Presione el botón físico del "interruptor" una vez más y debería ver que el concentrador identifica el ThingShield.
De vuelta, en el IDE, navegue hasta su Arduino ThingShield haciendo clic en "dispositivos" en la pantalla de inicio. Seleccione su dispositivo de la lista y haga clic en el botón "Editar" en la parte inferior de la página. En el menú desplegable "Tipo", elija el nuevo tipo de SmartDevice que creó. Resulta útil asignar a los dispositivos nombres de etiquetas significativos cuando necesite seleccionarlos más tarde. Presione actualizar para configurar el dispositivo a su nuevo tipo de dispositivo.
Tenga en cuenta que cuando publique actualizaciones para sus tipos de dispositivos personalizados en el futuro, querrá volver para confirmar que sus dispositivos físicos permanecieron asociados con el tipo de dispositivo correcto después de una actualización publicada.
Paso 7:escribir la aplicación SmartThings
Tenemos una pieza más de código en el proyecto:la propia SmartApp. Navegue a "Mis SmartApps" e inicie una "Nueva SmartApp" haciendo clic en el botón de la derecha. Asígnele un nombre, una descripción y una categoría ("Mis aplicaciones"). Haga clic en "Crear" para continuar codificando la aplicación.
Copie el código de la aplicación inteligente (consulte la sección de códigos). Seleccione "Guardar" y luego haga clic en "Publicar" para que la SmartApp esté disponible en su aplicación Smartthings para iOS o Android (próximamente).
Tenga en cuenta que hacemos referencia al tipo de SmartDevice por su nombre como "IrBridge" sin el espacio original que usamos originalmente en el nombre "Ir Bridge":
entrada "irDevice", "device.IrBridge"
La línea nos permite mostrar solo dispositivos del tipo “Ir Bridge” como opciones a seleccionar en la SmartApp. El camelCasing utilizado es muy específico:cuando se hace referencia a tipos de dispositivos en aplicaciones inteligentes, los espacios se eliminan del nombre. El primer carácter y los caracteres que siguen originalmente a un espacio están en mayúscula. Todos los demás están en minúsculas, independientemente de las mayúsculas originales.
Paso 8:Habilite la SmartApp
Dentro de la aplicación para teléfonos inteligentes SmartThings, asocie la nueva SmartApp con nuestro nuevo dispositivo de infrarrojos y seleccione los interruptores que desea controlar. Luego haga clic en "instalar".
Para programar cada uno de los botones en la aplicación, vaya a los detalles del mosaico haciendo clic en el engranaje en la esquina del mosaico. Seleccione el botón de grabación grande; se volverá rojo para mostrar que está en modo de grabación. Luego haga clic en el mosaico (Reproducir / Pausa o B) que desea controlar; se volverá amarillo. Apunte su control remoto al ThingShield y presione el botón que desea aprender. ThingShield ahora enviará ese código a la nube SmartThings y lo asociará con el botón que eligió en SmartApp. El botón recién programado se volverá verde y el botón de grabación volverá a ser blanco.
La próxima vez que presione ese botón en su control remoto, alternará el interruptor que asoció con el botón en la SmartApp.
Código
- Bosquejo de Arduino
- Definición de dispositivo
- código de SmartApp
Bosquejo de Arduino C / C ++
// ******************************************* ******************************** /// @file /// @brief /// Arduino SmartThings IR Shield / / ********************************************** **************************** # include// TODO necesita establecerse debido a algún enlazador de lenguaje de cable extraño, debería absorbimos toda esta biblioteca en cosas inteligentes # include #include // *************************** *********************************************** // Definiciones de pines | | | | | | | | | | | | | | | | | | | | | | | | | | | | | // VVVVVVVVVVVVVVVVVVVVV VVVVVVVV // ****************************************** ********************************** # definir PIN_LED 13 # definir PIN_RECV 11 # definir PIN_THING_RX 3 # definir PIN_THING_TX 2 // ********************************************* ***************************** // Variables globales | | | | | | | | | | | | | | | | | | | | | | | | | | | | | // VVVVVVVVVVVVVVVVVVVVV VVVVVVVV // ****************************************** ********************************** SmartThingsCallout_t messageCallout; // llamar a la función decalarationSmartThings smartthing (PIN_THING_RX, PIN_THING_TX, messageCallout); // constructorbool isDebugEnabled; // habilitar o deshabilitar la depuración en este ejemploint stateLED; // estado para rastrear el último valor establecido de LEDIRrecv irrecv (PIN_RECV); IRsend irsend; decode_results resultados; // ************************** *********************************************** // Funciones API | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | // VVVVVVVVVVVVVVVVVVVVV VVVVVVVVV // ***************************************** ********************************** void setup () {// configurar el estado predeterminado de las variables globales isDebugEnabled =true; stateLED =0; // coincide con el estado de los pines de hardware establecidos a continuación // configura los pines de hardware pinMode (PIN_LED, OUTPUT); // define PIN_LED como salida digitalWrite (PIN_LED, LOW); // establece el valor en BAJO (apagado) para que coincida con stateLED =0 if (isDebugEnabled) {// configura el puerto serie de depuración Serial.begin (9600); // configura el serial con una velocidad en baudios de 9600 Serial.println ("setup .."); // imprime 'setup ..' al inicio} irrecv.enableIRIn (); // Iniciar el receptor} // **************************************** ********************************** void loop () {// ejecutar la lógica de smartthing smartthing.run (); if (irrecv.decode (&resultados)) {azul (); irrecv.resume (); // Recibe el siguiente valor Serial.println (results.value, HEX); // volcado (&resultados); // EJEMPLO:smartthing.send ("HEX, XXXCODE"); String 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, MALEFICIO); } else if (results.decode_type ==RC5) {irCmd =String (results.value, HEX) + "," + "RC5" + String (results.bits, DEC) + ":" + String (results.value, MALEFICIO); } else if (results.decode_type ==RC6) {irCmd =String (results.value, HEX) + "," + "RC6" + String (results.bits, DEC) + ":" + String (results.value, MALEFICIO); } else {irCmd =String (results.value, HEX) + "," + "RAW" + String (results.bits, DEC) + ":"; } Serial.println (irCmd); smartthing.send (irCmd); irCmd =""; }} // ******************************************** ******************************* void messageCallout (mensaje de cadena) {smartthing.shieldSetLED (0, 0, 0); // si la depuración está habilitada, imprima el mensaje recibido if (isDebugEnabled) {Serial.print ("Rx:'"); Serial.print (mensaje); Serial.println ("'"); } Tipo de cadena =mensaje.substring (0,3); int startCode =message.indexOf (':'); String lenStr =message.substring (3, startCode); String codeStr =message.substring (startCode + 1); código largo sin firmar; // convierte la cadena hexadecimal en una cadena larga sin signo if (type! ="RAW") code =stringToNum (codeStr, 16); // no funcionará para RAW int len =stringToNum (lenStr, 10); // Para cada tipo - NEC, SON, PAN, JVC, RC5, RC6, etc ... los primeros 3 if (type =="NEC") {Serial.println ("NEC-SEND"); Serial.println (len); Serial.println (código, HEX); irsend.sendNEC (código, longitud); irrecv.enableIRIn (); } else if (tipo =="SNY") {irsend.sendSony (código, len); irrecv.enableIRIn (); } else if (escriba =="RC5") {irsend.sendRC5 (código, longitud); irrecv.enableIRIn (); } else if (escriba =="RC6") {irsend.sendRC6 (código, longitud); irrecv.enableIRIn (); }} // Vacía la estructura decode_results .// Llame a esto después de IRrecv ::decode () // void * para solucionar el problema del compilador // void dump (void * v) {// decode_results * results =(decode_results *) vvoid dump (decode_results * resultados) {recuento int =resultados-> rawlen; if (resultados-> decode_type ==UNKNOWN) {Serial.print ("Codificación desconocida:"); } else if (resultados-> decode_type ==NEC) {Serial.print ("Decodificado NEC:"); } else if (resultados-> decode_type ==SONY) {Serial.print ("Decodificado SONY:"); } else if (resultados-> decode_type ==RC5) {Serial.print ("Decodificado RC5:"); } else if (resultados-> decode_type ==RC6) {Serial.print ("Decodificado RC6:"); } else if (resultados-> decode_type ==PANASONIC) {Serial.print ("Decodificado PANASONIC - Dirección:"); Serial.print (resultados-> panasonicAddress, HEX); Serial.print ("Valor:"); } else if (resultados-> decode_type ==JVC) {Serial.print ("JVC decodificado:"); } Serial.print (resultados-> valor, HEX); Serial.print ("("); Serial.print (resultados-> bits, DEC); Serial.println ("bits)"); Serial.print ("Raw ("); Serial.print (recuento, DEC); Serial.print ("):"); for (int i =0; i rawbuf [i] * USECPERTICK, DEC); } else {Serial.print (- (int) resultados-> rawbuf [i] * USECPERTICK, DEC); } Serial.print (""); } Serial.println ("");} // ************************************ ************************************** // Funciones locales | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | // VVVVVVVVVVVVVVVVVVVVV VVVVVVVVV // ***************************************** ********************************** largo sin firmar stringToNum (String s, int base) // 10 para decimal, 16 para hexadecimal {unsigned long i =0; valor largo sin signo =0; lugar largo sin firmar =s.length (); char c; signo largo sin firmar =1; para (i; i ='0' &&c <='9') // 0 a 9 {valor + =(c - '0') * exponente (base, lugar); } más si (c> ='A' &&((c - 'A' + 10) ='a' &&(c - 'a' + 10) Definición de dispositivo Groovy
/ ** * Smart Ir * * Autor:[email protected] * Fecha:2013-03-06 * / metadata {// Simulator metadata simulator {} // Definiciones de mosaicos de interfaz de usuario mosaicos {standardTile ("recStatus", "device.recStatus", width:2, height:2, canChangeIcon:true, canChangeBackground:true) {estado "desactivado", etiqueta:'registro', acción:"registro", color de fondo:"#ffffff" estado "activado" , label:'record', action:"record", backgroundColor:"# ff0000"} // este es un mosaico secundario // set, unset, prog - green, white, yellow standardTile ("buttonA", "device.buttonAStatus ", ancho:1, alto:1, canChangeIcon:true, canChangeBackground:true) {estado" desarmado ", etiqueta:'', acción:" buttonA ", icono:" st.custom.buttons.play-pause ", backgroundColor :"#cccccc" // estado gris "prog", etiqueta:'', acción:"buttonA", icono:"st.custom.buttons.play-pause", backgroundColor:"# FDE910" // estado amarillo "establecido ", 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) {estado "no establecido", etiqueta:'', acción:"buttonB", icono:"st .custom.buttons.b ", backgroundColor:" #cccccc "// estado gris" prog ", etiqueta:'', acción:" buttonB ", icono:" st.custom.buttons.b ", backgroundColor:" # FDE910 "// estado amarillo" conjunto ", etiqueta:'', acción:" buttonB ", icono:" st.custom.buttons.b ", backgroundColor:" # 79b821 "// verde} // posibles mosaicos principales main ([ "buttonA", "buttonB"]) // esta es una matriz para varios detalles de mosaicos (["recStatus", "buttonA", "buttonB"])}} // Analizar los mensajes entrantes del dispositivo para generar eventsdef parse (descripción de la cadena) {log.trace "parse:" def value =zigbee.parse (description) ?. text def codeParts =value.split (/, /) log.trace "code:$ {codeParts [0]}" // [0] es el hexadecimal, [1] es el reenvío // de [1], los primeros tres caracteres son el tipo, seguidos por el código if (device.currentValue ("recStatus") =="on") // en modo de registro {log .trace "registro habilitado" si (device.cur rentValue ("lastButton")! ="") {log.trace "el último botón está activo" def buttonStatus ="$ {device.currentValue (" lastButton ")} Estado"; def buttonHex ="$ {device.currentValue (" lastButton ")} Hex"; def buttonCode ="$ {device.currentValue (" lastButton ")} Código"; def result =[createEvent (name:buttonStatus, value:"set", isStateChange:true) // cambia el botón a verde, createEvent (name:buttonHex, value:codeParts [0], isStateChange:true) // almacena el código, createEvent (name:buttonCode, value:codeParts [1], isStateChange:true) // almacena el código, createEvent (name:"recStatus", value:"off", isStateChange:true), createEvent (name:"lastButton", value:"", isStateChange:true) // restablecer el último botón] return result} else {log.trace "ningún botón seleccionado"}} else {// si no // verifica si coincide con algún botón if (codeParts [ 0] ==device.currentValue ("buttonAHex")) {// enviar un evento relacionado con buttonA def result =createEvent (name:"button", value:"A", isStateChange:true) log.debug "Parse devuelto $ {result? .descriptionText} "return result} else if (codeParts [0] ==device.currentValue (" buttonBHex ")) {// enviar un evento relacionado con buttonB def result =createEvent (name:" button ", value:"B", isStateChange:true) log.debug "Parse devolvió $ {result? .DescriptionText}" ret urn result}} def result =createEvent (name:null, value:"") return result} def record () {// ingresa al modo de registro log.debug "RecordMode cambiando de $ {device.currentValue (" recStatus ")}" clearLast () // borrar el último botón // activar / desactivar el atributo if (device.currentValue ("recStatus") =="on") {sendEvent (name:"recStatus", value:"off", isStateChange:true ) // el color del mosaico cambia a blanco} else {sendEvent (nombre:"recStatus", valor:"on", isStateChange:true) // el color del mosaico cambia a rojo}} def buttonA () {log.debug "ButtonA presionado" if (device.currentValue ("recStatus") =="on") // si está en modo de registro, configure el botón que se programará {clearLast () log.debug "Ponga buttonA en modo de programación" // establezca el atributo lastTile en tileA // ponerlo amarillo sendEvent (nombre:"buttonAStatus", value:"prog", isStateChange:true) sendEvent (name:"lastButton", value:"buttonA", isStateChange:true)} else if (device.currentValue (" buttonAStatus ") ==" set ") // si está configurado, envía el código almacenado {log.debug" Send buttonA Code "// envía el código remoto para el blaster zigbee.smartShield (texto:"$ {device.currentValue (" buttonACode ")}"). format ()} else {log.debug "botón es actualmente $ {device.currentValue (" buttonAStatus ")} "}} def buttonB () {clearLast () log.debug" ButtonB presionado "if (device.currentValue (" recStatus ") ==" on ") // si está en el modo de grabación, configure el botón para que se programe {log.debug "Poner el botón en modo de programación" // establecer el atributo lastTile en tileA // ponerlo en amarillo sendEvent (name:"buttonBStatus", value:"prog", isStateChange:true) sendEvent (name:"lastButton", value:"buttonB ", isStateChange:true)} else if (device.currentValue (" buttonBStatus ") ==" set ") // si está configurado, envía el código almacenado {log.debug" Send buttonB Code "// envía el código remoto a el blaster zigbee.smartShield (text:"$ {device.currentValue (" buttonBCode ")}"). format ()} else if (device.currentValue ("buttonBStatus") =="unset") {log.debug "botón actualmente no está configurado "}} def clearLast () {if (device.currentValue (" lastButton ")! =" ") {sendEvent (name:" $ {device.current Value ("lastButton")} ", value:" unset ", isStateChange:true) sendEvent (name:" lastButton ", value:" ", isStateChange:true)}}código de SmartApp Groovy
/ ** * Receptor de infrarrojos * * Autor:[email protected] * Fecha:31 de marzo de 2013 * / preferencias {sección ("Elija un dispositivo de infrarrojos ...") {input "irDevice", "dispositivo .IrBridge "} sección (" El botón A enciende o apaga ... ") {entrada" switch1 "," capacidad.switch ", título:" Esta luz ", requerido:falso} sección (" El botón B enciende o apaga ... ") {input" switch2 "," capacity.switch ", título:" Esta luz ", requerido:falso}} def installed () {log.debug" Instalado con configuraciones:$ {settings} "subscribe (irDevice , "button.B", handleB) subscribe (irDevice, "button.A", handleA)} def updated () {log.debug "Actualizado con la configuración:$ {settings}" unsubscribe () subscribe (irDevice, "botón. B ", handleB) subscribe (irDevice," button.A ", handleA)} def handleA (evt) {log.debug" botón recibido A "if (switch1.currentValue (" switch ") ==" on ") {switch1 .off ()} else {switch1.on ()}} def handleB (evt) {log.debug "recibió el botón B" if (switch2.currentValue ("switch") =="on") {switch2.off () } más {switch2.on ()}}
Controlador de tester Arduino DMX-512 Convierte (casi) cualquier superficie en un botón táctil con MPR121
Proceso de manufactura
- Creación de robots con Raspberry Pi y Python
- Construyendo un segway con Raspberry Pi
- ¡¿Qué hago con los datos ?!
- Capturando las gotas de agua con Arduino
- Monitoreo de CO2 con sensor K30
- Comunicación para personas sordociegas con 1Sheeld / Arduino
- Controlar el aceptador de monedas con Arduino
- ¡Arduino con Bluetooth para controlar un LED!
- ¡Conoce la temperatura de tu hogar desde cualquier lugar con Arduino Cloud!
- Uso del sensor de pulso portátil MAX30100 con Arduino
- Construyendo el futuro de la experiencia del empleado con automatización inteligente