Portail Notes

Notes on using sub-Ghz radios and a laser to control my home gate from the internet.

Main components are a Lantronix XPort Pro, two Wizzimote nodes, a Banner L-GAGE LT3 laser, PolymerJS, Riot-OS and the C, Ruby, and Javascript programming languages.

Background

Illustration of the gate communication problem

We just installed an automatic gate at home. It is far from the house and we didn’t install an intercom. Those who live here can get in using a remote. And if you are a guest, there is a code you can dial if you know it.

However, for security reasons, the code dial is disabled at night. Now when a guest is trying to enter or leave during nighttime, we have to walk out to the gate and let them through with our remotes, which is annoying.

As a solution, I tasked myself to link the gate to the internet for remote control. We will be able to open it from anywhere and friends and family will be able to let themselves in.

Disclaimer

These notes are from a personal educational project exploring electronics. Though I invested some effort into formatting and clarity, my note taking was sporadic.

The main goal of this endeavor was to learn electronics. I prioritized design decisions to maximize my learning experience, technical efficiency came in second. As a result, some design decisions of this project may be less than ideal from a technical point of view.

This project is not yet complete, these notes are a work in progress.

Code

System Design

Visitors interact with a web app which communicates with an endpoint located at my house acting as gateway. This gateway in turn communicates with a module located near the gate interfacing with it.

This overview of the request flow gives a wide angle view:

Illustration of the gate communication problem

Web Stack

Javascript/HTML front-end with a Ruby back-end.

Illustration of the web tier interactions

The web server and the browser client are clearly separated. The client is a standalone browser app that can run server-less given fake data. The server is headless and only serves API requests and a websocket. The websocket is used to keep the client informed about the state of the gate and for the client to send gate open and close commands.

Given the low scale, I left the API, the websocket endpoint and gate connection all in a single operating system process.

Client: Browser app using Polymer

Screencast of logging in, opening, closing the gate and logging out

Rationale: I wanted to experiment with web components.

Using web components was fun. Scope isolation and encapsulation simplifies the codebase. Polymer encourages declarative code, this was great, it helps decouples the HTML from CSS. Polymer is well written. I initially wrote an MVP using AngularJS. I’ve written a few small apps using Angular and though I liked it. Using Polymer I found myself fighting a lot less with the system. Code that I wrote would more consistently behave as intended. I ended up spending alot less time having to read documentation to understand abstract or unique concepts. Also, and this is quite revolutionary, I did not have to spend anytime in the bowels of Polymer … This is a important point for my productivity and sanity.

Polymer still has some edges to round but it is a solid base and I am pleased to read that they are working on these edges.

Backend: Ruby

I should have just used Rails. But I was curious to understand exactly what are the required parts of a web framework, so I wrote a custom stack. I am please with the end result, it isn’t too complicated and it was educative.

The database is SQLite.

Why Ruby? I’m used to it, it’s fun. Initially, I started using NodeJS as I thought some companies would appriciate that on my resume. I moved forward with not just one, but a few different NodeJS web frameworks. However I backed away from NodeJS frameworks after getting sick of having to implement my own plumbing too often. Javascript is fun in the browser but I prefer Ruby’s syntax and ecosystem on the server by far.

Hardware

There are two hardware modules. An internet gateway located at my house, where I have an internet connection. It relays communications between the internet and the module. The second piece module is located near the gate and interfaces with it.

For both devices I used an embedded OS for firmware. I initially wrote much bare metal code, but I quickly grew curious of what using an embedded OS looks like. I used Riot-OS on both. I had to fork it to write support for my wizzimote modules and tune resources requirements, the fork is here.

Home: Internet Gateway

Illustration of the gate communication problem

I’m using a Lantronix XPort Pro connected to a Wizzimote node.

When I chose this design I had little knowledge of electronics. With the confidence I now have, I would do it differently.

Why UDP? Why not. CoAP is often used with UDP so I started with it. CoAP provides message delivery guarantees, which is probably all I would need from TCP.

Why UART? The XPort is designed to interface over UART. This is the channel over which network packets are relayed to and from to the CC430.

The system only has two wireless nodes, so there was no opportunity to have fun and research IoT network routing. Riot-OS has many capabilities in that field. To keep things simple I am using the hardware radio packet facility provided by the CC430 chip.

Why wizzimotes? Why Riot-OS?

Wizzimotes are modules intended to explore the DASH7 IoT network stack. They are low power and come with a an SDK. The SDK’s core is a lightweight OS layer comprised of a HAL, process management (using pthreads) and DASH7 radio lib. I initially started developing using these tools and exploring the SDK was very educative; it is lightweight, well written and compact. Then I came accross Riot-OS.

I decided to switch over to Riot:

  • Riot is open source and open to the public (Wizzlab’s code wasn’t). That means more contributors, and codebase likely more representative of industry coding standards.
  • Riot was in line with my hardware: it already had support for the wizzimote’s CC430 MCU and its 2Kb of RAM
  • Riot was in line with my project goal. This is its current slogan: “The friendly Operating System for the Internet of Things”
  • Riot was great opportunity to learn more about emebeded development. My main project goal was educational, I got to learn tons by digging into Riot.

In hindsight I wish I had selected modules more powerful than wizzimotes. Though they were fun, their resources are very limited and designed for ultra-low power applications, whereas I’m plugging in to the power grid.

XPort

The XPort runs µClinux. Lantronix provides an SDK with sample applications. One of the applications is a UART to TCP/UDP bridge. I based my gateway off this app and made modifications. I will have to extract a patch from this work and commit it to source control. Most of my development of this device happened through a vagrant virtual machine.

video note

Gate: Control and Observation

Illustration of the gate communication problem

Located near the gate is a second Wizzimote. This one holds alot more code than its gateway sibling.

Its responsibilities include:

Both a hardware RC filter and an exponentially weighed moving average are used to sooth gate position readings from the laser. The module incorportates domain knowledge on how the gate behaves in order to provide stable status responses when the laser is temporarely obstructed. During the intial one-time setup phase, the gate’s average speed is measured allowing the module to detect laser obstruction and estimate gate position.

Communication with the module is done through the CoAP protocol. Data is represented using CBOR. In the final project phases, either message signing or encryption will be added.

CoAP GET /gate (observeable)

requests to the gate status response includes a code s representing the gate state and the position p of the gate represented as a number between 0 and 100.

{
  s: 2,  // state id
  p: 13  // position 0-100
}
CoAP PUT /gate

used to change the gate’s state to open or close it. Parameter s represents the status code. Accepteable values for s are 1 (open) and 4 (closed).

{
  s: 4 // state id 2 or 4
}
State representations
code rep string rep note
0 unknown state unreadeable, laser offline?
1 open  
2 opening  
3 open_partly rare case
4 closed  
5 closing  

Testing: the mock gate

I built a fake gate for testing purposes.

I went travelling before finishing this project. I continued to development from abroad, but being away meant I didn’t have access to the gate any longer. I had to find a way to test my prototype. Sensing yet another opportunity to learn electronics, I decided to build a mock gate in my room.

I gathered the following parts:

Notes on learning electronics

PCB

useful:

Coating

Assembly

Access to a workshop helped, pictures are the best record, see below.

[WIP][spin this] Notes on learning firmware development

http://homepages.inf.ed.ac.uk/dts/pm/Papers/nasa-c-style.pdf

[WIP][spin this] Notes on using the xport

[WIP][spin this] Notes on how Riot OS works

@@@ GET BACK TO THIS:

Photos

There was some photographic record, check it out