Talk slides: “APIs to Electrons”

10/17/2014– Eric Kolker

Hey Tesselators, Eric here.

FIT

Conference season has (unofficially) begun!

Jon and I just got back from speaking at an event in Guatemala called Foro de Innovación Tecnológica (Forum on Technological Innovation), or “FIT” for short. We ran a four-hour hack event for the attendees, each gave a talk, and generally had a blast, which is pretty much par for the course.

From API to Electrons

My talk was called “From API to Electrons” and walks through what happens when you set a sound trigger on the Ambient module. As you might expect, it looks at what happens at every level of the system, from JS all the way down to simulating the analog electronics on the Ambient module…and back.

I had a lot of fun writing the talk and hope to give it again (in English this time) in the not too distant future. If you’re in the San Francisco Bay Area, give our meetup a look and keep your eyes peeled. If not, or if you just can’t wait, I put the slides online here and all the resources for the presentation (code, LT SPICE simulation, SVGs, etc.) here.

Tessel + Keen.io

10/16/2014 – Jia Huang

Keen.io is a cloud analytics platform that’s extremely easy to use. It gives an endpoint to hit and logs all data sent to that endpoint as part of an event stream.

We’re excited to finally get it working with Tessel. In the early Tessel firmware/runtime releases we had bugs on our runtime (specifically about zlib decoding/encoding) that prevented their library from working properly.

Those bugs have since been fixed and working with Keen has been a breeze!

In order to use Tessel with Keen first create an account.

Then go on to the projects page and find the project ID & API keys

Keen has an NPM library that takes in these keys. In order to configure Keen:

var Keen = require('keen.io');
var keen = Keen.configure({
    projectId: "####", // swap these out with your own keys
    writeKey: "####",
    readKey: "####"
});

As a test script I’ve sent over some data from the Accelerometer up to Keen. This script sets up the Accelerometer on port A of Tessel and sends data up to Keen every second:

var Keen = require('keen.io');
var tessel = require('tessel');
// attach the accelerometer to port A
var accel = require('accel-mma84').use(tessel.port['A']);
var count = 0;

console.log("setting up keen...");
var keen = Keen.configure({
    projectId: "####", // swap these out with your own keys
    writeKey: "####",
    readKey: "####"
});

var dataArray = [];
accel.on('ready', function () {
  console.log("Accelerometer is ready!");
  // as we get data push it into an array
  accel.on('data', function (xyz) {
    dataArray.push(xyz);
  });
});

// every second send up all the accelerometer data
setTimeout(function sendData(){
  keen.addEvent("accel", {data: dataArray}, function(err){
    if (err) throw err;

    console.log("Added event #"+count, "data: ", dataArray);
    count++;
    dataArray = [];
    setTimeout(sendData, 1000);
  });
}, 1000);

Before running this make sure Tessel is connected to the internet:

tessel wifi -n <your_network_ssid> -p <your_network_pw> -s <wpa2|wep>

The security (-s) flag defaults to wpa2.

If the network is unsecure, the password and security flags can be omitted:

tessel wifi -n <your_network_ssid>

Tessel should go through the wifi connection process and the yellow LED should be lit after it successfully connects to the internet.

After connecting Tessel to wifi, just do a tessel run index.js to run the test script

And we can see the data as it gets pushed to Keen along with a timestamp.

The full code is here: https://github.com/jiahuang/tessel-keen

Let us know what you do with Tessel + Keen!

See Keen’s blog on our integration here

Onboarding with the SAMR21 MCU on OSX & Ubuntu

10/15/2014 – Jia Huang

I started playing with an Atmel SAMR21 dev kit this weekend.

Atmel recently released the SAMR21 series. It combines everything good about the SAMD21 series (USB controller, low power cortex M0+ architecture) and the AT86RF233 (802.15.4 wireless radio). 802.15.4 is the standard for low power IoT devices using Zigbee and 6loWPAN (IPV6 for IoT, primarily used for mesh networks).

So instead of having to use two chips (one for the logic and one for the wireless communications), both silicon wafers are put on one package:

Besides the main SAMR21 chip, the dev board has on it:

  • Another chip that acts as the embedded debug chip. This allows us to load code and use gdb to debug hardware without having to buy an expensive JTAG debugger. Instead we can just plug the board into a USB port and start hacking.
  • Two antennas. One is a chip antenna, and the other is an external antenna. During development we can switch between the two for different applications.
  • The usual assortment of LEDs & buttons that comes with every dev board.

If you just want to get the code running, here’s the final github repo with build & deploy instructions on OSX & Ubuntu: https://github.com/jiahuang/samr21-xplained-pro.

Getting the example code

As usual, the default example code that the chip manufacturer gives is a bit convoluted. As of Oct 2014, the only example on the SAMR21 Xplained Pro page is this project for doing FCC tests, though Atmel has a few more examples from the actual ATSAMR21G18A page.

The FCC test example goes through some radio emissions so that the Federal Communications Commission (FCC) can certify that the radio isn’t emitting in frequencies it’s not supposed to. The FCC test example that Atmel gives isn’t a good choice for a starting program since I can’t easily tell if it’s working or not.

But I went ahead and used the FCC test program anyway because I thought that it might have some pin-specific configs for the Xplained board. Those pin configs would help me identify and get started with the LEDs & buttons, at the very least.

Making it do something I can see

My first goal was to get something working on the board. That way I could verify that I had a working programming & debugging environment for more complicated examples. Often I find that simple things like Makefiles aren’t configured properly in example code.

