Tabla de contenido:

Temperatura y humedad usando ESP32-DHT22-MQTT-MySQL-PHP: 7 pasos
Temperatura y humedad usando ESP32-DHT22-MQTT-MySQL-PHP: 7 pasos

Video: Temperatura y humedad usando ESP32-DHT22-MQTT-MySQL-PHP: 7 pasos

Video: Temperatura y humedad usando ESP32-DHT22-MQTT-MySQL-PHP: 7 pasos
Video: Medir temperatura con PHP y DHT22 2024, Mes de julio
Anonim
Temperatura y humedad con ESP32-DHT22-MQTT-MySQL-PHP
Temperatura y humedad con ESP32-DHT22-MQTT-MySQL-PHP

Mi novia quería un invernadero, así que le hice uno. Pero quería un sensor de temperatura y humedad dentro del invernadero. Entonces, busqué ejemplos en Google y comencé a experimentar.

Mi conclusión fue que todos los ejemplos que encontré no eran exactamente los que quería construir. Tomé un montón de pequeñas partes de código y las combiné. Me tomó bastante tiempo terminar mi primera compilación de trabajo porque la documentación de la mayoría de los ejemplos era demasiado difícil de entender para mí o asumían parte que debería saber. Pero no sabía nada (todavía) ☹

Es por eso que construyo este instructable. Un tutorial de "principio hasta el final" para que todo el mundo lo entienda. (¿Al menos eso espero?)

Cómo funciona …

El producto final es una ESP32-CAM con un sensor DHT22 adjunto que obtiene energía de una batería 18650. Cada tres minutos lee la temperatura y la humedad y la envía a través de WiFi a un servidor MQTT externo y luego se pone en suspensión (durante tres minutos) para usar la menor cantidad de batería que sea necesaria

En un servidor Debian (que también podría ser una frambuesa pi, supongo) tengo python3, un servidor MQTT, un servidor MySQL y un servidor web

El script python3 se ejecuta como un servicio y cada vez que recibe un mensaje MQTT, cuenta el número anterior de entradas (número de índice) y lo incrementa en uno. Luego lee los valores de temperatura y humedad del mensaje MQTT. Comprueba si hay valores falsos y siempre que los valores son correctos, envía los valores junto con el nuevo número de índice y la fecha y hora actuales a un servidor MySQL

El servidor web tiene un script PHP que lee los valores del servidor MySQL y hace un buen gráfico usando Google Charts. (ejemplo)

Suministros

Las partes que utilicé son las siguientes:

  • ESP32-CAM (La razón por la que utilicé la versión de cámara es porque tiene un conector de antena externa. Probablemente también hay otros ESP32 que podrías usar)
  • Antena externa
  • Sensor AM2302 DHT22 (Este tiene una resistencia incorporada, por lo que solo necesita tres cables)

    https://www.amazon.de/gp/product/B07CM2VLBK/ref=p…

  • 18650 escudo de batería v3
  • Batería 18650 (NCR18650B)
  • Cable micro USB antiguo (para conectar el ESP32 al protector de la batería)
  • Algunos cables de puente cortos

Extra necesario:

  • Conector USB a TTL (imagen)

    https://www.amazon.de/FT232RL-Seriell-Unterst%C3%…

  • Soldador
  • Impresora 3D (solo necesaria para la carcasa)

Paso 1: cargue el código Arduino en el ESP32-CAM

Sube el código Arduino al ESP32-CAM
Sube el código Arduino al ESP32-CAM

¡Vamos a empezar!

Para cargar el código Arduino al ESP32-CAM, debe conectar el conector USBtoTTL al ESP32 usando los esquemas anteriores.

El código Arduino es:

/ * Solo un pequeño programa para leer la temperatura y la humedad de un sensor DHT22 y

