Computing stuff tied to the physical world

Archive for November 2011

All power-up puzzles solved?

In AVR, Hardware on Nov 30, 2011 at 00:01

As reported in a recent post, there were startup problems when powered from a 0.4 mA trickle-fed capacitor.

In short: it didn’t work…

The problem with a trickle-feed supply is not that the voltage level will ramp up very slowly (the brown-out detector and power-on reset circuitry should be able to handle that). The problem is that the circuit needs to draw less current than the trickle at all times – because otherwise the capacitor won’t ever reach its full charge level.

One problem was the MCP1702 voltage regulator, which has a large current draw before the input voltage reaches 3.3V where it can start regulating. So I removed the regulator, and created a setup which limits the capacitor charge to around 3.8V – thinking that without the regulator, the ATmega would at some point start up and immediately put itself and the RFM12B into sleep mode, letting the supply voltage rise a bit further.

Strangely enough, it didn’t work at all. I kept seeing a start-up spike of several milliamps. Here’s the current consumption on power-up (the scope shows the voltage over a 10 Ω resistor in series with the power supply):

DSC 2796

That’s over 10 milliamps, for well over a second – Huh?

And then it finally dawned on me: the boot loader! The ATmega is set to look for an upload right after power-up or reset, which is what the boot loader is all about. Guess what it does: look for incoming commands on the serial port for roughly one second, before passing control to the main sketch stored in the ATmega.

Clearly, the boot loader is running at full power. Whoops!

So the first conclusion is that in this context, we can’t use a boot loader. The solution is to change the high fuse from 0xDA to 0xDB with an ISP programmer. It’ll make it harder to upload code, but there’s no other way.

Great. I thought that would solve the problem. But that’s not all. The default fuse settings also cause the ATmega to wait for 65 milliseconds on power-up. This is for crystals to get up to a stable oscillation. Unfortunately, that means the ATmega is spending 65 ms in a higher-power mode on startup.

So I changed the fuses to use the 1K / 14 CK startup mode (power-up / reset). The way I read this, it means that the ATmega will power-up after 1024 + 14 clock cycles once it comes out of hardware reset, and after 1024 clock cycles when coming out of sleep mode.

Furthermore, the divide-by-8 prescaler fuse bit needs to be set, because the ATmega will power up with a 2.7 V supply voltage (the BOD level). At that level, running at 16 MHz is way out of spec, and no doubt very unreliable.

So all in all, the following fuse settings are required:

  • BOD level = 2.7V, i.e. don’t power up before the supply has reached 2.7V
  • enable ÷ 8 pre-scaler on startup (can be disabled in software later)
  • make the clock start up in low-power 1K / 14 CK mode
  • disable the boot loader, jump immediately to the main sketch

Here is the power consumption with these changes (note the 40x X scale and 5x Y scale differences):

DSC 2798

There’s still a 0.65 mA current draw during start-up. Unfortunately, this one is nasty: it’s caused by the RFM12B module, which powers up in this mode. Best thing I can do is put the RFM12B to sleep as soon as possible, but that can’t happen before the ATmega has started up fully. So basically, there’s a 0.65 mA current draw which we can’t get rid of (other than adding extra circuitry to control the RFM12B’s power – but see also below).

What this means, is that I’ll have to settle for a 1 mA trickle feed supply for now. It’s enough to keep charging the buffer cap, and this way things ought to finally get past that power-up hurdle.

And guess what? It works!

DSC 2801

The cap charges until the supply reaches 2.7V, then the ATmega snaps out of reset and puts the RFM12B to sleep.

The interesting thing now, is to check whether that MCP1702 current anomaly on startup really was a problem. So I switched back to a standard JeeNode, and tried it with the above fuse settings.

Hey, it still works! So we could go back to a 12V zener charging a 100 µF cap. This puzzle has come full circle!

More good news – it looks like there is a sneaky way to avoid the 0.65 mA power-up current draw of the RFM12B: make the ATmega start up at 1.8V instead of 2.7V – the RFM12B isn’t pulling much current at that level. So if we turn it off right away then the RFM12B will be put to sleep before it gets a chance to draw too much current.

Does this work? You bet. Here is by far the craziest low-power setup I’ve ever been able to get going:

DSC 2803

That’s a 100 µF cap charged using a 10 µA trickle. You can see the 1.8V bump where the ATmega kicks in, inits the RFM12B, puts it to sleep, and later on sends 2 packets. This is a standard JeeNode, but with special fuse settings:

  • internal 8 MHz RC oscillator, fastest startup
  • don’t enter the boot loader
  • brown-out level is set to 1.8V

The fuse settings are: extended = 0x06, high = 0xDB, low = 0xC2.

Fascinating how everything affects everything, eh?

UpdateI’m having some doubts about this last result. Will need to triple-check my calculations on this one. That last report is most definitely incorrect, there’s no way to get the RFM12B to start up with a 10 µA trickle – it starts up with the crystal oscillator active, which means that it’ll draw at least 0.6 mA until put to sleep.

Who needs MOSFETs?

In Hardware on Nov 29, 2011 at 00:01

The “EPAD” MOSFET circuit described in an earlier post is nice, but as Ronald recently suggested in a comment, LEDs also have a nice high forward drop – so why not take advantage of that instead?

Much simpler and cheaper!

LEDs act a little bit like zeners, but they too have a somewhat round “knee” ar very low current levels. I’ve done some experiments, and have come up with a blue LED in series with a red one as suitable voltage reference:

DSC 2795

As you can see, even with 1 mA of current, they are clearly visible (especially the red one, which is a low-current type). So this also makes an excellent power-on indicator – at no extra charge – if you pardon the pun. There’s also a 1N4148 diode to a 470 µF buffer capacitor. Here are the voltages this thing seems to stabilize on:

  • 3.69 V @ 2 µA
  • 3.80 V @ 5 µA
  • 3.86 V @ 9 µA
  • 3.97 V @ 25 µA
  • 4.09 V @ 98 µA
  • 4.13 V @ 150 µA
  • 4.18 V @ 251 µA
  • 4.22 V @ 399 µA

Taking the extra diode drop into account, this leads to a very acceptable 3.04 .. 3.57 V supply voltage for a JeeNode.

So for a capacitive AC mains supply, this could be doable with 7 components:

  • a 10 nF X2 capacitor as reactive component
  • a 4.7 kΩ fusible resistor to limit the inrush current
  • a blue LED plus a red LED to create the necessary voltage drop
  • a 1N4148 across the LED for the reverse current
  • a 1N4148 from LEDs to feed the capacitor
  • a 470 µF 6.3V electrolytic capacitor for energy storage

This circuit is dangerous when directly connected to AC mains, but if a direct reference to one of the input pins is not needed, then it can in fact be made a bit safer: replace the 10 nF cap by a 22 nF unit, and add a second 22 nF cap on the other power line input (plus a second 4.7 kΩ fusible resistor for extra security). Touching the “low-voltage” side limits current to 1 mA – this should cause at most a slightly tingling sensation when touched.

I don’t know about temperature sensitivity, but in a case like this where voltage stability is not so important, this circuit might in fact be the simplest way to build a 0.1 .. 0.4 mA ultra low power supply!

Update – as pointed out by Martyn in the comments below, this circuit is not safe in case of a fault. It’s still transformerless, so it has to rely on caps to do its work – both of which can fail by shorting out. Fusible resistors are not a good enough security in terms of safety, because they don’t blow at current levels below 1 mA – they only protect the circuit from large currents in case something goes wrong.

As always: be careful with 115V and 230V AC mains!

Sine Wave Generator

In Hardware on Nov 28, 2011 at 00:01

Frequency generators used to be very expensive. No more (for basic uses). Nowadays, a single chip does all the hard work. It runs off a fixed stable crystal oscillator, and it generates a sine wave of any frequency you want.

Here’s one I purchased off eBay recently – for under €40, including shipping:

DSC 2780

Just hook it up to a 12V power brick and it’ll generate the sine wave on its BNC output connector. The push buttons let you move to a specific digit and increment or decrement that position. I haven’t figured out what the rightmost button does (the labels are in Chinese).

Here’s a 10 MHz signal, on the Rigol DS5062CA scope:

DSC 2779

And here’s a 50 MHz sine wave, the maximum supported by the frequency generator:

DSC 2778

Note that the amplitude is a bit lower. This is a 60 MHz scope, which means it’ll drop off 3 dB at 60 MHz. Decibels are a logarithmic scale, and “6 dB” is a funny way of saying “half” (so 3 dB is 71%). So in effect, the scope will still show the 50 MHz sine wave nicely, but it won’t be accurate in amplitude.

Scope bandwidth is a subtle thing. Once you know your scope has bandwidth X, you might be tempted to think that all is well up to that value, for any signal you look at. It doesn’t work that way, however (and far be it from scope vendors to tell you about that) – here’s a wake-up call: an ideal square wave requires infinite bandwidth to display accurately! The reason is that scopes aren’t inherently limited by bandwidth, but by how fast their input circuits can track an input signal (capacitance stores charge, and that hampers the way signals move around). So another way to look at how fast a scope can track a changing signal is to look at its rise time – which is usually also included in the specs. A perfect square wave has zero rise time, which no scope can match.

Before I veer too far off topic, let me just mention a rule of thumb, which says that if you want to accurately view square waves (such as logic signals!), then you need a scope with a bandwidth which is 10 times as high as the frequency of the signal you want to examine. To accurately view a 1 MHz logic signal, you need a 10 MHz scope – to display a 20 MHz square wave properly, you need a 200 MHz scope (this is unrelated to the “Nyquist frequency” BTW, which says that you need to sample with at least twice the rate of the signal to pick it up).

So this Rigol DS5062CA scope is suitable for sine waves up to 60 MHz if you can live with some amplitude loss, and it will show square waves fairly accurately up to 6 MHz, i.e. a 160 nS cycle time. It will sample up to 1 Gs/s, i.e. once every nanosecond (!), and it’ll display results down to about 5 ns/div, so the above samples you see are a bit deceptive: there are 320 pixels across, i.e. about 25 pixels per division, but only 5 measurements per division.

What this means is that the 50 MHz sine wave you’re seeing above is looking very nice, but mostly interpolated.

Fortunately, digital storage scopes usually have a couple more tricks up their sleeve. This one is more accurate:

DSC 2781

I’ve turned off the grid and enabled “Analog” mode, which is a way to emulate the CRT beam of an analog scope – it only lights up where actual measurements have been made, and it’ll keep a few previous sweeps on the screen. Note that it’s slightly early w.r.t. triggering, which was set to exactly 0V. This is as good as it gets with this scope.

Anyone interested in “Direct Digital Synthesis”, i.e. how this nifty sine wave generator works?

