Friday, October 13, 2017

Wish List: Clojure tethered to an MCU running Forth

I want to do 2 things:

  1. Use the power of a full desktop system (e.g. Linux, Emacs, Clojure, etc) to play with some SPI/I2C peripherals
  2. Compile a very limited subset of Clojure/Lisp to Forth for flashing into a microcontroller

Essentially, I want to take the "tethered" Forth environment (i.e. a full blown interactive development environment talking directly to an MCU),  but instead of Forth (Gforth, etc) on the desktop I want to use Clojure/Lisp  (basically a language with very rich desktop support).  

#1 is pretty easy.  I can pick a popular Forth like Mecrisp (which runs on lots of MCUs) and talk to it's Forth interpreter from the Clojure REPL. 

#2 is harder, but necessary if I don't want to use #1 just for prototyping.

But why not just use a terminal and Mecrisp (for #1)?

Each Cortex M arm chip comes with a ton of definitions (registers, bit names, etc) that I don't want loaded onto the chip. Also, every little "helper" function I write (to enrich the Forth REPL)  takes space on the MCU

 Tethered Forths don't have this problem (as you leverage the desktop Forth to handle such things).   

But, while Gforth is very nice, it still isn't as "rich" as I want regarding integration into Linux/Emacs (i.e. not enough batteries included).

Tuesday, June 13, 2017

Low Power MCU Fetishes

So, I am pretty familiar with the STM32L4xx low power Cortex-M4 MCU.
It has some insanely low power consumption profiles including a  0.65 µA standby mode with RTC (and just 14 µs wakeup time).

This thing is a beast to program (1600+ reference manual to start with and copious app notes).  But, I work with this chip for a living.

This current consumption is specified (in the documentation) at 1.8V, so a more typical 3-3.3V actual power supply will likely cause it to consume more current.   I am assuming direct battery hookup otherwise the current consumption of an LDO regulator has to be considered.

Still... this is insanely low.

I am looking to play around a bit with some "old" 8-core Parallax Propeller Chips (P8X32A) I have laying around and I read some forum discussion where you could likely get it to consume as little as 7- 10 µA  when running just one COG doing not much (maybe as a timer?).

To these jaded ears that sounds like a lot of power, but... honestly... really?

With a couple of 1200 mAh  AAA batteries (3V) the P8X32A would run around 11 years.  That is greater than the shelf life of AAA batteries.

Most of the current consumption these days aren't from the MCU but from the peripherals and sensors. If I wanted to beacon some temperature measurements via BLE (connection-less -- just as a "tag") maybe every minute, the battery life drops to around 1 year.  So, it would be more reasonable to beacon every 10 minutes.  Then I could get maybe 5-6 years.

We get lured into thinking too much about how low an MCU can go, when in the world of IoT, it is the RF that is killing us.

Just food for thought.

Monday, June 05, 2017

My Forth Story (Part 1)

This is just a few collected thoughts on my 30+ years of using Forth. So, if you are expecting high quality technical content, please move on.  Yes, nothing to see here, move on...

This past weekend I was going through old books, trying to clear out some bookshelf space, when I came upon a yellowing Forth Dimensions from 1986.  It got me thinking about when I first became enamored with Forth and how it is has popped up now and then throughout my career.

Back in 1982, armed with my first computer: a Commodore VIC-20, I started my first year in college (I was 16 years old -- I skipped a year in grade school) infatuated by the possibilities offered by computer programming.  I wasn't really college material (I was planning on going into TV repair or maybe an Art school), but I had just (to everyone's surprise) won the Engineering division of the DC Science Fair and was offered a 4 year scholarship to the University of the District of Columbia.  I had prototyped an LED display based oscilloscope using some op-amps and 555 timers.  It was inspired by a design I saw in Popular Electronics.  But I digress...

So, here I was starting college (and a job as a TA in the computer lab!) and I knew it was time to "up" my skills (I was proficient in BASIC and some 6502 assembly).  We had a lab full of the newly purchased Commodore 64s (C64) and a terminal room (oooh, remember green phosphorous terminals?) remotely connected via 1200 baud modems to the school's DEC2060 (more on that later). I would split most of my day time between the C64 and DEC260 and my nights were spent hacking on my venerable Commodore VIC-20.

Suffice it to say, my VIC-20 wasn't cutting it to get me kick started into  the highly competitive CS department.   I saved up money to get a Commodore 64 so I could continue my hacking education from the comfort of home.

