Integration of a Bluetooth sensor onto a JeeNode for the purpose of detecting devices as they come into, and go out of, range so that events can be triggered.

The Bluetooth unit is connected to a JeeNode and it will perform an inquiry check for available devices every 30 seconds (adjustable). As each device reports in, its device ID will be transmitted via the RFM12B. A total of 6 bytes are needed to represent the 48 bit address, to a receiving unit.

On the receiver side the RF is decoded and transmitted as an ASCII string out the serial port for decoding.

xap_serial will pickup the serial transmission from our receiver node and transmit this data as an xAP message for decoding.

The decoder is a Lua applet that creates a BSC endpoint dynamically sending a xAPBSC ON event when the device is first registered. As long as the device updates itself within 35 seconds, the endpoint will remain alive. When the device moves out of range a reaper will take care of expiring the endpoint sending an xAPBSC OFF event and removing the endpoint.

These on/off events can then be used by other scripts to drive an action.

With Serial debugging enabled on the bluenode sketch this is the sample output.

[BlueNode.1] - RF disabled
SYNC> AT+NAME=blueNode
SYNC> AT+INQM=0,5,15
device=12:37:E90912 type=520204 rssi=7FFF

The ERROR:(17) can be safely ignored. That just means the SPP profile lib has already been initialized. You will notice the RF module is disabled, that's due to me running the bluetooth device attached to my Arduino which does not have any RF device on it, so I disabled that code whilst testing.

A packet will arrive on the Receiver. The first byte is the sender node ID, in this case it's node 18. The remaining data is the Device ID packed into 6 bytes.

[HAHCentral.1]1 g212 @ 868Mhz
OK 18 18 0 55 18 9 233

This message will be picked up by xap-serial and transmitted as an xAP packet for something to decode

data=OK 18 18 0 55 18 9 233

That 'something' doing the decoding is an applet running inside plugboard.

We are running the Lua decoder in debug mode so the lifecycle of an endpoint can be seen.

Loading jeenodeApplet.lua                [ JeeNode ]
build BlueNode[18]
  data = "OK 18 18 0 55 18 9 233",
  port = "/dev/ttyUSB0"
process BlueNode[18]
BlueNode reaper 12:37:e90912 alive=true ttl=35 timeout=4
BlueNode reaper 12:37:e90912 alive=true ttl=35 timeout=14
BlueNode reaper 12:37:e90912 alive=true ttl=35 timeout=24
BlueNode reaper 12:37:e90912 alive=true ttl=35 timeout=34
BlueNode reaper 12:37:e90912 alive=true ttl=35 timeout=44
expire 12:37:e90912

When a new bluetooth device is decoded the following endpoint is created and the state is set to ON, to indicate that its presence is known. The source xAP address will be dynamically created based on the device ID if a named address has not been defined.

A bluetooth device address breaks down like this: NAP:UAP:LAP
Each Bluetooth device is assigned a 48-bit address consisting of three parts: a 24-bit lower address part (LAP), an 8-bit upper address part (UAP), and a 16-bit so-called non-significant address part (NAP).
As a : has special meaning when used as part of the xAP address we translate the address 12:37:e90912 to 12.37.e90912 when creating the endpoint.


All going well, you should see an endpoint dynamically appear in xFXViewer when your Bluetooth device comes into range.

Wiring for JeeNode/Hahnode/Arduino

Arduino Port 1 HC-05
Digital 4 D RX
Digital 3 I TX
Analog 0 A KEY
3.3v + 3.3V
5v (NC) P (NC) 5v (NC)

We don't connect the 5v pins together, 3.3v is sufficient.

The source code for the SKETCH is called BlueNode. There is also a useful terminal emulator that uses the Arduino as a passthrough device.

The Lua decoder logic is found in bluenode.lua or on your HAH system in /usr/share/lua/5.1/xap

The decoder can operate in two modes; named device endpoints or dynamically created. Each are setup and configured in your /etc/plugboard/jeenodeApplet.lua configuration file.

Step 1 - Make sure you are include the BlueNode class decoder.

local monitor = require("xap.jeenode").monitor
RoomNode = require("xap.roomnode")
BlueNode = require("xap.bluenode")

Step 2 - Assign the remote node ID to this BlueNode class, choose use dynamic or static endpoints.

If you omit the endpoints table defintion all devices will derive their xAP source addresses dynamically. This snippet is for a static configuration as we have named the devices. Those devices not configured will be created with computed endpoint names.

In this example our remote node is configure as 18 and we have setup two known bluetooth devices.

-- Keyed by NODE ID
local nodes = {
   [18] = BlueNode{instance="bluetooth:presence",
                    ["1d:fe:720479"] = "brett.1",
                    ["12:37:e90912"] = "brett.2",

This is a dynamic configuration and it will be your starting configuration until you know what your Bluetooth device ID's are.

local nodes = {
   [18] = BlueNode{instance="bluetooth:presence"}

This code has been tested with the following Bluetooth devices and the following has been observed.

In general “Smart phones” have a habit of powering off the Bluetooth device when they sleep, which sort of kills this idea stone dead. Working on a way around this.

Device Year Observation
Nokia 6230i 2005 everything works perfectly.
Palm Pre 2010 the device only responds to AT+INQ command when its awake, once its goes to sleep it won't respond.
iPhone ? the device only responds when awake and paired (verify)

Ed. Sure smarts phones with all their apps are cool but they have taken their eye off the most important thing, in my opinion, which a phone should have; a long battery life and being able to make phone calls. They are so worried about battery drain everything gets turned off, even things you actually want left on.

Until I can go a week on one charge I'm sticking to my trusty Nokia, where I can leave Bluetooth on permanently without causing me duress. Oh and it works with this code :)

  • livebox/hah_hahnode/bluenode.txt
  • Last modified: 2014/02/18 10:42
  • by minerva9