Computing stuff tied to the physical world

Archive for 2010

Reflections

In Musings on Dec 31, 2010 at 00:01

What? Last day of the year already? Hey! Where did the rest go?

:)

It’s been a very exciting year at Jee Labs. But I don’t really want to rehash any accomplishments here, nor make all sorts of hand-waving predictions. Life’s too short for that sort of drum beating.

For me, 2010 has been the year where JeeLabs became totally real. The stuff I want to keep doing. The place I want to be. The people I want to meet. The adventures I want to be in. The experiences I want to share. The innate curiosity I want to nurture.

In 2010, I met lots of fascinating people and made several precious new friends. Not just online and virtually – THAT was really the biggest surprise of all: there’s this mostly-virtual world, yet it allows profoundly extending and deepening everything that happens in the real world – who would have imagined this? Certainly not me.

This month’s back-order fiasco has been a wakeup call. Atoms are not bits. I’m still learning. People tell me that I’m good with bits – well, I’m determined to get good with atoms too. There’s just way too much fun ahead in this Computing stuff tied to the physical world field.

Evidently, next month will be about recovery. But merely overcoming that would still be defeat. I don’t ever want to end up in this month’s situation again. It saps all the energy and it saps all the pride. Not to mention the failure to deliver in a timely manner and to meet all reasonable expectations. Never again.

There’s a lot that needs to be improved. The shop is awkward, the wiki documentation is incomplete, plug testing needs to catch a wider range of issues, known software problems need to be fixed, potential delays need to be communicated sooner, shipping needs a tracking option. Some of this is a matter of resources (my time, mostly), some of it is stuff I will need to get better at, and some of it is simply a matter of getting the priorities right.

Time will tell.

For 2010, I’d like to thank everyone who helped JeeLabs move forward and dive into numerous exciting projects.

Haagsche Hopje

May the year 2011 bring you – and everyone close to you – lots of curiosity and creative / fulfilling activities.

LED discharge – PWM and DAC

In Hardware on Dec 30, 2010 at 00:01

In yesterday’s post we saw how a digital signal gets turned into something a lot more gradual, i.e. analog.

The reason for this is what I described as capacitors “dampening change” in an earlier post. This is incredibly useful in the world of Physical Computing. We can do “gradual” things with nothing but 0/1 signals coming out of a microcontroller!

The reason this works, is that capacitors mess around with the time domain. Put a “1” on them, and they will follow along eventually, i.e. a little while later. And likewise for a “0” – to bring up a previous diagram again:

This is especially useful with the timer hardware built into an ATmega. You can set up some of the pins to toggle at the rate of a hardware-controlled counter. From the ATmega328 datasheet:

Screen Shot 2010 12 29 at 23.28.11

This is a pin which is set up to generate a pulse repeatedly, and the clever bit is that you can control not just the rate, but also the ratio between on and off times. This is amazingly useful:

  • if the ratio is all the way off, i.e. the pin is permanently “0”, the the voltage on the capacitor in the above circuit will be 0V

  • if the ratio is all the way on (100% on), then the voltage of the capacitor will stabilize to 3.3V if you wait a little while

  • anywhere in between, and the capacitor will be charged while high and discharged while low, and end up being some intermediate voltage between 0 and 3.3V on average

On average: that’s the key. The voltage will still go up and down, but if we choose a high-enough pulse rate, then that variation will be minimal.

This is one useful way of looking at Pulse Width Modulation (PWM): 0 = 0V, 255 (on an 8-bit counter) = 3.3V, and everything in between is N/255 * 3.3V – IOW, we’ve just created a digital-to-analog converter (DAC)!

There are more ways to generate such an adjustable output voltage – see the Bleep! weblog post, for example. But if you just want a slowly adjustable analog voltage, then all it takes is one resistor and one capacitor.

And all it needs on the microcontroller, is one pin which pulses up and down in a specified ratio. The faster it does, the smoother the output voltage. The more accurately the time-off vs time-on ratio is, the more accurately we can set that output voltage. An 8-bit timer will not be able to divide the 3.3V supply voltage into more accurate steps than 0.013V, i.e. 13 millivolt, for example.

It doesn’t really matter how the pulse is generated. There are six pins on an ATmega which can generate pulses with hardware support. This is why the very confusingly-named analogWrite() function in the Arduino library can only be used on 6 specific (digital!) output pins. And it’s not really analog at all, it just becomes analog if you attach a resistor and a capacitor.

The benefit of hardware PWM, as this is called, is that the timer pulses can be made to repeat very quickly (up to some 64,000 times per second). That means a smaller capacitor will often be sufficient, and you can get either a very smooth output voltage or one which can be adjusted rapidly (but never both at the same time).

With software PWM, the pin toggling is done with software loops or timer interrupts. In that case, any output pin can be used. But this incurs a lot more processor overhead, and the pulse rates are far more limited. A while back, I posted a software PWM example to drive some LED strips (the PWM being used for brightness control in this case, even though no caps are involved). That code was almost too slow to avoid visible flickering, although some software tricks can be used to improve the pulse rate a bit.

To be continued, probably about a week from now…

LED discharge – it’s analog!

In Hardware on Dec 29, 2010 at 00:01

The LED discharge circuit presented yesterday can be used for a number of experiments. Yesterday, I asked what this sketch does:

Screen Shot 2010 12 27 at 13.19.46

Here’s what happens:

(Not sure this video will work properly with all browsers – here are MP4 and MOV links)

It’s a little bit of a trick: pin 6 is set to a “1” digital output (i.e. 3.3V) for one second, and then to an input for 5 seconds. Being an input means it no longer supplies power (or rather: a negligible trickle through the pull-up). So running the sketch is like periodically connecting a 3.3V power supply for one second and then disconnecting it for the next 5 seconds:

Screen Shot 2010 12 27 at 16.25.41

If you look at the circuit schematic again, you can see that pin 6 (i.e. DIO3) is connected to VIN. When it it at 3.3V, it will charge capacitor C1 through resistor R1.

The JP3, JP4, and JP5 pins are not used yet (analog 1 and 2 are inputs). The LED and resistor R2 are powered by the same voltage as what is currently present on the capacitor C1:

  • when pin 6 is high, C1 charges, and the voltage over C1 increases
  • the LED draws some current, and lights up
  • when pin 6 “floats”, C1 discharges, and the voltage over C1 decreases
  • the LED still lights up, but it gets dimmer as the voltage over C1 drops

Here’s a graph of the LED brightness over time, which matches what is shown in the above video:

Screen Shot 2010 12 27 at 16.31.01

There’s a lot of hand-waving in there: can’t actually know excatly what’s going on until we measure it, right?

Let’s start by measuring the voltage over the capacitor C1. Note that the bottom is tied to ground, i.e. it’s 0V by definition. The top side of the capacitor is tied to VHIGH, i.e. analog 2 (AIO3). So all we need to do is measure while waiting for time to pass:

Screen Shot 2010 12 27 at 16.55.46

Sample output:

Screen Shot 2010 12 27 at 16.53.43

Oh, wait. That’s not terribly useful. The analog converter reports values from 0..1023, corresponding to voltages 0..3.3V – so why not convert it to millivolts first? (I prefer to use ints, floating point isn’t very convenient on small 8-bit microcontrollers). This is the improved version:

Screen Shot 2010 12 27 at 17.03.29

And here’s some new output over a longer period of time, rearranged for brevity:

Screen Shot 2010 12 27 at 17.05.39

A quick copy of these values into a spreadsheet produces this graph:

Screen Shot 2010 12 27 at 17.11.14

As you can see, the measurements follow a very clear and regular pattern. But what’s going on? Why are these lines curved? Why doesn’t the voltage go all the way up to 3.3V? Why doesn’t it drop to zero? How does this graph explain the LED’s brightness changes? How can we get a constant brightness?

Questions, questions. Welcome to the real world, which – in case you hadn’t noticed – is mostly analog!

The neat bit about all this is that not only can we just play around and hook up components in all sorts of funky ways, we can in fact even explain exactly what is going on. Those graph shapes, for example, are fully predictable exponential curves, and there’s a very simple reason why they are this way.

I’ll go into that in a future post, but first let’s find out how to create an arbitrary voltage using nothing but one digital output pin. C’ya tomorrow!

LED discharge circuit

In Hardware on Dec 28, 2010 at 00:01

Yesterday’s post ended with the suggestion to play with some electronics bij hooking up some components to a JeeNode (or Arduino). This is really very useful (and oodles of fun, what a bargain), since it brings together so many aspects of physical computing:

So let’s do it!

Here’s the initial plan, let’s see how it pans out:

  • set up a simple yet interesting circuit
  • hook it up to a JeeNode (an Arduino wold work just as well, but using 5V)
  • write a little test sketch to drive the circuit
  • use two analog input pins as a pair of DIY multimeters
  • report the results graphically
  • interpret the results and try out some variations

The circuit I’m going to use, looks as follows:

Dsc 2405

If you’re not familiar with solderless breadboards, note that those central holes in the picture are vertically interconnected in groups of five. I.e. the brown wire is connected to one side of a brown-black-red resistor on the right, as well as to one of the two wires coming out of that large black capacitor on the left. And so on.

One LED, one capacitor, two resistors, a few wires, and a JeeNode. That’s all. But as you will see, it’s enough to explore PWM and digital-to-analog conversion, and it illustrates how you can create your very own electronics workbench to explore “RC filters”, charge curves, discharge curves, pulse generators, timers, and even create a very simple oscilloscope to understand what’s going on in a dynamic electronic circuit.

The first thing I need to do is clear things up a bit. While that above picture is a fully functioning circuit, it’s pretty awkward to see exactly what is hooked up to what. Some of these components are polarized, so there’s in fact more to it than “which wire goes where”.

Here’s the same circuit, is schematic form:

Screen Shot 2010 12 27 at 12.24.48

See if you can match everything in the schematic up to that picture above.

First thing to notice, is that there’s a lot more info here, and it’s a lot more precise. The components use a standard notation, and their values are also indicated.

Now, although it was a fun exercise for me to draw this by hand and scan it in, it’s a bit tedious if I make mistakes while drawing or when things change. Fortunately, there are computer-aided design (CAD) software packages which make it simple to draw and edit such schematics on-screen. Here’s the same schematic using EAGLE:

Screen Shot 2010 12 27 at 12.37.42

It has the same layout as the hand-drawn version, but now all the components also have names: R1, R2, C1, LED1, etc. I’ll refer to these names from now on.

Ok, all nice and well, but what does the circuit DO ???

Well, first of all, since there is no energy source in there: nothing at all until you feed it from an external power source. Doh.

But this is where the fun starts. We could just hook up a battery to it (+ to VIN and – to GND), and there would in fact be some interesting behavior. But we can do a lot better than that: we can put the entire circuit under computer control! The digital output pins on an ATmega are terrific controllable power sources, as long as we only need a few milliamps at 3.3V or 5V. And if we need more… well, that’s where transistors come in (to be described in a future post).

The other great property of an ATmega (many MPUs, for that matter), is that they also have analog and digital inputs, so they can be used to measure various aspects of the circuit under test at the same time.

This is why the above circuit is hooked up to DIO3, AIO2, and AIO3 (digital 6, analog 1, and analog 2 on the Arduino, respectively).

I still haven’t told you what the circuit does. But if you’ve played around a bit with this stuff before, you should be able to predict what this little sketch does:

Screen Shot 2010 12 27 at 13.19.46

Stay tuned…

Easy Electrons – Electric charge

In Hardware on Dec 27, 2010 at 00:01

Welcome to another installment of the Easy Electrons series.

The previous article was about capacitance. And specifically about the dynamic properties of capacitors. Complex stuff (literally so, in fact).

This time, I will focus on the charge and energy aspects of capacitors (and similar components).

First a small diversion into the land of electrical units: a farad can be interpreted as the amount of charge you need to create a voltage potential of 1 volt. Charge is described in terms of coulombs (named after Charles-Augustin de Coulomb). One coulomb is equivalent to 1 amp current during 1 second.

Once you start diving into this, you will be thankful for the International System of Units which created a set of units of measurement that are very easy to use and to remember. Being able to write that previous paragraph about what a farad is, without a single conversion factor or physical constant is a great help, also intuitively. I can clearly picture an amount of water (coulomb), being lifted a certain height (volt), and flowing at a certain rate (ampere). And even though the water analogy is quite limited, it’s a great help to visualize what’s “happening” inside an electrical circuit.

The farad unit is awkward, though.

It’s far too big a unit for most capacitors. You will often see caps described in terms of µF (microfarad, 10^-6), nF (nanofarad, 10^-9), or even pF (picofarad, 10^-12). Capacitors in the mF (millifarad) range are less common.

There’s another very widespread type of electricity containers: batteries. A battery is a bit like a huge capacitor, even though its “charge” is not held as electrical energy but as chemical energy. For batteries, the farad unit is also awkward, because it’s in fact too small. Let’s find out how many farad a standard 1.5V 2500 mAh AA battery would be, if it were a capacitor:

  • 2500 mAh means it can supply 2500 mA during one hour
  • that’s 2.5 x 3600 = 9000 “ampere-second”
  • an ampere is defined as 1 coulomb per second
  • so the AA battery holds 9000 coulomb of charge
  • in our battery, that charge is “held” at 1.5V
  • so we’d need 9000/1.5 = 6000 coulomb to reach 1V
  • than means one AA battery is essentially a 6000 farad capacitor, charged to 1.5V

As you can imagine, it’s easy to make mistakes with farads because you may encounter values in normal use which vary over some fifteen orders of magnitude. Always check your zeros carefully!

Somewhere between the basic capacitor and the battery, lies the Supercap:

This is still a capacitor, but with a phenomenally high capacitance, compared to normal caps. The one shown here is 0.47 farad. No milli, micro, nano, or pico. These small devices are relatively new, and usually only work up to 2.7 or 5.5V, max.

If anything, supercaps look a lot like little batteries. They only hold their charge for a few hours though, due to a certain amount of internal leakage. Think of it as a resistor tied permanently to its output pins, draining the charge, slowly but incessantly.

One important use for capacitors (of all sizes) is as what I’d like to call “charge buffers”. This is the case whenever you see a capacitor with one side tied to negative, i.e. ground level:

Screen Shot 2010 12 12 at 21.17.17

What these do could be summarized as: resist change. If + in the left-hand image is tied to +3.3V, then the capacitor will charge up to 3.3V and then … it’ll essentially stop doing anything. But whenever there is a distubance in that 3.3V level, the capacitor will either draw current (if the voltage went up), or supply current (if the voltage went down).

It’s not that different from a rechargeable battery. Attach a voltage higher than the current battery and the battery starts charging. Attach a lower voltage, including any circuit consuming power, and the battery starts discharging.

The circuit on the right is slightly more involved, due to the extra resistor. The same happens as before, but now, as the capacitor draws or supplies current, the current has to pass through the resistor. As a consequence, the resistor will create a voltage drop (E = I x R, again!). The effect is similar to the LED circuit with a series resistor: the resistor will reduce the current flowing in or out, thus “dampening” the effect. So what you get, is that OUT lags IN, if IN changes, but eventually it’ll follow it to whatever voltage IN is.

The right-hand side is also called a low-pass RC filter. It tracks slow-moving changes fairly accurately, but rapid changes are evened out a bit.

The left-hand circuit is used all over digital circuits, to remove “noise” (i.e. very fast but random changes) in the power supply line. The noise comes from the fact that digital circuits switch connections all the time, changing electricity flow and power draw. Often a 0.1µF capacitor is used. This is usually called a “decoupling” capacitor. It rips high frequencies out of a supply line which you’d like to remain stable.

The right-hand circuit is also useful to even out variations, but in a more gradual and controlled manner. It’s used as last step in a power supply, and to even out pulse trains. One nice use of this, is to turn an PWM signal into an analog voltage:

  • a PWM signal which is always on will produce an output of that same voltage
  • a PWM signal which is always off will produce a zero volt output
  • everything in between will produce and averaged value in between the two extremes

There are some simple calculations to determine how fast things happen. Look for the term “RC time constant” on the web. And if you run into articles such as this one, don’t let the math discourage you. As I said in the previous post, the intricate details of capacitors involve complex calculations. Just skip them. There’s plenty you can do with caps without diving in.

Supercaps are also a lot of fun to play with. You get all the properties described above – after all, it is a capacitor like any other. The difference is that things happen a lot slower, due to the larger amounts of charge involved. Supercaps have enough energy to power an LED, for example (don’t forget the series resistor!). And when it does, you’ll see how it eventually fades and dies out, as the charge drops.

A simple experiment would be to measure the voltage over time with such a supercap driving an LED + resistor circuit. With Ohm’s law, you can then calculate the amount of current drawn. Which in turn gives you an idea how brightness in LEDs is related to the current through them. If you think that’s boring, how about measuring the voltage with a JeeNode, and then sending the results to your PC and plotting the values in real time? You may not realize it, but a lot of lab experiments related to electricity can be done with an ATmega, i.e. a JeeNode or an Arduino. Who needs a multimeter? Make one!

Easy Electrons!

Easy Electrons – Capacitance

In Hardware on Dec 26, 2010 at 00:01

This is the third installment of the Easy Electrons series.

Let’s talk about capacitance. Or more accurately: capacitors. What are they and what are they for?

My mental image of a capacitor uses the water analogy: a capacitor is like a bucket of water:

Screen Shot 2010 12 12 at 16.26.53

It’s a container, and in the case of a capacitor, it holds electrical energy. How much energy depends on how much water (electrical charge) and how high up (voltage potential) it is.

If you were to take a bucket of water to the top of the Eifel tower, you’d make a pretty hefty splash on the ground when emptying it!

Screen Shot 2010 12 12 at 16.26.43

Thinking in terms of electricity, a capacitor is a little bit like an isolator, because, when left alone, it prevents the water from going anywhere.

Capacity is measured in terms of farads, the name was chose in honor of Michael Faraday. I’ll talk more about that in a future post.

Ok, so what is a capacitor, eh?

Capacitors are funny little beasts. When you feed them with voltage or current changes, they sort of absorb them. It’s easy to visualize with the bucket of water analogy: if you hold one end of a hose submerged into the bucket and raise/lower the other end to model voltage change, you can imagine water flowing into or out of the bucket through the hose to rapidly adapt to the position (height) of the other end.

Once the current flows, capacitors immediately adapt and start to match the input voltage. Once they do, current stops. You can’t keep a constant current flowing through a capacitor. It’s not simply a conductor.

Another way to describe this, is that capacitors only affect a circuit while the voltage changes. Once it is constant, the capacitor stops playing along and will start to look more and more like a complete isolator.

This behavior is hard to grasp. You can’t just look at one state and reason from there, you have to look at the state over time and think in terms of change. Capacitance (and induction, for that matter) is substantially more complicated as concept than resistance.

But even though it’s hard, I think I can give you a feel for why it’s so tricky, using a little analogy.

When doing calculations with capacitance, dynamic systems, changes over time, and such, you’ll quickly run into something called complex numbers, a mathematical concept with immense implications in the field of electronics and other domains of physics.

Complex numbers are… w e i r d – well perhaps not as mind-bending as quantum physics, but still: complex numbers are an extension of normal numbers, in that every value consists of a real and an imaginary part. Want an example of how weird that is? How about: you can’t take the square root of a negative number such as -1, right? Because there is no value in the world which will produce -1 when multiplied by itself. Right? Wrong. With complex numbers, there is such a value (it’s called “i”, the unit of imaginary numbers).

But not to worry. I won’t expand further on complex numbers. And luckily there’s no need!

Suppose you were looking at a child sitting on a swing, swinging happily along – image on the left:

Screen Shot 2010 12 12 at 17.48.52

As you watch, you can see two things going on: a sideways motion and an up-down motion. Always mesmerizing, because there is this intriguing relationship between vertical and horizontal position and things like velocity. You’re looking at the fascinating world of complex numbers, using the analogy of a pendulum.

Now imagine yourself looking at that same child swinging, but from the back, swinging away and towards you. It’s the same situation, but you’re only seeing part of the picture – image above, on the right.

What you see, is a swing moving up and down in some smooth repeating cycle. There’s much less to reason about now. You can no longer contemplate the periodic alternation of angular velocity and potential energy (i.e. height). There’s a hidden dimension which you can’t observe. IOW, you’re no longer seeing the big picture, but only half the essential information, i.e. only the real part, not the imaginary part.

That’s what makes it so hard to build up an intuition about what capacitors do. They require a richer conceptual model. Most of us are not trained to think in complex numbers, we just see quantities as a simple numerical value.

Fortunately, this need not prevent us from dealing with capacitors. We just have to work a bit more from memorized rules and water analogies, instead of innate intuition.

This is why I think of a bucket of water, and how it “dampens” all changes it is subjected to:

Screen Shot 2010 12 12 at 17.20.41

That’s also known as a “low-pass filter”. Very useful to turn a PWM signal into an analog voltage level, for example.

And why for me, capacitors “pass electrical changes” and then “become isolators”:

Screen Shot 2010 12 12 at 18.26.30

That’s a high pass filter, by the way. It doesn’t let the flat portions of the input signal through, just the edges.

Next time: a bit more about farads, charge, and really really big caps.

Site changes

In News on Dec 25, 2010 at 00:01

Two small changes here at JeeLabs. Well, small for you, if I did my homework properly…

First, the http://jeelabs.org/ domain has been migrated to the new server, now that the new internet link appears to be stable.

This change should be mostly transparent. Same content, same format, same “content provider” as before, everything has been transferred as is.

The server and the internet link are quite a bit faster than before. Both are currently under 10% utilized, and should be able to handle growth as needed. The extra speed is particularly noticeable in the search box at the bottom right of this weblog:

Screen Shot 2010 12 24 at 14.56.13

The second small change is that “Jee Labs” will be called “JeeLabs” from now on. It’s official. No more white space. Eight bits closer to world domination :)

I’ve been wanting to get away from the two separate words for some time now, one reason being that a single InterCapped name is more googleable – and this server migration seemed like a good time to make the switch.

So better get used to it, this is the name of the new-yet-unchanged home:

Jeelabs

This was a fairly elaborate site migration for me, and now both jeelabs.net and jeelabs.org are done. I’ve got a few other changes ahead of me before the rented server (located in Nürnberg, Germany) can be taken offline. But that will have less impact and should be easy to finish in the months ahead.

Onwards!

Gas consumption

In Musings on Dec 24, 2010 at 00:01

The gas consumption at JeeLabs is enormous these days – some 15..20 m3 per day right now. One reason for this is that our house is well-insulated but very open. All the warm air tends to move 2..3 flights up, even though we try to keep all the doors upstairs tightly shut.

The trip to Germany a few days ago provided an interesting opportunity to get a better insight in how all this heating works.

Our thermostat is set up to heat the house from roughly 6:00 (6AM) to 23:00 (11PM). It’s a fairly advanced unit with some predictive logic to attain those settings, which is why it actually starts about an hourly early:

Screen Shot 2010 12 22 at 12.53.21

The above graph shows two superimposed heating cycles, with the current one still in progress (it was around 13:00 when I took that snapshot). As you can see, the heater is almost flat out, with some extra peaks during hot water use.

Here’s the gas consumption over the past 7 days:

Screen Shot 2010 12 22 at 12.51.45

The gray bands are sunset/sunrise, ie. day/night periods.

What I did was turn down the heating on Friday morning, when we left for our trip. The normal setpoint is 19..20°C, but the thermostat has a “vacation mode” which changes that into a permanent 14°C.

As you can see, the house took almost a day to cool off. Not bad, knowing that it was permanently freezing outside at that time.

On Saturday, the heating starts up a bit again, and then stays on at a reduced level most of the time, i.e. day and night, until we got back late Monday evening. Which is when I restored the normal cycle.

The interesting bit is the end effect of getting back to normal. Here are the same readings, now as totals over the entire day:

Screen Shot 2010 12 22 at 13.21.47

Same pattern as before, of course: 17th and 18th almost nothing, then slightly lower consumption rates to keep the house at 14°C, and finally on the 21st a big push to get back to our normal comfy levels.

Here are the same values, numerically:

  • 15th – 15.71 m3
  • 16th – 16.83 m3
  • 17th – 3.52 m3
  • 18th – 5.79 m3
  • 19th – 12.40 m3
  • 20th – 14.02 m3
  • 21st – 28.16 m3

I should add that outside temperatures were a bit lower on the 19th and 20th, so these consumption levels cannot be compared 100% accurately.

But what stands out is that heating up the house back to 19..20° takes almost as much energy as what was saved on the days before. In other words: you can try to save all you like by turning the heater low when leaving the house – if you come back and want to get it back to the original level again, you basically have to add almost as much energy back in as if you hadn’t turned the heater down in the first place!

Heating is not a matter of “on = comfy, off = energy saving”, but one of keeping a whole pile of stones and concrete at a certain temperature. And this holds true even in very cold times. Apparently, the amount of stored energy is substantial compared to the amount of energy loss, and having a slightly cooler house doesn’t affect the rate of energy loss all that much.

This probably also explains why our gas consumption can still be 25% lower than average in this neighbourhood, despite the fact that many people are away and work elsewhere – while I keep the house heated all day long… (just a bit more sparingly than most, I guess).

Snowed in

In Musings on Dec 23, 2010 at 00:01

There are worse times to be immobilized, than in this wintery time – with large parts of Northern Europe completely snowed in.

Here’s the view from JeeLabs, i.e. Houten / Netherlands, right now:

Dsc 2404

Dsc 2401

Dsc 2403

I find it absolutely gorgeous. With all the beauty of this scenery in plain view – and the nearly 30°C temperature differential across our double paned windows as reminder of the huge comfort brought about by yet another marvel of modern engineering.

Emergency stop

In News on Dec 22, 2010 at 00:01

This is a weblog post I never wanted to write…

If you’ve been waiting for stuff you’ve ordered from the JeeLabs shop in the past weeks, and it hasn’t arrived yet, then I have some really bad news for you: don’t expect anything the rest of this year…

I’m hitting the emergency stop button:

Emergency Stop

The two big issues in the past two weeks were mentioned in a recent post, and they are both of the kind I can (learn to) deal with: fluctuations in demand and fluctuations in supply, along with occasional shipping anomalies. It’s frustrating for everyone involved when this doesn’t work out well, but hey – been there done that, from both sides of the table now.

Trouble is, I’m now running afoul on a third hurdle: a couple of days ago, I strained my lower back. The trip to Braunschweig may have made it worse, unfortunately, although I had hoped these few days off would cure it. It’s most probably stress related, even though I consider myself an expert in stress avoidance. You see, normally I’m the guy who overcomes any type of setback, no matter what happens and no matter what the stress levels are. And having run a marathon 4 years ago, I have not the slightest inclination in the world to keep some mundane injury from letting me do what I love doing so much these days, i.e. taking JeeLabs further.

Except that now, I’m forced to pull all the stops on the shop. Continuing as is at this stage would be sheer folly.

There are currently some 70 back-orders. I will continue to send out packages as soon as new components come in. But given the delays of several of my orders, one of them pending for almost two months now, it’s no longer realistic to expect anything soon. The busiest delivery season of the year, a totally snowed-in infrastructure across all of Europe and beyond … it all doesn’t make the situation any better.

If you’ve been waiting for some time, please email me if you wish to cancel / get a refund and I’ll take care of it.

I’m not going to attempt to make a prediction for the next few weeks. My guess would be as good as yours. I can only wait, try and find out more about the actual status, and prepare to get things going again as quickly and smoothly as possible once everything returns back to normal.

Meanwhile, I’ve got some silly muscles to tend to… but that’s actually the easy and most predictable part!

Cheers,
– Jean-Claude

Touch screen

In Hardware on Dec 21, 2010 at 00:01

Steve Evans (tankslappa on the forum) emailed me recently to present some really exciting developments he’s been working on: a touch screen interface for the Graphics Board:

Whatiwrote

You’re looking at a little touch screen, placed over the Graphics Board, and as you can see, the size matches up surprisingly well.

Pretty fantastic result! And considerably more precise than I had expected.

He used the touch screen overlay of the Nintendo DS, which can be obtained from eBay. As it turns out, this can be hooked up using 2 digital + 2 analog I/O pins, which is exactly what’s still available on the unused two ports.

All that was needed, were 4 pull-down resistors:

Connection

The devil is in the details, though. very small details in fact:

Tinyconnector

Steve mentioned that it took a considerable amount of patience to get 4 wires soldered to that tiny flexible ribbon, with 0.5 mm between each connection. Clearly, a proper connector would have been a bit more convenient (though just as tiny).

Being resistive and analog, this whole thing needs to be calibrated:

Calibrate 1

The code for this has been added as a sample sketch called touchscreen.pde in the JeeLabs repository.

BTW, this is part of a new GLCDlib library, which I’ll describe in more detail tomorrow. Stay tuned!

Schönen Gruß aus Braunschweig!

In Musings on Dec 20, 2010 at 00:01

Not to worry, this weblog remains “mostly” English :)

Just wanted to say hello while on a very brief weekend-trip to Germany, visiting my brother…

I’ll leave you with a couple of visual impressions from this trip, including a visit to Wolfsburg (Alberto Giacometti and the “Phaeno” Science Museum) and the “Weinachtsmarkt” …

Regular scheduled transmissions to resume tomorrow…

Easy Electrons – LEDs

In Hardware on Dec 19, 2010 at 00:01

This is the second installment of the Easy Electrons series. This isn’t a “course” in electronics. Just a grab bag of topics, and an attempt to convey my somewhat intuitive grasp of them. That’s also why I’m not going to systematically cover all the usual types of components, not in the traditional order anyway.

Today’s topic is low-power signaling LEDs, or Light Emitting Diodes.

Heres a very nice exposed diagram of a standard low-power red LED, from HowStuffWorks:

Led Diagram

Schematically, a LED is shown as an arrow (same as a diode), with light coming out. Here’s the Blink Plug, with two LEDs and two switches:

Screen Shot 2010 12 12 at 14.42.29

Here is the way you hook up a single LED:

Screen Shot 2010 12 12 at 14.47.06

The arrow has to point from + to – for the LED to work. It’s a diode, meaning that in the other direction it just “blocks” (no current, nothing happens). Also note that, since this is a series circuit with LED and resistor connected one after the other, it doesn’t really matter in which order you hook them up. This circuit will work just as well if the resistor comes first. As long as + “flows” to – through the LED.

So what’s that resistor doing in there?

Well, LEDs (like any diode) are very peculiar in terms of voltage and current. They behave in a specific way:

  • below a certain voltage, nothing happens, i.e. no current flows
  • when no current flows, the resistor makes no difference at all (E = I x R, i.e. 0 x anything is still 0!)
  • above a certain threshold, the LED starts conducting and letting all current through
  • the LED only emits light above that threshold
  • the brightness of a LED is determined by the amount of current through it
  • LEDs only support a certain amount of current, any more will damage them

To use the water analogy, an LED is like a dam which will not let water through before a certain level has been reached. Once that happens, everything more spills over:

Screen Shot 2010 12 12 at 15.09.35

The threshold depends on LED type: with red LEDs, it’s usually around 1.7V, with blue LEDs, it’s more like 3V.

You can’t just connect an LED directy to a power source. Think about it. LED behavior can be graphed as follows:

Screen Shot 2010 12 12 at 14.47.16

In other words: if the voltage is too low, nothing will happen. And if it’s too high, the current through the diode will be immense (and destroy the LED). We could try to regulate the voltage just right, but it varies slightly per LED and also depends on temperature, for example. There’s no way we can adjust our power supply once and get just the right level, day in day out. Besides, often we can’t even adjust the voltage at all, such as with a battery.

So how do we solve this?

Well, that’s where the resistor comes in. This is an example of another major use of resistors: current limiting.

Again, go back to Ohm’s law, i.e. E = I x R (memorize it, please!). The more current flows through a resistor, the higher the voltage over it. Or equivalently, the higher the voltage placed on it, the more current will flow.

In the above LED circuit, the resistor will always have the input voltage minus the LEDs threshold voltage over it (once the input is higher than the threshold). The effect on the voltage and current in this circuit changes in an important way due to the extra resistor:

Screen Shot 2010 12 12 at 15.09.44

The vertical “knee” in the original LED graph has turned into a more gradual slope, due to the added resistor. As more surplus voltage is handed over to the resistor, it starts to gradually use more current. This effect is completely linear, btw. An LED with a 1.7V threshold will be twice as bright with a 4.9V power supply as with a 3.3V supply.

Ok, well, so much for the pictures. What this tells us is that we can now calculate exactly what resistor we need.

For example, say we want to light a LED using a 3.3V power supply and let 10 mA (0.01A) current flow through it, which is a good value for standard LEDs. What resistor do we need?

  • the LED “takes” a fixed 1.7V
  • that leaves 1.6V for the resistor when the supply is 3.3V
  • we want to get 10 mA flowing through the LED
  • since the resistor is in series, it’ll get those same 10 mA
  • E = I x R can also be written as R = E / I (same law, different usage)
  • so R needs to be 1.6 V / 0.010 A = 160 Ω

Take a LED, add a 160 Ω in series, and the LED will work great on a 3.3V power supply. A more easily available 150 Ω resistor will work fine too, BTW. Almost the same currrent.

What if you don’t have a 150 Ω resistor, but only a 1 kΩ one? No problem, the current through the LED then becomes: (I = E / R), i.e. 1.6 V / 1000 Ω = 1.6 mA – usally still enough to turn the LED on, but not as bright.

Easy Electrons!

Rethinking the Arduino hardware interface

In AVR, Hardware, Software on Dec 18, 2010 at 00:01

It’s been almost two years since the first design was created from which the JeeNode was born. It went from this very first prototype:

… to this leaner-and-meaner design, which is the current JeeNode v5:

Jlpcb 105

As you can see, it’s still essentially based on the same layout.

The JeeNode has been the flagship product here at JeeLabs for quite some time. It has been expanded to include a JeeNode USB variant which includes a USB interface and a LiPo charger, as well as a USB “stick-like” JeeLink that ties nicely into the WSN use of JeeNodes. And then there’s the bare-bones JeeSMD, which doesn’t have a wireless module built-in, but which is pin-compatible with the other two members of the JeeNode family.

With all the end-of-year stories coming up, and new year’s resolutions to follow soon, it seems like a good time to present my reasons for doing things this way.

Rethinking the Arduino hardware interface
That’s – in a nutshell – the essence behind the JeeNode.

I stumbled upon the fascinating world of Physical Computing and “Arduino’s” over two years ago, around the time when I also discovered an interesting low-cost wireless module. Lots of things “clicked” right away, but a few didn’t. Given that the Arduino is simply an ATmega (hardware), plus an IDE (software), plus a set of conventions (shields), I quickly realized that there might be more ways to skin this cat, and something new was born (inspired by the RBBB) – as summarized here a year ago.

I don’t want to rehash those points, but let me simply state what the JeeNode is about, assuming you know what an Arduino is.

  • the JeeNode lowers the operating voltage to 3.3V (implications)
  • it includes a wireless radio module (with software)
  • it drops the concept of shields (hard to combine)
  • instead, it adds 4 interchangeable 6-pin Ports (layout)
  • each port includes two dedicated I/O pins as well as power
  • there are numerous Plugs using this port pinout (list)
  • about half the plugs use (software) I2C and can be daisy-chained
  • there are many interface classes and code examples (here and here)
  • the remaining I/O pins are on two extra headers (details, PDF)
  • JeeNodes can be mounted upside-down (CB, GB, POF)
  • … or used alongside a solderless breadboard (BB)
  • with extension cables to move plugs further away (EC)
  • … or a prototype board to re-use all the I/O pins differently (PB)
  • reduced cost by using a detachable / reusable USB-FTDI interface

All this, while remaining fully compatible with “the” Arduino’s software + firmware.

But perhaps the most interesting bit coming out of all this, is that the JeeNode has become a practical ultra-low-power platform, with battery lifetimes measured in months, almost a year even, so far. There have already been tons of posts about this topic. It even spawned a nice little add-on to run JeeNodes from a single AA or AAA cell.

You may or may not agree with all the choices, but this is what the JeeNode is about.

Update – the Redmine repository is no longer available, everything is now on GitHub.

The downside of success

In News on Dec 17, 2010 at 00:01

With over 2,500 units produced to date, it’s safe to call the JeeNode (Kit + USB + JeeLink) a success. A runaway success in fact, in my opinion.

Great, but…

This isn’t purely good news, alas. The demand for JeeLabs products has been increasing so much lately, that I’ve run into serious supply problems in the shop these past few weeks. I can assure you that I’m extremely unhappy with that state of affairs – and the pain isn’t over yet, with some parts taking weeks longer than expected to reach me. This shortage might last into January 2011 for items such as the Ether Card.

So it’s a bit awkward to talk about “success” at a time when there are still 50 back-orders in the shop (down from 90…), with probably quite a few people frustrated by the slow delivery times. A postal strike next week in the Netherlands and the extra delays due to the busy Christmas season are clearly not going to help one bit.

Summary: the JeeNode design has been working out very nicely, but my ability to make it properly available is lagging far behind. My only way out is to “get larger quantities – sooner”. Which is exactly what I’ve been doing lately, in collaboration with Modern Device, who have started carrying more and more JeeLabs products for the US and nearby regions. We’re both scaling up, while trying not to drive ourselves off the cliff…

Cliff

The current “crunch” is with headers, with 10,000 of them waiting in customs (again) and holding up just about everything, and with Ether Cards, RTC Plugs, and 2×16 LCD displays. That last one is holding up the Wireless Starter Packs as well.

In principle, all packages are sent out when complete, or nearly so in some cases. I cannot speed up things, although I keep looking for alternative suppliers. If you would prefer to get two partial shipments (no extra cost), please get in touch. I will of course also honor any cancellation, if you decide that you’ve had enough of this.

Please bear with me as I try to get over these growing pains. I apologize for all the delays and inconvenience this is causing. As new deliveries are coming in, I am continuously going through my backlog to fullfill as many pending requests as possible.

Voltage: 3.3 vs 5

In AVR, Hardware on Dec 16, 2010 at 00:01

One of the decisions made early on for the JeeNode, was to make it run at 3.3V, instead of the 5V used by the standard Arduino.

The main reason for this was the RFM12B wireless module, which can only be used with supply voltages up to 3.8V, according to the specs. Running them at 5V seems to give varying results: I’ve never damaged one, but there have been reports of such failures. Given that the older RFM12 (no B) worked up to 5V, my hunch is that something in the design was found to give problems at the higher voltage. It’s just a guess on my part, though.

So what’s the deal with 3.3V vs 5V?

Well, the first thing to note, is that the ATmega328 used in a 3.3V JeeNode runs at the same 16 MHz frequency as a 5V Arduino does. This overclocking is “out of spec”:

You’re not supposed to do this, but in my experience the good folks at Atmel (the designers and manufacturers of ATmega’s and other goodies) have drawn up specifications which are clearly on the conservative side. So much so, that not a single case has been reported where this has caused problems in any of the several thousand JeeNodes produced so far. As I pointed out in a previous post, that doesn’t necessarily mean everything is 100% perfect over the entire temperature range. But again: no known problems to date. None.

This is good news for low-power uses, BTW. It means you can get the same amount of work done using less power, since power = voltage x current. Even more so because both voltage and current are lower at 3.3V than when running at 5V.

A second reason for running at 3.3V, is that you can use 3 AA batteries instead of 4 (either alkaline or rechargeable). And that you can also power 3.3V circuits with LiPo packs, which have this hugely convenient 3.5..4.2V range.

The third important reason to run JeeNodes at 3.3V, is that more and more neat sensor chips are only available for use in the 2.7 .. 3.6V range or so. By having the entire setup operate at 3.3V, all these sensors can be used without any tedious level converters.

Occasionally I’ve been bitten by the fact that I used a chip which doesn’t work as low as 3.3V, as in the first RTC Plug trial. But more often than not, it’s simply a matter of looking for alternative chip brands. One recent example was the 555 oscillator used on the Infrared Plug: the original NE555 needs at least 4.5V, but there’s an ICM7555 using CMOS technology which works down to 3V, making it a non-issue.

Mixing 3.3V and 5V devices

The trouble with these voltage differences, is not just that the power supply needs to be different. That’s the easy bit, since you can always generate 3.3V from a 5V supply with a simple voltage regulator and 2 little capacitors.

The real problem comes from the I/O interface. Placing a 5V signal on a chip running at 3.3V will cause problems, in the worst case even permanently damaging the chip. So each I/O pin connected is also affected by this.

Fortunately, there’s often a very simple workaround, using just an extra resistor of 1 kΩ or so in series. To see how this works, here’s the way many chips have their input signals hooked up, internally:

Screen Shot 2010 12 14 at 23.35.16

There’s a pair of diodes inside the chip, for each pin (not just the inputs), used for ESD protection, i.e. to protect the chip against static electricity when you pick it up.

These diodes “deflect” voltage levels which are above the VCC of the device or below GND level. They do nothing else in normal use, but if you were to place 5V on in a pin of such a device powered by 3.3V, then that would lead to a (potentially large) current through the upper diode.

With electronics (as with humans, btw), it’s usually not the voltage itself which causes damage, but the current flow it leads to, and – in the case of sensitve electronics components – the heat produced from it.

By placing a 1 kΩ resistor in series, we limit the flow through the diode to under 2 mA, which most devices will handle without any problems:

Screen Shot 2010 12 14 at 23.42.27

Ok, so now we can hook up signals to a JeeNode, even if they swing in the 0..5V range. This works best with “slow” signals, BTW. The extra resistor has a bad effect on rise and fall times of the signal, so don’t expect this to work with signals which are in the 1 MHz range or higher. Then again, it’s unlikely you’ll need to tie such fast signals directly to an ATmega anyway…

How about the other direction?

What if you have a chip running at 5V which needs to receive signals from a chip running at 3.3V, i.e. signals going in the other direction?

Well, it turns out that this may or may not work by simply tying the two lines together. The 3.3V output signal will definitely not damage a chip running at 5V. The worst that can happen, is that the 5V side doesn’t consider the signal valid.

We need to look into logic levels to figure this one out, as specified in the datasheet of the chip. The easy part is logic “0”, i.e. a low level. Most chips consider anything between 0 and 0.8V a logic “low”. There will hardly ever be an issue when tying a 3.3V chip to a 5V chip.

The tricky part is logic “1”, i.e. a signal which is intended to represent a high level. Now it all depends on what the 3.3V chip sends out, and what the 5V chip requires.

Most CMOS chips, including the ATmega, send out nearly the full power line voltage to represent a logic “1” (when the load current is low), so you can expect output signals to be just about 3.3V on a JeeNode.

On the input side, there are two common cases. Some chips consider everything above 1.6V or so to be a logic one. These chips will be perfectly happy with the JeeNode signal.

The only case when things may or may not work reliably, is with chips which specify the minimum logic “1” voltage to be “0.7 x VCC” or something like that. On a 5V chip, that translates to a minimum value of 3.5V …

Note that datasheets usually contain conservative specs, meant to indicate limit values under all temperatures, load conditions, supply voltages, etc.

In practice, I find that even with “0.7 x VCC”, I can usually drive a 5V chip just fine from a JeeNode. The only exception being higher power chips, such as stepper motor drivers and such, which operate mostly at much higher voltage levels anyway. For these, you may have to use special “level translator” chips, or perhaps something like the I2C-based Output Plug, which can be powered with voltages up to 50V or so.

This post only addresses digital I/O signals. With analog I/O, i.e. varying voltage levels, you will need to carefully review what voltage ranges are generated and expected, and perhaps insert either a voltage divider or an op-amp to amplify voltages. That’s a bit more involved.

But all in all, living mostly in a 3.3V world is often more flexible than living mostly in a 5V world, nowadays.

Which is the fourth reason why I decided to run JeeNodes at 3.3V, BTW.

Subversion

In Software on Dec 15, 2010 at 00:01

After yesterday’s post about source code control systems, here are some notes about getting started with it.

I’ll focus on Subversion, because that’s what I’m using.

Update, 2013 – Subversion is no longer in use, everything is now on GitHub.

There are two sides to a version control system: the server, where the source code “repository” is kept, and the client, which is your own workstation / PC. In distributed systems (DVCS), for example Git, there is no such asymmetry – client and server can perform the same tasks. But Subversion uses a centralized model: one repository, any number of clients.

You’ll need at least the client software to be able to use Subversion:

  • On Windows, you can use TortoiseSVN. It integrates deeply with the Windows Explorer, meaning that the current status of each file is always visible. See this page for some screen shots.

  • On Mac OSX it’s built-in (starting with 10.5, Leopard, I think) – although you probably have to install the Xcode that came with your Mac. You can check by typing “svn” in the terminal. If you get “Type ‘svn help’ for usage.”, then it’s ready for business.

  • On Linux, it’s a package called “subversion”. Install via your favorite package manager, depending on which flavor of Linux you’re using (e.g. Ubuntu).

Here’s the big picture:

Screen Shot 2010 12 14 at 15.26.17

Assuming you’re trying this out with existing source code (from JeeLabs, for example), then the server is somewhere on the internet, so you don’t have to deal with its setup. A little terminology and some conventions:

  • the server has all the source code and all the changes in a “repository”
  • you can get a local “working copy” by “checking it out” from the server
  • you can do anything you like on your copy, but…
  • don’t rename files or move anything around, without telling subversion
  • you cand send changes back by “checking them in” (a.k.a. “commit”)
  • you can adjust your copy to the latest version by “updating” your copy

So the basic idea is to check out a working copy (once), and then doing an update whenever you want to make sure you have the latest and the greatest. This update is totally safe: if you made changes on your working copy, and you do an update, subversion will tell you that there are changes, and occasionally maybe even a “conflict”, i.e. if your changes interfere with changes made by others.

Note that conflicts can occur in two ways: when updating your modified copy, or when committing your changes back to the server. The latter can lead to a conflict when someone made changes which you didn’t pick up yet.

If you don’t intend to make changes, or only minimally, then conflicts are a non-issue. In that case, subversion is simply a convenient (and very quick/efficient) way to keep up to date with all the latest changes.

There is another convenience, in that you can check to see what has changed, before updating. Perhaps you want to first examine the changes – and only the changes – to decide whether you want to adopt that latest version. This can be done with the subversion “status” and “diff” commands, but with the new Redmine setup at JeeLabs, it’s actually much simpler to use the web interface for this. Simply browse the repository from the web, starting here, and review the comments shown under the “Latest revisions” header (last ones are at the top). By zooming in as described yesterday, you can quickly see whether the changes are of interest to you. You could even decide to opdate only a single source file. Subversion will track all this, even with some parts updated and others not.

Let me give an example how to use subversion for getting the Ports library. I’ll use the command-line interface for this, assuming that it maps relatively simply to the GUI-based TortoiseSVN on Windows.

Step 1 – Initial check-out

You need to be in the proper place to check out. In this case, we want to get a “Ports” folder inside a “libraries” folder, which in turn needs to be placed inside the Arduino IDE’s “sketches” directory. On Mac OSX, this is “~/Documents/Arduino”. So the first thing to do, is make sure that the libraries folder exists:

    % mkdir -p ~/Documents/Arduino/libraries

Then go to that directory:

    % cd ~/Documents/Arduino/libraries

Now, we’ll check out the Ports library from JeeLabs:

    % svn checkout svn://svn.jeelabs.org/jeelabs/trunk/libraries/Ports

A new directory is created with the same name, i.e. “Ports”. It will contain all the source files. So we’re essentially done.

One thing to note, is that subversion needs to track a bit of information (such as where this Ports thing came from and when it was checked out). It does this in sub-folders called “.svn” – the leading dot is a convention to keep this area hidden. So it’s there all right, but you often won’t see it. That’s fine. Never go in there and make any changes, or you’ll completely mess up your working copy, as far as subversion is concerned.

Step 2 – Using the source code

Nothing much to say here. Just use it as if you had created the Ports folder yourself, perhaps by unpacking a ZIP archive. Apart from the “.svn” hidden areas, it’s the same thing. You should check out a copy of the RF12 library as well, since that’s always needed when using the Ports library:

    % cd ~/Documents/Arduino/libraries
    % svn checkout svn://svn.jeelabs.org/jeelabs/trunk/libraries/RF12

You can make changes to the source files if you want to. Subversion will know what you did, when asked, because it keeps an extra copy of the original files in the “.svn” folders, and besides, it could also use the server to check.

The one thing you can’t do with subversion (some other systems are more lenient), is to delete, rename, or move files and folders as you were used to. Don’t do things like these, or use other commands or programs to the same effect:

    % mv foo.c bar.c
    % rm foo.h

Instead, ask subversion to do it for you, and all will be well:

    % svn mv foo.c bar.c
    % svn rm foo.h

Step 3 – Tracking updates

Updating your copy to the latest version in the repository is trivial, and can be done at any time with:

    % svn update

You will get a concise summary of which files were changed. Changes may also include adding new files and removing obsolete ones. After the update, your working copy will be in sync with the repository again.

If you only want to find out what would be changed, without actually updating anything, use the status command:

    % svn status -u

But usually it’s simpler to use the web interface for this. For the Ports library, just go to http://jeelabs.net/projects/cafe/repository/show/Ports.

Step 4 – Submitting changes

If you have write access to the repository, then you can also submit the changes you made in your working copy. All you need is a reason… :)

Seriously, the only thing that needs some thought is what to put in the comment describing this change. Because Subversion insists on some comment. I usually check in after every little change and add a very brief note describing it, such as:

    % svn ci -m "fixed bug X so Y works again"

Note that with all these commands, you don’t have to mention the respository at all. Subversion knows which repository is being referenced by looking at the information in the “.svn” folder in the current directory you’re in.

I won’t go into conflict resolution or any of the numerous more advanced commands in subversion. Check the excellent manual online to find out more.

That’s it!

The only comment I’d like to add to conclude this weblog post, is that the above was written specifically for subversion. Many other systems exists, but once you are used to the terminology and conventions of one, using another version control system is usually no big deal. Lots of people seem to be using Git these days. No doubt due to the free GitHub source repository server, available to anyone who wants to maintain their source code in a public place. It comes with a nice and powerful set of features, see the help section for an overview.

Have fun with version control – and say goodbye to version mixups once and for all!

Source code

In Software on Dec 14, 2010 at 00:01

From the beginning, all Open Source Software at JeeLabs has been maintained in a system called Subversion. This is a version control system which makes it easy to manage changes in (large amounts of) source code over (large periods of) time.

There are many such systems, with names like CVS, Subversion, Bazaar, Git, Mercurial, and more. I used CVS in the past, and switched to Subversion many years ago. It suits me well.

If you think that version control is not much more than “making frequent backups in an organized manner”, then you may be in for a surprise. Please keep reading…

All of these systems deal with the same task: managing edits. And all of them have reached a level of functionality and maturity, that frankly, I couldn’t understand how anyone writing software these days could live without…

That’s quite a statement, so let me explain.

Software development is a process. You write code, you fix bugs, you add new features over time – sometimes over a period of years, in fact. Coding is an error-prone activity, from trivial typo’s, to syntax errors, to feature omissions, to design errors… it’s all part of the process.

Suppose someone finds a bug. Wouldn’t it be great if you could go back and see what changes you made, and in what order? Maybe the bug is a new one? Maybe it got introduced by a recent change? Maybe it’s part of a very specific feature?

Here’s an extract of a special “annotated” view of the RF12.h header file. This overview was generated by Redmine, as it is now used for the JeeLabs Café:

Screen Shot 2010 12 13 at 21.05.29

The color-coded areas are “change sets”. The numbers indicate in which “revision” this particular code was added or last changed. The numbers are clickable, so if I click on “5976” for example, to view the last change related to the rf12_sendStart() code, I get this:

Screen Shot 2010 12 13 at 21.08.23

This shows exactly which files were changed at the same time, and the comment I added when I made that change, i.e. “more rf12_sendStart() low power modes”. The value is not just this little overview, but the fact that all other files and changes have been omitted. All irrelevant info is gone.

Let’s say I want to find out what was changed in the “radioBlip.pde” sketch at that time. I can click on the “(diff)” link, to get this:

Screen Shot 2010 12 13 at 21.10.20

Aha, this is apparently where I added some extra low-power-mode options to the RF12 driver, as I was writing the radioBlip example (red = deleted code, green = added code).

Note how only a small part of the source code is shown. I’m only interested in what changed, so all I get is a “diff” with a few lines of context. I can always go back to my full copy of the source code to see the rest.

This particular change was made 4 months ago. It took me three clicks in the web browser to find out what happened. Not “sort of”, but precisely. I don’t know about you, but to me that is an incredible way to keep track of things. I never have to guess, I can go back in time and zoom in on any specific detail I’m interested in right now.

Let me drive the point home: this isn’t a feature, it’s a necessity. There is no way I could call myself a software developer without tools like these.

All version control systems do this, it doesn’t really matter which one you use. All I can say is: if you haven’t been using any of them, pick one and put your whole (software) life in it. Today. You will have to learn some new conventions and some new habits. You will feel constrained initially. But once that wears off and the new habits kick in, you will wonder how you ever did without.

This doesn’t just apply to “official” software development, btw. Anything that takes more than say a day to work on, will benefit from revision control, IMO. Some people put their entire websites in there. Some people even put their entire home directory in there!

The nice thing about modern revision control systems, is that they are networked. With proper care and authentication, source code can live in a public “repository” accessible to more people. Websites such as http://github.com/ specialize in providing a complete environment for anyone who wishes to manage their source code in public. Completely free. All you need is the proper “client software” for the version control system you’re using, and a server (such as Github) where you get source code and send changes back.

By now, I no longer consider the source code on my hard disk to be crucially important. It’s a copy, “checked out” from my main subversion repository, which lives on an internet-facing server. I can get an up to date copy anywhere, just by checking out a new copy (as long as I remember where the server is, and my personal username/password).

The second killer feature (no less) of a version control system, is that it lets people work together on a single project, no matter where they are. Everyone gets their own locally checked-out copy of the same project, and everyone can make whatever changes they like, and “check-in” the changes whenever they please.

This happens very efficiently, because version control systems are immensely clever about dealing with text changes. They don’t send around complete projects and source files all the time, they quickly send little changes around (called “diffs”). This makes the mechanism 100% scalable. You could be working on a project with millions of lines of source code. Yet when you send in a change, the process is almost as quick as with a tiny project.

When more than one person makes a change to a source file, and sends in that change, three things can happen:

  • there is no one else who changed that file, so the change is accepted as is
  • someone else changed that file, but not in the same place – again, the change is automatically accepted as is, and “merged” in
  • someone else changed one or more of the same lines, in which case the change is flagged as a conflict

The last case is the only one which needs a bit of attention. The changes need to be compared, and someone has to decide what the final version should look like. Usually, the intent is easy to spot, and things can be resolved without any further discussion. In rare cases, the two people involved will have to discuss and resolve the issue between them.

This sounds like a lot of hassle. But it’s in fact one of my favorite features: I can check out someone else’s source code, and use it. But I can also make changes in any way I like, without ever sending them in. IOW, I can tweak any code I have in any way I like. Never will I risk losing those changes, even if I never send them in (often, they are not of general use anyway). And I’ll always be able to go back and see what my own changes were.

So with this guaranteed checking and comparing of source code, it becomes impossibe to lose changes. My own, or anyone else’s. The version control system will flag any potential problem before it actually becomes one.

More tomorrow, as I describe how to get version control going on your own machine, and how to hook up to the source code in the JeeLabs repository.

If you can’t wait and already know how to use Subversion, all the JeeLabs code can be found here:

    svn://svn.jeelabs.org/jeelabs/trunk/

If you just want to have a quick look around using the new Redmine web interface: the JeeLabs libraries can be browsed here, while JeeMon has its own repository area, which can be browsed here.

Popping fuses

In Hardware on Dec 13, 2010 at 00:01

The power-line isolation saga continues…

Danger High Voltage alt 1 md

Ok, so the idea of adding an extra RCD device which trips on differences in current turns out to be a mistake. It adds no extra protection when used in the secondary winding of such a setup. I will leave it out.

Next step was to hook up the circuit as described in the above post. Soldered evertyhing in place, used heat-shrink tubing to isolate the loose ends, lots of hot-glue to fix things, and then:

Dsc 2398

POP, said the 5A “slow” fuse – and the next one too!

That’s not just a molten piece of metal, BTW, that’s a vaporized coating on the left. I suspect that the current was substantially over 5 amps. But no ill effect on the rest of the house, no lights dimming, and no other blown fuses (the main ones downstairs are all 16A).

Uh oh, something is wrong. Well, at least I now know the fuse works!

Here’s the plan again:

Ah, wait, not quite! … I have a transformer with dual secondary windings:

Screen Shot 2010 12 12 at 12.36.53

What I did was wire them up in parallel:

Screen Shot 2010 12 12 at 12.37.03

And that’s where I went wrong. Each winding generates an AC voltage. There are two ways to put them in parallel. Connect them right, and you get twice the power – connect them in reverse, and one will generate an AC voltage which is exactly opposite in phase w.r.t. the other winding. The result is not just a short circuit, but two power sources actively counter-acting each other:

Screen Shot 2010 12 12 at 12.42.00

Hence the blown fuses. I did not expect a 300 VA transformer to blow a 5A fuse, which implies its power draw was over 1100 watt – but that’s exactly what happened.

The solution is simple, once you step back and think about it. Instead of connecting the windings in parallel, I need to connect them in series:

Screen Shot 2010 12 12 at 12.37.11

(and the same on the other up-converting transformer too, of course)

Here’s the key: it’s still possible too hook them up the wrong way. But doing so will simply lead to no ouput, i.e. zero volts, instead of the desired double voltage output. But no blown fuse.

Once I made this change (which required a lot of undoing), I found out that the transformer secundaries were indeed wound the other way than their wires had initially led me to believe.

Problem solved!

I now have a working isolation setup which turns a 230.3V input voltage into a 230.9V output voltage under no load. An 80 watt test load worked fine.

P.S. I also gained more respect for AC “power”: such circuit mistakes are a different ball game from fiddling around with an AA Power board and getting all sorts of microcontroller- and sensor hookups messed up!

Easy Electrons – Resistors

In Hardware on Dec 12, 2010 at 00:01

A few days ago, I was completely overwhelmed by the positive response to a couple of posts about electronics principles such as power and circuit diagrams. Since I love to share what I’ve learned (and still learn) about this world full of discoveries, inventions, and creative engineering, I’ve been thinking about how to fold such a topic into this daily weblog.

The result is Easy Electrons – a series which will cover various aspects of electronics from the viewpoint of a technology enthusiast with a non-electronics background.

I’ve got some ideas about the frequency and topics for these posts, but I’m not commiting to a schedule or specific subjects just yet. Let’s see how it goes, and let me know what you think of these posts. Your comments will help guide me.

With that out of the way – let’s have some fun with electronics, eh?

But ya’ can’t run before you walk. This kick-off post has to go into some basic stuff. You may well know all this, but if in doubt, make sure you “get it”. Without these preliminaries, you will not be able to make sense of everything else in the upcoming posts of this series.

Resistance is not futile!

IMO, there is no concept more important in electrical circuits than resistance. One reason is that it’s everywhere, even the thickest copper wire has some resistance, however small. And an insulator, i.e. the stuff that prevents electricity from flowing all over the place, has essentially infinite resistance.

Take a voltage (or, using the water analogy: lift some water up). Once you let it “go”, it’ll want to flow. It does this using the path of least resistance. Thick solid copper pipe: huge current, massive power surge. Very thin wire: tiny current, squeezing its way through and heating up the wire. If the squeeze is strong enough (enough voltage) the wire will heat up to the point where Thomas Alva Edison made an incandescent light!

Voltage wants to flow. And when it does, it creates a current. It flows quickly when the resistance is low, it flows more slowly when the resistance is high, and it fails to flow when the resistance is infinite. That’s also why electricity will always pick a copper wire over plain air.

It’s time to introduce Ohm’s law:

    E = I x R

In words: voltage = current times resistance.

Voltage is described in volts (thanks to Alessandro Volta), current is described in amps (courtesy André-Marie Ampère), and resistance is described in ohm (due to Georg Simon Ohm).

I’ll simplify the world by saying: in simple cicuits with no effects from electric and magnetic fields, Ohm’s law is all you need to know. If you know any two of the quantities, you can calculate the third.

I won’t go into them now, but if you also learn the two Kirchoff’s circuit laws, then you’ll have some incredibly powerful tools to explain what’s going on, even in circuits with dozens of components, connected in all sorts of funky ways.

Physicists and chemists will be used to this, but if you come from the world of software, then note that these laws are really quite amazing: they let you predict what will happen when you hook up a circuit. Laws such as this were not “created” to terrorize kids in school, they are really extremely useful!

Let’s try it:

Screen Shot 2010 12 05 at 15.16.27

What’s the voltage on the right side? (assuming no load current)

I’m going to skip several details, but here’s how I would reason about it:

  • we want to know the voltage over the lower resistor
  • we know its resistance, so if we knew how much current is flowing, we could calculate it
  • the current flows through both resistors
  • the current IN is the same as the current OUT
  • so the same current flows through both resistors
  • we know the voltage over the total
  • if we knew the total resistance, we could derive the current through both
  • once we do, we know the current through the lower resistor
  • and from there, we can calculate the voltage, as requested

Question: what is the resistance of two resistors placed in series, one after the other?

Answer: this is one of those facts you’ll just have to memorize – resistance of R1 and R2 in series = R1 + R2.

  • so we have 9 volts over 3 kilo-ohm, i.e. 3000 ohm
  • the current is 9 / 3000 = 0.003 amps, i.e. 3 milliamps
  • voltage over 1 kΩ is 1000 x 0.003 = 3 volt

So the final answer is 3 volts.

But don’t stop there, please:

  • What if we use a 3V battery? Answer: (3/3000)*1000 = 1V.
  • How about a 12V power supply? Answer: (12/3000)*1000 = 4V.
  • See the pattern?

The two resistors act as a voltage divider. They don’t really “care” about the input voltage, they will simply divide it by 3. Because the ratio of the total to the lower resistance is (2+1)/1 = 3. This is also the reason why I drew that schematic in this particular way: it illustrates the voltage “drop”.

Hold on to that insight. Electric circuits usually have lots of voltage dividers. Whenever I see resistors in series, I try to determine what voltage is placed over them. And sure enough, most of the time, that’s what the resistors are used for. It works for any voltage. It also works for varying voltages: if you have an audio signal in the form a a rapidly varying voltage, then the voltage divider will simply pass the signal through, at a reduced voltage level.

Not every resistor is used as voltage divider. But more often than not, that’s all they do when used in series.

Easy Electrons!

P.S. Would you believe that I found out about this tutorial after writing the above? Heh… synchronicity :)

RF12 acknowledgements

In Software on Dec 11, 2010 at 00:01

The RFM12B wireless module is a transceiver, i.e. able to send and receive packets over wireless. This is an important advantage over simple sensor units which just send out what they measure, and things like RF-controlled power switches which only listen to incoming data but are not able to report their current state.

The only thing is… it’s a bit more work.

This is reflected in how the RF12 library works:

  • simple reception is a matter of regularly polling with rf12_recvDone()
  • simple transmission means you also have to call rf12_canSend() and rf12_sendStart()
  • the above are both essentially uni-directional, so packets can get lost

The second mechanism added to RF12 was a set of “easy transmission” functions, i.e. rf12_easyPoll() and rf12_easySend(). These look similar, but they send out data packets asking for an ACK (acknowledge) packet from the receiver to confirm that the packet was correctly received. If nothing comes in, they will re-send the packet (and repeat a few times, if needed). This mechanism greatly improves the chance of a message arriving properly at the destination. Losing an occasional packet is one thing, losing all retries is a lot less likely!

Note that packets can be damaged or get lost at any time. It may well be that the original packet arrived just fine, but the ACK got lost instead. The sender will resend, and then (probably) get the ACK which stops this retry cycle.

So with the easy transmission functions, note that very occasionally a packet might be received twice. If it is crucial to weed these out, you can include a counter in your data packets to help detect and ignore duplicates.

With RF12demo as receiver, ACK handling is automatic. It knows when the originating node wants to get an ACK, and will send it out as soon as possible. This is reported in the output as the text “-> ack”.

The code for this in RF12demo is horrendous:

Screen Shot 2010 12 10 at 18.27.08

This is silly, and overkill for simple cases. So let’s improve on it.

I’ve added two utility definitions to the RF12.h header, which can simplify the above code to:

Screen Shot 2010 12 10 at 19.58.02

That’s better, eh?

The rest is just there to deal with a special configuration setting in RF12demo.

So if all you want is to add logic in your own sketch to send back an empty ACK packet when requested, the above can be simplified even further to:

Screen Shot 2010 12 10 at 19.59.09

For completeness, here’s a complete processing loop for a receiving sketch which supports nodes using the easy transmission mechanism:

Screen Shot 2010 12 10 at 19.59.45

You have to send out the ACK after processing the packet, because the rf12_sendStart() call will re-use the same packet buffer and overwrite the incoming packet.

Also, RF12_WANTS_ACK and RF12_ACK_REPLY are defined as macros which access the global rf12_hdr variable, as set by rf12_recvDone(). IOW, the convenience comes for free, but it does depend on some fixed assumptions. I can’t think of a situation where this would lead to problems, given that RF12-based sketches are probably all structured in the same way, and that globals are part of the RF12 driver.

For another example, see the blink_recv.pde sketch, which has also been simplified with these two macros.

RCD finally in

In Hardware on Dec 10, 2010 at 00:01

Remember the weblog post about mains voltage and my plan to work on some circuits involving high voltage?

Well, with fear and trepidation I can announce that the missing link has finally arrived:

Dsc 2397

That’s an “Aardlekschakelaar” in Dutch, i.e. a Residual-current device.

People are probably either very thankful or very afraid of this thing, judging by the number of acronyms under which it is known: RCD, RCCD, RCCB, GFCI, GFI, or ALCI – take your pick!

An RCD continuously compares the current in with the current out, and breaks the circuit once the difference exceeds a certain threshold. I decided to get the most sensitive one I could find, which trips at 10 mA. I’m terrified of electric shock – especially the non-lethal kind… (no idea about the other variant, and I intend to keep it that way).

Ok, so it took over a month from ordering the RCD to getting it delivered – from a mail-order company here in the Netherlands, go figure. I’ll build the RCD into my super-duper isolation jig as soon as I find some time. I sure don’t want to fiddle with 230V while distracted or in a hurry.

Speaking of which…

There are a large number of people waiting for orders from the JeeLabs shop right now, for which I offer my sincere apologies. The reason is not really lack of time (well, maybe a little…), but the fact that stocks have run out on several items. I’ve got just about everything that’s missing on order right now, but in some cases my hands are tied because things don’t always arrive as quickly as promised or expected.

I’ve been refraining from sending out partial shipments, because it doesn’t really make much sense most of the time (sending out a JeeNode without the matching JeeLink, for example), and because it adds substantially to my overhead. Which is of course my own concern, but it also raises the chance of mistakes, something which I really want to avoid.

Not everything is in yet, but I hope to have just about all shipments ready by this weekend. Please get in touch if you’d rather have a partial shipment sent out soon, rather than waiting until next week. There will be no extra charges for such split shipments.

Crazy times around here. And the long-overdue server migration isn’t making it any easier!

P.S. Don’t get me wrong. I’m still working on quite a bit of fun stuff on the side, so let me finish this slightly panicky post with a little smiley anyway :)

New server

In News on Dec 9, 2010 at 00:01

JeeLabs is leaving the dark ages behind… into the light!

Yesterday, the fiber-optic cable was finally delivered. It’s that long box in the middle with the wiggly split:

Dsc 2391

Roll-out by Glashart, modem installed bij NKM, support bij Lijbrandt. It took three months between bringing that orange fiber-optic cable into the house to getting hooked up to internet with it!

This is offered as a Triple play service, of which I’ll only be using the internet connection and a telephone line (yeah, voice-over-wire still exists!).

The internet connection is not too shabby – here’s the “low-end” version I ended up with:

Screen Shot 2010 12 07 at 10.59.21

To be honest, I couldn’t care less about the download speed. Been happy ever since ADSL passed the 4 Mbit/sec mark (the rest is marketing, same as the CPU GHz “game”, and the top speed of a car, if you ask me).

The key reason to do this was to increase the upload bandwidth, which was 1 Mbit/sec – until now.

So finally I can announce the new web server for the JeeLabs Café:

Say hello to… jeelabs.net

Screen Shot 2010 12 08 at 16.03.12

I’ve been maintaining the docs in both places for a couple of months now. But as of today, cafe.jeelabs.net will be deprecated. I’ll gradually adjust all the bits there to redirect to the new server. The old URLs will continue to work for at least another 6 months, but no guarantees after that.

So what’s the deal with the new Café site, eh?

Well, it’s powered by Redmine and has a lot more features than the old site, which is just some static pages:

  • A wiki – with all the info from the old site, organized in a similar way, but now more people can join and participate. There’s already a nice section of contributed pages – see the interesting projects page. The wiki supports Markdown format, and attachments (which can be used as inline images).

  • An issue tracker, to better keep track of bugs, feature requests, and source code changes.

  • A forums section, which may replace the current Talk forums. I haven’t decided, the feature set is quite different. Main issue holding me back for now, is the lack of a simple spam filtering mechanism.

  • A respository browser for all the source code maintained at JeeLabs. This is a very nice and powerful interface to subversion, with full access to change logs, older versions, and source code differences. This replaces the code.jeelabs.org hack I had set up a while back.

Redmine has a number of other features which I haven’t enabled at this point. One of the things to note, is that it manages several different projects, including some private ones which aren’t even listed until you log in with the proper access rights.

Speaking of logins: all the info in the Café is public and browsable by anyone visitng the site. To submit bug reports or feature requests, however, you will need to register and log in. The process is simple an automated, with a quick check via email. To contribute on the wiki, I need to raise your access level to “Editor” – this is not automatic (to avoid spamming), so please contact me if you would like to add your own pages to the wiki or help maintain and extend pages already on there.

The main page of the new Café is at http://jeelabs.net/projects/cafe/wiki and here’s what it looks like:

Screen Shot 2010 12 08 at 17.34.20

There’s a separate Hardware sub-project in the Café with all the “official” documentation about hardware from JeeLabs. This is where you will find descriptions, detailed specs, connection diagrams, schematics, CAD files, and pointers to relevant posts on this daily weblog. An example:

Screen Shot 2010 12 08 at 16.29.51

Ok, enough screen shots. Back to work!

Binary packet decoding – part 2

In AVR, Software on Dec 8, 2010 at 00:01

Yesterday’s post showed how to get a 2-byte integer back out of a packet when reported as separate bytes:

Unfortunately, all is not well yet. Without going into details, the above may fail on 32-bit and 64-bit machines when sending a negative value such as -12345. And it’s not so convenient with other types of data. For example, here’s how you would have to reconstruct a 4-byte long containing 123456789, reported as 4 bytes:

Screen Shot 2010 12 07 at 09.56.08

And what about floating point values and C structs? The trouble with these, is that the receiving party doing the conversion needs to know exactly what the internal byte representation of the ATmega is.

Here is an even more complex example, as used in the roomNode.pde sketch:

Screen Shot 2010 12 07 at 08.44.28

This combines different measurement values into a 4-byte C struct using bit fields. Note how the “temp” value crosses two bytes, but only uses specific bits in them.

Fortunately, there is a fairly simple way to deal with all this. The trick is to decode the values back into meaningful values by the receiving ATmega instead of an attached PC. When doing so, we can re-use the same definition of the information. By using the same hardware and the same C/C++ compiler on both sides, i.e. the Arduino IDE, all internal byte representation details can be left to the compiler.

Let’s start with this 2-byte example again:

I’m going to rewrite it slightly, as:

Screen Shot 2010 12 07 at 08.57.23

No big deal. This sends out exactly the same packet. But now, we can rewrite the receiving sketch as follows:

Screen Shot 2010 12 07 at 09.00.14

The effect will be to send the following line to the serial / USB connection:

    MEAS 12345

The magic incantation is this line:

Screen Shot 2010 12 07 at 09.01.45

It uses a C typecast to force the interpretation of the bytes in the receive buffer into the “Payload” type. Which happens be the same as the one used by the sending node.

The benefit of doing it this way, is that the same approach can be used to transfer any type of data as a packet. Here is an example how a Room Node code sends out a 4-byte struct with various measurement results:

Screen Shot 2010 12 07 at 09.07.07

And here’s how the receiving node can convert the bytes in the packet back to the proper values:

Screen Shot 2010 12 07 at 09.10.55

The output will look like:

    ROOM 123 1 78 -15 0

Nice and tidy. Exactly the values we were after!

It looks like a lot of work, but it’s all very straightforward to implement. Most importantly, the correspondence between what happens in the sender and the receiver should now be obvious. It would be trivial to include more data. Or to change some field into a long or a float, or to use more or fewer bits for any of the bit fields. Note also that we don’t even need to know how large the packet is that gets sent, nor what all the individual bytes contain. Whatever the sender does to map values into a packet, will be reversed by the receiver.

This works, as long as the two struct definitions match. One way to make sure they match, is to place the payload definition in a separate header file, say “payload.h” and then include that file in both sketches using this line:

Screen Shot 2010 12 07 at 09.16.47

The price to pay for this flexibility and “representation independence”, is that you have to write your own receiving sketch. The generic RF12demo sketch cannot be used as is, since it does not have knowledge of the packet structures used by the sending nodes.

This can become a problem if different nodes use different packets sizes and structures. One way to simplify this, is to place all nodes using the same packet layout into a single net group, and then have one receiver per net group, each implemented in the way described above. Another option is to have a single receiver which knows about the different types of packets, and which switches into the proper decoding mode depending on who sent the packet.

Enough for now. Hopefully this will help you implement your own custom WSN to match exactly what you need.

Update – Silly mistake: the “rf12_sendData()” call doesn’t exist – it should be “rf12_sendStart()”.

Binary packet decoding

In AVR, Software on Dec 7, 2010 at 00:01

The RF12 library used with the RFM12B wireless radio on JeeNodes is based on the principle of sending individual “packets” of data. I’ve described the reasons for this design choice in a number of posts.

Let me summarize what’s going on with wireless:

  • RFM12B-based nodes can send binary packets of 0..66 bytes
  • these packets can contain any type of data you want
  • a checksum detects transmission errors to let you ignore bad packets
  • dealing with packet loss requires an ACK + re-transmission mechanism

Packets have the nice property that they either arrive intact as a whole or not at all. You won’t get garbled or inter-mixed packets when multiple nodes happen to send at (nearly) the same time. Compare this to some other solutions where all the characters sent end up in one big “soup” if the sending happens (nearly) simultaneously.

But first: what’s a packet?

Well, loosely speaking, you could say that a packet is like one line of text. In fact, that’s exactly what you end up with when using the RF12demo sketch as central receiver: a line of text on the serial/USB connection for each received packet. Packets with valid checksums will be shown as lines starting with “OK”, e.g.:

    OK 3 128 192 1 0
    OK 23 79 103 190 0
    OK 3 129 192 1 0
    OK 2 25 99 200 0
    OK 3 130 192 1 0
    OK 24 2 121 163 0
    OK 5 86 97 201 0
    OK 3 131 192 1 0

Let’s examine how that corresponds with the actual data sent by the node.

  • All the numbers are byte values, shown as numbers in the range 0..255.
  • The first byte is a header byte, which usually includes the node ID of the sender, plus some extra info such as whether the sender expects an ACK back.
  • The remaining data bytes are an exact copy of what was sent.

There appears to be some confusion about how to deal with the binary data in such packets, so let me go into it all in a bit more detail.

Let’s start with a simple example – sending one byte:

Screen Shot 2010 12 06 at 22.32.26

I’m leaving out tons of details, such as calling rf12_recvDone() and rf12_canSend() at the appropriate moments. This code is simply broadcasting one value as a packet for anyone who cares to listen (on the same frequency band and net group). Let’s also assume this sender’s node ID is 1.

Here’s how RF12demo reports reception of this packet:

    OK 1 123

Trivial, right? Now let’s extend this a bit:

Screen Shot 2010 12 06 at 22.38.13

Two things changed:

  • we’re now sending a larger int, i.e. a 2-byte value
  • instead of passing length 2, the compiler calculates it for us with the C “sizeof” keyword

Now, the incoming packet will be reported as:

    OK 1 57 48

No “1”, “2”, “3”, “4”, or “5” in sight! What happened?

Welcome to the world of multi-byte values, as computers deal with them:

  • a C “int” requires 2 bytes to represent
  • bytes can only contain values 0..255
  • 12345 will be “encoded” in two bytes as “12345 divided by 256” and “12345 modulo 256”
  • 12345 / 256 is 48 – this is the “upper” value (the top 8 bits)
  • 12345 % 256 is 57 – this is the “lower” value (the low 8 bits)
  • an ATmega stores values in little-endian format, i.e. lowest-range bytes come first
  • hence, as bytes, the int “12345” is represent as first 57 and then 48
  • and sure enough, that’s exactly what we got back from RF12demo

Yeah, ok, but why should we care about such details?

Indeed, on normal PC’s (desktop and mobile) we rarely need to. We just think in terms of our numbering system and let the computer do the conversions to and from text for us. That’s exactly what “Serial.print(12345)” does under the hood, even on an Arduino or a JeeNode. Keep in mind that “12345” is also a specific representation of the abstract quantity it stands for (and “0x3039” would be another one).

So we could have converted the number 12345 to the string “12345”, placed it into a packet as 5 bytes, and then we’d have gotten this message:

    OK 1 31 32 33 34 35

Hm. Still not quite what we were looking for. Because now we’re dealing with ASCII text, which itself is also an encoding!

But we could build a modified version of RF12demo which converts that ASCII-encoded result back to something like this:

    OKSTR 1 12345

There are however a few reasons why this is not necessarily a good idea:

  • sending would take 5 bytes instead of 2
  • string manipulation uses more RAM, which is scarce on an ATmega
  • lots of such little inefficiencies will add up, once more data is involved

There is an enormous gap in performance and availability of resources between a modern CPU (even on the simplest mobile phones) and this 8-bit few-bucks-chip we call an “ATmega”. Mega, hah!

But you probably didn’t really want to hear any of this. You just want your data back, right?

One way to accomplish this, is to keep RF12demo just as it is, and perform the proper transformation on the receiving PC. Given variables “a” = 57, and “b” = 48, you can get the int value back with this calculation:

Screen Shot 2010 12 06 at 23.11.04

Sure enough, 57 + 48 * 256 is… 12345 – hurray!

It’s obviously not hard to implement such a transformation in PHP, Python, C#, Delphi, VBasic, Java, Tcl… whatever your language of choice is.

But there’s more to it, alas (hints: negative values, floating point, structs, bitfields).

Stay tuned… more options to deal with these representation details tomorrow!

Update – Silly mistake: the “rf12_sendData()” call doesn’t exist – it should be “rf12_sendStart()”.

No more diode!

In Hardware on Dec 6, 2010 at 00:01

The JeeNode v5 introduced a change, which I now regret – due to the amount of confusion it has generated, and the limited utility: an extra protection diode in the PWR line on the FTDI connector (and only there!).

Here’s the PCB layout, as seen in EAGLE:

Screen Shot 2010 12 05 at 17.44.49

The diode is marked “D1”, with a solder bridge on the back side of the board (red lines are on top, blue lines on the bottom, and plated-through holes are in green).

Here’s a close-up:

Dsc 2074

What it does, is block the power when it’s connected the wrong way around. But that only protects the FTDI connector, which is actually quite well protected agains reversal already (if you flip the connector, GND will go to the reset cap, which blocks all DC current anyway).

The drawback of this design is that it lowers the voltage by about 0.7V, so instead of 5V, you get about 4.3V on the remaining PWR pins, such as on all the port headers.

Worse still, is that it causes the JeeNode to stop working from a 3.3V power source, such as the AA Power Board, because it will drop the voltage to about 2.5V – which is too low to run at 16 MHz!

I did design a workaround into the JeeNode v5: there’s a solder jumper on the other side of the board, to bypass that diode. Where “bypass” means: short out the diode, as if it wasn’t part of the circuit in the first place.

The irony is that I’ve been closing this solder jumper on every new JeeNode I’ve built so far.

Add to that the fact that the holes for that diode are almost too small to push the thick diode wires through, and it becomes clear that this new “feature” causes more problems than it solves.

Starting now, once the stock of kits is exhausted, new kits will be shipped WITHOUT the diode!

You will now have to always add a drop of solder to close the jumper on the back:

Screen Shot 2010 12 05 at 18.04.03

If you don’t, there will no power connection from the FTDI header to the JeeNode.

It’s an important change, but it removes the nasty suprise that sometimes things work and sometimes they don’t!

Oh, and if you’re into this tradition – I hope you had a nice Sinterklaas!

Electric circuits

In Hardware on Dec 5, 2010 at 00:01

At the risk of prolonging this “electronics course” and boring everyone after the past two installments about power and switching regulators, here are some thoughts about electronic circuits.

I find the hydraulic analogy very useful, as long as you don’t push it too far. There is a (thick) book called Practical Electronics for Inventors by Paul Scherz (2007) which manages to construct analogies for just about all types of electronic components. It’s a stretch, but it does help understand things.

Here’s an example I found on the web:

Transistor

It’s quite easy to see how a small current can control a larger one. It also falls short, because “current” is really “pressure” in this case. My suggestion would be: do look at those analogies if you want to quickly build a mental model of how a specific component works, but keep the limitations of such analogies in mind.

The neat thing about electricity, is that you can completely understand a circuit by just applying a bit of logic. By which I mean: reason how it probably / sort-of works. And predict some of its behavior. It really pays to invest a bit in understanding electronics circuits.

There is a whole world to discover when you get into this. There are lots of conventions to figure out, but the neat thing is that these conventions are pretty much standardized by now. Electric circuits have been around for a couple of centuries, even if some of the newer components are only decades old.

Here’s part of the Infrared Plug, as a circuit diagram:

Screen Shot 2010 12 04 at 23.47.50

Even without knowing all the conventions, you’re probably able to guess many of the components. Connectors (PORT1, SV1), resistors (R1, R2, R3, R4), capacitors (C1, C2), a transistor (Q1), two LEDs (LED1, LED2), and a box marked “LM555D” which is an integrated circuit for building timers and oscillators.

How it works would be a bit of a long story for this post, but let’s make a guess:

  • C1 is charged up because it’s connected between + (VCC) and - (GND)
  • there are two resistors (R1 and R2) which limit the current flowing into it
  • the charge on C1 is measured through pin 6 of the chip (THR, i.e. threshold)
  • pin 7 (DIS, i.e. discharge) is actually an output, which can be either open or low

What the LM555D does (consider it magic for now), is watch the voltage level on THR. When it is low, DIS is not connected. The capacitor will charge up, until THR reaches a certain voltage.

At that point, the chip (through magic), decides to pull DIS low, i.e. put it at almost 0 volts, i.e. ground level.

While DIS is low, something completely different happens: with pin 6 being at a fairly high voltage, and DIS low, capacitor C1 will start to discharge, with current flowing into R1 in the opposite direction.

At some point, the THR voltage will be very low again, at which point the chip (magically) decides that it’s time to disconnect DIS. Then the cycle repeats: C1 will start to charge up through R1 and R2, etc… ad infinitum.

These 4 components are the heart of what is called an astable multivibrator.

We haven’t even looked at the rest of the circuit yet. I’ll leave it at that for now, just mentioning that the transistor is there to drive a strong current through the LEDs in a rapid ON/OFF pattern.

The components are dimensioned in such a way that this circuit oscillates at… 38 KHz. Which “happens” to be what most remotes send out as well.

There is a lot more to say about electric circuits, of course. I just wanted to point out that there is a huge amount of information you can glean from such “schematics” of various circuit diagrams.

Since everything made at Jee Labs is open source, you can dive into all of this. Look for the PDF’s linked on the various hardware pages if you’re interested.

It’s fun. It’s enormously informative. And unlike my use of the term “magic” there is really nothing special going on at all. It’s only magic until you dive in. If you have questions about how JeeNode pins are hooked up, for example: check out the manual (PDF). It’s all in there!

Update – for entertaining introductions of the main electrical components, there are a couple of short videos by Collin Cunningham on the Gizmodo website.

What is “power” – part 2

In Musings on Dec 4, 2010 at 00:01

To continue yesterday’s post, let’s go into that last puzzle:

Why does the 1x AA Power Board run out of juice 3 times as fast as a 3x AA battery pack?

The superficial answer would be: it’s one battery instead of three, so obviously it’ll last 1/3rd as long.

But that’s not quite the whole story…

The AA Power Board contains a switching regulator called a boost converter. Switching regulators are a lot more efficient than ordinary “linear” voltage regulators. They play games with energy conversion into electrical and magnetic fields. And by doing so, they mess with the rule that current is always the same everywhere.

But let me first explain what a linear regulator does:

Screen Shot 2010 12 02 at 22.12.51

Don’t laugh – that’s the essence of a linear voltage regulator: a variable resistor!

Well, it’s far more complex than that in reality. But the machinery inside a linear voltage regulator is all about wasting energy. The goal is to waste just the right amount to get the desired 3.3V on the output pin, regardless of changes in input voltage and current draw. Functionally, all the regulator does is continuously adjust its internal resistance to get the right output.

If you think about it, there’s in fact little else you can do with resistors. They exist to drop voltage, and by doing so, they generate heat, even if the amount is minimal and usually irrelevant.

The other type of regulator is the switching regulator. Huge topic, way beyond the scope of this post (and way over my head, in fact). I’m bringing it up because the AA Power Board uses a switching regulator to “boost” the voltage from say 1.5V to 3.3V.

So how does one boost voltage?

The hydraulic analogy would be to pump water from one level to a higher level using only water power (height and flow). There’s an ingenious pump called a hydraulic ram which can do that. The one I’ve seen in action works by letting water flow and then quickly interrupting that flow. All of a sudden, the water has nowhere to go and pressure builds up. All you need is an outlet pointing up, and the water will go there as only option.

The flow will quickly stop, so the trick is to repeat this cycle, and then – in a pulsating fashion – you actually can get water to climb up. Voilá, a higher voltage!

That’s also how the AA Power Board works. It contains an efficient switch, which pulses the current flow, and (in most cases) an inductor which transforms current changes into a magnetic field, and vice versa. The inductive “kick” is what makes it possible to play games with current vs. voltage without turning it all into heat.

But you don’t get anything for free. Apart from circuit losses, you lose the conversion factor w.r.t. power – drawing 10 mA @ 3.3V will require 30 mA @ 1.1V – with circuit losses increasing that slightly further. You can’t ever get more watts out of this than you put in!

So, roughly speaking, to get 3.3V from a 1.2V AA NiMH battery, you need to draw about 3 times as much current from the battery as what will go into the target circuit.

Which is why a 2000 mA single AA battery behaves roughly like a 650 mAh battery delivering 3.3V via the boost converter. With our circuit drawing 10 mA, that will last 650 mAh / 10 mA = 65 hours.

That’s roughly a third as long as the 3x AA battery pack. QED.

There are some losses and inefficiences. Even with a switching regulator, you should expect no more than 90..95% efficiency under good conditions. But this is nowhere near the inefficiency of a linear regulator with a high input voltage. On a 9V battery, the on-board regulator of a JeeNode will be less than 40% efficient.

Note that there are also down-converting switching regulators (called buck converters), and these do have much higher efficency levels. Even the AA Power Board is able to handle over 5V on its input, and still deliver a 3.3V output, by going into a buck conversion mode. In which case the input current will be less than 10 mA to deliver 10 mA @ 3.3V on its output – something a linear regulator simply cannot do.

Conclusion: if you want very power-efficient solutions, look carefully at what voltages to use for supplying your circuits, and use switching regulators when the voltage differential is substantial. Linear regulators can only drop voltage, and can only do so by wasting energy.

There is another benefit to using a boost converter: it lets you suck the last breath out of batteries. The AA Power Board can be used with batteries with only 0.85V or so left in them, and if kept connected and running, it’ll work all the way down to 0.6V or so. You can be assured that by the time an AA Power Board gives up, its battery will have been completely drained!

One last note about the AA Power Board: maximum efficiency is achieved with an input voltage between 2.4V and 3.0V, so if you want to optimize, consider using either 2 AA (or AAA) cells, or a 3V battery such as the CR123A, which is half the size of an AA and a great source of energy with about 900 mAh of oomph…

But just to put all this into perspective: if all you want is a good solid source of power for a JeeNode and everything attached to it, use a 3x (or 4x if you have to) AA battery pack. Or use power from USB.

Me, I’ll stick to single rebranded Eneloops @ 1.2 .. 1.3V.

What is “power”?

In Musings on Dec 3, 2010 at 00:01

Here’s something which may be totally obvious to some, yet clear as a mud to others…

Voltage, current, power – what are they? Here are some puzzles I’ll go into:

  • Why does a 4x AA battery pack run out almost as fast as a 3x AA battery pack?
  • Why does a 9V battery last about 1/4th as long as a 3x AA pack?
  • Why does the 1x AA Power Board run out of juice 3 times as fast as a 3x AA battery pack?

Let’s take it one step at a time. An often-used analogy for electricity is water (see hydraulic analogy). To simplify, let’s say that electricity flows from a high voltage to a low voltage, such as ground. Likewise, water flows from a high location to a lower location. So let’s make the analogy that high voltage equals water high above the ground.

This is what happens in a circuit where a 3.6V battery powers a JeeNode:

Screen Shot 2010 12 02 at 19.56.58

While in the battery, the voltage is “at” 3.6V. When it goes through the on-board voltage regulator, it is made to drop to 3.3V, and then that electricity flows through the ATmega, RFM12B, etc, to ground.

Let’s assume the circuit draws 10 mA. The thing about current is that it’s doesn’t change across a circuit, like voltage does. Using the water analogy: current is the amount of water flowing. And no matter where it flows, the amount at the top is the same as the amount lower down. It might trickle down in different ways, but the amount into the whole circuit is the same as the amount coming out:

Screen Shot 2010 12 02 at 20.13.33

So what we have is a battery, where the electricty “starts out”, and then it traverses first the voltage regulator, then the ATmega, etc, and then it flow back into the battery at 0V, which in effect “pumps” it back up to 3.6V. And the the cycle repeats.

I’m taking many liberties here. Electricity doesn’t really flow from + to -, and there’s no pumping involved either. But as a mental model, this actually works pretty well.

So what’s “power” then, eh?

Well, power is defined as “voltage times current”. I’ve added the calculations in that second diagram. As you can see, with a 10 mA current consumption, the battery generates 36 mW, of which the voltage regulator consumes (i.e. wastes) 3 mW, and the ATmega, etc, get the remaining 33 mW.

What you may not realize, is that “consuming power” is basically equivalent to “turning electricity into heat” – because that’s what happens, essentially. Think about it: the JeeNode is really just a mini electric heating. It isn’t very much heat, and it happens over a long stretch of time. But in the end, when the battery is dead, you’ve done nothing but heat up the surroundings a teeny bit…

Well, almost: a small amount will have been emitted as radio energy when the RFM12B is transmitting.

Ok, so now let’s try to answer the above three questions.

Why does a 4x AA battery pack run out almost as fast as a 3x AA battery pack?

This is due to the voltage regulator. If you feed it say 4.8V, instead of 3.6V, it will simply waste that extra energy: the voltage drop over the regulator will be 1.5V instead of 0.3V, so that the output of he regulator stays at 3.3V. That’s the whole purpose of the regulator after all: to deliver a constant voltage, regardless of the voltage placed on its input pin.

Here’s what would happen if you put 9V on the voltage regulator:

Screen Shot 2010 12 02 at 20.32.10

And here’s how that works out in terms of power consumption:

Screen Shot 2010 12 02 at 20.33.05

(correction: the 5.3V – bottom middle – should have been 5.7V)

In other words: you can raise the voltage all you like, it won’t have any effect on the amount of power needed or used by the ATmega, etc. They will always get 3.3V, and will continue to draw 10 mA as before.

The only thing that happens, is that the voltage regulator works a little harder, and wastes a bit more power by turning it into more heat!

Conclusion: if your circuit doesn’t need the higher voltage to work properly, power it at the lowest practical voltage. Keep in mind that the “low-drop” voltage regulator on the JeeNode likes to have at least 0.1..0.2V to do its job properly. Both 3x AA packs and LiPo batteries are just about perfect for JeeNodes.

Another very important lesson from this is that if you’re trying out stuff, and you notice that the voltage regulator is getting very hot because some part of your circuit draws a lot of current, then you should try to reduce (!) the voltage you’re feeding into it: you’ll help the regulator, by giving it less power to eat up and waste.

Why does a 9V battery last about 1/4th as long as a 3x AA pack?

Now with the above explanation, it should be clear that the 9 volts won’t give you a longer-running JeeNode. But why is it so much shorter?

The reason is that not all batteries contain the same amount of energy. The capacity of a battery is specified in terms of milli-Ampere-Hour: an AA battery often has over 2000 mAh. This means it can supply 2000 mA for one hour. Or 1000 mA for 2 hours, 500 mA for 4, etc. And then it’s empty.

Energy is defined as Voltage x Current x Time (or equivalently: Power x Time). The unit is watt hour.

So the amount of power you get when draining an AA battery in one hour (voltage x current) is: 1.5V x 2000mA = 3.0 watt. Consquently, the amount of energy in a a 3x AA pack is 9.0 watt hour.

For a standard 9V battery, the figure is around 500 mAh. This is 9V x 500 mAh = 4.5 watt hour of energy.

Great, so a 9V battery has half as much energy as a 3x AA battery pack, and should last about half as long, right?

Wrong! – go back to that first discussion about feeding the voltage regulator with 9V instead of 3.6V: it just turns that extra voltage into heat.

The way to estimate lifetimes, is to use the current draw as starting point. We assumed in all these examples that the circuit is drawing a constant 10 mA.

On a 3x AA pack (or 4x AA, for that matter), this means we get 2000 mAh / 10 mA = 200 hours of run time.

But on a 9V battery, we’ll only get 500 mAh / 10 mA = 50 hours of run time!

Conclusion: don’t use 9V battery packs for JeeNode projects. They are an expensive way to waste energy, and you’ll keep running to the shop to get new ones.

Why does the 1x AA Power Board run out of juice 3 times as fast as a 3x AA battery pack?

Before even going into that, the first puzzling fact about running a JeeNode off a single AA is really: how can a 3.3V circuit run off a 1.5V power source in the first place? Think about it. As you know, most electrical circuits don’t work at all when the supply voltage is too low.

It’s equivalent to asking: how can you get water which flows at a certain level to lift itself to a higher level?

Hint: there exists an ingenious type of water pump which can do this!

To be continued in tomorrow’s post…

Bridge Board – caveats

In Hardware on Dec 2, 2010 at 00:01

There is some complexity lurking in the design of the Bridge Board, which in turn may lead to some head scratching, I’m afraid…

That complexity comes from the fact that not all I/O pins are always available.

Let’s start with an overview of the different pin groups:

Annotated bb

The basic idea is that when you connect all four port headers, then you’ll get access on the breadboard to all the pins marked above in RED. This is the most common usage, and main intended use of the Bridge Board. Note that DIO2, DIO3, AIO2, and AIO3 are available on multiple pins.

So if you follow yesterday’s post, you can use all the pins shown in red as is. The main benefit being that you can easily access the main 8 I/O pins, and that port 2 is in fact replicated in the same layout on the breadboard if you want to hook it up to JeePlugs.

If all you need are the leftmost 16 pins – you can skip the rest of this post.

The remaining pins takes a bit more explanation and preparation, and requires adding some more header on the Bridge Board as well as on the JeeNode! – here’s the summary:

  • to use the 6 SPI/ISP pins marked in BLUE, add the 2×4 pin header on the right
  • to use 4 more I/O pins marked in GREEN, add a 8-pin header on the left (the middle 6 are actually enough)
  • to use FTDI, add the 8-pin header on the left (only JeeNode v4: also the 2×4-pins on the right)

That last option also requires soldering in a 0.1µF capacitor if you want to include the reset-on-open capability for easy uploading. It’s mostly intended for use with a JeeSMD, which does not have an upload capability of its own.

There is a reasoning behind all this madness:

  • The leftmost 16 pins on the breadboard were the main design goal for this board.
  • The middle 13 pins (IRQ to B0) match the layout need for the Ether Card.
  • The rightmost 20 pins are compatible with both Ether Card and Carrier Board.
  • The Bridge Board is compatible with JeeNode v5 and v4, JeeNode USB, and JeeSMD.

The two LEDs are brought out on separate pins and always available – on the LED1 and LED2 pins, respectively. They are very efficient and require only a few mA to shine brightly. You can hook them up to any I/O pin or other 3.3/5V signal on your breadboard. They make a great debugging tool when the going gets tough.

The push-button at the top of the board is also always available on the BTN pin. It is connected to ground, so pressing the button shorts the BTN pin to ground – you can use the internal ATmega pull-up and some software debouncing to read out this button.

The button can be used as reset button if you have the RST pin, which is right next to it, hooked up to the JeeNode. This requires either the 8-pin PSIX header or the 2×4-pin SPI/ISP header to be hooked up, as described earlier.

Assembling the Bridge Board

In Hardware on Dec 1, 2010 at 00:01

This is going to be one of those long posts again, with lots of pictures…

I’ve switched to a new Bridge Board v2 revision, which differs only in some minor ways from the BB v1, so this also applies to that board. The changes are:

  • the FTDI connector orientation has changed to match the underlying JeeNode
  • one extra breadboard pin on the right, to better match the large breadboard
  • minor tweaks to layout and labeling

Since this is an assembly guide, let’s start with the parts included in the kit:

Dsc 2368

And here’s what we want to end up with – a module which plugs into a breadboard:

Dsc 2381

Ok, let’s get started… there are two current limiting resistors for the on-board LEDs. I prefer to mount them on the bottom of the board, because that leaves the “1” and “2” labels clearly visible on top:

Dsc 2369

Everything else is soldered on the top side of the board. Let’s start with the LEDs. These are polarized, so make sure to insert them properly:

Dsc 2370

The only other component left is the push-button:

Dsc 2371

Congratulations! All that remains is to solder on the various pin headers.

More…

Read the rest of this entry »

Meet the DC Motor Plug

In Hardware on Nov 30, 2010 at 00:01

Here’s a new I2C plug to drive two small DC motors. The DC Motor Plug has 2 H-bridges on board, which can drive each motor in forward or reverse. An additional 4 I/O pins are available, for limit switches, quadrature encoders, whatever:

Dsc 2310

Here is a test setup with a couple of (different) geared motors, driven from a 4x AA battery pack, plus the usual AA Power Board for the JeeNode itself (these could also have been combined):

Dsc 2309

All I/O is done via I2C, using the MCP23008 expander chip (same as used on the EP, LP, and OP plugs).

Here is a sample sketch called dcmotor_demo.pde which briefly drives each of the motors in both directions:

Screen Shot 2010 11 29 at 13.02.38

One notable detail about this plug is that it uses TC4424 chips which are in fact not DC motor drivers at all but MOSFET drivers… it turns out that these are also well suited for small DC motors, and should be able to handle up to 1.5A @ 4.5..18V.

A small bipolar stepper will probably also work, but I haven’t tried that yet. This board has a jumper to select between I2C addresses 0x26 and 0x27, so two of these can be daisy-chained on a single port.

Speed control should be possible using software PWM, but not at very high rates, since the I2C bus will be the limiting factor.

One use for this in the context of home automation would be to drive small highly-geared 12V motors to adjust the position and raising/lowering blinds.

Action!

Docs added to the café and kit in the shop, as usual.

Ethernet web client

In Hardware, Software on Nov 29, 2010 at 00:01

The Ether Card and the associated EtherCard library offer an easy way to connect a JeeNode to a LAN and internet. I consider this option useful enough to even want it within reach on a breadboard, so I designed the Bridge Board to support it as well. Here’s the setup, based on a JeeNode Experimenter’s Pack:

Dsc 2365

This is all it takes for an Ethernet-connected setup, and all JeeNode ports are still freely available for project use.

However, the EtherCard library only includes some examples for the web server approach, such as the EtherNode. What about using this setup to send requests out, and POSTing results to a remote web server?

Well, encouraged by a few great DNS-related patches to the code by Gérard Chevalier, who was also so kind to show me how he does DNS lookups and web requests, I’ve come up with two new example sketches:

  • The getStaticIP.pde sketch does just a HTTP get to a fixed IP address.
  • The getViaDNS.pde sketch looks up my server’s IP address by name, via a DNS lookup on startup.

Here is the code of getViaDNS:

Screen Shot 2010 11 27 at 15.38.35

Note that to make any kind of outgoing request outside your LAN, the IP address of the local LAN gateway has to be specified at setup time.

The dependency on the Ports library is due to the use of the MilliTimer class in this code. And because of that, the RF12 library also needs to be mentioned (it won’t increase the code size). Welcome to dependency hell…

Here is some sample output:

Screen Shot 2010 11 27 at 15.29.28

Even though this example is relatively short, I still find it quite awkward. The EtherCard library code really needs a major overhaul – far too much of the underlying mess is still being exposed for no good reason, IMO.

Furthermore, a massive code cleanup will be needed to overcome the current limitations of the EtherCard library: the need for a large RAM buffer, and the limitation that TCP requests and replies may only use a single ethernet frame (approx 1500 bytes).

But getting it working first was more important, and with these new examples you can now see how to implement outgoing TCP/IP requests (not just web/http, btw). Pachube, anyone?

Meet the new Room Board v2

In Hardware on Nov 28, 2010 at 00:01

For some time now, the Room Board kit has been outfitted with a new PIR sensor:

It’s nicely low-power, but unfortunately it has a pin-out which differs from the ELV model, even with 3 pins!

So I’ve decided to make a new Room Board v2, which drops support for the 8-pin ePir to allow the new PIR sensor to be mounted in two different ways.

Here’s the board, with a solder drop already applied for the SHT11 (much easier to solder it in that way):

Dsc 2345

Things have been moved around a bit, but the basic setup hasn’t changed. The 3 pins in the top left are still for the ELV PIR, and the 1-wire DS18B20 option is still there (with fixed pinout, yeay!).

Here is the board with SHT11 and LDR soldered on:

Dsc 2348

And here are the two ways to attach the new PIR sensor:

Dsc 2350 Dsc 2349

That second setup is the most compact, but also the most inconvenient one if you ever need to make changes or reach the headers. Note that the PIR pins were soldered in as far out as possible, and that the LDR was bent sideways a bit:

Dsc 2354

I would advise to use the first setup where possible.

Having said that, here’s a complete Room Node with the (relatively) “compact” layout:

Dsc 2355

Bit of a hodge-podge, but that’s what you get when everything is kept modular.

GLCD on battery power

In Hardware on Nov 27, 2010 at 00:01

I’m going to switch to a different type of graphic LCD once the next batch of Graphic Boards arrives. Instead of a white-on-black type, the new GLCD will be a blue-on-sort-of-blueish color:

Dsc 2356

The reason for this is that it is still quite readable without the backlight:

Dsc 2358

There is a solder jumper on the Graphics Board, to choose between powering the backlight continuously via PWR, or having it powered under software control, via the not-often-used IRQ pin. This not only lets you turn the backlight on and off, but even dim it under software control, because the IRQ pin supports PWM, i.e. analogWrite().

The above display draws about 280 µA without backlight right now, which means it will keep running for over a month on a single AA cell, using the AA Power Board. There are probably ways to reduce that current consumption further, as I’m not doing anything yet with the ST7565’s standby and other low-power modes.

And although it may not be practical for a permament display, this definitely is useful for something I’d like to have around and use on a regular basis. By sending it stuff to display over wireless, this setup can support what is quickly becoming my favorite mode of operation here at Jee Labs: no wires cluttering my desk!!!

Spectrum Analyzer

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

Intrigued by this post, I wanted to try the same thing with the Graphics Board.

So here goes:

Dsc 2330

A real-time Spectrum Analyzer, with due credit to “deif” on the Arduino forum for making Tom Roberts’ simple 8-bit FFT implementation available (three more people are credited in the source code). On the above display you can see a typical “power spectrum”, with one dominant frequency plus harmonics at fixed intervals.

The sketch can be found here:

Screen Shot 2010 11 23 at 00.14.25

This is almost the same code as the 100 KHz DSO sketch, just extended with FFT.

The LCD is refreshed at maximum speed. As you can see, the lag of the LCD itself is actually quite useful in this context. This did bring a bug to the surface: I’ve noticed that the speed-up I implemented for the ST7565 was slightly too fast for this chip. After running for a while, the display would just turn black and stop refreshing.

So I changed these two lines in ST7565::spiwrite() :

Screen Shot 2010 11 22 at 23.48.10

… to this, slightly slower but equivalent code:

Screen Shot 2010 11 22 at 23.48.43

I’ve also updated my version of the ST7565 ZIP file accordingly.

One more note about this code is that it uses most of the available RAM now: the 1 Kb buffer in the ST7565 library, plus two 256-char arrays to store 256 datapoints for running the FFT on.

With code such as this, it would actually be possible to get rid of the ST7565 buffer, since we’re re-constructing the entire display each time.

But for now, I’ll just leave it at this…

2-channel Logic Analyzer

In AVR, Hardware, Software on Nov 25, 2010 at 00:01

Let’s continue the tiny lab-instrument series ;)

Here’s a logic analyzer which takes 512 samples of 2 bits (DIO2 and AIO2):

Dsc 2318

The “trace” starts when either of the inputs changes. I’ve enabled the internal pull-ups, so in this example you can see that DIO2 has no signal. The AIO2 signal is from a JeeNode running the Arduino IDE’s built-in “ASCIItable” demo, which sends out a bunch of characters at 9600 baud (I took the signal from the USB-BUB connector).

Here is the glcdTracer.pde sketch which implements this:

Screen Shot 2010 11 20 at 17.24.06

Lots of trickery with bits. To keep memory use very low, I’m storing the 512 samples in a 128-byte buffer (512 x 2 bits = 128 x 8 bits). Low values are drawn as a pixel, high values are drawn as a little vertical line.

The code includes a minimal triggering mechanism, i.e. it waits for either of the input signals to change before collecting 512 samples.

Samples are collected at about 10 KHz, but this can easily be changed (up to ≈ 200 KHz with the current code).

Note that it would be possible to double the number of samples to 1024 and display them as 8 groups of 2 signals, but then you’ll have to really squeeze the output to fit it onto the 64×128 pixels on the display.

BTW, there’s some shadowing visible on the display – has to do with how the chip drives the GLCD, no doubt.

Soooo… now we also have a portable Logic Analyzer!

More box options

In Hardware on Nov 24, 2010 at 00:01

Here are a few more options for putting JeeNodes in a box which turn out to work really well:

Dsc 2316

Of course anything larger will fit as well, but I wanted to find out which boxes would be just enough for a JeeNode. As it turns out: several!

These boxes are all available from Conrad, which has an online shop in several European countries. I’m not going to stock them for two reasons: 1) there are just too many choices, and everyone has different needs and preferences, and 2) they won’t fit in an envelope. So to get them, you’ll have to order from Conrad yourself.

The good news is that all these boxes are very inexpensive.

Below is a summary of each one shown above, along with the Conrad order numbers and external dimensions.


#534347 – 85x56x25 mm

The smallest box of ’em all. The JeeNode PCB fits in any of the slots, but you need to make a small notch on the inside of the top cover:

Dsc 2311


#534346 – 85x56x39 mm

A taller version, same color and same perfect fit for a JeeNode (as with the previous box, the FTDI pins need to point up, not out). No need to adjust the cover on this one:

Dsc 2312


#530113 – 88x58x30 mm

This one is slightly larger on the outside, but the sides are slanted and the board only fits by slightly enlarging the plastic notches inside. There’s a small hole in one of the shells:

Dsc 2313

However, there’s also an optional PCB for it with copper islands on one side (#530126). Then the JeeNode can just sit on top as is:

Dsc 2317


#520861 – 90x60x51 mm

On the large side, and fairly high. The JeeNode won’t fit in tightly, so you’ll need to fasten it somehow. This box could almost include a 3x AA battery holder with switch, but to do so you’ll need to remove some plastic inside on all 4 stand-offs:

Dsc 2314


#528373 – 124x72x30 mm

This box is almost identical to the Jee Labs box, but it’s transparent, it has slightly smaller inner dimensions, and there are no slots to slide the Carrier Board into. You can either shorten the pcb a fraction of a millimeter or make some very shallow grooves on the inside of the box to hold the pcb in place:

Dsc 2315

This box also comes in BLUE (#528834), RED (#528347), and GREEN (#528360).

Don’t know about you, but I’m pretty sure I’ll find a good use for each of these little boxes around here…

100 KHz DSO

In AVR, Hardware, Software on Nov 23, 2010 at 00:01

You might have been wondering why I created the digital-to-analog converter a few days ago.

Well, because I needed a test signal… to build this thing:

Dsc 2307

You’re looking at a <cough> Digital Storage Scope </cough> with 100 KHz bandwidth :)

First of all: please don’t expect too much. There is no signal conditioning and no triggering whatsoever, and there are no external controls. This is simply a JeeNode plus a Graphics Board. It’s using the built-in ADC, with the conversion clock pushed quite a bit higher than what the Arduino’s analogRead() function will do. This speed comes at the cost of conversion accuracy, which isn’t so important since the Graphics Board display only has 6-bit vertical resolution anyway.

The screenshot shows a 1 KHz sine (from that Bleep! thing, obviously). As you can see, one cycle more-or-less covers the entire x-axis. So that’s about 128 samples per millisecond. This is not the maximum value, the ADC can also work twice as fast – i.e. with a division factor of 4 (ADPS2:0 = 2). This translates to 4 µs per sample.

Using the Nyquist–Shannon sampling theorem again, you can detect a frequency if you sample it at least twice per cycle, so that would have to be a cycle of at least 8 µs, i.e. over 100 KHz. Which is why I decided to call this thing a 100 KHz DSO :)

The code tries to get as many samples as possible into a little 128-byte buffer before doing the rest of the work. The graphics display has a fairly limited response time, so I’m refreshing the display at 5 Hz (it’s still visible up to 50 Hz, but only just…).

I find it pretty amazing what an MPU such as the ATmega can do these days, with just a few lines of C code. Here’s the entire glcdScope.pde sketch:

Screen Shot 2010 11 19 at 02.58.10

The rest of the code is in the same modified ST7565 library as used in the past few days.

There’s lots of room for expansion, this code uses less than 4 Kb.

So there you have it – a very crude, but functional, oscilloscope!

The obligatory clock…

In Software on Nov 22, 2010 at 00:01

Take a Graphics Board, a JeeNode (or JeeNode USB, or JeeSMD), some code, and you get this:

Dsc 2303

I guess it’s sort of the equivalent of “Hello World” for graphical displays by now.

This is my code for it:

Screen Shot 2010 11 21 at 17.38.44

It even includes a blinking colon! :)

There’s a separate header file with the ten bitmaps used for each digit.

Here is a copy of the modified ST7565 code I use.

This clock runs on the ATmega’s 16 MHz clock, which is only accurate to about 0.5% with a ceramic resonator. More importantly, this clock has no notion of real time – it just starts counting when turned on. The value it starts from uses a funky trick available in RTClib: it’s set to the compile time of the sketch … this is actually not a bad choice during development. But for real use, you’ll need to add an RTC Plug or some other means of obtaining the time (such as a DCF77 receiver, if you’re in Europe).

Anyway. At least now you can see that it really is a graphical display.

Bleep!

In AVR, Hardware, Software on Nov 21, 2010 at 00:01

Puzzle for you – what is this thing?

Dsc 2301

Maybe the demo sketch helps?

Screen Shot 2010 11 18 at 12.25.23

Answer: it’s an 8-bit digital-to-analog converter, using an R-2R ladder network (with 10 kΩ & 20 kΩ resistors).

The above toneGen.pde sketch generates a sine wave of approx 1 KHz:

Screen Shot 2010 11 18 at 12.25.17

There’s lots of ways to improve on this and turn it into a general-purpose function generator for example.

The interesting part is that all four ports are used for the required 8 I/O pins, and that due to the regularity of the pin assignment, they can all be set at once with very little code. The pin assignments for the DAC are:

  • bit 0 = AIO1
  • bit 1 = AIO2
  • bit 2 = AIO3
  • bit 3 = AIO4
  • bit 4 = DIO1
  • bit 5 = DIO2
  • bit 6 = DIO3
  • bit 7 = DIO4

The maximum attainable frequency is about 1.84 Khz with this software approach (1.95 KHz with the sine256 table placed in RAM), but that’s only if you use all 256 steps of the sine wave. The loop itself runs at about 1.84 * 256 = 470 KHz, so based on the Nyquist–Shannon sampling theorem, it should be possible to generate decent signals up to well over 200 KHz. The trick is to increment the “index” variable by larger values:

Screen Shot 2010 11 18 at 12.54.06

Here’s the corresponding output:

Screen Shot 2010 11 18 at 12.55.31

Still a pretty decent sine wave, so 16 resistors are all it takes to cover the entire audible frequency range.

By using fixed-point calculations for “fractional indexing”, you can get even more fine-grained control over the frequency of the generated signal. The following version generates an 8.01 KHz sine wave on my setup (note that “index” is now a 16 bit unsigned integer):

Screen Shot 2010 11 18 at 13.03.55

Update – I’ve changed the main loop to avoid the calling overhead of loop() itself. That increases the maximum attainable frequency by another 50%. Note that interrupts must be disabled to produce a clean tone.

Indoor temperature, etc.

In Hardware, Software on Nov 20, 2010 at 00:01

Here’s a fun little project…

A Graphics Board with a JeeSMD and two plugs: a Pressure Plug and a partially-populated Room Board.

The result is a geeky little indoor environmental monitoring station:

Dsc 2293

Couple of notes here:

  • I took the lazy way out and merely display the info as text, graphics would be so much nicer!
  • Both sensors can read the temperature, but as you can see, they don’t fully agree…
  • I added the FTDI hookup and used it to power this thing via an AA Power Board.
  • The AA board does double duty, as a little stand to hold this thing slanted upwards.

Adding FTDI was very useful in this case, since it also makes it possible to re-program the JeeSMD, which has no FTDI connector on board. All it needs is a 0.1 µF cap and the 6-pin header:

Dsc 2298

But there’s more to it than that, alas: to be able to upload to the JeeSMD, you need to hook up all the headers on the JeeSMD, i.e. also the PSI and the SPI/ISP headers. Adding those after the fact is very tricky, since you can’t reach the back of the Graphics Board pcb anymore if you soldered the LCD on permanently – as I did.

I had to solder the female headers slightly higher, to just barely reach the pins from the top with a very fine soldering iron tip (I use 0.4 mm). It worked, but as a result, the JeeSMD sits a bit higher on its pins than usual:

Dsc 2297

Here’s the indoor.pde sketch, also added to the Ports library:

Screen Shot 2010 11 17 at 22.47.37

Onwards!

Speedier graphics

In Software on Nov 19, 2010 at 00:01

The Graphics Board is going to enable a bunch of fun projects around here.

Unfortunately, the ST7565 library is a bit slow in one specific way – display updates. Since everything is buffered in RAM, most other operations are actually quite fast, but to get that data onto the gLCD takes time.

I had to find out how much time, of course. Here’s my test sketch:

Screen Shot 2010 11 17 at 19.45.42

All the loop does is send the same RAM buffer contents to the display, over and over again. The time it takes in microseconds is sent to the serial port, and the result is quite bad, actually:

  • 126 milliseconds, i.e. 8 refreshes per second, max!

The good news is that it’s a clear bottleneck, so chances are that it can be found and then hopefully also avoided. Sleuthing time!

The ST7565 core primitives, responsible for getting the data out to the display were coded as follows:

Screen Shot 2010 11 17 at 18.43.49

Guess what: the shiftOut() in the Arduino library is written with calls to digitalWrite(). That rings a bell.

Ah, yes, good OLD digitalWrite() again, eh? Of course

So I rewrote this code using fixed pin numbers and direct port access:

Screen Shot 2010 11 17 at 18.45.18

And sure enough, it’s almost exactly TEN times faster:

  • 12.3 milliseconds, i.e. 80 refreshes per second.

Needless to say, I’m going to leave these changes in my copy of the ST7565 library – even though that means it’s no longer general purpose since the pin assignments are now hard-coded. A 10-fold performance increase of something which really needs to be snappy and responsive is non-negotiable for me.

Here is a copy of the ST7565 code I use.

Could this bottleneck have been avoided?

The ST7565 library was clearly written as general purpose library, so making it usable with any set of pin assignments makes a lot of sense. The price paid in this case, was a 10-fold drop in performance, plus a few extra bytes of RAM used in the ST7565 class.

I’ll revisit this topic some other time, to discuss the trade-offs and implications of compile-time vs run-time logic, as well as tricks such as: putting the pin choices in a header file, using #include for source files, pre-processing and code generation, and C++ templates.

For now, I’m just happy with the 80 Hz refresh rate :)

Update – I had to slow down the SPI clock a bit, because the display was not 100% reliable with the code shown above. The fix is in the ZIP file.

Thermo Plug mismatch

In Hardware on Nov 18, 2010 at 00:01

The Thermo Plug was recently updated as a kit with a thermocouple for use as Reflow Controller, for example.

It uses screw terminals to connect the K-type thermocouple, because that wire can’t be soldered – I tried, really hard! Besides, you don’t want to add too many weird amalgamated cold metal junctions in this setup, which is all about the tiny voltage potential between different metals.

The whole thermocouple works nicely, but I goofed a bit on the connector: the screw terminal I got for this plug is slightly too big to fit on there in the intended position:

Dsc 2289

Yuck … two solutions:

  • solder it on anyway, and just ignore that tower-of-pisa effect…
  • solder it on the other way, and insert the thermocouple wires from the board side

Here’s how that will look:

Dsc 2290

Slightly odd, but it’ll work just fine of course.

Note that the back side of this screw terminal has two holes, but they cannot be used to insert wires, because those will end up too high and wouldn’t be held tight by the screws:

Dsc 2291

I’ll look around for a slimmer form-factor 3.5 mm screw terminal. If I can’t find any, then I’ll plan a board revision – but for now, it’ll have to do.

With a small nod to Mr. Murphy…

Room Node display

In Software on Nov 17, 2010 at 00:01

Now that there’s a Graphics Board, I thought I’d make a little display with the last few readings from a couple of room nodes around here. Ironically, it’s just a 8×21 character text display for now – no graphics in sight:

Dsc 2281

The information consists of:

  • a packet sequence number (only 4-byte packets are treated as room nodes)
  • the node ID
  • the temperature in °C
  • the relative humidity in %
  • the measured light intensity (0..255)

New readings get added at the bottom, with older readings scrolling upwards.

Unfortunately, the ST7565 library doesn’t have a normal print() & println() API, so the first thing I did was to create a new wrapper class:

Screen Shot 2010 11 16 at 12.42.57

One quirk about this code is that since we’re using a RAM buffer, the ST7565 screen contents needs to be explicitly updated. I solved it by adding a poll() method which you need to call in the main loop. It’ll make sure that the display gets refreshed shortly after anything new has been “printed” (default is within 0.1 s).

Another thing this class does is to scroll the contents of the display one line up when the bottom is reached. It does this in a slightly lazy manner, i.e. the display is not scrolled immediately when a newline is sent to it but when the first character on the next line falls outside the display area – a subtle but important difference, because it lets you use println() calls and the display won’t constantly leave an empty line at the bottom.

Scroll support does require one change to the “ST7565.cpp” source code. This:

    static byte gLCDbuf[1024];

Has to be changed as follows, to make the RAM buffer accessible from other source files:

    byte gLCDbuf[1024];

(should be around line 42 in ST7565.cpp)

With that out of the way, here’s the glcdNode.pde sketch, which has been added to the RF12 library:

Screen Shot 2010 11 16 at 12.53.36

For debugging purposes, the same information shown on the display is also sent to the serial port:

Screen Shot 2010 11 15 at 02.24.28

Note that gldeNode is hard-coded to receive packets from net group 5 @ 868 MHz, as you can see in the call to rf12_initialize().

So now I have a battery-powered wireless gadget which lets me track what our house is trying to tell us!

Update – the ST7565 library needs to be changed a bit more, I now realize. Perhaps the easiest way to do so is to simply insert the following line somewhere near the top of ST7565.c:

    #define buffer gLCDbuf

That way, the buffer will have a more meaningful name when made global by the above-mentioned patch.

Update #2 – no more need for the ST7565 library, use the new GLCDlib instead. The glcdNode demo sketch has been adapted and moved over to it.

Assembling the Graphics Board

In Hardware on Nov 16, 2010 at 00:01

This is going to be a weblog post with lots of pictures…

The Graphics Board is easy to assemble, but there are two things to watch out for:

  • the polarity markings for two of the electrolytic 1µF caps are reversed
  • if you solder the display onto the board, then you can’t easily reach the back anymore

The former is a mini goof-up by yours truly, the latter is something to keep in mind when deciding which headers you are going to use (you can side-step the issue by mounting the display using headers, but that will increase the height of the entire stack).

Here goes. As usual, I’m going to proceed from low to high-profile components, because that lets you put the components in, flip the board over, and press on it to get the components soldered closely to the board.

First the 100 Ω backlight series resistor:

Dsc 2251 2

Note that there’s a solder jumper right above it. The default is to connect the middle pad with the leftmost pad marked “P”. This connects the backlight permanently to the PWR line. If you want to control the backlight through the IRQ signal, you can set the solder jumper to the “I” position instead (see the backlight() docs). This can be changed later if you change your mind.

Then 5 yellow decoupling caps. These are not polarized, but make sure you put them into the right holes:

Dsc 2249

Update: The latest kit version ships with ceramic capacitors replacing the electrolytic capacitors. This gives longer life and simplifies the construction detail since these capacitors are not polarised. See the Wiki for more detail

The next step needs some care, because these two electrolytic caps are marked the wrong way on the silkscreen – they should be placed as follows:

Dsc 2251

The proper way to connect these, is to put long lead on the right and on the bottom, respectively. Or, same thing: put the gray stripes of the plastic case insulation on the left and on the top.

Note: the two caps on the left will only just barely fit when a JeeNode v5 is added on later. If you use a JeeNode v4, it is probably better to place them flat on their side pointing left. When in doubt, make sure you check the mechanical layout before soldering these two leftmost caps!

The other two 1 µF caps go as indicated on the board, they will in fact be oriented exactly opposite to the caps right next to them:

Dsc 2252

More…

Read the rest of this entry »

Meet the Graphics Board

In Hardware on Nov 15, 2010 at 00:01

Sometimes, 2×16 characters (or perhaps a few more) just don’t cut it, when I’d like to present things graphically, or use larger fonts for some of the info. That’s when a “GLCD” would be handy, one which lets you set individual pixels, that is. I was pointed to a nice low-power 128×64 display recently, and decided to create a pcb for it – so here’s the new Graphics Board:

Dsc 2258

Due to the size of the board, it’s not a plug or an add-on to a JeeNode, but the other way around: you can take a JeeNode, JeeNode USB, or JeeSMD, and push it onto this board to power and drive the display.

Ports 1 and 4 are used for the diplay, but ports 2 and 3 are available, and brought out in such a way that plugs can easily be added on. To make a clock, add an RTC Plug. To add a few touch buttons, add a Proximity Plug. To create a fancy Reflow Controller, add a Thermo Plug. Or just use it as is and add a sketch to display messages received over wireless. Endless possibilities…

Here’s the display in action, it’s pretty bright when driven from 5V:

Dsc 2278

It can display up to 8 lines of 21 characters, but it’s also fully graphical of course. BTW, in real life the display looks much more white-on-black.

I particularly like this setup, using the AA Power Board to make this thing completely self-powered:

Dsc 2245

The backlight resistor is chosen such that on 3.3V, this display draws ≈ 6 mA, and on 5V it draws ≈ 19 mA. It will last a few days with an AA Power Board, but when the 100 Ω resistor is replaced by 270 Ω or even 470 Ω, you can get well over a week of battery life on a single AA (assuming the JN itself is sleeping most of the time) – at the cost of dimming the backlight to a fairly low level.

There is a solder jumper on the board which normally connects the backlight to the PWR line. By connecting it to the IRQ line instead, that pin can turn off the backlight under software control (or dim it, using PWM).

The display is based on the ST7565 chip and can be driven by Limor Fried’s great ST7565 LCD library. Note that this library uses a 1 Kb RAM buffer.

Here’s the glcd_demo.pde sketch which generates the above display:

Screen Shot 2010 11 14 at 17.20.36

I included logic to put the ATmega and radio into power down mode to let me measure the display’s current consumption. While active, they draw another 5..30 mA.

The Graphics Board is now in the café and the shop.

UpdateHere is a copy of the ST7565 code I use.

Flippin’ bits – revisited

In Software on Nov 14, 2010 at 00:01

For one of the infinite number of projects here at Jee Labs, I wanted to know how fast you can toggle a pin. This has been covered before in a previous weblog post, but this time I’m going to actually measure the results.

I’m going to focus on sending out 8 pulses in a row, because my goal is to transfer one byte in or out of the system (i.e. software-based SPI).

Here’s the simplest possible way to do it:

Screen Shot 2010 11 14 at 02.13.56

Measured result = 124.60 KHz, i.e. ≈ 8 µs per bit.

Some of that is loop overhead, and one trick to avoid that is to “unroll” the loop:

Screen Shot 2010 11 13 at 18.19.02

Measured result = 129.14 KHz – no big difference?

The reason is that the Arduino library’s “digitalWrite()” is very slow. So let’s go back to the loop and use a faster mechanism:

Screen Shot 2010 11 14 at 02.17.19

Measured result = 1.72 MHzwhoa, 0.58 µS per bit!

Now let’s unroll that loop again:

Screen Shot 2010 11 13 at 18.25.30

Measured result = 3.03 MHz – yep, now the loop overhad makes a big difference…

Can we do better? Yes, we can (heh) – using the PIND trick to toggle an output:

Screen Shot 2010 11 14 at 02.18.30

Measured result = 2.16 MHz – that’s ≈ 0.46 µs per bit.

And now, at these speeds, loop unrolling makes an even bigger difference:

Screen Shot 2010 11 13 at 18.31.54

Measured result = 4.71 MHz!

That’s a bit odd though. The JeeNode is running at 16 MHz, and 4.71 MHz is not a very clear multiple or divisor of anything. How can a regular sequence of statements generate such an irregular frequency? The puzzle is solved by looking at the bigger picture with a scope:

Screen Shot 2010 11 13 at 18.59.09

(as you can see, my scope can’t sample 8 MHz square waves with good fidelity)

The scope measurement says it all: these are short bursts, because now the calling overhead of “loop()” is taking almost as much time as the 8 pulses.

If I unroll the loop further to contain several hundred “PIND = bit(4);” statements, the frequency readout increases to 7.82 MHz. IOW, each C statement takes one processor cycle!

Quite an amazing feat, the AVR MPUs are clearly RISC-class processors. And the gcc compiler is generating optimal code in this case.

So there you have it. A lowly JeeNode (or Arduino) can generate multi-megahertz signals on an I/O pin, just by writing a few lines of C code!

Note that these are limiting values. As soon as you start adding more logic to these loops – whether unrolled or not – the maximum attainable frequency will quickly drop. But still: not too shabby for them little chips!

Update – measurements were slightly off, because not all loops were 8 long. Fixed now, same conclusions.

Hand-made envelope

In Musings on Nov 13, 2010 at 00:01

Yesterday, I got a small cardboard box from India with some geared DC motors I’d like to experiment with. It came wrapped in this:

Dsc 2246

Quite sturdy and hard to remove, in fact. Note also the text on the declaration for customs: “Parts” – heh, yeah, that’s all they need to know :)

And it’s… hand-stitched!

Dsc 2247

Amazing. I now have this mental picture of someone with needle and thread, sitting in lotus position in the shipping department, in charge of wrapping up all the outgoing packages :)

I find these small glimpses of the cultural richness on our planet one of the most thrilling aspects of doing business these days. Long live human diversity!

Meet the Infrared Plug

In Hardware, Software on Nov 12, 2010 at 00:01

The new Infrared Plug needed a small adjustment to work, but now it’s working properly. Here’s my hand-soldered prototype:

Dsc 2243

Fits on any of the JeeNode ports, of course. The DIO pin controls the IR output, which is pulsed at 38 KHz (38.28 KHz on my unit, more than close enough). The light is generated with one or two IR LEDs. With one LED, the peak current is ≈ 50 mA (a bit high for the AA Power board) – with two LEDs, the current is ≈ 10 mA. That will no doubt have a lower range, but you could tape one of the LEDs onto a specific appliance, while still letting the other one shine into the room (or a second device).

The input is a 38 KHz detector, with its signal available on the AIO pin.

The “InfraredPlug class” in the Ports library makes it easy to interface to this plug, as described in recent posts.

I’ve also added an “ir_repeater.pde” demo sketch, which repeats any NEC command it receives three times, at 1-second intervals. When I press “Forward” on my Apple Remote, it’ll end up skipping 3 extra songs forward. Can’t quite think of a use for that, but it helped me flesh out the bugs:

Screen Shot 2010 11 11 at 18.16.58

There is a bit of logic in there to convert the incoming slot count to a bit pattern.

Sample output:

Screen Shot 2010 11 11 at 18.16.51

The Infrared Plug is now in the café and the shop.

Parallel port UltiMaker

In Hardware on Nov 11, 2010 at 00:01

I’m currently building the Mantis – a little CNC router designed specifically to help create custom PCB’s. Actually, mine will look more like this.

I’m not convinced yet that this thing will be able to do PCB isolation routing, but I’m willing to give it a try. It’d make it much simpler to do one-off’s, instead of having to live with this:

But I’m not quite willing to dedicate an Arduino Mega and the UltiMaker electronics that is offered as option in the workshop. If you’re interested in 3D printing: the UltiMaker is derived from the RepRap and the MakerBot CupCake, as described here.

So instead of following everyone using the MPU-based approach, I’m going to re-use my parallel-port laptop running the EMC2 software, and let the laptop do all the work, instead of yet another dedicated board. I can always switch to a microcontroller setup later if this machine is practical enough to use it frequently. And if it doesn’t work out, my investment will have been relatively low.

There’s also a second reason for doing it this way: I’d like to build my own electronics for this CNC/3D stuff one day. I think there are better ways to do this sort of thing, more modular, more extensible, and more flexible (why not Ethernet? why not closed-loop servos?). But it wouldn’t be realistic to think I can take on that challenge as well, with everything else also going on at Jee Labs. So for now, the parallel-port shortcut will have to do.

Driving CNC stepper motors from a parallel port is a proven (but by now somewhat outdated) concept. Either way, it all ends up doing the same thing: executing the CNC world’s de-facto standard G-Code scripts.

You still need stepper motors, and stepper motor drivers, since a parallel port can only send out feeble 5V signals.

To save some time, I decided to try something a bit whacky by re-purposing an UltiMaker electronics board to hook up its motor drivers to the parallel port:

Screen Shot 2010 11 10 at 17.49.08

Lots of stuff on there I won’t need: heater control, extruder control, PWM…

Here’s a minimal setup, using just 3 stepper drivers and a little JeePlug board sitting on top of some extra headers on this board:

Dsc 2242

I patched a 5V regulator (plus LED) on there to feed the logic levels of the Pololu stepper drivers, and left everything else off, basically. Only thing left to do is wire up 7 signals + ground between the parallel-port breakout board and the JeePlug.

And then figure out the software side of things…

IR packet decoding

In Software on Nov 10, 2010 at 00:01

The InfraredPlug class in the Ports library has been extended with a decoder which tries to recognize the incoming IR pulse trains. Remember that the data is returned as a list of on/off times, returned as multiple of the “slot size” given to the InfraredPort constructor on setup.

I merely added a new “decoder()” member:

Screen Shot 2010 11 09 at 12.16.09

It currently only recognizes the NEC protocol, which is what three of my remotes here use. The NEC packets have 32 bits of payload (or no bits at all in the case of a “repeat” packet).

Here’s is how the ir_recv.pde sketch calls this new decoder:

Screen Shot 2010 11 09 at 12.19.35

Sample output from three different buttons on three different remotes each:

Screen Shot 2010 11 09 at 12.52.03

The first remote (starting with 246) shows a “classical” NEC remote, where each second byte is the 1’s complement of the one before it.

The second remote (starting with 162) uses 1’s complement only on the command bytes at the end.

The third remote (starting with 119) is an Apple Remote which uses the extended NEC format, and presumably another way to check the validity of received packets.

Full details about the NEC and other protocols can be found on San Bergman’s page.

Almost, but not quite

In Hardware on Nov 9, 2010 at 00:01

There’s a new Infrared Plug in the works – it’s almost ready. The IR transmitter uses the venerable 555 chip:

Screen Shot 2010 11 08 at 20.36.42

I used the formulas from the datasheet to calculate the different resistor and capacitor values to arrive at 38 KHz, which is the most common IR frequency (and which most 36 and 40 KHz systems will pick up as well).

To check things out, I hooked the plug up for constant oscillation (DIO to +3V):

Dsc 2235

Despite using 1% parts for all the timing critical components, the output isn’t quite what it should be:

Screen Shot 2010 11 08 at 20.33.12

That’s 35.5 KHz … i.e. almost 10% off target!

(note that I measured the signal across the transistor – the IR current is actually the opposite, i.e. fast rise time)

I’ll have to tweak one of the resistors empirically (16.0 kΩ i.s.o 17.4 kΩ seems to fix it) and order some new SMD values. And then I need to check that the frequency across multiple plug builds will remain within bounds.

Not quite back to the drawing board (the PCB seems to be ok), but still: back to the soldering iron!

JeeNode Experimenter’s Pack

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

Neat – it looks like JeeNodes are starting to become popular for workshops!

I’m not really surprised: it’s more fun than an Arduino, IMO, because you get to learn the basics of electronics and soldering, and of course every JeeNode comes with wireless connectivity built-in. As I’ve said before, making things happen by wireless is a bit like magic…

FWIW, there are a couple of workshops scheduled for this month (“in-house”, i.e. for a specific audience, and I’m only indirectly involved), all are based on either a JeeNode or an RBBB. Both are well suited for solderless breadboards, which – if you ask me – is one of the greatest inventions ever for tinkering and learning electronics. Sure, soldering works best when the circuit is known and proven, but nothing beats a breadboard, some jumper wires, and a bunch of components and chips to try out things!

This gives me great satisfaction. No, not for the money side of it (it’s all discounted anyway), but because I find nothing more exciting than to see people try out new fun stuff and nurture their tech geek sides :)

Learning is great: if you’re young, it’ll make you wiser – if you’re old, it’ll make you younger … (and it’s fun!)

The big question is always: “what do I need to get started?” – and my answer is usually: “it depends on what kind of adventure you’re after”.

I’ve come up with a new “JeeNode Experimenter’s Pack” to create a baseline for the future. That way, it will be easier for me to set up and document my experiments, knowing that there is a common baseline on which to build. It’s also the logical step after this rubber-band concoction. It consists of the following key components:

Dsc 2221

In prose:

In addition, and only in combination with the rest of the Experimenter’s Pack, I’m throwing in a little 10×17 cm laser-cut wooden base and an LDR to get started with some sensor experiments:

Dsc 2220

The base turns the whole thing into a self-contained “project platform” for all sorts of experimentation. And the AA Power Board will supply 3.3V to make this setup portable and usable anywhere. The rest of the empty space is all yours. That’s where the fun happens :)

The AA Power Board is not just a gimmick, BTW: an AA battery will actually provide more power @ 3.3V than a 9V “block”! As someone pointed out recently, it’s also a great way to drain any half-used AA batteries you might still have lying around (who hasn’t?).

Here’s a recent example of use (which required a bit more power, so I hooked it up to a 12V supply):

Dsc 2215

It’s a little stepper motor tester (using an EasyDriver board). Nothing fancy, but it was a convenient way for me to try something like this out. That project board has now been cleared to make room for new experiments…

That’s the whole point, really – this self-contained setup is intended to provide a quick path for trying out new ideas. USB-connected or battery-powered, serial or wireless, local or remote, whatever.

Once it all works, you could:

  1. take the design and redo it as a more permanently soldered circuit
  2. design a pcb for it (which is what I did for the graphics board)
  3. put it all into a custom enclosure and keep using the setup
  4. stash it all away as is, for some other time
  5. put hot glue on it? (yikes!)

I’ve added this to the shop, as 1- and as 10-pack.

Isolation

In Hardware on Nov 7, 2010 at 00:01

There’s no escape… I have to get into mains voltage stuff and try some things out. All 220 volts of ’em!

I want to experiment with power measurement, power control, dimming, an such – but, ehm… preferably in a way which will let me live to tell the story! (how’s that for dedication to this weblog, eh?)

Now the thing about electricity is that it’s not the voltage that kills you, it’s the current – after all, if this weren’t the case, all the birds on high-voltage wires would be dropping dead out of the sky…

Current means: electricity going from A to B. And the problem with us human beings is that we are conductors – which isn’t too surprising, given that we’re mostly made of water anyway (the rest is hot air, I’m told).

So the first thing to do is to isolate myself from AC mains, by not allowing a ground path to carry any current. This can be accomplished with an “isolation transformer”, i.e. a transformer from 220V to 220V which – like any normal transformer – creates a galvanic isolation barrier:

Screen Shot 2010 11 06 at 20.25.22

Trouble is, these transformers are relatively expensive. One reason for this could be that you want to get a fair amount of power across, so these are hefty units with a lot of copper, iron, etc. in them!

Fortunately, there’s a simpler way to accomplish exactly the same using two back-to-back normal transformers:

Screen Shot 2010 11 06 at 20.26.38

The first one is a normal step-down transformer, producing 10.5V – and then we simply take a second one of the same type, and connect it the “wrong” way around.

There will be losses, so the output voltage won’t be exactly 220V, but I’m fine with that. In fact, it’s a nice test to see what a mains circuit will do with a somewhat lower voltage.

I’m going to use a pair of beefy 300W transformers I have lying around here, which will let me test some control and measurement options up to at least 250 Watts or so. Here are the main ingredients, which I’ll put in a wooden box with slots for natural convection. This dual wine bottle unit looks like a good fit:

Dsc 2212

(I told you they were hefty tranformers – each of them weighs several kilo’s!)

What this gives me, is an isolated source of mains-like AC voltage. It is still just as lethal when touching both power lines. The only safety this adds, is that touching a single high-voltage output wire is now harmless.

The other benefit is that an accidental short will limit the amount of current that can flow through this setup, thus also limiting heat and damage somewhat. But 300W of power is still a huge amount, so I have no illusions that things won’t break. It’s mostly to prevent fires and burnt-out cabling.

Evidently, this thing needs a switch with indicator light, and fuses: a 5 Amp fuse on the input, and a 4 Amp resettable fuse on the output (lowest I could find):

Dsc 2213

Scary stuff. I could set up a pair of much lower-amperage transformers for loads up to 25 Watt or so, but it’d still be potentially lethal, so that would only lead to a false sense of security.

The low-voltage / high-amp intermediate circuit does provide an option to insert a fast-acting fuse. A 100 mA fuse @ 10.5 VAC would translate to 5 mA @ 220 VAC, which is no longer lethal, but I’m not willing to “prove” that! Trouble is that such a setup would blow its fuse with anything over 1 Watt of power, even if only a power-up spike.

Here’s the whole contraption (not wired up yet) – with thanks to Ikea for the “front panel”:

Dsc 2214

I’ll finish this isolation setup for some experiments, but it won’t alleviate much of my fear. Unfortunately, there’s simply no other way to get going…

Better panels

In Hardware on Nov 6, 2010 at 00:01

While we’re on the subject of PCB panels…

All new plug panels are now made with a mix of V-scoring and routed slots:

Dsc 2194

The vertical lines are “V-scores” – small sharp cuts on both sides of the boards which makes it easy to break off the board at that point. Adds a few strips of waste, but the result is much cleaner.

The reason for this is that the sides come out better (and much more accurate) when routed, but you don’t want to route all four sides, because then you have to leave little break-off tabs to hold the boards. The problem is that these tend to break off with a very rough edge, requiring extra cutting or sanding to clean up.

Progress!

Smooth sailing

In Hardware on Nov 5, 2010 at 00:01

I’ve just completed three pcb panel reflows, based on my Reflow Timer progress. Here’s a panel of Pressure Plugs:

Dsc 2210

Perfect reflow, on all three panels. There is a small problem with a cold spot in the grill, but that’s a known (and predictable) issue with a specific spot on the panel. Nothing a soldering iron touch-up can’t fix.

Oh, and isn’t blue + gold just gorgeous? – I see that it’s being picked up / imitated by others as well, such as for the “USB BUB” and the “LCD Plug” – well, sort of… ;)

Here’s one of the (unretouched) corresponding reflow graphs:

Screen Shot 2010 11 04 at 18.27.00

A perfect profile on every run, as far as I can tell!

Note that the initial overshoot in the WARMUP phase is not very important. The key is to start off somewhere between 80° and 100°, with a fairly flat curve. How that point is reached turns out to vary a lot – but from then on, all reflow graphs I’ve seen so far look more or less the same. Which is all that matters.

The only improvement remaining, is to find a way to automatically come up with decent P, I, and D factors (I’m currently using 150, 5, and 700, respectively). I’m hoping that a calibration run which applies a step change will be able to solve this. The idea is to start at some temperature (below 40°C), then turn on the heater full blast until it reaches 120°C, then measure the slope at that point as well as the maximum temperature reached after the heater has been turned off. The slope says something about the heater power, the overshoot says something about the amount of “pent-up” heat stored between heater and thermocouple, i.e. the “thermal mass” of the system.

I’m delighted with my new setup, because it no longer needs to be chaperoned – I just turn the Reflow Timer on and walk away to start populating the next board. IOW, this reflow process is now a no-brainer and a time saver!

Onwards! :)

Reflow Timer software

In Software on Nov 4, 2010 at 00:01

Another episode in the reflow controller story…

Here is yesterday’s graph again, but manually annotated this time:

Annotated Reflow

Actually, I went ahead and extended the code to add those axis labels in there. I was concerned that they would overlap and distract from the graph data itself, but after seeing this… it clearly improves readability.

The trick is to get the PID control factors right, and these will be different for each setup. Right now, I just picked a couple of values which seem to be working ok on my particular grill. I’ve extended the JeeNode sketch to allow adjusting these values via a serial USB connection:

    <N> P       P factor (x1000)
    <N> I       I factor (x1000)
    <N> D       D factor (x1000)
    <N> L       I limit (x1000)

The PID calculation is:

    (Pfactor*Pval + Ifactor*Ival - Dfactor*Dval) / 1000

In other words, these factors are specified as a multiple of 0.001.

The result is brought into a range of 0..100. This in turn is used to determine when, how often, and how long to turn on the heater in the grill/oven/skillet.

The reflow profile parameters are also adjustable from the serial link:

    <N> o       ON temperature (°C), default 70
    <N> w       minimum time in WARMUP phase (sec), default 60
    <N> p       temperature at end of PREHEAT phase (°C), default 140
    <N> s       temperature at end of SOAK phase (°C), default 170
    <N> m       maximum REFLOW temperature (°C), default 250
    <N> r       minimum time in REFLOW phase (sec), default 15
    <N> c       temperature at end of COOL phase (°C), default 150
    <N> f       temperature at end of FINAL phase (°C), default 50

Once the FINAL phase ends, the JeeNode will power itself down.

A few more parameters:

    <N> l       lower calibration temperature limit (°C), default 40
    <N> u       upper calibration temperature limit (°C), default 120
    <N> d       stable duration (sec), default 5
    <N> t       stable trigger gap (°C), default 25
    <N> a       number of temperature averages to take, default 250

Some parameters for reporting, which happens once per second:

    <N> i       wireless node ID (sending disabled if 0), default 8
    <N> b       wireless frequency (4=433, 8=868, 9=915), default 8
    <N> g       wireless net group, default 5
    <N> e       enable (1) or disable (0) serial reports, default 0

And finally, the parameters which control the FS20 remote switch:

    <N> H       house code to use for FS20, default 4660
    <N> h       device ID to use for FS20, default 1

All PID factors and other parameters are stored in EEPROM, so they will remain in effect until changed.

To get a summary of all the current settings, type a question mark: “?”.

To reset all parameters to their “factory” defaults, type an exclamation mark: “!”.

The code for the “reflowTimer.pde” sketch is here The current code size is ≈ 14 Kb. I’ll probably be tweaking it a bit further in the coming days.

One thing I’d like to try adding to the current sketch is an easy way to self-calibrate and come up with a workable set of P/I/D factors, so that it can be used with a variety of electrical grills, toasters, skillets, ovens, barbecues, whatever – under the motto: if it can melt solder, we should try it!

The JeeMon script is here and is about 150 lines of code. If you save it as “application.tcl” next to JeeMon, it will automatically be picked up when JeeMon is launched. The code is still work-in-progress at this point: you will have to manually edit the “device” variable to refer to your attached JeeNode/JeeLink running RF12demo – you can also set it to a COM port (Windows) or tty device (Linux/Mac). Likewise, the “nodeID” variable should be set to match the current setting in the Reflow Timer sketch (“i” parameter):

    variable device   usb-A900ad5m    ;# which JeeNode/JeeLink to attach to
    variable nodeID   8               ;# which node ID to listen to

The frequency band + netgroup of the JeeNode/JeeLink are assumed to have been previously set in RF12demo.

Note that the script is an optional GUI front-end – you can launch it anytime, or you can ignore this whole JeeMon thing, since the sketch does not depend on it. It’ll drive the reflow process with or without the GUI.

If you try this out, or have suggestions about how to improve things, please let me know.

Update – I’ve adjusted the info above to match the latest code changes.

Meet the Reflow Timer

In Hardware, Software on Nov 3, 2010 at 00:01

Now we’re cookin’ – here’s the complete reflow configuration I am setting up for use at Jee Labs:

Dsc 2201

Yes, it’s a Project On Foam again!

As before, I’m using a 700 Watt low-end toaster/grill. It can heat about the area of a 10×16 cm pcb and it’s really small and practical for me. I removed the teflon-coated hot plates, and placed a thin aluminum sheet in there, to respond more quickly to heat changes. A small oven or a skillet could probably also be used.

The power is controlled by an FS20 remote switch (available from Conrad or ELV, both in Europe). This is very convenient, since JeeNodes can control this thing through the RFM12B without any further hardware. The big advantage: no need to mess around with 220V AC mains – it’s RF-isolated!

The LCD display makes this thing independent of a PC/Mac. And the battery pack makes it a fully stand-alone solution. The JeeNode (and LCD / radio) will shut off once the temperature drops below 50 °C. This whole setup draws about 30 mA, so with a run time of 10-minutes, four AA batteries will last hundreds of runs, i.e. plenty!

The Thermo Plug and Blink Plug have both been extended in the shop as pre-assembled unit and kit, respectively, including a thermouple which can be used up to 350 °C. I’ve also added a 4-cell battery holder.

Here’s how to operate this thing:

  • set up everything, place the board inside the grill, and close the lid
  • press the GREEN button, the green LED goes on
  • wait for the BEEP, then carefully open the lid
  • wait until the green LED turns off, i.e. the temperature drops under 150 °C
  • done!

This is an example of what happens during a run:

Screen Shot 2010 11 02 at 13.10.19

Tomorrow, I’ll comment on this graph and the JeeMon app that produced it.

Reflow profiles, again

In Software on Nov 2, 2010 at 00:01

Now that the thermocouple readout is working properly, things are moving again with the reflow controller.

What we need to do is set up a reflow temperature “profile” which drives the whole process. First the top level code which controls the whole shebang:

Screen Shot 2010 11 01 at 12.10.38

I’ve left out the reporting part, but basically we need to respond to button presses and go through the whole profile once activated. The reflow profile logic is handled by “setPhaseAndTemp()” function:

Screen Shot 2010 11 01 at 12.12.33

As you can see, it is a simple state machine which moves from one phase to the next according to current temperature and timing conditions. The parameters I’m currently using are as follows:

Screen Shot 2010 11 01 at 12.19.36

Each phase has slightly different conditions, and criteria with which it decides to move on to the next phase.

I’ve added a “warmup” phase at the start for two reasons: 1) to always start off on the main part of the reflow profile from a fairly well-defined temperature, and 2) to implement a drying period which removes any humidity present in the chips, since some chips seem to be sensitive to that. That does somewhat lengthen the whole cycle, because there is a lot of overshoot at low temperatures.

Tomorrow, I’ll describe the complete setup and show you how it performs.

Conquering the thermocouple

In Hardware, Software on Nov 1, 2010 at 00:01

(No Halloween stuff on this side of the pond – I’ll defer to Seth Godin for some comments on that…)

A while back, I had to shelve my experiments with the reflow controller, because I couldn’t get a reliable temperature reading from the Thermo Plug when using a thermcouple.

Or rather, sometimes it worked, sometimes it didn’t: the physical computerer’s equivalent of a nightmare!

The thermocouple circuit is very sensitive to ground currents, apparently. The effect was that my setup would work fine on batteries, but jump all over the place when attached to the USB port. Not very convenient for development, obviously.

It still has some unexplained behavior, but I’ve been able to narrow it down, so there are two new pieces of good news: 1) it only works badly while data is being transferred over the USB port, and 2) with some averaging, the readout is actually rock solid, both on batteries and on USB. I still see a difference in readout when data is transferred over USB, but since this is a JeeNode, I can work around that in the final version: go wireless!.

Here’s the readout code which produces good readings – all remaining jitter is now in 1/10’s of degrees Celsius:

Screen Shot 2010 10 31 at 18.48.10

The output is in 1/100’s of °C, because I’m trying to avoid floating point math in this sketch.

And here is the measuring side of my new reflow setup:

Dsc 2200

The thermocouple is taped to the thin aluminium insert in the grill using heat-resistant Kapton tape. When I turn on the heater, I now see a clear rise in temperature within seconds – perfect!

Note that I’m using a 4x AA pack i.s.o. 3x AA, because the AD597 needs at least 2V more on its supply line than the highest output voltage it is going to report. With 4x 1.2V (worst case, i.e. near-empty eneloops), the range will be at least 4.8 – 2 / 0.010 = 280°C, i.e. plenty!

And indeed, I’ve verified that at 250°, it reports valid temperatures on the attached LCD Plug w/ display.

The other plug you see in the lower left is a Blink Plug, with two pushbuttons and two LEDs.

Let’s see if this time around we can get the whole thing going properly!

Sending data TO remote nodes

In Software on Oct 31, 2010 at 00:01

Yesterday’s post described an easy way to get some data from remote battery-powered nodes to a central node. This is the most common scenario for a WSN, i.e. when reading sensors scattered around the house, for example.

Sometimes, you need more reliability, in which case the remote node can request an “ACK” and wait (briefly) until that is received. If something went wrong, the remote node can then retry a little later. The key of ACKs is that you know for sure that your data packet has been picked up.

But what if you want to send data from the central node TO a remote node?

There are a couple of hurdles to take. First of all, remote nodes running on batteries cannot continuously listen for incoming requests – the RFM12B receiver draws more than the ATmega at full power, it would drain the battery within a few days. There is simply no way a remote node can be responsive 100% of the time.

One solution is to agree on specific times, so that both sides know when communication is possible. Even just listening 5 ms every 500 ms would create a fairly responsive setup, and still take only 1% of the battery as compared to the always-on approach.

But this TDMA-like approach requires all parties to be (and remain!) in sync, i.e. they all need to have pretty accurate clocks. And you have to solve the initial sync when powered up as well as when reception fails for a prolonged period of time.

A much simpler mechanism is to let the remote take the initiative at all times: let it send out a “poll” packet every so often, so we can send an ACK packet with some payload data if the remote node needs to be signaled. There is a price: sending a packet takes even more power than listening for a packet, so battery consumption will be higher than with the previous option.

The next issue is how to generate those acks-with-payload. Until now, most uses of the RF12 driver required only packet reception or simple no-payload acks. This is built into RF12demo and works as follows:

Screen Shot 2010 10 30 at 20.17.37

That’s not quite good enough for sending out data to remote nodes, because the central JeeLink wouldn’t know what payload to include in the ACK.

The solution is the RF12demo’s “collect mode”, which is enabled by sending the “1c” command to RF12demo (you can disable it again with “0c”). What collect mode does, is to prevent automatic ACKs from being sent out to remote nodes requesting it. Instead, the task is delegated to the attached computer:

Screen Shot 2010 10 30 at 20.17.48

IOW, in collect mode, it becomes the PC/Mac’s task to send out an ACK (using the “s” command). This gives you complete control to send out whatever you want in the ACK. So with this setup, remote nodes can simply broadcast an empty “poll” packet using:

    rf12_sendStart(0, 0, 0);

… and then process the incoming ACK payload as input.

It’s a good first step, since it solves the problem of how to get data from a central node to a remote node. But it too has a price: the way ACKs are generated, you need to take the round-trip time from JeeLink to PC/Mac and back into account. At 57600 baud, that takes at least a few milliseconds. This means the remote node will have to wait longer for the reply ACK – with the RFM12B still in receive mode, i.e. drawing quite a bit of current!

You can’t win ’em all. This simple setup will probably work fine with remotes set to wait for the ACK using Sleepy::loseSometime(16). A more advanced setup will need more smarts in the JeeLink, so that it can send out the ACK right away – without the extra PC round-trip delay.

I’ll explore this approach further when I get to controlling remote nodes. But that will need more work – such as secure transmissions: once we start controlling stuff by wireless, we’ll need to look into authorization (who may control this node?), authentication (is this packet really from who it says it is?), and being replay-proof (can’t snoop the packet and re-send it later). These are all big topics!

More on this some other time…

Simple RF12 driver sends

In AVR, Software on Oct 30, 2010 at 00:01

(Whoops… this post got mis-scheduled – fixed now)

Yesterday’s post illustrates an approach I’ve recently discovered for using the RF12 driver in a very simple way. This works in one very clear-cut usage scenario: sending wireless packets out periodically (without ACK).

Here’s the basic idiom:

Screen Shot 2010 10 29 at 13.01.24

What this does is completely ignore any incoming data, it just waits for permission to send when it needs to, and then waits for the send to complete by specifying “2” as last arg to rf12_sendStart().

No tricky loops, no idle polling, everything in one place.

With a few lines of extra code, the RFM12B module can be kept off while not used – saving roughly 15 mA:

Screen Shot 2010 10 29 at 13.07.11

And with just a few more lines using the Sleepy class, you get a low-power version which uses microamps instead of milliamps of current 99% of the time:

Screen Shot 2010 10 29 at 13.09.03

Note the addition of the watchdog interrupt handler, which is required when calling Sleepy::loseSomeTime().

The loseSomeTime() call can only be used with time ranges of 16..65000 milliseconds, and is not as accurate as when running normally. It’s trivial to extend the time range, of course – let’s say you want to power down for 10 minutes:

Screen Shot 2010 10 29 at 13.11.16

Another point to keep in mind with sleep modes, is that it isn’t always easy to keep track of time and allow other interrupts to wake you up again. See this recent post for a discussion about this.

But for simple Wireless Sensor Network node scenarios, the above idioms will give you a very easy way to turn your sketches into low-power mode which can support months of operation on a single set of batteries.

Update – it looks like the above RF12_sleep() arguments are completely wrong. They should be:

  • rf12_sleep(N) turns the radio off with a wakeup timer enabled if N is 1..127
  • rf12_sleep(0) turns the radio off
  • rf12_sleep(-1) turns the radio back on

This list matches what is documented on the wiki page.

Meet the new Opto-coupler Plug

In Hardware on Oct 29, 2010 at 00:01

The plug barrage continues…

This time it’s an update of the flawed Opto-coupler Plug, which only worked properly on one channel (unless you patched it up). So here’s the new Opto-coupler Plug v2:

Dsc 2185

Wait! There’s more! It’s actually two plugs in one now:

Dsc 2186

(note: the solder jumpers need to be shorted out to use this as an output board)

Since there was enough room on this board, I decided to make it more versatile: it can now be used as dual Opto-coupled input (as before) or as dual Opto-coupled output plug. In the latter case, the JeeNode drives the IR LEDs and the output is a phototransistor which can be used as low-power (polarized) switch for some external device. The choice is determined by how the IC socket and Opto-coupler are hooked up.

The connectors are the same as before: detachable screw terminals, these are very convenient because you can prepare the wiring elsewhere and then plug / unplug / swap channels as needed.

I have no immediate use for these plugs right now, but of course I had to make sure that everything is working properly, so I hooked both of them up:

Dsc 2190

On the back you can see how things were connected together:

Dsc 2191

Here’s the updated opto_demo.pde test sketch for that – I decided to send the results by wireless for a change:

Screen Shot 2010 10 28 at 18.11.23

Sample output on my central JeeLink:

Opto Output

Yippie – looks like it’s working exactly as intended! Note the inverted signals, BTW.

Docs and shop have been updated for this new plug version. If you have version 1, please let me know and I’ll send out an updated board to you.

Meet the Current Source Plug

In Hardware on Oct 28, 2010 at 00:01

Here’s another new plug, firmly in the realm of home automation: the Current Source Plug drives two independent channels of Power LEDs with either 350 mA or 700 mA current:

Dsc 2183

As you can see, this plug was a very tight fit. These are based on high-efficiency AP8803 switching power supply chips, which also explains the two hefty inductors on the board. The 2 I/O pins are used to control both channels, and can use PWM to dim the LEDs.

The connector on the bottom is for the LED power supply (sorry for the tight fit!), and can be 8..30V. According to the specs, you can have up to 5 power LEDs in series at 30V, so the highest power this plug can theoretically switch is 5x 3W-LEDs @ 700 mA per channel!

There are some thermal limits though, due to the high amount of power involved in this small board. It is best to keep the voltage differential between what the LED needs and the input voltage fairly low. The two 3.7V LEDs I tried worked fine at 6..12V, but the board started heating up quickly with more than 12V (at full power).

Here’s the test setup I used:

Dsc 2182

The big LED is set to 700 mA, the small one to 350 mA – for a total of 1050 mA output. The nice part is the efficiency of this thing: the board draws less than 1050 mA due to the “buck” switching design. I measured roughly 960 mA @ 6V and 490 mA at 12V. At 18V it heated up a lot, I did not dare take it any higher. The main use I see for this board is two channels, each with 1 or 2 power LEDs in series, driven from a 12V supply.

At full power, the board temperature rose about 40°C above ambient after an hour, i.e. roughly 60..70°C. Hot to the touch, but not scorching hot. When dimmed, temperatures immediately went down. Note that the LED lights themselves were hotter than the board. Power LEDs need cooling!

For PWM dimming up to 500 Hz, just use the I/O pins. I haven’t tried it yet, but this could be done with the same rgbRemote.pde sketch as used for the MOSFET plugs.

The documentation and shop have been updated with this new plug.

More goodies coming, stay tuned…

Meet the Bridge Board

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

As mentioned not so long ago on this weblog, I’ve been doodling with some ideas to simplify using a JeeNode alongside a solderless breadboard. So – tada! – here’s the new Bridge Board:

Dsc 2167

As the name says, it acts as a bridge between a JeeNode (also USB or SMD variants) and a breadboard. All the I/O and power pins in one row, labeled for easy reference (including Arduino pin numbers), with two pins sticking into the power rail for ground and +3.3V. The JeeNode goes underneath, component-side up, with the radio on the right-hand side.

Two LEDs and a push button are also brought out, available for general-purpose use.

In the most basic form, the Bridge Board has just 4 6-pin male haders to push into the JeeNode ports, and 29 (+ 2 power-rail) pins to push into a medium or large size breadboard.

The generality of this setup increases if you hook up more headers between the JeeNode and the Bridge Board. With the SPI/ISP connector included, you get the ability to hook it up to an Ether Card, for example:

Dsc 2165

The reason this works, is that the 20 pins on the right are compatible with a Carrier Board – with the “BTN” and “LED2” pins extra. Note that with an Ether Card hooked up, all four ports (i.e. 8 DIO/AIO pins) are still fully available for your own use.

If you connect the 8-pin PSIX header on a JeeNode v5 (or both PSI and SPI/ISP on the other variants), plus a 0.1 µF capacitor, then the FTDI header on the left side can be used. This is paricularly useful for the JeeSMD, which doesn’t have an FTDI connector of its own.

Some I/O signals are brought out on more than 1 pin on the breadboard: DIO2/AIO2 and DIO3/AIO3. This maintains compatibility with the Carrier Board and also means that Port 2 is available on the breadboard in the standard port header layout: PWR, DIO, GND, +3V, AIO, IRQ if you want to insert any of the Jee Plugs.

Another way to combine plugs with the breadboard is to use stacking headers, so that the 4 ports can be re-used on the top of the Bridge Board. See the setup I plugged into the lower left:

Dsc 2166

Evidently, I had to make sure that all the I/O pins work properly, so I pre-loaded the SMDdemo.pde sketch onto a JeeNode and hooked up lots of LEDs:

Dsc 2161

Yeay – it works!

(note how the push-button has been turned into a reset button – this requires either the SPI/ISP or the PSIX headers to be hooked up)

I expect this new setup to be very convenient for all the endless experimentation going on here at Jee Labs. I’ll be updating the documentation site and shop shortly to reflect this addition to the Jee product line-up. I’ll also be adding 6- and 8-pin stacking header 10-packs.

Long live the breadboard!

Meet the Heading Board

In Hardware, Software on Oct 26, 2010 at 00:01

Here’s another plug which didn’t work initially, but as always it was a simple mistake in the software (and a not-so-clear datasheet) which prevented me from using this thing:

Dsc 2157

The Heading Board is based on a somewhat unusual HDPM01 combination sensor by HopeRF, containing a 2-axis compass / magnetometer and a … temperature + pressure sensor. My interest in this thing was the compass, which is relatively low-cost compared to most other options out there.

There’s now a HeadingBoard class in the Ports library to make this thing sing. Note that it’s called a “board” and not a “plug” because it requires two ports and sits as a mini-board on top of a JeeNode (same as the Room Board):

Screen Shot 2010 10 24 at 17.39.20

This board is a somewhat awkward match for the ports concept, because it needs a 32 KHz clock to function. I’ve hooked that up to the IRQ pin, which is reprogrammed by HeadingBoard::begin() to generate that clock using Timer 2, so you may have to jump through some hoops to use this if other ports use the IRQ pin for a different purpose. A more general approach would be to generate the required 32 KHz on-board with an NE555, as is done in an upcoming Infrared Plug – but that requires extra board space (or components on both sides of the pcb).

Here is the “heading_demo.pde” sketch, now added to the Ports library as example:

Screen Shot 2010 10 24 at 17.40.20

Sample output:

Screen Shot 2010 10 24 at 17.17.02

I haven’t figured out the conversion from X-/Y-axis values to compass heading yet. There is some sensitivity to how the board is positioned horizontally – this could be compensated by detecting the angular position using a Gravity Plug. But as you can see, there is a clear variation in readings as I turned the JeeNode + Heading Board around the Z axis.

So if you’re into robots: a Heading Board plus a Gravity Plug is all you need to determine your absolute orientation in all the 3 axes in space, i.e. X, Y, and Z.

Onwards!

PS. Here’s a crazy idea: we could use the Heading Board to create a door-open sensor. Simply attach this thing to a door, and track the Z-axis orientation!

Meet the Proximity Plug

In Hardware, Software on Oct 25, 2010 at 00:01

The Proximity Plug was created a while back, but at the time I couldn’t get the chip to respond properly. Turns out that this was just some silly mistake in the code, so now all is well and ready for use:

DSC_1267.jpg

This plug uses an MPR084 to support up to 8 capacitive touch sensors. These can be created in any shape you like, using some conductive board, film, or tape. There’s a solder jumper to set one of two I2C addresses, so up to 16 sensors can be hooked up to a single port.

Here’s a little test setup:

Dsc 2154

Capacitive sensing can be fairly tricky to get right – the sensors may respond slightly differently, cross-talk between each sensor, electromagnetic noise pick-up, etc. But this chip does a lot of the work for us.

There are many configurations settings, and I’ve only started to scratch the surface so far. The current setup is configured to only report a single touch at a time, and does auto-calibration on startup. I’m still seeing some cases where things lock up and may have to be reset (in software), so the interface class for this thing is very basic for now – simply giving acces to the individual registers from I2C.

Screen Shot 2010 10 24 at 13.01.33

I’ve added a “proximity_demo.pde” sketch to the Ports library to demonstrate the use of this plug:

Screen Shot 2010 10 24 at 13.10.36

It will print a message whenever a “key-press” is detected. The commented-out code prints out the following ID string extracted from the chip:

    #reescale,PN:MPR084,QUAL:EXTERNAL,VER:1_0_0

Note that the MPR084 chip wants a 100 KHz I2C bus.

One thing I’d like to try with this thing, is to create some input buttons with it using the Carrier Board box. It would be nice if the sensors can be made sensitive enough to reliably work with a bit of copper on the inside of the box, then you wouldn’t even have to drill holes or make any cutouts to be able to control what’s inside. Otherwise, perhaps a slit for adhesive / conductive copper tape, covered up with plastic foil?

More detective work needed…

Parsing input commands

In Software on Oct 24, 2010 at 00:01

I often need some way to get a bit of data and a few commands into an Arduino-type sketch from the serial port. Trivial but tedious stuff if you need to write the code for it, each time again.

Trouble is, the ATmega has very limited RAM space and string processing capabilities, so writing a super duper fancy string input parser is too wasteful of resources to be practical, in most cases.

In the RF12demo sketch, I used a very simple postfix notation, which lets you enter some bytes of data and a one-letter command. The syntax is:

<arg1>,<arg2>,... <cmd-char>

It works fairly well, but arguments are limited to single bytes and have to be entered as decimal values.

Here’s another attempt to simplify this sort of task. I’ve added an “InputParser” class to the Ports library, which takes care of basic parsing, while remaining flexible enough to allow use in different sketches. It supports input of bytes, ints, and longs in decimal or hex format, as well as short strings. It’s not JeeNode specific, and should work with any Arduino.

Here is the InpurtParser class definition (minor details omitted):

Screen Shot 2010 10 23 at 20.11.12

Note that many choices were made to keep the code overhead low, while allowing enough flexibility to input data in different ways. As a consquence, the syntax is a bit strict and limited:

  • args are separated by spaces or commas, with the command code typed last
  • plain numbers are interpreted as bytes: 123
  • negative values can be entered using a trailing minus sign: 123-
  • append a decimal point to enter 2-byte ints: 12345.
  • append a colon to enter as 4-byte longs: 123456789:
  • prefix with a dollar sign to use hex mode: $1A / $1A2B. / $123456:
  • enter strings between double quotes: “this is a string”

I’ve added a “parser_demo.pde” sketch to illustrate its use:

Screen Shot 2010 10 23 at 20.13.05

When initialized, the parser must be given a buffer it can use to collect all argument data and input strings in. In this simple example, a 50-byte buffer is allocated dynamically.

Each command is a separate function, which pulls its variables from the parser object when called. The parser is initialized with a table of these commands, listing the command code and minimum number of expected bytes, along with the function to call.

Here are some examples of input:

h
?
v
1234. v
"Hello, there!" s
123456789: "abc" $100. "defgh" 12345. c

Here is the output, corresponding to each of the above commands:

[parser_demo]
Hello!
Known commands: h v l s c
Not enough data, need 2 bytes
value = 1234
string = <Hello, there!>
complex = 123456789 <abc> 256 <defgh> 12345

Note that you get a list of known commands when entering a bad command (or “?”).

That last example illustrates how to pass a variety of input argument types to a command. The code for this is:

Screen Shot 2010 10 23 at 20.25.51

This demo requires about 5 Kb, including some 850 bytes for the command functions. 600 bytes for malloc (this is optional), and 600 bytes for the Serial class. The parser itself uses some 1.7 Kb.

By default, the parser object is attached to the “Serial” stream, but it can be hooked up to something else if necessary, such as an LCD or Ethernet.

Enjoy!

3D printing again

In Hardware on Oct 23, 2010 at 00:01

Finally found some time to fix the clogged extruder Mk4 I had on the CupCake. A new heater + extrusion head did the trick. Well, almost… watch the leaked blob of ABS on top of the extruder heat barrier:

Dsc 2138

As a result, the first part I printed did not contain enough material, and ended up too fragile for actual use. That’s part of a micro-lathe I’m printing for someone else, btw.

So I disassembled the extruder again, and replaced the PTFE rod with a new black one:

Dsc 2141

Yippie, now it’s working again. I’ve also upgraded to a heated build platform, which works great – no warping and the parts come off real easy, with raft and all:

Dsc 2148

Here’s a component from the Wade extruder which I’ll need for the Mendel:

Dsc 2151

Alas, not all is well yet. This was supposed to be the other half of that gearwheel pair:

Dsc 2150

Hmm, looks more like a cupcake to me…

The other nasty problem is that the main body of the Wade extruder I’m trying to build is too large for the CupCake. I can’t print it! Now I’ll either have to buy a complete extruder for the Mendel or find some other extruder which works with it. So as far as the next-generation “Mendel” is concerned, I still need to assemble the electronics and find some good extruder for it. Drat, it’s always those last 20% that bite…

Wireless mousetrap

In Hardware on Oct 22, 2010 at 00:01

Mathias Johansson recently sent me a description of his project which is just too neat to pass up. So here goes – photos by him and most of the text is also adapted from what he told me in a few emails.

I’ll let Mathias introduce his project:

It is late autumn here in Sweden and the mice starts to search for a winter home. They do normally stay outside modern constructions but I have a croft that is over 100 years old and they tend to like my attic. Mice are pretty cute, and I wish them no harm, but they damage my ceilings! Therefore I have to catch them in traps and transport them deep into the forest and release them near the brink of a stream.

Some properties of each of the three traps built so far:

  • Does not harm the mouse
  • Immediately reports which trap is closed on a webpage
  • Disables itself if the alarm system is turned on for longer periods of absence

Here’s the mousetrap, ready to go:

Mouse Trap

With a guest…

Mouse in Trap

And here the status page indicating which traps have been sprung:

Homepage

The schematic was implemented on what looks like a mini breadboard, here’s the Fritzing version of it:

Musetrap v0 1 bb

The infrared receiver was salvaged from a BoeBot and is used to detect the presence of a guest to spring the trap. Note that by the time it detects something, the tail of the mouse will be mostly inside the trap, so this is a gentle as it gets – well, if you’re a mouse…

Mathias concludes with:

Feel free to publish the pictures (and text) in your “success story” forum or elsewhere on your web-page if you think they are of interest to others or inspire new uses for the JeeNode.

Thanks, Mathias, for sharing your ideas and your delightful rodent-friendly project!

Reporting motion

In AVR, Software on Oct 21, 2010 at 00:01

Yesterday’s post presented a new sketch which did everything the old sketch did, except report motion. The reason was that the requirements for reporting motion are quite different from the rest: it has to be reported right away – using ACKs, time-outs, and retries to make sure this message is properly received.

The latest version of roomNode.pde now adds the missing logic. And it does indeed get a lot messier – doubling the total number of lines in the source code.

Here is the new loop() code:

Screen Shot 2010 10 19 at 22.37.41

The key change is that there is now a check for “pir.triggered()” which will be called outside all normal scheduling actions. Note that this code is still using scheduler.pollWaiting(), so the code is still spending most of its time in power-down mode.

Except that now, we’re also setting up a pin-change interrupt for the PIR sensor:

Screen Shot 2010 10 19 at 22.40.16

The new code to handle these PIR triggers is as follows:

Screen Shot 2010 10 19 at 22.42.14

So instead of folding this complicated case into the rest of the code, when a PIR trigger goes off, we now simply send that packet out and wait for the ACK, repeating it a few times if necessary. The normal measurement and reporting tasks are not affected by any of this, other than that the measurement scheduling is postponed a bit to avoid triggering another report right away.

The new PIR motion sensor turns out to be quite convenient, because it has an on-board trimpot to set the re-trigger timeout. As long as motion is detected more often than this threshold, the PIR output will remain 1, so there is no need to play tricks in software to avoid constant triggers. We’ll get one pin change for the start of motion, and another one when no motion has been detected for a preset amount of time.

Having said that, I’ve implemented a similar re-triggerable one-shot mechanism in software anyway, because my older nodes use the ELV PIR sensor, which send out a pulse for each motion trigger. So all ON pulses within 30 seconds of each other get coalesced into one.

To illustrate that the system is still doing almost nothing most of the time, I added a debug mode which prints a “.” on each iteration of loop(). In normal Arduino sketches, this would cause an incessant stream of characters to be printed out, but in this sketch there are just a few:

Screen Shot 2010 10 19 at 22.12.35

Motion detection now works more or less independently of the normal measure / report tasks.

There are still some rough edges, but I expect this new code to perform considerably better in terms of battery lifetime already. The dreaded battery rundown problem when the central node is not reachable should be gone. All that remains are a few attempts (I’ve set it to 5) whenever the PIR sensor turns on or off. In both cases the ACK has to be received within 10 milliseconds – after that the sketch enters power-down mode again.

The new code should also make it much easier to add sensor types (switches, hall-effect, 1-wire, barometer).

FWIW, this code needs 8238 bytes (without serial I/O), so it’ll still easily fit in an ATmega168. Without SHT11 (which uses floating point) that drops to 5682 bytes, including the RF12 driver. How’s that for a WSN node!

New roomNode code

In AVR, Software on Oct 20, 2010 at 00:01

It’s time to start putting the pieces together now: sensor readout, scheduling of measurements and packet sends, and low-power mode. Looks like the code in the Ports and RF12 libraries is now making this easier than ever.

There’s a new roomNode.pde sketch which illustrates the whole shebang. At 145 lines, it’s a bit too long to include here in full, but I’ll show some of the interesting pieces.

Note that this version implements everything except motion reporting, which is a bit more complex.

Following the good ol’ top-down tradition, first the setup() and loop() code:

Screen Shot 2010 10 19 at 14.06.12

It starts the measurement loop, which then keeps itself running periodically. The report activity is started every once in a while. Note also the “now” variable, which will make it easier to use 2-byte ints in the logic which will decide later about when to report motion, etc.

The measurement code depends completely on what sensors are supported, and is pretty straightforward:

Screen Shot 2010 10 19 at 14.10.36

No surprises, we just have to be careful to do things in an energy-efficient manner. All the readings end up in the “payload” struct.

And here’s the reporting code:

Screen Shot 2010 10 19 at 14.14.24

Here’s some sample output on the serial port:

Screen Shot 2010 10 19 at 14.18.17

I still need to add the logic for motion detection, but with the new scheduling capabiltities, I expect that extra complexity to stay within a small portion of the code – unlike the current rooms.pde sketch, where everything seems to affect everything else.

The best part? My multimeter stays mostly under 60 µa, i.e. the low-power logic is automatically kicking in!

Room Node – next steps

In AVR, Software on Oct 19, 2010 at 00:01

First of all: thanks to everyone who commented on the recent posts, both online and by direct email. Fantastic feedback, lots of ideas, and several valuable corrections.

In yesterday’s post, I agonized about how hard it is to track time in some sort of reasonably continuous way when most of it is spent in comatose state. Fortunately, a Room Node won’t need that awareness very much. I just wanted to show how things get complex in terms of watchdogs running-but-not-yet-expired, and multiple interrupt sources.

For the next version of the rooms.pde sketch, my plan of attack is to simply ignore the issue. The watchdog will be used for guaranteed wake-up, while PIR motion detection and radio reception interrupts will simply cause the millis() clock to lose time, occasionally.

For ACKs, I’m going to start simple and wait for up to 2 milliseconds in idle mode, before resuming lower-power options again. One interesting suggestion was to slow down the clock while doing so (through the system clock pre-scaler), but that has to be done with care because a slower-running ATmega will also respond more slowly to RF12 driver interrupts – and there is not that much slack there.

Here’s the updated Scheduler class, now included in the Ports library:

Screen Shot 2010 10 18 at 22.54.27

Only a minor extension on the API side: by using pollWaiting() instead of poll(), you can tell the system to enter low-power mode until the next scheduled task. If another interrupt pre-empts this wait cycle, then it’ll break out of power-down mode and go through the loop and re-enter the low-power state the next time around.

The other change I’m currently testing is that a few Scheduler functions can be called from interrupt code, so this provides a way for interrupt code to safely schedule, resume, or cancel a task “via the main thread”.

This is the tiny change needed to make the schedule.pde demo energy efficient:

Screen Shot 2010 10 18 at 23.01.24

However, because it now uses the watchdog, you also need to add the following boilerplate to the sketch:

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

The demo now draws 25 µA when I remove the LEDs.

So here’s the deal: if you can manage to write all your code is such a way that it never calls delay() – or delayMicroseconds() with large values – and instead uses this Scheduler-with-tasks approach, then you’ll get a fairly low power usage almost for free… i.e. without having to do anything else! (just don’t forget to turn the radio on and off as needed)

The code has been checked into subversion, and is also available as ZIP archive – see the Ports info.

Update – more changes checked in to better handle watchdog vs other interrupts.

Tracking time in your sleep

In AVR, Software on Oct 18, 2010 at 00:01

No, this isn’t a story about bio-rhythms :)

One of the challenges I’ll be up against with Room Nodes is how to keep track of time. The fact is that an ATmega is extraordinarily power efficient when turned off, and with it a JeeNode – under a few microamps if you get all the little details right. That leads to battery lifetimes which are essentially only determined by self-discharge!

But there are two problems with power off: 1) you need to be 100% sure that some external event will pull the ATmega out of this comatose state again, and 2) you can completely lose track of time.

Wireless packets are of no use for power-down mode: the RFM12B consumes many milliamps when turned on to receive packets. So you can’t leave the radio on and expect some external packets to tell you what time it is.

Meet the watchdog…

Fortunately, the ATmega has a watchdog, which runs on an internal oscillator. It isn’t quite as accurate, but it’ll let you wake up after 16 ms, 32ms, … up to 8 seconds. Accuracy isn’t such a big deal for Room Nodes: I don’t really need to know the temperature on that strict a schedule. Once every 4 .. 6 minutes is fine, who cares…

There’s a Sleepy class in the Ports library, which manages the watchdog. It can be used to “lose time” in a decently accurate way, and will use the slowest watchdog settings it can to get it out of power-down mode at just about the right time. To not disrupt too many activities, the “millis()” timer is then adjusted as if the clock had been running constantly. Great, works pretty well.

It’s not enough, though.

As planned for the next implementation, a Room Node needs to sleep one minute between wakeups to readout some sensors, but it also needs to wake up right away if the motion sensor triggers.

One solution would be to wake up every 100 ms or so, and check the PIR motion sensor to see whether it changes. Not perfect, but a 0.1s delay is not the end of the world. What’s worse though is that this node will now wake up 14,400 times per day, just to check a pin which occasionally might change. This sort of polling is bound to waste some power.

Meet the pin-change interrupt…

This is where pin-change interrupts come in, They allow going into full power-down, and then getting woken up by a change on any of a specified set of pins. Which is perfect, right?

Eh… not so fast:

Screen Shot 2010 10 17 at 22.05.30

Q: What time is it when the pin-change occurred?

A: No idea. Somewhere between the last watchdog and the one which will come next?

IOW, the trouble with the watchdog is that you still don’t really track time. You just know (approximately) what time it is when the watchdog fires again.

If the watchdog fires say every 8 seconds, then all we know at the time of a pin-change interrupt, is that we’re somewhere inside that 8s cycle.

We can only get back on track by waiting for that next watchdog again (and what if the pin change fires a second time?). In the mean time, our best bet is to assume the pin change happened at the very start of the watchdog cycle. That way we only need to move the clock forward a little once the watchdog lets us deduce the correct moment. FYI: everything is better than adjusting a clock backwards (timers firing again, too fast, etc).

Now as I said before, I don’t really mind losing track of time to a certain extent. But if we’re using 8-second intervals to get from one important measurement time to the next, i.e. to implement a 1-minute readout interval, then we basically get an 8-second inaccuracy whenever the PIR motion detector triggers.

That’s tricky. Motion detection should be reported right away, with an ACK since it’s such an important event.

So we’re somehere inside that 8-second watchdog cycle, and now we want to efficiently go through a wireless packet send and an ACK cycle? How do you do that? You could set the watchdog to 16 ms and then start the receiver and power down. The reception of an ACK or the watchdog will get us back, right? This way we don’t spend too much time waiting for an ack with the receiver turned on, guzzling electrons.

The trouble is that the watchdog is not available at this point: we still want to let that original 8-second cycle complete to get our knowledge of time back. Remember that the watchdog was started to get us back out in 8 seconds, but that it got pre-empted by a pin-change.

Let me try an analogy: the watchdog is like throwing a ball straight up into the air and going to sleep, in the knowledge that the ball will hit us and wake us up a known amount of time from now. In itself a pretty neat trick to keep track of the passage of time, when you don’t have a clock. Well, maybe not for humans…

The scenario that messes this up is that something else woke us up before the ball came down. If we re-use that ball for something else, then we have lost our way to track time. If we let that ball bring us back into sync, fine, but then it’ll be unavailable for other timing tasks.

I can think of a couple solutions:

  • Dribble – never use the watchdog for very long periods of time. Keep waking up very frequently, then an occasional pin-change won’t throw us off by much.

  • Delegate – get back on track by asking for an ack which tells us what time it is. This relies on a central receiving node (which is always on anyway), to tell us how to adjust our clock again.

  • Fudge it – don’t use the watchdog timer, but go into idle mode to wait for the ack, and make that idle period as short as possible – perhaps 2 ms. IOW, the ACK has to reach us within 2 milliseconds, and we’re not dropping into complete powerdown during that time. We might even get really smart about this and require that the reply come back exactly 1 .. 2 ms after the send, and then turn off the radio for 1 ms, before turning it on for 1 ms. Sounds crazy, until you realize that 1 ms of radio time uses as much energy as 5 seconds of power down time – which adds up over a year! This is a bit like what TDMA does, BTW.

All three options look practical enough to consider. Dribbling uses slightly more power, but probably not that much. Delegation requires a central node which plays along and replies with an informative ack (but longer packets take longer to receive, oops!). Fudging it means the ATmega will be in idle mode a millisec or two, which is perhaps not that wasteful (I haven’t done the math on that yet).

So there you go. Low power stuff isn’t always trivial, once you start pushing for the real gains…

Scheduling multiple tasks

In Software on Oct 17, 2010 at 00:01

Since Room Nodes are going to become more sophisticated in terms of timing, I’m adding some support code to simplify my work later on. In most cases, I think it’s not a good idea to start generalizing too early, but this is a pretty common utility: scheduling multiple activities in parallel. No rocket science, and badly needed…

So here’s a little “Scheduler” class I’m going to add to the Ports library:

Screen Shot 2010 10 17 at 00.00.53

Nothing fancy. My main concern is to keep RAM usage low. So the idea is that you can have a fixed number of tasks, each one with (at most) one timer running. Timers can be started and cancelled at will. The term “task” is used very loosely here: anything that needs to have an independent timer mechanism can be treated as a separate task. This is not multi-tasking or threading – just a way to manage activities which need to be performed some time into the future.

Unlike the Millitimer class, which works for durations up to 60000 milliseconds, the Scheduler class works in tenths of seconds, and supports durations from 0 to 6000 seconds, i.e. over an hour and a half. A zero duration means: run the associated task as soon as possible.

Probably best to show this in action with an example:

Screen Shot 2010 10 16 at 23.56.53

The way to use the scheduler, is to define an enum with all the tasks there can be, plus a “TASK_LIMIT” value, which is in fact simply the number of tasks.

Then you declare a “Scheduler” instance, and give it that TASK_LIMIT value, so it can allocate the proper amount of memory (each task needs only 2 bytes).

The only remaining thing to do is call the “poll()” member and handle each task request in a big switch statement.

The demo will blink two LEDs at different rates, the classical (and simplest) example of doing two different things at the same time. Eh… almost the same time.

I’m still putting the finishing touches on this code and making sure that this will play nicely with low-power and power-down modes, so it hasn’t been checked in yet – it should all be ready in at most a day or two. At which time this will become part of the Ports library, along with the above “schedule.pde” example sketch.

Modular nodes, revisited

In Software on Oct 16, 2010 at 00:01

As pointed out in the comments yesterday, “nodes” in a WSN should to be more parametrized. With ports, it’s very easy to mix and match different sensors – creating nodes which are not all the same should be equally easy.

I’ve touched on a related topic before in a post titled Modular nodes.

Ideally, you want to write interface code for say a PIR motion sensor once, and then re-use it in different nodes. Same for an SHT11 temperature/humidity sensor, an IR send/receive sensor, a barometer, door switches, an OOK receiver, and so on – the list is bound to grow considerably over time.

Even “more ideally” (heh), you probably would like someone else to already have written that interface code, so you can just fill in the parameters and incorporate it into your own room-or-other node.

In fact, the whole (modular!) Plugs & Ports concept of JeeNodes is yearning for this type of modularity to be carried through to the software.

To achieve such modularity all the way through, several questions need to be answered:

  • are these interface code “snippets” always very small and self-contained, or do they need additional C/C++ source files?
  • can interfaces depend on other interfaces / is a class hierarchy the best way to modularize such dependencies and derivations?
  • can we have multiple instances of the same interface in a single node? (answer: yes, for example multiple door-open sensors, attached to different I/O pins)
  • how do we deal with a mix of interfaces which use different timing periods for readout?
  • how do we compose packets to send, if the information types vary?

One way to implement this modularity, is what I’ve been doing in the Ports library until now: define and implement C++ classes for each interface, and then create (static) instances of each interface needed in a particular node.

This is an extract of the Ports.h library header file:

Screen Shot 2010 10 15 at 21.54.25

It works – and I think it’s a decent start – but it doesn’t go far enough:

  • Many configuration parameters are variables (and data members inside C++ objects), even though they are essentially contant (the port number, an I2C device ID, I/O pin choices, etc). This eats up scarce RAM space, and prevents the compiler from fully optimizing the code. The “heavy” solution to this is C++ templates, as I’ve written about in threeolderposts. Trouble is: C++ templates are “viral”, once you start on that path, everything tends to become a template. Not my idea of simplicity…

  • I want to figure out what a good set of reporting periods is, to minimize the number of packets sent, for example. This task comes back with every type of node, so having some automated tool to help with that effort would be useful.

  • There can be severe resource constraints in low-power nodes. I’d like to see what the RAM and EEPROM (and FLASH) usage is when choosing a specific mix of interfaces. I’d also like to find out whether the interrupts can co-exist and still service everything sufficiently quickly. And I’d like to get estimates for battery life. None of this is impossible, even if unnecessary for a first implementation.

  • Implementing pin-change interrupt handlers is not easy to fit into C++ as run-time mechanism, even though for any given interface mix it is very simple to generate the interrupt handler code for it.

  • The result of a choice of interfaces is not just a sketch – it also implies specific packet structures, as used for getting data across. And indirectly, it also means there has to be something node-specific at the central node (not necessarily in that receiving node, it could be code that runs on an attached PC).

  • If the number of interfaces grows considerably, and if more people were to start implementing such interfaces, then the management and versioning of all these interface definitions (code, data, docs) needs to be addressed.

What this points to IMO, is the need for a “configurator” or “wizard” type tool, which knows about a large number of interfaces, and which produces a sketch when given a bunch of configuration choices. An even more convenient tool would let me manage my entire collection of nodes, so I can make most configuration choices once, and then manage all node definitions together. It’d let me add and update interfaces and nodes as needed, over time:

Screen Shot 2010 10 15 at 22.30.14

What comes out is still a C/C++ coded sketch, since that’s what needs to be uploaded to the node.

What should also come out (not included in the above diagram), are one or more packet structure definitions, as well as the code (or data definitions) needed to decode those packets again.

With this approach, you can pick the hardware needed for a specific node, enter your choices into the configurator, and be done with it. Upload the sketch it generated, turn the node on, and launch the central server with the information it needs to understand the new incoming data packets. For other nodes, or to make changes, simply rinse and repeat…

I haven’t decided yet whether I’ll actually go for this. It’s fairly ambitious, even for a simple first implementation. But it sure would scratch an itch of mine…

Room Node redesign

In Software on Oct 15, 2010 at 00:00

Room nodes were one of the first reasons I came up with the JeeNode in the first place. It has all evolved a bit since then (and it will evolve further until there is a good enclosure):

Dsc 2134

It’s now time to start redesigning the software for Room Nodes. The main reason being that the code needs to take more advantage of all the low-power savings achievable with JeeNodes. Current battery lifetimes are 1..2 months, using 3x AA alkaline batteries. That’s not nearly good enough – I really do not want to go through the house replacing tons of batteries every month or so (even rechargable ones).

I can think of two reasons why the current rooms.pde sketch isn’t doing that well:

  1. The “easy transmission” mechanism does retries when no ACK is received – this is a good idea in general, but there is no exponential backoff mechanism in place in case the central node is off, mal-functioning, out of range, or if there is simply too much interference at times. What’s even worse is that the node sits there waiting for an ACK for many seconds, guzzling electricity like crazy with the RFM12B and the ATmega full on!

  2. The code sends out a fresh packet on each transition from the PIR motion detector. If the sensor is in a room where motion is very common, then new packets may get sent out far more often than necessary – and quickly drain the battery.

So the question is how to improve on this. One thing I’m going to do is side-step the rf12_easyPoll() etc. interface for the next Room Node implementation, and go back to rf12_recvDone() etc. Coding at this slightly lower level is more work, but also gives me substantially more control in return.

Next, some decisions need to be made about how often and when to send out packets, and when to work with acknowledgements. Here are some of my considerations for that – evidently not everyone will agree with this set of choices, but I think they are sufficiently general to work in many cases:

  • Temperature, humidity, and light levels need only be sent out once per five minutes. Perhaps averaging the values once a minute to smooth out measurement variations.

  • No need to use ACKs for this. Not knowing the exact temperature for the past hour is not the end of the world. The new logic can just send out readings once every five minutes, with the expectation that most of them will usually come in just fine.

  • The PIR motion sensor is a completely different matter: I’d like to be told when new motion is detected as quickly as possible, i.e. within less than a second.

  • Then again, once motion has been detected, I don’t really care too much about frequent vs. infrequent motion. Telling me once a minute whether any motion was detected in that past minute should be enough.

  • Once motion ceases to be detected for a minute, the system goes back into its highly responsive mode, i.e. the moment new motion is detected, I want to hear about it again, right away.

  • The system could send different packets for different triggers, but I don’t want to complicate things unnecessarily. My expectation is that in a room with no motion, there will be one packet going out every 5 minutes, with one “wasted” bit for the motion detector state. In a busy room, there will be a packet going out up to once a minute due to the motion detector firing all the time. The number of bytes saved is probably not worth the extra trouble of having to deal with different types of packets at the receiving end.

  • The last reason to send out packets, is when the battery voltage of the sensor node is getting low. This can be checked once a minute, along with the temp/humid/light cycle.

  • Changes in motion or battery level are important events. These should use the acknowledge mechanism to make sure the event gets to its destination even with occasional packet loss.

  • The mechanism for acks needs to be more sophisticated than it is now. The first big optimization is to only wait a few milliseconds for the ACK. If it doesn’t come in, go back to sleep, and try again a second later. That should by itself reduce the current worst-case current draw by two orders of magnitude.

  • Refinements such as exponential back-off would be nice, but I don’t expect them to make that much of a difference, in a home monitoring setup where all serious failures are likely to be noticed and resolved within a day.

  • Another refinement I don’t care too much about, is to adjust the 5-minute reporting interval depending on the measured light levels. Note that this does not apply to motion (which must always remain alert) – it’s just a way to reduce packet transmissions even further at times when very little happens anyway. I’m not sure it will increase battery life that much, though: brief packet transmissions are not the main power drain, the always-on PIR is the main determinant for battery life, as far as I can tell.

The highest packet frequency for this new approach is almost two packets per minute: motion is detected, then one minute later a packet comes in reporting that it is no longer being detected, and then immediately after that new motion is detected again.

So if you sit still in front of a Room Node, and move exactly once every 61 seconds, you’ll get extra brownie points and trigger twice as many packets as when you move around all the time. I’m willing to dismiss that scenario as being almost hypothetical :) – I can’t prove it, but my hunch is that this worst-case scenario will always exist, no matter what the algorithm is.

IR decoding with pin-change interrupts

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

Yesterday’s post described a new “InfraredPlug” class which handles the main task of decoding IR pulse timings. The “irq_recv.pde” example sketch presented there depended on constant polling to keep the process going, i.e. there has to be a line like this in loop():

    ir.poll();

Worse, the accuracy of the whole process depends on calling this really often, i.e. at least every 100 µs or so. This is necessary to be able to time the pulse widths sufficiently accurately.

Can’t we do better?

Sure we can. The trick is to use interrupts instead of polling. Since I was anticipating support for pin-change interrupts, I already designed the class API for it. And because of that, the changes needed to switch to an interrupt-driven sketch are surprisingly small.

I’ve added a new irq_send_irq.pde sketch to the Ports library, which illustrates this.

The differences between using polling mode and pin-change interrupts in the code are as follows. First of all, we need to add an interrupt handler:

Screen Shot 2010 10 13 at 00.26.10

Second, we need to enable those interrupts on AIO2, i.e. analog pin 1:

Screen Shot 2010 10 13 at 00.26.44

And lastly, we can now get rid of that nasty poll() call in the loop:

Screen Shot 2010 10 13 at 00.27.51

That’s all there is to it. Does it still work? Of course:

Screen Shot 2010 10 13 at 00.29.16

Note: I made some small changes in the InfraredPlug implementation to tolerate interrupts and avoid race conditions.

This all seems like an insignificant change, but keep in mind that this completely changes the real-time requirements: instead of having to poll several thousands of times per second to avoid missing pulses or measuring them incorrectly, we can now check for results whenever we feel like it. Waiting too long would still miss data packets of course, but this means our code can now continue to do other lengthy things (or go into a low-power mode). Checking for incoming packets a few times a second is sufficient (IR remotes send out a packet every 100 ms or so while a button is pressed).

So the IR decoder now has the same background behavior as the RF12 driver: you don’t need to poll it in real-time, you just need to check once in a while to see whether a new packet has been received. Best of all, perhaps, is that you can continue to use calls to delay() even though they make the main loop less responsive.

There is another side effect of this change: if your code includes a call to “ir.send()”, then the receiver will see your own transmission, and report it as an incoming packet as well. Which shows that it’s running in the background. This could even be used for collision detection if you want to build a fancy IR wireless network on top of all this.

So there you go: an improved version of the InfraredPlug class, which lets you use either explicit polling or pin-change interrupts. The choice is yours…

Decoding IR pulses

In Hardware, Software on Oct 13, 2010 at 00:01

After the last few posts, it must come as no surprise that I’ve been working on a new Infrared Plug – so now it’s time to start exploring the software side of things. Note that IR reception doesn’t really need a plug at all, I simply inserted a TSOP32238 IR decoder chip into port 2 while debugging the code:

Dsc 2129

Note: I’ll be using the TSOP34838 for the planned Infrared Plug. It only differs in pinout (!) – and both can be used at 3.3V, which is essential.

In preparation of that new plug (atoms need time!), I’ve added a new “InfraredPlug” class to the Ports library, with the following interface:

Screen Shot 2010 10 12 at 17.30.37

This allows receiving IR codes on the AIO pin of any port, as well as sending out IR bit patterns on the DIO pin.

There’s a new ir_recv.pde sketch to demonstrate reception of arbitrary IR signals:

Screen Shot 2010 10 12 at 17.33.59

Here is some sample output, using two different Apple remotes which send using the NEC protocol, as described on this excellent site by San Bergmans:

Screen Shot 2010 10 12 at 16.49.22

You’re looking at a decoded bit stream – some minor processing will be needed to extract the actual data bits from each packet. This was done to make the decoder as flexible as possible – allowing it to handle all sorts of remotes.

The basic idea is that you set up the InfraredPlug instance with “slot” and “gap” parameters. The slot value (1..255) specifies the granularity of the time slots used by the decoder (in units of 4 µs). The default slot value is 140, this corresponds to time slots which are 560 µs wide. De gap value tells the driver when to consider a data packet as being complete (in units of 256 µs). The default gap value is 80, i.e. treat a series of pulses as one packet once 20 ms have elapsed after the last pulse.

The values can be changed with the “configure()” method. In fact, ir_demo will change the slot value when it receives an integer followed by lowercase “s” on the serial port (not echoed). The default setting on startup is “140s”. For RC5 codes, use “222s”, for RC6 “111s”, and for Nokia remotes “125s”, to name a few.

Each time a packet has been received, ir_demo will send the decoded data to the serial port. The data consists of a series of hex digits, each representing one 4-bit nibble of data, as returned by the InfraredPlug class:

  • 0..9 = 1..10 slots
  • A = 10 = 11 or 12 slots
  • B = 11 = 13 or 14 slots
  • C = 12 = 15 or 16 slots
  • D = 13 = 17 or 18 slots
  • E = 14 = 19 or 20 slots
  • F = 15 = 21 or more slots

The nibbles at even positions correspond to pulse ON widths, the nibbles at odd positions are pulse OFF widths – both as a multiple of the configured slot time, with the above adjustment of longer pulses applied.

The “send()” method uses a different format. You give it a bit pattern and the number of bits to send. Each bit represents an ON or OFF signal value. The duration of each bit is the same slot value as used in the receiver.

That’s it. A simple design which should be able to support lots of different appliances and remotes.

JeeMon device discovery

In Software on Oct 12, 2010 at 00:01

Ok, I must admit that JeeMon has been a bit too ambitious in its original inception. It works quite nicely here at Jee Labs, but there are just too many hoops you have to jump through to make it happen on your own.

I’ll first explain why things are the way they are, and how that is supposed to work, and then I’ll present a different setup for the OOK Scope which jettisons all that machinery and lets you use the OOK Scope with nothing but a single source file and JeeMon.

The idea behind the “Serial” and “JeeSketch” rigs (code modules) in JeeMon, is that it should be possible to respond to changes in interfaces dynamically. So there’s a way to scan for USB interfaces periodically:

Serial periodicScan <cmd>

This will compare the list of USB devices it sees with the list it saw last time (once every 5 seconds by default). And then call the specified <cmd> whenever an interface is added or has gone away. Only FTDI interfaces are detected, by the way.

The next step is to decide what to do when a new USB device is attached. I’ve been using a convention for some time now, whereby every sketch starts by sending out its own name, with optional version and configuration details. For example, RF12demo will send out a string like this to the USB connection when it starts up:

[RF12demo.6] A i1 g5 @ 868 MHz

The trick is to wait for such a string when JeeMon detects the device and opens it. This is handled by the “JeeSketch” rig. Once the sketch type is known, JeeMon then tries to locate a “host.tcl” driver for it. It does this by looking in a directory, as configured at start up. I’ve been placing all my drivers in a directory called “sketches”, so my startup includes the following line:

JeeSketch register ./sketches

When RF12demo connects, JeeMon checks whether “./sketches/RF12demo/host.tcl” exists, and runs it.

Similarly, when plugging in a JeeNode running the OOK Scope sketch, it announces itself as:

[ookScope]

The script “./sketches/ookScope/host.tcl” then gets started, it creates a GUI window, takes over the communication link to process all incoming (binary) data bytes, and does its pulse histogram thing.

So far so good. It’s a nicely modular mechanism. I can add a new sketch, i.e. a “blah.pde” file for use in a JeeNode, and add a matching “host.tcl” script alongside to deal with the communication in any way it likes. Then, all I need to do is plug the device in and everything starts up. With a bit of care, everything is also shut down and cleaned up again when the device is removed.

Unfortunately, that’s not the end of the story. One of the important devices I want to support is a JeeNode or JeeLink running RF12demo. But how can JeeMon deal with remote nodes? After all, all they do is send packets to the central device. Each of these nodes will be running a sketch, and not all of them are necessarily the same. So we either need some sort of auto-discovery or some central configuration file. For a first implementation, I decided to use a configuration file to try and keep things, eh, simple. Which is why my startup code also contains these two commands:

set appDir [file dir [dict get [info frame 0] file]]
Config setup $appDir/config.txt

That’s a tricky way of making sure that the “config.txt” file will be picked up from the same directory as the source code, i.e. the “application.tcl” file.

I’ll refrain from describing the config.txt file in full detail. Let me just include an example which I’ve been using around here:


Screen Shot 2010 10 11 at 22.52.15


As with any such type of “registry”, you can see lots of little config details, for use in different modules and parts of the code. Even some obsolete stuff, in fact.

Does it work? Oh, sure, it works great and it’s very easy to extend for new modules and usage scenarios. Even node discovery works nicely, both coming on-line and dropping off-line, as seen in the voltmeter demo.

But there’s a problem with what I’ve described so far…

… there’s too much rope – to hang yourself. It’s brittle, it needs lots of documentation to use this stuff (unless you’re willing to dive into the JeeMon Tcl code), and it’s just too much trouble if you want to do something simple with JeeMon, like run the OOK Scope and nothing else. The entry curve is way too steep.

I can’t say I’ve figured out an alternative. There is a lot of ground to cover, and it is fairly hard to implement a system which dynamically adapts to interfaces getting plugged in and nodes coming (wirelessly) online.

But at the end of the day, all that extra bagage is unnecessary for simple cases.

Fortunately, JeeMon is flexible enough to adapt in any way I want. I don’t have to use any of the above machinery. So here’s the OOK Scope logic as a single “application.tcl” file. No scanning, no config, nothing:

Screen Shot 2010 10 11 at 23.05.06

The full code is available here. To run this version of the OOK Scope, download that file, make sure it is called “application.tcl”, and place it next to your JeeMon executable. Then launch JeeMon. Just make sure to have the JeeNode running ookScope.pde plugged in.

If more than one FTDI interface is found, you will be asked to pick one:

Screen Shot 2010 10 11 at 23.22.45

That’s it: ookScope.pde, application.tcl, plus JeeMon – should work on Windows, Mac OS X, and Linux.

IR pulse pickup

In Hardware, Software on Oct 11, 2010 at 00:01

With the sending of IR pulses out of the way, the next step is picking them up. That’s a lot simpler since there are various sensors which do this.

But unfortunately I only have a QSC113 IR photo transistor at hand right now. It doesn’t have any sort of 38 kHz filtering, it just senses IR light. Then again, it still seems to work – I don’t understand why, to be honest:

Dsc 2123

Anyway, this seemed like a good test case to throw at the OOK Scope. The name is a bit confusing actually – it was used to analyze OOK-encoded radio signals a couple of months ago, but it’s really more general than that. What the OOK Scope does, is create a histogram of incoming pulse widths (20 .. 4604 µs with the current code).

As a refresher, here’s some OOK Scope output with a 433 MHz radio attached, after pressing buttons on my KAKU remote control:

Screen Shot 2010 10 10 at 22.06.54

The histogram runs sideways: at the top are the short pulses, at the bottom the long pulses. The longer the bar, the more pulses of that length have been picked up.

Now the fun part is that this same setup can also be used for IR pulses:

Dsc 2122

I simply replaced the OOK radio in port 2 by my IR photo transistor, with the short lead to GND and the long lead to AIO2. Here’s what comes out when using the Apple remote:

Screen Shot 2010 10 10 at 22.47.36

The pulses are a lot sharper, which is not surprising since it’s picking up direct light pulses now, not radiomagnetic waves of a much lower frequency and intensity that has to be detected and converted into an electrical signal by the radio.

Reading these values is a bit more work, because the ookScope.pde does some trickery to increase the range of pulse widths it can report in a single byte:

if (width >= 128) {
    width = (width >> 1) + 64;
    if (width >= 192) {
        width = (width >> 1) + 96;
        if (width >= 224) {
            width = (width >> 1) + 112;
            if (width >= 240) {
                width = (width >> 1) + 120;
                if (width >= 248) {
                    width = (width >> 1) + 124;
                    if (width >= 252) {
                        width = (width >> 1) + 126;
                        if (width > 255)
                            width = 255;
                    }
                }
            }
        }
    }
}

See the OOK Scope post for details on how this works.

Back to the readings. The values reported are two strong bands centered around ≈ 105 and 158, respectively, with another set of pulses at 224. The pulse widths corresponding to these are ≈ 420 µs, 652 µs, and 1536 µs if I got my calculations right. That last one might be the time between retransmissions.

I’ll have to revisit this with a real 38 kHz filtering IR sensor when I get them in – but that sort of looks right to me. Another remote sending out RC5 codes ended up with very similar pulse widths, but with more variation.

Tomorrow, I’ll describe the OOK Scope setup in more detail, since it doesn’t seem to be working for everyone…

Update – I just figured out the pinout of a 5V sensor with IR filtering (TSOP1138) – here’s what comes out:

Screen Shot 2010 10 10 at 23.32.07

Hm, more variation now. Then again, also a lot more sensitive, it seems. And it looks like it should still be possible to discriminate between the two pulse widths at position 135, i.e. around 568 µs.

The pulse trains are now more consistent on the scope:

Dsc 2124

Note that I’m driving the JeeNode I/O pin to nearly 5V, which isn’t really such a good idea…

PS. That’ a DSO Nano scope, in case you’re wondering…

Generating IR pulses

In Hardware on Oct 10, 2010 at 00:01

There are lots of projects and schematics floating around the web for encoding and decoding IR remote-control pulses. Many MPU-based ones use one of the built-in hardware timers for this, which is understandable since you can’t easily bit-bang your way out of a 13.158 µs time between switching flanks.

But I don’t want to be constrained to a specific pin, nor dedicate a hardware timer to this task.

Instead, I’ve been experimenting with the venerable NE555. Its normal operating voltage is 4.5 .. 16V, but there’s a CMOS version which will easily go down to 3.3V, as preferred by JeeNodes.

So here’s the circuit (from the ICM7555 docs by NXP):

Screen Shot 2010 10 09 at 14.06.34

The RESET pin can turn this thing on and off. It’ll also need an extra transistor to drive a bright IR LED.

Had to try it out, of course (the chip I used wants at least 4.5V, hence the USB power):

Dsc 2118

Great. It works, but at 35.1 kHz the frequency is a bit off.

Here’s a Logic Analyzer screen shot (warning: MDI toolbar madness, flash from the past!):

Screen Shot 2010 10 09 at 23.11.14

(FWIW: my USB Scope and Logic Analyzer now both work properly on Mac OS X under Parallels 6 emulation – I no longer need a dedicated Windows setup.)

Let’s do the math for the components used in the above test setup, with RA = 1.2 kΩ, RB = 18 kΩ, C = 1 nF:

Screen Shot 2010 10 09 at 14.05.11

f = 37.09 kHz  
∂ = 51.6 %

Let’s use the 1 nF capacitor, smaller would make the circuit more sensitive to stray capacitance. Then I get:

RA + 2 RB = 36.315 kΩ

I don’t want to raise RA much, because that would change the duty cycle in the wrong direction: more LED-on time (i.e. higher current draw). I also don’t want to lower it much further, because that would draw more current in the discharge phase (pin 7 pulled low).

Using 1% resistors, RA = 1.5 kΩ and RB = 17.4 kΩ will do:

f = 38.02 kHz  
∂ = 52.1 %

The 1 nF capacitor will have to be 1% too, of course.

I think I’ll try this. What remains – as always! – is the software, to send out the proper IR bit patterns and to decode the ones coming in. It’d be nice if that could be done fully interrupt-driven like the RF12 driver, because then the whole real-time aspect of IR communication would be taken out of the loop(), so to speak.

Bridge Board it is

In Hardware on Oct 9, 2010 at 00:01

Yesterday’s post triggered some great comments and email exchanges. I came up with this 29-pin design:

Jlpcb 116

There’s a lot more to say about the board and the choices that ended up being made for this particular setup, but I’ll refrain from doing so until the pcb is ready and comes back for testing.

Let me just point out the two uncommitted LEDs with current-limiting resistors, as well as the sideways push-button at the top – again uncommitted, but it can easily be tied to the RESET pin.

Note again that this board is for male pins pointing down, so this effectively holds a JeeNode, JeeNode USB, or JeeSMD together with a half- or full-sized breadboard.

Attentive readers will have noticed the list of Arduino pin numbers along almost the entire length of the board. No more guessing or doc searching if you live in the Arduino ecosystem most of the time – Uno, Due, whatever. A few signals come out on more than one pin, but there’s a reason for that…

Onwards!

Experimenter’s setup

In Hardware on Oct 8, 2010 at 00:01

I keep looking for ways to make it easier to try out stuff – since that’s what I tend to do a lot, here at Jee Labs.

Here’s a trial with a graphics LCD I was mucking about with recently:

Dsc 2111

I don’t like it. Even if the JeeNode’s pins were facing down into the solderless breadboard, it eats up a lot of real-estate, while only a few pins are actually used. Part of the reason is that the ports have a lot of duplicated power pins (that’s the whole point when you use them independently).

I’d much rather use the JeeNode as follows:

Dsc 2109

Then you develop, upload, and test things while tethered. And when it’s ready to use elsewhere, just replace the BUB with an AA Power Board:

Dsc 2110

Now I’m wondering if it wouldn’t be useful to create a little “breadboard interface panel”, like this:

Screen Shot 2010 10 07 at 14.43.48

It’s a bit like the Breadboard Connector that is included with each Expander Plug, as described in this post.

The panel would re-route all pins to the pins along the top row of the breadboard, as well as hook up to the two power rails along the top.

The top of the panel could have extensive labeling for reference. Even some port headers to hook up plugs, if I can figure out which orientation might work best. No components, it’d just be a little back, eh, I mean, front-plane.

Over-packaging

In Hardware on Oct 7, 2010 at 00:01

I know I’ve sometimes “under-packaged” things…

But this is sort of the other extreme. A package with 80+ PCB relays from Conrad came in the following box:

Dsc 2009

That’s a 50 x 40 x 30 cm box, i.e. 60 liters of (mostly air).

The payload was this, which is admittedly a bit awkward in size:

Dsc 2010

And this is how I’m storing it at Jee Labs, until the plug PCB’s come in:

Dsc 2011

That’s a 11 x 7 x 5 cm box (they barely fit), or 0.385 liter.

A 155-fold reduction in size. Pfff…

Room Node battery life

In AVR, Hardware on Oct 6, 2010 at 00:01

The current Room Node sketch only gets 1..2 months of life out of a 3x alkaline AA battery pack. Not enough – by far – for practical use around the house.

The good news is that it’s almost entirely a software issue. There have been JeeNodes running for many months now, some up to 10 months, so there is no hardware limitation to achieve such lifetimes.

In fact, I’d like to push it a bit further and see how long one could run a Room Node off a single rechargable AA battery using the AA Power board. If it’s not that long, I could still opt for the 3x AA pack.

Let’s estimate the idle current draw of a JeeNode first.

The big consumer is the PIR sensor. I recently switched to a new one, because it only needs 3.3V and because of its low current draw. Note that the PIR motion sensor is the only component in the Room Node which should not be disabled during sleep: the whole point is to be able to detect motion at all times, after all. Also, a PIR sensor needs time to stabilize, in the order of a minute, so turning it on briefly is no option.

Here’s the good news:

Dsc 2077

That’s 41 µA idle current.

The JeeNode draws ≈ 3.3 µa, let’s round it up to 4 µA.

The SHT11 draws 2..5 µW, let’s round it up to 2 µA.

So total idle draw is 47 µA.

As it turns out, transmissions consume a neglegible amount of current – if the frequency of transmission is 5 minutes, for example (i.e. 288x per day). The motion detection is different, this needs to go out as soon as there is motion, but this probably won’t happen more than a dozen times a day, on average).

For a transmission, the RFM12B needs to be on for about 2 ms, at which point it draws around 25 mA. With 2 ms once every 300 seconds, that’s a duty cycle of 1:150000, i.e. under 2 µA when averaged out.

So let’s round up and assume that the average current draw of a Room Node is 50 µA @ 3.3V.

A 3x AA battery pack of 2500 mAh would last 50,000 hours, i.e. over 5 years if we ignore the self-discharge rate … assuming that the low-power code is perfect, that is!

Now for the AA Power Board lifetime estimate. At very low current levels, the efficiency of the LTC3525 regulator is 75..80%, according to the datasheet. But first, we need to estimate the current draw. Keep in mind that the power source will be 1.2 .. 1.3V, so we basically need a 3-fold step up. Let’s calculate the input current draw, assuming 1.2V in, 3.3 V out @ 50 µA, and 75% efficiency:

input current = 50 x 3.3 / 1.2 / 0.75 = 183 µA

With an Eneloop battery, I’ll assume it has 1900 mAh capacity, and loses 15% of its charge in two years. Let’s assume that it’ll be used no more than 2 years, and that it lost that 15% charge right at the beginning. Then this is effectively nothing more than a 1600 mAh battery.

Ok, how long can it power a JeeNode plus Room Board?

lifetime = 1600 / 0.183 = 8743 hours = 364 days

So all in all this setup should be able to run just about one year off a single rechargable AA battery. Note that there was some rounding in several places in these calculations, so these estimates are probably a bit conservative.

One year battery life… that’s in fact exactly what I was hoping for!

Now the “only” remaining challenge is to optimize the “rooms.pde” sketch enough to make this happen.

Low-end light box

In Hardware on Oct 5, 2010 at 00:01

Yesterday’s post was about trying to make better pictures for this weblog. The jury is still out on whether the results are dramatically better, but here’s the setup I used – first an add-on for the Nikon D40 built-in flash:

Img 20101003 11

What it does is place a small piece of mirror (extracted from a flatbed scanner) in front of the pop-up flash to reflect all the light up. It’s made of a few little scrap pieces of foam board, glued together to keep the light from directly reaching the object, reflecting the light upwards instead. It’s held in place by friction:

Screen Shot 2010 10 03 at 21.10.03

That solves one half of the problem. The other issue is to get light all around the object to avoid excessively sharp shadows. I made a little “light box” for that, from a little wooden storage box with the interior covered entirely in white foam board:

Img 20101003 12

I can now place the object on the bottom in the back, and sort of peek inside with the camera. The trick is to make sure that the flash sends its light inside the box, bouncing up against the top foam board.

That’s basically it!

The reason I chose this setup, is that I need the height to get the flash inside, and I wanted something that could be easily dismounted and stored away. Like this:

Img 20101003 13

All the foam pieces were cut from five A4-sized panels, because I’ve got lots of ’em lying around. Everything is held together purely by friction, so it’s trivial to assemble and disassemble, but also very easy to replace one of the form boards if it ever got dirty or damaged.

I can also rearrange things, and put the wooden box flat on the table, with the camera looking down into it for shots straight from above.

One detail I’d still like to improve is the amount of diffuse light striking the object at the front. There is currently still a bit of a shadow. One idea is to cover the top with aluminum foil, and perhaps also a surface inside which is slanted forward. Here is a cross section:

Screen Shot 2010 10 03 at 16.27.41

Here is the current setup (no foil yet), with the slanted top panel showing on the left:

Img 20101003 14

Note that foam board is very easy to use for “broken” panels – simply don’t cut them all the way through:

Img 20101003 15

Simple. Now I just need to understand all the adjustments and photo stuff a bit more…

Update – here’s the last trial – different angle, slightly more interesting surfaces, but the FTDI pins are too washed out:

Img 20101004 31

Better pictures?

In Hardware on Oct 4, 2010 at 00:01

Almost all the pictures on this daily weblog are taken with a Nikon D40 + 18..55 mm “kit” lens. I bumped into a fantastic deal two years ago for that setup and have never looked back since then.

Pictures matter on this weblog. In fact I try to get a picture, drawing, or code snapshot image into every single post. It’s simply more fun – to make, to read, and to look back to later.

And until now, almost all pictures were taken in plain daylight (indoor, on a table next to one of the windows). This has been a mixed blessing really – gorgeous light at times, but a widely varying white balance due to the different times of day at which I decide to take some snapshots. And with winter nearing, good daylight conditions are going to get scarce again.

Seeing some of the pictures uploaded to the new “JeeLabs” Flickr group (check it out!), I felt that I really need to beef up the images on future weblog posts a bit. Better close-ups, and more importantly: more consistent lighting conditions and while balance. I’m hoping to do this without killing the low-key basic approach to everything done at Jee Labs.

After some lengthy conversations with Steve Evans and with many thanks for his tips, I’m going to try doing a bit more with flash. At first I wanted to try something with RGB strips, but it simply makes no sense to light up a little scene like a theater (requiring substantial amounts of light!) while the shot only takes a fraction of a second.

There are three problems with using the built-in flash, though:

  • it causes horrible reflections
  • it causes horrible shadows
  • it’s still fairly weak

For decades, I’ve routinely turned off flash for any picture I took. It seemed so ill-suited to capture anything meaningful in a pleasant way, especially with people.

The good news: project / product shots are different…

First of all, everything I shoot for the weblog tends to be fairly small. So a “lightbox” is definitely an option: a micro-studio set up to photograph a very small area with all the lighting in place.

Ok, time for some examples (sorry if it looks a bit like a JeeNode commercial). This is the JeeNode v3, Jul 2009:

Dsc 0424

This is the JeeNode v4, Nov 2009:

Dsc 0767

And here’s the JeeNode v5, Sep 2010:

Dsc 1968

All of them shot out of hand, in daylight, most of them tweaked a bit for exposure, white balance, and shadows, and cropped / rotated for proper framing. No big setups, no comparisons, just some tweaks until it “looks right”, each time.

Here’s a shot of the JeeNode v5, as it came out today, while spending a lot more time on lighting, setup, histograms – but still essentially just some quick ad-hoc tweaking:

Img 20101003 7

Basically, I adjusted the exposure until the background is fully white, and I’ve boosted both color and the sharpness a fair bit (using Nikon’s View NX2 instead of my usual iPhoto).

That last image is definitely closer to the real thing. Much more detail in the shadows and in the highlights. I’m also pretty certain that this new setup can deliver results which are far more repeatable (and at any time of day).

But it is “better”? I’m not convinced. The crystal on the RFM12B is a good example of how you gain detail, but also lose some “vibrance”. Somehow, that JeeNode isn’t jumping off the page anymore … it just sits there.

Oh, here’s another fun shot:

Img 20101003 10

Maybe I’ve simply been staring at too many JeeNodes today. Comments welcome.

Tomorrow, I’ll show the setup I made for this.

Software PWM at 1 KHz

In AVR, Software on Oct 3, 2010 at 00:01

While pondering about some PWM requirements for a new project here, I was looking at the rgbAdjust.pde sketch again, as outlined in the Remote RGB strip control weblog post from a few months back. It does PWM in software, and plays some tricks to be able to do so on up to 8 I/O pins of a JeeNode, i.e. DIO and AIO on all 4 ports. The main requirement there, was that the PWM must happen fast enough to avoid any visible flickering.

The rgbAdjust sketch works as follows: prepare an array with 256 time slots, each indicating whether an I/O pin should be on or off during that time slot. Since each array element consists of one byte, there is room for up to 8 such bit patterns in parallel. Then continuously loop through all slots to “play back” the stored PWM patterns.

There is one additional refinement in that I don’t actually store the values, but only store a 1-bit during the change of values. That shaves off some overhead when rapidly changing I/O pins (see the Flippin’ bits post).

There are some edge cases (there always are, in software), such as dealing with full on and full off. Those two cases require no bit flipping, whereas normally there are always exactly two flips in the 256-cycle loop. But that’s about it. It works well, and when I simplified the code to support only brightness values 0..100 instead of the original 0..255, the PWM rate went up to over 250 Hz, removing all visible flicker.

So what rgbAdjust does, is loop around like crazy, keeping track of which pins to flip. ATmega’s are good at that, and because the RF12 driver is interrupt-driven, you can still continue to receive wireless data and control the RGB settings remotely.

But still, a bit complex for such a simple task. Isn’t there a simpler way?

As it turns out, there is… and it’ll even bump the PWM rate to 1 KHz. I have no idea what our cat sees, but I wouldn’t be surprised if cats turned out to be more sensitive than us humans. And since I intend to put tons of LED strips around the house, it better be pleasant for all its inhabitants!

What occurred to me, is that you could re-use a hardware counter which is always running in the ATmega when working with the Arduino libraries: the TIMER-0 millisecond clock!

It increments every 4 µs, from 0 to 255, and wraps around every 1024 µs. So if we take the current value of the timer as the current time slot, then all we need to do is use that same map as in the original rgbAdjust sketch to set all I/O pins!

Something like this, basically:

Screen Shot 2010 10 01 at 01.41.11

(assuming that the map[] array has been set up properly)

No more complex loops. All we need to do is call this code really, really often. It won’t matter whether some interrupts occur once in a while, or whether some extra code is included to check for packet reception, for example. What might happen (in the worst case, and only very rarely) is that a pin gets turned on or off a few microseconds late. No big deal, and most importantly: no systematic errors!

It’s fairly easy to do some other work in between, as long as the main code gets called as often as possible:

Screen Shot 2010 10 01 at 01.51.18

I’ve applied this approach to an updated rgbRemote.pde sketch in the RF12 library, and sure enough, the dimming is very smooth for intensity levels 25..255. Below 25, there is some flickering – perhaps from the millis() timer? Furthermore, I’m back to being able to dim with full 24-bit accuracy, i.e. 8 bits on each of the RGB color controls. Which could be fairly important when finely adjusting the white balance!

So there you have it: simpler AND better! – all for the same price as before :)

Poor Henry

In Hardware on Oct 2, 2010 at 00:01

The new AA Power Board is working very nicely, but it turns out that the ferrite-core inductor is a little fragile.

This is the 10 micro-Henry inductor core, as it should be:

Inductor

… and this is what happened to one of the shipments “all the way” to the UK:

Sje 3911

(photo courtesy Steve Evans – great close-up!)

Whoops, not good!

This happened to two of the five boards shipped as part of a “5-pack”, where I placed all the boards together in a single plastic bag, along with the metal AA clips. The fact that the inductor is placed near the outside edge also probably doesn’t help…

I’ll package the boards differently from now on. But if you got these boards, please check them and let me know if they got damaged (they may still work, depends a bit on the breakage) – I’ll send out replacements for any bad boards out there, of course.

Live and learn!

Save data to a logfile with JeeMon

In Software on Oct 1, 2010 at 00:01

I’ve added a little demo application called “SaveToFile” to JeeMon which saves data from an attached JeeNode or JeeLink to file, complete with timestamps.

When started, you’ll need to specify which device you want to log (unless there is only one):

Screen Shot 2010 09 30 at 21.01.18

Click on one of the lines, and you’ll get this dialog on Mac OS X (Windows and Linux look a little different):

Screen Shot 2010 09 30 at 21.01.31

Once you click “Save”, the main window changes to show the last received line:

Screen Shot 2010 09 30 at 21.02.07

Here’s the contents of the log file at this point:

Screen Shot 2010 09 30 at 21.02.55

You can just leave it running to collect more data.

The following code implements all this and shows a bit of Tcl and Tk scripting in action:

Screen Shot 2010 09 30 at 21.22.40

This code is now included in the JeeMon on-line demos, so all you need to do is get JeeMon, launch it, and then click on “Run web-based demo”:

Screen Shot 2010 09 30 at 21.04.34

(make sure you don’t have a file called “application.tcl” next to JeeMon)

A window will open, just select the “SaveToFile” link, and it’ll be downloaded to the “JeeMon-demos” folder and then launched.

To run this code from the downloaded copy, launch JeeMon as:

    ./JeeMon JeeMon-demos/SaveToFile.zip

To view the code, unpack that ZIP file and you’ll get what is shown above. You can adapt it to your needs, of course. It’s all open source software!

Relay Plug stocks

In Hardware on Sep 30, 2010 at 00:01

As it turns out, this slim-line relay (Conrad #504286, PCN-105D3MHZ) is not available until April 2011 (gasp!) … no matter where in the world I look:

Dsc 1813 2

Fortunately, there is an equally-slim replacement with the same footprint (thanks, Lennart!):

Dsc 2007

It’s a bit higher, and it handles a bit more current (up to 5A):

Dsc 2008

I’ve ordered a bunch of these, but I also need to get a new batch of PCB’s – didn’t want to order them without a chance of getting suitable relays (Conrad #502047). The new plugs won’t be here before mid-October. And the new relays are a bit pricier, so I’ve had to raise the price of the kit a bit.

Atoms, oh atoms … why can’t you be more like bits? As in: no stocks to worry about?

Sending strings in packets

In Software on Sep 29, 2010 at 00:01

Prompted by a question on the forum, I thought it’d be a good idea to write an extra “PacketBuffer” class which makes it easy to fill a buffer with string data to send out over wireless.

This new packetBuf.pde sketch in the RF12 library shows how to set up a packet buffer, fill it with some string data, and send it to other nodes in the same net group:

Screen Shot 2010 09 27 at 11.23.09

If you want to use the PacketBuffer class in your own code, just copy the dozen lines or so from the above example. The code is very small, because all the heavy lifting is done by the standard Arduino “Print” class.

The code includes logic to report incoming packets, which are also assumed to always contain text strings. To try this example, you’ll need at least two nodes, of course. Here’s output from the two I tried this with:

Screen Shot 2010 09 27 at 11.01.55

And the other side (not at the same time):

Screen Shot 2010 09 27 at 11.02.42

But having made this demo, I have to add that in general it’s not such a good idea to send out everything in string form. It takes (much) more code and RAM to deal with strings, and the receiver cannot easily convert everything back to numeric values. Then again, if you just want to send out strings to report or process on the PC, then the above may come in handy.

Enjoy!

Biting a mini-bullet

In Musings on Sep 28, 2010 at 00:01

After some agonizing over the infinite number of trade-offs available these days, I’ve finally made a couple of big decisions w.r.t. Internet and Jee Labs.

Until now, all the web sites for Jee Labs have been running on a rented dedicated web server located in Germany. That little setup has served me extremely well, running some 5 years with just a (precautionary) HD swap about halfway down the road. Downtime over these years has been less than 24 hours I think, in total – or as they say: “three 9’s” (99.9% uptime).

The current server machine is showing its age though, so some form of upgrade and transition is needed in the not too distant future. Preferably one which can again last 5 years or more. Content changes all the time – but a server really shouldn’t need to. It’s a commodity by now.

As it so happens, Fiber to the home (FTTH) is currently being rolled out around here at Jee Labs. Meaning: fast uploads, not just downloads. Which changes the landscape – it’s no longer necessary to rent something, a server at home will work just fine. Jee Labs is not a bank or some high-profile company setup. I don’t need a team of support personnel to get around-the-clock support. If it fails, I can fix it. And if I’m not there to fix it, then Jee Labs has a bigger problem than just its websites…

So the plan is now to move all of the Jee Labs internet “operations” to … Jee Labs in Houten, The Netherlands. Not hastily – there is no rush. But still.

Now I need a server. One which I won’t outgrow. One which won’t break – or at least if it ever does: one which is easily replaceable. I’ve traveled across the planet in my searches. I’ve seen it all. Amazingly small, amazingly cheap, amazingly powerful, amazingly robust, and amazingly simple. None of them is everything at the same time. But I did end up with a setup that fits me.

I’ve decided to base the system on the latest Mac Mini:

Server Hero 20100615

Server edition, i.e. no DVD but a second hard disk. High end stuff, more than I’ve ever plunked down for a server. Still under €0.50 a day, if it lasts and delivers over the planned 6-year lifetime. Modern in terms of capabilities, modern in terms of noise level, and modern in terms of energy consumption. I’m pleased with this decision.

Inside, it’s going to run a couple of virtual machines. That will give me a level of (manually managed) fail-over which I’ve never had before. Security is crucial, but there too, the VM’s should add some good security barriers. One of the VM’s will be used for home automation.

I’m already running parts of the setup at Jee Labs as virtual machines, so the task ahead is to continue that migration, and then bring it together on the new server.

I’ll do my best to minimize the hickups, for this weblog and for the rest of the public-facing activities at Jee Labs and Equi 4 Software. There will no doubt be some disruptions and even foul-ups. But the hard part for me is over – the direction and the goal are clear now. The rest is … just work :)

Opto-coupler doesn’t couple

In Hardware on Sep 27, 2010 at 00:01

It’s that time of year again… a mistake, courtesy Mr. Murphy: the recently-added Opto-Coupler Plug this time.

Triggered by a post on the forum, I created a little test setup. The idea is to feed some outputs in on one end of the plug, and then read them back out. First the outputs, using ports 3 and 4:

Dsc 2000

The plug itself is hooked up to port 1:

Dsc 2001

Here’s the test sketch (see opto_demo.pde):

Screen Shot 2010 09 26 at 15.55.52

What it does is toggle the ouput in all possible combinations, and then report the input signals it’s reading. Here is the correct output:

Screen Shot 2010 09 26 at 15.32.33

I had to create the EAGLE component for the MCT62, since it wasn’t available. Here’s what I made, using some existing part and modifying it:

Screen Shot 2010 09 26 at 16.29.27

Now if it were correct, then the Opto-coupler Plug would be fine. But it’s way off. Here is the datasheet pinout:

Screen Shot 2010 09 26 at 16.30.20

Silly me. The emitter is attached to “+”! – and the cap is also useless… there is no + on the chip, it doesn’t need a power supply.

I don’t know what I was thinking at the time, but it clearly doesn’t make any sense. The test setup I had on the breadboard worked fine, of course. It’s just that I went completely astray on the EAGLE design side of things. And then during the pcb test, I must have made a mistake and only tested one side.

Oh well. Fortunately there is a way to fix these plugs, but it ain’t pretty:

Dsc 2003

One copper trace from pin 8 on the bottom has to be cut, and a short wire has to be connected between pins 8 and 5 to attach the photo-transistor’s emitter to ground.

I’ll be fixing the (luckily small) batch of opto-coupler plug kits currently in stock here. And I’ll get new PCBs made ASAP – but this will take a few weeks, as usual.

Assembling the JeeNode v5

In AVR, Hardware on Sep 26, 2010 at 00:01

New JeeNode means: new build instructions.

Here goes. A long description of how to go from this:

Dsc 1973

… to this:

Dsc 1970

Make sure you’ve got a nice soldering iron (not too hot, not too large) and some solder wick to remove solder in case you need to back up a bit to fix things. The JeeNode printed circuit is very sturdy and can handle a lot of abuse, but some traces are thin, so be careful and don’t apply too much force.

Components are soldered on from lowest to highest profile, because then you can turn over the board and push on it to get each component snugly against the board as you solder it. So let’s start with the resistor:

Dsc 1974 Dsc 1975

Once you’re satisfied with the soldering, turn it over and snip off the leads:

Dsc 1976 Dsc 1977

More…

Read the rest of this entry »

Meet the JeeNode v5

In AVR, Hardware, News on Sep 25, 2010 at 00:01

I’m very pleased to introduce the – Fresh!Updated!New!JeeNode version 5 board:

Dsc 1929

Hold on. Don’t get too excited. It’s not that big a deal. It’s basically still the same JeeNode v4, with just some incremental changes.

Allow me go through each of the differences in some detail:

  • on the left, there is now a diode between the FTDI power input and the rest of the PWR lines – so you can power the board from a 4.5..13V battery, etc. and it won’t fry the FTDI board or cable when plugged in
  • this also means that “PWR” will be about 0.7V lower on the PWR pins in several places across the board, than on the power supplied to the FTDI power pin (i.e. 4.3V when fed from a USB-BUB)
  • for 100% compatibility with the JeeNode v4 and older, the diode can be disabled (i.e. shorted out) with a solder jumper on the back side
  • two extra header pins have been added (+3V and RST), on either side of what was the “PWR/SER/I2C” header on the JeeNode v4 – it is now called the “PSIX” header (X = eXtended)
  • on the right, the RFM12B module was moved a bit to make room for a hole for the antenna wire
  • not as easy to see, but the board is also fractionally longer, so that the RFM12B no longer sticks out
  • slight re-arrangement of components (caps and reset pull-up)
  • most holes are slightly larger, making it easier to unsolder components, if you ever need to
  • the long sides of the board are now routed i.s.o. V-scored, i.e. much smoother and more precise:

Dsc 1966

That’s more or less it. Oh, and D O T Sfour big white dots on each side of the board to be precise, next to the PWR pin of each of the Port 1 .. 4 headers. You’ll be surprised by how convenient that can be when hooking up all sorts of plugs – which have the same dots to mark the proper orientation.

All in all, no big changes. Nothing incompatible with the JeeNode v4, the JeeNode USB, or the JeeNode SMD. This isn’t about planned obsolescence, these are just some tweaks to squeeze the maximum usability out of what is essentially the flagship and workhorse of Jee Labs, if you pardon this odd mix of metaphors.

I did forget to fix two little teeny tiny label name spelling errors which were also on the JeeNode v4 (left as exercise for the diligent reader). Oh well. I hereby claim victory anyway, and now declare this v5 PCB to be TUJ!

… TUJ ?

Yes: TUJ. Shorthand for The Ultimate JeeNode of course! What else?

PS. The JeeNode v5 is shipping now. I don’t play “There’s Something New Coming Soon” games.

Update – I’ve updated the documentation:

  • JeeNode v5 manual (PDF)
  • JeeNode v5 pinout (PDF)

It’s all a bit in transition, with the Café moving to Redmine soon – which is where these docs will go, eventually.

It’s time to Do The Right Thing

In AVR, Hardware on Sep 24, 2010 at 00:01

This is long overdue…

If you have one or more JeeSMD v1 boards, which look tike this:

Dsc 1772 2

… then you are entitled to a free upgrade to the new JeeSMD v2 board, with the fixed VR (and tented vias):

Dsc 1963

Actually, I won’t send you a replacement board for each one you have, but an entire JeeSMD kit.

Likewise, if you ordered one or more Carrier Boards with Boxes, and never got these:

Dsc 1964

… then I owe you that DC Power Jack and matching connector. Ignore the 0.1 µF ceramic capacitor if you already have one – it’s for adding the reset circuitry on the Carrier Board’s FTDI connector.

Email me (please include the order number if possible) and I’ll get it out to you. No questions asked.

Mistakes happen – and I can’t undo the past. But I won’t walk away from my responsibilities either.

AA board testing

In Hardware on Sep 23, 2010 at 00:01

The latest AA Power board is one of those ideas where I can’t help but think… why didn’t I think of it before?

There’s a definite cost trade-off (that LTC3525 is expensive, and it’s only available in SMD so it has to be assembled), but I’m definitely going to switch my room nodes over to it – once that elusive how to enclose it? question gets answered, that is…

Anyway. I’ve been assembling dozens of those boards lately. Hand-soldering them, in fact – because the paste stencils aren’t ready yet. The soldering part is easy, I’ve got that down fairly well nowadays. I like soldering.

The issue is that each board must be tested. Recalls are tedious / inconvenient / annoying for everyone, and not just embarrassing for me, but totally robbing me of my pride in what I do and what I make.

Doh. Welcome to the real world.

Time to use those Pogo test pins. The nice part is that the AA Power board is ridiculously easy to test: apply 1.5V and watch 3.3V come out. Or, more loosely: connect it to an AAA battery, and watch it drive a green LED.

Here’s the AAA battery + green LED + Pogo pins part:

Dsc 1961

Note that there is no circuit on this board – no components, just the missing pieces.

To use it, I simply push the board under test against it, and voilá …

Dsc 1962

If it lights up green (see lower right corner), it works!

Great time saver. Caught about 1 in 10 (mistakes on first test), until every one of the first 50 boards was working.

Onwards!

HomeSeer and JeeNode WSN’s

In Software on Sep 22, 2010 at 00:01

HomeSeer is a commercial Windows-based home automation software package. I’ve seen it demo’d a few times, but I’m not using it myself – nor do I have a license for it (I don’t have a permanent setup running Windows).

The following describes a great new development by Tijl van der Velden, who wrote a very interesting extension for HomeSeer to link into aWSN based on JeeNodes, Room Boards, plus a JeeLink on the PC side.

Tijl just finished his project, which was done as student assignment for Computer Science at the University of Utrecht. He was so kind to send pictures of his setup and screen shots of the resulting application in HomeSeer.

I’m just the messenger in this case, but I’m very happy to be able to report about this on the weblog. For details about Tijl’s project, which has been released as open source on SourceForge, visit the JeeSeer page. The code running on Windows is VBScript, as used by HomeSeer – the software on the JeeLink and JeeNodes are C/C++ Arduino-type sketches.

Here’s his test stup:

Sam 0381

You can see the JeeNode with Room Board on top (and the temperature, humidity, light, and motion sensors), as well as an extra LED and small DC motor, driven by a transistor (with the inductive kickback protection diode).

The sketch running on the JeeNode includes some very interesting customizable “decision rules”, which can be configured from HomeSeer. Here’s the customization screen:

Decision Rules 2

The sketch running on the JeeNode looks fairly generic, allowing for different devices, so that you can use the port I/O pins for various purposes – both as inputs and as outputs. From a brief look, it reminds me a bit of Firmata.

The Jeelink is also running a custom sketch, to be able to pass these special requests and replies to a JeeNode and back. As with RF12demo, you can configure the JeeLink to listen on a specific frequency band and filter out a specific net group. This is also nicely configurable from the HomeSeer web interface:

Config 2

And here is what it’s all about – sensor results and device (i.e. LED + motor demo) control:

Status Page 2

Thank you Tijl, for completing this project and for sharing your results and your code on SourceForge. You are making it possible for others to learn from what you did, to plug what you made directly into HomeSeer, and to let people extend things further as the need arises.

It’s great to see the JeeNode – domotics integration becoming a reality!

Room Node mount?

In Hardware on Sep 21, 2010 at 00:01

I’m still searching for ideas to mount a JeeNode with a Room Board, a.k.a. as a “Room Node”. Now that the AA Power Pack lets me get rid of two of the 3 AA’s, I’m sort of hoping to bump into some new and practical options.

How about this position, against the ceiling?

Dsc 1957

The PIR motion sensor is placed above an empty spot between the JeeNode and the AA Power board. It’ll need to be wired up in that position, of course.

The shapes are still agonizingly unsuited for placement into a corner, but then again… it’s a lot better than with the 3x AA battery pack! Here’s the whole setup again, in close-up:

Dsc 1958

The trick will be to cover it up properly, here’s a first trial using my favorite foam-board as prototyping tool:

Dsc 1960

That’s 6.5 cm wide, btw. Any less, and the battery holder will poke into it and make it wobble.

Does it look good? I don’t know. I think I could live with a slanted 6.5 x 20 cm white strip along the ceiling, with a little PIR peeking out in the middle (and a small hole for the LDR + temperature/humidity sensor).

Next challenge is to come up with a mounting bracket for this darn thing. Perhaps 3D-printed? Two triangles on the end or something? If they slant slightly inwards, they would cast a shadow and not draw much attention…

It all needs to be properly detachable, since this thing runs on battery power. I could stick two little solar panels on the surface to get a warm fuzzy environmental feeling… but I doubt they’ll capture enough energy in that position.

Anyway – I’m happy to have a fresh option to think about. We’ll see…

Lots of AA’s

In Hardware on Sep 20, 2010 at 00:01

C’mon, admit it… you’ve got a pile of discarded AA’s somewhere in your drawers as well:

Dsc 1950

With all the JeeNodes and room nodes I’ve been trying out around here – and the modest results with the rooms.pde sketch w.r.t. battery life so far, I’ve gone through all these much faster than I would have liked to:

Dsc 1949

Went through over 60 here at Jee Labs, in the past year or so. So much for the environment!

Enough is enough. I’m switching to the Apple charger with the Eneloop NiMh’s. And with the new AA Power board, it looks like a single AA cell per node might be enough.

But wait! Are all those AA cells really empty? Time to find out!

Since the AA Power board is so efficient, I though it’d be interesting to see how many of those “dead” AA cells are truly empty. Note that the AA Power board can pull juice out of a battery and generate 3.3V even when it’s supplying less than half its original voltage:

Dsc 1946

So let the battle begin: which cells really can no longer drive a JeeNode as wireless test node?

The result surprised me quite a bit. These 10 were completely dead:

Dsc 1948

But the rest – which is ALL the batteries shown in the first picture – still worked!

This doesn’t mean that any of these batteries will last very long. But still – they drive the JeeNode and its on-board RFM12B transmitter well enough to send out a fresh packet once a second. Which means that even with an output voltage less than 1.1V, they are still able to a briefly deliver a 80 mA peak current once a second (i.e. 3x the current required @ 3.3V) !

Hmm, now what … charge an Eneloop with all that residual energy, perhaps? :)

AA power options

In Hardware on Sep 19, 2010 at 00:01

The new AA Power board is a pretty darn flexible little board, if I may say so myself. Its switch regulator draws very little current itself, 7..30 µA depending on the input voltage. The input voltage range is approx 1.0 .. 5.5V, to be able to start up, but it will drain the power source all the way down to 0.4V if it can, pulling every last bit of juice out of regular AA batteries.

But the AA Power board is also capable of providing a pretty decent amount of current when needed. This is essential for the on-board wireless radio of the JeeNode, but it even works with heavier loads than that:

Dsc 1942

That’s an Arduino-compatible JeeNode with an LCD Plug and a 2×16 character LCD with backlight – all running off a single 1.2V AA NiMH battery!

The maximum current depends on the input voltage. It is guaranteed to be at least 60 mA from a 1V supply, going up to 140 mA from a 1.8V supply. Note that the input current can be much more than that – drawing 60 mA at 3.3V means the battery may have to deliver about 200 mA at 1V to make it happen. A clever little power regulator it is – a producer of energy it is not!

There a several ways to connect the AA Power board with a JeeNode:

  • inline, feeding the PWR pin with 3.3V (this will be dropped some 30..50 mV by the on-board regulator of the JeeNode itself, with no ill effects)
  • in piggy-back mode, with an AA cell inserted in the battery clips (alkaline or NiMh)
  • as a shield on top of the JeeNode, again with an AA cell inserted

There’s also a fourth way to use this board: leave off the battery clips, and connect a battery between any PWR and GND pins on the JeeNode itself (or use the battery holes) – this requires a solder jumper on the AA Power board.

The flexibility of the regulator means that you can connect any power source between 1.0 and 5.5V to PWR and GND, just as you would with a stand-alone JeeNode. Whatever it is, the +3V pin will carry the essential 3.3V level.

There is one issue to beware of: when PWR is connected to BAT+ via the solder jumper, then do not hook up a second power source at the same time. The most common case is probably: when a battery is connected to PWR, do not connect an FTDI adapter such as the BUB, because it’ll put 5V on the PWR pin … and the battery (or the BUB!) probably won’t like it.

The PWR pin can in fact be used in four different modes:

  • normal – it’s higher than 3.3V and the on-board regulator brings it down to 3.3V for the +3V pin – this would be the case with 3 to 8 AA’s, for example (no need for an AA Power board)
  • boosted – it’s lower than 3.3V and it’s used to feed the AA Power board – in this case the on-board regulator does nothing (and could be omitted)
  • parallel – the PWR pin is connected directly to the +3V pin – this can be used with the AA Power board to make sure the PWR pin also carries power (always 3.3V), in case some plugs expect a supply voltage on the PWR pin
  • floating – the PWR carries no power – this is the case when the AA Power board is used without solder jumper (default case)

The important point here is that the PWR pins do not necessarily carry a higher voltage than the +3V pins. It might be more (normal), less (boosted), the same (parallel), or none (floating). Not every JeePlug can be used with each mode of operation, so be careful to check.

Tomorrow, I’m going to fool around with a bunch of batteries :)

AA mounting options

In Hardware on Sep 18, 2010 at 00:01

As promised yesterday, here is some more info on how to use the new AA Power board.

You’ve already seen the “inline” mode, using an Alkaline cell this time:

Dsc 1932

The second main mounting option is in piggy-back mode, flipped over and mounted on the back of a JeeNode:

Dsc 1939

This can be done either with regular male header pins (1×6 and 2×4, or 3×4), or with extra long pins which will stick out the front of the JeeNode as normal header pins:

Dsc 1938

Doing so requires some care, because once these two boards are soldered back-to-back, you can’t reach everything anymore. Disassembling such a sandwich later is tricky.

Note that you can stand the whole assembly on empty AA battery clips, but once a battery is inserted, this becomes unstable because the round battery sticks out:

Dsc 1940

With AAA clips and the much thinner (and weaker) AAA battery, it turns out that the whole construction does stand upright, but the size and position of the clips gives it limited stability when adding plugs on top.

There is a third option – use the AA Power board on top of a JeeNode with stacking headers, i.e. like a “shield”:

Dsc 1953

There is not that much room, but the 4 port headers can still be used. Note that the AA Power board needs to be mounted upside down in this case, i.e. with the SMD components and the silk screen facing down towards the JeeNode. Here’s another view of this shield-style option:

Dsc 1951

Coming up… a description of the full range of power connections supported by this little magician.

Long live the AA battery!

In Hardware on Sep 17, 2010 at 00:01

The AA Power board announced yesterday just arrived:

Dsc 1931

And it looks like it does indeed perform exactly as expected. Here’s the ripple:

Screen Shot 2010 09 16 at 13.41.07

That’s with the 1.6 mA LED load, i.e. a 75 µs cycle / roughly 13 KHz – this was as predicted: at light loads, the recharge frequency can reach down into the audible range. But it’s highly unlikely to be noticable due to the tiny size of the inductor, which after all is not built to act as a loudspeaker :)

Here’s the “AAv1” fully mounted for powering a JeeNode via the FTDI connector:

Dsc 1934

(there’s no charge circuit here, I’m just using an externaly-recharged battery as power source)

And here’s the whole setup in actual use:

Dsc 1935

Works like a charm. Runs just fine with the “rooms” and “radioBlip” sketches, and wireless just works – as before.

Quiescent current draw is about 20 µA when powered this way. That goes down to 10 µA when used with two cells @ 2.4V, and down to an amazing 7 µA when powered from a 3V source (a CR2032 ought to work nicely!). Above 3.3V, the circuit becomes just a tad less efficient when it switches into step-down mode, drawing about 30 µA all the way up to 5.5V.

Great, now we’re starting to get into some serious low-power options.

Tomorrow, I’ll describe other ways to use this new AA Power board…

Meet the AA Power board

In Hardware on Sep 16, 2010 at 00:01

Remember the recent post about running a JeeNode off a single battery?

Dsc 1897

That was 9 days ago, and that LED shown above is still lit. It’s not a huge accomplishment, because the LED draws only about 1.6 mA and is very dimly lit, but still. Over two hundred hours of operation time, and the rechargeable battery I used (this one) is still going. It started off at 1.35V and is now at a decent 1.22V level.

Assuming a 70% efficiency (at such low voltages, it probably won’t be much higher than that), and an average of 1.3V getting boosted to 3.3V, the power consumption over this period is … scribble, scribble … 1.6 * 3.3 / 1.3 / 0.7 * 216 = 1253 mAh, i.e. about two thirds of the total capacity of this one-cell AA battery.

Not too shabby. Even without power-down tricks, just by entering idle mode in all the busy loops, an ATmega328P will draw less than 1.6 mA when running at 16 MHz on 3.3V (which is slightly overclocked, but it works just fine). Idle mode is very nice, because you don’t have to play any serious low-power tricks, you just have to tell the ATmega: I have nothing to do right now, take it easy until the next interrupt occurs.

In other words: using only the simplest of all the low power tricks, a JeeNode can run about two weeks off a single AA battery (less, if you have power-hungry peripheral chips connected, of course).

Try running an Arduino Duemilanove off a 9V battery, or even a 4x AA battery pack. Fine board, but it sure ain’t low power…

Anyway, I’ve decided to design an AA Power board for this little power magician:

Screen Shot 2010 09 15 at 21.20.21

It’s not specific to the JeeNode, but it was of course designed to be a particularly good match for it:

  • the width of the board is exactly the same as JeeNodes and all the JeePlugs
  • it can be attached in-line, i.e. like an FTDI board/cable
  • it can be used in piggy-back mode, i.e. attached to the back of a JeeNode
  • or use it in shield mode, i.e. on top of a JeeNode with stacking headers
  • it has mounting holes (since there is plenty of room on this thing)
  • the board can be fitted with either AA battery clips, or AAA battery clips
  • or attach external batteries to it: one, two, three (even four, if NiMh) … you decide!

Whatever the power source is, this board will either boost or step-down the voltage as needed. The efficiency will be up to 95%, depending on load and supply voltage. But in any case, it’ll be way more efficient than any linear voltage regulator, including the one on the JeeNode.

One AA is smaller than 3 or 4, obviously, so a JeeNode with this AA Power board will also fit into smaller places.

In case you insist on using 3x or 4x AA’s, then you’lll still benefit from a much higher conversion efficiency, and the ability to run the batteries down until they are completely empty. In other words: they will last longer!

Now it’s just a matter of waiting to find out whether I did all my homework properly, and got the connections, traces, and physical dimensions right.

More RF12 driver notes

In Software on Sep 15, 2010 at 00:01

Yesterday’s RF12 driver changes added a new feature to capture packets from different net groups, and to easily send out packets to different netgroups (don’t hold your breath for a “group broadcast” to every node out there).

As reported on the forum, it’s still not perfect due to the high number of false packet triggers.

One effect of this is that correct packets are missed occasionally. Here is the output from yesterday again:

OKG 15 4 248 48
OKG 15 4 250 48
OKG 5 61 7 23 83 97 7 0 155 79
OKG 15 4 251 48
OKG 15 4 252 48
OKG 15 4 7 49
OKG 15 4 255 48

Node 4 in net group 15 is a little test node which sends out a packet once a second (it’s the radipBlip.pde sketch, in fact). And as you can see, 3 packets already got lost in that brief time window.

My hunch is that the radio syncs on far too many bit patterns. This starts the radio off, collecting bytes, until either the proper packet length has been reached or the maximum of 68 bytes (hdr + length + data).

The problem is that a correct preamble and sync pattern right after such a false start will be interpreted as data. It would be possible to solve this in software, by passing a set of valid groups to the RF12 driver, and have it abort the reception immediately if something comes in. Then the driver can immediately restart a fresh sync search, thus hopefulyl capturing a subsequent real packet.

More work will be needed in this direction, but I wanted to get the change in so others can try it out and have a go at coming up with improvements for this code.

Two more small changes were added to the RF12 driver: a way to use it in “buffer-less transmit” mode, and a slightly more flexible way to wait for the completion of packet sending.

Buffer-less transmit mode is a way to avoid having to use extra memory for sending out packets. An example:

    if (rf12_canSend()) {
        struct { ... } *buf = (void*) rf12_buf;
        rf12_len = sizeof *buf;
        // fill in values here, i.e. "buf->temp = 123", etc.
        rf12_sendStart(0);
    }

So instead of passing an area of memory to copy into the rf12_buf area, as done with a traditional call to the 3-argument rf12_sendStart(), you set up a pointer directly into that area and store results directly into them.

The crucial point is that you can only do this between the time when rf12_canSend() returns 1 and a subsequent call to rf12_sendStart(). That is the only time when the data in rf12_buf is guaranteed not to get changed by the RF12 driver itself.

In many cases, you don’t need all this trickery. This is just a way to reduce the amount of (scarce) ram needed to work with packets and the RF12 driver.

The other change in the RF12 driver concerns the following call, which uses the optional “sync” parameter to specify how to wait for send-completion:

    rf12_sendStart(hdr, buf, len, sync);

This recent addition to the RF12 driver is useful for reducing power consumption, because it lets you send out a packet through the RFM12B while the ATmega itself enters a low power mode.

I have added a new function called rf12_sendWait() which now does that waiting side separately. The above call is still available for backward compatibility, but for future use, it should be written as two calls:

    rf12_sendStart(hdr, buf, len);
    rf12_sendWait(sync);

The reason for this change, is that this now also supports the buffer-less transmit mode described above:

    if (rf12_canSend()) {
        struct { ... } *buf = (void*) rf12_buf;
        rf12_len = sizeof *buf;
        // fill in values here, i.e. "buf->temp = 123", etc.
        rf12_sendStart(0);
        rf12_sendWait(2);
    }

Small changes, all in all. This will of course be documented on the cafe/docs site, but since that site is going to be replaced by a more advanced wiki-based setup in the near future, this post will have to do for now. I don’t want to deal with two sets of documentation… maintaining one set is hard enough!

New RF12 driver mode

In Software on Sep 14, 2010 at 00:01

The RF12 driver has been extended with the ability to send and receive packets from any net group. This feature was long overdue – it allows a node to listen to packets coming from different net groups, and could be used to implement a packet forwarding “relay” or a mesh network.

The way to activate this “any net-group” mode, is to initialize the RF12 driver with net group zero:

    rf12_initialize(12, RFM_868MHZ, 0);

This puts the RFM12B in a special 1-byte sync mode. The new rf12_grp variable will contain the net group whenever a packet is received, i.e. whenever rf12_recDone() returns true.

To send a packet to a specific netgroup, say 34, you can now use the following code:

    if (rf12_canSend()) {
        ...
        rf12_grp = 34;
        rf12_sendStart(...);
    }

The RF12demo.pde has been extended to support this “any net-group” mode – simply set the group as “0g”.

When use in this special mode, the format of the reported lines changes slightly: “OK” becomes “OKG” plus the net group number – followed by the header byte + data bytes, as usual.

Here is some sample output, first normal mode, then any net-group mode:

Current configuration:
 A i1* g5 @ 868 MHz 
OK 3 215 66 0 0
OK 61 7 23 83 97 7 0 155 79
OK 61 52 239 0 218 39
OK 61 9 2 8 68 161 75 15 0 16 0
OK 3 217 66 0 0
OK 61 52 240 0 222 39
> 0g
 ?G 45 25 37 209 155 76 99 138 66 247 140 29 251 47 157 163 51 158
 ?G 7 133
 ?G 144 133 255 220 119 254 229 249 92 225 94 213 221 102 160 1 233 59 251
 ?G 255 185 205 23 165 55 175 172 161 229 207 108 141 152 56 127 208 134
> 1q
OKG 15 4 248 48
OKG 15 4 250 48
OKG 5 61 7 23 83 97 7 0 155 79
OKG 15 4 251 48
OKG 15 4 252 48
OKG 15 4 7 49
OKG 15 4 255 48

There is however a serious problem with the promiscuous / any net-group mode: the RFM12B module will report a lot of garbage. I added a “quiet” option to RF12demo to be able to suppress the reporting of bad packets, i.e. dropping “?…” lines. That’s why no “?…” lines were reported once the “1q” command was entered.

As you can see in the output, packets from both net-groups 5 and 15 are picked up and reported. Yippie!

The new version of the RF12 library has been checked into subversion and is also available as a ZIP file, see the software page for details.

There is a bit more to say about these changes… so stay tuned!

Modular nodes

In Software on Sep 13, 2010 at 00:01

Ok, so we have JeeNodes and JeePlugs, and it’s now possible to sense and hook up all sorts of fun stuff. In theory, it’s all trivial to use and easy to integrate with what you already have, right? Well… in practice there’s a lot of duplication involved – literally, in fact: for my experiments, I often take an existing sketch, make a fresh copy and start tweaking it. Shudder…

  • New plug. New bit of code to include in the sketch for that plug. New sketch.

  • New device connected. New bit of code to talk to that device. New sketch.

  • New idea. New logic to implement that idea. New sketch.

Yawn. Some of this WSN stuff sure is starting to become real tedious…

There are a couple of ways to deal with this. The traditional way is to modularize the source code as much as possible: create a separate header and implementation source file for each new plug, device, sensor, and function which might need to be re-used at some point. Then all you have to do is create a new sketch (again!) and include the bits and pieces you want to use in this sketch.

I have a big problem with that. You end up with dozens – if not hundreds – of tiny little files, all with virtually no code in them, since most interfaces definitions and interface implementations are trivial. My problem is not strictly the number of little files, but the loss of overview, and the inability to re-factor such code collections across the board. It just becomes harder and harder to simplify common patterns, which only show after you’ve got a certain amount of code. The noise of the C/C++ programming itself starts to drown out the essence of all these (small & similar) bits of interface code.

The other serious problem with too fine-grained modularization of the source code, is that you end up with a dependency nightmare. Some of my sketches need the RF12 driver, other need the PortsI2C class, yet others use the MilliTimer.

At the opposite end of the spectrum is the copy-and-paste until you drop approach, whereby you take the code (i.e. sketches) you have, and make copies of it all, picking the pieces you want to re-use, and dropping everything else. I’ve been doing that a bit lately, because most of this code is so trivial, but it’s a recipe for disaster – not only do I end up with more and more slightly different versions of everything over time, it also becomes virtually impossible to manage bug fixes and fold them into all the affected sources.

A version control system such as subversion can help (I couldn’t live without it), but it just masks the underlying issues, really. Being that some parts of the code deal with the essence of the interface, and other parts exists just to make the code into a compilable unit.

There is another alternative: go all out with C++ and OO, i.e. create some class hierarchies and make lots of members virtual. So that slight variations of existing code can be implemented as derived classes in C++, with only a bit of code for the pieces which differ from the previous implementation. This is not very practical on embedded microcontrollers such as the ATmega, however. V-tables (the technique used internally in C++ to implement such abstractions) tend to eat up memory when used for elaborate class hierarchies, and worse still, much of that memory will have to be in RAM.

There is a solution for this too, BTW: C++ templates. But I fear that the introduction of template programming (and meta-programming) is going to make the code virtually impenetrable for everyone except hard-core and professional C++ programmers. Already, my use of C++ in sketches is scaring some people off, from what I hear…

Is there a way to deal with a growing variety of little interface code snippets, in such a way that we don’t have to bring in a huge amount of machinery? Is there some way to plug in the required code in the same way as JeePlugs can be plugged in and used? Can we somehow re-use bits and pieces without having to copy and paste sketches together all the time?

I think there is…

The approach I’d like to introduce here is “code generation”. This technique has been around for ages, and it has been used (and abused) in a wide range of tasks.

The idea is to define a notation (a related buzzword is “DSL“) which is better suited for the specific requirements of Physical Computing, Wireless Sensor Nodes, and Home Automation. And then to generate real C/C++/sketch code from a specification which uses this notation to describe the bits and pieces involved:

Screen Shot 2010 09 12 at 17.16.38

To create a sketch for a JeeNode with the Room Board on it and using say an EtherCard as interface to the outside world, one could write something like the following specification:

Screen Shot 2010 09 12 at 18.29.39

The key point to make here is that this is not really a new language. The code you add is the same code you’d write if you had to create the sketch from scratch. But the repetitive stuff is gone. In a way, this is copy-and-paste taken to extremes: it is automated to the point that you no longer have to think of it as copying: all the pieces are simply there for immediate re-use.

Problems will not be gone simply by switching to a code generator approach. There will still be dependencies involved, for example. The “RoomBoard” device might well need the MilliTimer class to function properly. But it is no longer part of the code you write. It doesn’t show up in the source file, there’s no #include line as there would be in C/C++ or in a sketch. Which means it also no longer matters at this level whether the RoomBoard driver uses a MilliTimer class or not.

Code generation in itself also doesn’t solve the issue of having lots of little snippets of code. But what you can do, is combine lots of them together one source file, and then have the generator pick what it needs each time it is used:

Define RoomBoard {
    ...
}
Define EtherCard {
    ...
}

The technique of code generation has many implications. For one, you have to go through one more step before the real code can be compiled and then uploaded – you have to first produce an acceptable sketch. And with mistakes, the system has to be able to point you to the error in the original specification file, not some very obscure C/C++ statement in the generated source code.

And of course it’s a whole new mechanism on top of what already exists. One more piece of the puzzle which has to be implemented and maintained (by someone – not necessarily you). And documented – because even if the specification files can reduce a large amount of boilerplate code to a single line, that one line still needs to be clearly documented.

So far, these notes are just a thought-experiment. I’ll no doubt keep on muddling along with new sketches and plugs and nodes for some time to come.

But wouldn’t it be nice if one day, something like this were a reality?

RGB multi-meter?

In Hardware on Sep 12, 2010 at 00:01

How’s that for a weird title, eh? ;)

Just got around to hooking up a test set of 2x 5 meter RGB LED strips to the MOSFET Plugs – using the setup created and described here a few days ago.

These are water-proof strips, with only 30 LEDs/m and a somewhat unfortunate brown strip background color:

Dsc 1925

That’s with all LEDs full on.

Now some more color and power experiments, in the evening – full on:

Dsc 1920

You can see the current reading, the JeeNode setup, and the power supply.

And with 100% / 45% / 15% settings for red, green, and blue, respectively:

Dsc 1923

The color came out much more yellow on this picture than it actually was, btw.

Some power measurements on the 12V line:

  • full on: 2.4 amps @ 12 V = 28.8 watt
  • color-adjusted: 1.9 amps @ 12V = 22.8 watt

The power supply is a beefy 12A @ 12V cage which draws 4.4 watt even without anything connected. That’s very unfortunate, because I’d like to turn the LEDs off on the 12V side and leave the power supply on at all times. Will need to find a better supply – 4A would be plenty.

These results are slightly disappointing. First of all, 60 LEDs per meter will be a minimum to provide a decent level of (indirect) house lighting at full power. But also, it’s frustrating to see how the power gets eaten up in the supply and by the resistors (especially with red LEDs dimmed less than the others).

No doubt this is way better than incandescent lighting, but still…

Another surprising outcome, is that the RGB settings for this strip are completely different from the 5050 RGB test setup I used a few days ago. It looks like I’m going to have to adjust each strip individually to get a nice consistent white balance.

And then there’s the issue of fringing. Looking directly at these LED strips clearly shows the distinct RGB components, with the color balance very much dependent on the viewing angle. I sure hope that the 60 LED/m strip with white background and used as indirect lighting will even this out.

On the plus side, the ≈ 300 Hz PWM of the new rgbAdjust.pde sketch I’m using on the JeeNode seems to make these LED strips completely flicker-free.

Onwards!

JeeLink DataFlash logging

In Hardware, Software on Sep 11, 2010 at 00:01

Since July, the JeeLink has undergone a slight hardware change. It used to include an 8 Mbit AT26DF081A DataFlash chip, but unfortunately this chip is no longer being produced:

Jl Dataflash

As it turns out, only very few chips are physically and electrically compatible with the AT26DF081A. The only one I could find is the AT25DF041A, which has half the memory, i.e. 4 Mbit.

So that’s what’s being included on the current batch of JeeLinks. I’ll review the alternatives when it is up for a revision, but for now I’ve just opted for this change – especially since the use of the on-board DataFlash memory chip on the JeeLink is probably still very limited.

Having said that, the “RF12demo.pde” sketch does include support for the flash memory, in the form of a continuous data-logging capability. This is the main topic of this post, actually.

All packets received by the JeeLink are saved up and stored in flash memory whenever 256 bytes of data have been accumulated – along with a sequence number and the current value of the millisecond counter.

This process takes place continuously, wrapping around when all available flash memory has been filled. There are some tricky details involved, since DataFlash needs to be erased before re-use. The way RF12demo does this is that it always erases one extra 4 Kb block of memory, just ahead of the current write buffer pointer.

The “sequence number” is a 16-bit counter which gets incremented on each power-up and whenever the buffer writing wraps around. In practice, it’ll never overflow, but there is a “w” (wipe) command to fully erase the entire flash memory and start over if that is ever needed. It only works when executed as “12,34w” to prevent an accidentally typed “w” from wiping the flash.

The data-logging mechanism in RF12demo can be used to catch up on received messages when the attached computer has been asleep for a while. There is a “d” command which dumps info about each 256-byte page in the DataFlash – for example:

    > 0d
     df# 34 : 2 698 28309
     df# 35 : 2 955 3849
     df# 36 : 2 1213 38883
     df# 37 : 2 1471 51360
     df# 38 : 2 1728 55763
     df# 39 : 2 1986 26600
     df# 40 : 2 2244 10261
     df# 41 : 2 2501 57698
     df# 42 : 2 2757 1373
     df# 43 : 2 3016 25513
     df# 44 : 2 3273 41145
     df# 45 : 2 3532 39344
     df# 46 : 2 3789 63313
     df# 47 : 2 4047 57266
     df# 48 : 2 4304 13464

Pages 34 through 48 contain data, all from the same power-up cycle (seqnum = 2), and spanning time 0.698 through 4.304 (seconds). The last values are 16-bit checksums, and less useful here.

What you can do with this data is play it back with the “r” (replay) command:

    > 0r
    r: page 33 48
    R 2 698 3 129 44 0 0
    R 2 704 61 4 17 6 34 116
    R 2 708 56 199 0 215 0
    [...]
    R 2 944 56 147 0 215 0
    DF R 34 2 698
    R 2 955 3 133 44 0 0
    [...]
    R 2 4298 61 52 232 0 135 39
    DF R 47 2 4047
    R 2 4304 3 185 44 0 0
    [...]
    R 2 4525 56 198 0 215 0
    R 2 4538 61 52 233 0 134 39
    R 2 4541 61 4 1 135 49 145
    DF R 48 2 4304
    DF E 48 4 17476

If you replace the “R” and the next two numbers with “OK”, then you’ll see that a long stream of received packets is being reported. The data is internally stored as variable-length binary data, i.e. in a very compact format, but replay converts it back to the same bytes-as-small-integers format as the original “OK” packets.

The replay command also takes arguments to play back from a certain point. The way this works is that the output includes “DF R …” replay markers, which indicate which page has just been replayed. Furthermore, special “DF S …” store markers are also occasionally inserted in the output during normal reporting:

    DF S 49 4 28

With these two bits of information, it is possible to track the point in the logging process so far: whenever a “DF S” or “DF R” arrives, it marks which particular page has just been completed. By storing this on the receiving computer, we can remember how far we got when shut down (even accidentally).

To recover data when started up again, the replay command can be given 6 arguments: “S,S,T,T,T,T r” which tell the JeeLink to start replaying after sequence number SS and time TTTT.

This replay recovery hasn’t been added to JeeMon yet. Once implemented, JeeMon will be able to collect data from remote nodes even if the computer is off once in a while (at night, for example). All we have to do is keep the JeeLink powered, so that it will log all incoming data it its DataFlash.

Back to the hardware change in the JeeLink…

As mentioned on the discussion forum, the new DataFlash chips broke the RF12demo code, which looks for a specific hardware signature to detect the chips. I’ve added some conditional definitions to RF12demo, so that it can now be built for either the 4 Mbit or the 8 Mbit version:

Screen Shot 2010 09 10 at 21.27.24

The RF12demo.pde sketch in the RF12 library has been updated. This new version announces itself on the serial USB port as “[RF12demo.5]”. Note that the current batch of JeeLinks still has the older sketch, so you’ll need to recompile and upload the latest one if you want to use the datalogger functionality.

PC Bees

In Hardware on Sep 10, 2010 at 00:01

New batch of JeeSMD‘s and Carrier Boards just came in:

Dsc 1918

At last! – this batch took a lot longer than anticipated…

The JeeSMD fixes a nasty error reported in the Talk forums, which had two pins exchanged on the 3.3V voltage regulator.

The reason I missed this, is that I used the JeeSMD on a LiPo battery pack, which runs at around 3.7V – and as it so happens, an MCP1703 will generate a voltage drop of roughly 0.4V when connected the wrong way around. So it all basically worked exactly as expected in my setup.

I bet Mr. Murphy had a major role in this “accidental” design detail…

The Carrier Boards haven’t changed. I simply ran out of the first 100 way faster than I had expected. The good news with the Carrier Board + Box kits, is that I’ve now also got a decent stock of DC jacks, so these will be included with all orders. In fact, I’m also throwing in a DC plug, so you can make your own power cables, or adapt some 5..12V DC power supply to fit these standard 2.1/5.5 mm jacks:

Dsc 1919

There are several dozen packages waiting for this back-ordered stuff. I’ll get them out in the coming days!

RGB strips – the software

In Software on Sep 9, 2010 at 00:01

Now that the hardware is ready, let’s move on to the software. First task is to figure out all the pin assignments with a little “rgbTest.pde” sketch:

Screen Shot 2010 09 08 at 12.43.29

Yep, it works. Here’s AIO4 in action:

Dsc 1913

On to the real thing. I’m going to re-use the code from this post, but with a couple of modifications:

  • since that code apparently still flimmers a bit, I’m going to make it run faster by reducing the number of steps from 256 to 101, i.e. intensity values 0..100 – that should increase the refresh rate to about 300 Hz
  • the fourth value will be re-used as a general intensity control, so “RGBW” now means: take each individual RGB intensity times the W intensity
  • the main logic will remain the same, even for the “White” dimmer – this is harmless, since there is nothing connected to port 3
  • need to re-define the pin assignments to match the above, twice

Ok, the new sketch is here – it’s a bit long to include in this post. Now I can send messages via a JeeLink to control this thing:

  • full on: 100,100,100,100,100,100,100,100,30s
  • full off: 100,100,100,0,100,100,100,0,30s

And here’s a very first / rough attempt to create a decent white tint:

  • 100,40,5,0,100,40,5,100,30s

Here’s my (messy!) workbench with four different light sources:

Dsc 1916

  • top right – a warm white incandescent lamp, seems to use a 12V headlight
  • middle back, under the shelf: commercial sort-of-warm-white LED lamp
  • middle center, magnifying glass: fluorescent cool white tube
  • left front, paper sheet: my RGB test setup, indirect lighting

When looking straight at the LEDs (always a bit painful), you can clearly see the different colors. The color offsets produce a slight fringe in the shadows cast from this light:

Dsc 1917

This won’t be good enough for photographers, but my impression is that it might work out fine when used as indirect lighting.

The results did surprise me quite a bit: for this tint, you have to turn on as much red as possible, add some some green, and drop almost all the blue.

The unfortunate part is that the red LEDs are responsible for most of the energy loss via their series resistors. Sigh. I wish they’d make RGB strips with all resistors the same small value – I could easily adjust the actual intensity with PWM and stay below the maximum specs.

Some estimates gleaned from the lab power supply w.r.t. current draw for the 50 cm 60-LED strip + JeeNode:

  • all off: 10 mA
  • full on: 620 mA
  • warm white: 270 mA

That last one translates to 6.72 Watt/meter (with some 2W eaten up by the red-side resistors, yikes). I don’t think I’d want to go any lower than that as full-on lighting setting, so if Jee Labs is to get more of these RGB strips around the house, I’ll definitely want to use the 60 LED/meter strips.

RGB strips, revisited

In Hardware on Sep 8, 2010 at 00:01

A while back, I reported about hooking up an RGB strip. That was then.

Now there is the MOSFET Plug to make such hookups a lot simpler. So it’s time to revisit that experiment, because I want to find out how well RGB strips would work for < w a r m > white lighting in the house. Theoretically, RGB can generate any color, so that would include any “temperature” of white, right? Trouble is, I’m not convinced that LED strips are color matched well enough across their entire length to accomplish such lighting conditions over a few meters. The other concern is that RGB LEDs have the Red, Green, and Blue LEDs sitting next to each other, so there may be some fringe colorization – maybe diffusers will be needed.

Then again, I do have one LED lamp of 1 meter long which generates an abolutely great tint of white (“white tint” – interesting concept, eh?).

Time to find out:

Dsc 1912

I obtained some samples of “5050” RGB self-adhesive LED strip, one with 30 LEDs per meter, the other with 60 LEDs. They are mounted on nice white flexible strips, and the whole thing was tacked onto my all-time favorite material: foam board!

Since 2 x 3 is 3 x 2, I used 3 MOSFET plugs to connect this together, these are in turn plugged into a Carrier Board with a JeeNode on its back, and the whole kaboodle is placed in half a box. Since the plan is to later attach this unit to much longer LED strips, I don’t really want to close that box – the MOSFETs will no doubt generate too much heat once they drive several amps each.

Here is how everything is wired together:

Screen Shot 2010 09 07 at 22.31.09

Oh, there’s one more wire: on the photo you can see a red jumper wire running from +12V to a PWR pin on the Carrier Board (I used the FTDI connector) – so the same 12V supply is used to power the JeeNode itself.

That’s it. Six output lines to control the on-off state of two independent strips of RGB LEDs.

Tomorrow – the software…

Pogo pogo

In Hardware on Sep 7, 2010 at 00:01

Until now, I’ve always been testing plugs with an Extension Cable:

Dsc 1903

Works ok, but with two hands, it’s a bit limiting for more complex cases, such as this Input Plug test rig.

Looks like people seem to be using spring-loaded “pogo” test pins more and more. Here’s one, which comes as a small 6-pin wide SMD “header”:

Dsc 1902

I mounted it on an obsolete I2C plug, simply to have a better grip on it. Not a big step up from the Extension Cables, but it’s slightly better because of the spring-loaded pins. No need to press as hard.

But to really make it simpler, you need to place the pins in all the places you want to test at once. Here’s one adapter which works for several plugs:

Dsc 1900

Once soldered on both sides, it’s actually quite sturdy.

Now, all you need to do is place the board under test on top, and press down slightly:

Dsc 1901

This was the trivial part. It’ll be a bit more work to create custom pin arrangements for the different plugs with I/O headers on the side. But it’s a great step forwards, and will let me do a better job of testing the more elaborate plugs as well.

Right now, all I2C-type plugs are verified to work from the bus side, but connections to other headers are a matter of visual inspection still. There’s “room for improvement” as they say…

Running off a single AA battery

In Hardware on Sep 6, 2010 at 00:01

The other day, I found the LTC3525 – an interesting little (yes, tiny!) boost regulator chip, which might be a pretty good power source for low-power JeeNodes.

Couldn’t resist – had to try it…

Here’s a test setup using my favorite foam-board as base, with one AA battery driving a test LED:

Dsc 1897

(hard to see, but that LED is indeed on)

Did I mention that the whole thing uses tiny parts? It did take some patience…

Dsc 1898

Tests show that it will regulate any input voltage from 0.8V .. 5.5V to 3.3V @ 60..200 mA depending on the input voltage. And with 70..90% efficiency, even in the 10’s of µA current consumption range. I’ve verified that it will indeed down-regulate when fed > 3.3V, which makes it very flexible.

The quiescent current draw of this circuit appears to be around 20 µA on a 1.3V input.

So it looks like this could work out nicely:

Dsc 1899

My hunch is that this thing could last 6 months for a room node. Maybe more, but with a 6-pack of AA batteries plus charger, who cares?

Hmm, might be worth designing a little board for…

Utility Plug pack

In Hardware on Sep 5, 2010 at 00:01

The recently announced Utility Plugs have room on board to add some resistors, diodes, transistors, LEDs, etc. but that’s not always needed. Sometimes, you just want a way to bring a cable out with a decent connector.

The way to do that is to solder these 4 jumpers to connect everything straight through:

Dsc 1907

Now, all you need is a cable. But beware – this one isn’t what it seems:

Dsc 1906

It only has the middle two wires connected:

Dsc 1911

Not much we can do with those: they are +3V and GND on the Utility Plug!

The way to spot them before cutting the wire, is to look carefully at the connector:

Dsc 1908

As you can see: 4 gold-plated pins on the outside (i.e. RJ-11), but only 2 wires have acually been pushed into the connector. Here’s one I made myself, using modular plugs and flat telephone cable from a local DIY shop:

Dsc 1909

Now I get DIO and AIO as well (possibly altered by the circuits added to the Utility Plug):

Dsc 1910

To better support wired-through scenarios, I’ve added a “Pack of 4” variant of the Utility Plug to the shop:

Dsc 1904

It omits the extra components, so you just need to close those 4 solder jumpers. Note that there was no room on these boards for mounting holes – best way is probably to hot-glue them to a stable base plate of some kind.

Sleepy class

In AVR, Software on Sep 4, 2010 at 00:01

To make it simpler to experiment with the very low-power states of the ATmega on the JeeNode, I’ve moved some code to the Ports library.

It’s all wrapped up into a new “Sleepy” class:

Screen Shot 2010 09 03 at 14.07.54

See the powerdown_demo.pde and radioBlip.pde sketches for examples of use.

This class is documented in the Café:

Screen Shot 2010 09 03 at 14.23.39

FWIW, I’m also evaluating the Redmine system as a way to bring the code repository, Café docs, issue tracker, and Talk forums all into one context:

Screen Shot 2010 09 03 at 14.24.50

That site is still experimental, so I’m not making it public yet. The one missing feature holding me back is that Redmine does not have a good spam prevention mechanism, such as Akismet. At least last time I looked. But all in all, this would be a great way to provide a place to describe projects, fill in the documentation, and track all code changes and bugs collaboratively. If you’d like to have a sneak preview, or want to have a place to describe your project, or perhaps would like to help with the fairly gigantic task of getting a good documentation section going, please email me.

I’ve started copying over some content, but it’s going to take a while before everything has been brought over and adjusted. Both the old and the new system use Markdown, but there are always them pesky little details…

Anyway, back to the topic at hand – enjoy the low-power options, and please consider sharing your explorations, findings, and inventions in the Talk discussion forums.

JeeNode goes solar

In Hardware on Sep 3, 2010 at 00:01

Now that ultra low-power options are coming into reach for JeeNodes, lots of new scenarios can be explored.

The most obvious one is probably a solar-powered JeeNode … so meet the latest new node #5 at Jee Labs:

Dsc 1875

It also uses a 0.47 F supercap, same as yesterday, but now hooked up to a small 4.5 V solar cell (which can only deliver a few mA in bright sunlight), and a Schottky diode between the solar cell and the capacitor.

Here’s the “power supply” in more detail:

Dsc 1876

As you can see, the solar cell is tiny. A few square cm’s only. In fact, it takes quite some time for it to charge the supercap to acceptable levels. I had to place the cell in moderately bright sunlight for about half an hour to get to a 4 Volt charge. It was inching along, taking several seconds per 0.01 V increase.

To avoid losing all that charge right away in the power-up cycle, I modified the ATmega’s fuses to start in 258 clock cycles after power down, and to start up within 4.1 msec after reset. That way it will start up as quickly as possible at all times. The 258 CK setting is particularly nice, because it means the ATmega can get out of total power down within about 16 µs, fast enough to respond to a byte RX/TX interrupt from the RFM12B!

Does it work? Check it out: after connecting the JeeNode with the “radioBlip.pde” sketch pre-loaded… away it went – sending one packet every 60 seconds as node 5:

    OK 5 1 0
    OK 5 2 0
    OK 5 3 0
    OK 5 4 0

While exposed to the current partly-sunny / partly-cloudy light levels, the voltage on the supercap is still increasing. This is good – it means there’s a surplus of solar energy, even with these transmissions going on. That extra energy will be crucial if this thing is to last through the night…

If everything works out, this little Arduino-compatible bugger could well be the first JeeNode to become completely autonomous and transmit wirelessly… forever!

Time will tell :)

Sending packets without battery

In AVR, Hardware, Software on Sep 2, 2010 at 00:01

Here’s a fun experiment…

After yesterday’s improved power-down current results, I wanted to find out how much power it really takes to send out a bunch of small packets. No acks, just periodically sending out a packet and sleeping.

Trouble is, I didn’t want to wait for a battery to run down, since that would take months or even years. Bit long to get results for this weblog, eh?

So instead, I used this little chap:

Dsc 1873

It’s a super-capacitor which can handle up to 5.5V and has a capacity of 0.47 Farad! That’s like putting a thousand 470 µF caps in parallel. Amazing stuff, in an even more amazingly small package.

Here’s a JeeNode, fitted with this new power source, to give you an idea of just how small this thing is:

Dsc 1874

The next step was to design a small sketch to test this. Here’s what I came up with:

Screen Shot 2010 08 29 at 11.57.38

Some of the code left out for brevity. Full source code can be found here.

What this demo does is send out a packet with a 2-byte payload, then sleep for approximately 1 second, then send again, etc. Until power runs out.

Sure enough, packets started coming in every second:

    OK 4 0 0
    OK 4 1 0
    OK 4 2 0
    OK 4 3 0
    [...]

I expected it to send out say 100 packets or so, before the charge in the 0.47 F supercap would run out.

Guess how far it went…

    [...]
    OK 4 178 28
    OK 4 179 28
    OK 4 180 28
    OK 4 181 28

That’s packet number … clickety, clickety … 28 * 256 + 181 = 7349 !!!

In other words, the JeeNode was able to send out well over 7000 packets, i.e. two hours of packets sent once a second.

This is fantastic. I think the secret – apart from the 3 µA powerdown mode – is that the RFM12B + RF12 driver require very little time to start up, send off a packet, and go back to sleep again. There is no ACK involved, the RFM12B is hardly ever in reception mode.

With real-world use, I expect power requirements to be considerably higher. First of all, a Room Board will draw around 50 µA, due to the on-board PIR sensor. And second, I’m going to want to use ACKs for at least the motion detector reports, so that the system has a robust mechanism for reporting motion whenever it is detected. This means putting the RFM12B in receive mode for a few milliseconds, waiting for the ACK. And repeating this process a few times if that ACK isn’t immediately received.

But still … over 7000 packets without a battery!

Update – with one packet per 5 seconds, the charge lasted 4523 packets, i.e. just over 6:15.

Update #2 – with one packet per 60 seconds, 771 packets got sent out, that’s 12:51 hours … looks like the self-discharge of the supercap is eating up the remaining energy.

Sleep!

In AVR, Software on Sep 1, 2010 at 00:01

The “powerdown_demo.pde” sketch in this recent post draws 20 µA, which surprised me a bit…

A while back, I got it down to a fraction of that, by turning off the brown-out detector (BOD) through a fuse bit on the ATmega. That’s a little circuit which prevents the ATmega from coming out of reset and doing anything if the voltage is too low.

As it turns out, you can turn off the BOD in software, but only for sleep mode. The reasoning being that there’s no point in protecting the processor from going berserk while it’s not doing anything in the first place…

Well, my code to turn off the BOD was wrong. You have to do this right before going to sleep. Here’s the updated powerdown_demo.pde sketch:

Screen Shot 2010 08 28 at 12.50.18

(correction – I mixed up my bits: change “PINB |= …” to “PINB = …” or “PORTD ^= …”)

The result?

Dsc 1872

Now we’re cookin’ again!

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…

Improved EtherNode

In Software on Jul 14, 2010 at 00:01

The EtherNode.pde sketch described in this post not so long ago has been extended a bit with some of the functionality of the RF12demo.pde sketch.

That way, an EtherNode can now also be used as sort of a replacement for RF12demo – through Ethernet i.s.o. USB: i.e. to collect data (by polling the server and scraping all new data from the home page) and to send out packets (via a GET request with a properly-formatted HTTP query string).

First of all, the configuration settings are now saved to EEPROM, so that the webserver will come back with the same settings after a restart:

Screen Shot 2010 07 13 at 23.13.11

As you can see, the “collect” mode has also been added. When enabled, the EtherNode will not reply with an ACK when receiving a packet. The issue here is that at most one node should respond with an ACK to broadcast packets. IOW, for each net group you use, you should normally have a single node running RF12demo or EtherNode with collect mode turned off. The others will be “lurking” (with collect mode enabled), i.e. they will be able to see all packets but they won’t reply.

Note: there is one other way to deal with collect mode and ACKs: if you have software such as JeeMon (or your own code) set up to explicitly generate an ACK, then again you should set collect mode on, so that the ATmega itself doesn’t generate the ACK as well. This is why this feature was called “collect mode” btw: the ATmega collects packets and passes it hrough, but it does not act as a full receiver which sends out ACKs.

Also new is that for debugging, you can now connect a serial console to see the full incoming requests:

Screen Shot 2010 07 13 at 23.12.22

The main screen hasn’t changed very much:

Screen Shot 2010 07 13 at 23.19.29

The only changes are a new link to a “send packet” page, and the fact that packets are now properly numbered from 0000 to 9999 (and then wrapping back to 0000).

The send packet page is new: it lets you send out a packet with up to 66 bytes of arbitrary data, to either a specific node, or as broadcast:

Screen Shot 2010 07 13 at 23.43.52

There is currently no way to request an ACK or send out ACKs via this mechanism. It’s just for sending out a data packet via a web request.

This is just the beginning of what’s possible with a JeeNode hooked up to Ethernet, of course. The sky is the limit, since everything else is a matter of uploading new software. Long live open source :)

What a year it’s been…

In Musings on Jul 13, 2010 at 00:01

One year ago, the first serious PCB designs were “taped out” (heh, if that isn’t an anachronism by now!) – this is when the first batch of JeeNode v3 boards was produced, with all the ports and pins that have by now become a standard around here.

One year later, there are 4 JeeNode variants and over 20 “plugs” / add-ons – all part of a happy JeeFamily :)

What’s next? Well, I don’t have a crystal ball. But I do know what’s coming next because of some recent projects behind the scenes … and I can tell you that there will be several new plugs starting mid-August.

Another announcement I’d like to make now, is that after the summer more of the production will be out-sourced (here in the Netherlands), to free my time for work on new hardware and software development.

As you probably know, Jee Labs is just me, moi, and myself – with a few great people helping out behind the scenes. The major difference with traditional companies is that I’m neither driven by a boss, nor (primarily) by revenue, but by interest. Which means that you can have a considerably larger influence on where Jee Labs is going than you might think… all you need to do is speak up, preferably in the discussion forum, and point out neat / useful / practical stuff. I won’t guarantee that I’ll follow everyone’s lead, but I’m as keen as anyone to go where the neat stuff is regarding physical computing.

Speaking of neat stuff…

Franz Achatz sent in a great email today, describing what he’s been doing, complete with pictures and screen dumps. Here’s the latest addition to his RFM12B-based WSN – a fridge sensor (posted with permission):

Dsc05480

All in a neat little box, with the GSM-type antenna sticking out:

Dsc05478

The sensor is a 1-wire Dallas sensor, to allow tracking the current temperature inside the fridge.

And here’s the software side of it, all created by Franz with the current JeeMon software:

Screen Shot Small

(Click here for the full-size image)

Given how young JeeMon currently is, I’m amazed to see just how much it can already be made to do…

The story I’d like you to take home from this is not how great JeeNodes or JeeMon are (they’re not, they are still far too young and simplistic), but how much freedom you have when everything is open source, hardware as well as software.

It’s time for me to start winding down (with 30..39°C of humid heat, it’s almost a necessity, even…). There will be one or two more queued-up posts on the weblog, and then it’ll be set to read-only mode. In fact, all of internet will become read-only a few days from now, as far as I’m concerned. I’ll be away only part of this summer, but even when I’m in I won’t respond to emails – sorry.

If you ever get bored, there are now 550 posts on this weblog – feel free to browse around, and enjoy :)

TTYL, as they say!

Serial communication vs packets

In Hardware, Software on Jul 12, 2010 at 00:01

When you hook two devices up via wires, you’ve got essentially two options: parallel, i.e. one wire for each bit you want to transmit & receive (example: memory cards inside a PC). Or serial, where information gets sent across bit by bit over only a few wires (examples: ethernet, USB, I2C). Parallel can achieve very high speeds with little circuitry, but serial is more convenient and cheaper for large distances.

Serial communication is very common. The model even carries through to the way we think about the “command line” – a stream of characters typed in, followed by a stream of output characters. Not surprising, since terminals used to be connected via RS232 serial links.

Wireless connections are also essentially serial: you rapidly turn a transmitter on and off (OOK), or you change its frequency of operation (FSK), to get the individual bits across.

But there’s a lot more to it than that.

With two devices connected together, you get a peer-to-peer setup with a link which is dedicated for them. This means they can send whenever they please and things will work. The same can be done with wireless: as long as only two devices are involved, one device can send whenever it likes and the other will receive the signal just fine (within a certain range, evidently).

With such a peer-to-peer setup, the serial nature of the communication channel is obvious: A sends some characters, and B will receive them, in the same order and (almost) at the same time.

But what if you’ve got more than two devices? Ah, now it gets interesting…

With wires, you could do this:

Screen Shot 2010 07 11 at 11.20.41

It’s easy to set up, but it’s pretty expensive: lots of wires all over the place (N x (N-1) / 2 for N devices) plus lots of interfaces on each device (N-1). With 10 devices, that would be 45 wires and 90 interfaces!

Worse still, this is very hard to use with wireless, where each “wire” would need to be a dedicated frequency band.

The solution is to share a single wire – called multi-drop:

Screen Shot 2010 07 11 at 11.24.58

Now there’s one wire, a couple of “taps”, and one interface per device. Much cheaper!

Trouble is, you’ve now created a “channel” which is no longer dedicated to each device (or “node” as it is usually called in such a context). They can’t just talk whenever they like anymore!

Whole new slew of issue now. How do you find out when the channel is available? What do you do when you can’t send something right away – save it up? How long? How much can you save up? What if someone else hijacked the channel and never stops transmitting? What if all nodes want to send more than the channel can handle? How do you get your information out to a specific node? Can all nodes listen to everything?

Welcome to the world of networking.

All of a sudden, simple one-on-one exchanges become quite complex. You’ll need more software to play nice on the channel. All nodes need the same software revision. And you’ve got to deal with being told “not now”.

Note that these issues apply to wired solution sharing the same channel (RS485, Canbus, USB, Ethernet) as well as all wireless networks.

Simple OOK transmitters used in weather station sensors just ignore the issue. They send whenever they want to, in an après moi le déluge fashion… (“what the heck, I don’t care whether my message arrives”). This usually works fairly well when transmissions are short, and when lost transmissions are no big deal – they’ll send out a new reading a few minutes later anyway.

Another aspect of this shotgun approach is that it’s a broadcast mechanism. The sending node transmits its messages into the air without interest as to who receives them, or whether there’s anyone listening even. All it needs to do is include a unique code, so that the receiver(s) will be able to tell who sent the message.

For weather sensors, the above is ok. For security / alarm purposes, it’s a bit unfortunate – missing an intrusion alert is not so great. So what the simplest systems do is to yell a bit louder: repeat the alert message many times, in the hope that at least one will arrive intact. No guarantees, yet some very common security systems seem to be happy with that level of reliability.

For more robust setups, you really need bi-directional communication, even if the payload only flows in one direction. Then each receiver can let the transmitter know when it got a packet intact.

There’s a lot more (software) complexity involved to use a channel effectively, to get data across reliably with “ACK” packets, to detect new and lost nodes, to deal with “congestion” and external causes of bad reception, etc.

With JeeNodes and wireless comms via the RFM12B module, the basic RF12 driver is somewhere in the middle between unchecked uni-directional transmission and fully checked self-adapting configurations.

So what does this all mean for the “end user” ?

Well, first of all: wireless communication can fail. A node can be out of range, or a badly-behaved machine can be sending out RF interference to such an extent that nothing gets across no matter what nodes do. Wireless communication can fail, it’s as simple as that! But with bi-directional communication, at least all nodes can find out whether things work or not.

The second key property of communication via a shared channel, is that you can’t just send whenever you like. You have to be able to either save things up until later, or discard messages to let future ones through.

This means that treating a wireless channel as a serial link is really a very bad idea. Keep in mind that the baudrate can drop to zero – this means that you must be prepared to save up infinitely much data for re-transmission. And the more you intend to re-transmit later, the longer you’re going to have to need that channel when it becomes available. That will frustrate all the other nodes trying to do the same thing.

One way around this, is to use a RF link with very high data rates. That way there will be a lot of slack when nodes want to catch up. But then you still need to be able to buffer all that data in the first place. Not a great idea for limited devices such as an ATmega…

The better way is to design the system to work well with occasional loss of packets. Take an energy meter, for example: don’t sent the pulse or rotation trigger, but keep a count and send the current count value. That way, lost packets will not affect the accuracy of the results, they will merely be updated less frequently when the RF link is down.

The RF12 driver used in JeeNodes was designed for the context of a little data, sent on a periodic basis. The difference with a serial link, is that you don’t get garbled text on the other side, but packets (i.e. chunks of data). All you need to keep in mind is that occasionally an entire packet won’t make it.

This design also deals with multiple nodes. Each incoming packet can have a “node ID” so receivers can tell everything apart. Packets never get mixed up or combined or split in any way. Each packet is a verified and consistent amount of data.

Couldn’t we implement a virtual serial link?

Well, yes – there are well-known techniques to implement a virtual circuit on top of a packet-based communication channel.

But doing so would be a bad idea, for reasons which have hopefully become clear from the above. A virtual circuit would either have to act as perfect channel (not feasible with finite data storage) or drop characters in unpredictable places. It is far more practical to impose a packet / chunk structure on the sender, and then be allowed to drop chunks with clearly-defined boundaries when the RF link is out of service or overloaded.

The moral of the story: think in packets when using JeeNode wireless comms – you’ll get a lot more done!

Update – see some good comments by John M below, about IP, UDP, TCP, and the OSI model which describes all the levels of abstraction involved with networking, and all the standard terminology.

RF12 communication

In Hardware on Jul 11, 2010 at 00:01

(This weblog post seems to accidentally have escaped into the wild a few days early…)

The RFM12(B) wireless radio modules from HopeRF, as used on the JeeNode, uses “Frequency Shift Keying” (FSK) as the way to get information across a wireless channel on the 433, 868, or 915 MHz band.

With wireless, there’s always a trade-off between speed and range. More speed, i.e. a higher data rate, lets you either get more data across in the same time or the same amount of data in less time, which might reduce battery consumption. But higher data rates require a larger frequency shift in the transmitter for the receiver to still be able to detect all the bit transitions reliably. A larger frequency shift wastes more power though (I think…). And a larger frequency shift means that the receiver has to accept more bandwidth to catch all the signal details.

Btw, another way to extend the range is to improve the antennas – see this discussion.

I’ll leave the narrow-band vs. wide-band details to the EE’s and amateur radio experts in this world, along with all the RF / HF calculations, because frankly I’m at the limit of my knowledge on these topics.

But what the above comes down to is that we’ve got essentially three parameters to fool around with when using RFM12B’s for wireless networking:

  • the data rate, which needs to be identical on both sides
  • the frequency shift on the transmitter side
  • the bandwidth on the receiver to filter out unwanted signals

Here are the relevant sections from the HopeRF RF12B datsheet:

Data rate

Screen Shot 2010 07 08 at 00.58.29

Frequency shift

Screen Shot 2010 07 08 at 01.00.43

Bandwidth

Screen Shot 2010 07 08 at 01.01.15

Screen Shot 2010 07 08 at 01.01.37

The challenge is to find “good” settings, which really depends on what you’re after. The settings used in the RF12 v3 driver are as follows:

  • Data rate = 49.142 KHz (see this discussion)
  • Frequency shift is set to 90 Khz
  • Bandwidth is set to 134 KHz

This was chosen partly on what I found around the web, and partly by pushing the data rate up while verifying that the range in the home would be sufficient for my own purposes (i.e. to reach the office from the electricty meter: a few concrete walls and floors).

It can probably be improved, but since such changes affect all the node in a net group, I never bothered after the initial tests were “good enough”.

The RF12 library now includes a new rf12_control() function, which allows making changes to these parameters. It’s a low-level option, but you could easily add some wrappers and an API to adjust parameters in a more intuitive way.

As mentioned in the forum, there’s a (Windows-only) tool to do the conversion to hex parameter settings. That ought to make it fairly easy to tweak these things, if you want to push the envelope.

Some people will no doubt be quite interested in such optimizations, so if you’ve found an interesting new combination of parameters, please consider sharing your findings in this forum discussion.

Having said all this, please keep in mind that these settings will still lead to fairly low data rates. The default data rate corresponds to ≈ 6 Kbytes/second of one-way data, assuming perfect conditions and 100% utilization (“hogging”) of the frequency band. With the official ISM rules imposed on the 868 MHz frequency band in Europe, each node is allowed to use only 1% of that rate – i.e. about 60 bytes per second of throughput! (there are no such restrictions @ 433 and 915 MHz – but 915 is not allowed in Europe).

There are alternate bands in the 860’ish MHz range, but I’ve never quite figured out what works where, so for now I’m sticking to this simple 1% rule. For day-to-day sensing and signaling purposes around the house, it’s actually plenty.

To put things into perspective: the IEEE 802.15.4 standard used by XBee’s has up to 16 channels of 250 Kbaud each at its disposal, when operated at 2.4 GHz. It’s a whole different ball game. And a different range: 2.4 GHz gets absorbed far more by walls than the sub-GHz bands (which is why mesh networking becomes a lot more important, which requires more resources, making it harder to keep overall battery consumption low, etc).

So you see: speed, range, complexity, cost – lots of tradeoffs, as with everything in this world!

Update – just got an email with a lot more info about the 868 MHz regulations (for the Netherlands, but I assume it’ll be the same across Europe). Looks like cordless headphones get 40 channels to pick from with 100% utilization (in the 864..868 MHz range), so you could pick one of those channels to avoid the 1% rule.

Support

In Musings on Jul 10, 2010 at 00:01

A couple of days ago an email titled “Au secours! LCD ne marche pas” came in, with this picture:

Foto am 29 06 2010 um 20.07 #2

Two JeeNode tinkerers at the Computational Art department of the UdK in Berlin, looking sad and disappointed. And they guessed – correctly! – that sending an email from Germany, written in English, and with a French title would draw my attention :)

The email contained enough technical details to be able to resolve everything with a quick email reply from me (it was the brightness pot, which can be finecky!).

Then this came back:

Foto am 29 06 2010 um 20.56

Yeay – they look happy again! :)

(above pictures shown with permission)

Isn’t that what support is all about? It’s easy to forget that at the end of the day, support is for (and by) people, not technology.

Thank you, Alberto and Petja, for making my day and reminding me.

Assembling the JeeSMD, part 2

In AVR, Hardware on Jul 9, 2010 at 00:01

Yesterday’s post was about assembling all the SMD components of the JeeSMD kit.

The last step is to program a sketch into the ATmega. This isn’t as straightforwards as with a JeeNode, because there’s no on-board FTDI or USB serial port hookup.

It’s fairly easy to create an FTDI connection, but even if you do, you’ll still need an ISP programmer to install a boot loader (see this recent post for some background).

So let’s hook up an ISP programmer first:

Dsc 1787

I’m using a somewhat weird setup: first of all, my cable connector was attached the wrong way around, so I always have to use this one in that weird folded-over position.

But a more important issue is that the ISP connection needs to use pins 1..6 of the 2×4-pin SPI/ISP connector on the JeeSMD. That doesn’t work with normal flat cable connectors, which assume 2×3 pins and are too wide to fit in a 2×4-pin header. My solution is to insert wire-wrap pins the wrong way around into the cable header. This effectively extends the connector, but now it won’t be as wide and it’ll fit just fine. Another solution would be to only solder 2×3 pins in the SPI/ISP position – you can always add two more pins later.

Once you’ve passed that hurdle, you can use any ISP programmer you like. There have been several posts about this on the weblog, as listed here.

Now, if you want to use FTDI, then presumably you just uploaded a bootloader into the ATmega, with all the proper fuse settings, etc. The next step then, is to somehow connect to a 6-pin FDTI header.

There are several ways to do this. The one I use nowadays, is through a Carrier Board, which includes the 6-pin FTDI connector:

Dsc 1786

The point about the FTDI connector, is that it’s almost trivial. All you need is 4 wires to GND, PWR, TX, and RX – plus a way to reset the board from the RTS signal. The clever way to generate a reset is to insert a 0.1 µF capacitor between the serial side RTS and the ATmega’s reset pin. Tiny trick, huge implications (does the name “Arduino” ring a bell?).

So how does the Carrier Board implement FTDI? Easy: it adds the capacitor. And you can easily do that yourself without a Carrier Board. Here’s how:

Screen Shot 2010 07 08 at 23.20.52

Note that what FTDI calls “RX” is connected to what the ATmega calls “TXD”, and vice versa. It’s all a matter of perspective… Once you have the FTDI connection set up, you can upload sketches using the Arduino IDE just as with any other board. All you need is a USB-BUB or some other equivalent USB-to-FTDI interface.

Congratulations: that’s all it takes to build and use the Arduino-compatible JeeSMD!

Assembling the JeeSMD

In AVR, Hardware on Jul 8, 2010 at 00:01

The JeeSMD is a kit with tiny “Surface Mounted Device” (SMD) components. SMD was designed for automated assembly with Pick & Place machines, but with a bit of patience it’s fairly easy to assemble a board by hand – see this post for an overview of what you will need.

You won’t be able to do this without at least a fine-tipped (0.4..0.6mm) soldering iron plus the following tools:

Dsc 1773

A magnifier lamp also helps, I know I couldn’t do this without one anymore!

This is a step-by-step guide on how to assemble the SMD kit, which consists of these parts:

Dsc 1772

The tiny ones (don’t sneeze!) are hardest to tell apart:

Jee smd Closeup

(thanks to Steve E for the macro shot – I just added some labels)

There are 2 10 kΩ resistors in there, although you only need one. That lets you get started without having to worry too much – if you mess up completely, just remove it and start over with the other one.

For a fantastic resource with detailed videos about hand-soldering SMD, see this Curious Inventor page.

So let’s get started. First thing to do is to apply flux wherever you’re going to solder things. The flux is essential because the flux in your solder wire will have evaporated longe before you can move your tip from the wire to the part.

I’m right-handed, so that’s how I hold my soldering iron. That leaves only my left hand for the tweezers – and no hand at all for the soldering wire:

Dsc 1774

Use your tweezers for all these parts, and don’t let go – once a 0603 part flies off or drops on the floor, your chances of finding it again are next to zero. Best is to work on a clean flat surface with everything around you removed.

The trick is to place the part and then push it down while you touch it with your iron with solder already on it. The moment a part is soldered down on at least one pin, it becomes a lot easier:

Dsc 1775

The matte “stain” you see around these pads is the flux, which has dried up but is still active.

(Remainder continued after the break…)

Read the rest of this entry »

Mail order

In Musings on Jul 7, 2010 at 00:01

One of the things I was totally ignorant about when starting out on the Jee Labs adventure, was the whole process of running an internet shop. The real physics and mechanics of it, not just some imagined “process”.

Of course it was clear from the outset that it would be about packaging and shipping stuff. But what does it come down to, on a day-to-day basis? Does it add much overhead? What do you need? Is it tedious / boring?

To start at the end: no, it’s actually fun! You get to give something to people. And a surprising number of names on the orders even come back once in a while, which tells me that someone, somewhere appreciated this and liked it enough to get even more JeeStuff. Which is very rewarding: I get to come up with stuff and make it, and then I get to “give” it to people all around the world (of course it’s a sale, but for me it still feels like giving).

So what happens after the obvious assembly of boards and packaging of kits, etc? Well, I pick all the required items, and put them in a padded envelope – with lots of sizes to pick from:

Dsc 1669

Little did I know about how much room all that “sealed air” takes up!

To keep shipping costs as low as possible, I try to always fit all the stuff into one envelope. In fact, I think I’ve only had to ship in a cardboard box once until now, although I do have some extra large envelopes (25x38x3 cm) for bigger workshop packages, etc. And there are limits to this type of frugal packaging, as someone pointed out:

Hpim0756

So much for that Carrier Box. What did that postman do? Stand on it?

This is now solved by sending Carrier Boxes in slightly larger padded envelopes, btw. Apparently that gives just enough added cushioning to prevent this sort of damage.

Oh, and here’s a fun detail – check out the Jee Labs postal scale:

Dsc 1759

Seriously. That’s how each package here is weighed, to determine how much postage to apply. I can’t think of a nicer way to honor the makers of roughly a century ago. A timeless piece of engineering, with cast iron foot and all. Here’s a puzzle for you, if you haven’t seen such a postal scale before: try to figure out how it can have two ranges: 0..50 g and 0..250 g – it’s a very clever yet simple trick, as with all great inventions.

The next step is to add postage, which is now done with these state-of-the-art (ahem) digital stamps:

Dsc 1347

The convenience being that I’ve got a whole pile of them printed in advance, for each rate – instead of having to transfer up to 8 stamps.

And then it’s off to the mailbox: a 3-minute walk if I get everything done before 17:00 (5 pm), or a 10-minute walk to a more central mailbox which gets emptied at 19:00 (7 pm).

So there you have it – a peek into the Jee Labs kitchen, eh, I mean shipping department :)

Software hell

In Software on Jul 6, 2010 at 00:01

I wish this were an exceptional tale. But it isn’t, it’s the norm…

I run a webserver for Jee Labs and a couple of other web sites and services.

Screen Shot 2010 07 02 at 23.55.19

I wanted to add support for logging the last hours of a new “#jeelabs” IRC channel. IRC might not be a good fit for me personally, but since several people have asked for it, I do want to support it. With say the last 3 days of that discussion logged as some public web-pages, I could drop by once in a while and try and add to the discussion going on at that time.

The “eggbot” system was suggested to me as a way to accomplish this:

Screen Shot 2010 07 02 at 23.55.50

Ok. Server is Debian, so “aptitude install eggdrop” should work, right? Debian is good at package management.

Wrong.

Turns out my server is still running Debian Etch, and “Etch is end-of-lifed”, as I just found out. The server ISP’s repository is gone. No updates, no installs, no security fixes, nothing.

Ok. Better upgrade Debian Etch to Debian Lenny first.

I’ve been there before, I know how to do it. Takes a few hours, but then it’s done. Server is running Lenny now, and all the main servers and services are still running fine (impressive!). This is a server in Germany, btw.

That was yesterday (well, ehm… night).

Today, quick check. Server ok. Weblog ok. Forum ok. Cool.

Oops. Ikiwiki isn’t working anymore. That’s the software I use to convert the Markdown pages into the Cafe web site. Fully scripted, based on Perl.

Ikiwiki wasn’t installed as Debian package, because the one in Debian was waaaay too old. Even on Lenny, it lags (by over a year – Debian Lenny still has 2.x, Ikiwiki has been at 3.x for some time now).

Ok, so let’s try to re-install it from source. By now, usually all my warning systems go into in high alert mode, because source installs are a different ball game (even with a “scripted” language such as Perl, how ironic!).

The Ikiwiki installation page is reassuringly short. Three steps. First two look pretty easy, right?

PERL5LIB=`pwd` PERL_MM_USE_DEFAULT=1 perl -MCPAN \
    -e 'CPAN::Shell->install("Bundle::IkiWiki")'
PERL5LIB=`pwd` PERL_MM_USE_DEFAULT=1 perl -MCPAN \
    -e 'CPAN::Shell->install("Bundle::IkiWiki::Extras")'

Wrong.

I’m now waiting for step 2 to complete.

More than 10,000 lines of text have scrolled over my terminal window so far. This sort of drivel:

Screen Shot 2010 07 03 at 00.05.40

More than two hours have passed.

More than 180 Mb of disk space has been consumed.

I’m forced to watch closely, because disk space is running low on the root partition. And this is running as superuser, so it’ll bring down the server if it fills up the disk.

Pinch me, am I really in the year 2010?

Screen Shot 2010 07 03 at 00.08.42

My complaint is not that some things are complex and require a lot of work and understanding.

My complaint is that some things are NOT complex and yet you get treated to an incredible amount of nonsense. Not to mention the fact that the problem isn’t solved until you invest in figuring out every detail of lots of different kinds of packages.

The IRC logging? Not solved yet. I can probably write a 200 line script with not a single dependency on other code which does what I need: track the last 100 hours of an IRC channel disscussion as a web page.

The Ikiwiki setup for the Jee Labs Cafe? Broken. One week of work to write a Markdown parser and generate the static pages myself, would be my estimate. Probably well under 1000 lines of code, all in a single script. Three orders of magnitude less disk space, and easier to adjust to my needs.

I’m still waiting for the second step of the Perl install to complete. It’s running a “BigInt” package without proper library support, apparently. Falling back to “Math::BigInt::FastCalc”, and running tests which take ages:

Screen Shot 2010 07 03 at 00.26.24

Could someone help me understand where a static wiki page generator needs to do cryptographically secure factorization of large primes or something?

I’m stumped. Three hours waiting now. I give up.

I’ve aborted the (non-) install. With 220 Mb disk space gone, and no clue how to get it back. Oh yes, wait, it’s all in “~/.cpan” of course – how obvious. Thank you, Ikiwiki & Perl, for breaking down. Thank you, Eggdrop, for making simple things hard. And thank you Debian Linux, for not giving me the option to go back to my previous setup.

And you know what ticks me off? All of the above can be avoided. It has been solved.

But we’re living in medieval times, clearly. Most people haven’t even heard of Starkits. What a cruel joke.

Ah, wait. Maybe I’m the only one who runs into issues like these. Maybe everyone else has servers which just work, and to which you can add functionality without getting stuck. Doing everything you want. And a breeze to upgrade, of course.

That must be it. It’s just me. I have totally unrealistic expectations.

Apologies for the rant. Normal transmissions will resume tomorrow…

Update – thanks to a backport tip in the comments, Ikiwiki is now working again.

A whole lotta boxes

In Hardware on Jul 5, 2010 at 00:01

There are tons ideas floating around here at Jee Labs (thanks in no small part to a few people joining in on the brainstorming side of things). Never a dull moment!

One direction I’d like to explore a lot further, is coming up with kits which include a really nice enclosure. Even geeks sometimes like to show off their creations in such a way that not all the guts are spilling out, with wires everywhere, and everyone else scared of messing up… or even just touching something.

Because I like to get a real physical feel for things at times, I ordered a large set of ABS enclosures in a wide range of shapes, varieties, sizes, and colors:

Dsc 1760

See? That’s what “research” looks like! ;)

Now there are many ways to create enclosures, also with acrylic panels, aluminum plates, and PCBs. Even 3D printing is starting to become an option. Not to forget my favorite foam board, and more environmentally friendly materials such as cardboard and wood.

In many cases, it’s possible to fit a project + board into an enclosure after the fact – especially if the enclosure is made specifically for that purpose. And sometimes you just get lucky and find a case which turns out to fit existing boards really well with only a little extra tweaking:

But sometimes it’s easier to pick an enclosure first, and then see whether a proper board can be designed to create a perfect fit.

This is what the JeeLink did, and it ended up becoming a really practical gadget, IMO:

Anyway, with this new “box full of boxes” at Jee Labs, I hope to be able to design more kits in the future which are not only fun to build, but also end up looking good and practical for daily use in and around the house. We’ll see.

“Making stuff fit” is often a neat puzzle. But it’s also easy to overlook details – always the crucial ones, of course.

Uploading? ISP? FTDI? Huh?

In AVR, Hardware, Software on Jul 4, 2010 at 00:01

There seems to be a fair bit of confusion in- and outside the Arduino world, and it’s spilling over to JeeNodes …

I’d like to go through some terms and buzzwords to try and clarify how to get your Arduino or JeeNode to do the thing you want it to do. I’m going to assume that you are familiar with the process of writing software (“code”), compiling it, and running it – at least on a Windows, Mac, or Linux computer (let’s call them all PC’s for now). With software for the ATmega, there are two approaches, depending on whether you use the Arduino IDE or not:

Screen Shot 2010 06 28 at 23.50.22

Both lead to the same result: a “hex” file with code that needs to be transferred from the PC to the ATmega.

The step which can be puzzling when starting out with physical computing and embedded hardware is how to get things across from your PC to that little Arduino or Arduino-like system you’re holding in your hand. And vice versa, since we often want to get results back or see some confirmation that things are working properly.

The confusion comes from the different conceptual levels involved, and things like:

  • do you mean how to connnect? – plug in a USB cable
  • do you mean how does the ATmega change its own code? – through a boot loader
  • do you mean via ISP (In System Programming)? – no, that’s normally not needed
  • do you mean via FTDI? – yes, that’s the name of the chip which is hooked up to USB
  • isn’t FTDI a connector? – yeah, that too, sort of… i.e. a 6-pin convention
  • isn’t a power + serial cable enough? – no, resets also play a key role
  • do I have to use the Arduino IDE? – no, you can also use a program called “avrdude”
  • what’s avrdude? – a program which can upload to a boot loader or an ISP programmer
  • do I need an ISP progranmmer? – nope, the boot loader does essentially the same thing
  • so why not just get rid of ISP? – because you need ISP to install the boot loader

Confused? Welcome to the club…

In case you’re wondering… the process is called “uploading” because the PC initiates this as outbound transfer:

Screen Shot 2010 06 29 at 01.51.50

To get your code (“sketch” in Arduino-speak) into an ATmega, you need three things, working together to make uploading happen under all possible conditions:

  1. An electrical connection – to power the ATmega, to communicate with it, and to restart the ATmega when it is stuck or busy doing something else.

  2. A common language / protocol – the communication must be understood by both sides, i.e. PC and ATmega.

  3. Software on both sides of the connection – Sending something when the other side isn’t listening, or listening while no-one is sending will not have the desired outcome.

Let’s go through each of these separately.

1. An electrical connection

There are several ways to make the connection. With an Arduino, or any similar board which has a USB connector, you can simply plug in the USB cable:

Screen Shot 2010 06 28 at 23.52.41

Some boards use a separate USB interface (“FTDI adapter”), allowing reuse of that interface for multiple boards:

Screen Shot 2010 06 28 at 23.54.08

The end effect is the same: a connection which powers the ATmega and allows communicating with it using a simple serial protocol. There’s also a trick in this hookup to let the PC reset the ATmega whenever it wants.

2. A common language / protocol

Ah, now it gets interesting. First thing to note is that there is no single common language / protocol!

That’s right. It all depends on what you want to do. Here we want to upload code from the PC to the ATmega. That requires exchanging “ISP commands” over the connection. But once uploading is done, we really want to reuse the connection as a regular two-way serial link.

The way it works is that the PC will reset the ATmega just before uploading new code. This activates a “boot loader” on the ATmega. Now both sides will be in sync (briefly) so they can exchange the necessary information to make an upload happen. IOW, right after reset the protocol is “ISP commands”. Once the upload is done, the connection can be reused for any protocol you like – as determined by the code that was uploaded.

3. Software on both sides of the connection

Back to the software now. We need to send ISP commands over the connection.

As you may have guessed, that’s exactly what the Arduino boot loader on the ATmega understands. When reset, the boot loader in the ATmega gets control. It waits and listens for incoming STK500 ISP commands. If none come in within a second or so, it relinquishes control to whatever was previously uploaded to the ATmega.

On the PC side, we need software which resets the ATmega and then immediately sends all the ISP commands needed to transfer and program the contents of a hex file.

This is what “avrdude” does. You can either use it implicitly from the Arduino IDE by starting an “Upload” from the menu, or you can launch it manually from the command line – avrdude needs a few options to tell it where the USB port is, what baudrate to use, the type of ATmega, the protocol to use (i.e. STK500), etc.

There’s more…

The above describes the different pieces and concepts involved in getting code into an ATmega. The beauty of it is that once it works, it really works well. Supplying power, uploading, communication, control, debugging … all with one simple USB cable. You only need to go back a few years to appreciate just how much this approach simplifies embedded development.

But there’s one important detail: the ATmega has to have a functioning boot loader. Placing a boot loader into an ATmega is a bit more complicated (and involves other things such as “fuses”). It’s a chicken-and-egg problem.

This is where the ISP programmer comes in. An ISP programmer is a fairly simple piece of hardware. In fact, you can make your own, as I’ve described in several posts on this weblog. See this and this post for some quick solutions which require nothing more than a working Arduino or JeeNode.

The good news, is that you usually don’t have to worry about installing the boot loader – it’s all done for you. Once. For the mechanism described above, you’ll never need an ISP programmer.

Some people actually prefer to use the ISP technique for uploading their sketches. In fact, sometimes you have no choice, i.e. when you need the serial port at all times, or when you can’t spare the 1..4 Kb required by the boot loader code, or when working with ATtiny chips which don’t support bootloaders.

In thoses cases, you’ll need a setup with an ISP programmer. But for most people doodling around with ATmega’s and the Arduino IDE, the above boot loader mechanism is usually very convenient and the easiest to get going.

Either way, it helps to understand the process. I hope the above was helpful in that direction.

Six lousy pins!

In Hardware on Jul 3, 2010 at 00:01

This has been a somewhat frustrating week. Just when June ended up being the biggest month ever for the shop (no doubt propelled by the special June discount), Mr. Murphy strikes again.

I’ve been waiting for several weeks now for a batch of pin headers. Had lots of them when I ordered, but since the 6-pin headers are included in just about everything, I still ended up running out sooner than expected.

This is the cuplrit – the 6-pin female port header connector:

Dsc 1764

It’s not easy to find alternatives, because I insist on having a clean 6-pin header, not some cut-off-from-a-long-strip header with very rough plastic edges on both sides.

All would have been well, if the shipment had gone its normal route. But it’s been in this country, at Schiphol Airport, for over a week now! And some lazy bum in customs seems to be sitting on it. The irony is that they do this to charge me 19% VAT – which I then get back (being a company) a few months later. More paperwork.

I’ve started shipping some packages without this item, but often even that is not an option. I can’t really send out new JeeNode kits without these headers, for example – it really wouldn’t solve anyone’s problem.

So there you go. If you’re among the several dozen people waiting for the goodies from Jee Labs to get sent to you: I’m just as eager as you to get it all resolved! – probably more, because here, all those frustrations tend to accumulate by proxy :(

Affected are: Plug Headers, JeePlug Packs, JeeNode kits, Wireless Starter Packs, and probably a few more.

(A separate issue is that the JeeNode USB won’t be back in stock for at least another week)

What can I do? Order lots and lots of them, evidently. Which is what I did (many thousands) – in the hope that this silly state of affairs won’t happen again. And offer my sincere apologies to everyone waitng.

Six lousy pins! And in two days I’ll probably be drowning in them…

Update – Just got a letter from the postal service: no invoice included. Need to supply info. By mail. So there is light at the end of the tunnel, but it’s going to take several more days. My apologies. All for some VAT, which gets refunded later. What a silly world.

Fixing a faulty ATmega (Arduino)

In AVR, Hardware, Software on Jul 2, 2010 at 00:01

After a recent post on how to repair an ATmega with a faulty (or even missing) bootloader and helping someone out with it, it occurred to me that this mechanism will work for any Arduino – not just JeeNodes.

Any 3.3V or 5V Arduino’ish system which lets you upload the isp_repair.pde sketch can be used to program any board with an ISP connector on it. The code is for ATmega328’s, because that’s all I use around here these days.

The trick is to hook up a few power and I/O lines in a specific way:

Screen Shot 2010 06 28 at 16.59.11

I’m using an Arduino Pro as example, but that’s just one of many you could use. Now connect these six wires:

  • ISP pin 1 = BLUE = Digital pin 4
  • ISP pin 2 = RED = VCC (+5V)
  • ISP pin 3 = GREEN = Analog pin 0
  • ISP pin 4 = PURPLE = Analog pin 3
  • ISP pin 5 = ORANGE = Digital pin 7
  • ISP pin 6 = BLACK = GND

Note: if your working board operates at 3.3V, then you should connect the RED wire to +3.3V, not +5V (that way signal levels and power supply will match). Also: the target board should not be connected to anything, since it will be powered through the ISP connector.

The only thing left to do is to upload the isp_repair.pde sketch to your working board, and open up a console window. You should see something like this:

That’s it – disconnect all the wires. The ATmega on the target board now has a boot loader and the standard pin 13 blink sketch. Ready again to accept whatever sketch you upload to it!

Uploading without avrdude

In AVR, Software on Jul 1, 2010 at 00:01

In the future, I’d like to upload new firmware to JeeNodes, Arduino’s, and other AVR boards through channels other than a serial port or USB. Uploading to a “slave plug” via I2C would be neat, for example.

That means the standard avrdude won’t do. Besides, after having coded various types of ISP sketches recently, I realized that the upload mechanism is really quite simple. If all you need is STK500 compatibility (as used by several ISP programmers and by the Arduino boot loader itself), then avrdude is overkill.

So here’s a demo “rig” for JeeMon which does the same thing as avrdude, i.e. upload a sketch over a serial port:

Screen Shot 2010 06 27 at 23.19.45

That removes the need to compile and install avrdude. Better still, this should work as is on every platform supported by JeeMon.

(Note: the above code is now part of JeeMon, but the source code can also be found here on the web)

Onwards!

Update – the above code has been integrated into JeeMon as new Upload rig – with dudeLoader renamed to “stk500” and readIntelHex now called “readHexFile”. Here’s a new demo “application.tcl” using this:

Screen Shot 2010 06 28 at 01.46.48

Now works with the Arduino boot loader as well as with the Flash Board ISP programmer (add “19200” arg).

(Reminder: the Jee Labs shop will be closed from July 14th through August 14th)

Going for gold with the BMP085

In Software on Jun 30, 2010 at 00:01

The recent post about adding some battery savings logic got a lot of mileage out of a very simple change – more than 10x lower average power consumption.

Warning: getting power consumption down can be an addictive puzzle!

Jörg Binkele was very helpful, and sent me a scope image, measuring the voltage drop over a 10 Ω resistor in the power line (before the regulator). Here are the first 5 seconds after powering up:

Jeenode Start tb0

As expected, the node settles into a very low power mode most of the time, with an occasional blip once a second. FYI: one vertical division is 10 mA. The little horizontal bar at both ends is probably the trigger level.

One small surprise was the startup behavior. Well, that first 18 mA bump is really a very simple bug: in the first second when the timer is running and being polled, the node is not in low-power mode. Aha, of course – my power-down logic is at the end of loop(). Ok, trivial to change – just move the end of loop() to the beginning:

Screen Shot 2010 06 24 at 11.11.51

Yup, that seems to get rid of the 1 second hump @ 18 mA. Great. I don’t have an explanation yet for the initial 1.5 seconds, but I suspect that the RF12 driver is waiting in rf12_initialize() – there is still some oddness with RFM12B initialization after power-up. Oh well – that’ll be for another day.

But now it gets interesting – I told you it’s addictive! – the image above shows that each blip is ≈ 75 msec @ 18 mA. That’s when both the ATmega and the RFM12B are turned on.

Wait a minute. Why so long? Sure, the BMP085 needs to measure temperature and pressure, and that takes several tens of milliseconds. But why keep everything else running full throttle? There’s no need.

So I rearranged the core loop a bit, in a way where all major delays would be done with as much of the node’s hardware turned off as possible (bmp085demo.pde):

Screen Shot 2010 06 24 at 19.06.55

Here is the result, again courtesy of Jörg – and then annotated:

Detail Power use

There’s lots of info here. Please note that the time scale is 25 times more detailed than the first scope image. The fun part is that you can essentially tie each power level to a line of code.

For example, the first hump is when the timer hasn’t yet reached 1000 milliseconds (since the watchdog can only take steps of at least 16 ms), so the node waits. But since it uses idle mode i.s.o. normal mode, power levels are about half of what an ATmega usually consumes. With almost no effect on the code. All we’re doing is switch off to wait for the next timer interrupt – that’s 50% of easily obtained savings.

Then there are two medium peaks when the ATmega starts the BMP085 measurements, and in between it drops back to power-down levels. Then we waste some power sending results out on the serial port (this could be removed). Lastly, when it’s time to transmit the readings, we switch on the radio, make sure it gets its job done, and then loop, again in power-down mode with the watchdog to keep us going.

If you look very closely, you can even see how long the BMP085 is busy with measuring temperature (about 4ms) and pressure (roughly 20 ms). Exactly according to specs.

The blip on the first screen is about 4 divisions on the second screen, and as you can see, the node is now asleep most of that time. That’s probably another 10-fold improvement. I wouldn’t be surprised if this node will now run a year or so on one set of AA batteries. And it’s still reporting once a second.

The moral is: match your reasoning to measured facts, and you can get a lot of power savings. Each case will be different, but it’s not rocket science.

Thanks Jörg, but please don’t send any more scope shots … I need to kick this addiction again! ;)

(Reminder: last day of the June special in the shop!)

TwitLEDs finale

In AVR, Hardware, Software on Jun 29, 2010 at 00:01

The TwitLEDs project by Myra and Jean-Claude Wippler (daughter and father) has come to a conclusion. It was great. I’ll just summarize by pointing to the six posts on the Jee Labs weblog describing the technical details, and some pictures and videos, showing the results.

Here you can see the finished TwitLEDs robot:

Dsc 1741

This is the, ehm… print head?

Dsc 1749

And last but not least, some videos. First a trial run for the print mechanism:

Next, a trial run for the vehicle, trying to stay out of trouble:

And here the result!

And one more:

Ok, that’s it. Myra and I both had oodles of fun building this and trying things out – hope you did too :)

Onwards!

(If you can’t view the videos on vimeo, see 1, 2, 3, and 4)

TwitLEDs robot, part 4

In Hardware on Jun 28, 2010 at 00:01

Today’s episode continues the description of a little robot car which “prints” Twitter messages on a glow-in-the-dark surface.

The last missing piece was the Twitter interface. I implemented it in Tcl/Tk using JeeMon.

Here’s the setup we’re using:

Dsc 0002

The idea is to search Twitter every 30 seconds for a specific search term, and then send the message into the air using a JeeLink.

This is the main code, i.e. application.tcl:

Screen Shot 2010 06 27 at 13.02.06

It uses a custom rig (i.e. module) called twitter.tcl to do the generic part, i.e. firing off HTTP GET requests with a query, and reporting results on screen as well as calling a user-specified call-back proc:

Screen Shot 2010 06 23 at 22.58.32

Here’s an example of the output, when left running for a little while – note that only messages containing the text “design” will be picked up:

Screen Shot 2010 06 23 at 23.10.39

This implementation is a bit simplistic. It will truncate each tweet and only send out the first 60 characters (to fit into a single RF12 packet).

But hey… this is proof-of-concept, after all!

Update – the arena wall is ready. Time to try it out!

Dsc 0017

Here’s a video of the TwitLEDs robot, driving around while staying out of trouble… as you can see, it really manages to do so – mostly ;)

That almost concludes this project. Tomorrow, the last installment will be posted, with final photos and videos.

RFM12B as spectrum analyzer

In Software on Jun 27, 2010 at 00:01

Intrigued by a very interesting post by “loomi” on the discussion forum, I wanted to find out more…

What he did was use the RFM12B as a crude spectrum analyzer: sweep the frequency across its entire range, and use the RSSI threshold and status bit to find out whether there is any signal on that frequency.

First of all, I added an rf12_control() function to the RF12 library, to allow access to the low-level registers of the RFM12B. This allows changing the frequency and RSSI settings, and reading out the RSSI status bit.

On the software side, a sketch is needed for the JeeNode which does the sweeping and measuring:

Screen Shot 2010 06 21 at 00.26.21

This reports one line of 476 digits 0..6 for each sweep. Each digit in this line of text represents the measured signal strength at that particular frequency.

The RSSI readout is very crude. All you can do is set a threshold and read out a single bit in the status register, telling you whether the signal is above or below the threshold. Tedious, but doable.

The fun part starts once you get to plotting this as a graph. I used JeeMon and wrote a Tcl/Tk script for it:

Screen Shot 2010 06 21 at 00.30.15

And here’s some sample output:

Screen Shot 2010 06 21 at 00.21.30

The green line is the default frequency setting of the RF12 driver.

Each sweep will add a set of black dots to the graph, but since the values are being accumulated in a “counts” array, the dots will creep higher and higher, drawing a bar as more sweeps come in. Using the current delays, one sweep takes a few seconds, so to get the above graph I had to keep JeeMon running for a few minutes.

When left running for some 15 minutes, the large bars will move out of range, but the smaller accumulated counts will now become clearer:

Screen Shot 2010 06 21 at 00.30.53

I haven’t figured out whether these values are valid, nor what could be causing all this RF activity. The peaks are fairly sharp though, so it would seem like a reasonable set of measurements.

Manual labor

In Hardware on Jun 26, 2010 at 00:01

Isn’t it gorgeous?

Dsc 1738

Yeah – a panel of 20 UART Plugs, using my little reflow grill setup. Perfect, almost no adjustments needed – just two spots which didn’t get hot enough for a shiny solder joint and one solder bridge. Trivial to fix.

Except, ehm… all the chips were soldered on the wrong way around. Yet again: when it rains, it pours!

Fortunately, it was very easy to get all the chips off (using a hot air unit) and then redo the whole thing on a new panel. But it’s a shame, most panels now work out nicely these days. And this one came out really great. Oh well.

All I need to get a handle on is yours truly… doh.

TwitLEDs robot – action shots

In AVR, Hardware, Software on Jun 25, 2010 at 00:01

As promised in the previous post, some pictures and movies of the TwitLEDs robot in action.

First another view of the robot, with the different pieces:

Dsc 1747

We don’t have the proper “arena” yet, i.e. a big fenced-off floor area covered with glow-in-the-dark paint. Instead, these first trials used two pieces of foam board, taped together. It’s not perfect because the robot keeps running off track, and because the hump between the two pieces is quite high. Foam board isn’t really suited for this: it curls up too much from the moisture in the paint. We probably should have waited a bit longer for everything to dry completely…

The inital test code just printed out its name (povGlow) and the compilation date. In the first tests, one of the LEDs wasn’t working (a software bug, not hardware), so the text isn’t quite right:

Dsc 2039

You can clearly see the fading of the letters over time. This happens very quickly, but those faded letters then remain visible for quite a while. That’s why you can still see several trial runs “printed out” on the foam board.

So the basic idea of printing with light works, as you can see!

Here is a video (sorry, not inline), showing how the robot veers to the right as I put my hand in front of it to prevent it from running off the track. Note that I’m not touching the robot, I just briefly trigger the distance sensor. The on-board LED lights up in red when the correction takes place. It’s not very smooth, but it works.

Another picture, showing the decay of the printed text brightness:

Dsc 2067

Maybe 7 pulsed blue lasers (from DVD writers, perhaps?) could be used to create even more intense blue dots. As it is, with these blue LEDs the writing is very clear – but only in a relatively dark room. With the lights on, the text becomes virtually invisible. Even though the LEDs are bright enough to be painful to look at:

Dsc 1749

The quality of this “printer” is actually pretty good, considering how simple its technology is:

Dsc 2056

Finally, a run where the robot happened to stay a bit longer on track, allowing it to display its brief message a few times. Again as video – you can see the wobbling foam board, and this thing driving like a drunken duck, leaving its trail of fading messages behind.

All that remains, is to try and get some tweets into it in real time. Stay tuned…

Several days of testing have now drained the 4 alkaline AA to the point where the robot advances noticeably slower. Looks like we’re getting no more than an hour or two out of these batteries. Which is not really surprising: the DC motors must be eating quite a bit of current, and the LEDs probably draw up to 200 milliamps or so. Self-powered autonomous motion is really hard!

TwitLEDs robot, part 3

In AVR, Hardware, Software on Jun 24, 2010 at 00:01

To continue on yesterday’s post, here is how we got a little autonomous robot going.

The main part was solved by picking the Asuro robot kit. It’s really low-end, but it has just enough functionality for this project, and at €50, it’s very affordable. In fact, Myra built a spare one because the first unit broke down. In the end, I was still able to fix it: a burnt out transistor (both H-bridges are done with discrete components!). So now we have two Asuro’s:

Dsc 1750

The nice bit about the Asuro is that it has an odometer on each wheel. IOW, there are IR LEDs + sensors to count the number of steps (8 per rev) made by the wheel, and the C library code includes logic to adjust the speed of the motor. It’s a bit crude, but because of this the Asuro can drive fairly straight. As we found out later, it has a bit more trouble doing so while driving slowly, so it’s still a bit wiggly.

But it works. Two small DC motors, some simple gears, motor axles soldered to the PCB (what a great low-cost solution), and room for an extension board. To give you an idea of how crude this thing really is: there is no on-board voltage regulator. When used with 4 alkaline AA batteries, you have to remove a jumper so the extra voltage drop over a diode gets the supply voltage down to under 5.5V …

The Asuro is full of such nifty cost-cutting tricks. It even includes a bidirectional IR link, over which new code can be uploaded. The IR link is very short-range, so it would have been insufficient for our purposes – but for quick code tweaks, the IR link works fine.

Speaking of code, here is the main avoider.c logic running on the ATmega8:

Screen Shot 2010 06 18 at 23.57.08

This is not an Arduino sketch, but I made it look a bit like one by using the same setup() and loop() functions.

This code has to be compiled with avr-gcc. The Asuro comes with several examples with Makefiles. I simply copied one and started extending it. A little optional USB-IR adapter is used to connect to the Asuro (an RS232 one is included with the Asuro kit, but I don’t have any RS232 ports). The whole setup works pretty well from the command line, especially considering that it’s a completely different setup than the Arduino IDE.

Anyway, back to the design of the TwitLEDs robot.

The challenge was to find a simple way to make this robot drive around without bumping into things. The Asuro has a row of switches at the front, but these are not very reliable, and besides: bumping and stopping and turning would mess up the LED strip being “printed” on the glow-in-the-dark paint.

So instead, we mounted a Sharp 10..80 cm distance sensor on top. It’s very easy to read out, since it produces an analog voltage, inversely related to the distance of objects in front of it.

The logic for collision avoidance is crude, but sufficiently effective: turn more and more right as you get nearer to an obstacle. The on-board LED turns from off to green to yellow to red as the distance decreases, so it’s easy to see what the robot is doing. I’ve tweaked it so that when it drives straight towards an obstacle, then turning will be quick enough to never bump into that obstacle.

Here’s the completed unit, with the Sharp proximity sensor on a little expansion board at the front, and the LED blinker glued to the side of the battery pack – the LEDs hover 1 .. 2 mm above the ground:

Dsc 1741

Myra’s idea was to have this thing drive inside a more or less circular “fence” made of corrugated cardboard. The whole area inside the fence will be made of some panels, covered with 3 layers of glow-in-the-dark paint.

There is a flaw in the current design, in that the robot can only evade an obstacle by turning to the right. If it approaches a wall obliquely from the right, it will do the wrong thing and drive straight into the wall. But we’re hoping that as long as it doesn’t over-correct, and by sending it off in a tangent, it will keep adjusting slightly to the right as it drives around and around in “sort of” circles.

More tests and tweaks will no doubt be needed.

But as it is, this thing really seems to stay out of trouble. We can let it loose in the room and it’ll veer to the right whenever it comes near an obstacle. Sometimes it veers to far, though. Again, I hope a more controlled “arena” will be sufficiently simple to keep it going.

When the robot does bump into its front switches, it turns both motors off, blinks for 10 seconds, and then starts off again. Time enough to pick it up and aim it in a different direction.

So that’s it. An autonomous unit with two independent computers, IR distance sensing, a short range IR link, and the JeeNode with a longer-range wireless RF link. Even including a JeeLink on the laptop side, the cost of all this was only slightly over €100.

Tomorrow, some pictures + movies. Gives me time to finish the Twitter link, and then on to the grand finale!

(Reminder: one week left for the June special in the Jee Labs shop!)

TwitLEDs robot, part 2

In AVR, Hardware, Software on Jun 23, 2010 at 00:01

Yesterday’s post introduced the robot Myra and I have been working on. Here’s the first part we built:

Dsc 1725

It’s basically a backplane for the LED blinker component. Or to put it differently: a simple persistence-of-vision (POV) unit, using a JeeNode, and Output Plug to drive a few LEDs. Only the output plug was soldered-in permanently. The removable JeeNode allows it to be easily programmed and re-used, and the removable LEDs allow trying out different units. This turned out to be important, because I only had a few green LEDs when starting this, and had no idea then as to what sort of LEDs would give the best POV results later on.

Myra did all the soldering. Here are the two LED mounts we ended up with:

Dsc 1745

The one on the left is the super-duper LED concoction we built as final version. The one on the right was great for initial testing.

Everything is held together with rubber bands, zip-lock ties, tape, and ample amounts of hot glue (once verified to work!) – hacking at its best, clearly:

Dsc 1742

Here’s the LED blinker with the final LED strip, side view:

Dsc 1743

Side view close-up – with the foam board cover:

Dsc 1746

Bottom view:

Dsc 1744

Seven blue LEDs, ready to shine very brightly and controlled by the JeeNode.

The software started out very simple, of course. Things like this, just to make sure it all works:

Screen Shot 2010 06 18 at 23.01.21

This is the main part of what is more or less the final twitLEDs.pde sketch:

Screen Shot 2010 06 18 at 23.03.06

I found a suitable font table by googling around a bit. This is needed to go from ASCII characters to dots-in-a-readable-pattern. No room for Unicode (don’t laugh: some tweets are in Japanese and Chinese, and they won’t show properly).

The amazing bit is that everything worked essentially on first go. It blinked! But does it blink in the proper pattern? Our first test consisted of Myra taking a long-exposure shot, as I waved this thing around in the air – with the lights off. Liesbeth tracked progress through all the shrieks and laughs… but from a safe distance :)

Dsc 1793

Yippie. It really works!

Tomorrow: driving around without bumping into things.

Something different…

In AVR, Hardware, Software on Jun 22, 2010 at 00:01

Ok, so I’ve got tons of projects on my plate to do and to finish. And tons more that are still very experimental, or haven’t even been started. Plenty to keep me busy, with the summer vacation period nearing fast.

Yet here’s something different. The timeline for this project was imposed by external factors: my daughter Myra doing a project for the last quarter of her second year at the Design Academy in Eindhoven.

She wanted to do something which triggers human interaction, and she wanted to try something with Physical Computing. “Terrific, I’ll help!” – I shouted, completely ignoring all the pending work on my own plate…

So here’s the start of a few articles about the “TwitLEDs” project we’ve been working on recently. All the basic ingredients work as I write this, but we have yet to finish the final setup and go through a last rehearsal.

What is it?

It’s a mix between a matrix printer and a persistence-of-vision (POV) display.
It’s called the TwitLEDs robot. And it’s hooked up to the internet.

Get it? No? Ok, then let me try again. I think this picture tells it best:

Dsc 2069

The idea is to have a little autonomous robot driving around, leaving messages behind on a floor covered with glow-in-the-dark paint. The messages are collected off Twitter using a configurable search term. This is done from a laptop and then sent to the robot by wireless.

There were several fairly non-trivial problems to solve here, with some experimentation needed to find a workable mix – as well as some time contraints. A few days of work would be the most I could set aside for this. Luckily, I didn’t get lost in too many dead alleys, so it worked out nicely.

Here are the pieces we used:

  • A low-cost robot kit called Asuro – based on an ATmega8, so I had all the software ready for it. In fact, I played around a bit with it a while back – as reported here.
  • A JeeNode for wireless connectivity.
  • An Output Plug to drive some LEDs.
  • Seven blue LEDs. I picked a bright one with a very focused beam (C503B-BAN-CY0C0461).
  • Glow-in-the-dark paint. Green stuff. Three coatings.
  • Some panels to create a floor. Covered with the green stuff.
  • Some cardboard to create an “arena” on the floor to contain the robot.
  • JeeMon running on a MacBook, with a JeeLink to send out the messages.
  • A fairly dark room. This just won’t work with the lights on, unfortunately.

As with every project, the first part is the hardest and the most critical success-factor: figuring out what to do, what not to do, and finding solutions within the many constraints we had to operate under. I’ll spare you the ideas that didn’t make it, and the (really neat) ideas we simply didn’t have time for.

Being the sole programmer on the team, I got to deal with all the software. Yummie! :)

The most important insight for me was that we could implement this project with three completely independent subsystems:

  • The LED blinker, driving 7 LEDs in the proper pattern, basically a POV unit (plus receiver).
  • The robot, moving around while continuously trying to stay out of trouble.
  • The server process running on the laptop, connecting to Twitter and sending messages into the air.

We started off with the LED blinker because it was a major component with few unknowns, i.e. we picked the low-hanging fruit first. Here’s a picture of it, still under construction:

Dsc 1726

More on the LED blinker tomorrow…

A small improvement to rf12_sendStart()

In Software on Jun 21, 2010 at 00:01

The RF12 driver has a function called rf12_sendStart() which – you guessed it – is used to start sending out a new wireless packet.

Yesterday’s post was about battery savings, which I implemented by going into a power-down state right after sending out a new data packet.

That code included this little detail:

Screen Shot 2010 06 20 at 03.50.41

The reason for this is that the RF12 driver works mostly on an interrupt basis – i.e. in the background. Without the delay, the node would power down before the packet had actually been sent out. Then, when waking up, the transmission would fail due to the transmitter underrun caused by this logic.

By simply waiting a bit, the interrupts can continue to take place, and all the bytes will get sent to the RFM12B and from there into the airwaves.

Totally by chance, an EtherCard software problem was reported on the Jee Labs discussion forum, which turns out to be related to this very same issue. Sure enough, adding the “delay(5);” fixed that problem as well.

This felt a bit unsatisfactory as solution, so I’ve extended the rf12_sendStart() function to support a “synchronous mode”. The change is backwards compatible, i.e. the default behavior of rf12_sendStart() hasn’t changed.

Now, if you pass 1 as fourth argument, rf12_sendStart() will wait for the packet transmission to actually complete before returning to its caller. In general, calling rf12_sendStart() in sync mode is probably a good idea. Sync mode can be used for sending data packets as well as acknowledgement packets.

So the above code can be replaced by this single line:

Screen Shot 2010 06 20 at 04.02.11

This simplifies the bmp085demo.pde sketch slightly, and it also solves the problem that the EtherCard library may occasionally lock out interrupts on the SPI bus a bit too long to keep the RF12 driver running.

The code and documentation have been updated.

Onwards!

Battery savings for the Pressure Plug

In AVR, Hardware, Software on Jun 20, 2010 at 00:01

Reducing power consumption is fairly tricky, as you can see in the many previous posts about this topic. And to be honest, I haven’t quite gotten to the point where I want to be with the Room Board. My first “major” (ahem) setup with about a dozen nodes around the house didn’t quite go as I had hoped. Most batteries were empty within a month. A few nodes are still going, but those are hooked up to power adapters…

I’d like to revisit this issue and try to improve things a bit. To make the rooms sketch perform better, and also to make the code structure a bit clearer. The current rooms code is quite complex and hard to follow.

But before messing with the rooms.pde sketch, let’s tackle something simpler: the wireless sensor node based on the Pressure Plug, as described here, and then simplified here. I’ll use that last version as starting point.

The first point to note is that to get a substantial first power reduction, you have to focus on the portion of the code where it’s spending most of the time. Which, in the case of “bmp085demo”, is here:

Screen Shot 2010 06 17 at 01.55.06

That’s right: it’s waiting for the next second to “happen”. And even with a slow’ish sensor such as the BMP085 at maximum resolution, it’s spending more than 90% of its time there… waiting!

I’ll use an approach which might be a bit surprising: let’s not change any of the current logic. The idea is that once we’ve done our thing for the current second, we can go into low power mode, as long as we make sure to get back to normal operating conditions in time for the next second.

So what we’re going to do is add some code to the end of the loop() function. It’s functionally equivalent to adding it at the start, since loop(), eh, loops – but I think it makes a better point.

The end of loop() used to look as follows:

Screen Shot 2010 06 17 at 02.01.01

I’m changing it to this:

Screen Shot 2010 06 17 at 01.43.00

IOW, at this stage all the hard work has been done. We wait a bit for all interrupt-driven I/O to complete (serial and RF12). And then we need to figure out how much time remains until the next second. The power saving happens by spending that time in power off mode.

But this requires some preparation. When inducing a comatose state like this, you have to make absolutely sure that something is still able to get you out of coma and back up and running again. This is what the ATmega’s “watchdog” is for: we set it up to wake us up in 16 milliseconds, just before entering sleep mode. And then we keep doing that until it’s almost time to take another reading. The actual watchdog interrupt handler does nothing, btw – all we want is to get back out of power down.

Note that the radio also needs to be turned off and back on again. It’s the biggest power consumer when enabled. Turning it off and going into power down mode is what lets us go from a tens-of-milliamps current drain to a tens-of-microamps current drain.

All the logic for this is located in the loseSomeTime() function, which was adapted from a slightly different version in the rooms.pde sketch:

Screen Shot 2010 06 17 at 01.42.33

And that’s about it. The average power consumption of this sensor node will go down by an order of magnitude. It’ll still be 1..2 mA, but it’s a major improvement: this node should now run 2..3 months on AA batteries. The source code for bmp085demo.pde has been updated.

I’d like to stress that such gains require very little effort for many types of sketches. All you have to do is figure out where the sketch is spending most of its time, and deal with just that part of the code. Getting into yet lower power consumption levels would require more work.

Input Plug, oh my

In Hardware, Software on Jun 19, 2010 at 00:01

More fallout from the bad ISP programmer. As reported on the forum, there is a problem with the Input Plug. Fortunately, it’s fixable in software.

The problem is that the ISP programming of the ATTiny45 chip on the Input Plug had the same problem as the recent, ehm, Murphy debácle: the fuses weren’t always set properly.

So the ATTiny starts up running at 1 MHz i.s.o. 8. And hence the timing is off when driving pulses to it to control the analog multiplexer.

The solution was to add a “fix” parameter to the InputPlug class in the Ports library. It defaults to 0 (no fix needed), but when set to non-zero, the timing is adjusted to slow down by a factor 8. That way, channel selection will take a bit longer – but at least it’ll work:

InputPlug myPlug (3, 1); // plug on port 3, slow down for wrong ATTiny fuse

This code has been added to the Ports library. There is a downside: the fix means that channel slection now takes roughly 900 µs, instead of the intended 100 µs.

Next question is: how to make sure this won’t happen again? – Answer: build a test jig, so all plugs can be tested fully before shipping. Trouble is, all Input Plugs ship as follows (this is an early hand-soldered unit):

Dsc 1732

Without headers!

My mistake was of course that I would wing it, and avoid the testing. Bzzzt. Time to build a little test contraption:

Dsc 1733

The other side is filled with 17 tiny 1 kΩ SMD resistors, creating a voltage divider with 16 different voltage levels. Soldering this was quite a challenge, btw:

Dsc 1737

And now I can take advantage of the fact that everything is gold-plated. So the following will make contact, just with the pins being pushed in and pressing lightly against the board:

Dsc 1735

I’ve been using the same trick for some time now, to test other plugs. Here’s how to connect the whole thing to one of the ports:

Dsc 1736

Below is a little readout test – a better test setup would be to simply perform the check and display a go / no go signal, but for now I’m just reporting the 16 values:

Screen Shot 2010 06 16 at 19.00.21

Sample output:

Screen Shot 2010 06 16 at 20.24.30

As you can see, the selection is now working reliably (once connected).

So that proves the bug and gives me a new tool to test Input Plugs before shipping. And of course I’ll re-flash the ATtiny45 chips on all remaining Input Plugs in stock at Jee Labs. For those already out there: you can either use the software fix, or send your Input Plug(s) back to me and I’ll fix the fuse settings to make selection snappier, as originally intended.

Problem solved. Phew.

Does it feel good to have to confess to another goof-up on my end? Of course not. But worse than that would be to keep quiet on this – and I won’t. I’m human, I make humiliating mistakes (LOTS!), I occasionally cut corners, but I do my best to learn and deal with it all. There is no doubt whatsoever in my mind that every person and company goes through these sorts of mishaps. It’s just usually not out in the open for everyone to see. Well, at Jee Labs, it doesn’t work that way – this is open source: software, hardware, goofs … e v e r y t h i n g !

Mac Mini as home server

In Hardware on Jun 18, 2010 at 00:01

Whoa, great news – the Mac Mini is getting even more energy efficient:

Screen Shot 2010 06 15 at 12.41.01

It was announced today. Here’s what the new box looks like (and no more power brick!):

Screen Shot 2010 06 15 at 12.41.20

We’ve been using the Mac Mini as our TV + audio system for several years now. It’s connected to a master/slave power switch to switch off the other components when in sleep mode (sat tuner and amplifier). Works great, although I had to replace the hard disk recently. The new one would be a great successor… one day.

Might also be an excellent option for a home server, although a SheevaPlug or GuruPlug uses even less power in idle mode (approx. 4 vs 10 Watt). But that’s more of a software decision really: Mac OS X vs. Linux.

RGB via the Dimmer Plug

In Hardware on Jun 17, 2010 at 00:01

As someone pointed out in the comments a few days ago (see? that’s what weblog comments are for!), there’s Jee Labs’ own Dimmer Plug to unload the ATmega of all PWM duties:

Dsc 1729

Hm, I really forgot all about that one… doh.

It’s a great suggestion, of course. And fortunately, it can easily be swapped into the RGB strip controller series. All I need is a slightly different JeePlug to tie things together:

Dsc 1730

The result has a 2×3 pin header which matches the one on my previous interface, so now it’s just a matter of swapping cables.

And new software, of course. Here’s a test sketch which cycles brightness and colors similar to the first test sketch:

Screen Shot 2010 06 15 at 18.42.36

Except that this no longer requires any processor attention once set. And there are a few extras: it’ll work with up to four independent sets of RGBW LED strips, and it has a “global” brightness control (currently set to max), making it easy to set up the color once, and then dim the whole shebang while keeping that setting.

Also – because it’s hardware now – the PWM happens much faster. I can’t tell the difference, but I have this hunch that our cat probably can. There’s got to be a difference between blinking at 120 Hz and 100 KHz!

I’m not sure yet which approach I’ll keep. Both software and hardware PWM work fine. Decisions, decisions…

A little GUI for the RGB LED strip

In Software on Jun 16, 2010 at 00:01

After yesterday’s post, this RGB strip control project is essentially done. Keep in mind that I’m doing this only to adjust what comes out as “white”. I’ll leave light levels and color variations up to nature, since all I need to do is look out the window…

But since wireless control is present anyway, I might as well create a little demo using the JeeMon software.

So here goes. The setup I’m using is as follows:

Screen Shot 2010 06 14 at 16.31.37

The JeeNode is configured as node 30 and the JeeLink as node 1 (in the same group). The manual way to send out a color command via serial USB is to type:

<red>,<green>,<blue>,<white>,30s

Where each of the four values are in the range 0..255 (0 = off, 255 = full on).

Now the GUI version (Mac OS X):

Screen Shot 2010 06 14 at 18.21.51

The code for this is as follows:

Screen Shot 2010 06 14 at 18.16.26

Like everything in JeeMon, it’s cross platform since it uses Tcl/Tk.

Here are the screen shots for Linux (Ubuntu) and Windows (W7, XP, 2K), respectively:

Screen Shot 2010 06 14 at 18.01.42 Screen Shot 2010 06 14 at 18.35.25

Screen Shot 2010 06 14 at 18.14.21 Screen Shot 2010 06 14 at 18.09.26

As you can see, the light gray background color was adjusted for the Mac – on some of the other platforms it needs to be darkened a bit to match the default label background.

Anyway. I’m not a GUI wizard, so this’ll have to do for now…

Remote RGB strip control

In Software on Jun 15, 2010 at 00:01

To continue this series on driving RGB strips with a JeeNode, here is a sketch which allows setting the brightness levels using PWM. It’s a bit long for a weblog post, but I thought it’d be useful, since there is quite a bit of trickery in here. Notes follow below:

Screen Shot 2010 06 11 at 23.17.29

This code does some hefty bit manipulation. The idea is to keep an array of 256 time “slots”, with bits to indicate when an I/O pin should be toggled on or off. The loop then continuously scans these slots at the rate of ≈ 32 microseconds per slot (this corresponds to roughly 120 Hz). The 8 bits in each slot map to the JeeNode’s I/O pins: bits 0..3 = AIO1 .. AIO4 and 4..7 = DIO1 .. DIO4.

A refinement is that only the first 255 of the 256 slots are scanned. This way, 0 is 100% off and 255 is 100% on.

The static “masks” array defines which setting gets mapped to which I/O pin. It depends on the way the output driver is connected to the JeeNode.

The main PWM timing loop is done fully in software. It will run slightly irregularly due to timer interrupts and RF12 driver interrupts, but the effects aren’t noticeable.

The RGBW values are stored in EEPROM, so that the LEDs come back on with the same settings after power cycling. The settings can be adjusted by sending a packet with the new values to node 30, group 5 @ 868 MHz.

This sketch could be extended to support “animations”, i.e. ramping up/down to specific levels, mood lights, etc – I’m not interested in that, I just want to be able to trim the color of my room lighting to a pleasant level of white:

Dsc 1723

All I did to adjust the strip on the right was send the following “RGBW” command out via a JeeLink:

255,140,40,120,30s

The above sketch does PWM, but this whole thing is still being turned on and off with an old-fashioned mechanical switch … if you still remember those :)

FWIW, I’m considering making a dual-channel “MOSFET Plug” – two of those could then be used to replicate this same setup for the LED strip on the left.

Tomorrow: a little GUI front end for all this.

RGB driver board

In Hardware, Software on Jun 14, 2010 at 00:01

To follow up on yesterday’s post, I made a more permanent 4-channel board for driving an RGB LED strip plus the original white LED strip already in use.

A JeeNode is used to drive these strips, using a small custom JeePlug to hook up ports 1 and 4, as well as to use the LED voltage as power source for the JeeNode:

Dsc 1717

Here is the plug in more detail:

Dsc 1718

It includes an LP2950 linear regulator to put 5V on the PWR pin, that way this thing can be used with any input voltage from 12 to 24V. Here is the bottom side:

Dsc 1719

The driver itself uses four IRLZ34N MOSFETs, three of which will be used for the RGB strip, and the other for the white strip so that it too can be controlled and even dimmed remotely:

Dsc 1715

The back side is hand-wired using sturdy copper wire, although in this case only 300 .. 600 mA is being switched per color. The 10 kΩ pull-down resistors prevent the lights from turning on in the absence of control signals.

Dsc 1716

And here’s the completed setup:

Dsc 1714

The two wires sticking out are for attaching my 12V lab power supply during testing. The other green 2-pin screw terminal is for attaching the white LED strip.

The RGB ledstrips can now be installed next to the LED strips already in use here at Jee Labs:

Dsc 1722

Here’s a trivial test sketch to turn each of the 4 colors on and off:

Screen Shot 2010 06 11 at 13.17.35

The results can be seen in this brief video.

What remains, is to write the software so this thing can be controlled via wireless. I might add an LDR to sense ambient light levels, or even a Room Board. Perhaps some basic ramp-up / ramp-down PWM logic. Or maybe I’ll just duplicate this setup and drive the two sets of LED strips I have, independently and from a single JeeNode.

Hardware is easy, it’s always the software… the code will be presented tomorrow!

Reminders: 1) June discount and 2) Jee Labs will be closed from July 14th to August 14th.

Driving an RGB strip with MOSFETs

In Hardware, Software on Jun 13, 2010 at 00:01

Another day, another project started. I have a nice 5-meter LED strip in the office, which provides indirect lighting at Jee Labs. Works fine, but despite being called “warm white”, it’s slightly greenish. Not so great…

Someone suggested adding an RGB strip next to it, to compensate for the color.

So to start off this multi-part series, I wanted to simply control RGB. This is very easy to do with three MOSFETs. I used IRLZ34N’s N-channel, since the LED strips are common anode. The circuit is trivial: source to ground, drain to LED cathode, and gate to an I/O pin. Rinse and repeat three times. I didn’t even add a pull-down resistor to the gate, though I probably should.

Here’s the circuit, fully connected to a test strip with 9 RGB LEDs using a separate 12V power supply:

Dsc 1664

I wrote a little test sketch which ramps the light levels up and down using PWM, and which goes through all the RGB combinations – using some bit fiddling:

Screen Shot 2010 06 07 at 13.17.10

The LEDs are pulsed in software, with a cycle time of 8160 µsec (32 * 255), i.e. roughly 120 Hz. No discernible flickering. A more advanced version ought to use interrupts to keep the PWM going in the background.

Here’s a video of the result – with apologies for the very low quality.

Since the JeeNode has RF on board, it will only be a small step to add wireless control. Stay tuned…

Update – Source and drain were listed the wrong way around, I’ve updated the text above.

IR trigger for Nikon camera

In AVR, Hardware, Software on Jun 12, 2010 at 00:01

Here’s a fun project: sending out infrared remote codes to takes snapshots :)

This is the code:

Screen Shot 2010 06 10 at 17.19.44

This sketch is doing everything in software, and it’s sort of pushing the limits by pulsing a TSKS5400S IR emitter LED at 38.4 KHz using software delay loops.

The timing diagram on this website was a great help to get this working in no time. Here’s another site.

With the 33 Ω resistor in series, total current through the IR LED should be somewhere between 20 and 50 mA. Since the latter is beyond the ATmega’s current sourcing capapbility, I suspect that the pin voltage will actually drop quite a bit below VCC. A transistor or MOSFET could be added for more power. As it is, this seems to trigger reliably up to about a meter away.

Here’s the setup, triggering my trusty D40 Nikon:

Dsc 1692

a self-portrait!

Lot’s of people have already done this ages ago, btw. Here’s a sketch which uses assembler to get the timing more accurate. But the above does work – the main point is to avoid digitalWrite(), which is relatively slow.

Long term decisions

In Software on Jun 11, 2010 at 00:01

This post is a question, but maybe I’m already answering it by posing the question in the first place …

The question is: what to do with the Jee Labs source code?

As you may remember, I went through a few mad gyrations recently w.r.t. setting up a community site using TikiWiki, and then quickly abandoning it again.

In the end, I’m glad I didn’t buy into TikiWiki. Too many compromises, and for my particular needs, far fewer benefits than I had originally hoped to see.

The current Jee Labs Café that has replaced it is very crude, visually, because I haven’t yet done the work to bring over the layout and style sheets from this weblog. But far more importantly, IMO, is that the information is finally organized in a sensible way – until someone tells me otherwise, anyway!

Screen Shot 2010 05 24 at 21.03.33

The pages are maintained by subversion (svn), a version control system which is well-known and widely used by software developers (as are the older “cvs” and the newer “git”), although I do find that a surprising number of people are not used to the whole idea of “source code control systems” and “code repositories”. Frankly, I couldn’t live without something like svn anymore, these days. It’s the only way to develop software and not lose your mind w.r.t. change management and long term maintenance – IMO.

Maybe I should go into the features and benefits of such an approach in another post.

My point here is that the entire Café website is managed by svn. This means that all older versions of pages, sources, documents, pictures, etc. are available. At least as importantly in this context, is that the pages can be edited by anyone with write access to the repository. It’s pretty simple: get a copy (“check out”) of the website, make changes, and write it back to the repository (“check in”). Writing is only allowed to those with a user name and password in the repository, so this is wiki-like, but not publicly writeable.

The interesting tidbit about the Café website is that all changes are automatically published on the web. I’m using ikiwiki as tool to take care of all that. Thats why all the pages for the Café can be maintained as simple Markdown text pages, and how the result ends up as HTML, with links and embedded images. I’m only using a very small subset of ikiwiki’s features, btw.

Another great side-effect of using ikiwiki is that the entire Café website consists of static web pages. No server load, inifinite scalability for free.

In practice, it’s all working out really well. I can easily update, extend, and maintain the Café website this way. And if anyone wants to participate and contribute more content for the wiki (one can always hope, eh?) then that would be very easy to fit in, since subversion can be used over the internet.

As far as I’m concerned, the daily weblog and the Café / wiki are in good shape for a long time to come.

There are two other areas. One is the Talk discussion forum, which uses bbPress. I’m not terribly excited by its functionality, nor by its (lack of) progress, but it’s holding out fine, sooo… if it ain’t broken, don’t fix it.

The fourth area of public Jee Labs activity is the source code being developed for use with JeeNodes and JeeMon. It’s been in my subversion repository for a while, then I moved it to Google Code, en then I moved it back to my subversion repository again, which is where it has been for many months now.

As fas as the repository goes, this way of managing source code works well, at least for me. But there are some sharp edges. For one, the web-browsing interface is based on ViewVC – which is a bit quirky, and which turns out to be CPU resource hog on my server. Probably just web-crawlers, constantly triggering CGI execution of the ViewVC Python scripts.

Also, I currently have no issue tracking system in place. Would be nice to get something going one day.

I’ve been looking into GitHub, which seems to attract a lot of attention (and open source projects), these days. It has git-based code repositories, with an optional svn interface, and it offers a wiki, issue tracker, and download area. Reminds me a bit of SourceForge, which seems to have fallen out of grace, these days.

My main concern with GitHub is that it’s yet another big central site, offering a mix of features and functions to attract as many developers as it can, with no guarantees that it won’t be gone a few years from now, or start doing “targeted” ads, or selling email addresses, or other nasty stuff.

There is, however, one tempting option out there: GitHub + JekyllJekyll is similar to ikiwiki, in that it takes text files (including Markdown, yeay!) and generates a website from it. Jekyll even offers a migration path for WordPress sites. The interesting bit is that GitHub supports Jekyll out of the box, and that it can be set up to work with custom DNS domains. IOW, I could merge this daily weblog, the Café, and the code repository into a single consistent system. The result could be one or two static websites (hm, I guess that rules out blog comments), fully under version control, and using the Markdown format I’ve already standardized on. Needs more thought!

As it currently stands, I think I’m going to stick with WordPress + subversion, which is rock solid and has some really nice software tools for it (like Versions on the Mac). Maybe just integrate the source code areas with the Café, and use ikiwiki to allow browsing the latest version on the web, right next to the supporting doocumentation.

It feels a bit like “going it alone” by placing everything in my own subversion repository and maintaining it all on a privately managed server, but all I can say is that a lot of what I’ve done in the past has been around a lot longer – and still is! – than some of those fads…

The web is somewhat too ephemeral for my tastes…

A Happy Ending!

In AVR, Hardware, Software on Jun 10, 2010 at 00:01

The multi-ISP programmer I built and started using some two weeks ago, turned out to be quite a nightmare. Not only were incorrectly programmed ATmegas sent out to about two dozen people, I also had to go through about 70 kits, prepared as new stock just days after I started using this programmer. Twice!

Yes, twice. Because the first “fix” turned out to be insufficient. Doh.

This was a clear case of one bug hiding another, and another, and another. Yep, four bugs: a bug in the MemoryStream class in the Ports library, a timing problem exposed by fixing that bug, and two incorrect assumptions about how the “avrdude” utility works. I’ve now got an explanation for everything that went wrong.

There’s no doubt some interesting psychology at work here … I was so proud of my idea op programming multiple ATmega’s! The main idea was to create an AVRISP-compatible unit which stores everything sent through it and then just replays the saved stream as often as needed. Trouble is, I jumped to conclusions the minute a first “run” worked. Roll the presses! Print it! Tell it to the world!

Anyway. There is a happy ending to all this!

The latest version of the isp_capture.pde sketch in the Ports library has been working properly for over a week now, programming well over a hundred ATmega’s (and it now does auto shut-down a few minutes after use):

Isp Capture Output

The last bug was a very puzzling one: everything worked, but sometimes the fuses wouldn’t get programmed. It turns out that avrdude first reads the fuses, and only sends out commands to program them if the fuses don’t match the new value. Since the programmer needs to work with brand-new as well as previously-programmed chips, the replay mechanism would have depended on the prior state of the chips: not good.

The solution is very simple: I now always program each fuse twice, with two different (valid) values. The second one will remain in force, evidently. Since the replay code was already ignoring fuse mismatch checks, this now means that even if the first setting is skipped by avrdude, the second will always be emitted.

Here is the shell script to prepare the Flash Boards:

Screen Shot 2010 05 30 at 01.35.40

So this has now become a very useful tool at Jee Labs:

Dsc 1432

I love the on-board LiPo battery: I can grab it, use it where I need it, and put it back – no wires = freedom!

For pre-loading the fuses, boot loader, and RF12demo, it already saved me a huge amount of time. Its “burn rate” is up to 500 chips/hour. And Mr. Murphy taught me some valuable lessons along the way…

And now it’s time to move on!

Repairing a faulty ATmega

In AVR, Hardware, Software on Jun 9, 2010 at 00:01

This post is being written after a pretty nasty foul-up on my part w.r.t. sending out badly-flashed ATmega chips. It’s probably too late to be of use to anyone involved in that little débâcle, but I thought I’d describe a DIY fix here in full detail anyway. I’ve simplified the code to make it even easier to use than what was described here.

So what is this about, eh?

The ATmega328 chip used in JeeNodes (and Arduino’s, and various other similar board) comes with a serial boot loader pre-loaded into the high end of its flash memory. This is arguably one the most important features that made the Arduino popular: it lets you upload a new “sketch” into the ATmega over the serial or USB port.

Lots of little details, but the point here is that the boot loader itself can’t easily be damaged, even if you load a non-functional sketch into the ATmega. Just resetting it will let the boot loader overwrite the flash memory with a new version – hopefully a better one. Basically, no matter what goes wrong, there’s always the boot loader in the ATmega to upload a new sketch to it.

There’s a chicken-and-egg problem, though: how do you get that boot loader into the ATmega in the first place? Well … you don’t. It’s normally placed there by the supplier of your ATmegas.

Since Jee Labs is one of the suppliers of JeeNodes (for Europe, and Modern Device for the US), I do need to do a little more. I use an “ISP” programmer to place that boot loader there, along with the RF12demo sketch.

But there’s really not much to all this, and this whole boot loader / ISP stuff can easily be performed by anyone. Keep in mind that’s it’s just about getting that first step right: proper fuses and the boot loader stored in flash memory. Nothing more.

All you need is a working unit and a second target unit with the ATmega that needs to be repaired (or initialized for the first time – same thing). For Arduino’s, it’s all explained at http://arduino.cc/en/Tutorial/ArduinoISP.

As it so happens, there’s now even simpler software to do this, so I’m going to describe the process in terms of using one (working) JeeNode to repair another JeeNode (note that this still should work for Arduino’s as well).

The basic idea is still the same: we need to connect 6 wires. There are 2 wires for +3V and GND and 4 wires connected to ports 1 and 4. On the target JeeNode, the wires will be connected to the ISP connector:

Screen Shot 2010 05 29 at 01.37.23

The target JeeNode will receive its power from the working JeeNode, so don’t plug it into anything. Note that this can also be done with JeeNode USBs. All we need, is to make a few connections for power and I/O.

The working JeeNode should be plugged into a USB-BUB, or something similar. Do that now, because the following wiring step can be a bit sensitive to movement.

The following six connections need to be made:

Screen Shot 2010 05 29 at 02.57.58

On the working unit, the wires or wire jumpers can be inserted into the 6-pin port headers.

On the target side, you’ll probably just have gold-plated holes for the ISP connector. The nice thing about gold plating is that it easily makes contact. So one way to hook up the wires is to insert all six as shown above, and position the whole thing in such a way that there is a slight tension on the wires – just enough to make contact.

Ok, you should now have the working unit powered up, and the target unit receiving power and signals through these 6 wires. Good, leave them alone now.

To do the actual reflashing, I’ve added an isp_repair.pde sketch to the Ports library, which does everything. Upload that sketch to the working JeeNode, and open up the console. Here’s what you should see:

Screen Shot 2010 05 29 at 02.24.05

That’s it. The target ATmega has been set up with the proper fuse settings and a boot loader. You can remove all the wires, and hook up the JeeNode to a USB-BUB. It’ll now accept sketches like any other JeeNode. Fixed!

SMD hand-soldering tools

In Hardware on Jun 8, 2010 at 00:01

I’ve been hand-soldering SMD for some time now. The reflow approach is better suited for batches and recurring work, but sometimes I don’t have solder paste stencils, and sometimes I just need to do one-off builds.

There are tons of instructions on the web. Seach for “curious inventor smd” for example, for some great videos.

First thing to note is that it’s not as hard as it seems. Soldering SMDs by hand is still just that: soldering. The only thing you have to take care of, IMO, is alignment. Once a component is soldered on in two or more places, it’s virtually impossible to adjust it. And pushing too hard, or heating far too long, just gives you lifted solder pads and broken traces, because SMD pads are not as robust as a plated-through hole. Once that little piece of copper comes off the board, you’re hosed…

Ok, here are the tools I use:

  • a soldering iron
  • tweezers
  • a flux pen
  • solder wick
  • solder
  • magnifying lamp

That’s it. I hardly ever use my hot-air soldering station. I don’t have a de-soldering unit (a soldering iron with a hole in it and air suction, basically). For lots of SMD-by-hand work, you don’t need ’em. Although for serious “rework”, you probably do.

Here’s the “Ersa i-CON nano” soldering station I’ve been using for a month or so now:

Dsc 1515

The iron is excellent. Small, and due to its construction it’s also incredible cool (yeah, in both senses):

Dsc 1516

The tip is held on with a spring. It’s clever, because that knob shields even more of the heat, and the tip sits around the heat core, absorbing every bit of heat instead of radiating it out:

Dsc 1517

The warm-up speed of this thing is incredible, it’s ready for use in under 10 seconds. The unit will fall back to 240°C when not used for a few minutes, and drops all the way back to about 45°C when left unused yet longer. It’s configurable, but in an odd way: a Windows program can write a file to a µSD card, which you then insert into the base. It’ll pick up the settings, and use them from then on. I’ve configured the presets as 280°, 320°, and 360°, respectively. For manual work (with leaded solder) I usually set it to 320°. For work on reflowed boards (using unleaded solder), I use the 360° setting.

Should have bought this ages ago. I use the smallest tip available, which is a 0.4 mm round tip. It’s slightly too pointed IMO, so the solder tends to move away from the tip due to adhesive forces. But it works well, and the heat really gets all the way to the tip. On the handle, I hardly feel any heat. I check the display to see if it’s on.

The holder is also clever. It’s some sort of shaped rubber, I think. Heavy, so it won’t slide away, nor get damaged from touching it with the iron, and the way it is shaped means that at rest the handle will cool down all the way back to room temperature.

It’s not cheap (Conrad #588374), but to me it’s worth every penny. Having said that, there are no doubt other units at a fraction of the price which should also work really well. What I’d look for: pencil-like, regulated, and no more than 40 to 60 Watt. I fell for the instant startup, the configurability, and the auto switch-off.

Here’s my previous 15 Watt Weller soldering iron, a few decades old by now (tip replaced only once, I think):

Dsc 1518

Also really nice, but slightly underpowered (ground pins and ground planes are a bit tricky, as are thick copper wires). Another difference is the lenght of the tip – I really like the Ersa’s short pencil-like dimensions.

My daughter still prefers the Weller btw, so we’re both happy now :)

Here are the other tools I use:

Dsc 1519

Not much to say about this, other than that you really should get tweezers wich were designed for this work. They become an extension of your hand. They let you pick up grains of sand, even blind-folded. Well, almost. They may not look like much, but use them gently or you’ll bend them and bring the two opposite sides out of alignment – rendering them useless. Can’t remember where I got these – DigiKey and Farnell have ’em too.

The flux pen is essential for SMD work: apply flux, place component, then solder. When fixing things, I often apply flux again. The enemies are corroded solder and corroded pads – flux takes care of both. This is Farnell #876732.

The wick is equally essential. It took me a while to learn an important lesson: shorted pins are no big deal. Just wick the solder away and everything will be fine again. Can’t get the solder off? Just add more solder first, and then use the solder wick. Snip off each piece after use, as solder wick can only be used once. The type I use is not great – it leaves an ugly brown flux residue.

And last but not least, get a magnifying glass with built in circular lighting:

Dsc 1521

Actually, my daughter prefers broad daylight and nothing between her eyes and her work. To which I can only say: 1) yeah, but she’s 21! and 2) I’m a night owl … starlight + moonlight don’t seem to cut it for me! :)

I think I got that lamp from Conrad, but I can’t find it anymore. It was under € 15, ten times cheaper than another lamp I got with a long arm. The short arm is inconvenient, but it’s more solid. The big benefit of this 3x magnifier is that it has a built in 10x close-up section. Great for very close inspection. The one drawback of this small light is that you can’t look through with both eyes, so you don’t get stereoscopic vision with better depth clues. The cover is useless, btw. I haven’t needed a microscope yet, although there are limits to what you can see with this thing.

Anyway, that’s what I’m using. The rest is patience. And practice.

EtheRBBBreadboard

In AVR, Hardware, Software on Jun 7, 2010 at 00:01

Please excuse the crazy title. This picture probably tells you more:

Dsc 1509

You’re looking at an RBBB from Modern Device, hooked up to the Ether Card from Jee Labs. The hookup is trivial, it need 6 wires: 2 for power and 4 for SPI:

Screen Shot 2010 05 29 at 04.18.26

And that’s all you need to create a webserver!

Here’s a sample screen (yep, it’s been running for almost 12 hours):

Screen Shot 2010 05 29 at 00.03.48

And here’s the code for it:

Screen Shot 2010 05 28 at 12.05.03

It presents a self-refreshing page with the “uptime”, i.e. how long the server has been running since power-up.

The code is available as “rbbb_server.pde” example sketch in the EtherCard library and is a simplified adaptation of the etherNode sketch, omitting the RF12 driver and calls, of course. It compiles to 6 Kb of code.

As with the etherNode sketch, the MAC address and IP address have to be set to suitable values in the source code before uploading it to the RBBB.

BTW… did you notice anything?

The RBBB is running at 5V. And it works. Because the Ether Card is compatible with 3.3V and 5V signals!

Which also means that the Ether Card can be used with any Arduino board. It’s not specific to JeeNodes and it’s not limited to being used with the Carrier Board, either.

The generic software for the Ether Card is contained in the “EtherCard” library, listed on the software page in the Café. It doesn’t depend on Ports or RF12 libraries, so this thing really is a completely independent product.

It just “happens” to fit gorgeously into a box alongside a JeeNode :)

So there you have it – the Ether Card can be used with just about any microcontroller setup. All it needs is a power supply of 3.6V or more, 4 SPI I/O pins, and the proper software to make it sing of course…

Onwards!

Why use acknowledgements

In Software on Jun 6, 2010 at 00:01

Yesterday’s post showed how to receive packets sent out by the “bmp085demo.pde” sketch, and report them back to the serial port. By reporting in the same format as the sender, this makes it possible to easily switch between a local direct-connect setup and a two-node wireless setup.

But there’s a bit of unnecessary complexity in there.

Note that I’m using the Easy Transmission mechanism, which is indeed easy to use – only four lines of C code is all it takes to turn a local node into a wireless node.

If you try out this setup, you’ll see that the receiver doesn’t always report packets, i.e. not every second. That’s not because it’s missing packets, but because the Easy Transmission mechanism includes logic to avoid sending anything if the data hasn’t changed.

There is a way to force sending packets with rf12_easySend.

But there’s another issue with this setup. The Easy Transmission mechanism uses acknowledgements and timers to make sure that all data arrives at its destination. If no ACK is received within one second, the data will be resent.

Trouble is, this is a bit silly: we’re sending out fresh readings every second anyway, in this setup! Why use timeouts and a retransmission mechanism, just to resend potentially outdated information in the first place?

This setup doesn’t need a retransmission mechanism, it adds no value.

In fact, we don’t even need ACKs: what’s the point of an ACK if the proper arrival at the receiver end doesn’t really matter to the sender? In this setup, the sender is going to send updated readings once a second anyway.

This is a clear case of overkill, so let’s simplify. Here is the improved sender:

Screen Shot 2010 05 26 at 22.11.57

It’s not shorter than before, because the rf12_easy* functions really are indeed quite easy and compact. But the code size is reduced a fair bit:

Screen Shot 2010 05 26 at 21.33.00

vs.

Screen Shot 2010 05 26 at 22.13.12

(Much of the remaining code size is due to the code needed for the BMP085 pressure calculations)

And here’s the receiver, which no longer sends ACKs:

Screen Shot 2010 05 26 at 22.08.15

The difference in size is due to no longer loading any transmit code:

Screen Shot 2010 05 26 at 21.38.27

vs.

Screen Shot 2010 05 26 at 22.07.28

More importantly perhaps, the receiver now reports readings once a second, including unchanged ones:

Screen Shot 2010 05 26 at 22.22.32

… and of course, that – without the ACKs – there will be about half as many packets flying through the air.

The moral of this story is: don’t include functionality if it doesn’t serve a need!

Switching from direct serial to wireless

In Software on Jun 5, 2010 at 00:01

The recent weblog post about the BMP085 sensor used on the Pressure Plug sends its readings out to the serial port once a second. It also included a few extra lines of code to send the results wirelessly via the RF12 driver. I added that code to illustrate how easy it is to go from a wired hookup to a wireless hookup with JeeNodes:

Screen Shot 2010 05 26 at 21.36.01

Sending it is only half the story – now I need pluck it out of the air again. I could have used the RF12demo sketch with – say – a JeeLink to pick up these transmissions, but then I’d get something like this back:

Screen Shot 2010 05 26 at 21.33.22

I.e. 6 bytes of raw data. One way to deal with this is to write some code on the other end of the serial port, i.e. on the receiving workstation, to decode the reported temperature and pressure values. That’s what I’ve been doing with JeeMon on several occasions. Then again, not everyone wants to use JeeMon, probably.

Another way is to simply create a special-purpose sketch to report the proper values. Such as this one:

Screen Shot 2010 06 24 at 18.42.53

Sample output:

Screen Shot 2010 05 26 at 21.27.22

I used the same format for the output as the “bmp085demo.pde” sketch, but since the two raw data values are not included in the packets, I just report 0’s for them. As you can see, the results is more or less the same as having the Pressure Plug attached directly.

The ACK logic in this sketch looks a bit complicated due to the bit masking that’s going on. Basically, the goal is to only send an ACK back if the sending node requests one. And since we assume that the sending node used a broadcast, we can then extract the sending node ID from the received packet, and send an ACK just to that node.

Tomorrow, I’ll describe how all this can be streamlined and simplified.

LCD display voltages

In Hardware on Jun 4, 2010 at 00:01

As of this month, the 2×16 character LCDs from Jee Labs are 100% suitable for 3.3V use. The previous batch was made for 5V, although the backlight can always be used at a lower voltage: it’s just a few LEDs with a current-limiting resistor after all.

But the logic level officially had to be 5V. Then again, in practice, I’ve used those LCDs with a LiPo battery without any noticeable problems.

The new LCD units are specifically for 3.3V, so both voltage jumpers on the LCD Plug should be set to +3V.

To see which unit you’re using, look on the back. These are the new 3.3V units:

Dsc 1522

Note the “33V33” suffix.

I suspect that the difference is only in a few on-board resistors. I haven’t tried running these new LCDs at 5V logic levels – they may not be up to it.

But for LiPo and 3x AA battery use, the new units will be perfect.

IC socket ≠ IC socket

In Hardware on Jun 3, 2010 at 00:01

Ok, so the JeeNode v4 kit is fine, judging from how many people have ordered them and built them. Cool, that was the whole point – a small Arduino-compatible kit with RF on board that’s easy to build and use.

As was to be expected, I ran out of IC sockets the other day. So I ordered new ones. Except, I picked a different supplier (DigiKey i.s.o. Farnell), because I thought it would simplify my life to obtain everything from as few sources as possible. Silly me…

Here’s what I got, 500 times:

Dsc 1500

Guess where it doesn’t fit?

Dsc 1503

The bent pins won’t fit through the JeeNode v4 PCB, where I used smaller holes to simplify soldering. Grrr…

There’s a solution, but it requires a bit of extra work. Take a set of flat beak pliers and flatten the pins, sort of:

Dsc 1501

Now it will fit, with a bit of juggling, while being careful not to bend any pins:

Dsc 1502

Problem solved. But I’ve learned another lesson: when things work, don’t change … A N Y T H I N G !

FWIW, I only found out about this problem after a handful of JeeNode kits had been sent out with these bent-pin IC sockets. I immediately ordered more suitable ones, which arrived the next day, and switched over to resolve the problem.

(Luckily, these IC sockets fit just fine on the Ether Card, so all it not lost…)

Mystery boxes

In Hardware on Jun 2, 2010 at 00:01

Ok, here’s a puzzle for you. A project with two boxes, but what are they for?

The first box is truly a “black box” – no connections at all, no display, no button, nothing:

Dsc 1495

Not much to see on the inside either:

Dsc 1494

The second box has a 5-way button and an LCD display:

Dsc 1497

There’s a USB connector on the bottom right, but it’s only used for charging and debugging.

There’s a bit more electronics inside this one:

Dsc 1496

Still a few wires missing, because I haven’t hooked everything up yet.

So there you have it. Both boxes are self-contained, but the project I’ll be using them for needs both. I’ll reveal the project once I’ve got the basic software going – it’s always the code that takes the most time to develop!

June Special

In News on Jun 1, 2010 at 00:01

I’ve got two announcements to make:

1. Jee Labs will be closed from July 14th through August 14th

No new posts will be published on the weblog, and no orders in the shop will be processed or sent out during one month, starting on Wednesday “Bastille Day”.

2. Special discount during the entire month of June

Discount 2010

JeeNode as web server

In AVR, Software on May 31, 2010 at 00:01

The new Ether Card add-on makes a lot of new fun stuff possible. Even with a measly 8-bit ATmega chip, it’s possible to create some pretty neat things. Like a little webserver for displaying the last received RF12 packets.

I’ve added an EtherCard library to the subversion repository, next to the Ports and RF12 libraries, etc. It’s now listed on the software page in the Café.

This is mostly the Ethernet code by Guido Socher and Pascal Stang, but I’ve moved some stuff around a bit, and kept the changes added by Andras Tucsni to make this work together with the RF12 driver.

A new “BufferFiller” class has been added, to help create web pages and such:

Screen Shot 2010 05 22 at 00.04.55

What it does is expand a PSTR given to it, by replacing $S, $F, and $E with strings copied from RAM, flash, or EEPROM, respectively. A bit like “printf” in standard C. It’s easiest to just show an example of use:

Screen Shot 2010 05 22 at 01.42.00

The $D code is expanded as integer, for convenience. And since BufferFiller derives from the Arduino’s “Print” class, all the usual “print()” and “println()” members are also available.

The above code will generate the following web page (and yes, it’s been up and running more than 3 days):

Screen Shot 2010 05 25 at 09.55.06

It’s part of the etherNode.pde sample sketch in the EtherCard library – a little web server which shows the last few incoming RF12 packets and continuously self-refreshes to present the latest info.

There’s also a configuration page:

Screen Shot 2010 05 21 at 18.46.32

The whole etherNode demo sketch is under 10 Kbyte, including both EtherCard and RF12 drivers, leaving plenty of room to implement more features.

Assembling the Ether Card

In Hardware on May 30, 2010 at 00:01

(This is going to be a long post, so I’ve split it up a bit)

Here are the steps needed to assemble the Ether Card kit, starting from this PCB:

Dsc 1433

This board is very easy to build, since it uses only through-hole parts and has relatively few components. The basic idea is to build from the flattest to the highest components. That way, when you turn the card over for soldering, you can push on it to press the component against the board.

So let’s start with the 7 resistors. Don’t mix them up, they have three different color-coded values:

Dsc 1435

Turn over the board, don’t use too much solder, make clean solder joints, and snip the wires off when done:

Dsc 1436

The important thing is to get the solder flowing into the plated-through holes.

Next, the ferrite bead (a small inductor which blocks high frequencies):

Dsc 1439

More…

Read the rest of this entry »

Using LiPo batteries

In Hardware on May 29, 2010 at 00:01

The latest revision of the JeeNode USB includes a LiPo battery charge circuit:

Screen Shot 2010 05 22 at 13.45.15

The “+5V” pin is the incoming pwoer from the USB bus, it goes directly to the MAX1555 LiPo charger. From there, the PWR line is fed, so this will normally be at 4.2V when no battery is attached. That PWR voltage in turn is fed to the on-board 3.3V regulator for the ATmega and RFM12B.

This design was chosen because it lets you very easily add a LiPo battery: simply attach it between PWR and GND. There are no switches or switch-over issues: plug-in to charge, then use unplugged as needed.

I’m going to use the Carrier Board as example, and I’m going to use a LiPo battery from SparkFun, which comes with a polarized JST plug already attached. Here is the matching socket:

Dsc 1486

What we need is a spot where this socket can be soldered on. Ah, here it is, on the PWR/SER/I2C connector:

Dsc 1487

The trouble is that the pins are not 0.1″ apart as needed here, and that the socket won’t be usable if mounted sideways. So I cut off the plastic tabs and bent the wires a bit differently (taking care not to bend too much, because they break very easily):

Dsc 1484

The result fits perfectly on the Carrier Board, with the whole setup in turn fitting very nicely in the ABS box:

Dsc 1485

I’m using an 850 mAh LiPo cell.

One point to note is that the charge current from the MAX1555 is fixed at 280 mA. The rule for LiPo battery is to charge them at no more than 1C, i.e. a 850 mAh cell shouldn’t be charged with more than 850 mA. So in this case, we’re fine, with an estimated charge time of 3..4 hours for a fully discharged battery.

IOW, don’t use this setup with LiPo batteries smaller than 300 mAh or so.

Another thing to avoid with LiPo batteries is to discharge them below about 3V. You can check rf12_lowBat() from the RF12 library once in a while. It reports when the voltage at the RFM12B drops below 3.1V, i.e. around 3.2 .. 3.3V on the LiPo. Once this happens, power down the ATmega + radio to avoid draining the battery any further.

Why all the fuss? Because LiPo batteries can burn and explode, when improperly handled. There’s a lot of energy in there, and at some point things can exceed the design limits. Search for “lipo explode” on YouTube…

There are really only two issues: 1) the short-circuit discharge current can be extremely high (20C, i.e. 17 Amps with the above unit!), so short circuits and polarity reversals must be avoided at all times. And 2), charging should be done with the proper circuitry, such as the one in the JeeNode USB.

Why use LiPo’s? Well, they are very compact for the amount of energy they store, they can be recharged over and over again, and they have a very low self-discharge rate (i.e. long shelf life when not used).

When used properly, LiPo batteries are a great way to power JeeNodes, etc.

Dear Mr. Murphy

In AVR, Hardware on May 28, 2010 at 00:01

Dear Mr. Murphy, you must have had a ball these past few days…

I goofed. Again. Big time. Well, not Toyota- or BP-scale big time, but still. It’s all your fault, Mr. Murphy!

About two dozen faulty ATmega’s were shipped as part of the JeeNode Kits. And another five dozen or so were packed into kits-in-stock:

Dsc 1505

What happened? Well, that “flashy” new multi-ISP programmer I was so proud of has a bug when the “isp_cpature.pde” sketch is used in replay mode: it doesn’t program the fuse bits properly. Whoopsy daisy. I thought I had all the scenarios covered and tested, but clearly I didn’t. Those ATmega’s are shipped running at 1 MHz, and the pre-loaded RF12demo is initializing the serial port to a totally useless 57600 / 16 = 3600 baud.

This morning (i.e. yesterday by the time this post comes out), I went through the stock of ATmegas, including those in already-packaged-and-labeled JeeNode kits, and redid the fuses and uploads. Not quite my idea of fun.

Anyway. The good news is that everyone has been contacted, and that I’ve sent out replacement ATmega’s to those people who I’m quite certain have the botched version. A few people will have run into the problem (that’s how I found out!), but most kits are probably still in transit, and will now be followed by the fixed ATmega(s) shortly.

In case I missed anyone, here are the symptoms: the LED on the USB-BUB stays on relatively long when a JeeNode kit is plugged in, there is no greeting from the pre-loaded RF12demo or there are only garbled characters, and you can’t upload to the JeeNode. The problem is only with ATmegas sent out in the past few days, no more than perhaps a week ago. JeeNode USBs and JeeLinks are not affected. If you run into exactly this problem, please email me and I’ll send you a replacement ATmega.

To make matters worse, I also mixed up some of the early Carrier Board and Ether Card orders, fogetting to include this or that. All issues reported to me have now been resolved.

Oh well, live and learn.

Now go home, Mr. Murphy, and don’t come back. Please? :)

BMP085 in high-resolution mode

In Software on May 27, 2010 at 00:01

The BMP085 is a pressure sensor, as used on the Pressure Plug:

Dsc 0735

It’s quite popular. Some people get more than one – I can only assume it’s for some sort of altitude application.

By popular demand, I’ve updated the BMP085 code to support all 4 resolution modes. There is now an optional second argument to set the oversampling:

Screen Shot 2010 05 22 at 11.45.55

Allowed values are 0..3 – the default is the same as before, i.e. 0 (no oversampling).

Sample output from the bmp085demo.pde sketch in the Ports library, adjusted to use maximum oversampling:

Screen Shot 2010 05 22 at 11.42.09

Note that the return values of some intermediate routines have been changed from 16-bit to 32-bit. The calculated results are the same as before: temperature in units of 0.1°C and pressure in Pascal (i.e. x 0.01 hPa).

Good news and bad news

In Hardware on May 26, 2010 at 00:01

You’re supposed to tell the bad news first, so…

The Carrier Board described a few days ago works nicely, along with the box, Carrier Card, and EtherCard.

BUT… I completely goofed with the optional DC power jack connector :(

With the current board, the center pin is connected to ground. Whoops! I’ve hacked it for now by rewiring stuff a bit, and leaving 2 of the 4 solder pads on the power jack unsoldered:

Dsc 1475

If you look very closely, you’ll see some black electrical isolation tape between the board and this side of the power jack. The other side of the jack looks like this:

Dsc 1476

Warning – the wires are not attached correctly in this picture. The PWR line on the top side needs to be hooked up to the rightmost pin on the DC power jack.

It all looks worse than it actually is, because the whole thing gets mounted into a box and is also held into place by the cutout in the outer wall. So the power jack can’t really move around, despite the fact that it’s only held by two solder joints on a single side.

Oh well – s…tuff happens.

And the good news is…

There are actually two much simpler and stronger workarounds for this problem, because only a single copper pad is causing the problem. The copper pad in the very corner of the board is the only one that needs to be fixed!

The first workaround is to cut the two thin traces connecting this pad with the surrounding ground plane:

Dsc 1483

Since the traces are right next to the edge of the board and very thin, all you need is a Stanley knife to cut those two traces. A V-type cut is the way to do it:

Dsc 1482

Use a multimeter or continuity tester to verify that the pad is indeed no longer connected to ground.

Voilá! Now that the corner pad has been isolated, the power jack can be soldered on in the normal way, and wired into the rest of the circuit as needed.

The second workaround is to cut the pin off from the jack itself, so it can’t touch the exposed corner pad:

Dsc 1481

Better safe than sorry, so it’s probably best to also use insulating tape, as was done above.

IOW, the incorrect power jack connection is a major glitch, but there are several effective ways to work around it. Given that not everyone will even want that DC power jack option, I’m going to stick with these PCBs.

Today is a big day

In News on May 25, 2010 at 00:01

This is weblog post number …

Fivehundred

Yes, five hundred!

If you’ve been following along, you know what I do, and why. And my views on OSH and OSS.

My motivation for the daily weblog format comes from a guy called Seth Godin, who – surprise! – writes a daily blog (for many years now). I find his never-ending stream of insights absolutely delightful and inspiring.

So what does it take to write about something I care about, day in, day out? Surprisingly little. The trick is to stop chasing quick results. And to stop chasing big results. The drive comes from within. The challenge comes from the problem. The goal is to understand and to solve. You start with a puzzle, you end up with learning something new. The journey is the reward, to quote Steve Jobs – something I profoundly agree with.

This weblog isn’t a race. To the top, more readers, fame, success, fortune, or even to get the most posts in. This weblog is a dedication, to those who explore and invent, and to those who teach and inspire. Day in, day out.

It’s a lifetime thing.

Check out the following story…


Driveby culture and the endless search for wowby Seth Godin, March 2010

The net has spawned two new ways to create and consume culture.

The first is the wide-open door for amateurs to create. This is blogging and online art, wikipedia and the maker movement. These guys get a lot of press, and deservedly so, because they’re changing everything.

The second, though, is distracting and ultimately a waste. We’re creating a culture of clickers, stumblers and jaded spectators who decide in the space of a moment whether to watch and participate (or not).

Imagine if people went to the theatre or the movies and stood up and walked out after the first six seconds. Imagine if people went to the senior prom and bailed on their date three seconds after the car pulled away from the curb.

The majority of people who sign up for a new online service rarely or never use it. The majority of YouTube videos are watched for just a few seconds. Chatroulette institutionalizes the glance and click mentality. I’m guessing that more than half the people who started reading this post never finished it.

This is all easy to measure. And it drives people with something to accomplish crazy, because they want visits to go up, clicks to go up, eyeballs to go up.

Should I write blog posts that increase my traffic or that help change the way (a few) people think?

Should a charity focus on instant donations by texting from a million people or is it better to seek dedicated attention and support from a few who understand the mission and are there for the long haul?

More and more often, we’re seeing products and services coming to market designed to appeal to the momentary attention of the clickers. The Huffington Post has downgraded itself, pushing thoughtful stories down the page in exchange for linkbait and sensational celebrity riffs. This strategy gets page views, but does it generate thought or change?

If you create (or market) should you be chasing the people who click and leave? Or is it like trying to turn a cheetah into a house pet? Is manipulating the high-voltage attention stream of millions of caffeinated web surfers a viable long-term strategy?

Mass marketing used to be able to have it both ways. Money bought you audience. Now, all that buys you a mass market is wow and speed. Wow keeps getting harder and dives for the lowest common denominator at the same time.

Time magazine started manipulating the cover and then the contents in order to boost newsstand sales. They may have found a short-term solution, but the magazine is doomed precisely because the people they are pandering to don’t really pay attention and aren’t attractive to advertisers.

My fear is that the endless search for wow further coarsens our culture at the same time it encourages marketers to get ever more shallow. That’s where the first trend comes in… the artists, idea merchants and marketers that are having the most success are ignoring those that would rubberneck and drive on, focusing instead on cadres of fans that matter. Fans that will give permission, fans that will return tomorrow, fans that will spread the word to others that can also take action.

Culture has been getting faster and shallower for hundreds of years, and I’m not the first crusty pundit to decry the demise of thoughtful inquiry and deep experiences. The interesting question here, though, is not how fast is too fast, but what works? What works to change mindsets, to spread important ideas and to create an audience for work that matters? What’s worth your effort and investment as a marketer or creator?

The difference this time is that driveby culture is both fast and free. When there’s no commitment of money or time in the interaction, can change or commerce really happen? Just because you can measure eyeballs and pageviews doesn’t mean you should.

In the race between ‘who’ and ‘how many’, who usually wins–if action is your goal. Find the right people, those that are willing to listen to what you have to say, and ignore the masses that are just going to race on, unchanged.


(Re-posted with permission)

Meet the Ether Card

In AVR, Hardware, Software on May 24, 2010 at 00:01

Yesterday’s post was a sneaky way to show you a glimpse of an exciting new addition to the always-evolving Jee Labs product range – meet the Ether Card !

Dsc 1454

It’s a low-end Ethernet extension card, with a form-factor specifically made for the Carrier Board + Box:

Dsc 1467

It is based on the good ol’ trusty ENC28J60 chip, with all the components needed to hook it up to a JeeNode (or any other unit running the SPI bus at 3.3V).

I’ve started working a bit on the software side. The Ether Card is pretty standard in every respect, with the GPL2 code by Pascal Stang and Guido Socher working just fine with it. All it needs is a different chip select pin (PB0, Arduino pin 8) and proper interrupt guards to prevent the RF12 driver from interfering.

The card has been running smoothly for days on end here. It gets slightly warm, I’d estimate some 20°C above ambient. The regulator stays cool when powered from 5V. Total current draw is ≈ 150 mA, incl. JeeNode.

The Ether Card only uses through-hole parts, no SMDs. It has been added to the shop as kit and as PCB-only version. Here’s the PCB – in glorious blue-and-gold:

Dsc 1433

Here’s a sample web server requiring under 10 Kb of flash and showing a page with the last 25 RF12 packets:

Screen Shot 2010 05 19 at 11.33.18

So there you have it. JeeNodes can now handle wireless and wired networking.

It’s going to be oodles of fun to develop software for / on / with this Ether Card!

Credits: I would like to thank Andras Tucsni, who started the ball rolling by prototyping a complete working system and implementing the chip-select and interrupt changes needed for inter-operation with the RF12 driver on SPI. Andras also wrote the demo sketch which generated the above output. Knowing that it can be done and having working sample code makes a huge difference!

In and out of the box

In Hardware on May 23, 2010 at 00:01

The last two posts about the Carrier Board and Carrier Card showed how the whole kaboodle was designed for a specific light-gray plastic ABS box:

Dsc 1463

If you just use batteries and wireless, then that’s the end of the story.

But most of the time, this needs some cutouts. Let me describe how I created a custom version with a standard low-voltage power jack and an RJ-45 connector, using just these tools:

Dsc 1480

First step is to very carefully mark the position and saw some thin slots in this thing. ABS plastic is very soft and easy to cut with a little saw like the one above:

Dsc 1468

I tend to make the cutouts too narrow, because there is no way back!

To get a clean break, I use the knife to scratch along the line where the plastic needs to break, and then bend it (oops, you’ll also need some small pliers for that):

Dsc 1469

This coutout was in the top half, for the DC jack. After some trimming with the knife, the cutout looks pretty accurate. Next one was the RJ-45 connector:

Dsc 1470

Same idea: mark, saw, scratch, and break off:

Dsc 1471

Almost there. Still a bit too narrow, and not quite deep enough – some more trimming produced this:

Dsc 1473

Ah, that’s just about perfect (the left side could still be made a tad deeper):

Dsc 1478

Finished!

Meet the Carrier Card

In Hardware on May 22, 2010 at 00:01

The companion to yesterday’s Carrier Board is the Carrier Card:

Dsc 1458

It fits exactly in the plastic case, of course:

Dsc 1459

(If you look closely, you can see a hole to screw the left half of the board to the center of the shell.)

The Carrier Card is made of two halves which can be broken apart and used separately, if needed:

Dsc 1462

Here’s another configuration:

Dsc 1461

This allows inserting all sorts of JeePlugs, and using some or all of the connectors on the lower edge of the carrier Board for more elaborate projects. Everything is on a 0.1″ grid, so this also works with perf-board, etc.

By including the PWR/SER/I2C + SPI/ISP headers and connecting everything together, up to 19 I/O pins from the JeeNode are available when a full-width Carrier Card is inserted in the lower row of five 6-pin headers.

I’m looking forward to finally setting up some of the Jee Labs projects in a more permanent manner.

Tomorrow, I’ll show how to make some nice cutouts in the side of this box. ABS plastic is fairly easy to trim manually. Really good looking rectangular cutouts in the top or bottom are no doubt a bit harder – I intend to experiment with some CNC stuff for that.

Stay tuned!

Meet the Carrier Board

In Hardware on May 21, 2010 at 00:01

Finally, all the pieces have arrived to be able to announce the Carrier Board !

Dsc 1434

It fits into a plastic box of about 70 x 125 x 30 mm, made of two identical ABS shells which click together:

Dsc 1310

The JeeNode, JeeNode USB, and JeeSMD can all be used, they are “carried” by this board, so to speak:

Dsc 1311

Tons of ways to hook up plugs to this thing. There’s a diagram with all the pinouts (PDF).

Here’s a version which has all headers soldered in – not very useful, but I had to test everything anyway:

Dsc 1315

Note that only the port headers use male pins on the Carrier Board (towards the JeeNode, that is). The PWR/SER/I2C and the SPI/ISP headers both use pins with the opposite orientation. This was done because the ISP header is more useful as pins on the JeeNode, and to avoid confusing the PWR/SER/I2C header with ports, since both types use 6 pins.

More related news tomorrow…

A subtle RF12 detail

In Software on May 20, 2010 at 00:01

Someone recently emailed about a baffling problem when trying to get two JeeNodes to alternately transmit and receive. It turns out that there is a subtle aspect to calling the rf12_canSend() routine in the RF12 driver, which really needs to be clarified.

The basic idea is to have two nodes running the same sketch. Each of them broadcasts a small packet every 3 seconds, and displays incoming data the rest of the time.

I used my favorite LED debugging technique to create a simple setup with two JeeNodes:

Dsc 1456

The idea is to blink the red LEDs on each send, and the green ones on each receive. Here’s a first attempt which doesn’t do what you’d expect:

Screen Shot 2010 05 17 at 17.40.42

There’s one minor and one major problem with the above code.

The minor problem is that since sending takes place in the background, you’ll probably not see the send LED blink at all: it’s only lit for a few microseconds. The same holds for the receiving end, although there it’ll probably be visible because serial I/O takes some time. The solution for this little problem is to insert delays so the LEDs stay on longer.

But the big problem with the above code is that it doesn’t work. Whoops!

The reason for this is that rf12_canSend gets called constantly, i.e. each time through the loop. Even when the timer hasn’t gone off, and we won’t be sending anything out.

The thing about calling rf12_canSend is that it is also being used to signal your intention to send out a packet. So when sending is possible, and rf12_canSend returns 1, the RF12 driver will stop reception and get ready to send your packet out. Which is what the subsequent rf12_sendStart will do.

The gotcha is that if rf12_canSend returns 1, then you have to also call rf12_sendStart.

How do we solve this? We can’t just exchange the calls to rf12_canSend and the timer poll, because we’d lose timer events (i.e. when the timer fires and just at that very moment rf12_canSend happens to return 0 – which it does, occasionally).

The problem can be solved by using a slight variation of the code:

Screen Shot 2010 05 17 at 17.51.10

I’ve added the complete code of this “pingPong.pde” sketch as example to the RF12 library.

Note: both nodes are set to ID 1. This isn’t a problem in this case, because the packets are sent as broadcasts. A node will never receive its own packet, since it is busy sending. With RF12, packets always go out to “everyone else but me”. When you’re only using broadcasts (and no ack’s), node IDs are irrelevant.

Reflow profiles

In Software on May 19, 2010 at 00:01

This is part 7 of my reflow controller series.

Reflow soldering is a pretty simple process. Take a PCB, add solder paste, place components, and then let the whole thing go through a controlled reflow termperature profile. As I’ve described before.

In my (limited) experience, these temperature profiles are not nearly as critical as one might expect. Just preheat the thing while staying under the melting point of solder, then ramp up and keep it all well over the melting point for a while. Not too high and not too long, so nothing gets damaged. Then let it cool down. That’s basically it.

I’m going to use the following profile to start with:

  • do nothing for 10 seconds
  • heat up to 140°C
  • stay there for at least 30 seconds
  • heat up to 170°C
  • stay there for another 20 seconds
  • heat up to 250°C
  • stay there for 15 seconds
  • turn off and open up the grill for fast cool down
  • the finished board can be removed when under 150°C or so

In code:

Screen Shot 2010 05 12 at 23.00.15

I’m staying a bit longer at the high temperature because my grill is a bit uneven in its temperature distribution. I want the cooler spots to work properly as well. Hopefully that won’t damage anything.

So how do you go from a thermostat to a reflow controller? Simple: implement the profile. I added a RunProfile proc, which keeps calling itself over and over again, so it behaves like a background process. Its task is to adjust the target variable over time to match the requested reflow profile. When a step has been completed, it will be removed from the front of the profile list:

Screen Shot 2010 05 12 at 23.02.44

RunProfile is called in start, right after calling InitPlot.

Ok, let’s try it:

Screen Shot 2010 05 13 at 00.10.50

Hey, this is starting to look like something!

I changed the colors a bit and am now also plotting the target temperature for reference.

Latest source code available here.

But all is not well. While trying this out, I noticed that the current setup hangs once in a while. No more incoming data, so the plot and the control stops. I suspect that there’s an occasional conflict between sending out OOK commands and handling incoming packets – perhaps a bug in RF12demo. I worked around this by omitting all the redundant OOK commands.

There was also another case where the last temperature target was set, but the heater wouldn’t get turned on, i.e. HeaterControl returning 0.

So… progress, but not finished yet!

Multi-ISP programmer

In AVR, Hardware on May 18, 2010 at 00:01

This is a project I’ve been meaning to do for a long time:

Dsc 1432

It’s a portable ISP programmer which can program four 28-pin ATmega’s independently. It takes about 12 seconds to program fuses, bootloader, and RF12demo sketch into each chip, so with this unit I can essentially keep going and program some 20 chips per minute. Just what I need for yesterday’s batch of fresh ATmega’s. For reference: a USBtinyISP needs a few minutes per chip! (update: but it can be speeded up, see comments below)

Not that I need to program 1200 chips/hour! The point is that at this speed, I can now flash ATmega’s just-in-time, i.e. with the very latest version of RF12demo, etc.

This multi-ISP programmer is built from 4 Flash Boards, 1 JeeNode USB, 3 JeeSMD’s, a 450 mAh rechargeable LiPo battery, and a couple of ZIF sockets, resonators, and resistors. I’ve got roughly a dozen more ZIF sockets for the shop of there is interest. Also some 6-pin IDC headers and flat-cable.

The unit uses the capturing ISP programmer sketch and is very simple to use: plug the JeeNode USB in and use it as a normal AVRISP programmer @ 19200 baud. Use as many programming steps as you want. When idle for 3 seconds, the process stops – blinking the LED twice. Then exchange its Flash Board with one of the others and repeat the process until all flash boards have been set up.

From then on it can also work in battery-powered mode: insert chip, press button, wait for LED to start blinking, then rinse and repeat. Total current draw will be well under 90 mA, so this programmer should get over 5 hours of autonomy on one charge – up to 6000 chips… :)

The programmers are independent, so I can upload different contents in each of them. I’ve labeled each flash board to be able to do this without mixing things up.

The JeeNode USB v3 powers all the boards and includes the LiPo charge circuit, so the battery can be recharged by simply plugging it in. There’s a slide switch to disconnect the LiPo battery.

Some more build pictures. As you may have noticed, there is no connection from the 2×3-pin ISP header to the ZIF socket. That’s because I wired those up from below by using stacking headers for 2 of the 4 ports:

Dsc 1422

Here is the other side, wired up manually with wire-wrap wire. I’ve since covered it up a bit to avoid accidental shorts. The risky one is a direct short between the LiPo power pins, the rest is probably harmless.

Dsc 1430

And here’s the side view:

Dsc 1431

I’m looking forward to using this thing: swap chip, push button, swap chip, push button, … how convenient!

New ATmega batch

In AVR, Hardware on May 17, 2010 at 00:01

At last, 250 new ATmega328’s came in from DigiKey:

Dsc 1419

You may not have noticed, but in these past months there has been a major shortage of ATmega328 chips – everywhere. Once that happens, people start stockpiling, driving the shortages and delays up yet further, etc.

That’s 250 chips to intitialize with a boot loader + RF12demo sketch! Kinda illustrates my need for a good ISP programmer setup, eh?

There’s a substantial amount of capital investment involved in this stuff, so I’ve been cautiously moving about while trying to keep all the essential items in stock for the shop. So far, so good, mostly. But this batch sure is welcome… one less thing to worry about.

Onwards!

Temperature control

In Software on May 16, 2010 at 00:01

This is part 6 of my reflow controller series. Let’s see if we can get the reflow grill to a stable 150°C.

It’s not trivial: this grill has a slow startup time and a very noticeable lag in its response curve. Turning on the grill and turning it off at 150° is not the way to do it, since the stored heat will lead to a huge overshoot.

The proper way to do this is to use a PID control algorithm. PID stands for Proportional Integral Derivative. It’ll be interesting to try that, but first I want to try something simpler (actually, it is still PID, but just P and D).

The idea is to try and predict where the temperature will end up when we turn the heater off. I’ve got two relevant pieces of information for my particular grill, obtained from the last few trials:

  • The grill will heat up at about 2.5°C/sec once it gets up to speed.
  • When turned off at that rate, it appears to overshoot by about 40°.

Let’s try something easy first. Let’s find out what the grill does when turned off at 110°. I’ve added this line to the GotData proc to do so automatically:

if {$value >= 110} { set heat 0 }

Result:

Screen Shot 2010 05 12 at 17.29.53

Not bad – still some overshoot, so I’m going to assume an overshoot of 50° from now on. BTW, this is not the same as keeping the oven at a preset temperature, but it’s a start. In fact… I’m going to keep this line as a permanent safety valve:

if {$value >= 265} { set heat 0 }

It’s not essential, since the grill has a mechanical temperature cut-off as well, but that way I can be sure that this code will never try to push its heater beyond 265°C. It would have avoided yesterday’s runaway failure.

To improve on this, let’s assume that the overshoot is proportional to the heat-up rate. So if we turn off the heater while it’s heating up at 1.25°C/sec, it will overshoot by 25° – it seems plausible, since that probably means the heater hasn’t been on that long yet, so there is less “stored excess heat” in the system.

Next thing to do is to track the rate of change and base heater decisions on that. I’ve added a new HeaterControl proc which decides what to do for a given target temperature:

Screen Shot 2010 05 12 at 18.35.46

Note that heater control is simply a matter of setting the heat variable. It controls both the remote switch and the GUI checkbox, courtesy of Tcl’s built-in variable tracing facilities. This does the actual control, in GotData:

set heat [HeaterControl $value $lastv $x $lastx]

And in the start proc, this extra code will get the ball rolling:

variable target 0
after 10000 set [namespace which -var target] 150

IOW, after 10 seconds, JeeMon will attempt to maintain the grill temperature at 150°C. Let’s try it:

Screen Shot 2010 05 12 at 18.38.52

Woohoo, it works! A thermostat!

The “application.tcl” source code is available here. Next step is to add a reflow temperature profile.

Controlling the oven

In Software on May 15, 2010 at 00:01

This is part 5 of my reflow controller series.

Today, I’d like to be able to remotely turn the grill on and off. To avoid having to deal directly with high voltages (220V is scary!), I’m going to use an RF controlled switch – i.e. this FS20 module:

Dsc 1428

It’s perfect here, because it operates @ 868 MHz and can be controlled directly from a JeeLink or JeeNode, and because it has an on/off button right on the unit itself (unlike these). Which is great as emergency stop – we’re going to play with serious levels of electricity, current, and heat after all.

As it so happens, the RF12demo sketch I’ve been using to receive packets from the thermocouple node also supports sending FS20 commands out of the box.

So all that’s needed is to extend the GUI a bit with a control element, and hooking that up to send the proper FS20 command out.

This requires a few extra lines in the initPlot proc:

variable heat
pack [checkbutton .h -text Heater -variable [namespace which -var heat]]
trace add variable heat write [namespace which HeatChange]

And a proc called HeatChange, for which I’ll use a bit of test code for now:

proc HeatChange {args} {
  variable heat
  puts "heat = $heat"
}

The result is a window with an extra checkbox at the bottom:

Screen Shot 2010 05 12 at 024300

Clicking that button simply generates some test output:

heat = 1
heat = 0
heat = 1
heat = 0

Great. The GUI side is working. Here’s an updated version of HeatChange which actually sends out the proper FS20 commands:

proc HeatChange {} {
  variables heat conn
  if {$heat} {
    $conn send 54,32,1,17f
  } else {
    $conn send 54,32,1,0f
  }
}

The first 3 values are the house code and address bytes. They can be anything, because FS20 modules are configured by putting them in a special listening mode (press the button until the LED starts blinking). The next RF command sent to them will then be remembered, so that it will respond to that specific code from then on. Code 17 means ON, code 0 is OFF – that’s part of the standard FS20 protocol (see this German info page). The trailing “f” tells RF12demo to send everything out as an FS20 command.

IOW, to respond to these RF signals, put the FS20 unit in that special mode and then send one of the above commands by clicking on the checkbox in the GUI. You should now be able to manually control the remote switch.

Note: make sure you have the latest RF12demo. A nasty OOK bug was fixed a few days ago. If your JeeLink hangs: unplug, reconnect, then upload the latest code.

One more thing I’d like to do is include the heater status in the plot. That requires a few more changes. Here’s the latest “application.tcl” (I’ve collapsed the start and HeatChange code, since they are the same as before):

Screen Shot 2010 05 12 at 03.57.04

Let’s try this new setup, i.e. measuring and controlling 100% by wireless.

What I wanted to do is hook it up to my Ersa I-Con Nano temperature-controlled soldering station (with the soldering tip removed), because that would have been a great demo of how real temperature control works:

Dsc 1418

Unfortunately, that didn’t work – and drove home that there’s a real risk of fire involved in these experiments. Here’s what happened:

Screen Shot 2010 05 12 at 15.48.26

The temperature shot up to 450°C in seconds! – I think there’s a sensor in the very tip of the iron, and it wasn’t touching anything, so this heater went full blast – charring the thermocouple insulation on its way up. I switched the iron off manually, and then everything coooled off.

Second try, this time replicating yesterday’s setup:

Screen Shot 2010 05 12 at 16.02.57

Perfect. A step pulse and the response curve (grill was opened @ 175°C, like yesterday).

Warning: if you try these experiments, make sure you unplug your oven / grill / whatever when you’re done. Starting a fire while you’re tinkering with something else, or out of the house, or asleep is not a good idea…

Tomorrow, I’m going to create a feedback-control loop.

Oven temperature plot

In Software on May 14, 2010 at 00:01

This is part 4 of my reflow controller series.

Data is coming in over the serial USB connection. Quick, let’s visualize it!

There are two ways to do this: with some external tool such as Excel, or with the GUI facilities built into JeeMon.

Let’s do Excel first, because it requires less coding. Change yesterday’s “application.tcl” example to this:

proc start {} {
  set conn [Serial connect usb-A900adav 57600]
  oo::objdefine $conn forward onReceive [namespace which GotData]

  variable fd [open logfile.csv w]
  chan configure $fd -buffering line
  puts $fd "time,temperature"

  vwait forever
}

proc GotData {msg} {
  variable fd
  if {[Serial cmdParser $msg OK -node id -int1 temp]} {
    puts $fd "[Log now],$temp"
  }
}

The cmdParser function in Serial helps with decoding the “OK …” lines. It takes type arguments and variable names. In this case the node id header and an integer, to be stored in a variable called temp. The “-int1” notation means: treat the int as having one decimal, i.e. convert 123 to 12.3, etc.

Run JeeMon and it will create a “logfile.csv” file with readings (in “Comma Separated Values” format). You may have to stop JeeMon before you can open the logfile with another application.

Using “Numbers”, a Mac OS X application similar to Excel, this is what I get:

Screen Shot 2010 05 10 at 20.11.19

You can see the sensor at room temperature, heating up as I touched the thermocouple, and then cooling off again gradually.

The other approach is to create the plot with Tk, the GUI toolkit which is built into JeeMon, as I did with the OOK Scope. This is more work, but you get a plot which updates in real time.

So now let’s make a graph. I turned the grill on until it reached about 175°C, then let it overshoot and cool back down to 175°C again, and then I opened the lid. This is the result over a period of some 8 minutes:

Screen Shot 2010 05 10 at 23.16.59

Looks like this little grill will overshoot by some 40°C, and that it can heat up about 2.5°C per second. It’s only 700 Watt, which probably explains it. Should be fine for reflow, though.

This is the code I used, i.e. “application.tcl” (source here):

Screen Shot 2010 05 12 at 01.04.40

All this is standard Tcl/Tk code, as documented here if you want to explore how it works. With some elbow grease, I hope to add such basic plotting facilities to JeeMon as utility code, hiding most of the distracting details.

Tomorrow, I’m going to add remote switching to control the oven.

Setting up JeeMon

In Software on May 13, 2010 at 00:01

This is part 3 of my reflow controller series. I’ve got a remote node sending out temperature readings once a second, and now I want to do something with that data.

First step is simply to get it into JeeMon and display values as they come in.

Warning: JeeMon is not Emacs, Eclipse, or Processing. For several reasons:

  • JeeMon is portable across a far wider range of platforms. The core also works on tiny embedded Linux boards such as this one, for example.
  • I want a system which can be wrapped up, shipped, and used elsewhere without installation hassles – even cross-platform. JeeMon can do that.
  • I prefer to use the same editing environment for everything I do because I work with lots of different environments, so I use “TextMate” on Mac and fall back to “vi” on Linux.
  • JeeMon can be grown into a “big” system, but it doesn’t need to. It can also be used as bridge for numerous other tools.
  • There’s a lot to like about big environments which take care of everything, but I prefer lower-level tools which let me get under the hood and tinker.

Does that make JeeMon primitive? I don’t think so. Infancy: yes. Limited scope: yes (so far). One-man activity: yes (so far). Perfect: nope (nothing ever is). Fit for its intended purpose: you bet!

All good things come in three, so to work with JeeMon, you need three things:

  • The JeeMon runtime, a single executable file.
  • A programmer’s editor. Pick your favorite. Get a good one. It’ll change your life, as developer.
  • Willingness to figure out how to glue things together using the Tcl programming language.

Let’s get started.

1. Set up the tools

There are JeeMon binaries for Windows, Mac OS X, and Linux as ZIP files, 2..3 Mb each:

Download the one you need, unpack, and you should end up with an executable called “JeeMon”. Feel free to rename it to “jeemon” (lowercase) or even “jm”. These files are 100% open source, but they’ve been wrapped up into single-file executables to get going fast. See the JeeMon page for more background info on the technology used inside JeeMon.

As for which programmer’s editor to use, you’ve probably already got a preference. It doesn’t matter what it is – stick with it and learn it well, is all I can say. A good editor lets you find references and definitions, colorize your source code, compare file versions, lookup documentation, create boilerplate templates, interface with a version control system, and much much more.

2. Get organized

This is going to be a moving target. I’m still exploring the best way to manage code and data, so that it is easy to use in the editor, in the Arduino IDE, and with JeeMon.

The Arduino IDE already sort of imposes a structure to use for its libraries and sketches. Fine.

We just need a good place for JeeMon. I suggest creating a new folder called “JeeMon”, right next to your “Arduino” sketches folder. On my Mac, that happens to be the Documents folder. This is where the above JeeMon executable should be placed.

Here’s a mock-up of the folder structure I have, when following the above guidelines:

Screen Shot 2010 05 09 at 17.42.47

It should be fairly similar on Windows and Linux, I expect.

3. Tie everything together

This is where the real work starts. We need to tell JeeMon how to hook up to the JeeLink, and what to do with incoming packets once connected.

Everything in JeeMon is always driven from a file called “application.tcl”. For this first trial, we can just create that file next to the JeeMon executable itself. Create a file called “application.tcl” with the following contents:

proc start {} {
    array set ports [SysDep listSerialPorts]
    parray ports
    vwait forever
}

In prose: call the listSerialPorts function in the SysDep module, and store the results in an array called ports. Then print that array. Then just stop and wait (but don’t exit, because then the output would be gone too).

In JeeMon, modules are called “rigs” btw – SysDep is a built-in rig. The above “application.tcl” file is also a rig. Once initialized, the system executes “application start” as its very last step. Which is how the “start” procedure in the above “application.tcl” file gets control. There’s no magic and very little syntax. Just some conventions.

Launch JeeMon. Sample output here, with three JeeNodes / JeeLinks hooked up:

ports(usb-A8007UsI) = /dev/tty.usbserial-A8007UsI
ports(usb-A900ad5m) = /dev/tty.usbserial-A900ad5m
ports(usb-A900adav) = /dev/tty.usbserial-A900adav

Your output will be different. The info you need to extract from the output is the connection name of your JeeLink. In my case it is “usb-A900adav”, so that’s what I’ll use in the following examples.

Stop JeeMon.

Replace the contents of “application.tcl” with the following code, but use the name of your interface in that second line, of course:

proc start {} {
    Serial connect usb-A900adav 57600
    vwait forever
}

In prose: call connect in the Serial rig, then wait forever. Communication takes place in the background.

When you start JeeMon again, you should see some output similar to this:

22:04:30.328        . (adav) [RF12demo] _ i31 g6 @ 868 MHz 
22:04:30.342        . (adav) DF I 42 4
22:04:30.343        . (adav) Available commands:
[...]

That’s output from the JeeLink. When the thermocouple node is turned on, you should see its packets being reported. Sample output:

22:04:34.348        . (adav) OK 33 209 0
22:04:34.350        . (adav)  -> ack
22:04:35.346        . (adav) OK 33 212 0
22:04:35.348        . (adav)  -> ack
22:04:36.344        . (adav) OK 33 206 0
22:04:36.346        . (adav)  -> ack
22:04:37.341        . (adav) OK 33 209 0
22:04:37.343        . (adav)  -> ack

Not much to write home about. But now you’ve got all the pieces in place to start doing more interesting stuff. GUI, networking, webserver, database, it’s all there in JeeMon, waiting to be activated and combined as needed.

There will be some minor differences between Windows, Mac OS X, and Linux, but not much really. If you’re following along and things don’t work as expected, please let me know. I’ll be happy to adjust these notes to cover as many possible details as needed to get going.

Let’s get back to the reflow side of things. We need to figure out how our thermocouple and our oven behave, and after that we need to find a way to control the oven temperature. No worries – one step at a time.

Tomorrow, I’ll set up a temperature graph. Two, in fact.

Note – as of mid 2011, this info is no longer valid. JeeMon has evolved to version 1.5.

There IS a reason

In Musings on May 12, 2010 at 00:01

Yesterday’s post was an attempt to explain what I’m doing, and how the bigger issues cause me to wander around a lot, working on secondary projects while trying not to stray too far from the main direction – which is to experiment with fun stuff in the home, around the topics of energy use and environmental monitoring. And a whiff of domotics… when it serves a useful purpose.

Ok, so Jee Labs is about JC’s Environmental Electronics. Doh.

Today I’d like to go into why I’m working on this stuff.

Whenever you ask people why they do what they do, the usual answers are: money, prestige, influence. But the most exciting answers in my book are from those who chase their dreams: because they can or because they want to see where it leads to. Fortunately, these answers do come up, once in a while.

Here are some “why” answers from me:

  • Why environmental? Because we’re on a dangerous course. I’m ashamed of what my species is doing, yet I share full responsibility. Unfortunately, I don’t know how to change the rest of the world. Them. Out there. But maybe I can change the small world I live in. Me, my family and friends. My living space.

  • Why electronics? Because it’s what I loved doing when I was a teenager. It was my biggest passion, before computers took over that spot. I would love nothing more than share that passion. If I can somehow reach some kid, somewhere, to discover the magic of exploration and invention, then that would be fantastic.

  • Why microcontrollers? Because they bring together everything I like: electronics, logic, code, mechanical design. And because nowadays, they are so low-cost and so darn easy to work with. Incredibly robust (hey, you can plug ’em in backwards!) yet infinitely malleable (its all code, just change the flash memory!).

  • Why wireless? Because wireless is as close to magic as technology will ever get. Making things happen somewhere else with invisible power, literally!

  • Why sensors? Because it’s about time our technology started paying more attention to the “real” world out there. Out with the big and noisy machines, which operate in a strictly controlled fashion. The future belongs to sentient systems, which fit in, investigate, respect, respond to, take care of, and even protect our most valued aspects of life.

  • Why networks? Because this world is about information. Data which does not reach the right places and persons, has no value.

  • Why the home? Because that’s where people live. Factories, offices, and commutes are all artifacts of the industrial revolution. That was long ago. We’re living in the internet revolution now. Being in a specific place to make something happen is losing its grip on our lives.

Ok, so maybe that last one is pushing things a bit … :)

Now some more focused why’s

  • Why JeeNodes? Because Arduino’s got it almost right, but shields are simply not modular enough to encourage real mix-and-match tinkering. Single-purpose shields are made for consumption and they restrict needlessly (try stacking them, and feel the pain!).

  • Why Ports and Plugs? Same reason, really. Because I want everyone to be able to experiment with combinations of sensor and actuator functions. JeeNodes are not about consuming (“I create a neat combination kit with all sorts of choices fixed in advance and you build a copy of it”) but about de-constructing and re-constructing stuff. Analyze and synthesize. Take it apart, combine it in other ways. Go and try something new, please!

  • Why RFM12B’s? Because they are low cost and more than capable enough. Mesh, frequency hopping, TDMA, sure… if you want to dabble in complexity, go for it. Go swim in network protocol “stacks”. Add in a micro-kernel to deal with all the required parallelism. Go overboard in failure modes and recovery mechanisms. Use beefier chips. But count me out. I can live with imperfect packet delivery, and simple manual configuration of a few dozen nodes. I cheerfully pass w.r.t. all this “self-inflicted complexity”.

  • Why 3.3V? Because more and more of the new and interesting sensors operate only up to 3.6V or so. And wireless chips, and Ethernet chips. And because LiPo batteries are very good power sources: very low self-discharge, very fast recharge times, and available in a huge range of sizes and capacities.

  • Why JeeMon? Because I want the software equivalent of a breadboard to explore lots and lots of ideas, and it doesn’t exist – not equally simple and equally powerful as a breadboard, not to my knowledge anyway. I think we haven’t even scratched the surface of software design yet, and the potential for real modularity and simplification. Hardware is much further along, in that respect.

  • Why Tcl? Because there seems to be nothing quite like it, in terms of simplicity, expressive power, flexibility, robustness, portability, scalability, and deployment. I don’t mean in terms of each individual issue, but in terms of the combination of those aspects. As a package deal, Tcl embodies a surprisingly clever and effective set of trade-offs. I could probably dismiss Tcl on every single issue in isolation, and name another language which would be preferable – but no single language can go where Tcl goes.

  • Why multi-platform? Because I want to create interesting solutions on the desktop as well as on small Linux boards. I’m fascinated by the idea of moving solutions around, modularizing larger systems into loosely coupled sub-systems, and migrating some of those pieces to dedicated miniature hardware platforms.

  • Why open source? Because it simplifies my life – I can work in the open, share and discuss everything, and benefit from every mode of collaboration imaginable. And because it simplifies your life. If you don’t like what I do, you have three options, instead of just the first one: 1) ignore me, 2) take what you like and change everything else, and 3) make your case and bring up arguments to steer me into a better direction. I’m against lock-in, so if there’s anything I can do to further reduce inter-independencies, let me know.

  • Why no standards, such as XML or ZigBee? Because in this context, standards make no sense. The context is an environment where you can choose every data structure and every side of the communication. In a world where everyone speaks a different language, you need dictionaries, translators, and interpreters. They are all essential, useful, and valuable. I should know, I speak 4 languages, 3 of them regularly within my own family (the fourth being English). But the compactness of well-chosen words and the intricacy of their nuances really take off when you’re totally on the same wavelength. XML has many virtues, but “impedance matching” and compactness are not amongst them. Standards stand in the way of creativity. XML and ZigBee add no value in this context, just tons of complexity, which then creates its own set of problems and distractions.

Speaking of complexity…

This post is starting to become a little too complex as well. So let me summarize and simplfy it as follows: why am I doing all this stuff at Jee Labs? To share my excitement, to convince those interested in technology that there are infinitely many fascinating adventures ahead in the land of Physical Computing, to give me an interesting and useful context to try out lots of new software ideas, and … for the sheer fun of hacking around and learning.

Oh, and because I can, and want to see where it leads to, of course :)

PS. The “normal” weblog posts will resume tomorrow, i.e. how to set up JeeMon for the reflow project.

There IS a pattern

In Hardware, Software on May 11, 2010 at 00:01

If you’ve been following this daily weblog for a while, you may have noticed that it’s all over the place – as if I’m working on everything and nothing. At the same time!

But there’s a pattern, dear reader.

Not fully worked out, not fully planned, not static, but still… there is.

The pattern is that I’m currently trying to automate some of the stuff I need to do here to keep Jee Labs running. The shop has been growing steadily, which is great because it means I can keep doing this – which is exactly what I want to do. Indefinitely, preferably.

But the shop needs to run smoothly, so that I don’t end up becoming its slave. That means the daily production work needs to be automated as much as possible. Only then will it be possible for me to work on all sorts of fun projects, keep up this daily weblog, and fill it with – hopefully – interesting topics, day in day out.

This “self-automation” is why I created the Flash Board, for example. And why I’m redoing the reflow controller to work more reliably. I’ve also been automating like crazy recently to try and stay on top of this huge pile of parts called (haha!) inventory.

I have not lost track of the main focus of Jee Labs – the direction where it all started: energy use tracking and environmental monitoring around the house. It’s still my main focus. And now that the basic hardware works, with lots of configurations and sensors to play with, the next frontier is the software.

But software is a very finicky beast. With hardware, you hook up a few parts and it starts working – after some soldering and/or tinkering, evidently. Software is both primitive and complex in comparison: primitive, in the sense that you have to create these big house-of-cards constructions to get anywhere. Complex, because each of the ingredients is usually a massive chunk of code.

So I’m taking a lot of time to think through numerous aspects of the software. JeeMon is the house I’m building, but its core structure needs to support ideas which haven’t even been invented yet. In terms of software, that means it has to be very modular. I’ve currently got a few components in place, and the binding structure and modularity trade-offs are starting to become clear.

What I don’t have right now, is a clear enough view on the data storage side of things. So all the little JeeMon experiments so far have been side-stepping the issue of persistence (the IT word for “storage”). I’m showing things on screen. Great, but of limited utility.

What’s the big deal with persistence? Well, the moment software includes a storage mechanism, you get into the issue of how to make changes. Suppose you have a working system, and you want to change it in some fundamental way because of a new insight. How do you deal with the data it has already stored? It sounds trivial, but I think it’s everything but trivial – on a very fundamental level.

Storage is a big deal. It is crucial. And it comes up even with something as simple as displaying a moving average. How do you deal with a system restart when there are moving averages in graphs you want to show, for example?

Software development and persistence create opposing forces. Development means just that: to progress from one insight to the next as you go along and extend your understanding of the deeper issues in the problem space at hand. And then, ideally, to implement solutions in better – sometimes completely new – ways. As a developer, I constantly tear my software apart, to put it back together in improved ways (I probably do it 10x more often than most developers). This is a learning process, and the result – IMO – leads to simplicity, elegance, and almost as a side effect: robustness.

Persistence is the elephant in the room. It opposes change. Data saved on disk (or flash memory) has a structure, and changing that structure can be anything from awkward to nearly impossible. That’s why starting from scratch is so easy. That’s also why version 2 of anything in software can be so elusive. It’s not just data, btw – code is data too, in this context. Try folding a new idea into an existing bit of code …

Maybe I’m overstressing this a bit – m a y b e. But this is the main reason why I work on completely unrelated issues at times, such as streamlining the shop activities.

In the meantime, as background process, I keep exploring scenarios for the software and collecting insights from what others do or even just ask for.

So there you have it: ISP programmers, solder reflow controllers, even tangential activities such as 3D printing and CNC milling, they all get addressed here at Jee Labs. Meanwhile, I try to figure out the best way forward for many far-reaching design choices w.r.t. JeeMon.

The good news is that I think this detour is coming to an end. I think a simple, small, modular, and fun way of tying all sorts of hardware together via software is starting to shape up – in a vague hand-waving style right now, but that’s just a matter of pushing the ideas into code. And doing the grunt work.

Neither the ideas nor the code are the hard part. Ideas are cheap and plentiful. Code is easy and can be created gradually. No, the really hard part is to come up with a “pervasively modular” architecture. I.e. how to set up a system (and hence make choices) which can evolve, even in ways not yet imagined.

What I’m after is not a solution, but a tool. And that takes a bit more time…

As the well-known Chinese proverb goes:

Fish

I’m not a teacher, but the fish doesn’t interest me nearly as much as improving the whole process of fishing.

Setting up the thermocouple node

In AVR, Hardware, Software on May 10, 2010 at 00:01

This is part 2 of my reflow controller series. Unlike what was announced yesterday, I’m going to first describe how to set up the temperature sensing wireless node. JeeMon hookup to follow soon.

Our very first step could be to connect the thermocouple via a JeeNode and USB to the PC, but I’m going to do something more interesting and go straight for a wireless hookup. One reason for this is due to a problem with direct connections, but since this is going to be used in un-tethered mode anyway, it’s a good excuse to use a wireless configuration right from the start.

Here is the “thermoSend.pde” sketch I’m going to use (code here):

Screen Shot 2010 05 09 at 14.29.35

This contains all the ingredients needed for a simple basic sensor node: all we do is set up wireless, and then read out the thermocouple value and send it off once a second.

The easy transmissions code works with broadcast packets, so we don’t need to define a destination for the wireless packets, just this sensor node’s ID (1), the choice of frequency band (868 MHz), and a group ID (6). That’s done with the rf12_initialize() call.

The readings are converted to an integer in the range 0 .. 3300, representing a temperature range of 0 .. 330.0°C. Then we send that 2-byte integer in binary mode over wireless. That’s what the code inside loop() does. The map function is part of the Arduino library code.

The easy transmit system will take care of re-transmission if a packet is lost. All the transmission details are handled by rf12_easyPoll(), which needs to be called often.

One detail of the easy transmit system to keep in mind, is that only changed values are sent. No packets will go out if the reading is the same as the last one. In this scenario, that’s fine – there’s always some jitter in the readings, so we should see new packets at least a few times a minute, even when the sensor temperature is constant.

Ok, let’s get going. If you haven’t installed the Arduino IDE yet, go do it now.

Create the above sketch named “thermoSend” in the Arduino IDE. On my Mac, it ends up as a folder named “Documents/Arduino/thermoSend/” in my home directory. Plug in the JeeNode via an FTDI adapter such as the USB-BUB (or use a JeeNode USB) and check your Arduino IDE / Tools / Serial Port settings to make sure you’re hooked up to it. With multiple nodes on USB, it’s easy to mess up the wrong one – happens to me all the time…

Now the node is ready. Unplug, hook it up to a battery, and power it up.

You’re sending packets into the ether now. Quick, let’s try and collect those packets before they falll on the floor!

To do that, hook up a JeeLink or a second JeeNode. It needs to be running the RF12demo sketch, which is what it does out of the box if you got it from Jee Labs or Modern Device.

We need to connect to the JeeLink. Easiest way is to use the Arduino IDE. Make sure you are connected to the proper USB port. So again, check the Arduino IDE / Tools / Serial Port menu and select the JeeLink serial port.

Now open the Arduino IDE’s serial console. You should see something like this:

[RF12demo] A i1 g212 @ 433 MHz
Available commands:
[etc]

You are now in direct communication with the JeeLink. We need to set it up to listen to the proper transmissions. Sort of like tuning to the proper radio station. So type the following line and press “Send”:

2i 8b 6g

This sets node ID = 2, frequency band = 868 MHz, and net group= 6.

If all is well, and the wireless node is powered up, you should start to see packets come in, something like this:

OK 33 212 0
 -> ack
OK 33 209 0
 -> ack
OK 33 212 0
 -> ack
OK 33 209 0
 -> ack
OK 33 212 0
 -> ack

That’s a header byte (i.e. 33, associated with node ID 1) and 2 data bytes.

There won’t be packets every second, because only changed readings are sent. But there will be packets, and if you touch the thermocouple end, you should immediately see the rise in temperature:

OK 33 212 0
 -> ack
OK 33 226 0
 -> ack
OK 33 24 1
 -> ack
OK 33 44 1
 -> ack

No, I’m not suffering from sudden hypthermia: that’s not 4.4°C :) – what you’re seeing is binary overflow of the first data byte. A byte can only hold values 0..255. Anything higher and it will wrap around. That’s why two bytes are sent. The second byte contains the reading divided by 256, i.e. the number of wraparounds. You’re looking at the binary representation of an “int” on Atmel AVR chips.

So the above readings are: 21.2°C, 22.6°C, 28.0°C, and 30.0°C.

IOW, the actual temperature is: (byte1 + 256 * byte2) * 0.1°C

The next episode will be about hooking up JeeMon to the Jeelink and using it to read out the data and do something more meaningful with it. Stay tuned.

Reflow revisited

In Hardware on May 9, 2010 at 00:01

As mentioned yesterday, I’m restarting the reflow oven/grill project because my old setup with an NTC resistor is causing some mechanical problems with the connection of the NTC and because I want to end up with a setup which will be easier for others to replicate.

My intention is to start this project from scratch, using a JeeNode and a Thermo Plug as sensors, and then adding a JeeLink, an FS20 remote-controlled power switch, and of course a grill to create a fully automated and self-contained reflow station for soldering SMDs on printed circuit boards.

I’ll be replicating some of the first experiments, but there will be no need to calibrate NTC readings.

I’m also going to use JeeMon to illustrate how to design and implement the software for this from scratch. I expect to extend and improve JeeMon itself along the way, since it’s still very much in its infancy.

In case this is all new to you: reflow soldering is a technique whereby you apply solder paste to a PCB, carefully add all the components on top, and then bake that whole enchillada according to a preset temperature / time profile. The end result is a finished circuit. Here are some pictures from a few months ago.

Here is the intial setup:

Dsc 1413

From left to right: a 4.5V 3x AAA battery pack, the JeeNode, the Thermo Plug, and a 1-meter thermocouple sensor. This consists of two metal wires of different types, joined at the end. The end is where sensing takes place, because every junction of two different metals generates a tiny electric potential related to temperature.

Yesterday’s post contained the very simple sketch I’m using for this first step.

Tomorrow, I’ll describe the software setup and the first steps needed to read out the data sent by this sketch.

Update – switched to a slightly simpler setup, as shown in the updated picture.

Thermocouple enigma

In Hardware on May 8, 2010 at 00:01

I’ve been scratching my head while trying to get the Thermo Plug to work with an on-board AD597 + thermocouple.

Sure, it works fine…

But only on a 4.5V battery pack! When I connect this thing through a USB-BUB, the readings are severely distorted 9 out of 10 times.

Here’s a sample of the readings on USB:

251 251 251 238 244 261 238 248 251 254 251 206 241 261 251 254 241 209 244

Here are some readings I get on battery power, i.e. not attached to anything:

206 209 206 206 206 209 206 209 209 209 206 206 206 209 203 206 206 206 209

This is the sketch I’m using (code here):

Screen Shot 2010 05 07 at 14.36.29

I’ve tried to rule out noise and other flakiness on the 5V PWR pin by adding capacitors and even a ferrite bead to filter out HF, but none of it seems to have any effect.

Big puzzle! Does anyone have any suggestions what else to try?

The good news is that everything works fine with batteries, so I can continue working on the code for my reflow grill controller. It needs an update because the NTC has a flaky wiring connection (can’t use solder there!) and because I want an accurate temperature readout without having to calibrate things.

Assembling the Flash Board

In AVR, Hardware on May 7, 2010 at 00:01

Here is a step-by-step instruction for assembling the Flash Board, starting from these components:

Dsc 1386

The 24M01 1 Mbit EEPROM is already on the board. The build proceeds essentially in flattest-to-higher order, so that when you turn the pcb around for soldering, you can push down the part properly.

We start with the 470 Ω current limiting resistor for the LED:

Dsc 1388

Try to make nice and shiny joints:

Dsc 1387

Cut off the excess wires:

Dsc 1389

Next is the little start button:

Dsc 1390

There are four pins to solder:

Dsc 1391

They are a bit long, so it’s best to cut them off:

Dsc 1393

Next, the LED. This one is polarized, be sure to put it in the right way:

Dsc 1394

The last component on the top is the 2×3-pin ISP header:

Dsc 1396

Again, make sure all pins have good solder joints:

Dsc 1397

Now, all we need to do is solder in the 4 6-pin headers. The easiest way to do so is to push these headers into a JeeNode for proper positioning:

Dsc 1398

The push the Flash Board on top and you’ve got a convenient way to solder them:

Dsc 1399

That’s it, done!

Dsc 1400

Now you can upload the isp_capture.pde sketch on this page and use this brand new ISP programmer.

Happy programming!

Low-level development

In AVR, Hardware on May 6, 2010 at 00:01

I’m working on some ideas which require some low-level code, and fairly accurate timing. Serial or wireless I/O are not an option, and hooking up the logic analyzer is not convenient (I may have to, if the going gets tough).

For now, here’s a very simple setup which ought to be sufficient:

Dsc 1385

Two boards, hooked up via two USB ports. They are on the same computer, so there should be no issues with voltage levels when leaving them both connected at the same time (I’m not too worried about the ground loop).

The board at the top is the Flash Board as ISP programmer (I’m not using the new capturing features here). The board below is the “target”, a plain JeeNode hooked up to a USB-BUB. Nothing fancy.

I’ve added 8 bits of “I/O” by hooking up 8 LEDs with current-limiting resistors – red on the DIO pins, green on the AIO pins as debugger, as described here.

The target board also has the option to communicate over serial (i.e. through its USB connection), but that adds code and affects timing – something which I probably can’t tolerate in my specific tests.

Nothing very unusual here, but it’s worth pointing out that a couple of years ago, a setup like this could easily have cost over 1000 <pick-your-favorite-currency>, whereas this one is well under 100.

Let’s see how it goes…

A capturing ISP programmer

In AVR, Hardware, Software on May 5, 2010 at 00:01

Meet the new, improved, autonomous, self-guiding, hassle-free, portable ISP programmer!

Dsc 1381

It works as follows:

  • hook up a JeeNode or JeeNode USB to your computer
  • upload the isp_capture.pde sketch to it
  • insert the Flash Board and hook it up to the target
  • program the target, using this as a standard STK500/AVRISP programmer @ 19200 baud
  • wait for the LED to blink twice
  • done

And this is where the fun starts:

  • connect the JeeNode to a battery or any other power source
  • insert the above Flash Board again and hook it up to the target
  • press the button on the Flash Board
  • wait for the LED to first turn off and then start flashing
  • done

You’ve just programmed another target MPU … look ma, no hands!

The first hookup went through a normal programming cycle, but it also stored everything in the EEPROM on the Flash Board: code, data, fuses, verification bytes, everything. That’s why I’m calling this a capturing programmer.

When pressing the button, it essentially repeats all the same steps.

This works for anything you can program with an AVRISP programmer: ATmega, ATtiny, whatever. And it will even capture multiple programming cycles, as long as they are started before the LED blinks twice, i.e. within a few seconds. So you could set up a script to call avrdude with a few different things to do – e.g. set fuses, program the flash, program the AVR EEPROM, set the lock bits.

There are some tricks under the hood to make this work. First of all, the baudrate as ISP programmer is set to 19200, so that the bootloader in the JeeNode doesn’t accidentally take over after reset (it listens at 57600 baud).

Another trick, and the main reason this all works transparently, is that the entire serial communication session is stored in EEPROM as is. When pressing the button, it simply replays the input to the programmer code as if it was coming from the serial port (and matches the results, also against EEPROM). There is some logic involved to be able to store both input and output streams, and keep them properly apart.

The EEPROM is connected via I2C to port 3. I used the MemoryPlug and MemoryStream classes from the Ports library to access it.

Lastly, there is some debugging built in. While used as AVRISP programmer, the serial port is in use for programming @ 19200 baud. But when in replay mode, the serial port is set to 57600 baud and used to report what the programmer is doing. Here is a transcript:

[isp_capture]
ISP bytes: 39680
Code size: -32768
Page size: 128
Data size: 1024
Signature: 86 00 00 01 01 01 01 03 FF 95 0F
Programming...
Done in 13.9 seconds.

That’s it. There is visual feedback when programming succeeds in the form of a flashing LED, so that this setup can be used without serial link. I’d like to add auto power-down one day, for serious battery use.

I’m going to use a bunch of Flash Boards here, pre-loaded with the different contents of ATmega’s and ATtiny’s I’m constantly preparing here at Jee Labs. Will probably also dedicate a bunch of JeeNodes to this, but that’s optional – any available JeeNode can be temporarily turned into an ISP programmer by simply uploading the “isp_capture.pde” sketch to it and inserting a Flash Board.

Now I can easily reprogram all those Room nodes in the house!!

PS. There’s nothing JeeNode-specific about this setup. The on-board wireless isn’t used (yet?).

PPS. For your convenience, I’ve tagged all related posts on this weblog with ISP.

Communication 101 – Networks

In Hardware, Software on May 4, 2010 at 00:01

After yesterday’s introduction, let’s tackle the more advanced version of communication: networking.

For example a set of machines connected via Ethernet:

Screen Shot 2010 04 26 at 13.48.00

(often, the hub will also be connected to a router and/or internet)

While similar to “point-to-point” communication on the surface, and sometimes even at the hardware level, this is completely different in terms of software.

The difference between dedicated links and networks, is that the network is shared for use by multiple nodes. It can’t deal with everything at once, so again, “time” is a crucial aspect of networking.

First of all, you’ve got to take turns talking, How do you take turns? Not so easy. In face-to-face conversations, we use an intricate system of pauses, expressions, gestures, and behaviors to effortlessly take turns in a conversation. On the phone, it’s a little harder, on a phone with a noticeable time lag, it can be frustratingly hard.

With computers, one thing you have to do is break each transmission into chunks – i.e. “packets”. Then it’s a matter of getting all the packets across, one by one, in the correct order, until the task is done. Or abort between packets, and allow changing roles so that other nodes can start to transmit.

Ethernet is a common way to connect computers, and TCP/IP is the standard used to do make communication possible. The whole internet is built on it. On a network, everyone has to play by mutually agreed rules. These can be fairly complex, which explains why microcontrollers need some extra hardware and code to be able to act as Ethernet node – and it can easily reach the limits of what they can do.

The nice bit about networking is that once you’re “on” a network, any node can communicate with any other node. But again, there is quite a bit of machinery and logic needed to make that possible.

The two key features of the serial communication described yesterday, is that they are reliable and throttled. Well, not so on a network. Packets get lost or damaged in transit. Someone could be messing with the cable while two units are exchanging packets, and disrupt the whole process. Even if two nodes are working 100%, they can still fail to exchange a packet!

So with networking, you have to deal with things like timeouts, acknowledgement packets (which can get damaged as well), and re-transimssions. You also have to deal with flow control, to avoid sending more data than a receiver can handle. Imagine sending a steady stream of packets: if one of them gets lost, we have to detect the failure (takes time), re-send the packet (takes more time), and catch up with the new incoming data!

Before you know it, yesterday’s “Serial.println(value);” example turns out to require a lot of logic and error-handling.

It gets worse: what if the receiving node isn’t even connected right now?

The transmitter should to be able to detect this so it can decide what to do.

Sometimes, there is no alternative but to ignore it. Sometimes, that’s not even such a big deal – for example with a sensor which is periodically sending out new readings. It’ll fail, but once the receiver is back online, it’ll all start to work again.

If you’ve ever ever looked into a “networking stack” (i.e. its code), or even implemented one yourself, you know that writing this sort of code is a complex task. It’s not easy to communicate reliably when the communication channel is unreliable.

This daily weblog is a nice analogy, btw. I send out daily “posts” (packets), but this one for example continues where yesterday’s discussion left off. In a way, by assuming that you, dear reader, will follow along for more than one post, I’m creating a “story” (virtual circuit), based on daily chunks. It’s a fairly robust communication stream operating at a constant rate. Based on nothing but web pages. So now you can think about packets, next time you watch a YouTube video :)

What about wireless networks?

Screen Shot 2010 04 26 at 13.48.08

The good news is: wireless networks have to deal with most of the same issues as wired networks, and these issues are well understood and solvable by now.

The bad news is: wireless networks have to deal with a lot more unreliability than wired networks. All it takes to disrupt a wireless network is some RF interference from an old arcing motor, or even just walking out of range!

It’s possible to maintain the illusion of a serial connection over a network – it’s called a virtual circuit. TCP/IP does that: when you talk to a web server, you often exchange a lot more than will fit in one data packet. So TCP/IP sets up a mechanism which creates the illusion of a serial link – a virtual pipe between sender and receiver. Put stuff in, and it’ll come out, eventually.

Except that this illusion can break down. There’s no way to maintain the illusion of a permanent “connection” when you unplug the receiver, for example. Or walk out of range in a wireless network.

There’s no way even to give guarantees about communication speed. You might be at the very edge of a wireless network, with the system frantically trying to get your packets across, and succeeding perhaps once an hour. Oof – made it – next – yikes, failed again – etc.

In a wireless sensor network (WSN), which keeps sending new readings all the time, the illusion of a virtual circuit – i.e. virtual serial connections – can break down. And what’s worse: when it does, it’ll do exactly the wrong thing: it will try to get the oldest packet across, then the next, and so on. Which – if the network is really slow – is just going to lead to a permanent backlog.

What you want in a WSN, is to occasionally drop the oldest readings, which are more and more obsolete anyway, if that helps recover and obtain the most recent readings again.

A bad WSN’s can give you lots of data you don’t want, whereas a good WSN will give you the latest data it can. The trick is to stop trying to send an old value as soon as you’ve got a new and more up-to-date reading.

This is the reason why the RF12 driver used with JeeNodes uses a packet delivery model, instead of a virtual circuit model. In networking terms: UDP instead of TCP. Also: best effort instead of (semi-) guaranteed in-order delivery.

Nice bonus: packet delivery is far simpler to implement than virtual circuits.

What has worked so well for teletypes and serial consoles for several decades, is not necessarily a good idea today. Not in the context of networks, particularly WSN’s. For another example, you need look no further than the web: part of HTTP’s success is based on the fact that it is “state-less”, i.e. not fully connection-based.

So all I have to do now, is to convince the whole world that thinking of communication as serial connections can be awful in some scenarios!

Heh, piece of cake: just make the whole world read this weblog, eh?

Communication 101

In Hardware, Software on May 3, 2010 at 00:01

Triggered by a recent post on the discussion forum, it occurred to me that I may be taking way too many concepts for granted. My problem is that I’ve been around computers too long. Not so much in being socially inept (just a bit introvert :) – no, the issue is that I seem to have become pretty familiar with how they work, from silicon to database to web-server.

This is a huge hurdle when trying to share and explain what I’m doing, and it probably makes this weblog harder to dive into than I intended, as a friend recently pointed out – an insight for which I’m very grateful.

So after this little bit of personal communication, let me get to the point: what I’d like to do from time to time on this weblog is to go into some key topic, relevant to the projects here at Jee Labs, but doing it in such a way that will hopefully bring more insight across to people who share the enthusiasm for all this Physical Computing stuff, but not necessarily all that techie background.

Not to worry – this is not the start of a textbook :) – nor a treatise. Just trying to clarify some stuff. Succinctly, as much as I can. If you know all this, or if it bores you – bear with me for one or two posts, I will go back to other topics again in the next posts. When I make mistakes, or say nonsense, please do correct me. I live to learn.

Today, I’ll kick this off with Communication (Wikipedia) – in the context of information exchanges between computers and peripherals, and within the hardware of various types of systems.

First off: why communicate? Because that’s what computers do, essentially. Number crunching (i.e. the literal sense of “to compute”) is secondary by now.

Examples, in the context of physical computing:

  • sending a measurement value to our PC
  • sending information to a display
  • sending data to an attached chip or device
  • sending a control signal to turn things on or off
  • sending packets by wireless to another node

How can information be sent? In short: as bits, from a software perspective, or as electric / magnetic / optical / mechanical signals from a hardware perspective. You could say that Physical Computing is about bridging those software and hardware perspectives. Sensing “stuff” and making “stuff” happen. With the fascinating part being that there is computation and change awareness (state) and decision-taking involved via the microcontroller which sits in the middle of it all.

This is a big topic. Let’s narrow it down. Let’s focus on communication in the form of bits, because ultimately just about everything goes through this stage.

Screen Shot 2010 04 26 at 13.38.51

Let’s take that first example: sending a measurement value to our PC. How do you do that? Simple, right? Just put something like this in your sketch:

Serial.println(value);

Whoa… not so fast. There’s a lot going on here:

  • we select an interface (Serial)
  • we fetch the measurement value from a variable (value)
  • we convert that data to a text string (println)
  • we transmit the text, character by character, over a serial link
  • somehow that serial link uses electrical signals to travel over a wire (hint: FTDI)
  • somehow this finds its way into a USB port (hint: device driver)
  • somehow this is picked up by an application (hint: COM or /dev/tty port)
  • somehow this appears on the screen (hint: serial console)

And what’s probably the most complex aspect of this entire process: it takes time. What appears to happen in less than the blink of an eye to us, is in fact a huge time consumer as far as the microcontroller is concerned.

If we ignore the details, you have to admit that this works pretty well, and that we can indeed easily get results from a microcontroller board to our PC.

That’s due to two key features of this comms channel:

  • the connection is reliable: what is sent, will arrive, eventually
  • the connection is throttled: sending is slowed down to match the reception speed

It’s easy to take this for granted, but not everything works that way. When you send data to an attached LCD display for example, the software has to take care not to send things too fast. LCD displays need time, and there are limits to how fast information can be presented to them. The Arduino “LiquidCrystal” library is full of little software delays, to avoid “overrun”, i.e. sending stuff faster than the LCD can properly handle.

The trouble with delays is that they hold everything up!

Well, that’s the whole point of delays, of course, but in a microcontroller, it means you don’t get to do anything else while that delay is in progress. Which has its own problems, as I’ve described earlier.

If you think about it for a moment, you might see how delays in fact make communication virtually impossible: because if you’re supposed to wait for all the little steps to complete, how can you possible handle incoming data, which has no idea that you’re currently waiting in delays and not listening to anything?

I won’t go into the (hardware-based) solutions which work around this issue, but it has been solved, to a certain extent. This is why data coming in from the USB link will usually arrive just as expected, yet at the same time sending out data usually slows down the microcontroller in clearly noticeable ways. Try making a blinking LED, and then sending a string with Serial.println in between each blink. Sure enough, either the blinking or the serial output will become slower or even irregular.

Communication of of data takes time. We don’t have infinitely fast connections. Even something as simple as “Serial.println(value);” is full of nasty side-effects and details, especially on a microcontroller such as the ATmega.

It’s good to keep this in mind. This is one reason why something as seemingly simple as collecting data from multiple serial streams requires a fairly advanced library such as NewSoftSerial, and why even that clever code has its limitations.

Tomorrow, I’ll talk about packets, networking, and wireless communication.

Cat and mouse games

In News on May 2, 2010 at 00:01

Not so long ago, junk comments on the Jee Labs daily weblog started rising sharply:

Screen Shot 2010 04 28 at 11.14.10

Flagged by Akismet, but still a pain because I have to clean them up once in a while – and manually skim over each one to pick out any false positives. No fun, especially knowing that all this spamming is scripted – regardless how little effort it takes, life’s too short for this sort of nonsense!

Fortunately, there are additional tools for WordPress to prevent most of this junk from even reaching Akismet (which does a terrific job, btw).

As you can see at the end of the graph, the spam log is clean again. Five incoming junk comments in two weeks – that, I can deal with :)

Thanks to Project Honey Pot!

ATtiny 8-pin ISP programmer

In AVR, Hardware on May 1, 2010 at 00:01

Yesterday’s ISP programmer used a 28-pin socket wired up for ATmega328 chips (and the older 48/88/168 versions).

As it turns out there are enough unused pins available in that socket to also support the ATtiny 8-pin series (such as 25/45/85). The trick is to add a few extra wires so that the ISP programming signals have the proper setup for these smaller chips as well:

Dsc 1376

This allows placing an ATtiny in the socket at the top end, i.e. using just pins 1..4 and 25..28:

Dsc 1377

This trick works, because the I/O pins used by the ATtiny happen to be normal I/O pins for the ATmega, so it doesn’t mind having some logic signals there (pins 9..12 and 17..20 can probably also be used, but then inserting the chip becomes more error-prone).

And sure enough, avrdude can now program the ATtiny as well:

Screen Shot 2010 04 25 at 02.44.46

For other chips, you’ll need to wire up a chip-specific socket, but at least for these ATtiny chips an ATmega setup will work just fine!

ATmega 28-pin ISP programmer

In AVR, Hardware on Apr 30, 2010 at 00:01

The Flash Board presented a few days ago was only half the story. Here is the other half, i.e. the chip socket.

What you need is a board with a 10 kΩ reset pull-up resistor, an 8..16 MHz resonator for the clock, and – just to be safe – a 0.1 µF decoupling capacitor. I used an empty JeeNode v4 PCB to hook it all up:

Dsc 1372

I added the ISP connector in a slightly unusual way: with long pins bent sideways. The reason being that the ZIF socket won’t fit on the board otherwise. In fact, it won’t fit directly anyway because the holes are too small and the socket is too long. So I pushed it (hard!) into a 28-pin IC socket first:

Dsc 1371

Then I soldered the socket in, and there it is:

Dsc 1373

An ISP programmer for 28-pin ATmega’s!

Tomorrow, I’ll describe how I’ve modded this setup to also allow programming 8-pin ATtiny DIP chips …

JeeLink’s “Plan B”

In Hardware on Apr 29, 2010 at 00:01

Hmm, it looks like the plastic “USB stick” cases are seriously and totally unavailable. I’ve completely run out of cases, and the next shipment from Farnell is reported to be in… July!

Can’t have everyone wait for it, so I’ve started replacing the case by some semi-transparent heat-shrink tubing:

Dsc 1375

It’s not quite as pretty or sturdy, but it does protect the board so you can easily plug in or remove the JeeLink. The red, green, and blue LEDs are still clearly visible.

If nothing changes on the delivery-of-cases front, then this change will become permanent. Otherwise, I’m willing to repackage any JeeLink you send back at no extra cost. Once the original cases are available again.

Will keep y’all posted on this …

Update – Just got a note from Farnell that the cases are shipping (!). I’m going to hold back on all JeeLink shipments until Monday – with a bit of luck, I can send them off with the “real” plastic cases after all!

Meet the Input Plug

In Hardware on Apr 28, 2010 at 00:01

After yesterday’s exploration into sending 4 bits over one I/O pin, it was easy to complete the Input Plug:

Dsc 1364

I got the silkscreen labels completely wrong, but once that was clear it all went more or less as intended.

A new “InputPlug” class has been added to the Ports library. It’s essentially still a Port, but with one extra “select(channel)” member to set the input channel from 0..15.

Note that this is called an input plug, but it’s really an analog 16-channel multiplexer in front of the AIO pin of a port. It can be used for analog input as well as digital input (just use digiRead2() i.s.o. anaRead()).

But it can also be used as output demultiplexer, even for analog (i.e. PWM) output when connected to port 2 or 3! Just keep in mind that as output, the usefulness is limited since there is no latching going on: the pin goes to high impedance, i.e. disconnects, when the channel is not selected.

One possible use as output, is to drive a set of transistors – one at a time, e.g. to multiplex a 7-segment or matrix display. By setting the AIO pin permanently to 0 (or 1), you could use the channel selection to pull one of the 16 pins down (or up).

The Input Plug is not an I2C plug – it requires a dedicated port and can’t be daisy-chained.

The following “input_demo.pde” example sketch has been added to the Ports library:

Screen Shot 2010 04 19 at 23.26.41

Sample output:

Screen Shot 2010 04 19 at 23.10.33

All inputs read out as 1023 because of the pull-up in this demo, except for one pin which I was manually connecting to a 1.5V battery in rapid succession.

Will be adding this plug to the shop shortly. See the documentation page for further details.

Decoding a pulse train

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

The (planned) Input Plug uses an ATtiny chip to decode a 16-channel selection code using a single I/O pin.

Here is the relevant part of the schematic:

Screen Shot 2010 04 19 at 19.50.37

The DIO pin is connected to PB4 of the ATtiny. The ATtiny PB0..PB3 pins in turn are hooked up to the A..D select inputs of the analog multiplexer. So all the ATtiny needs to do is decode an incoming “pulse train” on its PB4 pin, and send out the decoded value on its PB0..PB3 output pins.

My first attempt used a simple serial protocol: a start bit and 4 data bits, clocked at a fixed rate:

Screen Shot 2010 04 19 at 19.52.59

This worked, but it was a bit flakey because the internal clock of the ATtiny is not accurate enough to ensure everything stays in sync for the entire duration of the transmission, i.e. across 5 bit periods. This is clearly explained in the following image (from here):

async1

It’s better to use a self-clocking format, for example 5 pulses of varying width, because then only the length of each individual pulse matters. Above a certain threshold = 1, below = 0. And we can reset when there are no pulses.

Here’s the a transmit test sketch, which sends a 0..15 counter every 100 ms:

Screen Shot 2010 04 19 at 19.57.36

As you can see, the pulses are 4 or 8 µs wide, with one pulse every 12 µs. Roughly.

Note that interrupts have to be disabled during each “transmission”, since these pulses are very short and need to be fairly strictly controlled.

The decoder on the ATtiny (ATtiny85 in this test) is also quite simple. It waits for a pulse start and then counts in a loop until the signal drops to zero again. Counts above a certain value are treated as “1”. Missing pulses and pulses which are way too long cause the decoder to be reset and start from scratch:

Screen Shot 2010 04 19 at 20.01.21

This can be compiled with avr-gcc, and it’s of course just a few bytes (even an ATtiny is overkill here):

Screen Shot 2010 04 19 at 20.02.44

I’m using yesterday’s Flash Board for ISP programming. Makes a good test that it also works with ATtiny MPUs.

Here’s the test setup (with the ISP programmer disconnected):

Dsc 1362

And sure enough, the LEDs display a little running 4-bit counter, driven by data sent over a single DIO pin.

Should be good to go for the Input Plug!

Meet the Flash Board

In Hardware on Apr 26, 2010 at 00:01

The Flash Board is a brand new piggy-back board to turn a JeeNode into an ISP programmer:

Dsc 1352

It’s compatible with the ISP plug described a few days ago, but it includes a few extra features:

  • on-board button and LED
  • on-board 128 Kbyte EEPROM memory
  • holes for a “direct-connect” ISP connector

It works with the isp_flash.pde and isp_prepare.pde sketches. See those two posts for details about these.

This board is now in the shop as kit, with the EEPROM soldered on since most people probably don’t want to solder such tiny surface-mounted chips. Note that the above two sketches don’t use the on-board EEPROM.

Here’s the Flash Board in more detail:

Dsc 1357

Nothing fancy, but I find it convenient, especially in combination with a JeeNode USB and a LiPo battery pack as a Portable ISP Programmer!

The “direct connect” ISP connector is a funky way to dispense with the ISP cable altogether, and plug this thing directly into a board with 6-pin ISP holes:

Dsc 1358

The master JeeNode + Flash Board are pushed upside down into the 6 holes of the ISP header, i.e. without header. Due to the way these extra long pins are placed, they will go in under an angle and push sideways to make a good connection. The trick is that these pins use two separate ISP headers, to end up with pins 1-2/3-4/5-6 swapped, so that they’ll work properly upside down. See the after-burner weblog post for another example of this.

Sure, it’s a bit funky. And you don’t have to use this. But it works :)

Preparing ATmega’s with ISP

In AVR, Software on Apr 25, 2010 at 00:01

Here’s a second use of yesterday’s ISP plug: pre-loading ATmega’s with a fixed sketch and bootloader.

This uses a very nice trick from the Arduino Boot-Cloner: store the code to be sent to the target MPU as PROGMEM data inside the ISP sketch itself!

I’ve adapted that Boot Cloner so that it takes its data from a separate C include file, added a couple of other features, and speeded the whole thing up a bit.

The result is called “isp_prepare” (code here).

Here’s what you’ll see on the USB serial port when starting it up:

Screen Shot 2010 04 18 at 23.14.22

The list reports the files which have been integrated into this sketch at build time, using this C code at the top of isp_prepare.pde:

Screen Shot 2010 04 18 at 23.23.36

Here is the contents of that include file, with most of the data bytes omitted:

Screen Shot 2010 04 18 at 23.24.51

The data consists of “sections” of code, to be programmed into the target ATmega using ISP. In this case there are two sections, a RF12demo sketch starting at address zero, and a bootloader in high memory.

Here’s is isp_prepare in action:

Screen Shot 2010 04 18 at 23.14.47

So the steps to load RF12demo onto a JeeNode with a fresh ATmega are as follows:

  • upload this isp_prepare.pde sketch to a “master” JeeNode
  • insert the ISP plug described yesterday,
  • connect the target JeeNode to this master JeeNode via ISP
  • enter G to start programming and wait for it to complete
  • done: disconnect, now the target JeeNode is ready to run with RF12demo on it

I’ve also included a “data_blink.h” header file, if you want to preload the ATmega with the standard Arduino blinking LED demo. Just change the include in isp_prepare and upload the sketch again.

I can now use this setup for initializing all the ATmega’s here at Jee Labs, since it means I no longer have to start up the Arduino IDE or use avrdude.

Convenience!

ISP plug

In AVR, Hardware, Software on Apr 24, 2010 at 00:01

For one of my projects, I needed a quick way to reflash an AVR via ISP. Didn’t want to have to use any of the several ISP programmers around here, so I made my own “ISP plug” for use on a JeeNode:

Dsc 1353

The pins are connected as follows:

  • ISP pin 1 = MISO = DIO1
  • ISP pin 2 = VCC (+3.3V)
  • ISP pin 3 = SCK = AIO1
  • ISP pin 4 = MOSI = AIO4
  • ISP pin 5 = RESET = DIO4
  • ISP pin 6 = GND

Here the top view, made from a little JeePlug board:

Dsc 1354

Bottom side:

Dsc 1355

Note that this ISP setup draws 3.3V from the JeeNode and uses it to power the target, so the target board should not have its own power and it should not draw more than say 100 mA of current @ 3.3V.

The code for this is called “isp_flash.pde” and is derived from the “ArduinoISP” sketch. I added software-based (bit-banged) SPI communication for use with the above I/O pins, and did a fair bit of cleanup of the source code.

The nice thing about this ISP programmer is that it works out of the box with Arduino IDE 0018:

  • upload the ISP_flash.pde sketch to the JeeNode
  • insert the ISP plug and hook it up to the test circuit (or one of these …)
  • burn the boot loader using the Arduino IDE:

Screen Shot 2010 04 18 at 18.04.06

The result will be a properly initialized ATmega, with protected bootloader and the default blink demo pre-loaded.

It’s not terribly fast because it uses a 19200 baud connection, but it’s simple and can be a life-saver if you ever damage the bootloader on an ATmega, or want to prepare blank ATmega’s for use with a JeeNode.

This plug can in fact be used as ISP programmer for any type of ATmega or ATtiny with “avrdude”:

Screen Shot 2010 04 18 at 18.14.42

You’ll need to adjust the serial / USB port, fuse settings, and sketch as needed, of course.

(Not so) Home Easy

In Software on Apr 23, 2010 at 00:01

Here’s the Elro / Home Easy AB440R remote control:

Dsc 1351

On the surface, it looks like a very clean 433 MHz protocol:

Screen Shot 2010 04 17 at 12.16.22

Here are some bit patterns, as I see them coming in:

Screen Shot 2010 04 17 at 12.15.26

All the pulse widths are in the expected range (first two are timestamp and pulse count):

Screen Shot 2010 04 17 at 12.38.38

This is completely in line with the protocol description I found. Given that it uses a special 0-0 pattern for extended group codes, I decided to pass all the transitions back, leaving the interpretation to higher-level code:

Screen Shot 2010 04 17 at 12.31.28

Here’s what comes out:

Screen Shot 2010 04 17 at 12.30.50

Several very odd problems with this:

  • the incoming bit patterns are less than 50 bits
  • the KAKU decoder also matches these patterns
  • I’m getting spurious empty lines reported

The KAKU decoder match is very surprising, since it only fires when receiving exactly 12 bits! As it turns out, the other way leads to false positives as well: the KAKU transmitter currently triggers the HEZ decoder – but that’s more logical, since the HEZ decoder isn’t checking exact packet sizes yet.

Something very fishy is going on, but I can’t see where :( – despite this, I’ve updated the code.

Oh well, can’t win ’em all…

A mini scope

In Hardware, Software on Apr 22, 2010 at 00:01

Triggered by a discussion on the forums, here’s a little demo of how to build your own “Poor Man’s Scope”:

Screen Shot 2010 04 21 at 20.36.10

I connected an LDR between AIO1 and ground, and played around with light levels during this screen shot. The last samples were all over the map because I inadvertently touched the LDR leads.

All you need to reproduce this experiment is: an LDR, a JeeNode, and the JeeMon runtime. Oh, and the Arduino IDE to compile and upload a sketch to the JeeNode.

The sketch is adapted from the arduino-arduinoscope.pde demo. This is not nearly as fancy (or even flashy) as that Processing-based version, but it’s very easy to set up and get started with, IMO.

Anyway, here is the sketch running on the JeeNode:

Screen Shot 2010 04 21 at 20.44.32

It does a lot more than I’ll be using here, since I’m only picking up and displaying the first analog value, i.e. AIO1 on the JeeNode.

To get started with JeeMon, you could go read this page to get some background, but all you need really is the executable, so you can just download the appropriate one: for Windows, Mac, or Linux.

Then:

  • unpack the ZIP file, so you end up with a “JeeMon” executable
  • create a directory called “JeeMon-rigs”
  • in that directory, create a file called “application.tcl” (contents shown below)
  • adjust the serial port of the JeeNode to your setup (look at the top of application.tcl)
  • launch JeeMon, and you should get the real-time scope display shown above

Here is the application.tcl file, written in Tcl and using the built-in Tk GUI subsystem for visual display:

Screen Shot 2010 04 21 at 20.53.36

I’ve sprinkled some comments in the code. There are a fair number of pesky little details (as in all programming languages), but even without knowledge of Tcl/Tk you should be able to more or less see what’s going on.

There’s a lot one could improve or add to this thing. There always is. This is just a starting point.

But there you go: a Poor Man’s Scope in less than 100 lines of JeeNode sketch + JeeMon rig code. Fun!

Digital postage stamps

In News on Apr 21, 2010 at 00:01

At last, this country has entered the 21st century…

Dsc 1347

It is now possible to print postage stamps with a label printer, instead of having to constantly buy stamps and place up to 8 (!) of them on the packages going out at Jee Labs. Not to mention keeping 4 different stamps around.

Until now, the only other option was to buy a fairly expensive franking machine which weighs the packages and prints stamps on them, but it doesn’t handle thicker packages, so I’d end up printing on separate labels anyway – and essentially waste most of the investment while still doing the same as before.

I’ll probably keep using stamps for the small shipments. But no more reams of stamps per envelope, new shipping options in reach, and no more running out of specific stamps!

Now, if only they supported the Mac… oh, well.

X10 RF reception

In Software on Apr 20, 2010 at 00:01

One more decoder, a home automation protocol this time – a X10 RF transmitter:

Dsc 1342

That’s a Marmitek SS13, sending out over 433 Mhz (European model).

This is a fairly simple protocol (documented here), although synchronization and packet detection works a bittle differently from the other decoders so far:

Screen Shot 2010 04 16 at 00.06.22

Sample output:

Screen Shot 2010 04 16 at 00.05.35

Easy!

More OOK decoders

In Software on Apr 19, 2010 at 00:01

O(o)k … so there are now several decoders for OOK transmissions: 3 for 433 MHz and 4 for 868 MHz:

Screen Shot 2010 04 15 at 10.36.43

Sample output:

Screen Shot 2010 04 14 at 23.20.21

The code is here now here. It has been set up as an Arduino sketch, but the decoder logic is not Arduino-specific, nor even ATmega-specific in fact. The sketch compiles to under 5 Kb, leaving plenty of room for future extensions.

All that is needed is to call the decoders with pulse widths in microseconds. They all run in parallel, but normally at most one will succeed for any given pattern of pulses. The actual decoding completion happens during the final long pulse (2000 µs or more, in most decoders).

Here is the rest of the sketch, which drives the decoder from pulses measured in an interrupt routine:

Screen Shot 2010 04 15 at 10.36.58

Note that there is something odd in this code: all the decoders are fed the same pulses! In real use, separate receivers will need to be connected for 433 Mhz and 868 Mhz, and then pulses fed to the appropriate decoders only. The reason I did it this way was for testing: I can simply replace the OOK receiver with whatever I’m currently trying out to see if it works – no reset needed.

So that’s it for now: 7 decoders, capable of decoding packets from several dozen different types of sensors and transmitters.

The data is reported as a set of hex nibbles, which need to be separated into the specific bit patterns for each type of packet. Also, checksums still need to be verified, to weed out any remaining false positives.

But that’s another topic, for another day.

Note – the RFM12B receiver cannot receive OOK signals. I hooked up extra hardware to make the above work.

Visonic sensors

In Software on Apr 18, 2010 at 00:01

Another set of sensors is made by Visonic. Here’s the door sensor:

Dsc 1341

It has three sources of triggers: a reed switch, normally kept closed with a magnet on the door or window, an extra set of ordinary contacts, and an internal switch which is released when the case is opened.

There are other sensors using the same protocol, such as a PIR motion detector and a “universal transmitter”.

The sensors send OOK data on the 868 MHz band, but it took me a while to figure it all out. The main reason being that I couldn’t find a preamble for these radio packets – apparently there is none! – instead, the tail of the packet is a good reference point, i.e. the 72 pulses preceding the long pause at the end can be reliably decoded.

Each bit is either a short-long pulse pair, or a long-short pulse pair. This can in fact be used to resync even before the end of the packet is reached, because short-short and long-long combinations indicate that we’re off sync.

The total packet has 72 pulse transitions, i.e. 36 bits of data. I add 4 extra zero bits to create a 5-byte result. Here is the main decoding logic:

Screen Shot 2010 04 14 at 16.28.07

Here is some sample output:

Screen Shot 2010 04 14 at 16.35.43

I’ll postpone decoding of the actual bit pattern to another day but note that you don’t really need to interpret all the bits: just look which patterns your sensor is sending out under various conditions, and you can match the incoming packets accordingly.

Improved OOK Scope

In Software on Apr 17, 2010 at 00:01

In yesterday’s post, I used the OOK Scope to find the distinctive pulse pattern emitted by a specific sensor to be able to write a decoder for it.

Keep in mind that this is a bit like looking for a needle in a haystack: there are often over a million pulses coming in within just minutes. That’s why I had to compare the “sensor-off” baseline with the “sensor-on” pattern. And even then, you never know for sure where pulses come from and especially whether they came together in quick succession, as expected for genuine RF packet data.

So I added some filtering: instead of showing all pulses, I only look for pulse sequences with pulse widths and pulse counts in a certain range, followed by a brief period of silence (i.e. a relatively long pulse).

I also added some configurability, i.e. whether to display using a logarithmic horizontal scale, whether to “decay” old data so new pulses are weighted more heavily in the counts.

One last very convenient feature added was a “peak detector”, i.e. trying to identify the most prominent peaks in the graph and reporting their microsecond values in a status line at the bottom (the first value is a pulse count).

I didn’t implement a GUI to adjust these values – I simply set them as needed in the code and restart JeeMon:

Screen Shot 2010 04 13 at 20.58.19

Here’s the result of running the OOK decoder with these settings and waiting for a packet from the Cresta sensor:

Screen Shot 2010 04 13 at 19.52.25

Bingo: very clean peaks, as well as the actual durations of the main pulses, i.e. 392 µs, 576 µs, 880 µs, and 1056 µs. As I’ve been able to determine from previous experiments, these are just two groups of pulses: 392/576 = 0 and 880/1056 = 1. The reason is probably skew – these receivers appear to have a completely different response to carrier-start and carrier-end transitions.

Here’s a plot when leaving the OOK Scope on and accumulating for one hour:

Screen Shot 2010 04 13 at 21.05.53

There’s a bit more garbage now, with additional noise and a few more peaks being “detected”. I’ve added code so that pressing ESC clears the counts and starts from scratch – this can help isolate a specific transmission.

This version of the OOK Scope was used to establish more accurate pulse widths for the Oregon and Cresta sensors, and that’s was led to the values used in those decoders. The latest source code of the OOK Scope has been checked in, replacing the previous version. It’s still very small: under 200 lines of Tcl/Tk code.

Note how much you can do with just an OOK receiver and software: it’s like a special-purpose scope. For these experiments it’s in fact better than a storage scope or a logic analyzer, because of the custom pulse filtering!

Cresta sensor

In Software on Apr 16, 2010 at 00:01

Another day, another sensor:

Dsc 1339

This is a Cresta unit (no serial number on it), with a simple outside temperature sensor (which has been outside for a some time). Here’s the OOK scope fingerprint:

Screen Shot 2010 04 12 at 13.50.25

Here’s the baseline, i.e. the background signal with the sensor switched off:

Screen Shot 2010 04 12 at 14.06.37

Some clear peaks, at values 100, 135, 175, and 195, roughly. These correspond to pulse intervals centered around 400 µs, 570 µs, 890 µs, 1080 µs, respectively.

My hunch is that the 400/570 and 890/1080 pairs are really just the same pulse, skewed by the size of the preceding pulse.

In this case, it turns out that the sensor sends 3 copies of the packet, with a 1..3 counter value inside. Seeing that counter in the raw bits indicates that this sensor is not using Manchester encoding, simply 1 = 1 and 2x 0 = 0:

Screen Shot 2010 04 13 at 20.11.30

I get better results with the sensor at least 1 meter away from the receiver – a very strong signal probably adds extra spikes or shifts pulses too far apart.

Time to write a decoder for this thing:

Screen Shot 2010 04 13 at 20.15.06

With the base unit turned on to see what the values being reported are, I was again able to determine the basic details of the packet layout. Each 8-bit byte is followed by a 9-th parity bit. So this hex data isn’t as easy to read:

Screen Shot 2010 04 13 at 20.18.56

But the expected temperature values are in there, and the 1..3 channel selection is as well. Again, I’ll save the checksum verification and the post-processing in JeeMon for another day.

Onwards!

Oregon sensors

In Software on Apr 15, 2010 at 00:01

Let’s try to decode the OOK data coming from an Oregon Scientific THGR810 sensor:

Dsc 1340

It sends at 433 MHz (the above picture was accidentally set to Fahrenheit). I used the OOK scope to figure out which pulse widths to use in the decoder. Ended up splitting pulses shorter and longer than 700 µs.

Anyway, now I can write a bit-decoder for it, using the same finite state machine approach I’ve used before for KAKU and FS20. But there’s one difference: these bits are Manchester encoded, i.e. 0 has two short pulses, while 1 is one long pulse. The Manchester encoding can be deduced from the fact that when you replace two short pulses my one marker, you get more or less consistent packet lengths. Since successive 1’s must flip the interpretation of the signal, there’s one extra bit of state to carry around in the decoder.

Most of these things can be determined by trial and error. Same for the synchronization pattern, the exact bit offset to start the data, and the bit / nibble / byte order of the data.

It helps tremendously that the sensor has an LCD display, showing what values it is transmitting, of course.

My basic approach is to collect lots and lots of pulses, and save them to file as Tcl scripts. Then I weed out impossible runs of bits, keeping only what looks like potential 0/1 sequences of a decent length. Then just keep collecting, until some “packets” end up being received more than once.

Once I have a dozen or more packets which keep showing up, it’s time to look at the preamble, to try and figure out what the common prefix could be. It’s usually pretty obvious by then. The only uncertainty being at which bit the preamble stops and the actual data starts.

Anyway, for the THGR810, this is some of the data I ended up receiving:

Screen Shot 2010 04 12 at 17.43.19

If you look closely, you can already see the reported values in reverse hex in the data.

That’s it!

Here’s the main part of the decoding logic for this sensor:

Screen Shot 2010 04 13 at 16.11.39

And here’s the received data:

Screen Shot 2010 04 12 at 12.18.44

The last value is the seconds timer, showing that this sensor is reporting values roughly every 70..90 seconds. I did some resets and fiddled with the channel switches, to be able to later determine which bits they correlate to.

Another run, showing the temperature dropping from 21.1° ro 20.1°:

Screen Shot 2010 04 13 at 00.37.49

Will do the checksums and separation into readings in JeeMon … another time!

Picking up RF noise

In Hardware on Apr 14, 2010 at 00:01

In yesterday’s OOK scope, there were many pulses at around 880 µs and 1100 µs which I couldn’t explain:

Screen Shot 2010 04 11 at 152609

Here’s another graph from new readings, same sketch, same ELV 868 MHz receiver:

Screen Shot 2010 04 11 at 16.39.16

That’s clearly much better. The difference? It’s all about how you hook up the RF receiver!

This was used during the first set of readings:

Dsc 1337

And this was used for that second graph:

Dsc 1336

So the receiver is picking up a lot more noise from the Carrier Board!

It’s not that surprising, in hindsight – the Carrier Board has a lot of traces running all over it it to hook up the numerous different signals on the board.

Note also that it took 20% less time to pick up the roughly 1,000,000 pulses for that second graph. My hunch is that the receiver’s AGC is ending up being set more sensitive without the spurious noise picked up from the circuit next to the OOK receiver.

Anyway, that’s one mystery solved.

Is the Carrier Board a bad idea? Not so fast. Here’s the ELV 433 MHz receiver, plugged directly into a JeeNode:

Screen Shot 2010 04 11 at 17.19.58

And here it is again, with a Carrier Board between receiver and JeeNode:

Screen Shot 2010 04 11 at 17.28.43

So at 433 MHz, it’s now attenuating the noise from the JeeNode.

Unfortunately, it gets even more confusing: look how few pulses the 433 MHz Conrad receiver picks up when plugged directly into a JeeNode during the same amount of time:

Screen Shot 2010 04 11 at 17.38.21

I’m inclined to go with the Conrad receiver for testing BTW, since it seems to pick up all the important pulses. Much simpler to debug with less noise!

Looks like I’ll have to be real careful while comparing results and drawing conclusions. And use some sort of ground plane or shield in the final setup.

An OOK Scope

In Software on Apr 13, 2010 at 00:01

Using yesterday’s OOK plugs, I wanted to get a feel for what sort of RF pulses are flying around here at Jee Labs. It’s a first step to picking up that data and trying to decode some of it.

Meet the OOK Scope, a sketch which reports every pulse it receives over the serial port, and a matching Tcl/Tk script for JeeMon to display the results graphically, and in real time.

Here’s the “ookScope.pde” sketch:

Screen Shot 2010 04 11 at 14.17.41

The analog comparator is used to generate interrupts on each transition of the input signal across the 1.1V bandgap reference voltage (the digital pin-change interrupt would also have worked – I’ve use both in the past).

One byte of data is sent over the serial port for each transition, containing the elapsed time since the previous one.

Note that the serial port can easily become a bottleneck for all these pulses: at 57600 baud, it can “only” report some 5700 pulses per second, so rapid pulse trains under 170 µs or so will hit the serial port bandwidth limit.

Reporting pulse lengths with 2 bytes of data would halve this bandwidth, so a trick is used to be able to report pulse lengths from 20 µs to over 3 ms using a single byte of data. It works by encoding large values more coarsely, sort of like a poor man’s logarithm:

  • pulses are measured at 4 µs resolution, using the Arduino micros() function
  • pulses of 20 µs or less are ignored, they are simply too short to deal with
  • 24..508 µs pulses are reported as byte values 6 .. 127 (4 µs granularity)
  • 512..1020 µs pulses are reported as values 128 .. 191 (8 µs granularity)
  • 1024..1532 µs pulses are reported as values 191 .. 223 (16 µs granularity)
  • 1536..2044 µs pulses are reported as values 224 .. 239 (32 µs granularity)
  • 2048..2556 µs pulses are reported as values 240 .. 247 (64 µs granularity)
  • 2560..3068 µs pulses are reported as values 248 .. 251 (128 µs granularity)
  • 3072..4604 µs pulses are reported as values 252 .. 255 (256 µs granularity)
  • all longer pulses are also reported as value 255

In other words: short pulses get reported fairly precisily, longer ones less so.

Due to the way AGC (Automatic Gain Control) works, most receivers will end up constantly generating pulses, because the gain is adjusted continuously until something is detected, whether actual RF signals or noise.

So this sketch tends to generate a huge amount of data over the serial port. In my case, I’m usually seeing over 2000 bytes of data per second coming in.

That’s a lot of bytes. Trying to make sense of it is not trivial – needles and haystacks come to mind …

So let’s just start by plotting the frequency with which pulses of different durations come in. This is an excellent task for JeeMon, with its built in Tk graphical user interface.

Here’s a first plot, based on some 1,000,000 samples:

Screen Shot 2010 04 11 at 15.34.35

The shortest pulses are represented by the lines at the top (i.e. starting at 24 µs), the longest ones are lines furher down. The width of the lines is the number of times such pulse lengths were received. The whole graph is scaled to fit horizontally, with some statistics showing in the window title.

Every 10th pulse width is marked in blue. Every 100th is marked in red.

Note that these are condensed values, as listed above. The “widths” are shown as values 5..255 on the vertical axis.

What the graph shows, is essentially noise. There’s a gradual decrease in pulse widths, i.e. short noise pulses are more frequent than longer noise pulses.

There is a very surprising peak of pulse lengths around 880 µs – I haven’t figured out where they are coming from, but that’s clearly not noise.

Let’s change the graph by switching to a logarithmic scale on the horizontal axis from now on (note that the vertical scale is sort of logarithmic as well, due to the above encoding). Here’s the logarithmic version, from roughly 1,000,000 samples:

Screen Shot 2010 04 11 at 15.26.09

Interesting: there’s another source of pulses around 1100 µs – again, no idea where those come from.

Here’s a graph where I held down a button on an FS20 remote control:

Screen Shot 2010 04 11 at 15.44.50

Sure enough – peaks around 380 µs, 412 µs, and 584 µs. The FS20 protocol works with 400 and 600 µs pulses – the variations are probably due to skew in the receiver, with different skews depending on the length of the preceding pulse.

Here’s the Visonic “fingerprint”, also on 868 MHz:

Screen Shot 2010 04 11 at 16.05.53

Let’s try the 433 MHz band now – a nice clean histogram using the ELV 433 MHz OOK receiver:

Screen Shot 2010 04 11 at 15.14.58

And here’s one using the Conrad 433 MHz OOK receiver:

Screen Shot 2010 04 11 at 15.12.35

Odd, there’s a blind spot in there. Also, the Conrad receiver reports only 1/10th the number of pulses reported by the ELV receiver. Either it’s filtering out noise much better, or it’s simply a lot less sensitive!

The ookScope code (sketch and Tcl/Tk script) can be found here.

OOK plugs

In Hardware on Apr 12, 2010 at 00:01

I’d like to get some more weather sensors etc. connected to JeeNodes, so I made some “OOK plugs” by hand:

Dsc 1332

  • top: 433 MHz receiver and transmitter, by Conrad
  • bottom left: 868 MHz receiver by ELV
  • bottom right: 433 Mhz receiver (also by ELV?)

The top two units need an external 17 cm wire antenna, the bottom two have built-in PCB antennas.

Here’s my OOK test unit, using a JeeNode USB v3 and the new Carrier Board & box:

Dsc 1334

And here a first test setup:

Dsc 1335

One of the things I’d like to establish is to what extent these units can be combined in one box. A previous attempt with the OOK relay seems to indicate that there can be severe interference between these units. Even “receivers” tend to emit quite a bit of RF power from their tuned circuits over short distances.

Haven’t wired up these units yet The plan is to tie receivers to the AIO pin and transmitters to the DIO pin, so that a pair of them can be used on a single port.

Update – Here is a detailed view of the different receivers and how they were hooked up:

Dsc 1513

Dsc 1514

Closing in …

In Hardware on Apr 11, 2010 at 00:01

The first Carrier Boards and Carrier Cards have come in, as described a few weeks ago on this weblog:

Dsc 1309

The Carrier Board is sort of a chameleon, given all the options it has for connecting stuff together:

Dsc 1329

You’re not supposed to use all those options at the same time, although you could if you really want to:

Dsc 1313

On the back you can plug in either a JeeNode, a JeeNode USB, or a JeeSMD as “processing engine”. Here’s a JeeNode USB:

Dsc 1315

As you can see, the USB connector will fall inside the case when plugged in this way, e.g. when you don’t use it, or to hook up a cable permanently.

Or… you can turn the board around, and make a cutout in the case to access the USB jack from the outside:

Dsc 1316

Wanna see how much you can cram into a box? Here’s a first attempt, with still some room to spare:

Dsc 1323

One more feature worth mentioning, is that there are pads and holes for an SMD-type DC jack. Here’s the jack soldered on, with a JeeSMD plugged in (the “+” end needs to be wired up manually):

Dsc 1325

Lots of options with all this. Great, now I can start working out some projects which need an enclosure.

There is one issue with the Carrier Board, alas … It turns out that the RX/TX pins on the FTDI connector (top right, first picture) were accidentally reversed. So this board doesn’t work with a USB-BUB out of the box.

That’s ok, though. I only had five of these prototypes made – just enough to try them out. Will fix it before ordering more boards for the shop.

It’ll take some time, but it’ll all work out nicely in the end, I expect.

Debugging with LEDs

In AVR on Apr 10, 2010 at 00:01

There was a problem in the RF12 driver with startup, with hard-to-reproduce behavior, unfortunately. I couldn’t make heads or tails of it, until more details started coming in via the Jee Labs forumlong live open source!

The problem, as originally identified: sketches don’t start reliably, when power is applied through batteries.

The diagnosis: it’s not related to battery power, it’s due to the RFM12B staying in some sort of “powering-up” limbo mode for several seconds.

Trouble with this sort of problems is that they can be very hard to reproduce, and even harder to debug. It all happens at startup, before any comms with the outside world is possible, and what’s worse: sending out some debug bytes over the serial port may affect the problem, due to the time it takes to do so, or the interrupts taking place, or even RAM memory being changed by the debugging.

They’re called Heisenbugs, and they’re the worst…

In this case, the breakthrough came when I had a “reliably failing” setup: running the lcd_demo.pde sketch and inserting a call to rf12_config() was enough to get a hang after each power-up. Good – now I can chase this bug!

In this case, there was an LCD hooked up, but it gets initialized after the rf12_config() call. All I wanted to know at first, is where the code hangs.

Time for the LED debugger:

Dsc 1331

Two LEDs, inserted in an unused port. Both with 1 kΩ current limiting resistors in series (470 Ω would be brighter). One between DIO and GND, the other between +3V and AIO.

The code to init this is quite simple:

pinMode(5, OUTPUT);
digitalWrite(5, 0);
pinMode(15, OUTPUT);
digitalWrite(15, 1);

I used port 2, i.e. DIO = Arduino pin 5 and AIO = Arduino pin 15. Due to the way these LEDs are connected, the one on the left will light when DIO is set high and the one on the right will light when AIO is set low. The above code starts with both LEDs off.

Now, all I have to do is turn DIO on at the start, and move the code to turn it off further and further into the initalization code:

digitalWrite(5, 1);
rf12_config();
digitalWrite(5, 0);

As expected, the LED never turns off again – rf12_config is going haywire.

Then I tried simplifying, replacing rf12_confg() by a call to rf12_intialize(). Same outcome: hangs. So it’s not the EEPROM code.

Tried out several things: delays, sending stuff to the RFM12B driver to try and initialize it better, or even twice – no difference: stil hangs.

Hm. The RF12 driver uses interrupts. Maybe it’s in there (yuck, even harder to debug). I called rf12_inititalize() with 0 as first arg, so attachInterrupt() would not be called – and bingo … no more hang.

So the RFM12B is generating interrupts, at a point when I don’t expect it: i.e. right after initialization. Interrupts should only happen when sending out data bytes (TX FIFO empty) or when receiving them (RX FIFO full).

To make a long story short: the RFM12B is pulling the IRQ line low for some eight seconds after power up. Since the IRQ line is set up as a level interrupt, that means it’s generating interrupts all the time!

No matter what I tried, I couldn’t make the RFM12B stop generating interrupts. But then, after about 8 seconds, it ended up going high and all was fine. Go figure.

So now I’ve added a loop which waits and polls the RFM12B in the init code, until it stops pulling IRQ low. On power up, that takes around 8 seconds. On reset, there is no wait. This should fix the remaining issue reported with hanging of JeeNodes, battery-powered or otherwise, i.e. any scenario which doesn’t use resets to restart the ATmega when the RFM12B is ready. If this affected you, get the latest code and re-compile / upload your sketch.

In hindsight, I’m surprised it worked before this fix!

Case closed. One more victory over bits and silicon. Onwards!

The JeeNode USB v3 has arrived

In Hardware on Apr 9, 2010 at 00:01

Well, I finally got around to finishing the details (ehm… at least some) of the new JeeNode USB v3.

I’ve added it to the Shop, replacing the older JeeNode USB v2. Starting now, all JU’s sent out will be v3’s.

As you may recall, the main reason for bringing out a new version was because the v2 model had the 3.3V on-board regulator mounting messed up, requiring manual fixes to be made for each unit.

The new v3 board has the regulator mounted correctly. Here is a list of all the differences, since a new run gave me the opportunity to do a bit more:

  • The 3.3V regulator is now also used to supply power to the ATmega and RFM12B. This improves ADC accuracy, since running the ATmega off the FTDI regulator and bringing out 3.3V from another regulator isn’t really a good idea.

  • The RFM12B has been moved to the side a bit, to make room for a pad with hole to solder the antenna wire to. Less risk of it breaking off during use.

  • The board length has been increased (80.7 mm vs 79.8 mm) so the RFM12B no longer sticks out.

  • The USB jack has been moved out a bit, so now it sticks out. This will be more convenient when mounting the board flush against the outer wall of some enclosure.

  • There is now an on-board MAX1555 Lithium Polymer battery charge chip on board, as well as an orange LED, which lights up while the circuit is charging.

  • As a result, the PWR pins brought out on the port headers, etc, will now be at 4.2V instead of 5V, while plugged into USB. When on battery power, it will be whatever the battery supplies. You can still connect other types of batteries to the PWR pin to power the unit, as long as their voltage does not exceed 5V!

  • The on-board FTDI chip used for USB comms will be unpowered while running off batteries, to lower power consumption (it draws a few mA).

  • There is an on-board voltage divider connected to PWR, so that the ATmega can monitor the current battery voltage level. This is a high-impedance divider.

Oh, and since I got bored with just fixing things, I decided to throw a fresh bug into the mix ;)

The current boards have some incorrect silkscreen labels:

Juv 3 Silkscreen Errors

Just ignore ’em. The P1 / P2 / P3 / P4 labels are the proper ones. FWIW: this was caused by panelizing this board in EAGLE without moving the labels out of the NAME layer. Probably a common (beginner’s?) mistake.

Anyway, I’ll get new boards made once my small initial batch runs out. Speaking of batches… I’ve now got lots of obsolete “JeeNode USB v2” pcb’s :(

Comes with the territory, I guess: bugs in the atom world lead to REAL junk!

Turning the protocol around

In Software on Apr 8, 2010 at 00:01

Yesterday‘s post made it possible to send a message to a remote LCD screen. The remote node is set to constantly receive packets, and once a valid packet comes in, it displays the text.

There is no acknowledgement, so the sender does not know whether the remote node actually did receive the message, nor even whether it is turned on.

This can be solved by “turning the protocol around”: instead of sending packets to a remote receiver, the remote node periodically polls a central node to see if there is new data. The communication becomes bi-directional.

Let’s first change the code in the remote node to do this periodic polling (code here):

Screen Shot 2010 04 07 at 19.26.48

I’m using the “easy transmission” calls in the RF12 driver. They are used in a somewhat unusual way: by sending out empty packets, and then waiting for a valid acknowledgement packet to come in. This is done by checking the return value of rf12_easyPoll() – it will be 1 when an ack has been received.

But now there’s a problem. The JeeLink will immediately send an ACK back when it gets the data:

Screen Shot 2010 04 07 at 19.28.25

That’s not what we want, because the acknowledgement will contain no message text.

Instead, the RF12demo needs to be configured to use “collect” mode instead of “respond” mode. That will stop it from sending out the ACK:

1c

Now something else happens. Lots of packets will start coming in, in quick succession, because the remote node’s easy transmission setup is not getting any ACKs. So it keeps retrying:

Screen Shot 2010 04 07 at 19.31.40

We’ll need to change the JeeMon “application.tcl” script to use ACKs instead of direct packets (code here):

Screen Shot 2010 04 07 at 19.52.21

This change is fairly subtle. The SendToLCD code hasn’t changed. But it’s used in a completely different way now: instead of just sending out one packet, we set up a connection and keep it going – and therefore listening…

The trick is now to check what’s coming in, and when an empty packet from node 9 is coming in (“OK 41”, i.e. 32+9), then we send an ACK (128+9) with the message text. And since we’re done, we also quit the application.

There’s one small GOTCHA… it doesn’t work!

The problem is a bug in the RF12demo code, which prevents it from sending out packets that look like an ACK. I’ve fixed it now, so you’ll need to update your JeeLink or JeeNode – whichever you use as central node.

Once you’ve done that, it should work: power up both nodes and then launch JeeMon in the same way as before. If all is well, a message will again appear on the LCD screen:

Dsc 1327

Note that I’ve extended the remoteLCD sketch to support 2 lines of output: everything after a newline ends up on the second line of the display.

Sooo – similar result, but using a completely different mechanism.

This approach has as benefit that the remote node will stubbornly keep trying to obtain a message to display, even when packets get lost. But in its current form, that’s also a drawback: when JeeMon is not running, the LCD node will keep on retrying forever. With the easy transmission mechanism, it normally retries 8 times, once a second, but since we restart the packet every 5 seconds, it ends up constantly retrying, each second.

There are some other advantages with this remotely-initiated protocol. One of them is less important in this particular case: since the remote node is in control, it doesn’t have to keep the receiver on all the time, and can go into low-power sleep mode any time to save on battery consumption.

The second advantage is that the remote node doesn’t need to know where to get its data from. The easy transmission mechanism uses broadcasts, so whichever node decides to respond to it, gets its message displayed. As long as exactly one node always does, to prevent constant retries.

A third advantage is that the central node can detect when a remote node is up and when not, and act accordingly. This is a topic for another weblog post…

P.S. The Dimmer, Gravity, and Lux plugs have been added to the shop.

Remote LCD from JeeMon

In Software on Apr 7, 2010 at 00:01

Yesterday‘s post got a message to an LCD display, using a JeeLink with RF12demo to send the packet over the air. It works, but the packet had to be manually encoded as decimal bytes. Not very convenient.

Today, I’ll use JeeMon to streamline this somewhat. There will be several iterations of this example, so that it can also be used as an introduction to JeeMon and the Tcl programming language it uses.

To that end: here is a list of Tcl links which may be useful if you want to learn more about Tcl. Having said that – the code below should be fairly clear, even if you don’t want to dive in further.

This first example is mostly to get started with JeeMon.

Read the Getting Started section to obtain a suitable version of JeeMon (Windows, Mac, several Linux’es).

Got that? Ok, make sure it launches and no errors appear. Most likely result of doing so should be a message with “Can’t start (yet), …“. Good. It works.

Let’s set up JeeMon to send a message to the remote LCD.

  • Create a directory called “JeeMon-lcd1”.

  • Inside, create a file “application.tcl” with a text editor, and place the following Tcl program code in that text file (you can download it here):

Screen Shot 2010 04 06 at 10.14.32

  • Change the “usb-A600dVNz” in the above program to match the USB device you’re using to send the message with (can be either a JeeLink or a JeeNode). You can use the Arduino IDE to find out the proper name (probably COMn on Windows). Do not use the port of the remote LCD node, since that JeeNode is listening to incoming packets, not its serial port.

  • Launch JeeMon from the command line, by typing this command: “JeeMon lcd1” – JeeMon will now load the code contained in the JeeMon-lcd1 directory.

If all went well, you should see two things happen:

  • Some debug output will be printed:

    Sending: 72,101,108,108,111,44,32,87,111,114,108,100,33,9s
    
  • the text “Hello, World!” appears on the LCD!

Dsc 1307

To be continued…

Update – only moments ago, a bug in the RF12 driver was fixed. Make sure to get the latest one and re-build / upload the remoteLCD.pde sketch again if needed.

Demo remote LCD

In Hardware, Software on Apr 6, 2010 at 00:01

It’s hard for me to realize just how confusing all this Jee stuff can be, and it’s certainly good to be reminded of that once in a while. Not everything makes sense for people who aren’t immersed into all this every day.

I want to improve that. In fact, it’s the main reason I’ve been chasing around in search of a good forum + wiki setup. As it stands, I’m hesitant to start writing down lots of things and, eh… yes, documenting all this Jee stuff. But this will change. Promise.

For starters, some good news on the forum + wiki front: I’ve decided to standardize on Markdown as formatting language. It’s ancient (i.e. proven), it’s clean, and with just one or two extras it will be good enough for most of the things I need. The reason I’m bringing it up here, is that I’ve just finished converting all the wiki pages to Markdown, as well as 90% of the current Jee Labs documentation pages. The forum remains bbForum, but it has now been adjusted to use Markdown formatting as well. So has WordPress. In fact, this is the first weblog post written in Markdown (in Textmate, my favorite text editor).

Yeay for one set of conventions, and yeay again for simplicity!

Ok, back to the main topic of this post.

Here’s a demonstration on how to send a text string to a remote LCD via wireless JeeNodes. This is the hardware I’m going to use for that remote LCD node:

  • a JeeNode USB
  • an LCD Plug with 2×16 LCD display
  • one extension cable
  • plus a hookup to USB to power this whole thing

Dsc 1300

Ok let’s set up a simple demo sketch for the remote receiver end (code here):

Screen Shot 2010 04 05 at 20.09.58

Very simple, really: wait for an incoming packet and display the bytes as characters on the LCD. Plus some initialization code.

On the sender end, I’m using a JeeLink running the pre-loaded “RF12demo” sketch:

Dsc 1302

First step is to put the JeeLink in the right mode:

8b 4g 1i

That’s the 868 MHz band, group 4, node ID 1.

Now we can send a message to node 9, which is running the remoteLCD sketch, by sending a packet with the individual character codes to the JeeLink (the “9” at the end is the destination node ID):

84,101,115,116,32,49,50,51,9s

The result:

Dsc 1305

Yippie. No wires. Magic! :)

Gravity Plugs

In Hardware on Apr 5, 2010 at 00:01

Ok, some panelized boards and components are starting to trickle in. Here’s the first production batch:

DSC_1299.jpg

(no, I don’t reflow ’em as a triangle, it just looks pretty this way…)

You’re looking at 15 brand new Gravity Plugs, i.e. 3-axis accelerometers. This is by far the smallest SMD chip ever soldered here at Jee Labs. The pads are too small for a soldering iron, even with a 0.4 mm tip.

Out of a panel of 20, some 18 appear to be working properly, but I did have to wick away some solder (i.e. fix solder bridges) to get several of these units working.

I’ll be adding this and a few other new plugs to the shop in the next few days.

Now, if I only had some time to play with these sensors…

Stencil Jigs

In Hardware on Apr 4, 2010 at 00:01

Ok, I’ve prepared a couple more Stencil Jigs for applying solder paste:

DSC_1297.jpg

Here’s one in more detail:

DSC_1298.jpg

Basic idea is that a couple of scrap PCB pieces are hot-glued to an A5-sized piece of foam board to keep the panel in a fixed spot. Then add the stencil and fix it to the jig in exactly the right spot.

The placement of components is still a manual task, and quite a precision job for some of the latest boards, but by now my daughter and I are starting to get quite good at it – yep, it’s become a family thing :)

The new jigs will speed up production of the ever-growing Jee Labs collection of JeePlugs and other boards!

After-burner

In AVR, Hardware on Apr 3, 2010 at 00:01

To reply to a comment posted yesterday, this is the contraption I use to re-flash a JeeNode or JeeLink after the fact via its ISP connector:

DSC_1295.jpg

It has two diodes, dropping the incoming 5V power from the programmer to around 3.8V – this turns out to be needed in the case of JeeLinks, which has the VCC pin on the ISP header connected to 5V instead of the 3.3V driving the ATmega. The high voltage was causing problems with logic signal levels.

The other component on the board is a 100 µF capacitor, to reduce voltage fluctuations (it.s probably superfluous, I added it while debugging the setup).

Here’s this “after burner” in action:

DSC_1296.jpg

The long pins are at an angle, because that way they can be gently pressed into the holes and they will stay there during programming.

Like most hacks, it looks awful, but it works pretty well!

AVRISP mkII w/ 5V power

In AVR on Apr 2, 2010 at 00:01

I’ve been using the USBtinyISP AVR programmer for some time now, to set the fuses, burn the boot loader, and burn the RF12demo.pde compiled sketch into each ATmega.

Trouble is, it’s slow as molasses …

So I got the AVRISP mkII programmer a while back, but the problem is that it’s unpowered. Not good for my setup, which expects power from the USB programmer:

2937E56E-F019-4E55-99F4-60B1B15111DB.jpg

So I went looking around for tips on how to bring 5V to pin 2 of the 6-pin ISP connector. Found this mod which uses a 5-to-3.3V regulator, and this one which draws 5V directly from the board.

I decided to tap the 5V USB power, but after the polyfuse, so that a short won’t damage the computer or USB hub as easily:

DSC_1294.jpg

The connection is jumpered, so this can still be used in its original form when needed.

And then I spent ages chasing ghosts…

It turns out that avrdude needs a “-B 3” time adjustment to reliably program the chips. Now how am I supposed to know that!

Anyway, here’s the shell script I’m currently using on my old PowerBook, which automates it all:

Screen shot 2010-04-01 at 23.08.28.png

That last character being echoed is a CTRL+G, i.e. an audible bell to signal when the process is done. It used to be essential, since the USBtinyISP took so much time for each burn. Now, it’s clocking in at 17 seconds, and that could probably be reduced even further by combining the three separate avrdude runs.

A roughly 10-fold improvement!

New stencil is in

In Hardware on Apr 1, 2010 at 00:01

Just received the new solder paste stencil from Pololu, it’s laser-cut from 3 mil mylar sheet:

DSC_1293.jpg

Great, once all the parts are in I can try out the new JeeNode USB v3 boards and start “baking” a couple!

Welcome to the Café

In News on Mar 31, 2010 at 00:01

So far so good, I think yesterday’s community site setup is working out fairly well!

Here’s one of the pages, as seen by anonymous visitors:

Screen shot 2010-03-30 at 23.15.14.png

The same page, once you pick a username and register:

Screen shot 2010-03-30 at 23.16.02.png

As you can see, the site can be extended to include more features for registered users (there are lots more!).

TikiWiki has 12,723,940 options – I’ve only tweaked 83 of ’em so far…

In fact, I’ve been turning off features, stripping menus, changing permissions, and simplifying the CSS theme, to try and regain some uncluttered screen space. I may have gone too far in some areas, but there’s definitely room for further simplification in others.

There are built-in anonymous, registered, editor, and admin “groups”, so we can make this thing as open as possible w.r.t. participation, while sharing the maintenance burden later on if this site becomes hyperactive.

I still find web-based page entry and editing extremely tedious. But I’m willing to stick to this wiki formatting convention, and I can easily use my own text editor to prepare new pages off-line when it gets too painful.

I’ve moved the site to its definitive cafe.jeelabs.net URL (www.jeelabs.net and jeelabs.net will also work).

The talk.jeelabs.net forum and the wiki/jeelabs.net wiki will be kept around in read-only mode for a month or so, until all the main content has been moved over.

Update 2010-04-02 – the Café has been closed again. I’m sticking to BBpress + ProjectForum for now.

One more Forum + Wiki try

In News on Mar 30, 2010 at 00:01

Ok, I’m going to try one more forum + wiki setup:

Screen shot 2010-03-29 at 21.45.15.png

Sample wiki page:

Screen shot 2010-03-29 at 21.22.43.png

It’s based on TikiWiki, as suggested yesterday.

This new setup is hosted on the Jee Labs server again. No user signup in some big wiki farm, no tracking of activity (I don’t do big-brother style “analytics” – not now and not ever…).

The interesting aspect of TikiWIki is that it is even more powerful than Wikidot, but that almost each individual feature can be turned off, so that I can pick exactly what’s needed to create a convenient site, without all the bells and whistles which would only distract from creating useful content and discussing important topics. The flip side is that it’s quite a large set of config options to navigate through!

I’ve replaced the Wikidot with this new site, again at test.jeelabs.org – you are hereby invited to sign up and try it out (all user names are available, since this is a standalone setup). I can assure you that it is an order of magnitude more tedious for me as it probably is for you to have to go through all this hassle again…

As before – this is a test. Final decision as to whether this becomes the new Jee Labs community site will be made within the next 10 days … I sure hope this is it!

Less and less convinced

In News on Mar 29, 2010 at 00:01

After having played around a bit with the recently installed Forum + Wiki site, I’m having some serious doubts about switching over to it. Here’s the Sandbox page, as example:

sandbox.png

Looks great, right? So what’s the problem?

It’s too powerful and it’s too complex.

The #1 feature which drew me to Wikidot, is its unification of a discussion forum with a wiki. The forum is very good: hardly any setup needed, good threaded discussions, good notification options, and good admin interface. Perfectly usable, right out of the box. As I described here, the combination of a timeline-oriented forum and a project / topic oriented wiki sounds like the pefect way to merge the two major areas one would like to have on a community-based site.

But the wiki, if you pardon my French, sucks

It’s an attempt to shoehorn formatting options, style elements, and content management features into a wiki-like syntax which just doesn’t make sense. Tables, tabbed views, modules, footnotes, formulas, … the list doesn’t end, but the confusion just increases as you go along. There are numerous ways to create links, yet I can’t make internal and external links appear differently on the page. The way to change a link’s title depends on the type of link used. Some features are modules, others are built-in. I don’t know about others, but as I’ve been trying out a few things, I’m not getting more and more used to the syntax – which to me is a sign that it lacks regularity.

In terms of site structuring features, there is too much functionality: sections w/ table-of-content, tags, categories, and parent-child page relationships. The problem with this is that every contributor will choose a different mechanism when adding new pages. Some people will put everything into a single page, others will try to create “islands of personal hierarchies”, twisting the available features to match a personal preference for specific pages. I don’t fancy spending my time editing pages and adjusting structures to try and unify things. And I’m only going to end up stepping on everyone’s toes if I change something they spent ages perfecting to look “just right”.

Don’t get me wrong. There is a lot to like about Wikidot.

But for an open community site, which aims to help lots of people find their way around, while letting active members share and contribute highly informative nuggets of knowledge (link broken as of 2010-04-05), I think the Wikidot format has (far!) too many degrees of freedom. Style should be pleasing (which is evidently a personal preference) but most of all it should be uniform. This daily weblog gets information across because its style was defined long ago and has become unimportant – both for me as writer, and for its readers, judging by the friendly emails I keep receiving.

A drawback which bothers me more than I expected: posting on the forums requires signing up with Wikidot.

The other thing I found out is that browser-based editing is tedious. There’s not much Wikidot can do about that (it does explain why I prefer email-based discussions over web forums).

If only someone would create the perfect community site … open source, preferably, with minimal lock-in!

I’m inclined to keep the current forum and wiki as is for now. They are not perfect, but Wikidot is too much of a compromise. Maybe something else will come along …

Update 2010-04-05 : this particular wiki is no longer being used.

Improved carrier board

In Hardware on Mar 28, 2010 at 00:01

Two weeks ago, I posted a note about a new enclosure and carrier board design to mount a JeeNode inside.

This led to several (virtual) experiments, to figure out how it would work out in different usage scenarios. One of the main problems remaining was that the design was not suited for a JeeNode USB, because the USB connector would have been inside the case – not perfect…

Here’s an improved design, which has been sent off to create a first prototype:

Screen shot 2010-03-27 at 21.23.13.png

The main change is that this allows using either a JeeNode with FTDI connector or a JeeNode USB. This was accomplished by moving the connectors around a bit, which urned out to be fairly tricky due to the huge number of interconnections.

The new trick is that this carrier board can now be used with two different JeeNode orientations. By attaching it one way, the FTDI or USB connector will end up inside the box, while turning it around 180° will put those connectors on the left side, almost sticking out. Just right to access it through a cutout.

Two other improvements over the previous design are that the carrier board includes connectors positioned in such a way that they will accept a Room Board, and the presence of an extra FTDI connector.

As before the bottom row of five 6-pin headers gives access to all signals of the JeeNode. Plugs can be attached in many different ways, supporting lots of combinations, with room for a variety of other components.