Zápisník experimentátora
Hierarchy: Node.js
Pokud máte Arduino připojené k počítači a neustále odesílá do počítače nějaké údaje, může se stát, že se komunikace zastaví. Arduino se zasekne, nebo se rozpojí vytvořeno spojení přes sériový port. V tomto příkladu si ukážeme, jak takovou komunikaci sledovat v Node.js a v případě problémů ji automaticky obnovit.
Pro Arduino jsem napsal jednoduchý kód, který simuluje zaseknutí Arduina po nějakém čase. To je simulované pomocí proměnné crash_count
. Když dosáhne hodnotu 0, přestane odesílat hodnoty na sériový port.
int crash_count = 10;
void setup() {
Serial.begin(9600);
}
void loop() {
while (crash_count) {
Serial.println(millis());
delay(1000);
crash_count--;
}
}
Program funguje tak, že pokud ho spustíte přes node index.js
, vypíše na konzolu seznam sériových portů. Pokud ho spustíte přes node index.js 0
, řeknete mu, že si má otevřít port s pořadovým číslem 0. Tehdy si vytvoří proměnnou ph
typu PortHandler
, která se postará o celou komunikaci.
PortHandler
je třída se dvěma funkcemi. V konstruktoru
se nastaví interní proměnné a ve funkci openPort
se odehrává celá činnost. V události data
se zaznamenává čas poslední komunikace. V proměnné interval
je funkce, která se spustí každých 5 sekund. Když je komunikace přerušena na více než 10 sekund, restartuje připojení sériového portu.
'use strict';
const serialport = require('serialport');
const sp_readline = serialport.parsers.Readline;
class PortHandler {
constructor(config) {
this.config = config;
this.last_data = Date.now();
this.openPort();
}
openPort() {
var self = this;
this.port = new serialport(this.config.port, {
baudRate: this.config.baudrate || 9600
});
const parser = new sp_readline();
this.port.pipe(parser);
this.port.on('close', function(error) {
if(error)
console.log('on close error', error.message);
else
console.log('on close');
});
parser.on('data', function(data) {
self.last_data = Date.now();
console.log(new Date(self.last_data).toLocaleTimeString(), data);
});
this.interval = setInterval(function() {
console.log('Checking...');
var millis = Date.now() - self.last_data;
if(millis>10000) {
console.log('Crash detected');
self.port.close(function() {
self.openPort();
});
clearInterval(self.interval);
}
}, 5000);
}
};
var idx = 0;
var ports = [];
serialport.list(function (err, p) {
p.forEach(function(p) {
ports.push(p.comName);
});
if(process.argv.length==2) {
console.log('COM port list:');
ports.forEach(function(p) {
console.log(' [' + idx + '] ' + p);
idx++;
});
}
if(process.argv.length==3) {
var port = ports[parseInt(process.argv[2])];
console.log('Connecting to', port);
const ph = new PortHandler({port: port, baudrate: 9600});
}
});
Takto vypadá vystup z programu v případě, že jsem po třech sekundách odpojil Arduino z USB portu. Program nám zaznamenal i samotné odpojení. Pak se několik sekund snažil program rozeznat, co se děje a když po stanoveném čase nepřišla odpověď, pokusil se o automatický restart. To už bylo Arduino zase připojeno do USB a proto se mohla komunikace opět rozjet.
Connecting to COM6 22:37:12 0 22:37:13 999 22:37:14 1999 22:37:15 3000 on close error Reading from COM port (ReadIOCompletion): Operation aborted Checking... Checking... Checking... Crash detected 22:37:27 0 22:37:28 999
Zdrojový kód se nachází na serveru GitHub.
Pokud máte nainstalovaný program git
, můžete si zdrojové kódy nainstalovat například takto. Pokud ho nemáte, dají se stáhnout i jako zip archiv.
Do svého Arduina nahrajte kód pomocí Arduino IDE.
Spusťte si konzolu příkazového řádku. Důležitý je poslední řádek, který nainstaluje všechny související knihovny, které jsou v souboru package.json
.
cd d:
mkdir arduino
cd arduino
git clone https://github.com/roboulbricht/arduinoslovakia
cd arduinoslovakia\node.js\arduino_reopen_after_crash\node
npm install
10.02.2018