Computing stuff tied to the physical world

Archive for August 2010

Making 6-wire cables

In Hardware on Aug 31, 2010 at 00:01

I’ve been making cables for the Utility Plug recently. They come with the kit, but the reason for choosing these “modular” jacks and connectors, is that they are very easy to make yourself.

FYI, the 26 AWG wires in this type of cabling are rated for 360 mA current. Plenty for signaling and powering electronic stuff, but not suited for high power or high voltages.

I use the following low-cost crimp tool for most of my 4-. 6-. and 8-core cables:

Dsc 1851

Actually, I have a second one for 8-core cables (i.e. RJ-45 network cables) – it’s sturdier but also more expensive:

Dsc 1862

Here’s how the cable is made, from start to finish. First, make a clean straight cut:

Dsc 1852

Then you have to strip the outer mantle, without damaging the inner wires:

Dsc 1853

This is what comes out:

Dsc 1854

It fits perfectly into a “6P6C” RJ-12 modular plug (6 positions, 6 connections):

Dsc 1855

Now the magic part:

Dsc 1856

Seen from the other side, with the plug ready to be crimped on:

Dsc 1857

Here’s a before-and-after picture, you can see the metal pushed into the cable (and the cable jacket clamped for strain relief):

Dsc 1858

Another view:

Dsc 1859

How does it work? Well, here’s the crimp tool, in released state:

Dsc 1860

And here it is again, squeezed tight (it has a stop, ya can’t squeeze too far):

Dsc 1861

If you keep goin’ at it for a while, you get this:

Dsc 1863

And that’s where they end up at Jee Labs:

Dsc 1864

Easy. And if you don’t want to go through all this: just cut up a telephone cable instead (note that such cables will work fine, but most of them only connect the inner 4 wires, i.e. AIO, DIO, +3V, and GND, not PWR & IRQ).

New PIR motion sensor

In Hardware on Aug 30, 2010 at 00:01

From now on, the Room Board is going to be shipped with a new PIR (passive infrared) motion sensor:

Dsc 1866

The reason I went looking for a replacement is that the ELV unit was out of stock for a long time, especially in quantity. It seems to be back now, but I had already found a good alternative.

The unit shown above is nice for a couple of reasons:

  • it’s equally low-power, drawing 40..50 µA
  • this unit is specifically for 3 .. 3.3V, whereas the ELV unit was running slightly out of spec
    • (it officially requires 5..24V, but the regulator brings that to 3V)
  • it’s slightly lower on the sensor side (and higher on the component side)
  • the sensor seems to be sensitive over a somewhat wider angle
  • it’s no longer a kit, no need to solder-in that sensitive PIR chip anymore

I’ve yet to do some serious testing w.r.t. range, but it appears to be ok.

Here are the two sensors side-by-side:

Dsc 1867

One unfortunate detail is that the pinout is different. Yes, even 3 pins can lead to incompatible variations!

The old sensor has: VCC GND OUT – the new one uses: VCC OUT GND. Besides, I want to connect it to +3V now, i.s.o. PWR.

I solved this by using the other side of the room board, and reconnecting GND slightly differently – i.e. cutting the pin off and rewiring it as follows:

Dsc 1868

It’s a hack, but it works. The two remaining pins are still enough to keep the sensor board firmly in place.

Onwards!

LED strip efficiency

In Hardware on Aug 29, 2010 at 00:01

LED lighting is efficient right? Oh, sure… the LEDs are, but the way they are connected isn’t necessarily!

I’ve always been puzzled by those resistors you see on RGB LED strips:

Dsc 1664 2

My impression is that these strips consists of segments which all have (essentially) the following schematic:

Screen Shot 2010 08 27 at 21.59.22

Measuring the 60-LED/meter RGB strip I have here, I get the following readings for 0.5 m, i.e. 10 of the above segments:

  • RED draws ≈ 180 mA, the voltage over its resistor is ≈ 5.5V
  • GREEN draws ≈ 170 mA, the voltage over its resistor is ≈ 2.2V
  • BLUE draws ≈ 190 mA, the voltage over its resistor is ≈ 2.4V

Total current draw is roughly 540 mA, or 1.08 A/meter @ 12V. So the total power consumption is 13 watts for each meter of LED strip.

But…

  • the red LED’s resistor consumes 0.18 x 5.5 = 0.99 W on each 0.5 m
  • the green LED’s resistor consumes 0.17 x 2.2 = 0.37 W on each 0.5 m
  • the blue LED’s resistor consumes 0.19 x 2.4 = 0.46 W on each 0.5 m

That’s 3.64 W of the 13 W pumped in per meter – turned into … heat!

Is LED lighting a good idea, in terms of efficiency? Yes, probably. A meter of RGB LEDs at full power draws 13 watts and looks a lot brighter to me than a classical lightbulb, halogen light, or even them new fluorescent “long-life” bulbs that are all the rage (but oh so ugly).

Note that I’m not talking of “power LEDs”, i.e. the 1W, 3W, or more LEDs that are used for very bright lights and which need te be mounted on a cooling fin (Infineon, etc). These are usually driven by a (more complex) constant-current source, and not a plain 12V supply. The reason for this is that at those power levels, you couldn’t possibly adjust the current draw via resistors – these would become scorching hot and cause lots of problems of their own!

The are a couple more figures to be gleaned from the above information, btw, but you can also measure these values directly on the RGB strip:

  • the red LED resistors are 300 Ω each, each LED gets 2.2V
  • the green LED resistors are 120 Ω each, each LED gets 3.3V
  • the blue LED resistors are 120 Ω each, each LED gets 3.2V

