Cómo utilizar SQLite con ESP32 PLC

Con la ayuda de la librería "esp32_arduino_sqlite3_lib"
12 de septiembre de 2023 por
Cómo utilizar SQLite con ESP32 PLC
Boot & Work Corp. S.L., Joan Vilardaga Castro

Introducción


La integración de SQLite en ESP32, un potente microcontrolador ampliamente utilizado en aplicaciones IoT industriales, revoluciona las capacidades de almacenamiento de los sistemas embebidos. Con la incorporación de SQLite, un sistema de gestión de bases de datos relacionales ligero y rico en funciones, los desarrolladores pueden mejorar la persistencia de datos, la funcionalidad de consulta y la seguridad en el extremo.

Este blog explora las razones para aprovechar SQLite en ESP32, profundiza en sus técnicas de implementación práctica y destaca su idoneidad para entornos con recursos limitados. Explore con nosotros cómo la fusión de SQLite y ESP32 potencia las soluciones IoT industriales con una gestión eficaz de los datos y la toma de decisiones en tiempo real.

¿Qué es SQLite?


SQLite es un popular sistema de gestión de bases de datos relacionales embebido, de código abierto y sin servidor que se utiliza ampliamente en diversas aplicaciones de software. Se trata de un motor de base de datos autónomo y sin configuración que opera directamente desde archivos de disco, eliminando la necesidad de un proceso de servidor de base de datos independiente.

A pesar de su pequeño tamaño, SQLite ofrece muchas funciones potentes que se encuentran en sistemas de bases de datos más grandes. Admite consultas SQL estándar, transacciones, tipos de datos, índices y otras operaciones de base de datos. Además, SQLite ofrece propiedades ACID (Atomicidad, Consistencia, Aislamiento, Durabilidad), que garantizan la integridad y fiabilidad de los datos.

Debido a que SQLite tiene un enfoque sin servidor, puede integrar SQLite en proyectos basados en ESP32. Esto le permite aprovechar la potencia de un sistema de gestión de bases de datos relacionales directamente en el dispositivo ESP32, para cosas como el registro ligero, consultas de datos avanzadas y ahorro de variables a través de reinicios.

Requisitos


Para esta demostración, utilizamos el ESP32 21+ Industrial PLC, pero cualquier PLC ESP32 con una tarjeta SD será compatible.

Tendrás que instalar la herramienta de línea de comandos sqlite3 en tu PC, utilizando un gestor de paquetes (como "apt") o descargándola del sitio web oficial de SQLite en https://sqlite.org/cli.html.

Por último, para instalar la librería esp32_arduino_sqlite3_lib library tendrás que utilizar el Gestor de Bibliotecas del IDE de Arduino (busca "esp32_sqlite").

