Computing stuff tied to the physical world

Archive for 2011

Tempus fugit …

In AVR, Hardware, Software on Dec 31, 2011 at 00:01

Another year is about to end, and the next one is already anxiously waiting to carry us along into the future…

A fitting moment to get that Dutchtronix clock working (a lot easier than this geek version):

DSC 2832

I bought this little kit long ago, not realizing that a low-end USB scope front-end can’t deal with it. Besides, it turns out that it didn’t work back then because of some bad solder joints (ground planes and 15W soldering irons don’t go well together – even my current soldering iron has trouble heating up some of those pads!).

Anyway, this is as far as the Hameg HMO2024 will go:

SCR60

Recognizable, but a far cry from what analog scopes can do. That’s what you get when digital sampling, waveform refresh rates, and vector drawing clash (bumping up the sampling rate causes a fuller, but flickering, image).

This design was from 2007, I think – which goes to show that fun stuff (especially clocks) can be time-less!

I wish you a healthy, safe, and happy 2012 – with lots of opportunities to tinker, learn, and create.

Update – for another example of how such X-Y displays differ between analog and high-end vs low-end DSO’s, see this video on Dave Jones’ EEVblog.

Anatomy of a Room Node transmission

In Hardware on Dec 30, 2011 at 00:01

Now that my analysis capabilities have improved, it thought it’d be interesting to see the power consumption profile of a Room Node, running the roomNode.ino sketch. Here’s an annotated capture of a motion event:

Annotated room packet

The yellow line is the current consumption of the entire room node. I’ve added some annotations, although there are still a few things I’m not so sure about, such as the 2.5 ms delay between SHT readout and XMIT start.

The red line is the integral of the yellow line, i.e. the total amount of energy consumed as time progresses. It took about 3 ms between the end of the packet transmission and the first ACK packet header byte coming in – this thumb-twitching with the receiver enabled accounts for about 1/3rd of the power consumption!

There is almost always room for improvement with this sort of stuff. The closer you look, you more you find things to optimize. For example, I noticed that there were blips every 32 mS or so (it’s slightly irregular):

SCR54

This is zoomed in on both axes. The noise level is a bit higher, perhaps due to the 2 mV/div setting of the scope.

That’s over 1 ms @ 0.8 mA, at about 30 times per second on average. I don’t know what it is – it’s not the PIR sensor, which was removed during this measurement. Not a lot of energy per blip, but it does add up: ≈ each uses 1.1 µC, i.e. some 2,000 µC per minute. Whereas the first screen shows that a transmission takes only 130 µC.

So there you go: vampire power at microwatt levels!

Update – Ah, wait – of course! – it’s the Scheduler class in the Ports library! When idling, it lets time pass in steps of 0.1s (or rather 96 ms), and there’s no other way to do this than with 32 and 64 ms watchdog timer steps. I told you – there are no show-stoppers in this game, it works on logic and insight, all the way down!

Out with the old – in with the new!

In AVR, Software on Dec 29, 2011 at 00:01

Le roi est mort …

It’s time to move on. I’m dropping all support and maintenance of the Ports and RF12 libs, as well as some others. Well, as far as subversion is concerned. All files are kept read-only at svn.jeelabs.org – for reference.

… vive le roi!

But the good news is that all this software has now been moved and updated on GitHub … and is fully supported.

All libraries on GitHub have been adjusted to work with Arduino IDE 1.0 (they may or may not still work on 0022 or 0023, but that will be supported only to the point of accepting patches to increase backward compatibility).

There is one change which I’ve been meaning to get to for a long time: the Ports and RF12 libraries have been combined into a new library called JeeLib. This means that you no longer have to include “Ports.h” and “RF12.h” at the start of your sketches (although those still continue to work). Instead, insert this one line instead:

    #include <JeeLib.h>

All the examples from both libraries have been retained, but make sure that the old Ports and RF12 are gone.

There are three other libraries for the JeeNodes which you may be using: EtherCard, GLCDlib, and RTClib. These too are now on GitHib and have all been adapted for use with Arduino IDE 1.0.

So how does one start using any of these libraries? Ah, glad you asked :)

  • go to GitHub, and pick the library you’re interested in to get to its home page
  • at the bottom of each home page is a README section with the latest info – always worth a check
  • one of the links at the top is marked “ZIP” – you could click it to download everything as ZIP archive
  • … but you shouldn’t !

The reason for this is Git. If you download a ZIP archive, unpack it, and install it in the right place (which is in the “libraries” folder where all your sketches are), then you’ll get a copy of the code your after, but no way to stay up to date. That might sound like a minor detail, but with open source, there are usually many changes over time. Bug fixes as well as new features. If you grabbed a ZIP file, then you’ll be forced to re-install the next version over the previous one every time there is an update. This quickly gets very boring, and can lead to all sorts of awful mistakes, such as overwriting a file you had fixed in some way (after a lengthy debug session, long ago).

I can’t stress it enough: don’t grab open source software and install it on your disk by just downloading and unpacking it. Not just the stuff from JeeLabs – any open source software distributed in source code form. It’s a nuisance, a ticking time bomb, a mine field, a disaster waiting to happen – get the message?

There is only one sane / long-term approach to working with source code, and that’s through a Version Control System. In this case Git – in combination with GitHub, which is the web site where all source code is stored.

So instead of downloading a ZIP or TAR archive, you need to create a “clone” of the original code on GitHub. The difference with the ZIP archive is that a clone knows where it came from, and gives you the ability to find out what changed, to instantly update your clone, or to revert to any older version, since GitHub keeps track of all versions of the code – past, present, and future.

The trick is to get started with Git and GitHub without drowning in the capabilities they offer. How depends on the environment you’re in:

  • On Windows, you can install TortoiseGit – then you need to get that clone onto your machine. For JeeLib, you’ll probably need to enter this path to it somewhere: git://github.com/jcw/jeelib.git

  • On Mac OSX, you need to install the Xcode developer tools, which includes Git (it’s a free install from the App Store). If you have an account at GitHub (or don’t mind getting one, it’s free), then I highly recommend getting the GitHub for Mac application. If not, you can always use the command line, like so:

        cd ~/Documents/Arduino/libraries
        git clone git://github.com/jcw/jeelib.git
    
  • On Linux, you need to install git through whatever package manager you’re using. On Debian / Ubuntu, this command line will probably do it:

        sudo apt-get install git-core
    

    After that, it’s the same as the Mac OSX command-line version, i.e. “cd …” and “git clone …” (see above).

So far, this is only a little more involved than grabbing that ZIP file. The gains start when you want to update your copy to the latest version. In git-speak, this is called “pulling” the latest changes (to your local disk). I encourage you to search around on the web, it’s usually as simple as doing “git pull” from inside the cloned area (from the command-line, some GUI, whatever). The difference with re-installing is absolute security – “git pull” will never overwrite or lose any changes you made, if they conflict with the original.

If all you do is track changes from time to time, then this is all you need to benefit from Git and GitHub.

If you actually make changes, then you’ll need to dig a little deeper when a “conflict” occurs, meaning you’ve made a change which interferes with changes made in the original on GitHub. But on the plus side, you’ll also be able to easily submit your changes (GitHub calls this “making a pull request”, i.e. pulling your changes back into the original). Why bother? Because contributions, no matter how small, are what make open source software fly!

Welcome to the world of open source software collaboration – where code lives, evolves, and grows.

Finished Low-power Supply

In Hardware on Dec 28, 2011 at 00:01

The Low-power Supply described previously on this weblog now has a PCB – and it’s about as small as a JNµ:

DSC 2827  Version 2

Here’s an assembled unit, ready for testing and hooked up to power a JeeNode (w/ disabled bootstrap):

DSC 2831

And here’s the whole test setup I had to create to check this thing out:

DSC 2830

Lots of stuff involved, including high-voltage probe and 230V isolation transformer (to the right, out of view).

Here’s a demonstration of how it works – summarized as one elaborate scope capture:

SCR42

Green is the mains voltage (235 Vrms), purple is the charge building up on the 100 µF reservoir capacitor, yellow is the regulated output, and blue is the JeeNode’s current consumption (measured as voltage drop over 10 Ω). Note how some of the voltages measured here differ more by than four orders of magnitude!

Anyway, that zoomed-in image is the clear signature of the second 8-byte RFM12B packet transmission. Current consumption varies from 23 to 26 mA. It’s a relatively coarse image, since it has been zoomed in 4,000 times.

The 3.3V supply level is reached ≈ 2s after power-up, with another 2.5s needed to fully charge the reservoir cap. You can see from the purple dips that this supply could sustain at least one packet transmit per second.

No surprises here, but it’s good to see that the PCB design works as intended. Next step: implement deep sleep on the ATtiny84 – hopefully this’ll take just some minor adjustments to the Sleepy::loseSomeTime() code.

The convenience of “Git”

In Software on Dec 27, 2011 at 00:01

I’ve written before about source code respositories and Subversion / Git – about a year ago, in fact.

Suprisingly, lots of people working on software are still not using any “Version Control System” (VCS) !

So let me try a new angle today, and show you how you need only use 5% of those systems to get a huge benefit out of them when dealing with the Arduino sketches and libraries from JeeLabs. Since all the code from JeeLabs is now located at GitHub, the rest of this post will be about Git (and GitHub, a truly phenomenal free web resource).

Why bother with a VCS? Well… I once heard of a little anecdote about a sign at the dentist, which said:

“You don’t have to floss all your teeth, just the ones you want to keep.”

It’s a bit like that with source code. If you don’t write code, or don’t ever change it, then you don’t need to manage it. But if you do, then you know how much effort goes into a working sketch, library, script, program, etc. Things change – either your own code, libraries from others, tools like the Arduino IDE (1.0 broke lots of stuff), even core computer software or hardware. Things always change, and if you want to be able to deal with it, you need VCS.

Not everyone aspires to be a full-time software developer (what an odd world that would be!), but even in the simplest situations you can benefit from version control. Here’s a possible scenario, close to home JeeLabs:

  • Suppose you want to use the EtherCard library, but not necessarily with the JeeLabs Ether Card hardware.
  • The GitHub page includes a README at the bottom, with a link to the ZIP archive with all the code.
  • So you download the ZIP, unpack it, and figure out where to put it so the Arduino IDE can find it.
  • Say you want to try out the “backSoon” example, as demo of a tiny web server. You compile and upload.
  • It doesn’t work – now what? After a lot of digging and searching, you figure out that the code was written for the SPI select signal tied to Arduino’s digital pin 8 (PB0) whereas your hardware uses pin 10 (PB2).
  • After that it’s easy: change “#define SELECT_BIT 0” to “#define SELECT_BIT 2” in enc28j60.cpp.
  • Fantastic, you’ve cut through the problem and made the EtherCard library work for you. Congratulations!

This is a typical case: code was written for a specific purpose, but a small change makes it more widely usable.

I picked this example, because it is likely that we’ll update the EtherCard library soon to support different pins at runtime. That’ll allow you to leave the EtherCard library alone and set things up in your sketch, i.e. at run time. Note that it’s always a trade-off – some things usually become more general, but only if there’s a need. You can’t write code to cover all the cases. Well, you could, but then you end up with a nightmare (I won’t give examples).

So sometime in the near future, there will be an update to the EtherCard library. That’s when trouble starts…

Because there are now three different versions of the EtherCard library, and you’re about to create a fourth:

  • the original EtherCard library on GitHub
  • your copy of that library, on your disk, with a tiny change made to it
  • the updated! improved! whiter-than-white! new EtherCard library on GitHub
  • your copy of the new library, which you’re now forced to update and adjust again

There’s more going on: in this particular case, that update made your small change superfluous. But now the API of the EtherCard library has changed, so you need to change each of your sketches using the EtherCard library.

It’s not hard to see how these little details can turn into a nightmare. You build something, and you end up having to keep track of all sorts of dependencies and changes on your disk. Worse: everyone is wasting their time on this!

Version control systems such as Git can do a lot more, but the key benefit they offer can be summarized as:

You can easily manage THREE different versions of all the source files: the OLD, the NEW, and YOURS.

So if all you want is to use open source code and stay up to date, then Git lets you do that – even if you make changes yourself in any of those files. And it gets even better: if your changes have nothing to do with the changes made to the original code, then all you need to do is to issue the “git pull” command, and the remote changes will be folded into your local copy of the source file – chances are that you can simply re-compile, upload, and keep on running with the latest updates!

If your local changes do interfere or overlap with the changes made to the original code, then “git pull” will detect this and avoid making the changes to prevent it from altering yours (which always take precedence). This is called a “conflict” – and Git offers several (maybe too many) ways to deal with it.

For JeeLabs, all the code is now maintained on a free and public web site called GitHub. You don’t have to have an account there to browse or download any source code. You can not only see all the latest code, you can also look at any previous changes, including the complete history from the moment the first version was placed on GitHub.

Here’s an example: https://github.com/jcw/jeelib/commit/6f8415607ff6eef3966363751975c8f807ef9814

You’ll see a comment about the change, the list of files affected, and for each file an exact summary of the changes and some nearby lines for context. This change has been recorded forever. If logged in, you could even discuss it.

Even if you never intend to share your own changes and code, you can see how this resource lets you examine the code I’m providing, the changes I’m making to it over time, and the affected files. You can view a source file as it was at any point in time (wouldn’t it be great if this also included the future?).

Here’s one more gem: say you are looking at the enc28j60.cpp file, and wondering when what change was made. There’s a way to see where each change came from (and the look at that specific change in a larger context, for example). This annotated source file is generated by “git blame” – follow this link as example.

So what VCS, Git, and GitHub offer is really no less than a Time Machine. But even if you don’t ever use that, Git gives you the ability to keep your code in sync with the changes happening in the original source code repository. And if something gets messed up, you can revert to an older version of the code – without having copies on your disk, which need to be given meaningful names so you can find them back. The “git diff” feature alone is worth it.

Wanna get started? Terrific. Cast your doubts aside, and keep in mind that you need a little time to get used to it.

How to start using Git (and GitHub) depends a bit on your operating system: on Windows, best option might be to install TortoiseGit (see also this intro, which goes a bit deeper). On the Mac, it’s included with the Xcode developer tools, but there’s actually a great app for it called GitHub for Mac, and on Linux it’s probably one of the best supported packages out there, since it came from the same guy who made Linux possible in the first place…

With Git, you can stay up to date, you’ll never lose changes, and you never have to guess who changed what, when, where, why, or how. Is there a new update? Try it! Doesn’t work as expected? Back out! It’s that simple.

Bussed SPI – a first test

In Hardware on Dec 26, 2011 at 00:01

It’s time to try out that “bussed SPI” idea, which could turn the 2×4-pin SPI/ISP connector into a real bus for up to 8 high-speed devices. What I came up with as test case, is to hook up two SPI RAM chips, write different values to each of them, and then read them back to check that the values are correct.

Let’s dive in, which in this electro-world means: grab a breadboard and a bundle of wire jumpers!

DSC 2825

At the top, a red USB BUB (v1), and a JeeNode underneath a Bridge Board to bring all the necessary connections onto the breadboard. On the breadboard, from left to right: two 23K256 static RAM chips in 8-pins DIP, and a 74AHC595 shift register as 16-pin DIP package. Apart from the jumper wires, some pull-up resistors, and the scope probes, there are also lots of 0.1 µF decoupling caps. At 8 MHz, they are crucial (as I found out, eventually).

This was (approximately) the code I used for testing (combined with the code in this post):

Screen Shot 2011 12 18 at 00 52 21

Here is a scope trace of the result (yes, it’s the same screenshot I posted a few days ago):

SCR30

There are two decoded SPI signals: MOSI at the top and MISO at the bottom.

What you can see, is that the bytes 0x38 and 0x39 are being read back from one SRAM, immediately followed by the command to write 0x3C and 0x3D – these values then get read back on the next iteration. The values 0x3A and 0x3B end up in the other SRAM. You can also see the slave select setup via the B0 pin for SRAM #1 (0xFD), and a different value for SRAM #2 (0xFB). Note how this needs a mere 2 µs extra to switch SPI slaves.

In short: it all seems to work!

I’ll have to do a lot more testing of course, to find out how reliable this is at this high 8 MHz speed, and how this works out across multiple boards, all stacked up together. But if it does, then this might become a very handy new convention for little “stacker” boards on top of a JeeNode. Look Ma, no extra pins!

The SPI bus: tamed, at last?

The Ultimate Bookshelf

In Musings on Dec 25, 2011 at 00:01

I do a lot of reading…

Reading has changed a lot these past few decades. I used to devour books in the library and subscribe to lots of magazines. As a kid, when visiting New York one summer, I spent weeks on the floors of the the New York Public Library – because they had all the back issues of Scientific American and you could read as much as you want!

The thing with SciAm, is that it had a column every month, called The Amateur Scientist – which, in hindsight, was really the ultimate “maker” breeding ground. I don’t think I ever built anything described in it (’cause teenagers don’t have any money), but that did not diminish the fun and learning experience one bit.

A side-effect of all this was that my environment filled itself with books, papers, magazines, and articles.

And although the human mind is incredibly good at remembering where things are, by association, and particularly by how it looks and its location, there comes a point when ya’ can’t find that one friggin’ article back. With computers, things quickly got (much!) worse… no more clues as to which book (file!) is large, which one looks worn-out, what the books (files!) around it look like, or to leaf through it quickly to locate a section (bits!) by its visual appearance.

Besides, most magazines and books are really just meant to be read once. You digest the info, learn from it, and never look back. It seems silly to buy them in dead-tree form, and continuously add more bookshelves for them.

So I started to get more and more books, articles, and magazines in PDF form. They were easy to store, could be browsed as well as searched via keywords. I bought – and still buy – lots of books that way. My favorite PDF shop (for programming-related books) is probably the Pragmatic Programmers – nice collection, well-written and good-looking books, and you get update notifications when books get revised (a key benefit of the electronic format).

My collection of PDFs is growing fast. Purchased as well as downloaded. And now also lots of electronics datasheets.

This reached a point where I decided that I wanted to get rid of the paper stuff, at least for normal technical books to which I have no particular emotional attachment. So I got one of these a couple of years ago:

S510m header

That’s a Fuijistu ScanSnap S510M document scanner. There are newer models now, for Mac and PC. The thing about this scanner is that it’s surprisingly effective. It scans quickly, and does both sides of the page at the same time. But the real gem is the supporting software. It knows what’s color and what’s black and white, it knows what’s up and what’s down, it knows what’s portrait and what’s landscape, and it it knows how to start up the software when you press the big button on the front. Best of all, it comes with OCR software which places the recognized text inside the PDF, and puts it there invisibly – behind the scanned images, so to speak. That sounds crazy, but the result is that the pages you look at are complete photographic reproductions, and yet the document is fully searchable!

To be honest, the OCR process is so time-consuming that I don’t enable it for books & magazines. But for invoices and loose sheets of paper, this is incredibly useful. I do not need to organize it – text search does it all!

I’ve cut up some 10 meters of books already, and turned them into PDFs. Yeah, it hurts a little at first, but hey.

For reading PDFs, I use the Mac’s built-in Preview, which is a lot better (and faster) than Adobe’s, eh… junk.

For locating documents, by file name or by content, there is Spotlight in the Mac, which also works with a server. This search technology is fast enough to instantly locate documents in many dozens of gigabytes of data. And since it’s available to all applications, there are some great front ends for it such as Yep, Leap, and Papers. I’ve been using DEVONthink Pro Office for all my docs and notes, because of its integration with the ScanSnap.

The above is all for the Mac, but there are probably similar offerings for Windows.

But the real revolution is much more recent…

Screen Shot 2011 12 18 at 03 10 33

There’s an “app” for the iPad, called GoodReader. This little bit of software lets me put over a thousand documents on the iPad and actually be able to find stuff, read stuff, and manage stuff. About 25 GB so far. Offline.

Which means I can now manage my entire collection as a folder on the server, add books, reorganize as needed, add tags and quickly access it from multiple Macs through Yep, as well as have the entire set on an iPad.

The Ultimate Bookshelf, no less, if you ask me. Alan Kay’s DynaBook has become an affordable reality.

To put it differently: food for thought – especially slow food for slow (off-line) thought, as far as I’m concerned!

Trying to improve on the SPI bus

In Hardware on Dec 24, 2011 at 00:01

Yesterday’s experiment was done with a very specific purpose (yeah, sometimes I do things for a purpose…).

I’m trying to overcome a major drawback of the SPI bus. But to explain this, allow me to go on a little detour first. The I2C bus is an extremely convenient design, because it only needs 4 wires to connect several chips together:

350px I2C

Each chip sees the same information, but it works because each chip has been set up to respond only to a specific address on the bus. And that address happens to be conveniently located at the start of each I2C message.

But although the I2C bus is slow, usability is where the SPI “bus” suffers in comparison:

350px SPI single slave

With one chip, there’s no problem: one “slave select” (SS), a “serial clock” (SCLK), a “master-out slave-in” (MOSI) pin for outgoing data, and a “master-in slave-out” (MISO) for incoming data (brilliant naming – no confusion!).

The trouble is with multiple chips, i.e. slaves. The SCLK, MOSI, and MISO pins can be shared, but not the “slave select”. Each slave will need a separate pin to select it. And that makes it impossible to use it as a real bus…

If only there were a way to get multiple slave selects onto a single pin…

And that’s where yesterday’s post comes in. Suppose we had all the SPI signals, as well as power, as well as two chip selects. Like, eh… the SPI/ISP connector, using B0 and B1 as the two select signals – how convenient!

So here’s the idea: first we send a byte over SPI with B0 set low and then we send the actual data with B1 set low. The B0 transfer is used to select one specific slave, and the B1 transfer then takes place only with that slave.

The good news is that a 74HC595 shift register has all the functionality needed to perform this task, by using the three-state enable pin as a gate to turn the shift register outputs on or off. Here’s the schematic for it all:

Screen Shot 2011 12 17 at 22 40 47

The idea is to put this simple circuit on each slave board. On each one, a different output from the shift register gets jumpered. In the above schematic, for example, QD (the 4th bit) has been wired up as slave select.

Here’s code for trying out this idea, optimized to only send data on B0 when a different slave is being selected:

Screen Shot 2011 12 17 at 23 47 07

The following code also needs to be executed to set things up properly on power-up:

    // init PB0 and PB1 as outputs, set high
    PORTB |= bit(1) | bit(0);
    DDRB |= bit(1) | bit(0);

Anyway. So much for theory… stay tuned!

PS. Season’s greetings to everyone. This weblog will continue on auto-pilot for the next two weeks. Enjoy!

Decoding SPI with a shift register

In Hardware on Dec 23, 2011 at 00:01

Here’s a fun experiment – adding 8 very fast output pins via SPI, using just a 74AHC595 shift register:

JC s Doodles page 31

This is the “spiCycle” test sketch I used to try out the above hardware:

Screen Shot 2011 12 15 at 18 43 23

It sends bytes to the shift register, with only bit 0 set, then only bit 1, etc. At the end, a zero byte is sent to clear all bits again, which is why the loop runs to 9 i.s.o. 8. Here’s the output, as seen on the scope via a logic probe:

SCR25

The yellow trace is SCK. The blue trace is PB0 (Arduino digital 8), which is used as chip select for the shift register. The purple lines are the 8 outputs of the shift register. You can see the “1” bit rippling across all 8 pins.

As you can see, there’s plenty of “ringing” on these signals, which is not surprising, given that it’s a bus running at 8 MHz (and it was all set up on a breadboard using jumper wires). Setting these 8 bits takes just 2 µS!

Note that the number of output bits can easily be extended by “cascading” multiple shift registers, so this is in fact a way to add lots of output pins to an ATmega which can be set very, very quickly.

There’s one oddity in there which I can’t explain – for some reason, the PB0 select pin is being pulled low longer and longer as the loop repeats (see the blue line “low” states).

Tomorrow, I’ll explain the point of this exercise…

My scope story – conclusion

In Hardware on Dec 22, 2011 at 00:01

As it so happens, my scope finally arrived – and was immediately given a central place on the JeeLabs workbench:

DSC 2823

It’s phenomenal. You’ve seen plenty of analog signal traces on this weblog recently, but this one includes a logic analyzer (up to 11 channels) and serial protocol decoding + triggering. Here’s an example with bi-directional SPI:

SCR30

(these screenshots are slightly fuzzier than the real thing, because I had to resize the images to fit this weblog)

Light blue is the bus decoding, yellow is the analog SPI clock (with lots of over- and under-shoot), and purple is for the logic analyzer POD. Small gotcha: on a 4-channel scope, it’s either analog channel 3, or the 8-wide logic probe – never both at the same time. But on the plus side: if you only use 2 analog channels, then the scope can re-purpose the unused channels to double its max sample rate to 2 GSa/s, and its memory depth to 2 MB each.

That first photo shows the same SPI clock, BTW – it’s what 8 MHz on jumper wires + a breadboard looks like!

As it turns out, I ran into two problems while pushing the HMO722 unit loaned to me by Rohde & Schwarz. One of them was a mis-interpretation of the screen display on my side, while the other one uncovered a limitation of (only) the HMO722. In both cases, the support from R&S was very impressive: quick, knowledgeable, and best of all… effective. In this day and age, that’s exceptional – and laudable.

Here’s another capture, triggering in RS232 / UART mode on the character 0x1D, as decoded at 115.2 Kbaud on the TX line. You can see a small sketch upload (green) and the beginning of the verification read-back (yellow):

SCR36

I’ve not seen this feature in low-end logic analyzers yet. It’s probably a separate FPGA, able to decode various protocols to generate the desired trigger signal, and – being an MSO – it also ties into analog acquisition.

Note that this can be done without logic probe. It was enabled here (the two purple lines) but it’s not essential, since serial protocol decoding + pattern-based triggering can also be performed with just the analog channels. The serial data single-shot storage limit is around 2.5 Kbyte (all data is sampled and stored as a bit stream).

One more thing I really love about this scope: it’s totally quiet (thank you Hameg, for following Apple’s lead!).

I can only repeat: this HMO series is the most modern in its class IMO and has an excellent price / performance ratio, with features matching some Tektronix and Agilent scopes at twice the price. If you don’t want to settle for a USB scope or one of the Rigol’s, then get the Hameg HMO724 (or one of the others, with a higher b/w front-end).

A scope is not for everyone, of course. And this one even less so, no doubt. Keep in mind that the landscape will be completely different again two years from now. So if you don’t plan to use it much, better hold on to your cash.

But if you do need a scope now, then I hope these last few posts can help you make up your mind…

PS. A comparison in German between the Hameg and Agilent scopes can be found here (written by Hameg).

Getting an oscilloscope – part 2

In Hardware on Dec 21, 2011 at 00:01

This post continues where yesterday’s post leaves off, w.r.t. my adventures with oscilloscopes.

Last October, I decided to get a “real” scope. There were plenty of experiments (ongoing and planned), which would justify getting a new instrument for. Besides, Dave Jones’s review and teardown of in particular the Agilent InfiniiVision 3000 X series scopes got me completely drooling, while at the same time knowing I’d never be able to afford (let alone justify) buying such a high-end (for me!) oscilloscope.

The most popular unit by far probably, is the Rigol 1052E and its cousin the 1052D with logic analyzer. The former is called a “DSO” (Digital Storage Oscilloscope), while the latter is a more recent trend called the “MSO” (Mixed Signal Oscilloscope). The market price for these two seems to be around €400 and €900, respectively.

MSO’s are more pricey than DSO’s, and in a way it’s not easy to justify the price difference, particularly if you consider that USB-connected Logic Analyzers such as the ZeroPlus and Openbench Logic Sniffer can be had for a fraction of that price difference. My main reason for exploring MSO’s can be summarized in one word: knobs.

But before I explain, let me describe the Rigol scope and how it worked out for me.

As it so happened, a good friend was willing to lend me his Rigol DS5062CA, which appears to be the predecessor of the DS1052E. It’s very similar, in looks and in functionality:

DSC 3557

The specs of this scope are actually really good: 60 MHz bandwidth and a whopping 1 GSa/s sample rate. This means you really will get more than enough samples to get a very accurate view of a 60 MHz sine wave on screen, and probably also of a 5 .. 10 MHz square wave.

If you’ve been following this weblog in October and November, then you’ll have seen dozens of blue screen shots in the various posts, all taken from this Rigol scope (using a camera, as this unit has no front-side USB).

Since I really wanted to learn as much as I could about a scope like this, I spent a lot of time exploring all its features, including signal filtering, trigger delays, zooming in, measurements, cursors, maths, all the way to FFT. My first conclusion has to be that there is an incredible amount of functionality in such an instrument. This little unit is a perfect example of what sets a DSO apart from classical analog scopes. It’s a different ball game.

But the second unexpected outcome of this learning process, is that it convinced me completely that “knobs” are dramatically more convenient than any computer-based emulation using keyboard and mouse. Within a few weeks, motor memory sets in: you intuitively push the right buttons and turn the right knobs, while analyzing a signal and looking for the best way to visualize it. You can keep your eyes on the screen and on the circuit, while resting one hand on the controls and adjusting things. I’ll never go back to a USB-connected solution.

So the search was on – a scope, preferably with a built-in logic analyzer.

I had already figured out two things: 1) scope prices are unbounded, and 2) I’ll buy one once, and never again. This insight was an agonizing one: I knew I was going to spend way more money than I was comfortable with (for both reasons #1 and #2) and I also knew I’d be stuck with my choice forever, for better or for worse.

I’ll spare you all my deliberations. Everyone will attach a different weight to different aspects. In my case, I did want a “better than 320×240 display” and a bandwidth of ≥ 100 MHz, to cater for (vague) future needs.

As already documented on this weblog, I ended up going for the Hameg HMO722 .. HMO2024 series, now produced by Rohde & Schwarz. The bandwidths run from 70 to 200 MHz, as 2- or 4-channel units. Here’s the HMO722, on loan from R&S until my unit arrives:

DSC 2819

It’s interesting how the controls are organized slightly differently from the Rigol, and how relatively long it took me (already!) to re-learn and re-internalize the placement and menu structure. As with a photo camera, you really have to go in the deep end and completely familiarize yourself with all the different corners of the equipment to the point that – after that – you can fully focus on the experiment, the circuit, and its signals.

My conclusion? I’m very happy with this choice, and I’m not saying this to mask any form of buyer’s remorse – there is none. I ended up going for the high-end model: 200 MHz, 4-channel. And I’d do it again tomorrow.

So what would you do, if you’re considering getting a scope? Here are my – unsolicited – suggestions:

  • budget €100 – don’t get anything and don’t worry too much – you can have lots if fun without one
  • budget €250 – get something like a DSO-2090: 2-channel, very decent software – or check out this list
  • budget €400 – get the Rigol DS1052E, it’s popular and it’ll give you the most bang for the buck, IMO
  • budget €900 – get either a Rigol DS1052D, or a DS1102E w/ separate logic analyzer (such as the OLS)
  • budget €1700 – get the Hameg HMO724, superb features, can also act as 4-channel logic analyzer
  • budget €2600 – get the Hameg HMO2022 w/ options, or the HMO2024 (which is what I chose)
  • budget €4000 – don’t despair, there’s one just right for you too (there are no doubt newer lists)
  • budget €7000 – go for it, get that 4-channel 350+ MHz Agilent 3000-X series MSO, with lots of options

If I had to pare the list down further, I’d make it a choice between the Rigol DS1052E and the Hameg HMO724.

Stay tuned for the last part of this series, tomorrow.

Getting an oscilloscope

In Hardware on Dec 20, 2011 at 00:01

(Note – a better title would probably have been: “How I picked an oscilloscope”, since YMMV!)

Oscilloscopes are the “printf” of the electronics world. Without a “scope” you can only predict and deduce what’s happening in a circuit, not actually verify (let alone “see”) it. Here’s what an oscilloscope does: on the vertical axis, you see what happens, on the horizontal axis you see when it happens. It’s a voltmeter plus a time-machine.

Most modern oscilloscopes are digital. One advantage is that they can store the observation, long enough for us sluggish humans to look at the captured signal and ponder about it. For things which happen only rarely, that is crucial. But even when you’re examining things that are periodic, like the shape of a waveform, the scope gives you time to think regardless of the time scale of the event.

If you’re into soldering, then you really need at least one multimeter. Any one will do, even the cheapest one. If you’re into electronics, to the point of trying out new circuits, then you should consider getting an oscilloscope. And lastly, if you’re into pushing limits of any kind with these circuits, then you must have an oscilloscope. Let me add for completeness, that if you are only working with digital chips, interconnecting them in your projects but not really operating at the upper range, then you might want to get a Logic Analyzer first. A logic analyzer is similar to a scope, but only cares about (multiple) 0/1 signals, not actual voltage levels – their analog input circuitry is simpler than scopes, but they usually need to sample over much longer periods of time to be useful.

In this 3-part post, I’ll describe how I started out and where I ended up, with also a bit of “why” thrown in.

My first purchase, 3 months after I started with JeeLabs, was a DSO-2090 USB oscilloscope front end for a PC:

DSC 2820

It samples at 100 MSa/s and is quoted as having a 40 MHz bandwidth. Realistically, these figures tell me that it’ll give a good view of sine waves up to 20 MHz, and square waves up to say 3 .. 5 MHz. It cost me €239 at Conrad.

Such a “USB scope” does all the analog stuff in the box, and then pushes the digitized data over USB to the host PC to do the rest of the work, including presenting an oscilloscope-like display on the screen. The DSO-2090’s software is fairly good (Windows-only, not very convenient for me).

First off, let me say that I’ve got over 2 years of excellent mileage out of this thing. It’s 100x better than no scope.

The limitations I ran into were as follows:

  • It’s tied to USB, and hence needs to be close to the computer or notebook. This wasn’t always convenient for me. A second aspect is that the whole thing is not “galvanically isolated” – signal ground is USB ground. For my recent 230V AC mains experiments, that simply wasn’t practical anymore.
  • Emulating a scope on screen, while tempting due to the available screen real-estate, is not as great as I had thought. It’s downright tedious to rotate a knob on-screen using a mouse, and if you don’t, then you have to figure out a bunch of keyboard shortcuts (and remember them next time around!).

Which led me to get this tiny unit as add-on – a DSO Nano (v1), sized and shaped a bit like a mobile phone:

Dsc 2123

At US$ 90 from SeeedStudio, I didn’t expect this 1-channel 1 MSa/s scope to replace my DSO-2090, it was more a way to get a very portable unit, and a convenient little box on the desktop.

The DSO Nano trades screen size (dropping back to 320×240) for battery-powered unthethered operation. There are now more capable (and more pricey) models with 2 analog channels.

It’s a neat little box, but I underestimated the fact that the controls are even more limiting, and that a 1-channel unit very much reduces the number of things you can do with it. It’s probably fine for audio work, but with a scope, capturing the right signals at the right time is crucial, and a 1-channel unit doesn’t offer many options for triggering. In the end, I decided that the unit was not for me, and have since re-sold it.

Two years pass…

Yes, it actually took me about two years to realize that I wasn’t getting nearly as much out of my DSO-2090 as I ought to. I had also bought a Logic Analyzer around the same time (a ZeroPlus LAP-16032U), but it too was mostly sitting on the shelf collecting dust, again because having a USB device with Windows software connected to my Mac in the wrong place wasn’t truly convenient.

Last October, I decided that it was time for a change – stay tuned for the rest of this story in tomorrow’s post.

The JeeNode, as seen from 15.24 km

In AVR, Hardware on Dec 19, 2011 at 00:01

(that’s 50,000 feet, or 9.47 miles – if those units mean more to you)

This post was prompted by a message on the forum, about what this whole “JeeNode” thing is, really.

Here are a JeeNode v6 and an Arduino Duemilanove, side by side:

DSC 2826

Let me start by saying, tongue-in-cheek: it’s all Arduino’s fault!

Because – let’s face it – the core of each Arduino and each JeeNode is really 95% the same: an Atmel AVR ATmega328P chip, surrounded by a teeny little bit of support circuitry and placed on a printed circuit board. So part of the confusion comes from the fact that the Arduino introduced its own conventions, moving it further away from the underlying common ATmega technology.

The differences between an Arduino Duemilanove and a JeeNode v6 – which resemble each other most – are:

  • the JeeNode has a “skinnier” shape, incompatible with Arduino “shields”
  • the Arduino runs at 5V, whereas the JeeNode runs at 3.3V (this carries through to all I/O pins)
  • the JeeNode includes a wireless radio module, called the RFM12B by HopeRF
  • the Arduino includes an FTDI <-> USB interface, while the JeeNode relies on an external one

There are many other differences, of course – so let’s continue this list a bit:

  • the Arduino’s “eco-system” is far, far bigger than the JeeNode’s (translation: everyone who finds out about JeeNodes probably already knows about the Arduino platform, and usually already has one or more of ’em)
  • this carries through to articles, websites, books, and discussion forums – Arduino is everywhere
  • you can do lots of stuff with an Arduino without ever touching a soldering iron, whereas the JeeNode is really not usable without some soldering (even if just to solder on a few pin headers)
  • different pinouts… it’s one big conspiracy to confuse everyone, of course! (just kidding: see below)

My reasons for coming up with the JeeNode have been documented in the past on this weblog, and can be summarized as: 1) running at 3.3V for lower power consumption and to better match modern sensors and chips, and 2) supporting a simpler form of expandability through the use of “plugs” – little boards which can be mixed and matched in many different combinations.

On the software side, JeeNodes remain fully compatible with the Arduino IDE, a convenient software environment for Windows, Mac, and Linux to develop “sketches” and upload them to the board(s).

The biggest stumbling block seems to be the way pins are identified. There are 4 conventions, all different:

  • Atmel’s hardware documentation talks about pins on its internal hardware ports, in a logical manner: so for example, there is a port “D” with 8 I/O pins numbered 0..7 – the sixth one would be called PD5.
  • Then there is the pin on the chip, this depends on which chip and which package is being referred to. On the 28-pin DIP package used for an ATmega328P, that same PD5 pin would be identified as pin 11. That’s the 11th pin, counting from the left side of the chip with pin 1 at the top.
  • The Arduino run-time library has software to control these pins. For a digital output pin, you can set it to “1” for example, by writing digitalWrite(5,1). This resembles PD5, but it fails for other pins (PB0 is “8” in Arduino-land, and PC1 is “1” if used as an analog input, or “15” if used otherwise – go figure…).
  • The JeeNode organizes several pins as part of 6-pin “Ports” (no relation to Atmels terminology!), each of them having 1 digital and 1 analog-or-digital pin.

The thing about JeeNode Ports is that there are 4 of them, and they can all be used for plugs in the same way. To support this, there’s a Ports library which lets you define port objects. This is an abstraction layer on top of the Arduino runtime. The reason is that it lets you associate a port object with a header on the JeeNode:

    Port myport (2);

Then you can connect your hardware / sensor / plug / whatever to the header marked “P2” on the JeeNode, and access it as follows:

    myport.digiWrite(1);

This happens to be the same pin as in the examples above, i.e. PD5 of an ATmega, pin 11 of the 28-pin DIP chip, and digitalWrite(5,1) on an Arduino. This also means that there are numerous ways to perform the same action of setting pin 11 of the chip to a logical “1” (i.e. 3.3V or 5V):

  • the “raw” C-level access, using Atmel’s register conventions and definitions (fastest, by far):

        PORTD |= 1 << 5;  // or ...
        PORTD |= _BV(5);  // same thing
        bitSet(PORTD, 5); // same thing, using an Arduino macro
    
  • the Arduino way of doing things:

        digitalWrite(5, 1);
    
  • the JeeNode Ports library way of doing things, as shown above:

        Port myport (2);
        myport.digiWrite(1);
    
  • … let’s throw in an extra bullet item, since every other list in this post appears to come in fours ;)

The one (minor) benefit you get from using the Ports approach on a JeeNode, is that if you attach your hardware to a different port, say port 3, then you only need to change a single line of code (to “Port myport (3);” in this case). The rest of the code, i.e. everywhere where its pins are being read or written, can then remain the same.

For an overview of all pinout differences, see also this weblog post. For full details, see the JeeNode PDF docs.

Meet the Low-power Supply

In Hardware on Dec 18, 2011 at 00:01

Now that everything is working, I want to have a ready-to use printed circuit board for it. Came up with this:

Screen Shot 2011 12 09 at 18 34 14

It’s tiny – about 48 x 12 mm – even though it’s based entirely on through-hole parts. The idea is to build it up, add wires, and then encapsulate the whole thing in heat-shrink tubing to reduce the number of contact points.

It can not be repeated enough: when tied to AC mains, the ENTIRE circuit carries AC mains voltage levels!

I have a couple of configurations in mind (see yesterday’s post for the schematic):

  • with C1 a 10 nF X2 cap and C4 replaced by a wire, this delivers an average of 0.3 mA on 230 VAC mains
  • with C1 a 22 nF X2 cap and C4 replaced by a wire, this delivers an average of 0.3 mA on 115 VAC mains
  • with both C1 and C4 22 nF caps, this supplies 0.3 mA on 230 VAC with no direct connection to AC mains
  • with C1 and C4 replaced by a wire, this supply can be used with 10..24V DC in – which is great for testing
  • with C1 and C4 each replaced by a 220 kΩ resistor, and R1 by a 1N4007 diode, this becomes a somewhat less efficient (but lower-profile) resistive version, again delivering up to 0.3 mA at 230 VAC

With C4 replaced by a wire, this circuit will have its “GND” output tied directly to the “N” input. This is important when powering the AC current monitor, which needs to have one side of its shunt at 0V relative to AC mains.

Note that no matter what, even with C1 and C4 both included, faults can develop in this circuit which cause the “low voltage” output of the circuit to end up directly tied to an AC mains “live” line. This is not, and will never be, a “safe” circuit. It can only be used safely while enclosed in a plastic box, with no contacts or parts sticking out.

In all cases, the on-board regulator will be activated once the input voltage rises to about 6V. This is the key to being able to power up a JeeNode or JeeNode Micro with their on-board RFM12B module.

A power supply which draws 12 mW!

In Hardware on Dec 17, 2011 at 00:01

It’s been a challenge to get all the bits of the AC current monitor ready, but the last hurdle has now been taken.

In a nutshell: the AC current monitor is a small unit based on a JeeNode Micro, which periodically broadcasts information about the current consumption of an attached appliance. It’s hooked up to 230V, so it’d be a bit silly to run it off batteries. It would be equally silly if it were to draw lots of power, and since it has to be permanently on, I wanted to get its power consumption really, really low – under 0.1 Watt. That goal has now been reached.

According to this calculator, the following setup draws only 12 mW @ 230V and will supply 0.3 mA @ 3.3V:

DSC 2821

Here is the schematic:

Screen Shot 2011 12 09 at 02 54 33

It’s a transformer-less capacitive power supply, combined with an LT1121 low-power 3.3V linear regulator. C4 can be omitted. This regulator has a shutdown pin, which is tied to the input voltage via a voltage divider. As a result, the output of this supply switches on only once the 100 µF reservoir capacitor has charged up to 6V (it’ll continue charging to 12V, at which point the zener diode kicks in). Here is the power-up behavior w/o D2, and no load:

SCR85

The blue line is the voltage over the reservoir cap, and the yellow line is the regulated output. If you look very closely, you can even see the 50 Hz cycles “pumping up” the reservoir once every 20 milliseconds.

By itself, this isn’t good enough yet to drive my test JeeNode (no bootstrap, brief wakeup activity every 10s):

SCR90

Very odd behavior, as the regulator and the RFM12B start pulling more current than is coming in, preventing the output from ever reaching more than 1.8 V (I used a 470 µF reservoir cap in this test).

The final trick was to add a diode from the regulator output to the shutdown pin. This positive feedback causes the regulator to very quickly snap out of shutdown mode. So once the reservoir cap reaches about 6V, the regulator switches on, at which point the shutdown pin is quickly pulled high to finish the job and keep it on:

SCR96

This is running from 150 VAC using the new AC power box. At lower voltages, the trickle current becomes too weak to reliably turn on. At 230V, on the other hand, the whole startup process is even quicker and very robust.

I have not yet been able to measure the power draw of this supply. Due to its design it will always draw the same amount (predicted to be 12 mW), regardless of load. The feed capacitor (C1) is a 10 nF X2 type.

Here’s the final proof – a JeeNode, powering up in a few seconds and sending out a test packet every 10 seconds:

SCR99

Many thanks to martynj – his weblog comments and great suggestions by email made this result possible.

Good – now I can sprinkle dozens of these around the house and still use no more than one Watt extra!

Messy signals

In Hardware on Dec 16, 2011 at 00:01

Digital circuits work with 0’s and 1’s, right?

Well, yes, but that doesn’t mean the analog voltages and currents are necessarily very “clean”. To fabricate a somewhat extreme example, I connected a JeeNode without regulator and without 10 µF capacitor to a 3x AA battery pack, and made it run this simple loop:

Screen Shot 2011 12 01 at 17 07 09

Sleep for 3 seconds, then send an SPI command to the RFM12B wireless module. Note that the RFM12B is not set to receive or transmit mode – the ATmega just sends it 2 bytes over SPI.

Let’s look at the variation in voltage and the current consumption (this shows the benefit of an MSO, BTW):

SCR65

The ATmega wakes up, sends four 16-bit commands over SPI (the compressed timeline is a bit misleading) and powers off again. The whole process takes less than 200 µs. The four SPI transfers are: wake up the RFM12B, send it the 0xFE00 soft reset, and then two more to send the RFM12B back to sleep. You can even see the ≈ 0.6 mA baseline increase while the RFM12B is awake and idling. The SPI bus runs at 1 MHz in this example i.s.o. 2 MHz, because the ATmega is running off its 8 MHz internal RC oscillator, but the sketch was compiled for 16 MHz.

The current spikes are not so important. It’s normal for switching signals to consume relatively much energy (that’s why turning off the clock saves so much power). The problem here, is that these current fluctuations have such a large impact on the supply voltage – one of the spikes causes the supply to briefly drop more than 0.25V!

This is why “decoupling” capacitors are used around digital chips, even a lowly ATmega consuming just a few milliamps (it’s running at 8 MHz here, BTW). There is a 0.1 µF cap on the JeeNode board, but it’s not enough.

Here’s the same circuit, with both signals in close up:

SCR57

Nasty stuff. I’m not 100% convinced that the real waveforms look exactly like this (the scope and probe might be distorting it a bit), but there’s no question that each SPI pin change has a substantial impact on the supply rail.

Here’s the same, with a 0.1 µF capacitor added near the battery pack:

SCR58

And with a 470 µF electrolytic cap (both showing just the scope’s measurement results):

SCR60

Note that the 0.1 µF cap has much more effect, relatively, than the 470 µF one. It’s better for HF noise reduction.

Does it matter? Yes, probably. Although all these setups work fine, the variation in voltage is fairly large, and could cause problems when operating at lower voltage levels, nearer the specified limits. Also, such currents might generate a fair bit of Electromagnetic Interference (EMI).

By adding more capacitors very near to the power consumers, i.e. the ATmega and RFM12B, this can be reduced. Such decoupling capacitors will act like little charge buffers, helping the supply cope with such sudden changes.

There’s much more to it than that (there always is). At switching frequencies of 1 MHz and above, the impedance of a wire starts to matter a lot. In fact, it’s amazing that digital circuits work at all – even without any HF design!

I’ll investigate further, but for now just remember: when in doubt, add caps … everywhere.

The steepness dilemma

In Musings on Dec 15, 2011 at 00:01

There have been comments occasionally about the steep learning curve involved with stuff from JeeLabs. This is very unfortunate, but perhaps not totally surprising. Nor easy to avoid, I’m afraid…

The thing is, I love to get into new adventures, and I also really want to bring across the joy and excitement of it all. But what’s new for me may not make much sense to you, and what’s new for you may not be new for me.

There is a huge variety in what you, collectively, dear readers, may or may not already know and in what interests y’all. Even if we narrow the field down to “computing stuff tied to the physical world”, as this weblog does.

My approach has been to just throw everything together and write new posts in a fairly chaotic whatever-comes-to-mind-first order. Sometimes about raw electronics or micro-controllers, sometimes about hardware or software techniques, and often simply about what catches my interest and keeps me occupied. My plat du jour, so to speak.

There’s a problem with this, and it’s perhaps gradually getting worse: it may not help you with getting started. This daily weblog has an alphabetical and chronological index, listed at the bottom of each page, and updated from time to time – but that’s a bit like trying to learn how to swim by jumping in at the deep end, isn’t it?

Steepness1

A few days ago, my daughter asked me about how to learn programming. I was shocked – because I don’t know !!!

What I do know is that learning something as complex as programming really well takes years (my take on it is at least a decade, seriously!). Of course you don’t have to learn everything in depth and become a pro at it all. More often than not, we just want to make a nice sandwich, not become a master chef or start a new career.

Malcolm Gladwell has written several times about the “10,000 hours rule”, which says that to get really well at something you have to throw at least 10,000 hours at it. Learning, struggling, wrestling, pondering, agonizing, and… enjoying your progress. For at least 10,000 hours, i.e. 10 years of 4-hours-a-day – being obsessed helps!

Wanna learn something really well? My advice: start today. And prepare yourself for a fascinating marathon.

The trick IMO, is to define success in smaller steps than you might normally do. Got a blinking LED? Celebrate!

Here’s the secret: there’s an incredible (yet vastly under-appreciated) advantage of open source hardware and software. That advantage is that every hurdle can be overcome. You’re not fighting a closed system, nor a puzzle which only others can solve. You’re fighting the challenge of figuring it all out. With nothing but hardware and software which can be 100% inspected and documentation which can be found. When stuck, you can have access to people who know more about it and are often willing to help you along to solve your specific puzzle.

Let me rub it in: there are no show-stoppers in this game. The worst that can happen is that you run into real-world limitations of either atoms or bits or time, but there’s an immense body of knowledge out there. Get ready for this, because here’s a fact for you: if it can be done, then you can do it. And if it can’t you can find out why. This is technology – it works on logic and insight, all the way down.

But there are two constraints: 1) it takes time and effort, and 2) nobody is perfect.

What this means is that sometimes it will take more time and effort to get to the bottom of a problem and solve it. And we all make mistakes, cut corners, run out of steam, or grow impatient at times. Part of the game.

I’m no different. I didn’t get to figure out things better than others. I stumble and fight as much as anyone, of course. But I do spend time and try to push through – especially when I get frustrated. Because I know there’s an answer to it. Always – though sometimes unexpected or unsatisfying (“it couldn’t possibly work, because …”).

Back to the real issue: how to get started with all this stuff.

Ok, to stay close to home let’s assume you want to learn more about “computing stuff tied to the physical world”. If you’re starting from scratch (which is a relative concept), my suggestion would be to look for example projects which interest you, and start off by trying to repeat the same project. Find a web site or a book describing a project which fascinates you, and … spend time with it, just reading. If it sounds too daunting to reproduce, then it probably is – in that case, look for a simpler project to get your feet wet cq. cut your teeth in. You’ll get a much bigger boost from succeeding with a simpler project at first, and then tackling the bigger one.

Steepness2

I used to have lots of practical experience in electronics, from years of fiddling around with it as a teenager. Yet here’s the project I picked as first one to get back into this game: a trivial electronics kit. It was a no-brainer in terms of complexity, and there was virtually no risk that I’d fail at assembling it. Sure enough, it worked. And guess what: this little project got me excited enough again to … write over 900 weblog posts, and spend the last few years fiddling with today’s hardware.

The reason it seems to work for me, is what Steve Jobs once described as: The journey is the reward. So true.

If you can set your goals and expectations such that you get a really nice mix of learning experiences (i.e. struggles ending in new insight) and successes, then you’re in for a wonderful journey. It’ll last a lifetime, if you want it to.

I will try to help where I can, because that’s one of my central goals with this weblog, but I’m not going to turn this site into a handholding step-by-step and just-follow-me kind of place. Because the second goal of this weblog is to encourage creative work. Which is what you get to once you get past some initial hurdles, and are (at least partly) on your way to becoming a 10,000 hour master of some topic aligned with your own interests.

The “steepness” of this weblog is not there to frustrate, of course – it’s unavoidable, IMO. And I encourage you to bite the bullet with each bump you run into. It’s part of the game to be able to find your way in, and when you do you will have gained the experience that everything in this field can be explored, learned, and reasoned about.

I’m not handing out pre-packaged fish, I’m trying to show you the fun that comes from fishing!

Having said that, I do have a request for y’all, dear readers: if you’ve wrestled your way through some of these weblog posts, and came out wishing that something very specifc had been presented differently, or summarized, or linked to, then please do let me know (in the comments or by email). Most people who struggle and come out on top quickly move on to the next challenge, happy they now understand something better than before. But you can do your fellow future readers and strugglers a huge favor by explaining what the difficulty was. It’s often as simple as “if you only had mentioned at the start that …” and things can sometimes becomes so much clearer. I’m at the writing end of this weblog, see, and I never know where the confusion or lack of detail sets in. Please help me learn – about you, about how to reduce unnecessary steepness, and about all my mistakes, of course.

Anyway. Onwards with the adventures!

AC Power Box

In Hardware on Dec 14, 2011 at 00:01

Finally got around to finishing the low-power steppable AC mains transformeryeay!

DSC 2818

The box I had picked was almost too small, so it’s a pretty tight mess in there:

DSC 2817

Main parts used (and yes, that board is kept in place with hot glue!):

  • 2×11 rotary switch – DigiKey # 360-2353-ND
  • 2x28V @ 20 mA transformer (2x) – DigiKey # MT2129-ND
  • 2x18V @ 65 mA tarnsformer – DigiKey # MT2122-ND
  • 230V 3W signal lamp – RS Components # 3393254

The circuit is as described on that “Transformers – part 2” link listed above, except that I’ve added a 3W 230V incandescent light bulb in series with the primary windings (thx for the tip, Martyn!). They draw 13 mA when glowing, but when cold the filament resistance is only 2 kΩ – which is great, because this way over 85% of the AC mains will go to the transformer while it is unloaded, or very lightly loaded. Once the load increases, the light bulb acts as a PTC, lights up, and reduces the voltage left for the transformer. It’s an extra precaution – I’ll need to test it with a dummy load to see what happens to the voltage when drawing more current.

Also, I’ve decided not to ground a center tap on the secondary windings after all. The reason is that I want to be able to tie this to a regular oscilloscope probe (not just the new isolated differential probe). This automatically grounds one side (and would interfere with a grounded center tap), so the safe way to use this thing will be to stay in the lower voltage ranges. That means this setup is now simply an isolation transformer, like my other one.

Anyway, the point of this all is to have 10 different voltage steps to test with. Here’s how they came out:

  • 17.8 Vrms
  • 30.0 Vrms
  • 35.5 Vrms
  • 47.0 Vrms
  • 58.3 Vrms
  • 64.3 Vrms
  • 75.6 Vrms
  • 92.3 Vrms
  • 119.6 Vrms
  • 147.7 Vrms

This was measured with a 100 kΩ resistor over the output, to create a very light load. Unloaded, the maximum voltage will rise slightly further – to 155 Vrms.

Now maybe 155 Vrms doesn’t sound like that much, but that “rms” stands for root mean square. That’s sort of an average value. The peak voltage at the crest of this particular waveform is actually 240 V. On the scope, this is displayed as a wave with an amplitude of 480 Vpp peak-to-peak.

Speaking of waveforms – in my setup, it’s not really a sine wave that comes out:

SCR80

The FFT analysis shows that there are all sorts of harmonics in there:

SCR78

(a pure sine wave would only have that very first 50 Hz peak at the left, as far as I understand FFTs)

But hey, it’s a great setup to test low-power transformer-less power supplies. The lower voltage ranges are safe, currents are limited to tens of milliamps, it’s isolated, and the output voltage ought to collapse when loaded by more than 20..30 mA (this still needs to be verified).

Developing a low-power sketch

In AVR, Software on Dec 13, 2011 at 00:01

As you’ll know if you’ve been reading this weblog for more than a few nanoseconds, I put a lot of time and effort into making the ATmega-based JeeNode use as little power as possible – microwatts, usually.

In the world of ultra-low power, the weakest link in the chain will determine whether your sketch runs days, weeks, months, or years… low power can be a surprisingly elusive goal. The last microoulombs are the hardest!

But it’s actually quite easy to get some real savings with only a little effort. Here are some things to avoid:

  • Don’t optimize in the wrong place – it’s tempting to start coding in a way which seems like a good idea in terms of power consumption, although more often than not the actual gains will be disappointing.

  • Don’t leave the lights on – the ATmega is amazingly easy to power down, which instantly reduces its consumption by several orders of magnitude. Make sure you do the same for every major power consumer.

  • Don’t just sit there, waiting – the worst thing you can do in terms of power consumption is wait. Unfortunately, that’s precisely what the Arduino runtime’s delay() and delayMicroseconds() calls do.

Ok, with this out of the way, I’ll describe a very simple way to get power consumption down – and hence battery lifetimes up (waaay up in fact, usually).

The trick is to use a convenience function from JeeLib (a.k.a. the Ports library). It’s in the “Sleepy” class, and it’s called loseSomeTime(). So if you have this in your code:

    delay(100);

… then you should replace it with this:

    Sleepy::loseSomeTime(100);

You also need to include the following code at the top of your sketch to avoid compilation and run-time errors:

    #include <JeeLib.h>

    ISR(WDT_vect) { Sleepy::watchdogEvent(); }

As the name indicates, the timing is not exact. That’s because the ATmega is put into a power down mode, and then later gets woken up by the watchdog timer (this is hardware, part of the ATmega). This timer can be several percent off, and although the milliseconds timer will automatically be adjusted by loseSomeTime(), it won’t be as accurate as when updated by the crystal or the ceramic resonator often used as system clock.

The second issue with the watchdog is that it can only delay in multiples of ≈ 16 ms. Any call to loseSomeTime() with an argument less than 16 will cause it to return immediately.

Furthermore, loseSomeTime() can only work with argument values up to 60,000 (60 seconds). If you need longer delays, you can simply create a loop, i.e. to wait 120 minutes in ultra-low power mode, use this:

    for (byte i = 0; i < 120; ++i)
      Sleepy::loseSomeTime(60000);

One last aspect of loseSomeTime() to be aware of, is that it will abort if an interrupt occurs. This doesn’t normally happen, since the ATmega is shut down, and with it most interrupt sources. But not all – so if loseSomeTime() returns prematurely, it will return 0. Normally, it returns 1.

The trade-off of loseSomeTime() is power consumption (system clock and timers are shut down) versus accuracy.

But the gains can be huge. Even this simple LED blink demo will use about 10 mA less (the ATmega’s power consumption while running at 16 MHz) than a version based on delay() calls:

    void loop () {
      digitalWrite(4, 1);
      Sleepy::loseSomeTime(250);
      digitalWrite(4, 0);
      Sleepy::loseSomeTime(250);
    }

To reduce this even further, you could shorten the blink ON time as follows:

    void loop () {
      digitalWrite(4, 1);
      Sleepy::loseSomeTime(50);
      digitalWrite(4, 0);
      Sleepy::loseSomeTime(450);
    }

The LED may be somewhat dimmer, but the battery will last 10x longer vs. the original delay() version.

Battery-powered operation isn’t hard, you just have to think a bit more about where the energy is going!

Inside the RF12 driver – part 3

In Software on Dec 12, 2011 at 00:01

After part 1 and part 2, I’d like to conclude with a description of how everything fits together.

The main functions in the public API are:

  • uint8_t rf12_initialize (uint8_t id, uint8_t band, uint8_t g)
    Sets up the driver and hardware, with the RFM12B in idle mode and rxstate set to TXIDLE.

  • uint8_t rf12_recvDone ()
    If in receive mode, check whether a complete packet has been received and is intended for us. If so, set rxstate to TXIDLE, and return 1 to indicate there is a fresh new packet. Otherwise, if we were in TXIDLE mode, enable the RFM12B receiver and set rxstate to TXRECV.

  • uint8_t rf12_canSend ()
    This only returns true if we are in TXRECV mode, and no data has been received yet, and the RFM12B indicates that there is no signal in the air right now. If those are all true, set rxstate to TXIDLE and return 1.

  • void rf12_sendStart (uint8_t hdr, ...)
    This function may only be called right after rf12_recvDone() or rf12_canSend() returned true, indicating that we are allowed to start transmitting. This turns the RFM12B transmitter on and set rxstate to TXPRE1.

  • void rf12_sendWait (uint8_t mode)
    Can be called after rf12_sendStart() to wait for the completion of the transmission. The mode arg can be used to do this waiting in various low-power modes, to minimize the ATmega power consumption while the RFM12B module is drawing a relative large current (ca 25 mA at full power). This call is optional – either way, the RF12 driver will return to TXRECV mode after the transmission.

Note that this design places all time-critical code inside the RF12 driver. You don’t have to call rf12_recvDone() very often if you’re busy doing other things. Once a packet has been received, the RF12 driver will stop all further activity and prevent the current contents of the packet buffer from being overwritten.

Likewise, since you have to ask permission to send, the logic is such that the packet buffer will only be filled with outgoing data at a time when it is not being used for reception. Thus, a single packet buffer can be used for both.

The main thing to keep in mind, is that rf12_recvDone() needs to be called as main polling mechanism, even if you don’t care about incoming packets. You can’t simply call rf12_canSend() forever, hoping that it will return 1 at some point. Instead, use this logic:

    while (!rf12_candSend())
        rf12_recvDone();
    rf12_sendStart(...)

This code ignores all incoming packets, i.e. when rf12_recvDone() returns true, but the call is still needed to keep the finite state machine in the driver going.

So much for the general structure and flow through the RF12 driver. To find out more about the protocol and how the different header fields are used, see this post and this post. And lastly there’s the RF12 library‘s home page.

Inside the RF12 driver – part 2

In Software on Dec 11, 2011 at 00:01

Yesterday, I described the big picture of the RF12 driver: a public polling-type API with a private interrupt-driven finite state machine (FSM). The FSM turns the RF12 driver into a background activity for the ATmega.

But first, let’s take a step back. This is how you would write code to send out a packet without FSM:

  • set up the RFM12B for transmission
  • feed it the first byte to send (i.e. 0xAA, the start of the preamble)
  • wait for the RFM12B to request more data
  • feed it more bytes, as long as there is more to send
  • then terminate transmit mode and reset the RFM12B mode to idle

Here’s an old sketch which does exactly this, called rf12xmit.pde.

The problem with this code is that it keeps the ATmega occupied – you can’t do anything else while this is running. For sending, that wouldn’t even be such a big deal, but for reception it would be extremely limiting because you’d have to poll the RFM12B all the time to avoid missing packets. Even a simple delay() in your code would be enough to miss that first incoming byte – keep in mind that although packets don’t come in all the time, when they do there is only 160 µs time to deal with each incoming byte of data.

The solution is to use interrupts. It’s for this same reason that the millis() clock and the Serial handler in the Arduino runtime work with interrupts. You don’t want to constantly check them in your code. With interrupts, you can organize your own code however you want, and check whether a new RFM12B packet was received when you are ready for it. The simplest way is to add a call to rf12_recvDone() in the loop() body, and then simply make sure that the loop will be traversed “reasonably often”.

With interrupts, the RF12 driver is no longer in control of when things happen. It can’t wait for the next event. Instead, it gets activated when there is something to do – and the way it knows what the next step needs to be, is to track the previous step in a private state variable called rxstate.

As mentioned yesterday, the RF12 driver can be doing one of several different things – very roughly summarized as: waiting for reception of data, or waiting to send the next data byte. Let’s examine both in turn:

Waiting for reception: rxstate = TXRECV

The most common state for the RF12 driver is to wait for new data bytes, with the RFM12B in receive mode. Each interrupt at this point will be treated as a new data byte. Recall the packet format:

RF12 packets

The good news, is that the RFM12B will internally take care of the preamble and SYN bytes. There won’t be any interrupts until these two have been correctly received and decoded by the RFM12B itself. So all we have to do is store incoming bytes, figure out whether we have received a full packet (by looking at the length byte in the packet), and verify the checksum at the end.

All of this happens as long as rxstate is set to TXRECV.

The driver doesn’t leave this mode when done, it merely shuts down the RFM12B receiver. Meanwhile, in each call to rf12_recvDone() we check whether the packet is complete. If so, the state is changed to TXIDLE and we return 1 to indicate that a complete packet has been received.

TXIDLE state is a subtle one: the driver could start sending data, but hasn’t yet done so. If the next API call is a call to rf12_recvDone(), then rxstate will be reset to TXRECV and we start waiting for incoming data again.

Sending bytes: rxstate = TXPRE1 .. TXDONE

I’ll skip the logic of how we enter the state TXPRE1 for now, and will just describe what happens next.

In these states, interrupts are used to keep things moving. Whenever an interrupt comes in, the driver decides what to do next, and adjusts the state. There’s a switch statement in rf12_interrupt() which looks like this:

Screen Shot 2011 12 09 at 14 05 42

It’s fairly compact, but the key is the “rxstate++” on the first line: the normal behavior is to do something and move to the next state. So the basic effect of this code is to proceed through each state in sequence:

    TXPRE1, TXPRE2, TXPRE3, TXSYN1, TXSYN2, ..., TXCRC1, TXCRC2, TXTAIL, TXDONE

If you look closely, you’ll see that it corresponds to the packet layout above. With one exception: after TXSYN2, the rxstate variable is set to a negative value. This is a special state where payload data is sent out from the buffer. In this context, the two header bytes are treated as payload, and indeed they “happen” to be placed in the data buffer right in front of the rest of the data, so the driver will send header bytes and payload data in the same way:

Screen Shot 2011 12 09 at 14 11 34

Ignore the details, just note that again there is the “rxstate++” in there to keep advancing the state.

At some point, incrementing these negative states will lead to state 0, which was cunningly defined to be the state TXCRC1. Now the switch statement takes over again, and appends the CRC etc to the outgoing data.

Finally, once state TXDONE has been reached, the interrupt code turns off the RFM12B’s transmit mode, which also means there will be no more interrupts coming in, and bumps the state one last time to TXIDLE.

This concludes today’s story. What you’re looking at is a fairly conventional way to write an interrupt-driven device driver. It may be full of trickery, but the logic is nevertheless quite clean: a public API to start things going and to pick up important state changes (such us having received a complete packet), while interrupts push through the states and “drive” the steps taken at each point.

Each interrupt does a little dance: where was I? oh yes, now do this and call me again when there is new work.

In a previous life I wrote a few Unix (not Linux) kernel drivers – this was for a PDP11 at the time. It’s amazing how the techniques and even the programming language are still the same (actually it’s more powerful now with C++). The difference is the price of the hardware – 10,000 x cheaper and affordable by anyone!

Tommorow, I’ll conclude with some more details about how everything fits together.

Inside the RF12 driver

In Software on Dec 10, 2011 at 00:01

This is the first of 3 posts about the RF12 library which drives the RFM12B wireless modules on the JeeNode, etc.

The RF12 driver is a small but reasonably complex bit of software. The reason for this is that it has some stringent time constraints, which really require it to be driven through interrupts.

This is due to the fact that the packet data rate is set fairly high to keep the transmitter and receiver occupied as briefly as possible. Data rate, bandwidth, and wireless range are inter-related and based on trade-offs. Based on some experimentation long ago, I decided to use 49.2 kBaud as data rate and 134 KHz bandwidth setting. This means that the receiver will get one data byte per 162 µs, and that the transmitter must be fed a new new byte at that same rate.

With an ATmega running at 16 MHz, interrupt processing takes about 35 µs, i.e. roughly 20% of the time. It works down to 4 MHz in fact, with processor utilization nearing 100%.

Even with the ATtiny, which has limited SPI hardware support, it looks like 4 MHz is about the lower limit.

So how does one go about in creating an interrupt-driven driver?

The first thing to note is that interrupts are tricky. They can lead to hard-to-find bugs, which are not easy to reproduce and which happen only when you’re not looking – because interrupts won’t happen exactly the same way each time. And what’s worse: they mess with the way compiled code works, requiring the use of the “volatile” datatype to prevent compiler optimizations from caching too much. Just as with threads – a similar minefield – you need to prepare against all problems in advance and deal with weird things called “race conditions”.

The way the RF12 driver works, is that it creates a barrier between the high-level interface (the user callable API), and the lower-level interrupt code. The public calls can be used without having to think about the RFM12B’s interrupts. This means that as far as the public API is concerned, interrupt handling can be completely ignored:

RF12 driver structure

Calling RF12 driver functions from inside other interrupt code is not a good idea. In fact, performing callbacks from inside interrupt code is not a good idea in general (for several reasons) – not just in the RF12 driver.

So the way the RF12 driver is used, is that you ask it to do things, and check to find out its current state. All the time-critical work will happen inside interrupt code, but once a packet has been fully received, for example, you can take as much time as you want before picking up that result and acting on it.

The central RF12 driver check is the call:

    if (rf12_recvDone()) ...

From the caller’s perspective, its task is to find out whether a new packet has been received since the last call. From the RF12’s perspective, however, its task is to keep going and track which state the driver is currently in.

The RF12 driver can be in one of several states at any point in time – these are, very roughly: idling, busy receiving a packet, packet pending in buffer, or busy transmitting. None of these can happen at the same time.

These states are implemented as a Finite State Machine (FSM). What this means, is that there is a (private) variable called “rxstate“, which stores the current state as an integer code. The possible states are defined as a (private) enum in rf12.cpp (but it can also have a negative value, this will be described later).

Note that rxstate is defined as a “volatile” 8-bit int. This is essential for all data which can be changed inside interrupt code. It prevents the compiler from applying certain optimizations. Without it, strange things happen!

So the “big picture” view of the RF12 driver is as follows:

  • the public API does not know about interrupts and is not time-critical
  • the interrupt code is only used inside the driver, for time-critical activities
  • the RF12 driver is always in one of several well-defined “states”, as stored in rxstate
  • the rf12_recvDone() call keeps the driver going w.r.t. non time-critical tasks
  • hardware interrupts keep the driver going for everything that is time-critical
  • “keeping things going” is another way of saying: adjusting the rxstate variable

In a way, the RF12 driver can be considered as a custom single-purpose background task. It’ll use interrupts to steal some time from the running sketch, whenever there is a need to do things quickly. This is similar to the milliseconds timer in the Arduino runtime library, which uses a hardware timer interrupt to keep track of elapsed time, regardless of what the sketch may be doing. Another example is the serial port driver.

Interrupts add some overhead (entering and exiting interrupt code is fairly tedious on a RISC architecture such as the ATmega), but they also make it possible to “hide” all sorts of urgent work in the background.

In the next post, I’ll describe the RF12 driver states in full detail.

PS. This is weblog post number 900 ! (with 3000 comments, wow)

Noisy workbench!

In Hardware on Dec 9, 2011 at 00:01

It never occurred to me that RFI would be an issue, but it sure is. There’s lots of electromagnetic interference around my workbench here at JeeLabs. And it’s messing up my scope experiments – here’s a baseline:

SCR27

That’s the signal, picked up by an unconnected probe lying on the table. The pane at the top is the raw signal, synchronized to the AC mains line frequency. The pane at the bottom is a Fast Fourier Transform – which has always fascinated me as a kid (yeah, I was born a geek) – the X axis is frequency instead of time. This analyzes a signal and decomposes it into a set of sine waves (every periodic signal can be treated as a sum of sine waves).

The peak at the left is “zero”, or rather, 50 Hz. There’s a weak peak at 128 KHz and a surprisingly strong peak at 675 KHz (update: probably a nearby 100 kW AM transmitter). That’s the noise the probe is picking up.

This was with my LED light strip powered from the (linear) 12V lab power supply. With a switched 12V supply, still powered on 100%, i.e. no PWM, I get a couple of extra spikes:

SCR28

Looks like this SMPS is switching at about 55 KHz. So I think I’m going to drive these LEDs with a conventional linear power supply – unregulated, to keep losses low.

I’m averaging the FFT results to get a clean readout. This is possible because the signals I’m after are repetitive and constantly present. Now let’s change the scale a bit and look again at the probe’s pickup with no lights on:

SCR24

Pretty clean – but watch what happens with the little fluorescent light of the magnifying glass I use for soldering:

SCR25

It’s a pretty hefty 30 KHz transmitter! (the strong odd harmonics indicate a square wave, i.e. on/off switching)

The moral of this story: if you want to measure weak signals, clean up your desk – electromagnetically, that is!

RFM12B low-power startup

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

The startup saga continues. Too many inter-related issues, I need to simplify…

Before tackling the power-ramp startup scenario, i.e. starting up a JeeNode (or JeeNode Micro) on a slowly-charging capacitor, I wanted to make absolutely certain that the sketch is set up to get the best low power mode as quickly as possible after a hardware power-on reset.

Time to create a test setup:

DSC 2816

This is a JeeNode running off 3.6 .. 3.9 V battery power, driving a MOSFET plug using this sketch:

Screen Shot 2011 11 30 at 17 08 54

In other words: power up for 2.5 seconds, power down for 0.5, then rinse and repeat. The JeeNode sitting upright at the bottom right is the Device Under Test (DUT). It’s a JeeNode without regulator, with a little test board to pass the ground connection through a 10 Ω resistor. This lets me measure current (or rather: voltage drop) as well as the voltage of the power supply.

Here is the behavior of a standard ATmega, with standard fuses and a sketch to init & power down the RFM12B:

SCR36

There’s a 1.5s startup delay as the boot loader listens for incoming commands, before it passes control to the current sketch. The lower half of this screen shot shows that point, i.e. right when the sketch is given control. Within about 250 µs, the RFM12B is put to sleep. The vertical scale is 2 mA/div (Ohm’s law, 10 Ω resistor).

Note the time scale: the lower portion is zoomed in 1000x w.r.t. the top.

After lots of experimentation, with the boot loader disabled, I managed to get startup a lot quicker, using a lot less energy. The code used was as follows (with these fuse settings: EXT = 0x06, HIGH = 0xDB, LOW = 0xC2):

Screen Shot 2011 11 30 at 18 22 47

Here is a screenshot with all the traces properly labeled and with measurement units added:

SCR50

Note again the horizontal time scale (top left). Here’s how to identify the different portions of these graphs:

  • the first blip is when the ATnega comes out of power-on reset
  • the second blip is for the rf12_initialize() and rf12_sleep() calls
  • the third blip is the first time loop() is run, which then quickly goes to sleep again

The big surprise (and disappointment) here, is the time between blips 1 and 2, where the average current consumption is about 0.75 mA (between the white cursor lines). This is caused by the RFM12B starting up (a bit irregularly) with the crystal oscillator enabled, instead of in power down.

The problem is that the RFM12B can’t be accessed in the first 30 ms or so after power up (probably because it’s still busy getting out of its own hardware reset). That’s a shame, since the ATmega can go to sleep in ≈ 250 µs.

The point of this all, is to make a JeeNode (or JNµ) start up with a capacitor powered from AC mains, using as low a current trickle as possible. But unless I can find a way to shut that RFM12B down very early on, it looks like a 1 mA or so trickle will be needed to overcome this initial power “hogging” behavior.

I’m not (yet?) willing to throw more hardware at the problem, but that would be one way to work around it: use an I/O pin and a MOSFET to power the RFM12B, after the voltage is high enough to be able to overcome this dip.

In the previous post, I managed to get a JeeNode started with what I though was a 10 µA trickle, but it now looks like I was off by two orders of magnitude in those tests. It’s easy to lose track of details while making changes!

Conclusion: an AC mains power supply with 1 mA trickle is an option, but I’m not ready to give up … yet!

How grounding works – part 2

In Hardware on Dec 7, 2011 at 00:01

After yesterday’s post, here are some more details about grounding do’s and dont’s

First, let me reiterate that there is no such thing as a fixed “0 volt” level. Voltages are measured as “potential differences“. You can only have a voltage between points A and B – even if there is virtually no current flow.

Warning: from here on, I’m just going to invent an explanation for how ground works and how to deal with it. If I’m wrong, please correct me. The point is to try and get my intuition across – because IMO it’s not complicated.

The solution presented yesterday was to use a “star grounding” approach: all the big power consumers get their own power and ground wires to the power supply. As was explained there this prevents big currents from “raising the ground floor”, i.e. reducing the way ground level changes end up messing with low-power signals.

Here’s a delightfully simple and practical rule: tie all the big power consumers directly to the power supply, and do whatever you like with the rest. There’s still a risk of “ground loops” (which is a nightmare in audio circuits, because it can leads to audible hum), but it’s not nearly as important as getting the big currents under control.

So if ground levels can vary, how come this doesn’t lead to trouble when connecting multiple devices?

Well, the simple answer is: they could, but the trick is to avoid currents going through ground connections. Now, before all this gets too confusing, let me make the distinction more explicit with an image from Wikipedia:

Screen Shot 2011 11 25 at 00 46 12

The differences are quite subtle:

  • signal ground denotes the return path for low-power, eh… signals
  • chassis ground is the mechanical frame, if it is made of a conducting material
  • earth ground is that rod in the ground I mentioned before

During my recent scope experiments, I’ve been quite puzzled by all this. How do you prevent damage when you tie sensitive circuits together, all at different potentials, different power supplies, and different grounding points?

Observation #1: voltages don’t cause damage, it’s the resulting current that does.

So as long as a circuit is high-impedance, you don’t really have to worry about damage. Poking around with a scope probe (which is usually 1..10 MΩ) won’t be a problem (unless you exceed the maximum voltage rating).

Observation #2: electricity only flows when there is a return path.

This is a biggie. Imagine a heavy power supply with lots of voltage and current capability to cause lots of damage:

Power1

A power supply is normally galvanically isolated from AC mains. This means it has no connection to it and no current can flow. Tying the “–” side of the supply to the chassis and enclosure will not change this. Likewise, tying this “chassis ground” to “earth ground” will not cause any current to flow. So far, so good!

Let’s look at two such installations, and let’s assume the second one is actually quite sensitive – such as a scope:

Power2

Again, tying its “GND” probe line to both chassis and earth ground will – in itself – not cause current to flow.

So far so good. Now let’s look at the bigger picture – since both appliances are tied into the same AC mains:

JC s Doodles page 28

As shown in part 1, if there are large currents flowing through AC mains wiring, then there will be a voltage drop in the wires (red box), which means the different power inputs will start to “float” relative to each other.

Observation #3: the ground wire normally carries NO current!

This is the crucial bit which makes grounding sane. When there’s no current, there’s no voltage drop. In a 3-wire system, now common in most parts of the world, that ground wire is nice as reference and as fail-safe.

First the fail-safe: as you saw, it is common to tie all chassis and signal grounds to the “G” wire, which in turn is normally tied to earth ground somewhere in the basement (in one spot only). If there is ever a short between the other current-carrying (and dangerous) wires of AC mains and this “G” wire, then two things happen: 1) currents in the “L” (live) and “N” (neutral) wires no longer cancel, and 2) a current will start to flow through the “G” wire.

This is where the RCD or “RRCB” enters the picture. In modern house wiring setups, it kicks in the moment a current difference larger than 30 mA is detected between L and N. So what this does is shut down power as soon as 30 mA or so starts flowing through the “G” wire. An excellent safety device – it must have saved countless lives.

Observation #4: electricity takes the path of least resistance (or inductance in the case of HF).

So if the “G” wire normally carries no current and up to 30 mA during a fault, why is it as thick as “L” and “N”?

One reason that it’s an extra safety – if the RCD doesn’t trip, then the fuse will blow. But another reason is to keep the resistance of the “G” wire much lower than the resistance of say a probe’s “GND” tied to the “–” of the power supply. If there’s a fault current and it decides that it’s easier to go through the probe’s “GND” wire, then it could send a damaging spike through it (again, the scope is a very sensitive low-current device).

So the effect of that green-and-yellow “G” wire running through the house, is to create a splendid 0 V reference (when everything is operating properly) and to act as fail-safe if L or N are brought in contact with it.

G is not there to carry current, but to tie all isolated, i.e. floating, power supplies in all devices together!

If you review observation #2 in this light, then each appliance has its own isolated power supply and the current it produces always goes back “into it”, so to speak. To put it differently: each power supply takes care of its own electrons. The common ground connection merely “secures” one side of each supply to a safe reference point – and ties it firmly to all the conducting surfaces around us. The more surfaces we tie to “G”, the more we can be assured that faults will trip an RCD or a fuse – and leave us happily intact to tell stories like this and write weblog posts.

How grounding works

In Hardware on Dec 6, 2011 at 00:01

I’ve often wondered how “ground” works.

Let me explain: ground is of course the zero voltage reference level, which we implicitly think of when talking of a 3.3V or 5V signal, for example. You can only measure voltage between two points – it’s a relative concept.

But we all (well, I do, anyway) loosely talk about 0V and “ground” as if it’s an obvious thing. Not so, if you talk to electricians or engineers involved with power circuits.

First of all, there’s no such thing as a single ground potential. You can push a metal rod into the ground and think you’ve hit a solid reference but you might be surprised what two such metal rods pushed into the ground at some distance will do in a thunderstorm!

So why is grounding and ground level so tricky?

The problem is resistance. Every copper wire has some resistance. And where current flows in a resistance, you get a voltage drop (Ohm’s law, again – it’s everywhere!).

Let’s take a simple circuit, and let’s stay in the domain of JeeNodes and Physical Computing:

JC s Doodles page 26

A 3.3V power supply feeds a JeeNode, which in turn controls a lamp. In normal low-power cases, things behave exactly as you’d expect. Ground is tied to the power supply, but both the JeeNode and the lamp are also connected on one side to ground, i.e. 0V.

I’ll redraw this to make the wiring resistance explicit:

JC s Doodles page 26 1

Those resistance values will be very small, let’s say about 10 milliohm, i.e. one hundredth of one ohm.

Now imagine that you’ve got a super-powerful 33 Watt lamp instead, which draws 10 A. And assume the power supply is a big fat one which can supply those currents, and that the Relay Plug is also a beefy souped-up version.

With the lamp off, and the JeeNode drawing about 10 mA, the voltage drop over R1 and R2 will be around 0.00001 V (10 µV). Virtually undetectable.

Let’s turn the lamp on. Now a 10 A current will flow through R1, R2, R3, and R4. That means the voltage drop over each one will be 0.1V – so the JeeNode, for example, will be running at 3.1V now!

But that’s not all. Since the “ground” level of the JeeNode, i.e. the wire between R2 and R4 is now floating 0.1V above the power supply ground, everything the JeeNode does starts to float. The signal to the relay will switch between 0.1 and 3.2V – it’ll never be 0V (to ground) in fact.

For a relay plug, that doesn’t really matter – it’ll still switch on and off as intended. But for things like analog signals and ADC/DAC conversions, this really messes things up. If you don’t plan for it, all your analogRead() measurements could easily be 0.2V off, that’s a 6% error.

Now imagine driving the lamp with a big fat MOSFET instead and using PWM. It’s not hard to see that the JeeNode is almost literally going to be in a roller-coaster ride as the switching ends up affecting everything!

Remember seeing the lights dim briefly when a big heater is turned on? That’s due to cable resistance (and inductance) and floating grounds, in essence. So forget about an absolute ground – there’s no such thing.

Does that mean we can’t measure properly? Of course we can. Because there are some simple ways to deal with these resistance effects. The first obvious trick is to use fat wires for stuff that draws a lot of current. This lowers the resistance, and hence the voltage drop. Reduced voltage drop is why cables are sometimes much thicker than strictly needed w.r.t. current-carrying capacity.

But that doesn’t mean you need to waste copper all over the place. Have a look at this design:

JC s Doodles page 26 3

Same circuit, but the JeeNode’s “ground level” is back in the microvolt range, even though it’s still switching 10 A. That’s because the current drops caused by the lamp currents no longer affect the JeeNode. R1 and R2 carry just 10 mA for the JeeNode again, even when the lamp is on: thin wires from power supply to JeeNode are ok.

Tomorrow, I’ll try to apply some common-sense to AC mains and multi-device grounding…

Types of memory for an ATmega

In AVR, Hardware on Dec 5, 2011 at 00:01

There are a number of types of memory in (and for) the ATmega.

Flash memory is the place where compiled sketches end up. This memory has an important property: it retains its contents even when power is off, yet it’s modifiable (even by the ATmega itself – that’s how the boot loader works). An ATmega328 has 32 KByte of flash memory, enough to store fairly substantial sketches. When an ATmega is powered up, it starts executing the code stored in its flash memory.

RAM memory is the work memory where variables, buffers, strings, and other bits of data reside which get used and changed by the running sketch. The contents of RAM memory is lost when power is turned off, but access to the data kept here is extremely efficient. RAM is limited to 2 Kbyte on an ATmega328, and often a scarce resource, especially since all strings also need to stored there (these get copied from flash on startup).

EEPROM memory is the “configurable” memory available to a sketch. It’s very similar to flash, but not used for code – only data can be stored in EEPROM, and you need to call specific routine to read and write data (i.e. copy them to/from RAM). EEPROM memory retains its contents, which makes it very suitable for configuration settings, encryption keys, i.e. data which needs to be retained. There are 2 KByte of EEPROM in an ATmega328.

That’s it as far as built-in memory goes. The are many other types of memory (some far larger than the above), but they all have to be connected to the ATmega as “external memory” through its I/O pins. External memory is slower (sometimes dramatically so), and requires more code to work with.

There are three common ways to use external memory: I2C, SPI, and parallel (links / images from Wikipedia).

I2C memory uses the “I2C bus” protocol to talk to external hardware. The I2C bus is also known as the “Two Wire” bus, because it requires only 2 I/O lines (plus ground and power, i.e. 4 wires). The I2C bus is several orders of magnitude slower than the above three types of memory, but one advantage is that it is very low cost, and that I2C-capable chips are small and available in many shapes and sizes. The main types of I2C memory chips are SRAM (static RAM, same as in the ATmega) and EEPROM (also same as in the ATmega). The most common sizes are in the order of kilobytes, or dozens of kilobytes. Adding I2C memory such as the Memory Plug for JeeNodes, is cheap and simple. It’s also relatively slow – requiring in the order of a few milliseconds to write out a page of 32 bytes.

350px I2C svg

SPI memory uses the “SPI bus”, which needs 3 I/O pins shared among all SPI devices, plus 1 I/O “chip select” pin per device. It can be one or two orders of magnitude faster than I2C. The choice of SPI memory chips is more limited than I2C, but the memory chips are usually larger (such as the 2 Mbyte chip used in a JeeLink). The advantage of SPI over I2C is speed, but it’s still a serially-connected solution, and therefore still an order of magnitude slower than the ATmega’s built-in memory.

350px SPI single slave svg

Parallel memory uses many I/O pins together to get address and data information exchanged at a higher speed. This option is not really practical with an ATmega328, which has a limited number of I/O pins. It’s the way “real CPU’s” work, connecting the processor with external memory using over a hundred I/O pins.

One more memory type is worth mentioning here, because it’s easy to interface with an ATmega:

SD and µSD cards are a form of external flash memory, used widely in digital camera’s, for example. They offer by far the largest memory sizes (2 GByte and up) for a very low cost. The reason these cards can be used, is that the SD standard supports an SPI fallback mode, which means that they can be connected in the same way as other SPI memory chip solutions. Two caveats: 1) some initial handshaking will be needed to put an SD card into SPI mode, and 2) SD and µSD cards tend to be slow in SPI mode, i.e. nothing like SPI-capable memory chips.

In case you think that cheap and ample memory storage has always been so convenient: here are some flashes from the past of funky technologies used decades ago – check out mercury, drums, tubes, cores, and bubbles!

Update – see also this weblog post about RAM usage.

Generating sine waves with DDS

In AVR, Hardware on Dec 4, 2011 at 00:01

This is a topic I’ve covered before, in a post of about a year ago, but given the recent post about a sine wave generator, and yet another opportunity to learn and show the new scope in action, here goes…

The first step towards Direct Digital Synthesis (DDS), is to generate a rapidly-adjusted analog signal through a Digital-to-Analog Converter (DAC). One way to do so is to use a resistor ladder network, tied to a number of digital output pins. The idea is that all these pins are either 0 or 1 using fixed voltage levels, so with the proper resistors, you get a signal where bit N has the proper weight in the final signal to represent the voltage 2^N.

With 8 output bits, you get an 8-bit DAC which can output voltages 0 .. 3.3V in 256 steps, i.e. ≈ 13 mV each.

The next step is to approximate a sine wave by rapidly adjusting the output bits to the values of a sine wave. This toneGen sketch from the 2010 weblog post does precisely that:

This lets us generate an decent sine wave by stepping voltages in the proper sequence, looping forever:

SCR31

The trouble is the “glitching” and the step-wise behavior of the signal:

SCR32

This last image shows a small portion of the signal near zero, greatly magnified – and it’s quite a mess!

Fortunately, this is usually very easy to fix with a low-pass filter (even just a single R-C filter), since these artifacts are at a much higher frequency than the generated sine wave itself. But let’s not go into such details for now.

The AD9851 chip used in the Sine Wave Generator works the same way, but it has one more clever trick up its sleeve, which lets it generate arbitrary frequencies using a single fixed crystal-based master clock.

Let’s start from a 1 MHz clock, and use a 1000-element lookup table for the sine wave. Then every microsecond, a new value is looked up, and after 1000 lookups we can start over. The result would be a 1000Hz sine wave.

Now suppose we want a 500 Hz sine wave, driven by the same 1 MHz clock source: we can simply re-use the same table entry twice, before moving on to the next. Likewise, for a 1 Hz sine wave, we’d re-use the same table entries 1000 times, before moving on to the next table entry.

How about 300 Hz? Ah, yes, that’s a bit tricky. We’d need to re-use the same table entry 3 1/3rd times, which is not really meaningful. But what we can do, is represent the step time as a fractional value, i.e. 0.3. The 1st “step” is 0.3, the 2nd 0.6, the 3rd 0.9, the 4th 1.2, etc. The fractional part is called the “phase”, BTW.

And now the big trick: ignore the fractional part while deciding which table entry to use!

This causes the table entries to be used in sequence, but possibly with a slight jitter as the stepping progresses in such a way that the full table will be cycled through exactly fast enough to produce the desired frequency.

So 1 Hz output is produced with a 0.001 step, and 500 Hz is a 0.500 step. I.e. frequency = 1000 x step.

The same mechanism can also be used to generate frequencies higher than the 1 KHz you get when stepping through each of the 1000 table entries with a 1 µs step rate. All you need to do is allow the fractional step rate to be larger than 1. Stepping through the table with rate 100.000 (i.e. skipping the next 99 entries each time) will generate a 100 KHz sine wave, albeit with only 10 data points per wave. So its amplitude changes will not be as fine-grained, but its frequency will be exact. Again, same formula: frequency = 1000 x step – easy!

This is the basis on which a DDS chip such as the AD9851 can adjust its frequency output. It’s based on very fast hardware with a very fast DAC: the input clock can be up to 30 MHz, and it even has a built-in 6x clock multiplier, so the “sine wave table stepping” can be based on a 180 MHz clock, which is equivalent to a 5.56 ns step time!

For completeness: an Arbitrary Waveform Generator (AWG) works similar to a DDS in that it also synthesizes a wave by running samples through an DAC from a table, but now the table may contain anything, not just a pure sine wave. The entries in the table describe one full wave. In this case, stepping is not possible (neither fractional nor skipping) because then you’d no longer be creating the proper waveform. Instead, an AWG really has to accurately control its step time from table entry to table entry to produce the desired frequency. This is more complicated – also because the wave table is RAM, not just a fixed ROM with sine wave coefficients.

So much for DDS and AWG … onwards!

Same RFM12B’s, but flatter

In Hardware on Dec 3, 2011 at 00:01

This is to announce that from now on JeeNodes will be fitted with a different type of RFM12B wireless module:

DSC 2681

Previous module on the left, new module on the right.

The difference? It’s just a bit flatter, that’s all. As you can see, it’s the same board – with a low-profile crystal:

DSC 2682

For most purposes, the change is irrelevant. The module is electrically identical: same pinout & commands, same RF12 library, etc. But in some scenarios, the lower profile might be useful, i.e. when the MPU is also SMD.

This is also why the flat model is going to used with the new JeeNode Micros.

New oscilloscope

In Hardware on Dec 2, 2011 at 00:01

Get ready for more oscilloscope screen shots after yesterday’s sneak preview…

These come from a Hameg HMO0722, which is techno-babble for “70 MHz bandwidth, 2-channel oscilloscope”:

SCR02

It’s the “little” brother of a series of 8 scopes, covering 70..200 MHz bandwidths in 2- and 4-channel versions.

There are three aspects of this series which make it stand out, IMO:

  • The display: full VGA, 640×480, with lots of room for graph detail and informational text
  • The software: this thing is packed with features, such as the above one-button “Quick View” mode
  • The hardware: small, quiet, fast-sampling, sensitive, deep memory, and an optional logic analyzer

I’m not going to do a full review here – I wouldn’t even know how to do that, but more importantly, this isn’t really a story about a specific scope, but more an impression of the sort of capabilities you can find in a modern digital oscilloscope nowadays. FWIW, the HMO series costs from ≈ €1300 .. €3400 – depending in part on what options are included (the logic analyzer adds €345 .. €690, for example) – pretty hefty price tags!

The above screen shot was made via a USB stick, which is why it can be shown here in jaw-dropping resolution. The automatic measurements shown above are extremely convenient, with lots of attention to detail and precise tags / markers. Note that this mode is “live”, i.e. it tracks the signal while the scope is running.

The sampling rate is the maximum 2 GSa/sec in this case (a 1 KHz signal from one of the test pins). That means you can stop the scope and zoom in to see considerable detail: 2 samples per ns, 100 ns/div, 12 div/screen is 2400 ADC samples, just for this single screen. When only one channel is active, the scope cleverly re-uses the spare channel’s memory to store 2 million samples (looks like it’s actually a bit more).

Here is the zoom function, pushed to the limit (the top is an overview pane, the bottom shows the details):

SCR04

There are 4 sample points per division (the rest is merely interpolated), but as you can see when moving the horizontal trigger time, it really has one sample every 500 picoseconds. Note the rise time, which seems to be about 10 ns for this 70 MHz model. Zooming back out gives me slightly more than 1 ms, so there really are over 2 million samples available to look at: one “up” and two “down” flanks of the 1 KHz square wave.

There’s a catch, however. Such extreme acquisition rates would require phenomenal amounts of processing power if you wanted to capture everything and display up to 2000 waveforms per second, as this model claims. Usually, this scope will not go fill its memory to the limit, but trade refresh speed for sampling depth (it’s all configurable). This reduces the “blind time” when the scope isn’t capturing but busy processing and presenting the information.

So much for raw power. Speaking of power: this scope draws 22 Watt when in use, and 0.4 Watt in standby.

Here’s a more meaningful measurement – the 3.3V supply ripple from an AA Board driving a JeeNode:

SCR09

(No, I didn’t smash up the screen – the above image was doctored to remove some empty space.)

The other feature I want to highlight here is the logic analyzer option. Since I don’t have the logic probe yet, the only way to capture logic signals is via the analog scope channels – which luckily is supported just fine:

SCR66

You’re looking at a short burst of SPI commands sent to an RFM12B. This is just SCK and MOSI, since I have only 2 analog probes to read this in with. The rest of the buffer is empty, since the bursts are sent only every 3 seconds.

Here again, the settings were adjusted to store as much as possible in sample memory. I found out by trial and error that the 2 ms/div setting was the maximum usable to reliably decode this 1 MHz SPI stream. The sampling rate is shown as 250 kSa/sec, which seems odds (4 µs resolution isn’t possibly enough to detect flanks in a 1 MHz signal). Maybe the hardware is playing tricks and storing 8 bits per byte? It’d explain the “20 MSa” value.

Then again, the top pane only displays 24 ms, and it appears to be the entire dataset. Which is 24,000 bits of decoded data @ 1 MHz, i.e. a couple of thousand bytes from the SPI stream. Enough for most purposes, especially since you can trigger on a specific serial bit pattern and then start capturing there (another add-on).

I’m not too concerned with ultra-deep logical analyzer storage. It’s easy to toggle an I/O pin in software where it gets interesting, and then trigger on that. There’s also a “B trigger” feature, as a way to cascade triggers.

Other supported protocols: UART, I2C, and parallel (requires the logic probe to acquire more signals).

This is not my own scope, BTW. I recently ordered another one from this series, but was given this unit on loan by Rohde & Schwarz (tops!) – it turns out that the scope is in short supply and has a delivery time of many weeks.

So much for gushing over an oscilloscope – geek stuff!

RF12 power optimization

In AVR, Hardware, Software on Dec 1, 2011 at 00:01

Here’s a small evolutionary change to the RF12 driver, to squeeze one more drop of power consumption out of it.

This is the code for which I’m trying to optimize power consumption:

Screen Shot 2011 11 19 at 11 31 16

The Sleepy::loseSomeTime() call is the big power saver. It puts the ATmega into a total power down mode, except for the watchdog timer, which is used to get it back out of this comatose state. So we’re sleeping for 10 seconds.

Around it are the rf_sleep() calls needed to put the RFM12B into low-power mode as well.

And lastly, the rf12_sendWait(3) call does something pretty nifty: it puts the ATmega into full power down mode between each byte sent to the RFM12B while transmitting. This requires a non-standard fuse setting in the ATmega – it only works with a ceramic resonator or the internal clock oscillator, not with a crystal: wake up out of power down within a few clock cycles.

The most efficient mode turns out to be with the ATmega running at 8 MHz off the internal RC oscillator (which starts up really fast). With default Arduino’ish settings, you have to use mode 2, i.e. a less extreme power down mode so it can wake up fast enough.

Here’s one complete transmission of a 8-byte payload (scope details to follow tomorrow):

SCR33

Each vertical division is 5 mA current draw (the voltage drop across a 10 Ω series resistor). You can see the ATmega turn on, drawing 5 .. 9 mA, and the RFM12B in transmit mode consuming about 23 mA.

The red line is pretty advanced stuff: it integrates the current over time – which is equivalent to the amount of charge consumed. At the end of the trace, this leads to a result of 7.22 microcoulombs per packet sent. One way to interpret this (thanks, Jörg – see comments), is that you could send one packet per second on an average current of less than 8 µA (hm, I think that should be 80 µA).

The “blips” are when the ATmega wakes up and feeds another byte to the RFM12B. In detail (edited image):

SCR16

These blips take about 32 µS @ 5 mA, which is what it takes to communicate with the RFM12B on the SPI bus at 2 MHz. The reason is that the RFM12B supports a 2.5 MHz maximum SPI rate (it turns out that this limitation only applies for data read from the RFM12B module).

The blips repeat 18 times, every 162 µS. Why 18? Well, an RF12 data transmission looks as follows:

RF12 packets

That’s 9 bytes of overhead, plus the 8 payload bytes, plus a trailing interrupt to shut down the RFM12B once the transmission is over.

For completeness – in case you think I can’t count blips: there’s one more activity peak at the start. That’s the call to rf12_canSend(), to check that the RFM12B is ready to start a transmission (which then takes 250 µs to start).

This is probably the limit of what you can push out of power savings with an ATmega (or ATtiny) and an RFM12B. Well, apart from: 1) sending less data, 2) increasing the transmit data rate, or 3) decreasing transmitter power.

When re-using the same code with “rf12_sendWait(2)” and running with normal fuse settings at 16 MHz using a ceramic resonator, it uses only slightly more charge – 7.70 µC, i.e. 7% more. So while this was a nice exercise, it’s not really a major improvement.

All in the name of nanowatt yak power s(h)aving…

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://github.com/jcw/jeerev.git jee
    cd jee
    wget http://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://github.com/jcw/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 http://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…

Permanent LCD display

In Hardware on Oct 31, 2011 at 00:01

Remember the re-using an LCD screen post?

Well, I’ve now built it into my lab corner at JeeLabs:

DSC 2698

The panel is hinged and swings to the left for access to other stuff, and everything has simply been screwed on. You can see the Acer Aspire One netbook mid-center, which is driving this display in mirroring mode right now.

Here’s the back, with 12V power, VGA, and DPMI connectors:

DSC 2700

You can see the (ugly) drilled cutout, with the backlight of the display shining through.

This display is going to be used mainly to experiment with basic in-house display of the data I’ve been collecting for so long, but it will also be available for a new oscilloscope I ordered recently, as well as other experiments which produce a VGA or DPMI signal, such as embedded Linux boards. A Raspberry Pi, perhaps?

A new life for an old discarded laptop display!

Driven by passion

In Musings on Oct 30, 2011 at 00:01

After three years, I thought that it might be interesting to “show you around” here at JeeLabs:

DSC 2638

To the right – not visible here – is the main electronics corner, which will be shown in tomorrow’s weblog post because of another little project I’ve been working on. Let me explain the various bits ‘n bobs you see here:

JeeLabs tagged

It might seems odd, but this is all there is to the JeeLabs, ahem, “empire”.

The Vancouver view always brings back lots of good memories from a year-long stay there, a couple of years ago. An amazing place, in terms of cultural diversity and with its breathtaking nature wherever you go.

I also wanted to show you this to illustrate how little is needed to sustain a small shop. It wouldn’t be sufficient if you’re chasing riches and fame, but if all you want is to have fun and keep going, then hey, it’ll do fine.

JeeLabs would have been totally unthinkable on this scale two decades ago.

CC-RT: Pin assignments

In AVR, Hardware on Oct 29, 2011 at 00:01

Part 4 of the Crafted Circuits – Reflow Timer series.

Now that all the pieces of the circuit are known, more or less (I’ll assume that the MAX31855 can be used), it’s time to figure out whether everything will fit together. One issue I’d like to get out of the way early on, is pin assignments on the ATmega. There are 20 I/O pins: 14 digital, of which 6 PWM, and 6 digital-or-analog.

The best thing would be to make this as compatible with existing products as possible, because that simplifies the re-use of libraries. For this reason, I’ll hook up the RFM12B wireless module in the same way as on a JeeNode:

  • D.2 = INT0 = RFM12B INT
  • D.10 = SS = RFM12B CS
  • D.11 = MOSI = RFM12B SI
  • D.12 = MISO = RFM12B SO
  • D.13 = SCK = RFM12B SCK

5 I/O pins used up – let’s see how many the rest needs:

  • 2 LED’s = 2 pins
  • 2 buttons = 2 pins
  • buzzer = 1 pin
  • LCD + backlight = 7 pins
  • thermocouple = 3 pins
  • SSR output = 1 pin

Total 5 + 16 = 21 pins. Whoa, we’re running out of pins!

Unfortunately, we’re not there yet: the thermocouple chip consumes about 1 mA, so we need a way to power it down if we want a serious auto power-off option. That’s one extra pin.

Also, it would be very nice if this thing can be programmed like a regular Arduino or JeeNode, i.e. using D0 and D1 as serial I/O. That also would help a lot during debugging and in case we decide to use the serial port for configuration. Hm, another 2 pins.

And lastly, I’d like to be able to measure the current battery voltage. Drat, yet another (analog) pin.

All in all we seem to need 5 more pins than are available on an ATmega168/328 28-DIP chip!

The good news is that there are usually a few ways to play tricks and share pins for multiple purposes. One easy way out would be to just use an I/O expander (like the LCD-plug) and gain 5 I/O pins right away. But that’s cheating by throwing more hardware at the problem. Let’s look at some other options:

  • the SSR output can be combined with one of the LEDs, since a red LED will probably be used to indicate “heater on” anyway
  • the thermocouple chip is a (read-only) SPI chip, which means that its SCK and SO pins can be shared with those of the RFM12B
  • one way to free the button pins is to put the buttons on data lines used by the LCD – with extra resistors to let the LCD output work even while pressed
  • the buttons and LEDs could be combined, as on the Blink Plug (this is mildly confusing, since pressing a button always lights its LED as well), but this would prevent sharing the SSR output with the red LED
  • multiple buttons could be tied to a single analog input pin by adding some extra resistors, but this rules out the use of pin-change interrupts
  • yet another trick is to combine a high-impedance analog input (for measuring battery voltage) with a pin which is usually used as output, such as one of the LCD data pins

I’m inclined to adopt the first three tricks. That frees five pins – one can be used to power the thermocouple chip and two would be D0 and D1 to support standard serial I/O. We could have up to 5 push buttons this way.

So all in all, the 28-pin ATmega seems to be just right for the Reflow Timer. Depending on the complexity of the sketch, either an ATmega168 or an ATmega328 could be used. My current reflow sketch fits in either one.

With luck, the Reflow Timer can remain compatible with Arduino, RBBB, JeeNode, etc. and it will support sketch uploads in exactly the same way as with JeeNodes and RBBB’s, i.e. through an FTDI 6-pin header with a USB-to-FTDI interface such as the USB-BUB.

Let’s try and come up with a tentative pin allocation:

  • D.0 and D.1 = serial I/O via FTDI pins
  • D.2 and D.10 .. D.13 = RFM12B, as above
  • D.3 = LCD backlight (supports hardware PWM)
  • D.4 = buzzer
  • D.5 and D.6 = LED outputs (both support PWM)
  • D.8 and D.9 = thermocouple power and chip select
  • A.0 = battery voltage readout
  • A.1 .. A.5 and D7 = LCD (4 data + 2 control)
  • A.1 .. A.5 = shared with up to 5 push buttons

Several pins could be changed if this will simplify the board layout later – but hey, ya gotta start somewhere!

Note that I’m using D.X as shorthand for digital pins, and A.Y for analog pins, matching Arduino terminology (where A.Y can also be used as digital pin => D.(Y+14)).

The next step will be to work out more electrical details, i.e. figure out how to add some new features.

The AC current sensor node lives!

In Hardware, Software on Oct 28, 2011 at 00:01

At last, everything is falling into place and working more or less as intended:

    OK 17 172 31 173 31   <- 25 W incandescent
    OK 17 169 31 177 31
    OK 17 40 0 41 0       <- open
    OK 17 245 95 40 0     <- 75 W incandescent
    OK 17 140 95 245 95
    OK 17 43 0 140 95     <- open
    OK 17 39 0 43 0
    OK 17 118 2 42 0      <- 2W LED-light
    OK 17 211 2 97 2
    OK 17 219 2 102 2
    OK 17 107 2 219 2
    OK 17 89 2 107 2
    OK 17 40 0 82 2       <- open
    OK 17 39 0 40 0
    OK 17 38 0 39 0
    OK 17 219 53 38 0     <- 40 W incandescent
    OK 17 234 53 219 53
    OK 17 43 0 234 53     <- open
    OK 17 149 75 43 0     <- 60 W incandescent
    OK 17 23 0 149 75     <- open
    OK 17 42 0 23 0

That’s the log of packets coming in from the AC current node, as I inserted and removed various light bulbs. Still through the isolation transformer for now.

As you can see, every change is very clearly detected, down to a 2W LED light. These are all the bulbs with an E27 fitting I happened to have lying around, since the test setup was fitted with one of those. Some other time I’ll try out light inductive loads, chargers, and eventually also a 700 W heater as load.

I’m not interested that much in the actual readings, although there is a fairly direct relationship between these wattages and the 2-byte little-endian int readouts. The fluctuations across readings with unchanged load are small, and the no-load readout is lower than in my previous tests, perhaps the shorter and more direct wiring of this setup is helping avoid a bit of noise.

One problem I see is that some packets are lost. Maybe the way the wire antenna is laid out (quite close to the PCB’s ground plane) prevents it from working optimally.

The other problem seems to be that this node stops transmitting after a while. I suspect that the current draw is still too large, either on the ADC side (500+ samples, back to back) or due to the RFM12B packet sends (unlikely, IMO, after the previous test results). At some point the voltage over the supercap was 3.1V – I’m not sure what’s going on, since after a new power-up the unit started transmitting again.

Hm… or perhaps it’s that plus an antenna problem: when I rearranged it, things also started working again (I’m always cutting power before messing with the test circuit, of course).

But all in all I’m delighted, because this unit has a really low component count!

AC current node prototype

In AVR, Hardware on Oct 27, 2011 at 00:01

Time for some pictures. Here’s the “AC current node” prototype I’ve been working on:

DSC 2680

And in case you’re wondering: that’s a simple plastic enclosure I found a while back, which looks pretty much like (and probably was intended as) … a game catridge!

Here’s the completed unit with a test hookup:

DSC 2690

You can see the transformer-less power supply, and an ATtiny84-with-RFM12B board, which I’m tentatively calling the “JeeNode Micro” (“JNµ”) – 16 x 48 x 4 mm:

Screen Shot 2011 10 17 at 21 18 07

Please note that I’m using this for internal projects for now. I haven’t figured out whether it’s suitable for the shop, since the JNµ is different from a JeeNode in several ways, not in the least in that it requires quite a bit more hand-holding to develop “sketches” for and to load them into the unit. This isn’t even the first JNµ board – I’ve tried several different layouts in the past.

For this particular project though, it’s quite a good fit, both in size and due to the ATtiny’s differential ADC plus 20 x gain stage. I’ve yet to hook up the analog input to the sense resistor, BTW. It’s all work-in-progress…

Running on charge

In AVR, Hardware, Software on Oct 26, 2011 at 00:01

Now that the supercap charger works, and now that I’ve switched to the ATtiny84 as processor, everything is ready to create a self-contained AC current sensing node.

The one missing piece is the software for it all. It’s going to take a while to get it tweaked, tuned, and optimized, but a basic check is actually quite easy to do.

Here is the main loop if my first test, reusing most of the code already in the tiny50hz sketch:

Screen Shot 2011 10 17 at 20 03 56

My main goal was to quickly get power consumption down, so that the ATtiny would use less than what’s available through the low-power supply, i.e. roughly 1 mA. Without extra steps, it’ll draw over 4 mA @ 8 MHz.

What I did was to reduce the clock rate to 1 MHz (except while processing RF12 packets), and to turn off subsystems while not needed (timer 1 is never used, and the ADC and USI h/w is now enabled only while used).

These two lines at the top of loop() are special:

  set_sleep_mode(SLEEP_MODE_IDLE);
  sleep_mode();

They will reduce power consumption by halting the processor until the next interrupt. Since time is being tracked via the millis() call, and since that operates through a timer interrupt, there is no reason to check for a new millisecond transition until the next interrupt. This is a quick way to cut power consumption in half.

But keep in mind that the processor is still running most of the time, and running at 1 MHz. That explains why the current consumption remains at a relatively high 440 µA in the above code (with a brief “power blip” every 16 s). For comparison: in power-down mode, current draw could be cut to 4 µA (with the watchdog timer running).

Still, this should be enough for a first test. Sure enough, it works fine – powered by the ISP programmer:

    OK 17 84 2 0 0
    OK 17 67 2 84 2
    OK 17 103 2 67 2

Every ≈ 16 seconds, a 4-byte packet comes in with the latest reading and the previous reading (as 2-byte ints).

The interesting bit is what happens when the ISP programmer gets disconnected. While connected, it charged the supercap to about 4.9V – so with a bit of luck, this node should keep running for a while, right?

Guess what… it does. My test node just sent out 197 packets before running out of steam!

This includes the ≈ 500 x ADC samples and 16-second waits in each cycle. IOW, a 0.47 F capacitor charged to 4.9V clearly has more than enough energy for this application. In fact, it makes me wonder whether even a normal electrolytic capacitor might be sufficient. The benefit of a smaller capacitor would be that the node can be up and running much faster than the 1 hour or so needed to charge up a supercap.

Here’s my very very sketchy estimate:

  • let’s assume the unit operates down to 2.5 V
  • with 4.9 V charge, it can run for about 200 cycles
  • so with 3.7 V charge (on AC mains), it ought to run for 100 cycles
  • using a capacitor 1/100th the size, we ought to have enough charge for one cycle
  • with more power-saving logic, energy use can no doubt be lowered further

Given that the node is permanently powered, a 4,700 µF cap ought to be sufficient. I’ve ordered a 6,800 µF @ 6.3V electrolytic cap – with a bit of luck, that should also work. And if it does indeed, startup times will go down drastically, to hopefully just a few seconds.

Progress!

Picking an ATtiny

In AVR, Hardware on Oct 25, 2011 at 00:01

The reason I’m using an ATtiny for the AC current measurement setup, is their differential ADC + gain, and because it is fairly easy to develop for them using the same Arduino IDE as used by, eh, well, Arduino’s and JeeNodes. There are good installers for Windows, Mac OSX, and Linux.

There are several very interesting alternatives other than ATmega and ATtiny, such as the Microchip Technologies PIC and the Texas Instruments MSP430 series. But while they each are attractive for a number of reasons, they either have only a development environment for Windows, or they don’t support standard gcc, or they just don’t offer enough of an advantage over the Atmel AVR series to justify switching. So for something like the AC current node, which doesn’t even need to run off a battery, I’d rather stick to the Arduino IDE and carry over much of what is already available for it. In terms of cost, the differences are minimal.

The trouble with the ATtiny85 I’ve been using for the AC current sensor is that it only has at most 6 I/O pins, while the RFM12B needs 5 to operate (with polling instead of interrupts, this could be reduced to 4).

I’ve tried hard to find tricks to re-use pins, so that the differential ADC pins can be used during measurements while still supporting the RFM12B somehow. I even considered using a 1-pin OOK transmitter instead of the RFM12B. But in the end I gave up – the hassle of finding a solution, figuring out how to support this in software, and still have a decent way of debugging this (read: ISP) … it didn’t add up.

It’s much easier to pick a chip which is slightly less I/O-pin limited, such as the 14-pin ATtiny84:

Screen Shot 2011 10 17 at 14 10 11

One drawback w.r.t. to the ATtiny85, is that it has no 2.56V bandgap reference, only 1.1V – but it does have differential ADC inputs with optional 20x gain stage, which is what made AC current measurements possible.

It turns out that the ATtiny84 has enough I/O pins (a whopping 11!) to support an SPI interface to the RFM12B as well as 2 complete JeeNode-like ports. There is in fact enough I/O capability here to hook up a Room Board.

The 8 Kb flash rom size is sufficient for the RF12 driver plus a bit of application-specific functionality. The 512-byte RAM is not huge, but should also be sufficient for many purposes (two full RF12 buffers will use up less than a third of what’s available). And lastly, there are 512 bytes of EEPROM – more than enough.

To be honest, I’ve been fooling around with this chip for some time, since it could be used to create even smaller PCB’s than the JeeNode. But it has taken me quite a while to get the SPI working (both hardware- and software-based), which was essential to support the RFM12B wireless module. The good news is that it now does, so this is what I’m going to use for the rest of the AC current sensor experiments – wireless is on the way!

Stay tuned …

No, wait. One more factoid: this weblog was started exactly 3 years ago. Celebration time – cheers!

Charging a supercap

In Hardware on Oct 24, 2011 at 00:01

This is a quick experiment to see how this very low-power direct AC mains supply behaves:

JC s Doodles page 20

Note that I’ve built the 200 kΩ value from two resistors in series. This reduces the voltage over each one, and offers a slight security if one of them shorts out. The max 1 mA or so of current these resistors will let through is not considered lethal – but keep in mind that the other side is a direct connection, so if that happens to be the live wire then it’s still extremely dangerous to touch it!

One idea would be to add a “fusible” 100 Ω @ 0.5 W resistor in series with the 200 kΩ. These are metal-film resistors which will disconnect if they overheat, without releasing gases or causing flames. I can’t insert it in the other wire due to the voltage issue, so I’m not really sure it actually would make things any safer.

Here’s my first test setup of this circuit, built into a full-plastic enclosure:

DSC 2687

It took 20 minutes to reach 1.8V, the absolute minimum for operating an ATtiny. This is not a practical operating voltage, because whenever the circuit draws 1 mA or more, that voltage will drop below the minimum again.

The RFM12B wireless module will need over 2.2V to operate, and draw another 25 mA in transmit mode. The only way to make this work will be to keep the transmit times limited to the absolute minimum.

Still, I’m hoping this crude power supply will be sufficient. The idea is to run on the internal 8 MHz RC oscillator with a startup divider of 8, i.e. @ 1 MHz. The brown-out detector will be set to 1.8V, and the main task right after startup will be to monitor the battery voltage until it is considered high enough to do more meaningful work.

With 3.5V power, an ATtiny draws ≈ 600 µA @ 1 MHz in active mode and 175 µA in idle mode, so in principle it can continue running at this rate indefinitely on this power supply. But for “fast” (heh) startup, it’ll be better to use sleep mode, or at least take the system clock down well below 1 MHz.

This might be a nightmare to debug, I don’t know. Then again, I don’t have to use the AC mains coupled supply to test this. A normal low-voltage DC source plus supercap would be fine with appropriately adjusted resistors.

After 35 minutes, the voltage has risen to 2.7V – sure, take your time, hey, don’t rush because of me!

Another 5 minutes pass – we’re at a whopping 3.0V now!

Time for a cup of coffee…

After 45 minutes the charge on the 0.47F supercap has reached 3.3V – yeay! I suspect that this will be enough to operate the unit as current sensor and send out one short packet. We’ll see – it’ll all depend on the code.

After 1 hour: 3.75V, which is about as high as it will go, given the 5.1V zener and the 2x 0.6V voltage drop over the 1N4148 diodes. Update: my test setup tops out at 3.93V – good, that means it won’t need a voltage regulator.

Apparently, supercaps can have a fairly high leakage current (over 100 µA), but this decreases substantially when the supercap is kept charged. In an earlier test, I was indeed able to measure over 2.7V on a supercap after 24 hours, once it had been left charged for a day or so. In this current design the supply will be on all the time, so hopefully the supercap will work optimally here.

Not that it matters for power consumption: a transformerless supply such as this draws a fixed amount of current, regardless of the load. Here’s the final test, hooked up to live mains without the isolation transformer:

DSC 2688

Of this energy, over 95% is dissipated and wasted by the resistors. The rest goes into either the load or the zener.

Funny Eneloop battery

In Hardware on Oct 23, 2011 at 00:01

I don’t know what happened…

DSC 2685

Weird wrinkled plastic wrapper. No leakage or bulge. The other side:

DSC 2686

Maybe this thing got short-circuited and became very hot? Maybe the wrapping has some heat-shrinking properties on purpose, to report this condition even if you look well after things have cooled down again?

I’ve been switching to Eneloop AA batteries everywhere since over a year now, due to the three nice chargers I’ve got. The advantage over NiCad and NiMh is that these really retain their charge for more than a year – perfect for wireless sensor nodes. When fully charged, each cell supplies 1.3V @ 1900 mAh. I’m also re-using these batteries over and over again in the wireless keyboards and mice we have (my mouse runs out once a month).

But that’s the end of the line for this one!

ELRO energy monitor decoding #2

In Hardware on Oct 22, 2011 at 00:01

Yesterday’s post showed how to try and figure out the data sent out by the ELRO wireless units. There’s a lot of guesswork in there, but the results did look promising.

The last guess was about how the data bytes are organized in the packet – which is usually the hardest part. Ok, so now if I treat these as low-to-high 8-bit bytes, then the two packets give me:

    12 1 231 4 16 0 0 213 81 17    hex: 0C 01 E7 04 10 00 00 D5 51 11
    12 1 232 4 16 0 0 214 81 17    hex: 0C 01 E8 04 10 00 00 D6 51 11

There’s not much more one can do with this, because all the packets contain the same information. Now it’s time to add a load to the monitor, so that it will report some more interesting values. I used a 75 W light bulb, so the instantaneous consumption reported should be around that value, and there will probably be a slowly-increasing cumulative power consumption reported as well.

Here are a bunch of packets, using the most recent decoding choices:

Screen Shot 2011 10 16 at 16 10 13

Great – the first four repetitions have again mostly zero’s, with a minor fluctuation in what is presumably the line voltage again. Looks like each reading gets sent out 15 (!) times or so. Or maybe a few more which aren’t recognized – the pulse width thresholds might still be off slightly.

And then values start coming in. Let’s see what this gives when decoded as bytes:

    200 8 1 231 0 32 0 0 216 81 33
    200 8 1 230 0 32 0 0 215 81 33
    200 8 1 230 0 32 0 0 215 81 33
    200 8 1 229 0 32 0 0 214 81 33
    200 8 1 230 32 32 243 2 236 82 33
    200 8 1 230 32 32 242 2 235 82 33
    200 8 1 229 32 32 240 2 232 82 33
    200 8 1 229 32 32 239 2 231 82 33
    200 8 1 229 32 32 239 2 231 82 33
    200 8 1 229 32 32 240 2 232 82 33
    200 8 1 230 32 32 240 2 233 82 33
    200 8 1 229 32 32 239 2 231 82 33
    200 8 1 229 32 32 238 2 230 82 33

Hm. That fourth byte could indeed be the line voltage, but the rest?

Let’s try the 25 W lamp:

    200 8 1 229 10 32 246 0 214 82 33
    200 8 1 229 10 32 246 0 214 82 33
    200 8 1 228 10 32 246 0 213 82 33

Aha – 10 is ≈ 1/3rd of 32. And 246 is ≈ 1/3rd of 2*256+238. Maybe these are amps and watts, not cumulative values after all. No wonder it’s transmitting so often – a lost transmission will cause an inaccurate reading.

Here’s a 700 W load (my reflow grill):

    200 8 1 230 44 33 255 26 29 83 33
    200 8 1 230 44 33 246 26 20 83 33
    200 8 1 230 43 33 221 26 250 82 33

Checking the load with another meter tells me it’s more like 680 W and 2.89 A @ 231 V.

Well, well: the bytes 221 and 26, when interpreted as little-endian int are 6887, i.e. the wattage in 0.1 W steps!

Let’s try amps the same way. With no load, there were values 16 and 32, so probably bits 4..7 of that second byte are used for something else. Let’s try 43 and 33-32, little-endian: could it be 2.99 A?

If all these guesses are correct, then the 75 W lamp readings are: 0.32 A and 75.0 W, and the 25 W lamp readings are: 0.10 A and 24.6 W – hey, these are indeed all pretty much spot on, yippie!

Here’s the other unit with no load plugged in:

    102 12 1 232 0 16 0 0 210 81 17
    102 12 1 232 0 16 0 0 210 81 17

The first two bytes differ. Perhaps a unit ID with its own header checksum?

It looks like the 6-byte is either 16 or 32, perhaps indicating an auto-scale amps range. Also, note how the next to last byte changes from 81 to 82 to 83 on these readings. I suspect that the packet checksum is actually 16 bits.

Great, I think I can implement a decoder for them now. It would be nice to get the checksum validation right, but even without this it will be useful.

These two units are going to be used for some varying loads here at JeeLabs: probably the dish washer and the washing machine. Since they send out readings once every 10 seconds, that should give me sufficient info to correlate with the house meter downstairs.

The readout unit is of no use to me anymore, so I’ve taken it apart:

DSC 2683

Simple OOK receiver, and single-sided board. Not many surprises, really:

DSC 2684

There are low-cost temperature (an NTC ???) and humidity sensors in there, as well as a buzzer (you can set an alarm when a certain power level is exceeded).

The only interesting bit is that the power for the receiver is switched via a transistor, so presumably it synchronizes its reception timing to when the units transmit (the display supports up to 3 units).

One nasty habit of these ELRO units is that they send out a lot of packets: each one sends about 15 per every 10 seconds, and it looks like this takes well over one second per transmission. I’m glad they use the 433 MHz band, otherwise they’d cause quite a few collisions with all the wireless RF12 stuff going on at JeeLabs.

Onwards!

ELRO energy monitor decoding

In Hardware on Oct 21, 2011 at 00:01

I recently found this set at reichelt.de:

ELROEC11

The battery-powered receiver is a bit large and ugly (10×13 cm), but what I was after were the measurement units, which transmit wirelessly on the 433 MHz band, using OOK.

That was a good reason to dust off the ookScope project and adjust them to work with the latest Arduino IDE (sketch) and JeeMon (script).

Here is the result after over 1,000,000 pulses:

Screen

This is a histogram with counts on the horizontal axis and pulse widths on the vertical axis. Both are scaled in a somewhat peculiar logarithmic’ish way, but the main info is on the bottom status line: the packets contain 360 pulses (i.e. bit transitions) with maximum counts at pulse widths of 184, 360, and 460 µs.

I used very specific settings and thresholds to single out these packets:

Screen Shot 2011 10 16 at 14 28 48

So it only picks up packets with 360..362 bit transitions, and ignores all pulses under 40 µs (10 x 4 µs).

The two longer pulse widths might be the same “long” pulse, depending on whether that pulse comes after a short or a long pulse. Here are the first few pulse widths of a quick burst of packets (ignore the P and first int):

Screen Shot 2011 10 16 at 14 28 14

There’s clearly a pattern. If I apply the following translation:

  • pulse < 260 -> display as “-“
  • pulse 260..411 -> display as “.”
  • pulse > 411 -> display as “|”

… then this comes out (this is one long line, wrapped every 80 characters):

Screen Shot 2011 10 16 at 14 43 55

So it looks like there are short (< 260 µs) and long (> 411 µs) pulses, with always a pulse in the range 260..411 µs in between them. And if those dots contain no extra information anyway, then we might just as well omit them:

Screen Shot 2011 10 16 at 14 48 16

That leaves 181 bits of “data”, presumably. If I drop all packets which don’t end up with exactly 181 dashes and pipe symbols, then it turns out I get just a few patterns – here’s a group which changes halfway down, if you can spot the difference:

Screen Shot 2011 10 16 at 14 58 25

But there’s still too much regularity here, IMO. Note that there’s not a single run of three _’s or |’s in there (other than at the start of the line). In fact, all these are either _|’s or |_’s, back to back. So it looks like there are not 2 transitions per data bit, but 4. Let’s reduce the output further. I’ve replaced _| by “0” and |_ by “1” (assuming there are more 0’s than 1’s). I’ve also removed all duplicate lines, and inserted a count of them at the front:

Screen Shot 2011 10 16 at 15 16 03

Note the alternation of 1110 and 0001 in these lines. My hunch is that it’s a slowly varying measurement value, overflowing from 7 (binary 0111) to 8 (binary 1000). This would indicate that the bit order is low-to-high.

Note also that further down the packet, the bit pattern flips from 10 to 01, which is a difference of 1 in binary terms. That’s probably a checksum, and it’s not using exclusive or (since 4 bits have changed) but simple byte-summing. Furthermore, the checksum is 40 bits to the left of the changed value, so there are either 5 bytes from value to checksum, or 8 nibbles-plus-guard-bit units. Let’s try grouping them both ways:

Screen Shot 2011 10 16 at 15 32 18

There is no load right now. The 8-bit grouping is interesting, because then the value alternates between 231 (0b11100111) and 232 (0b11100100) … could this be the line voltage?

Tomorrow, I’ll continue this exploration – let’s see if the data can be extracted!

CC-RT: Choices and trade-offs

In Hardware on Oct 20, 2011 at 00:01

This is part 2 3 of the Crafted Circuits – Reflow Timer series.

There are many design choices in the Reflow Timer. The goal is to keep it as simple and cheap as possible, while still being usable and practical, and hopefully also convenient in day-to-day use.

Display and controls – there are several low-cost options: separate LEDs, 7-segment displays, a character LCD, or a graphics LCD. The LEDs would not allow displaying the current temperature, which seems like a very useful bit of info. To display a few numbers, a small character-based LCD is cheaper and more flexible than 7-segment displays (which need a lot of I/O lines). The only real choice IMO, is between a character-based and the graphics LCD. I’ve decided to go for a 2×16 display because A) fancy graphics can be done on a PC using the built-in wireless connection, and B) a character LCD is cheaper and sufficient to display a few values, status items, and menu choices. And if I really want a GLCD option, I could also use wireless in combination with the JeePU sketch.

For the controls, there’s really only one button which matters: START / STOP. The power switch might be avoided if a good auto-power implementation can be created in software. For configuration, at least one more button will be needed – with short and long button presses, it should be possible (although perhaps tedious) to go through a simple setup process. A third button might make it simpler, but could also slightly complicate day-to-day operation. So two or three buttons it is.

Temperature sensor – this is the heart of the system. There are essentially two ways to go: using an NTC resistor or using a thermocouple. The NTC option is considerably cheaper and can be read out directly with an analog input pin, but it has as drawback that it’s less accurate. In the worst case, accuracy might be so low that a calibration step will be needed.

Thermocouples don’t suffer from the accuracy issue. A K-type thermocouple has a known voltage differential per degree Celsius. The drawback is that these sensors work with extremely low voltages which require either a special-purpose chip or a very sensitive ADC converter. Since thermocouple voltages are based on temperature differences, you also need some form of tracking against the “cold junction” side of the thermocouple. Thermocouple-based sensing is quite tricky.

But the main reason to use them anyway, is mechanical: although there are glass-bead NTC’s which can withstand 300°C and more, these sensors come with short wires of only a few centimeters. So you need to somehow extend those wires to run from the heater to the Reflow Timer. And that’s where it gets tricky: how do you attach wires to that sensor, in an environment which will heat up well beyond the melting point of solder? And what sort of wire insulation do you use? Well… as it turns out, all the solutions I found are either very clumsy or fairly expensive. There’s basically no easy way to get a glass-bead NTC hooked up to the reflow timer in a robust manner (those wires out of the glass bead are also very thin and brittle). So thermocouple it is.

Thermocouple chip – for thermocouples, we’ll need some sort of chip. There seem to be three types:

  • dedicated analog, i.e. the AD597
  • dedicated digital, i.e. the MAX6675 or MAX31855
  • do-it-yourself, i.e. a sensitive ADC plus cold-junction compensator

The AD597 is used the the Thermo Plug and in my current reflow controller setup. It works well, with a voltage of 10 mV/°C coming out as analog signal. So with 250°C, we get 2.50V – this is a perfect match for an ATmega running at 3.3V. The only small downside, is that it needs an operating voltage which is at least 2V higher than the highest expected reading. If we need to go up to say 275°C (above what most ovens can do), then we’ll need a 4.75 V supply voltage for the AD597.

The MAX6675 doesn’t have this problem because the readout is digital, and works fine with supply voltages between 3.0 and 5.5V. But it’s a very pricey chip (over €14 incl VAT). Keeping these in stock will be expensive!

The MAX31855 is also a digital chip, and about half the price of the MAX6675. The main difference seems to be that it can only operate with a supply from 3.0 to 3.6V, which in our case is no problem at all (we need to run at 3.3V anyway for the RFM12B). I’ve no experience with it, but this looks like a great option for the Reflow Timer.

There is a slight issue with each of these chips, in that they do not exist in through-hole versions but only in a “surface mounted device” (SMD) style. The package is “8-SOIC”, i.e. a smaller-than-DIP 8-pin plastic chip:

8 SOIC sml

For people who don’t feel confident with soldering it might pose a challenge. There are no sockets for SMD, you really have to solder the chip itself. Then again, if you’re going to create a reflow setup for building SMD-based boards anyway, you might as well get used to soldering these size chips. Trust me, SOIC is actually quite easy.

(note: there is an all-DIP solution with the LT1025, but it needs an extra op-amp, so I’ve not checked further)

Battery

If we can use the MAX31855, then everything can be powered with 3.3V. This means that either 3x AA or 1x LiPo will work fine, in combination with a 3.3V regulator. I’ll stick with the MCP1702 regulator, even though it’s not the most common type, because of its low standby current – this will help reduce power in auto power-down mode.

But how much current do we need? To put it differently: how long will these batteries last? Let’s find out.

The prototype I have appears to use about 35 mA while in operation. Let’s take a safety margin and make that 50 mA in case we also need to drive an opto-coupler for the SSR option. And let’s say we use 2000 mAh AA cells, then we’ll get 40 hours of operation out of one set of batteries. Let’s assume that one reflow cycle takes 10 minutes, plus another 5 minutes for auto power-off, then we can use one set of batteries for 160 reflow cycles. Plenty!

We could even power the Reflow Timer with an AA Power Board, and still get about 50 cycles – but that would increase the cost and require some very small SMD components.

Let’s just go for the 3x AA setup, with either a DC or USB jack as possible alternative.

AC mains switching

For switching the heater, there are several options. The one I’m using now is a remote-controlled FS20 switch from Conrad (or ELV). It can be controlled directly by the RFM12B wireless module. An alternative would be the KAKU (a.k.a. Klik Aan Klik Uit or Home Easy) remote switch, which operates at 433 MHz and kan also be controlled directly from the RFM12B. The advantage of this setup is that you never need to get involved with AC mains – just place the remote switch between mains socket and heater (grill, oven, etc) and you’re done.

Another option is to use a Solid State Relay (SSR), which needs 5..10 mA of current through its built-in opto-coupler. I built this unit a while back to let me experiment with that. The benefit of such a configuration is that all the high-voltage AC mains stuff is tucked away and out of reach, and that the control signal is opto-isolated and can be attached to the Reflow Timer without any risk. Note that with SSR, the RFM12B module becomes optional.

Yet another option would be to use a mechanical relay, but I’d advise against that. Some heaters draw quite a bit of current (up to 10A) and will require a hefty relay, which in turn will require a hefty driver. Also, very few power relays can operate at 5V, let alone 3.3V – which means that a 3x AA powered approach would not work.

So, RF-controlled switch it is, with an extra header or connector to drive the LED in an SSR as option.

That’s about it for the main Reflow Timer circuit design choices, methinks.

CC-RT: Prototyping

In Hardware on Oct 19, 2011 at 00:01

This is part 2 of the Crafted Circuits – Reflow Timer series.

Now that the initial requirements of the Reflow Timer have been laid out, it’s time to design and build a first prototype of the whole setup. Normally, I’d do this with either a solder-less breadboard (shown on the left) or a soldered protoyping PCB (bottom view of an example shown on the right):

DSC 2691

But in this case, I’ll skip those since I already built up a system using a JeeNode, some plugs, and my favorite circuit hacking setup, which I call Projects On Foam:

DSC 2189

That’s a JeeNode mounted upside-down, with a few plugs: a Thermo Plug, a Blink Plug, and an LCD Plug with a 2×16 character LCD on top. In the bottom right is a 4x AA battery pack, stuck to the board with double-sided tape.

I’ve been using this setup for about a year now. There are some “features” listed which don’t actually exist, such as the calibration mode: the current sketch has fixed values, tweaked by trial and error for my specific grill. But apart from that, it works well: prepare grill, turn on, press start, wait for beep, open grill, turn off, done.

The reason to skim over this step in this series of posts, is that your setup will differ anyway, unless you intend to build exactly the same thing. But it’s still a crucial step to go through. This is where you get to test that your idea actually works, and where you create the setup needed to develop and test the software, i.e. sketch.

Having constructed this setup, I know it works. I also gained valuable experience with it – and I’m still not 100% satisfied (besides being a mish-mash of plugs stuck together on a foam board). The main issues are:

  • this is using an AD597 thermocouple chip, which needs at least 5V – hence the 4x AA
  • there is no provision for a mechanical or solid-state relay to switch the heater
  • I’d like to have more control over the backlight, i.e. dimming through PWM
  • it’d be nice to support an auto-power-down mode which draws virtually no current
  • the LCD plug could be omitted if we have enough I/O pins to drive the LCD directly
  • maybe the transistor driving the beeper can be omitted as well

Those last two items are all about reducing the number of components. Less components = lower cost = simpler build instructions = better chances of success = everybody happy :)

Tomorrow, I’ll go through the main choices / trade-offs.

Coming back for more

In News on Oct 18, 2011 at 00:01

The JeeLabs shop has always been based on the Shopify service (which I won’t recommend for European shops, because they haven’t got a clue about VAT). It looks nice, and I guess I fell for it before understanding all the implications. So Shopify it is, as far as JeeLabs is concerned. I’ve worked my way around VAT by simply refunding and issuing a VAT-exempt invoice where needed.

Anyway, it turns out that there is now a “customer login” option, which I activated a few days ago. What that means is that whenever you shop at JeeLabs, you now get a choice when checking out your order:

Screen Shot 2011 10 11 at 17 59 07

What that really means, is that you won’t have to re-enter your shipping details over and over again if you decide to come back for more. And judging from the info in Shopify, that’s about a third of all JeeLabs customers. I am very proud of that fact BTW, because in my view a return customer is someone who is genuinely satisfied with what he/she got the first time around. It feels good to be able to follow up.

If you don’t want to leave this sort of info on the Shopify servers, please keep in mind that the only difference is that you get to pick a password for re-using what you’ll need to enter anyway.

In case you’re worried that this information is going to be used (by me or anyone else), for anything but order fulfillment: don’t be. I’m probably far more extreme in my position than you on privacy. I do not track personal details. The internet is a nightmare in that respect as it is. I Really Do Not Track, nor keep logs, nor “forget” to remove logs. I don’t do Google Analytics. I don’t have the Shopify “stats” option. I don’t “visualize” web accesses. All I keep are recent activity logs of my own servers, to be able to figure out problems when needed.

Life’s too short for lots of things – and that includes feeding ego’s and spying on people, IMO :)

But that doesn’t mean you have to suffer and re-enter the same info over and over in the JeeLabs shop, eh?

Voltage levels

In AVR, Hardware on Oct 17, 2011 at 00:01

In yesterday’s post, I described the idea of powering the AC current detector via a transformer-less power supply, using a very large capacitor or a supercap.

That means the whole circuit ends up being connected to 220V AC mains. You might think that nothing changed, since the circuit was already connected to mains via the 0.1 Ω shunt, but there’s more to it – as always!

If the power supply is tied to AC mains, then that means the circuit’s GND and VCC are also tied to these wires. The problem is that these two things interfere with each other:

JC s Doodles page 19

Because now we have a signal coming from the voltage drop generated by the shunt which is referenced to the same voltage level as the GND of the circuit. In other words, that signal we’re trying to measure now swings around zero! And while the ATtiny has a differential input, which in principle only cares about the voltage differential between two pins, it’s not designed to deal with negative voltages.

Uh, oh – we’re in trouble!

I could use a capacitor to “AC-couple” the 50 Hz frequency into a voltage divider, but that effectively creates a high-pass filter which attenuates the 50 Hz and lets more of the noise through. Not a very nice outlook, and it’s also going to require a few additional passive components. I’m still aiming for a truly minimal component count.

But we’re in luck this time. The differential ADC appears to be perfectly happy with tying one side to ground. It might not be able to measure the negative swings, but it does the positive ones just fine. When I tried it on my existing setup, I still got more or less the same readings.

Still, we do have to be careful. A negative voltage on any input pin is going to seek its way through the ESD protection diodes present on each ATtiny I/O pin. Keep in mind that we’re dealing with a very low-impedance shunt, and large currents. So it’s important to limit the effect of negative swings to avoid damage to the chip. The easiest way to do so is to include a 1 kΩ resistor in series, i.e. between signal and ADC input pin. That way, even a 1 V negative voltage excursion will drive less than 1 mA current through the ESR diode, a value which is still well within specs. Even better, that 1 kΩ resistor can be combined with a 0.1 µF cap to ground, as low-pass for the ADC.

Good, so if that weak-supply-feeding-a-big-cap idea works, then the rest of the circuit ought to continue working as intended, even though we’re operating at the limit of the ATtiny’s ADC voltage range.

All that’s left to do then, is get that power supply right. Oh, wait: and figure out a way to get a wireless setup going. Oh, and also figure out a good enclosure to keep this dangerous hookup safely tucked away and isolated.

Oh well. Not there yet, but progress nonetheless!

Finding a power source

In Hardware on Oct 16, 2011 at 00:01

Assuming I can figure out a way to transmit wireless information from the ATtiny, I’d like to make that recent AC current change detector a self-contained and self-powered unit. At minimal cost, i.e. with as few parts as possible.

That’s a bit of a problem. Adding a transformer-based power supply, however feeble, or a ready-made AC/DC converter would probably triple the cost of the setup so far. Not good.

I really only need a teeny bit of power. The techniques to a get a JeeNode into low-power sensing have been well-researched and documented by now. It shouldn’t be too hard to make an ATtiny equally low-power.

First of all, this “power sensing node” really doesn’t have to be on all the time. Measuring power once every few seconds would be fine, and reporting over wireless only when there is a significant change in detected current. So for the sake of argument, let’s say we measure once a second, track the average of three to weed out intermittent spikes, and report only when that average changes 20% or more since the last value. For continuity, let’s also report once every 3 minutes, just to let the system know the node is alive. So that’s one packet with a 2-byte payload every 3 minutes most of the time, and one current measurement every second (with the same ADC sampling and filtering as before).

What this comes down to is that we need perhaps 3.3V @ 10 µA all the time, with a 30 mA peak current draw every couple of minutes.

A battery would do fine. Perhaps 2x AA or a CR123 1/2 AA. But it feels silly… this thing is tied to a power line!

Why not use a transformer-less power supply, as described in this well-known application note from MicroChip?

Well, there’s a problem. These types of supplies draw a constant amount of current, regardless of the load. Whatever the circuit doesn’t use is consumed by the zener diode. So to be able to drive a 30 mA peak, we’d need a power supply which constantly draws 30 mA, i.e. 6.6 watts of power. Whoa, no thanks!

Here’s a basic resistive transformer-less supply (capacitive would also be an option):

JC s Doodles page 19 copy

There is a way to reduce the current consumption, since we only need that 30 mA surge very briefly, and not very often: use a big fat capacitor on the end, which stores enough energy to provide the surge without the voltage collapsing too far. This might be a good candidate for a trickle-charged small NiMh cell or even a supercap!

Hm, let’s see. If the supply is dimensioned to only supply a very small amount of current, say 1 mA, then it would be more than enough to charge that capacitor and supply the current for the ATtiny while in power-down mode. A 0.47 F supercap (which I happen to have lying around) ought to be plenty. This power supply would draw 0.22 W – continuously. Still not stellar, but not worse than several other power bricks around here.

Alas, such a design comes with a major drawback: with such a small current feeding such a large cap, it will take ages for the initial voltage to build up. I did a quick test, and ended up waiting half an hour for the output to be useful for powering up an ATtiny + RFM12B. That’s a lot a waiting for when you plug in such a system for the first time, eager to see whether it works. It also means that the firmware in the ATTiny has to very careful at all times with the limited energy available to it.

Still, I’m tempted to try this. What’s half an hour in the grand scheme of things anyway?

Digital filter design

In Software on Oct 15, 2011 at 00:01

In the moving averages post a few days ago, I just picked whatever seemed reasonable for filtering – i.e. running a moving average of order 31 over 531 samples, sampling at roughly 7,000 samples/second (which is what the free-running ADC does with my clock choice). And indeed, it looks like it will work quite well.

The nice thing about moving averages done this way, is that the calculations are trivial: just add the new value in and omit the oldest one. All it takes is an N-stage sample memory, i.e. 31-int array in this case.

But diving a bit deeper into FIR filters, which includes such a moving average as simplest case, it’s clear that I was sampling more than needed. I really don’t need 531 samples to measure the peak-to-peak level of the underlying 50 Hz signal, I just need to measure for the duration of a few 50 Hz cycles (about 3 in the above case).

As it turns out, once you dive in there are many ways to improve things, and lots of online guides and tools.

There’s a lot more to FIR filter design, and there’s an amazing design technique by Parks and McClellan which lets you basically specify what cutoff frequency you want, and what attenuation you you want above a second (higher) frequency. Then I found this site with an easy to use on-line tool for visualizing it and doing all the calculations:

Screen Shot 2011 10 10 at 0 52 23

That’s attenuation on the Y axis vs frequency on the X axis. The gray lines are what I specified as requirement:

Screen Shot 2011 10 10 at 1 08 23

And this is the C code it generated for me:

    /*
    FIR filter designed with http://t-filter.appspot.com

    sampling frequency: 1000 Hz
    fixed point precision: 16 bits

    * 0 Hz - 50 Hz
      gain = 1
      desired ripple = 5 dB
      actual ripple = n/a
    * 100 Hz - 500 Hz
      gain = 0
      desired attenuation = -50 dB
      actual attenuation = n/a
    */

    #define FILTER_LENGTH 31

    int filter[FILTER_LENGTH] = {
      -226,
      -328,
      -486,
      -608,
      -628,
      -474,
      -81,
      595,
      1565,
      2793,
      4194,
      5646,
      7000,
      8103,
      8825,
      9076,
      8825,
      8103,
      7000,
      5646,
      4194,
      2793,
      1565,
      595,
      -81,
      -474,
      -628,
      -608,
      -486,
      -328,
      -226
    };

There’s a drawback in that this is no longer a moving average. Now each output of the filter is defined by applying these integer coefficients to each of the past 31 samples. So there’s more computation involved – a quick test tells me that each sample would take 100..200 µs extra (on an ATmega @ 16 MHz).

But the nice part of this is that it might support a lower-power implementation. Instead of running the ADC 531 times @ 7 KHz (with an unknown filter response), I could run the ADC 100 times, clocked on the 1 ms timer interrupt (and sleeping in between), and apply this modified FIR filter to extract a similar peak-to-peak results.

Why low power? Well, running this on batteries is probably not practical, but I might consider running this setup off a very low-power transformer-less supply. After all, the goal of these experiments is to create a simple low-cost sensor, which can then be used for all the major energy consumers in the house. I’m trying to reduce power consumption, not add yet more to it from all these extra AC current sensors!

Note that maybe none of this will be needed – a simple RC filter before the ADC pin, plus an order 7..31 moving average may well be more than sufficient after all.

But it’s good to know that this option is available if needed. And it’s pretty amazing to see how easily such DSP tasks can be solved, even for someone who has never done any digital signal processing before!

CC-RT: Initial requirements

In AVR, Hardware, Software on Oct 14, 2011 at 00:01

Let’s get going with the CC-RT series and try to define the Reflow Timer in a bit more detail. In fact, let me collect a wish list of things I’d like to see in there:

The Reflow Timer should…

  • support a wide range of ovens, grills, toasters, and skillets
  • be self-contained and safe to build and operate
  • include some buttons and some sort of indicator or display
  • be created with through-hole parts as much as possible
  • (re-) use the same technologies as other JeeLabs products
  • be built on a custom-designed printed circuit board
  • use a convenient and robust mechanical construction
  • be very low-cost and simple to build

To start with that last point: the aim is to stay under € 100 as end-user price, including a simple toaster and whatever else is needed to control it. That’s a fairly limiting goal, BTW.

I’m sticking to “the same technologies” to make my life easy, both in terms of design and to simplify inventory issues later, once the Reflow Timer is in the shop. That translates to: an Arduino-like design with an ATmega328, and (for reasons to be explained next) an RFM12B wireless module.

Safety is a major concern, since controlling a heater tied to 220 V definitely has its risks. My solution to controlling an oven of up to 2000 W is the same as what I’ve been doing so far: use a commercially available and tested power switch, controlled via an RF signal. KAKU or FS20 come to mind, since there is already code to send out the proper signals through an RFM12B module. Range will not be an issue, since presumably everything will be within a meter or so from each other.

With wireless control, we avoid all contact with the mains power line. I’ll take it one step further and make the unit battery-operated as well. There are two reasons for this: if we’re going to uses a thermocouple, then leakage currents and transients can play nasty games with sensors. These issues are gone if there is no galvanic connection to anything else. The second reason is that having the AC mains cable of a power supply running near a very hot object is not a great idea. Besides, I don’t like clutter.

Having said this, I do not want to rule out a couple of alternatives, just in case someone prefers those: controlling the heater via a relay (mechanical or solid-state), and powering the unit from a DC wall wart. So these should be included as options if it’s not too much trouble.

To guard against heat & fire problems, a standard heater will be used with a built-in thermostat. The idea being that you set the built-in thermostat to its maximum value, and then switch the entire unit on and off via the remote switch. Even in the worst scenario where the switch fails to turn off, the thermostat will prevent the heater from exceeding its tested and guaranteed power & heat levels. One consequence of this is that the entire reflow process needs to unfold quickly enough, so that the thermostat doesn’t kick in during normal use. But this is an issue anyway, since reflow profiles need to be quick to avoid damaging sensitive components on the target board.

On the software side, we’ll need some sort of configuration setup, to adjust temperature profiles to leaded / unleaded solder for example, but also to calibrate the unit for a specific heater, since there are big differences.

I don’t think a few LEDs will be enough to handle all these cases, so some sort of display will be required. Since we’ve got the RFM12B on board anyway, one option would be to use a remote setup, but that violates the self-contained requirement (besides, it’d be a lot less convenient). So what remains is a small LCD unit, either character-based or graphics-based. A graphic LCD would be nice because it could display a temperature graph – but I’m not sure it’ll fit in the budget, and to be honest, I think the novelty of it will wear off quickly.

On the input side, 2 or 3 push buttons are probably enough to adjust everything. In day-to-day operation, all you really need is start/stop.

So this is the basic idea for the Reflow Timer so far:

JC s Doodles page 18

Ok, what else. Ah, yes, an enclosure – the eternal Achilles’ heel of every electronics project. I don’t want anything fancy, just something that is robust, making it easy to pick up and operate the unit. I’ve also got a somewhat unusual requirement, which applies to everything in the JeeLabs shop: it has to fit inside a padded envelope.

Enclosures are not something you get to slap on at the end of a project. Well, you could, but then you lose the opportunity of fitting its PCB nicely and getting all the mounting holes in the best position. So let’s try and get that resolved as quickly as possible, right?

Unfortunately, it’s not that easy. We can’t decide on mechanical factors before figuring out exactly what has to be in the box. Every decision is inter-dependent with everything else.

Welcome to the world of agonizing trade-offs, eh, I mean… product design!

New series: Crafted Circuits

In Hardware on Oct 13, 2011 at 00:01

I’m thrilled to announce a new series of posts for this weblog about how to craft, i.e. design and create, an electronic circuit based on all the neat Physical Computing stuff which has been flying across this weblog for several years now.

The purpose of these posts is to present and explain the complete process of producing a working product. It’ll be geared towards people who want to do this themselves, implementing designs of their own invention. Whether as a hobby for personal use, for teaching these skills to others, or to get rich and famous… whatever makes you tick!

Creating a complete product from start to finish is a major undertaking. But it’s also something I’m passionate about, so that’ll help stay on the path to completion. With as reward for me: a new product in the JeeLabs shop.

Cc

What

The product to be created will be a Reflow Timer kit – this is a circuit to control a heater in such a way that it can be used for reflow soldering. Hardware, software, PCB, assembly, enclosure – everything will be addressed.

It’s nothing new or earth-shattering, but it’s an excellent project for this series, because creating your own tools is a great way to extend your own capabilities. I’m all for empowerment. Given that reflow soldering is now within reach of any electronics hobbyist, and since I’ve already written many posts about this topic on the JeeLabs weblog, I feel confident that all the hurdles can be overcome.

And hurdles there will be, I assure you. Because creating a product is quite different from building a working one-off setup. Things like making it work under all sorts of real-world conditions, ease of assembly, repeatability, the availability and suitability of components for hobby use (since this will be a kit). Not to mention the 2,718,281 decisions which need to be taken.

Why

I’m doing this to share what I know and what I’ve learned so far, but also to learn new tools and try out new ideas. So while I’ll stick to several technologies which are already familiar (like the ATmega and RFM12B), you’ll also get to see me start with a new tool and struggle as I learn how to put it to use.

My second reason is to end up with a nice Reflow Timer. I love my prototype, but now I want a real product!

So my motivation is in fact two-fold: to expose the entire process and to end up with a neat new product.

How

While writing down a first outline for this series, it dawned on me just how huge the task might become, so I’m going to try hard and keep things manageable and moving forward. An unfinished product is not a product.

The plan is to create a series of posts (two dozen?) which document different aspects of this process, in the same order in which things get tackled. If you’re interested in reflow control, great – if not, please keep in mind that a lot of this should carry over to whatever electronics project you decide to work on yourself.

Ok, so much for raising expectations. Now let me lower them again to get our feet back on the ground:

I don’t know yet how often I’ll be able to come up with a new post for this series. It will to some degree depend on what sort of issues come up – there’s little point in writing a new post for the sake of continuity, when there’s not enough progress to stay ahead of the game and come up with tangible results.

I’m no “star” EE designer. I haven’t created lots of complex electronic products, and I don’t have sophisticated equipment to analyze tricky problems (neither hardware nor software). What I’ll be describing is what works for me, and what I think any enthusiastic hobbyist with a technical interest can accomplish with limited means.

Knowledge is not a pre-requisite, but something you can pick up along the way. As you’ll see, there’s an amazing amount of stuff you can accomplish nowadays, if you’ve got the interest to dive in and the time to push through.

As always, I welcome all tips, suggestions, and of course corrections. Let’s make this series as good as we can.

And lastly: the entire series will be listed on the Café website. I’ll abbreviate it as “CC-RT” from now on.

AC measurement status

In AVR, Software on Oct 12, 2011 at 00:01

Before messing further with this AC current measurement stuff, let me summarize what my current setup is:

JC s Doodles page 17

Oh, and a debug LED and 3x AA battery pack, which provides 3.3 .. 3.9 V with rechargeable EneLoop batteries.

I don’t expect this to be the definitive circuit, but at least it’s now documented. The code I used on the ATtiny85 is now included as tiny50hz example sketch in the Ports library, eh, I mean JeeLib. Here are the main pieces:

Screen Shot 2011 10 07 at 00 32 58

Nothing fancy, though it took a fair bit of datasheet reading to get all the ADC details set up. This sketch compiles to 3158 bytes of code – lots of room left.

This project isn’t anywhere near finished:

  • I need to add a simple RC low-pass filter for the analog signal
  • readout on an LCD is nice, but a wireless link would be much more useful
  • haven’t thought about how to power this unit (nor added any power-saving code)
  • the ever-recurring question: what (safe!) enclosure to use for such a setup
  • and most important of all: do I really want a direct connection to AC mains?

To follow up on that last note: I think the exact same setup could be used with a current transformer w/ burden resistor. I ought to try that, to compare signal levels and to see how well it handles low-power sensing. The ATtiny’s differential inputs, the 20x programmable gain, and the different AREF options clearly add a lot of flexibility.

Onwards!

Elektro:Camp

In News on Oct 11, 2011 at 00:01

Looks like I’ll be participating in this year’s Elektro:Camp (updated link) coming November 4th and 5th. Not sure what it’s all about and how it’s set up – I’ve never been to a “barcamp-style” meeting – but it seems like a good place to be for anyone in the area and interested in hacking on their energy consumption and automation systems at home:

Elektro camp 2011 10 final

If you’re into this sort of thing, consider joining. It’s bound to be fun, and it’ll be great to meet up in person :)

(Groningen brings up lots of memories, I grew up there – most of my primary school time anyway)

Soooo… see you there?

AC current detection works!

In AVR, Software on Oct 10, 2011 at 00:01

As promised, the results for the ATtiny85 as AC current detector, i.e. measuring current over a 0.1 Ω shunt.

Yesterday’s setup showed the following values in the display:

    30 71-101 68.

From right to left, that translates to:

  • it took 68 ms to capture 500 samples, i.e. about 7 KHz
  • the measured values were in the range 71 .. 101
  • the spread was therefore 30

With a 75 W lamp connected, drawing about 100 mA, I get this:

DSC 2677

With the 25 W lamp, the readout becomes:

DSC 2673

And finally, with a 1 kΩ resistor drawing 20 mA, this is the result:

DSC 2679

As soon as the load is removed, readings drop back to the first values listed above.

Now it seems to me that these readings will be fine for detection. Even a low 20 mA (i.e. 4.4 W @ 220V) load produces a reading with is 30 times higher than zero-load (with about 10% variation over time).

I’m measuring with 2.56V as reference voltage to remain independent of VCC (which is 3.8V on batteries). So each step is 2.5 mV with the built-in 10-bit ADC. With the 20x amplification, that becomes 0.125 mV per ADC step. Now let’s see… a 20 mA DC current across a 0.1 Ω shunt would generate a 2 mV differential. I’m using an order 31 moving average, but I didn’t divide the final result by 31, so that 1099 result is actually 35 on the ADC. Given that one ADC step is 0.125 mV, that’s about 4.4 mV peak-to-peak. Hey, that looks more or less right!

There is still a problem, though. Because half of the time I get this:

DSC 2675

Total breakdown, completely ridiculous values. The other thing that doesn’t look right, is that none of the readings are negative. With a differential amplifier fed with AC, one expects the values and signs to constantly alternate. Maybe I damaged the ATtiny – I’ll get another one for comparison. And maybe I didn’t get the sign-extensions right for the ADC’s “bipolar differential” mode. There’s a lot of bit-fiddling to set all the right register bits.

But still… this looks promising!

Update – Problem solved: it was a signed / unsigned issue. The values are now completely stable with under 1 % variation between measurements. I’m not even filtering out high frequencies, although I know I should.

More sensitivity

In Hardware on Oct 9, 2011 at 00:01

Yesterday’s post was nice, but it stepped over one teeny weeny little detail: the ATmega’s ADC isn’t sensitive enough to measure AC signals in the millivolts range. With a 3.3V reference, each step is ≈ 3.3 mV, while the signals at low power levels are close to a single ADC step. I could bump the sensitivity slightly by using the 1.1V bandgap as ADC reference voltage, but that still only gets me to 1.1 mV steps. Hardly enough to apply filtering to and set thresholds.

Ah, but there’s a way out… (there always is!)

The ATtiny85 is the smaller brother of the ATmega with a frighteningly low pin count of 8. The key is that it has a differential ADC option, i.e. it’s able to measure the voltage between two points (within 0..VCC) and that it has an optional 20 x analog signal amplifier built-in, when used in differential mode. As reference voltage, there is 1.1V, 2.56V, and VCC – providing a couple of ways to tweak the actual range and sensitivity.

Since I had the right ATtiny85 lying around, as well as TinkerLog’s prototyping board, I thought I’d give it a go:

DSC 2678

The problem with an 8-pin chip, of course, is that it only has 5 I/O pins (6 if you’re willing to use the RESET line and lose the ISP programming mode – which I wasn’t). That’s not much to interface with. The ATtiny85 I used has 8 Kb flash and 512 bytes of RAM, so that in itself should be sufficient for all the code I need.

There’s no boot loader. There’s no ready-to-use serial port. And it’s not an Arduino-compatible system, so you can’t just write sketches for it, right?

Not so fast. First of all, there’s the LCD Plug which needs only 2 I/O lines. That leaves me 3 pins: 2 for the differential analog input, and 1 for a debug LED. Plenty!

The LCD needs the Ports library. Which needs the Arduino IDE and runtime. Ah, but there’s more good news: there’s an arduino-tiny project which defines some boards and a set of “core” runtime source files which are intended to run on ATtiny85’s and other non-mega AVR chips. That’s quite a feat, btw, once you consider just how limited an ATtiny85 is (ASCII art by the arduino-tiny project):

                             +-\/-+
    Ain0       (D  5)  PB5  1|    |8   VCC
    Ain3       (D  3)  PB3  2|    |7   PB2  (D  2)  INT0  Ain1
    Ain2       (D  4)  PB4  3|    |6   PB1  (D  1)        pwm1
                       GND  4|    |5   PB0  (D  0)        pwm0
                             +----+

Still, they managed to support a couple of digital and analog I/O pins, with support for the millis() timer, analog in and out, and more. With this installed, I can write sketches and upload them via the AVR-ISP. Pretty amazing!

Sooo… just had to make a few small and obvious tweaks, and the Ports library works. There’s exactly one port (AIO1 = PB2, DIO1 = PB0, IRQ = PB1). Note that I’m using the new Arduino IDE 1.0 (beta).

That leaves me a whopping two pins for the differential analog input, which is what this is all about, after all.

Here’s my setup (hooked up to the safe 20 VAC brick):

DSC 2672

I was too excited to tidy up once the LCD hookup worked. It would all have fitted on a single (mini) breadboard.

Tomorrow, I’ll show you how this crazy little setup measures up…

Moving averages

In Software on Oct 8, 2011 at 00:01

In the comments, Paul H pointed me to a great resource on digital filtering – i.e. this online book: The Scientist & Engineer’s Guide to Digital Signal Processing (1999), by Steven W. Smith. I’ve been reading in it for hours on end, it’s a fantastic source of information for an analog-signal newbie like me.

From chapter 21, it looks like the simplest filtering of all will work just fine: a moving average, i.e. take the average of the N previous data point, and repeat for each point in time.

Time for some simple programming and plotting. Here is the raw data I obtained before in gray, with a moving average of order 349 superimposed as black line (and time-shifted for proper comparison):

O349s1

Note that the data points I’m using were sampled roughly 50,000 times per second, i.e. 1,000 samples for each 50 Hz sine wave. So averaging over 349 data points is bound to dampen the 50 Hz signal a bit as well.

As you can see, all the noise is gone. Perfect!

Why order 349? Because a 349-point average is like a 7-point average every 50 samples. Let me explain… I wanted to see what sort of results I would get when measuring only once every millisecond, i.e. 20 times per sine wave. That’s 50x less than the dataset I’m trying this with, so the 1 ms sampling can easily be simulated by only using every 50th datapoint. To get decent results, I found that an order 7 moving average still sort of works:

O7s50

There’s some aliasing going on here, because the dataset samples aren’t synchronized to the 50 Hz mains frequency. So this is the signal I’d get when measuring every 1 ms, and averaging over the past 7 samples.

For comparison, here’s an order 31 filter sampled at 10 KHz, i.e. one ADC measurement every 100 µs:

O31s5

(order 31 is nice, because 31 x 1023 fits in a 16-bit int without overflow – 1023 being the max ADC readout)

The amplitude is a bit more stable now, i.e. there are less aliasing effects.

Using this last setting as starting point, one idea is to take 500 samples (one every 100 µs), which captures at least two highs and two lows, and to use the difference between the maximum and minimum value as indication of the amount of current flowing. Such a process would take about 50 ms, to be repeated every 5 seconds or so.

A completely different path is to use a digital Chebyshev filter. There’s a nice online calculator for this over here (thx Matthieu W). I specified a 4th order, -3 dB ripple, 50 Hz low-pass setup with 1 KHz sampling, and got this:

Cheb

Very smooth, though I didn’t get the startup right. Very similar amplitude variations, but it needs floating point.

Let me reiterate that my goal is to detect whether an appliance is on or off, not to measure its actual power draw. If this can be implemented, then all that remains to be done is to decide on a proper threshold value for signaling.

My conclusion at this point is: a simple moving average should be fine to extract the 50 Hz “sine-ish” wave.

Update – if you’re serious about diving into DSP techniques, then I suggest first reading The Scientist & Engineer’s Guide to Digital Signal Processing (1999), by Steven W. Smith, and then Understanding Digital Signal Processing (2010) by Richard G Lyons. This combination worked extremely well for me – the first puts everything in context, while the second provides a solid foundation to back it all up.

iPad oscilloscope

In Hardware on Oct 7, 2011 at 00:01

While exploring the different ways to get to grips with the 50 Hz AC signal, I stumbled on video about oScope, an app for iPad and iPhone. It’s just €3.99, and samples with 16 bit @ 48 KHz.

It works via the audio input, which is a decent A/D converter for signals in the audio range. The neat bit is that it can also get its input via a USB audio adapter hooked up using the iPad’s camera adapter kit. And I happened to have all the required bits lying around:

DSC 2671

Woohoo – instant scope!

The horizontal and vertical are set with pinch-and-zoom, and the scale displays in the top left corner. Likewise, setting the trigger you just drag the red trigger line up or down.

Here’s a screen shot:

IMG 0045

(it doesn’t quite come out at reduced size, but on-screen it’s gorgeous)

There’s also what appears to be an FFT power spectrum:

IMG 0044

There’s also a (more expensive) app from ONYX Apps which can sample both audio channels and has a convenient auto-set mode (but no FFT):

IMG 0046

The problem I have with all this is that the noise in my signal is gone. These samples were taken from the same 0.1 Ω shunt setup as in the previous days, so I’m not quite sure why the amplitude is different and why the signal is so noise-free. Perhaps there is some signal processing going in in the iPad.

But a real scope based on touch screen controls and such a large display sure would be phenomenal!

Captured samples

In Software on Oct 6, 2011 at 00:01

With the USB scope hookup from yesterday’s post it’s also quite easy to capture data for further experiments. It helps to have a fixed data set while comparing algorithms, so I used the DSO-2090 software again to capture over a million 8-bit samples.

The dump is binary data, but decoding the format is trivial. Some header bytes and then each value as 2-byte int. Just to show that JeeMon is also up to tasks like this, here’s the “rec2text.tcl” script I created for it:

Screen Shot 2011 10 04 at 17 13 47

And this is how it was used to generate a text file for the plots below:

Screen Shot 2011 10 04 at 16 43 09

(silly me – I’m still impressed when I see a script process over a million items in the blink of an eye…)

That’s a bit too much data for quick tests, but here are the first 10,000 values from the 75W-bulb-on-20-VAC:

Screen Shot 2011 10 04 at 15 28 12

There’s quite a bit of noise in there if you look more closely:

Screen Shot 2011 10 04 at 15 33 20

The measurements are all over the map, with values over almost the entire 0..255 range of the scope’s 8-bit ADC. The actual spikes are probably even larger, occasionally.

I hope that this is a decent dataset to test out filtering and DSP techniques. It’ll be much quicker to try things out on my Mac than on a lowly ATmega 8-bit MPU, and since both can run the same C & C++ code, it should be easy to bring things back over to the ATmega once it it does the right thing.

Hmmm… now where do I find suitable DSP filtering algorithms and coefficients?

Update – Found a great resource, thx Paul & Andreas. Stay tuned…

Back to basics

In Hardware on Oct 5, 2011 at 00:01

After all this messing around with 220V, and none of it working out so well, it’s time to simplify. I had a 17 VAC transformer lying around, so I decided to first get rid of all that risk. The goal remains the same: trying to reliably determine whether a low-wattage appliance is on or off. Here’s what I’m going to use:

DSC 2664

That’s a 75W lightbulb, hooked up to that AC power supply. It’s drawing 100 mA, as you can see. Unloaded, the voltage is a bit higher (as usual with transformers) – bit still harmless to experiment with:

DSC 2667

So now I can go back to a more convenient setup, and measure directly:

DSC 2668

Note that the light bulb is not on, but it does get hot to the touch. It’s still generating 20 V x 0.1 A = 2 Watts of heat, after all. Except that in this case the heat only rises, so it’s just the top of the light bulb which heats up.

It’s pretty odd that this draws only 3x as much current at 220V as at 20V. The reason for that is that the resistance of a lightbulb filament increases considerably when glowing. When a light bulb is turned on, it creates a “cold surge” which heats it up – at which point it’ll start drawing less current – a light bulb is a NTC PTC resistor!

Good, now we’re cookin’ again. I can hook up the USB scope at last:

Screen Shot 2011 10 04 at 14 19 58

Oooh… if that’s similar to the signal I’ve been measuring so far, then no wonder my amplitude algorithm was bad. Yikes… this thing is full of noise and spikes!

There are some nice features in the DSO-2090 software. Here’s the same waveform averaged over 128 scans:

Screen Shot 2011 10 04 at 14 43 22

Which shows that the signal indeed has non-repetitive noise superimposed on it.

Here’s something interesting. The purple line is an FFT spectrum analysis (the input signal was resized/moved):

Screen Shot 2011 10 04 at 14 26 40

There’s one spike in that spectrum. No idea what it is, but I bet that’s what’s messing up the sine wave.

Good. At least these different readings are consistent.

Capturing (no go) – part 2

In Software on Oct 4, 2011 at 00:01

On to the next step in capturing samples from the direct 220V connection.

First, let me clarify why I called the first sketch “fatally flawed” – because it is, literally! The sketch required a button press to get started, a big no-no while hooked up to AC mains (isolated or not, I won’t touch it!).

The other problem I didn’t like after all, is that the sampling was taking place in burst, saving to the Memory Plug in between – which takes several milliseconds each time. That doesn’t produce a nice stream of equally-spaced ADC measurements.

So instead, I decided to redo the whole sketch and split it into two separate sketches in fact. One fills the EEPROM on the Memory plug, the other dumps it to the serial port. No more buttons or LEDs. Just a JeeNode with a Memory Plug. To make things work, a fairly peculiar series of steps has to be taken:

  • upload the “saveToMem” sketch and plug in the Memory Plug
  • disconnect, and hook up to the 0.1 Ω shunt etc (with power disconnected)
  • insert AA battery to power the whole thing, it starts collecting
  • turn on AC power
  • let it run for a few seconds
  • turn off AC power
  • disconnect, remove the battery and Memory Plug, and reattach to USB
  • upload the “saveFromMem” sketch
  • open serial monitor and capture the dump to file (with copy & paste)

The key is to remove the Memory Plug as soon as it has been filled, so that the next power-up doesn’t start filling it all over again. There’s logic in the sketches to do nothing without Memory Plug.

Note that the internal ATmega EEPROM is also used to record how far the save has progressed (in units of 128 samples, i.e. 256 bytes).

It turns out that the writes to EEPROM via I2C take quite a bit of time. I settled on a 1 KHz sampling rate to avoid running into any timing issues. That’s 20 samples per 50 Hz cycle, which should be plenty to reliably identify that frequency even if its not a pure sine wave. The samples will tell.

Ok, first test run, nothing powered up. Result is mostly 511’s and a few 510’s, which is as expected – halfway the 0..1023 range:

    $ grep -n 510 unplugged.txt |wc
         115     115    1062
    $ grep -n 511 unplugged.txt |wc
       14605   14605  135044
    $ 

Next run is with the 60 W light bulb turned on a few seconds after sampling starts.

Whoops, not so good – I’m only getting 510, 511, and 512 readings, almost nothing else!

    $ grep -n 509 powered.txt |wc
           0       0       0
    $ grep -n 510 powered.txt |wc
         110     110    1012
    $ grep -n 511 powered.txt |wc
       13750   13750  126668
    $ grep -n 512 powered.txt |wc
         220     220    2026
    $ grep -n 513 powered.txt |wc
           0       0       0
    $ wc powered.txt 
       14084   14086   56366 powered.txt
    $

My conclusion so far is: can’t detect these small AC signals without additional amplification, it’s simply too weak.

It’s not really a setback, since I wasn’t planning on creating a directly-connected JeeNode setup as official solution, but it would have been nice to get a basic detection working with just a few resistors.

Maybe there’s an error in these sketches, but I’ve verified that the input senses ground as 0 and VCC as 1023, so that part at least is working as expected. I’ve placed the two sketches as a “gist” on GitHub, for reference (sampleToMem and sampleFromMem).

Back to the drawing board!

Dabbling in HTML5 + CSS3

In Software on Oct 3, 2011 at 00:01

(Small change of plans, the continuation of yesterday’s post has been postponed to tomorrow)

I’ve been tipping my toes a bit in the waters of HTML5 + CSS3. Nothing spectacular, but here’s what came out:

Screen Shot 2011 10 02 at 22 59 24

Small “widgets” to display home readings on a web page (it’s in Dutch… but you can probably guess most of it).

There are no colors in here yet, but hey… just visit a site such as the Color Scheme Designer to fix that.

Here are the CSS styles I used:

Screen Shot 2011 10 02 at 22 20 27

And here is the funky code I used to generate the HTML for this in JeeMon:

Screen Shot 2011 10 02 at 22 20 59

It’s still a bit awkward to generate elements which need to be combined inline, i.e. <span> elements.

To see the actual generated HTML, use your browser to check the page source of the new Widgets page at http://tools.jeelabs.org/. To examine the entire file needed to generate this from JeeMon, click on this link.

For actual use, all I’ll need to change is: 1) generate the HTML with $blah Tcl variables, or 2) use JavaScript on the browser to fill in the values (driven by Server Sent Events, for example). The latter avoids page refreshes.

The separation of content, structure, and style has come a long way since the early days of HTML. It just feels right, the way this works out. Applications can be written with nearly complete independence between, eh… “looks” and “guts”. Even complete page make-overs which are well beyond the positioning capabilities of CSS can be taken care of with basic templating on the server side. It’s interesting that the elaborate and efficient templating “engines” which used to drive dynamic websites and which are still used in many frameworks are becoming irrelevant. With a bit of JavaScript smarts on the client side, the server now only needs to serve static files plus JSON data for REST-style Ajax calls. The good news for embedded home automation systems, is that very low-end servers may well turn out to be sufficient, even for sophisticated web presentations.

As I said, nothing spectacular, but I’m delighted to see how simple and cleanly-structured all this has become.

Capturing some test data

In Software on Oct 2, 2011 at 00:01

(Whoops, looks like I messed up the correct scheduling of this post!)

Coming soon: a bit of filtering to get better AC current readouts.

There are many ways to do this, but I wanted to capture some test measurements from the AC shunt first, to follow up on the 220V scope test the other day. That way I don’t have to constantly get involved with AC mains, and I’ll have a repeatable dataset to test different algorithms on. Trouble is, I want to sample faster and more data than I can get out over wireless. And a direct connection to AC mains is out of the question, as before.

Time to put some JeePlugs from my large pile to use:

DSC_2661.jpg

That’s a 128 Kbyte Memory Plug and a Blink Plug. The idea is to start sampling at high speed and store it in the EEPROM of the Memory Plug, then power off the whole thing, connect it to a BUB and press a button to dump the saved data over the serial USB link.

Here’s the sketch I have in mind:

Screen Shot 2011-10-02 at 01.31.52.png

Note that saving to I2C EEPROM takes time as well, so there will be gaps in the measurement cycle with this setup. Which is why I’m sampling in bursts of 512. If that doesn’t give me good enough readings, I’ll switch to an interrupt driven mechanism to do the sampling.

Hm… there’s a fatal flaw in there. I’ll fix that and report the results tomorrow.

Time for a new mousetrap

In Hardware on Oct 1, 2011 at 00:01

It’s been a while. In December 2008, I posted about my setup for detecting the rotation of my electricity and gas meters. This was before the JeeNode even existed. It was built with an RBBB plus RFM12B with voltage dividers.

That setup has been running ever since, probably sending over a million packets around the airwaves here at JeeLabs. But it’s getting a bit old – and it’s still that dangling mess of wires. Besides, I’d really like to get a more up-to-date setup going: the current unit is still using the old v1 RF12 protocol, so it needs a specially-built receiver to pick up the packets. Then again, I don’t want to replace it before there is a sufficiently stable alternative.

First thing I did quite a while back was to get an extra electricity meter, if only to avoid the constant runs up and down the stairs. That way I can hook up a scope, and try things at my leisure:

DSC 2659

I also wanted to experiment with different sensors, so I tried the GP2S700HCP, which is a tiny SMD device:

DSC 2660

Unfortunately, the range is a bit low -it’s specified as 0.5 .. 5.5 mm. That translates to a fairly weak signal:

Screen shot 2011 06 29 at 02 16 43

About 150 mV swing on a 1.8 V signal, it seems. Hm… I might go for the venerable CNY70 after all. That’s the sensor most people seem to be using. I was hoping to find something smaller, because it would be easier to create a mounting solution for it.

Even better would be to try and detect the irregularities around the entire Ferraris wheel, and perhaps also to detect variations on the digits of the gas meter.

More tinkering needed…

Relational data

In Software on Sep 30, 2011 at 00:01

This post strays solidly into the realms of software and database architecture…

I’m having a lot of fun with JeeMon, but it’s also starting to look like a bone which is slightly too large to chew on…

As in any application, there is the issue of how to manage, represent, and store data structures. This is an area I’ve spent quite a few years on in a previous life. The nice bit is that for JeeMon I get to pick anything I like – there are no external requirements. Time will tell whether that freedom won’t become a curse.

So now I’m exploring the world of pure relational data structures again:

Screen Shot 2011 09 29 at 14 28 25

What you’re looking at is the definition of 4 drivers (I’m leaving off a bunch more to keep this example limited). This was rendered as nested HTML tables, btw – very convenient.

Each driver has a description of the type of values it can produce, and each set of values is grouped (as in the case of ookRelay2, which can generate data for three different types of packets it is relaying). Drivers can support more than one interface (the roomNode driver supports both remote packets and direct serial connection, for example). And drivers can expose a number of functions (in this case they all only expose a “decode” function).

In the “flat” SQL world, you’d need 5 tables to represent this sort of information. But since I’m supporting relations-as-values, it can all be represented as a single relation in JeeMon (I call ’em “views”, btw).

Note that this isn’t a hierarchical- or network-database. It’s still purely relational. There’s an “ungroup” operator to flatten this structure as many levels as needed, along with the usual “select”, “project”, “join”, etc. operators.

There’s also something else going on. Some of the information shown above is virtual, in the sense that the information is never actually stored into a table but gets extracted on-demand from the running application. The “values” relation, for example, is produced by scanning some simple lists stored (as dicts) in a Tcl variable:

Screen Shot 2011 09 29 at 15 12 46

And the “functions” relation is created on-the-fly by introspecting the code to find out which public functions have been exposed in each driver.

It’s a bit unusual to think of application data in relational terms. This lets you “join” a list with another one, and do strange things such as perform selection and projection on the list of all public functions defined in the application. But it’s also extremely powerful: one single conceptual mechanism to deal with information, whether present in application variables, i.e. run-time state, from a traditional database, or as the result of a remote request of some kind. Here’s another example: perform a join between a local (scalar) variable and a dict / map / hash (or whatever you want to call associative arrays), and you end up doing key lookup.

This approach turns (at least part of) an application on its head: you don’t need to register every fact that’s relevant into a database, you launch the app and it sets up “views” which will extract what they need when they need it, from the running app itself. Don’t call us, we’ll call you!

It might seem like a complicated way to do things (indeed, it is!), but there’s a reason for this madness. I’m looking for a design which can adapt to changes – even in the code – while running. If a driver is updated to add support for Ethernet, say, then it should reflect in these data structures without further explicit effort from the programmer. I’m not there yet by a long stretch, but this sort of experimentation is needed to get there. IMO, the magic lies in not copying facts but in seeking them out when needed, combined with smart caching.

My research project which pioneered this approach is called “Vlerq”, and I’m considering resuscitating it for use in JeeMon. Trouble is, it’s quite a bit too ambitious to implement fully (I’ve hit that wall before) – so my current experimentation is aimed at finding a workable path for the near future. Perfection is the enemy of done – and right now I’m seeing my “done” horizon racing further and further away. It’s like trying to exceed the speed of light – oh, wait, didn’t someone do that the other day?

Noise spectrum

In Software on Sep 29, 2011 at 00:01

Not only is there a glcdScope sketch which is useful for displaying voltage across the 0.1 Ω shunt in my 220V experiments, there’s also a little Spectrum Analyzer sketch to try out. Yummie!

Spectrum analysis tells you what frequencies are present in a given sample of a periodic signal. Lots of math there – just Google around for “Fast Fourier Transform” (FFT) and you’ll get it all on your plate if you’re curious.

But this stuff is a bit harder than a plain signal. Here’s what I’m seeing, with just a short wire connected, picking up some 50 Hz presumably (as with the scope test) – again with the “digital phosphor” persistence:

DSC_2655.jpg

In principle, this graph is ok: lots of signal at lower frequencies and progressively less at higher frequencies. After all, with a perfect 50 Hz sine wave and no noise, we’d expect a single peak at the start of the scale.

The repeated peaks every few pixels also look promising. With a bit of luck they are in fact the harmonics, i.e. the 100 Hz, 150 Hz, … multiples – which is what you get when a signal is repetitive but not exactly a sine wave. Harmonics are what makes music special – the way to distinguish a note played on the violin and on the piano.

But I was hoping for something else: a bit more peaks at the right hand side of the graph. This would indicate that there are high frequencies in the signal, the computer’s switching power supply close to this setup, for example.

And worse: I’m seeing a completely flat line when hooking this up to the 220V current shunt. Looks like this signal is too weak to play FFT games with (should the data be auto-scaled?).

Anyway, here’s the glcdSpectrum50 sketch:

Screen Shot 2011-09-27 at 19.04.17.png

It relies on the fix_fft.cpp file by Tom Roberts which does the FFT heavy-lifting (original is here).

Also, note that I’m using a slightly different algorithm this time to determine the average signal value: the average of the last 256 samples is used to compute the center value subtracted from the next 256 samples. The outcome should be similar, as long as the signal is indeed symmetric around this value.

All in all a nice try, but it didn’t really provide much new insight (yet?).

It just blew apart

In Hardware on Sep 28, 2011 at 00:01

Got quite a scare the other day:

DSC_2649.jpg

One moment I was cheerily plugging in and unplugging my 100 W light bulb for testing current measurements, and the next it came apart with a huge bang. No fuse tripped anywhere (as it would have in UK households).

It’s a good reminder of the amount of energy an AC power outlet can discharge at any time. In fact, the standard rating for individually-fused 220 V power groups is 16 Amps around here. That’s roughly 3600 W.

To get an idea of what that means – one Horsepower is the sustained power a horse can generate, which is about 740 Watt. So there are almost 5 horses in each power outlet, waiting to charge at you!

If you push that much energy into a liter of water, it’ll boil in 2 minutes flat. Doesn’t sound like much, eh? How about 1000 Amps at 3.3V? You’ll need copper wire with a diameter of 18 mm to handle that much current.

Compare that to a JeeNode in sleep mode drawing 10 µA, i.e. 33 microwatt. That’s 8 orders of magnitude less.

Anyway, I’ve gained some extra respect for 220V mains circuits.

Now, if only I could find a replacement … 100 W incandescent light bulbs are no longer sold in Europe.

GLCD scope on 220V

In Hardware, Software on Sep 27, 2011 at 00:01

I’m not willing to hook my Mac up to 220V through USB, whether through the DSO-2090 USB scope I have, or any other way – even if it’s tied to a galvanically isolated setup such as the recent current measuring setups. One mistake and it’d go up in smoke – I’d rather focus all my attention on keeping myself safe while fooling around with this AC mains stuff.

But there’s this little 100 KHz digital sampling scope sketch, based on the Graphics Board. Looks like it could be a great setup for this context, since it can run detached off a single AA battery.

It took some hacking on the original sketch to get a system which more or less syncs to the power-line frequency (well, just the internal clock, but that turns out to be good enough). Here’s what it shows with the input floating:

DSC_2639.jpg

Definitely usable. The three different super-imposed waves are most likely an artifact of the scanning, which takes place every 60 ms. One huge improvement for this type of repetitive readout is “digital phosphor”, like the professional DSO’s do: leaving multiple traces on the screen to intensify the readout. Single traces on a GLCD like this one end up with very little contrast, due to the lag of liquid crystals. What I do now, is leave pixels on for 10 scans before clearing the display. It’s not quite digital phosphor (where each scan fades independently), but it’s pretty effective as you can see. And this setup is a tad cheaper than that Agilent 3000X MSO I dream of…

Here’s a readout with this setup tied to the 0.1 Ω shunt in the AC mains line, with the power off:

DSC_2643.jpg

That’s three pixels of noise, roughly, i.e. some 10 mV.

With a 60 W light bulb turned on, we get this:

DSC_2641.jpg

Not bad at all! It looks like with a bit of smoothing and averaging, one could turn this into an ON / OFF signal.

Alas, the sensivity does leave to be desired. With a 25 W light bulb:

DSC_2644.jpg

That’s barely above the noise threshold. It might be difficult to obtain a reliable detection from this, let alone at lower power levels. The 1W power brick showed almost no signal, for example.

Note that with North-America’s 110V, the readout would be twice as sensitive, since it’s measuring current.

Still, these results look promising. Here is the <cough> DSO with digital phosphor </cough> sketch I used:

Screen Shot 2011-09-26 at 15.52.38.png

This code can be found as “glcdScope50” example in GLCDlib on GitHub.

Fun stuff. Just look how simple it is to gain new insight: a few chips, a few lines of code – that’s all it takes!

Package management done right

In Software on Sep 26, 2011 at 00:01

Yeah, ok, this is probably a bit off topic…

I’m talking about installing Unix’y software on the Mac (which has a big fat GUI on top of a Posix-compliant OS).

There have been several projects in the past which have addressed the need to use a Mac as a Unix command-line system with all the packages coming out of the Linux, FreeBSD, etc. universes. The places where “tar”, “patch”, “make”, “autoconf”, “libtool”, and so on rule.

First there was Fink – implemented in Perl:

The Fink project wants to bring the full world of Unix Open Source software to Darwin and Mac OS X. We modify Unix software so that it compiles and runs on Mac OS X (“port” it) and make it available for download as a coherent distribution. Fink uses Debian tools like dpkg and apt-get to provide powerful binary package management. You can choose whether you want to download precompiled binary packages or build everything from source.

Then came MacPorts – implemented in Tcl:

The MacPorts Project is an open-source community initiative to design an easy-to-use system for compiling, installing, and upgrading either command-line, X11 or Aqua based open-source software on the Mac OS X operating system. To that end we provide the command-line driven MacPorts software package under a BSD License, and through it easy access to thousands of ports that greatly simplify the task of compiling and installing open-source software on your Mac.

And now there’s Homebrew – implemented in Ruby:

Homebrew is the easiest and most flexible way to install the UNIX tools Apple didn’t include with OS X. Packages are installed into their own isolated prefixes and then symlinked into /usr/local.

It’s interesting to note that all systems were written in a scripting language. Which makes perfect sense, given that they offer a huge jump in programmer productivity and no downsides to speak of in this context.

As for my pick: Homebrew gets it right.

Homebrew (i.e. the “brew” command) is installed with a one-liner:

    /usr/bin/ruby -e "$(curl -fsSL https://raw.github.com/gist/323731)"

This is a big deal, because the last thing you want is to use a package manager to overcome installation hassles, only to end up with… an extra step which introduces its own installation hassles!

The actual design of that one-liner is quite clever: it points to a script in a secure area, with full history of all changes made to that script, so you can make sure it won’t do weird (or bad) things with your system.

Homebrew doesn’t introduce new conventions (like /sw/ or /opt/, which need to be added to your exe search path). It’ll simply install the packages you ask for in /usr/local/bin etc (which means you don’t need to sudo all the time). And it does it intelligently, because it actually installs in /usr/local/Cellar and then puts symlinks in /usr/local/*. Which means there’s a way out of an installation, and there’s even a (drastic) way to get rid of all Homebrew-installed packages again: delete Cellar, and remove the dangling symlinks from /usr/local/*. Not that you’d ever need to – Homebrew supports uninstalls.

It’s succinct (and colorized):

Screen Shot 2011 09 24 at 0 22 56

No endless lists of compiler commands on my screen, telling me absolutely nothing, other than “CPU == busy!”.

It does the right thing, and works out all the dependencies:

    fairie:~ jcw$ brew search rrd
    rrdtool
    fairie:~ jcw$ brew install rrdtool
    ==> Installing rrdtool dependency: gettext
    ==> Downloading http://ftpmirror.gnu.org/gettext/gettext-0.18.1.1.tar.gz
    ######################################################################## 100.0%
    ==> Downloading patches
    ...
    ==> Summary
    /usr/local/Cellar/gettext/0.18.1.1: 368 files, 13M, built in 5.4 minutes
    ==> Installing rrdtool dependency: libiconv
    ==> Downloading http://ftpmirror.gnu.org/libiconv/libiconv-1.14.tar.gz
    ...
    ==> Summary
    /usr/local/Cellar/libiconv/1.14: 24 files, 1.4M, built in 70 seconds
    ==> Installing rrdtool dependency: glib
    ... etc, etc, etc ...
    ==> Installing rrdtool
    ==> Downloading http://oss.oetiker.ch/rrdtool/pub/rrdtool-1.4.5.tar.gz
    ######################################################################## 100.0%
    ==> Patching
    patching file configure
    Hunk #1 succeeded at 31757 (offset 94 lines).
    Warning: Using system Ruby. RRD module will be installed to /Library/Ruby/...
    Warning: Using system Perl. RRD module will be installed to /Library/Perl/...
    ==> ./configure --prefix=/usr/local/Cellar/rrdtool/1.4.5 --mandir=/usr/local/Cel
    ==> make install
    /usr/local/Cellar/rrdtool/1.4.5: 148 files, 3.2M, built in 68 seconds
    fairie:~ jcw$ 

It does its work with “formulas”, i.e. Ruby scripts which describe how to fetch, build, and install a certain package. The formulas (formulae?) are managed on GitHub, which means that there is a massive level of collaboration going on: new packages, issue tracking, fixes, and discussion. Here’s what I got when self-updating it again after having done so one or two days ago:

    $ brew update
    remote: Counting objects: 294, done.
    remote: Compressing objects: 100% (103/103), done.
    remote: Total 250 (delta 174), reused 212 (delta 143)
    Receiving objects: 100% (250/250), 39.46 KiB, done.
    Resolving deltas: 100% (174/174), completed with 32 local objects.
    From http://github.com/mxcl/homebrew
       36f4400..99bc0b7  master     -> origin/master
    Updated Homebrew from 36f4400e to 99bc0b79.
    ==> New formulae
    apktool             hexedit             p11-kit             solid
    denyhosts           jbigkit             qi                  tinyfugue
    gearman-php         kbtin               shen
    graylog2-server     opencc              sisc-scheme
    ==> Updated formulae
    android-ndk         ffmpeg              libquicktime        python
    aqbanking           frink               libraw              python3
    audiofile           fuse4x              libvirt             sleepwatcher
    cassandra           fuse4x-kext         nasm                tomcat
    class-dump          gflags              nginx               transcode
    csshx               google-sparsehash   nss                 tsung
    dash                gpsbabel            pdfjam              xml-security-c
    dvtm                gwenhywfar          pixman*
    elasticsearch       libiconv*           pos
    $

But best of all IMO, the formulas use an almost declarative style. Here’s the one for re2c I just installed:

Screen Shot 2011 09 24 at 0 33 33

It’s not hard to guess what this script does. No wonder that so many people submit and tweak such formulas.

Note that there’s neither a description, nor explicit version handling in there (other than what can be gleaned from the download URL). Brew is an installer, not a catalog. Wanna know more? Visit the home pages. Brilliant.

It’s great to see the Ruby community adopt a concise, declarative, and Domain Specific Language style. Nothing new or revolutionary – has been done many times before – but nevertheless underappreciated, IMNSHO.

It’s all about dialogue

In Musings on Sep 25, 2011 at 00:01

Don’t know about you, but I’m having a great time with this weblog!

I’d like to go on a small excursion of what it’s all about, why it matters, and unpredictable stuff, such as the future.

This weblog started roughly three years ago. I love tinkering with technology, I love learning more about it, I love making new things (even if it’s only new for myself). Especially when it’s about mixing software, hardware, and mechanical stuff. I describe myself as an architect, a hacker, and a maker, and I’m proud of it. And I decided to write about it. One day I didn’t, the next day I did – it’s really that easy. You could start doing it too, any day.

A weblog is a publishing medium. Push. From me to you – whoever you are and wherever you are. As long as I enjoy writing it, and as long as you enjoy reading it, we both win.

One crucial aspect of this process is that we need to share the same interests. If I tried to write about culture, nature, politics, or music, chances are that we’d no longer be in sync (and I might have very little interesting to report!). We all differ, we all embody our own unique mix of interests, opinions, and experiences, and there’s no reason whatsoever to assume that a shared interest in technology means we share anything else. The great thing is: it doesn’t matter. We are linked by our humanity, and our diversity is our greatest asset. Vive la différence!

So how does this weblog thing work? Well, from what I’m writing about and have written in the past, you can tell where my passion lies. And you have the simple choice of reading and following the posts on this weblog – or not. From your comments and emails, I think I get an idea who (some of) you are. We’re in sync.

This process excites me. Because it transcends culture, age, background, and all those other aspects in which we differ (and don’t even know about each other). We can share our interests, learn from each other, exchange tips and ideas, and all it takes is an internet connection and the ability to read and write in English, even if that’s not everyone’s native language.

But weblogs publishing is an asymmetric process – there’s no real dialogue going on at all. I don’t really know who reads this. There might be thousands of readers coming back every day, or there might be just those who post comments – I wouldn’t know. I used to care about that, but I no longer do. I don’t collect stats and I don’t “track” visitors. It’s just another distraction and life’s too short. But more important to me, is motivation: my goal is not to have an “important” blog, a big readership, or lots of fans. Nor a big shop or many customers, for that matter. My goal is to have fun with technology, learn as much as I can, invent new stuff, and share to inspire others to do the same. It took me a long summer break to figure this out.

Of course I have my preferences, and of course there are areas where I know more and less about. The field is way too large to dive into every topic, let alone build up expertise in each – although I do consider myself reasonably open minded and knowledgeable about a decent range of technical domains. And those gaps? Well, that’s the challenge, of course: filling one little gap each day – day in, day out!

So what does this mean for the future?

I see no reason why any of this should stop. It’s proven to be sustainable for me, and there’s plenty of material to go into and talk about to last a lifetime. As you may have noticed, I’m moving away from a pure hardware focus in this weblog. The central theme will definitely remain “Physical Computing in and around the house”, but there’s more to it than the ATmega + RFM12B that form a JeeNode, and I’d like to explore a wider range of topics, including software and data processing, and probably also mechanical aspects (construction, CNC, 3DP, bots):

Topics

I do have a little request I’d like to make: whenever you read a post on this weblog and have a suggestion or insight which is relevant, please consider adding a comment. I tend to go with the flow (of ideas), and I tend to pick the easy low-hanging fruit first. Suggestions made in recent days on all this scary 220V power measurement stuff have helped me greatly to better understand what’s going on and to come up with more experiments to set up to try and figure it all out. I encourage you to point me in the right direction and to point out mistakes.

Who knows, it might lead to a post which is more useful to you. We’ll all benefit!

Hacking around in software

In Software on Sep 24, 2011 at 00:01

Here’s a web page I’ve been designing recently – one of many planned for the JeeMon system I’m working on:

Screen Shot 2011 09 20 at 13 00 26

A couple of notes:

  • there are three “master” tables on this page: Devices, Interfaces, and Drivers
  • devices are a 1:N mapping between drivers and interfaces
  • … except that some devices are remote, and not tied to a local interface
  • clicking on any row of these three tables displays details in the rightmost column
  • drivers are listed but not managed on this page, that’s a software admin task

I’m describing this here for a number of reasons (other than showing off what I’ve been spending my days on).

First of all, you can see that this more or less covers what needs to be set up to in a home monitoring and/or home automation system. I like to see everything at a glance, i.e. on a single page and with as little navigation as possible. With this setup, I hope to keep it all essentially on one page. Whereby the right-side column may vary widely, depending on the device / interface / driver.

But it doesn’t really need to be about home automation at all. A very similar setup could be used to hook up to devices which I’m experimenting with in the lab, or devices which act like measuring instruments, or control some aspect of an experiment. Anything related to Physical Computing, really.

The other thing that interests me is the “degree of variety” needed to cover all the cases. Many devices will simply collect or send out one or more values, but not all devices are like that.

The RF12demo sketch is essentially a gateway from and to an entire group of RFM12B-based nodes. Each node can have its own driver. The ookRelay2 sketch is similar: it collects data from quite different devices, each of them sending out their specific packets with their specific types of measurements. It differs from RF12demo, in that it contains decoders for all the devices it knows about. There are no separate KS300 drivers, etc (although perhaps there should be, since some code is currently duplicated in the CUL driver).

The autoSketch driver is yet another beast. It listens on a serial interface for a line of the form “[…]” and when it sees one, tries to load a driver with the name in brackets and hand over control to it. This is the reason why just about all my sketches start off with the following boilerplate code:

    void setup() {
        Serial.begin(57600);
        Serial.println("\n[mySketch]");
        ...
    }

When associated with the autoSketch driver, this will automatically load a “mySketch” driver, if present. Which in turn means that all you have to do is plug in the JeeNode (JeeLink, Arduino, etc) and JeeMon will automatically detect it and start communicating with it. IOW, plug-and-play – with a simple implementation.

This is why there’s a “Use autoSketch for new interfaces” checkbox. I could have called it “Enable plug & play”.

But although this web page is functional in my test setup, it’s far from finished. The hardest part I want to get right, is to make the page completely dynamic. Right now, a click on a row will update the details via Ajax, but nothing will happen when there is no user interaction. What I want is that the page automatically adjusts when a JeeLink is plugged in (on the web server side). What I really want, is to generalize that mechanism to everything shown on any web page. The challenge is to do this without tedious periodic polling or complete table refreshes, just “pushing” changes in an event-driven manner. Events on the server side, that is.

The visual layout, styling, and behavior of a page like this has become very simple with today’s tools:

  • jQuery is the core JavaScript library
  • jQuery UI is used as basic style engine (the tabbed group on the right, for example)
  • jQuery TableSorter adds support for (surprise!) table sorting via their headers
  • Knockout is used to manage a lot of the user-facing behavior in the browser
  • 960 grid regulates the page structure flow in CSS
  • there is a small amount of custom CSS and custom Javascript (about 20 lines each)
  • the entire page is implemented as a single Tcl source file (175 lines so far)

There are a few trivial utility functions in there, which are bound to migrate to a more general module once I better understand the trade-offs and benefits of re-use. And the rest is gobbledygook which looks like this:

Screen Shot 2011 09 23 at 22 19 41

This is the notation I came up with and described in my Playing with indentation post a short while back. This particular code describes the HTML text returned for drivers in the “details” column, via Ajax.

This notation gets expanded to HTML, but the real value of it is that describing the HTML on a page is fun, because it’s now trivial to insert grouping levels (i.e. mostly <div>’s) and rearrange stuff until it’s just right.

Shielding!

In Hardware on Sep 23, 2011 at 00:01

Is it time for a tin foil hat?

Well, a recent comment mentioned common-mode voltage swings, and I think there’s a point there. With some resistance and impedance between the point I’m measuring and the power source downstairs, it’s easy to see how the whole thing swings widely in its “common mode”. Even the slightest leakage path to a non-swinging voltage potential could introduce a very substantial voltage difference.

Here’s a new test (it’s not the time to make mistakes!):

DSC 2635

What this does is place a ground plane underneath the whole circuit, sitting on (my all-time favorite) foam board. The foil is only attached to the JeeNode’s ground, nothing else.

And lo and behold – it really makes a difference!

The signal is 4 mV with nothing connected, and 7 mV with the power cable plugged in (but the switch still off). Turning the switch on has various effects, depending on whether the 100 W light bulb is plugged in.

With the light bulb included, the voltages I see are 80 .. 120 mV. Without, the voltages are 150 .. 400 mV. Still large swings, but nowhere near the consistent 650 .. 700 mV I was seeing before.

But what was more surprising (well… not in hindsight), is that these measurements depend on which way the power plug is plugged in. These old plugs are not polarized, so it’s easy to turn them around. It lets me put the measurement circuit in series with either the “live” or the “neutral” wire this way.

What I really like is that I’m back to 4 .. 7 mV readings when nothing is hooked up. That’s just one or two least significant bits, since the ATmega’s 10-bit ADC measures with ≈ 3 mV step sizes. It’s impossible to expect any better. This is also essential to get a decent shot at detecting low power levels.

Hm… this outcome is very awkward. A fully conducting enclosure might be best, but it’s also the most tricky one to deal with. This is after all still a dangerous 220 V hookup. A metal box inside a plastic box, perhaps? Yuck.

A shielded cable might help. Electrical signal amplification would introduce more (active i.e. power-consuming) complexity. Still, an op-amp with a super diode would allow using a capacitor to do the averaging.

One piece of the puzzle

In Software on Sep 22, 2011 at 00:01

The measurement anomalies of the recent experiments are intriguing. I don’t want to just tweak things (well, up to a point) – I also want to explain what’s happening! Several insights came through the comments (keep ’em coming!).

Let me summarize the measurement algorithm: I measure the < 1 VAC peak-to-peak voltage ≈ 5000 times per second, and keep track of a slow-moving average (by smoothing with a factor of 1/500-th). Then I calculate the arithmetic mean of the absolute difference between each measured value and that average. Results are reported exactly once every second.

Some notes:

  • noise should cancel out for both the average and the mean values, when the signal is large
  • noise will not cancel out if it is larger than the fluctuation, due to the absolute function

There’s also another problem:

JC s Doodles page 15

I’m not synchronizing the averaging period to the power-line frequency, nor taking zero crossings into account.

This matters, and would explain up to some 2% variation in the measurement. Here’s why:

  • each 1-second sampling period measures about 50 cycles
  • let’s assume it’s 49-cycles-and-a bit
  • the extra “bit” will be residuals at both ends
  • the 49 cycles will be fine, averaged from zero-crossing to zero-crossing
  • but the ends may “average” to anything between 0 and 100% of the true average for entire cycles
  • so 1 of the 50 cycles may be completely off, i.e. up to 2% error (always too low)

So it looks like there are two measurement issues to deal with: noise and the lack of zero-crossing syncing.

It doesn’t quite explain the extreme values I’ve been seeing so far, but for now I’ll assume that an excessive amount of noise is being picked up in my crude breadboarded circuit and all the little dangling wires.

Shielding, digital noise filtering, and syncing to zero-crossings… quite a few things to try out!

A simpler direct connection

In Hardware on Sep 21, 2011 at 00:01

Now that direct connection to AC mains is no longer out of the question (at least to establish a baseline), I decided to create a much simpler hookup:

DSC 2633

That’s a 0.1 Ω resistor in series with the load and two diodes, all in parallel. The diodes are not that useful for load protection (anything over 1000 W will be a problem), but they may help with transients and spikes:

DSC 2633  Version 2

Note that the sense wires are attached to the shunt resistor. If anything were to get yanked loose by accident, then it would be those wires, not the shunt itself. As usual, this is all hooked up via an isolation transformer.

A quick check tells me that this setup does not perform any better than the previous direct connection with the sketch I’ve been using all along.

Even without anything plugged in, I can affect the readings by moving my hands close to the circuit:

    reading:RF12-868.5.17:oneLong:value = 28250
    reading:RF12-868.5.17:oneLong:value = 28247
    reading:RF12-868.5.17:oneLong:value = 28184
    reading:RF12-868.5.17:oneLong:value = 28637
    reading:RF12-868.5.17:oneLong:value = 33743
    reading:RF12-868.5.17:oneLong:value = 77924
    reading:RF12-868.5.17:oneLong:value = 92240
    reading:RF12-868.5.17:oneLong:value = 50233
    reading:RF12-868.5.17:oneLong:value = 30663
    reading:RF12-868.5.17:oneLong:value = 28476
    reading:RF12-868.5.17:oneLong:value = 28176
    reading:RF12-868.5.17:oneLong:value = 28145
    reading:RF12-868.5.17:oneLong:value = 29082
    reading:RF12-868.5.17:oneLong:value = 34851
    reading:RF12-868.5.17:oneLong:value = 43977
    reading:RF12-868.5.17:oneLong:value = 54547
    reading:RF12-868.5.17:oneLong:value = 62388
    reading:RF12-868.5.17:oneLong:value = 61987
    reading:RF12-868.5.17:oneLong:value = 61366
    reading:RF12-868.5.17:oneLong:value = 62199

So the next step will be to add filtering. Either analog or digital, we’ll see!

Direct connection summary

In Hardware on Sep 20, 2011 at 00:01

The different circuits described in the past few days all had problems (the first ACS Hall-effect hookup worked reasonably well, but was not sensitive enough for my purposes).

Here’s the circuit as it is now:

DSC 2631

Bottom side:

DSC 2632

(a slightly different layout would have avoided the overhang, had I known the complete setup in advance)

There are 3 independent circuits on there connected in series (so the same current passes through each of ’em):

JC s Doodles page 14

As you can see in the first image, there’s a little screw-less terminal block on the board. It lets me short out any combination of these setups – this was useful until everything had been built up, and also lets me rule out interference while focusing on a specific setup. Note also that this is an epoxy-based board, not the pressed-cardboard type which breaks easily and isolates less.

Let me just repeat that messing with AC mains voltages like this can be extremely dangerous. This circuit has all the wires completely exposed, and that’s intentional: I prefer to be reminded of the risks, instead of getting a false sense of security because it all looks ok! One way to deal with these risks is to completely stand back from the entire hookup and only transfer measurement data over wireless whenever applying power to this stuff.

Tomorrow I’ll describe a simpler setup to get to the bottom of the measurement anomalies I’ve been seeing so far. With many thanks for all your comments – there’s clearly a lot more to it than with simple logic level signals!

Direct 220V hookup

In Hardware on Sep 19, 2011 at 00:01

This next hookup is the most tricky one – measuring current draw via a direct connection to AC mains:

Direct connect

No more transformers, no more galvanic isolation. The 0.1 Ω resistor in series with the appliance generates 0.1 VAC of output for each 1A passed through it. The resistor handles up to 2W, which means it’ll be ok up to about 1000 W: the current will be 1000 / 220 ≈ 4.5 A, and the power generated as heat will be 0.45 V x 4.5 A ≈ 2 W.

Not that I intend to go that far. My main load test is still a 100 W light bulb.

The rest of the circuit is the same as before: one side connected to 1/2 VCC, the other end connected to an AIO pin. I’m using the same test sketch as before, sending out one reading per second.

So how does it perform? Not good, so far. Here’s the sketch running with no AC connected:

    reading:RF12-868.5.17:oneLong:value = 18070
    reading:RF12-868.5.17:oneLong:value = 14045
    reading:RF12-868.5.17:oneLong:value = 14117
    reading:RF12-868.5.17:oneLong:value = 13375
    reading:RF12-868.5.17:oneLong:value = 13359
    reading:RF12-868.5.17:oneLong:value = 38606
    reading:RF12-868.5.17:oneLong:value = 17196

That’s 13 .. 39 mV, and it’s all over the map. These readings are with no load but AC connected:

    reading:RF12-868.5.17:oneLong:value = 625570
    reading:RF12-868.5.17:oneLong:value = 631161
    reading:RF12-868.5.17:oneLong:value = 632028
    reading:RF12-868.5.17:oneLong:value = 632705
    reading:RF12-868.5.17:oneLong:value = 631796
    reading:RF12-868.5.17:oneLong:value = 632296
    reading:RF12-868.5.17:oneLong:value = 631882

Hm – 630 mV. Doesn’t make sense. Turning it off (still connected) gives this:

    reading:RF12-868.5.17:oneLong:value = 31128
    reading:RF12-868.5.17:oneLong:value = 30760
    reading:RF12-868.5.17:oneLong:value = 30961
    reading:RF12-868.5.17:oneLong:value = 30512
    reading:RF12-868.5.17:oneLong:value = 30292
    reading:RF12-868.5.17:oneLong:value = 34016
    reading:RF12-868.5.17:oneLong:value = 32847

And with the 100 W light bulb:

    reading:RF12-868.5.17:oneLong:value = 474201
    reading:RF12-868.5.17:oneLong:value = 475105
    reading:RF12-868.5.17:oneLong:value = 475399
    reading:RF12-868.5.17:oneLong:value = 474646
    reading:RF12-868.5.17:oneLong:value = 475105
    reading:RF12-868.5.17:oneLong:value = 474585
    reading:RF12-868.5.17:oneLong:value = 468425
    reading:RF12-868.5.17:oneLong:value = 463834

Now it’s 470 mV. I’m lost…

I understand how a very high-impedance circuit can pick up a signal even when not connected. But the above levels make no sense at all. On an open line, one could explain how noise pickup would completely throw off the ADC, especially when no load is plugged in.

But in this case, the input impedance towards the AIO pin is 0.1 Ω + 22 kΩ. As a test, I even removed the voltage divider, and connected the 0.1 Ω resistor directly between GND and AIO, well… with a 100 Ω resistor in series to avoid damaging the I/O pin. The only difference was that the off-state now reads as 4 mV, as expected. But load or no load, with AC connected, the reading still jumps to around 0.7 V.

Doesn’t look like the ATmega is broken, since it sends out packets and reacts to changes on its analog input pin.

I’ll look into filtering. I’ll also consider hooking up my scope, but this comes with a considerable risk – all those wires plugged into all sorts of things and a USB-powered scope which could easily fry my computer!

Perhaps there’s a bug in the sketch. A simple multi-meter hooked up across the 0.1 Ω resistor indicates levels between 4 and 12 mVAC – which seems about right.

RFM12B Command Calculator

In Software on Sep 18, 2011 at 00:01

I wanted to learn a bit more about how to implement non-trivial forms in HTML + JavaScript. Without writing too much HTML, preferably…

There are a few versions of a tool floating around the web, which help calculate the constants needed to configure the RFM12B wireless module – such as this recent one by Steve (tankslappa).

Putting one and one together – it seemed like an excellent exercise to try and turn this into a web page:

Screen Shot 2011-09-17 at 15.47.21.png

If only I had known what I had gotten myself into… it took more than a full day to get all the pieces working!

In fairness, I was also using this as a way to explore idioms for writing this sort of stuff. There is a lot of repetitiveness in there, mixed with a frustrating level of variation in the weirdest places.

Due to some powerful JavaScript libraries, the result is extremely dynamic. There is no “refresh”. There is not even a “submit”. This is the sort of behavior I’m after for all of JeeMon, BTW.

The calculator has been placed on a new website, called http://tools.jeelabs.org/. The page is dynamically generated, but you can simply save a copy of it on your own computer because all the work happens in the browser. The code has been (lightly) tested with WebKit-based browsers (i.e. Safari and Chrome) and with FireFox. I’d be interested to hear how it does on others.

If you want to look inside, just view the HTML code, of course.

As I said, it’s all generated on-the-fly. From a page which is a pretty crazy mix of HTML, CSS, JavaScript, and Tcl. With a grid system and a view model thrown in.

You can view the source code here. I’ve explored a couple of ways of doing this, but for now the single-source-file-with-everything-in-it seems to work best. This must be the craziest software setup I’ve ever used, but so far it’s been pretty effective for me.

Why use a single programming language? Let’s mash ’em all together!

A 220 : 6.3 V transformer… backwards

In Hardware on Sep 17, 2011 at 00:01

A new day, a new setup:

DSC_2630.jpg

The schematic of this new setup was shown yesterday.

Wait – a regular transformer AND it’s connected the wrong way around?

My first reaction when I saw this article was that this couldn’t possibly work. After all, a 220 -> 6.3 VAC transformer has a 35:1 step down ratio, so when connected in reverse, that would simply generate 7.5 kiloVolt!

The first reason this doesn’t happen, is that the transformer is connected in series with the load. It’s not measuring voltage but current. This is in fact exactly what a current transformer does.

The second reason why the high voltage never gets generated, is the 0.1 Ω (2W) resistor placed in parallel with the 6.3 V winding. With a 1000 W load, there’s 4.5 A going through the resistor, which leads to a 0.45 V voltage across the transformer. Together with the 1:35 step-up, that’s “only” 15 VAC or so on the “primary” side.

There is a risk, though: if the 0.1 Ω parallel resistor were to ever get disconnected during use, then the secondary winding will instantly turn into a little fuse, heat up, and blow. And while it does, a very high voltage spike might come out the other end!

Still, 15 V is far too much for an ATmega. But this voltage is not directly connected between the I/O pin and ground. Instead, one side is connected to a 22 / 22 kΩ voltage divider, which nicely puts the AC signal in mid-range for the ADC. When the voltage exceeds the ± 1.65 V (VCC/2) swing supported by the I/O pins, it will start to flow through the ESR protection diodes of the ATmega. With 22 kΩ on the other end to limit the current, these currents will be less than 1 mA – this is not high enough to do any harm.

Anyway, let’s see what comes out:

    $ jeemon examples/driver-demo
    ...
    reading:RF12-868.5.17:oneLong:value = 8180
    reading:RF12-868.5.17:oneLong:value = 7952
    reading:RF12-868.5.17:oneLong:value = 7886
    reading:RF12-868.5.17:oneLong:value = 8004
    reading:RF12-868.5.17:oneLong:value = 7364
    reading:RF12-868.5.17:oneLong:value = 32577
    reading:RF12-868.5.17:oneLong:value = 171745  <- 100 W light bulb
    reading:RF12-868.5.17:oneLong:value = 174525
    reading:RF12-868.5.17:oneLong:value = 175552
    reading:RF12-868.5.17:oneLong:value = 175254
    reading:RF12-868.5.17:oneLong:value = 175263
    reading:RF12-868.5.17:oneLong:value = 175193
    reading:RF12-868.5.17:oneLong:value = 175308
    reading:RF12-868.5.17:oneLong:value = 175101
    reading:RF12-868.5.17:oneLong:value = 174102
    reading:RF12-868.5.17:oneLong:value = 171595
    reading:RF12-868.5.17:oneLong:value = 89046   <- off
    reading:RF12-868.5.17:oneLong:value = 12378
    reading:RF12-868.5.17:oneLong:value = 8650
    reading:RF12-868.5.17:oneLong:value = 9568
    reading:RF12-868.5.17:oneLong:value = 9532
    ...
    reading:RF12-868.5.17:oneLong:value = 13413
    reading:RF12-868.5.17:oneLong:value = 12650
    reading:RF12-868.5.17:oneLong:value = 26564
    reading:RF12-868.5.17:oneLong:value = 111262  <- 1 W power brick
    reading:RF12-868.5.17:oneLong:value = 205944
    reading:RF12-868.5.17:oneLong:value = 209868
    reading:RF12-868.5.17:oneLong:value = 210105
    reading:RF12-868.5.17:oneLong:value = 210249
    reading:RF12-868.5.17:oneLong:value = 210311
    reading:RF12-868.5.17:oneLong:value = 210668
    reading:RF12-868.5.17:oneLong:value = 209933
    reading:RF12-868.5.17:oneLong:value = 210106
    reading:RF12-868.5.17:oneLong:value = 210014
    reading:RF12-868.5.17:oneLong:value = 209756
    reading:RF12-868.5.17:oneLong:value = 235024  <- off
    reading:RF12-868.5.17:oneLong:value = 52646
    reading:RF12-868.5.17:oneLong:value = 21260
    reading:RF12-868.5.17:oneLong:value = 10945
    reading:RF12-868.5.17:oneLong:value = 9046
    reading:RF12-868.5.17:oneLong:value = 9381
    reading:RF12-868.5.17:oneLong:value = 9236
    reading:RF12-868.5.17:oneLong:value = 8695
    reading:RF12-868.5.17:oneLong:value = 9015
    ...

How can this be? A jump from 8 mV to 175 mV for the light bulb, and then 210 mV for a much lighter load?

It gets even weirder:

    reading:RF12-868.5.17:oneLong:value = 8642
    reading:RF12-868.5.17:oneLong:value = 8567
    reading:RF12-868.5.17:oneLong:value = 11567
    reading:RF12-868.5.17:oneLong:value = 32239
    reading:RF12-868.5.17:oneLong:value = 122999
    reading:RF12-868.5.17:oneLong:value = 180108
    reading:RF12-868.5.17:oneLong:value = 180393
    reading:RF12-868.5.17:oneLong:value = 180469
    reading:RF12-868.5.17:oneLong:value = 180344
    reading:RF12-868.5.17:oneLong:value = 180702
    reading:RF12-868.5.17:oneLong:value = 180036
    reading:RF12-868.5.17:oneLong:value = 180432
    reading:RF12-868.5.17:oneLong:value = 180197
    reading:RF12-868.5.17:oneLong:value = 179220
    reading:RF12-868.5.17:oneLong:value = 174530
    reading:RF12-868.5.17:oneLong:value = 172794
    reading:RF12-868.5.17:oneLong:value = 32629
    reading:RF12-868.5.17:oneLong:value = 13266
    reading:RF12-868.5.17:oneLong:value = 7944
    reading:RF12-868.5.17:oneLong:value = 7909

This time, there is no load! I just turned on power without anything attached, i.e. an open circuit!

There’s something completely wrong here. My hunch is that this is either due to some extreme level of noise or an improperly-dimensioned burden resistor.

Noise might explain it, since the code tracks maxima, including any high-frequency spikes there might be. Maybe a digital low-pass filter could help, but I haven’t found a good source for calculating the coefficients of a FIR filter.

Further investigation will be required – this setup is useless!

SMD current transformer

In Hardware on Sep 16, 2011 at 00:01

Here’s another attempt to detect whether an appliance is on and consuming power.

This time I’m going to use a tiny SMD transformer (DigiKey part# 811-1193-1-ND). It has a 1:100 turn ratio, with 0.007 Ω resistance in the primary “coil” (I think it’s just a single loop), and rated up to 10 A.

The problem with this part, which rules it out for serious use, is that it’s only meant for frequencies in the range 50 kHz to 500 kHz. Whoops, that’ll be off by three orders of magnitude when used with 50 Hz AC mains…

Oh well, since I had one lying around, least I can do is try it – right? Here’s the setup:

DSC_2629.jpg

The hookup is a bit odd, but will become clear in future posts. The SMD transformer is only a few millimeters square, between the green jumper block and the black mini-breadboard.

I’m using the current transformer (CT) as follows:

JC's Doodles, page 12.png

… except that this schematic is for another experiment, still pending. In this case, there is no 0.1 Ω resistor on the primary side (it wouldn’t make a difference, next to the primary’s 7 mΩ), but there’s a 100 Ω “burden resistor” on the secondary side. This matches the data sheet for getting a 1 V/A sensitivity. For info on CT’s and burden resistors, see this OpenEnergyMonitor page.

Here are some first results, using the same sketch as in yesterday’s post:

    OK 17 164 19 0 0
    OK 17 17 16 0 0
    OK 17 66 16 0 0
    OK 17 42 19 0 0
    OK 17 241 163 0 0   <- 100 W light bulb
    OK 17 107 95 0 0
    OK 17 49 93 0 0
    OK 17 77 94 0 0
    OK 17 134 94 0 0
    OK 17 244 93 0 0
    OK 17 7 94 0 0
    OK 17 151 93 0 0
    OK 17 27 93 0 0
    OK 17 124 90 0 0
    OK 17 119 24 0 0    <- off
    OK 17 125 24 0 0
    OK 17 36 16 0 0
    OK 17 246 15 0 0
    OK 17 109 16 0 0
    OK 17 33 18 0 0
    OK 17 50 16 0 0

These are raw bytes, i.e. a 32-bit long int, sent once a second and received via wireless. I’m powering the JeeNode with an AA Power Board and standing back during testing, the 220 VAC is now a bit too close for (my) comfort…

The average measurement value with no current is now about 16 x 256 = 4 mV.

The high value when the light has been turned on is about 94 x 256 = 24 mV, a 20 mV increase.

Not bad… but it’s less sensitive than the ACS714 Hall-effect sensor. I didn’t even try it with a 1 W load. This is a far cry from the claimed 1 V/A sensitivity, no doubt because the 50 Hz signal is so far off from the design specs of this SMD current transformer. Saturation effects, or something…

I’ll continue these experiments in the next few days with another current transformer which is designed to work at 50 Hz, as well as with a reversed 220 : 6.3 V PCB transformer. Stay tuned!

Power Measurement (ACS) – code

In Software on Sep 15, 2011 at 00:01

For yesterday’s setup, I had to write a bit of code. Here’s the main part:

Screen Shot 2011 09 14 at 12 38 44

(this “powerACS” sketch can be found here)

The idea is to keep reading the analog pin as often as possible (several thousand times per second), and then keep track of its moving average, using this little smoothing trick:

    avg = (499L * avg + value) / 500;

Each new measurement adds 1/500th weight to the average. I didn’t want to use floating point, so it takes some care to avoid long int overflow. Here’s how I scale the input (0 .. 1023) to microvolts (0 .. 3,300,000):

    uint32_t value = measure.anaRead() * (3300000L / 1023);

Note that 500 x 3300000 is under the max of a 32-bit int, so the above “avg” calculation is ok.

It’s easy to calculate the offset, once we know the average voltage. Keep in mind that we’re measuring 50 Hz AC, and that the result we’re after is the fluctuation – i.e. what you get when putting a multimeter in VAC measurement mode. The way to do that is to calculate the “average absolute difference from the average”:

JC s Doodles page 13

IOW, what I want is the average height of those red bars. I flipped the lower half up because we’re interested in the absolute difference (otherwise the bars would just cancel out).

Here’s the calculation:

    if (value > avg)
      total += value - avg;
    else if (value < avg)
      total += avg - value;
    ++count;

When the time comes to report a “range” reading, we calculate it as follows and reset the other variables:

    uint32_t range = total / count;
    total = count = 0;

Here’s some sample debug output on the serial port:

    [powerACS]
    ...
    2560650 2569286 5916 31973363 5404
    2576775 2569256 5911 32175178 5443
    2563875 2569266 5917 32888792 5558
    2567100 2570205 5911 33200506 5616
    2573550 2569935 5917 32798060 5543
    2580000 2565675 5910 183251691 31007  <- 100 W light bulb
    2573550 2565108 5916 356840654 60317
    2570325 2565479 5916 355916529 60161
    2512275 2565467 5910 355676919 60182
    2525175 2565688 5916 356664359 60288
    2486475 2566547 5909 354854663 60053
    2480025 2566631 5916 355567509 60102
    2480025 2568658 5910 355608745 60170
    2583225 2569370 5916 178542547 30179  <- off
    2576775 2569122 5915 33193018 5611
    2570325 2569274 5911 33236267 5622
    2560650 2568988 5917 32873935 5555
    2576775 2569290 5911 32733630 5537
    2567100 2568564 5917 33390738 5643
    ...
    2560650 2569179 5917 32917499 5563
    2576775 2568640 5911 32354114 5473
    2570325 2569121 5916 32820006 5547
    2576775 2568319 5917 33896284 5728
    2570325 2569996 5911 33120608 5603
    2567100 2568514 5917 37697489 6371    <- 1.1 W power brick
    2550975 2568582 5911 36764137 6219
    2567100 2568767 5916 37434853 6327
    2567100 2568813 5911 36272763 6136
    2563875 2568659 5917 37738504 6377
    2563875 2568355 5911 37911395 6413
    2567100 2568586 5917 37444158 6328
    2563875 2568672 5916 37607002 6356
    2580000 2568879 5911 37293083 6309    <- off
    2570325 2568330 5917 33082874 5591
    2563875 2567713 5911 33007567 5584
    2567100 2568380 5917 32770050 5538
    2580000 2568846 5910 33002639 5584
    2570325 2568844 5917 33201661 5611

You can see the 60 mV signal when the power consumption is 100 W. Which is a bit low: I would have expected 100 W / 230 V * 0.185 V/A = 80 mV. But it turns out that the lamp really is an 87 W lamp, so that makes it 70 mV. I’ll attribute the remaining difference to my crude setup, for lack of a better explanation.

What’s worse though, is that there is always a 5.5 mV “hum” when no current is flowing (even when the whole circuit isn’t anywhere near a power line). One possible explanation could be ADC measurement noise: the 10-bit ADC resolution is 3.3 mV. Then again, note how multiple measurements do lead to a much finer resolution: the 60 mV readout fluctuates by only a fraction of one millivolt. Noise actually improves resolution, when averaged over multiple readings.

Still, the 5.5 mV baseline value makes it hard to reliably measure really low power levels. The 1.1 W test was from an unloaded power brick, i.e. an inductive load. It causes the output to jump from 5.5 mV to only 6.3 mV, which is not a very distinct result. Another 0.3 W test load didn’t even register.

Conclusion: this detects current fairly well, was very easy to set up, and offers galvanic isolation protection. But it does require a hookup to AC mains power and it’s not super effective at really low power levels.

Power measurement (ACS)

In Hardware on Sep 14, 2011 at 00:01

The first try I’ll make at measuring AC mains power is with an Allegro ACS714 Hall-effect sensor (this one). I measures ± 5 Amps. It’s a bit expensive for wide-scale use, and it does require hook-up (i.e. AC mains pass-through). Hopefully a non-contact solution will present itself, eventually. For now, it’s a good baseline test.

The circuit provides 2.5 kV isolation, but of course that means nothing when everything is so close that you could easily touch the wrong pin by accident.

Here’s my setup:

DSC_2627.jpg

Everything is connected to my home-made isolation transformer. Which means grounding adds no safety and to remind me of the risk at all times, I’m using old 2-wire cabling and old ungrounded connectors. Not used anywhere else around here, so a mixup is not possible (those old power plugs won’t fit in today’s grounded sockets). If you look very closely, you can see that the splice is secured with two zip-lock ties. Cables are short so they don’t get tangled up, but long enough to avoid pulling on them.

As I was preparing the setup, I found out that the ACS714 needs 4.5 .. 5.5 V to operate, so the JeeNode + AA Power Board shown here won’t cut it. Oh well, I’ll switch to a 4x EneLoop battery pack (which is 5.2V).

Since I’m only interested in low-power for this test (under 100 W), the output voltage is within range of an ATmega running at 3.3V (the ACS714 output is 185 mV/A, centered around 2.5V).

The initial test worked flawlessly: the light went on! :)

Next, the software. It’s always the software which requires most work.

Sending RF12 packets over UDP

In Software on Sep 13, 2011 at 00:01

As I mentioned in a recent post, the collectd approach fits right in with how wireless RF12 broadcast packets work.

Sounds like a good use for an EtherCard + JeeNode pair (or any other ENC28J60 + RFM12B combo out there):

DSC_2625.jpg

The idea is to pass all incoming RF12 packets to Ethernet using UDP broadcasts. By using the collectd protocol, many different tools could be used to further process this information.

What I did was take the etherNode sketch in the new EtherCard library, and add a call to forwardToUDP() whenever a valid RF12 comes in. The main trick is to convert this into a UDP packet format which matches collectd’s binary protocol:

Screen Shot 2011-09-12 at 17.50.37.png

The sendUdp() code has been extended to recognize “multicast” destinations, which is the whole point of this: with multicast (a controlled form of broadcasting), you can send out packets without knowing the destination.

The remaining code can be found in the new JeeUdp.ino sketch (note that I’m now using Arduino IDE 1.0beta2 and GitHub for all this).

It took some work to get the protocol right. So before messing up my current collectd setup on the LAN here at JeeLabs, I used port 25827 instead of 25826 for testing. With JeeMon, it’s easy to create a small UDP listener:

And sure enough, eventually it all started to work, with RF12 packets getting re-routed to this listener:

Screen Shot 2011-09-12 at 20.04.08.png

Now the big test. Let’s switch the sketch to port 25826 and see what WireShark thinks of these packets:

Screen Shot 2011-09-12 at 17.15.16.png

Yeay – it’s workin’ !

The tricky part is the actual data. Since these are raw RF12 packets, with a varying number of bytes, there’s no interpretation of the data at this level. What I ended up doing, is sending the data bytes in as many collectd 64-bit unsigned int “counter values” as needed. In the above example, two such values were needed to represent the data bytes. It will be up to the receiver to get those values and convert them to meaningful readings. This decoding will depend on what the nodes are sending, and can be different for each sending JeeNode.

I’ve left the original web browser in as well. Here is the “JeeUdp” box, as seen through a web browser:

Screen Shot 2011-09-12 at 18.02.28.png

(please ignore the old name in the title bar, the name is now “JeeUdp”)

It’s not as automatic out of the box as I’d really like. For one, you have to figure out which IP address this unit gets from DHCP – one way to do so is to connect it to USB and open the serial console. The other bit is that you need to configure the unit to set its name, the UDP port, and the RF12 settings to use. There’s a “Configure” link of the web page to do this – a some point, I’d like to make JeeMon aware of this, so it can do the setup itself (via http). And the last missing piece of the puzzle is to hook this into the different drivers and decoders to interpret the data from these UDP packets in the same way as with a JeeLink on USB.

Ultimately, I’d like to make this work without any remote setup:

  • attach Ethernet and power to this box (any number of them)
  • each box starts reporting its status via UDP (including its IP address)
  • a central JeeMon automatically recognizes these units
  • you can now give a name to each box and fill in its RF12 configuration
  • packets start coming in, so now you can specify the type of each node
  • decoders kick in to pick up the raw data and generate meaningful “readings”
  • that’s it – easy deployment of JeeNode-based networks is on the horizon!

Not there yet, but all the essential parts are working!

A site for the home – part 2

In Software on Sep 12, 2011 at 00:01

I’ve been making good progress since the recent post.

Some things work, some things don’t when you use “off-the-shelf Open Source”. For example, I started using Twitters Bootstrap as CSS grid framework for page layout. It looks great. But there was too much interference with other components, such as jQuery DataTables. Well, either that or I simply don’t get it. So I ended up removing it all, in favor of the 960 Grid System (note how all JavaScript development seems to be happening on GitHub).

So now I’ve got a first rough cut at the “Niner” layout, i.e. 3×3 pages accessed via tabs on the bottom/right. Here’s a screen shot from an iPad:

Photo

The tabs don’t look so great (I’m so inept at GUI design that I don’t even try), but the general design is shaping up nicely. The area at the bottom left shows the last two lines of the log on the server, and it’s updating in real time. So is the table itself, using Server-Sent events.

With this sort of dynamics, all sorts of details start to jump out. My first approach was to have one page per URL, i.e. “http://127.0.0.1:8181/1” for page 1, etc. But that causes a full page refresh, which is too disruptive, especially with that log area constantly updating.

Which is where JavaScript and Ajax come in, of course. So now navigation only updates the main area – not the bottom & right-side borders. I’m only testing with Safari/Chrome, and occasionally FireFox, BTW.

The indentation idea I described earlier is also working out nicely. Here’s the main page description which produces the HTML sent to the browser:

Screen Shot 2011 09 11 at 22 39 33

(as you can see, there are limits to syntax coloring when mixing several languages in a single source file!)

And here’s the description of the page with that table shown above:

Screen Shot 2011 09 11 at 22 40 15

Let me just say that I’m “over” HTML. Bye bye, <div> et al. Good riddance.

PS. Oh yes, and here’s the fun part – this defines the structure of the site:

Screen Shot 2011 09 12 at 0 02 40

Tabs and titles are automatically generated unless overridden in this layout.

Sensing power consumption

In Hardware on Sep 11, 2011 at 00:01

A small exploration of a circuit which went nowhere…

I’ve been looking for a low-cost way to detect whether an electrical appliance is drawing current. There would be several uses for that, from power-saving master/slave power strips, to helping figuring out what’s going on in the house by measuring the central meter, as I’m doing already.

Here’s my original (naïve) line of thought:

  • optocouplers are a great way to stay out of AC mains electrical trouble
  • many units will still work with currents down to well under 1 mA
  • all I want is detection – is a device ON or OFF?
  • the rest can be done with JeeNodes, wirelessly, as usual

Here’s the (pretty silly) first step, in series between power outlet and appliance:

JC's Doodles, page 11.png

A resistor to limit the current, and the opto-coupler to “light up” and produce a signal in a galvanically isolated manner. But don’t get your hopes up, this setup definitely won’t work!

  • First of all, the appliance will stop working, if the resistor is in the 100 kΩ range.
  • With resistance values much lower, the resistor will become a heater and self-destruct.
  • Besides, even a 100 W load will draw 0.5 A or so… way too much for the LED.
  • There’s also a small problem with the voltage being AC, not DC, but that’s easily solved with a diode.

It’s a pretty useful mental exercise to work through this and understand how voltage, current, and power interact. If you’re totally lost, you could check out this series of posts and this link.

Sooo… could this approach be made to work?

In this case, an indirect demonstration that it can’t possibly work is actually easier to argue: suppose there were a circuit with the opto-coupler’s LED in series between outlet and load. It only needs to cause a voltage drop of about 1.5V to get the IR led inside to light up. Now suppose the load draws 1000 W, i.e. nearly 5 A. Big problem: (due to P = E x I) the power consumed by the opto-coupler would be 7.5 W … an excessive amount of heat for such a tiny device (apart from the sheer waste!).

Even some form of magical “power reduction” would be tricky, since I do need to detect the power-OFF case, i.e. power levels down to perhaps 0.5 W of standby power consumption for modern appliances (some even less). For 220V, 0.5 W corresponds to an average current of only 2.2 mA.

Maybe there’s a clever way to do this, but I haven’t found it. Something with a MOSFET, mostly conducting, but opening up just a little perhaps 1000x per second, to very briefly allow the LED in an opto-coupler to detect the current (with an inductor to throttle it). Heck, an ATtiny could be programmed to drive that MOSFET, but now it’s all becoming an active circuit, which needs power, several components, etc.

The trouble with AC mains is those extremes – on the one hand you need decent sensitivity, on the other you need to deal with peak loads of perhaps 2000 W, with their hefty currents, and where heat can become a major issue. We’re talking about power levels ranging over more than three orders of magnitude!

Of course there is the current transformer. But those are a bit too expensive to use all over the place.

Another option would be to use a regular transformer in reverse, as in this article. With a little 220 => 6.3V transformer, the ratio would be 35:1. With 5A max, a 0.1 Ω resistor would have 0.5 W of heat loss and create a 0.5V difference, amplified up to 17.5 V. For a 2.2 mA “off” current (0.5 W standby), that voltage would drop to 7.7 mV, which is probably too low to measure reliably with the ATmega ADC. Still.. might be worth a try.

An interesting low-cost sensor is based on the Hall-effect to detect magnetic fields. Because wherever there is alternating current, there is a magnetic field.

With hall-effect sensors, the problem is again at the low end. Keep in mind that the goal is reliable detection of current, not measurement. Now, you could increase the sensitivity by increasing the intensity of the magnetic field – i.e. by creating a coil around the sensor, for example. Trouble is: since those wires need to also handle large power consumption levels, they are by necessity fairly thick. Thick wires make lousy coils, and are impossible to get close to the sensor.

There are other ways. Such as measuring light levels, in case of a lamp. Or heat in case of a TV (would be a bit sluggish). Or vibration in case of a fridge.

Maybe a hand-made 100-turn current transformer would work? That’s a matter of winding some thin enameled wire around a single mains-carrying insulated copper wire.

Hm… might give that a try.

The challenge is to find something reasonably universal, which does not require a direct galvanic connection to AC mains. It seems so silly: an ATmega can detect nanowatt levels of energy, yet somehow there is no practical path from AC power ON/OFF detection to that ATmega?

PS. A related (and more difficult) problem is “stealing” some ambient magnetic energy to power a JeeNode. You don’t need much while it’s asleep, but transmitting even just one tiny packet is another story.

A site for the home

In Software on Sep 10, 2011 at 00:01

I’m building a “home monitoring and automation” system. Not just the hardware “nodes”, but also the software side of things, i.e. a server running permanently. Web-based, so that it can be accessed from anywhere if needed.

I’ve got a lot of code lying around here, ready to be put to use for just that. It’s not that hard to create a website (although truly dynamic displays are perhaps a little harder).

One thing I’ve been struggling with for a long time, though, is the overall design. Not so much the look & feel, but the structure and behavior of it all.

I’m not too keen on systems with elaborate menu structures, tons of hoops dialogs to jump through, even scrolling messes with our innate sense of location. Been there, done that. Modes suck – they just create labyrinths.

What I’ve come up with is probably not for everyone (heh, nothing new here). An entire system, organized as nine pages. No more, no less. Instant navigation with a keyboard (digits, function keys, whatever), and trivial navigation with a mouse or touch screen:

Web layout

Even a laptop screen with 3+3 buttons (or a joystick) could navigate to any page with just two clicks.

Here is a first exploration of what these pages could be for (vaporware, yeay!):

Web pages

Each page is nearly the full screen, with only the bottom and right-side borders used. And each page can have any content, of course: tabs, sidebars, widget collections, it’s still all up in the air. There’s plenty of software to extend this system infinitely, using HTML, CSS, and JavaScript.

One of the things I’d like to do with this, is make the system automatically return to the main Status Overview page when idle for a minute or so. With the option to “pin” one of the other pages to prevent this from happening.

This might all seem very basic, inconsequential, and even arbitrary, but for me it’s a major step forward. I’ve been running around in circles for ages, because there was no structure in place to start assembling the different parts of the site. It’s all nice and well to develop stuff and tinker endlessly behind the scenes, but in the end this still needs to lead to a practical setup.

So now there’s a plan!

Playing with indentation

In Software on Sep 9, 2011 at 00:01

Bear with me – this isn’t directly related to Physical Computing, but I’ve been having fun with some code.

If you’ve ever written any web apps or designed a web site, chances are that you’ve also written some HTML, or at least HTML templates. Stuff like this, perhaps:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset='utf-8' />
        <title>Flot graph demo</title>
        <script type='text/javascript' src='.../jquery.flot.js'></script>
        <script type='text/javascript'>
          $(function(){ ... });
        </script>
        <style type='text/css'>
          #placeholder { width: 600px; height: 300px; }
        </style>
      </head>
      <body>
        <div id='placeholder'></div>
      </body>
    </html>

Well, I’m getting a bit tired of all this nesting. The essence of it is buried far too deeply inside what I consider line noise. There are currently a number of developments related to HTML, CSS, and JavaScript which might change this sort of development considerably. Much of it seems to be driven by the Ruby and Rails community, BTW.

Some examples: for HTML, there is Haml. For CSS, there is Sass. And for JavaScript there is CoffeeScript.

All of these have in common (along with Python and YAML) that they treat indentation as a significant part of the notation. Before you raise an eyebrow: I know that the opinions on this are all over the map. So be it.

I wanted to try this with JeeMon, so after a bit of coding, I ended up with a “Significant Indentation Formatter” and then applied that to HTML. Here’s the above, re-written in a HAML-like notation:

    !html
      head
        meta/charset=utf-8
        title: Flot graph demo
        script/type=text/javascript/src=.../jquery.flot.js
        script/type=text/javascript
          $(function(){ ... });
        style/type=text/css
          #placeholder { width: 600px; height: 300px; }
      body>#placeholder

It generates the same HTML as above, but there’s less to write. Even less in fact, because I’ve also integrated it with JeeMon’s templating system:

    !html
      head
        meta/charset=utf-8
        title: Flot graph demo
        [JScript includes flot]
        [JScript wrap $js]
        [JScript style { #placeholder { width: 600px; height: 300px; } }]
      body>#placeholder

Here’s a slightly more elaborate KAKU send example which illustrates basic template looping:

    !html
      head
        meta/charset=utf-8
        title: KAKU send
        [JScript includes ui]
        [JScript wrap $js]
      body
        % foreach x {1 2 3 4}
          p.toggles
            button#on$x: On $x
            button#off$x: Off $x
        p#group
          label: Group:
          % foreach x {I II III IV}
            input#g$x/type=radio/name=g/value=$x
            label/for=g$x: $x
        p
          label: House Code:
          select
          % foreach x {A B C D E F G H I J K L M N O P}
            option/value=$x: $x

So far, this system doesn’t use standard conventions, is undocumented, hasn’t been used in anger or proven itself to handle more complex layouts, has almost no error handling, and has only been used by yours truly for a few hours. Still, I’ve adjusted all the examples in JeeRev to gain a bit more experience with this approach.

I like it. The above is pretty close to how I want to design the structures and sections of a web page.

Low-end Linux

In Hardware, Software on Sep 8, 2011 at 00:01

It’d be neat to use a very low-end embedded Linux system for running (part of) my home monitoring and automation system.

I’ve mentioned the BifferBoard before, twice in fact. With a BogoMips rating of 56, it’s as low end as it gets.

Unlike most low-end boards, which are ARM-based, the BifferBoard runs on a “S3282/CodeTek” which is 486SX-compatible, so many 32-bit Linux binaries will work as is. I’m running a fairly standard Debian Lenny on mine, very convenient. It needs 650 Mb, including a full gcc build chain.

IMO, there’s great value in such a low-power system. For one, with just 30 MB RAM and no swap support on the standard setup, you’re really forced to look at memory consumption. Running out of memory will cause a program to be terminated (it can easily be restarted with a watchdog shell script).

The other feature this board does not have is hardware floating point. It’s all emulated. Here’s what that means:

  $ ssh biffie jeemon tcl 'time {/ 1 2} 1000'
  36.735 microseconds per iteration
  $ ssh biffie jeemon tcl 'time {/ 1.0 2.0} 1000'
  336.717 microseconds per iteration
  $

Versus my lowly 1.4 GHz laptop:

  $ jeemon tcl 'time {/ 1 2} 1000'
  0.569055 microseconds per iteration
  $ jeemon tcl 'time {/ 1.0 2.0} 1000'
  0.546295 microseconds per iteration
  $

As you can see, it’s a whole different ballgame :)

Anyway, let’s try and get a bit more substantial code running on this setup. I’ll use JeeMon, since I’ve recently been doing some work to combine round-robin data storage with graphing in the browser:

Screen Shot 2011 09 07 at 17 10 29

The graphs on the right are 1-day / 1-week / and 2-month previews, but let’s ignore the actual graphs since there is not enough test data for them to be meaningful.

What I wanted to see, is whether this would run on a BifferBoard. Here’s my first attempt:

Screen Shot 2011 09 07 at 17 03 14

Whoops… out of memory. Not only that, it’s taking ages to generate the JSON data for each Ajax request coming from the browser. Here’s my laptop for comparison:

Screen Shot 2011 09 07 at 16 59 31

The laptop is generating data for 5 graphs (one is off-screen) in a fraction of a second, while the BifferBoard needs several minutes (before running out of memory).

Good. Because with such a slow process, it’s much easier to find the bottlenecks. It turned out to be in the round-robin storage module I recently coded (using a USB stick as mass storage device doesn’t help either). Two hours later, things started working a lot better:

Screen Shot 2011 09 07 at 19 02 40

Progress! Still too slow for practical use… at least it’s no longer running out of memory. But although the BifferBoard is no longer maxed out, it is struggling – here’s a “vmstat 3” display, with one line per 3s:

Screen Shot 2011 09 07 at 20 13 16

I now realize that with my current settings, all data streams are aggregated to a larger “bucket” every 5 minutes. This probably explains these periods of 100% CPU activity.

Memory use is reasonable (with all interactive SSH shells logged out):

  $ ssh biffie free
               total       used       free     shared    buffers     cached
  Mem:         30000      28248       1752          0        444       8040
  -/+ buffers/cache:      19764      10236
  Swap:            0          0          0
  $

There’s still a lot of floating point activity going on, because I store all data points as 64-bit doubles. This needs to be improved at some point. My hunch is that it will take care of the performance problem. But it’s nice to see that JeeMon can cope (sort of), even in such a very limited environment. A BifferBoard with JeeMon will definitely be sufficient as “slave” controller in a larger configuration.

Power consumption is pretty neat: 2.85 W under full load and 2.20 W when idle. Measured at the AC outlet, i.e. including 5V power supply losses.

There are numerous low-end Linux systems out there. If the above can be made to work reasonably well, then it should work with most of them… ARM- / PPC- / x86-based, whatever.

For now, that BifferBoard is a good way to keep me honest, and on edge :)

Versions à la GitHub

In Software on Sep 7, 2011 at 00:01

As mentioned a few days ago, I’m in the process of moving all my software development to GitHub.

In a nutshell: Git is a Version Control system which lets you keep track of changes to groups of files, and do it in such a way that many people can make changes and nothing will ever get lost. You might feel lost if you really make a mess of it, but every change is tracked and can be recovered and compared against any other point in time. Based on git, GitHub takes it all to the next level, by fostering collaboration and combining tons of useful features – for free, via their website. GitHub is to git as JavaScript is to assembler (the analogy is a bit rough).

If you’re writing code, there is no excuse for not using a VCS. Even as a single developer, even if no-one else ever gets involved, and even if you’re the most organized person on the planet. An organized developer? Hah! :)

Life without a VCS looks like this:

  • let’s write some code – great, it works!
  • let’s try out something more difficult now
  • drat, didn’t work, I hope my editor undo buffer lets me back out
  • let’s make a copy of what worked before
  • now let’s write some more code – great, it works!
  • … time passes …
  • time to write code again – hm, I messed up
  • where was that copy I made earlier, again?
  • drat, it doesn’t have my latest changes
  • do I remember which part worked, and what I added?
  • … time passes …
  • I want to continue on that first attempt again
  • hmm, guess I’ll start from scratch
  • no wait, let’s make a copy before I mess up
  • … time passes, the disk fills with copies, none of them work …

Now let’s revisit that with a VCS:

  • write some code, check it in – add a brief comment
  • try out something more difficult now
  • check it in, let’s add a note that it’s still experimental
  • hm, can’t seem to get it to work
  • oh, well, I’ll go back to the previous version – easy!
  • writing more code, having fun, we’re on a roll
  • let’s check it in right away
  • … disaster strikes, my laptop breaks down
  • get it fixed or get a new one, check out from GitHub
  • where was I? oh yes, got one good version and two bad ones
  • let’s switch to that failed attempt again
  • wait, let’s first merge the latest good changes in!
  • cool, now I’ve got an up-to-date set of files to work on
  • oh, darn, still can’t make it work, let’s save it with a note
  • … time passes …
  • ok, time to review the different attempts and take it from there

Note that there are no more copies of files. Only a repository (on your laptop and on GitHub – but you still need to back it up, like everything else). The repository contains the entire history of all the changes, including notes, backing out steps, merges, everything.

A lot of this is possible with any modern VCS, including the “subversion” setup I’ve been using until now. But GitHub makes it effortless, and throws in a lot of nice extras. You still need a “git” application on your laptop (there are several versions), and if you’re using a Mac, you can use GitHub’s own app to communicate with GitHub without having to go through a browser.

Here’s what a “diff” looks like, i.e. a comparison of the source code, showing only the differences:

Screen Shot 2011 09 02 at 21 53 17

One line was replaced, two more lines were added at the end. It’s totally obvious, right?

Here’s a history of the “commits” made, i.e. the times when a new version was sent to git and GitHub:

Screen Shot 2011 09 02 at 21 51 01

Almost everything is a link – you can compare versions, find out what else was changed at the same time, see what else any of the developers is working on, and of course download a full copy of any version you want.

The other mechanism I’d like to describe is branching and merging. That change shown above was not made by me but by “Vliegendehuiskat” (hello, Jasper :) – and the way it works is quite neat, if you’ve never seen collaboration via VCS in action.

What Jasper did, was create a “fork” of JeeLib, i.e. a personal copy which knows exactly where it came from, when, and from which version of which files. And then he made a small change (without even telling me!), and at some point decided that it would be a good idea to get this change back into the official JeeLib code. So he submitted a “pull request”, i.e. a request for me to pull his changed version back in:

Screen Shot 2011 09 06 at 22 25 56

This generated a new entry in GitHub’s issue tracker and an email to me. I liked his change and with one click, merged it back in. Only thing left to do was to “pull” those changes to my laptop copy as well.

GitHub has a graphical “network” view to display all commits, forks, branches, and merges:

Screen Shot 2011 09 06 at 22 29 10

Each dot is a commit. The black line is my code, the blue diversion shows Jasper’s fork, his commit, and my merge. Hovering over any of these dots will show exactly what happened.

This illustrates the simplest possible case of GitHub for collaboration. If you want to see how a entire team puts git and GitHub at the center of a large-scale collaborative software development effort, read this article by Scott Chacon (who works with and at GitHub, BTW).

I’ve been moving lots of stuff to GitHub these past few days, not all of it related to JeeLabs. Here are the three main projects, as far as physical computing goes:

Screen Shot 2011 09 02 at 21 48 41

Note another nice feature: you can instantly see how active a project is. JeeLib is the brand new combination of the Ports and RF12 libraries, while EtherCard and GLCDlib have been around a bit longer (and the full change history has been imported). It’s been over half a year since Steve and I worked on GLCDlib, as you can see – with a small blip before the summer, when I added font support.

There are a few features which I haven’t enabled at GitHub. One of them is their wiki – because having yet another spot on the web with pages related to JeeLabs would probably do more harm than good. The Café at http://jeelabs.net is as before the place to look for documentation. There are ways to merge this stuff, so maybe I’ll go there one day.

A warning: the “sketches” on GitHub have all been adjusted for the new upcoming Arduino 1.0 IDE, and do not work with Arduino 0022, which is still the main version today. So I’m slightly ahead of the game with this stuff.

I’m really looking forward to how the software will evolve – and you’re cordially invited to be part of it :)

PS. I’m updating to GitHub fairly often because I work on two different machines – and this is the easiest and safest way to keep stuff in sync.

System status

In Software on Sep 6, 2011 at 00:01

Yesterday, the WordPress server dropped out. Looks like some joker decided to grab the whole site, no throttling, nothing. Oh well, I guess that’s what fat pipes lead to.

In principle, WordPress should be able to handle such things, but I think it caused the underlying MySQL to run out of memory and abort.

A restart of the WordPress VM fixed it, once I found out. But this gives me an excuse to describe some things I’ve been starting to set up here.

One of of things I did this summer, was set up a collectd process on most of the machines running here – collectd is a bit Linux-centric, but one of the things it can do is grab various system statistics and broadcast it on the LAN over UDP. There are loads of plugins, and you can interface to it with scripts to feed it anything you like.

The nice thing about UDP broadcasts, is that senders don’t need to know anything about receivers. As with the RF12 driver, you just kick stuff into the network and then it’s up to others to decide what to do with it, if anything.

Collectd is also extremely low overhead, both in terms of CPU & memory load and in terms of network load. I’ve enabled it permanently on five systems, sending out 50..100 system parameters each, once every 30 seconds.

Here’s a partial view of the information being collected:

Screen Shot 2011 09 05 at 12 57 52

This was generated in the browser using JeeMon and jstree, as an exercise (I’m looking for a more convenient JavaScript widget to adjust a live tree using JSON).

Broadcasting is very convenient, as the collectd tool and the RF12 driver have shown, because there’s no setup. In theory, packets can get lost without acknowledgements and re-transmissions. In practice, some do indeed get lost, but very rarely. No problem at all for periodic / repetitive data collection.

I created a small script to display system status on my development Mac, using a tool called GeekTool. It can put information right on the desktop, i.e. as unobtrusively as you want, really. Here’s what I see when there are no windows obscuring the desktop background:

Screen Shot 2011 09 05 at 12 42 27

On the left is a periodic “ps“, the output on the right is from “ssh myserver jeemon overview.tcl“. This is a remote call to the server using a small script to pull info out of a text file and format it. The output shows that there are 5 systems online (running collectd, that is), and the script last ran at 12:41 in 39 ms.

Perhaps more interesting is that the server also collects this data from the LAN. To do this, I just launch JeeMon next to this “main.tcl” script:

    History group * 1w/5m 1y/6h
    collectd listen sysinfo

The first line is optional – it defines the parameters for historical round-robin data storage. So what I end up with, is the last 7 days of information, with details every 5 minutes, as well as up to one year of information aggregated per 6 hours.

The second line starts listening for collectd packets on the standard UDP port, tagging the results with the “sysinfo” prefix. As side effect, JeeMon will update a “stored/state.map” text file once a minute with the current values of all variables plus some other details. This is what was used to generate the above GeekTool on-screen status. There’s a built-in web server to query and access the saved historical data.

There’s no further setup. It’s up to the clients to decide what to collect and how often to send it. Data storage on the server is fixed, since this is stored in round-robin fashion (like rrdtool). It’s now collecting nearly 600 800 variables and using about 100 125 Mb of disk space. Data collection adds 2% load on a 2.66 GHz CPU.

This could also be used to collect home sensor data.

Re-using an LCD screen

In Hardware on Sep 5, 2011 at 00:01

This summer, someone gave me an old laptop which had stopped working. I couldn’t figure out what was wrong, so I decided to take it apart. Hehehe…

One of the parts coming out was a 15″ TFT LCD screen. Nothing stellar – 1280×800 – but still.

It turns out that there are several ways to get such a thing going again (thank you, Google). I ended up buying a DPMI/VGA interface board on eBay, complete with high-voltage supply and cables. It worked right out of the box:

DSC 2618

The display is not running at its native resolution here, because I couldn’t figure out how to force Win2000 to a specific screen resolution, but with Linux it did, so all is well.

I’d like to build a small & flat enclosure for this, hook it up to the Mac Mini, and hang it on the wall. Preferably with a distance sensor to control the whole thing so it only turns on when someone is standing directly in front of it. No need for a touch screen, a few buttons would be fine as home status display.

The whole combination runs off 12V, drawing 10 Watt when fully on and 0.3 W while asleep.

Yeay, reuse is fun!

The beat goes on

In Hardware on Sep 4, 2011 at 00:01

Today, a milestone was reached:

    $ jeemon examples/driver-demo/
    15:45:01.975 RF12demo config usb-A700fdxv RF12-868.5
    reading:RF12-868.5.3:radioBlip:ping = 493295
    reading:RF12-868.5.3:radioBlip:age = 365
    ^C

That’s nearly half a million packets, one every 64 seconds, all on a single LiPo battery charge:

Screen Shot 2011 09 03 at 15 51 53

The setup is very simple. A 1300 mAh LiPo battery (I just picked one up in a camera shop with a convenient size), attached to a JeeNode USB:

At 3.94 V the battery is still far from dead, so it’ll probably stay alive for quite a bit longer…

The sketch running on this node is:

Screen Shot 2011 09 03 at 16 14 28

(looks like I had lost the low-power stuff in the “radioBlip” code, now fixed on GitHub)

Lots of low-power nodes are holding out nicely here at JeeLabs, by the way. There are about half a dozen permanent room nodes, and with the latest roomNode sketch they just keep going. Some are running on 3x AA rechargeable EneLoop batteries, others use 3x AAA with even less juice, and all of them have been running with just a single charge since the beginning of this year.

The bits have moved

In News, Software on Sep 3, 2011 at 00:01

There are some changes planned in how things are going to be done around here. I want to streamline things a bit more, and make it easier for people to get involved.

One of the major changes is to move all JeeLabs open source software to GitHub:

Screen Shot 2011 09 02 at 22 01 27

The main reason for doing this, is that it makes it much easier for anyone to make changes to the code, regardless of whether these are changes for personal use or changes which you’d like to see applied to the JeeLabs codebase.

For the upcoming Arduino IDE 1.0 release (which appears to break lots of 0022 projects), I’ve moved and converted a couple of JeeLabs libraries so far:

  • Ports and RF12 have been merged into a single new library called JeeLib
  • the EtherCard and GLCDlib libraries have been moved without name change
  • all *.pde files have been renamed to *.ino, the new 1.0 IDE filename extension
  • references to WProgram.h have been changed to Arduino.h
  • the return type of the write() virtual function has been adjusted
  • some (char) casts were needed for byte to fix unintended hex conversion

If you run into any other issues while using this code with the new Arduino IDE 1.0beta2, let me know.

So what does all this mean for you, working with the Arduino IDE and these JeeLabs libraries?

Well, first of all: if you’re using IDE 0022, there’s no need to change anything. The new code on GitHub is only for the next IDE release. The subversion repositories and ZIP archives on the libraries page in the Café will remain as is until at least the end of this year.

New development by yours truly will take place on GitHub, however. This applies to all embedded software as well as the JeeMon/JeeRev stuff.

The new JeeLib should make it easier to use Ports and RF12 stuff – just use #include <JeeLib.h>.

Note that you don’t need to sign up with GitHub to view or download any of the JeeLabs software. The code stored there is public, and can be used by anyone. Just follow the zip or tar links in the README section at the bottom of the project pages, or use git to “clone” a repository.

To follow all my changes on GitHub, you can use this RSS feed. To follow just the changes to JeeLib in slightly more detail, this feed should do the trick.

One of the features provided by GitHub is “Issue Tracking”, i.e. the ability to file bugs, comment on them, and see what has been reported and which ones are still open. This too is open to anyone, but you have to be signed up and logged in to GitHub to submit issues or discuss them.

For questions and support, please continue to use the JeeLabs forum as before. But if you’re really pretty sure there’s a bug in there, you’re welcome to use the issue trackers (as you know, Mr Murphy and me tend to sprinkle bugs around from time to time, just to keep y’all sharp and busy ;)

And if you’d like to suggest a change, consider forking the code on GitHub and submitting a “pull request”. This is GitHub-speak for submitting patches. Small changes (even multiple ones) are more likely to go in than one big sweeping request to change everything. I’m open for suggestions (in fact, I’ve got a couple of patches from people still waiting to be applied), but please do keep in mind that code changes often imply doc changes, as well as making sure nothing breaks under various scenarios.

All in all, I hope that GitHub will help us all keep better track of all the latest changes to the software, work together more actively to fix bugs and add more functionality. I haven’t heard of GitHub ever going offline, but if it ever does, I’ll make sure that the latest code is also available from the JeeLabs servers as backup.

Update – Here’s an excellent article on how to collaborate via Git and GitHub.

The Murphy brothers

In Hardware on Sep 2, 2011 at 00:01

Let’s get this out of the way first…

About a week ago, it came to my attention that Mr. Murphy has been having a good time again, this time with the RBBB board by Modern Device.

Turns out that some units were accidentally shipped with a 3.3V regulator instead of a 5V unit:

RBBB regulator mixup

The effect is not dramatic, in the sense that the RBBB will work just fine with either regulator. But as soon as you start hooking up stuff, you may get weird behavior. The worst case would be to hook up stuff with its own 5V power supply, since that means the attached device could potentially put a higher voltage on the IO pins than the 3.3V supply voltage of the ATmega.

So how do we fix this? Well, if you’ve got an RBBB from JeeLabs in the past months (probably anywhere from just before the summer break until now), please check the regulator voltage. Let me know if it’s the wrong one and I’ll send replacement 5V regulators.

(Note that the RBBB’s L4931 and the JeeNode’s MCP1702 regulators have different pinouts!)

As for the current batch of RBBB’s I still have here, the store gets a little bit more complicated: these are all wrapped and sealed by Modern Device, and the bags are too thick to be able to read that lettering on the regulator. I’ve opened up almost a dozen bags and found a few 3.3V units in the older batch, and none in the newer one. There’s not much more I can do than replace those I know about, and repeat that offer to replace any regulators you come across yourself.

FWIW, I suspect that this problem is gone by now.

But there’s a second member in the Murphy family, still dropping by occasionally, it seems…

As you may remember, I switched all SMD-based ATmega328’s over to use OptiBoot a couple of months ago. As it turns out, the standard OptiBoot loader included with the Arduino IDE 0022 isn’t reliable under Windows – my hunch is that there’s some timing problem with the combination OptiBoot <=> FTDI USB interface. It appears to be solved by changing the watchdog timer from 500ms to 1s, see the discussions here and here.

There’s now a new Arduino IDE 1.0beta2 out, and I’m getting some signals that we’re not alone with these OptiBoot troubles, so for now I’ll just stick to that modified 1s OptiBoot code which I’ve been using for several months now, and I’ll hold off switching to OptiBoot on the DIP version of the ATmega328, as used in JeeNode kits. Failing bootstraps are no fun if you don’t have an ISP programmer and no time to try out various tricks to emulate one.

In a nutshell: all SMD chips from JeeLabs use the 1s OptiBoot (which runs at 115,200 baud), while all the DIP chips get pre-loaded with the Duemilanove bootstrap (which runs at 57,600 baud).

I’ll revisit this when the dust settles.

Onwards!

Back!

In Musings on Sep 1, 2011 at 00:01

Well, that was a pretty strange “break”, as far as summers go… mostly cloudy!

For the first half of the summer, I’ve learned to relax and not go online, even when at home. And for the second half, we’ve been going out, mostly short trips around the country – like a few days by train + bike in “Drenthe”:

And a quick trip to Paris:

Paris? Yes, that’s Paris. There’s a vineyard at the Montmartre, not far from the Sacré Coeur.

So is this:

Don’t believe me? Ok, here’s a more traditional image:

(all vacation pictures by Liesbeth, as usual)

Anyway, it’s good to be back. I’m looking forward to smell the solder fumes, burn my fingers, and see chips go up in smoke again – eh, something like that … ;)

Self-imposed hiatus

In News on Jun 30, 2011 at 00:01

It’s time for a break. And this one was planned :)

But it’s only fitting that today is also a great time to celebrate. Because this weblog has reached…

800

That’s right. Eight hundred articles on this weblog, published on a daily basis – at midnight Central European Time. About all the fun in physical computing and the electronics, hardware, software, and mechanics surrounding it – collected as a stream of notes describing my adventures in this geeky world of techno-babble.

The posts on this daily JeeLabs Weblog are – by definition – organized as a timeline. Some of it will inevitably be wildly obsolete by now, other parts are timeless and still useful, but if you didn’t tag along from the beginning in 2008, then it might all be somewhat overwhelming – or ridiculously frustrating, depending on your expectations.

There are a few ways to find your way around here. First of all, there are six categories (some of them quite large by now): AVR, Hardware, Musings, News, Software, and the catch-all Uncategorized. A somewhat more fine-grained structure is available through 28 “tags”, shown at the top of each post. There’s an updated listing of them on the intro page.

Another approach to finding your way around here, is to use the Search box at the bottom right of each page. It works quite well, but don’t search too broadly or you’ll get a result with hundreds of posts.

The third place to look for interesting posts is on the “Café“, and especially the pages in the hardware wiki, many of which have a Related Weblog Posts section at the end. I’ve tried to add links to new pages there whenever I could, although there’s still lots of room for improvement.

And last but not least, there’s the forum area, which is getting more and more traffic these days, so it could be a good place to search and ask questions. I tend to participate at least once a day (although quite a bit less in the two months ahead).

If shopping for JeeNodes and other JeeStuff is your kind of thing, don’t forget that the shop will close for one month, starting two weeks from now, and that there’s a discount / sale right now for current customers and contributors. See this page for all the details.

I’d like to thank everyone who in some form or other voiced their appreciation and encouraged me to push further. Techie as it all may be, this weblog is still about people, creativity, and shared passions. Because without all that, there is no point.

Scattered over the coming two months, Liesbeth and I will break away and travel in Europe for a while, and I’ll fill in the rest of this long summer by relaxing, learning, tinkering, experimenting, working on top-secret stuff, and cooking up all sorts of crazy hardware and software for future JeeLabs projects and products.

These daily weblog posts will resume on September 1st.

Until then, for your entertainment, a tale of two worlds: Splitscreen.

Enjoy!
-jcw

Update – Full alphabetical and chronological index.

All about Easy Electrons

In Hardware on Jun 29, 2011 at 00:01

Long-time readers will probably remember the Easy Electrons series of posts on this weblog – as the first post says: “a series which will cover various aspects of electronics from the viewpoint of a technology enthusiast with a non-electronics background.”

There have been 14 posts so far, covering everything from resistors and capacitors, to the basics of power consumption and heat, as well as diodes, transistors, and MOSFETs.

It’s been great fun to write, and the response to it has been absolutely overwhelming. Never did I expect that so many people would enjoy reading about these topics…

I tried to write these posts to convey my intuition on most of the topics covered. There’s a lot of theory out there on electronics, with as much maths and physics as you’re willing to muster, even. But none of that is really needed, if all you want is hook up some circuits with say a few sensors, some display, and a microcontroller such as the JeeNode, Arduino, or chipKIT.

So the point of the Easy Electrons series was really to try and bring across that essential understanding which can help avoid damaging stuff. It should after all be fun…

I say “was”, because I’ve decided to stop writing Easy Electrons installments. First of all, there’s a summer break coming up, but more importantly, I don’t really want to go too deeply into topics which are well covered by other sites on the web.

There are plenty of getting started sites, but the one I’d like to highlight is All About Circuits – it’s a goldmine of information, and it has a very active discussion forum area. Best of all, it’s not aligned to any particular supplier (as far as I can tell), so I would expect the information in it to be generally useful (and much broader and deeper than what I could possibly come up with). There are some ads on the site – to which I’m usually allergic, but they tend to be quite small and unobtrusive, IMO.

There’s bound to be info for everyone. I particularly liked Volume IV of their extensive documentation – filled with interesting experiments, with all the details and background info one could possibly need.

If all you want is to get started in electronics, perhaps because you have a computer software background, then skimming through the first 5 chapters, such as this section on voltage and current, ought to go a long way.

I’m not ruling out new posts which might still get tagged as part of the Easy Electrons series, but don’t wait for full-scale coverage of all electronics aspects one could think of. There’s no point duplicating what others are doing, and doing better and more thoroughly, in fact.

I’m delighted that there are such good resources, freely available to anyone with an internet connection. Would have loved to have had that access as a teenager!

So now I can focus my energy on exploring and blogging about all the new adventures ahead :)

JeeNode with a 32 KHz crystal

In AVR, Hardware on Jun 28, 2011 at 00:01

Another experiment: running a JeeNode on its internal 8 MHz RC clock while using the crystal input to run timer 2 as an RTC. This would allow going into a very low-power mode while still maintaining a much more accurate sense of time.

To this end, I modified a JeeNode SMD, by replacing the 16 MHz resonator with a 32 KHz crystal:

Dsc 2599

I didn’t even bother adding capacitors, these are probably not needed with this crystal (same as on the RTC Plug) since there is probably enough parasitic capacitance already.

The tricky part is the code, since the ATmega is now running in a not-so-Arduino-like mode. Could almost have used OptiBoot with this setup, but the only internal RC clock build for it is the LilyPad, which has an ATmega168.

I ended up using the ISP programmer. IOW, I now compile for “LilyPad w/ 328” and then bypass the bootstrap and serial-upload. Less convenient, but it works.

Here’s a quick test sketch which writes a dot on the serial line exactly once a second:

Screen Shot 2011 06 24 at 15.51.49

So this setup is working. It draws 4.10 ma, consistent with the recent current measurements: slightly less than with the 16 MHz resonator pre-scaled by two.

In idle mode, current use drops to 1.71 mA, not bad!

Now let’s power down with just the timer running as real time clock. There’s a special “power save” mode which does just that. The difference is that timer 0 will now be off, so there won’t be interrupts waking up the ATmega every 1024 µs (as side-effect, the millis() function will start to lose track of time):

Screen Shot 2011 06 24 at 16.15.04

A small adjustment is needed to make sure the serial port is finished before we go into low-power mode, hence the call to delay(3).

Hm, power consumption is still 0.67 mA – quite a bit, given that we’re really powering down most of the time.

Ah, wait. I forgot to turn off the radio. Doing that brings the reading down to 0.15 mA – and I forgot to turn off the ADC and other sub-systems. Now we’re down to … 0.05 mA, while still printing dots:

Screen Shot 2011 06 24 at 16.39.15

Note that these 1 second interrupts are very accurately timed, more so even than with the standard 16 MHz resonator. This could be used to perform time-domain tricks on the wireless side, i.e. waking up just in time whenever a “scheduled” packet is expected to come in – as described in yesterday’s post.

There’s probably more left to try. The delay is running on full power, waiting for the serial output to clear the USART. It could be done while in idle mode, for example. Anyway… that entire delay becomes superfluous when we stop sending out debugging output over the serial port.

So there you have it – a JeeNode running at ≈ 8 MHz, with a precise 32,768 Hz pulse feeding timer 2, in a way which supports low-power sketches while maintaining an accurate sense of time.

Wanna make a clock?

Time-controlled transmissions

In Hardware, Software on Jun 27, 2011 at 00:01

Receiving data on remote battery-powered JeeNodes is a bit of a dilemma: you can’t just leave the receiver on, because it’ll quickly drain the battery. Compare this to sending, where nodes can easily run for months on end.

The difference is that with a remote node initiating all transmissions, it really only has to enable the RFM12B wireless module very briefly. With a 12..23 mA current drain, brevity matters!

So how do you get data from a central node, to remote and power-starved nodes?

One way is to poll: let the remote node ask for data, and return that data in an ACK packet as soon as asked. This will indeed work, and is probably the easiest way to implement that return data path towards remote nodes. One drawback is that if all nodes start polling a lot, the band may become overloaded and there will be more collisions.

Another approach is to agree on when to communicate. So now, the receiver again “polls” the airwaves, but now it tracks real time and knows when transmissions for it might occur. This is more complex, because it requires the transmitter(s) and receiver(s) to be in sync, and to stay in sync over time.

Note that both approaches imply a difficult trade-off between power consumption and responsiveness. Maximum responsiveness requires leaving the receiver on at all times – which just isn’t an option. But suppose we were able to stay in sync within 1 ms on both sides. The receiver would then only have to start 1 ms early, and wait up to 2 ms for a packet to come in. If it does this once a second, then it would still be on just 0.2% of the time, i.e. a 500-fold power saving.

Let’s try this out. Here’s the timedRecv.pde sketch (now in the RF12 library):

Screen Shot 2011 06 24 at 20.54.37

It listens for incoming packets, then goes into low-power mode for 2 seconds, then it starts listening again. The essential trick is to report two values as ACK to the sender: the time the receiver started listening (relative to that receiver’s notion of time), and the number of milliseconds it had to wait for the packet to arrive.

There’s no actual data processing – I’m just interested in the syncing bit here.

The sender side is in the timedSend.pde sketch:

Screen Shot 2011 06 24 at 20.58.17

This one tries to send a new packet each time the receiver is listening. If done right, the receiver will wake up at just the right time, and then go to sleep again. The ACK we get back in the sender contains valuable information, because it lets us see how accurate our timing was.

Here’s what I get when sending a new packet exactly 2,096 milliseconds after an ACK comes in:

Screen Shot 2011 06 24 at 20.39.33

Not bad, one ack for each packet sent out, and the receiver only has to wait about 6 milliseconds with its wireless receiver powered up. I’ve let it run for 15 minutes, and it didn’t miss a beat.

For some reason, send times need to be ≈ 2.1 s instead of the expected 2.0 s.

Now let’s try with 2,095 milliseconds:

Screen Shot 2011 06 24 at 20.37.17

Something strange is happening: there’s consistently 1 missed packet for each 5 successful ones!

My hunch is that there’s an interaction with the watchdog timer on the receiver end, which is used to power down for 2000 milliseconds. I suspect that when you ask it to run for 16 ms (the miminum), then it won’t actually synchronize its timer, but will fit the request into what is essentially a free-running counter.

There may also be some unforeseen interaction due to the ACKs which get sent back, i.e. there’s a complete round-trip involved in the above mechanism

Hmm… this will need further analysis.

I’m using a standard JeeNode on the receiving end, i.e. running at 16 MHz with a ceramic resonator (specs say it’s 0.5% accurate). On the sender side, where timing is much more important, I’m using a JeeLink which conveniently has an accurate 16 MHz crystal (specs say it’s 10 ppm, i.e. 0.001% accurate).

But still – even this simple example illustrates how a remote can receive data while keeping its wireless module off more than 99% of the time.

Current measurements

In AVR, Hardware on Jun 26, 2011 at 00:01

Wanted to check a few things w.r.t. current consumption of a JeeNode. The old way of doing this was a bit inconvenient, so I made a new test setup:

Dsc 2597

(old one on the left, new one on the right)

Sturdier, no need to disconnect the multimeter to short it out, and most importantly: high-side current sensing! That’s quite important, because multimeters can add a small voltage drop when used in current measurement mode, and that voltage drop will affect the serial I/O on the FTDI pins when placed in the GND line. Silly me, should have been on the PWR line all along!

The back side of the new connector is trivial:

Dsc 2598

The multimeter attaches to the top pins, bent apart for easy connection. The jumper shorts it out so this contraption can still be used when the multimeter is turned off.

Ok, time for some simple measurements:

  • ATmega full speed, doing nothing: 6.84 mA
  • ATmega full speed, with the RFM12B receiver on: 18.42 mA
  • ATmega powered down, only the RFM12B receiver on: 11.53 mA
  • ATmega full speed, with the RFM12B tranmitter on: 29.92 mA

Idle mode is a simple way to reduce power consumption without changing the logic of the code. It turns the MPU off until an interrupt occurs. Basically, you’re telling it “I’ve got nothing to do until something new happens”. It’s a pretty safe change, and well worth doing in any idle loop which isn’t directly polling I/O pins. The ATmega’s current consumption is slashed by more than half:

  • ATmega in idle mode, doing nothing: 2.80 mA

Another way to reduce power consumption, is to slow down the clock at which everything takes place, by setting the “clock pre-scaler”:

  • ATmega @ 16 MHz, doing nothing: 6.84 mA (as before)
  • ATmega @ 8 MHz, doing nothing: 4.35 mA
  • ATmega @ 4 MHz, doing nothing: 2.96 mA
  • ATmega @ 2 MHz, doing nothing: 2.02 mA
  • ATmega @ 1 MHz, doing nothing: 1.55 mA
  • ATmega @ 500 KHz, doing nothing: 1.28 mA
  • ATmega @ 250 KHz, doing nothing: 1.16 mA
  • ATmega @ 125 KHz, doing nothing: 1.09 mA
  • ATmega @ 62.5 KHz, doing nothing: 1.06 mA

Diminishing returns, clearly. Note that lowering the system clock in this way is not necessarily the best choice – getting something done N times faster and then powering down completely might be more efficient (see below).

One thing to watch out for: don’t go below 4 Mhz if you want to be able to use the RFM12B, or the processor will be too slow to process each byte.

When combining this, we get:

  • ATmega @ 4 MHz in idle mode, doing nothing: 1.48 mA
  • ATmega @ 62.5 KHz in idle mode, doing nothing: 1.03 mA

The advantage of this approach is that the clock is still running on the 16 MHz resonator (which probably draws most of that remaining current), so you’re still able to keep track of time – just more slowly.

A different approach is to go into real low power mode, and use the watchdog to get back out of this comatose state. The watch dog timer is less accurate, but depending on your application that may not be an issue.

Here’s the current consumption with the ATmega alternately in full speed and in power down mode:

  • ATmega 16 ms @ 16 MHz / 16 ms powered down, doing nothing: 3.49 mA
  • ATmega 8 ms @ 16 MHz / 16 ms powered down, doing nothing: 2.31 mA
  • ATmega 4 ms @ 16 MHz / 16 ms powered down, doing nothing: 1.39 mA
  • ATmega 2 ms @ 16 MHz / 16 ms powered down, doing nothing: 0.80 mA
  • ATmega 1 ms @ 16 MHz / 16 ms powered down, doing nothing: 0.46 mA

That last one does about the same amount of work as when running constantly @ 1 MHz, but with a third of the power consumption. Here is the corresponding sketch:

Screen Shot 2011 06 24 at 13.45.56

And it will continues to scale downward:

  • ATmega 100 µs @ 16 MHz / 16 ms powered down, doing nothing: 90.4 µA

Which still represents 100,000 active processor cycles per second…

And lastly, let’s take it into power down and run for just 1 ms per second, i.e. 0.1% of the time. I can’t measure this with the multimeter, because the power use jumps up every second, but the comatose period draws a mere 6.8 µA, which is consistent with what has been reported several times before (the watchdog is still active, and so is the brown-out detector).

Desktop power supply

In Hardware on Jun 25, 2011 at 00:01

Apart from a variable lab suppy (mine does 0..15V @ 0..3A), I’ve often wanted a simpler supply with just a few fixed voltages and say 500 mA. For experimentation, a weak supply which collapses under too much load is in fact better, because it can help avoid damage (which is almost always thermal and due to large currents).

Today, I decided to put something together, using parts which have been lying around here for some time.

It starts with an encapsulated switching AC/DC converter. I used a Traco 04115, i.e. 15V @ 4W. That addresses the AC mains side of things and limits the power involved in the circuit. Then I added 4 adjustable switching power supplies, which I got off eBay last year:

Dsc 2594

They are all running in parallel, using 15V as input. You’re looking at the bottom side of the box, BTW – the bottom plate of this particular box has nice little rubber feet.

The hardest part was deciding how to bring the power out of the box. I didn’t want large jacks – this thing is a dekstop power supply! But leaving wires with various valotages coming out and dangling all over the desk is also not such a good idea.

The solution I chose, was to bring out everything together via a 40 cm piece of 6-core cable:

Dsc 2595

The cable is squeezed behind one of the enclosure’s inner posts for strain relief (the AC mains cable has a knot in it for the same reason).

At the other end sits this thing – ready to take lots of jumper wires:

Dsc 2596

I still need to figure out how to attach labels to it. This is the pinout (with the cable pointing up):

Screen Shot 2011 06 23 at 18.34.21

No idea how yet, but it would be best if this were placed as label on top of the experimenter’s board in the middle, hiding the solder joints and clearly indicating which pin is what.

As it turns out, this power supply is considerably more powerful than I expected. The 15 V AC/DC converter will in fact go up to twice its rated power, i.e. over 500 mA, before the short-circuit protection sets in.

Due to the nature of switching regulators, the other voltages provide even more current: I was able to pull well over 1A continuously from the 3.3V supply. Although at those levels, the voltage did drop to 3.1 V.

Efficiency was not a primary goal, since this desktop supply is relatively low-power anyway, but the entire setup draws 0.7 W unloaded, and about 10 W when pulling 15V @ 500 mA out of it. I don’t expect to be loading this power supply down much, let alone getting into heat problems, even though the box is completely closed.

Oh, and in case you hadn’t noticed – another baby step in dealing with AC mains…

Alternating current

In Hardware on Jun 24, 2011 at 00:01

I’m not only interested in high-power AC mains switching, but also in the low-voltage / low-power side of things. So here’s another little step towards experimenting with that:

Dsc 2592

A simple 6V @ 58 mA transformer, soldered onto experimenter’s board and wrapped in a couple of heat-shrink layers. What comes out is a safe 6V @ 50 Hz signal.

Eh…

Open

Make that over 15 VAC (half the peak-to-peak value) and nowhere near a clean sinewave!

I suspect that this is what you’ll often get with low-grade / low-cost transformers. Even without any load, the transformer draws about 1.1 W and heats up to around 50°C, yuck!

Actually, the shape isn’t as bad as it looks. If you look carefully, you can see that it’s more or less one harmonic superimposed on the main sine wave. I won’t go into details (and risk exposing my ignorance), but that’s where Fourier transforms come in. The idea is that any repetitive waveform can be constructed from a set of sinewaves at a multiple of the original frequency (these are the harmonics, same as in music). By calculating the Fourier transform, you can decompose any repetitive waveform back into a sum of those basic waves.

Cool, now I have an excuse to try out the FFT feature on my oscilloscope!

Fft

The purple line shows a graph of the intensities of the different harmonics. It’s not really a continuous graph, since FFT is a discrete algorithm, but what it does show is that there are harmonics. If the input were a pure sine wave, there would only be a single peak, at the frequency of the sine wave itself. But in this example there’s a very strong second peak. Which produces this severely distorted waveform.

Here’s a better transformer for comparison (rated at 17 VAC):

Better

You can see that the harmonics are much weaker. Which translates to a much cleaner sine wave. Well, up to a point, anyway.

One reason why these voltages are much higher than the ratings, is that AC is specified as average – after all, the voltage is changing all the time, so it really is a matter of definition how you measure these values. For a sine wave, the average (or RMS in techno-speak) is about 0.7 times the peak value, or equivalently: the peak value is about 1.4 times the rated voltage.

For 6V, we should get 6 x 1.4 x 2 = 16.8 Vpp (a far cry from the above measurement!), and for 17V, the peak voltage should be 17 x 1.4 x 2 = 47.6 Vpp.

In both cases, the measured value is higher, perhaps because this is measured at no load. Although that first transformer really is way off.

Welcome to the world of alternating current, analog effects, distortions, and conversion losses!

TRIAC trials

In Hardware on Jun 23, 2011 at 00:01

To start some tests with TRIAC control of 220V AC mains devices, I’ve built a trivial setup – based on the S216S02 TRIAC, which goes up to 16A and includes a built-in opto-isolator and zero-crossing detector. That last part makes it unfit for dimming (that requires phase-controlled switching) but it should be fine for turning lights and heaters on and off.

The circuit is very simple, but I really wanted to have something that wouldn’t expose me to 220V no matter how much I start goofing around. Here’s the basic idea:

Dsc 2556

There’s a small heatsink on the TRIAC, since the datasheet says that it’ll only go up to 2A without one.

Now just Splice, Solder, and Seal:

Dsc 2558

And voilá – nothing fancy:

Dsc 2557

Trivial stuff, I added a 220 Ω resistor in series with the LED, making it switch reliably on 3.3V, with under 10 mA current, i.e. fine for an ATmega.

The ends of the power wire are attached to a plug and a receptacle, respectively – making this an extension cord.

Baby steps, as I overcome my fear of the unknown, eh I mean 220V AC mains…

Latching relays

In Hardware on Jun 22, 2011 at 00:01

The traditional relay looks like this (thank you Wikipedia):

Relay

A spring pulls on the vertical lever on the right (above its pivot), keeping the contact pushed agains the “NC” contact – hence the name: normally closed.

An electromagnet can pull the (iron) lever towards the left, against the “NO” contact – i.e. normally open, but closed once the electromagnet is powered.

Great invention. Perhaps the first example of electric amplification: using a small amount of electricity to switch a potentially much larger voltage or current.

For ultra-low power devices, ordinary relays have a drawback: you have to keep them energized as long as you want to keep the “NO” contact closed. With the Relay Plug, things are no different – the latest relays used on it have a coil resistance of about 125 Ω, and each of the two requires 40 mA @ 5V to stay “on”:

Dsc 2591

That amount of current consumption is not so convenient with batteries – when turned on, they wouldn’t last more than a day or two on a bunch of AA batteries.

Fortunately there’s an alternative, called a “bi-stable” or latching relay. It uses two coils to move that lever back and forth, with weak magnets in the relay set up in such a way that they’ll stay in place without using a spring as counter-force.

The benefit is that latching relays don’t need any power to stay in their current state (be it open or closed), you only need to give them a pulse to change their state from ON to OFF or from OFF to ON.

There are actually two types of latching relays:

  • dual coil, usually with a common pin which should be tied to ground
  • single coil, where changing the state is done by applying reverse voltages

Most dual coil latching relays can also be used in single-coil mode, by simply leaving that common pin floating.

In principle, the circuitry for a dual-coil latching relay is simple: you just need two relay drivers and then turn one or the other on briefly to make the relay change its state. The point being that you only need to pulse them very briefly, 10..100 msec should be enough.

Unfortunately, the Relay Plug isn’t usable for bi-stable relays, because it assumes a common PWR pin, not GND. It turns out that these relays are polarized. Thinking about this a bit more, this is actually quite logical: the force of the little latching magnet(s) need to be overcome with a magnetic field with a specific opposite orientation.

But there’s a surprising way out…

With single-coil plugs, the trick is to let current flow in different directions to set or reset the relay. IOW, either connect one pin to PWR and the other to GND (briefly), or vice versa. Hm, that sounds awfully like running an electric motor forwards or backward…

Now here’s the trick: instead of a Relay Plug, use the DC Motor Plug!

Dsc 2310 Large

It contains two H-Bridges which are intended to control two small DC motors (or one stepper motor), allowing them to run in either direction.

You even get 4 additional general-purpose I/O pins thrown in…

Now, instead of hooking up a motor, just hook up a relay, and only pulse the power briefly (by making both sides GND or PWR the rest of the time). With as added benefit that the DC Motor Plug will support two latching relays, and being an I2C device, it’ll also allow daisy-chaining with other I2C plugs.

Note that the chips used on the DC Motor Plug require at least 4.5V to operate, according to the data sheet. Maybe a slightly lower voltage will work – I haven’t tried it.

Update – DC Motor Plug is confirmed to work. The 5V relays I was testing this with appear to switch reliably with pulses down to 4 ms, using this test code (modified from the dcmotor_demo.pde) sketch:

Screen Shot 2011 06 22 at 16.33.58

MCP1702 current draw

In Hardware on Jun 21, 2011 at 00:01

The MCP1702 used in JeeNodes and other circuits here at JeeLabs is a nifty little voltage regulator. It’s not particularly good for high voltages (limited to about 13V), but it has a very low idle current. That’s very useful for low-power circuits, especially when trying to get months or even years of service out of one set of batteries.

Let’s find out how it’s performing. I’ve set up this little test circuit:

Screen Shot 2011 06 20 at 00.39.11

Well, it’s not really a test circuit at all – it’s in fact exactly what you need to use one of these things.

Putting 5V on the input (Vin), and leaving it a few minutes to settle, gives me a reading of 2.2 µA. Great, just what the specs say. It doesn’t really go up much with input voltage: 2.8 µA @ 12V. This is at no load.

With a 10 kΩ load, current draw rises to 338.1 µA, i.e. 330 µA for the resistor and about 8.1 µA for the regulator (assuming perfect calibration). That’s only 6 µA more, i.e. about 2% of the load.

Now let’s take the input voltage down, and see how this “low-drop” regulator behaves:

  • 5.0 V -> 2.2 µA
  • 4.0 V -> 2.2 µA
  • 3.5 V -> 2.1 µA
  • 3.3 V -> 2.1 µA
  • 3.2 V -> 90.4 µA
  • 3.1 V -> 84.1 µA
  • 3.0 V -> 78.2 µA

Whoa… it sure doesn’t like being fed less voltage than it needs to supply a regulated output of 3.3V! The change is quite pronounced between 3.30 and 3.28V (I couldn’t get my power supply knob to adjust any more accurately).

For yesterday’s AA power board discussion that’s actually bad news, because it means that when the supply drops a mere 20 mV, it could cause the regulator to start wasting a fair amount of current (relatively speaking).

Let’s try something different: no power on Vin, but power on Vout instead.

This simulates connecting a battery to the +3V pin, and bypassing the MCP1702 voltage regulator altogether. Evidently, it’s not a good idea putting much more than 3.3V on there, since now we’re reverse feeding the regulator, something not all regulators are happy with:

  • 3.40 V -> 1000 µA
  • 3.35 V -> 500 µA
  • 3.30 V -> 90 µA
  • 3.25 V -> 90 µA
  • 3.20 V -> 90 µA
  • 3.10 V -> 84 µA

The conclusion seems to be: when using the AA Power Board in combination with a JeeNode, it might be better in certain cases to omit the regulator altogether if you’re aiming for minimal power consumption!

It’s not enough to short the regulator’s Vin and Vout, it really has to be taken out of the circuit. Fortunately, you don’t have to disconnect all three pins – just disconnect the ground pin (on the JeeNode v4..v6, that’s the one closest to the FTDI connector).

But if all you want to do is power the whole thing from some power source over 3.3V, such as a 3x AA battery pack or a LiPo battery, then all is fine… you’ll see that ultra-low 2.2 µA figure – as intended in this design.

Just beware of low voltages: weird things do happen!

AA boost ripple

In Musings on Jun 20, 2011 at 00:01

The AA Power Board contains a switching boost converter to step the voltage from a single AA battery up to the 3.3V required by a JeeNode.

Nifty stuff. Magic almost… if you take the water analogy, then it’s similar to pushing water up a mountain! Wikipedia has a schematic with the basic idea:

Boost Circuit

Think of the coil as a rubber band (I’ll use a gravitational force analogy here), then closing the switch is like stretching it from the current voltage to ground. Opening the switch is equivalent to letting it go again – causing the rubber band to contract, pulling the end back up and then exceding the original height (voltage) as it overshoots. The diode then sneakily gets hold of the rubber band at its highest point. The analogy works even better if you imagine a cup of water attached to the end. Well, you get the picture…

The trick is to repeat this over and over again, with a very efficient switch and a good rubber band, eh… I mean inductor. The way these boost regulators work, you’ll see that they constantly seek the proper voltage (feeding a storage pool at the end, in the form of a capacitor).

Enough talk. Let’s look at it with a scope:

Open

What you’re seeing is not the output voltage, which is of course 3.3V, but the variation in output voltage, which is measured in millivolts. IOW, 45 times a second, the regulator is overshooting the desired output by about 20 mV, and then it falls back almost 20 mV under 3.3V, at which point the booster kicks in again.

Let’s load the circuit lightly with a 10 kΩ resistance, i.e. 330 µA current draw:

10k

No fundamental change, but the horizontal axis is now greatly enlarged, because the discharge is more substantial, causing the boost frequency to go to 2.2 KHz.

With a 1 kΩ load, i.e. 3.3 mA current draw, you can see the boost working a bit harder to charge up, i.e. the slope towards ≈ 20 mV above 3.3V is more gradual:

1k

Keep in mind that the difference is also due to yet more magnification on the horizontal time axis. The boost converter is cycling at 21.1 KHz now.

With a 330 Ω load, i.e. 10 mA current draw, the wavevorm starts getting a few high-frequency spikes:

330

The total regulation is still good, though, with about 25 mV peak-to-peak ripple.

Now let’s simulate what happens with the RFM12B transmitter on, using a 100 Ω load, i.e. 33 mA current:

100

Looks like the regulator needs more time to charge than to discharge, at this power level. Still the characteristic “hunting” towards the proper voltage level.

With a 68 Ω / 50 mA load, the regulator decides to use more force, losing a bit of its fine touch:

68

The scope’s frequency measurement was off here, it probably got confused by the high frequency components in the signal. Repetion rate appears to be ≈ 65 KHz. But now the total ripple has increased to about 70 mV.

That’s probably about as high as we’re going to need for a JeeNode with some low-power sensors attached. But hey, why stop here, right?

Here’s the output with a 47 Ω load, i.e. about 70 mA:

47

Whoa… that’s a ± 0.05 V swing, regulation is starting to suffer. I also just found out that the scope software has peak-to-peak measurement logic built in (and more). No need to estimate values from the divisions anymore.

Note that a 70 mA current at the end will translate to some 200 mA current draw on the battery – that’s the flip side of boost regulators: you only get higher voltage by drawing a hefty current from the input source as well.

Until this point, I used a standard 1.5V alkaline battery, but it’s not fresh and showing signs of exhaustion at these power levels (the output was a bit erratic).

To push even further, I switched to a fully charged Eneloop battery, which supplies 1.2 .. 1.3V and has a much lower internal resistance. This translates to being able to supply much larger currents (over 1 A) without the output voltage dropping too much. In this case, the change didn’t have much effect on the measurements, but I was worried that continued testing would soon deplete the alkaline battery and skew the results.

To put it all in perspective, here is the output with the same 47 Ω load, but showing actual DC voltage levels:

47dc

So you see, its still a fairly well regulated power supply at 70 mA, though not quite up to 3.3V, as it should be.

One last test, using a 33 Ω resistor, which at 3.3V means we’ll be pulling a serious 100 mA from this circuit:

33dc

Measuring these values with a multimeter gives me 3.16 V @ 89 mA, while the resitance reads as 32.7 Ω – there’s some inconsistency here, which might be caused by the high-frequency fluctations in the output, I’m not sure.

But all in all, the AA Power Board seems to be doing what it’s supposed to do, with sufficient oomph to drive the ATmega, the RFM12B in transmit mode, and a bit of extra circuitry. A bit jittery, but no sweat!

Update – With a 10 µF capacitor plus 10 kΩ load the limits don’t change much, just the discharge shape:

Slow

The same, at higher horizontal magnification:

Cap

Note that AC coupling distorts the vertical position, it’s still ± 18 mV ripple, even if the up peak appears higher.

EtherCard library API

In Software on Jun 19, 2011 at 00:01

As you may have noticed in the last few weblog posts, the API of the EtherCard library has changed quite a bit lately. I’m not doing this to be different, but as part of my never-ending quest to try and simplify the calling interface and to reduce the code size of the library (these changes shaved several Kb off the compiled code).

The main change was to switch to a single global buffer for storing an outgoing Ethernet packet and for receiving the next packet from the controller. This removes the need to pass a buffer pointer to almost each of the many functions in the library.

Buffer space is scarce on an ATmega, so you have to be careful not to run out of memory, while still having a sufficiently large buffer to do meaningful things. The way it works now is that you have to allocate the global buffer in your main sketch:

Screen Shot 2011 06 15 at 09.32.45

This particular style was chosen because it allows the library to access the buffer easily, and more importantly: without requiring an intermediate pointer.

To make this work, you have to initialize the EtherCard library in the proper way. This is now done by calling the begin() function as part of your setup() code:

Screen Shot 2011 06 15 at 09.34.46

The ether variable is defined globally in the EtherCard.h header file. The begin() call also needs the MAC address to use for this unit. The simplest way to provide that is to define a static array at the top of the sketch with a suitable value (it has to be unique on your LAN):

Screen Shot 2011 06 15 at 09.37.18

Next, you can use DHCP to obtain an IP address and locate the gateway and DNS server:

Screen Shot 2011 06 15 at 09.39.27

The printIp() utility function can optionally be used to print some info on the Serial port.

If you are going to set up a server, then a fixed IP address might be preferable. There’s a new staticSetup() function you can use when not doing DHCP:

Screen Shot 2011 06 15 at 09.42.55

The gateway IP address is only needed if you’re going to access an IP address outside of your LAN, and the DNS IP addres is also optional (it’ll default to Google’s “8.8.8.8” DNS server if you do a DNS lookup). To omit values, pass a null pointer or leave the arguments off altogether:

Screen Shot 2011 06 15 at 09.45.55

Just remember to call either dhcpSetup() or staticSetup() after the begin() call.

DNS lookups are also very simple:

Screen Shot 2011 06 15 at 09.47.32

The one thing to keep in mind here, is that the website argument needs to be a flash-based string, which must be defined as follows:

Screen Shot 2011 06 15 at 09.51.10

Note the “PROGMEM” modifier. See the Saving RAM space weblog post for more info about this technique.

This concludes the intialization part of the EtherCard library. Next, we need to keep things going by frequently polling for new incoming packets and responding to low-level ARP and ICMP requests. The easiest way to do so is to use the following template for loop():

Screen Shot 2011 06 15 at 09.59.01

The packetReceive() function polls for new incoming data and copies it into the global buffer. The return value is the size of this packet (or zero if there is none).

The packetLoop() function looks at the incoming data and takes care of low-level responses. The return value is the offset in the global packet buffer where incoming TCP data can be found (or zero if there is none).

As to what to do next: it really all depends on what you’re after. Check out the examples in the Ethercard library for how to build web servers and web clients on top of this functionality.

To get an idea of the code overhead of the EtherCard library: a simple web client using DHCP and DNS is around 10 Kb, while an even simpler one using static IP addresses (no DHCP and no DNS) is under 7 Kb. The fairly elaborate EtherNode sample sketch, which includes DHCP and the RF12 library is now ≈ 13 Kb.

IOW, lots of room for adding your own app logic!

Ping example

In AVR, Software on Jun 18, 2011 at 00:01

Another example of how to use the EtherCard library:

Screen Shot 2011 06 15 at 09.08.33

This example illustrates doing DHCP, DNS, and then periodically pinging a remote server to see if it’s alive.

Sample output:

Screen Shot 2011 06 15 at 09.10.11

As you can see, it not only pings others, but also reports when it’s being pinged by others.

Add a LED and you could make a trivial server status display. Or add a web page fetch to verify that the web server is also still alive. Or add a graphics display to show a graph of the ping times. Or add a relay and power-cycle the server when it’s not responding … endless possibilities, and very simple to implement!

Complete web client demo

In AVR, Software on Jun 17, 2011 at 00:01

After yesterday’s addition of DHCP to the EtherCard library, it’s only a small step to create a sketch which does everything needed for convenient stand-alone use on a local LAN.

Here’s a webClient.pde demo sketch which sets itself up via DHCP, then does a DNS lookup to find a server by name, then does a web request every 5 seconds and displays the first part of the result:

Screen Shot 2011 06 15 at 09.04.57

Sample output:

Screen Shot 2011 06 15 at 09.05.51

The total sketch is under 10 Kb, so there’s still lots of room to add the RF12 wireless driver, as well as a fair amount of application logic.

Who says a little 8-bit processor can’t be part of today’s internet revolution, eh?

DHCP support

In AVR, Software on Jun 16, 2011 at 00:01

Not long ago, Andrew Lindsay added support for DHCP to his EtherShield library, which is derived from the same “Guido Socher & Pascal Stang” code base as the EtherCard library. Fantastic work, hats off!

I’ve reworked the code to simplify things, and more importantly: reduce its code size. Many of these changes made it into Andy’s Github code base, but I’ve decided to take it quite a bit further and completely redo the way DHCP gets called in sketches.

It’s now based on just one call: dhcpSetup(). For completeness, I must mention that lease expiry and re-lease have been swept under the rug for now. Here’s the new testDHCP.pde demo I’ve come up with:

Screen Shot 2011 06 16 at 00.10.07

Sample output:

Screen Shot 2011 06 08 at 13.43.27

The entire demo sketch is currently 7732 bytes (6420 without the serial I/O). The DHCP part appears to require about 1200 bytes in all this. Note that the actual code to perform or serve web requests will add several more Kb to the total size, this merely illustrates the minimal code for doing DHCP.

There’s a “#define SELECT_BIT” in the enc28j60.cpp source which can be changed for boards which don’t use B0 (i.e. arduino digital I/O pin 8) as chip select. There’s also a “#define FULL_SPEED” setting which switches the SPI bus to 8 MHz during block transfers – it’s enabled by default and has a noticeable impact on performance.

So now any ENC28J60-based EtherCard with an ATmega328 can be connected to a local LAN and become usable as web server and/or client without having to configure an IP address, DNS server, or gateway!

Sale!

In News on Jun 15, 2011 at 00:01

Ok, here we go again…

1. The JeeLabs online shop will be closed from July 16 to August 15, 2011.

2. The JeeLabs daily weblog will be on hold from July 1st to August 31st.

3. Sale!

Discount 2011

Each order will be checked, if I can’t figure it out I’ll contact you by email (this may add to the delay).

Update – Similar conditions now also apply for JeeLabs products in the Modern Device – same discount code!

One last refinement

In Hardware on Jun 14, 2011 at 00:01

With the high-side DC power switch circuit working, there’s room to tweak things just a teeny bit further.

Summary: we’re switching DC power on and off through a MOSFET, and measuring the voltage drop across that same MOSFET with a bit of amplification to get better readout sensitivity.

Let’s add one more feature: the ability to detect whether a disk is connected. But first, the complete schematic:

Screen Shot 2011 06 06 at 19.06.57

The R1 resistor protects the op-amp from negative voltages, which occur when the MOSFET (Q1) is open and a device has been attached.

R2 and R3 put the op-amp in 11x amplification mode, referenced to VCC.

The C1 capacitor was added to smooth out the analog readings a bit (R1 + C1 form a low-pass filter).

The R5 resistor makes it possible to detect whether there is anything connected to OUT or not: when Q1 is open, R5 creates a pull-up, forcing the “+” side of the op-amp to VCC, unless there’s a device attached. At 1 MΩ, the pull-up is so weak that any device will pull it down to ground potential (keep in mind that Q1 is open). When Q1 is closed, then R5 no longer matters since it gets shorted out.

And lastly, R4 was added as pull-up to avoid a startup glitch as the JeeNode is powering up (i.e. while DIO is still floating). Note that Q1 will conduct when DIO is low.

Here are some readings under different conditions. These are referenced to VCC and converted to mV x 11, i.e. 0.3V under VCC on the op-amp “+” pin reads out as 3300. The three values are low, high, and averages, sampled 50 times over a 5 second interval:

  • OFF, no device: 0 / 16 / 6
  • OFF, device switched off: 9 / 48 / 16
  • OFF, device switched on: 3280 / 3287 / 3280
  • ON, no device: 0 / 0 / 0
  • ON, device switched off: 0 / 0 / 0
  • ON, device switched on, start: 1267 / 2761 / 2348
  • ON, device switched on, stable: 925 / 1096 / 983

When OFF, there’s a clear difference between a device waiting to get power and no device at all, or one which has been physically switched off. When ON, the readout becomes proportional to the amount of current drawn.

According to the lab power-supply readout, the startup current goes to about 1A, and then once stable it drops back to about 380 mA. The device is a “Green Power” WD 500 Gb hard disk in a no-brand external USB enclosure.

This concludes the “high-side” experiment (all related posts have been collected on the wiki). For a stand-alone setup, it should work fine, but after all this floating ground trickery I’ve come to the conclusion that a COMMON ground setup will be more useful if this were ever to be turned into a plug…

Better resolution

In Hardware on Jun 13, 2011 at 00:01

Yesterday’s high-side DC power control circuit was not able to measure current in a very exact way. Each ADC step is about 3.3mv, and with a 0.1 Ω sense resistor, that translates to 33 mA steps (a bit less, now that the MOSFET turns out to have a slighty higher “on” resistance).

So let’s add an op-amp, to amplify the voltage:

Screen Shot 2011 06 05 at 18.27.58

That’s a standard way to amplify an input voltage by a factor of 11, so a 0.3V input should generate a 3.3V output voltage, which is nicely full-scale for the ATmega’s analog input when running at 3.3V.

But there’s a little mistake in this setup…

The voltage we’re measuring is not a small voltage above 0V, but a small voltage below 3.3V, so we’re in fact feeding the op-amp a voltage between about 3.0V and 3.3V. Amplified by 11 you get… something the op-amp can’t handle when powered from 3.3V, so it’ll simply return 3.3V all the time. Overflow!

Simple to fix though. Instead of tying that lower resistor to ground, we tie it to 3.3V as reference level. And lo and behold, I’m seeing a roughly 11x larger reading with the same setup as yesterday:

Dsc 2563

Now, the input voltage swings between about 2.4V and 3.3V, which is just fine as analog input.

The one thing to watch out for is that we’re sailing very close to the edge, or in op-amp speak: “close to the rail”. This circuit is working with an input voltage which is very close to the +3.3V power supply “rail”, and the output of the op-amp also needs to be able to swing up to that same +3.3V level. This requires some care in selecting a “RRIO” type op-amp (i.e. Rail-to-Rail Input and Output) – the chip I used here is the TLV2373, a dual op-aamp. It does fairly well, but the output can’t quite totally reach 0V or 3.3V. I suspect that most op-amps will have this problem: a tiny residual voltage on both sides of the output swing. Such is life, no op-amp is perfect.

Here is the test sketch I used for this experiment:

Screen Shot 2011 06 05 at 18.22.28

It’s set up for 4 channels, although this circuit only has one. This could be used as the basis for a 2-channel plug, since both the MOSFET and the op-amp are dual-channel.

The output measurements come in via wireless every 5 seconds, and a simple “1,21s” sent out to it (since this is node 21) will turn on the disk.

But this code doesn’t even come close to what I’d really like to implement: it needs to track power use, only switch off when a device is consistently below a preset level (could be different for each device), implement encryption to prevent unauthorized control, store settings in EEPROM, support configurable behavior after power loss, and power devices up in a staggered mode to reduce the load on the power supply, oh my – not there yet!

DC high-side control

In Hardware on Jun 12, 2011 at 00:01

Good news: the “high-side” DC power switch works!

Dsc 2561

On the bottom, a DC jack getting 12V power, on the right a cable with a DC plug powering an external USB disk.

The little board in the middle is sort of a breakout board for two SMD chips: a dual P-MOSFET and a low-drop -3.3V linear voltage regulator to power the JeeNode. The rest is boilerplate stuff, i.e. the JeeNode Experimenter’s Pack, a couple of resistors, and some electrolytic caps.

I’ve only tested it with a load of about 1A, but it should work up to 3A without any problem. What’s also nice is that as a high-side switch, it doesn’t really care what voltage is being used as power supply – anything between 3.5V and 16V should work just fine. That means this can also be used for 5V devices and even with devices powered off 1..4 LiPo-batteries. This simply fits between a DC power plug and its device – convenient!

The current consumption is 21 mA with the ATmega and receiver permanently on. Could easily be lowered a few mA by putting the ATmega in “idle” mode.

The current sensing capabilities are definitely working, but the resistance of the P-MOSFET is not quite 0.1 Ω: with a 390 mA current, I see about 90 mV across the MOSFET, indicating that its internal resistance when driven from a 3.3V JeeNode is more like 0.23 Ω. That’s on the high side (pardon the pun), because this would mean a 1A load will get about 0.23V less out of the power supply than it would with a direct connection – and 0.7V less when drawing 3A. Oh well, it’ll be ok for most devices, cheap power bricks don’t always supply exactly 12V anyway.

The question of course is how consistent this MOSFET resistance is. I suspect that there will be quite a bit of variation across different units. But that’s not necessarily a problem: we don’t really care about absolute currents, we just need to see how the device’s current consumption is relative to full power and idle modes, basically. And we can always calibrate the value with a multimeter or power resistor.

The other weak spot in all this is that the voltage levels measured with this setup are very low, and only cover a few percent of the ADC range. It would be nice to have a bit more resolution there.

Ok, let’s throw an op-amp into the mix…

Controlling the Dimmer Plug

In Hardware, Software on Jun 11, 2011 at 00:01

The Dimmer Plug contains an I2C chip which can control the brightness of up to 16 individual LEDs using hardware PWM. The advantage over the ATmega’s PWM is that there is no limitation to use only the DIO2, DIO3, or IRQ pin (the only ones which support hardware PWM), and of course that 16 individual LEDs can be controlled. In fact, since there are 3 solder jumpers, up to 128 LEDs can be controlled from a single I2C port (by daisy-chaining eight Dimmer Plugs).

Note that the output of the Dimmer Plug is only suited for driving single low-power LEDs with a series resistor. The default setup assumes that these LEDs are tied to 3.3V or 5V. For higher voltages and higher power, additional driver circuitry must be added (transistors, MOSFETs, or the ULN2803 8-wide driver, for example).

Here’s a demo setup:

Dsc 2559

(it’s not visible here, but the test LED has a 470 Ω resistor in series)

Although software PWM can handle more I/O pins, that does place a fairly high load on the ATmega, and the dimming takes place at a much lower frequency, which can be visible to the naked eye (and quite annoying).

The disadvantage of the Dimmer Plug is that it’s based on a fairly complex chip, the PCA9635. I’ve extended the DimmerPlug class in the Ports library a bit further to make it somewhat easier to use.

There’s also an updated dimmer_demo.pde sketch:

It exercises several of the PCA9635’s features:

  • all 16 output are set to maximum brightness
  • the “group blink” mode is enabled, using a specified blink frequency and blink duty cycle
  • the sketch waits 10 seconds, while blinking
  • the chip is reset to its default “group dimming” mode
  • then gradually make all channels dim at the same time
  • and lastly enter a loop, which illustrates how to do per-channel dimming

The setMulti() call takes a start register number, then a variable of arguments 0..255, and then a “-1” value to mark the end. It is shorthand for calling setReg() with successive register values, but more efficient.

The code in loop() does some tricky bit fiddling. Figuring out what it does is left as exercise for the reader, but you can simply ignore it if you don’t care about such trickery. The main thing to note is that indiviudal LEDs can be controlled by setting their corresponding register: dimmer.PWM0, dimmer.PWM1, …, up to dimmer.PWM15.

As you can see, the PCA9635 can control individual outputs, but also several outputs combined via the “group” modes. There are other options, i.e. only controlling a subset of the outputs in group mode, inverting the output signal, using open-collector mode instead of the default totem-pole configuration, and more. You will need to go through the datasheet (PDF) to take full advantage of all this. All registers in the PCA9635 can bet read and written using the getReg() and setReg() calls, respectively.

But for simple uses, the above should be sufficient!

RF12 broadcasts and ACKs

In Software on Jun 10, 2011 at 00:01

In yesterday’s post, the general design of the RF12 driver was presented, and the format of the packets it supports.

The driver also support broadcasting, i.e. sending packets to all interested nodes, and ACKs, i.e. sending a short “acknowledge” packet from receiver to transmitter to let the latter know that the packet was properly received.

Broadcasting and ACKs can be combined, with some care: only one node should send back the ACK, so the usefulness of ACKs with broadcasts is limited if the goal was to reliably get a packet across to multiple listeners.

Broadcasts and ACKs use the HDR byte in each packet:

Rf12 Packets

There are three bits: C = CTL, D = DST, and A = ACK, and there is a 5-bit node ID. Node ID 0 and 31 are special, so there can be 30 different nodes in the same net group.

The A bit (ACK) indicates whether this packet wants to get an ACK back. The C bit needs to be zero in this case (the name is somewhat confusing).

The D bit (DST) indicates whether the node ID specifies the destination node or the source node. For packets sent to a specific node, DST = 1. For broadcasts, DST = 0, in which case the node ID refers to the originating node.

The C bit (CTL) is used to send ACKs, and in turn must be combined with the A bit set to zero.

To summarize, the following combinations are used:

  • normal packet, no ACK requested: CTL = 0, ACK = 0
  • normal packet, wants ACK: CTL = 0, ACK = 1
  • ACK reply packet: CTL = 1, ACK = 0
  • the CTL = 1, ACK = 1 combination is not currently used

In each of these cases, the DST bit can be either 0 or 1. When packets are received with DST set to 1, then the receiving node has no other way to send ACKs back than using broadcasts. This is not really a problem, because the node receiving the ACK can check that it was sent by the proper node. Also, since ACKs are always sent immediately, each node can easily ignore an incoming ACK if it didn’t send a packet shortly before.

Note that both outgoing packets and ACKs can contain payload data, although ACKs are often sent without any further data. Another point to make, is that broadcasts are essentially free: every node will get every packet (in the same group) anyway – it’s just that the driver filters out the ones not intended for it. A recent RF12 driver change: node 31 is now special, in that it will see packets sent to any node ID’s, not just its own.

It turns out that for Wireless Sensor Networks, broadcasts are quite useful. You just kick packets into the air, in the hope that someone will pick them up. Often, the remote nodes don’t really care who picked them up. For important events, a remote node can choose to request an ACK. In that case, one central node should always be listening and send ACKs back when requested. An older design of the Room Node sketch failed to deal with the case where the central node would be missing, off, or out of range, and would retry very often – quickly draining its own battery as a result. The latest code reduces the rate at which it resends an ACK, and stops asking for ACKs after 8 attempts. The next time an important event needs to be sent again, this process then repeats.

RF12 packet format and design

In Software on Jun 9, 2011 at 00:01

The RF12 library contains the code to support the RFM12B wireless module in an Arduino-like environment. It’s used for JeeNodes but also in several projects by others.

Here’s the general structure of a packet, as supported by the RF12 driver:

I made quite a few design decisions in the RF12 driver. One of the goals was to make the communication work in the background, so the driver is fully interrupt-driven. An important choice was to limit the packet size to 66 bytes of payload, to keep RAM use low and still allow just over 64 bytes of payload, enough to send data in 64-byte chunks with a teeny bit of additional info.

Another major design decision was to support absolutely minimal packet sizes. This directly affects the power consumption, because longer packets take more time, and the longer the receiver and transmitter are on, the more precious battery power they will consume. For this same reason, the transmission bit rate is set fairly high (about 50 kbits/sec) – a higher rate means the same message can be sent in less time. A higher rate also makes it harder for the receiver to still pick up a good packet, so I didn’t want to push this to the limit.

This is how the RF12 driver can support really short packets:

  • the network group is one byte and also doubles as second SYN byte
  • the node ID is small enough (5 bits) to allow a few more header bits in the same byte
  • there are only three header bits, as described in more detail in tomorrow’s post
  • there is only room for either the source node ID or the destination node ID

That last decision is a bit unusual. It means an incoming packet can only inform the receiver where it came from, or define which receiver the packet is intended for – not both.

This may seem like a severe limitation, but it really isn’t: just add the missing info in the payload and agree on a convention so that the receiver can pick it up. All the RF12 does is enforce a truly minimal design, you can add any info you like as payload.

As a result, a minimal packet has the following format:

That’s 9 bytes, i.e. 72 bits – which means that a complete (but empty) packet can be sent out in less than 1.5 ms.

Tomorrow, I’ll describe the exact logic used in the HDR byte, and how to use broadcasts and ACKs.

How the JeeNode evolved

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

Thought it might be interesting to put the six JeeNode versions / designs next to each other. It nicely illustrates my progress in learning PCB design, and making some trade-offs and pinout choices over the past 2.5 years:

JeeNode v1:

Jlpcb 002

JeeNode v2:

Jlpcb 003

JeeNode v3:

Jlpcb 018

JeeNode v4:

Jlpcb 044

JeeNode v5:

Jlpcb 105

JeeNode v6:

Jlpcb 128

We’ve come a long way. And I think it’s now time to call this final v6 design… it!

Font tables – proportional

In Software on Jun 7, 2011 at 00:01

Unlike monospaced font tables, proportional fonts have character glyphs which all differ in size and relative positioning. This not only requires more storage, it also complicates the way these glyphs are stored in the bitmap image in flash memory.

In the GLCD library, I implemented this by storing two bytes for each character:

  • P: the horizontal start position of the glyph in the image (1 byte)
  • A: same as for monospaced fonts, but per-character pre-gap (4 bits)
  • B: same as for monospaced fonts, but per-character post-gap (4 bits)

The width of a glyph can be found by looking at the position of the next character glyph in the bitmap, which is placed right next to it.

Here is an example of a small proportional font:

Screen Shot 2011 06 01 at 17.24.37

I removed some parts for brevity.

So the “!” exclamation point for example, has width 2 in the bitmap (i.e. 3-1), with pre- and post-gaps of both 1 (i.e. 5-4). And the “#” numbersign charcter uses kerning, with a -1 pre-gap.

There is a problem, however. Most characters are fine, but after the “S”, the bit map position increments to a value greater than 255, which can’t be represented in a single byte!

Instead of doubling the position to use 2 bytes each, I implemented an “overflow” mechanism. This saves some memory, since most positions are just fine, if we ignore the top byte. We merely need to keep track of those few character positions where overflow actually happens.

This is what the “overflow position table” at the end does: for each character which straddles a 256-pixel boundary, it stores the offset of that character in the table. The result is that there is now sufficient info to locate each glyph, and this process only requires a few flash memory reads for any character code.

Note that for consistency, there are also two sentinels: one at the end of the per-character info, so that the width of that last character can be computed, and another one at the very end, to simplify the overflow calculation logic.

So there you have it: full font support, which easily fits in an ATmega!

Font tables – monospaced

In Software on Jun 6, 2011 at 00:01

The font support added yesterday works with compact byte tables stored in flash ROM to store all the “glyphs”, i.e. pre-computed bitmaps.

Here’s the entire table of the clR6x8 font:

Screen Shot 2011 06 01 at 16.31.53

All the characters are stored side-by-side in a very wide horizontal bitmap image. In this case, the height is 8 pixels and the width = 72 x 8 = 572 pixels.

In detail:

  • H: the height of the image, in pixels (1 byte)
  • W: the width of the image, in bytes (1 byte)
  • the image data, 8 horizontal bits per byte (H x W bytes)
  • F: the code of the first character stored for this font (1 byte)
  • N: the number of consecutive characters in this font (1 byte)

And then it depends on whether the font is monospaced or proportional. For a mono-spaced font, i.e. where all the glyphs have the same size:

  • P: the number of horizontal pixels per glyph (1 byte)
  • A: the “pre-gap” (value -4..11, encoded as 4 bits by adding 4 to it)
  • B: the “post-gap” (value -4..11, encoded as 4 bits by adding 4 to it)

The pre-gap defines where to start copying the glyph, relative to the current horizontal position. A negative value causes kerning. Likewise, the post-gap indicates where to start writing the next character. IOW, after a character has been processed, the horizontal position is advanced by P + B pixels (A does not participate in this calculation).

Proportional fonts

In Software on Jun 5, 2011 at 00:01

The GLCDlib library for the Graphics Board has been extended to support multiple fonts!

Dsc 2568

If you look closely, you’ll see that even kerning has been implemented – making italics much nicer.

The main use I see for this is not so much about going overboard with all sort of “roman”, “italic”, or “bold” mixes (although now you can), but to mix different font sizes on the same screen (large values, small labels, etc).

Here’s the new font_demo.pde sketch which produces the above display:

Screen Shot 2011 06 06 at 17.36.02

That’s just 7 of the 250+ fonts and variations now present in the GLCD library :)

To use a font, include the proper header in your sketch, and call glcd.setFont() to activate it. The thing to keep in mind is that fonts use up flash memory space. I’ve come up with a fairly compact way to store them, but larger fonts obviously need more memory than tiny ones, especially if they include all ASCII character codes. Also, proportional fonts need more space than mono-spaced fonts, due to extra per-character width / offset info.

Here is an overview of the amount of memory needed for each font, sorted by size:

    246   micro
    294   4x6
    294   clR4x6
    366   clR5x6
    426   5x7
    438   clR6x6
    486   5x8
    486   clR5x8
    582   clR6x8
    606   clR5x10
    ...
    7099  helvBO24
    7165  charB24
    7240  ncenI24
    7376  lubB24
    7478  lubI24
    7529  charBI24
    7595  ncenBI24
    7762  luBS24
    8148  lubBI24
    8627  luBIS24

The above sketch compiles to 12572 bytes, of which about 8 Kb are fonts.

One last note: these changes mean that you now always have to set up some font before calling drawChar() or drawString(), there is no default (it might not be the one you want, or you might not need any fonts at all).

Hard disk power – Mac OSX

In Hardware on Jun 4, 2011 at 00:01

Ok, quick manual test with Mac OSX gives me this pop-up dialog box when powering off a mounted disk:

Screen Shot 2011 05 30 at 11.19.42

The good news is that I can simply leave this message on the screen, since subsequent power cycling won’t create more dialog boxes. The disk mounts as usual, presumably after a sanity check. I’m using a journalled file system, so these checks should be quick and risk-free.

I can live with that on a “headless” server. Key issue will be to only power off when there really is nothing happening on the disk drive.

Server upgrade

In Hardware on Jun 3, 2011 at 00:01

The JeeLabs server is running out of steam…

No, not CPU load:

Screen Shot 2011 05 30 at 12.41.31

It’s idling at under 10%, and drawing 10..15W, exactly as planned.

It’s running out of RAM, all friggin’ 4 Gbytes of ’em!

There are 4 VM’s running so far, of which Drupal gets 768 Mb, and WordPress / Redmine each get 512 Mb. With Parallels, VM’s take up a bit more memory than the raw amount, I suppose there’s some caching going on.

It’s bordering on the ridiculous. The entire WordPress MySQL database is probably not more than a few dozen Mb by now (which in itself is silly, but that’s another story). Yet it needs more than an order of magnitude more RAM to serve it all up as web pages?

I can’t help but think that a fully RAM-based database (with disk image backup) could dramatically reduce the memory needs. But hey, I’m not in the business of redoing the database world – well, not these days anyway ;)

The shining exception is the nginx reverse proxy I use: it runs in 128 Mb, and would probably run just as fine with 64 Mb. It serves lots of static pages, and handles all the re-routing for the rest of the traffic. Brilliant software.

So I bought a fresh pair of 4 Gb memory sticks off eBay (thx, BWired):

Dsc 2541

With the latest Mac Mini models, memory upgrading is – at last – trivial. You might have seen the backSoon server for a few minutes, which is just a JeeNode USB with EtherCard presenting this (dynamic!) web page:

Screen Shot 2011 05 30 at 18.56.17

So there you go. All the JeeLabs .org and .net sites (and a few more) now run with a bit more breathing space. We’re solidly back in the green again:

Screen Shot 2011 05 30 at 19.01.55

Onwards!

Update – Looks like software always expands to consume all available memory: this time it is Apache, btw. I probably need to tweak it, it just grows and grows and grows! (the Drupal VM is now 1.5 Gb)

Screen Shot 2011 06 03 at 11.15.42

Hard disk power – bonus

In Hardware on Jun 2, 2011 at 00:01

Ok, there’s now a design for a high-side power switch which can power disk drives up and down at will.

Wait a minute…

You’re not supposed to power down disk drives just like that! It might be in the middle of a disk write. Even journaled disks are at risk, because journaling usually covers meta data (directories, files sizes, allocation maps, etc) … but not the data itself. So an unfortunate power down could leave the disk in an awful state: sure, the diks will be scanned and fixed on startup, but even then, some of the data blocks might contain inconsistent data. Whoops – bad idea!

One solution would be to add a JeeLink to the computer, and have it send out the power down command only after it finishes flushing and unmounting the disk. It’ll take some scripting, depending on the OS, but it’s all doable. Also, this isn’t really for disks which need to be online most of the time – for that, the normal hard disk spin down and idling modes will be fine.

But I’d like it to be a bit more automatic than that. I don’t want to have to remember to turn off the disks. Nor tie it to a specific time of day, or day-of-the-week. The whole point of these disks, is that I rarely need them. Some disks may stay off for weeks, even months.

Here’s an idea: by adding a current sensor to each disk power supply line, we could monitor disk activity and make sure that power is never shut off while a disk is “doing something”. By adding a bit of extra logic in the sketch, we could implement a timer so that the disk will only be powered down if the disk has been idle for say 15 minutes. Most operating systems have a periodic flush in place, so that changes always get flushed out to disk fairly soon after they have been buffered by the OS. If nothing has happened for a while, then we know there’s no important change pending.

OK, how do you measure the amount of current a circuit draws? Easy: insert a small resistance in series with the load, and measure the voltage drop. For the same reasons as before, we can’t do this “low side”, i.e. in the ground connection. But high-side would be fine:

Screen Shot 2011 05 30 at 02.00.54

With 1A of current, we get (using Ohm’s E=IxR law): E = 1 x 0.1 = 0.1V voltage drop across the resistor. And since the high side of the resistor is tied to “+”, all we need to do is connect the other side to an analog input.

The nice thing about the power control circuit presented yesterday, is that it has a MOSFET between + and the disk drive power pin. And MOSFETs are really very much like a small resistor when turned on. So we can simply use the MOSFET itself as a sense resistor:

Screen Shot 2011 05 30 at 01.54.25

Here are the characteristics of the P-MOSFET I’m going to try this with:

Screen Shot 2011 05 30 at 02.06.51

As you can see, at 3.3V, the MOSFET acts almost exactly like a 0.1Ω resistor: 0.1V drop at 1A – perfect!

There is still one problem though: when the MOSFET is turned off, the voltage on the low side will be at ground level, which is 8.7V below the JeeNode’s “ground”. So we can’t just tie it to an analog input pin, it would fry the ATmega. That’s is why I added a 10 kΩ resistor: it will still be a very “bad” input signal when the MOSFET is off, but the resistor will limit the current to less than 1 mA, and it will flow through the internal ESD protection diode. That amount of current should be harmless.

So now we have a way to sense the current. When the disk draws 1A, the analog input will be at 0.1V below 3.3V, i.e. 3.2V, which can easily be measured. Since the ADC resolution is 3.3 mV, this means that a change in power consumption as small as 33 mA could in principle be detected by this setup. Should be accurate enough to detect a disk spinning up or down and the seek actuator moving.

I’ve ordered a bunch of parts and will report when something useful comes out of these experiments.

Hard disk power #3

In Hardware on Jun 1, 2011 at 00:01

As promised in the previous post, here’s an improved design for controlling hard disk power.

The first conclusion is that we need to switch the positive +12V line, not the ground. Ground is inter-connected between all disks, the server, and this circuit – so we shouldn’t mess with it.

Here’s one way to do a “high-side” switch:

Screen Shot 2011 05 29 at 20.02.56

First problem: we don’t have a voltage higher than 12V available, so the N-MOSFET can’t simply be moved to the upper power line (it needs a few volts above its source to drive it, and when conducting, that source is at 12V). A P-MOSFET solves that, because it needs a few volts below 12V to drive it into conduction.

Second problem: we can’t drive the P-MOSFET high enough (12V) to make it disconnect, when driven from an ATmega output pin (which can’t go higher than 3.3..5V). So we need a resistor to pull the gate up, and a transistor to pull the gate down. And lastly, we need a resistor to limit the current into the transistor.

Quite a few parts, expecially since this circuit needs to be repeated for each hard disk.

For reasons which will become clear tomorrow, I’d like to simplify this circuit a bit further, and get away from handling 12V power levels. This “simplification” needs a bit of explanation, unfortunately:

Screen Shot 2011 05 29 at 21.05.13

To see what’s going on, this trick may help: look at the VOUT pin as being a regulated 8.7V voltage. In other words: the JeeNode “ground” is at +8.7V above ground, in relation to the power supply, hard disks, and server.

This means that the JeeNode is running with a 12 – 8.7 = 3.3V voltage difference between its 3.3V and GND pins, just as it always does. It’s merely floating a bit above ground, but that’s all relative anyway. As far as the JeeNode goes, it’s getting exactly the right power levels.

The result is that the output pins of that JeeNode will be at about 8.7V when “0” and at 12V when “1”. Which is just right to drive the gate of a suitable P-MOSFET (a “1” will turn it off, and a “0” will make it conduct).

So instead of making all the disk ground levels float, this setup places the JeeNode at an unusual 8.7V above ground level, which lets it turn on and off P-MOSFETs by controlling the positive supply line.

Now we need a regulated 8.7V supply. Eh, actually, no… we need a supply which is exactly 3.3V below the +12V line. That way, even if it fluctuates a bit from hard disk load changes, the JeeNode still gets a nice clean 3.3V.

The way to do that is to use a minus 3.3V regulator, such as an LM337. And from the perspective of that regulator, +12V is “ground” and ground is… -12V!

Perfect. You just have to look at voltages upside-down :)

Hard disk power #2

In Hardware on May 31, 2011 at 00:01

Yesterday, I described a design to control the power of hard disks. Now let’s see what happens when two hard disks are hooked up this way:

Screen Shot 2011 05 29 at 19.24.25

I’m including the USB cables to the server now, because that’s what causes a major problem: ground loops!

USB is a 4-wire (+ shield) connection between computer and devices. It is not isolated, i.e. all devices get hooked up galvanically. This in turns means that the ground potential of all inter-connected devices will be the same.

With a disk powered from a 12V power supply, ground is the negative wire. It’s also the ground of the USB connection to the server, so the “–” side of the power supply is connected directly to ground on the USB cable.

When two or more disks are plugged into one computer via USB, all ground pins will be connected together.

So far, no problem. Most devices have their own power supply, and these are all “floating”, i.e. they will adopt any ground voltage potential imposed on them (if any). You can connect any number of power supplies together through their “–” pins, and they’ll happily each feed their own devices and share a common ground.

Yesterday’s design is different – it uses a MOSFET to connect or disconnect the GND level from the disk drive:

Screen Shot 2011 05 29 at 19.36.05

The MOSFETs act as switches, connecting or disconnecting the wires on top to the JeeNode (and power supply) ground. So what one disk sees as “ground” is not the same as what the other sees (unless both are powered up). But… with the USB cables inserted, we’ve in effect created a direct connection between “GND1” and “GND2” through the USB’s common ground wires.

The result will be that no matter which MOSFET turns power on, it will end up powering BOTH disk drives!

And what’s (much) worse: the power supply current for the other drive will go through both USB cables and the server, which isn’t designed to handle the 1..2A peak currents flowing on startup.

Phew! I’m glad I didn’t start building this circuit :)

Tomorrow, I’ll describe a better design.

Hard disk power control

In Hardware on May 30, 2011 at 00:01

There’s a server running 24 hours a day, 7 days a week here at JeeLabs. It has two internal hard drives, one of them used as hourly backup for the system partition on the other disk. It’s running a couple of VM’s with all sorts of services, and it’s been running flawlessly for several months. Draws 10..15W.

Now, I’d like to attach a couple of extra hard disks to this server. A pair of disks for off-site backups (yes, there is a daily cloud backup, but I want a second fall-back system for some files), and a disk with stuff I rarely need, but don’t want to throw away. Disks are cheap – in fact I’ve got enough disks, so disk storage is actually free here. And while I’m at it: maybe add a little NAS for private stuff, since it’s been lying around and collecting dust anyway.

But I don’t want to have everything on-line all the time, for safety reasons and to keep power consumption low.

Why not use a JeeNode to control the power to these devices, which all run off a 12V supply? And why not just use one beefy switching supply, instead of that endless collection of power bricks?

Here’s a first idea:

Screen Shot 2011 05 29 at 18.49.52

Only one of the two channels on the MOSFET Plug is used here. And instead of switching a power LED or LED strip with it, it’s being used to control the power to the external disk drive.

There’s a flaw in this design, though: it’ll only work with ONE hard disk…

Tomorrow I’ll go into this and explain what’s going on, and why it can’t work with multiple disk drives. Hint: this setup only works if the JeeNode is controlled by wireless.

Summary of ISP options

In AVR, Hardware, Software on May 29, 2011 at 00:01

First of all, see this weblog post for an overview of what ISP is, why you’d want to know, and when you need it.

There have been quite a few posts about ISP on this weblog over time – all tagged, so they can be reached via this link: http://jeelabs.org/tag/isp/.

I’ll summarize here, since particularly the different sketches floating around by now might be a bit confusing.

The ZIF socket is a way to connect to chips before they have been soldered into a circuit. There’s one for through-hole DIP chips, and one for 32-TQFP SMD chips:

Once soldered into a circuit, you can use an I(C)SP programmer, which not everyone has. So I created a couple of different options based on a JeeNode (can also be an RBBB or Arduino) to perform the same function.

My first trial was a hack with the isp_flash.pde sketch, which then led to the Flash Board (info). The nice thing about this board is that it has 128 Kbyte of EEPROM on board – enough to hold the complete programming instructions for an ATmega168 or ATmega328.

One way to use the Flash Board is as capturing ISP programmer: you send a sketch to it as if it were an ISP programmer, and then you can disconnect it and use it repeatedly to upload that sketch to other boards via ISP:

I used this to build a 4-fold Multi-ISP programmer to program all those gazillion ATmega’s needed for JeeNodes:

Took a few attempts to get all the bugs worked out, but now it works perfectly.

But there’s a much simpler way to do this, if all you want is to fix a JeeNode, occasionally:

… or use an Arduino:

These two ISP setups use an isp_repair.pde sketch, which has as novelty that it includes the sketch and bootstrap its needs for programming – as data array in flash memory. So all that’s needed is: connect the two boards and power up the master. No need to use the Arduino IDE’s “Burn Bootloader” command or anything.

Then came OptiBoot, which is compatible with the Arduino Uno, and smaller/faster. This is a relatively new boot loader so you might want to update your current JeeNodes – even though an ISP programmer isn’t normally needed for development.

I updated the isp_repair.pde sketch, and then fixed a few remaining problems with it:

And finally, I added a LiPo battery, and 4 config switches, to end up with this tool:

On the software side, the most recent design is called isp_repair2.pde. It supports two different sketches, up to four different bootstrap loaders, and setting the fuses either as 16 MHz crystal or optimized specifically for ceramic resonators.

The include files with the bootstraps included with these sketches are generated from HEX files created by the Arduino IDE. This is done with a small Tcl script called hex2c.tcl, which is located in a slightly older isp_prepare example sketch folder. It’s not needed for normal use, only when one of the boot loaders changes.

Phew. Still there?

In a nutshell: if you need to re-flash your ATmega, pick one of the above options to hook things up, and use the isp_repair2 sketch in the Ports library. By default, it’ll upload a blink demo sketch and the OptiBoot loader.

More bootstraps

In AVR, Hardware, Software on May 28, 2011 at 00:01

Some projects just don’t want to lie down…

The isp_repair example sketch in the Ports library was written for a single purpose: to upgrade a JeeNode to the OptiBoot loader, which leaves more room for sketches and is compatible with the Arduino Uno.

It took two attempts to get it right, but in the end I think it all worked out as intended.

Until featuritis sets in…

First, I added a #define OPTIBOOT in the sketch, to allow re-using that same sketch to revert to the original boot – in case you ever want to go back. So now it’s a setup which can “repair” an ATmega in various ways.

But why stop there?

There are a couple variations for flashing which all make sense in the context of JeeNodes:

  • load a short Blink sketch, or load the entire standard RF12demo sketch
  • OptiBoot vs the original Arduino 2009 bootstrap code
  • faster wakeup after power down, works only with a 16 MHz resonator

The fast wakeup makes it possible to completely power down an ATmega between the reception and transmission of individual bytes via the RF12 driver. It won’t make a huge difference, but it will reduce power consumption just a notch more than staying in idle mode.

So here’s a new setup, and hopefully the last:

Dsc 2536

It includes yesterday’s DIP-switch Plug, which gives me 4 bits of configurability. There’s a new sketch which adds support for these switches and includes all the different pieces if code – it’s called isp_repair2:

Screen Shot 2011 05 26 at 01.34.25

The sketch includes up to four different boot loaders, currently:

Dip Switch Plug

There are two “sketch” code sections, followed by 4 bootstrap code sections:

Screen Shot 2011 05 26 at 03.09.23

With all switches set to “1” (same as not connecting any switches at all, BTW), we get:

Screen Shot 2011 05 26 at 03.06.53

And since (in my case) there’s an on-board LiPo recharger and battery tacked onto the back: this setup is fully self-contained and ready for use at any time.

Hmmm, I wonder what sort of bootstrap loader I could put in that spare slot, one day…

Funky plug

In Hardware on May 27, 2011 at 00:01

What is this thing?

Dsc 2533

Maybe you can guess from the other side?

Dsc 2534

Simple – it’s a funny kind of DIP switch, to manually configure 4 input pins as needed:

Screen Shot 2011 05 25 at 13.17.43

When used with internal pull-ups, this causes each switch to pull an I/O pin down when latched in the top position (as indicated in parentheses).

Works on any pair of ports and in any orientation, of course – but then the pin assignments will be different.

Fixing the isp_repair sketch

In AVR, Hardware, Software on May 26, 2011 at 00:01

A few days ago I posted a new sketch to reprogram an ATmega with the OptiBoot loader when you don’t have an ISP programmer. Worked for me, so I thought… kick it into the world!

Whoops…

First of all, there should have been a warning that if it didn’t work, this would leave you with an unusable ATmega. Never occurred to me, since I have an ISP programmer within reach to recover from such mistakes.

Fortunately, someone on the forum reported that the ATmega can be brought back to life with an old version of isp_repair.pde (which can be found here, BTW).

That’s odd… can’t program with the sketch, but can recover with the same sketch and different data bytes?

Time to dig in. First, I wanted to make sure that the timing was slow enough to work in all cases. Time to fire that logic analyzer up again:

Screen Shot 2011 05 25 at 11.33.22

Looks good – since I’m using standard digitalWrite() calls, the pins aren’t toggling very fast at all:

Screen Shot 2011 05 25 at 11.34.29

Then it dawned on me:

The lock bits don’t look right: 0xFF – should have been 0xCF (top 2 bits are always 1, i.e. same as 0x0F).

Maybe everything was working, except the setting of the fuse bits? That would explain everything: a new boot loader gets loaded in the top 512 bytes, overwriting parts of the old boot loader, but the fuse bits perhaps wouldn’t get adjusted to just to the new boot address!

I changed a couple of things:

  • do the full chip erase before setting the fuse bits
  • set the lock bits to 0x0F at the end, i.s.o. 0x3F
  • included both bootstraps in the updated sketch
  • tri-state the ISP programming pins when done

The erase is needed to recover from a locked fuse state. The programming always took place after the erase, so it went well, but the fuse bits themselves would still be locked while trying to adjust them.

The second step should have been there all along, the way I was doing it the boot section was not protected from overwriting itself. This might explain the occasional report I got of people damaging boot loaders during use.

You can now also adjust the #define OPTIBOOT at the top of the sketch to 0 to revert to the original bootstrap code and fuse settings. So if OptiBoot is not what you want, recompile and restore as needed.

And lastly, the SPI programming pins are now reset to high-impedance after programming, so that the programming connections can be left in place without interfering with the target board.

Here’s the serial output from the updated sketch:

Screen Shot 2011 05 25 at 11.41.31

And here’s why it would sometimes have worked: if your ATmega had the lock bits unset (0x3F i.s.o. 0x0F), then the fuse settings would work as intended even with the chip erase in the wrong order. But with a locked setup, not everything would get set to the proper state.

Which goes to show: bugs can bite at any time!

Update – still some issues to iron out (see forum), but it looks like these are more related to OptiBoot than to this bootstrap replacement sketch.

Update #2 – OptiBoot issue solved.

Avoiding memory use

In Hardware on May 25, 2011 at 00:01

On an ATmega328, memory is a scarce resource, as I’ve mentioned recently. Flash memory is usually OK, I’ve yet to run into the 30..32 Kb limit on code. But the crunch comes in all other types of memory – especially RAM.

This becomes apparent with the Graphics Board, which needs a 1 Kb buffer for its display, and with the EtherCard, which can often not even fit a full 1.5 Kb Ethernet packet in RAM.

The Graphics Board limitation is not too painful, because there’s the “JeePU“, which can off-load the graphics display to another JeeNode via a wireless connection. Something similar could probably be done based on I2C or a serial interface.

But the EtherCard limitation is awkward, because this essentially prevents us from building more meaningful web interfaces, and richer web server functionality, for example.

The irony is that there’s plenty of unused RAM memory, just around the corner in this case: the ENC28J60 Ethernet controller chip has 8 Kb RAM, of which some 3.5 Kb could be used for further Ethernet packet buffers… if only the code were written differently!

In fact, we have to wonder why we need any RAM at all, given that the controller has so much of it.

The problem with the EtherCard library, is that it copies an entire received frame to RAM before use, and that it has to build up an entire frame in RAM to send it out.

I’d like to improve on that, but the question is how.

A first improvement is already in the EtherCard library: using strings in flash memory. There’s also basic string expansion, which you can see in action in this code, taken literally from the etherNode.pde example sketch:

Screen shot 2011 05 24 at 22 57 26

The $D’s get expanded to integer values, supplied as additional arguments to buf.emit_p(). This simplifies generating web pages with values (and strings) inserted, but it doesn’t address the issue that the entire web page is still being constructed in a RAM buffer.

Wouldn’t it be nice if we could do better than that, especially since the packet needs to end up inside the ENC28J60 controller anyway?

Two possibilities: 1) generate directly to the ENC28J60’s RAM, or 2) generate a description of the result, so that the real output data can be produced when needed.

For now, this is all just a mental exercise. It looks like option #1 could be implemented fairly easily. The benefit would be that only the MAC + IP header needs to stay in RAM, and that the payload would go directly into the controller chip. A huge RAM saving!

But that’s only a partial solution. The problem is that it assumes an entire TCP/IP response would fit in RAM. For simple cases, that would indeed be enough – but what if we want to send out a multi-packet file from some other storage, such as an external Memory Plug or an SD card?

The current EtherCard library definitely isn’t up to this task, but I’d like to think that one day it will be.

So option #2 might be a better way: instead of preparing a buffer with the data that needs to be sent, we prepare a set of instructions which describe what is needed to generate the buffer. This way, we could generate a huge “buffer” – larger than available RAM – and then produce individual packets as needed, i.e. as the TCP/IP session advances, packet by packet.

This way, we could have some large “file” in a Memory Plug, and its contents would be copied to the ENC28J60’s RAM on-demand, instead of all in advance.

It seems like a lot of contortions to get something more powerful going for the EtherCard, but this approach is in fact a very common one, called Zero Copy. With “big” computers, the copying is done with DMA and special-purpose hardware, but the principle is the same: don’t copy bytes around more than strictly needed. In our case, that means copying bytes from EEPROM to ENC28J60, without requiring large intermediate buffers.

Hm, maybe it’s time to create a “ZeroCopy” library, sort of a “software based generic DMA” between various types of memory… maybe even to/from external I/O devices such as a serial port or I2C device?

It could perhaps be modeled a bit like Tcl’s “channels” and “fcopy” command. Not sure yet… we’ll see.

RF bootstrap design

In Software on May 24, 2011 at 00:01

After some discussion on the forum, I’d like to present a draft design for an over-the-air bootstrap mechanism, IOW: being able to upload a sketch to a remote JeeNode over wireless.

Warning: there is no release date. It’ll be announced when I get it working (unless someone else gets there first). This is just to get some thoughts down, and have a first mental design to think about and shoot at.

The basic idea is that each remote node contacts a boot server after power up, or when requested to do so by the currently running sketch.

Each node has a built-in unique 2-byte remote ID, and is configured to contact a specific boot server (i.e. RF12 band, group, and node ID).

STEP 1

First we must find out what sketch should be running on this node. This is done by sending out a wireless packet to the boot server and waiting for a reply packet:

  • remote -> server: intial request w/ my remote ID
  • server -> remote: reply with 12 bytes of data

These 12 bytes are encrypted using a pre-shared secret key (PSK), which is unique for each node and known only to that node and the boot server. No one but the boot server can send a valid reply, and no one but the remote node can decode that reply properly.

The reply contains 6 values:

  1. remote ID
  2. sketch ID
  3. sketch length in bytes
  4. sketch checksum
  5. extra sketch check
  6. checksum over the above values 1..5

After decoding this info, the remote knows:

  • that the reply is valid and came from a trusted boot server
  • what sketch should be present in flash memory
  • how to verify that the stored sketch is complete and correct
  • how to verify the next upload, if we decide to start one

The remote has a sketch ID, length and checksum stored in EEPROM. If they match with the reply and the sketch in memory has the correct checksum, then we move forward to step 3.

If no reply comes in within a reasonable amount of time, we also jump to step 3.

STEP 2

Now we need to update the sketch in flash memory. We know the sketch ID to get, we know how to contact the boot server, and we know how to verify the sketch once it has been completely transferred to us.

So this is where most of the work happens: send out a request for some bytes, and wait for a reply containing those bytes – then rinse and repeat for all bytes:

  • remote -> server: request data for block X, sketch Y
  • server -> remote: reply with a check value (X ^ Y) and 64 bytes of data

The remote node gets data 64 bytes at a time, and burns them to flash memory. The process repeats until all data has been transferred. Timeouts and bad packets lead to repeated requests.

The last reply contains 0..63 bytes of data, indicating that it is the final packet. The remote node saves this to flash memory, and goes to step 3.

STEP 3

Now we have the proper sketch, unless something went wrong earlier.

The final step is to verify that the sketch in flash memory is correct, by calculating its checksum and comparing it with the value in EEPROM.

If the checksum is bad, we set a watchdog timer to reset us in a few seconds, and … power down. All our efforts were in vain, so we will retry later.

Else we have the proper sketch and it’s available in flash memory, so we leave bootstrap mode and launch it.

That’s all!

ROBUSTNESS

This scheme requires a working boot server. If none is found or in range, then the bootstrap will not find out about a new sketch to load, and will either launch the current sketch (if valid), or hit a reset and try booting again a few seconds later.

Not only do we need a working boot server, that server must also have an entry for our remote ID (and our PSK) to be able to generate a properly encrypted reply. The remote ID of a node can be recovered if lost, by resetting the node and listening for the first request it sends out.

If the sketch hangs, then the node will hang. But even then a hard reset or power cycle of the node will again start the boot sequence, and allows us to get a better sketch loaded into the node. The only drawback is that it needs a hard reset, which can’t be triggered remotely (unless the crashing sketch happens to trigger the reset, through the watchdog or otherwise).

Errors during reception lead to a failed checksum at the end, which then leads to a reset and a new boot loading attempt. There is no resume mechanism, so such a case does mean we have to fetch all the data blocks again.

SECURITY

This is the hard part. Nodes which end up running some arbitrary sketch have the potential to cause a lot of damage if they also control real devices (lights are fairly harmless, but thermostats and door locks aren’t!).

The first line of defense comes from the fact that it is the remote node which decides when to fetch an update. You can’t simply send packets and make remote nodes reflash themselves if they don’t want to.

You could interrupt AC mains and force a reset in mains-powered nodes, but I’m not going to address that. Nor am I going to address the case of physically grabbing hold of a node or the boot server and messing with it.

The entire protection is based on that initial reply packet, which tells each remote node what sketch it should be running. Only a boot server which knows the remote node’s PSK is able to send out a reply which the remote node will accept.

It seems to me that the actual sketch data need not be protected, since these packets are only sent out in response to requests from a remote node (which asks for a specific sketch ID). Bad packets of any kind will cause the final checksums to fail, and prevent such a sketch from ever being started.

As for packets flying around in a fully operational home network: that level of security is a completely separate issue. Sketches can implement whatever encryption they like, to secure day-to-day operation. In fact, the RF12 library includes an encryption mechanism based on XTEA for just that purpose – see this weblog post.

But for a bootstrap mechanism, which has to fit in 4 Kb including the entire RF12 wireless packet driver, we don’t have that luxury. Which is why I hope that the above will be enough to make it practical – and safe!

Saving RAM space

In AVR, Software on May 23, 2011 at 00:01

Yesterday’s post was about finding out how much free memory there is in an ATmega running your sketch.

The most common out-of-memory case is free RAM, which is where all the interesting stuff happens – not surprising, if you interpret “interesting” as “changing”, which by necessity has to happen mostly in RAM.

Let’s go into some ways to reduce RAM usage. As mentioned yesterday, C strings are often a major cause of RAM bloat. Here’s part of a simple sketch to report which one of five buttons have been pressed:

Screen shot 2011 05 22 at 21 34 00

Let’s assume that the checkButton() returns a value from 1 to 5 when a button press has been detected, and 0 otherwise. The problem? We’ve just used about 150 bytes of RAM…

Given how simple and regular this example is, here’s an easy way to improve on it:

Screen shot 2011 05 22 at 21 34 45

Total RAM usage will drop to just over 50 bytes.

Here’s another way to do it:

Screen shot 2011 05 22 at 21 42 43

This one uses 42 bytes for the data, and 26 bytes for the remaining two strings, i.e. total 68 bytes. I’ve included this example because it illustrates a more data-driven approach, but it leads to some waste because the colors array requires a fixed amount of 6×7 character space.

Here’s a variation of that, which is more idiomatic in C:

Screen shot 2011 05 22 at 21 46 14

It differs in a subtle but important detail: the array is now an array of pointers to string constants.

Estimating RAM use is slightly more involved: 1+4+6+5+7+7 bytes for the strings (including the zero byte at the end of each one) = 30 bytes, PLUS 12 bytes for the pointer array (6 pointers, each 2 bytes). That’s still 42 bytes, so no gain compared to the previous fixed-size array.

Using standard C/C++, that’s about all you can do. And it still wastes some 40..70 bytes of RAM. This may not sound like much, but keep in mind that the same will happen everywhere you use a string in your code. C strings are painfully awkward for tiny embedded MPU’s such as the ATmega and ATtiny series.

Fortunately, there is one more trick at our disposal, which removes the need for RAM altogether …

The trick is to place these strings in flash memory, alongside the code, and extract the characters of the string whenever we need them. It’s a great trick, but it will affect our sketch everywhere, unfortunately.

First of all, we need to include this line at the top of our sketch:

    #include <avr/pgmspace.h>

This header file gives access to a number of preprocessor macros and functions, needed to define strings in the proper way, and to read the character data from flash memory at run time.

The reason for this added complexity, is that flash memory isn’t simply an “address” you can read out. The AVR family uses two separate address spaces for code and data. This is called a Harvard architecture. As far as pointers go in C, there is no access to data in flash memory. Well – there is, because function pointers in C automatically refer to code in flash memory, but there is no way to mix these: data pointers cannot access flash, and function pointers cannot refer to RAM.

Back to the task at hand. We need a small utility function which can print a string located in flash ROM memory:

    void showString (PGM_P s) {
        char c;
        while ((c = pgm_read_byte(s++)) != 0)
            Serial.print(c);
    }

Note that the argument is not a const char*, but a PGM_P (defined in the pgmspace.h include file).

Now let’s redo the code with this ROM-based approach:

Screen shot 2011 05 22 at 22 16 10

The result? No RAM is used up by any of these strings, yippie!

The price to pay is a slightly larger compiled sketch, and more importantly: we have to use that “PSTR(…)” notation with each of the strings to make it all work.

This technique is not invasive, i.e. you don’t have to choose between RAM-based and ROM-based C strings for the entire sketch. It’s probably easier to only do this in those parts of your sketch which use lots of strings.

ATmega memory use

In AVR, Software on May 22, 2011 at 00:01

Sometimes, it’s useful to find out how much memory a sketch uses.

Sometimes, it’s essential do so, i.e. when you’re reaching the limit. Because strange and totally unpredictable things happen once you run out of memory.

Running out of flash memory for the code is easy to avoid, as the Arduino IDE will tell you exactly how much is being used after each compile / upload:

Running out of EEPROM memory is harder, but usually not an issue, since very few sketches use substantial amounts of EEPROM, if any.

Running out of RAM space is the nasty one. Because it can happen at any time, not necessarily at startup, and not even predictably because interrupt routines can trigger the problem.

There are three areas in RAM:

  • static data, i.e. global variables and arrays … and strings !
  • the “heap”, which gets used if you call malloc() and free()
  • the “stack”, which is what gets consumed as one function calls another

The heap grows up, and is used in a fairly unpredictable manner. If you release areas, then they will lead to unused gaps in the heap, which get re-used by new calls to malloc() if the requested block fits in those gaps.

At any point in time, there is a highest point in RAM occupied by the heap. This value can be found in a system variable called __brkval.

The stack is located at the end of RAM, and expands and contracts down towards the heap area. Stack space gets allocated and released as needed by functions calling other functions. That’s where local variables get stored.

The trick is to keep RAM usage low, because it’s a scarce resource: an ATmega has a mere 2048 bytes of RAM.

Here’s a small utility function which determines how much RAM is currently unused:

int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

And here’s a sketch using that code:

void setup () {
    Serial.begin(57600);
    Serial.println("\n[memCheck]");
    Serial.println(freeRam());
}

void loop () {}

The result will be:

[memCheck]
1846

Ok, so we have about 1.8 Kb free in a tiny sketch which does almost nothing. More precisely: a basic sketch uses 2048 – 1846 = 202 bytes for internal bookkeeping and stuff (128 bytes of which are needed for the hardware serial input buffer, BTW).

When that value drops to 0, your sketch will crash. This might show as an endless loop, strange calculations or output, or constant restarts. Don’t expect a nice error message!

Let’s make a tiny change:

Serial.println("\n[memCheck2]");

Output:

[memCheck2]
1844

Huh?

The first part of the explanation is that all C strings are also stored in RAM! This explains why adding a single character to the string reduced available memory.

The second part of the explanation, is that flash memory is organized in words. Therefore, sometimes when you expect a single-byte effect, this may get rounded up due to the way things are stored in flash memory.

And the third part of the explanation, is that all C strings also get stored in flash memory. The reason is that RAM contents is undefined on power-up, so one of the tasks performed by the C runtime startup code, is to copy all the strings from flash to RAM memory.

Moral of the story: be very careful when doing things with strings on an ATmega, because you may find that you quickly run out of memory space. Adding lots of verbose debugging print statements might cause more problems than you think!

Update – Here’s a great AVR RAM memory overview:

(from the avr-libc website)

Still running on LiPo

In Hardware on May 21, 2011 at 00:01

A while back, a post on this weblog described a simple setup I had running to see how long the radioBlip.pde sketch would keep running on a single LiPo battery.

Here’s the setup again:

That’s a 1300 mAh battery, and the test sketch on it sends out an incrementing counter approximately once a minute (I extended the counter to 4 bytes, instead of the 2 bytes used in the original sketch).

It’s still going strong, i.e. this sketch has been running for 9 months on a single battery charge so far.

The counter is now at about 350,000 and I’ve determined that packets actually go out every 64 seconds, so that puts the counter at about 260 days. There’s a gap there, because the node was once reset some two weeks after being started for the first time.

So with some 275 days of running time, we can deduce that the average power consumption of this node has to be under (1300 * 1000) µAh / (275 * 24) h = 197 µA. This assumes that the battery would be empty, which it isn’t yet – so we know the average current must be lower (a lot lower, probably). Unfortunately, I didn’t include logic to measure and send out the LiPo voltage, which would be a good indicator of how far the LiPo battery actually is. The good news: a check with my multimeter shows the battery to still supply a whopping 3.985 V!

Anyway – I wouldn’t be surprised to get at least 4 times as much runtime, i.e. 3 years, out of this setup (which would translate to 50 µA average current draw).

Sooo… just hang around for another few years, and I’ll let you know!

C++ overloading with enums

In Software on May 20, 2011 at 00:01

A brief excursion into the land of advanced C++ tricks…

Create an enumTrick sketch with the following contents:

  #include "header.h"

  static int fun (One x) {
      return 10 + x;
  }

  static int fun (Two x) {
      return 20 + x;
  }

  void setup () {
      Serial.begin(57600);
      Serial.println("\n[enumTrick]");
      Serial.println(fun(A));
      Serial.println(fun(B));
      Serial.println(fun(C));
      Serial.println(fun(D));
      Serial.println(fun(E));
      Serial.println(fun(F));
  }

  void loop () {}

Now create a “header.h” file with the following contents:

  typedef enum { A, B, C } One;
  typedef enum { D, E, F } Two;

The stupid Arduino IDE pre-processing logic makes it necessary to place these definitions in a separate header file, unfortunately.

You can see that there are two definitions of fun (heh).

This code compiles without errors, because C++ supports “function overloading”, a mechanism to disambiguate function calls through the number and type of the arguments. In this case the args differ in type, being different enumeration constants.

Here’s the output:

  [enumTrick]
  10
  11
  12
  20
  21
  22

Note that if you were to call fun with an integer value, you’d get an error:

  enumTrick.cpp: In function 'void setup()':
  enumTrick:17: error: call of overloaded 'fun(int)' is ambiguous
  enumTrick.cpp:12: note: candidates are: int fun(One) <near match>
  enumTrick.cpp:13: note:                 int fun(Two) <near match>

Ok, so what’s the point?

Well, this provides a way to create a simpler API for drivers. Say we have a device which can turn the lights on and off, and dim the lights to a certain level (a Dimmer Plug, perhaps, or an X10 interface). We could do this:

typedef enum { ON, OFF } CmdSet1;
typedef enum { DIM } CmdSet2;

void DeviceControl (CmdSet1 cmd) { ... }
void DeviceControl (CmdSet2 cmd, byte level) { ... }

Now the only valid calls are those where ON or OFF is specified and nothing else, or DIM is specified and a single byte value is required. Every other mix generates an error at compile time. And there’s a single “DeviceControl” function you need to deal with and remember.

It’s definitely a contrived example, but I’m currently digging into some stuff which could probably benefit from this. Basically, you get static typing to help simplify more cases at compile time, which I expect will lead to more compact code.

Which – on a low-end 8-bit MPU – can be a big deal!

LiPo bulge

In Hardware on May 19, 2011 at 00:01

Speaking of Lithium Polymer batteries…

Last week, I was working on the (2007-vintage?) MacBook Pro now used by my wife Liesbeth, who uses it every day as desktop machine with an external keyboard and mouse hooked up all the time. Then I noticed that for some reason, the built-in trackpad had stopped working…

Here’s what happened:

Dsc 2524

The battery pack had bulged to almost twice its normal thickness. Here’s a good battery pack for comparison:

Dsc 2523

Sure enough, that bulge pressed up very hard against the mouse pad. I’m surprised it didn’t bend or damage anything else in the laptop! Removing it made the trackpad work again, BTW.

These battery packs are quite large and can store a serious amount of energy:

Dsc 2528

Ok, now since that pack is hosed anyway, I decided to take it apart. Which wasn’t relly hard, considering how much of the innards were already exposed:

Dsc 2525

After prying off the aluminum cover, which was glued on, this came out:

Dsc 2526

You can see the battery protection / charge circuits, and what appear to be three sets of LiPo batteries in a sturdy plastic pouch. And the middle one sure doesn’t look right:

Dsc 2527

I’ve stopped there, afraid to open up the battery and expose the Lithium to air, which as far as I understand could cause it to spontaneously catch fire. Well, that’s what Sodium (Na) does, anyway.

Given that the battery was produced 5 years ago and has given me several years of good service, I don’t really mind. Just need to get rid of this chemical waste in the proper manner.

Or did I narrowly escape a major disaster?

Self-powered Opti-rebooter

In AVR, Hardware on May 18, 2011 at 00:01

After yesterday’s post about switching to OptiBoot, I decided to go one step further and go for a self-powered solution, a bit like this unit which has been serving me well for many months now.

So here’s the “Opti-rebooter” with a 400 mAh LiPo backpack:

Dsc 2521

Hookup is trivial, given that the JeeNode USB has an on-board LiPo charger. I picked a battery which matches the width of the board and fits quite well:

Dsc 2522

The two connectiosn of the LiPo battery are wrapped up in heat-shrink tubing to prevent accidental short circuits – the currents involved could easily cause trouble. Note that this is a “raw” LiPo cell, without any protection circuitry. That’s fine in this case, because the on-board circuitry takes care of charging.

To make this complete, the isp_repair.pde was extended to completely power down when done. So there’s no need for an on-off switch, the idle consumption is probably lower than the battery’s own self-discharge rate. And it blinks the on-board led twice: once on power up and once when properly programmed. Very convenient!

The way to use this thing, is: connect to a target JeeNode / JeeLink / Arduino, press the RESET button, wait three seconds, disconnect, done.

I also made changes to the very similar but slightly more elaborate isp_prepare.pde sketch, which was presented in this weblog post.

The updated isp_prepare.pde sketch supports a number of variations. These can be configured by adjusting a few values at the start of the sketch:

Screen Shot 2011 05 16 at 15.00.32

You can choose which type of boot loader to install, which sketch to load initially (just to start off, this can be overwritten later), and there’s a third option to adjust some “fuse bits” in the ATmega to select how fast the ATmega can start up after resuming from a power down.

That third option is particularly useful with battery-powered JeeNodes using the RF12 driver. With USE_FAST_WAKEUP set to 1, the power-up sequence is fast enough for an ATmega to wake up when the first data byte is received. This means you can completely power down the ATmega (while leaving the receiver running), and it’ll still be able to pick up incoming packets and respond to them. There is one gotcha: USE_FAST_WAKEUP can only be set to 1 on units running with a resonator – JeeLinks and Arduino’s running with a crystal must be not use the fast wakeup mechanism, as the clock may not start up properly in this case.

Haven’t tried it though – for now, that LiPo powered unit shown above is really the most convenient way for me to upgrade all the JeeNodes, JeeLinks, and Arduino’s floating around the house at JeeLabs.

Switching to OptiBoot

In AVR, Hardware on May 17, 2011 at 00:01

Now that some of the JeeNode/JeeLink boards from JeeLabs come pre-loaded with the OptiBoot boot loader, it’s time to start thinking about switching everything over. Having to constantly switch the Arduino IDE between “Arduino Uno” (OptiBoot) and “Arduino Duemilanove w/ 328” (original 2009 boot) is quickly going to become very tiresome …

See this weblog post for a quick summary of what all this uploading and boot loader stuff is about, and why you should care. In a nutshell: you need a boot loader on the ATmega to save sketches onto it via FTDI and USB.

There’s a nasty detail, though: to upload sketches you need a boot loader, but how does that boot loader end up on the ATmega in the first place? The good news is that this is usually done in the factory, well, ehm… at JeeLabs, in my case. The good thing is, it’s all taken care of, and the boot loader doesn’t normally get damaged or need to be replaced. It just works.

Except when the boot loader itself needs to be changed, as in the case of OptiBoot. Note that it’s quite worthwhile to switch to OptiBoot: the uploads are twice as fast, and you get 1.5 Kb of extra memory for your own sketches.

So how do you go about updating the boot loader on a JeeNode when you don’t have a special hardware tool called an “ISP Programmer”?

Fortunately, there is a simple trick to do this using a second JeeNode (or Arduino). I’ve written about this in a previous post. There’s an isp_repair.pde sketch in the Ports library which does everything (it emulates an ISP programmer, basically).

I’ve just updated the isp_repair.pde sketch to use OptiBoot.

Here’s the setup to upgrade a target JeeNode to OptiBoot using another JeeNode:

Six wires need to be connected as follows:

And then it’s a matter of attaching the target to the programming JeeNode, and then powering up the whole assembly.

If you happen to have the serial port connected to the programming JeeNode, you’ll see this info:

Screen Shot 2011 05 16 at 17.08.48

I made a permanent setup using a JeeNode USB, because I’ve got a pile of JeeNodes to reprogram here at JeeLabs:

Dsc 2518

The connector was constructed from a 2×4 header, with the pins bent in such a way that the whole thing stays in place when pressed into the 2×4 holes of the SPI/ISP header. And then the whole thing was sealed off with a few pieces of heat-shrink tubing:

Dsc 2519

To program a board (in this case another JeeNode USB), just power it all up and wait 3 seconds:

Dsc 2520

That’s it – you could call this an “opti-rebooter” :)

JeeLink v3 w/ OptiBoot

In AVR, Hardware on May 16, 2011 at 00:01

Small changes. Previous, i.e. v2:

Dsc 2515

And here’s the new JeeLink v3:

Dsc 2516

The changes are mostly cosmetic and include a number of changes to simplify the assembly process. Some minor but oh so important tweaks to more accurately fit it in the case:

Dsc 2517

See those four tiny notches line up? Phew!

Two changes which will be more important for everyone using these:

  • The JeeLink v3 comes with the OptiBoot loader pre-installed, i.e. you need to select the “Arduino Uno” as board type when uploading sketches to it.

  • The on-board DataFlash memory has been increased to 16 Mbit. This fast SPI-connected permanent memory makes it possible to use a JeeLink for collecting even more data when the PC is off (but power has to remain, evidently). The RF12demo sketch has a FLASH_MBIT constant defined, it should be set to 16.

You can easily see which JeeLink you have by looking at the gold lettering on the back side.

Apart from that, nothing really changes. All JeeLinks sent out from now on will be this new v3 build.

Onwards!

RFM12B range testing

In Hardware on May 15, 2011 at 00:01

There have been many questions and discussions about the range achievable with the RFM12B wireless modules. Usually, my answers have been: 1) should be about 100m outside, and 2) gets through about two walls inside the house. But the most accurate answer really is a resounding “it depends” …

Because it really does. RF range will depend on a huge number of factors. What works for me may not work for you, and what works today may not work tomorrow.

Triggered by some recent discussions on the forum, and with the help of Steve Evans (@TankSlappa) who wrote a good set of sketches and did some tests, I’ve come up with two sketches and a setup to report reception quality.

This setup requires two RFM12B modules evidently, plus an LCD connected via the LCD Plug. I re-used one of my Mystery Boxes – one of so many projects here at JeeLabs waiting to get finished.

My sending unit is a JeeNode with an AA Power Board on the back. The rfRangeTX.pde transmitter sketch is very simple, and sends out 1-byte packets 10 times per second:

Screen Shot 2011 05 14 at 15.00.18

The receiver is based on a JeeNode USB with LCD and LiPo battery, so both units are portable / self-powered:

Dsc 2513

The code for the rfRangeRX.pde receiver sketch is too long to be shown in its entirety, but here’s an overview:

Screen Shot 2011 05 14 at 15.03.34

The display shows 4 fields:

  • top left = percentage of packets received in the last 5 seconds
  • top right = percentage of packets received in the last second
  • bottom left = sequence number of the last valid incoming packet
  • bottom right = history of last reception counts (10x 0.5s intervals)

Here, one packet was missed in the last second (98% is 1 out of 50, 90% is 1 out of 10):

Dsc 2509

And here, two packets were missed a few seconds ago:

Dsc 2511

Feel free to take these sketches as starting point for your own tests. You could do all sorts of funky range testing with this, from just seeing how much gets lost in a particular setup, to investigating the effect of different RFM12B baud rates, working in other bands, antenna optimization, identifying in house “cold spots”, and checking the effect of adding an extra pull-up resistor, as recently suggested here and here on the forum.

There are still quirks (i.e. bogus reports every 5s when no packets are coming in, due to byte wraparound).

Both sketches have been added to the RF12 library. There is probably a ton of neat stuff to add – please share your improvements and I’ll try to fold them in so others can use them too. By adding logic for two buttons (or a joystick as on the above RX unit), we could even configure the receiver in the field.

Many thanks to Steve E for coming up with the original idea and getting a first implementation going.

Crunch time

In Hardware on May 14, 2011 at 00:01

Ouch…

The new JeeNode v6 boards have run out. The initial batch has been flying out the door quite a bit faster than I anticipated. And it’s going to take another 10 days until new ones arrive, unfortunately.

My apologies for the delays this will cause.

Colorful GLCD

In Hardware on May 13, 2011 at 00:01

Whoops! The other day, one of the Graphics Boards here at JeeLabs fell on the floor:

Dsc 2505

Pretty, but not quite what it’s supposed to be :)

Fortunately, I still had a similar black display left over from the initial builds:

Dsc 2507

(ignore the info – node #3 is a radioBlip sketch, even though glcdNode interprets it as a room node)

Sooo… don’t drop the GLCD, it’s brittle! Unless you prefer that first display, of course :)

Assessing the damage

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

Yesterday’s post was about wearing out the EEPROM memory on an ATmega168. It took over 6.7 million writes to address zero to make it fail. As mentioned, this is a limited test, because reading out the value was done right after writing it. But hey, at least I didn’t have to write 100,000 times to each EEPROM address and wait 20 years @ 85°C to find out whether each byte was still correct…

So we got a failure, now what?

Well, re-running the test caused it to fail after a mere 6,200 write cycles, so that EEPROM definitely isn’t up to spec anymore.

Today, I wanted to see what effect this single massive rewrite of address zero did to the rest of the EEPROM. So I wrote another test which would go through the entire EEPROM and see how well writes + read-backs would work on this same ATmega168 with its massively-abused EEPROM:

Screen Shot 2011 05 11 at 17.23.32

All failures are counted, per EEPROM address. Whenever the maximum number of failures at any single address increases, a map is printed with the counts for each of the 512 bytes. Here’s the startup situation – no errors yet:

Screen Shot 2011 05 11 at 17.23.10

The map counts are encoded as single characters:

 0         =  "."
 1 to 9    =  "1" .. "9"
10 to 35   =  "a" .. "z"
36 to 61   =  "A" .. "Z"
62 and up  =  "?"

Every 100 cycles, the cycle count is printed, just to let me know that the sketch is still running. Unfortunately, re-writing all 512 bytes in EEPROM is way slower than yesterday’s test, over 1 second per cycle. So I also added an LED to toggle on each cycle:

Dsc 2503

Now the waiting begins… it’s going to take hours (maybe even days!) to force the next failure again.

And one thing is clear: it’s not easy to get these chips to fail quickly!

Update – 100,000 cycles later, no new failure yet…

Destruction!

In AVR, Hardware on May 11, 2011 at 00:01

No, not distractions

Had a ATmega168 chip lying around which isn’t going to be used anymore anyway, so why not do some destructive testing on it, eh?

There have been a couple of such tests floating around on the web, so I thought I’d try to replicate them – to try and find out how many read-write cycles the internal ATmega’s EEPROM can sustain. I started from the info on John Boxall’s weblog, and set up a similar configuration, but based on a JeeNode:

Dsc 2497

Note that this isn’t using the LCD Plug, but has direct connections to 6 digital output pins (I used the same pins as in the original sketch: digital 4..9).

Made a simpler sketch to just toggle bits in the EEPROM and display the counter (the display is fast when there’s no I2C expander chip involved):

Screen Shot 2011 05 10 at 18.46.38

It turns out that flipping all the bits in the EEPROM takes a few seconds, and with an expected lifetime well over 100,000 that test would have lasted several days. So instead, I rigged the test to only flip byte 0 in the EEPROM. Let’s see how much beating that single byte can take!

Several hours later…

Dsc 2499

Over 3,260,000 write cycles and still going.

Note that this is only testing EEPROM address 0x000, and that the check is right after the write, so this is not necessarily a very useful test: bad bytes might hold charge, but not for over 20 years as listed in the specs, and some other address might give an error much sooner.

But still… 32x above spec so far. Not bad!

Update – The ATmega168 finally broke down:

Dsc 2502

Then it failed 6200 cycles after the next power-on.

Distractions

In Hardware, Software on May 10, 2011 at 00:01

Sorry, no serious weblog post this time. I’ve been distracted by an iPad which got delivered here today.

Couldn’t resist trying out some stuff…

Portrait

Here’s one in landscape mode:

Landscape

(both screen shots were created via the simulator, but the real thing looks exactly the same)

It’s obviously just a web browser. It’s also totally obvious to me now that touch screens are a natural fit for this sort of stuff. Goodbye double-click, hello swipe and pinch.

Pretty amazing how long we’ve done without ’em!

Another power option

In Hardware on May 9, 2011 at 00:01

Here’s a nice little power supply:

Dsc 2137

It’s one of many LED drivers currently available on the market.

These supplies are designed to provide a fixed current – not voltage. What this means is that if you “overload” them, then they will regulate the voltage down to the point where the current reaches a preset value (700 mA in this case).

In itself, this isn’t really useful for powering anything but power LEDs, but this unit also specifies that as long as the load remains under 650 mA, it will supply a fixed voltage of about 6V. So the other way to interpret these specs, is to see this as a 6V power supply with automatic current limiting to 700 mA.

This means that if we add the optional diode to a JeeNode v5 or v6, then the voltage would be just right to power one or more 5V relays.

The nice thing about these units is that they are fully “potted”, i.e. encased with proper high-voltage isolation.

This might offer a practical way to set up mains-powered JeeNodes, with perhaps a Relay Plug to switch simple AC loads, or a triac for switching / dimming incandescent lights. Another option would be to use a MOSFET to switch 1..3W power LEDs.

PS. Unfortunately, I don’t remember where I got this particular unit (yeah, I know – I feel pretty stupid!)

Web hooks and feeds

In Software on May 8, 2011 at 00:01

I’m starting to look into hooking stuff together via TCP/IP on the PC/Mac host side of things.

One approach is to use Web Hooks. The idea is that the sender initiates a simple HTTP GET or POST request to some web browser, with all the information contained in the URL and/or query arguments.

In JeeRev, I decided to try it out by adding a webfeed feature and a webhook feature.

The webfeed mechanism is absolutely trivial: make a web request to a URL with the name of the parameter and the value of the parameter at the end, and add any other info you want as query args:

http://127.0.0.1:8181/webfeed/abc-def/12345?unit=mV&scale=2

This creates a new reading for parameter “abc-def” with value “123.45” (I used the scaling mechanism in this example, but direct input of “123.45” would have worked too).

That means any process with access to the webserver running in JeeRev can feed values into the system.

The reverse is the webhook: each time one of a specific set of parameters changes, a web request is made to a configurable URL, with the parameter name, its value, and such filled in automatically.

Here’s an example feed to the ThingSpeak web service:

Screen Shot 2011 05 07 at 17.03.54

(hmmm, looks like ThingSpeak only presents information on an hourly basis)

There’s no coding involved with either of these features in JeeRev, it’s all defined in a local config file.

Trivial. There really are tons of ways to do this collecting / storing / graphing stuff, and you can find lots of sites doing similar things all over the web these days. The Pachube website has been around for some time and appears to be used a lot.

To be honest, I would think twice before handing over my home monitoring and automation info to a public website. Sure, it might look cool to show everyone what you’re doing at home, and what you’ve automated – but it’s a privacy risk I can do without. I don’t intend to create a public site for JeeLabs sensor access and control. That’s the whole point of JeeRev: low cost hardware, running a local monitoring and control system, with optional outside access via secure channels, i.e. a password-protected SSL connection. The technology is open, but not our data (not even energy info: I’m more interested in optimizing than in making a statement).

The way I see these web hook/feed mechanisms, is not to create a world wide web of things, but as a way to tie different software systems together within the confinements and privacy of the home. Every device, app, and language has web technologies built-in these days, so it’s only natural to use them as exchange mechanism.

But I’ll leave the “look ma, my front door is open” sensor reports to others ;)

Update – the ThingSpeak web site service does support private channels and more fine-grained access, see the comments below.

RF12 skeleton sketch

In Software on May 7, 2011 at 00:01

The RF12 library has all the code to drive an RFM12B wireless module, and supports full interrupt-drive sending and receiving of arbitrary packets up to 66 bytes in length.

Interrupt drivers are fiendishly hard to debug and get 100% right, but often well worth the effort. The result is code which behaves almost as if it’s running in the background, i.e. it makes the ATmega appear to support multi-tasking, with all I/O happening all by itself.

In the case of the RFM12B, this is quite important, because there are some very strict timing requirements as to how and when to exchange data with the hardware. Once a driver is interrupt-driven, the rest of the code doesn’t have to be as strict – all critical timing requirements are dealt with, even if you don’t poll the driver regularly.

But the logic of all this stuff can be a bit overwhelming at first. So, to help out, and prompted by a recent discussion on the forum, I’ve set up an example of how to write a sketch which can read and send packets:

#include <Ports.h>
#include <RF12.h>

MilliTimer sendTimer;
typedef struct { ... } Payload;
Payload inData, outData;
byte pendingOutput;

void setup () {
    ...
    // call rf12_initialize() or rf12_config()
}

static void consumeInData () {
    ...
}

static byte produceOutData () {
    ...
    return 1;
}

void loop () {
    if (rf12_recvDone() && rf12_crc == 0 && rf12_len == sizeof inData) {
        memcpy(&inData, (byte*) rf12_data, sizeof inData);
        // optional: rf12_recvDone(); // re-enable reception right away
        consumeInData();
    }

    if (sendTimer.poll(100))
        pendingOutput = produceOutData();

    if (pendingOutput && rf12_canSend()) {
        rf12_sendStart(0, &outData, sizeof outData, 2);
        // optional: rf12_sendWait(2); // wait for send to finish
        pendingOutput = 0;
    }
}

You’ll need to do a few things to get this going, which are all common sense really:

  • define a proper struct for the Payload contents you want to send/receive
  • set up the RF12 driver with the proper configuration settings
  • fill in the code to handle incoming data in inData
  • fill in the code to save new outgoing data to outData

This sketch will also work with an RFM12B Board and an Arduino.

One crucial detail is that you can’t just send data whenever you feel like it – you have to throttle the outgoing sends a bit using sendTimer , and you have to ask the RF12 driver for permission to send using rf12_canSend(). Failure to do this will “mess up the air waves” and severely interfere with RF communication between any nodes, even those that play nice.

To write a sketch which only sends, leave consumeInData() empty – don’t throw out the first “if”, because those rf12_recvDone() calls are still essential.

To write a sketch which only receives, simply make produceOutData() return 0. Removing the last two if’s is also ok, in this case.

Once you have your sketch working, you can start adding tricks to reduce power consumption: turning the RFM12B on and off, running at lower clock speeds, putting the ATmega into a low-power sleep state, etc.

Inside the USB supply

In Hardware on May 6, 2011 at 00:01

The USB power adapter is a nice little unit pumping out 5V:

Dsc 2461

It’s no doubt intended mostly as charger for USB devices, but with a 1A output current, it can actually power lots of things, including JeeLinks and JeeNodes.

I was curious as to what’s inside this CE-approved device, so I took one apart:

Dsc 2472

A chip, a bridge rectifier, lots of electrolytic capacitors (with limited lifetimes if things get hot), an isolation transformer of some kind, some inductors, and a USB jack:

Dsc 2473

The 400V rating on the 4.7 µF caps sounds a bit far-fetched, though.

The bottom side shows an interesting mix of SMD components and solder joints:

Dsc 2474

I haven’t looked into the circuit itself yet. I can’t help but wonder whether a 50mA supply couldn’t be done with fewer components.

Oh well. This unit works, is certified, comes from an official local wholesale supplier, and nothing I can come up with could be made for less.

JeeRev pre-release

In Software on May 5, 2011 at 00:01

As mentioned in an earlier post, I’ve been working on a new open source software design lately:

Jeerev

Best way to introduce it is perhaps to just copy this blurb from its home page:

Physical Computing projects usually involve several components: the hardware, the firmware for it, and code running on a PC, Mac, or Linux box. I’m tired of having to manually plug in / unplug devices all the time, start compiles, upload code, launch apps, and go through the same edit-build-launch-debug-quit cycle over and over again. It’s all so brittle, repetitive, and at the same time so hard to automate to the point where you can leave a non-trivial setup running unattended once it works. There has to be a better way. JeeRev is about growing and evolving such systems more organically.

You could call it “JeeMon, Reloaded” – but that’s not 100% accurate, because JeeRev is built on top of the existing JeeMon core. And in the grand scheme of things it’s in fact only half of the way w.r.t. where I’d like to go: JeeRev is an application framework to help build a new “environmental monitoring and home automation” system.

JeeRev 0.9 is a pre-release in the sense that I’m still just tipping my toes in the water of all this physical-computing-with-monitoring-and-automation stuff. But the path forward is getting clearer all the time, and many of the choices so far are starting to settle and work out nicely.

JeeRev aims to be as light as a butterfly, as flexible as a bamboo twig, as distributed as the wind, and a open as source code can be. You are welcome to participate in this project – in any form, at any time: at last count, there were some 2,718,281 fascinating avenues still waiting to be explored ;)

I don’t intend to flood this weblog with posts about JeeRev, but as with the hardware side of things I do hope to report advances once in a while, when they lead to practical uses for Physical Computing.

Because magic is fun, and magic is what happens when you bring together the worlds of atoms and bits!

Meet the JeeNode SMD

In Hardware on May 4, 2011 at 00:01

After yesterday’s change of name, I’m pleased to announce a brand new member of the ever-expanding JeeNode family, the JeeNode SMD (aka NS1).

It’s a pre-assembled unit with SMD parts, and just some 6-pin headers you have to solder on yourself. Here’s a hand-soldered test unit with the port headers mounted sideways:

Dsc 2493

Here’s that same unit, seen from the bottom:

Dsc 2494

Sideways mounting adds a new option for using plugs, because this unit is flat enough to use upside down:

Dsc 2495

(Note: oops, that BUB needs to be flipped around!)

You don’t have to do it this way, and can of course just choose to mount the headers in the normal vertical orientation.

The main differences with the standard JeeNode Kit are:

  • on-board activity LED (same as JeeLink and JeeNode USB)
  • on-board reset button
  • pads for A6/A7 analog in, and the AREF pin
  • much flatter, fits in more places than the trough-hole kit
  • less soldering, just a few headers (so you get to choose their orientation)

Still the same as a JeeNode in most other respects, i.e. same size, same battery options, same FTDI connection to the outside world, and same RFM12B radio.

The Café page is here. Along with a page in the shop.

What’s in a name

In Hardware on May 3, 2011 at 00:01

The JeeSMD is getting a new name:

Jsx

JeeSMD is OUT, SMD Kit is IN!

Sknew

The new product link is http://jeelabs.org/sk1 (was “js2”). The SKU label and link on the PCB will be updated later, in the next batch of boards.

The new shop link is http://jeelabs.com/products/smd-kit (was “jeesmd”).

All in the name of progress…

Relays at last

In Hardware on May 2, 2011 at 00:01

It has taken months to settle this issue, but I’m happy to report that the supply problems are all over now… the Relay Plug board has been redesigned to accommodate a slightly different model:

Dsc 2488

Still fits, still same size. And still rated 5A @ 250 VAC.

The coil resistance is 125 Ω, which means each of the two relays will draw 40 mA @ 5V when closed. Slightly more than the previous model, but well with the specs of the on-board relay drivers.

The point of it all is that these new relays have a major distinguishing feature: I’ve got them in stock, at last :)

For the record: first an order for the original units was postponed from January to May, then a second order with another supplier was pushed back to June when they told me the stock listed on their website was grabbed by someone else moments before me…

All is well again now. End of story. Well… until the next supply issue pops up, anyway!

Meet the JeeNode v6

In Hardware on May 1, 2011 at 00:01

The JeeNode v5 addeth a diode, and the JeeNode v6 taketh it away again:

Dsc 2490

Here is the new board, which I’ve started including in the latest packages:

Dsc 2492

The differences with v5 are:

  • The diode jumper is now shorted out by default (cut a trace on bottom side to use a diode).
  • There is a new ground connection near the antenna connection.
  • The PD2 (INT0) and PB2 (SS) pins are now connected to pads (same layout as on JS2).
  • Minor tweaks, such as labeling fixes.

Nothing big or serious, as you can see – I’ll gradually update various bits and pieces on the web to match this revision. For now, please just continue using the links and build instructions of the v5.

(Apologies for the long hiatus, but I needed the break!)

Software evolution

In Software on Mar 17, 2011 at 00:01

With all the focus on sensors and embedded hardware, I’ve lost track a bit of the other side of the equation – monitoring all that incoming data, and (later on) using it to control devices. The receiving end – i.e. software running on a central PC (or embedded Linux box) has not kept up with the rest of the Jee world.

One reason was that my setup for collecting sensor data around the house has been running quite smoothly. Producing these graphs, updatable via a browser refresh:

See this, this, and this post for more details about how it was done. The JeeMon 2009 setup has been running almost non-stop on a low-power NAS, called the Bubba II (now replaced by newer models). There were only about half a dozen system restarts in these past two years, some due to power outages, some due to devices needing a reset, but that’s about it.

Trouble is… all development on this has stagnated. I did start on a JeeMon 2010 successor, but that has only been used for newer projects, such as the ookScope. In the end, I didn’t really want to disrupt my working data-collection setup and just kept the old one going. So now I’ve got two years worth of detailed logging and a local web site which is showing its age and not very useful for meeting my new requirements – let alone being able to perform more meaningful stats and controlling devices for home automation.

Last summer a student project was started at the nearby Utrecht University to try and come up with a general infrastructure which would be able to do a lot more than what I had. The result is a new system called “JeeBus” (more details coming soon on this weblog).

While JeeBus does provide a fair set of interesting features, one of the issues that kept bothering me is that normally in software development you have to either run the code or make changes to it. The “conventional” operation mode is to stop the server, edit the code, and then restart it to pick up the changes. With a bit of luck, there may be the option to re-install certain parts – but usually this is limited to “drivers” and “extensions”.

I find this stifling. Having to restart an app just to try out a one-line change is much more disruptive during active development than such a simple stop/re-start would suggest, because each time you also have to get the process back to the state you were working on. And with dynamic scripting languages, it’s a bit silly to have to jump through such hoops – which really stem from the edit-compile-run cycle of statically-bound environments, decades ago.

So I’ve started scratching my itch, and implemented a small core “hub” which starts up functionally empty with just enough capability to accept remote procedure calls (RPC‘s) and to inject plugins into a (local or remote) running process. The last version of each plugin is saved and is automatically loaded again after a restart. The result is a JeeMon process which starts off as a blank slate and evolves into a full-fledged app – web server, gui, hardware interface, background task, anything.

So far, development in a “live” process looks promising. There are less and less situations where I need to restart. I’ve set up a little tool to push all changed plugins to a remote hub, and that really completely changes the landscape of software development for me. No need to take down a real-time system anymore, which is what most of all this is about when it comes to physical computing and devices. Bugs generate stack traces, but the hub continues to function, so re-installing a fix usually solves the problem. And changing code in a working system has never been easier. This matters a lot, because I really really want to be able to “grow” a system over time.

Starting and stopping a process which is designed to run non-stop is odd. Let’s see if this new design will make it unnecessary in most cases – during active development as well as for tweaking a working setup at a later date.

Gas flow measurement artifacts

In Hardware on Mar 14, 2011 at 00:01

The raw gas consumption graph always looks a bit odd:

Screen Shot 2011 03 13 at 12.59.45

Green is gas flow, red is electricity consumption.

This is the same oddity I described two years ago on this weblog. The values are calculated from the last rotation time of the meter, but with gas flow things are a bit different: gas consumption is not continuous but a discrete on/off process, with some “modulation” once on.

So instead of each of those “tapering off” effects, what really happens is that the flow stops completely for a while and then resumes again later on.

This is an example of where the measurements need to be “fixed” (!), by injecting fake data points. It also illustrates how you can’t really know anything about consumption between disk rotation pulses.

The vertical grid lines in the above graph are spaced 500 l/h (resp. 500 W) apart, btw.

Power consumption

In Software on Mar 12, 2011 at 00:01

I’ve been working on some new software to better handle all the messages flying around the house. Took down the old system, and started collecting stuff with the new framework.

First one that always interests me, is the baseline power consumption. So I grabbed some values from last night:

Power 11 03 2011

That’s about 450 watts when all the lights are out and nothing is happening – shocking!

Uh, oh – 4000 kWh of vampire power on a yearly basis. Either my new calculations are way off, or some serious stuff has crept in here at Jee Labs which is drawing lots of power!

Update – Yeah, I was off by a factor of 4 in the low range. Forgot that I had added some fancy bit packing to get more resolution across in the metering sketch:

Screen Shot 2011 03 12 at 11.58.23

The lows are around 110 W. With the 24h “internet presence” (server + router + fiber modem) taking an estimated 30 W. Now that makes sense again!

New USB-BUB II

In Hardware on Mar 8, 2011 at 00:01

There’s a brand-new “Modern Device” out, the BUB II !

Screen Shot 2011 03 07 at 22.21.15

Lots of options, also on the back (sorry for the color difference: pictures were taken in different contexts):

Dsc 2478

I’ve been waiting for some time for this one, since the old BUBs ran out quite abruptly not so long ago…

The important thing to note is that the BUB II is compatible with JeeNodes out of the box. No jumpers, no settings to tweak, nothing. Just solder in the header and you’re all set.

And of course, most importantly…

Dsc 2477

It’s now the same blue-and-gold as all the other boards at JeeLabs, and it even has exactly the same width as a JeeNode. One more step towards world-21.1mm-wide domination :)

I’ll update the shop shortly, all new BUBs are now sent out as this BUB II.

New USB power option

In Hardware on Mar 2, 2011 at 00:01

Ah, I’ve finally found a nice little CE-certified power supply for USB:

Micro usb

Extremely small (i.e. easy to ship), and very efficient. This thing will provide up to 1000 mA at a stable 5V level. Perfect for JeeLinks, JeeNode USB’s, and Arduino’s – or any other USB devices for that matter:

Dsc 2461

The power consumption when idle is a mere 0.20 watt, i.e. less than 1 mA of mains current. When plugging in a JeeLink, this increases to 0.32 watt, which is pretty phenomenal actually: the difference is 120 mW @ 5V = 24 mA, just about exactly what the JeeLink consumes with an ATmega running full-power and the RFM12B in receive mode.

I’ve added it to the shop and also added it as option to replace the AA board in the JeeNode Experimenter’s Pack in case you’d rather run off mains power.

Something needs to change

In Musings on Feb 27, 2011 at 00:01

The previous post was about explaining which walls I have been hitting. Many thanks for your comments on that!

The task ahead is to move on! This must not become a blog about my ability to function (or not) in the context of JeeLabs. I’ve been doing a lot of thinking, and talking to people around here.

There’s a pattern. It goes as follows: I start on a big new challenge. Push really hard, get totally in the flow, and get lots of things done. This can last for days, or in the case of JeeLabs: several years. Until, gradually, other mechanisms start taking over, governed by obligations and expectations, essentially.

The reason this has worked so well with JeeLabs, is that the weblog was simply a report of what was happening anyway. A diary. Easy to do, and useful for me as well, to go back and review what I did. The shop just gave it more direction: making stuff happen was already a given, so making stuff which others can use as well was really just “low hanging fruit”. Easy to include, and very helpful to stay focused.

I think that over these past two years, I’ve unconsciously moved deeper and deeper into this pipeline. From doing it all as challenge and exploration, came the desire to describe it all more and more on the weblog. And from there it all evolved into making sure an increasing portion of this would end up as products in the shop.

It’s not quite the Peter Principle, but in a way, I’ve gradually drifted away from what this was all about: exploration, learning, and yes, also sharing. That’s why I started JeeLabs, and that’s what I want to continue doing with JeeLabs as much as ever.

I came across some interesting articles these past few days. Seth Godin talks about business needing to be of the right size. In my case, that means: sustainable. No more. No less. I’m confident that I can figure this one out.

Paul Graham talks about Maker’s vs. Manager’s schedules. Real life has a way of interfering with makers. Tinkering requires concentration, for all but the most trivial and obvious projects. This would explain exactly what happened here – as I kept ahead of the curve with weblog posts and shop items, all was well. I was in the flow and tinkering all day in the fascinating and endless world of physical computing. The emphasis was on the right stuff, and the rest followed effortlessly. Really. The weblog was oodles of fun, even with a daily post, and so was the shop, which is filled with interesting and new experiences about the world of atoms, production, and fulfillment.

I don’t want to list the projects here which I have already started up or new ones I would love to go into. It’s all fun, except that even just thinking about listing them drives home the fact that they are all out of reach for me!

Got to track inventories, order stuff, find second sources, juggle the cash flow, get stuff assembled and tested, deal with back-orders and new orders, handle sales / tech support emails, and more. Welcome to doing business, eh?

I’ll share a secret with you: I liked so much doing the daily weblog when it went well, that I’ve been pondering for the last week about how to resume this weblog on a daily basis. Conclusion, alas: it can’t be done. I need to be on a maker’s schedule again, to use Paul Graham’s terms. And both the weblog and the shop make that impossible.

Something needs to change.

No more daily weblog. Maybe after the summer, if I can get ahead of the curve again. Instead, I’d like to do a couple of regular columns – such as the Easy Electrons series, which I really want to keep going. Maybe a second series, but no promises yet. And posts on an irregular basis, when there is something substantial to report. I’m not going to water down the posts and write about trivialities. Nor am I going to just report about what others do elsewhere. You’ve got the same access to internet as I do. The JeeLabs weblog will remain about original content. For noise and fluff, I’m sure you have plenty of choices elsewhere.

The webshop is currently not in optimal shape. Too many out-of stock cases popping up all the time. I’m solving this by scaling up. Getting components by the thousands where needed, and getting products assembled by the hundreds where possible. I’m also going to do something painful: raise prices. I’m serious about JeeLabs. It is going to stay, and it needs to be run in a serious, sustainable manner. I can pour in my time and energy. But the figures have to add up, in a way which matches the scale at which JeeLabs operates. There are some economies of scale, but obviously not in the way DigiKey or Apple can operate :)

The shortages won’t go away overnight. I ordered 500 relays in January. Expected a first batch end of that month, only to be told a week ago that it was “pushed back” to the end of April. I came across a second source, so hopefully mid March I can provide relays anyway. ATmega shortages are over. Same for several other important items. I’ve got outstanding orders and agreements for hundreds of units for just about all items. I understand the risks and I’m learning the ropes. I just need to get better at it so it won’t take so much of my time in the long run.

Because in the end, JeeLabs is all about exploring and inventing. And, once those are back in the picture, sharing.

Onwards!

What’s going on

In News on Feb 21, 2011 at 00:01

If you’ve been following this weblog, then you may have noticed that things have been quiet around here…

There are a couple of reasons for this. The first one which triggered it all, was an unfortunate – but ordinary – flu, which swept me off my feet for a couple of days, and then sapped all my energy for a few more. I’m sorry about that, and I’m happy that this is all behind me now.

But there’s more to it than that.

In the beginning, I often had a queue of over a week of weblog posts pending and ready to go out on a daily basis. At that time, the weblog was working out exactly as planned: as a way to report on my adventures in the fascinating land of Physical Computing…

However, over 730 posts later, that buffer has been steadily decreasing, and I’ve often been forced to write a weblog post on the day before its publication. Sometimes this was ready only minutes before the deadline. No fun, and in the past month or two, this ended up happening more and more often. The reporting task became a recurring “what shall I write about today?” challenge. Somewhere along the way, the adventure got lost.

And finally, there’s the web shop, which has taken off much faster than I expected and anticipated. In a way, that’s good: a well-running shop means it provides funding for everything else – from keeping that shop going to being able to start new projects and work on fun stuff. Which is the point of JeeLabs after all.

Except… I’ve been swamped. It’s been a while since I’ve actually been able to “start new projects and work on fun stuff”. And some products added to the shop haven’t gotten the attention they need and deserve, such as writing more software examples and documentation to make things interesting, useful, and practical for everyone. Not to mention some stock problems (there are still a few right now).

One solution would be to “scale up”, i.e. to invest in larger amounts of stock and bring in more people to help with production, packaging, and sales. That’s probably what most people would do when presented with such an incredible “business opportunity”, right?

Ah, but there’s the rub… you see, my goal is not to create a large business and become the boss of something “big”.

Let me tell you a story I heard many years ago…

There’s this guy somewhere on a island, sitting under a tree. He takes a little branch, and patiently carves it into a magnificent little flute. He loves making his flutes, and does it all day long, day in day out. His family and friends enjoy what he’s doing, and everyone’s happy. Then, one day, a visitor comes along and sees him sitting there under his tree, amidst his branches and flutes. He walks over and says: “Wow, that’s amazing what you do. You ought to make lots of flutes, I think you could sell tons of them!”

The guy shrugs, and continues with his flute.

The visitor goes on: “Imagine how much money you could make, and how rich and famous you could become. Man, you could teach others to make these flutes, set up a factory, hire a workforce, and rake in the money! You’d be free to do anything you like. Wouldn’t that be incredible? Now tell me, if you were rich, what would you really like to do most of all?”

The guy looks up and says: “Me? Oh, nothing, just sit under a tree and make flutes.”

I’m not saying I’m exactly like that guy. But close. I want to spend my days exploring new things. And for a while, it’s been happening less and less.

Don’t get me wrong. I do want to share. I do want to encourage others to explore and learn more about all sorts of new and fun technologies. And I do want to continue with Open Source Hardware and Software. The mix of software, hardware, and electronics is absolutely fascinating and oh so worth sharing, and I love to be able to encourage people in those directions. But I don’t want to let the weblog or the shop run my life. My life is not about business, revenues, power, or even success. Heck, it probably wouldn’t be, even if I tried ;)

Dsc 1970

Just for the record: JeeLabs is not going away. On the contrary, I intend to find a way which makes sure that it will last and stay around for many years to come. I want to keep the weblog, as a source of unique posts with 100% original content. I want to keep the web shop going with kits and products which help anyone interested in Physical Computing to try things out, experiment, explore, and learn about it all.

But I need to take care of the inner fire and energy source which drives me. And that requires time to concentrate and the liberty to run off in lots of directions. I’m back into a bit of that right now, and it’s doing wonders for me.

There will be only a few more posts on the weblog this month. I’ll respond to emails and forum posts as before, and I’m committed to keep the shop running in a responsible way, with proper support and doing my best to maintain sufficient stock levels to keep everything listed available for people who want it. In fact, I expect this activity to increase, as more and more larger projects are starting up and several workshops are currently under way. But my focus will be on streamlining things, so I can recover that precious time I need for the longer term health of everything at JeeLabs, including myself.

Take care, and please don’t let the radio silence on this weblog affect your plans and activities. There are lots of old posts to go through which might interest you, just use the search box or go through any of the archived months at the bottom of this page.

When I figure out how to best take this all forward, you’ll be the first to know.

PS. Thanks for all kind emails and encouragements. It makes a very real difference.

Easy Electrons – Pull Ups and Downs

In Hardware on Feb 13, 2011 at 00:01

Time for another installment of the Easy Electrons series. This one is about the why’s and how’s of pull-up and pull-down resistors.

There are many ways to generate digital output signals. They almost always work with “high” and “low” voltages – for suitable definitions of high and low. As it turns out, there are lots of tricks you can play with this.

The high-end solution is to use a “push-pull” driver with two transistors. Similar to the H-bridge circuit described in an earlier post. By switching either one of the transistors on, you get an output which can carry current in either high or low states (“sourced” to ground, or “drained” from the supply rail, respectively):

Screen Shot 2011 02 12 at 11.32.02

The CTRL A & B pins are set up in such a way that one transistor conducts, and the other blocks. When a PNP/NPN pair is used, tying them both together turns out to work exactly as needed. This is what an Atmega pin does in OUTPUT mode, essentially.

But you don’t really need such a setup in many cases. That upper transistor can also be replaced by a resistor:

Screen Shot 2011 02 12 at 22.40.17

Resistors are cheaper, but more importantly, resistors offer more flexibility. The effect is that when the only remaining lower transistor is conducting, then it draws the signal to ground, and when it is not, then the resistor pulls the now-floating signal to a high level. This works as long as you don’t draw too much current. A common value for such a “pull-up” resistor will be between 1 kΩ and 100 kΩ. In that last case, you can’t put a load of more than a few microamps on the circuit, but again: for signaling purposes that is often just fine.

Why is this useful?

Well, for one, the voltage levels can be different. It’s possible to control a 0..12V digital signal using just one transistor and a pull-up to… 12V. This is also perfect for 3.3V -> 5V conversion, for example, and it even works when the output voltage is lower than the signal input (which goes through a current-limiting resistor anyway).

Another nice property is that you can tie several such outputs together. The output signal will drop to 0 whenever any output is low, and stay at 1 when all the outputs are high. i.e. it acts as an implicit AND-gate. This makes such a circuit suitable for “bussing”, i.e. putting multiple devices on a single signal line. You still need to collaborate between the devices to make sure only one of them talks at any given time, but electrically they can all be tied together with no extra circuitry. An output which is high is in effect not participating in the state of the bus signal.

Third, the single-transistor can still drive larger currents, but only in the “0” state. So you can still use this to turn on a LED (+ resistor), as long as you tie the LED/resistor combo between output pin and the supply voltage, not between output pin and ground.

And fourth, perhaps not as important as the rest: shorting such an output to ground when it only has an active-low transistor cannot harm the circuit (unlike shorting it to the positive supply rail). All that happens is that the pull-up will be supplying a little bit of current as it ends up getting the full supply voltage.

Note that putting a positive voltage on the transistor base willl cause it to conduct, and than tying something between the output pin and the supply voltage will cause it to get power when the transistor is conducting current from the output pin to ground. So loosely speaking, a “high” input voltage leads to an energized output state, even though the effect is to pull the collector low.

A slight variation is to use one transistor and leave the resitor off altogether. This is called an “open-collector” (OC) output, for obvious reasons. Sometimes, that extra resistor is not needed, i.e. when all you care about is energizing a lamp / motor / LED, or not. Sometimes a pull-up is still required, but then a single one will be sufficient, even with multiple OC outputs tied together. This is a way to reduce the total component count a bit further.

The I2C bus is an example which uses the open-collector output plus pull-up resistor approach, to implement a bus with multiple devices, exchanging information between them in any direction.

On an ATmega, you can enable a pull-up resistor on any pin by setting the pin up as an input pin, while writing a “1” as if it were still an output pin. The result will activate a weak pull-up resistor of 20..50 kΩ. One side-effect is that the input pin will read as a clear “1” when nothing else is connected. A pull-up resistor is a bit like slanting the table, i.e. the signal tends to stay in the high state unless a certain amount of current pulls it low.

What about pull-downs?

Technically, all this pull-up trickery can also be done with pull-down resistors and transistors tied between supply and output pin, but it is less comoon to do so. Due to the way transistors work, such a “high-side” switch is easiest to implement with a PNP transistor – and these used to be less common and more expensive. Furthermore, a “high” input signal would now cause no output current to flow. So the sense of operations is inverted. Are these essential reasons to avoid such an approach? No. But the NPN low-side switch approach has become prevalent. It has become second nature to use NPN transistors, and to tie small loads directly between the output pin and the positive supply voltage.

The ATmega has no built-in pull-down mechanism.

OOK fix

In Hardware on Feb 10, 2011 at 00:01

Here’s a great suggestion from Stefan Schulze (“kami” on the forum) for getting that wrong 433 MHz transmitter working with the OOK 433 Plug:

Img 5951

Sideways:

Img 5950

It requires some pin-bending, and you can attach an optional antenna, as he did.

I’m currently discussing option with the supplier to find a more “official” solution, but if you want to use the OOK plug right now, the above is definitely an option.

Thanks, Stefan!

Update – For everyone who received the OOK 433 Plug in its current form: I will send a solution out to everyone once it has been worked out. If you don’t need the TX side immediately, it might be an option to postpone soldering it until that solution is available.

Update #2 – Problem has been resolved, the OOK Plug is now supplied with the correct 3-pin transmitter.

Time-out

In Musings on Feb 9, 2011 at 00:01

Sorry, no post today. A cold and flu got the best of me.

OOK Murphy

In Hardware on Feb 8, 2011 at 00:01

Looks like there is a problem with the OOK 433 Plug

Here’s the transmitter I started out with:

Dsc 2455 2

Here’s the print layout I designed, based on that:

Screen Shot 2011 02 07 at 20.36.25

Everything worked fine. So I ordered larger quantities, to be ready for production. Here’s what I got in that new batch order:

Dsc 2455 3

Whoops… different unit!

Worse still, the original board had +, Gnd, Data as pins (as seen on the board layout), whereas the new boards have Data, Gnd, +, Antenna. It would be possible to cut the antenna pin off, but that’s not enough since the pinout is in fact reversed!

I’ve contacted the supplier. Let’s see how this goes. For the time being, I’m forced to take the OOK 433 Plug “off the shelf”. Sorry about that – please hang in there, also if you’ve already ordered this plug. Note that this only affects the 433 MHz transmitter – the 433 MHz receiver should work just fine.

Easy Electrons – MOSFETs, part 2

In Hardware on Feb 7, 2011 at 00:01

Yesterday was about MOSFETs and the heat they generate. Pretty impressive, those components which can control a 15A current with just a little bit of voltage.

Unfortunately, it’s not quite as simple as that. We have to check what happens with a lowly 3.3V applied to the gate. This can be found in the IRLZ34N datasheet:

Screen Shot 2011 02 06 at 20.43.00

This is an important graph for MOSFETs. Each line corresponds to a different voltage applied to the gate – this graph is in fact eight graphs in one.

You can see that they really do have some limits at lower voltages. At 3.3V, the IRLZ34N will not go much higher than 7A – quite a bit lower than the 30A maximum specs on the front page of the datasheet. Most MOSFETs are still at the end of their range when driven by a 3.3V microcontroller.

What this graph also shows, is the drain-to-source voltage at different current levels. This makes it very easy to estimate power consumption: at 3V and roughly 5.5A, that voltage will be 1V. In other words: 5.5W – quite manageable if the MOSFET is mounted on a suitable heat sink. But again: quite a bit lower current handling capacity than the 15A from yesterday. Note that we could drive it at a higher voltage by adding an extra stage in front, using either a BJT transistor or a MOSFET to get better current handling capacity.

As you can see, there is a very distinct switch-over point at each gate voltage level, where the MOSFET stops conducting more current. Under the switch-over point MOSFETs act essentially like a pure (low-value) resitor, but above that point they start acting more like a current limiter. This has major implications for power consumption, since the drain-to-source voltage will rise.

With this particular IRLZ34N, driving it at 3.3V, it is best not to push it beyond about 5..6A, and to use a heat sink when power consumption rises above say 1W (i.e. at 62°C/W, that makes the bare MOSFET rise 62° above ambient). Looking at the 3V line in the graph, I’d estimate that this MOSFET would work just fine without heat sink up to at least 2A, perhaps even 3A.

But what if we want to regulate the current? I.e. what if we want to use the MOSFET in an analog manner, and not just as on-off switch?

We could lower the gate voltage somehow, to force the current down. It won’t be a linear relationship, and I’m not even sure a MOSFET will conduct any current at all when the gate voltage is lower than 1 or 2V.

But in general, it’s a bad idea. The reason is (again!) power consumption. Say we use the following circuit:

Screen Shot 2011 02 06 at 22.17.58

(the resistor is a pull-down, explained in a future post)

That’s a 12W incandescent light bulb, powered by 12V, and controlled by a MOSFET, in other words: it draws 1A when full on. Let’s say we want to dim the light by halving the current through it. The lamp acts like a resistor (it just get pushed so hot that it starts glowing, that’s all). So half the current is what you get when you apply half the voltage to it. In this case 6V.

Suppose we figured out exactly what gate voltage to apply to get a drain-to-source voltage over the MOSFET of 6V. That would essentially accomplish our goal: the lamp would be dimmed. Another way to look at this, is that we’re tweaking the gate voltage until the MOSFET acts like a 12 Ω resistor between drain and source. Then the lamp and the MOSFET both get half the voltage.

What about power? Well, the MOSFET will have to have 6V across it, as we just saw. At 0.5A, this means that it will have to burn 6 (V) x 0.5 (A) = 3 Watts of power.

This is totally counter-intuitive: when we switch a lamp full on, the MOSFET will consume less than 0.1 W (as gleaned from the graph), but to dim it, that same MOSFET would need a heat sink!

There is some logic in this, though, if you think about it. The 12V supply voltage is a given. So if we want to apply less voltage to the lamp, we have no other choice but to waste the excess energy. Which is exactly what the MOSFET (or BJT transistor for that matter) will do. So although we’re reducing the total power consumption in this circuit by halving the current, we’re forced to do so by wasting power – as non-visible light, i.e. heat.

Can we do better? Yes, fortunately, we can.

This is where “pulse-width modulation” (PWM) comes in. Instead of eating up the excess power, we can take advantage of the fact that incandescent lights are fairly sluggish in their response. What we do is pulse the power on and of in very rapid succession. So the lamp will constantly heat up and cool down, and the result is that it won’t be burning at full brightness.

Why is PWM so incredibly useful? Several reasons:

  • we don’t need a way to generate a regulated analog gate voltage, we can simply generate digital on-off pulses with no extra circuitry needed
  • the MOSFET is again being used as pure on-off switch, and remains maximally efficient – so we probably won’t need a heat sink
  • power is no longer wasted, it is now effectively throttled instead – in very short and rapid bursts

It turns out that PWM works in a lot more cases than just incandescent light bulbs. DC motors are also sluggish, so controlling their speed with PWM also works extremely well. And better still, even LEDs work well with PWM, even though they respond instantly – because it turns out that our own vision is sluggish too!

See also an earlier post about PWM on this daily weblog.

So there you go. MOSFETs are the workhorses of power control, due to their incredible properties, and PWM is the technique of choice when it comes to throttling power devices (lights, heaters, motors, and more).

Easy Electrons – MOSFETs (and heat)

In Hardware on Feb 6, 2011 at 00:01

To continue this Easy Electrons series, this time I will go a little bit into MOSFETs.

To me, MOSFETs rank high up there, next to operational amplifiers as one of the foundation components in electronic circuits which are extremely useful and practical. The most amazing detail is that MOSFETs only exist since a few decades – newbies when you consider the time scale of most electrical components.

In a way, a MOSFET is like a BJT transistor. Even the symbol for it looks similar (from Wikipedia):

80px Igfet n ch enh Labelled.svg

This “N-channel enhanced MOSFET” type is the most common one, and like the NPN transistor, current flows into the top (D = drain) and comes out the bottom (S = source), all controlled by a third pin (G = gate).

One key difference between a BJT transistor and a MOSFET, is that a BJT is driven by current, whereas a MOSFET is driven by voltage. You feed a (small) current into a transistor to make it conduct, whereas you apply a (small) voltage potential to make a MOSFET conduct. The gate of the MOSFET doesn’t conduct current – it just senses the voltage. Bit like a capacitor.

You could say that a transistor is like a water wheel: you have to keep churning the crank to keep the water flowing through it. Whereas a MOSFET is more like a flexible tube: you pinch (well, “un-pinch”) to control the flow, but that pinch doesn’t consume energy. You could use a small mechanical clamp to maintain the pressure and keep the flow going.

This also explains why a transistor won’t conduct if the base is left unconnected (no current coming in), whereas a MOSFET could be doing anything when its gate is left unconnected, depending on how much charge was left when last connected. Early MOSFETs were in fact incredibly sensitive to static electricity – just touching the gate with a finger would often destroy a MOSFET. Nowadays, they are ESD protected.

MOSFETs are perfect for controlling large currents via a microcontroller. Even the weakest output pins can drive them, as long as the voltage is high enough. In the past, MOSFET’s needed at leat 4.5 to 5V to make them conduct, but nowadays voltages in the 2.5..3V range are sufficient in these so-called “logic-level” MOSFETs.

I’ll take the MOSFET Plug as example. It has two MOSFETs tied directly to two ATmega output pins:

Screen Shot 2011 02 05 at 13.35.58

Let’s look at a manufacturer’s datasheet for that “IRLZ34N” MOSFET, because there’s a lot of useful information in there.

The IRLZ34N datasheet is a great example. Seven pages, full of details, facts, graphs, circuits, pinouts, drawings, etc. It’s worth getting used to reading datasheets. They are loaded with info. To me, datasheets are the user interface of electronics. Give me a part number, and I’ll grab the datasheet to understand what it can do.

Here’s the first part:

Screen Shot 2011 02 05 at 13.42.00

  • logic level – aha! it can probably work with 3.3V
  • VDSS – that must be the max switching voltage, 55V .. plenty!
  • RDS(on) – will come to that in a minute
  • ID – max current through the drain, a whopping 30 amps
  • 175°C – looks like it can witstand scorching hot temperatures

Ok, there’s your helicopter view of this component. What I’m interested in is: will it be able to switch my <insert-some-high-power-device-here> ?

Well, we’ve seen the max voltage and current specs. But what really matters is power consumption. Because that’s the heat that gets generated, and that’s usually what breaks things.

Power is voltage x current (E x I). The voltage in this case is the voltage across the MOSFET. But we don’t know that – not directly. What we do know is its “RDS(on)” – this is the resistance between drain and source when turned on. Heh, how obvious. And exactly the value we want. It’s a mere 0.035 Ω.

Ohm’s law says V = I x R, so the voltage across the device is the current through it times its resitance.

Combine these two and we get P = E x I = (I x R) x I = I x I x R. Power consumption is proportional to the square of the current. Aha – that explains why large currents can be so destructive!

Let’s try this. Let’s go all out and push 30 amps of current through the MOSFET. Its power consumption will be 30 x 30 x 0.035 = 31.5 Watt. That’s a fair bit of heat (small lightbulb).

But will it work?

To find out, we need to do a thermal calculation. What’s going to happen to those 31.5 Watt of power? Well, they will come out as heat, but how much heat?

Time to look at another bit of info on the datasheet:

Screen Shot 2011 02 05 at 13.57.09

Let’s take the last value first: R(theta)JA, or Junction-to-Ambient thermal resistance = 62°C/W. In other words, each watt of power at the junction (i.e. inside the MOSFET package) will leed to a whopping 62°C temperature rise when the component is suspended in “ambient”, i.e. free, air.

Hmmm: 31.5 x 62 = nearly 2000°C. Yikes, our MOSFET is going to evaporate!

What we need to do is mount this part on a massive heat sink to make sure those temperatures are never reached, by drawing the heat away and keeping the MOSFET (relatively) cool.

Fortunately, there are two other values. The way these work, is that they tell you how much “heat resistance” there is when it flows away from the junction where all the heat is being generated. And it’s really easy to work with:

  1. draw a picture of the MOSFET and how it’s mounted
  2. find out the heat resistance in each step
  3. add them up to get a combined °C/W value
  4. re-calculate 31.5 x <that-value>
  5. make sure it stays under the max temp you want stay under (175°C would be too hot for a plastic case, for example – or even for a printed circuit board)

I’ll use a quick example, just to see how far we can push our MOSFET. Let’s assume the MOSFET is mounted on a (very good) heat sink which has only 5°C/W. Then we add up: 2.2 (junction to case) + 0.5 (case to heat sink) + 5 (heat sink to air) = 8.7°C/w.

With 30A current, we get 30 x 8.7 = 261°C. Whoops, can’t be sustained without damage.

Ok, let’s aim a bit lower: 15 amps. Now the power consumption becomes: 15 x 15 x 0.035 = 7.9 Watt. Without heat sink: 7.9 x 62 = 490°C – still way too hot, but with heat sink we get 7.9 x 8.7 = 69°C.

This value is a relative value. It means 69°C above the ambient temparature. So in a 25°C room, the whole thing would become 94°C. Still very hot, but not a problem for the MOSFET!

In other words: take a MOSFET, mount it on a big heat sink, and you can see how a tiny little microcontroller could control a 15A light or a motor which has a 15A peak current. That’s what makes MOSFETS so magical…

Careful with heat sinks, though. To get it right, you really have to include all the paths to “ambient”. If you mount the heat sink in a big box (which can withstand 94°C), then the temperature inside will rise. And those 69°C we calculated will make the whole setup rise accordingly! – it doesn’t take much to get a “thermal runaway”: core heats up, ambient heats up, core heats up further, etc. Until disaster strikes. Not quite Tchernobyl, but hey… be careful.

Soooo… what started out as a MOSFET introduction, has turned into a power and heat calculation. As you can see, it’s not very complex. It’s not a bad idea to find out up front whether a power circuit will self-destruct or not. Now just add a 2x safety margin, and you should be OK. Or better still: build the circuit, and confirm that the results match these predictions, especially under stress and near design limits.

Ehm… I’ve swept a little detail under the rug:

Screen Shot 2011 02 05 at 14.22.04

These calculations assume that we’re driving the gate to 10V, but we’ll only be applying a feeble 3.3V or so. Whoopsy daisy. Let’s go into that tomorrow.

No time, yet

In Hardware, Software on Feb 5, 2011 at 00:01

Heh, I bet this isn’t about what you thought the title suggested :)

I’ve been spending a couple of hours today, trying to get a DCF77 time code receiver working on the new ookRelay2.pde sketch. There’s a dcf77demo.pde sketch in the Ports library, which actually does all the hard work of decoding that pulse train.

It’s fairly tricky code, and I tend to throw in lots of tricky hacks (silly me, I know):

Screen Shot 2011 02 04 at 23.31.52

To use this, dcf77poll() has to be called often in loop(), like so:

Screen Shot 2011 02 04 at 23.14.35

(lots of #ifdef’s in there now, to make the sketch more configurable)

The weird thing is that this all worked fine in the previous incarnation of the OOK relay.

This timing code is far less critical than the 433/868 MHz OOK decoding, by the way. Pulses come in once a second, and all it needs to do is disambiguate short and long pulses. Easy stuff for an ATmega.

Except today… well, I don’t know why, but I can’t make any sense out of what’s happening. Been debugging with a few prints to the serial port via LEDs, but no luck. I’ve switched prototype setups, redone it all from scratch, changed DCF77 receivers… nada. Worst of all, there’s no pattern.

It’s probably the wrong moon phase, or somethin’ – I’ll revisit this some other time (soon).

Out of the woods?

In Hardware on Feb 4, 2011 at 00:01

Great, got a new batch of of ATmega328p’s in today:

Dsc 2450

(that’s a mix of ATmega’s and DIP sockets, btw)

With five hundred more in transit this very moment. No more worries!

So that’s a the end of a couple of months of supplier-anxiety :)

Then again, JeeLink and JeeNode USB stocks are low again. I don’t have good estimates on when those will be back in good supply. Am chasing a couple of options right now… for the time being, I can only point to JeeNodes plus assembly service as workaround, I’m afraid.

You can never win 100% at this atoms game, it seems!

OOK relay, revisited

In Software on Feb 3, 2011 at 00:01

With the modded RFM12B receiving 868 MHz signals, and the new OOK 433 Plug doing the same for the 433 MHz band, the new OOK relay is coming in sight.

Just a lousy bit of code. Elementary – I thought…

Except it wasn’t. Software always seems to take a lot more time (and concentration) than hardware. Silly!

Still, I think I managed to collect all the pieces lying around here from earlier experiments in that area, and combine them into a new ookRelay2.pde sketch.

It’s fairly elaborate and too long to show here, but I’ll pick out some pieces:

  • all the decoders live in the decoders.h file
  • since they all share common logic, each is derived from a common “DecodeOOK” class
  • the protocol for each decoder is the same: feed puse widths to nextPulse(), and it will return true whenever a valid packet has been decoded, then call getData() to get a pointer and byte count
  • the ookRelay2 sketch includes a variety of decoders, I hope we can improve/extend/add-more over time
  • there are two pulse sources: the 868 MHz receiver and the 433 MHz receiver
  • for each, a “DecoderInfo” table is defined with decoders to use for them
  • the runPulseDecoders() function does what the name says: evaluate each of the decoders in turn
  • when a decoder succeeds, data is added to an outgoing buffer (and optionally, printed to serial)
  • in this example, I send the accumulated data off to the RF12 wireless network, but Ethernet or any other transport mechanism could be used as well

With this out of the way, you can probably, eh… decode the following lines at the top op the ookrelay2 sketch:

Screen Shot 2011 02 02 at 23.30.36

And here’s the main loop, which is keeping things going:

Screen Shot 2011 02 02 at 23.31.24

The hard part is doing this efficiently with accurate timings, even though a lot of stuff is happening. That’s why there are two interrupt routines, which trigger on changes in 868 MHz and 433 MHz signals, respectively:

Screen Shot 2011 02 02 at 23.33.22

I’m still debugging, and I need to analyze just how much leeway there is to run all the decoders in parallel. Earlier today I had the 433 MHz reception going, but right now it seems this code is only picking up 868 MHz signals:

Screen Shot 2011 02 02 at 23.34.46

Oh well, it’s a start. Feel free to check out the code, which lives as example in the RF12 library.

Update – Bug fixed, now 433 MHz decoding works.

Meet the RFM12B Board

In Hardware on Feb 2, 2011 at 00:01

With the RFM12B becoming a nice low-cost option for low-volume wireless communication, and the RF12 library proving to be a solid software driver for it, it’s time to generalize a bit further…

Say hello to the new RFM12B Board:

Dsc 2448

This board adds a voltage regulator and 3.3V/5V level conversions, to be able to use the RFM12B on 5V systems such as the various Arduino’s out there, the RBBB, … anything you want, really.

There are 8 pins on this board, of which the 8th is a regulated 3.3V supply which can be used in other parts of the circuit – the voltage regulator will be able to supply at least 100 mA extra on that supply pin.

The other 7 pins are:

  • +5V
  • Ground
  • SPI clock (SCK) – Arduino digital 13
  • SPI data out (SDO) – Arduino digital 12
  • SPI data in (SDI) – Arduino digital 11
  • SPI select (SEL) – Arduino digital 10
  • IRQ – Arduino digital 2

Just hook each of those up to an Arduino, and you can use the RF12 library as is!

Sample output:

Screen Shot 2011 02 01 at 22.08.14

Look ma, just like a JeeNode or JeeLink!

With an 8-pin stacking header and a bit of bending, cutting, and soldering two wires (I used a jumper wire, cut in half), you can even stick this thing right onto an Arduino:

Dsc 2449

But of course using a normal solderless breadboard and some wire jumpers will work just as well.

Note that this board can also be tied to 3.3V systems – just use the bare PCB (and short out three solder jumpers), which then becomes a breakout board for the RFM12B. No need to mess with the 2.0 mm pin/pad distance on the RFM12B module itself.

Docs can be found in the Café, and the kit/pcb is now available in the shop, as usual.

SMD lab supplies

In Hardware on Feb 1, 2011 at 00:01

With SMD becoming more and more common, I really wanted to get a supply of different resistor values – a bit like this binder with through-hole components:

Dsc 2443

So I decided to get 100 of each of the E12 series, thus named because it has 12 values per order of magnitude – spread out in a logarithmic scale: 10, 12, 15, 18, 22, 27, 33, 39, 47, 56, 68, 82.

Here are all the values from 1 Ω to 10 MΩ:

Dsc 2439

Nothing fancy, but pretty low cost. And as a bonus: 0 Ω resistors! Don’t laugh, these can actually be quite handy as bridges over other traces. You could even use a single-sided PCB by adding a couple of these as “wire jumpers”!

Here’s the final result, as stored in the lab. I keep a set of 100 Ω, 1 kΩ, 10 kΩ, and 100 kΩ around for quick-and dirty uses, but this way all the usual values are available when I need ’em:

Dsc 2442

Each drawer has 3 compartments, with two values of the E12 series in each. So that’s two drawers per order-of-magnitude (“decade”), times 7, plus the extra 0 Ω and 10 MΩ. All that’s left, is to add a couple of labels on the drawers to quickly pick the right one.

Ready to do lots more experiments here at JeeLabs! :)

Back-soon server

In Hardware, Software on Jan 31, 2011 at 00:01

Soon, I’m going to move the JeeLabs server to a new spot in the house. Out of sight, now that the setup is stable.

But to do so requires rerouting an ethernet cable to the internet modem downstairs.

To do it right, I’d like to have a “we will be back soon” surrogate server plugged into the internet modem while transitioning, so that the status is reported on-line:

Screen Shot 2011 01 30 at 16.36.21

I could plug in a temporary Linux box, of course, or a laptop. But I want to keep this option available at all times, so a dedicated solution would be more practical. That way I can easily take the server off-line at any moment.

Ah, but that’s easy, with an Ether Card and an RBBB:

Dsc 2434

This combination just needs a 5..6V power supply, and 6 wires between the RBBB and the Ether Card.

Here’s the backSoon.pde sketch, which I’ve added to the EtherCard library:

Screen Shot 2011 01 30 at 17.24.05

In this case, being able to configure the MAC address of the interface as well as the IP address is in fact quite convenient, because this way the modem needn’t notice the hardware switch.

Only needs about 6 Kb. Actually, I’ll probably add a wireless option and use a JeeNode instead, to report total hits every once in a while. But either way, such a “back-soon server” really doesn’t come any simpler than that!

So if one of these days you see that message while surfing at JeeLabs, you know where it’s coming from :)

PS. I’ve put the back-soon server on-line as a test, it can be reached at http://jeelabs.org:8080/.

EtherNode on a breadboard

In AVR, Hardware, Software on Jan 30, 2011 at 00:01

After some recent comments on the forum about the etherNode.pde sketch, I wanted to make sure that the code is still working properly on this hassle-free setup (as well as with the Carrier Board):

Dsc 2432

And sure enough, it works as intended:

Screen Shot 2011 01 29 at 21.12.06

The output shows some packets from node 19 – which is the modded RFM12B running the RFM12B_OOK sketch, and it’s working nicely as you can see.

This sketch takes about 12 Kb of code (web server + EtherCard + RF12 driver), so there is ample room to add more features in there. You could use a modded RFM12B module, for example, and have everything you need to create a gateway between 868 MHz OOK devices and the LAN. In both directions in fact, since the RFM12B can also be tricked into sending out OOK packets.

Note that the Ether Card uses a few extra I/O pins from the JeeNode, so be sure to connect the 2×4 headers on the SPI/PSI pins between JeeNode and Bridge Board.

And the best part is that even with this Ether Card attached, all 4 ports on the JeeNode are still available for other uses. They are all brought out on the 8 leftmost pins, clearly labeled with both port numbers and Arduino pin numbers. Also available from the bridge board, as bonus: 2 LED’s and a push button.

As you can see, there’s a lot of empty real-estate on that breadboard – yearning to be put to good use…

PS. In case you’ve been waiting for one of those wooden bases, as included with the JeeNode Experimenter’s Pack: not to worry, I haven’t forgotten about you. The recent batch of packs were sent out without the base – they will be shipped separately once back in stock.

New OOK and DCF relay

In Hardware on Jan 29, 2011 at 00:01

With all the pieces finally in place, and now that I’m getting a little bit more time to hack around again, this seemed like a good time to reconsider the OOKrelay.

So I combined a JeeNode USB, the new OOK 433 Plug, a Carrier Board with box, and half a Carrier Card:

Dsc 2429

In the top left I also added a DCF77 receiver from Conrad, attached to the Carrier Card prototyping board. It’s a bit hard to see, because the little receiver board is actually mounted upright. Here’s a better view:

Dsc 2430

A JeeNode USB was selected, because this thing will be powered permanently, and I chose to hide the connector inside the box to make it more robust. So all this needs is a little USB charger. The LiPo charge option might be useful if I decide to make this thing more autonomous one day (i.e. to record accurate power outage times).

Note that this is a modded JeeNode, as described here, to be able to receive 868 MHz OOK signals.

So what this thing can do – as far as the hardware goes – is listen for both 433 MHz and 868 MHz OOK signals at the same time, as well as pick up the DCF77 atomic clock signals from Frankfurt. Sending out 433/868 MHz OOK is possible too, but since the unit isn’t constantly listening for OOK packets, it’ll have to poll for such commands, which will introduce a small delay.

That’s the hardware, i.e. the easy part…

The software will be a lot more work. I’m going to adapt / re-implement the functionality from the OOKrelay sketch, i.e. this unit will decode and re-transmit all incoming data as RF12 packets, so that they can be picked up by a JeeLink hooked up to my PC/Mac. The clock signal will be useful to accurately time-stamp all receptions, and is really of more general use.

So far, the following I/O pins have been used:

  • one port for the OOK 433 Plug, i.e. one DIO and one AIO pin
  • one input pin for the modded JeeNode, to receive 868 MHz OOK signals
  • one input pin for the DCF77 signal

There is still lots of room left for expansion. A Pressure Plug perhaps, to track barometric pressure. Or a Memory Plug to save up the last data while the central receiver is unavailable. Or both, since these can combined on a single I2C port.

Absent from all this, is a display. First of all, squeezing a 2×16 LCD in there would have been very tight, but more importantly, now that there is a JeePU, there really is no need. I’m already sending the info out by wireless, so a remote graphical display is definitely an option – without PC – or I could use a central server to get this info to the right place(s). This box is intended to be hidden out of sight, somewhere centrally in the house.

Only thing I might consider is a small LED near the USB cable, to indicate that all is well. Maybe… I’m not too fond of blinking LEDs everywhere in the house :)

Meet the OOK 433 Plug

In Hardware on Jan 28, 2011 at 00:01

After yesterday’s post about modding the RFM12B to receive OOK RF data, here’s a new option which goes the other way: add-on hardware for 433 MHz.

Meet the OOK 433 Plug:

This plug can probably be used without antenna, but adding one is bound to increase the maximum reception range (I haven’t done any range tests yet).

The receiver output is tied to the AIO pin, which must be configured as input on the JeeNode. The transmitter is tied to the DIO pin, to be used as output pin.

Both receiver and transmitter can be operated from 3..12V (I’ve only tested with 3.3V and 5V, so far). For the transmitter, I would expect the power output and range to increase with voltage, but even at 3.3V things seem to work quite well in both directions. There is a jumper to select between PWR and +3V as power supply, and there is an optional series resistor for the receiver output, which may be needed at higher voltages (normally, it can be omitted by closing that second jumper).

The reason for creating a separate plug is that it allows a single JeeNode to operate simultaneously on the 433 MHz and 868 MHz frequency bands. As suggested in the comments on yesterday’s post, a modded 868 MHz RFM12B can probably be made to receive 433 MHz OOK signals, but the receiver sensitivity is bound to be fairly low since the RF circuitry is really dimensioned for 868 MHz. Haven’t tried this, though.

There are several sketches which can be used with the OOK 433 Plug. To use the receiver on this board with little or no adjustment, try recv433_test.pde or ookRelay.pde. For tranmission, there is the send433_test.pde sketch.

I expect to combine and integrate code from the different OOK and relaying sketches in the near future, now that this plug has been created, but for now you’ll have to tinker with what’s available.

If you have suggestions (of better still: code or docs) for new protocol handlers to add and implement on a JeeNode, please let me know or share it on the discussion forum. It will interesting to see how many OOK protocols on 433 and 868 MHz we can figure out and implement, to make this all truly versatile for lots of different RF devices out there.

All code and docs are in the Café, with the OOK 433 Plug available from the shop, as usual.

Enjoy!

Note – This server was down on Jan 28, from about 1:00 to 10:00 (CET). I’m investigating what happened.

OOK reception with RFM12B

In Hardware, Software on Jan 27, 2011 at 00:01

A while back, JGJ Veken (Joop on the forum) added a page on the wiki on how the RFM12B can receive OOK.

I never got around to trying it … until now. In short: if you’re not afraid of replacing an SMD capacitor on the RFM12B wireless module, then it’s trivial!

Here’s what needs to be done – the capacitor on the left is 4.7 nF:

Screen Shot 2011 01 25 at 14.16.36

Unsolder it and replace it with a cap in the range 150..330 pF (I used 220 pF).

This cap appears to determine the time constant w.r.t. how fast the RSSI signal adapts to varying RF carrier signal strengths. With 4.7 nF, it’s a bit too sluggish to detect an OOK signal – which is nothing other than a carrier being switched on and off (OOK stands for: On / Off Keying).

The next trick is to connect the FSK/DATA/nFSS pin of the RFM12B via a 100 Ω resistor to AIO1 (a.k.a. analog 0, a.k.a. PC0, a.k.a. ATmega pin 23 – phew!):

Dsc 2427

As far as I can tell, this is a digital signal, so connecting it to AIO0 is really not a requirement. It might be more practical to connect it to one of the B0/B1 pins on the SPI/ISP header. Perhaps I should add a jumper in a future revision of the JeeNode PCB?

And lastly, the RFM12B must be placed in a special mode to get the RSSI signal onto that pin – i.e. compared to the RSSI threshold, also configured into the RFM12B (97 dBm).

All the pieces were there, and all I had to do was to follow the steps mentioned on the wiki page.

I made some changes to the code and added it as RF12MB_OOK.pde example sketch. Here is the main logic:

Screen Shot 2011 01 25 at 16.42.14

As you can see, all incoming data is forwarded using the normal RF12 mode packet driver.

Sample output:

Screen Shot 2011 01 25 at 16.56.39

It’s happily picking up FS20, EM10, S300, and KS300 packets, and the overall sensitivity seems to be excellent. And since it forwards all data as packets into the rest of the JeeNode network, I now have all the data coming in over a single JeeLink.

Sooo… with this “mod”, no separate OOK receiver is needed anymore for the 868 MHz frequency band!

PS. Haven’t done too many tests with this yet. Transmission is unaffected, as far as I can tell. Reception of packets with the RF12 driver still seems to work – it may be more susceptible to RF variations, but then again a “normal” packet uses FSK which is a constant carrier, so in principle this modification should not affect the ability of the RFM12B to receive standard FSK packets.

Thermo Plug fix (v2)

In Hardware on Jan 26, 2011 at 00:01

Another day, another fix.

The Thermo Plug also had a problem with layout, as described in this weblog post a while back.

I’ve had a new batch of boards made which moves the thermocouple screw terminal slightly outwards to get it out of the way of the AD597 chip:

Screen Shot 2011 01 25 at 16.54.26

The sharp edges come from the fact that new plug designs are now placed differently on a panel, using routing along the longer side of the plugs.

All plug PCBs and all JeeNode types have boards using a “standard” 21.1 mm width. The new approach simply means that these widths are now more accurate – “across the board” one could say :)

I’ve also addressed the transistor pinout confusion by adding a “C” label next to where the collector pin is.

Again, small tweaks, but good to have them resolved. All Thermo Plugs sent out from now on will be this new “tp2” version (the old board has “tp1” on it).

Onwards, again!

Carrier Board fix (v2)

In Hardware on Jan 25, 2011 at 00:01

This was looong overdue…

The Carrier Board has been updated to fix a problem with an incorrectly placed DC jack, as described here.

The new board simply omits the (faulty) connection to the DC jack:

Dsc 2421

If you want to use the DC jack you’ll need to connect some wires to it (both “+” and GND). It may not be the most elegant “fix”, but it’s effective and this change was risk-free…

To re-iterate: the DC jack can be soldered to all four pads now, there is no longer a risk of shorting anything out due to mixed-up wires on the schematic. It’ll be much sturdier than before.

All boards sent out in 2011 include the new design – you can recognize it by the fact that it includes the white DC Jack silk-screen printing on the back side – which v1 did not. And that it’s labeled “cb2” instead of “cb1”.

Onwards!

Easy Electrons – Transistor circuits #3

In Hardware on Jan 24, 2011 at 00:01

A third installement about transistors in this Easy Electrons series.

So far, I’ve shown how to get more current out of an I/O pin from an ATmega, since this will probably be the most common reason to use transistors in combination with a micro-controller. But these circuits all act as switches, i.e. they turn current on and off (or in the case of the voltage regulator: adjusting current flow to a certain value).

What if we wanted to control one or two DC motors for a little robot? Lots of fun stuff to do in that area, especially with wireless communication. To do this, we also need to be able to reverse the voltage placed on the motor, so we can make it turn forward or backward under software control. And if we want to make it a bit fancier, it would be nice if we could control the speed of the motor as well.

First things first. Reversing the direction of a motor can be done with a double-pole double-throw (DPDT) relay:

This low-tech solution will switch the +12V and the -12V poles to make the motor run clockwise or counter-clockwise. And if we were to use a transistor for the -12V (i.e. GND) side, we could also turn it on and off.

But that’s clunky! – let’s see if we can do differently. What we need is a way to place either a high or a low voltage on either side of the motor. Here’s a first (flawed!) attempt:

Look what happens when we put the proper voltages on A, B, C, and D:

  • with A high and B low, the left side of the motor is tied to “+”
  • with D low and C high, the right side of the motor is tied to “-“
  • it will start running

And now the other case:

  • with A low, B high, the left side of the motor is tied to “-“
  • with D high, C low, the right side of the motor is tied to “+”
  • it will start running in the opposite direction

And of course, when A = B = C = D = low, the motor will stop.

What the two transistors “on top” of each other do, is create sort of a push-pull circuit, since you can tie the central connection to either the “+” or the “-” voltage rail. This type of circuit is called an H bridge, due to it’s shape.

(note that I’ve left out 4 protection diodes, i.e. one across each C-E junction – they do need to be added in a real-world setup with DC motors)

There are several serious problems with this particular design, though:

  • to pull A or D high, we have to apply 12V, since 3.3V won’t be high enough to raise the base 0.7V above the emitter voltage level
  • if we pull A and B high, then we’ve got ourselves a short-circuit, with huge currents through both transistors on the left!
  • same for C and D…
  • and lastly, this thing needs a whopping 4 I/O pins

Let’s tackle that last point first: we can halve the I/O pin count by tying A and C together, and by tying B and D together. Now three out of the possible combinations will get us just what we want: stop, turn clockwise, turn counter-clockwise. But with both signals high, we still get a short circuit. Not good – we don’t want a software error to be able to start a fire…

The bigger problem though, electrically speaking, is that the input voltages involved are no longer suitable for an ATmega. This can be solved by adding an extra NPN transistor on both sides, for a total of 6 transistors. Instead of explaining the whole setup in detail, let me point you to some articles I found on the web:

  • this one describes the basic idea using relays
  • this page uses 6 transistors (lots more interesting pages on that site)

As you can see, it takes quite a few components to drive one small motor. Fortunately there are lots of H-bridge driver IC’s with various voltage- and current ratings. Some of these are quite small – such as the TC4424A I used on the DC motor plug, which is why I was able to actually put 2 of them on a single plug.

The second task we’d like to be able to do is control the motor speed.

This turns out to be fairly easy. The trick is to use pulse-width modulation (PWM). This is just a fancy term for a simple concept: we generate a set of pulses, and we control the on-time vs. off-time ratio of these pulses. As it turns out, DC motors are far too slow to follow these pulse trains if you generate them at 100 Hz or more. Instead, they will tend to average out the 0/1 values sent to them. And sure enough, a pulse train which is 100% off will cause the motor to stop, and a pulse train which is 100% on will cause the motor to run at full speed. Everything in between will lead to a motor running at intermediate speeds – simple!

For completeness’ sake, let me mention that the on-off power control circuits I’ve been describing in these last posts often use MOSFETs nowadays, instead of the traditional BJT transistors. For simple experiments and small DC motors, BJT’s are fine though.

Now if you think transistors are so great… wait ’till you see what MOSFETs can do!

I’ll go into those next week. Enough electronics for now.

Easy Electrons – Transistor circuits #2

In Hardware on Jan 23, 2011 at 00:01

Today, a second example of a transistor circuit. As announced yesterday, this one is about boosting the output current further…

With a transistor which amplifies current say 100 times, there are still limits to what you can control from an ATmega I/O pin: 10 mA x 100 = 1A. What if you want to drive a DC motor with a stall current well above that?

Quite simple, really: use two transistors “in series”. But how?

Note that this is not the way to do it:

Screen Shot 2011 01 22 at 23.13.37

On first sight, it looks exactly like what we need: after all, when the inout voltage rises above 2x 0.7V, both transistors will start to conduct, right? And since each of them can amplify their input current by 100, that means we could control a current which is a whopping 10,000x as large as the input current! So with the proper high-power transistors, this ought to work, right?

There is a sneaky problem, though. Keep in mind that the base voltage is always capped to at most 0.7V above the emitter, since the B-E junction is like a diode. So when the first transistor starts conducting, it’ll drive the second base up. Up to 0.7V, in fact. And that’s where things go wrong: the first transistor will drive 100x its base current into the second base. With 10 mA, that might well end up being around 1A. But most transistors can’t handle that: they expect small base currents to drive large collector currents. Another way to explain the problem, is that the C-E junction of the first transistor will always be 12 – 0.7 = 11.3V, so with a large current, it’s bound to overheat.

What we need, is a way to limit the current into the second transistor. Here are two ways to do it:

Screen Shot 2011 01 22 at 23.22.24

Both should work. The former is like a double amplification stage, whereas the latter uses the voltage follower approach described yesterday. I don’t really know which one would be better, because I’ve never tried either one.

That’s because there is also another circuit called the Darlington transistor, named after the person who invented it, Sydney Darlington:

150px Darlington Configuration.svg

The difference is subtle but important: the collector of the first transistor is no longer tied to the positive power supply rail, but to the collector, i.e. the lower side of the load.

The practical advantage of this combination, is that it’s still a 3-pin device, so you can use it wherever a transistor is being used, and that’s indeed it’s main raison d’être. Roughly speaking, a Darlington transistor acts like a transistor with a much higher current gain than a single transistor.

Its main drawback is that the saturation voltage, i.e. the voltage over the (combined) C-E junction, is higher than with a regular transistor – i.e. more like 1.1V than 0.4V. This is the voltage you get when driving the transistor all out – and it affects the amount of power absorbed by the transistor (P = E * I). So although a Darlington can switch higher currents from an I/O pin, it also generates roughly three times as much heat.

The reason I’m going into Darlingtons, is that they are very convenient and widely used. There is a 18-pin chip with 8 Darlingtons, tied into a tiny package, the ULN2803:

Uln 2803

This is what I used on the Output Plug, by the way. Not only does each pin drive 500 mA at up to 50V, you can actually tie them together to control larger currents. Each Darlington on this chip includes the necessary resistors, so it’s simply a matter of tying an I/O pin to its input, and it will “sink” up to 500 mA to ground.

An extra benefit of the ULN2803 is that it has a built-in reverse kickback protection diode, as needed when hooking up relays and motors. So that’s 8 more components saved, all by using this single chip.

Don’t get you’re hopes up too high, though. When driven from a 3.3V input, the output current of the ULN2803 might not go much higher than 300..350 mA on each pin. The components on the chip seem to have been designed for 5V. But it does work fine at 3.3V!

To summarize: the Darlington transistor pair is an easy way to get just a little bit more current (or more accurately: a higher gain) than from a single transistor.

So much for switching current on and off. Tomorrow, as last part of this mini-series, I’ll describe how to reverse the current as well, so we can also control the direction of a DC motor. And how we can control their speed. All with just a bunch of transistors.

Easy Electrons – Transistor circuits

In Hardware on Jan 22, 2011 at 00:01

With the basics and some real-world details out of the way, it’s time to start looking at some other circuits with transistors.

I’m going to describe three different types of circuits, to give you a feel for transistors – while noting that I’m just scratching the surface w.r.t. these amazing devices:

  • regulated power supply
  • more current with chained transistors
  • push-pull drivers

There’s way too much to say about this. Let’s get’s going!

Regulated power supply

In the post about diodes, I described a circuit based on a zener diode. One problem with that circuit was that it only worked for a few milliamps of current, the other was that this current was being drawn even under no load.

With a transistor, we can fix both problems at once:

Screen Shot 2011 01 21 at 23.48.09

Well, we’re not changing the fixed current draw really. But we can use a higher resistor value to draw less current, since only a little bit will will be needed to feed the transistor base.

So what’s going on here? Well, remember that the B-E junction is essentially a diode, connected in the forward direction. So from base to emitter, we have a 0.7 volt drop. Since the zener keeps the voltage fixed, the output voltage will be 0.7V below the zener breakdown voltage: i.e. 4 – 0.7 = 3.3V, tada!

The neat thing is that this is basically all there is to it!

The output voltage doesn’t really depend on the load current. With an amplification factor of 100, with a very light 1 mA load, the transistor will need to draw 10 µA on its base to generate that amount of current. It may seem like it does this as if by magic, “seeking” the proper settings all by itself. Let me try to describe what happens anyway. What we’re doing is keeping the base voltage at a fixed level. Here’s what happens when things start up, i.e. when the emitter is still at zero volts, right after turning on the power:

  • the base will then be at 0.7V, because it’s always 0.7V above the emitter level
  • this is much lower than the zener voltage
  • so all the current through R1 goes into the base
  • the transistor will amplify this and start conducting
  • that will “pull” the emitter voltage up, since the collector is tied to the input voltage
  • this in turn means that the load will be supplied with power
  • assuming the load is not a short circuit, the voltage on the emitter will rise
  • so will the base voltage – by 0.7V more, as always
  • at some point, the base reaches the zener voltage
  • that’s when current will start going into the zener
  • meaning: less current into the transistor base
  • where does it end? simple: when the emitter is precisely at 0.7V under the zener voltage
  • this adjustment process takes place continuously, so when the load current changes, the transistor will keep on adjusting its current to keep the base at the zener voltage
  • similarly, this will keep the emitter voltage at a fixed level even when the input voltage changes, since the voltage at the base remains the same

Voilá, a regulated power supply with a constant voltage output, a.k.a. a linear voltage regulator.

This voltage regulator will work fine for fairly large currents. After all, if we have a 10 mA current through R1, then a transistor with hFE 100 will be able to amplify this up to 1A.

But there is a catch: power consumption – again!

Note that the collector is held at the input voltage, and let’s assume this is fixed at 5V. And the emitter is held fixed too, at 3.3V in this example. So we have 1.7V on the C-E junction, with all the load current going through it. With a 1A current draw, that’s 1.7 watt of power. Not huge, but already well beyond what a little transistor can handle. This is why such circuits need to use power transistors and large heat sinks.

It gets worse with higher input voltage. Suppose we connect our setup to 9V instead of 5V. Now the C-E junction will have 5.7V over it, while still drawing 1A = that’s 5.7W of power, i.e. generated heat! So keep in mind, no matter how fancy your regulated supply is: if it works according to this “linear” principle, then it’ll turn all excess voltage into heat. See also an earlier post about this topic.

Our circuit also gives us a new way of looking at a transistor: while regulating, as shown above, it acts like a variable resistor, with the resistance being controlled by the amount of current flowing into the base.

So there you have it, the basic properties of a linear voltage regulator. I don’t want to stray too far from microcontrollers in this Easy Electrons series, but this really is a good example of how unusual transistors can be, compared to resistors and capacitors. Besides, voltage regulation is so common that it’s really useful to understand how it works and to be able to reason a bit about power consumption.

Tomorrow, we’ll go into “Darlingtons”! :)

2×16 LCD’s – yeay!

In News on Jan 21, 2011 at 00:01

At last… the long-awaited order of 2×16 character LCD’s has arrived!

Here’s what one of those boxes looks like:

Dsc 2418

Many of the pending LCD (+ LCD Plug) back-orders have now been sent out. Yippie!

That still leaves 3 more major items which are holding up a couple of packages: Carrier Board PCB’s, Relay Plugs and RBBB’s. The Carrier Boards are currently in Leipzig and will be here either on Friday, or else right after the weekend. The second item which is really hard to get these days, is the relay used on the Relay Plug – they are expected in about a week. The third item is the RBBB, which has been postponed a bit due to a temporary ATmega328 DIP shortage. This has now been resolved, so I expect to have them in by early February.

Phew.

It’s strange how these supply issues can make such a difference… looks like I can’t seem to focus on anything substantial when there is a large back-log. Pretty silly, really. Oh well.

Sorry for the interruption, I just had to post about this. Tomorrow will be the third Easy Electrons post about transistors, as promised.

Easy Electrons – Transistors #2

In Hardware on Jan 20, 2011 at 00:01

Yesterday’s post started off a little mini-series about transistors. Today, I’ll go a bit more into the practical side of things. And in case you’re curious: tomorrow I’ll describe some interesting circuits with’em.

Let’s look at that NPN transistor symbol again:

NewImage.jpg

First thing I want to point out is that there’s essentially a diode between the base and the emitter. The most important property of that, is that when there is current flowing from base to emitter, then there will be an ≈ 0.7V voltage drop across this “B-E junction”.

So yesterday’s calculation was a bit inaccurate. When putting 3.3V on the IN pin, current will flow through the resistor into the base, and from there to the emitter and to ground. Since the base is 0.7V above the emitter, and the emitter is tied to ground, there will be 3.3 – 0.7 = 2.6V over the resistor. Which means that the current through the base will be 2.6 mA, not 3.3 ma as reported yesterday.

With 0V on the IN pin, there is no current, so the voltage between base and emitter is irrelevant (0V in fact).

There was another inaccuracy in yesterday’s post (thx Reinhard), in that the current into the base also comes out the emitter. So with 2.6 mA into the base, and 3.3V current going into the collector, the total current coming out of the emitter is 2.6 + 33 = 35.6 mA (not 33 mA).

We’re not out of the woods yet. Transistors are not perfect conductors. Even when driven all out, there is a small residual voltage from collector to emitter. Usually it’s around 0.4V – this means we can now make much a more accurate calculation:

  • with 3.3V on IN, and 0.7V on the base, there is 2.6 mA into the base
  • with a current amplification factor (hFE) of 100, the collector-to-emittter current might reach 260 mA
  • however, the R2 resistor will limit this
  • with one side of R2 at 3.3V and the other at 0.4V, current through R2 is (3.3 – 0.4) / 100 = 29 mA
  • currents will be: 2.6 mA into the base, 29 mA into the collector, and 2.6 + 29 = 31.6 mA out of the emitter

Now we’re ready for a calculation which is crucial: the amount of power dissipated in the transistor!

It’s really very simple (P = I * E): the base current corresponds to 2.6 mA x 0.7 V = 1.82 mW, and the collector current corresponds to 29 mA x 0.4 V = 11.6 mW, for a total of ≈ 13.4 mW.

How do we know this? Well, if there is a current flowing and a voltage drop, then that’s by definition a form of power consumption. And it can’t turn into anything but heat, really!

Fortunately, 13.4 mW is very little heat, so even the simplest small-signal transistor will be able to handle it. But with larger currents involved, this type of calculation can tell you whether the circuit will: 1) work, or 2) overheat and fail.

Here’s an example to illustrate the point of such calculations – suppose you want to turn a motor on or off, controlled from an ATmega I/O pin:

Screen Shot 2011 01 19 at 23.45.31

(I’ll explain the “kickback” protection diode some other time – it just blocks, mostly)

We know that an ATmega can’t supply more than a few milliamps. Let’s assume it can output 10 mA, and that when doing so the output pin voltage drops to 2.5V – what value do we need for the R1 resistor? And what type of transistor would we need?

Clearly it depends on the motor. Let’s assume it’s a fairly small motor driven from a 12V power supply. What we need to make sure is that the circuit won’t break down. The worst case is when the motor “stalls” and then starts drawing a large current – that’s when something prevents it from turning while power is being applied. Don’t be surprised to see stall currents of several amps, even for small motors which only draw a few hundred milliamps under light load conditions!

Ok, now let’s figure out how much of a motor current we could handle with the circuit shown above:

  • to get max current output, we’ll feed as much current into the base as we can, i.e. 10 mA
  • so we’re feeding 2.5V, and the base is 0.7V, meaning that R1 needs to be (2.5V – 0.7V) / 10 mA = 180 Ω
  • let’s assume we get a transistor with an amplification factor of 100
  • IOW, it can only produce 100 x 10 mA = 1 A current

If we have a motor with a stall current larger than 1 amp, then something nasty will happen: the voltage between collector and emitter will rise above the 0.4V saturation voltage that you get when driving a transistor all out.

So what’s the problem? Heat!

We’ve got 12V on the one side of the motor. Say it has a 2A stall current. The transistor only amplifies its base current to let 1A through. What happens, is that the collector voltage will rise – my hunch is that it will reach about 8V (4V over the motor and 8V over the transistor, matching the 2:1 current ratio).

Now we’re in big trouble. The transistor is conducting 1A with a 8V voltage drop. That’s eight watt of power consumption, i.e. heat. If you take a simple little transistor which isn’t designed for that sort of heat dissipation, then it’ll heat up and go up in smoke. Fireworks!

Note how the lack of output current is what caused this. If the transistor had been able to deliver those 2A, then it’s power consumption would be “only” 2A x 0.4V = 0.8 watt – one tenth of what happened here.

As you might expect, there are several solutions around this. I won’t go into them here, though – I just wanted to go through these calculations to show you that you can’t drive everything directly from an ATmega I/O pin.

Tomorrow, some real circuits!

Easy Electrons – Transistors

In Hardware on Jan 19, 2011 at 00:01

Another installment of the Easy Electrons series. This time I’m going to follow up on the diode post, and go into transistors.

Transistors. Phew. Biiig topic!

There are several types of transistors. The most common one is the BJT. There are two variants, which are schematically drawn like this (from that same Wikipedia page):

Screen Shot 2011 01 18 at 23.32.33

A transistor has three pins, called Base, Collector, and Emitter. Using the convention that current “flows” from “+” to “-“, it’s easy to remember which in an NPN transistor (the most common variant):

  • the collector, eh, “collects” current – IOW, this is where current flows into the transistor
  • the emitter is where the current flows out again, to ground at some point
  • the base is the main control which determines what the transistor does

So what does it do?

One way to look at it, is as a current amplifier: put 1 mA into the base, and the current from C to E will be a multiple of that – anywhere between 50 and 500 times depending on the particular model, i.e. 50 .. 500 mA!

Note that I’m not suggesting that a transistor generates current. Only that when a voltage is applied between C and E, then the current flowing will be a multiple of the “control current” fed into the base.

Things are not quite that simple, though. How do you “put a current” into a component? You can’t just put a voltage on all the pins… before you know it, the current might easily exceed some allowed maximum rating! Transistors have pretty rigid limitations. When you exceed them, they can easily overheat and get damaged.

We don’t really have an easy way to control current, but what we can do is turn ATmega I/O pins on and off, i.e. control the output voltage on those pins. It’s relatively easy to turn that into current though – Ohm’s law: use some resistors!

Here’s a simple circuit to let us explore this behavior:

Screen Shot 2011 01 19 at 00.21.58

The input pin can be fed a voltage, and the R1 resistor will make sure that the current flowing into the base of the transistor will be limited. Likewise, R2 makes sure that no matter how much current the transistor wants to pass from its collector to its emitter, there will be a limit.

How much are these limits? Depends on the voltages and resistor values, of course. Let’s assume the following:

  • the “+” voltage is 3.3V (and GND is 0V, as always)
  • the input pin can have voltages between 0 and 3.3V applied to it
  • resistor R1 is 1000 Ω
  • resistor R2 is 100 Ω

The maximum current flowing into the base will never be more than when IN = 3.3V, i.e. 3.3V over 1000 Ω = 3.3 mA (using “I = E / R”).

The maximum current flowing from collector to emitter is what you’d get if the transistor were a complete short circuit between C and E, i.e. 3.3V over 100 Ω = 33 mA.

Note how I’ve made all sorts of worst-case assumptions about the transistor. In fact, I’ve calculated these values as if B, C, and E were all shorted together, and hence tied to ground (since E is tied to ground).

A real transistor behaves somewhat differently. But no matter how it actually behaves, I know that no more than 3.3 mA will be flowing into the base, and not more than 33 mA will be flowing into the collector and out of the emitter. Just about any NPN transistor can handle that.

Here’s what happens when IN is 0V (i.e. GND):

  • no current will flow into the base
  • since the transistor amplifies the current, no current will flow from C to E
  • if no current flows from C to E, then it’s basically like an open (unconnected) circuit
  • if unconnected, there will be no current flowing through R2
  • with Ohm’s law, the voltage across R2 is (E = I x R) = 0 x 100 = 0
  • so the voltage on the OUT pin will be 3.3V, the same as on the other side of R2

Now, when IN is 3.3V, this is what happens:

  • current will flow through R1
  • lots of current will flow from C to E
  • that’s the same as saying that C and E are more or less shorted
  • that means the OUT pin will now be (close to) 0V

We’ve created a signal inverter: 0V in = 3.3V out and 3.3V in = 0V out!

As I said, big topic. I haven’t even touched on some important details of a “real” transistor.

Stay tuned…

Two lousy caps

In Hardware on Jan 18, 2011 at 00:01

A couple of Ether Card kits have escaped into the wild without these ceramic 20 pF capacitors:

Dsc 2416

And a few probably also had no RJ45 MagJack (where you plug an Ethernet UTP cable into).

I’m very sorry about that. Turns out that we had a couple of kits prepared at a time when these components were out of stock. With the intention to add them into the bag before shipping.

In retrospect, placing those bags in the box was of course an urgent invitation for Mr. Murphy.

I’ve already sent out 2 sets of caps to people who’ve emailed me, but in case you recently got an Ether Card kit and these components were missing, pleasee email me. I’ll send them over asap, of course. I suspect that about a handful of these incomplete kits were sent out.

Stock levels are starting to return to normal here at Jee Labs, well at least to the point that most orders from 2010 have been processed (not all!), with a dozen single-item back-orders pending. Most of these are waiting for 2×16 character LCDs and Carrier Boards – both these are expected later this week. I’m also still behind w.r.t. the wooden base in the JeeNode Experimeter’s Packs.

On related news: there is a world-wide shortage of ATmega328 DIP chips, as you may have noticed. I’ve still got a couple to go, and more orders queued up for February and March, but it’s hard to tell right now when this is going to hit another of them atom-related walls around here.

On the plus side, all these stock issues have helped me better understand how to track what’s going on in the shop. I really wouldn’t mind adopting some sort of ERP and SCM systems at JeeLabs. Well… if they were a couple of orders of magnitude cheaper, that is :)

Two other interesting and related TLA’s are GLP and GMP – which describe ways to track exactly what goes on in laboratory cq. manufacturing processes. I’ve been involved with those in a previous life – the neat part is that if you get them right, then you can answer sort of “inverted questions” about a product, such as “what ingredients is it made of?” and “which batch of ingredients were used in this particular item?”.

Having such systems in place would have helped me figure out exactly who got the incomplete Ether Card kits, and then I would not have needed to publicly sollicit your help to fix this particular Murphy-case!

Oh well… one can always dream, right?

Touch screen mount

In Hardware on Jan 17, 2011 at 00:01

Electronics design is trivial compared to mechanical design, I tell you!

I’ve been looking at creating a Touch Screen option for the Graphics Board. In theory, it’s simple – just combine these two parts:

Dsc 2413

But how?

What I’d like to end up with of course, is that the touch screen is firmly held in place in front of the GLCD display:

Dsc 2414

The width of this touch panel is perfect. The touch surface is slightly higher than the 128×64 GLCD, but that could actually be used to create a couple of extra “fixed” buttons, perhaps even with some LEDs – right above the display itself (or below, if we turn the whole thing around).

It’s not hard to create a one-off mounting setup: just hot-glue the thing together, with plastic, wood, or foam-board. But that’s hardly a solution for others to replicate. And this really is one of those cases where the end result needs to look sharp, IMO. I’d really like to use this as a small self-contained unit for display and control of a few variables as part of a home-automation setup. So it better be robust. And battery powered, if possible.

The headache is the mechanical part… suggestions would be most welcome!

Poor Man’s Mesh Network

In Software on Jan 16, 2011 at 00:01

The recent packet relay and Extended node ID posts set the stage for a very simple way to create a fairly long-range (and very low-cost) little Wireless Sensor Network around the house.

Say hello to the Poor Man’s Mesh Network :)

Screen Shot 2011 01 14 at 13.54.50

(the main computer doesn’t have to be a PC/Mac, an embedded Linux box would also work fine)

Well, that’s a bit presumptuous. It’s not really “mesh” in the sense that there is no dynamic or adaptive routing or re-configuration involved at all. All the packet routes are static, so failure in one of the relays for example, will make everything “behind” it unreachable. In the world of wireless, that matters, because there are always unexpected sources of interference, and occasionally they completely wipe out the ability of a network to communicate on a given frequency band. For example, a couple of times a year, the data I’m collecting from my electricity and gas meters here at JeeLabs just stops getting in. Not sure what’s going on, but I’m not touching that setup in any way, and it’s unrelated to power outages. It might not be an RF issue, but who knows.

So what I’m referring to is not a super-duper, full-fledged, kitchen-sink-included type of wireless network. But given the extremely low cost of the nodes, and the fact that the software needs less than 4 kb of code, I think it’s a good example of how far you can get when using simplicity as guiding principle. Even an 8-bit MPU with 8 Kb of flash and 512 bytes of RAM would probably be sufficient for sensor nodes – so with the ATmega328’s used in JeeNodes, we really have oodles of spare capacity to implement pretty nifty applications on top.

Most of the details of how this works have already been presented in previous posts.

The one extra insight, is that the packet relay mechanism can be stacked. We can get data across N relays if we’re willing to limit our data packets to 66-N bytes. So by sacrificing a slight reduction in payload length we can extend the number of relays, and hence the total maximum range, as much as we like. Wanna get 10 times as far? No problem, just place a bunch of relays in the right spots along the whole path. Note that ACK round-trip delays will increase in such a setup.

The big design trade-off here is that all packet routing is static, i.e. it has to be set up manually. Each sensor node (the stars in that diagram) needs to have a netgroup which matches a relay or central node nearby, and within each netgroup each sensor node has to have a unique ID.

It’s not as bad as it may seem though. First of all, the range of the RFM12B on 433, 868, and 915 MHz is pretty good, because sub-GHz radio waves are far less attenuated by walls and concrete floors than units operating at 2.4 GHz. This means that in a small home, you wouldn’t even need a relay at all. I get almost full coverage from one centrally-placed node here at JeeLabs, even though the house is full of stone walls and reinforced concrete floors. As I mentioned before, I expect to get to curb and to the far end of our (small) garden with one or two relay hops.

Second, this star topology is very easy to adjust when you need to extend it or make changes – especially if all packet relays are one “hop” away from the central node, i.e. directly talking to it. You can turn one relay off, make changes to the nodes behind it, and then turn it back on, and the rest of the network will continue to work just fine during this change.

I’ve extended the groupRelay.pde sketch a bit further, to be able to configure all the parameters in it from the serial/USB side. These settings are saved in EEPROM, and will continue to work across power loss. This means that a relay node can now be as simple as this:

Dsc 2412

IOW, a JeeLink, plugged into a tiny cheapo USB power adapter. All you need to do is pre-load the groupRelay sketch on it (once), adjust its settings (as often as you like), and plug it in where you need it. How’s that as maintenance-free solution? And you can add/drop/alter the netgroup structure of the entire network at any time, as long as you’re willing to re-configure the affected nodes. If some of them turn out to be hard to reach because they are at the limit of the range, just insert an extra relay and tell the central software about the topology change.

It doesn’t have to be a JeeLink of course. A JeeNode, or some home-brew solution would work just as well.

Now that this design has become a reality, I intend to sprinkle a lot more sensors around the house. There have been lots of little projects waiting for this level of connectivity, from some nodes outside near the entrance, to a node to replace one of the first projects I worked on at JeeLabs!

So there you go. Who needs complexity?

Extended node IDs

In Software on Jan 15, 2011 at 00:01

The packet relay implementation shown a few days ago has some properties which somewhat limit its usability.

It all has to do with node IDs. As a relay it all works fine, i.e. packets will get relayed as intended. But the problem is that with a relay, all the packets relayed into another netgroup appear to come from that single relay node.

To go into this, let’s first set up a relay with the following configuration:

  • the main netgroup is #1, the relay listens on netgroup #2
  • the central node in netgroup 1 is node 31
  • the relay node listens on netgroup 2 as node 31
  • the relay sends packets out to netgroup 1 as node 30

Here’s that setup:

Screen Shot 2011 01 14 at 12.05.01

So – in principle – we could have up to 59 sensor nodes for getting actual work done. But there’s a problem: all packets sent by nodes 1..30 in netgroup 2 look like packets coming from node 30 once they reach the central node in netgroup 1!

Note that this is no problem if the relay is only used to extend the range of a single node: all we have to do is give the relay the same number of the node in netgroup 1 as what is assigned to that single node in netgroup 2.

But with more nodes behind the relay, we’re losing all their node ID’s. This is not very practical if we need to know exactly where the reported sensor data was generated, for example. We’re hitting the limitation that there are only 31 different ways to identify all incoming packets!

The solution is to insert the node ID of the original node as first byte of the payload data. So a packet coming from say node 7 in netgroup 2, will come in as a packet from node 30 (the relay), with an extra byte inserted in front of the packet, containing the value 7. The groupRelay.pde sketch has been extended to support this “multi-node relaying” capability.

On the receiving end, the software needs to know that node 30 in netgroup 1 is a relay. It then knows that the first byte is not data but an “extended” node ID, and it can use that to re-identify the packet as coming from a node in netgroup 2.

The extra data byte means that the maximum payload length across a relay is one byte less than what the nodes in netgroup 1 can send to the central node, i.e. 65 bytes instead of the 66 bytes supported by the RF12 driver.

Let’s use some conventions for node ID’s to support this mechanism. Node ID’s will be assigned as follows:

  • node ID’s 1..26 are available for “real” end points, e.g. sensor nodes
  • node ID’s 27..30 are available for relays and other “management” nodes
  • node ID 31 is to be used as standard ID for the central receiver
  • node ID 31 is also used by relays on the listening side
  • lastly, node 31 is normally the node which always listens, and which sends out ACKs

Note that there is nothing in the RF12 driver implementation which enforces such a numbering scheme. It’s just a convention to simplify configuration, and to simplify the software later on.

This scheme has the following implications:

  • the maximum number of end point sensor nodes is 26 x 250 = 6,500 nodes
  • each netgroup can have at most 4 group relays, i.e. the “fanout” is up to 4
  • each relay introduces a “hop” and may reduce the max payload size by one byte

Tomorrow, I’ll describe how to use this in a larger context.

Nodes, Addresses, and Interference

In Software on Jan 14, 2011 at 00:01

The RF12 driver used for the RFM12B module on JeeNodes makes a bunch of assumptions and has a number of fixed design decisions built-in.

Here are a couple of obvious ones:

  • nodes can only talk to each other if they use the same “net group” (1..250)
  • nodes normally each have a unique ID in that netgroup (1..31)
  • packets must be 0..66 bytes long
  • packets need an extra 9 bytes of overhead, including the preamble
  • data is sent at approximately 50,000 baud
  • each byte takes ≈ 160 µs, i.e. a max-size packet can be sent in 12 milliseconds

So in the limiting case you could have up to 7,500 different nodes, as long as you keep in mind that they have to share the same frequency and therefore should never transmit at the same time.

For simple signaling purposes that’s plenty, but it’s obvious that you can’t keep a serious high-speed datastream going this way, let alone multiple data streams, audio, or video.

On the 433 or 868 MHz bands, the situation is often worse than that – sometimes much worse, because simple OOK (which is a simple version of ASK) transmitters tend to completely monopolize those same frequency bands, and more often than not, they don’t even wait for their turn so they also disturb transmissions which are already in progress! Add to that the fact that OOK transmitters often operate at 1000 baud or less, and tend to repeat their packets a number of times, and you can see how that “cheap” sensor you just installed could mess up everything!

So if you’ve got a bunch of wireless weather sensors, alarm sensors, or remotely controlled switches, chances are that your RF12-based transmissions will frequently fail to reach their intended destination.

Which is why “ACKs” are so important. These make it possible to detect when packets get damaged or fail to arrive altogehter. An ACK is just what the name says: an acknowledgement that the receiver got a proper packet. No more no less. And the implementation is equally simple, at least in concept: an ACK is nothing but a little packet, sent the other way, i.e. back from the receiver to the original transmitter.

With ACKs, transmitters have a way to find out whether their packet arrived properly. What they do is send out the packet, and then wait for a valid reply packet. Such an “ACK packet” need not contain any payload data – it just needs to be verifiably correct (using a checksum), and the transmitter must somehow be able to tell that the ACK indeed refers to its original packet.

And this is where the RF12 driver starts to make a number of not-so-obvious (and in some cases even unconventional) design decisions.

I have to point out that wireless communication is a bit different from its wired counterpart. For one, everyone can listen in. Radio waves don’t aim, they reach all nodes (unless the nodes are at the limit of the RF range). So in fact, each transmission is a broadcast. Whether a receiver picks up a transmitted packet is only a matter of whether it decides to let it through.

This is reflected in the design of the RF12 driver. At the time, I was trying to address both cases: broadcasts, aimed at anyone who cares to listen, and directed transmissions which target a specific node. The former is accomplished by sending to pseudo node ID zero, the latter requires passing the “destination” node ID as first argument to rf12_sendStart().

For the ACK, we need to send a packet the other way. The usual way to do this, is to include both source and destination node ID’s in the packet. The receiver then swaps those fields and voilá… a packet ready to go the other way!

But that’s in fact overkill. All we really need is a single bit, saying the packet is an ACK packet. And in the simplest case, we could avoid even that one bit by using the convention that data packets must have one or more bytes of data, whereas ACKs may not contain any data.

This is a bit restrictive though, so instead I chose to re-use a single field for either source or destination ID, plus a bit indicating which of those it is, plus a bit indicating that the packet is an ACK.

With node ID’s in the range 1..31, we can encode the address as 5 bits. Plus the src-vs-dest bit, plus the ACK bit. Makes seven bits.

Why this extreme frugality and trying to save bits? Well, keep in mind that the main use of these nodes is for battery-powered Wireless Sensor Networks (WSN), so reducing power usage is normally one of the most important design goals. It may not seem like much, but one byte less to send in an (empty) ACK packet reduces the packet length by 10%. Since the transmitter is a power hog, that translates to 10% less power needed to send an ACK. Yes, every little bit helps – literally!

That leaves one unused bit in the header, BTW. Whee! :)

I’m not using that spare bit right now, but it will become important in the future to help filter out duplicate packets (a 1-bit sequence “number”).

So here is the format of the “header byte” included in each RF12 packet:

Screen Shot 2011 01 13 at 23.35.02

And for completeness, here is the complete set of bytes sent out:

Screen Shot 2011 01 13 at 23.34.14

So what are the implications of not having both source and destination address in each packet?

One advantage of using a broadcast model, is that you don’t have to know where to send your packet to. This can be pretty convenient for sensor nodes which don’t really care who picks up their readings. In some cases, you don’t even care whether the data arrived, because new readings are periodically being sent anyway. This is the case for the Room Nodes, when they send out temperature / humidity / light-level readings. Lost one? Who cares, another one will come in soon enough.

With the PIR motion detector on Room Nodes, we do want to get immediate reporting, especially if it’s the first time that motion is being detected. So in this case, the Room Node code is set up to send out a packet and request an ACK. If one doesn’t come in very soon, the packet is sent again, and so on. This repeats a few times, so that motion detection packets reach their destination as quickly as possible. Of course, this being wireless, there are no guarantees: someone could be jamming the RF frequency band, for example. But at least we now have a node which tries very hard to quickly overcome an occasional lost packet.

All we need for broadcasts to work with ACKs, is that exactly one node in the same netgroup acts as receiver and sends out an ACK when it gets a packet which asks to get an ACK back. We do not want more than one node doing so, because then ACKs would come from different nodes at the same time and interfere with each other.

So normally, a WSN based on RFM12B’s looks like this:

Screen Shot 2011 01 13 at 23.35.09

The central node is the one sending back ACKs when requested. The other nodes should just ignore everything not intended for them, including broadcasts.

Note that it is possible to use more than one receiving node. The trick is to still use only a single one to produce the ACKs. If you’re using the RF12demo sketch as central receiver, then there is a convenient (but badly-named) “collect” option to disable ACK replies. Just give “1c” as command to the second node, and it’ll stop automatically sending out ACKs (“0c” re-enables normal ACK behavior). In such a “lurking” mode, you can have as many extra nodes listening in on the same netgroup as you like.

To get back to netgroups: these really act as a way to partition the network into different groups of nodes. Nodes only communicate with other nodes in the same netgroup. Nodes in other netgroups are unreachable, and data from those other nodes cannot be received (unless you set up a relay, as described a few days ago). If you want to have say hundreds of nodes all reporting to one central server, then one way to do it with RF12 is to set up a number of separate netgroups, each with one central receiving node (taking care of ACKs for that netgroup), and then collect the data coming from all the “central nodes”, either via USB, Ethernet, or whatever other mechanism you choose. This ought to provide plenty of leeway for home-based WSN’s and home-automation, which is what the RF12 was designed for.

So there you have it. There is a lot more to say about ACKs, payloads, and addressing… some other time.

Another topic worth a separate post, is using (slightly) different frequencies to allow multiple transmissions to take place at the same time. Lots of things still left to explore, yummie!

Packet relaying vs. storage

In Software on Jan 13, 2011 at 00:01

In yesterday’s post I introduced a groupRelay.pde sketch, which implements a packet relay.

This can be used to (approximately) double the range between sensor nodes and the central data-collecting node. I’ve got two uses for this myself:

  • To try and get through two layers of reinforced concrete here at JeeLabs, i.e. from the garage to the living room to the office floor where my central data-collecting node is. I can get through one floor just fine (easily, even with a few extra walls), but two is giving me trouble.

  • To have a simple way to work with multiple groups of JeeNodes around here for testing and experimentation, while still allowing me to “merge” one of the test groups with the main, eh, “production” group. This can easily be accomplished by turning a suitably-configured relay on or off.

Note that all traffic takes place in the same 868 MHz frequency band. This isn’t a way to double the amount of bandwidth – all the packets flying around here have to compete for the same RF air space. All it does is separate the available space into distinct logical groups, i.e. net groups, which can be used together.

To summarize from yesterday’s post, this is how the relay code works right now:

Screen Shot 2011 01 12 at 18.07.18

If you think of time as advancing from top to bottom in this diagram, then you can see how the packet comes in, then gets sent out, then the ACK comes in, and finally the ACK gets sent back to the originating node. Let’s call this the Packet pass-through (PPT) approach.

This is very similar to how web requests work across the internet. There is an “end-to-end” communication path, with replies creating one long “round trip”.

But that’s not the only way to do things. The other way is to use a Store-and-forward (SAF) mechanism:

Screen Shot 2011 01 12 at 18.07.30

In this case, the relay accepts the packet, stores it, and immediately sends back an ACK to the originating node. Then it turns around and tries to get the stored packet to its destination.

This is how email works, BTW. The SMTP servers on which email is built can all store emails, and then re-send those emails one step closer to their intended destination.

There are several differences between PPT and SAF:

  • with PPT, it takes longer for the originating node to get back an ACK
  • with SAF, you get an ACK right away, even before the destination has the data
  • with PPT, all failures look the same: no proper ACK is ever received
  • with SAF, you might have gotten an ACK, even though the destination never got the data
  • with PPT, the logic of the code is very simple, and little RAM is needed
  • with SAF, you need to store packets and implement timeouts and re-transmission

But perhaps most importantly for our purposes, PPT allows us to place payload data in the ACK packet, i.e. ACKs can contain replies, whereas with SAF, you can’t put anything in an ACK, because the originating node already got an empty ACK from the relay.

Since SAF is harder to implement, needs more storage, and can’t handle ACK reply data, it just an inferior solution compared to PPT, right?

Not so fast. The main benefit of SAF, is that it can deal with nodes which don’t have to be available at the same time. If the relay is always on, then it will always accept requests from originating nodes. But the destination nodes need not be available at that time. In fact, the destination node might use polling, and ask the intermediate relay node whether there is data waiting to be sent out to it. In effect, the SAF relay now becomes sort of a PO box which collects all incoming mail until someone picks it up.

The implications for battery-powered wireless networks are quite important. With an always-on relay node in the middle, all the other nodes can now go to sleep whenever they want, while still allowing any node to get data to any other node. The basic mechanism for this is that the low-power nodes sleep most of the time (yeay, micro power!) and then periodically contact the relay node in one of two ways:

  • sending out a packet they want to get to some other place
  • polling the relay to get data waiting for them back as ACK reply data

The “sleep most of the time” bit is an essential aspect of low-power wireless networks. They can’t afford to keep a node awake and listening for incoming wireless packets all the time. An RFM12B draws about 15 mA while in receive mode (more than an ATmega!), and keeping it on would quickly deplete any battery.

So if we want to create an ultra low-power wireless network, we will neeed a central relay node which is always on, and then all the other nodes can take control over when they want to send out things and ask for data from that central node whenever they choose to. Which means they could sleep 99.5% of the time and wake up for only a few milliseconds every second, for example. Which is of course great for battery life.

BTW, in case you hadn’t noticed: we’re now entering the world of mesh-networking…

But the drawbacks of SAF remain: more complex logic, and the need to be able to queue up a lot of packets. So we need one node which is always on, and has plenty of memory. Hmmm, ponder, ponder… I remember having seen something suitable.

Of course: the JeeLink! It draws power via USB and has a large DataFlash memory buffer. Whee, nice! :)

Relaying RF12 packets

In Software on Jan 12, 2011 at 00:01

Since the RF12 driver does not implement a full OSI network “stack”, there are no such things as routers and mesh networks in Jee-land. This means you’re basically limited to the range of a single 868/915 MHz point-to-point packet connection.

There are a number of ways to increase the range. One is to use a directional antenna (I’ve never tried this, but it has been mentioned on the discussion forum). Another option is to lower the transmission baud rate inside the radio and the bandwidth settings, so that the power is “beamed” into a narrower frequency range. Both of these are based on RF properties.

A third option if you can’t get from here to there in one go is to take multiple “hops”. That’s what a mesh network tries to do fully automatically, adapting on the fly to varying reception conditions and network topologies.

I’m more interested in much simpler approaches, which can easily be implemented in a little 8-bit ATmega with limited code storage. There’s a lot we can do, even within these pretty hard constraints – and it’s fun to push those little boundaries!

So here’s another option: a dedicated “packet relay” node, which listens to a specific RF12 net group most of the time, and when a packet comes in, it turns around and sends the packet out over another net group. Apart from picking two net groups for this, the mechanism should be fairly transparent.

Here’s what happens when you install such a relay:

Screen Shot 2011 01 11 at 23.44.59

That only covers packets going one way. A refinement is to also deal with ACK packets. In that case, the relay should wait a little while to see whether an ACK comes in, and if it does, send that ACK back out to the original packet source:

Screen Shot 2011 01 11 at 23.45.05

Here’s a groupRelay.pde sketch, which implements this:

Screen Shot 2011 01 11 at 23.58.18

It’s pretty straightforward. But it’s only made for broadcast scenarios, i.e. the originating node must be using a broadcast packet (i.e. send to special node “0”). The relay can then simply re-broadcast the information.

In the case of ACKs, the originating node id will be in the header. The relay saves this, sends out a packet with an ACK-type request of its own, waits briefly for such an ACK to come in, and when it does, sends an ACK back to the originating node.

Note how the loss of packets will have the same effect as without a relay. The only difference being that there are 2 hops (or 4 w/ ACK) where packets can be lost or get damaged.

Tomorrow, I’ll explain a little bit what’s going on and what sorts of trade-offs this leads to.

Kit with SMD parts

In Hardware on Jan 11, 2011 at 00:01

A few weeks ago, I ordered a DDS-60 kit, because I wanted to do some experiments with an adjustable frequency generator. The kit is very interesting because it is controlled via a microcontroller, and because it works from 1 to 60 MHz, which is quite an impressive range for such a simple module:

Dds 60 (top) 400a

The other intriguing aspect was that it is built with SMD parts, so this kit needs to package a lot of very small components. Here’s what I got:

Dsc 2394

Very nice package. Not only are the parts individually labeled, they even were color-marked on one side. Here’s the SMD resistor / capacitor packaging in more detail:

Dsc 2396

What is a bit hard to see, is that these parts were actually sandwiched between a sheet of paper and a sheet of transparent adhesive plastic.

It was great fun to put together (I haven’t had an opportunity to try it out yet, but there is ATmega software for it among a long page of other options).

My curiosity was triggered because I found that the production of SMD kits such as the JeeSMD is fairly labor intensive.

We’re bound to go there more and more though, as an an increasing number of DIP-packaged through-hole chips and sensors are starting to disappear.

I’m not sure what that means for the future of Physical Computing hobbyists. It could go a couple of ways, IMO:

  • more and more “break-out boards” with the small chip pre-soldered
  • more SMD-style kits like the DDS-60, for hand-soldering with tweezers
  • a move towards low-end reflow controllers with manually-applied solder paste
  • … something else?

The first feels a bit more Lego-like to me, though it’s really an artificial distinction – as hobbyists, we’ve never manufactured the chips ourselves either, so it’s just one small “pre-fab” step extra.

Soooo… given the choice, in which direction would you want JeeLabs to go?

Wiki docs

In News on Jan 10, 2011 at 00:01

I’ve started adding some more info to the new “JeeLabs Café” wiki at http://jeelabs.net/.

First change is that all products (boards, plugs, etc) now include at least these four files:

  • jlpcb-<NNN>.pdf – the schematic as a PDF page
  • jlpcb-<NNN>.sch – the schematic as EAGLE schematic (binary data)
  • jlpcb-<NNN>.png – the board traces as a PNG image
  • jlpcb-<NNN>.brd – the board design as EAGLE board (binary data)

The files are listed at the bottom of each page mentioned on the Hardware list (a read-only sub-area of the Café).

I’ve also started adding pointers to relevant weblog posts on these product pages. For example, the end of the JeeNode page now looks like this:

Screen Shot 2011 01 09 at 23.01.50

The other addition, is that I’m going to start adding pages focused around specific topics, acting as quick indexes into the weblog. The “stream of conscience” timeline that makes up the daily weblog is probably fine if you’ve been following along for some time and tend to read or skim most new pages fairly regularly. But for anyone stumbling upon this jeelabs.org site out of the blue, I suspect that this site is really nearly impenetrable by now.

I don’t intend to the change the style and approach of the daily weblog, because it really is sort of a diary of my adventures through Physical Computing, finding my way around as a maker, and getting to grips with atoms. With all the ups, downs, exciting advances, and dead ends that I happen to bump into at JeeLabs.

But for task-specific and topic-specific access, it makes more sense to have an index to locate specific posts and perhaps annotate them a bit if the weblog entry is incomplete or obsolete by now.

Here’s the new Easy Electrons page on the Café to kick this off:

Screen Shot 2011 01 09 at 22.52.42

This new Easy Electrons index page is mentioned on the main Projects page.

The main page of the Café is still a bit crude, but there are a couple of automatically-generated pages worth visiting to find your way around in the Café, eh, I mean wiki:

Note also that the short URLs printed on all the pcb’s and on the package labels have been adjusted to point to pages in the Café. So when you type jeelabs.org/jn4 into your web browser, you’ll see a page which tells you that it’s a JeeNode v4, provides some info about it, and mentions that there is now a newer version.

I haven’t filled in all the older versions with full details yet, but for all current products, that two-letter-plus-a-digit code will always get you to the latest information in the Café.

Is everything perfect today? No… not by a long shot. But I hope this’ll let us move in that direction.

Easy Electrons – Diodes

In Hardware on Jan 9, 2011 at 00:01

It’s time for some Easy Electrons again.

Semiconductors are at the heart of today’s electronics designs: diodes, transistors, and the huge advances made possible by Integrated Circuits (i.e. IC’s) is what makes all those electronic devices around us possible. And it all happened in the time scale of just a few decades…

I can’t possibly cover everything in this series, so I’ll cover the two most common ones for now: the diode today, and the “normal” (BJT) transistor in the next installment.

Very roughly speaking, a diode is a one-way conductor. This is also indicated by the schematic symbol used for diodes (image from Wikipedia):

800px Diode 3d and ckt

The arrow-like symbol points in the direction of the current flow, if you stick with the convention that current flows from “+” to “—”. If you keep forgetting which side is called the Anode and which the Cathode, this trick might help: in the alphabet, we (eh, I mean currents) go from A (to B) to C.

Diodes are useful to protect a circuit against connecting a power source the wrong way around (we’ve all been there, right?):

Screen Shot 2011 01 08 at 22.40.28

With this diode, the circuit is protected. Hooked up the wrong way, the diode will block, so no current will flow through the circuit.

But diodes aren’t perfect. There’s a voltage drop when conducting current, usually around 0.7V. So with the above circuit, if the power supply is 5.0V, then the circuit will only get about 4.3V. With low-voltage components, and especially battery-powered devices, this sort of voltage loss is awkward – and often unacceptable.

Which is why you won’t see this reverse voltage protection very often in circuits operating at 5V, 3.3V, or less. There is another type of protection, however:

Screen Shot 2011 01 08 at 22.40.40

This one is a bit nasty. It doesn’t really prevent the circuit from getting a reversed voltage at all. Instead, it will act (almost) like a short circuit when the voltage is applied the wrong way around. The idea being that this will cause the power supply to shut down (or the battery to drain very quickly). The RBBB uses this type of protection to overcome the voltage drop problem. The (cheap) diode will protect the (much more valuable) ATmega, as well as all other components hooked up to it.

This sort of protection is tricky. If you were to connect a LiPo battery, for example, then the short circuit can cause HUGE currents to flow, since many LiPo’s are able to supply them. Think many Amps… and now something else may happen: even if the diode can handle the current, the rest of the power lines might well become overloaded. Especially thin copper traces on a PCB are likely to act like a fuse and simply… evaporate!

There are other ways to deal with the voltage drop and still end up with diode protection. One of them is to minimize the voltage drop – this is where Schottky diodes can be useful. They usually have only half the voltage drop of normal diodes, i.e. around 0.3V. That might just be low enough for your particular setup.

Another option is to build an “ideal diode”. This might sound like an impossible task, given the properties of diodes, but there is actually a way to do this using a MOSFET. I won’t go into MOSFETs here, but basically they can switch current while having almost no resistance and (Ohm’s law!) therefore also almost no voltage drop. Trouble is: MOSFETs don’t know which way the current is flowing, so you need considerable extra circuitry to tell them when to turn on and off, based on comparing voltages on both ends. And although it is not a simple or cheap solution, this datasheet of the LTC4413 chip shows that it is indeed possible to beat the diode characteristics with some clever engineering. Electronics is often like that: people have come up with the most amazing tricks to overcome certain drawbacks, for all sorts of electronic circuit tasks. That’s why it’s so much fun just exploring and discovering it all, IMO :)

The graph of what a diode does is very characteristic: in reverse mode it blocks, and in forward mode (i.e. above around 0.7V) it conducts, albeit not perfectly. For some good example graphs see this page on Wikipedia (just skip the math formulas and look at the pretty pictures).

Now, assuming the voltage drop is no problem, because you’ve got some extra volts from the power supply anyway, then diodes can be extremely useful. The bridge rectifier for example, can be used to get a properly polarized voltage out, regardless of how the power supply is hooked up. This is particularly useful with alternating current, as present on the AC mains lines and on the coils of a transformer (a lot more Easy Electrons articles will be needed to present all this stuff!).

Another interesting diode is the Zener diode. It’s like a regular diode, but one which can’t support a very high reverse voltage. With Zeners, this voltage is called the “breakdown voltage”, and it ranges from about 2..200V. The value is fixed for any particular model.

Zener diodes make very simple (low-current) regulated power supplies:

Screen Shot 2011 01 08 at 23.03.19

Note how we’re putting the Zener in reverse mode, and counting on it to break down. As it does, current will start to flow. Until enough current is flowing across the resistor (Ohm’s law!) to take up all the “remaining” voltage.

So with a resistor of 100 Ω, and a Zener of 5.0V, we could power it with say 6..9V. At 6V, the current would be (6 – 5) / 100 = 10 mA. At 9V, the current would stabilize at (9 – 5) / 100 = 40 mA.

The reason this can be used as a regulated power supply, is that we can connect our circuit in parallel with the Zener, and it would always get 5V. The only drawback is that we can’t draw more than 10 mA from it:

  • at 6V, the resistor needs to “eat” 1V, so that the Zener ends up with 5V
  • if the circuit draws 10 mA, then 0 mA will go through the Zener
  • if the circuit draws 5 mA, then 5 mA will go through the Zener
  • if the circuit draws 0 mA, then 10 mA will go through the Zener
  • at 9V, the current will increase to 40 mA (to get 4V over the resistor)
  • in all cases, the circuit will see a 5V input voltage

Cool, so now we have built ourselves a simple regulated power supply!

As I mentioned, this circuit is not very powerful. If we draw more than 10 mA, then the voltage drop over the resistor may increase, leaving less than 5V for our circuit.

There is another drawback with the above regulated supply: it’s grossly inefficient. The reason is that it will always draw 10 mA, whether our circuit needs it or not. And that’s at 6V – at 9V it will always draw 40 mA!

I’ll show you how a transistor can easily increase the current and improve the regulating efficiency in a future installment. Exploring these simple electronic circuits can be great fun, and most of the time you can reason your way through without even having to build them!

Next time: transistors – incredibly useful devices, with tons of ways to use ’em!

PS. Does anyone have tips on how to improve these diagrams? I really want to continue drawing them by hand, but the texts don’t come out very nice, no matter what I try!

Life resumes

In Musings on Jan 8, 2011 at 00:01

This thing came in recently – yippie!

Dsc 2410

Eh, 10.000 of them in fact – that ought to be enough for a while! ;)

In the past two days, I’ve been going through all the back-orders and sending out over 50 of them in fact. Note that most orders are bigger orders, since all the small and easy ones had already been dealt with.

This also brought out a serious shortcoming in my store’s inventory tracking system. I can see how many items are left (by going through the shelves and counting stuff), but I can’t see how much of those items are “already taken”, i.e. reserved for current back-orders.

Now in general, that’s not such a big deal, because most items are supposed to be in stock and the back-order is (should be!) low on most days. It was just a matter of making a mental note and taking care of the low-stock stuff.

But with so many items sold-but-not-yet-shipped, I’ve started seeing an avalanche effect: finding out that most of the stuff on the shelves was going much faster than anticipated while taking care of back-orders, and even running into some new shortages. Yuck.

This has happened to Ether Cards (now resolved), and has just happened to Carrier Boards as well (will be resolved in 2nd half of this month). Oh, and then there’s that 2×16 LCD which I think are in customs right now.

Summary: if you’re waiting for stuff, please hang in there. There’s more coming this weekend, but I’m not going to go all out 7 days a week and risk my health again. Been there, done that – I can now confirm from experience that it’s counter-productive.

In the atoms world, some limits, constraints, and delays are hard. Can’t do much else but respect that.

The good news is that I’ve just implemented some new tracking logic in my shop database, giving me real-time insight in those “already taken” figures. It’s nice to be on the consuming end of a database system for a change (I used to be on the producing end in a previous life).

Sorry for this somewhat off-topic post, but I’m going to call this Feierabend and enjoy the rest of this Friday evening watching a TV series with a nice sip of whisky. More substantial content to resume tomorrow.

LED discharge – measure or simulate

In Hardware on Jan 7, 2011 at 00:01

Yesterday’s post tried to create a new data point for measuring the forward drop voltage over a red LED at a slightly higher current. To summarize:

  • the voltage over the LED was read out as 2.229 V
  • the LED current was calculated to be 10.71 mA

But not so fast. What about component tolerances? What if the 100 Ω resistor isn’t exactly 100 Ω? And what if the supply voltage isn’t exactly 3.3 V?

It turns out that there’s quite a bit more going on here. Time to get the multimeter out and measure these values. If nothing else, this will be useful as cross-check against everything we did so far.

Here’s what I found (expected vs. actually measured):

  • 3.3V power supply = 3.298 V
  • “1” on VIN = 3.036 V (!)
  • “0” on VLOW = 0.213 V (!)
  • voltage over LED = 2.011 V
  • 100 Ω resistance = 99.7 Ω
  • current out of VIN = 7.85 mA
  • current into VLOW = 7.72 mA

Whoa – very different outcomes!

First off, this is a Voltcraft VC940 multimeter with 5-digit readout and a specified accuracy on DC voltage and current ranges (substantially) below 1%. For up to 4V, that means it shouldn’t be off by more than 20..30 mV, worst case.

First the good news: the power supply voltage on the 3.3V rail is very close to the desired voltage (3298 mV).

But check out those “1” and “0” digital I/O voltages: they are 3036 and 213 mV, respectively, i.e. around 10% off!

There’s a very simple explanation for that, and as it turns out, it’s in fact fully according to specs. Here is the output voltage you get when powering an ATmega at 3V, while drawing some current from one I/O pin:

As you can see, there’s just about a 0.3V drop at 25°C when drawing 10 mA. These I/O pins were not meant to be used as power supplies for other circuits, let alone as reference for analog circuitry.

Another way to put it, is that an I/O pin on an ATmega has an internal resistance of around 30 Ω. It’s easy to see that when we start drawing several milliamps through a 100 Ω resistor, then those “perfect” I/O signal lines are in fact a lot less like a real switched power supply.

The same holds for the “0” pin voltage levels. Once you start dumping current into such an I/O line, it will start to look more and more like a resistor tied to ground, and not just a direct connection to ground.

So the first conclusion is that the LED isn’t being fed as much current as we had expected, because the voltage levels are not quite 3.3V and 0V.

Let’s recaclulate our results with this new insight:

  • VIN = 3.036 V
  • VHIGH = 2.229 V (same as before, via the ADC)
  • VLOW = 0.213 V
  • voltage over the LED = 2.229 – 0.213 = 2.016 V
  • 99.7 Ω resistor voltage = 3.036 – 2.229 = 0.807 V
  • current through resistor = 0.807 / 99.7 = 8.1 mA

Ah, that’s a lot better: 2.016 V calculated vs. 2.011 V measured, and 8.1 mA calculated vs. 7.85 mA measured (about 3% off, oh well).

One last puzzle: why is the current measured out of VIN not the same as the current into VLOW?

You’ll need to check the schematic again to see what’s going on. Since the VLOW voltage is not 0V as would be the case with a perfect I/O output, there is now also some current flowing from VLOW to GND, through that other 1 kΩ resistor.

How much? Well, Ohm’s law points to the answer, as always: 0.213 V over 1 kΩ means there is 0.21 mA flowing through that resistor. Since the only source of power is VIN, and since all current must flow either into VLOW or GND, this means we can add that 0.21 mA to 7.72 mA to get 7.93 mA total.

Ok, it’s not conclusive in that some unexplained differences still remain, but this is nevertheless a lot closer to the real values in the circuit than the original 2.2V @ 11 mA we arrived at earlier.

Note that we don’t really need a multimeter to be able to make these corrections. I could have tied VIN to another analog input, to be able to use the digital I/O as (imperfect) power supply for the circuit, while at the same time measuring the voltage drop due to the higher current. I’ll leave that as an exercise for the reader.

There’s a lot more to be said about this sort of design and measurement work. Electronics is a very large field, and all we did so far, was hook up 4 simple components!

One very interesting option, is to simulate the circuit instead of building it on a breadboard. There is a well-known application for that called SPICE which takes a circuit description and computes, time step by time step, how the circuit behaves when subjected to certain input signals and power conditions.

JGJ Veken (Joop on the forum & wiki) was very kind to help out with a simulation of the LED discharge circuit I’ve been describing in these weblog posts. Here’s what came out:

Spice led Discharge

The voltage levels are slightly different, because the LED charateristics are different, but you can clearly see more or less the same graph as shown in yesterday’s post. Just to drive tht point home: yesterday’s results were measured in a real circuit, whereas the graph above is a simulation performed 100% inside a computer.

To find out more about this exciting way to try out circuits and explore different parameter settings, see these excellent wiki pages by JGJ Veken: 5Spice and LTSpiceIV. These are two different systems (both with common ancestry), the former commercial but free for personal use, and the latter available from Linear Technology as freeware (I don’t think either of them is open source).

So there you have it. This concludes my mini-series about experimenting with simple components, and using JeeNodes and Arduino’s to investigate the circuit and create a simple test-jig setups for it. Combine that with the SPICE simulation options available out there, and you’ve got a very simple and low-cost way to exlore electronics for yourself. Transistors? Filters? Op-amps? Go for it – there’s a world out there to explore and tinker with!

LED discharge – more measurements

In Hardware on Jan 6, 2011 at 00:01

Following earlier posts about the LED discharge circuit (here, here, and here), let’s do a few more measurements. Here is the schematic again:

I’m going to apply a 1-second charge pulse and then disconnect for 5 seconds, as before. This time, I’m going to disable the pull-up during those 5 seconds, and improve the timing of the reporting so the time to send out characters over the serial port does not affect the whole measurement cycle:

Screen Shot 2011 01 05 at 13.09.50

The reason the timing is so much better in this version, is that it is now based on MilliTimer, which continues to count while the serial port deals with its outgoing data. Note that 20 chars @ 57600 baud takes a few milliseconds, which can quickly add up when reporting values 10x per second.

The values are sent out in a format which can be used directly in a spreadsheet – here are the first few lines of output:

Screen Shot 2011 01 05 at 13.10.55

The values are:

  • voltage measured over the capacitor, i.e. LED + 1 kΩ resistor (Volts)
  • voltage measured over the 1 kΩ resistor (Volts)
  • difference, i.e. voltage measured over the LED (Volts)

Here’s a graph of the resulting measurements:

Screen Shot 2011 01 05 at 12.42.29

Due to Ohm’s law (E = I x R, i.e. I = E / R), that yellow line is also the amount of current going through the resistor in milliamps. Since there is no other path for the current than through the LED, by deduction this is also the current through the LED.

What you can see (blue curve), is that the capacitor charges up within a fraction of a second, and then discharges to under 2V in the next 5 seconds.

What you can also see (yellow curve) is that the current through the LED is proportional to the voltage on the capacitor. As the capacitor charges up, the current increases, and from the shape of the curves is should be clear that the relationship is essentially linear.

This is not surprising, since linear voltage-vs-current curves are inherent to resistive loads, i.e. the 1 kΩ resistor in this case. What is special is the LED placed in series with that resistor. What it does is “eat up” a fixed voltage, i.e. 1.8..1.9 V of the voltage present on the capacitor “stays” in the LED. The rest is passed on to the resistor, which does its usual linear current-to-heat conversion thing (only milliwats of heat in this case – we’re dealing with very small currents and very low voltages here).

But LEDs are not perfect devices. If they were acting like a perfect diode, they would have a fixed voltage drop, regardless of how much current goes through them. You can see from the green line that there is a slight change in voltage drop.

Does that mean a LED has something like a “hidden resistor” inside it? Not really. Here’s a plot over that same data, as current versus voltage:

Screen Shot 2011 01 05 at 12.50.33

That’s not very linear. Remember that resistors just do what Ohm’s law tells them to (or was it the other way around?): twice as much voltage = twice as much current, etc. Which in a graph would show up as a straight line.

In this case, the graph appears to be tapering off. In other words, as more and more current goes through the LED, its forward voltage seems to stabilize around a certain value. Probably around 1.9V, but this will be different for each type of LED.

Note that I placed the current on the horizontal axis, because that’s the variable we can control. The LED “decides” what voltage drop it wants to add.

What seems to be happening in this circuit, is that between 1.75 and 1.80 V there is a small amount of leakage. This is consistent with the video, showing that the LED continues to light up very dimly as the charge leaks away, even though the current is less than 0.25 mA, i.e. 250 µA, at these voltage levels!

Ok. Can we find out more about this forward voltage behavior? Sure. Let’s put 3.3V on VIN and 0V on VLOW, and then measure the voltage on VHIGH:

Screen Shot 2011 01 05 at 13.45.46

(Isn’t it fun to do this stuff under computer control?)

Sample output:

Screen Shot 2011 01 05 at 13.47.05

Whoa, looks like I need to revise my conclusions a bit. The LED forward voltage does go up quite a bit when more current is applied!

Let’s try to figure out how much current is flowing:

  • the cap is fully charged after a few seconds, so we can ignore it
  • therefore the cap voltage will be 2.229 V, as measured by the ATmega
  • and the voltage over the 100 Ω resistor will be 3.3 – 2.229 = 1.071 V
  • the resistor is 100 Ω so with “I = E / R”, we get 1.071 / 100 = 10.7 mA

IOW, at roughly 11 mA, the foward voltage drop of this particular LED is about 2.23V, quite a bit more than the 1.87 V we measured at 1 mA. But still not anywhere near a linear relationship.

Tomorrow, I’ll examine these results a bit more closely … because they aren’t quite right!

GLCD library

In Hardware, Software on Jan 5, 2011 at 00:01

There’s a new GLCD library to drive the 128×64 graphics LCD display on the Graphics Board. The library is called, wait for it… GLCDlib – with a wiki page and a web interface to the source code in subversion. There’s also a ZIP archive snapshot, but it probably won’t get updated with each future subversion change. For some notes about using subversion (“svn”), see this post.

The main class is “GLCD_ST7565”, it has the following members:

Screen Shot 2011 01 04 at 19.52.45

(some longer entries above were truncated, see the website for the full version)

The settings in this library have been hard-coded for use with the Graphics Board, which uses ports 1 and 4 to drive this display. If you want to use this with other I/O connections, you’ll need to change the #define’s at the top of the “GLCD_ST7565.cpp” source file in the library.

Here is the demo used in an earlier post, now included as “glcd_demo.pde” example sketch in the library:

Screen Shot 2011 01 04 at 19.49.49

This produces an output screen similar to this image. Note the use of flash-based string storage with “PSTR” to reduce RAM usage. It not an issue in this example, but more strings tend to rapidly consume RAM, leading to strange and hard-to-find bugs.

The nice thing about GLCDlib, is that you can also use it over wireless. There is a “GLCD_proxy” class, which sends all graphics commands out to another node. Each command is sent as a packet, complete with ACKs, retries, and resends to deal with lost packets.

The “JeePU.pde” example sketch implements the “host”, i.e. a JeeNode with Graphics Board, listening to incoming wireless requests. The “JeePU_demo.pde” sketch shows how to talk to such a remote JeePU node.

Because the transport layer (i.e. wireless or other comms mechanism) is separated out from the main graphics primitives, it is very easy to switch between a locally-connected GLCD and a remote one on a JeePU node. The magic is contained mostly in these lines:

Screen Shot 2011 01 04 at 20.02.40

The only other change needed to use a remote GLCD is to add these lines at the start of setup():

Screen Shot 2011 01 04 at 20.04.57

See the JeePU_demo.pde sketch for an example of how this can be used.

The JeePU node should be running in its own RF12 net group, because clients use broadcasts to send out the graphics commands. They do not need to know the node ID of the JeePU, just its net-group. This also means that multiple GLCD proxy clients can run at the same time, and each could be adjusting a specific part of the same JeePU display … whee, a multi-node status display!

One of the advantages of running the Graphics Board as a JeePU node, is that the other nodes don’t need to load the entire GLCDlib code, in particular they avoid the 1 Kb RAM buffer needed to drive the display.

The graphics code is based on what used to be the ST7565 library by Limor Fried at AdaFruit, which was in turn derived from public domain code attributed to “cstone@pobox.com”.

Several great extensions (and a couple of bug fixes) for the core graphics routines were written by Steve Evans (aka tankslappa on the wiki and forum). Steve also implemented the remote/proxy code and the JeePU “host” and JeePU_demo “client”.

I just hacked around a bit on all that, including renaming things and adding an ACK mechanism to the RF12 wireless layer.

This code is likely to change and extend further, as we come up with more things to do with the current implementation. But for now, enjoy :)

Update – all the code is now at https://github.com/jcw/glcdlib.

Thermo Murphy

In Hardware on Jan 4, 2011 at 00:01

Mr. Murphy strikes again in the new year…

A post a while back, mentioned that the NPN transistor footprint on the Thermo Plug was wrong. I should have tracked this down earlier, but due to all the supply issues I only found some time just now (with thanks to Lennart for helping figure this one out).

Here’s the board footprint:

Screen Shot 2011 01 03 at 12.08.50

It’s not hard to see that from left to right, the pinout is emitter-base-collector.

Guess what… NPN TO-92 transistor footprints are not standardized!

Here’s the one from the BC549 I’ve been shipping in a few recent units:

Screen Shot 2011 01 03 at 12.06.16

Bzzzt… you have to mount it the other way around to make it work!

To give you an example of the mess w.r.t. orientation, here’s a diagram I found on Solarbotics:

Pinouts

And here’s the one from the 2N4401 I’m going to use for the Thermo Plug from now on:

Screen Shot 2011 01 03 at 12.05.37

Well, at least it’s just mirrored, with the base always in the middle. Not quite as bad as with voltage regulators (such as with MCP1702 vs LM2940, where the order is completely different).

If you’ve got a kit with the BC549, please make sure to mount that transistor 180° rotated w.r.t. what’s shown on the pcb. All units sent out from now on will have an NPN transistor which matches what’s on the board.

New wire jumpers

In Hardware on Jan 3, 2011 at 00:01

Just a quick note that the current Wire Jumpers in the shop are going to be replaced with new ones very soon:

Dsc 2407

Instead of 50 wires, the new pack will have 70 wire jumpers, consisting of the following length, in various colors:

  • 50x 80 mm
  • 10x 125 mm
  • 5x 165 mm
  • 5x 205 mm

Same flexible wire as before, with the same easy-to-insert pins on both ends.

No downsides, no compromises. Just more wires and more variations!

Easy Electrons – Need more power

In Hardware on Jan 2, 2011 at 00:01

Welcome to another installment of the Easy Electrons series.

There have been a few posts about What is “power”?, but that was about the electrical concepts of power and energy, and how it relates to voltage and current.

In this post, I’d like to go into a different topic: how to control more powerful electrical devices. As you’ve seen in the LED discharge circuit post, the I/O pins of an ATmega can be used as weak power supply, sort of. This is because an output pin set to “1” can be used as a 3.3V (5V on Arduino) power source, as long as you don’t draw more than a few milliamperes of current.

Here are the specifications of what a single pin can do, taken from the ATmega datasheet:

Source Datasheet

A few milliamps is not much. Barely enough to light a LED, and far too little to drive even the simplest electric motor. Let alone a light, a heater, or any AC mains appliance.

The first thing to note, is that there are a lot of different ways to control power – and each approach has fairly rigid limitations. You could use a power transistor to drive a bright 12V halogen lamp, but that same transistor would fail (spectacularly and dangerously so) if you tried to use it to control even the smallest AC mains lightbulb. Controlling power is a tricky business. As voltages and currents increase, so do the risks and potential effects of failure.

Let’s start simple, with an LED strip. These strips often need 12V to light up, and use about 300..900 mA per meter. There are several ways to control an LED strip of up to a few meters – using a relay, transistor, or MOSFET, respectively:

Screen Shot 2010 12 29 at 10.20.57

The relay is is the oldest type of power switch, and easiest to understand: an electromagnet closes a switch while powered up. It has been around for centuries. And although I included it as option, in practice even the smallest relays draw more current than what an ATmega I/O pin can supply (apart from very low power reed switches).

The transistor was invented only a few decades ago, and is at the heart of every electronic circuit these days. It’s usually depicted as follows in schematic diagrams (image from Wikipedia):

200px Transistor 2.svg

There’s a lot more to say about this fascinating invention. For now, let me just say that you can feed it a small current and it’ll control a much larger current (and voltage) on another pin.

And then there’s the MOSFET, which is even more recent than the standard bipolar-junction transistor. MOSFETs are pretty incredible: feed it a few microamps, and it can switch a huge amount of current (dozens of amps!). Perfect for direct hook-up to a microcontroller.

So how do we control an LED strip?

Easy – with a MOSFET, for example:

Screen Shot 2010 12 29 at 10.33.02

Note that the LED needs 12V at a fairly high current, whereas something like a JeeNode tolerates 12V – and needs only a few milliamps. In this case, we can get away with connecting both power supply inputs to the same 12V. The built-in voltage regulator will immediately reduce that 12V input to the 3.3V used in the rest of the circuit. So the voltage on the MOSFET “gate” will only be 0V or 3.3V – fortunately, that’s enough for many common MOSFETs these days.

It’s important to note that all these voltages and currents are fairly independent. The following would work just as well, using two separate power supplies:

Screen Shot 2010 12 29 at 10.33.14

I’ve drawn some extra arrows to indicate how the different current paths work. The crucial point is that current always needs to go through a closed loop. If the current “came from” the power supply on the left, then it will also always “return” to that same left-side supply. Think of it as “tagged electricity” if you like: what goes out of a battery on one en must come back on the other end of that same battery. It doesn’t really matter whether you think of electricity as “flowing” from + to –, or electrons flowing from – to +.

Note the connection between “–” on the left and “–” on the right. Without it nothing will work. The reason for this, is that voltages are always relative to some other part of the circuit. You can’t have a voltage (or a current, for that matter) over a single wire. You always need a return path. So in the case of the MOSFET, to drive it and put a voltage on it, you need to connect two wires – even if the current is small, as in this case. That’s why “–” is usually called ground, i.e. the reference against which we measure everything else.

Does this matter? You bet. If the power circuit uses a lot of current, then all its conductors must be able to carry that current: it needs thick wires! – but at the same time, the rest of the circuit can still get by with thin copper traces, as usual on boards like the JeeNode. This means that the ground connections (“–”) may need to be thick on one side, but not on the other – even though all ground connections have to be electrically tied together!

Current flow and proper design of all the wiring and connections is essential in power circuits. It’s a lot more involved than with purely digital circuits, or circuits which carry just milliamps.

How about controlling a lightbulb connected to 220V (or 110V)?

One way is with a relay (designed for such high voltages). But a relay can’t be driven directly from an output pin – so we add a transistor in between:

Screen Shot 2010 12 29 at 10.42.01

The extra resistor and diode are required (for reasons I won’t go into right now).

Note that there is no connection between this circuit and the switch shown at the top which is used to control the lightbulb. That relay does something which is crucial in the case of AC mains: it adds an isolation barrier between the low-voltage (safe!) side of the circuit and the AC mains (potentially lethal!) side of the circuit.

The second common way to control such a lightbulb is a Solid state relay, which uses a built-in opto-isolator to provide the isolation barrier. The advantage of an SSR is that it has no moving parts – hence no mechanical wear.

I’ve only touched briefly on how you can hook up stuff which needs more power than a feeble ATmega output pin can provide. Follow the links above if you want to find out more.

And marvel at the amount of knowledge and understanding Wikipedia brings us, freely available to anyone with an internet connection, anywhere in the world!

Meilleurs voeux de Paris

In Musings on Jan 1, 2011 at 00:01

Happy new year!

We’re celebrating with a brief trip to Paris, visiting friends.

We’re just south of Paris actually, in a tiny village called Vauhallan. Won’t have the opportunity to go to the “real” Paris today, so here’s a mini-impression from this delightful little village …

Regular transmissions will resume tomorrow :)