Jan Rychter: blog (electronics, programming, technology)

System perspective: channels do not necessarily decouple


Clojure's core.async channels provide a great metaphor for joining components in a system. But I noticed there is a misconception floating around: that channels fully decouple system components, so that components do not need to know anything about one another. As a result, it's easy to go overboard with core.async. I've seen people overuse channels, putting them everywhere, even when a cross-namespace function call would do just fine.

What channels do provide is asynchronous processing. The "degree" of asynchronicity can be controlled — we may choose to always block the caller until someone reads from a channel (thus providing a rendezvous point), or we may choose to introduce asynchronicity, letting the caller proceed without worrying about when the value gets processed.

Since you can put anything onto a channel, it's easy to forget that this "anything" is part of the protocol. Just as functions have an argument signature, channels have value signatures, or protocols: the common data format that all parties agree on.

It isn't true that channels fully decouple components, so that "they don't need to know anything about one another". You still need a wire protocol, just as with directly calling functions in another component. Channels do decouple things in time: you are not forced to a synchronous execution model and can control when things are being processed. But they are not a magic component decoupling wand, so don't use them when a simple synchronous function call will do.

Hard Drive Encryption, revisited


Hard Drive Encryption, revisited

Several years ago I made a comment on Hacker News (full discussion) about full-disk encryption performed by the hard drives themselves. Basically, the idea is that you give your hard drive a password/key and hope that it transparently encrypts your data before it hits the platters (or flash memory for SSDs).

I wrote:

That kind of encryption is useless, because I can't audit it. How do I know my data really IS encrypted and the key isn't just stored on the drive itself?

Now, Hacker News has a number of well-known people, who have a following. Opposing their opinions is not popular. Notice how my to-the-point response to tptacek gets downvoted.

Anyway — I feel somewhat vindicated by the recent revelations of hard drive firmware hacking by the NSA. I was right: you can’t and shouldn’t trust your hard drives. If you care about encryption at all, your drives should see the data already encrypted.

I2C driver for Freescale Kinetis microcontrollers


I wrote a tiny driver that allows you to access I2C (IIC, I²C, or I squared C) on Freescale Kinetis microcontrollers. It works asynchronously (interrupt-driven), supports repeated start (restart) and does not depend on any large software framework.

The code is on Github and the driver has its own page, too, with a README.

Even though it isn't fully-featured or well tested, I have a good reason for publishing the code. I wrote this and then had to put my Kinetis-related projects on hold. After several months I forgot having written this driver and started searching online for one… only to finally find it using Spotlight, on my hard drive. This is what happens if you work on too many projects.

To avoid this happening in the future, I now intend to publish most things I write as soon as they are reasonably complete, so that I can find them online when I need them.

Fablitics Launch


We have just launched Fablitics — our friendly business intelligence and E-commerce analytics solution.

The driving idea behind Fablitics is that only meaningful numbers and graphs should be shown in business intelligence software. We tried to understand which numbers are important and can help decision making, and which bring little value and only confuse.

Early on we noticed that many analytics-type products show lots of data, but most of that data isn’t related to actual business.

Let’s take an example: page views and visits in an online store. They are related to the business, but very remotely. Estimating performance based on page-views could be compared to estimating the performance of a supermarket by the number of cars in the parking lot. Sure, that number is correlated with supermarket sales. Yes, probably the more cars there are in the lot, the better. Yes, the days when there is more traffic will likely bring in more revenue. But the relationship is too weak to allow meaningful conclusions.

So, when designing Fablitics, we decided to focus on fundamental business concepts: customers, products, sales. Instead of showing the number of page views, we count customers that visit the store. We determine which customers enter the store for the first time, and which are returning. We know how much each customer purchased, and we also know how the customer was referred to us, so we can put a monetary revenue value on advertisement campaigns.

All this is based on a rethinking of what analytics software should do. In our opinion, as long as the purpose is to improve the business, it should be strongly rooted in business concepts.