Blinky lights are the “Hello world” of hardware, so I modified the example FCC tester code to blink the LED on and off instead.

In order to blink the LED, I had to find the program’s entry point. I had hoped for a main.c file, but the folder structure for Atmel’s test program is:

fcc_test_r21/
  LwMesh_1_2_1/ 
    apps/
       Peer2Peer/ # main application
         astudio/ # AVR studio files
         linker/ #linker files used during compilation
         make/ #makefiles for the different boards
         config.h
         fcc_test_dut.c 
     doc/ #pdf files for explaining Atmel’s Light Weight Mesh protocol
     hal/ #the Hardware Abstraction layer. Useful because this application is for multiple boards
     phy/ #the physical layer. This is code specific to the radio.
     service/ # unused
     sys/ #system files, stuff like timers, clock config, and timers.
     tools/ # Also unused. 

I ended up grepping for a main(void) function, found that it’s in the counterintuitively named fcc_test_dut.c file, and put in some blinky code:


void delay_s(uint32_t time) {
    for (int i = 0; i  100*time; i++) {
        // this delay is in us 
        HAL_TimerDelay(10000);
    }
 }

 int main(void)
 {
  SYS_Init();
  HAL_UartInit(38400);
  HAL_LedInit();
  while (1)
  {
    HAL_LedOn(0);
    delay_s(1);
    HAL_LedOff(0);
    delay_s(1);
  }
}

Building the program

Atmel has nicely included all the makefiles for their various boards so that I can build using GCC.

>> ls LwMesh_1_2_1/apps/Peer2Peer/make
Debug
Makefile_Rcb128rfa1_ATmega128rfa1
Makefile_Rcb231_ATmega1281_Rf231
Makefile_Rcb256rfr2_ATmega256rfr2
Makefile_XplainedPro_ATSAMD20_Rf233
Makefile_XplainedPro_ATSAMR21
Makefile_XplainedPro_ATmega256rfr2
Makefile_Xplained_ATxmega128b1_Rf212
Makefile_Xplained_ATxmega128b1_Rf231
Makefile_ZigBit_ATmega1281_Rf230

The makefile requires the gcc-arm compiler.

This is the same compiler we use for Tessel, and during Tessel’s development we made a brew tap to install it on our machines. We can use the same brew tap to install the tools needed for compiling the SAMR21 code.

brew tap tessel/tools
brew install gcc-arm

On Ubuntu, get gcc-arm from Terry Guo’s PPA:

sudo add-apt-repository ppa:terry.guo/gcc-arm-embedded;
sudo apt-get update;
sudo apt-get install gcc-arm-none-eabi;

With these tools, I could now build the makefile: make -f Makefile_XplainedPro_ATSAMR21

Remember the counterintuitively named fcc_test_dut.c file? Turns out at one point the program files were properly named the application name (as Peer2Peer.c) before being changed to fcc_test_dut.c because the makefile still looks for it:.

> make -f Makefile_XplainedPro_ATSAMR21
...
arm-none-eabi-gcc: error: ../Peer2Peer.c: No such file or directory
arm-none-eabi-gcc: fatal error: no input files

The makefile also uses a gmkdir command that should just be a mkdir.

I ended up modifying the makefile to fix these and the build succeded.

> make -f Makefile_XplainedPro_ATSAMR21
size:
   text    data     bss     dec     hex filename
   4776       0    1888    6664    1a08 Debug/Peer2Peer.elf
   4776       0    1888    6664    1a08 (TOTALS)

Configuring OpenOCD

OpenOCD is an open source chip debugger. It allows me to do “on-chip” debugging, stuff like looking at registers, setting breakpoints, loading code, etc.

As of the current release (v0.8.0) OpenOCD does not have configurations for the SAMR21 chip, but it’s already in their master branch. In order to get it, rebuild from master. When it releases, v0.9.0 should have these configs by default.

On OSX:

brew install openocd --HEAD

On Ubuntu:

git clone https://github.com/ntfreak/openocd.git;
cd openocd;
./bootstrap;
./configure;
make;
sudo make install;

Now running openocd --version should show something like:

> openocd --version
Open On-Chip Debugger 0.9.0-dev-snapshot (2014-10-05-17:42)

OpenOCD uses .cfg files to set up configs for the type of board that it’s programming/debugging. The config file specifies things like how the chip is programmed, the interface used to do the programming, and the specifications of the MCU.

In the make folder I added a tools/samR21.cfg file to tell OpenOCD what to do:

#samR21.cfg
source [find interface/cmsis-dap.cfg]

# chip name
set CHIPNAME at91samr21g18

source [find target/at91samdXX.cfg]

$CHIPNAME.cpu configure -event gdb-attach {
   echo "halting"
   halt
}

This tells OpenOCD to use cmsis-dap as its programming interface, and that the chip being programmed is a samr21. Once gdb attaches, I halt the microcontroller to prevent any code from being run. Having a halt as a first step is useful for debugging later if I want to set up breakpoints at the start.

Loading up the program

By then I had:

  • the built binary (Peer2Peer.elf)
  • the OpenOCD config file (samR21.cfg)

Now I could run GDB on the dev kit with OpenOCD:

arm-none-eabi-gdb Debug/Peer2Peer.elf -ex 'target remote | openocd -c "gdb_port pipe;" -f tools/samR21.cfg'

