Registro de datos de balanza via WIFI




Presentación


El presente proyecto nace a partir de la inquietud planteada por @JluisGamers en el OffTopic del grupo ESP32 8266 S2 S3 C3 RISC-V (ES/EN) de Telegram para migrar la trasnmisión de datos entre una balanaza y una PC que se venía realizando con una placa Arduino conectada mediante el puerto serie a la PC a una conexión median wifi utilizando placas Esp32”.

A los efectos de la migración evalue dos posibilidades, la primera usar dos placas Esp32 una conectada a la balanza y la otra conectada a la PC, aprovechando de la programacion hecha en la PC para recibir los datos por el puerto serie y la segunda usar una sola Esp32 en la balanza y recibir los datos a traves del wifi de la PC, me incline por la segunda en vitud que se ahorraba una placa Esp32 y el uso de un puerto USB de la PC y si bien habia que reprogramar la recepción de los datos, en el otro caso también haía que programar la placa receptora.

En relación a los posibles lenguajes de programacio decidi utilizar la IDE de Arduino para programar la Esp32 y Python 3 para programar la recepción de los datos en la PC y volcado a la hoja Excel

Cabe aclarar que personalmente estoy encontra del uso de software privativo y me incninaria por otras alternativas al Excel para el registro de los datos pero en virtud que la programación original a migrar utilizaba este programa decide respetarlo

Asi mismo tambien debo señalar que he usado la placa Esp32-Cam ya que era la que disponia, pero puede usarse cualquier otra placa Esp32



Materiales


Placa Esp32-Cam

Programador Esp32-Cam


Si bien por ser mas cómodo y práctico se ha usado el adaptador el mismo puede ser remplazado por una placa FTDI y el cableado pertinente.


Programación Esp32


El programa de la Esp32 es bastane sencillo consta de un servidor web que sirve una pagina donde solamente se muestra una variable con la siguiente estructura;

"nndatoxxxxxxxxxxxx" donde "dato" es la marca para poder luego localizar los datos para guardar "xxxxxxxx" es el dato a enviar y "nn" representa la longitud del dato a enviar

Dado que no dispongo de la balanza donde se originan los datos lo simule mediante un ingreso de datos a traves del Monitor Serial del IDE de arduino


Programación de la lectura en la PC


Para la lectura de los datos en la PC utilice la librería "requests" nediante la cual se carga en una variable los datos servidos por la Esp32. En la misma luego de localizado la marca #dato" se puede mediante recortes de cadena obtener la longitud del dato enviado y luego el dato mismo.

Luego usando la libreria "openpyxl" se agrega ese dato mas la fecha y la hora a una hoja de Excel.


Codigo


El codigo se ha escrito en dos archivos lectubalanza.ino que se carga en la Esp32 y lectura.py que sse ejecuta en la PC.