On the DEC2060 we didn't have BASIC.  We had a sophisticated Macro assembler, Rutger University Pascal and Fortran IV and 77.  None of this would work on the C64, and BASIC was quickly running out of steam.

It was either through BYTE (or maybe it was Compute!) magazine that I stumbled upon this language developed by this guy named Chuck Moore.  It was Forth and there were a couple of implementations available on the C64.  An implementation that intrigued me, in particular, came in cartridge form and booted (nearly) instantaneously.  This wouldn't require me to fiddle with the painfully slow floppy drive.

I became obsessed with Forth. The interactivity and the power (to lock up the C64) was addictive.

But, my CS (well EE, I started as an EE student and defected to CS) courses were on a DEC2060. The DEC20 was a lovely 36-bit word "mainframe" (shhhh! DEC wasn't allowed to call them mainframe as they didn't want to face the wrath of IBM and their patents). The 36-bit word size happened to be perfect for a Lisp cons cell.  I found Lisp quite lovely, powerful and intriguing but I was still in the midst of my Forth obsession.

This obsession became even more all consuming, around 1985, when I read about Chuck Moore's  amazing Novix NC4016. I even ordered a fact sheet from Novix Inc so I could pour over as much detail as I could -- knowing I would never likely touch one.

In late 1985, my C64 Forth obsession hit a wall.   This wall was my obsession with Fractals, particularly the Mandelbrot Set, of which I first heard about in the August 1987 issue of Scientific American.  The C64 just didn't seem to have enough processing power to execute my naive implementation of Mandelbrot's algorithm.

Eventually, I found a Forth that ran on a DEC20, converted the algorithm to fixed point and managed to get the set rendered on a graphics terminal (over a 1200 baud modem!).  If my memory serves me correctly, the terminal was a fancy Tektronix 4150.  It took a lot of false starts and missed classes, but a couple of days later I had a color fragment of the famous fractal.

As I got further along in my CS curriculum, I discovered that technologies like home computers (C64, etc) and languages like Forth were not really encouraged as tools of study.  So, I learned TOPS-20 assembly, Pascal, Fortran (IV and 7), TeX and Lisp.  I fell in love with Emacs (the original written in TECO!) and generally was happy, but I was missing some of the hands on immediacy of having my own personal computer and personal happy-to-crash-it-language like Forth.  There was a driving need, brewing inside me, to do something low level -- something dangerous.

So when a secretly procured  copy of AT&T's UNIX Version 7 arrived at the University Computer Center (where I worked, distracting me from my scholarship and short circuiting the pursuit of my degree), I worked with a couple of my friends to boot it on the DEC20, play around with it and then remove it,  before the next day's classes began.  This was no trivial task as it required hand entering the bootloader on the front panel. Fun stuff.

I soon fell for the spartan language that accompanied the UNIX tape: C.

Over the years, I would continue to play with (and implement my own) Forths, but it wouldn't be until 20 years later that I would get a chance to program in it extensively (around 2006), when I revisited my low level hardware past in the form of embedded development on Microcontrollers.

To be continued...

Friday, April 14, 2017

Hack C

Work has been busy and eating up most of my "Copious Free Time", so most of my projects have been placed on hold.

However, one thing I am getting from the past 6 months "deep dive" back into C programming (I've been programming C on and off since 1985 -- yes over 30 years *gasp*), is that a lot of my code in LuaJIT, Perl, C++11, Clojure and Haskell (and others) could be rewritten pretty concisely in C (C99 or C11 in particular).

Now, hold on, you say -- that is crazy talk.

A lot of the types of applications/tools I write are "system level".  When not coding Cortex M4 ARMs (my day job) I do a fair bit of networking (ethernet/IP packet level) hacking.  Or, I use libraries such as OpenCV to do simple vision stuff. So, I am not really using the advantages of higher level programming languages.

What I am really benefiting from is those language's  REPL -- the interactivity.  

I recently rewrote an OpenCV based image detection application, I originally explored and coded in LuaJIT, in C99. It was almost a line by line translation (I even found a couple of bugs!).

Okay, so honestly, I wonder if I had some sort of C REPL (gdb on steroids?), all I am missing is a nice convenient hash table (i.e. associative array, dictionary, etc).  I don't like the baggage of bringing in whole toolkits/frameworks for that (I like to keep my C lightweight and avoid things like pseudo-OO), so I just need a nice fast, generic hashtable implementation.

I need to get back into hacking C (for a while at least) and avoid the drama associated with picking a programming language "tribe".

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?

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?