El programa de ejemplo


    El objetivo del programa ESP32 que desarrollaremos es registrar los valores de dos pines específicos en el microcontrolador ESP32 y almacenarlos en una tabla. Esta funcionalidad sirve para una amplia gama de aplicaciones en las que es necesaria la monitorización continua y el registro de los cambios de estado de los pines.

    Mientras que el caso de uso específico de registro de valores de pin puede ser de interés para ciertos lectores, la más amplia toma de este blog es la integración de SQLite con el ESP32 y el potencial que tiene para diversas aplicaciones de registro de datos. Si usted está monitoreando las condiciones ambientales, el seguimiento de las lecturas del sensor, o la recogida de cualquier otro tipo de datos, la comprensión de cómo utilizar SQLite con un ESP32 y una tarjeta SD abre un mundo de posibilidades.

    En primer lugar, tenemos que crear la base de datos en el PC con un esquema SQL. Abra un símbolo del sistema o terminal y navegue hasta el directorio donde desea crear el archivo de base de datos. Crea un archivo schema.sql y pega este código:

    PRAGMA foreign_keys = ON;

    CREATE TABLE IF NOT EXISTS analog_pins (
    id INTEGER PRIMARY KEY,
    pin VARCHAR(5) UNIQUE
    );

    CREATE TABLE IF NOT EXISTS analog_log (
    id_pin INTEGER,
    value INTEGER,
    timestamp_log DATETIME,
    FOREIGN KEY (id_pin) REFERENCES analog_pins(id)
    );

    INSERT INTO analog_pins (pin) VALUES("I0.12");
    INSERT INTO analog_pins (pin) VALUES("I0.11");

    Con el esquema definido, puedes crear la base de datos con el comando sqlite3 web.db < schema.sql. Ahora, formatea una tarjeta SD usando el sistema de archivos FAT32 (si no está ya en FAT32), y pon el archivo web.db en la raíz de la SD. Extrae la SD y ponla dentro del PLC ESP32, y carga el siguiente programa:

    #include "SD.h"

    #include <sqlite3.h>
    #define DB_NAME "web.db"

    #include <RTC2.h>

    int openDb(sqlite3** db) {
    int rc = sqlite3_open("/sd/" DB_NAME, db);
    if (rc) {
    Serial.print("Can't open database: ");
    Serial.println(sqlite3_errmsg(*db));
    }
    else {
    Serial.println("Opened database successfully");
    }
    return rc;
    }

    void closeDb(sqlite3* db) {
    sqlite3_close(db);
    }

    int execDb(sqlite3* db, const char* query) {
    char *zErrMsg = NULL;
    int rc = sqlite3_exec(db, query, NULL, NULL, &zErrMsg);
    if (rc != SQLITE_OK) {
    Serial.print("SQL error: ");
    Serial.println(zErrMsg);
    sqlite3_free(zErrMsg);
    }
    else {
    Serial.printf("Operation done successfully\n");
    }
    return rc;
    }

    #define START_QUERY "INSERT INTO analog_log SELECT (SELECT id FROM analog_pins WHERE pin='"
    #define MAX_LENGTH_QUERY sizeof(START_QUERY)+32
    template <const int PIN>
    void read_analog(void* pvParameter) {
    pinMode(PIN, INPUT);
    sqlite3 *db;
    char query[MAX_LENGTH_QUERY];
    const int occupied_query_bytes = snprintf(query, sizeof(query), START_QUERY "%s'),", (const char* const)pvParameter);
    char* parameters = query + occupied_query_bytes;
    while (1) {
    int r = analogRead(PIN);
    auto timestamp = RTC.getTime();
    snprintf(parameters, MAX_LENGTH_QUERY-occupied_query_bytes, "%d,%ld;", r, timestamp);
    if (openDb(&db) != SQLITE_OK) break;
    execDb(db, query);
    closeDb(db);
    vTaskDelay(5000);
    }
    }

    const char* const sI0_12 = "I0.12";
    const char* const sI0_11 = "I0.11";
    void setup() {
    Serial.begin(115200);
    SD.begin(13);

    if (!RTC.read()) {
    RTC.setTime(0);
    }

    sqlite3_initialize();

    xTaskCreate(read_analog<I0_12>, "TaskI0.12", 8192, (void*)sI0_12, 0, NULL);
    xTaskCreate(read_analog<I0_11>, "TaskI0.11", 8192, (void*)sI0_11, 0, NULL);
    }

    void loop() {}

    Este programa crea dos tareas. Cada tarea es responsable de leer el valor de un pin analógico cada 5 segundos y almacenar las lecturas dentro de una base de datos SQLite. También utiliza la librería RTC para obtener las marcas de tiempo de cada lectura, de forma que puedas saber con certeza cuándo se ha leído el valor.

    Buscar en nuestro blog

    Cómo utilizar SQLite con ESP32 PLC
    Boot & Work Corp. S.L., Joan Vilardaga Castro 12 de septiembre de 2023
    Compartir

    ¿Estás buscando tu Controlador Lógico Programable ideal?

    Echa un vistazo a esta comparativa de producto de varios controladores industriales basados en Arduino.

    Comparamos entradas, salidas, comunicaciones y otras especificaciones con las de los equipos de otras marcas destacadas.


    Industrial PLC comparison >>>