Once GDB attached, I ran the load command to load up the elf into flash.

The load command loads up the .elf file I specified earlier in the arm-none-eabi-gdb command.

After this is loaded, the board is put in a halted state again so I could attach breakpoints if I wanted. In order to run the code, I had to issue the “continue” command (c for short).

And it blinks!

The modified example code is up on github.

Next up, putting two of these things together and getting them talking over 6loWPAN!

A Peek at Technical Machine’s Plans

10/14/2014– Updates

We’ve been talking to a lot of customers recently and brainstorming what our next most important projects are. As of today, much of this is now in R&D, and we want to keep you apprised.

Taking prototypes into production is very difficult, almost occult. We’re reinventing this process with a new project called Fractal. Our vision is a tool to create software-defined hardware– helping automate the prototyping process, reducing work duplication, and allowing for transparency through the whole design process. You can read more about our progress so far here. We’ll be publishing more on this soon, and reach out to us if you want to learn more.

Variations on next-generation Tessel research and development are in the works. Currently, we’re investigating a few smaller development targets: 6LoWpan, Wifi, BLE, and 3G connectivity. Expect to see more detailed product announcements within the next several months.

Also in the pipeline are new Tessel modules! Here are some we’ve been working on, based on user suggestions:

  • A proto-module: a solderable module to make it easy to add your own capabilities to Tessel. This will be accompanied by some documentation about how to make your own module.
  • A soil moisture sensing module.
  • A biosensing module.

What would you like to see next? Suggest modules here!

Beyond research and development, here’s how we’ve been spending our time:

  • Events, workshops, and hackathons
  • Re-released the GPS module into the store
  • Talking with potential international distributors
  • Runtime improvements
  • Hiring (interested?)
  • Compiler improvements
  • Soliciting user feedback
  • Working on our pitch deck
  • Support, as always
  • Wifi improvements
  • Got a 6LoWPAN chip running (R&D)
  • Got closer to merging in LuaJIT

We have a blog post up with various conferences and events that have a connection to Tessel– if you’re doing a Tessel-related talk or event, contact kelsey@technical.io and she’ll add you!

All the best,
Jon, Tim, Kelsey, Jia, Kevin, Ken, and Eric

Community Feedback

10/7/2014– Kelsey Breseman

In order to be successful, a startup needs to know its customers. The company needs to talk to users, try to understand their needs, and react accordingly.

I’ve talked to a lot of our customers, largely because I’ve been taking lead on support since we started shipping product. But most of the time, I’m talking to prospective customers, customers who have questions about the delivery of their packages, and the self-selecting few who reach out to the team.

Jon decided, sometime in September, to individually email 100 users and personally ask for their thoughts. I decided to follow up Jon’s effort with one of my own: I sent out over 500 individual requests for feedback to our early backers, asking them what they thought of Tessel so far, what they’d made, and what they might like to see in the future.

Requesting feedback

I sent the emails out one at a time, and adjusting the wording a bit where I could; if I’d had previous contact with a customer, I’d try to follow up on that interaction. I tried changing around my tone so I wouldn’t sound automated. Ultimately, I did everything I could think of to invite genuine conversation and useful feedback.

Around 16% of the people I emailed responded. Where useful and appropriate, I kept up the conversation. For some respondents, feedback requests funnelled into support, tracking down packages or finding examples and documentation. Others had very specific ideas for our company direction, and I discussed with them individual use cases and specific design concepts they needed.

Understanding responses

In order to keep track of the body of correspondence, I worked through the whole process in Zendesk. I tagged each email that I sent with one tag, and had Zendesk automatically add another if a customer responded. I could then add my own tags to try and break down response types.

With one set of tags, I broke user reaction into five mutually exclusive categories:

  • Has not yet used Tessel
  • Happy with Tessel
  • Has not yet received Tessel
  • Unhappy with Tessel
  • No opinion stated

I also added a set of descriptive tags for things I saw mentioned regularly:

  • Has run across bugs
  • Hasn’t used Tessel much
  • Called out first run experience as good
  • Has plans for big projects
  • Called out docs as good
  • Doesn’t know what to do next
  • Seems to have hardware experience
  • Developing a product
  • Using Tessel in education
  • Using Tessel in a workplace setting

My tagging wasn’t rigorous enough to merit statistical analysis, but it was useful to pull out these specific, common reactions. However, these lists are in order from most frequent to least.

I also pulled out quotes of specific feedback from emails, for example describing a use case or project, or details regarding a desired case or module. These, I collected in another sheet. After pulling out quotes, I categorized them thematically (e.g. “cases”, “product development”, etc.). If a specific piece of feedback spanned multiple categories, I broke it out onto multiple lines, to keep the feedback focused. This let me grow themes from feedback snippets in an organic way.

The feedback quotes were extremely useful. By filtering for different categories, it’s now easy to see several views on how people feel about our documentation, or about Tessel’s performance. Keeping the original wording and context also has great value; the way a user talks about a feature gives insight into their expertise in hardware and software.

Interestingly, the key themes were different in this set than the specific reactions I’d tagged:

  • Modules
  • Product
  • Ease of Use
  • Cases
  • Project
  • Compatibility and Integration
  • Performance
  • Documentation
  • Remote deploy
  • Features
  • Size
  • Powering Tessel
  • Cables
  • Tessel 2
  • Education

Of course, I must again stress that the feedback from these categories was specific and often conflicting. But even when reduced to mere categories, it highlights what’s on our users’ minds.