Ultra low power supply

In Hardware on Nov 27, 2011 at 00:01

This is another post about my quest for an ultra low power supply for the JeeNode and JeeNode Micro, directly connected to AC mains (and hence dangerous, I can’t stress that enough).

To reiterate: the goal is to create a supply using at most 0.4 mA for powering a device at roughly 2.5 .. 3.5 V. With a capacitive transformer-less circuit, this should lead to a 230V power drain of under 0.1 W.

The zener diode approach doesn’t work for voltages under 6V. Low voltage zeners are too leaky.

Neither does a low-power linear regulator – maybe – driven from say a 12V zener + cap. It probably draws too much current on power-up.

A possible solution was mentioned in a 2008 article by Bob Chao, titled “Voltage clamp circuits for ultra-low-voltage apps”. It’s based on a special type of MOSFET called an “EPAD”.

There’s a chip called the ALD111933 (scary name!) which includes two of these. Here are some specs:

Screen Shot 2011 11 17 at 16 46 14

So its gate threshold is very strictly specified as 3.3V, and it can only drain just a few milliamps. Still plenty for me, though. Another design limit is that the device only supports up to 10V between source and drain.

Here’s what I have in mind as my next attempt for the ultra low power supply:

JC s Doodles page 24

The 9.1V zener will have no more than 10 µA of leakage, and the leakage of the MOSFET is negligible as long as the supply voltage remains under 3.3V. Which means all the surplus current can be used by the JeeNode – at last!

Note that there are no other voltage levels of this thing, so there’s not much leeway for charge on the capacitor to drop during high power use, i.e. packet transmission. I can think of two ways to improve on that: go back to a 470 µF cap, which will hold more charge, or add an extra diode in the MOSFET’s gate to increase the voltage level at which it triggers. Either way, I think this circuit ought to finally give me that constant trickle to keep going!

I’ve ordered the necessary parts. To be continued…

Maximum speed wireless transfers

In Software on Nov 26, 2011 at 00:01

Prompted by a question of the forum, I wanted to go bit into the way you can collect data from multiple JeeNodes as quickly as possible.

Warning: I’m completely disregarding the “1% rule” on 868 MHz, which says that a device should not be sending more than 1% of the time, so that other devices have a good chance of getting through as well (even if they are used for completely unrelated tasks). This rule is what keeps the 868 MHz band relatively clean – no one is allowed to “flood”. Which is exactly what I’m going to do in this test…

Ok, first of all note that all devices on the 868 MHz wireless ISM band have to share that frequency. It only works if at most one device is transmitting at a time. Many simple OOK transmitters, such as weather sensor nodes, don’t do that: they just send out their packet when they feel like it. Fortunately, most of them do so relatively infrequently, once every few minutes or so. And due to the 1% rule, most transmissions will be ok – since the 868 MHz band is available most of the time.

This changes when you start to try and push as much information across as you can. With one sender, it’s easy: just ignore the rule and send as much as you can. With the default RF12 settings, you should be able to get a few hundred small packets per second across. With occasional loss due to a collision with another sender.

But how do you get the maximum amount of data across from say three different nodes?

It won’t work to let them all send at will. It’s also a bit complicated to make them work in perfect sync, with each of them keeping accurate track of time and taking turns in the right order.

Here’s a simpler idea to “arbitrate media access”, as this is called: let the central node poll each of the remote nodes, and let each remote node then send out an ACK with the “requested” data only when asked.

I decided to give it a go with two simple sketches. One is the poller, which sits at the center and tries to obtain as many packets as it can:

Screen Shot 2011 11 24 at 12 47 39

It cycles over each of the remote node ID’s, sends them a packet, and waits briefly for a reply to come in. Note that the packet sent out is empty – it just needs to trigger the remote node to send an ACK with the actual payload.

The remote nodes each run a copy of the pollee sketch, which is even simpler:

Screen Shot 2011 11 24 at 12 37 07

They just wait for an empty incoming packet addressed to them, and reply with the data they want to get across. I just send the node ID and the current time in milliseconds.

Here is the result, with one poller and three pollee’s:

    1: 36974
    2: 269401
    3: 10128
    1: 36992
    2: 269417
    3: 10145
    1: 37009
    2: 269434
    3: 10163

As you can see, each node gets one packet across about once every 17 ms (this will slow down if more data needs to be sent). So that’s 6 short packets flying through the air every 17 ms, i.e. ≈ 350 packets per second.

There are ways to take this further, at the cost of extra complexity. One idea (called TDMA), is to send out one poll packet to line up the remote’s clocks, and then have them send their payload a specific amount of time later. IOW, each node gets its own “time slot”. This reduces the 6 packets to 4, in the case of 3 remote nodes.

No more collisions, but again: this will block every other transmission attempted on the 868 MHz band!

JeeMon for early birds

In Software on Nov 25, 2011 at 00:01

Time to dive in. Let’s create a development setup for JeeMon on Mac OSX, in a new folder called “jee”:

    cd ~/Desktop
    git clone git://git.jeelabs.org/jeerev.git jee
    cd jee
    wget https://jeelabs.org/pub/jeemon/jeemon-macosx.zip
    unzip jeemon-macosx.zip

That gives me the following files:

Screen Shot 2011 11 23 at 23 21 47

There is more here than strictly needed for production use – just ignore most of this for now. The main bits are “jeemon” and the “kit/” sub-folder with all the JeeRev code in it.

On Linux, the commands will be almost the same, but you’ll need to get a different JeeMon zip file.

Since I don’t use Windows myself, I’ll have to rely on help / support from others (yes, you!) to get the details right. Thanks to @tankslappa, here’s a first report of an install on XP SP3:

cd %homepath%\desktop
“C:\Program Files\Git\bin\git” clone git://git.jeelabs.org/jeerev.git jee
Cloning into jee…
remote: Counting objects: 1810, done.
remote: Compressing objects: 100% (670/670), done.
remote: Total 1810 (delta 1187), reused 1742 (delta 1119)
Receiving objects: 100% (1810/1810), 1.45 MiB | 87 KiB/s, done.
Resolving deltas: 100% (1187/1187), done.
cd jee
wget https://jeelabs.org/pub/jeemon/jeemon-win.zip

Then unzip using your favorite zip manager, and you should be good to go (I’ll optimize further, one day).

Note: on Mac OSX and Linux, if “.” is not in your path, you’ll need to add it or type “./jeemon” i.s.o. “jeemon” everywhere it is mentioned below.

At this point, JeeMon is ready for use. There are a few built-in commands – here’s a quick sanity check:

    jeemon env general

The output provides some general details about the current runtime environment:

    GENERAL:
           JeeMon = v1.5
          Library = /Users/jcw/Desktop/jee/kit
         Encoding = utf-8
        Directory = /Users/jcw/Desktop/jee
       Executable = /Users/jcw/Desktop/jee/jeemon
      Tcl version = 8.6b1.1

If you got this far, then everything is working as intended. If not: you’ve hit a bug – please get in touch.

But the normal procedure is to simply launch it:

    jeemon

If this is the first time, you’ll get something like this:

    No application startup code found.
    21:22:29.157      app is now running in first-time configuration mode
    21:22:29.189      web server starting on http://127.0.0.1:8181/

Where “first-time configuration mode” means that JeeMon didn’t find a “main.tcl” rig, which is normally used to start up. To get past this step, you need to point your web browser to the indicated URL, which’ll show this page:

Screen Shot 2011 11 23 at 21 28 54

There’s not much point in selecting anything else but “YES”at this stage. This creates a 3-line “main.tcl” file:

    # default JeeMon startup file
    Log main.tcl {in [pwd]}
    Jm needs HomeApp

From now on, JeeMon will start up using the built-in “HomeApp” rig when there are no command-line args.

The next steps depend on what you’re after – you can either dive into Tcl programming and explore how JeeRev (i.e. the kit/ area) is structured, or you can try out some examples and get a more top-down impression of it all.

To explore Tcl, the thing to keep in mind is that JeeMon will act as a standard no-frills Tcl 8.6 programming environment when launched with a source file as argument (just like tclsh and tclkit). Here’s how to make a hello-world demo – create a file called “hello.tcl” with your favorite text editor and put the following code in it:

    puts "hello, world"

Then run that code using the command “jeemon hello.tcl“. You can probably guess what it does…

If you want to use a convenient interactive shell with scrollback, history, and debugging support, download the TkCon script and launch it using “jeemon tkcon.tcl” – this uses Tk to create a mini IDE.

For Tcl manuals, books, and demos, see http://www.tcl.tk/. To really dive in, check out this tutorial or this.

But chances are that you just want to get an idea of what JeeMon does in the context of Physical Computing, House Monitoring, or Home Automation. I’ll describe just two simple examples here, and will point to the JeeMon homepage for the rest. Note that everything described below is really part of JeeRev, i.e. the standard library used by JeeMon – or to put it differently, by the source files located inside the “kit/” folder.

First, let’s launch a trivial web server (you can see the code at examples/hello-web/main.tcl):

    jeemon examples/hello-web/

You’ll see a log output line, similar to this:

    18:23:46.744      web server starting on http://127.0.0.1:8181/

JeeMon is now running in async event mode, and keeps running until you force it to stop (with ^C, kill, whatever). Leave it running and go to the indicated URL in your browser. You’ll be greeted with a web page generated by JeeMon. Hit refresh to convince yourself that it really works.

Now quit JeeMon and check out the files in the “examples/hello-rf12/” folder. This example connects to a JeeNode/JeeLink running the RF12demo sketch, and displays incoming packets via its web server. But before launching JeeMon, you have to tell it what serial interface (COM or tty port) to use: copy “config-sample.txt” to “config.txt” and edit it to match your setup. Make sure the JeeNode/JeeLink is plugged in, then start JeeMon:

    jeemon examples/hello-rf12/

The output will look something like this:

    18:37:57.166      web server starting on http://127.0.0.1:8181/
    18:37:58.154    rf12? [RF12demo.8] A i1* g5 @ 868 MHz 
    [...]

And two dozen more lines which you can ignore. Now go to that same URL again with your web browser. If your config file defines the proper net group and you have some JeeNodes sending out packets in that net group, you’ll see them in your browser after a while. This is what I got within a few minutes, here at JeeLabs:

    #1 18:42:21 - OK 19 186 200 8 1 226 2 32 0 0 213 81 33
    #2 18:42:31 - OK 19 186 200 8 1 226 2 32 0 0 213 81 33
    #3 18:42:44 - OK 3 132 43 9 0
    #4 18:42:51 - OK 19 186 200 8 1 226 2 32 0 0 213 81 33
    #5 18:43:11 - OK 19 186 200 8 1 226 2 32 0 0 213 81 33
    #6 18:43:21 - OK 19 186 200 8 1 226 2 32 0 0 213 81 33
    #7 18:43:29 - OK 6 1 95 212 0
    [...]

