Zápisník experimentátora
Hierarchy: Node.js
Ak máte Arduino pripojené k počítaču a neustále odosiela do počítača nejaké údaje, môže sa stať, že sa komunikácia zastaví. Arduino sa zasekne, alebo sa rozpojí vytvorené spojenie cez sériový port. V tomto príklade si ukážeme, ako takúto komunikáciu sledovať v Node.js a v prípade problémov ju automaticky obnoviť.
Pre Arduino som napísal jednoduchý kód, ktorý simuluje zaseknutie Arduina po nejakom čase. To je simulované pomocou premennej crash_count
. Keď dosiahne hodnotu 0, prestane odosielať 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 ak ho spustíte cez node index.js
, vypíše na konzolu zoznam sériových portov. Ak ho spustíte cez node index.js 0
, poviete mu, že si má otvoriť port s poradovým číslom 0. Vtedy si vytvorí premennú ph
typu PortHandler
, ktorá sa postará o celú komunikáciu.
PortHandler
je trieda s dvomi funkciami. V konštruktore
sa nastavia interné premenné a vo funkcii openPort
sa odohráva celá činnosť. V udalosti data
sa zaznamenáva čas poslednej komunikácie. V premennej interval
je funkcia, ktorá sa spustí každých 5 sekúnd. Keď je komunikácia prerušená na viac ako 10 sekúnd, reštartuje pripojenie 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 vyzerá vystup z programu v prípade, že som po troch sekundách odpojil Arduino z USB portu. Program nám zaznamenal aj samotné odpojenie. Potom sa niekoľko sekúnd snažil program rozoznať, čo sa deje a keď po stanovenom čase neprišla odpoveď, pokúsil sa o automatický reštart. To už bolo Arduino zase pripojené do USB a preto sa mohla komunikácia opäť rozbehnúť.
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 sa nachádza na serveri GitHub.
Ak máte nainštalovaný program git
, môžete si zdrojové kódy nainštalovať napríklad takto. Ak ho nemáte, dajú sa stiahnuť aj ako zip archív.
Do svojho Arduina nahrajte kód pomocou Arduino IDE.
Spustite si konzolu príkazového riadku. Dôležitý je posledný riadok, ktorý nainštaluje všetky súvisiace knižnice, ktoré sú v súbore 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
09.02.2018