Taking it to the team

Feedback from users should be pervasive in a startup, especially one as small as we are. So I took this distilled version of the many feedback response emails, sent it to the team, and scheduled a discussion.

Everyone read through the feedback, then we opened the meeting with each person silently writing post-its of the things that stood out or surprised them. We then followed up by trying to identify the strongest user needs.

The two strongest areas that stood out were:

  • Users felt the need to make a “final” project: in the form of a case, a specific form factor, external power, etc. They felt that this need was not yet met.
  • Users were often unsure where to go next. Nearly all agreed that the first run experience was excellent, and were impressed by how quickly they could get a light blinking and a sensor collecting data. However, they weren’t sure how to take next steps– say, combining different modules, using the GPIO port, or taking ideas closer to productization.

There were also some less abstract and very clear wants:

  • More modules– though there were few repeats on requests for specific modules. (We have a module suggestion form here if you’d like to weigh in)
  • Cases– ideally with a power source built in
  • Remote deployment of code

We continued to discuss for an hour or two, putting our company plans and vision in the context of user feedback. Ultimately, I think we’re headed in the right direction, but it’s useful to factor user needs into the current design phase for the specifics of features and interface.

I’d also like to call out a bit of specific follow-up:

  • Tim is taking point on a docs page redesign. We’re hoping to make it more navigable and complete, and to add more tutorials in the vein of start.tessel.io.
  • Kelsey and Jon will be working together to put up a page offering support for those of you who want to take your prototype and turn it into a product. (But don’t wait for the page to go up; email team@technical.io if you’d like to discuss.)
  • Eric is working on more modules. He’s also working on a way to make hardware components of tessel more modular, such that we might be able to scale a PCB that’s more specific to a given use case.
  • Jia and Eric have been working with manufacturers to produce module extension cables. We’re making sure the quality is good before we mass produce and sell them.
  • Ken is working on bug fixes and compatibility issues.
  • Jia is working on Wifi bug fixes.
  • Kevin is working on Fractal, which should help streamline product development. It’s under development.
  • Kelsey will look into modular case solutions.

We really appreciate your feedback! If you’d like to add your opinion, I’m listening: kelsey@technical.io

Tessel Near You: Events and Conferences

Some of the events we’ll be at this season– come find us! We’ll have Tessels you can play with:

Events we won’t be at, but Tessels will:

  • PragueJS in the Czech Republic has a presentation by Ladislav lined up for October 23rd.
  • CampJS 10/31-11/3 in Australia looks like an amazing event. We wish we could go, but Glen has kindly agreed to run a workshop with quite a number of Tessels at the event.
  • Node One-Shot in Budapest (11/20) is running a Tessel Nodebots meetup hosted by the marvelous Matteo
  • MLH Hackathons USA have Tessels as part of their hardware library all fall.
  • CodeMash in Ohio in early January features a talk about Tessel by Adam.

Other ways to play with Tessels near you:

Want to host your own Tessel-related meetup or event? We’d like to help! Reach out to kelsey@technical.io

Also send me an email if you’re giving a Tessel talk or workshop and would like me to list you here!

The Unintended Cost of Shipping

9/30/2014– Jon McKay

Note: The opinions voiced in this retrospective are Jon’s. Other Technical Machine team members may or may not share the same thoughts.

The Low Point

Anyone who has started a company will inevitably tell you “it’s an emotional rollercoaster”. True to the maxim, Technical Machine hit its first real valley just after we shipped Tessel, a crowdfunded, JavaScript programmable microcontroller platform. The months of June and July at Technical Machine were the most difficult times I’ve experienced as both an engineer and as a CEO.

We had some legitimate problems: when we shipped we had nearly a third of customers contact us with fulfillment issues, we missed a critical GPS module hardware issue, and most of our software testing infrastructure was decrepit when we shipped rushed code, to name a few. But those issues aren’t difficult to solve. Those issues have been more or less fixed with a combination of engineering time and money.

But we had a scarier issue: our motivation to keep pushing was dwindling. Before shipping, we had this single, unifying, direction-full goal of getting this novel product out the door. But after Tessel was in the hands of users, all there was to do was feel burnt out from the 16 hours days, fix those difficult bugs that had been haunting us (and now our customers) for months, and try to track down lost shipments. Sure, there was the joy of hearing from our customers how much they loved our getting started experience but, between those snippets, it was hard to not feel demoralized. Surely, there had to be more to it than this?

During my one-on-one meetings with everyone on the team, they each independently explained that they felt that we were now directionless. Why wasn’t I providing more direction for the company? “We need to be working on the next thing by now”, they all said. What was the grand vision for Technical Machine?

The truth was, I didn’t have one yet. I felt that this was our time to learn as much as we could from our product being released into the wild. I thought that the future of our company depended on what our customers taught us about how they build hardware with Tessel.

It turns out, as is usually the case, I was partially right and mostly wrong.

The Cause

We started Technical Machine with the idea that developing hardware should be as easy for a web developer as deploying to a server. Whether or not it’s possible, it is an ambitious technical and social engineering challenge. These types of lofty goals attract the type of people that want to work on very hard, unsolved problems every single day. We were all comfortable working towards solving looming, unanswered technical questions. But after we shipped Tessel, there weren’t many architectural questions left. We had proven that JavaScript and Node on microcontrollers could make for a great prototyping experience; all that was left was (a lot) of polish.