Now might be a good time to look at the code in examples/hello-rf12/main.tcl – to see how it all works.

Wanna experiment? Easy: quit JeeMon, create a new directory “blah“, and copy the files from the example to it. Edit them as you like, then start JeeMon using “jeemon blah“. Go ahead, try it! – the worst that can happen is that you get error messages. Usually, error tracebacks will refer to JeeRev files in the “kit/” folder.

This concludes my intro for those who want to get their feet wet with JeeMon. We’ve only scratched the surface!

I’ll work out more examples on the JeeRev page as I start building up my own setup here at JeeLabs. If you want to try things and run into trouble (there will be rough edges!) – here are two places to post problems and bugs:

Feel free to ask and post anything else on the forum. If it gets out of hand, I’ll set up a separate area for JeeMon.

A quick note about the Shop: I’m running into some shortages across the board (such as wire jumpers), which also affect the JX and WSP packs. All the missing bits are on order, but some of this might not get in before early December. My apologies for the delay and inconvenience! -jcw

JeeRev sits under the hood

In Software on Nov 24, 2011 at 00:01

Here’s another post about the JeeMonBusRev trilogy, i.e. the JeeMon project I started a few years ago.

First, let me go into why there are still two pieces and two names left in this project:

  • JeeMon is two things at once: the name of the entire system, and the name of the executable file to start it up. This exe file contains a general-purpose set of tools – it has no clue about Physical Computing or Home Automation. It could as well be used to build an accounting system or a CAD system… if you wanted to.

  • JeeRev is the name of the software which extends the JeeMon executable for domain specific use, i.e. its run time library. This is where the code lives which does know very specifically about Physical Computing and Home Automation. This is also where all the (software development) action is.

Do these names stand for anything? Yeah, probably – but I’ve stopped agonizing about cool acronyms.

JeeRev is used by JeeMon in one of two ways:

  • Development mode – as a “kit/” folder full of source files, which JeeMon will automatically detect and use. This is what you get when you grab the code from GitHub. Easy to browse, tweak, and keep up-to-date.

  • Production mode – as a single file called “jeemon-rev“. Normally, JeeMon will automatically download the latest official version of that file if it doesn’t exist yet (if there’s no “kit/” folder to put it in development mode). End users (i.e. normal people!) don’t care about JeeRev. They just download and launch JeeMon.

The precise startup process is fully configurable – it’s documented in JeeMon’s README file on GitHub.

I suggest forgetting about production mode for now. It’s not going to matter for quite some time, even though that aspect has had a major effect on the “structural design” of JeeMon. For now, everything will be happening in development mode, with JeeRev fully exposed – like a car kept in the garage with the hood open, so to speak.

To expose what’s in JeeRev, I have to describe one more mechanism – which is the way the different pieces of an application work together in JeeMon. Since I don’t know how familiar you are with recent implementations of Tcl, I’ll start from scratch and go through the basics – it’ll be easy to follow if you know some programming language:

Commands – everything in Tcl is based on commands. The line < puts "hello, world" > (without the <>’s) is treated as a call to the command puts with one argument. The difference with older versions of Tcl, is that commands can also be namespaces (it’s actually the other way around, and they’re called “ensembles”, but let’s not be picky for now). That means that a command such as the following can mean different things:

    Interfaces serial connect $device 57600

The simplest case would be that there is a command called “Interfaces” which gets called with 4 arguments. So you might expect to see a command definition somewhere in the code, which looks like this:

    proc Interfaces {type action device baudrate} {
      ...
    }

But there is another interpretation in Tcl 8.6 (and 8.5): it can also be used to call a “serial” command defined in the “Interfaces” namespace. And in this particular case, it’s in fact nested: a command called “connect” defined in the “serial” namespace, which in turn is defined in the “Interfaces” namespace. Perhaps like this:

    namespace eval Interfaces {
      ...
      namespace eval serial {
        ...
        proc connect {device baudrate} {
          ...
        }
        ...
      }
      ...
    }

Or, more succinctly:

    proc Interfaces::serial::connect {device baudrate} {
      ...
    }

This is like writing “Interfaces.serial.connect(…)” in Python, Ruby, or Lua. But not quite – it’s slightly more general, in that callers don’t need to know how code is structured to be able to perform certain operations. It also allows you to alter the internal organization of the code later, without having to change all the calls themselves. But it can also be a bit more tricky, because you can’t tell from the appearance of a call where the actual code resides – you have to follow (or know) the chain in the code.

This is a fairly important concept in Tcl. The command “a b c d e” can lead to very different code paths (even in the same app, if things are added or re-defined at run-time), depending on whether and how “a”, “b”, etc are defined. At some point, the command name lookup “stops” and the arguments “begin”.

Apologies for the lengthy exposé. I really had to do this to introduce the next concept, which is…

Rigs – this is a mechanism I’ve been refining for the past few years now, which unifies the above nesting mechanism with the way code is arranged in source files. To continue the Interfaces example: there’s a file in JeeRev called serial.tcl, and inside is – as you would expect – a “proc connect …” definition.

The point is: that “serial.tcl” source file is located in a folder called “Interfaces”. So the nesting of command detail is reflected in the way files and folders are organized inside the “kit/” area, i.e. JeeRev.

If you’re familiar with Python, you’ll recognize the module mechanism. Yep – “rigs” are similar (not identical).

Some rig conventions: 1) definitions starting with lowercase are public (i.e. “serial” and “connect”), whereas everything else is considered private to that rig, 2) “child” rigs can access the definitions in their “parent” rigs, and 3) if you don’t like the way a built-in rig works, you can supply your own and completely override it.

If you look at this in objected-oriented terms: rigs are essentially singletons, like Python / Ruby / Lua modules. Speaking of objects: the result of the “Interfaces serial connect …” call is a connection object – Tcl 8.6 finally includes a single OO framework (there used to be tons!), so things are becoming a lot more uniform in Tcl-land.

Thanks for reading this far, even though I haven’t said anything about what’s inside JeeRev yet.

But with this out of the way, that’s easy: JeeRev consists of a collection of rigs, implementing all sorts of features, such as serial communication (serial), a web server (Webserver), logging (Log), config files (Config), and the very important “state manager” (State) which provides an event-based publish / subscribe mechanism for representing the state of sensors and actuators around the house. There is a rig which manages automatic rig loading for JeeMon (Jm), and one which has some utility code I didn’t know where else to put (Ju).

There’s a rig called “app”, which orchestrates startup, general flow of events, and application-wide event “hooks”. This hook mechanism is similar to the Drupal CMS (written in PHP) – because good ideas deserve to prosper.

And lastly, if you supply a rig called “main”, then this will become the first point where your code can take control.

I can’t go into much more detail in this post, but I hope it gives an idea of the basic design of JeeMon + JeeRev.

Tomorrow, I’ll close this series with details about getting started with JeeMon – for those who care and dare!

What’s in the yellow box?

In Software on Nov 23, 2011 at 00:01

So much for the big picture – but what’s this JeeMon?

JeeMon yellow

JeeMon ties stuff together – it can talk to serial and network interfaces using event-driven asynchronous I/O. This means that it can talk to lots of interfaces at the same time (like what the Twisted framework does in Python, but more deeply integrated into the system).

JeeMon collects data – it includes a column-oriented embedded and transactional database. This means that it can store lots of measurement data in a very compact format, using variable int sizes from 1 to 64 bits (usually an order of magnitude smaller than SQL databases, which add extra overhead due to their generality and are less suitable for repetitive time-series data).

JeeMon talks to browsers – it has an efficient embedded co-routine based web-server. This means that it can be used with web browsers, delivering rich user interfaces based on JavaScript, HTML 5, CSS 3, Ajax, and SSE. By pushing the logic to the browser, even a low-end JeeMon server can create a snappy real-time UI.

JeeMon likes to network – with the built-in event-based background network support, it’s easy to connect to (or provide) a range of network services. This lets you do remote debugging and create distributed systems based on JeeMon, as well as extract or feed information to other network-based systems.

JeeMon has a pretty face – on desktop machines running Windows, Mac OSX, or Linux, the “Tk” toolkit is included to quickly create a local user interface which does not require a browser. This means that you can create distinctive front panels showing real-time data or perhaps extensive debugging information.

JeeMon is dynamic – it is based on the 100% open source Tcl scripted programming language, which is used by several Fortune 100 companies (if that matters to you). This means you can work in a mature and actively evolving programming environment, which gets away from the usual edit-compile-run cycle. Making changes in a running installation means you don’t have to always stop / restart the system during development.

JeeMon is general-purpose – the structure of JeeMon is such that it can be used for a wide range of tasks, from quick command-line one-offs to elaborate long-running systems running in the background. This is possible because all functionality is provided as modules (“rigs”) which are loaded and activated on-demand.

Technically, JeeMon consists of the following parts:

  • the Tcl programming language implementation
  • (on desktop versions) the Tk graphical user interface
  • support for serial interfaces, sockets, and threads
  • the Metakit embedded database (by yours truly)
  • co-routine based wibble web server, by Andy Goth
  • upgrade mechanism using Starkits (by yours truly)
  • domain-specific code, collectively called JeeRev

That last item is the only part in this whole equation which is in flux. It creates a context aimed specifically at environmental monitoring and home automation. This is the part where I keep saying: Wait, it’s not ready yet!

Tomorrow, I’ll describe what’s inside this “JeeRev” …

JeeMon? JeeBus? JeeRev?

In Software on Nov 22, 2011 at 00:01

For several years now, I’ve been working on a software project on the side, called JeeMon. Then something called JeeBus was created, and then JeeRev came along.

That’s a lotta names for a pile of unfinished code!

I’d like to explain what it’s all about, and where I want to take this (looking back is not so interesting or useful).

The Big Picture ™

With monitoring and control in the home and <cough> Home Automation </cough>, the goal is quite simple, really: to figure out what’s going on in the house and to make things happen based on events and rules.

In a nutshell: I want energy consumption graphs, and curtains which close automatically when it gets dark.

There are no doubt roughly one million different ways to do this, and ten million implementations out there already. JeeMon adds one more to the mix. Because I’ve looked at them all, and none of the existing ones suit me. Call it “Not Invented At JeeLabs” if you like, but I think I can help design / build a better system (please remind me to define “better” in a future weblog post, some day).

I’ve pondered for some time on how to present the big picture. Threw out all my initial attempts. This says it all:

Jeemon context

