domingo, 1 de diciembre de 2024

Aprende a medir corriente alterna y contina con el sensor ACS712 y ardui...

//CODIGO PARA LEER LA SEÑAL DE CORRIENTE DE UN MODULO ACS712
//http://www.editronikx.com.co
float Sensibilidad_5A = 0.185; //sensibilidad en Voltios/Amperio para sensor de 5A Sale de la tabla
float Sensibilidad_20A = 0.1;//sensibilidad en Voltios/Amperio para sensor de 20A Sale de la tabla
float Sensibilidad_30A = 0.066;//sensibilidad en Voltios/Amperio para sensor de 30A Sale de la tabla

#define ACS712_PIN A0  // Pin analógico donde está conectado el sensor ACS712
#define NUM_LECTURAS 200  // Cantidad de mediciones para hacer el promedio

float offset = 2.49;  // Offset del ACS712 (2.5V para señales DC)

void setup() {
  Serial.begin(9600);
}

void loop() {
  float sumLecturas = 0;

  // Realizar múltiples lecturas y sumarlas
  for (int i = 0; i < NUM_LECTURAS; i++)
  {
    int bits = analogRead(ACS712_PIN);
    float voltage = (bits / 1023.0) * 5.0;  // Convertir el valor analógico a voltaje (0-5V)
    sumLecturas += voltage;
  }

  // Calcular el promedio de voltaje
  float voltaje_prom = sumLecturas / NUM_LECTURAS;

  // Calcular el amperaje en base al voltaje promedio
  float corriente = (voltaje_prom - offset) / Sensibilidad_20A;

  // Mostrar el valor de corriente en el monitor serie
  Serial.print("Corriente: ");
  Serial.print(corriente,4);
  Serial.println(" A");

  delay(500);  // Esperar un poco antes de la siguiente lectura
}

domingo, 3 de noviembre de 2024

No 12 Diseña tu App en AppInventor y Conéctala a Firebase para Control a...

codigo
/*
    idea original de: ESP32: https://RandomNerdTutorials.com/firebase-control-esp32-gpios/
    modificado por: Mg.ing.edison v
*/

#if defined(ESP32)
  #include <WiFi.h> // Incluye la librería WiFi si el microcontrolador es ESP32
#elif defined(ESP8266)
  #include <ESP8266WiFi.h> // Incluye la librería WiFi si el microcontrolador es ESP8266
#endif
#include <Firebase_ESP_Client.h> // Incluye la librería Firebase para interactuar con el servicio

// Proporciona información sobre el proceso de generación de tokens
#include "addons/TokenHelper.h"
// Proporciona funciones para imprimir los datos de la base de datos en tiempo real (RTDB)
#include "addons/RTDBHelper.h"

// Insertar las credenciales de la red WiFi
#define WIFI_SSID "SU RED WIFI" // Nombre de la red WiFi
#define WIFI_PASSWORD "LA CLAVE WIFI" // Contraseña de la red WiFi

// Insertar la clave de API del proyecto Firebase
#define API_KEY "SU API" // Clave API de Firebase

// Insertar el nombre de usuario autorizado y la contraseña correspondiente
#define USER_EMAIL "SU CORREO" // Correo electrónico del usuario
#define USER_PASSWORD "CU CLAVE DE CORREO QUE INGRESO" // Contraseña del usuario

// Insertar la URL de la base de datos en tiempo real (RTDB)
#define DATABASE_URL "URL DE DU BASE DATOS" // URL de la base de datos

// Define los objetos de Firebase
FirebaseData stream; // Objeto para manejar la transmisión de datos de Firebase
FirebaseAuth auth; // Objeto para manejar la autenticación en Firebase
FirebaseConfig config; // Objeto para manejar la configuración de Firebase

// Variable para guardar la ruta de la base de datos
String listenerPath = "board2/outputs/digital/"; // Ruta para escuchar los cambios en la base de datos

// Declarar pines de salida
const int output1 = 12; // Pin GPIO 12 para salida
const int output2 = 13; // Pin GPIO 13 para salida
const int output3 = 14; // Pin GPIO 14 para salida

// Inicializar WiFi
void initWiFi() {
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD); // Inicia la conexión WiFi con las credenciales proporcionadas
  Serial.print("Connecting to WiFi .."); // Imprime mensaje de conexión en progreso
  while (WiFi.status() != WL_CONNECTED) { // Espera hasta que se establezca la conexión WiFi
    Serial.print('.'); // Imprime un punto cada segundo mientras intenta conectarse
    delay(1000); // Espera un segundo antes de volver a intentar
  }
  Serial.println(WiFi.localIP()); // Imprime la dirección IP local asignada al dispositivo
  Serial.println(); // Salto de línea para mejorar la visualización
}

