• Evan's Summer Internship Farewell

    Monday, August 18, 2014

    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.

    #evan simpson #internship #summer #summer intern #technical machine #tessel #open source #hardware

  • Getting the CC3000 working with JavaScript

    Friday, August 15, 2014

    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.

    #Jia Huang #tessel #Technical Machine #cc3k #cc3000 #wifi #javascript #api

  • Getting Started with BLE + Tessel

    Thursday, August 14, 2014

    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 http://www.uuidgen.com/.

    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.

    #ble #tessel #evan simpson #getting started #tutorial #documentation #bluetooth #Bluetooth 4.0 #Bluetooth Smart #Bluetooth Low Energy #iBeacon

  • Introducing the Tessel Projects Portal

    Wednesday, August 13, 2014

    8/13/2014– Kelsey Breseman

    We’ve just released Tessel’s Projects Portal, a site for Tessel hackers to show off what they’ve made. It’s designed to be simple: an aggregator requiring little more than a Github link and a picture to show off a project. The simplicity is deceptive, though: there’s something important happening at the intersection of open source software and a physically modular open system.

    The interaction for the Tessel projects portal lies somewhere between Instructables and Thingiverse. Since your projects might require some special setup (hardware or software), projects are given space for photos and explanation– like Instructables.

    There’s also the capacity for plug-and-play interaction. For example, clap-on lights is now a solved problem. Plug the pieces together, push the code, and clap: easy as Ikea. Projects exist fully-formed, and anyone can just download the product, like on Thingiverse.

    But what happens when you build something more complex? A Nest-type project for your greenhouse, for example, or a motion-tripped home security camera. It’s not exactly DIY when the interaction is plug-and-play (and clone the code). It’s more like a system of highly configurable modular appliances.

    This is, I think, a step closer to the promise of consumer 3D printing. When you think of 3D printers in every home, you think of people downloading products all the time, printing out the objects they need, maybe customized for their particular application.

    With current 3DP, you see a lot of excitement, but not a lot of practical purpose in the consumer sphere. It turns out that there aren’t many everyday problems that can be solved with a specifically shaped piece of weak plastic. But what if you could add brains to that piece of plastic? What if right alongside the 3D file was a link to some code and two or three simple parts that you could slot together?

    This is the intersection of freely licensed software and open source hardware; this is open source products. You can get a kit, tweak it to your needs, and interact from an interface (online or off) that you control.

    What’s more, you can reach in to this product at any level; nothing is proprietary, and there’s no warranty to void. If you’re a software developer, you can fork the way that data is collected, the way it’s presented, the interaction with outside libraries. If you know hardware, you can swap out your own parts in place of our modules and still run the code. This is open; this is indie; this is just plain cool.

    Open source has a lot of existing community and infrastructure, but not yet one with this particular facet of digital and physical modularity. That’s why we made the Projects Portal, hoping to develop it into a testing ground for open projects and products. We seek to empower, and this is a powerful idea.

    You can use our Projects Portal to gauge reactions to your projects and products. You can try to determine if an interaction holds value, seeking beta testers from our community of people who already have the parts.

    If you want to test out something someone has already made, you can git clone, tessel run. It’s simple, and you don’t have to reinvent it.

    There’s also the whole spectrum between: you can write a library for a component, or a node module for an interaction. You can make a piece of a project, a unitary interaction, so people can fork it or require it and build from there.

    This is a whole open source ecosystem; it’s time to start building.

    Check out the projects portal at projects.tessel.io.

    #kelsey breseman #technical machine #projects #projects portal #tessel #instructables #thingiverse #ready-mades #modules #modularity #npm #open source #OSHW #OSS #3D Printing #3DP

  • Tessel Projects Page, New Hire, and More

    Tuesday, August 12, 2014

    8/12/2014– Updates

    Tessel Projects Portal

    We’d like to invite you to try our new (beta) projects portal! Check it out at projects.tessel.io. Find ideas of what to build next, get example code, show the community what you’re capable of building. We’re excited to see the things you’ve made!


    In the last month, we..

    • Published a bunch of firmware updates, JS/Node compatibility fixes, and wifi improvements (see the changelogs)
    • Exposed Wifi in the JS
    • Wrote the BLE getting started guide
    • Successfully ported LuaJIT to ARM Cortex M3 on PC. We still need to get it working on Tessel itself to realize the speed improvements. Look for a timeline soon!
    • Beefed up our testing infrastructure so that we can run a suite of tests on every module with every change to the firmware or module drivers
    • Sponsored Nodebots day

    We also made progress on:

    • Building out the backend infrastructure for remote code deployment. Over the next week, we need to add the firmware-level changes to accept tarballs over Wifi
    • Putting together a better internal system of engagement metrics (support, sales, sponsorship, etc.) so we can work with you more effectively
    • Rewriting our JS->Lua translator in C so that we can eventually compile on Tessel itself. This will allow the use of functions like eval() and Function()

    Company-wise, we made a hire! We’re pleased to announce Ken Nierenhausen is joining our team. One of his focuses will be improving Node compatibility (near and dear to all of our hearts).

    The docs repo is continually growing and changing. At the moment, the repo holds more tutorials than we link to on tessel.io/docs, so feel free to poke around. We’ll try to highlight some of these documents in upcoming blog posts.

    Research and Development

    Expect to see blog posts soon regarding our efforts in R&D. We’re currently looking into:

    • Potential new modules
    • A new version of Tessel
    • Tools to help you transition from a prototype to a scalable embedded system
    • Expanding the Tessel module ecosystem to other platforms (so far we have the Tessel library working on the Raspberry Pi and Cubieboard: node module [pre-production])

    All of these will take some time to develop, but what we wanted to let you in on what we’re exploring. We’d love to hear from you on the Forums or via email!

    See you on the forums,
    Eric, Jia, Jon, Kelsey, Ken, Kevin, Tim, Evan, Nathan, and Paige

    #update #tessel #technical machine #hiring #new hire #projects #portal #updates

August 2018

January 2018

July 2017

February 2017

November 2016

October 2016

September 2016

August 2016

July 2016

June 2016

April 2016

March 2016

February 2016

November 2015

September 2015

August 2015

July 2015

June 2015

May 2015

March 2015

February 2015

January 2015

December 2014

November 2014

October 2014

September 2014

August 2014

July 2014

June 2014

May 2014

April 2014

March 2014

February 2014

January 2014

December 2013

November 2013

October 2013

September 2013

August 2013

July 2013