Let’s call the yellow box… JeeMon ! Forget about JeeBus. Forget JeeRev (it’s still there, under the hood).

JeeMon is the always-on software “switchboard” which talks to all this hardware. It can run on a dedicated little server box or on the router. The devices can be connected via serial, USB, Ethernet, WiFi, FSK, OOK, whatever.

Functionality & Features

The primary tasks of JeeMon are to …

  1. track the state of sensors around the house
  2. display this real-time state via a built-in web server
  3. interface to remotely operated devices around the house
  4. present one or more web pages to control these devices
  5. act as a framework which is easy to install, configure, use, and extend

Everything is highly modular, JeeMon is based on drivers and other extensions – collectively called “features”.

Some other tasks which are a natural fit for JeeMon:

  • configuration of each sensor, device, and interface involved
  • collecting and saving the full history of all sensor data and control actions
  • presenting a drill-down interface to all that historical data
  • managing simple rules to automatically make things happen
  • access control, e.g. to prevent “junior” from wreaking havoc

That’s about it. It’s that simple, and it needs to be built. JeeMon has been “work in progress” for far too long.

Transformers – part 2

In Hardware on Nov 21, 2011 at 00:01

Yesterday’s post described a new test setup to be able to safely experiment with low- to medium-range AC voltages. As a first check when working on new AC mains powered circuits, and to allow me to poke around.

The main idea is to use a few small transformers to create relatively weak AC power sources with a range of different voltage outputs. Here’s one way to connect their six secondary windings together:

Transformers in series

The key safety feature is the connection to ground. Anchoring the middle of the output signal to ground effectively halves the voltage when you touch one of the outputs. It also (sort of) centers the sine wave around earth ground.

Note that touching both ends of the 6 series-connected secondaries will still cause a scary 148 VAC jolt.

To make this more convenient to test with, a double-pole 11-position rotary switch will be used (the best I could find for a reasonable price). This will allow me to switch between each of the above voltages, as well as 0V.

Every position up to 92V will have at most 56V to ground, the highest two positions will make that 74V and 84V, respectively (through secondary coils designed to supply at most 20 mA). I’ll consider up to 46V to be safe.

Here are the parts I got from DigiKey – and how I would like to arrange it all:

DSC 2797

Next step is to come up with a nice box for it – the work never ends!

Transformers!

In Hardware on Nov 20, 2011 at 00:01

(No, not comic strips or movies…)

With 230V experiments becoming more commonplace here at JeeLabs, I’m worrying about safety again. It doesn’t take much to get sloppy once you do things over and over. But sloppiness and 230V don’t mix well!

Given the recent trials, and some great comments, I’d like to get back to a safer voltage level for day-to-day testing. Using the isolation transformer only for incidental cases because no matter what, 230V is tricky.

According to Wikipedia, a “safe” voltage is 50 VAC or less. According to another page, it’s even lower: 30 VAC.

Until now I’ve been using my lab supply, which goes up to 30 VDC. But that’s limited, and more importantly it doesn’t let me see the effects of AC rectification and ripple. It’s time to come up with a better test setup:

JC s Doodles page 25

A couple of small well-insulated PCB transformers, one rated 2x 18V @ 45 ma and two with 2x 28V @ 20 mA secondaries, respectively. The 18V and 28V secondaries are completely safe (by themselves) – they might damage a circuit, but they won’t harm me.

When combined, these can produce from 18 to 148 VAC. Note that 148 VAC is still over 400 Volts peak to peak, so this is serious stuff. The best way to keep the risks down is still to use low voltages as much as possible, of course.

One reason why these voltages are less risky than AC mains, is that the output current is very limited. I picked the weakest transformers I could find, meaning that their secondary coils have a high internal resistance and small magnetic cores. That and magnetic saturation should keep maximum currents limited to 20..30 mA.

Tomorrow I’ll describe a convenient hookup for all these little power sources.

Zeners – success!

In Hardware on Nov 19, 2011 at 00:01

In yesterday’s post, I reported how the 4.3V zener diode wasn’t quite cutting it – it wasted too much power.

But the new setup described in that post (12V zener w/ 100 µF cap from a 0.4 mA input trickle) works great:

DSC 2783

Note how the supply voltage recovers from a packet send within a mere 0.2 seconds. What I’m hoping now, is that with a capacitive supply on 230V, the average power supply consumption will end up well under 0.1 W.

This experiment was done with almost the same sketch as before – running on a standard JeeNode for now:

Screen Shot 2011 11 17 at 03 22 27

Every 10 seconds, a dummy packet gets sent out – as this receiving node shows:

    OK 4 0 0 0 0 0 0 0 0
    OK 4 0 0 0 0 0 0 0 0
    OK 4 0 0 0 0 0 0 0 0

And it keeps on going as long as the 0.4 mA trickle is on. It turns out that the energy consumption is so low that it will keep running for quite a while on a single 100 µF charge, before crashing into some indeterminate state:

DSC 2784

Note the time scale: 10 s/div – enough to send out six valid packets!

There’s still some nastiness to get startup reliable. I’ll probably need to mess with the BOD fuse setting and perhaps also power up with the 8x prescaler enabled, to be absolutely sure that the JeeNode doesn’t start drawing too much current before there is sufficient energy in the 100 µF capacitor.

For kicks, I tried pushing things to the limit: with a 10 µF cap, plus the 10 µF on board the JeeNode, the sketch still works, but each packet transmissions now drops the supply to a dangerously low level of about 3.7V:

DSC 2786

Eventually, sailing this close to the edge causes the node to fall into some sort of zombie state. But as you can see, it now takes only 50 mS to recharge this cap @ 0.4 mA. So could that trickle feed be reduced to – gulp – 0.04 mA? This is getting silly, but first I must get that power-up logic fixed – right now, the JeeNode isn’t starting reliably.

Anyway. It’s mind-boggling how little energy is needed to get a little bit of info across the house!

PS. I’ll stop posting oscilloscope snapshots for a while. There’s more to this weblog than scopes and signals…

Zeners?

In Hardware on Nov 18, 2011 at 00:01

If you recall the 6800 µf supply test, I used the following setup:

The problem was that this uses a 10 mA supply current as test, which is 10x higher than I want for the final 220V capacitive transformer-less version.

Trouble is, increasing the resistor to 22 kΩ didn’t work, there wasn’t enough juice to keep the JNµ running.

In a comment, Koen remarked that it might be due to the zener soft “knee”. Zeners are not perfect, they tend to cut off the voltages at a specified point, but it really depends on how much current flows. With too little current, the zener-like properties are in fact far less pronounced. Here’s what I measured, roughly:

  • 2.7 V @ 0.25 mA
  • 2.9 V @ 0.5 mA
  • 3.2 V @ 1 mA
  • 3.8 V @ 5 mA
  • 4.0 V @ 10 mA

That’s a lot of variation. In the case of the ultra-low power supply where very little current flows once the capacitor has been charged, it looks like a 1 mA “trickle” feed is not getting the energy to the right spot. Aha, found it:

Zener knee

Those zener diodes under 6V are pretty leaky! Unfortunately, I can’t seem to find any with better specs.

Time to try something else. How about the forward voltage drop of a regular diode? After all, that’s supposed to be somewhere in the range of 0.6 .. 1.0 V.

Here’s what I got with 5x the 1N4004 diode in series, and connected in conducting mode:

  • 2.6 V @ 0.25 mA
  • 2.75 V @ 0.5 mA
  • 2.9 V @ 1 mA
  • 3.1 V @ 2 mA
  • 3.3 V @ 5 mA
  • 3.45 V @ 10 mA

Hm, looks like that’s already a lot better! Next test is to replace the zener in the above circuit with 7x an 1N4004. With a bit of luck, that might provide a voltage in the proper range for the unregulated JNµ. Here’s what I get:

DSC 2777

Not bad! The 470 µF 6.3V cap charges up to 3.8 V in about 2 seconds.

Even better is that with a 4.7 kΩ simulated 0.65 mA load, the voltage drops a bit but still stabilizes at ≈ 3.15 V.

