Parsing the output from Arduino using Node.js

Zápisník experimentátora

Hierarchy: Node.js

In this article, we will show how the output from Arduino can be parsed in javascript. Arduino will measure the temperature using the DS18B20 sensor and send the results to the serial port. We will process the contents of the serial port using the code in Node.js and transform it into the objects. We can then process the acquired objects.

Arduino and DS18B20

Arduino and sensors are connected as shown. I have two temperature sensors on my breadboard. Both are connected by a pull-up resistor and are connected to Arduino via pin 2. The number of sensors is not important. There should be at least two to have enough sources for Node.js. Arduino obtains two values for each sensor.

  • Unique address of the sensor.
  • Measured temperature.

The data obtained will be sent to the serial port. For all sensors, the results are sent in one line. The result looks like this. For human eyes, this is not very readable, but we have a table that contains individual columns separated by a semicolon. The data in this form we can, on the Node.js well parse.

The source code for the Arduino looks like this. The resolution of each sensor is set to 12 bits, and one line is sent every 5 seconds with measurements on the serial 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 in Node.js

The source code in Node.js converts the data from each row and converts them to the form of objects. Each object contains two properties.

  • id - Unique address of the sensor.
  • temperature - Measured temperature.

Depending on how many sensors we have, so many objects appear in the Javascript. We can then easily process these objects. We can, for example.

  • Save it to database.
  • Send it to the cloud.

For the purposes of this article, I just write them on the console. The result looks like this.

The program source code looks like this. A similar code I've already published in the previous article on communication between Node.js and Arduinom. For parsing, I use the class DS18B20Controller. It is derived from events.EventEmiter. This allows me to send events. The event is a pair of id and temperature. An example of sending an event is the line of self.emit ('temperature', t) ;. To process an event, see line ds18b20.on ('temperature', ..., where the event parameter is printed on the console.

'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);
  });

});

Source code

The source code is located on the GitHub server.

If you have a git installed, you can install the source code as follows. If you do not have it, you can also download zip archives.

Installation for Arduino

Upload to your Arduino code using Arduino IDE.

Installation for Node.js

Run the Command Line Console. Important is the last line that installs all the related libraries that are in 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