If you run an online store, you can sign up now for a free trial http://fablitics.com/ — no credit card required.

Lsquaredc: accessing I²C in Linux


It might seem that writing I2C libraries is my favorite activity, but it really isn't. This library is not something I expected to write, but since I had to, I'm releasing it in the hope that it will save others time and frustration.

Lsquaredc is a tiny Linux library that allows you to access I2C (IIC, I²C, or I squared C) from userspace without causing excessive pain and suffering.

When I tried accessing I2C on my BeagleBone Black, I was sure it would be obvious. Well, I was wrong. It turned out that the usual way is to read/write data using read() and write() calls, which doesn't support restarts. And if one needs repeated start, there is an ioctl with an entirely different and difficult to use interface.

For more information, see the Lsquaredc page and its Github repository.

Designing a High Voltage Power Supply for Nixie Tube Projects


PCB layout for the switch-mode HV PSU
PCB layout for the switch-mode HV PSU

I've posted a page describing the design of a HV PSU (High-Voltage Power Supply) that generates up to 220V from a 12V input. In addition to that, it also provides 2*Vout (so, up to 440V, for dekatrons), and two outputs for powering digital logic: 5V and 3.3V. The primary HV boost circuit reaches 88% efficiency when going from 12V to 185V at 55mA, with a 3% output ripple.

The version I'm posting online is not perfect, but works quite well in a number of my projects. I decided I'd rather publish it as it is now rather than keep it locked forever.

It is published as Open-Source Hardware, to be used however one likes. All source design files are provided. It's my way of paying back: I learned a lot from looking at other designs and by asking questions, so now it's time to give back.

Dollhouse built from laser-cut plywood


I wanted a dollhouse for my daughter. But, as it often happens, I couldn't find anything I liked. I wanted it to be tall, with multiple floors connected with stairs. I wanted every room easily accessible, with few external walls. And I also wanted it built in a way that would allow four kids to comfortably play together.

I ended up designing my own dollhouse in a CAD program, then laser-cutting it in 5mm plywood. The structure is held together by mortise-tenon joints, with just a little glue so that it doesn't fall apart when picked up. It's amazing how precisely you can cut plywood with a laser.

This is my second design in laser-cut plywood (the first was an Art-Deco inspired Nixie clock) and I feel I've learned a lot. My main discoveries so far:

  • Plywood will warp. Not as much as wood, but expect large surfaces to eventually warp. You can either ignore it (it might not matter), or design additional support structures.
  • Laser cutter is incredibly precise, but your plywood often isn't. You can't rely on the "official" thickness. I found 5mm plywood to be anything from 4.75mm to 5.25mm (and that is supposedly pretty good). Measure your particular batch and design your structure for the measured thickness. It really helps to use a parametric modelling CAD program, so that you can change the thickness anytime.
  • It is easy to design a structure, but more difficult to design a structure that you can assemble. I discovered the hard way that some designs simply can't be assembled (parts block one another and there is no order of putting things together that will allow you to complete the structure).
  • Your mortise-tenon joints will fit even if you make both the hole (mortise) and the peg (tenon) the same size. Cutting laser thickness provides enough room. Still, unless you have perfect quality plywood, it is better to offset your hole edges and make holes slightly larger.

I'm quite happy with the results so far and will certainly use this method for other projects.

I2C using USI on the MSP430


I've released a tiny library that implements I2C master functionality for MSP430 chips that have the USI module (MSP430G2412 or MSP430G2452 are ones that I use often).

The code is on GitHub, it is MIT-licensed, so you can do whatever you want with it.

From the README:


  • Small.
  • Works.
  • Reads and writes.
  • Implements repeated start.
  • Uses the Bus Pirate convention.


I wrote this out of frustration. There is lots of code floating around, most of which I didn't like. TI supplies examples which seem to have been written by an intern and never looked at again. The examples are overly complex, unusable in practical applications, ugly and badly formatted, and sometimes even incorrect.