There is a major drawback, though: the forward drop over a diode tends to be very temperature-dependent :(

Here’s an idea for a different approach: add a regulator and let the capacitor charge up to say 12V. That would give a lot more energy to draw from, even if a sizeable portion of those milliwatts get “wasted” as heat. Also, it turns out that the 12V zener I used (1N5242) has a considerably better behavior – less than 10 µA when I drop 0.1 V under the zener voltage (11.8V in the unit I tested), whereas the 4.3V zener eats up most of a 1 mA trickle feed.

And lastly, there’s the idea of tracking the supply voltage with the ATmega/ATtiny itself, to let it decide when to delay a power-hungry transmission. After all, the micro-controller is able to turn itself from a 10 µA to a 30 mA power consumer, just by changing its own mode and the RFM12B from mostly power-down to full-power.

Theoretically, an MPU could in fact regulate the power supply voltage by “modulating” its current consumption!

Ok, so the new target I’d like to aim for as ultra-low power source will be: 0.01 µF X2 cap (a mere 0.4 mA trickle), 12V zener, MCP1703 regulator, and an even smaller 100 µF 16V cap, since there’s a lot more voltage drop available if you start from a full charge @ 12V. Will it work? Well, there are some surprises ahead – stay tuned…

AC Mains measurements

In Hardware on Nov 17, 2011 at 00:01

One of the things I ordered recently was a High-voltage Differential Probe. The reason for this is that I want to be able to view signals which are tied directly to 230V AC mains, both isolated and directly connected.

That’s – d a n g e r o u s – stuff, unfortunately.

And I intend to do this absolutely safely. My own safety first, of course. But also the safety of all the circuits I’m messing about with. One important trick is to simplify: the shorter the checklist of things I need to deal with, the more concentrated I can stay on the task and its risks.

With a multimeter, measuring 230V stuff goes as follows: disconnect all power, attach the multimeter, put it in the right mode, check that nothing touches anything it shouldn’t (and that all connections are solid!), stand back, turn on the power, read out the measurement, and power down again.

That’s already more than enough to worry about. Now imagine hooking up an oscilloscope and adjusting its knobs to get a good readout. Too many risks, potential for mistakes, and wires going all over the place!

I use the isolation transformer as much as possible. The voltages are still just as high between the two mains pins, but at least an accidental single connection to me or anything else isn’t a problem. The worst that can happen is a blown fuse, which in the case of the isolation setup is resettable and is set to go off at 4 amps.

Trouble is, an oscilloscope normally measures between its probe input pin and ground. Yes, ground!

One way to deal with that is to power the scope through an isolation transformer. But that’s actually one of the most dangerous “solutions” one could think of, because that means you lose all safety nets of having a safe ground attached to the instrument, its case, its probe’s BNC connectors, etc. I want more safety, not less!

Luckily, there’s a much better way to do this – but at €200 it’s not cheap:

DSC 2776

This is an isolated differential probe, which I got from BitScope. The box is 20 cm long, so it’s quite large.

Looks like there’s a fair bit of circuitry in there, too:

DSC 2773

It’ll run off an internal battery (which I just added) or off the included 9V power brick.

The point of all this is that you can put any voltage up to 1000 V between the two input pins, and that both of the pins can be up to 600 V “away” from ground potential. Yet the output will still stay within 6.5V of the scope’s ground level. The differential aspect is that it doesn’t care what the common-mode voltage excursions are, i.e. it’ll ignore any voltage which happens to be present on both inputs – only the difference is passed through.

With this probe, all you need to think about is the high voltage on the circuit and on the test leads. And as you can see, it comes with some very well-isolated cables, (huge!) clips, and test hooks. The specs are as follows:

Screen Shot 2011 11 15 at 23 05 28

The 20x range is nice for low-voltage measurements on AC-connected stuff, such as the output of a switching regulator: a scope set to 1 mV/div will be able to display signals from this probe at 20 mV/div, which is enough to view power supply ripple, for example.

Here’s a first test, simply viewing the 230V mains:

DSC 2775

Note that the vertical scale is 200x higher than indicated on this snapshot, i.e. 100 V/div (230 VAC RMS ≈ 325 VAC peak). The voltage shown here is definitely not a 100% pure sine wave – I have no idea why.

Onwards! (with caution)

Wait… make that 470 µF

In Hardware, Software on Nov 16, 2011 at 00:01

Yesterday’s post used a 6,800 µF capacitor as charge reservoir for stored energy. But wait, we can do better…

Now that I understand how discharge works out with the JeeNode in transmit mode, it all becomes a lot easier to handle. With a relatively small 470 µF 6.3V cap (still charged at 10 mA for now), I see this behavior:

DSC 2752

It’s running on 1000 x less charge than the 0.47 F supercap I started out with! Here’s the actual sketch:

Screen Shot 2011 11 03 at 01 09 37

First of all, the payload sent is now 8 bytes. Probably a reasonable amount for many uses (such as AC current sensing). Also, I’m now sending a single “a” character at the same time as the rest starting up, so there’s no need to wait for it – sending will overlap everything else that’s going on. Debugging comes for free, in this case.

What the scope shows, I think, is that the RFM12B needs about 1.6 ms to start a transmission, and that the transmission takes about 3.4 ms. The rf12_canSend() call probably returns true right away, since the RFM12B has just been woken up (this also means there’s probably no “listen before send” carrier detect in this test!).

Let’s zoom in a bit further…

DSC 2753

Ah yes, that actually makes a lot of sense (the channel 1 scale is actually 10 mV/div, not 100, and AC coupled):

  • ≈ 1 ms before “time is up”, the loseSomeTime() code switches to idle mode and draws a bit more
  • the start bit of the “a” is sent out the moment the loseSomeTime() code returns
  • brief high power consumption as the transmision is also set up and started
  • for roughly 2 ms, the RFM12B is initializing, not drawing much current
  • meanwhile, the ATmega is in rf12_sendWait(), in a relatively low-power mode
  • once transmission actually starts, a lot more current flows and the cap discharges
  • note the little bumps “up” – there’s probably a bit of inductance in the circuit!

All in all, the voltage drop is about 0.2 V, which is ok – especially in this setup, i.e. a JeeNode plus regulator.

Now, all that’s left to do is get the charging current as low as possible. I tried a 22 kΩ resistor, i.e. a 1 mA charge current, but that’s too weak right now: the voltage drops off and the node stops functioning. Looks like the JeeNode (yes, JN, not JNµ yet) is not quite in the ultra low-power mode I thought it was.

Oh, well. More work needed, but progress nevertheless!

Running off a 6800 µF cap

In Hardware, Software on Nov 15, 2011 at 00:01

The running on charge post described how to charge a 0.47 Farad supercap with a very small current, which drew only about 0.26 W. A more recent post improved this to 0.13 W by replacing the voltage-dropping resistor by a special “X2” high voltage capacitor.

Nice, but there was one pretty awkward side-effect: it took ages to charge the supercap after being plugged-in, so you had to wait an hour until the sensing node would start to send out wireless packets!

As it turns out, the supercap is really overkill if the node is sleeping 99% of the time in ultra low-power mode.

Here’s a test I did, using a lab power supply feeding the following circuit:

JC s Doodles page 21

The resistor is dimensioned in such a way that it’ll charge the capacitor with 10 mA. This was a mistake – I wanted to use 1 mA, i.e. approximately the same as 220 kΩ would with AC mains, but it turns out that the ATtiny code isn’t low-power enough yet. So for this experiment I’m just sticking to 10 mA.

For the capacitor, I used a 6,800 µF 6.3V type. Here’s how it charges up under no load:

DSC 2745

A very simple RC charger, with zener cut-off. So this thing is supplying 3.64 V to the circuit within mere seconds. That’s with 10 mA coming in.

Then I took the radioBlip sketch, and modified it to send out one packet every second (with low-power sleeping):

DSC 2746

The blue line is the serial output, which are two blips caused by this debug code around the sleep phase:

Screen Shot 2011 11 02 at 17 30 23

This not only makes good markers, it’s also a great way to trigger the scope. Keep in mind that the first blip is the ‘b’ when the node comes out of sleep, and the second one is the ‘a’ when it’s about to go sleeping again.

So that’s roughly 10 ms in the delay, then about 5 ms to send the packet, then another 10 ms delay, and then the node enters sleep mode. The cycle repeats once a second, and hence also the scope display refresh.

The yellow line shows the voltage level of the power supply going into the JeeNode (the scale is 50 mV per division, but the 0V baseline is way down, off the display area). As you can see, the power drops about 40 mV while the node does its thing and sends out a packet.

First conclusion: a 6,800 µF capacitor has plenty of energy to drive the JeeNode as part of a sensor network. It only uses a small amount of its charge as the JeeNode wakes up and starts transmitting.

But now the fun part: seeing how little the voltage drops, I wanted to see how long the capacitor would be able to power the node without being “topped up” with new charge.

Take a look at this scope snapshot:

DSC 2747

I turned on “persistence” so that old traces remain on the screen, and then turned off the lab power supply. What you’re seeing is several rounds of sending a packet, each time with the capacitor discharged a little further.

The rest of the time, the JeeNode is in ultra low-power mode. This is where the supply capacitor gets re-charged in normal use. In that last experiment it doesn’t happen, so the scope trace runs off the right edge and comes back at the same level on the left, after the next trigger, i.e. 1 second later.

Neat huh?

The discharge is slightly higher than before, because I changed the sketch to send out 40-byte packets instead of 4. In fact, if you look closely, you can see three discharge slopes in that last image:

JC s Doodles page 21

A = the first delay(10) i.e. ATmega running
B = packet send, i.e. RFM12B transmitting, ATmega low power
C = the second delay(10), only ATmega running again

Here I’ve turned up the scale and am averaging over successive samples to bring this out more clearly:

DSC 2750

You can even “see” the transmitter startup and the re-charge once all is over, despite the low resolution.

So the conclusion is that even a 6,800 µF capacitor is overkill, assuming the sketch has been properly designed to use ultra low-power mode. And maybe the 0.13 W power supply could be made even smaller?

Amazing things, them ATmega’s. And them scopes!

A “beefy” power supply

In Hardware on Nov 14, 2011 at 00:01

In a comment on the daily weblog, Jörg pointed to a very interesting chip which can directly switch 220 V.

All the parts are available as through-hole, so I decided to give it a go:

DSC 2743

I used the LNK302, with a 2.00 kΩ / 2.32 kΩ 1% resistance divider to select the output voltage. At the left there’s a fusible 100 4700 Ω resistor, a diode, and a 3.3 µF (400V!) electrolytic cap for (high-voltage) DC input.

The circuit officially only works with input voltages above 70 V, but that’s a conservative spec. It actually works fine from my 30 VDC lab supply, which means I can safely poke around in it and see how it behaves.

Time to fire up the scope again. Here’s the output with a 1 mA load:

DSC 2736

Channel 1 (yellow) is the output, but AC coupled, i.e. just the fluctuations, while channel 2 (blue) is hooked up to the same pin but in DC-coupled mode.

As you can see, the output is roughly 3.8V with brief but fairly large spikes of almost 0.3V. Basically, the switching chip periodically connects the input voltage to the output (through an inductor, and charging a 100 µF cap).

The fun begins when you start loading the supply a bit. Here’s what it does at 10 mA:

DSC 2737

Similar spikes, at roughly 10 KHz (quite a bit of variation in timing). Now 25 mA:

DSC 2738

More of the same, the repetition rate doubles to around 20 KHz, and the voltage drops a bit. Let’s go for 50 mA:

DSC 2739

It’s getting a bit jittery now, doubling its frequency every once in a while. And here’s 75 mA:

DSC 2741

Nice and steady output, the ripple voltage is under 0.2V now. Still holding at 3.2V.

Can we pull more current out of this circuit? Not really, I’m afraid – see what happens at around 80 mA:

DSC 2742

Going full speed now at around 65 KHz, but there’s simply not enough energy: the output collapses to 1.32 V.

With roughly 70 mA @ 3.2 V, input power consumption is about 20 mA @ 30 V. This isn’t stellar (37% efficiency), but also not really indicative of what it will do at 220 V, since I’m running the chip way out of spec.

I’ll need to do some tests at the full 220 VAC to make sure this behavior is similar under real-world conditions, but from what I can tell, 50..65 mA is probably about the limit of what this circuit can supply at about 3.3V. Which would be plenty for a JeeNode in full transmit mode BTW, including some additional circuitry around it.

One problem is the fairly large ripple voltage. It would be better to dimension the circuit for a 5V output, or even 12V, and then add the usual linear regulator to get it down to 3.3V for the logic circuit. This could actually be quite practical in combination with a small 12V relay (which isn’t affected by such voltage fluctuations).

Note that a circuit like this – even if it were to supply only 5 mA – would be plenty to drive a JeeNode which sits mostly in low-power mode and only occasionally needs to activate its RFM12B wireless module.

So all in all: a very interesting (non-isolated) option!

Update – Also ok on 220 V: 65 mA @ 3.0 V (draws 1.25 W, i.e. 15 %). With 2 mA @ 3.7 V, power consumption is 0.40 W (vs. ≈ 8 mW delivered, i.e. 2 % efficiency). At 80 mA, the voltage drops to 2.5 V – above that it collapses.

Capacitive transformer-less supply

In Hardware on Nov 13, 2011 at 00:01

The first AC-mains powered current node configuration used a resistive transformer-less supply. It took about an hour to charge with no load, and consumed about 0.26 Watt.

This is an improved version, using a capacitor:

JC s Doodles page 20

(Whoops, I see I forgot to draw the 470 kΩ resistor across the 22 nF cap, to discharge it when disconnected!)

The 4.7 kΩ 1/2W resistor limits inrush current – the worst case being when the cap is empty and plugged in at the top of the AC mains cycle. It’s also a “fusible” resistor, meaning that it’ll act as a fuse when overloaded for any reason. This won’t be enough to protect the circuit, let alone a person touching this circuit, but it will prevent a fire in case of a catastrophic short (which could otherwise pull over 16 amps until the mains fuse blows).

As before, it’s charging the supercap – supplying nearly 1V in this case:

DSC 2724

The 470 kΩ resistor right across that yellow 22 nF capacitor quickly drops the residual charge once unplugged.

Charging appears to go a bit faster, but there’s a problem because I’m running the ATtiny with a disabled brown-out detector (BOD). This means the ATtiny isn’t kept in reset as the voltage ramps up. As a result, it’s trying to run even at low voltages (and is bound to malfunction at voltage levels under 1.8V), but more importantly: it’s going to consume current while trying, which will prevent the supercap from charging! Which is is exactly what I see: the supercap voltage is barely rising above 1.34 V.

The BOD is an important hardware feature for circuits like these. It keeps the ATtiny in reset until the power reaches a certain level. That level is configurable for 1.8V, 2.7V, or 4.3V via the ATtiny’s fuses. In this case, 1.8V seems like the proper value to use – it will be too low for the RFM12B module which requires at least 2.2V, but this way the ATtiny can continue to run correctly even at lower levels, and then decide whether it wants to enable the RFM12B or not.

Unfortunately, I’m going to have to improve the sketch first. Right now, it just starts up and tries to do its thing, without consideration for the current voltage. Leaving the unit on for over two hours didn’t lead to a packet transmission, and only got the voltage up to about 1.8 V, whereas it keeps on rising with the ATtiny disconnected. Clearly, the ATtiny needs to become more aware of its current power state before it can act as a reliable AC current sensor. That’s the trouble with ultra-low power systems: it can be tricky to get them right!

Drat, it looks like I just messed up the fuses on the ATtiny, because I can’t reprogram it anymore. That’s the trouble with low pin-count controllers: it’s easy to mess them up!

Time to go back to separate power supply and JNµ test rigs. Let’s not muddle the issues any more than needed.

The good news is that this supply now consumes half of the resistive version, i.e. 0.13 Watt. Note that the power consumption of the resistive version could have been halved as well (see this comment). So in this case, the extra efficiency of the cap seems to be going into supplying a bit more current, i.e. charging the supercap faster.

Progress nevertheless (says the optimist): lower power consumption, faster start-up!

Meet the Slave Plug

In AVR, Hardware on Nov 12, 2011 at 00:01

While fooling around with the ATtiny85 for the first AC current measurement tests, I found that ATtiny85 to be a pretty neat little chip in and by itself.

So why not create a plug for it, eh? Here’s the new Slave Plug:

DSC 2707

It’s all through-hole, so that it’s easy to assemble and easy to replace the ATtiny85 (or other compatible unit).

There are just enough pins to act as a (daisy-chainable) I2C slave and to drive a 6-pin header with 3..4 I/O pins:

Screen Shot 2011 11 08 at 23 14 11

With some care, that header can be made compatible with JeeNode ports, which means that this plug could even be used to act as host for another plug. Sort of an offloaded task for the “main” JeeNode. Or perhaps stand-alone, just to drive that single plug. Note also that the ATtiny85 supports differential ADC and an optional 20x gain stage, so that full scale voltages down to ≈ 55 mV can be measured (using the internal 1.1V bandgap as reference).

Here’s the schematic:

Screen Shot 2011 11 08 at 23 12 50

Pin 1 of the side header can be tied to either PWR (to create a port) or to the ATtiny’s RESET (SJ1).

And the port’s IRQ pin can optionally be connected to the ATtiny’s RESET pin via a solder jumper (SJ2).

Using a fuse setting, the ATtiny’s RESET pin can be turned into an I/O pin, but this means you’ll need a high-voltage programmer to re-flash the chip and lose the normal ISP programmability.

I’ll add it to the shop shortly, along with the other new boards.

It’s called v2, because there has been an (SMD) Slave Plug before, but that never made it into the real world.

Pulsing the LED strip

In Hardware on Nov 11, 2011 at 00:01

With the new LED Node hookup there are some small color changes across the strip. Not a show stopper, but something I’d like to reduce as much as possible anyway, of course. Get ready for more oscilloscope shots…

I hooked up a flexible 5 m RGB LED strip (got plenty of those here), and instead of extending scope probes, decided to simply let the strip dangle on the table and bring the end back near the scope. Why make things any harder, eh?

Here’s is the blue LED pulse, which is the shortest one when trying to produce warm colors. Channel 1 (yellow) is hooked up to the power feed side of the LED strip and channel 2 (blue) to the end:

DSC 2759

Pulses are negative, because LEDs are connected between this signal and +12V. So low means on. Pretty nasty spikes, as you can see. Note also that the end of the strip doesn’t quite pull the blue LEDs down to zero.

Zooming out to see the bigger picture, you can see that the supply voltage (from my lab supply in this case) is also fluctuating due to what is probably the green LEDs being switched:

DSC 2762

Hm, I seem to be off with the voltages for some very strange reason. The supply is 12V, so I was expecting to see twice the amplitudes reported by the scope. After some pondering, it became obvious: there’s noting which will pull the blue LED signal to 12V, since there are three LED voltage drops! So I added a 100 kΩ resistor to +12V:

DSC 2764

Ignore the very slow rise times – a 100 kΩ resistor is a very weak pull-up. But it does explain the voltages seen.

What it means is that those “nasty spikes” seen before are probably not as serious as they seem. This is simply the +12V voltage rail – the odd thing is that the LEDs are placing the signal lines into a mid-level voltage range while nothing is connected (i.e. the MOSFET is open).

Anyway. There’s a small hickup as the MOSFET is brought into conductance, and there’s a large spike when it switches off again (without 100 kΩ). The average current draw from the power supply is 1.66 A in this setup.

Let’s zoom in into that switch-off spike at the end:

DSC 2755

We’re looking at 100 ns/div, i.e. a signal “ringing” at ≈ 10 MHz. This scope has a 60 MHz bandwidth, so I’m not 100% convinced that these results are in the LED Node + strip. The bottom line (a bit hard to see that it’s green) is a math operation, i.e. the difference between channel 1 and 2 – a 6V difference between both ends of the strip!

Then I connected +12V to both ends of the LED strip. The color change was dramatic. The reddish tint at the far end was gone (of course), and I couldn’t really see a reddish tint in the middle of the strip either.

More surprisingly, the current draw jumped to 1.82 A, i.e. some 10% more. It looks like the RGB strip is not dimensioned properly for carrying these types of currents, i.e. for driving a full 5 meter strip in one go.

Here are the two pulse tails with +12V on both ends:

DSC 2758

An even bigger difference, but about half the ringing frequency. Does this mean half the inductance?

It’s extremely difficult to capture the color effects in a photograph. These effects are far less visible in real life, let alone across the room (which has shades for which we seem to correct without any effort). But here goes:

DSC 2769

That’s, from top to bottom: the middle, end, and start of the strip. The +12V line is tied to both ends.

The colors are actually quite pleasant – but I’d still like to tweak it further. One change which comes to mind is to reduce the PWM frequency to perhaps 250 Hz, preferably in Phase Correct PWM mode, which would have the benefit that the blue and green LEDs don’t get switched on and off at the same time (unless their pulse widths are identical, which is unlikely for white tints).

All these scope traces makes one wonder how much RF noise other dimmed LED strips generate – I wouldn’t be surprised if that were the case even in commercial ones.

Onwards!

Pins, damned pins, and JeeNodes

In AVR, Hardware, Software on Nov 10, 2011 at 00:01

(to rephrase Mark Twain …)

There is confusion in the ATmega / Arduino / JeeNode world, as brought to my attention again in the forum.

It all depends on your perspective, really:

  • if you want to connect to pins on the ATmega chip, then you’re after “pin 6”, “pin 17”, and “pin 26”
  • if you want to understand the ATmega data sheet, then you’re after names like “PD4”, “MOSI”, and “PC3”
  • if you want to follow Arduino sketches, then you want “digital 4”, “digital 12 11″, and “analog 3”
  • if you want to plug into JeeNode ports, then you’d prefer “DIO1”, “MOSI on SPI/ISP”, and “AIO4”

They are all the same thing.

Well, sort of. If you’re looking at an SMD chip, the pin numbers change, and if you’re using an Arduino Mega board, some names differ as well. They might also be different if you were to look at older versions of the JeeNode. In short: it’s messy because people come from different perspectives, and it’s unavoidable. There is no relation between “pin 4”, “PD4”, “digital 4”, and “DIO4” – other than that they all mention the digit 4 …

For that same reason, diagrams are not always obvious. For example, this one is nicely informative:

Arduino To Atmega8 Pins

But it doesn’t help one bit when hooking up a JeeNode.

Likewise, this one doesn’t really help if you’re after the pins on the ATmega328 chip or Arduino pin #’s:

Screen Shot 2011 11 08 at 13 02 04

Then there’s this overview, but it’s incomplete – only the DIO and AIO pins are mapped to the rest, in a table:

JN colors

This one from TankSlappa uses the DIP chip as starting point (and creates new abbreviations for DIO1, etc, alas):

Affectation GPIO JeeNode

Each of these diagrams conveys useful information. But none of them seem to be sufficient on their own.

Can we do better? I’ll be happy to take suggestions and make a new – c o n v e n i e n t – one-pager.

Fixing the Arduino’s PWM #2

In AVR, Software on Nov 9, 2011 at 00:01

Yesterday’s post identified a problem in the way different PWM pulses are generated in the ATmega.

It’s all a matter of configuration, since evidently the timers used to generate the PWM signals all run off the same clock signal, and can therefore be made to cycle at exactly the same rate (they don’t have to roll over at the same time for our purposes, but they do have to count equally fast).

The problem is caused by the fact than PWM pins D.5 and D.6 are based on timer 0, which is also used as millisecond timer, whereas PWM pin D.9 is based on timer 1. It’s not a good idea to mess with timer 0, because that would affect the delay() and millis() code and affect all parts of a sketch which are timing-dependent.

Timer 0 is set in “Fast PWM” mode, which is not perfect. So the Wiring / Arduino team decided to use “Phase Correct PWM” mode for timers 1 and 2.

In Fast PWM mode, the timer just counts from 0 to 255, and the PWM output turns high when the counter is in a specific range. So far so good.

In Phase Correct PWM mode, the timer counts from 0 to 255 and then back to 0. Again, the PWM output turns high when the counter is in a specific range.

The phase correct mode counts up and down, and takes twice as long, so that explains why the green LED output runs at half the speed of the others.

Except that… it’s not exactly twice!

Timer 0 wraps every 256 counts, and that should be kept as is to keep the millisecond code happy.

But timers 1 and 2 wrap every 0 -> 255 -> 0 = 511 counts (I think – or is it 510?). Hence the out-of-sync effect which is causing so much trouble for the LED Node.

See also Ken Shirriff informative page titled Secrets of Arduino PWM, for the ins and outs of PWM.

The solution turns out to be ridiculously simple:

    bitSet(TCCR1B, WGM12);

Just adding that single-bit change to setup() will force timer 1 into Fast PWM mode as well. The result:

DSC 2730

This picture was taken with the scope running. The signals are in lock-step and rock solid. More importantly, the result is a perfectly smooth LED light – yippie!

Fixing the Arduino’s PWM

In AVR, Hardware on Nov 8, 2011 at 00:01

The LED Node presented a few days ago, with the software to drive it, has exposed a nasty little problem…

The light has a slight periodic flicker.

Not good, in fact this gets pretty irritating fairly quickly. But how can this be? Each of the RGB colors is dimmed using the ATmega’s hardware PWM, after all – and well above the 50 Hz rate which our eyes could detect!

Luckily, I recently borrowed a oscilloscope from a friend which allowed me investigate this further. This is a Rigol DS5062CA, a predecessor of the popular DS1052E.

So let’s dive in, shall we?

DSC 2727

Channel 1 is tied to the PWM output driving the MOSFET for the green LEDs, and likewise channel 2 is for blue. There is little point in connecting to the PWM for the red LEDs, because these were driven 100%, i.e. not pulsed. The output color is sort-of-warm-white for the PWM ratios used for this test.

The first surprise was the PWM cycle frequency, which turns out to differ for these two PWM channels. The blue LED’s PWM pulse cycles at twice the rate of the green LED’s PWM (shown as yellow trace).

Ah, but wait… it’s not an exact multiple!

This is very easy to see while the scope is auto-triggering, because no matter how I set it up, I can only get one of the channels to stabilize. The other one always keeps moving, meaning that its phase is constantly changing.

The scope has some measurement options, and as you can see the PWM frequencies are not exact multiples (actually, this readout was a bit erratic – sometimes the frequency did get reported as exact multiple).

So what’s happening, is that there is sort of a Moiré effect between the different LED colors, and the difference is small enough that it manifests itself as a slight but very annoying flickering of 1 or 2 Hz, roughly.

I’ve been using analogWrite() to set these PWM values, but it now looks like I’ll have to change the setup and configure the timers and PWM outputs myself. Surely there’s a way to make all the timers count at the same rate?

Here’s another check I did:

DSC 2729

In this snapshot, channel 1 is the same as before, i.e. the PWM output for the green LEDs, while channel 2 is the power supply voltage (AC-coupled, i.e. only showing the fluctuations). You can see how the green LEDs pull the 12V down when turned on, with the blue LEDs presumably pulling it down further twice as often.

Again, the scope’s measurement capabilities come in handy to see the scale of these variations. Nothing extreme really, although I might add a fat capacitor to try and dampen them. I suspect that the combination of the out-of-sync PWMs and these slight power level fluctuations are what’s causing the visible flicker.

As you can see, a Digital Storage Oscilloscope (DSO) – even a basic one! – can be a fantastic diagnostic tool.

There is one more issue with these RGB LED strips:

DSC 2728

If you look closely, you can see that the left side is slightly more yellow and the right side slightly more red. Which is odd, because both strips are driven from the same LED Node, for a total of 5 meter. My explanation for this is that the ≈ 1000 Hz PWM rate, especially the short blue pulses, are being dampened by the strip’s inductance while traveling from the LED Node’s MOSFETs through the left strip to the right strip.

I haven’t tried it, but one way to verify this would be to compare the power signal of the blue LED at the start and at the end of the LED strip. If my theory is correct, then the pulses should look different.

It’s a small effect, but it shows, and I don’t like it at all. I’ve got two ways to solve it, I think: 1) feed the PWM power signals separately to both LED strips, or 2) use two LED Nodes, each directly feeding their own LEDs.