Myself excluded, the entire team consisted of “research-heavy” engineers. Engineers who want to build entirely new things as quickly as possible and aren’t as interested in polish. Nobody on our team strongly identified as the type of engineer who likes to sit down and make a code base shine. The desire to fix bugs and maintain the product after it was released was not as high as developing a prototype to begin with.

To compound the problem, we had little testing infrastructure in place while developing Tessel, so our product was buggier than it could have been (an artifact of having just graduated from college, where testing code was rarely discussed or practiced).

In short, there were more bugs to fix and nobody interested in fixing them. Asking our engineers to continue preening over our existing code base after months of working on it wasn’t making anyone happy or productive.

At this point, we had two related but distinct issues: the company had little sense of direction, and what we did have to work on wasn’t making anyone excited to come in to work.

The Lessons

In an effort to give our company more direction, we started having long brainstorming sessions about what we wanted to build and where we wanted the company to go. We talked about what we had learned from customers using Tessel in the wild. We talked about what we were interested in as individuals.

Ultimately, we arrived at a couple of key points:

  • Prototyping tools and manufacturing tools have traditionally been disjointed. There has always been a leap from the device that proves out the viability of an idea and the device that eventually gets to market. Creating a sustainable funnel for customers to progress from prototype to a product at scale is a business opportunity worth pursuing.
  • As a company, we’d like to head further away from the toy/hobbyist market and closer to being a trusted provider of embedded hardware tools – not just for web developers but eventually electrical engineers and seasoned product developers as well.
  • We’re not interested in being another hardware platform that succumbs to building the “IoT cloud” to rule them all. We feel that, while cloud platforms have their intricacies, the technical and social engineering challenges are not appealing.
  • Tessel’s getting started experience is top-notch. Integrating npm with the hardware modules provides for (in our opinion) the fastest prototyping platform available. Users could go from unboxing with no hardware experience to serving pictures from the camera module in a web app in under 5 minutes. It’s important to us to continue enabling that type of interaction.
  • While we do believe Tessel is the best way to prove out an idea’s viability, it leaves the user further from a technical prototype than they could be if they used other hardware platforms like Arduino or Launchpad. Working in JavaScript and Node land doesn’t scale well in hardware because of the unavoidable consequence of working with components that are overpowered.

Focusing our attention on Scalability

We reframed the problem as “How can developers leverage the speed of development of JavaScript and Node while still making the transition to a technical prototype as simple as possible?”. In order to get an idea of the areas of opportunity in the space, we drew up a checklist of all the task items that have to be complete before a developer is ready to ship a product (the topic of an upcoming blog post) to get a better idea of where we can add value.

Based on what we’ve heard from users of Tessel, one of the most important and opaque transition points from the “idea viability” stage to the “technical prototype” stage is picking out the actual components (integrated circuits, sensors, etc.) that are to be used in the final design.

We held quite a few brainstorming sessions as a whole team but didn’t make much progress until Kevin, Eric, and I were casually discussing the hardware development process.

Kevin, our lead firmware engineer and previously a co-founder of a hardware tools company called Nonolith Labs, started explaining an idea he had for how hardware development should be done. I’m not sure how much of it was formed before our brainstorming meeting, but it came out in a fairly cohesive stream. Kevin’s idea was largely focused on software defining hardware interfaces in such a way that it becomes possible to automatically generate more components of a hardware device.

Imagine embedded hardware development as being composed of six levels of abstraction:

  1. Data Flow: A description of how data flows between different inputs (sensors) and output (network) blocks, as well as code blocks (JS, Rust, C, etc.) of various languages.

  2. Firmware: A verbose and precise description of machine-readable code that dictates how the hardware works at the lowest level to allow that flow of information. Boilerplate configuration code, for example, setting up registers to communicate with external memory, can be autogenerated if parts are known.

  3. Part Selection: The actual integrated sensors and integrated circuits that comprise the system. There is a dependency between the code that is generated and the microcontroller that is used.

  4. Schematic: How the pins should be connected together. If parts are known, then this becomes an datasheet scraping problem.

  5. PCB: How components are physically laid out on a circuit board. If a schematic is known and context of each signal is known (is this power, ground, a high speed usb signal, RF signal, etc.), then a PCB becomes easier to automatically route. Auto routing has traditionally been considered a bad practice and nobody has done it well yet.

  6. Manufacturing: Who actually manufactures the PCB and/or assembles the parts.

In theory, the hardware development process could be described from any of the above levels of abstraction (besides manufacturing) and a circuit board could be generated as precisely as it was described. Each level of the process should be optimizable so that a seasoned firmware engineer could tweak the firmware or an electrical engineer could add necessary passive components and modify the size of any sensitive traces.

The idea of “software defined hardware” resonated with the team as a solution space worth attacking. An accessible but powerful hardware development tool that would take years of development work aligned very well with the personal interests of everyone on the team. The question turned from “what are we building next?” to “how do we approach such a giant, complicated system?” Once we we were able to frame the problem around solid technology choices that could accomplish the goal of “software defined hardware”.

As a first step towards that goal, we’d like to enable a user to program a single application in both low-level and high-level languages. This means developers can prototype an idea quickly in JavaScript, and if it proves viable, start breaking the component parts into C or Rust. It’s a much easier path to a technical prototype than starting from scratch when moving to a technical prototype.

