Twilio, Tessel, and the Internet of People

9/16/2014– Jon McKay

Twilio and Tessel

Twilio is a company that is near and dear to our hearts at Technical Machine. We’re excited to announce that their Node.js library runs on Tessel. Twilio is the SMS and Voice glue for any communications-based applications and they have an amazing developer experience. Hands down, Twilio is the easiest way to send SMS and voice communications and I’ve yet to meet a dissatisfied customer.

In my opinion, Twilio and Tessel seem like a perfect match. Tessel is the fastest way to gather data about the physical world, and Twilio is the fastest way to get that information to the people who care.

Why SMS?

There are a whole slew of ways devices communicate with each other and with people: lightweight, data transfer protocols (MQTT, CoAP, XMPP, BLE), haptics, or visual displays. But what happens when an individual needs to be notified of an event regardless of where they are in the world?

SMS is the best way to immediately get data to to the right person. While push notifications are also a reliable way of getting information directly to a user, it still requires them to download yet another app. As more and more connected devices have their own applications, it becomes increasingly tedious to download and use a separate smartphone application for each. Text messages are still the simplest way to get data from a device to a smartphone.

Running Twilio on Tessel

When we shipped Tessel, the runtime wasn’t compatible enough with Node for the Twilio Node.js library to run on Tessel. Not only that, but our WiFi state machine was unstable and prone to crashing making HTTP requests unreliable.

We’re really proud of the progress we’ve made since then to get the Twilio Node.js library running directly on a microcontroller. We’ve slogged through a whole slew of WiFi, JavaScript, and Node compatibility bugs for this library to start working. We’re starting to see other libraries (like and MQTT which we’ll talk about more soon) Just Work on Tessel and it’s really exciting to see our original design finally coming to fruition.

We worked Ricky Robinett, a developer evangelist at Twilio to test out the Node library as we were fixing it. He was able to write a simple app on Tessel to get an idea of exactly how lazy his dog, Gif, really is. Using the Twilio Node library and the accelerometer module, he could detect when his dog was napping on the job, and send him a text with the nap duration. While it is an, admittedly, silly use case, his blog post shows the basics of loading the Twilio node module, monitoring the accelerometer values, and posting an SMS with an event has occurred. Check it out if you’re interested in sending a text message from Tessel!

Note: SMS in production

Lastly, running Twilio on Tessel is the fastest way to prototype an SMS-enabled system but you would want a different system design when moving to production. For example, you could move to a proxy-service oriented architecture: Tessel would send an HTTP request to a remote server and that server would take care of interacting with the Twilio service. The proxy server could also route incoming SMS messages down to the Tessel.

If you’re building an SMS-enabled Tessel application and you’d like help, feel free to post on our forums or shoot me an email at


We’re hiring, cool projects, and meeting up

9/15/2014– Updates

We’re hiring

We miss our summer interns– seven people is too few for our grand plans! Check out if you think you can help fill the hole in our hearts.

Progress report

Here’s what we’ve been up to lately: * Bug fixes and feature requests, as always. See the changelogs here. * Prep for conference/hackathon season: there should be Tessel hardware to borrow at most of Major League Hacking’s hackathons, and we’re speaking and providing hardware at a number of to-be-announced conferences. * Improved internal testing infrastructure: we’re working on a continuous integration server that automatically runs a suite of tests on every PR through Tessel and merges if acceptable. * Added contribution labels to Github issues to make it easier to contribute– see details here. * Added Tessel Packs to the store: bundles of modules for specific applications, such as the Hackathon Pack. * Reached out to a lot of customers for feedback– we love to hear your feedback, so much so that Jon spent a lot of time last week individually emailing customers to hear their thoughts. If you have anything to share, please let us know! * Made a meetup group in the Bay Area and held our first couple of events. * Got LuaJIT running some JS scripts.

Meeting up

Hardware is more fun in person– want to start a meetup group in your area at the intersection of hardware and web development? Reach out to for support and ideas– and we’ll cover your meetup fees. Check out our group as an example.


We’ve been watching projects roll in, as well. Here are a few picks: * Tessel + Auth0 authentication * Neopixel animation over websockets * A ring level using accelerometer + Neopixels * A Meteor.js temperature monitoring dashboard

Do you have a Tessel project you’ve been working on? Please post!

Until next time,
Kelsey, Tim, Ken, Eric, Jon, Jia, and Kevin

An Interview with Stefan van Dockum

8/30/2014– Kelsey Breseman

Stefan Van Dockum, or stefanvandockum on our projects page, has made a number of cool projects lately: a haptic metronome, a bulls-eye level using Neopixels and an accelerometer, Tessel adaptations for a Wii Nunchuck and an NES controller, and a couple of other promising works in progress. So I sent him a message to see if I could learn more about his background, inspirations, and impressions.

Stefan made time to speak with me late at night his time in The Netherlands . He’d just put his two young kids to bed, and so Skyped me quietly, white earbuds in. Quick to smile, he was full of ideas– both for projects he wanted to make and for directions he thought we as a company might want to look.

Kelsey: You’ve made a broad range of projects– what’s your background in engineering?

Stefan: I have a pretty standard background for here in Holland for engineering. I got a bachelor’s degree in higher informatics; embedded systems. Before that I was in electrical engineering.

I hadn’t done anything with engineering until now, since then; I went right into the internet business– that’s more .NET and PHP programming.

I had played with electronics since I was seven, since we got our first Nintendo 8-bit thing, and after that, we got our first XT8086 computer with less than 64 kilobytes of RAM. So I started programming then. But then after that, you get to puberty, so you go skating, guitar playing, drinking, that sort of stuff.

I’m more of a “knower” than a “doer”; if I see something for electronics, I know what it does, but I don’t know exactly how to make it from scratch. So copy and enhance is the standard tactic.

That’s why I love the Tessel right now. It has the electronics– what I went to school for– and it has the programming language that I’ve done the last couple of years, for the internet business. It’s the perfect combination for me right now.

When Tessel came out, I ordered the whole set, and I was very happy.

Kelsey: Would you consider yourself primarily a JavaScript programmer?

Stefan: JavaScript was always a thing you did ‘on the side’. It was not a main thing for me; I was mainly a backend developer. Databases were my specialty. But the last two, three years I’ve gone into JavaScript some more, with JQuery and stuff. Last year, at our work, Node.JS was a hot topic, so we’ve learned stuff from that, too.

In the end, the programming language itself is not that interesting to me; it’s just what you can do with it. I have learned ten programming languages, I think: Delphi, PHP, .NET, Turbo Pascal and even Basic in the old days; I also did some Java stuff in school. I’ve seen almost every programming language there is. The only thing that’s hard is switching between the languages.

Kelsey: Did you have anything particular in mind when you bought a Tessel?