// Función de callback que se ejecuta cuando hay cambios en la base de datos
void streamCallback(FirebaseStream data){
  Serial.printf("stream path, %s\nevent path, %s\ndata type, %s\nevent type, %s\n\n",
                data.streamPath().c_str(),
                data.dataPath().c_str(),
                data.dataType().c_str(),
                data.eventType().c_str()); // Imprime información del stream recibido
  printResult(data); // Llama a la función para mostrar el resultado del stream (definida en RTDBHelper.h)
  Serial.println(); // Salto de línea para mejorar la visualización

  // Obtiene la ruta que activó la función
  String streamPath = String(data.dataPath());

  // Si el dato devuelto es un entero, hubo un cambio en el estado del GPIO en la ruta /{gpio_number}
  if (data.dataTypeEnum() == fb_esp_rtdb_data_type_integer){
    String gpio = streamPath.substring(1); // Extrae el número de GPIO de la ruta
    int state = data.intData(); // Obtiene el estado (1 o 0) del GPIO
    Serial.print("GPIO: "); // Imprime el número de GPIO
    Serial.println(gpio);
    Serial.print("STATE: "); // Imprime el estado del GPIO
    Serial.println(state);
    digitalWrite(gpio.toInt(), state); // Actualiza el estado del pin GPIO
  }

  // Si el dato devuelto es una cadena, convierte el valor a entero para el control del GPIO
  if (data.dataTypeEnum() == fb_esp_rtdb_data_type_string){
    String gpio = streamPath.substring(1); // Extrae el número de GPIO de la ruta
    String stateString = data.stringData(); // Obtiene el estado en forma de cadena ("0" o "1")
    int state = stateString.toInt(); // Convierte la cadena a entero
    Serial.print("GPIO: "); // Imprime el número de GPIO
    Serial.println(gpio);
    Serial.print("STATE: "); // Imprime el estado del GPIO
    Serial.println(state);
    digitalWrite(gpio.toInt(), state); // Actualiza el estado del pin GPIO
  }

  /* Cuando se ejecuta por primera vez, se activa en la ruta raíz (/) y devuelve un JSON con todas las claves
     y valores de esa ruta. Así podemos obtener todos los valores de la base de datos y actualizar los estados de los GPIO */
  if (data.dataTypeEnum() == fb_esp_rtdb_data_type_json){
    FirebaseJson json = data.to<FirebaseJson>(); // Convierte los datos recibidos en formato JSON

    // Para iterar todos los valores en el objeto JSON
    size_t count = json.iteratorBegin(); // Inicia la iteración sobre el objeto JSON
    Serial.println("\n---------"); // Imprime una línea separadora para mejor visualización
    for (size_t i = 0; i < count; i++){
        FirebaseJson::IteratorValue value = json.valueAt(i); // Obtiene el valor actual del JSON
        int gpio = value.key.toInt(); // Convierte la clave a un número de GPIO
        int state = value.value.toInt(); // Convierte el valor a un estado (1 o 0)
        Serial.print("STATE: "); // Imprime el estado del GPIO
        Serial.println(state);
        Serial.print("GPIO:"); // Imprime el número de GPIO
        Serial.println(gpio);
        digitalWrite(gpio, state); // Actualiza el estado del GPIO
    }
    Serial.println(); // Salto de línea para mejorar la visualización
    json.iteratorEnd(); // Libera la memoria utilizada en la iteración
  }
  
  // Imprime el tamaño del payload recibido en el stream (actual y máximo)
  Serial.printf("Received stream payload size: %d (Max. %d)\n\n", data.payloadLength(), data.maxPayloadLength());
}

// Función de callback en caso de que el stream se desconecte por timeout
void streamTimeoutCallback(bool timeout){
  if (timeout)
    Serial.println("stream timeout, resuming...\n"); // Muestra mensaje de reanudación tras el timeout
  if (!stream.httpConnected())
    Serial.printf("error code: %d, reason: %s\n\n", stream.httpCode(), stream.errorReason().c_str()); // Imprime código y razón del error si la conexión HTTP falló
}