Maybe it’s just the +12V supply line, in which case it’d be enough to connect +12V to the end as well. We’ll see.

Finicky things, them RGB LED strips!

Update – I’ve placed the LED Node between both strips. Color differences are now almost gone, but there’s still a shift-to-red towards the ends, i.e. the high PWM frequency is hampered by signal propagation.

JeeNode USB problems

In Hardware on Nov 7, 2011 at 00:01

A new problem has surfaced with the JeeNode USB v3: it turns out that the most recent units have accidentally been assembled and shipped with a 3.0V regulator instead of the required 3.3V regulator.

This is a problem for two reasons:

  • all attached devices will run at 3.0V instead of 3.3V
  • the ATmega328 runs further out of spec at 16 MHz

The second (older) problem is that the original OptiBoot loader had a bug in combination with the FTDI interface as used on JeeNodes. This has affected a number of people over the past months, but was resolved before the summer by switching to a modified version of OptiBoot on all JeeNode USB’s and JeeLinks (the fix was to change the watchdog timeout from 500ms to 1s). This problem appears to only matter on Windows systems.

Still, these past few weeks, I was surprised to see yet more problem reports on the forum about “not being able to upload a new sketch” – which is how the OptiBoot bug manifested itself.

My hunch is that this new 3.0V regulator mixup can lead to the same problem, but for a different reason: when running at 16 MHz from 3.0V, the ATmega is running out of spec, or in other words: it’s being over-clocked.