That voltage is the real reason for all these resistors. If you were to feed exactly 6.6V to the 3 red LEDs (9.8V for green, 9.6V for blue), then you wouldn’t need any resistors to pick up the slack. But that’s not feasible in a practical / cheap way, so instead we drive these strips with 12V and have the resistors eat away 28% of excess energy in the form of generated heat. Note: it would be more accurate to say: “if you were to feed exactly 180 mA, etc” … because the voltage is a “side effect” for each type of LED, the current is what determines their brightness.

Another source of inefficieny is the 12V power supply – let’s assume it’s about 90% efficient. Then 72 watts of power going into the LEDs will draw a total of 111 watts from the power line.

The good news is that these ratios won’t change when the LEDs are dimmed via PWM. A 50% pulse reduces the total amount of energy used by the same percentage (again: 28% of that is gobbled up by resistors).

Sooo… if you’ve got 8 meters of RGB strip going at full power, then that’s about 100 watts – 28 of which are turned into heat before they even reach the LEDs. And the power supply used another 11 to do its job.

I still think LED strips are a good idea – if I can get the white balance right and if their color is very even.

Fractional bits?

In AVR, Hardware, Software on Aug 28, 2010 at 00:01

To continue this little weblog series on bits, I’m going to go into bit fractions.

Yeah, right… there is no such thing, of course – unless you’re into probabilities or fuzzy logic, perhaps.

What I actually want to do, is describe “analog output” on the ATmega, using the Arduino library’s analogWrite() function. And throw in some bit manipulations along the way, to stay somewhat on topic.

The little secret with analogWrite() is that it doesn’t do what its name suggests. The ATmega has no way of generating an analog signal, i.e. a voltage level between 0 and VCC.

Instead, a pulse is generated, with a varying duty cycle. I.e. the “on” and the “off” times of the pulse will be different, the ratio of these times being proprtional to the 0..255 value passed as argument to analogWrite(). With “0”, the signal will be 100% off, with “255” the signal will be 100% on. With “128” the pulse will be on the same amount of time as off. With “1”, it will be on very briefly, and then off most of the time, and so on…

The neat thing is that you connect it to an incandescent lamp, or a motor, then the effect will be that these will light/turn at less than their full power, due to the time it takes for these devices to try and follow the pulse. So the effect is similar to a fractional adjustment: you can dim / slow down these devices by using analogWrite().

It even works with LEDs, although these turn on and off very fast. In this case, the reason is that our eyes can’t follow such fast changes, and so we perceive the result as dimmed as well. A whole industry was once created around this “persistence of vision” property of our eyes – it’s called TV…

Here’s a sketch which uses this pulsed output to control the brightness of a LED connected to DIO3 (i.e. D6):

Screen Shot 2010 08 27 at 16.44.38

Note that I didn’t have to define pin 6 as an output, analogWrite() does that.

What the above does, is ramp up gradually from 0 to 255, and then repeat:

Screen Shot 2010 08 27 at 16.49.06

Suppose we want it to fade in and out instead:

Screen Shot 2010 08 27 at 16.49.17

Try implementing this yourself.

Note that you’re going to need at least 9 bits of information to do this: 8 for the brightness level and 1 to keep track of whether you’re currently in the up ramp or in the down ramp:

Here’s one way to do it, using some bit trickery:

Screen Shot 2010 08 27 at 17.05.15

A few notes:

  • I’ve changed the “level” variable from an 8-bit byte to a 16-bit word
  • bit 8 toggles from 0 to 1 and back every 256 level counts
  • it’ll be 1 when level is 256..511, 768..1023, etc
  • when it’s 1, we flip the bits, i.e. 0 becomes 255, 1 becomes 254, etc
  • the analogWrite() function ignores all upper bits

If you think that was an obscure call to analogWrite(), try this one:

    analogWrite(6, level ^ -((level >> 8) & 1));

Maybe you can decypher it when written slightly differently?

    analogWrite(6, level ^ -bitRead(level, 8));

(hint: bitRead() always returns either 0 or 1)

It’s all pretty geeky stuff, and let’s hope you’ll never have to deal with code such as this again, but the point of this story is that there’s no magic. You just have to know what each operator does, and how to translate an integer from decimal to binary notation and back.

I’ll summarize my intuitive interpretation of bit operators below:

  • X | Y” = take X and copy all the 1’s of Y into it
  • X & Y” = take X and copy all the 0’s of Y into it
  • X ^ Y” = take X and flip all the bits where Y has 1’s
  • ~ X” = flip all the bits of X
  • – X” = arithmetic minus (same as “(~X) + 1” !)
  • ! X” = 1 if X is zero, 0 otherwise
  • X << N” = multiply X by 2, N times
  • X >> N” = divide X by 2, N times

Some tricks based on this:

  • ~ 0” = all bits set to 1 (same as “-1” !)
  • ~ 0 << N” = all bits 1, but N lowest bits set to 0
  • bit(N) – 1” = a constant with N lowest bits set to 1
  • X & (bit(N) – 1)” = the N lowest bits of X, the rest is 0
  • X & ~ (bit(N) – 1)” = X, but with the N lowest bits set to 0
  • !! X” = 0 if X is zero, 1 otherwise

An useful rule when writing logical expressions is: when in doubt, parenthesize! – see C operator precedence.

