Codigo de la tarjeta ESP32 midiendo temperatura y humedad con DHT11 y enviando datos por esp-now a otra ESP32:
#include <Arduino.h>
#include <WiFi.h>
#include <esp_now.h>
#include <DHT.h>
#include <Adafruit_Sensor.h>
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
#define DHTPIN 14
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
// Structure example to send data
// Must match the receiver structure
typedef struct struct_message {
String dht="dht";
int a;
float b;
float c;
} struct_message;
// Create a struct_message called myData
struct_message myDataSen;
esp_now_peer_info_t peerInfo;
// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("\r\nLast Packet Send Status:\t");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
void setup() {
// Init Serial Monitor
Serial.begin(9600);
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
dht.begin();
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for Send CB to
// get the status of Trasnmitted packet
esp_now_register_send_cb(OnDataSent);
// Register peer
//Este apartado del peer es util para enviar el paquete
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
}
void loop() {
float h = dht.readHumidity();
// Read temperature as Celsius
float t = dht.readTemperature();
// Read temperature as Fahrenheit
float f = dht.readTemperature(true);
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println(F("Failed to read from DHT sensor!"));
return;
}
// Compute heat index in Fahrenheit
float hif = dht.computeHeatIndex(f, h);
// Compute heat index in Celsius
float hic = dht.computeHeatIndex(t, h, false);
myDataSen.b=h;
myDataSen.c=hic;
// Send message via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myDataSen, sizeof(myDataSen));
delay(2000);
}
El archivo platform.ini para importar las librerias quedaría de la siguiente forma:
[env:az-delivery-devkit-v4]
platform = espressif32
board = az-delivery-devkit-v4
framework = arduino
lib_deps =
adafruit/DHT sensor library @ ^1.4.3
adafruit/Adafruit Unified Sensor @ ^1.1.4
Las primeras líneas son directivas de preprocesador en C++ que incluyen («include») varias bibliotecas:
- #include <Arduino.h>: Esta línea incluye la biblioteca principal de Arduino, que proporciona las funciones básicas de Arduino como digitalRead(), digitalWrite(), analogRead(), analogWrite(), delay(), etc.
- #include <WiFi.h>: Esta línea incluye la biblioteca WiFi, que proporciona las funciones necesarias para conectarse a una red WiFi. Esta biblioteca es específica para algunas placas de Arduino que tienen capacidades WiFi incorporadas, como el ESP8266 y el ESP32.
- #include <esp_now.h>: Esta línea incluye la biblioteca ESP-NOW, que es un protocolo de comunicación desarrollado por Espressif (los fabricantes de los chips ESP8266 y ESP32) que permite la comunicación directa entre dos dispositivos ESP sin necesidad de un punto de acceso WiFi.
- #include <DHT.h>: Esta línea incluye la biblioteca DHT, que proporciona funciones para leer datos de los sensores de temperatura y humedad DHT.
- #include <Adafruit_Sensor.h>: Esta línea incluye la biblioteca Adafruit_Sensor, que proporciona una interfaz común para varios sensores de Adafruit. Esta biblioteca es necesaria para usar la biblioteca DHT.
Esta línea de código «DHT dht(DHTPIN, DHTTYPE);» está creando una instancia de la clase DHT llamada dht. DHT es una clase definida en la biblioteca DHT que se utiliza para interactuar con los sensores de temperatura y humedad DHT, como el DHT11 o el DHT22.
- DHT: Es el nombre de la clase. Esta clase proporciona las funciones necesarias para leer datos del sensor DHT.
- dht: Es el nombre de la instancia de la clase DHT que estás creando. Una vez que esta instancia se ha creado, puedes usarla para acceder a las funciones y propiedades de la clase DHT.
- DHTPIN: Es el número del pin al que está conectado el sensor DHT. Este valor se pasa al constructor de la clase DHT cuando creas la instancia dht.
- DHTTYPE: Es el tipo de sensor DHT que estás utilizando. Los sensores DHT vienen en varias versiones, como DHT11, DHT22 y AM2302. Este valor también se pasa al constructor de la clase DHT.
Por lo tanto, DHT dht(DHTPIN, DHTTYPE); está creando una nueva instancia de la clase DHT, pasando el número del pin y el tipo de sensor al constructor de la clase. Esta instancia se puede utilizar luego para leer datos del sensor.
La siguiente linea de código está definiendo una estructura (struct) llamada struct_message. Una estructura es una colección de variables de diferentes tipos que se agrupan bajo un mismo nombre. Aquí está el desglose:
- typedef struct struct_message: typedef es una palabra clave en C++ que se utiliza para dar un nombre a un tipo de datos existente. En este caso, se está utilizando para dar el nombre struct_message a la estructura que estás definiendo.
- String dht=»dht»;: Esta línea está definiendo un miembro de la estructura llamado dht que es de tipo String y se inicializa con el valor «dht».
- int a;: Esta línea está definiendo un miembro de la estructura llamado a que es de tipo int.
- float b;: Esta línea está definiendo un miembro de la estructura llamado b que es de tipo float.
- float c;: Esta línea está definiendo un miembro de la estructura llamado c que es de tipo float.
- } struct_message;: Esta línea cierra la definición de la estructura y repite el nombre struct_message como parte de la declaración typedef.
Esta línea de código «struct_message myDataSen;» está creando una instancia de la estructura struct_message que se llama myDataSen.
Aquí está el desglose:
- struct_message: Es el nombre de la estructura que se definió anteriormente. Esta estructura incluye los miembros dht (una cadena), a (un entero), b (un flotante) y c (un flotante).
- myDataSen: Es el nombre de la instancia de struct_message que estás creando.
Esta línea de código «esp_now_peer_info_t peerInfo;» está creando una instancia de la estructura esp_now_peer_info_t llamada peerInfo.
esp_now_peer_info_t es una estructura definida en la biblioteca ESP-NOW de Espressif. Esta estructura se utiliza para almacenar información sobre un «par» o «peer» en la red ESP-NOW:
- esp_now_peer_info_t: Es el nombre de la estructura. Esta estructura incluye varios miembros que almacenan información sobre un par, como su dirección MAC, el canal en el que está operando, y si el par está permitido para encriptar datos.
- peerInfo: Es el nombre de la instancia de esp_now_peer_info_t que estás creando.
Este código pertenece al detector de humedad de suelo, colocado en una planta, y enviando los datos a otra ESP32 por esp-now:
#include <Arduino.h>
#include <WiFi.h>
#include <esp_now.h>
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
int sensorValue;
const int SensorPin=14;
// Structure example to send data
// Must match the receiver structure
typedef struct struct_message {
String moisture="moisture";
int a;
float b;
float c;
} struct_message;
// Create a struct_message called myData
struct_message myDataSen;
esp_now_peer_info_t peerInfo;
// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("\r\nLast Packet Send Status:\t");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
void setup() {
// Init Serial Monitor
Serial.begin(9600);
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
pinMode(SensorPin, INPUT_PULLDOWN);
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for Send CB to
// get the status of Trasnmitted packet
esp_now_register_send_cb(OnDataSent);
// Register peer
//Este apartado del peer es util para enviar el paquete
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
}
void loop() {
sensorValue = analogRead(SensorPin);
int humedad = (100 - ((sensorValue/4095.00) * 100));
myDataSen.a=humedad;
// Send message via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myDataSen, sizeof(myDataSen));
Serial.println(myDataSen.moisture);
Serial.println(myDataSen.a);
delay(2000);
}
Este codigo de abajo pertenece al tarjeta ESP32 que recoge los datos de las otras tarjetas ESP32 por esp-now y los envia por USB a una tarjeta CPU PINE A64:
#include <Arduino.h>
#include <WiFi.h>
#include <esp_now.h>
typedef struct struct_message {
String sensor;
int a;
float b;
float c;
} struct_message;
// Create a struct_message called myData
struct_message myDataRec;
esp_now_peer_info_t peerInfo;
String array[4];
// callback function that will be executed when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&myDataRec, incomingData, sizeof(myDataRec));
array[0]=myDataRec.sensor;
array[1]=myDataRec.a;
array[2]=myDataRec.b;
array[3]=myDataRec.c;
Serial.print(array[0]);
Serial.print(",");
Serial.print(array[1]);
Serial.print(",");
Serial.print(array[2]);
Serial.print(",");
Serial.println(array[3]);
}
void setup() {
// Initialize Serial Monitor
Serial.begin(9600);
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for recv CB to
// get recv packer info
esp_now_register_recv_cb(OnDataRecv);
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
}
void loop() {
}
El código de abajo pertenece a la CPU de la tarjeta PINE A64, que recoge los datos de la ESP32 por puerto USB y los muestra en una pantalla, el sistema operativo es linux-armbian, y el código que administra los datos es python:
import tkinter as tk
import serial
from PIL import Image, ImageTk
window=tk.Tk()
def end_fullscreen(event=None):
window.attributes('-fullscreen', False)
window.geometry('500x500')
window.title("Ventana de control")
window.attributes('-fullscreen', True)
window.bind('<F10>', end_fullscreen)
image1 = Image.open("/home/control/Downloads/planta.jpeg")
image1=image1.resize((200, 200))
photo1 = ImageTk.PhotoImage(image1)
image2 = Image.open("/home/control/Downloads/sol.gif")
image2=image2.resize((200, 200))
photo2 = ImageTk.PhotoImage(image2)
frame1 = tk.Frame(window, bg='white')
frame1.pack(side='left', fill='both', expand=True)
label1=tk.Label(frame1, image=photo1)
label1.pack(padx=10, pady=10)
frame2 = tk.Frame(window, bg='white')
frame2.pack(side='right', fill='both', expand=True)
label2=tk.Label(frame2, image=photo2)
label2.pack(padx=10, pady=10)
esp32_1_label=tk.Label(frame1, text="")
esp32_1_label.pack()
esp32_2_label=tk.Label(frame2, text="")
esp32_2_label.pack()
#Centrar la ventana
window_width=window.winfo_reqwidth()
window_height=window.winfo_reqheight()
position_top=int(window.winfo_screenmmheight() / 2 - window_height / 2)
position_right=int(window.winfo_screenmmwidth() / 2 - window_width / 2)
window.geometry("+{}+{}".format(position_right, position_top))
ser=serial.Serial('/dev/ttyUSB0', 9600)
def update_label():
if ser.in_waiting > 0:
line=ser.readline().decode('utf-8').rstrip()
values=line.split(',')
if values[0] == 'moisture':
esp32_1_label.config(text="La humedad de la planta es:" + "\n" + values[1] + " %")
if values[0] == 'dht':
esp32_2_label.config(text="La temperatura que hace es:" + "\n" + values[3] + " °C" + "\nLa humedad que hace es de:" + "\n" + values[2] + " %")
window.after(100, update_label)
update_label()
window.mainloop()
En el siguiente enlace puedes ver la explicación del código python de arriba, para mostrar los datos recibidos por usb de una ESP32 en una pantalla de ordenador:
La siguiente imagen pertenece a la pantalla que monitorea las señales de los sensores:
Deja una respuesta Cancelar la respuesta