首页 > 解决方案 > nodejs:http监听干扰串行端口读取

问题描述

我正在尝试使用串行端口从 arduino 读取数据,并将其提供给 Web 浏览器。

如果没有网络服务器(即,如果我在最后省略了“监听”调用),串行数据会不断流入,控制台中会显示预期的每秒 5 次更新。

但是当我添加“listen”调用时,控制台上不会显示任何内容,直到我使用 Web 浏览器向服务器发出请求,此时控制台最多只添加一个日志条目(但有时仍然没有)。

Web 浏览器中显示的数据是上次发出请求时的“旧”数据,而不是来自 arduino 的当前最新数据。换句话说,串行数据在每个 http 请求被服务都会被处理一点——不是很有用。

const http = require('http');
const serialport = require('serialport');

var serial = new serialport('/dev/ttyUSB0', {
    baudRate: 115200
});

var jsonStr = '';
var jsonObj = {};

function handleData(data) {
    jsonStr += data;
    if ( data.indexOf('}') > -1 ) {
        try {
            jsonObj = JSON.parse(jsonStr);
            console.log(jsonObj);
        }
        catch(e) {}
        jsonStr = '';
    }
};

serial.on('data', function (data) {
    handleData(data);
});

const app = http.createServer((request, response) => {
    response.writeHead(200, {"Content-Type": "text/html"});
    response.write(JSON.stringify(jsonObj));
    response.end();
});

app.listen(3000);

(来自 arduino 的数据已经是一个 JSON 字符串,这就是为什么我要寻找一个 '}' 来开始解析它。)

我还尝试使用“可读”事件来获取串行数据,但没有区别:

serial.on('readable', function () {
    handleData(serial.read());
});

如果我理解正确,监听调用本身并没有阻塞,它只是注册一个事件监听器/回调以便稍后触发。正如相关问题中的一个公认答案所说:“认为 server.listen(port) 有点类似于浏览器中的 someElement.addEventListener('click', handler) 。”

如果 node.js 是单线程的,那么为什么 server.listen() 返回?

那么为什么“监听”会阻止串行连接接收任何东西,除了每次服务请求时短暂地接收?我有没有办法在不相互干扰的情况下使用这两个功能?

标签: node.jsserial-port

解决方案


我发现代码在另一台计算机上按预期工作,即使另一台计算机使用完全相同的操作系统(Fedora 20)和完全相同的 node.js 版本(v10.15.0)同样的方式(从源代码构建)。

我还发现它在装有更新版本的 Fedora (29) 的原始计算机上运行良好。

这可能表明我没有时间、知识或需要深入研究的 USB/串行驱动程序存在一些细微差别。我只会使用我知道可行的配置。


推荐阅读