Stefan: Not really; I always had my eye on the Arduino, but the problem was that it was C, and I didn’t want to go back to C after programming with .NET and PHP for so long.

I wanted an Arduino for just making things. You always want to build a robot or something– standard stuff. Just dabbling in electronics is always a cool thing to do. I just wanted to have it as a new gadget.

Kelsey: You’ve been prolific so far; you’ve published, I think, five projects?

Stefan: Five or so. I’ve got some more in my mind.

I need to move to a new house, so I’m thinking about a home sensor network, with small temperature sensors, to monitor the whole house.

I have a checklist of all the modules that work with Tessel. When I got the Tessel first, I said, let’s try module 1. Okay, example code works. What to do with it? Thinking, thinking, don’t know yet, let’s try module 2. Let’s try that one. At first I tried all the example codes. Then you have a really nice idea of what you can do with them.

One thing on my checklist was the infrared module. Controlling your TV is so dull, it’s standard, so controlling the TV was not very cool. But I’m also a portrait photographer. I had my DSLR in front of me, and I was thinking, wait a second, I’ve got a remote for that, and that remote is infrared. I’ve done a couple of product photography assignments; now I can automate my product photography just by sending IR codes to the camera and using the servo to turn a table.

I’m still working on the woodwork part. I went to Ikea to buy some really cheap turntable thing; it’s like seven euros for a turntable, and I just have to put on the servo to move it. That’s a project that I’m still doing. Like I said, moving into a new house, but it will probably be done before the end of the month.

Editor’s note: here is Stefan’s product photography project writeup so far.

Kelsey: A lot of your projects involve a physical component– is that a fun piece of the project for you?

Stefan: It depends on what I want to achieve, the problem is that it takes some more thinking; programming is easier than making a piece of hardware. But it’s bringing back childhood memories, the electrical part. It was fifteen years ago that I created my own PCB boards. In the old days, I etched my own PCB boards, with the lighting and the different kinds of chemicals. When I was at school, the SMD technology was just arriving. I really had to do everything by hand then.

I had an internship that shipped amplifiers to Hong Kong. I was soldering on my own, I made some mistakes, and I really hated that part. But now when I’m tinkering, I’m thinking, why that capacitor, why that resistor?

That’s really a fun part to think of: what kind of schematic do you need? But it’s still a hard part. I think most software programmers really hate that part, to get that electronic stuff up and running. You really don’t know what’s happening if you’ve never had any background. Why would I learn four years for it, if someone could do it in two weeks? So the pre-made modules are pretty cool, because you can just plug in and do your stuff.

Kelsey: How long does it take you to make a project?

Stefan: One evening, or two or three evenings, depending on how much I need to debug.

I’m always thinking about really short code blocks, trying to get those basic blocks first: turn a servo, send an IR command, that sort of stuff. Later on, I can always extend those basic building blocks.

Mostly it’s just one evening to get the prototype running. If I wanted to make it really complete, I think I would be doing two days or something. For the projects that I do right now, I get the idea in the morning, and then in the evening I program it, hook it up, and it’s ready to go.

Kelsey: What are you excited about making right now?

Stefan: The Neopixel stuff is really cool. You can get a nice ring with colorful LEDs. It’s just so easy to program, you can do basically anything with it.

I got a 3D printer, also. I’m trying to mix and match some ideas that I have with the Tessel. But the problem is, my 3D modeling capabilities are also from ten years ago, so I need to pick that up also.

I saw the Rapiro robot– that’s a pretty nice robot for 3D printing. So I want to make it with much more stuff on it– more lights, more talking back.

Robots are pretty standard. You always want to make a robot, but in the end it’s sometimes too hard, and everybody does it. But to make a really cool robot, that’s still on the bucket list.

Kelsey: Have you thought about turning any of your projects into products?

Stefan: I was thinking about how to do it. You need to do it in quantity.

For most people, the Tessel is expensive. It’s not a really expensive thing, but it’s still an expensive thing to buy for a product.

You could do something Bluetooth Low Energy and NFC. I was thinking about a teddy bear with NFC in it. My kids could put the telephone to its paw and an app would come to life and it would say how old the teddy bear is, its birthday, that sort of thing.

It’s in my mind to try selling some things. But the Tessel right now isn’t the right thing to do to sell. You really need to make your own microcontroller with its own chips. I could maybe make things for friends.

Kelsey: What would make it better for the applications you have in mind?

Stefan: The Arduino proto-mini is ten euros if I get it from Hong Kong. But I really hate Arduino’s programming language, and I really like Tessel. You should make a Tessel mini, or some ‘satellite’ sensor like boards which can directly talk to a tessel ‘hub’.

The sensors need wireless communication– I want to make a low-mesh network.

Tessel mini should be one of the products you should sell. Max of two modules, and half its price, you would sell a lot more I think. Especially for hackathons. At my company, there are some other front-end developers who are looking into Tessels, but don’t have the money yet. Sell them by tens, you can really have a cool hackathon.

Kelsey: What do you think is a good direction for this sort of technology?

Stefan: The nicest things about Tessel– and those were the first things that triggered me– there are two things. The JavaScript, and the built-in Wifi.

Connecting a physical thing to the internet is the way to go. The only thing you need to know is, what do you want to do with this connection? It’s an in between medium; you’ve got some actuators, you’ve got some sensors, and you can always reach and trigger them. You can move something through the internet. But in the end, I don’t really have a concrete idea yet. First get the basics up and running and expand from there…

The basic implementation would be the sensors: getting to know your environment, and adapt your environment to the situation. So the the next best thing, what I think, in the next five years is really automating your house and making sure everything in it knows what it’s doing: close the windows, sun screens, temperature, air conditioning. Together with information (weather for example), shared algorithms as API etc.

The other thing I was thinking about is portable stuff. That’s a race against the phone, because your phone can do a lot of things, but they’re consumer things. You can’t add really other hardware things to it, other than the microUSB port. You have Bluetooth protocol. In ten years, maybe there will be a difference between a phone and a microcontroller, but maybe not. That’s a possibility.

Paige’s Intern Farewell

8/29/2014– Paige Cote

Choosing a startup for my first technical internship was pretty scary. While the benefits of working for a very small company are definitely large (I’ll get to that in a minute), I knew that this was going to be jumping into the deep end. Looking back at the end of the summer, I can say that while I was definitely justified in my anxiety, I would make the same choice again.

Jump Right In

The best thing for me about this summer was that I could make an impact from day one. While my other friends shared stories about weeklong onboarding processes and intern projects that would never see the light of day, I was immediately pulled into the craziness of shipping Technical Machine’s first product, with all hands needed. Any worry that I would not be making a significant impact this summer was quickly put behind me. We were working on bug fixes from the first day, and as soon as our customers had Tessels in their hands, we were the first line of support.