Sooo… use bit(), bitRead(), bitWrite(), bitSet(), and bitClear() wherever you can, since it usually makes the code easier to read. But there’s no need to get lost if you see ^&|~!’s in your expression – just slow down and decode such expressions step by step!

Flippin’ bits

In AVR, Hardware, Software on Aug 27, 2010 at 00:01

After yesterday’s post about setting and clearing bits, let’s explore reversing bits, i.e. changing them from 0 to 1 and back. And let’s do it by blinking an LED attached to DIO of port 1 – i.e. Arduino digital pin 4:

Screen Shot 2010 08 26 at 10.31.26

The “if (onOff = 0)” etc is the logic that toggles onOff between 0 and 1 on each pass through the loop:

    if (onOff == 0) onOff = 1; else onOff = 0;

But there are lots of ways to do the same thing, coded differently:

    if (onOff == 0) onOff = 1; else onOff = 0;
    if (onOff == 0) onOff = bit(0); else onOff = 0;
    if (onOff == 0) bitSet(onOff, 0); else bitClear(onOff, 0);
    onOff = onOff ? 0 : 1;
    onOff = (~ onOff) & 1;
    onOff = (onOff + 1) & 1;
    onOff = ! onOff;
    onOff = 1 - onOff;
    onOff = onOff ^ 1;
    onOff ^= 1;

See if you can figure out all of these.

Take your pick. Those last two use C’s XOR operator. I tend to prefer shorter source code, so I’d use that last notation (note that the resulting compiled code is not necessarily shorter than the other examples).

Now suppose you have a byte value “X” and you want to flip the 4th bit in it, while not changing anything else. That’s a bit more work. It could be done like this, for example:

    if (bitRead(X, 4) == 0) bitSet(X, 4); else bitClear(X, 4);

Or like either of these:

    X = X ^ bit(4);
    X ^= bit(4);

This shows clearly that the “^” XOR operator does exactly what we need: flip bits.

Back to blinking an actual LED, as done with the above sketch. Here’s a little mind bender – another sketch, doing the same using raw ports and the XOR operator:

Screen Shot 2010 08 26 at 10.58.10

The first example was doing things “the Arduino way”, using pinMode() and digitalWrite(). It compiles to 890 bytes of code. This second example goes straight to the hardware and uses 554 bytes of code:

  • Arduino digital pin 4 is bit 4 on the “D port” of an ATmega
  • “DDRD” is the “Data Direction Register”, where we set up pin 4 as an output
  • “PORTD” is the out “Port Register”, which controls the actual output signal

You can see the XOR in action in that last example. It takes all the output bits of port D (Arduino pins 0 .. 7), and flips just a single bit, i.e. bit 4.

Just for kicks, I’ll show you one more way to blink the LED:

Screen Shot 2010 08 26 at 11.03.44

This uses a relatively little-known feature of the hardware, which actually has “bit flipping” built-in. The “PIND” register is normally used for input, i.e. for reading the state of a pin as an input signal. But you can also write to that register. When you do, it will be used to flip output pins, but only for the bits which were set to 1. It’s essentially a built-in XOR.

That last example uses 550 bytes of code, most of which is overhead from the Arduino run-time library (setting up the milliseconds timer, etc). So what’s in a measly 4 bytes, right? Wrong. There is a minute, but sometimes important difference: the other approaches all had to read the register value first, flip the bit, and then write the value back. This last version only writes a (constant) value to a register. With interrupts, that can be very important: this last version can’t ever go wrong, it will always flip the requested bit. The other version could have an interrupt occur between the read and the write. It’s a known issue for the Arduino Mega. It can lead to code which runs for a week, and then fails mysteriously. Bugs like these are fiendishly hard to properly diagnose.

Bit-flipping can be quite useful for physical computing. Not only does it let you easily toggle specific bits, and change the state of some output pins, it can also be a way to clear a bit. Let’s say you need to generate a (very) quick pulse. Here are four ways to accomplish the same thing:

    bitSet(PORTD, 4); bitClear(PORTD, 4);
    PORTD |= bit(4); PORTD ^= bit(4);
    PORTD |= bit(4); PIND = bit(4);
    PIND = bit(4); PIND = bit(4);

That second one based on XOR works, because bit 4 is known to be one, so setting it to zero is always the same as flipping it. That’s also why the third PORTD/PIND example works, with PIND doing the XOR in hardware. Lastly, the fourth approach will only work if bit 4 was initially zero. It’s the fastest one, and does not suffer from the interrupt race condition mentioned above.

Ok, that’s enough flippin’ for one day!

Tomorrow, I’m going to go into, ehm… “fractional bits” (haha!) ;)

Update – see comment below on why “bitSet(PORTD, 4); bitClear(PORTD, 4);” are also interrupt-safe (mostly – but not on every pin of an Arduino Mega!).

Bit manipulation

In AVR, Software on Aug 26, 2010 at 00:01

Today I’d like to go into bit manipulation, ehm, a bit

You need bit manipulation when you’re dealing with the individual bits in a byte, such as on the I/O ports of an ATmega, for example.

First the easy approach – use these predefined macros from the Arduino library:

  • bit(N) returns an integer with the N’th bit set to 1
  • bitRead(X,N) – returns the N-th bit of X as 0 or 1
  • bitWrite(X,N,B) – sets Nth bit of X to B (0 or 1)
  • bitSet(X,N) – sets the Nth bit of X to 1
  • bitClear(X,N) – sets the Nth bit of X to 0

This is why you might see code such as the following:

    bitSet(WDTCSR, WDIE);