void setup(){
  Serial.begin(115200); // Inicia la comunicación serial a 115200 baudios
  initWiFi(); // Llama a la función para inicializar la conexión WiFi

  // Inicializar pines de salida
  pinMode(output1, OUTPUT); // Configura el pin GPIO 12 como salida
  pinMode(output2, OUTPUT); // Configura el pin GPIO 13 como salida
  pinMode(output3, OUTPUT); // Configura el pin GPIO 14 como salida
  
  // Asignar la clave API (requerida)
  config.api_key = API_KEY; // Asigna la clave API de Firebase

  // Asignar las credenciales de inicio de sesión del usuario
  auth.user.email = USER_EMAIL; // Asigna el correo electrónico del usuario
  auth.user.password = USER_PASSWORD; // Asigna la contraseña del usuario

  // Asignar la URL de la base de datos en tiempo real (RTDB)
  config.database_url = DATABASE_URL; // Asigna la URL de la base de datos de Firebase

  Firebase.reconnectWiFi(true); // Configura la reconexión automática de WiFi

  // Asignar la función de callback para la generación de tokens de larga duración
  config.token_status_callback = tokenStatusCallback; // Función definida en TokenHelper.h

  // Asignar el número máximo de intentos para la generación de tokens
  config.max_token_generation_retry = 5; // Define el máximo de intentos para generar tokens

  // Inicializar la biblioteca de Firebase con la autenticación y configuración proporcionada
  Firebase.begin(&config, &auth); // Inicializa Firebase con los datos de configuración y autenticación

  // Iniciar la transmisión (streaming) en una ruta de la base de datos
  if (!Firebase.RTDB.beginStream(&stream, listenerPath.c_str()))
    Serial.printf("stream begin error, %s\n\n", stream.errorReason().c_str()); // Muestra el error si no se pudo iniciar la transmisión

  // Asignar una función de callback para ejecutarse cuando se detecten cambios en la base de datos
  Firebase.RTDB.setStreamCallback(&stream, streamCallback, streamTimeoutCallback); // Asigna las funciones de callback para cambios y para el timeout

  delay(2000); // Espera 2 segundos antes de continuar
}

void loop(){
  if (Firebase.isTokenExpired()){ // Verifica si el token ha expirado
    Firebase.refreshToken(&config); // Refresca el token si ha expirado
    Serial.println("Refresh token"); // Imprime mensaje indicando que el token se ha actualizado
  }
}

martes, 29 de octubre de 2024

código test cómo conectarse a una red WiFi con el ESP32

código test cómo conectarse a una red WiFi con el ESP32

En algunos casos algunas versiones de esp suelen tener problemas de conexión, dejare dos imágenes de esp que encontraran en la red, el ESP32 con puerto usb tiene unos componentes extra por la configuracion que requiere el puerto pero funciona igual que el micro usb

Modulo ESP32 DevKit V1 – Micro USB

este modulo por lo comun al subir el archivo al esp no requiere presionar el boton BOOT y es el modulo mas tipico en el mercado (en algunas versiones suele tener problemas para conexion a wifi, mas abajo explico como solucionarlo)


Modulo ESP32 DevKit – USB Tipo-C







La biblioteca incorporada WiFi.h  permitirá utilizar las funciones WiFi de la placa ESP32 fácilmente.

El ESP32 tiene 2 modos WiFi: en el curso de IOT de este canal miramos en el primer video el tema, en resumen:

  • ESTACIÓN ( WIFI_STA ) : El modo Estación (STA) se utiliza para conectar el módulo ESP32 a un punto de acceso WiFi. El ESP32 se comporta como un ordenador que está conectado a nuestro router.

  • AP (Access Point) ( WIFI_AP): En el modo Access Point, el ESP32 se comporta como una red WiFi (un poco como un router): otros dispositivos pueden conectarse a él. En este modo, el ESP32 no está conectado a ninguna otra red y, por lo tanto, no está conectado a Internet. Este modo requiere más recursos computacionales y de energía (la placa del ESP32 se calentará), ya que el ESP32 tiene que simular un router WiFi completo (Soft AP). 

  • El ESP32 está, por defecto, en modo ESTACIÓN.

El código para testear su ESP32 para verificar si el modulo esta bueno y se conecta correctamente, caba resaltar que si despues de subir el codigo continua sin conectarse debe verificar varias item

1. revisar que el cable usb conectado PC a ESP32 sea de datos y sea de la mejor calidad ya que el esp en el momento de trabajar consume buena corriente y el voltaje debe ser estable, preferiblemente conectelo a usb 3

2. Si el cable esta bien y persiste el problema revice que el led de power ilumine correctamente y solo ensaye el ESP32 solo, no conecte nada mas, en su defecto conecte lo entre VCC y GND un capacitor de 470uF o 1000Uf/16v para estabilizar el voltaje y ayudar al inicio del ESP32

