OK, I have decided to use some tools to work better and to improve my productivity and, in some way, the quality of my posts.
I have decided to start using MarsEdit, for my “Tra le Nuvole” blog.
OK, I have decided to use some tools to work better and to improve my productivity and, in some way, the quality of my posts.
I have decided to start using MarsEdit, for my “Tra le Nuvole” blog.
Note: this is rather a long post !!!
Coding in JavaScript is easy, and you have many modules that you can use.
For example, I have soon discovered that there is a module for MQTT. With this module you can easily publish MQTT messages to topics and subscribe.
You have also two good libraries, allowing you from a NodeJS program to interface with HW and to read from sensors: MRAA and UPM.
But to work in NodeJS on Intel Edison is NOT always easy and fun.
What is the main reason? Well I think it all points to the fact that the Linux distribution (well, it is not actually a distribution) is Yocto.
The NodeJS version shipped with Intel Edison, even if you download the latest available version (very. 3) is 0.10
This is an old version, with many important bugs.
For example, I have discovered soon that using MQTT if you send frequently messages from the board to the MQTT broker (let’s say every 10 sec.) very soon the programs stops working after 10 min.
Some test have showed me that the problem can be solved upgrading Node. It is ok with 0.12 version.
But the upgrade of the Node environment is not easy.
When I talk about environment I mean:
Actually, now there is not a simple way, and it take a lot of manual work. And as I see, there is not a single, clear document describing how to do it.
In this blog post, I want to document the steps I have undertaken to upgrade NodeJS on Edison Board with an environment fully working.
High level steps:
The only way that always works for me is to use the flashall.sh script, from the command line.
Sometimes, I need to reboot my MAC, before to start the flashing procedure. This is needed to avoid that the flashing procedure timeout while waiting for the FTDI device to re-appear.
You download and unzip the distribution (Yocto Release 3.0), taken from here,
https://downloadmirror.intel.com/25871/eng/iot-devkit-prof-dev-image-edison-20160315.zip
then launch from the command line flashily.sh and connect through USB cables when requested.
It should take about 10 min
At this point, you need to have the Intel XDK installed on your MAC or Laptop.
Launch the XDK and connect to the Edison using the serial connection (you have still the board connected with the two cables).
From the command line interface, launch
configure_edison —password
configure_edison —name
configure_edison —wifi
to setup a password, the hostname and to connect to the WI-FI network.
From XDK, launch, upgrade libraries.
After, you can verify with opkg info
opkg info mraa
Package: mraa
Version: 1.0.0
Provides: mraa-dev, mraa-dbg, mraa-doc
Replaces: mraa-dev, mraa-dbg, mraa-doc, libmraa, libmraa-dev, libmraa-doc
Conflicts: mraa-dev, mraa-dbg, mraa-doc
Status: install user installed
Architecture: i586
Installed-Time: 1462025597
opkg info upm
Package: upm
Version: 0.6.2
Depends: mraa (>= 0.9.1)
Provides: upm-dev, upm-dbg, upm-doc
Replaces: upm-dev, upm-dbg, upm-doc
Conflicts: upm-dev, upm-dbg, upm-doc
Status: install user installed
Architecture: i586
Installed-Time: 1462025678
Again, from the XDK IDE (see preceding image).
First of all, remember that the space is limited. Therefore, you need to download the NodeJS distribution and start the build in a directory where you have enough space.
I have decided to create a downloads directory under /home/root
There, you can put the tree obtained from the tarball, downloaded from the NodeJS site.
But, I have hit one (of the many) annoying problem: if you simply download (with wget) the tar.gz file and explode it with tar xvf, when you launch configure on Edison you get a very strange error: the configure script (that is a Python script) complains that it cannot find the nodedownload module.
Well, I have found that the problem is in the tar utility, that doesn’t extract all the files (strange, but this is the reason). Actually, when I have unzipped the tar.gz file on my MAC I have found that the file nodedownload.py is there.
Solution: unpack the tarball file on your MAC, and upload all the resulting tree of directories and files on the Edison.
It will take some time, but I have no idea of a better solution.
then, update the XDK agent, from the XDK
The link where I took the tarball is:
http://nodejs.org/dist/v4.2.0/node-v4.2.0.tar.gz
Then, go inside the node-v4.2.0 directory and execute
./configure
make
It will take about three hours !
make install
Then, you have
root@thunder10:/# /usr/local/bin/node -v
v4.2.0
Then, update the XDK agent, from the XDK IDE.
after, you should be able to upload a NodeJS application directly from XDK, connected to the board through WIFI, to the directory /node_app_list on the Edison board.
Then, in the directory /node_app_list run
npm install mraa
After this, mraa is correctly linked to Node. In fact, the following blink code works
var mraa = require('mraa'); //require mraa
console.log('MRAA Version: ' + mraa.getVersion()); //write the mraa version to the Intel XDK consolevar myOnboardLed = new mraa.Gpio(13); //LED hooked up to digital pin 13
myOnboardLed.dir(mraa.DIR_OUT); //set the gpio direction to output
var ledState = true; //Boolean to hold the state of LedperiodicActivity(); //call the periodicActivity function
function periodicActivity()
{
myOnboardLed.write(ledState?1:0);
ledState = !ledState; //invert the ledState
setTimeout(periodicActivity,200);
}
Under /home/root/downloads clone upm git repository
git clone https://github.com/intel-iot-devkit/upm.git
cd upm
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX:PATH=/usr
After, to compile only upm_grove (and produce the right jsupm_grove module)
cd src/grove
make
make install
To test, I have used the Grove Light sensor, attached to A1. This is the code I have used to test:
var groveSensor = require('jsupm_grove');
// Create the light sensor object using AIO pin 0
var light = new groveSensor.GroveLight(1);// Read the input and print both the raw value and a rough lux value,
// waiting one second between readings
function readLightSensorValue() {
console.log(light.name() + " raw value is " + light.raw_value() +
", which is roughly " + light.value() + " lux");
}
setInterval(readLightSensorValue, 1000);
and this is the output from the program:
Light Sensor raw value is 184, which is roughly 2 lux
Light Sensor raw value is 190, which is roughly 2 lux
Light Sensor raw value is 357, which is roughly 5 lux
Light Sensor raw value is 361, which is roughly 5 lux
It works fine under Node 4.2 !!!
Under /node_app_slot execute
npm install mqtt
and this is the code of the program that I have used to test that UPM and MQTT work under NodeJS 4.2
var mqtt = require('mqtt');
var groveSensor = require('jsupm_grove');
var MSG_TOPIC_NAME = 'sensors/SN3/msg';
var CONTROL_TOPIC_NAME = 'sensors/control/SN3';var SENSOR_ID = 'SN3';
var BROKER_URL = 'mqtt://broker_host';
var SLEEP_TIME = 3000; // 3 seconds
var PIN_TEMP = 0;// Create the temperature sensor object using AIO pin 0
var temp = new groveSensor.GroveTemp(PIN_TEMP);
// connect to the Broker
var mqtt_client = mqtt.connect(BROKER_URL, {'keepalive' : 60});//
// define events and callback
//
mqtt_client.on('close', handle_mqtt_close);
mqtt_client.on('connect', handle_mqtt_connect);
mqtt_client.on('reconnect', handle_mqtt_reconnect);
mqtt_client.on('error', handle_mqtt_err);
mqtt_client.on('message', handle_messsage);// the variable that will contain the object for the MQTT msg
// This is the format of the msg: {"id":"SN3","temp":"26"}
//
var msg = {};
var count = 0;function handle_mqtt_connect()
{
console.log("MQTT Connect...");mqtt_client.subscribe('CONTROL_TOPIC_NAME', handle_mqtt_subscribe);
}function handle_mqtt_subscribe(err, granted)
{
console.log("MQTT Subscribe...");
if (err)
{
console.log(err);
}
}function handle_mqtt_reconnect(err)
{
console.log("MQTT Reconnect...");if (err)
{
console.log(err);
}
mqtt_client.subscribe('CONTROL_TOPIC_NAME', handle_mqtt_subscribe);
}function handle_mqtt_err(err)
{
console.log("MQTT Error...");
if (err)
{
console.log(err);
}
}function handle_mqtt_close()
{
console.log("MQTT Close...");
}function after_publish()
{
// for now nothing...
}function handle_messsage(topic, message, packet)
{
console.log('Message received!');
console.log('msg = ' + message.toString());
}function readSensors()
{
count = count + 1;
console.log('***********************');
console.log("Iteration n. %d", count);
var rounded_temp = temp.value();
// build the object message
// that will be sent as a JSON message
msg.id = SENSOR_ID;
msg.temp = rounded_temp.toString();
// send with MQTT QOS = 1
if (rounded_temp)
mqtt_client.publish(MSG_TOPIC_NAME, JSON.stringify(msg), {'qos' : 1}, after_publish);setTimeout(readSensors, SLEEP_TIME);
}readSensors();
MQTT messages are sent to a Mosquitto broker installed on a Raspberry PI 2, connected to the WIFI network.
To verify that messages are correctly sent and received from the Broker, I have used the Eclipse Paho GUI Client:
I have posted an issue on github about the problems we have in Edison with NodeJS
https://github.com/intel-iot-devkit/mraa/issues/501
Let’s see.
I have found some time to dedicate to the issues I have found using NodeJS on Intel Edison.
As I wrote some posts ago, the version shipped with Edison is Node 0.10, that is not really stable.
For example, using MQTT, a simple programs that reads from several sensors and send msgs to a MQTT Topic, hosted on RPI, stops working after about 10 minutes (it depends on the frequency of sends).
I have tried to upgrade to at least Node version 0.12.7. But the upgrade of the entire environment is not easy.
I asked on Intel Communities, and this is the answer from an Intel guy:
"Hello LSaetta,
As you mentioned, mraa and upm are not compatible with the later versions of Node.JS. There are methods to make mraa work with newer versions of node, however they don't work at 100%. So, my best suggestion is that you submit an issue to the mraa and upm developers in https://github.com/intel-iot-devkit/mraa or https://github.com/intel-iot-devkit/upm".
Manually you can do the upgrade, finding a combination that works, but it is really NOT easy.
I'll post an issue and ... hope Intel wants to really improve support of NodeJS.