Parsovanie výstupu z Arduina pomocou Node.js

Zápisník experimentátora

Hierarchy: Node.js

V dnešnom článku si ukážeme, ako je možné výstup z Arduina parsovať v javascripte. Arduino bude merať teplotu pomocou senzora DS18B20 a výsledky bude odosielať na sériový port. Obsah zo sériového portu budeme spracovávať pomocou kódu v Node.js a budeme si ho transformovať do objektov. Získané objekty môžeme následne spracovávať.

Arduino a DS18B20

Arduino a senzory sú zapojené podľa obrázku. Na breadboarde mám dva senzory teploty. Oba sú zapojené pomocou jedného pull-up rezistora a k Arduinu sú pripojené cez pin 2. Počet senzorov nie je dôležitý. Mali by byť minimálne dva, aby sme mali dosť podkladov pre Node.js. Arduino pre každý senzor získa dva údaje.

  • Jedinečnú adresu senzora.
  • Odmeranú teplotu.

Získané údaje sa odošlú na sériový port. Pre všetky senzory sa výsledky odošlú v jednom riadku. Výsledok vyzerá takto. Pre ľudské oči to je nie veľmi čitateľné, ale takto máme k dispozícii tabuľku, ktorá obsahuje jednotlivé stĺpce oddelené bodkočiarkou. Údaje v takejto podobe vieme na strane Node.js dobre parsovať.

Zdrojový kód programu pre Arduino vyzerá takto. Nastaví sa rozlíšenie každého senzora na 12 bitov a každých 5 sekúnd sa odošle jeden riadok s meraniami na sériový port.

#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
#define TEMPERATURE_PRECISION 12 // Maximum resolution

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

int numberOfDevices; // Number of temperature devices found

DeviceAddress tempDeviceAddress; // We'll use this variable to store a found device address

void setup(void) {
  Serial.begin(9600);
  sensors.begin();
  numberOfDevices = sensors.getDeviceCount();
  for (int i = 0; i < numberOfDevices; i++) {
    if (sensors.getAddress(tempDeviceAddress, i)) {
      sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION);
    }
  }
}

// function to print a device address
void printAddress(DeviceAddress deviceAddress) {
  for (uint8_t i = 0; i < 8; i++) {
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}

// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress) {
  float tempC = sensors.getTempC(deviceAddress);
  Serial.print(tempC);
}

void loop(void) {
  sensors.requestTemperatures();
  for (int i = 0; i < numberOfDevices; i++) {
    if (sensors.getAddress(tempDeviceAddress, i)) {
      printAddress(tempDeviceAddress);
      Serial.print(";");
      printTemperature(tempDeviceAddress);
      Serial.print(i==(numberOfDevices-1) ? "" : ";");
    }
  }
  Serial.println("");
  delay(5000);
}

Parser v Node.js

Zdrojový kód v Node.js konvertuje údaje z každého riadku a mení ich do podoby objektov. Každý objekt obsahuje dva parametre.

  • id - Jedinečná adresa senzora.
  • temperature - Odmeraná teplota.

Podľa toho, koľko senzorov sme mali, sa vo výsledku objaví v javascipte toľko objektov. Tieto objekty si vieme následne pohodlne spracovať. Môžeme ich napríklad.

  • Uložiť do databázy.
  • Odoslať do cloudu.

Pre potreby tohto článku ich iba vypisujem na konzolu. Výsledok vyzerá takto.

Zdrojový kód programu vyzerá takto. Podobný kód som už publikoval v predchádzajúcom článku o komunikácii medzi Node.js a Arduinom. Na parsovanie využívam triedu DS18B20Controller. Tá je odvodená od triedy events.EventEmiter. To mi umožňuje odosielať udalosti. Udalosťou je dvojica id a temperature. Príklad na odoslanie udalosti je riadok self.emit('temperature', t);. Spracovanie udalosti nájdete na riadku ds18b20.on('temperature', ..., kde sa parameter udalosti vypíše na konzolu.

'use strict';

const serialport = require('serialport');
const readline = require('readline');
const sp_readline = serialport.parsers.Readline;
const events = require('events');

class DS18B20Controller extends events.EventEmitter {

  constructor(config) {
    super();
    var self = this;
    this.config = config;
    this.port = new serialport(this.config.port, {
      baudRate: this.config.baudrate || 9600
      });
    const parser = new sp_readline();
    this.port.pipe(parser);

    parser.on('data', function(data){
      //console.log(data);
      var ar = data.trim().split(';');
      for(var i=0;i<ar.length;i+=2) {
        var t = {
          id: ar[i],
          temperature: parseFloat(ar[i+1])
        };
        self.emit('temperature', t);
      }
    });

    this.port.on('error', function(e) {
      console.error(e.message);
      process.exit(0);
    });

    this.port.on('open', function() {
      console.log('Serial Port Opened');
    });

    this.port.on('close', function(err) {
      console.log('Serial Port Closed: ' + err);
      process.exit(0);
    });

  }
}

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  prompt: 'select port> '
});

var idx = 0;
var ports = [];

console.log('COM port list:');
serialport.list(function (err, p) {
  p.forEach(function(p) {
    ports.push(p.comName);
    console.log(' [' + idx + '] ' + p.comName);
    idx++;
  });

  rl.prompt();
 
  rl.on('line', function(line) {
    //console.log(line);
    //console.log(ports);
    if(line<idx) {
      console.log('Opening ' + ports[Number(line)]);
      const ds18b20 = new DS18B20Controller({port: ports[Number(line)], baudrate: 9600});
      ds18b20.on('temperature', function(temp) {
        console.log('Temperature:', temp);
      });
 
    } else {
      console.error('ERROR: Wrong port number');
      process.exit(0);
    }
  });
 
  rl.on('close', function() {
    console.log('Bye!');
    process.exit(0);
  });

});

Zdrojový kód

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.

Inštalácia pre Arduino

Do svojho Arduina nahrajte kód pomocou Arduino IDE.

Inštalácia pre Node.js

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_ds18b20_parser\node
npm install

17.01.2018


Menu