3. Revise que el esp32 este bien y tenga actualizado las bibliotecas y la version de tarejetas del ESP32

#include <WiFi.h>

const char* ssid = "nombre de su red wifi";
const char* password = "clave de su red wifi de casa o celular";

void setup(){
    Serial.begin(115200);//configura la velocidad de configuración del monitor serial
    delay(1000);//tiempo de  espera

    WiFi.mode(WIFI_STA); //garantiza que el esp32 se conectara en modo estacion
    WiFi.begin(ssid, password);//inicia el modelo wifi con la red y clave
    Serial.println("\n ...Connecting...");//mensaje conectando

    while(WiFi.status() != WL_CONNECTED){
        Serial.print(".");//sacara un punto hasta que se conecte
        delay(100);
    }

    Serial.println("\n conectado a red wifi");
    Serial.print("IP asignada esp32: ");//mensaje
    Serial.println(WiFi.localIP());//imprime la ip asignada
}

void loop(){}
//*****************************************************************************
Si es una red abierta (sin contraseña), use el siguiente código:
#include <WiFi.h>

const char* ssid = "yourNetworkName";

void setup(){
Serial.begin(115200);
delay(1000);
WiFi.begin(ssid);
Serial.println("\nConnecting");

while(WiFi.status() != WL_CONNECTED){
    Serial.print(".");
    delay(100);
}

Serial.println("\n conectado a red wifi");
Serial.print("IP asignada esp32: ");
Serial.println(WiFi.localIP()); } void loop(){}
//***********************************************************************

Depurar problemas de conexión Wi-Fi
Monitorizando el estado de la conexión,Podemos conocer el estado de la
conexión WiFi con la función WiFi.status(). Esta función devuelve
un entero según el estado actual de la conexión.
Los estados posibles son:

WL_IDLE_STATUS:Este es el estado predeterminado antes de intentar
conectarse a una red.
WL_SCAN_COMPLETED:El escaneo de la red WiFi ha finalizado.
WL_NO_SSID_AVAIL:El ESP32 no puede encontrar el nombre de la red WiFi.
La red está demasiado lejos del ESP32 o el nombre (SSID) de la red es incorrecto.
WL_CONNECT_FAILED:El ESP32 no puede conectarse a la red WiFi designada.
WL_CONNECTION_LOST:Se perdió la conexión WiFi a la red. Si este error se repite, puede ser un problema de alimentación del ESP32.
WL_CONNECTED:El ESP32 está conectado a la red WiFi.
WL_DISCONNECTED:El ESP32 está desconectado de la red WiFi.

#include <WiFi.h>

const char* ssid = "yourNetworkName";// Define el nombre de la red WiFi (SSID)
const char* password = "yourNetworkPassword";// Define la contraseña de la red WiFi
// Función para obtener el estado del WiFi en formato de texto
String get_wifi_status(int status){
    switch(status){
        case WL_IDLE_STATUS:// Estado en espera, no conectado aún
        return "WL_IDLE_STATUS";
        case WL_SCAN_COMPLETED:// El escaneo de redes WiFi se completó
        return "WL_SCAN_COMPLETED";
        case WL_NO_SSID_AVAIL:// No se encontró la red (SSID) especificada
        return "WL_NO_SSID_AVAIL";
        case WL_CONNECT_FAILED:
        return "WL_CONNECT_FAILED";// Falló la conexión al intentar conectarse a la red
        case WL_CONNECTION_LOST:
        return "WL_CONNECTION_LOST";// La conexión se perdió después de haber sido establecida
        case WL_CONNECTED:
        return "WL_CONNECTED";// Conectado correctamente a la red WiFi
        case WL_DISCONNECTED:
        return "WL_DISCONNECTED";// El módulo se ha desconectado de la red
    }
}

void setup(){
    Serial.begin(115200);
    delay(1000);
    int status = WL_IDLE_STATUS; // Establece el estado inicial en 'espera'
    Serial.println("\nConnectando");
    Serial.println(get_wifi_status(status));
    WiFi.begin(ssid, password);
    while(status != WL_CONNECTED){// Bucle hasta que se conecte al WiFi
        delay(500);
        status = WiFi.status();// Actualiza el estado del WiFi
        Serial.println(get_wifi_status(status));// Imprime el estado actual del WiFi
    }

    Serial.println("\n conectado a red wifi");
Serial.print("IP asignada esp32: ");
Serial.println(WiFi.localIP()); } void loop(){}// Bucle vacío, no se realizan acciones continuas después de la configuración inicial

Reiniciando el ESP32