This means: “set the Watchdog Interrupt Enable to 1 in the Watchdog Timer Control Register”. The WDTCSR and WDIE terms are predefined constants. WDIE is 6, for example.

Note that some of these routines can be written in terms of the others, i.e.

  • bitSet(X,N) is the same as bitWrite(X,N,1)
  • bitClear(X,N) is the same as bitWrite(X,N,0)

But what does it all mean?

Well, let’s dive in. First make sure that you are comfortable with “bit shifting”. The expression “bit(3)” is the same as “1 << 3”, which in turn is the same as doubling the value 1 three times, i.e. the value eight. So “bit(0)” is 1 doubled zero times (i.e. 1) and “bit(7)” is 1 doubled 7 times, i.e. 128. Bytes have 8 bits numbered 0 to 7, so all you need for (byte-sized) hardware registers is to remember that bits 0..7 map to (specific!) integers with values 1 to 128.

Setting a bit, is like OR-ing the bit with the rest of the value. The following statements are all identical:

    WDTCSR = WDTCSR | bit(WDIE);
    WDTCSR = WDTCSR | (1 << WDIE);
    WDTCSR = WDTCSR | (1 << 6);
    WDTCSR = WDTCSR | 0b1000000;
    WDTCSR = WDTCSR | 0x40;
    WDTCSR = WDTCSR | 64;

This, in turn, can be abbreviated in C as:

    WDTCSR |= bit(WDIE);
    WDTCSR |= (1 << WDIE);
    WDTCSR |= (1 << 6);
    etc...

Or you could write:

    bitSet(WDTCSR, WDIE);

It’s all the same. So OR-ing is about setting bits (to 1).

Likewise, AND-ing is about not clearing bits (to 0). Whoa, that’s confusing. This expression returns a value which is what X was, but only for bit N:

    X & bit(N);

So this will change X to a value with all bits except bit N set to zero:

    X = X & bit(N);

To put it differently: X will lose its original bits, except bit N, which will be left alone. All the bits are set to zero, except bit N.

Usually, you want the opposite, setting only bit N to zero. That too is accomplished with AND-ing, but you have to flip all the 0’s to 1 and all the 1’s to 0 first. Hang in there, it’s a slightly longer story. This sets bit N to zero:

    X = X & ~ bit(N);

Let’s examine what’s going on here. First, “bit(N)” is a value with only the Nth bit set. Now, “~ bit(N)” is a value with all the bits flipped around (“~” is called the complement operator in C), so that’s a value with all but the Nth bit set. Everything is 1, but bit N is 0.

Now we can tackle the expression “X & ~ bit(N)”. Since AND-ing is about “not clearing bits”, that means that the result of this expression is all the bits of X unchanged where “~ bit(N)” was one, which is almost everywhere. The only bit that differs is bit N – it is zero in “~ bit(N)”, therefore that particular bit will “not not clear …” (a double negation!): it will be cleared (to 0) in the result.

Finally, we replace X by that result. So X will change in precisely one bit: bit N. That bit will be cleared to zero, the rest is not affected. In short: we’ve cleared bit N.

Confused?

Well, that’s why the bit/bitSet/etc macro definitions were introduced. These expressions are all identical:

    X = X & ~ bit(N);
    X = X & ~ (1 << N);
    if (X & bit(N)) X = X - bit(N);
    bitClear(X, N);

That last one is clearest by far, because it conveys the actual operation with a well-chosen name: clear bit N, leave the rest alone.

So why would anyone ever choose to use anything but the bit/bitRead/etc routines?

Many reasons. Habit, perhaps. Coming from another environment which doesn’t have these macros. Being so used to this bit-manipulation that the use of words doesn’t really look any clearer. Whatever…

But another more important reason is that you can’t do everything with these bit/bitSet/bitClear routines. Sometimes you just have to go to the raw code. Such as when you need to set multiple bits at once, or flip bits. That’s why the ATmega datasheet has examples like these:

    WDTCSR |= (1<<WDCE) | (1<<WDE);

By now, you should be able to decode such a statement. It’s the same as:

    WDTCSR |= bit(WDCE) | bit(WDE);

In other words:

    WDTCSR = WDTCSR | bit(WDCE) | bit(WDE);

Which in turn is almost the same as these two statements together:

    WDTCSR |= bit(WDCE);
    WDTCSR |= bit(WDE);

That in turn, can be written as these two lines:

    bitSet(WDTCSR, WDCE);
    bitSet(WDTCSR, WDE);

Much clearer, right? Except… it’s not 100% identical!

The problem is a hardware issue: timing. The above two statements will set both bits, but not at the same time! For hardware register settings, that difference can be important. There is a fraction of a microsecond between the WDCE bit being set and the WDE bit being set. Unfortunately, in some cases that causes real problems – your code won’t work as expected.

Tomorrow, I’ll continue on this topic, but it’ll be a bit more fun, because there will be LEDs involved!

Dsc 1385 2

(Please ignore the cable on the left, I snatched the above picture from this post)

Update – see this excellent Wikipedia article for more details about bitwise operations.

Sideways?

In Hardware on Aug 25, 2010 at 00:01

I’m always looking for new ways to fit stuff together. JeeStuff ain’t no Lego, but that sure won’t stop me from trying to make it as modular as possible…

Here’s an idea:

Dsc 1842

I just used a pair of Proto Boards and inserted a bunch of plugs into them. Just to see what it would lead to, not as “the” actual design.

Would probably have to invent another type of “backplane” for this approach, but what surprised me was how sturdy the resulting object was.