lectubalanza.ino




        /*
        * ESP32 
        * Envia datos a pagina web y refresca la pagina
        * 
        */
       #include <WiFi.h>
       
       
       //------------------Datos de la Red WIFI---------------------
       
       const char* red = "xxxxxxxxxx";
       
       const char* clave = "xxxxxxxxx";
       
       //------------------Servidor Web en puerto 80---------------------
       
       WiFiServer server(80);
       
       char caracter = '0';
       String texto = "";
       String texto_enviar = "";
       
       
       //---------------------VARIABLES GLOBALES-------------------------
       int contconexion = 0;
       
       String cabecera; // Variable para guardar el HTTP request
       
       //------------------------CODIGO HTML------------------------------
       String paginaInicio = "<!DOCTYPE html>"
       "<html>"
       "<head>"
       "<meta charset='utf-8' />"
       "<META HTTP-EQUIV='Refresh' CONTENT='10'>"
       "</head>"
       "<body>"
       "<center>";
       
       
       String paginaFin = "</center>"
       "</body>"
       "</html>";
       
       
       
       
       
       //---------------------------SETUP--------------------------------
       void setup() {
       
         
         Serial.begin(115200);
         Serial.println("");
         
         // Conexión WIFI
         WiFi.begin(red, clave);
         //Cuenta hasta 50 si no se puede conectar lo cancela
         while (WiFi.status() != WL_CONNECTED and contconexion <50) { 
           ++contconexion;
           delay(500);
           Serial.print(".");
         }
         if (contconexion <50) {
             
             Serial.println("");
             Serial.println("WiFi conectado");
             Serial.println(WiFi.localIP());
             Serial.println("Esta es la IP que debe colocarse en el programa de lectura");
             server.begin(); // iniciamos el servidor
         }
         else { 
             Serial.println("");
             Serial.println("Error de conexion");
         }
       }
       
       //----------------------------LOOP----------------------------------
       
       void loop(){
         WiFiClient client = server.available();   // Escucha a los clientes entrantes
       
         if (client) {                             // Si se conecta un nuevo cliente
           //Serial.println("New Client.");          // 
           String currentLine = "";                //
           while (client.connected()) {            // loop mientras el cliente está conectado
             if (client.available()) {             // si hay bytes para leer desde el cliente
               char c = client.read();             // lee un byte
             //  Serial.write(c);                    // imprime ese byte en el monitor serial
               cabecera += c;
               if (c == '\n') {                    // si el byte es un caracter de salto de linea
                 // si la nueva linea está en blanco significa que es el fin del 
                 // HTTP request del cliente, entonces respondemos:
                 if (currentLine.length() == 0) {
                   client.println("HTTP/1.1 200 OK");
                   client.println("Content-type:text/html");
                   client.println("Connection: close");
                   client.println();
                            
                   // Muestra la página web
                   client.println(paginaInicio + texto_enviar + paginaFin);
                   texto_enviar ="";
                   // la respuesta HTTP temina con una linea en blanco
                   client.println();
                   break;
                 } else { // si tenemos una nueva linea limpiamos currentLine
                   currentLine = "";
                 }
               } else if (c != '\r') {  // si C es distinto al caracter de retorno de carro
                 currentLine += c;      // lo agrega al final de currentLine
               }
             }
           }
           // Limpiamos la variable cabecera
           cabecera = "";
           // Cerramos la conexión
           client.stop();
           //Serial.println("Client disconnected.");
           //Serial.println("");
         }
       
       
         //////////////// ENVIAR TEXTO DEL MONITOR SERIE  ////////////
         // esta parte se debe modificar para enviar datos recibidos por el puerto serie desde la balanza
           if (Serial.available() > 0) { // ¿Hay algún caracter?
               caracter = Serial.read(); // Toma el caracter
               texto += caracter;
             
               if (caracter == '\n') {
                   texto_enviar = "dato" + texto;
                   char char_texto[3];
                   int largo = texto.length(); 
                   sprintf(char_texto, "%2d", largo);
                   String largo_texto = String(char_texto);  
                   texto_enviar = largo_texto + "dato" + texto; 
                   texto = "";
               }
           }
       //////////////////////////////////////////////////////////////
       }            
    

lectura.py



        
import requests
import openpyxl
import sys 
from datetime import date
from datetime import datetime


try:
    open('balanzas.xlsx')
    
except FileNotFoundError:
    nuevo = openpyxl.Workbook("balanzas.xlsx")
    nuevo.save("balanzas.xlsx")
    nuevo = openpyxl.load_workbook("balanzas.xlsx")
    nueva = nuevo.worksheets[0]
    nueva.append(["Fecha", "Hora", "Peso Registrado"])
    nuevo.save("balanzas.xlsx")


hoja = openpyxl.load_workbook("balanzas.xlsx")

celda = hoja.worksheets[0]



# URL de la página web
url = 'http://192.168.0.129' #esta Ip debe cambiarse por la que la red le asigne a la esp32 

# Hacer una solicitud HTTP para obtener el contenido de la página
linea = celda.max_row

while True:
     
    response = requests.get(url)
    if response.status_code == 200:
        pagina = response.text
        # Encontrar el dato
        indice = pagina.find("dato")
        if indice != -1:
            linea = linea + 1
            largo = pagina[indice - 2 : indice]
            fin = int(largo) + indice + 4
            peso = pagina[indice + 4 : fin]
            if peso.rstrip() == "exit":
                sys.exit()
                
            celda.append([date.today(), datetime.now().strftime('%H:%M'), int(peso.rstrip())])
            hoja.save("balanzas.xlsx")
    
      
    

Cerrar