After the first few weeks, which included surviving shipping, things hardly slowed down. I eventually got involved with every facet of the company. From web development to firmware to support, I was encouraged to find projects that were interesting to me and tackle them. Because Technical Machine is so small (7 full-time and 3 interns), there were always projects that were genuinely important. I could simply express interest in working a specific project and then start working.

This freedom encouraged me to attempt to solve problems that would have intimidated me a month earlier. It also highlighted a huge benefit of startups. At Technical Machine, everyone who made the product is in the same room/building as you. As I worked to solve problems, I knew I would have the support from the team if I needed it. If something strange was going on with the my project, I could just ask the person who wrote the entire section of code or designed the circuit that you’re having trouble with. It was a pretty awesome introduction to a professional engineering environment.

Back to The Real World

As I get ready to go back to school again this fall, I am so excited to apply what I’ve learned this summer. There are the obvious skills that I gained, like my confidence with JavaScript and general appreciation for writing tests. And then there is the less obvious personal motivation that I will take away from my summer at Technical Machine.

Considering that Tessel didn’t even exist as a concept until about a year ago, the amount of quality product that the team has been able to produce is amazing. I am so close to being in a similar position, and it is incredibly encouraging to see how much I could do with the knowledge I gain in the next few years.

Contributing to Tessel this summer gave me a new perspective to take back to school with me this fall. It gave me insight on what problems I look forward to solving, and what I need to focus on improving if I want to make an impact on similar projects in the future. Working in the startup space feels like the best parts of school mashed into one, there are always new things to learn, and you learn new skills with the purpose of immediately applying it.

This fall you’ll find me back at Olin taking classes, Tessel-vangelizing at medical hackathons in Boston, and trying to learn C on the side so that I can more successfully tackle firmware problems next time I’m presented with that opportunity.

If you have any questions about my summer, feel free to get in touch!


How to Expose a C Function up to JS Userspace on Tessel

8/27/2014– Jia Huang

This document will be kept up to date on Github

This tutorial goes over how to expose a C function to JS where the user can interact with it via any JS function.

The function will pass this simple test case:

