Computing stuff tied to the physical world

Archive for May 2011

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: https://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 https://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 https://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!)