Aviad Zuck (aviadzuc at tau.ac.il), George goldberg (g.kalashnikoff at gmail.com)
We use TelosB nodes to generate a people counter. Two nodes detect movement and signal a third "sink" node connected to a host machine. A sink node receives those messages and keeps track of the number of people inside the room. This node also runs a web server, which uses the host machine as a gateway. External users can access the people counter through a browser.
Two nodes are located about a meter apart from each other. These nodes are our “slaves”. The TelosB platform includes two light-sensitive sensors. We aim a constant laser beam from a simple flashlight (30NIS) to one of these sensors. Each “slave” runs a process with the Contiki embedded OS which samples the sensor 10 times every second. This is done to avoid excessive use of the batteries. If a sample indicates a drop in lighting beneath a pre-determined threshold, it sends a signal to a “sink” node through a unicast connection.
CLOSE FAR DOOR
The sink saves a state, and every message received triggers a state change, according to a basic state machine.
The variable holding the people counter is updated according to the state machine changes.
Besides the process running the state machine, there is also a process for the web server
The web server was initially built using an example at examples/sky-ip/sky-webserver.c. Which in turn uses contiki-os webserver app.The webserver is based on a httpd interface, and uses the contiki's coffee file system to send files to respond for a GET requests. The whole server part of our code is provided in: ajax-cgi.c file , a standard httpd-fs.c (basic file system io which is actually an io on in-memory buffers), and httpd-fsdata.c , that is generated by contiki/tools/makefsdata utility from in httpd-fs/ directory and gives a hardcoded representation of each file as a hexadecimal data buffer. Where webserver uses a constant (macro) HTTPD_FS_ROOT to refer to a root of this 'filesystem', and the names of a files to search this buffers to find a requested file, (using methods provided by coffee-fs).
The webserver provided by contiki knows how to parse html files, requested by GET and substitute '%! "identifier"' with a string 'returned by' httpd_cgi("identifier")() (which is defined by user , as well as httpd_cgi_init , which is called before the server starts)
Though this may sound simple enough to use, we ran into many difficulties making this work. On Contiki-2.3 the whole webserver app and actually tcp/ip stack did not work at all, (even though we were able to compile it). On Contiki-2.5 tcp/ip stuff and rime sensors refused to work together. The problem was mitigated after some fiddling with the Makefile and removing redundant code.
On the host-side a utility called linslip, which ships with Contiki, creates a pseudo-IP over the USB port connecting the TelosB node to the device. This IP can be accessed from the host’s browser, to retrieve a simple html page with the updated people count.
We started off by exploring the light sensing capabilities of the TelosB platform. Our hope was to utilize natural light settings in the room to detect changes. We quickly realized that the light sensors in TelosB were very limited and not up for the task. Even when left unmoved without any obstruction, the variance in sensed data was very large and insufficient for any reliable conclusions.
We decided to sample light sensing data on every slave, to avoid exhausting the battery. Our first naïve solution was to collect the recent history of sensed data, compute the average and standard variation, and signal a light change event whenever such a change occurs that exceeds this variation. Then we encountered another limitation of TelosB – it simply could not compute stdev. out of the box, without rebooting Contiki every time. We had to resort to a more manual computation of stdev. only to realize that it was so unreliable as to render it useless.
We needed to make the light change threshold much more reliable. Therefore we decided to introduce light sources to our system. Our first attempt was with pocket lights. We experimented with several models, ranging from cheap 20NIS ones, to a much more expensive 180NIS LED flashlight. All of them gave us a very limited effect – even the strongest flashlight stopped impacting the sensors beyond a distance of 30cm.
We then realized the solution was in front of us – many elevators use small laser beams to detect a person crossing. These lasers emit a focused strong red light, which was easily detected by the sensors, and also are very cheap (30NIS). Using these beams every blockage of light transferring from the source to the sensor resulted in a significant drop in the sensor lighting level which reliably indicated a person crossing.
Finally we’ve implemented several optimizations to handle various edge cases and improve performance. First, we added a background mechanism to eliminate false signals. For example let’s look at a case where a person has entered the room and was detected by the FAR sensor, but immediately exited before passing in front of the CLOSE sensor. The sink will be left in the FAR state. If another person now chooses to exit the room, this will first be detected by the CLOSE sensor, causing the state machine to falsely detect a person entering the room. To eliminate this, we sample the state between received signals. If a pre-configured period of time has passed without receiving any new signal, we promptly return to INIT_STATE.
Another safety mechanism was added, after we realized that a person crossing creates multiple identical light change notifications to the sink. We’ve added a quick & dirty detection for repeated identical messages in a limited time interval, that should be ignored (we later realized that this should actually be moved to the slave-side. See below further details).
This entire phase of development was done using simply printouts to a console
However we wanted to make it more aesthetic, convenient and available for outside users. We quickly learned there was a sample program in Contiki which created a web server displaying sensors data (see  for further details). We could not make it work with Contiki 2.3. After several failed attempts, we simply tried it with Contiki 2.5 where it was successful. We stripped this example of all redundant code, and inserted a simply printout of the current people counter, and a reload button (see above).
As previously mentioned, a person crossing creates multiple light change events in every slave. Besides causing redundant notifications to the sink, this also exhausts the batteries on the slave due to multiple transmissions. A possible mechanism to avoid this is to use a recent history of the samples, and check whether the light threshold has been crossed recently. We have implemented this mechanism partially, but did not use it in our final version, since we could not make it behave reliably. Therefore it was left for future work.
Another possible enhancement is of course to add a third slave for increased reliability.
Our main conclusion is not a surprising one – development on small embedded systems is not straightforward. Perhaps 10% of the time invested in this project was utilized for actual coding. The rest was mainly wasted on repeated attempts to retrieve meaningful data out of the sensors, bumping into problems caused by the limitations of the underlying hardware and its weak computing capabilities, futile attempts to make example code work on Contiki 2.3 etc.
It seems pretty obvious that using TelosB for any real purpose (i.e. besides as a research platform) should be VERY carefully considered.
Click here to download the code