Would probably need to have 15 to 25 possible slots to place headers in (perhaps even allow soldering the plugs in for good?). And some way to select which AIO and DIO pins go to which port. With I2C, they could be connected in parallel, with dedicated plugs you’d have to reserve a port for them of course.

The reason this could work is that everything in the JeeFamily has the same 21.1 mm width. That was quite deliberate, although I didn’t have this particular path in mind at the time.

Hmm… mounting? Power options? Ethernet? Breadboard area?

Just doodling… ideas are cheap – and plentiful, here at Jee Labs!

Simplified button interface

In AVR, Software on Aug 24, 2010 at 00:01

The Blink Plug has two pushbuttons and two LEDs. The buttons are simple miniature switches, but nothing is ever simple in microcontroller-land: reading out the state of a pushbutton reliably can be deceptively hard, due to mechanical bounce issues.

The Ports library has had a BlinkPlug class for some time now, including a “pushed()” function to do all the debouncing. Unfortunately, that function turned out to be a bit harder to use than I originally intended.

Time to add some more code to the BlinkPlug class!

I’ve added a new “buttonCheck()” member, which returns events instead of state. That makes it a lot easier to detect when people press a button, which is usually all you’re after anyway.

Here’s a new button_demo.pde example sketch, which illustrates the new functionality:

Screen Shot 2010 08 23 at 17.44.21

Sample output:

Screen Shot 2010 08 23 at 17.44.39

As you can see, it’s now a lot simpler to detect when people press or release one of the two buttons on a Blink Plug. Each time you call buttonCheck(), you’ll get one of the following events:

ALL_OFF, ON1, OFF1, ON2, OFF2, SOME_ON.

You have to keep calling “buttonCheck()” reasonably often, at least 10 times per second, if you don’t want to miss any events. Calling it all the time in the main loop is fine. Keep in mind that ON1, etc. will be returned only once for each actual button press.

You can still call “state()” whenever you want, to check the position of either button. But when you use buttonCheck(), you should not call the old – now deprecated – “pushed()” function, as these two will interfere with each other.

This code is now part of the Ports library (subversion and ZIP). Gory details are in Ports.cpp, near line 230.

Meet the Utility Plug

In Hardware on Aug 23, 2010 at 00:01

To end the current series of new plug announcements, here’s one which is a bit of everything and nothing, called the Utility Plug:

Dsc 1834

It comes as a kit:

Dsc 1837

It brings out 6 pins to a modular jack, the same kind as used by fixed-line telephone sets around the world.

In its simplest form, you can just put a dab of solder on each of the 4 solder jumpers, and you’ll end up with a connector that brings out the 6 pins of any of the ports on a JeeNode. This plug kit includes a 1-meter length of flat white cable with a connector attached to one end. The other end is … up to you!

Modular plugs and jacks were chosen because they are very easy to get and crimp on (there are cheap plastic tools for it). If you don’t need the PWR and IRQ pins, i.e. if you only need to use AIO, DIO, +3V, and GND, then you can even take a spare telephone cable, cut it in half, and end up with… not one, but two pieces of cable which fit this connector! That’s because most telephone cables only connect to the inner 4 wires, but they still use this same 6-pin connector.

As far as I understand it, the 6-pin variant is called RJ-12, and the 4-pin variant RJ-11. They can be mixed because they have the same physical dimensions.

One reason I’ve wanted this Utility Plug for some time, is simply to have a more solid connector to plug and unplug stuff from, without having to mess with 6-pin headers. Unlike the headers, modular jacks are polarized, so there’s never a chance of connecting stuff the wrong way around – quite important once you’ve built a project and finished it by putting it inside a box, for example.

But that’s just the first half of the story…

As you can see, there’s a bit more going on with this plug. There are some places to add resistors, transistors, and diodes. The reason for this is that you often have to put a resistor in series (for say an LED), or to “pull up” the voltage on a pin, or even a small transistor to handle a little more current than a ATmega pin can by itself. Other uses would be to adjust the level of input signals, or to add reverse-polarity protection to an input pin.

The Utility Plug has 2 identical areas to handle such simple modifications:

Dsc 1840

Each of those dotted areas has the following circuit traces laid out for it:

Screen Shot 2010 08 22 at 19.55.15

(this is the DIO side, the AIO side is virtually identical)

This won’t be sufficient to deal with every scenario you might encounter, but my calculations tell me that it will deal with 27.183 ± 0.0002 different cases :)

To make this practical, a few extra components are included in the kit:

  • 2x 100 Ω, 1 kΩ, and 10 kΩ resistors (1/6 watt)
  • 2x 1N4004 diodes, for AC to DC conversion and to drive inductive loads
  • 2x 2N4401 transistors which can switch up to 500 mA @ 40V

One word of advice when using this plug, is that you should really do some back-of-the-envelope calculations, to make sure things will work within the range you’re designing your circuit for. The resistors will let you keep currents down, and the transistor will let you generate a slightly more powerful output signal.

Remember: “E = I x R” is your friend!

Other components than those supplied can also be used, of course. Each section on this Utility Plug is nothing more than a miniature breadboard area with some pre-defined circuit connections.

See the café and shop pages for further info.

Now I’ve got to fire up some projects to use this thing. I’ll keep you posted when I get to that.

Getting organized

In Musings on Aug 22, 2010 at 00:01

Nothing like a good vacation to forget everything…

An now, coming back, I’m faced with the fact that I don’t always remember where things are, and having way too much stuff piled up in several places.

Time to do someting about it:

Dsc 1827