páselo a MQTT. B. Duijnhouwer, 8 de junio de 2020 * / #include #include #include #define wifi_ssid "*** WIFI_SSID ***" // wifi ssid #define wifi_password "*** WIFI_PASSWORD ***" // wifi password #define mqtt_server "*** SERVER_NAME ***" // nombre del servidor o IP #define mqtt_user "*** MQTT_USER ***" // nombre de usuario #define mqtt_password "*** MQTT_PASSWORD ***" // contraseña #define topic "invernadero / dhtreadings "#define debug_topic" glasshouse / debug "// Tema para la depuración / * definiciones para el sueño profundo * / #define uS_TO_S_FACTOR 1000000 / * Factor de conversión de microsegundos a segundos * / #define TIME_TO_SLEEP 180 / * Tiempo que el ESP32 se dormirá durante 5 minutos (en segundos) * / bool debug = true; // Mostrar mensaje de registro si es verdadero #define DHT22_PIN 14 dht DHT; WiFiClient espClient; Cliente PubSubClient (espClient); datos de char [80]; configuración vacía () {Serial.begin (115200); setup_wifi (); // Conectarse a la red Wifi client.setServer (mqtt_server, 1883); // Configure la conexión MQTT, cambie el puerto si es necesario. if (! client.connected ()) {reconectar (); } // LEER DATOS int chk = DHT.read22 (DHT22_PIN); float t = DHT.temperatura; flotador h = DHT.humedad; String dhtReadings = "{" temperatura / ": \" "+ String (t) +" / ", \" humedad / ": \" "+ String (h) +" / "}"; dhtReadings.toCharArray (datos, (dhtReadings.length () + 1)); if (depuración) {Serial.print ("Temperatura:"); Serial.print (t); Serial.print ("| Humedad:"); Serial.println (h); } // Publicar valores en temas MQTT client.publish (tema, datos); // Publicar lecturas sobre el tema (invernadero / dhtreadings) if (debug) {Serial.println ("Lecturas enviadas a MQTT."); } esp_sleep_enable_timer_wakeup (TIME_TO_SLEEP * uS_TO_S_FACTOR); // ir a dormir Serial.println ("Configurar ESP32 para dormir por cada" + String (TIME_TO_SLEEP) + "Segundos"); Serial.println ("Ahora me voy a dormir normalmente"); esp_deep_sleep_start (); } // Configurar conexión a wifi void setup_wifi () {delay (20); Serial.println (); Serial.print ("Conectando a"); Serial.println (wifi_ssid); WiFi.begin (wifi_ssid, wifi_password); while (WiFi.status ()! = WL_CONNECTED) {retraso (100); Serial.print ("."); } Serial.println (""); Serial.println ("WiFi está bien"); Serial.print ("=> La nueva dirección IP de ESP32 es:"); Serial.print (WiFi.localIP ()); Serial.println (""); } // Vuelva a conectarse a wifi si se pierde la conexión void reconnect () {while (! Client.connected ()) {Serial.print ("Conectando con el agente MQTT…"); if (client.connect ("ESP32Client", mqtt_user, mqtt_password)) {Serial.println ("OK"); } else {Serial.print ("[Error] No conectado:"); Serial.print (client.state ()); Serial.println ("Espere 5 segundos antes de reintentar"); retraso (5000); }}} bucle vacío () {}

Y nuevamente, ¡no olvide reemplazar las credenciales con sus propias credenciales

Paso 2: ¡Conéctese

¡Cablear!
¡Cablear!

Para la alimentación, utilicé un cable USB antiguo del que corté el conector USB-A. Hay cuatro hilos en el cable USB, solo necesitamos el negro y el rojo.

Por lo tanto, conecte todo de acuerdo con el programa anterior.

Paso 3: secuencia de comandos de Python3

La secuencia de comandos de Python3 entra en un lugar donde es accesible para el usuario root.

Usé /root/scripts/glasshouse/glasshouse.py para este script. El contenido del script de Python es:

# Script Python3 para conectarse a MQTT, leer valores y escribirlos en MySQL

# # B. Duijnhouwer # 8 de junio de 2020 # # versión: 1.0 # # import paho.mqtt.client como mqtt import json import pymysql pymysql.install_as_MySQLdb () import MySQLdb from datetime import datetime db = MySQLdb.connect ("localhost", "glasshouse", "*** MYSQL_USERNAME ***", "*** MYSQL_PASSWORD ***") cursor = db.cursor () broker_address = "localhost" #Broker address port = 1883 #Broker port user = "** * MQTT_USERNAME *** "#Connection username password =" *** MQTT_PASSWORD *** "#Connection Password def on_connect (client, userdata, flags, rc): # La devolución de llamada para cuando el cliente se conecta al broker print (" Connected con el código de resultado {0} ". format (str (rc))) # Imprime el resultado del intento de conexión client.subscribe (" glasshouse / dhtreadings / # ") def on_message (client, userdata, msg): # La devolución de llamada para cuando un Se recibe el mensaje PUBLICAR desde el servidor. cursor.execute ("select * from sensordata") numrows = int (cursor.rowcount) newrow = numrows + 1 now = datetime.now () formatted_date = now.strftime ('% Y-% m-% d% H:% M:% S ') payload = json.loads (msg.payload.decode (' utf-8 ')) print ("Nueva fila:" + str (newrow)) temperatura = flotar (carga útil ["temperatura"]) humedad = float (payload ["humedad"]) print ("Temperatura:" + str (temperatura)) print ("Humedad:" + str (humedad)) print ("DateTime:" + str (formatted_date)) if ((temperatura > -20) y (temperatura = 0) y (humedad <= 100)): cur = db.cursor () cur.execute ("INSERT INTO glasshouse.sensordata (idx, temperature, humedad, timestamp) VALUES (" + str (newrow) + "," + str (temperatura) + "," + str (humedad) + ",% s)", (formatted_date)) db.commit () print ("datos recibidos e importados en MySQL") más: print ("los datos excedieron los límites y NO se importan en MySQL") client = mqtt. Client ("duijnhouwer-com-glasshouse-script") client.username_pw_set (usuario, contraseña = contraseña) client.on_connect = on_connect # Definir la función de devolución de llamada por conexión exitosa client.on_message = on_message # Definir la función de devolución de llamada para la recepción de un mensaje client.connect (broker_address, port = port) #connect to broker client.loop_forever () # Iniciar demonio de red