Tessel is just the first development board which would be the target of this new hardware development tool. Over time, we hope more and more microcontroller targets will be contributed so that our open source tool can extend past just the Tessel ecosystem. We’ll be releasing more information about this new tool as we start speccing it out.

Maintaining Tessel

As for maintaining Tessel’s architecture, we’ve made a huge amount of progress. By having each person in the company split their time between working towards these new engineering goals and working on maintaining the released Tessel platform, we’ve reinvigorated our collective enthusiasm for our vision. We’ve also started hiring people who would be well-suited for support positions. In that vein, we’ve hired Ken, who is one of the most patient and detail-oriented people I know, to work on improving Tessel’s JS and Node compatibility. We’ve also hired an external contractor to work on some of the finer points of JS compatibility like the unicode implementation.

Unanswered Questions

We’re really excited about our new direction but we still have a few questions to answer:

  • Who are our customers? Tessel’s customers are usually web developers interested in hardware. But now that we’re starting to prototype tools for the wider user group of product developers, how do we market our product and who do we approach about user research? We also need to gather more information about how much of our current customer base is interested building scalable devices and how many are building one-off solutions.
  • Is this user group big enough and growing fast enough to be sustainable? Tessel itself hasn’t yet answered the question of how big the group of hardware-interested web-developers really is and it’s unlikely that traditional product developers will use our system until it’s more proven.
  • How do we go about automating the “human” parts of hardware development? The deals with manufacturers and working with suppliers, smoothing out issues with contract manufacturers, and debugging issues with field application engineers all currently require face to face interactions.

Going Forward

We’re continuing to dish out more Node and JavaScript compatibility for Tessel and make WiFi more robust. We’re pushing forward with enabling more programming languages on Tessel, enabling more microcontrollers and microprocessors to take advantage our runtime, and looking into more diverse wireless hardware. We’ve released the Project Portal to share Tessel-based projects and we’re working on remote code deployment. More and more Node Modules are starting to work out of the box, like Twilio and MQTT.

We’ve still got a lot of work to do before we start making the hardware development experience we’ve been dreaming up. In the past year we’ve learned a ton about what it means to build a company but we need to start talking to users to get these new questions answered. If you have experience or suggestions you’d like to share, please email me at jon@technical.io. I’d love to hear it.

We also have open, full-time positions that we’re hiring for, including web developers, HR/recruiting, business development, and firmware engineers. If you’d like to contribute to our vision of reimagining hardware development, don’t hesitate to reach out!

MQTT on Tessel

9/24/2014– Jon McKay

Using MQTT on Tessel

MQTT is a lightweight publish/subscribe protocol designed for machine to machine communication. The architecture features one central server that manages the subscriptions and publications from each of its numerous clients. Clients can publish data without having to be aware of who is subscribed (much like Node’s EventEmitter class).

source: Eurotech

MQTT is also designed to require minimum protocol overhead for each packet in order to preserve bandwidth for resource-constrained embedded devices. It’s a really simple framework for managing mesh networks of TCP-enabled devices.

Tessel-MQTT Compatibility Backstory

As far as I could tell, there is only one MQTT implementation in Node (surprising, right?!) and it’s really well maintained. Up until a few weeks ago, the library couldn’t run on Tessel due to a couple of Node and JS incompatibility issues. The biggest problem was the use of Function constructors, used primarily for speed improvements, which isn’t supported on Tessel yet.

In JavaScript, the Function constructor accepts a string of JavaScript code which it processes into an actual function:

var f = new Function(foo, bar, “console.log(‘the arguments are’, foo, bar)”);
f(‘a trivial’, ‘example’); // prints ‘the arguments are a trivial example'

It’s often used as a faster way to template a function, replacing Function.prototype.bind which runs abnormally slow on V8.

Tessel’s runtime translates JavaScript to Lua on a host PC before being pushed to Tessel and run on a Lua Virtual Machine. We’ll need to push compilation functionality over to Tessel before Function constructors (or eval) can work on the device. Tim has made stready progress on a compiler written in C (as opposed to JavaScript) that will reside on Tessel itself and compile JavaScript to LuaJIT bytecode. But it isn’t quite ready yet, so we looked for another way around the issue.

Matteo Collina, one of the primary maintainers of the MQTT.js library, and I started a discussion about the MQTT library’s compatibility with Tessel. He was kind enough to accept a pull request that replaced the Function constructors so that we wouldn’t have to wait for the C-based compiler to be complete to use MQTT on Tessel. I just had to fix one more issue with Buffer parsing and the library worked without a hitch on Tessel!

Code Example

Tessel can act as either an MQTT server or a client, and the client code is impressively simple in practice. In this code snippet, I publish the current temperature to an MQTT server every five seconds:

var mqtt = require('mqtt')
  , host = '192.168.8.102'
  , port = 1883
  , client = mqtt.createClient(port, host, {keepalive: 10000})
  , tessel = require('tessel')
  , climate = require('climate-si7020').use(tessel.port['A']);

climate.on('ready', function ready() {
  console.log('climate ready');
  setInterval(function() {
    climate.readTemperature(function(err, temperature) {
      if (!err) {
       // You can only publish strings
        client.publish('temperature', temperature.toString());
      }
    });
  }, 5000);
});

You can find the entire example on this Github Gist.

If you have a project that requires the use of multiple data gathering clients interacting through a single server, consider trying out MQTT because it’s one of the simplest protocols for M2M communications.

-Jon

How-to: Adding Buttons to Tessel

9/24/2014– Kelsey Breseman

