You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Electron.js与Arduino串口通信渲染异常问题求助

问题:Electron与Arduino串口通信页面渲染异常

我正尝试实现Electron.js与Arduino的串口通信,已确认Electron与Arduino能相互响应,但页面渲染显示异常——应用输出为“SerialRead [object Object]”,预期应为“SerialRead v”。


Arduino代码

char x = 'v';
void setup() {
  // initialize serial:
  Serial.begin(9600);
}

void loop() {
  // print the string when a newline arrives:
    Serial.print(x);
    delay(1600);
  }

Electron渲染进程代码(__renderer.js)

var path = "/dev/ttyACM0";
const { SerialPort } = require('serialport')
const {DelimiterParser} = require('@serialport/parser-delimiter')
var ports = new SerialPort({path, baudRate: 9600});
const parser = ports.pipe(new DelimiterParser({ delimiter: '\n' }))
//ports.pipe(parser);
//parser.on('ready', () => console.log('the ready byte sequence has been received'))
data=parser.on('data', console.log) // all data after READY is received
// Read the data from the serial port
//parser.on("data", (ports) => console.log(ports));

//   console.log('ports', ports);
           document.getElementById('ports').innerHTML = data;

index.html代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Read from USB port</title>
    <style>    </style>
</head>
<body>
    <h1>Read</h1>
<center>
 SerialRead <span id="ports"></span>
    <div id="error"></div>
    <div id="ports"></div>
</center>
</body>
<script src="./__renderer.js"></script>
</html>

main.js代码

const { app, BrowserWindow } = require('electron')
app.commandLine.appendSwitch("disable-gpu");
const path = require('path')
const url = require('url')

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow

function createWindow() {
    // Create the browser window.
    mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        backgroundColor: "#ccc",
        webPreferences: {
            nodeIntegration: true, // to allow require
            contextIsolation: false, // allow use with Electron 12+
            preload: path.join(__dirname, 'preload.js')
        }
    })

    // and load the index.html of the app.
    mainWindow.loadURL(url.format({
        pathname: path.join(__dirname, 'tindex.html'),
        protocol: 'file:',
        slashes: true
    }))

    // Open the DevTools.
    // mainWindow.webContents.openDevTools()

    // Emitted when the window is closed.
    mainWindow.on('closed', function() {
        // Dereference the window object, usually you would store windows
        // in an array if your app supports multi windows, this is the time
        // when you should delete the corresponding element.
        mainWindow = null
    })
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)

// Quit when all windows are closed.
app.on('window-all-closed', function() {
    // On OS X it is common for applications and their menu bar
    // to stay active until the user quits explicitly with Cmd + Q
    app.quit()
})

app.on('activate', function() {
    // On OS X it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (mainWindow === null) {
        createWindow()
    }
})

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

解决思路

  • 核心问题分析:

    1. parser.on('data', console.log)返回的是事件订阅对象,并非串口接收的实际数据,直接赋值给innerHTML会显示[object Object]。
    2. Arduino代码中仅使用Serial.print(x)未输出换行符,导致DelimiterParser无法触发数据事件。
    3. HTML中存在两个重复的id="ports"元素,可能导致DOM选择器混淆。
  • 修复步骤:

    1. 修改Arduino代码:将Serial.print(x)改为Serial.println(x),发送数据时附带换行符,匹配DelimiterParser的\n分隔规则。
    2. 修正渲染进程代码:在data事件回调内处理并更新DOM,替换原错误赋值逻辑:
      parser.on('data', (receivedData) => {
          // 转换为字符串并清除多余空白字符
          const cleanData = receivedData.toString().trim();
          console.log(cleanData);
          // 更新目标DOM元素内容
          document.getElementById('ports').innerHTML = cleanData;
      });
      
    3. 清理HTML重复ID:移除其中一个id="ports"的元素,确保DOM选择器唯一。

内容的提问来源于stack exchange,提问作者Harry Hobson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 16:05:53