Sunday, April 22, 2012

Why Forth still matters in this ARM/Linux/Android world

My sensors (for my home monitoring system) need to run off of coin cell batteries (the sensors need to be tiny). They also need to run for at least 1 year (under normal circumstances).

The sensor transceivers consume around 15mA when transmitting. This is a lot for a coin cell battery.  The general sensor development strategy is to use communication sparingly: If you don't need to broadcast data, don't.

With a battery that can only source 200mA for just one hour, you really need to start thinking about low power design. An ARM/Cortex capable of running Linux consumes a lot of current. You are going to use a low power 8 or 16 bit processor (e.g. Silabs 8051, MSP430, etc).

Now add C and some libraries to the mix. The more generic/portable stuff you do, the longer the processor is going to stay awake. While it is awake, it is consuming power. The longer it "sleeps", the longer your battery will last.

So, I am using a very low level Forth (MyForth) on a Silabs 8051 low power processor. MyForth is essentially a high level macro assembler -- there is very little overhead to support Forth.

There are no libraries that come with MyForth, so I had to roll my own code.  This keeps me true to the Forth philosophy (or at least Chuck Moore's philosophy) of only doing what you need to do to meet the task at hand. I am not writing "generic" libraries. I have to fully understand the devices I am interfacing with.  I doubt that I could write tighter/faster code for my transceiver -- I am engaging it at a primitive level. No abstractions but the ones that MyForth provides at a (mostly) macro level.  Forth, like Tcl, is more idiom reuse oriented -- you can do a lot with just a little code.

If I need to work harder to make sure that my sensor works 24/7 for at least a year (or two!) off of a coin cell battery, then I will.

My stove monitor (temperature + motion sensor) runs on a Silabs C8051F912. That MCU has 768 bytes of RAM and 16KB of Flash. I am talking to an RFM12B transceiver over a SPI interface and controlling a low power IR motion sensor module.  Currently, I am broadcasting motion and temperature over the air using less than 128 bytes of RAM (including Forth stack) and less than 4KB of Flash. I spend only a few seconds awake, a most of the time asleep consuming less than .001mA of battery current.
You can do this in C (of course!), but I don't think you could reach the code density (especially as you start using third party libs).  I can also hand tune my code directly in assembler where needed.

Yep, Forth still matters to me.


Sethish said...

Can you post more about what kind of home sensors you're building? (or link to a previous post if I missed it). I'm interested in what you're measuring.

Todd Coram said...

An overview on the sensors and project has been posted here:

Anonymous said...

If your C compiler is adding libraries that do things to keep your MCU awake, you are using the wrong C or the wrong MCU. Forth is great for those who love it.

Hamachisn't said...

I'm with you. I think Forth is so much more useful than people give it credit for. It's fast to write, it takes up little memory, it runs fast... what more do you need?

Its biggest problem is that if you have a team of programmers all writing Forth, each of them must exercise much discipline in documenting their code, or else each programmer ends up rewriting their own version of each low-level routine. It's possible to write in a team, but too often the code grows to a few times the size it need be (and the coding time multiplies as well).


Todd Coram said...

Yes. Getting a group of Forth programmers to work with other is very tricky. I think the Forth is more tuned to the "single" developer (sub)projects.

I tend to work alone on most of my projects, so the main concern is making my code readable/maintainable for those that follow me (i.e. maintenance).

Anonymous said...
This comment has been removed by a blog administrator.