A number of users have requested a button module on Tessel. We welcome this and other module suggestions here, but in the meanwhile, I thought you’d find a tutorial on adding your own buttons (of any size and shape) useful.

I’ve put this up on the Projects Page, so I encourage you to also check it out, access the repo, and comment there!

But as long as I’m going into the details of how buttons work, I thought you all might appreciate it on the blog.

Quick start: I just want a button.

Your button should have two wires sticking out of it. Plug in one side to ground, and the other to pin G3.

Install:

npm install tessel-gpio-button

Use:

var tessel = require('tessel');
var buttonLib = require('tessel-gpio-button');
var myButton = buttonLib.use(tessel.port['GPIO'].pin['G3']);

var i = 0;

myButton.on('ready', function () {
  myButton.on('press', function () {
    i++;
    console.log('Press', i);
  });
});

Congratulations, you now have a button!

How it works, and why

Why add a button over the GPIO?

Buttons are a nice, easy way to make your project interactive. Tessel comes with API access to the Config button on the board. For many use cases, this is enough. But perhaps you want more buttons, or buttons with a certain look or feel. That’s where this tutorial will come in handy.

What is a button, in terms of circuits?

Electrically, a button is nothing more than a switch. One wire goes into the button; one wire comes out. When the button is pressed, the wires are connected. When not pressed, the wires are not connected.

Making a button talk to Tessel

Tessel communicates over 3.3V. That means that its pins operate between 0V and 3.3V. For a digital pin, 3.3V evaluates to “high” or 1 (truthy), and 0V evaluates to “low” or 0 (falsy).

Tessel has six digital pins along the GPIO bank, marked G1-G6. Each of these pins is pulled high (3.3V) by default. In order to change the state of these pins from high to low, all you have to do is connect a digital pin to ground (GND).

If you have a wire, you can try it out– plug in a wire (ideally black, for ground) in to the GND pin on Tessel’s GPIO bank. While running the code below, try sticking the other end of the wire into G3:

// tutorial/polling-read.js
// Read Tessel's GPIO pin G3 every 100ms

var tessel = require('tessel');
var myPin = tessel.port['GPIO'].pin['G3'];

setInterval(function readPin () {
  console.log(myPin.read());
}, 100);

You should see a stream of ones while the wire is not plugged in, and a stream of zeroes when it is plugged in.

Okay, now let’s try it with a button. It’s basically the same thing. Unplug your Tessel (it’s bad practice to mess around with wires while your Tessel is powered). Your button should have two wires sticking out of it. One of them should plug into GND; the other into pin G3.

Run the same code, and try pressing the button. You should see zeroes when the button is pressed, and ones when the button is not pressed.

Button events

Tessel has events for its pins. It fires an event each for rise, fall, and change.

Since the signal falls to low when the button is pressed, and rises to high when the button is released, it seems like you should be able to just use pin.on(fall, function () {}). Let’s try it and see what happens:

// tutorial/simple-event.js
// Logs a message each time the pin falls

var tessel = require('tessel');
var button = tessel.port['GPIO'].pin['G3'];

var i = 0

button.on('fall', function buttonPress () {
  i++;
  console.log('You pressed the button!', i);
});

If you have a really nice button, this might just work. However, if you have a cheap button like mine, the fall event will be emitted more than once per button press. This is because you are dealing with a mechanical system, and the electrical contact is actually bouncing a little bit on contact and messing up the signal. You can read about this phenomenon here.

In order to correct this problem, we need to do some software debouncing.

Debouncing can be a very complicated problem if you need the ability to read the button several times a second (read a few approaches here). However, for most applications, you can simply reduce the rate at which your events can fire.

Let’s try adding a delay timer to the event:

// tutorial/debounced-event.js
// Logs a message at button presses that are sufficiently spaced

var tessel = require('tessel');
var button = tessel.port['GPIO'].pin['G3'];

var delay = 500; // Let's try every 500ms
var ready = true;

var i = 0

button.on('fall', function () {
  if(ready) {
    buttonPress();
  }
});

function buttonPress () {
  i++;
  console.log('You pressed the button!', i);
  
  // Set a delay timer
  ready = false;
  setTimeout(function () {
    ready = true;
  }, delay);
}

500ms worked well for my button, but feel free to adjust the delay and see how long it takes for your button to stop bouncing.

Wrapping the events

For the sake of consistency, I’ve set up index.js of this folder the same way we set up every module, to emit an event on press. press and release are individually easy, but harder to have both due to our simple debouncing method. I’ve left that as an exercise for the reader (PRs welcome).

Here’s some example code requiring index (or just npm install tessel-gpio-button):

// examples/button.js
// Count button presses

var tessel = require('tessel');
var buttonLib = require('tessel-gpio-button');
var myButton = buttonLib.use(tessel.port['GPIO'].pin['G3']);

var i = 0;

myButton.on('ready', function () {
  myButton.on('press', function () {
    i++;
    console.log('Press', i);
  });
});

Multiple buttons

Say you want more than one button. Maybe you’re making a game controller, or a musical instrument or something. So you have several buttons to connect.

All you have to do is connect one side of each to ground, and the other side to a different digital pin.

Then make different instances for each button. Like this:

// examples/two-buttons.js
// Log button presses from two different buttons

var tessel = require('tessel');
var buttonLib = require('tessel-gpio-button');

var button1 = buttonLib.use(tessel.port['GPIO'].pin['G3']);
var button2 = buttonLib.use(tessel.port['GPIO'].pin['G2']);

button1.on('press', function () {
  console.log('Pressing button 1.');
});

button2.on('press', function () {
  console.log('Pressing button 2.');
});

Pressing the different buttons will give you different messages.

Note that I used a breadboard to connect several buttons to the same ground. If you’re interested/want to know more about breadboards, this is a really good place to start.

That’s all! Enjoy.

I’ll keep this tutorial up to date on its projects page

How Tessel Works: The Basics

9/23/2014– Kelsey Breseman

Ever since Jon pushed out the Contribution Guide, I’ve been meaning to distill some of it into a more digestible format. It’s the basics of how Tessel works, hardware and software.

This is an overview, not a complete picture– I recommend that you check out the docs and the full contribution guide if your interest is piqued.

Rolls up sleeves.

Okay, here’s how it works:

Software

Let’s dig into the software first. This software is designed to work on Tessel’s specific hardware, but we’re working on making it portable to other platforms as well.

The basic interaction with Tessel is this:

  1. In the command line, you enter tessel run <file.js>.
  2. From here, the CLI bundles all of the files except those blacklisted in the hardware section of your package.json. If there is no package.json or node_modules folder, Tessel will bundle only the specified file.
  3. We then pass all the files found through Colony, our JS to Lua compiler.The CLI creates a tarball and sends it off to Tessel’s firmware via USB.
  4. The firmware receives the tarball, puts it in RAM*, and loads the script into the Lua VM in Tessel runtime. *or Flash, if you use tessel push instead of tessel run. We’ll go into that in the hardware section.
  5. The runtime environment takes over and defines all the global functions and node modules that the Lua code called into.
  6. When hardware-specific tasks are called by the Lua code, runtime makes calls into the appropriate C functions.
  7. When the process completes, runtime is shut down and the script is freed from memory.
  8. After the initial script runs and sets up event callbacks, the runtime waits for events. When an event occurs, the processor wakes up, runs the callback, and then goes back to sleep.
  9. When no event sources are waiting for events, or when you call process.exit(), runtime is shut down.

To separate this out by components instead of chronology, there are four basic parts of Tessel’s software:

CLI: Command line interface for interacting with Tessel over USB (repo: https://github.com/tessel/cli)

Colony: JavaScript to Lua compiler (bundle installed with the CLI) (repo: https://github.com/tessel/colony-compiler)

Runtime: Lua VM running the interpreted code. The runtime layer also includes the compatibility layer for core JS functions (such as String and Number) and core Node function (such as fs and buffers). (repo: https://github.com/tessel/runtime)

Firmware: C code interfacing the Lua runtime with all of the hardware components (Wifi, RAM, Flash, SPI/UART/I2C busses). The firmware layer also handles interrupts. (repo: https://github.com/tessel/firmware)

All right, that’s the software basics. There are more details overall and for each subsystem on our contribution guide (https://github.com/tessel/contribution-guide), so for the sake of brevity I’ll let you investigate on your own. Let’s move on to Tessel’s hardware.

Hardware

At its core, Tessel runs a 180MHz ARM Cortex-M3 LPC1830. The M3 was chosen as the smallest available chip with the capacity to support external Flash and RAM. Tessel’s Wifi chip is the TI CC3000. There was a lot of excitement about this chip at the time of prototyping, and it was chosen as a good balance between cheap and easy to integrate into a system.

Since Tessel was designed to be intuitive and familiar to web programmers, we needed a bit more memory to play around with than, say, an Arduino. So we have 32 Megabytes each of Flash and SDRAM. (For comparison, Arduino Uno has 32 Kilobytes of Flash, and 2 Kilobytes of SRAM.)

Tessel’s firmware and runtime (compiled into the firmware) are stored in Flash memory. Current firmware takes up about 1.3MB, but the boot and firmware partitions reserve 2MB of memory just in case– leaving you 30MB to use for your own files.

Tessel’s CLI gives you the option to either push or run any given JS file. When you run, code is temporarily stored in RAM and is not persistent across hardware resets; if Tessel loses power, you will need to re-run the code. This is designed for quickly testing code in development.

If you push, the files are saved to Flash memory and run every time Tessel boots up– so if you want to plug Tessel into a battery, you’ll need to tessel push, disconnect, and plug the battery in. This is designed for deployment. You can read more about push vs. run here.

The primary interaction for Tessel takes place through the four module ports. Each can be used to communicate with devices using SPI, I2C, and/or three digital GPIO pins. Ports A, B, and D also include UART, another communication interface.

Module ports are designed for hardware modularity; currently we have fourteen single-function modules (BLE, servo, accelerometer, etc.) that you can swap into (almost) any of these ports. Drivers and APIs are npm installed with the package name written on the silk screen on the module. These modules are also all OSS/OSHW. You can find third-party design guidelines and module design philosophy here.

There’s also a GPIO bank on the board designed to make it easy to interface with other hardware, or anything not available in module form. All of Tessel’s input and output signaling is 3.3V maximum voltage.

You can power Tessel through its microUSB port (5V USB sources only), or through a pair of solderable pins on the board. Please read the guide on powering Tessel before you use these, though.

You can find links to all of Tessel’s hardware designs (schematics and layouts for Tessel and all modules) here: https://github.com/tessel/hardware

Whew! Now that you understand everything about Tessel, you’re all set to contribute to this open source project!

See you on the repos,
Kelsey