Simple cardboard boxes with 5×30 and 10×30 cm footprints. Tons of ’em…

I’m already tracking most of my inventory, including pictures and locations, but the problem was that these locations were too broad. Rummaging through various piles of, ehm, junk can get boring and tedious after a while!

Now I’ve got to think about where everything should go. Shop products in one place, projects-in-progress in another, lab supplies in a third, not to mention the shipping department.

Jee Labs is about fun, not size, after all – I don’t really want to expand beyond the current 4 x 7 meter space currently in use (apart from a few large supply boxes and tools in the basement), which is going to require a bit of self-discipline. There’s still a fair bit of unused wall space, so that’s good.

Ah, the wonders of the “atoms” world… :)

Another LiPo option

In Hardware on Aug 21, 2010 at 00:01

The other day, I found a Lithium battery in a local shop, which has just about the right size and properties for use with a JeeNode USB:

Dsc 1818

Found it here, for €9 … so it won’t break the bank.

The nice bit, apart from its size, is that it is fully enclosed and isolated, with two contacts which are easy to solder:

Dsc 1819

Do read that warning, and then proceed anyway :)

What you see above, is the battery with a bit of solder applied to each terminal. Next, I attached some wires:

Dsc 1820

I used two-sided tape to permanently fasten the battery to the JeeNode USB’s back side. Note that the headers were already soldered on, with all the extruding pins clipped to get a slightly flatter surface:

Dsc 1821

The ground wire didn’t need insulation after all, since it connects right next to where the battery is. The positive wire was connected to PWR on port 3, to leave the PSI header free if it ever needs to be hooked up later.

And that’s all there is to it:

Dsc 1822

There is no switch to disconnect the LiPo, so the JeeNode USB can run down the battery if it’s not running a good power-saving sketch. But who needs a switch anyway, when you can do it in software, right? Just upload this:

Screen Shot 2010 08 16 at 01.23.09

When run, the JeeNode will power off completely. This code has been added as “powerdown_demo.pde” sketch in the Ports library.

For proper use, sketches running on a LiPo-powered JeeNode USB should periodically measure the current LiPo voltage via the ADC6 pin, which is tied to a voltage divider. For this to work, the voltage should not have dropped below about 3.4V, so that the ATmega still gets a properly regulated 3.3V as AREF to compare with. The voltage on ADC6 is always half the voltage on the PWR pin. So what every sketch needs to do, is to occasionally measure the voltage, and once it reaches 3.4V, shut down completely using something like the above code.

So there it is – another JeeNode, ready to go … to recharge it, I just plug it into USB!

Meet the Opto-coupler Plug

In Hardware on Aug 20, 2010 at 00:01

After two new output plugs, here’s one for input – a dual Opto-coupler:

Dsc 1841

The idea is simple: feed it 5..50 mA of the proper polarity, and the other side can be read out by a JeeNode without any electrical contact. As the name says: light is used to remove the need for a galvanic connection.

This can be used for more than just high voltages: there are many cases where two different low-voltage circuits have independent ground levels, and where you want to keep it that way.

Electricity always takes the path of least resistance (literally!), and with high-current loads (or inductive spikes), you never know when some piece of equipment decides that it would love to send 5A through the GND pins across a JeeNode. There’s no danger involved here, but some traces on the JN print will go up in smoke (literally!).

A simple example is when you’re dealing with two power sources, and hook them up – accidentally or on purpose. Nothing will usually guarantee that the ground pins get connnected first. You might just briefly get the positive high-current supply hooked up in such a way that it finds another ground loop…

As with the Relay Plug, I’ll mention that you can use this Opto-coupler Plug to sense AC mains voltages (well not directly… more on that in a moment). But the risk is all yours.

The terminals on this plug are also detachable, but smaller: they use a 3.5 mm pin separation, and can handle a bit less current. The reason for this distinction is that you don’t want to accidentally put a high-power connector from the Relay Plug into this low-power Opto-coupler Plug. Since the connectors don’t match, this risk is avoided.

So what can you use as input source with this Opto-coupler Plug? Well… that depends – on the resistors soldered onto this plug, to be precise. Each resistor is in series with a LED contained inside the opto-coupler:

Screen Shot 2010 08 19 at 18.11.47

The dual opto-coupler used here will operate with roughly 4 .. 55 mA of current through the LED. The series resistors included with the kit are 1 kΩ @ 1/8W – this translates to a DC input voltage range of about 5 .. 12V. Any higher, and the resistor will get too hot – any lower, and the opto-coupler won’t trigger.

For higher voltages, you can replace these resistors with a higher value. Try to keep current consumption minimal, say 5 mA. Here’s the calculation to make it work with a 24V input: 23 V (roughly 1V gets taken up by the LED) with 0.005 A is … scribble, scribble, scratch, scratch … E=I*R … R=E/I … R = 23 / 0.005 = 4600 Ω!

So you should be good with a 4.7 kΩ resistor. Now let’s calculate the power consumption of that resistor … ponder, ponder … P=I*E … E = I*R … P = I*I*R = 0.005 * 0.005 * 4700 = 0.1175 W. Phew, a 1/8W (0.125W) resistor will work, but with little slack. Not surprising, really: the resistor is eating up 23 of the 24 V sent into the plug. Meaning: heat. That’s why low current use is best: current has a quadratic impact on the power consumption.

The trouble is that with 4.7 kΩ, you can only use the plug with 24V: any lower, and the current through the opto-coupler will be too low, any higher and the resistor will deliver its final puff, in the form of smoke…