The MSP430G2xx2 devices are tiny and inexpensive and could be used in many application requiring I2C, but many people avoid them because it is so annoyingly difficult to use I2C with the USI module.

This code is very, very loosely based on the msp430g2xx2usi16.c example from TI, but if you compare you will notice that:

  • the state machine is different (simpler): see doc/usi-i2c-state-diagram.pdf for details,
  • it actually has a useful interface,
  • it is smaller.


This is a simple I2C master that needs to fit on devices that have 128 bytes of RAM, so scale your expectations accordingly. There is no error detection, no arbitration loss detection, only master mode is implemented. Addressing is fully manual: it is your responsibility to shift the 7-bit I2C address to the left and add the R/W bit.

Have fun!

Bus Pirate Reference Card


The Bus Pirate from Dangerous Prototypes is a really useful tool. I use it regularly to bring up and test new I2C devices, or as a cheap protocol analyzer for I2C and SPI.

Unfortunately, the supplied cables aren't clearly labeled (only color-coded), and I found the reference cards available on the net lacking: they were usually not clearly readable and didn't help much. So I created my own.

You can print it on A4 paper and laminate it (which is what I did), or cut away just the upper color-coding portion and make a smaller laminated card.

Enjoy — Bus Pirate Reference Card (PDF)

Kinetis K and L Series Power Consumption


While considering a new microcontroller to use, I looked at the power consumption figures for the Freescale Kinetis K and L Series. Having some experience with various MSP430 MCUs, I am used to shaving off microamps and running systems on battery power, sometimes for years.

While the real answer can only be gotten with a real setup, one can get some preliminary information from the datasheets. And I found some surprises lurking there.

I was mostly interested in comparing three MCUs: KL05, KL25 (basically a KL05+USB) and the K20. The K10 which appears in the figures can be thought of as the K20 without USB, and I didn't expect its power figures to be any different from the K20.

The ARM Cortex M0+ has a range of power modes, so comparisons aren't easy. I left out those that basically amount to a full power-down (losing the contents of the RAM). The numbers do not include analog supply current, and are taken at 3V, 25C. The RUN values are at full core frequency (48MHz) with a while(1) loop executing from flash. VLPR and RUN values are with peripheral clocks enabled. Let's look at the first four modes:

As expected, the Cortex M4 core draws significantly more current when running at full speed. About three times more than Cortex M0+, in fact. Note that this doesn't necessarily mean the final product will use more power — if you draw three times more current, but get your computations done three times as fast, you're basically even.

Note what begins to happen in STOP mode, though. The power draw for all chips is nearly the same. Continuing on into the lower-power modes (note the change of scale to 5µA max):

Apart from the strange discrepancy with KL25 in VLPS mode, all numbers are nearly identical.

This is not something I expected — although in retrospect, it makes sense: a stopped core and stopped peripherals consume little to no current, and you can stop nearly everything on all MCUs. Still, this has some real-life implications.

My takeaway from this is:

  • if your application spends most time in deep sleep modes, then it doesn't really matter which MCU you choose, from the power consumption point of view they are nearly the same,

  • if you use the CPU a lot, the choice isn't at all clear, and will really depend on the application and its computation patterns.

For comparison, let's look at the MSP430F5510, a chip comparable (from the application point of view) with the KL25, though the CPU is significantly less powerful. Values are in mA, taken at 3V, 25C, RUN values at full frequency (25MHz) running from flash:

The interesting fact here is that the F5510 at 25MHz running code consumes about as much current as the KL05 or KL25 running at 48MHz. ARM Cortex M0+ really is a very power efficient core. It makes sense: the MSP430 is a rather old design. But note how years of experience allow TI to achieve the impressive LPM0 number: 83µA. LPM0 is the lightest sleep mode on the MSP430, roughly comparable to WAIT mode (core stopped, peripheral clocks active, ability to wake up on any interrupt). When you get down to deep-sleep modes (LPM3), the numbers become more comparable.

Take all this with a grain of salt, as it is only based on datasheet numbers. Still, I found the data interesting and worth sharing.