{"id":3463,"date":"2021-04-15T10:36:30","date_gmt":"2021-04-15T15:36:30","guid":{"rendered":"http:\/\/blog.espol.edu.ec\/girni\/?p=3463"},"modified":"2026-08-04T22:35:57","modified_gmt":"2026-08-05T03:35:57","slug":"lorawan-interruptor-temporizado-archivo-ino","status":"publish","type":"post","link":"https:\/\/blog.espol.edu.ec\/girni\/lorawan-interruptor-temporizado-archivo-ino\/","title":{"rendered":"LoRaWan - Interruptor temporizado: Archivo.ino"},"content":{"rendered":"\n<p>Un dispositivo como actuador requiere recibir un mensaje de control desde el broker para establecer el estado del artefacto o cosa. En el caso de LoRaWan el mensaje debe gestionarse por el gateway para transformar un mensaje Mqtt enviado al formato de bytes usado en la red LoRa, es decir un Encoder.<\/p>\n\n\n\n<p>En el dispositivo LoRa se requiere al menos una funci\u00f3n para recibir los mensajes, interpretaci\u00f3n de los bytes recibidos y con \u00e9stos actualizar el estado de los pines de salidas usados como control.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Datos de control<\/h2>\n\n\n\n<p>Lo primordial en el dispositivo es el pin de control. Para el ejemplo inicial se usa el LED incorporado en el m\u00f3dulo de desarrollo Pin25.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\n\/\/ actuador\n#define LEDPin 25  \/\/LED light\nboolean estado = false;  \/\/estado dispositivo\n<\/pre><\/div>\n\n\n<p>Un dato complementario es la <strong><em>duraci\u00f3n<\/em><\/strong> del actuador en estado encendido, es un factor necesario en el sistema de riego, pues se deber\u00eda usar solo por periodos cortos de tiempo. Se aprovecha el modo de ahorro de energ\u00eda del dispositivo en contraste con los largos periodos sin riego.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Intrucciones Principales<\/h2>\n\n\n\n<p>A las instrucciones principales se a\u00f1aden las l\u00edneas para la declaraci\u00f3n de las variables. El resto de operaciones se las a\u00f1ade como funciones.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\n\/* HelTec Automation(TM) LoRaWAN 1.0.2 OTAA example use OTAA, CLASS A\n * Solo ESP32+LoRa series boards con licencia http:\/\/www.heltec.cn\/search\/);\n *https:\/\/github.com\/HelTecAutomation\/ESP32_LoRaWAN\n*\/\n#include &lt;ESP32_LoRaWAN.h&gt;\n#include &quot;Arduino.h&quot;\n\n\/*licencia Heltec ESP32 LoRaWan http:\/\/resource.heltec.cn\/search *\/\nuint32_t  license&#x5B;4] = { 0xC254CA22, 0xFB5646A9, 0xA23B184F, 0x8F613844};\n\n\/* OTAA parametros*\/\nuint8_t DevEui&#x5B;] = { 0xbc, 0x55, 0x31, 0x89, 0x12, 0xbf, 0xd0, 0x90 };\nuint8_t AppEui&lt;&#x5B;] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };\nuint8_t AppKey&#x5B;] = { 0x99, 0x42, 0xd4, 0x4b, 0xfc, 0x59, 0x85, 0x0a, 0xad, 0x76, 0x15, 0x3b, 0x7a, 0xdb, 0x50, 0x32 };\n\n\/* ABP parametros*\/\nuint8_t NwkSKey&#x5B;] = { 0xd6, 0x28, 0x15, 0x0c, 0x99, 0x79, 0xbc, 0xec, 0xed, 0x11, 0x67, 0x75, 0x0b, 0x37, 0xb4, 0xe0 };\nuint8_t AppSKey&#x5B;] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };\nuint32_t DevAddr  = ( uint32_t )0x00052815;\n\n\/\/LoraWan channelsmask, default channels 0-7\/\nuint16_t userChannelsMask&#x5B;6]={ 0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000 };\n\nDeviceClass_t  loraWanClass = CLASS_A;  \/*Soporte de A and C*\/\nuint32_t appTxDutyCycle = 30000;        \/*15000; en &#x5B;ms]*\/\nbool overTheAirActivation = true;     \/*OTAA or ABP*\/\nbool loraWanAdr = true;               \/*ADR enable*\/\nbool isTxConfirmed = true;            \/*confirmed or unconfirmed messages *\/\nuint8_t appPort = 3;                  \/* Application port *\/\n  \n\/* reintentos de transmisi\u00f3n, en caso de no recibir ack *\/\nuint8_t confirmedNbTrials = 8;\n\n\/* Seleccionado de Arduino IDE tools *\/\nuint8_t debugLevel = LoRaWAN_DEBUG_LEVEL; \nLoRaMacRegion_t loraWanRegion = ACTIVE_REGION;\n\n\/\/ Mensajes por Puerto Serial\nvolatile boolean serial_msg = true;\n\n\/\/ actuador\n#define LEDPin 25  \/\/LED light\nboolean estado = false;  \/\/estado dispositivo\n\n\/\/ Sensor de estado de bateria, revisar modelo de m\u00f3dulo\n\/\/ PowerDetection 13 en Wireless Stick lite, otros 37\n#define Vext 21\n#define PowerDetection 13\n\nvoid setup(){\n  Serial.begin(115200);\n  while (!Serial);\n  SPI.begin(SCK,MISO,MOSI,SS);\n  Mcu.init(SS,RST_LoRa,DIO0,DIO1,license);\n  deviceState = DEVICE_STATE_INIT;\n}\nvoid loop(){\n  switch( deviceState )  {\n    case DEVICE_STATE_INIT:    {\n      LoRaWAN.init(loraWanClass,loraWanRegion);\n      break;\n    }\n    case DEVICE_STATE_JOIN:    {\n      LoRaWAN.join();\n      break;\n    }\n    case DEVICE_STATE_SEND:    {\n      prepareTxFrame( appPort );\n      LoRaWAN.send(loraWanClass);\n      deviceState = DEVICE_STATE_CYCLE;\n      if (serial_msg){\n        Serial.print(&quot;  estado: &quot;);\n        Serial.println(estado);\n      }\n      break;\n    }\n    case DEVICE_STATE_CYCLE:    {\n      \/\/ Schedule next packet transmission\n      txDutyCycleTime = appTxDutyCycle + randr( -APP_TX_DUTYCYCLE_RND,\n                                                APP_TX_DUTYCYCLE_RND );\n      LoRaWAN.cycle(txDutyCycleTime);\n      deviceState = DEVICE_STATE_SLEEP;\n      break;\n    }\n    case DEVICE_STATE_SLEEP:    {\n      LoRaWAN.sleep(loraWanClass,debugLevel);\n      break;\n    }\n    default:    {\n      deviceState = DEVICE_STATE_INIT;\n      break;\n    }\n  }\n}\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Recibe trama<\/h2>\n\n\n\n<p>La recepci\u00f3n de los datos en la trana, \"downlink\", se realiza en la variable Buffer que es un arreglo de Bytes. La instrucci\u00f3n de control requiere dos valores: estado y duraci\u00f3n , por lo que se usa el primer y segundo Byte. Este detalle se debe ajustar en cada situaci\u00f3n para la cantidad de bytes que se requieran.<\/p>\n\n\n\n<p>Recibidos los datos, se invoca a la funci\u00f3n para control del actuador \"actuador_pin()\".<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nvoid  downLinkDataHandle(McpsIndication_t *mcpsIndication){\n  lora_printf(&quot;+REV DATA:%s,RXSIZE %d,PORT %d\\r\\n&quot;,\n              mcpsIndication-&amp;gt;RxSlot?&quot;RXWIN2&quot;:&quot;RXWIN1&quot;,\n              mcpsIndication-&amp;gt;BufferSize,\n              mcpsIndication-&amp;gt;Port);\n  lora_printf(&quot;+REV DATA:&quot;);\n  \n  actuador_pin(mcpsIndication-&amp;gt;Buffer&#x5B;0],\n                mcpsIndication-&amp;gt;Buffer&#x5B;1]);\n\n  for(uint8_t i=0;i&amp;lt;mcpsIndication-&amp;gt;BufferSize;i++)  {\n    lora_printf(&quot;%02X&quot;,mcpsIndication-&amp;gt;Buffer&#x5B;i]);\n  }\n  lora_printf(&quot;\\r\\n&quot;);\n}\n\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Controla estado de actuador<\/h2>\n\n\n\n<p>Con los dato recibidos en la funci\u00f3n anterior, se selecciona la acci\u00f3n para cada caso de valor de estado.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\nvoid actuador_pin(uint8_t estado, uint8_t duracion) {\n  if (serial_msg){\n    Serial.print(&quot;\\n instruccion recibida: &quot;);\n    Serial.print(estado);\n    Serial.print(&quot;  &quot;);\n    Serial.println(duracion);\n  }\n  switch(estado) {\n    case 49: {\n      pinMode(LEDPin,OUTPUT);\n      digitalWrite(LEDPin, HIGH);\n      estado = true;\n      if (serial_msg){\n        Serial.print(&quot;activador: ON &quot;);\n        Serial.print(&quot; duraci\u00f3n (s): &quot;);\n        Serial.print(duracion);\n      }\n      delay(duracion*1000); \/\/ en segundos\n      digitalWrite(LEDPin, LOW);\n      estado = false;\n      break;\n    }\n    case 50: {\n      pinMode(LEDPin,OUTPUT);\n      digitalWrite(LEDPin, LOW);\n      estado = false;\n      if (serial_msg){\n        Serial.println(&quot;activador: OFF&quot;);\n      }\n      delay(duracion*1000); \/\/ en segundos\n      break;\n    }\n    default: {break;}\n  }\n}\n\n<\/pre><\/div>\n\n\n<p>Las siguientes funciones son las mismas usadas en el ejemplo de revisi\u00f3n de estado de bater\u00eda.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prepara trama<\/h2>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\nvoid actuador_pin(uint8_t estado, uint8_t duracion) {\n  if (serial_msg){\n    Serial.print(&quot;\\n instruccion recibida: &quot;);\n    Serial.print(estado);\n    Serial.print(&quot;  &quot;);\n    Serial.println(duracion);\n  }\n  switch(estado) {\n    case 49: {\n      pinMode(LEDPin,OUTPUT);\n      digitalWrite(LEDPin, HIGH);\n      estado = true;\n      if (serial_msg){\n        Serial.print(&quot;activador: ON &quot;);\n        Serial.print(&quot; duraci\u00f3n (s): &quot;);\n        Serial.print(duracion);\n      }\n      delay(duracion*1000); \/\/ en segundos\n      digitalWrite(LEDPin, LOW);\n      estado = false;\n      break;\n    }\n    case 50: {\n      pinMode(LEDPin,OUTPUT);\n      digitalWrite(LEDPin, LOW);\n      estado = false;\n      if (serial_msg){\n        Serial.println(&quot;activador: OFF&quot;);\n      }\n      delay(duracion*1000); \/\/ en segundos\n      break;\n    }\n    default: {break;}\n  }\n}\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Lectura de Sensor<\/h2>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\nuint16_t SensorBateria(){\n  \/\/ lectura ADC Voltaje de bateria \n  digitalWrite(Vext, LOW);\n  delay(10);\n  uint16_t ADC_voltage = analogRead(PowerDetection);\n  digitalWrite(Vext, HIGH);\n  \n  if (serial_msg){\n    Serial.print(&quot;Voltaje Bater\u00eda (V): &quot;);\n    Serial.println(ADC_voltage);\n  }\n  return ADC_voltage;\n}\n<\/pre><\/div>","protected":false},"excerpt":{"rendered":"<p>Un dispositivo como actuador requiere recibir un mensaje de control desde el broker para establecer el estado del artefacto o cosa. En el caso de LoRaWan el mensaje debe gestionarse por el gateway para transformar un mensaje Mqtt enviado al formato de bytes usado en la red LoRa, es decir un Encoder. En el dispositivo [&hellip;]<\/p>\n","protected":false},"author":8043,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1465791],"tags":[],"class_list":["post-3463","post","type-post","status-publish","format-standard","hentry","category-lorawan-interruptor-temporizado"],"_links":{"self":[{"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/posts\/3463","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/users\/8043"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/comments?post=3463"}],"version-history":[{"count":5,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/posts\/3463\/revisions"}],"predecessor-version":[{"id":4903,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/posts\/3463\/revisions\/4903"}],"wp:attachment":[{"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/media?parent=3463"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/categories?post=3463"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/tags?post=3463"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}