{"id":2683,"date":"2020-11-20T15:34:18","date_gmt":"2020-11-20T20:34:18","guid":{"rendered":"http:\/\/blog.espol.edu.ec\/girni\/?p=2683"},"modified":"2026-08-04T11:32:41","modified_gmt":"2026-08-04T16:32:41","slug":"captura-datos-lora-rssi-snr-archivo-txt","status":"publish","type":"post","link":"https:\/\/blog.espol.edu.ec\/girni\/captura-datos-lora-rssi-snr-archivo-txt\/","title":{"rendered":"2.2 Captura datos - Dispositivo con USB-Serial a un archivo.txt usando Python"},"content":{"rendered":"\n<p>La relaci\u00f3n de valores de Rssi y distancia hacia cada punto de referencia (baliza), se estima a partir de las mediciones en varios puntos establecidos y ubicados en un mapa.<\/p>\n\n\n\n<p>En cada punto, los valores se estiman considerando usar al menos 100 lecturas hacia cada baliza en cada punto.<\/p>\n\n\n\n<p>En \u00e9ste proceso usa un computador port\u00e1til que captura las tramas de cada paquete recibido por el dispositivo desde el puerto USB-Serial a un archivo.txt.<\/p>\n\n\n\n<figure class=\"wp-block-image alignleft\"><a href=\"http:\/\/blog.espol.edu.ec\/girni\/files\/2020\/11\/SerialUsbTXT01.png\"><img loading=\"lazy\" decoding=\"async\" width=\"409\" height=\"312\" src=\"http:\/\/blog.espol.edu.ec\/girni\/files\/2020\/11\/SerialUsbTXT01.png\" alt=\"\" class=\"wp-image-2760\" srcset=\"https:\/\/blog.espol.edu.ec\/girni\/files\/2020\/11\/SerialUsbTXT01.png 409w, https:\/\/blog.espol.edu.ec\/girni\/files\/2020\/11\/SerialUsbTXT01-300x229.png 300w\" sizes=\"auto, (max-width: 409px) 100vw, 409px\" \/><\/a><\/figure>\n\n\n\n<p>Cada baliza peri\u00f3dicamente emite un paquete que permite al dispositivo registrar los valores de Rssi y SNR. Cada captura se registra en una l\u00ednea de texto como un paquete recibido y etiquetado como \"rx\".<\/p>\n\n\n\n<p>Para registrar el Rssi y SNR desde el otro extremo, la baliza, se emite un paquete de difusi\u00f3n desde el dispositivo, con el que la baliza al recibirlo toma los valores de Rssi y SNR y los env\u00eda al dispositivo en el pr\u00f3ximo env\u00edo. El paquete de difusi\u00f3n del dispositivo se etiqueta como 'tx' en el archivo txt.<\/p>\n\n\n\n<p>En la pantalla del computador port\u00e1til se muestra el estado del registro de datos en cada evento de recepci\u00f3n.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Configuraci\u00f3n del algoritmo en Python<\/h2>\n\n\n\n<p>La captura de datos desde USB se realiza usando instrucciones en Python, con la que se pre-procesa cada paquete y se almacena en un archivo.<\/p>\n\n\n\n<p>En el bloque de INGRESO es necesario indicar:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>el puerto 'com' y los baudios del dispositivo conectado por USB<\/li>\n\n\n\n<li>el nombre del archivo de texto que registra la captura de datos<\/li>\n\n\n\n<li>las direcciones de las balizas, identificadores indicados en la secci\u00f3n anterior<\/li>\n\n\n\n<li>la cantidad m\u00ednima de lecturas desde cada baliza<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image alignright\"><a href=\"http:\/\/blog.espol.edu.ec\/girni\/files\/2020\/11\/LoRaPuertoCom01.png\"><img loading=\"lazy\" decoding=\"async\" width=\"523\" height=\"471\" src=\"http:\/\/blog.espol.edu.ec\/girni\/files\/2020\/11\/LoRaPuertoCom01.png\" alt=\"\" class=\"wp-image-2775\" srcset=\"https:\/\/blog.espol.edu.ec\/girni\/files\/2020\/11\/LoRaPuertoCom01.png 523w, https:\/\/blog.espol.edu.ec\/girni\/files\/2020\/11\/LoRaPuertoCom01-300x270.png 300w\" sizes=\"auto, (max-width: 523px) 100vw, 523px\" \/><\/a><\/figure>\n\n\n\n<p>El puerto 'com' se puede verificar antes de iniciar la captura, usando el IDE de Arduino, al conectar lo muestra en el menu de herramientas\/puerto.<\/p>\n\n\n\n<p>El proceso de captura se ejecuta en un lazo, en caso de ser necesario detener se pueden usar las teclas \"Ctrl-c\".<\/p>\n\n\n\n<p>En cada punto de referencia se requiere asignar un nombre a cada archivo, iniciando el nombre con \"multipunto\" a\u00f1adiendo letras para identificar el sector y un n\u00famero como identificador del punto.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"http:\/\/blog.espol.edu.ec\/girni\/files\/2020\/11\/LoRaLocalizaCampus01.png\"><img loading=\"lazy\" decoding=\"async\" width=\"643\" height=\"507\" src=\"http:\/\/blog.espol.edu.ec\/girni\/files\/2020\/11\/LoRaLocalizaCampus01.png\" alt=\"\" class=\"wp-image-3142\" srcset=\"https:\/\/blog.espol.edu.ec\/girni\/files\/2020\/11\/LoRaLocalizaCampus01.png 643w, https:\/\/blog.espol.edu.ec\/girni\/files\/2020\/11\/LoRaLocalizaCampus01-300x237.png 300w\" sizes=\"auto, (max-width: 643px) 100vw, 643px\" \/><\/a><\/figure>\n\n\n\n<p>En los puntos de prueba el nombre del archivo inicia con \"mpcircuito\". Observe que ambas palabras de inicio contienen la misma cantidad de caracteres, pues facilita el procesamiento de los archivos.<\/p>\n\n\n\n<p>Los archivos se almacenan en una carpeta de donde se puedan leer por lotes en el siguiente proceso de los datos.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Algoritmo en Python<\/h2>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n''' Rssi y SNR LoRa punto a punto\npaquete de datos desde puerto Serial\ngenerados desde dispositivo LoRa\nmodelo Heltec Lora 32 v.2\nGirni 2020-10-07 propuesta: edelros@espol.edu.ec\n'''\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport serial, time\n\n# INGRESO\n# Puerto de captura de datos USB-Serial\npuerto = 'com3'\nbaudios = 115200\n\n# Archivo para el registro de cada evento rx,tx\nnombrearchivo = 'multipuntoFIEC101.txt'\n\n# identificadores de balizas\nbaliza = &#x5B;'d1','d2','d3']\n\n# M\u00ednimo de lecturas por baliza\nlecturasMin = 100\n\n# PROCEDIMIENTO\n# Crea registro de lecturas\nn = len (baliza)\nregistro = {}\nfor elemento in baliza:\n    registro&#x5B;elemento] = {'cuenta': 0 ,\n                          'rssi': np.array(&#x5B;0.0,0.0]),\n                          'snr':  np.array(&#x5B;0.0,0.0]),\n                          'SumaRssi': np.array(&#x5B;0.0,0.0]),\n                          'SumaSnr':  np.array(&#x5B;0.0,0.0]),\n                          'minmaxRssi': np.array(&#x5B;0.0,-200.0,0.0,-200.0]),\n                          'minmaxSnr': np.array(&#x5B;100.0,0.0,100.0,0.0])\n                          }\n\n# inicializa archivo.txt a vacio\narchivo = open(nombrearchivo,'w')\narchivo.close()  # Cierra el archivo\n\n# Abre puerto Serial\narduino = serial.Serial(puerto, baudios)\narduino.setDTR(False)\ntime.sleep(0.3)\n\n# limpia buffer de datos anteriores\narduino.flushInput()  \narduino.setDTR()  \ntime.sleep(0.3)\nprint('\\nEstado del puerto: ',arduino.isOpen())\nprint('Nombre del dispositivo conectado: ', arduino.name)\nprint('Dump de la configuraci\u00f3n:\\n ',arduino)\nprint('\\n###############################################\\n')\n\n# Lectura de datos\nnp.set_printoptions(precision=2)\nconteo = 0\ndifunde = 0\nwhile conteo&lt;lecturasMin:\n    #esperar hasta recibir un paquete\n    while (arduino.inWaiting()==0):\n        pass \n\n    # leer linea desde puerto serial\n    linea = arduino.readline()\n    # binario a texto, elimina \/r\/n\n    texto = linea.decode()\n    texto = linea.strip()\n    \n    # identificar la trama como rx, tx\n    cond1 = texto.startswith('tx')\n    cond2 = texto.startswith('rx')\n    if cond1 or cond2:\n        archivo = open(nombrearchivo,'a')\n        archivo.write(texto+'\\n')\n        archivo.close()\n        \n        if (texto.startswith('tx')):\n            difunde = difunde + 1\n        if (texto.startswith('rx')):\n            texto = texto.split(',')\n            tipo  = texto&#x5B;0]\n            dir_remite = texto&#x5B;2]\n            paqrcbvID  = texto&#x5B;3]\n            rssi_tx    = float(texto&#x5B;4])\n            snr_tx     = float(texto&#x5B;5])\n            rssi_rx    = float(texto&#x5B;6])\n            snr_rx     = float(texto&#x5B;7])\n            if tipo == &quot;rx&quot;:\n                # conteo de lecturas\n                cual = dir_remite\n                registro&#x5B;cual]&#x5B;'cuenta']=registro&#x5B;cual]&#x5B;'cuenta']+1\n                if registro&#x5B;cual]&#x5B;'cuenta']&lt;conteo:\n                    conteo = registro&#x5B;cual]&#x5B;'cuenta']\n\n                # acumulado\n                registro&#x5B;cual]&#x5B;'SumaRssi']&#x5B;0] = registro&#x5B;cual]&#x5B;'SumaRssi']&#x5B;0]+rssi_tx\n                registro&#x5B;cual]&#x5B;'SumaSnr']&#x5B;0]  = registro&#x5B;cual]&#x5B;'SumaSnr']&#x5B;0]+snr_tx\n                registro&#x5B;cual]&#x5B;'SumaRssi']&#x5B;1] = registro&#x5B;cual]&#x5B;'SumaRssi']&#x5B;1]+rssi_rx\n                registro&#x5B;cual]&#x5B;'SumaSnr']&#x5B;1]  = registro&#x5B;cual]&#x5B;'SumaSnr']&#x5B;1]+snr_rx\n\n                # promedios\n                cuantos = registro&#x5B;cual]&#x5B;'cuenta']\n                registro&#x5B;cual]&#x5B;'rssi'] = registro&#x5B;cual]&#x5B;'SumaRssi']\/cuantos\n                registro&#x5B;cual]&#x5B;'snr']  = registro&#x5B;cual]&#x5B;'SumaSnr']\/cuantos\n\n                # minimos y maximos\n                registro&#x5B;cual]&#x5B;'minmaxRssi']&#x5B;0] = np.min(&#x5B;rssi_tx,registro&#x5B;cual]&#x5B;'minmaxRssi']&#x5B;0]])\n                registro&#x5B;cual]&#x5B;'minmaxRssi']&#x5B;1] = np.max(&#x5B;rssi_tx,registro&#x5B;cual]&#x5B;'minmaxRssi']&#x5B;1]])\n                registro&#x5B;cual]&#x5B;'minmaxRssi']&#x5B;2] = np.min(&#x5B;rssi_rx,registro&#x5B;cual]&#x5B;'minmaxRssi']&#x5B;2]])\n                registro&#x5B;cual]&#x5B;'minmaxRssi']&#x5B;3] = np.max(&#x5B;rssi_rx,registro&#x5B;cual]&#x5B;'minmaxRssi']&#x5B;3]])\n\n                registro&#x5B;cual]&#x5B;'minmaxSnr']&#x5B;0] = np.min(&#x5B;snr_tx,registro&#x5B;cual]&#x5B;'minmaxSnr']&#x5B;0]])\n                registro&#x5B;cual]&#x5B;'minmaxSnr']&#x5B;1] = np.max(&#x5B;snr_tx,registro&#x5B;cual]&#x5B;'minmaxSnr']&#x5B;1]])\n                registro&#x5B;cual]&#x5B;'minmaxSnr']&#x5B;2] = np.min(&#x5B;snr_rx,registro&#x5B;cual]&#x5B;'minmaxSnr']&#x5B;2]])\n                registro&#x5B;cual]&#x5B;'minmaxSnr']&#x5B;3] = np.max(&#x5B;snr_rx,registro&#x5B;cual]&#x5B;'minmaxSnr']&#x5B;3]])\n\n            # Muestra en pantalla el estado de recepci\u00f3n\n            print('\\n difusion: ',difunde)\n            print(texto)\n            for elemento in baliza:\n                print(elemento,registro&#x5B;elemento]&#x5B;'cuenta'],\n                      '\\tprom Rssi&#x5B;tx,rx] \\t   Snr&#x5B;tx,rx]')\n                print(&quot;prom   :&quot;,registro&#x5B;elemento]&#x5B;'rssi'],&quot;\\t  &quot;,\n                      registro&#x5B;elemento]&#x5B;'snr'])\n                print(&quot;min,max:&quot;,registro&#x5B;elemento]&#x5B;'minmaxRssi'],\n                      registro&#x5B;elemento]&#x5B;'minmaxSnr'])\n\n# Cerrar el puerto serial.\nserial.Serial.close\n<\/pre><\/div>","protected":false},"excerpt":{"rendered":"<p>La relaci\u00f3n de valores de Rssi y distancia hacia cada punto de referencia (baliza), se estima a partir de las mediciones en varios puntos establecidos y ubicados en un mapa. En cada punto, los valores se estiman considerando usar al menos 100 lecturas hacia cada baliza en cada punto. En \u00e9ste proceso usa un computador [&hellip;]<\/p>\n","protected":false},"author":8043,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1463489],"tags":[1457738,20777],"class_list":["post-2683","post","type-post","status-publish","format-standard","hentry","category-lorawan-localizacion-rssi","tag-lora","tag-python"],"_links":{"self":[{"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/posts\/2683","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=2683"}],"version-history":[{"count":31,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/posts\/2683\/revisions"}],"predecessor-version":[{"id":4806,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/posts\/2683\/revisions\/4806"}],"wp:attachment":[{"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/media?parent=2683"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/categories?post=2683"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/tags?post=2683"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}