So there you have it, with some free electricity calculations thrown in: this plug will work as is on a 5 .. 12V input source, and with the proper resistor value you can also make it work @ 12 .. 24V. The two inputs are fully independent, so different resistor values are possible.

If you happen to have a current-limited source in the 4 .. 55 mA range, then simply omit the resistors and put a dab of solder to close the jumper on the pcb. That’s 0 Ω, if you really want to know :)

On the JeeNode side, first enable the pull-up resistors on AIO and DIO, and then read them out as digital inputs. If you wanted to get maximum sensitivity, you could even use the AIO pin in analog input mode, and place the threshold a bit lower. That’s going to require a bit of experimentation (and it only works on the AIO side).

New café and shop pages have been added, as usual.

There’s one more new plug on the menu, a few days from now … that one will be a bit different from the rest. Even simpler, yet fairly versatile. Stay tuned!

New AA battery option

In Hardware on Aug 19, 2010 at 00:01

Today might be a good day to set aside your dislike of Apple for a moment…

There is a new battery pack + charger option on the market:

Dsc 1816

In Europe, this combination costs €29.95, and it gets you 6 rechargable batteries plus a charger.

The specs are what make this thing particularly interesting for low-power battery-powered devices:

  • each NiMH AA cell holds 1900 mAh charge (rumored to be rebranded Sanyo Eneloops)
  • the batteries are reported to retain at least 70% of their charge for 2 years
  • battery lifetime is reported as being at least 10 years (with recharges, of course)
  • the charger drops to 30 mW “vampire” power draw once the batteries are charged

To start with the latter: I’ve verified it. When charging, there’s a small yellow LED and it draws less than 4 watts. When done, the LED turns green, and power consumption drops to 0.18W. Then, after 6 hours, the LED goes off and the power consuption drops to… zero! At least on the very sensitive SBC-500 I used.

This is a very big deal!

It means you can permanently leave these chargers plugged in, with a few spare AA’s. No cost, no waste – simply a way to keep a couple of cells fully charged and ready to go.

It’s also perfect for JeeNodes, using the standard 3x AA battery holder:

Dsc 1817

That’s 4.1V when fully charged. And JeeNodes will work with them all the way down to 3.3V, i.e. 1.1V per cell. Also, unlike LiPo batteries, running NiMH batteries down won’t do them any harm.

At last, I can stop wasting alkaline batteries… I’m probably going to replace all of them in the months ahead!

Meet the Relay Plug

In Hardware on Aug 18, 2010 at 00:01

Here’s another plug, useful for various applications around the house – the Relay Plug:

Dsc 1812

This one uses miniature relays to control two independent contacts. It has two MDC3105 relay drivers on board, and uses the same detachable terminals for connection to the outside world as the MOSFET Plug.

Unlike MOSFETs, relays provide a fully isolated switching capability. There is no electrical connection between the switched out pins on the terminal block and the JeeNode. The traces on the PCB were in fact laid out with a wide separation between switched pins and the rest of the circuit.

These plugs have just the right size for the Carrier Board + Box, by the way:

Dsc 1823

The relays currently used for this board are rated up to 3A @ 250V (both AC and DC). This means that you could use them for controlling up to 750W worth of devices connected to the mains on each output. Just keep in mind that messing around with the mains voltage is dangerous and can be lethal. Note also that neither the pins on the underside, nor the screws on the terminal blocks are isolated, so you’ll have to consider really carefully how to physically mount everything to prevent shock hazard. I definitely wouldn’t use these plugs for mains power in the box as shown above – such a box can easily open when dropped.

Did I mention that AC mains can be lethal? Ah, yes, I think I did…

Then again, if you know what you’re doing: sure, go right ahead.

For the rest of us, these relays are probably more suitable for controlling low-voltage lights, motors, fans, and… larger relays. One item on my (infinitely long) to-do list is to use these relays to control the power of a couple of external hard disks. Not just to save on electricity when not in use, but also because disks which are not powered up and hence don’t rotate are pretty safe from software mishaps, both accidental or malicious.

The relays are driven from the PWR line, which has to have a supply voltage between 4 and 6V to operate properly. Less, and the relays won’t turn on – more, and the relays + relay drivers will be damaged. Each relay draws about 30 mA of current while turned on. They are not latching: power loss will switch them off.

Controlling the relays in software couldn’t be simpler: use the Port class in the Ports library to set both DIO and AIO as outputs, and then use digiWrite() and digiWrite2() to control DIO and AIO, respectively. Since each relay uses up one port, you can have up to 4 Relay Plugs, i.e. 8 relays hooked up to a single JeeNode.

Here’s an example which listens for incoming radio packets to control a Relay Plug on port 1 (this example is included in the Ports library as “relay_demo.pde”):

Screen Shot 2010 08 15 at 23.18.02

Sending “1,1,17s” via another JeeNode or JeeLink turns both relays on. Sending “0,0,17s” turns them off again.

Documentation for the new Relay Plug is in the Wiki, and there’s an order page in the shop for them now.

Pulling data from an EtherNode

In Software on Aug 17, 2010 at 00:01

Last month’s EtherNode sketch was an example of a simple web server which allows viewing incoming packets received by the RFM12B. Here’s a sample web page again:

Screen Shot 2010 07 13 at 231929

If JeeMon could access and pick up that data without requiring an extra JeeLink or JeeNode, then you could place the EtherNode wherever reception is best while running JeeMon on your desktop machine, or anywhere else.