Over-clocking works fine, mostly. But not always. It may depend on chip fabrication, operating temperatures, and maybe even on what the chip is doing.

In short: there are probably still a few dozen JeeNode USB’s out there which are not performing properly due to either the OptiBoot bug, or the wrong regulator (probably not both, because the OptiBoot bug was solved before the regulator mixup happened).

How to diagnose these problems

If you have a JeeNode USB which isn’t working as expected, you can take these steps:

  • try to upload a new sketch to it (set the board type to “Arduino Uno”)
  • if that doesn’t work, and you’re certain that you did it right, you can return it

If you can upload sketches (best chances are on Mac and Linux), then you can perform an additional test to check the regulator voltage, by uploading the following sketch:

Screen Shot 2011 11 06 at 21 22 03

This only works on the JeeNode USB, which has a voltage divider connected to analog pin 6.

Now open the serial console and watch the values, reported once a second:

  • with a good 3.3V regulator, they will be about 4200
  • with an incorrect 3.0V regulator, they’ll be ≈ 4600

The 4600 value comes from making an incorrect calculation, due to the assumption that the total input range is 6600 mV, whereas with a 3.0V regulator it is actually 6000 mV. If you change the 6600 to 6000 on a bad unit, it’ll again report about 4200, which is indeed the voltage on the PWR pin when powered from the USB bus through the LiPo charger (even when no LiPo battery is attached).

If you have the wrong regulator, you can of course also return it and I’ll repair it and send it back ASAP. In that case, please return it to the address listed on this page and include your own address so I can send it back.

So what happened?

Well, these units are being assembled in small quantities for me by a third party. Somewhere, someone messed up and placed the wrong chips on the board. These are SMD chips, so after such a mixup happens it’s pretty unlikely that anyone would spot it from the tiny lettering on the regulator. During programming, the power is supplied by the ISP programmer, i.e. the intended 3.3V. And during testing they will probably all have passed because the ATmega’s do tend to work correctly, even when over-clocked to 16 MHz @ 3.0V.

Sooo… I / we messed up, and delivered flawed units. For which I am really sorry, and for which I sincerely apologize. It shouldn’t have happened, but it did. Mr. Murphy decided to drop by, clearly.

I find this deeply embarrassing. I know how frustrating it is (who doesn’t?) when dealing with products which don’t work as expected – as promised, in fact. This post is obviously about damage control. Doing what is needed to address the issue. Not just for now, but also to make sure it won’t happen again. I’ve got some ideas on that, which I hope will have an effect – an invisible one, in that such mishaps will not happen again. Or much less.

Because, let’s face it: mistakes happen.

For a normal business, the way to deal with mishaps like these, is no doubt to improve the QC/QA procedures, install a sense of more accountability and stricter procedures, and basically “improve the system”. This is a slow and costly process. And the way to handle it is to scale up and amortize the expenses. Economies of scale.

But JeeLabs is not a normal business in this respect. Scale is not my goal, sustainability is. Which means that quality and durability is just as important to me as to anyone, but there are no others to “install a sense of more accountability” into. Like any business, I try to pick my suppliers with care, and work with them so we all perform as well as we can, but that’s about it. Problems must be solved at JeeLabs’ current scale of operation.

Maybe it can’t be done, maybe it can. But IMO it’s worth trying, because more small business-like “shops” are being started every day. So why not try and figure out how to produce stuff – good stuff – on a smaller scale?

Anyway. If you’ve got a flawed JeeNode USB, and want to have it fixed ASAP, please return it. New ones will be ready in three weeks, so if you’d rather use it and receive the replacement first, please let me know by email and I’ll send a replacement out once available. If so, there’s no need to send it back before the new one arrives.

Again, my apologies for the mixup. Products are fun – and producing quality products is hard.

Let’s use LEDs

In Hardware on Nov 6, 2011 at 00:01

For many years, we’ve had this fixture + Edison-type incandescent light tube above our front door:

DSC 2708

And it shows… my apologies for the dirty fixture (top) and light bulb (bottom).

That’s a 120 W lamp (it’s 120 cm long!), which used to be on for several hours each evening, day in day out.

Time to move on to a better solution:

DSC 2709

This is a standard RGB LED strip in an aluminum profile with diffuser. It draws about 15 Watt from a 12V LED supply, i.e. an immediate eight-fold improvement over the previous setup. And it didn’t cost me anything, because this unit came from my workbench, where I also switched to a different (LED-based) lighting setup.

It’s now also an excellent candidate for the new LED Node, which includes support for a PIR motion detector and an LDR light sensor. What I’d like is to have this light turn on very dimly once night falls, and then gently ramp up to full brightness when someone is actually at the door. Welcome!

Not there yet: I still need to implement the software – the Achilles’ heel of Physical Computing!

