Computing stuff tied to the physical world

Archive for May 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


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 …


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


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.


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 }


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:


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:

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 bytes: 39680
Code size: -32768
Page size: 128
Data size: 1024
Signature: 86 00 00 01 01 01 01 03 FF 95 0F
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:


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!