Ocasionalmente, el ESP32 puede fallar temporalmente al conectarse al WiFi por razones desconocidas o extrañas. La mejor solución es decir que después de n unos segundos, si el ESP32 aún no se ha conectado al WiFi, reiniciamos el ESP32. Simplemente agregamos un tiempo de espera y usamos la ESP.restart() función para reiniciar el ESP32 desde el código.

Aquí hay un ejemplo que reiniciará el ESP32 después de 10 segundos si aún no está conectado a WiFi.

#include <WiFi.h>

#define CONNECTION_TIMEOUT 10

const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";

void setup(){
    Serial.begin(115200);
    delay(1000);

    WiFi.mode(WIFI_STA); //Optional
    WiFi.begin(ssid, password);
    Serial.println("\nConnecting");
    int timeout_counter = 0;

    while(WiFi.status() != WL_CONNECTED){
        Serial.print(".");
        delay(200);
        timeout_counter++;
        if(timeout_counter >= CONNECTION_TIMEOUT*5){
        ESP.restart();
        }
    }

    Serial.println("\nConnected to the WiFi network");
    Serial.print("Local ESP32 IP: ");
    Serial.println(WiFi.localIP());
}

void loop(){}

//*****************************************************************************

Ejemplo de aplicación: escaneo de Wi-Fi

Aquí tienes una aplicación concreta que te permite escanear las redes WiFi que hay a tu alrededor:

#include "WiFi.h"

String get_encryption_type(wifi_auth_mode_t encryptionType) {
    switch (encryptionType) {
        case (WIFI_AUTH_OPEN):
            return "Open";
        case (WIFI_AUTH_WEP):
            return "WEP";
        case (WIFI_AUTH_WPA_PSK):
            return "WPA_PSK";
        case (WIFI_AUTH_WPA2_PSK):
            return "WPA2_PSK";
        case (WIFI_AUTH_WPA_WPA2_PSK):
            return "WPA_WPA2_PSK";
        case (WIFI_AUTH_WPA2_ENTERPRISE):
            return "WPA2_ENTERPRISE";
    }
}

void setup(){
    Serial.begin(115200);
    WiFi.mode(WIFI_STA);
}

void loop() {
    Serial.println("uPesy WiFi Scan Demo");
    Serial.println("[*] Scanning WiFi network");

        // WiFi.scanNetworks will return the number of networks found
        int n = WiFi.scanNetworks();
        Serial.println("[*] Scan done");
        if (n == 0) {
            Serial.println("[-] No WiFi networks found");
        } else {
            Serial.println((String)"[+] " + n + " WiFi networks found\n");
            for (int i = 0; i < n; ++i) {
                // Print SSID, RSSI and WiFi Encryption for each network found
                Serial.print(i + 1);
                Serial.print(": ");
                Serial.print(WiFi.SSID(i));
                Serial.print(" (");
                Serial.print(WiFi.RSSI(i));
                Serial.print(" dB) [");
                Serial.print(get_encryption_type(WiFi.encryptionType(i)));
                Serial.println("]");
                delay(10);
            }
        }
        Serial.println("");

        // Wait a bit before scanning again
        delay(5000);
}

Ahorrar energía

Si estás usando un ESP32 en un proyecto que necesariamente debe usar WiFi para funcionar, es una buena idea configurar el ESP32 en modo de suspensión profunda en caso de falla de conexión para minimizar el consumo de energía. Esto es similar al código ESP32 que se queda en modo de suspensión durante 10 segundos entre cada intento.

Código que permite poner el ESP32 en Deep Sleep entre 2 intentos

#include <WiFi.h>
#include <esp_wifi.h>

//Time in seconds
#define CONNECTION_TIMEOUT 5
#define DEEP_SLEEP_DURATION 10

const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";

void setup(){
    Serial.begin(115200);
    WiFi.begin(ssid, password);
    Serial.println("\nConnecting");
    int timeout_counter = 0;

    while(WiFi.status() != WL_CONNECTED){
        Serial.print(".");
        delay(100);
        timeout_counter++;
            if(timeout_counter >= CONNECTION_TIMEOUT*10){
                Serial.println("\nCan't establish WiFi connexion");
                //Setup timer
                esp_sleep_enable_timer_wakeup(DEEP_SLEEP_DURATION * 1000000);
                //Start deep sleep
                esp_deep_sleep_start();
            }
    }
    Serial.println("\nConnected to the WiFi network");
    Serial.print("Local ESP32 IP: ");
    Serial.println(WiFi.localIP());
}

void loop(){}
fuente: https://www.upesy.com/blogs/tutorials/how-to-connect-wifi-acces-point-with-esp32#