A color-shifting LED Node

In AVR, Software on Nov 5, 2011 at 00:01

Yesterday’s post described the logic which should be implemented in the LED node. It is fairly elaborate because I want to support subtle gradual color changes to simulate the natural sunrise and sunset colors.

Here’s the ledNode sketch – with a few parts omitted for brevity:

Screen Shot 2011 10 27 at 04 56 36

It’s pretty long, but I wanted to include it anyway to show how yesterday’s specifications can be implemented with not too much trouble.

The main trick is the use of fractional integers in the useRamps() routine. The point is that to get from brightness level X to Y in N steps, you can’t just use integers: say red needs to change from 100 to 200 in 100 steps, then that would simply be a delta of 1 for each step, but if blue needs to change from 10 to 20 in exactly the same amount of time, then the blue value really should be incremented only once every 10 steps, i.e. an increment of 0.1 if it were implemented with floating point.

And although the gcc compiler fully supports floating point on an ATmega, this really has a major impact on code size and execution performance, because the entire floating point system is done in software, i.e. emulated. An ATmega does not have hardware floating point.

It’s not hard to avoid using floating point. In this case, I used 32-bit (long) ints, with a fixed decimal point of 23 bits. IOW, the integer value 99 is represented as “99 << 23” in this context. It’s a bit like saying, let’s drop the decimal point and write down all our currency amounts in cents – i.e. 2 implied decimals (€10 = 1000, €1 = 100, €0.50 = 50, etc).

To make this work for this sketch, all we need to do is shift right or left by 23 bits in the right places. It turns out that is only affects the setLeds() and useRamp() code. As a result, RGB values will change in whatever small increments are needed to reach their final value in the desired number of 0.01s steps.

The sketch compiles to just slightly over 5 Kb by the way, so all this fractional trickery could have been avoided. But for me, writing mean and lean code has become second nature, and sort of an automatic challenge and puzzle I like to solve. Feel free to change as you see fit, of course – it’s all open source as usual.

So there you go: a color-shifting LED strip driver. Now I gotta figure out nice ramp presets for sunrise & sunset!

A sketch for the LED Node

In AVR, Software on Nov 4, 2011 at 00:01

The LED Node presented yesterday needs some software to make it do things, of course. Before writing that sketch, I first wrote a small test sketch to verify that all RGB colors worked:

Screen Shot 2011 10 26 at 20 59 17

That’s the entire sketch, it’ll cycle through all the 7 main colors (3 RGB, and 4 combinations) as well as black. There’s some bit trickery going on here, so let me describe how it works:

  • a counter gets incremented each time through the loop
  • the loop runs 200 times per second, due to the “delay(5)” at the end
  • the counter is a 16-bit int, but only the lower 11 bits are used
  • bits 0..7 are used as brightness level, by passing that to the analogWrite() calls
  • when bit 8 is set, the blue LED’s brightness is adjusted (pin 5)
  • when bit 9 is set, the red LED’s brightness is adjusted (pin 6)
  • when bit 10 is set, the green LED’s brightness is adjusted (pin 9)

Another way to look at this, is as a 3-bit counter (bits 8..10) cycling through all the RGB combinations, and for each combination, a level gets incremented from 0..255 – so there are 11 bits in use, i.e. 2048 combinations, and with 200 steps per second, the entire color pattern repeats about once every 10 seconds.

Anyway, the next step is to write a real LED Node driver. It should support the following tasks:

  • listen to incoming packets to change the lights
  • allow gradually changing the current RGB color setting to a new RGB mix
  • support adjustable durations for color changes, in steps of 1 second

So the idea is: at any point in time, the RGB LEDs are lit with a certain PWM-controlled intensity (0..255 for each, i.e. a 24-bit color setting). The 0,0,0 value is fully off, while 255,255,255 is fully on (which is a fairly ugly blueish tint). From there, the unit must figure out how to gradually change the RGB values towards another target RGB value, and deal with all the work and timing to get there.

I don’t really want to have to think about these RGB values all the time though, so the LED Node sketch must also support “presets”. After pondering a bit about it, I came up with the following model:

  • setting presets are called “ramps”, and there can be up to 100 of them
  • each ramp has a target RGB value it wants to reach, and the time it should take to get there
  • ramps can be chained, i.e. when a ramp has reached its final value, it can automatically start another ramp
  • ramps can be sent to the unit via wireless (of course!), and stored in any of the presets 1..99
  • preset 0 is special, it is always the “immediate all off” setting and can’t be changed
  • to start a ramp, just send a 1-byte packet with the 0..99 ramp number
  • to save a ramp as a preset, send a 6-byte packet (preset#, R, G, B, duration, and chain)
  • preset 0 is special: when “saving” to preset #0 it gets started immediately (instead of being saved)
  • presets 0..9 contain standard fixed ramps on power-up (presets 1..9 can be changed afterwards)
  • the maximum duration of a single ramp is 255 seconds, i.e. over 4 minutes

Quite an elaborate design after all, but this way I can figure out a nice set of color transitions and store them in each unit once and for all. After that, sending a “command” in the form of a 1-byte packet is all that’s needed to start a ramp (or a series of ramps) which will vary the lighting according to the stored presets.

Hm, this “ledNode” sketch has become a bit longer than expected – I’ll present that tomorrow.

Meet the LED Node

In AVR, Software on Nov 3, 2011 at 00:01

More than a year has passed, and I still haven’t finished the RGB LED project. The goal was to have lots of RGB LED strips around the house, high up near the ceiling to provide indirect lighting.

The reason is perhaps a bit unusual, but that has never stopped me: I want to simulate sunrise & sunset (both brightness and colors) – not at the actual time of the real sunset and sunrise however, but when waking up and and when it’s time to go to bed. Also in the bedroom, as a gentle signal before the alarm goes off.

Now that winter time is approaching and mornings are getting darker, this project really needs to be completed. The problem with the previous attempt was that it’s pretty difficult to achieve a really even control of brightness and colors with software interrupts. The main reason is that there are more interrupt sources (the clock and the RFM12B wireless module), which affect the timing in subtle, but visibly irregular, ways.

So I created a dedicated solution, called the LED Node:

Screen Shot 2011 10 26 at 11 48 54

It’s basically the combination of a JeeNode, one-and-a-half MOSFET Plugs, and a Room Board, with the difference that all MOSFETs are tied to I/O pins which support hardware PWM. The Room Board option was added, because if I’m going to put 12V power all over the house anyway for these LEDs, and if I want to monitor temperature, humidity, light, and motion in most of the rooms, then it makes good sense to combine it all in one.

Here is my first build (note that all the components are through-hole), connected to a small test strip:

DSC 2706

The pinouts are pre-arranged to connect to a standard common cathode anode RGB strip, and the SHT11 temp / humidity sensor is positioned as far away from the LEDs as possible, since every source of heat will affect its readings. For the same reason, the LDR is placed at the end so it can be aimed away from the light-producing LED strip. I haven’t thought much about the PIR mounting so far, but at least the 3-pin header is there.

The LED Node is 18 by 132 mm, so that it fits inside a U-shaped PVC profile I intend to use for these strips. There can be some issues with color fringing which require care in orienting the strips to avoid problems.

Apart from some I/O pin allocations required to access the hardware PWM, the LED Node is fully compatible with a JeeNode. It’s also fully compatible with Arduino boards of course, since it has the same ATmega328. There’s an FTDI header to attach to a USB BUB for uploading sketches and debugging.

The MOSFETS easily support 5 m of LED strips with 30 RGB LEDs per meter without getting warm. Probably much more – I haven’t tried it with heavier loads yet.

Here’s what I used as basic prototype of the whole thing, as presented last year:

DSC 2710

Tomorrow, I’ll describe a sketch for this unit which supports gradual color changes.

Running LED ticker #2

In Software on Nov 2, 2011 at 00:01

After the hardware to feed yesterday’s scrolling LED display, comes the software:

Screen Shot 2011 10 25 at 18 31 38

The code has also been added to GitHub as tickerLed.ino sketch.

Fairly basic stuff. I decided to simply pass incoming messages as is, but to do the checksum calculation and start/end marker wrapping locally in the sketch. The main trick is to use a large circular 1500-character FIFO buffer, so that we don’t bump into overrun issues. The other thing this sketch does is throttling, to give the unit time to collect a message and process it.

Here’s what the display shows after power-up, now that the JeeNode is feeding it directly:

DSC 2705

(that’s the last part of the “Hello from JeeLabs” startup message built into the sketch)

So now, sending a 50-byte packet to node 17 group 4 over wireless with this text:

    <L1><PA><FE><MA><WC><FE>Yet another beautiful day!

… will update line 1 on page A and make the text appear. The unit rotates all the messages, and can do all sorts of funky stuff with transitions, pages, and time schedules – that’s what all the brackets and codes are about.

Time to put the end caps on and close the unit!

Running LED ticker

In Hardware on Nov 1, 2011 at 00:01

For a while, these “ticker tape” displays were quite the rage. They probably still are in shop displays where LCD screens haven’t taken over:

590996 BB 00 FB EPS

This one is powered from 12 VDC, and has a serial RS232 interface with a funky command structure to put stuff into its line- and page-memory. Lots of options including lots of scroll variations, blinking, and beeping.

Well, a friend lent me one a while back and we thought it’d be fun to add a wireless interface via a JeeNode.

Time to take it apart, eh?

It didn’t take long to figure out the way to hook up to it, and there was some useful info in this domoticaforum.eu discussion from a few years back.

I decided to use this P4B serial adapter from Modern Device to interface the JeeNode to the RS232 signals:

DSC 2702

It’s convenient because it plugs right into the FTDI connector, and it has the onboard trickery needed to generate “RS232’ish” voltages. The whole thing is mounted on foam board using double-sided tape and the JeeNode can easily be unplugged to upload a new sketch.

Here’s the whole “mod” on the back side of the display:

DSC 2701

There’s a wire to the +5V side of a large cap, used to drive the displays no doubt. The JeeNode’s internal regulator will convert that down to 3.3V, as usual.

The positioning of the JeeNode is tricky, because the entire enclosure (apart from the smoked glass at the front) is metal – not so good for getting an RF signal across. I decided to place the antenna at the far edge, since the end caps are made from plastic. Hopefully this will allow good enough reception to operate the unit while closed.

The serial pins are conveniently brought out on some internal pads, right next to the RJ11 jack used for RS232:

DSC 2703

I haven’t hooked up RX and TX yet, because I still need to find out which is which.

I’ve verified that I can communicate with the unit through a USB-BUB wired through to the P4B adapter, i.e. straight from my laptop.

Next step is to write a sketch for the JeeNode…