In response to a request on the forum for just that, I started writing a little demo “application.tcl” for JeeMon to do this sort of web-scraping. Here’s what I came up with (code):

Screen Shot 2010 08 16 at 10.35.49

Sample console output:

Screen Shot 2010 08 16 at 10.42.48

The point here, is that it needs to periodically poll the EtherNode, get a web page from it, and skip the readings it has already seen before. That’s what most of the code in “EtherNodePull” does. Each packet that remains will be sent to the “GotPacket” proc, which just logs it on the console.

But that’s just one half of the required solution…

The bigger challenge is to also make JeeMon decode these packets, as if they came in through a serial USB link. There is quite a bit of logic in sketches/central/host.tcl to do that for a JeeNode or JeeLink running the “central” sketch (which is almost identical to RF12demo).

The reason this is more complicated, is that I want to be able to decode each packet in different ways, depending on the sketch running on the remote (sending) node. My network has more than just room nodes, and will be extended with many more node types in the future.

One workaround would be to collect all nodes of the same type in their own group, i.e. net group 1 for room nodes, net group 2 for the ookRelay, etc. And yes, that would work – but it’s not very convenient, and I’d need separate etherNodes to pick up the packets from each net group. Messy.

The approach I have used so far, is to maintain a config section for JeeMon, with information about the type of each node, organized by frequency band, net group, and node id:

Screen Shot 2010 08 16 at 10.52.23

It’s not automatic, but this way I just need to adjust one list whenever a new wireless node is brought online.

The current code in sketches/central/host.tcl is all about picking up packets, and mapping them thtough this configuration section to know what is what. It does this by setting up a pseudo “connection” whenever packets come in for the first time and includes logic to tear down this connection again when no new packets are received within a certain amount of time.

To use this approach with an EtherNode as data collection node, I need to re-factor the exisiting code and make the core mechanism independent of the Serial implementation. I also need to bring more of the code from central/host.tcl into the JeeMon code, so it can be re-used for EtherNodes.

Re-factoring is my middle name – I’ll update this post when the code changes are complete.

Meet the MOSFET Plug

In Hardware on Aug 16, 2010 at 00:01

There’s a new plug at Jee Labs – one I’ve been waiting to use myself for quite some time – a dual MOSFET plug:

Dsc 1807

The IRLZ34N’s used here should be able to drive over 5A @ 50V, but this will require a heatsink. For use without heatsink, a maximum currrent of 1 .. 3 amps should work fine. Just keep in mind that MOSFETs can generate a few watts of heat when used continuously at 2A or more. You can tie the MOSFETs in parallel for larger currents. You’ll need to add protection diodes to switch inductive loads, such as DC motors, relays, and solenoids.

This plug was designed for driving LED strips, but other loads can be driven as well. With two MOSFET Plugs, there are 4 individually controllable switches – to drive an RGB strip and a white strip, for example.

The terminal blocks used on this plug are heavy duty and detachable and use a standard 0.2″ grid (5.08 mm). They are much more convenient than fixed terminal block, particularly if the plug is mounted high or in some remote spot behind a book case or curtain. The two outputs have separate connectors.

The traces on this board have been made extra wide to be able to handle large currents flowing through the terminal block pins. The pins are laid out as two pairs: one side must be tied to ground, the other side (+A or +D) is then tied to the load, which in turn gets connected to a positive supply voltage (3..50V). Note that the positive supply voltage used by the load is not connected to the plug. A pulldown resistor is used to keep the MOSFETs switched off when the I/O pins are not connected, or not set up as outputs. Also, keep in mind that this plug ties the plug signal ground and the load ground together – it is not isolated from the load power supply.

The length of the plugs is 34 mm, making them a perfect fit for the Carrier Board + Box:

Dsc 1815

Note that a closed box provides little airflow to cool the MOSFETs, so this setup is not recommended for high-current use. Having said that, I’ve been driving a few meters of RGB LEDs with these MOSFETs without them even getting warm. See this earlier weblog post.

For dimmer use, there’s example code for a remote-controlled JN and 4 MOSFETs using software PWM.

I’ve set up a documentation page in the café and an order page in the shop. Since the prototypes worked on first try, these MOSFET Plugs are available as simple through-hole part kits right away.

A Murphy-less plug, so to speak :)

Back from vacation

In News on Aug 15, 2010 at 00:01

Last month, we (Liesbeth and I) spent a delightful time in the Provence:

Img 6808

As usual, that means I get to switch to my French persona, as we visit new places and meet delightful people of all ages. Lots of baguettes, cheese, wine, and fruit – as usual. Life is embarrassingly good this way…

We visited a friend of a friend at this amazing spot in the Provence:

Img 6691

I’ve never been in a house before, on top of a hill, with a 360° view towards all the surrounding mountains. Here’s the side of the house where we stayed:

Img 6659

It was an incredible place to be.

The geek in me couldn’t resist peeking at the way electricity is hooked up there:

Img 6741

The black box at the bottom right is an earth leakage circuit breaker, which trips at… 350 mA! IOW, it doesn’t protect people, only the house wiring! – luckily, a modern 10 mA version has also been added.

Lots of personal stories, which I won’t bore you with. Been back for over a week now, but still mostly in vacation mode. I’m looking forward to going into lots of Jee Labs projects again, starting tomorrow…

A few more images from the country which gave us the phrase Joie de vivre and a lifestyle I truly love:

Img 6739

Img 6780

Img 6732

Img 6391

P.S. Liesbeth took all the pictures, roughly 600 in all – I just tagged along to relax and enjoy…