¡No olvide reemplazar el nombre de usuario y contraseña de MySQL y el nombre de usuario y contraseña de MQTT por sus propias credenciales

Puede hacer que el script se ejecute como un servicio creando dos archivos.

El primero es “/etc/init/glasshouse.conf” con el siguiente contenido:

comenzar en el nivel de ejecución [2345]

detener en el nivel de ejecución [! 2345] exec /root/scripts/glasshouse/glasshouse.py

El segundo es “/etc/systemd/system/multi-user.target.wants/glasshouse.service” con el siguiente contenido:

[Unidad]

Descripción = Servicio de monitoreo de Glasshouse Después de = multi-user.target [Servicio] Tipo = simple Reinicio = siempre RestartSec = 1 ExecStart = / usr / bin / python3 /root/scripts/glasshouse/glasshouse.py [Instalar] WantedBy = multiusuario.objetivo

Puede hacer que esto se ejecute como un servicio usando el siguiente comando:

systemctl habilitar invernadero

e inícielo usando:

invernadero systemctl start

Paso 4: servidor MySQL

Tienes que crear una nueva base de datos MySQL con solo una tabla.

El código para crear la tabla es:

CREAR TABLA `sensordata` (`idx` int (11) DEFAULT NULL,` temperature` float DEFAULT NULL, `humedad` float DEFAULT NULL,` timestamp` datetime DEFAULT NULL) ENGINE = InnoDB DEFAULT CHARSET = utf8;

Paso 5: servidor web

El servidor web tiene dos archivos, el archivo index.php y un archivo config.ini

El contenido del archivo config.ini es:

[base de datos]

db_host = "localhost" db_name = "invernadero" db_table = "sensordata" db_user = "*** DATABASE_USER ***" db_password = "*** DATABASE_PASSWORD ***"

Donde, por supuesto, reemplaza *** DATABASE_USER *** y *** DATABASE_PASSWORD *** con sus propias credenciales.

google.charts.load ('actual', {'paquetes': ['corechart']}); google.charts.setOnLoadCallback (drawChart); function drawChart () {var data = google.visualization.arrayToDataTable ([// ['Marca de tiempo', 'Temperatura', 'Humedad', 'Índice de calor'], ['Marca de tiempo', 'Temperatura', 'Humedad'], query ($ sql); # Este ciclo while - formatea y coloca todos los datos recuperados en forma ['marca de tiempo', 'temperatura', 'humedad']. while ($ fila = $ resultado-> fetch_assoc ()) {$ marca de tiempo_resto = substr ($ row ["marca de tiempo"], 10, 6); echo "['". $ timestamp_rest. "',". $ fila ['temperatura']. ",". $ fila ['humedad']. "],"; // echo "['". $ timestamp_rest. "',". $ fila ['temperatura']. ",". $ fila ['humedad']. ",". $ fila ['índice de calor ']. "],";}?>]); // Opciones de var de línea curva = {título: 'Temperatura y humedad', curveType: 'function', legend: {position: 'bottom'}, hAxis: {slantedText: true, slantedTextAngle: 45}}; // Gráfico curvo var chart = new google.visualization. LineChart (document.getElementById ('curve_chart')); chart.draw (datos, opciones); } // Fin del corchete de drawChart //

Paso 6: Carcasa impresa en 3D

Para la carcasa, utilicé dos carcasas separadas, una para ESP32-CAM y DHT22 juntas y otra para el protector de batería 18650.

Paso 7: ¡El resultado final

¡El resultado final!
¡El resultado final!
¡El resultado final!
¡El resultado final!
¡El resultado final!
¡El resultado final!
¡El resultado final!
¡El resultado final!

El resultado final también se muestra en las imágenes de arriba.

Y siempre que la batería esté vacía, puede cargarla con un cable mini USB.

Recomendado: