← Volver

Comunicación serie en Electron

Publicado el 14 de diciembre de 2025

Las librerías que se usan para leer/escribir el puerto serie son:

const { SerialPort } = require("serialport");
const { ReadlineParser } = require("@serialport/parser-readline");

En le renderer.js iniciamos la función startReading y onArduinoData:

button1.addEventListener("click", async(e)=> {
  window.api.startReading();
});

window.api.onArduinoData((data) => {
  textAreaReadData.textContent += `Button1: ${data.button1}\n`;
  textAreaReadData.scrollTop = textAreaReadData.scrollHeight;

    if(data.button1 == 1){
        window.api.execCommand(appName.value);
    }

});

En el preload.js definimos las funciones startReading y onArduinoData:

const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('api', {
    startReading: () => ipcRenderer.send('start-reading'),
    onArduinoData: (callback) => {
            ipcRenderer.on('arduino-data', (event, data) => {
            callback(data);
        });
    },
});

En el index.js llamamos a la función readArduino y enviamos arduino-data:

ipcMain.on('start-reading', (event) => {
  readArduino((dato) => {
    try {
      const json = JSON.parse(dato);
      if (mainWindow) {
        mainWindow.webContents.send('arduino-data', json);
      }
    } catch (err) {
      console.error('Dato no válido:', dato);
    }
  });
});

Finalmente declaramos la función readArduino:

const { SerialPort } = require("serialport");
const { ReadlineParser } = require("@serialport/parser-readline");

let port;
let parser;

const readArduino = (callback) => {
  if (!callback || typeof callback !== "function") {
    throw new Error("Se requiere una función callback");
  }

  if (!port) {
    port = new SerialPort({
      path: "/dev/tty.usbmodem1301",
      baudRate: 9600,
    });

    parser = port.pipe(new ReadlineParser({ delimiter: "\n" }));
    parser.on("data", callback);

    port.on("open", () => console.log("Puerto abierto."));
    port.on("error", (err) => console.log("Error:", err));
  }
};

Cerrar la comunicación:

const stopArduino = () => {
  if (parser) {
    parser.removeAllListeners("data"); // elimina el callback
  }
  if (port && port.isOpen) {
    port.close((err) => {
      if (err) console.log("Error cerrando puerto:", err);
      else console.log("Puerto cerrado");
    });
  }
  port = null;
  parser = null;
};

Finalmente exportar las funciones:

module.exports = { readArduino, stopArduino };

Y el programa para el Arduino:

#include <ArduinoJson.h>

const int BUTTON1 = 2;

void setup() {
  pinMode(BUTTON1, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop() {
  StaticJsonDocument<200> doc;
  
  doc["button1"] = digitalRead(BUTTON1) == LOW ? 1 : 0;

  serializeJson(doc, Serial);
  Serial.println();
  delay(200);
}