Wednesday, February 01, 2017

Perl 6 - Diving in...

So, I've been a long time Perl user since the 1990s.  I rarely used it on job, but my only (widely?) used open source contribution is an application written in Perl 5: AFT (It is on github and is also available to any Ubuntu based distro by typing "sudo apt install aft".

Apparently, Perl 6 is now usable.

It looks very interesting. In particular, I am excited about its concurrency/parallel support (why is it that so few languages come with this baked in?).  The FFI looks usable (I've managed to get Perl 6 working with libusb pretty quickly).

But why bother?

I've always liked the language design approach of Perl.  The maximal syntax approach is dense but can have some appeal. In particular, it seems to avoid the (overbearing) library approach that other languages take.  This is a strength shared by Haskell and (yes) C++1x (C++11, C++14, etc).

For me, a couple of lines of well written code always wins over the "I must dive into a hierarchy of libraries and calls".  You just need to avoid making the couple of lines too dense.

This is the thing... in C++ and Perl I tend to avoid libraries if I can.  Externally dependencies are more subject to code rot. AFT still runs (on almost any Perl distro)  in part due to lack of dependencies on libraries that may be "abandoned" or improperly upgraded (to kill backward compatibility with older Perl distros).

But, I digress....

This entry is just my way of committing myself to a Perl 6 learning effort:

I have written 2 Mumble compatible chat/VoIP servers: One in Erlang and one in Lua(JIT). (I attempted one in Clojure but Java based networking made it nearly impossible to do sanely.)

I am now trying to see if Perl 6 is up to the task.

Stay tuned...

Wednesday, January 18, 2017

Crazy Complexity:The STM32L476

The STM32L476 very low power Cortex M4  costs $9 at Digikey.
This tiny MCU has, among other features, 128KB RAM, 1Mbyte Flash and
  • USB OTG 2.0 full-speed, LPM and BCD
  • 2x SAIs (serial audio interface)
  • 3x I2C FM+(1 Mbit/s), SMBus/PMBus
  • 6x USARTs (ISO 7816, LIN, IrDA, modem)
  • 3x SPIs (4x SPIs with the Quad SPI)
  • CAN (2.0B Active) and SDMMC interface


The reference manual is 1704 pages long.  
The reference manual is 1704 pages long.  
The reference manual is 1704 pages long.  

I work on this beast at my day job.

Friday, December 16, 2016

Even Simple things are Complicated... in IoT

So, I strive for simplicity in my design.  But I realize that simplicity in design doesn't  mean simplicity in implementation.  Even simple things are complicated when you consider IoT.

Let's take a fairly "simple" example: You want to design a water leak detector for your water heater (or the utility room/closet that hosts it).  Or maybe you are in a flood zone.

This water leak detector should notify you (via your Internet connected Smartphone -- you may not be at home) that there is water present (or rising significantly)on the floor.  Assume that this is VERY IMPORTANT to you because your house is prone to floods or leaks.  Or, you want to make sure your "pump" is doing it's job.

During rainstorms while you sit at work... your mind may wander... to your house... to that damn pump...  Okay, IoT to the rescue!

Simple? Sure. Just throw an ESP8266 or ($10-20) Raspberry Pi at it.

Fine... now let us look at what needs to be done.

  1. A water sensor.  Okay, let's assume you found one or threw together a nice one that can be securely mounted to the floor or wall just above the floor.  Basically let's punt on this one. Done.
  2. You need Wi-Fi. Chances are you aren't located near an Ethernet port and probably don't want wires everywhere.
  3. You need to be battery powered. (Assuming even if you rather plug it into AC, there are flood conditions that could occur during a power loss, right? Like your flood pump isn't working..) So, yes, you need to be battery powered. And the battery should last at least 1 year.
  4. You need a cloud server to host the relaying of messages to your Smartphone.
Okay, so you've done all of that hard work or found a nice little sketch/hackaday-device that does all that for you. Done?
Nope.

Here are some issues you need to consider:
  1. How do you get notified that the battery is dying?
  2. What if someone does an DoS attack (or you changed your Wi-Fi router and forgot to re-configure this device).
  3. Speaking of Wi-Fi... How do yo configure this device in the first place?
  4. Do you have redundant servers in the cloud. (What if your cloud server goes down?)
  5. What do you do if your ISP (or cloud) connection goes away for a few minutes?
  6. What if the water sensor is accidentally "detached" (or is damaged)?
  7. Is your connection to the cloud secure? Is it authenticated? What if some joker thinks it would be funny to fake out your server into thinking that there is a water leak?
  8. What if the device was suddenly "unpowered" (unplugged or batteries were removed). Can you handle that?
  9. How do I know, in general, that the device (and my connection to it) is working properly?
Now, you don't have much control over the "Internet" portion of this (realistically). But, at the end of the day, your device will always be blamed. It didn't notify you and your basement is now flooded.

So, let's address some of these issues.  Let's assume that this device is either very, very critical to you (you have lots of water problems and can't afford the massive damage an unattended one would cost) or you want to go to market with this device.
  1. How do you get notified that the battery is dying?  
    • You are going to have to monitor the battery voltage.  So, some ADC work. 
    • And you probably should have a local (loud) buzzer in addition to sending it over Wi-Fi
    • LEDs will be next to useless (unless you tend to hang around your utility room/closet a lot)
    • Also... Wi-Fi transmission take a lot of power. Consider that in your power budget.
  2. What if someone does an DoS attack (or you changed your Wi-Fi router and forgot to re-configure this device).
    • Once again, a buzzer. But don't make it too annoying. 
    • How (and/or when) do you shut off this buzzer?
  3. Speaking of Wi-Fi... How do yo configure this device in the first place?
    • Smartphone? Via Bluetooth? As a (temporary) Wi-Fi access point?
    • You are also going to need a "rich" app for the phone, or otherwise a nice web server for the device (a web server for a freaking water monitor, ugh)
  4. Do you have redundant servers in the cloud. (What if your cloud server goes down?)
    • Of course, your ISP can go down... but more likely it will be that $5 per month virtual instance in the cloud that you thought was a really good bargain.
    • Consider at least 2 servers (not co-located).
  5. What do you do if your ISP (or cloud) connection goes away for a few minutes?
    • You are going to need to cache this information and send it later... so you need a "retry" mechanism
    • You are probably going to want an event  "date" (or at least elapsed time from). Has it been trying to notify your for hours?
  6. What if the water sensor is accidentally "detached" (or is damaged)?
    • First you need to detect this. Your monitoring algorithm considers false positives right? Is this a measurement glitch or did the sensor get yanked?
    • The sensor (which may just be a couple of traces on a board) needs to have some means of being "detected". So.. it needs to be more than a couple of bare wires or traces on a board.
  7. Is your connection to the cloud secure? Is it authenticated? What if some joker thinks it would be funny to fake out your server into thinking that there is a water leak?
    • Encryption may not be important (this isn't critical private info), but spoofing can and will be a problem. You will need to some form of SSL/TLS, so you just went beyond your 8 bit Arduino in terms of parts count.
  8. What if the device was suddenly "unpowered" (unplugged or batteries were removed). Can you handle that?
    • Basically... ask this question if you want to use a Linux based solution (A Pi or Beaglebone). 
  9. How do I know, in general, that the device (and my connection to it) is working properly?
    • A system check... a heartbeat... an alert to your smartphone that something is amiss
    • A heartbeat will affect battery life... be careful.
So... this simple device starts to become complicated really, really fast. Doesn't it?

Monday, December 12, 2016

Brutal High Availability vs Simplicity

I've been toying with the idea of using an ESP8266 Wi-Fi SoC (running NodeMCU) as the basis for my kitchen/stove monitor.  It's cheap ($3), it has the sensor inputs (and libraries) I need and gets my device on the Internet (IoT!)

However, I have some serious questions regarding the stability of the platform (mostly the software -- and yeah I know I can punt NodeMCU and go with C, but I am still using frameworks and libraries I don't trust yet).   Can I run this SoC for years without a glitch?  My device can't afford to "fail".  It needs to always be working. Even if it had to "reset" due to a watchdog or long running glitch, it needs to be up and running in order to be useful.  It needs "High Availability". 

What can I do if I want to use this useful SoC?

Well...assuming that the hardware is stable, I can address software instabilities by adding another "trusted/reliable" system.

Maybe an ATmega326 running minimal firmware: Just logic.  It would be the "master".  But, it is quite an anemic master.

Since my device is AC powered (I wanted something you could enable and use without thinking about battery replacement, etc -- not play the Wi-Fi power budget problem),  I don't have to limit myself to an anemic microcontroller.  Maybe a Linux SBC?  Maybe... a Beaglebone Black?

So, here, I begin to abandon "Simplicity" (and increase my cost significantly).  But, I can do a few more things by choosing a Linux SBC:

  1. More robust protocol for Internet use:  A real messaging system (XMPP? RabittMQ client?) with caching and reconnect strategies.
  2. More security (Stronger encryption and authentication at endpoint)
  3. Leverage proven multi-year uptime of a Debian or Ubuntu distro

But, why use the ESP8266 at all?  Because getting peripherals (e.g. I2C, 1-wire, etc) to work on a Linux SBC is black magic and a waste of my time.  Plus, the ESP8266 is cheaper than any Wi-Fi USB module I can get for Linux.

The idea here is to have the Beaglebone control the ESP8266.  The Beagle will periodically either ping it for liveliness or simply reset the module before transactions or as a "daily" ritual.  It may sound kludgey but so as long as the ESP8266 is okay with periodic resets, this lends the system to higher availability than a pure MCU (bare metal or non-commercial RTOS) solution.  

Another benefit is I can do an "all Lua" implementation (Lua on the ESP8266 via NodeMCU) and LuaJIT on the Beaglebone.  This would allow me to integrate some telephony (SIP) stuff I've been working on (a completely different project) to "call" instead of just message the user about kitchen/stove activity.

Or, I could just continue developing with my current minimalistic approach of using the ATmega326p with Charley Shattuck's myforth-arduino (which is a pleasure to use -- I've already got my temperature monitor working :)


Thursday, December 01, 2016

The Mind of a (low level) Systems Programmer

I'm a systems programmer... an obsolete term, indeed.  But that is what I am.  It's not about coding in assembly (fun!) or squeezing out every drop of optimization in C (double fun!), but it is about wanting to "make" systems.

Compare this with an "application programmer" (another archaic term).  They love the domain.  I love the innards, the thing that runs the application.  My work should be silent and never seen. My stuff needs to just "work".

I like watching my front loading washing machine run. It is a complete system, but no fancy UI or IoT interface to be seen. It has sensors, it has actuators, it spins.... that's it.
Most of the time it works (it's getting old so there are a few faults here and there).  But it is successful because no one thinks about it. It lies in the background of our lives, silently do its job.

A year ago I had to replace the logic board in my HVAC. It was expensive ($700 list -- but I got mine new from ebay for around $400).  The complexity (and wonder) of that board is that it has to be as solid as NASA system.

My HVAC uses natural gas.  A lot of the components on that board (and the logic / program) are there to make sure my house doesn't blow up.  No fancy interface. No operating system. No complex 32-bit floating point math (I assume... I mean, my house shouldn't blow up do to a rounding error, right?).

I installed the Hunter ceiling fan, in my bedroom, over 15 years ago. It runs every night and mostly through the day. It has never failed. It is still silent. I wonder what kind of motor it has built in and how it is commutated (must be AC since brushless DC wasn't widely available back then -- I think).

That was a good design... a systems design.

Sunday, November 27, 2016

Excessive Portability and Embedded Development

Which is better?


/* Read the angle register (ANGLECOM) */
angle = spi_write(0xFFFF);

or

/* Read the angle register */
angle = spi_write(A_READ | A_PARITY_1 | A_ANGLECOMREG);

Now, you don't have to understand exactly what's going on here (and the actual process of reading an angle from the AS5147 rotary position sensor is a little bit more complicated), but I am trying to make a point.

I would argue that the second code snippet is a waste of time. (Some presumptions here: You had to define A_READ, A_PARITY_1 and A_ANGLECOMREG).

But, why would I advocate the hard coded version?

  1. The chip (AS5147) isn't going to change SPI command structure anytime during its production cycle.
  2. If you choose a new chip, you are going to have to study it and figure out the hard coded values anyway.
  3. The abstraction in the 2nd code snippet is going to only work for this exact chip.
  4. You have to work out the bit twiddling anyway (to come up with A_READBIT, etc)
  5. 0xFFFF is what you will see in your debugger
  6. It is *always* 0xFFFF 
  7. Ease of modification doesn't work here. If you go "oh, that should be A_PARITY_0" and change it (without verifying the actual resulting write value, it is going to cause a lot of debugging woes).
This is sort of an argument between "ease of writing" vs "ease of debugging" and in embedded development, "ease of debugging" is what you are really shooting for (or maybe call it "ease of validation").

I see the same thing happening with STM32's HAL or StdPeriph.  There is a focus on making it easier to load up registers (often taking 1 line of register loading code and stretching it into multiple lines of structure loading using verbose enums/types you have to look up).

To be honest, when I work in Forth on the STM32, I don't have such luxuries and my program is full of well documented hex and binary register banging.

Monday, November 14, 2016

Attack At Dawn


This is a painting on display at The Walters Museum in Baltimore Maryland. (http://art.thewalters.org/detail/4911/the-attack-at-dawn/).   It is by "Attack At Dawn" by Alphonse de Neuville.  

I am not particularly a fan of military battle scenes, but there is something about this painting that I can't get the image out of my head. 
This photo does it no justice.  The somber, winter setting, the lighting, the mastery of painting techniques. It is not a famous painting, but it does so many things that resonate with me: The distant foggy morning sky, the snow, the dim light sources (e.g. dawn, the lamp post, the doorway on the left, the rifle fire), the sparse brush strokes, the sense of desolation.
Go see it, if you can.


Literate Programming... A Revisit

For someone reason (nostalgia?) I've been re-visiting Donald Knuth's concept of Literate Programming.

(For a quick intro, critique and discussion on this approach see this blog entry and the responses.)

I first discovered Literate Programming via looking at TeX sources in the 1980s.  Then I became somewhat obsessed with the approach around 1992 with the publication of Literate Programming by Knuth. This is still one of my favorite books on programming.

I still like to thumb through TeX: The Program (likely the largest Literate Program ever written).

Perhaps I am starting to revisit Literate Programming because of my full-time-deep-dive into embedded programming (again).  Still stuck with C and code that is supposed to work (I deal more with "firmware" than software these days -- code that can't just be frequently updated, is hard to unit test and must be very, very reliable).

Literate Programming doesn't fit well in today's rapid development, big team, fastest-time-to-market culture.  But, when I am writing control systems with little instructional software/literature available (e.g. learning how to spin a BLDC motor using sinusoidal waves), I start thinking about approaching it in a literate style.

Shhh... don't tell my partners, but I am definitely thinking about using cweb  or perhaps cwebx for this ;)