I wanted to control my Arduino via Bluetooth using NodeJS but I could not find a Node module to do it. That is why I decided to build my own. This post describes how to use it.
Arduino setup
First, lets take a look at the Arduino setup I am using. It is a simple Arduino Uno with breadboard. For Bluetooth connectivity I’ve added a Bluetooth shield. For testing purposes I’ve configured a simple layout on the breadboard that allows me to control a LED. The picture below shows the configuration.
I wrote a simple schema to control the LED. The program can change the status of the LED according to the value that is read from the serial Bluetooth connection. The program also allows to read the current state of the LED.
Bluetooth-serial-port
On the NodeJS side I have created a module that allows a script to communicate via a Bluetooth serial connection. The module can be used to communicate via Bluetooth as well as to search for Bluetooth devices and serial port channels.
Currently the module only supports the Bluez Bluetooth stack on Linux. I might add OS X support in the future. supports both Linux, Mac OS X and Windows (thanks Elmar!).
The module is available on npm and can be installed by issuing:
$ npm install bluetooth-serial-port
Using the module
To use the module you’ll have to import it into your script. Below is a simple example program that controls the Arduino configuration described above.
var BTSP = require('bluetooth-serial-port'); var serial = new BTSP.BluetoothSerialPort(); serial.on('found', function(address, name) { // you might want to check the found address with the address of your // bluetooth enabled Arduino device here. serial.findSerialPortChannel(address, function(channel) { serial.connect(bluetoothAddress, channel, function() { console.log('connected'); process.stdin.resume(); process.stdin.setEncoding('utf8'); console.log('Press "1" or "0" and "ENTER" to turn on or off the light.') process.stdin.on('data', function (data) { serial.write(data); }); serial.on('data', function(data) { console.log('Received: ' + data); }); }, function () { console.log('cannot connect'); }); }); }); serial.inquire();
Open issue
Currently the module works quite well. The only thing not working is when a script wants to reconnect the Bluetooth connection.
When a connection is ended, for example when the Arduino is switched off, and the scripts starts a new Bluetooth inquiry the module will find the Bluetooth serial channel again but does not connect to it.
My current work around for this issue is to terminate my script when a connection has ended and than restart the script again. To achieve this I’m using forever.
For example…
I hope this post helps you to build cool stuff using using NodeJS and Bluetooth. I’m curious about the applications you’ll come up with. Please drop me a note ;-)
I’ve used the above configuration to make a UPnP controlable Bluetooth lightbulb prototype. For the UPnP side of the prototype I used the upnp-device module. The prototype will be part of the Figaro demonstrator that will demonstrate how IP-based and non-IP based home networks can be converged (PDF). This demonstrator is shown in the IEEE booth on the CES coming January.
All sources from this post are available as gist.
Happy programming!
Hi my Name is Ivan , I was working with you great module.
I made this:
But now I want to pass data to the arduino, but I’m geting some errors.
I doing this:
serial.write(data);
And I’m getting some errors with the module, like I should pass mode parameters to the function.
I don’t have my project here, so I will ask you late for this, with the issue and the real application.
Anyways, thanks a lot for this great module
Good luck, Ivan.
Hi Ivan,
Great to see the cool stuff you’ve created with the module!
Version 1.0.0 breaks the API of previous version so when you upgrade you should also update your code accordingly. The key change is that you should pass a Buffer object instead of a string.
I hope this helps!
Eelco
This is my code, I use socket too.
serial.on(‘found’, function(address, name) {
serial.findSerialPortChannel(address, function(channel) {
serial.connect(“00:00:00:00:00”, channel, function() {
//Robot Connected
console.log(‘Robot Connected’);
//socket
io.sockets.on(‘connection’,function SocketConnection (socket) {
//Socket Connected
console.log(“Socket Connected”);
process.stdin.resume();
process.stdin.setEncoding(‘utf8’);
/*process.stdin.on(‘data’, function (data) {
serial.write(data);
});*/
serial.write(new Buffer(‘Hello Robot’, ‘utf-8’));
serial.on(‘data’, function(buffer) {
console.log(buffer.toString(‘utf-8’));
});
//Cuando recibo info del Robot
serial.on(‘data’, function(data) {
buf+=data.toString(‘utf-8’); //Fix para el bluetooth
if(buf.length >= 2){
datos.push(buf);
buf=””;
if(datos.length == num){
procesarData(datos,socket,dist,dir,robot); //cuando ya tengo los 4 datos
datos=[];
}
}
});
});
}, function () {
console.log(‘cannot connect’);
});
});
});
I’m getting this error:
/node_modules/bluetooth-serial-port/lib/bluetooth-serial-port.js:95
this.connection.write(buffer, this.address, cb);
^
TypeError: Third argument must be a function
at BluetoothSerialPort.write (/node_modules/bluetooth-serial-port/lib/bluetooth-serial-port.js:95:29)
Thanks for the report. I will look into it. You are using Linux right? What version of node.js and what version of the bluetooth module are you using?
Hi , thanks a lot for hear it :)
Yes I’m using linux, and this is my node version v0.10.20
And the version of the bluetooth module I think I’m using the last , how I can check that?
Thanks
Hi Ivan,
There is an error in the code example that I’ve provided in the README. The write function should have a callback function as the second argument (it is described in the API section of the README). If you change your call to the write to the code below it should work fine:
serial.write(new Buffer(‘Hello Robot’, ‘utf-8′), function(err, count) {
if (err) console.log('Something went wrong');
});
I’ve updated the documentation and the example will be fixed in the next release. Thanks for pointing this out!
Ohhh men thanks you so much!!!!! , I don’t know for some reason I had never read that line , but you’re right , I change that and all works fine.
Thanks you so much for this great module, and for your answers, I can continue with my little project now.
Thanks, Ivan.
hi eelco,
very excited to see this module, but i’m having some trouble installing it. i’m new to node.js, so it is likely my fault, but i thought you should know. this is the error message:
152 error Exit status 1
153 error Failed at the bluetooth-serial-port@1.1.4 install script.
153 error This is most likely a problem with the bluetooth-serial-port package,
153 error not with npm itself.
153 error Tell the author that this fails on your system:
153 error node-gyp configure build
153 error You can get their info via:
153 error npm owner ls bluetooth-serial-port
153 error There is likely additional logging output above.
154 error System Darwin 11.4.2
155 error command “node” “/usr/local/bin/npm” “install” “bluetooth-serial-port”
156 error cwd /Users/meg/Documents/Files/nodejs
157 error node -v v0.10.29
158 error npm -v 1.4.14
159 error code ELIFECYCLE
sorry to bug you about this, but i’d love to get this up and running and start to explore node.js!
cheers,
meg
Hi meg. Did you install the dependencies? On OS X these are Xcode and the Xcode command-line tools. See the README: https://github.com/eelcocramer/node-bluetooth-serial-port/blob/master/README.md.
If you have the dependencies installed and you still face issues installing the module please create an issue on GitHub with the complete output of the install command. If you create an issue others can benefit from the solution.
You can create an issue here: https://github.com/eelcocramer/node-bluetooth-serial-port/issues?state=open
Thanks!
Hi Eelco,
Thanks for the module – it seems that a lot of people found it quite useful, and I’m hoping it will help me, too. However, I’m stuck at the moment :-( True, I’m not a Node.js expert, still a lot to learn about Bluetooth, but I spent quite a bit of time on this with no avail. I’m not sure where I’m failing nor whether this module is right for my task.
I got a Raspberry Pi with Bluetooth USB dongle, which is paired with my Android mobile. I can run a python rfcomm server (/usr/share/doc/python-bluez/examples/simple/rfcomm-server.py) on it, which listens to RPi’s bluetooth port for any connection requests and messages. I can successfully initiate outgoing bluetooth connection from my mobile to the RPi and send some messages. I’d like to do the same with Node.
I tried using bluetooth-serial-port and your simple example program finds visible devices (my mobile), but findSerialPortChannel doesn’t find anything at all, so I cannot open a connection.
Best,
Max
Hi Max,
Thank you for your response. Do you want to run the node script on the RPi? In that case, please note that the bluetooth-serial-port module is not a RFcomm server but a client. It is not comparable with the python script you use.
I hope this helps!
Thanks for the speedy reply. Yes, I want to run the node script on the RPi as a RFcomm server. Do you have any recommendations? Do you know if any modules that would do that? Would it be difficult to make such a module?
Sorry I don’t know if there is such a server component for node. If you want to build one yourself you might want to look at that python module to see if you reuse parts of the native code or maybe they just wrap some command line tools? Good luck!
Hi Eelco,
Thanks for the module! We have downloaded and ran your code on a windows computer. It compiles but does not find any devices. When we call serial.isOpen() we get false. Do we need to specify which serial port we are interested in? Or, any advice on how to open a serial port?
Thanks,
Becky
Hi Becky,
Thanks for the feedback. Please take a look at the provided samples but make sure there aren’t any old bluetooth addresses left in it. If it doesn’t work please create an issue on the projects github page. This is were all development takes place and there is more help available. Good luck!