var tessel = require('tessel');
console.log("Can Tessel add?", 3 == tessel.add(1, 2));
  1. Clone down the tessel/firmware repo.
  2. Set up the firmware according to the tessel/firmware readme.
  3. Open up src/tessel.c. Add these lines

    uint32_t tessel_add(uint32_t x, uint32_t y)
        return x + y;
  4. Add this function to the header file. Open up src/tessel.h and add

    uint32_t tessel_add(uint32_t x, uint32_t y);
  5. Add the Lua binding. Open up src/hw/l_hw.c and add

    static int l_hw_add(lua_State* L)
        uint32_t x = (uint32_t)lua_tonumber(L, ARG1);
        uint32_t y = (uint32_t)lua_tonumber(L, ARG1+1);
        lua_pushnumber(L, tessel_add(x, y));
        return 1; // return 0 if the c function doesn't return a value
  6. Scroll down to the bottom of src/hw/l_hw.c where we’re defining all the JS function names in luaL_reg regs[] and add in the following entry:

    {"add", l_hw_add}

    So it should look something like:

    luaL_reg regs[] = {
        {"add", l_hw_add},
        // spi
        { "spi_initialize", l_hw_spi_initialize },
        { "spi_enable", l_hw_spi_enable },
  7. Add the JS bindings. Open up builtin/tessel.js and find this function:

    this.deviceId = function(){
        return hw.device_id();

    Add the following right below it

    this.add = function(x, y){ // the "this" object is referring to the "tessel" object
        return hw.add(x, y); // the "add" function here corresponds with the string in the lua binding. That's how we get from C -> Lua -> JS
  8. Go back to the main directory of the firmware repo and do a make arm. You should see an output like this

    [183/183] STAMP obj/tessel-firmware.actions_depends.stamp
    arm-none-eabi-size out/Release/tessel-firmware.elf out/Release/tessel-boot.elf out/Release/tessel-otp.elf
    text       data     bss     dec     hex filename
    824912     3576   24660  853148   d049c out/Release/tessel-firmware.elf
    30848      2260    3232   36340    8df4 out/Release/tessel-boot.elf
    6100      34272      36   40408    9dd8 out/Release/tessel-otp.elf

    This outputs the elf file for hardware debugging.

  9. Now go to out/Release/ and do an ls. You should see the following              tessel-cc3k-patch.bin    tessel-firmware.bin.cpgz
    gen                      tessel-cc3k-patch.elf    tessel-firmware.elf
    obj                      tessel-erase.bin         tessel-firmware.hex
    tessel-boot.bin          tessel-erase.elf         tessel-otp.bin
    tessel-boot.elf          tessel-firmware.bin      tessel-otp.elf

    Here’s what each of those do:

    • tessel-boot: bootloader for Tessel. Also writes the Tessel version number (04) in otp.
    • tessel-cc3k-patch: updates the firmware for the CC3000 wifi chip on Tessel. Current version is 1.28.
    • tessel-erase: erases all JS user code on Tessel.
    • tessel-firmware: the firmware for Tessel. This was just changed this to add the ‘.add’ function.
  10. Overwrite the Tessel firmware with the new firmware you just built. In the Release directory:

    tessel update ./tessel-firmware.bin Don’t forget that ./ before tessel-firmware. It specifies a local path. Otherwise tessel update will look for firmware patches on our build server.

  11. Now run the test code you have for this function and it should pass.

If you want to revert back to the original Tessel firmware, just run a tessel update --force which will force Tessel to update to the newest release version.

This document will be kept up to date on Github

Arduino <-> Tessel communication

8/21/2014– Jia Huang

This document will be kept up to date on Github

This is a tutorial for how to pass data back and forth between an Arduino and a Tessel.

The data is passed via a UART bridge. Arduino has the SoftwareSerial library for UART comm and Tessel has it’s built in UART functions.

UART works through having TX (transmit) and RX (recieve) pins. A TX of one device is hooked up to the RX of another device like this:

  • Tessel TX Arduino RX
  • Tessel RX Arduino TX
  • Tessel GND Arduino GND

Step 1: Get an Arduino

The Arduino needs to operate at 3.3V. Some boards which operate at this voltage are:

Both the Seeeduino and the Crowduino can switch between 5V and 3.3V.

Arduino Uno

Arduino Unos send over signals at 5V and this will damage Tessel. If you are planning on using an Arduino Uno, you need to make a 5V to 3.3V level converter which shifts the 5V UART TX signal from the Arduino to 3.3V.

The UART TX coming from Tessel is at max 3.3V, but this will register as a digital “high” signal so it does not need to be boosted up to 5V.

Step 2: Hook up the Arduino to the Tessel

There are 3 pins that need to be hooked up, UART TX, UART RX, and Ground.

In the code example, we’re going to be using Arduino’s SoftwareSerial on pins 10 and 11.

wiring an arduino to a tessel

  • Arduino Pin 10 (orange wire) Tessel Port D, pin TX/G1
  • Arduino Pin 11 (white wire) Tessel Port D, pin RX/G2
  • Arduino Ground (brown wire) Tessel Ground

Step 3: Program the Arduino

Run this code on the Arduino

#define rxPin 10 // connect to TX of other device
#define txPin 11 // connect to RX of other device

SoftwareSerial tesselBridge =  SoftwareSerial(rxPin, txPin);

void setup()  
  // open serial port at 9600 baud
  Serial.println("Starting up...");
  // set the data rate for the SoftwareSerial port

void loop() // run over and over
  if (tesselBridge.available())
  if (Serial.available())

Step 4: Program Tessel

Make a folder for the code:

mkdir arduinoBridge;
cd arduinoBridge; touch uart.js;

Put this in the uart.js file.

var tessel = require('tessel');
var led1 = tessel.led[0].output(0);
var led2 = tessel.led[1].output(0);
var i = 0;

// baudrate must match the baudrate set in the Arduino file
uartBridge = tessel.port['D'].UART({baudrate: 9600}); 

uartBridge.on('data', function(data){
  // UART data is not packetized, so you will get the data 
  // buffer as the message is sent. This means that long
  // messages will be truncated as several events.
  var number = parseInt(data[0]) - 48; // convert hex to ascii to int
  console.log("got data", data, number);

  if (number == 1)

  if (number == 2)

// every 3 seconds write some data over to the arduino
  uartBridge.write("Hi there "+i+"\n");
}, 3000);

Run the code with tessel run uart.js, or if you want this to be persistent through power cycles, tessel push uart.js.

Step 5: Test it

You should be able to go into the Arduino console and see the blue and green LEDs on Tessel change as you enter a “1” or a “2”.


This document will be kept up to date on Github

Tessel Faster Better Stronger

8/20/2014– Nathan Lintz

How do we make Tessel faster? How do we keep Tessel simple for users yet powerful enough to take on big problems? What does it take to make a bulletproof wifi connected microcontroller that can truly deliver on the promise of the Internet of Things? These were just a few of the questions which guided the projects I worked on the summer.

To solve these sorts of problems, I focused on improving the speed of Tessel by writing new firmware apis and porting the Tessel platform to other chipsets. I learned a lot about developing hardware and software platforms, so I thought I’d share some of the insights I gained along the way.

How Fast? This Fast

Moving Pixels

I was inspired to work on improving the Tessel’s performance after reading a request on our forums for an LCD screen module. I naively believed that getting the Tessel to cooperate with a screen would be as simple as porting a C graphics library to JavaScript and plugging in an LCD.

My first attempt resulted in a graphics library which could output approximately 1 pixel a second. At this rate, filing a phone screen sized display would take approximately 100 hours…bummer. I profiled the program to find what was taking so long and it turned out that making a JavaScript call per pixel was causing the library’s performance to degrade dramatically.

Not wanting to give up quite yet, I decided to dive into the firmware and see if there was any way to pump out pixels at a faster rate. I created a new hardware API for the Tessel, the SPI Batch API, which improved the performance of the graphics library I wrote by a factor of 400! With this new implementation we went from making one JS call per pixel to one JS call for the entire screen. When I tested the library, colorful pixels began pouring into the screen, proving that graphics programming is possible on the Tessel.

Developing a graphics library and a firmware API for the Tessel taught me a lot about the power and limitations of JavaScript. When it comes to event driven programming and IO bound tasks, JavaScript is great. However, when it comes to matters of raw speed, C is usually the right answer. This insight can be distilled into the following heuristic which is applicable any time you’re writing code which involves hardware and software components:

For CPU bound tasks, like pushing pixels to a buffer,write your code in C. For IO bound tasks, like reading from a file or handling HTTP requests, use a high level language like JavaScript.

Portable Tessel - Modules Everywhere

After modifying the Tessel firmware to handle graphics, I talked to the team about other ways we could improve Tessel’s performance. We realized that many of our problems could be solved by having an operating system. At the moment, Tessel doesn’t run an operating system; rather, it has a firmware layer which can run a single program. As a result, we can’t use libraries which rely on an OS. By running Tessel on a Linux board, we would have access to these sorts of libraries such as V8, Google’s JS engine, and the Linux TCP stack. This insight blossomed into the Portable Tessel Platform, a node package which emulates the Tessel API on a computer such as the Raspberry Pi or Cubieboard.

Raspberry Pi


I started off this project by writing up a spec and picking node libraries that would emulate the hardware APIs for the Tessel. Our modules each use either SPI, UART, GPIO pins, I2C, or some combination thereof. After some quick searching on NPM, I found found libraries which would implement the needed protocols.

The libraries I found seemed to work, so I assumed that all I had to do was wire the boards to the modules. Unfortunately, I neglected to make sure that the hardware of the different boards was similar enough to the Tessel and that Linux fully supported all of the drivers I needed. I began testing some of our modules on the Raspberry Pi and Cubieboard, and I found that I2C on the Raspberry Pi has issues communicating with our modules, as its processor doesn’t support certain commands such as repeated start transfers. Similarly, the Cubieboard doesn’t have SPI support unless you recompile the kernel drivers.

After discovering that the boards did not support the needed protocols, I began to research how other people got them working. It took a while, but eventually I found a way to properly compile the drivers for the Cubieboard and how to fix the I2C driver for Raspberry Pi. Once I had working drivers, I just had to hook up the boards to the Tessel modules and the Portable Tessel Platform was born. Now users can build projects using our hardware modules on their own boards, opening our platform up to people who haven’t purchased a Tessel yet.

Working on the Portable Tessel Platform taught me a lot about the challenges of hardware-software integration. In pure software projects, it is easy to just swap out or modify source code to meet your needs. In hardware, planning out everything ahead is necessary as some boards not have all the features you need. I was lucky that I found new drivers for the Cubieboard and Raspberry Pi, but picking boards which have full support for SPI and I2C would have made building the Portable Tessel Platform much easier.

Next year I’ll be back at college so you won’t be hearing from me on the blog for a while. Please message me @nlintz if you get a chance to build any exciting hardware projects on the Portable Tessel Platform or graphics projects using SPI Batch.

Nathan Lintz

Evan’s Summer Internship Farewell

8/18/2014– Evan Simpson

It feels like just last week that Jon turned to me in the car and asked, “now that you’re halfway through your internship, what do you think so far?” I then pointed out to him that I had only been at Technical Machine for three weeks, and had planned on staying for two more months, so I was nowhere near halfway done. I can’t really blame Jon for thinking I’d been there longer, since I joined during the busiest time of the company’s short history, when Tessel was getting ready to ship for the first time. That being said, I’m finding it hard to believe how quickly the remaining time has gone by.

The work that I did for Technical Machine was so diverse that there was never a dull moment. I started with small module examples and README fixes, and went on to actually adding functionality to the module libraries, as well as fixing bugs. At one point I was making changes to the runtime, at another, firmware. From hardware debugging and module design to web server development, I’ve certainly had my fill of fun things to work on. Through all of this fun work, though, I did learn quite a bit in just these short months, and I’d like to share some of those things with you now.

Internships Can be Meaningful Without Gimmicks

I’ve seen and heard about too many different intern programs that will include things like field trips and fun events to make sure the interns have a good summer. While I do appreciate the intent of these activities, I feel that sometimes it is done as a way of saying “sorry the work isn’t very interesting, let’s take a break and have some fun”. Working at Technical Machine I realized that when the work itself is fun, those other perks and gimmicks don’t really seem all that special. What I wanted out of an internship was to work on something I enjoyed with other people, and to feel like my accomplishments mattered to the company. That’s exactly what I got here at Technical Machine, and I couldn’t have asked for more.

Hardware Doesn’t Have to be Hard

I’d say I had a very basic understanding of electronics and hardware development before joining Technical Machine, having only worked with Arduino on a handful of different projects. That quickly changed as I started to make changes to different module libraries. I became much more familiar with how microcontrollers load and run programs, and the different protocols devices use to talk to each other over, with or without wires. The thing that struck me the most was how simple it all was. Most of the devices we use today are all digital electronics, which coming from a background in software development, isn’t nearly as complex as I thought it all was. Putting a “digital-only” constraint on a system means that it can translate very well from the hardware domain into the software domain, where it can be abstracted and automated with ease.

If you’re a software developer looking to learn more about hardware, I’d definitely recommend reading through some of the source code for some of the Tessel module libraries. They’re all written in JavaScript, so they’re easy to understand, but they also show you how the Tessel is communicating with the different modules. This also leads me straight into my next point…

Open Source is Great

Tessel is the first open source project I’ve ever contributed to, and I love it. I think there is a lot of good that can come from open source projects, whether they be based in software, hardware, data, or otherwise. Right now there isn’t nearly as much open source hardware as there is software, but there are still some good resources out there that are invaluable when it comes to starting a new hardware project. There were a few times when I was working on one of our modules and the best resources for debugging certain problems were other open source projects using similar parts.

Now that I’m all done, it’s time for me to return to school for one more year. I had a great time out here and I plan to continue contributing to the project in my spare time, so expect to see me around on Github.

See you around,
- Evan

P.S. If you’re interested in working or interning for Technical Machine, and want to know more about what it’s like day-to-day, let me know! I’d love to share more of my experiences.

Getting the CC3000 working with JavaScript

8/15/2014– Jia Huang

When Tessel’s wifi is connected the wifi chip’s features can be accessed through Node’s net and http libraries.

However, there are a few features of the CC3000 that do not fit within Node’s API, such as the ability to connect to a network, or exposing to a user that their network connection has been dropped.

We recently introduced the ability to control Tessel’s onboard wifi connections from JavaScript. It’s done through another library called wifi-cc3000 that now comes bundled on Tessel, much like the tessel library. It allows for something like this:

var wifi = require('wifi-cc3000');

// connect to a network
function connect(){
    security: 'wpa2'
    , ssid: '#####' // network name
    , password: '#####'
    , timeout: 30 // in seconds

// reconnect on dropped connection
wifi.on('disconnect', function(err, data){
  console.log("disconnect emitted", err, data);
  connect(); // try to reconnect

A more indepth example is on Tessel’s getting started page and the full documentation is on our docs page.

How it’s implemented

The technical details behind the wifi-cc3000 library are similar to how we expose other C functions to JS, with the exception of having to also work with the CC3000 wifi chip.

TI gives out a closed source firmware binary that gets loaded on to the CC3000, along with the C libraries needed to communicate with the CC3000. This provides us the socket interface and CC3000 specific functions like network connection.

It communicates over SPI, where our Tessel MCU acts as the master and the CC3000 is the slave device. In addition to the default SPI pins (clock, data in, data out, and slave select), it also has an interrupt pin (IRQ).

An interrupt is raised by pulling the IRQ pin low, which triggers an interrupt on our main MCU. This allows our microcontroller to give the CC3000 a set of commands (like go connect to X network), and then go do other processing until the CC3000 responds with a connected or disconnected event.

A typical call on the CC3000 looks like this:

  1. We call a CC3000 driver function.
  2. The command gets translated into a SPI signal which is passed to the CC3000.
  3. The CC3000 does some processing.
  4. The CC3000 fires an interrupt.
  5. We handle the interrupt by calling a CC3000 processing function to the interrupt handler.

Some calls from the CC3000 are unsolicited, such as when we drop a wifi network. In this case the CC3000 directly fires an interrupt without us initiating the call.

The wifi-cc3000 library needs to handle both types of calls:

  1. Calls which are initiated from the user, such as .connect.
  2. Unsolicited events from the CC3000, such as a disconnected event.

In order to make this easier, we wrote some wrapper libraries.

Calls initiated by the user

Calls initiated from JS are similar to any other JS -> C exposure (like our Pin API for example). It usually follows these three steps:

  1. Bind C functions to Tessel’s VM functions. We have two locations for this, one in the runtime repo, and another in the firmware repo. The bindings on runtime relate to anything needed for Node compatibility (such as the `net` lib) while the ones in firmware relate to how Tessel specifically operates (such as Pin toggling and LEDs). Since the wifi commands we’re looking at (connect, disconnect, setting timeouts) are specific to the CC3000 and not to Node, the bindings are in the firmware repo. A typical binding looks like this:
       static int l_wifi_is_busy(lua_State* L) {
         lua_pushnumber(L, hw_net_inuse() ||  
             tessel_wifi_is_connecting() ? 1 : 0);
         return 1;
    This pushes a `1` into the global Lua context for this function’s return value if the wifi chip is in use, otherwise it pushes a `0`.
  2. Expose VM functions through a process binding to JS. All of our firmware’s hardware functions are bound to the `luaopen_hw` context. When Tessel first boots up we push in these functions into the VM.
  3. Wrap it in a JS library. We can link to a process binding in order to access the functions exposed through `hw`. This allows us to call C functions.
       self.isBusy = function(){
         return hw.wifi_is_busy() == 1 ? true : false;

Unsolicited calls

Unsolicited calls are more complicated since we’re going from C -> JS.

All JS is handled inside of the event loop, so in order to surface up a call from C we have to wrap our C function as if it were an event and then push it to the head of the event queue.

The process is:

  1. Create a tm_event from C. In this case it’s the disconnect event.
       tm_event wifi_disconnect_event = TM_EVENT_INIT(wifi_disconnect_callback);
  2. On the C callback that the CC3000 triggers, also trigger the tm_event.
       void _cc3000_cb_wifi_disconnect ()
  3. This pushes the event to the head of the event queue.
       void tm_event_trigger(tm_event* event) {
        if (event->pending == false) {
            event->pending = true;
            event->next = 0;
            if (event_queue_head) {
                // Link it on to the end of the existing linked list
                event_queue_tail->next = event;
                event_queue_tail = event;
            } else {
                event_queue_head = event_queue_tail = event;
  4. Push the event message on to the VM and clean up.
       void wifi_disconnect_callback(void) {
          lua_State* L = tm_lua_state;
          if (!L) return;
          lua_getglobal(L, "_colony_emit");
          lua_pushstring(L, "wifi_disconnect_complete");
          lua_pushnumber(L, 0);
          tm_checked_call(L, 2);
  5. Listen for the hardware process in JS.
       process.once('wifi_disconnect_complete', function(err, data){
            self.emit('disconnect', err, data);
            callback && callback();

For those of you who are curious and want to see the implementation, here’s pull request #40, which has all the changes in order to get the wifi-cc3000 library functional.

Getting Started with BLE + Tessel

8/11/2014– Evan Simpson

This document will be kept up-to-date on Github.

This guide is meant to be suitable for a Bluetooth novice. If you find any part of this guide hard to understand or inaccurate, let us know! We’d love to fix that. We hope that after reading this you’ll understand what is and is not possible with BLE, as well as know when to properly refer to a BLE device as an iBeacon.


Bluetooth Low Energy (BLE/Bluetooth 4.0/Bluetooth Smart) is the most recent incarnation of Bluetooth technology put out by the Bluetooth SIG (the organization that maintains the specification). It is designed for applications in which transferring small amounts of data at a relatively low speed makes sense, and low power consumption is necessary. It is important to understand that BLE is not at all backwards compatible with older versions of Bluetooth.

Comparison to Classic Bluetooth

The list of reasons why Bluetooth Classic (also known as Basic Rate/Enhanced Data Rate - BR/EDR) and BLE are incompatible is extensive, but we’ll try to cover some of the more fundamental differences here. This section can help you decide whether BLE is right for the application you might have in mind.

Pairing and Bonding

In Bluetooth Classic, before any data can be exchanged a few things need to happen.

First, a master device needs to find a slave device to connect to. If the master has an address for a device, it can attempt to pair directly, without even scanning for devices. Bluetooth Classic devices can be either discoverable or non-discoverable, but can still be paired with while non-discoverable. So, even if the master did scan for the device and found nothing, there is still a chance the device is in range and not-discoverable, so it might as well try pairing any way. Once the two devices have paired successfully, exchanging pin codes and security keys if necessary, then they are bonded and can initiate a connection.

Once the devices are bonded, any time they come within range of each other, they will automatically connect, if possible. When the connection has been made, the devices can exchange data wirelessly as needed.

With the introduction of BLE, there are a number of differences to the connection process. First, in order to connect to a BLE device, the target device must be advertising that it is connectable. Second, a connection can be made without pairing, with pairing being left as an optional security mode. Finally, a connection does not have to be made in order to get data from a remote device. We’ll see how this is possible later on.

Data Model

Bluetooth Classic is set up to stream data from one device to another. It can accomodate data rates high enough to support streaming audio. One of the most popular use cases for Bluetooth has historically been serial cable replacement, which is just a two-way communication stream, conveniently made wireless.

BLE, on the other hand, exchanges data through a database located on one of the connected devices. Rather than keep an open stream of data, data is only exchanged when the database is modified, or a connected device requests a value from the database. For this reason, it doesn’t really make sense to use BLE in the same way Bluetooth Classic has been used, but there are plenty of new applications involving sensors and other devices exchanging small amounts of data, which BLE was designed for.

Dual Mode Devices

There are some devices, such as cell phones and computers, which need to be able to connect to both types of devices. These devices will have Bluetooth hardware that separately supports both versions. This class of devices is referred to as dual-mode, contrary to a single-mode device, which is only compatible with same-version devices and dual-mode devices.

BLE Roles

The BLE specification allows a device to take on various roles that define the specific actions the device may be capable of. There are really two types of roles, with each device in a network fulfilling one of each type of role. The two types are central or peripheral, and client or server.

Central vs Peripheral

The central and peripheral roles describe the order of command in a BLE network. The role of the central device is similar to that of the master in Bluetooth Classic. The central device is responsible for searching for and establishing a connection with one or more peripheral devices.

The role of the peripheral device is similar to that of the slave in Bluetooth Classic. The peripheral device advertises whether or not it is connectable, as well as any services it might provide. The central can use that data to decide if it should connect to the peripheral or not.

Client vs Server

The client and server roles describe the data ownership and transmission relationship in a BLE network. In a typical network, the central device will take on the role of client - requesting and sending data from and to one or more server devices.

Peripheral devices will typically take on the role of server. Servers keep a database of attributes that a connected client can write to, and read or subscribe to changes from.


A beacon is a specific implementation of a peripheral device that does not act as a server. All of the data a central device needs from a beacon is broadcast through the advertisement, so there is no need to connect to request the data. It is also important not to confuse any generic BLE beacon with iBeacons.

Generic Attribute Profiles

Generic Attribute Profiles (GATT Profiles) are used to define the hierarchical structure of the database a server uses to store the data it makes available to clients. A profile consists of services, each of which may contain multiple characteristics. The core specification has a small set of pre-defined profiles, however the specification does allow you to create your own.


A characteristic represents one data attribute that a client can access. Each characteristic can store only a single value at a time. Each characteristic can have different access permissions such as read, write, and notify.


A service is used to group a category of characteristics. All characteristics must belong to a service. Usually when central devices are looking for a device to connect to, they will look to see if they support a particular service, rather than an individual characteristic.


Every service and every characteristic must be assigned its own Universally Unique Identifier (UUID). This UUID is how devices will look for and recognize if another device supports a particular attribute. There is a set of reserved 16-bit and 32-bit UUIDs outlined in the core specification that have a predefined or reserved use across both services and characteristics. The list of profiles linked above makes use of this reserved space. If you are looking to create your own profile, the best way to get UUIDs is through the command line tool uuidgen if you are on OS X or Linux, or through a simple online service like

Tessel’s GATT Profile

Below, we show a portion of the Tessel’s GATT profile, which has two unique services. One service is for sharing the BLE module’s firmware version, and the other is for sending and receiving data.

The second service has a total of 12 characteristics which can be used generically for sandboxed design and prototyping of your own services.

  "services" : [
            "uuid" : "08c8c7a06cc511e3981f0800200c9a66"
          , "description" : "Tessel Firmware Information"
          , "characteristics" : [
                  "uuid" : "50888c106cc511e3981f0800200c9a66"
                , "id" : "c_tessel_firmware_version"
                , "description" : "Firmware Version"
                , "value" : "1.0.1"
      , {
            "uuid" : "d752c5fb13804cd5b0efcac7d72cff20"
          , "id" : "data_transceiver"
          , "description" : "Data Transceiving"
          , "characteristics" : [
                  "uuid" : "883f1e6b76f64da187eb6bdbdb617888"
                , "id" : "c_trans_0"
                , "description" : "Transceiver Value 0"
                , "properties" : ["read", "write", "indicate", "notify"]
                , "length" : "255"
              . // The full service contains 12 generic characteristics
              , {
                  "uuid" : "4a0efa07e1814a7fbd72094df3e97132"
                , "id" : "c_trans_11"
                , "description" : "Transceiver Value 11"
                , "properties" : ["read", "write", "indicate", "notify"]
                , "length" : "255"

You can find a JSON version of the Tessel’s entire GATT Profile, including omitted services and characteristics, in the ble-ble113a library. Please note that this is just a description of the GATT profile, which is actually defined in the firmware of the BLE module. Making changes to the GATT profile on the module requires creating a modified version of the firmware and uploading it to the module. A guide for doing this is coming soon.


In order to form a connection between two devices, the peripheral device must broadcast an advertisement for the central device to see. An advertisement packet contains the perihperal device’s address, as well as a device-configurable section of data that can contain various kinds of data. A scanning central device can also request a scan response from a peripheral, which has the same format as an advertisement, but can contain different, additional data. Think of a scan response as a second advertisement that can be sent upon request.

Advertising packet data

The type of data an advertisement can contain is strictly defined by the core specification and a full list of available data types can be found here. Fortunately, we have put together an npm module called bleadvertise to help you create and decode advertising data packets in a more semantic manner. Some of the more common data types to put in the advertisement are Flags (which is more or less mandatory), Incomplete List of 128-bit Service UUIDs, either Short Local Name or Complete Local Name, as well as Manufacturer Specific Data which is used in iBeacons. The maximum length an advertising data packet can be is 32 bytes, so this is an important consideration in designing what kinds of information to put in the advertisement and/or scan response.

Finding the right device

When a central device is looking for a specific device or specific type of device, it has a few options in terms of what to look for in an advertisement to determine whether or not to connect. The two most common pieces of advertising data that are examined are the device address, and the complete or incomplete list of supported services. Sometimes the address is not the best way to keep track of a device, because many devices use what is known as a random address which will change relatively frequently, and in this case, other information in the advertisement should be used to pick a device.


While any peripheral device can be a BLE beacon, and can beacon any data it wants to, there is now a very popular type of beacon specification created by Apple called the iBeacon. iBeacons are meant to be used for location-based applications, where high accuracy is important (i.e. inside a grocery store). The advertisement packet for an iBeacon is relatively simple consisting of a 128-bit location UUID followed by 2-Byte Major region code and 2-Byte Minor region code, marked as Manufacturer Specific Data. You can read more about the specification and licensing on Apple’s developer website.

Advertising Examples

The following example will show you how to set up a Tessel with a custom advertisement.

var tessel = require('tessel');
var bleLib = require('ble-ble113a');
var bleadvertise = require('bleadvertise');

var packet = {
  flags: [0x02, 0x04], // Connectable, BLE only
  incompleteUUID128 : ['08c8c7a06cc511e3981f0800200c9a66'], // Tessel Firmware Version Service UUID
  shortName : 'Tessel'

var ad = bleadvertise.serialize(packet);

var peripheral = bleLib.use(tessel.port['A'], function(){
  peripheral.setAdvertisingData(ad, function(){
    console.log('Now advertising');

That’s it! We’ll come back and add more to this later, once we learn about receiving connection events from a central device.

The example for creating an iBeacon is similar, but uses slightly different data.

var tessel = require('tessel');
var bleLib = require('ble-ble113a');
var bleadvertise = require('bleadvertise');

var uuid = 'D9B9EC1F392543D080A91E39D4CEA95C'; // Apple's example UUID
var major = '01';
var minor = '10';

var iBeaconData = new Buffer(uuid+major+minor, 'hex'); // Create data Buffer

var packet = {
  flags: [0x04], // BLE only
  mfrData : iBeaconData

var ad = bleadvertise.serialize(packet);

var beacon = bleLib.use(tessel.port['A'], function(){
  beacon.setAdvertisingData(ad, function(){

Since beacons generally aren’t meant to connect to other devices, this is pretty much everything you need to make a beacon. Of course, if you want to beacon something besides a static value, you’ll need to make some changes, but that’s the gist of it.


Now that we understand how peripherals let central devices know they’re available, let’s look at how the central finds them and initiates a connection.

Scan for Peripherals

The first step in discovering advertising peripherals is with a device scan. In the scanning process, the central will listen for advertisements and report when it finds one. On most platforms, there will be scanning options that let you filter discovered peripherals by the service UUIDs in their advertisements, and also prevent reporting of duplicate devices. Once you have discovered a suitable device to connect to, just send a connect command and you’re ready to start exchanging data!


With BLE there are two main modes of secure data exchange - encryption and bonding, as well as three different methods for exchanging encryption keys - Just Works, Passkey Entry, and Out of Band.

Encryption and Bonding

With BLE, a connection can be encrypted with a short term key through pairing, and it can also be encrypted with a long term key through bonding. When paired, the encryption will last for the duration of the connection, and will need to be re-encrypted each time the connection is established. Through bonding, the devices will store the encryption keys, such that each time they re-connect, they will attempt to encrypt the connection. The simplest, however insecure, means of encrypting the connection is called Just Works and uses an exchanged passkey of 000000, so there is no required input from the user. The more secure options are Paskey Entry and Out of Band. To use Just Works pairing with a Tessel in the central role, call the ble.startEncryption() method after a connection has been made.

Passkey Entry

With passkey entry pairing, there is a requirement that one device be capable of displaying a passkey value (6 digits) and the other device be capable of inputting the passkey. When the passkey is displayed, it is up to the user to enter the code on the input device. Once the passkey is confirmed, the connection will be encrypted. There is no requirement that the the central or peripheral take on either display or input roles, just that both are implemented between the two devices. To enable passkey entry on a Tessel central device, call ble.setMITMProtection(true) as well as ble.setIOCapabilities() to identify the device as a display or input before scanning for devices. After connecting, once again call ble.startEncryption() to start the passkey process. In either central or peripheral mode, a Tessel can receive a 'passkeyDisplay' or 'passkeyRequest' event, and can input a displayed passkey with the ble.enterPasskey(000000) method.

Out of Band

Out of Band (OOB) pairing requires the use of another means of communication, besides BLE, to exchange encryption keys. A common example of an OOB exchange would be over NFC. Once the devices have exchanged keys over NFC, the data is relayed to the BLE controller, and the connection can be encrypted using the keys. This method is the most secure option BLE currently offers to prevent MITM attacks. Implementing OOB security on a Tessel is similar to passkey protection, however instead of needing to set the IO capabilities, you need to use ble.setOOBData(data), where data is a 16-byte string. If either one of the connecting devices has OOB data set, then the other will need to have the same data set in order for the connection to be encrypted.

Connection Examples

First let’s see what our code looks like on a Tessel acting as a central device that wants to connect to another Tessel acting as a peripheral. Let’s assume that the peripheral is advertising the same packet from our first advertisement example above.

var tessel = require('tessel');
var bleLib = require('ble-ble113a');

var serviceUUID = ['08c8c7a06cc511e3981f0800200c9a66']; // UUID to filter for
var central = bleLib.use(tessel.port['A'], function(){
  central.startScanning(serviceUUID); // Start the scanning process
  central.on('discover', function(peripheral){ // Catch the discover event
    peripheral.connect(); // Connect to this device
  central.on('connect', function(peripheral){ // Catch the connect event
    console.log('Connected to', peripheral.address.toString());

As you can see we have two events we can listen for that let us know when a new device has been discovered or connected to.The connect event works for both central and peripheral devices, so we can go back to our advertisement example and add a listener for a connect event.

var tessel = require('tessel');
var bleLib = require('ble-ble113a');
var bleadvertise = require('bleadvertise');

var packet = {
  flags: [0x02, 0x04], // Connectable, BLE only
  incompleteUUID128 : ['08c8c7a06cc511e3981f0800200c9a66'], // Tessel Firmware Version Service UUID
  shortName : 'Tessel'

var ad = bleadvertise.serialize(packet);

var peripheral = bleLib.use(tessel.port['A'], function(){
  peripheral.setAdvertisingData(ad, function(){
    console.log('Now advertising');
  peripheral.on('connect', function(connectionId){
    console.log('Connected to central device');

When the connection is established the central will automatically stop scanning, and the peripheral will stop advertising. Since the central can handle connections with multiple peripherals, you can start scanning again and look for another device, if needed.

Transferring Data

Once we have established a connection, we can start transferring data back and forth between our devices. This is where the terms client and server become relevant again. For this tutorial let’s assume our central will play the role of client, and the peripheral will be the server. With BLE all data is read from and written to the server’s GATT database, which is that data store who’s structure is defined by the GATT profile, discussed above.

Service Discovery

In order for a client to read and write characteristics on a remote server, it first needs to know which services and characteristics are available. To get this information, the client can request the server send over a list of all of its services and characteristics. Part of this service discovery includes a short 1-byte handle value for each characteristic. Once the client has the handle, it will use that instead of the 16-byte UUID for each exchange. This handle will be unique on different devices for characteristics with the same UUID, so it is always necessary to do a service discovery in order to get the proper handle, even if you already know the UUID.

Updating a local GATT database

Since the GATT database lives on the server, it should always have direct access to the data being exchanged. The way this is handled will vary by platform and device, but most devices that support server mode should have methods for directly updating and reading values in the GATT database.

Updating a remote GATT database

Once the client has access to the handle for the characteristic it needs to read or write to, doing so is pretty straightforward. Again, any reasonable platform should expose methods for reading/writing methods through its API. At this point it probably also important to mention that you should make sure the permissions on the characteristic you are trying to access allow your desired operation. On the Tessel, all of the Tessel-specific characteristics can be read, and all of the characteristics in the Transceiver service can be written and subscribed to, as well.

Subscribing to changes on a remote GATT database

For some applications, you don’t want to periodically check if a remote value has updated, but would rather get a notification when it has, and only then read the value. BLE allows this through two similar mechanisms. A client can set up either notifications or indications on a particular characteristic, assuming the server permissions allow it. Once a client subscribes to notifications, any time the server makes a change to the subscribed characteristic, it will let the client know, along with a short preview of the data. If the entire piece of data does not fit in the notification, the client can then send a read request for the rest. An indication works the same way, except the client must send a message back to the server, acknowledging that it received the indication.

Data Transfer Examples

Let’s go ahead and add to our earlier connection example, and make our two devices exchange data. First we’ll set up our central as a client by adding a service discovery request, looking for the first transceiver characteristic, and then subscribe to notifications.

var tessel = require('tessel');
var bleLib = require('ble-ble113a');

var options = { serviceUUIDs : ['08c8c7a06cc511e3981f0800200c9a66'] }; // UUID to filter for
var characteristicUUID = ['883f1e6b76f64da187eb6bdbdb617888'] // Characteristic we will write to
var central = bleLib.use(tessel.port['A'], function(){
  central.startScanning(options); // Start the scanning process
  central.on('discover', function(peripheral){ // Catch the discover event
  central.on('connect', function(peripheral){
    console.log('Connected to', peripheral.address.toString());
    peripheral.discoverCharacteristics(characteristicUUID, function(err, characteristic) {
      if (characteristic.length){
        characteristic[0].on('notification', function(data){
          console.log('Got notification', data.toString());

And now we’ll update our peripheral example with some corresponing server functionality. We’ll need to set it up to listen for when the client subscribes to a characteristic. Once that happens, we can periodically update the value and the client should automatically receive notifications.

var tessel = require('tessel');
var bleLib = require('ble-ble113a');
var bleadvertise = require('bleadvertise');

var packet = {
  flags: [0x02, 0x04], // Connectable, BLE only
  incompleteUUID128 : ['08c8c7a06cc511e3981f0800200c9a66'], // Tessel Firmware Version Service UUID
  shortName : 'Tessel'

var ad = bleadvertise.serialize(packet);

var peripheral = bleLib.use(tessel.port['B'], function(){
  peripheral.setAdvertisingData(ad, function(){
    console.log('Now advertising');
  peripheral.on('connect', function(connectionId){
    console.log('Connected to central device');
  peripheral.on( 'remoteNotification', function(connectionId, index){ // Catch when remote subscribes
    console.log('Notifications started');
    var count = 0;
      peripheral.writeLocalValue(index, new Buffer( count.toString() )); // Write to [index] transceiver value
    }, 2000);

Testing and Debugging

When working with BLE you might encounter an issue that you realize you have no way to resolve, especially if you are using a device which you cannot make any changes to. The following are some of the most helpful that we’ve found in working with Bluetooth.


LightBlue is an OS X and iOS application that allows you to see and connect to BLE devices, as well as run a service discovery, and make read/write/notify requests. This is great if you are working with a peripheral device and want to see it from the perspective of a central device.


Noble is a Node library which allows you to access the BLE capabilities of newer Mac Books as well as Linux laptops with the appropriate hardware. Noble allows you to set up your laptop as a central device, and its companion library, Bleno, allows you to set up the computer as a peripheral.


This document will be kept up-to-date on Github.