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
  }
}