OpenSCAD is great stuff! (Part 2)

[This is Part 2 of this post; click here for the first part.]

OpenSCAD is an open-source (completely free) 3D solid CAD program; it works on Windows, Linux, and Mac OS X.

It calls itself “The Programmers Solid 3D CAD Modeller”, and indeed that’s what makes it special.

Unlike any other CAD system I’ve seen, OpenSCAD is driven entirely by a program-like script. That sounds like it would be a lot harder to use than a GUI-based CAD system – but it’s not! It’s much easier to use, with a much shorter learning curve. The scripts use a C-like syntax that will be instantly familiar to anyone who’s worked even a little with C or a C-derived braces-and-semicolon language (C++, Java, C#, etc.).

In 15 minutes with OpenSCAD, I was able to do far more than I could with AutoCAD or SketchUp after several hours – with a lot less frustration. If you have any background in programming at all, you’ll find it ridiculously easy to learn and use.

OpenSCAD has a simple but effective IDE, so you can try things interactively at the keyboard – just type some commands, mash F5, and see the result instantly. Once your 3D model is rendered, you can use the IDE to zoom in and out and look at your model from any angle.

OpenSCAD showing my modeled speaker set

OpenSCAD showing my modeled speaker set

What makes OpenSCAD great for engineering drawings is it’s ability to position and size things numerically – if you want a part exactly 3.75 inches to the left of another part, just subtract 3.75 from the x-coordinate of the part, and that’s where it will be. If you want a part to be tall enough to cover 9 other parts, just get the dimensions of the other parts, add them up (in your script) and feed the result in as the height value.

That way, if you resize one part of your model, all the other parts that depend on it for their own size and position automatically get adjusted to compensate. If you want something centered with respect to some dimension, just take the dimension and divide it by 2 to get the proper position!

None of this is “magic” performed by OpenSCAD – this is stuff done by you, in your own script (program), so it’s 100% under your control.

For example:

cube([w, h, d]);

Gives you a rectangular prism with the given width, height and depth. “w”, “h”, and “d” can be literals – so cube([1,4,9]); gives you a 2001-type monolith. Or they can be program variables, which you can pass to a module and whose values you can compute.

There are commands to translate, mirror, and rotate objects (or groups of objects), and you can assign colors and transparency to them (but not textures, yet anyway). All the basic arithmetic and trigonometry functions are there to help you compute sizes, positions, and angles. And you can construct objects by any combination of adding or subtracting primitives (rectangular prisms, cylinders, spheres, and polyhedrons).

Conditionals and iteration are available with C-like “if” and “for” statements, so you can write a “real program”.

One unexpected thing is that the compiler is somewhat primitive – all variable values are computed at compile time (not “run time”); this has to be kept in mind when writing scripts, but I didn’t find it a serious problem.

The OpenSCAD website has an excellent manual (by freeware standards) that explains all this, as well as a handy “cheat sheet” for quick reference.

So far, I’ve used OpenSCAD only for this one project, and that took just a few hours – most of the time was spent tweaking the design of my speaker case. (Unlike all the other CAD programs I tried, hardly any time was spent figuring out how the program works.)

However, I quickly found a few tricks worth mentioning:

module part(name, w, h, d) {
cube ([w, h, d]);
echo (name, w, h, d);
}

This defines a module (something like a function) called “part”, which I use to define each separate part I’ll have to cut out of plywood to assemble the speaker set. Each part has a name, width, height and depth, and when the part is rendered, it prints out (via the “echo” statement) the name and dimensions, so I get a automatically-generated “cut list” of parts to make.

For example, I have this code:

module base(x,y,z) { translate([x,y,z]) { part(“Base”, BaseW, BaseH, BaseD); } }

This defines a module “base” that will create the base of the speaker case, using the dimensions in the variables BaseW, BaseH, and BaseD. The x, y, z inputs to the module give the position where the base should be.

Later in my script, I call:

base(0,0,0);

Which creates the base of the speaker set, positioned at the origin of my coordinate space. It also prints the output:

ECHO: “Base”, 14.375, 0.75, 4.75

Which gives me the dimensions I need to cut to make the base. (The print formatting abilities of the script language are minimal, but adequate for this purpose.)

Here is the first part of my final script – it gives you an idea of how I calculated the dimensions of parts:

// Case for HelderHiFi amplifier, power supply, and speakers. 2013-03-27, nerdfever.com

// GENERAL CONSTANTS

slop = (1/16); // inches
PartAlpha = 0.5;

// COMPONENT DIMENSIONS

AmpH = 1.75;
AmpW = 2;
AmpD = 5;

SpeakerW = 4.5;
SpeakerH = 7.25;
SpeakerD = 4.5;

BatteryW = 3.5;
BatteryH = 2.75;
BatteryD = 4;

PowerW = 3.35;
PowerH = 2;
PowerD = 3.5;

// PARTS DIMENSIONS – INPUTS

Thick = 3/4; // for load-bearing base, top, supports
ShelfThick = 1/4;
StripThick = 1/8;

StripLip = 1/4;

TopW = 8.5;

PlateThick = StripThick;

// PARTS DIMENSIONS – CALCULATED

BaseW = slop + SpeakerW + slop + Thick + slop + BatteryW + slop + Thick + slop + SpeakerW + slop;
BaseH = Thick;
BaseD = max(max(max(AmpD, SpeakerD), BatteryD), PowerD) – 2*StripThick;

The idea here is that I’m allowing a “slop” of 1/16th inch – this is extra space beyond what is strictly needed per the component dimensions, to allow something for clearance and imperfect cuts.

Then I have the dimensions of the parts that need to fit inside the speaker case, and then the thickness of the plywood stock (3/4, 1/4, 1/8″) I’m going to use for different parts. Finally, from those I calculate the dimensions of the base – the width of the base is the sum of all the parts it has to hold, plus two “Thick” dimensions (for the vertical pillars), and slop around each of the parts. The base depth is calculated as the maximum of all the parts it will have to support, less “2*StripThick”, subtracting for retaining strips on either side of the base, which will be used to prevent the speakers from sliding off the base while being carried.

You can download my whole script here if you want to see it – I’m certain others have made vastly more complex and impressive things with OpenSCAD, but this shows what can be done after just a few hours of work.

When I run the script with F5, I get the rendered model:

Speaker set model. Grey boxes are speakers (translucent), blue box is amplifier. (Note the top, plus 1/8" lip around the speakers, prevent speakers from falling out unless carefully lifted.)

Speaker set model. Grey boxes are speakers (translucent), blue box is amplifier. (Note the top, plus 1/8″ lip around the speakers, prevent speakers from falling out unless carefully lifted.)

And this output:

Parsing design (AST generation)…
Compiling design (CSG Tree generation)…
ECHO: “Base”, 14.375, 0.75, 4.75
ECHO: “Long strip”, 14.625, 1, 0.125
ECHO: “Long strip”, 14.625, 1, 0.125
ECHO: “Short strip”, 0.125, 1, 4.75
ECHO: “Short strip”, 0.125, 1, 4.75
ECHO: “Pillar (less subtraction)”, 0.75, 7.625, 5
ECHO: “Pillar remove”, 0.25, 0.125
ECHO: “Pillar remove”, 5.875, 0.125
ECHO: “Pillar (less subtraction)”, 0.75, 7.625, 5
ECHO: “Pillar remove”, 0.25, 0.125
ECHO: “Pillar remove”, 5.875, 0.125
ECHO: “Shelf1”, 3.625, 0.25, 4.75
ECHO: “Shelf2”, 3.625, 0.25, 4.875
ECHO: “Power strip”, 3.625, 0.5, 0.125
ECHO: “Plate”, 5.125, 5.625, 0.125
ECHO: “Top”, 8.5, 0.75, 5
ECHO: “Clearance for speakers above lip”, 0.125
Compilation finished.
Compiling design (CSG Products generation)…
PolySets in cache: 15
Polygons in cache: 90
CGAL Polyhedrons in cache: 0
Vertices in cache: 0
Compiling design (CSG Products normalization)…
Normalized CSG tree has 21 elements
CSG generation finished.
Total rendering time: 0 hours, 0 minutes, 0 seconds

As you can see from the last line, this simple project renders nearly instantly.

From the cut list, I was able to go to my wood shop and cut out all the parts, ready to assemble:

Speaker set parts, per the cut list

Speaker set parts, per the cut list

 

I quickly piled the pieces together to see if they really fit with the components…

Front view. (Amplifier will go on top shelf.)

Front view. (Amplifier will go on top shelf.)

Back view.

Back view.

 

…and they did! Perfect on the first try!

 

Here’s the case part way thru assembly:

Case partially assembled.

Case partially assembled.

 

And the finished product, painted and wired up:

 

Front view.

Front view.

Back view.

Back view.

It sounds good, too.

OpenSCAD is great stuff! (Part 1)

It all started with a pair of Radio Shack Optimus Pro 7 bookshelf loudspeakers I picked up on eBay for a song.

These little speakers sound fantastic for their size, and at one time you could get them new at Radio Shack really cheap – I’ve been using a pair of white Pro 7AVs (the magnetically-shielded version) since the mid-90s as my PC desktop speakers.

Pro 7AV speakers (photo courtesy of Wade's Audio and Tube)

Pro 7AV speakers (photo courtesy of Wade’s Audio and Tube)

One day I was procrastinating by surfing eBay, ran across a black pair that looked nice, put in a bid, and soon had them in my basement, waiting for a project to use them.

Then I noticed the existence of low-cost TriPath TA2020-based amplifiers like this very popular one from Lepai. These things get fantastic reviews – the TA2020 uses PWM amplification and its distortion sounds like tube (valve) amplifier distortion. And audiophiles have been paying outrageous prices for tube amplifiers ever since tubes went out of style. Yet these TA2020 amplifiers go for 20 bucks! (And, yes, I know putting “audiophile” and “outrageous prices” in the same sentence is a bit redundant, but I’m not getting into that now.)

You may have figured out by now that I just can’t resist cheap things that deliver ridiculous value – it’s a character flaw. So combine the cheap-but-great loudspeakers with the cheap-but-great amplifier, and I just had to do something with them.

I decided to make a set of portable Bluetooth speakers. I’ve bought a few different Bluetooth loudspeakers and they all sound terrible to my ears; even the way-overpriced Bose ones sound bad to me (and I’m too cheap to pay that much anyway). So I thought I’d make my own.

There’s a guy Arjen Helder in Shenzhen (arjenhelder_electronic on eBay) who makes very well-reviewed TA2020 amplifiers, and he has a model “TA2024 MKV Bluetooth” with the Bluetooth module already built in. So 20 pounds sterling later (“Approximately US $30.35”), I’ve got one of those and I’m ready to start.

Helder HiFi TA2024 MKV Bluetooth amplifier

Helder HiFi TA2024 MKV Bluetooth amplifier

I wanted my speaker set to be portable, so that means they need a battery, and I happened to have an old 12V 5AH AGM battery around. Since the amplifier runs on 12VDC, that seemed a good fit. And I had a spare Harbor Freight 12V charger too ($9.99; did I mention I’m cheap?), so I figured I’d use that to both charge the battery and power the amp while it’s plugged in.

12V 5AH SLA battery and $9.99 Harbor Freight charger. (Not quite to the same scale...)

12V 5AH SLA battery and $9.99 Harbor Freight charger. (Not quite to the same scale…)

(Yes, I’m going to get to OpenSCAD. Be patient!)

So now I had most of the bits and pieces, and needed to come up with a design for the speaker set. I wanted a handle (to make it more portable; the speakers and lead-acid battery are heavy) and a place to wind some extra speaker cable, so I could separate the speakers for better stereo. That meant the speakers had to be held in a way that allows removing them, yet at the same time I didn’t want them to fall out by accident while carrying the set by the handle.

So I started sketching on paper. Here’s one of the earlier sketches:

Sketch1OK, so I’m not a good artist.

But the important thing was to get the dimensions right. I wanted it to be compact, but have room for all the pieces. (BTW, I hate using inches and fractions as much as anyone, but I’m in the US and lumber here only comes in those dimensions, so I’m stuck with them.)

As I made each sketch, I realized there were opportunities for improvement (perfectionism is another of my character flaws), so first I’d scratch things out, then at some point I’d start a whole new sketch:

Sketch2

and another:

Sketch3

and another:

Sketch4

Etc.

This was frustrating. Any little change cascaded all across the design, and it was easy to make a mistake in calculating dimensions.

So I decided to see if I could find some simple CAD program to help. I spent some time communing with Google, and decided that SketchUp (ex-Google SketchUp, now owned by Trimble) was the way to go.

I spent a few hours learning to use it, and made moderate progress getting my design into the program:

How far I got with SketchUp

How far I got with SketchUp

However, I found it very difficult to transfer the dimensions from my paper sketches into SketchUp; there didn’t seem to be any direct way to force SketchUp to size things exactly, or to position parts at particular offsets with respect to other parts. SketchUp, although it’s far simpler than most “serious” CAD programs, still has a long learning curve, and it didn’t seem very well suited to the kind of engineering drawings I was trying to do. I could easily get things close, but couldn’t get them exact (I suppose there must be a way to do it, but I didn’t figure it out).

After trying and getting stuck for a few hours, I went looking for a better solution.

And that’s when I found OpenSCAD.

[To be continued in Part 2…]

Motorola’s USB charging scheme

As I mentioned in the previous post, I have a Motorola Xyboard 8.2 Android tablet [1].

Motorola Xyboard 8.2 (Xoom 2 ME) Android tablet

Motorola Xyboard 8.2 (Xoom 2 ME) Android tablet

Among other things, I use it as a GPS (with live Google Maps) in the car – it’s a WiFi-only tablet, but I tether it to my phone via WiFi or Bluetooth, so the tablet can talk to Google in the car. This works great.

But after a day of driving, the tablet always runs out of power, even though I had it plugged into a car charger the whole time.

I tried a bunch of different car chargers, including ones rated for tablets and iPads, claiming to source anywhere up to 3.1 amps, but they all did the same thing.

Finally, I hooked up the USB charging port to some meters and an oscilloscope to see what is going on.

About USB charging

USB charging is an unreasonably complex subject. You can read lots about the details here and here and here (and of course here), but I’ll summarize:

  • Per the USB 2.0 spec, all USB devices can draw 100 mA (at 5v) without negotiation.
  • Also per the spec, USB devices can draw up to 500 mA (again at 5v) after negotiating with the USB host

In practice, lots of devices draw 500 mA without negotiating. They get away with it because most PC USB ports just supply 500 mA to all the ports, regardless of whether or not the device negotiates.

Smartphones usually want more, and tablets, much more. My Nexus 4 draws up to about 750 mA when charging. And the Xyboard tablet can draw up to 1.5 A. Most phones and tablets are smart enough to reduce the amount of current they draw if the USB port can’t supply what they want – the result is they charge slower. In the case of my Xyboard tablet, 500 mA isn’t enough to keep it from discharging – it just drains the battery slower. That’s why I run out of power after a day of driving.

It would be expensive for vendors to make a dumb charger that’s smart enough to do the USB power negotiation, and even if they did, 500 mA isn’t really enough. So they came up with their own schemes:

  • Apple has a complicated and slightly-secret scheme where on their dumb chargers they put resistors on the D+ and D- USB data lines. The effect of the resistors is to put different voltages on these lines, which indicate to the device how much current the charger can supply.
  • In 2007, the Chinese set a standard that if the D+ and D- lines are shorted together, that indicates that the charger can supply more than 500 mA (at least 1000 mA; often more).
  • In 2009, the EU set a standard almost identical to the Chinese one, except they say to put 200 ohms between D+ and D-. Happily, this is close enough to the Chinese standard that they work with each other.

So as of 2013 (as I write this), virtually all non-Apple high-current chargers do the Chinese thing and short D+ to D- to indicate their capability.

But the result of this mess is that Apple chargers can’t charge Android devices (very fast), and vice-versa.

What Motorola does

But that still doesn’t explain why I couldn’t charge the Xyboard (well enough to keep it from draining), even with a high-current Android-type car charger.

It turns out that, at least on the Xyboard 8.2/Xoom 2 ME (and possibly on other Motorola devices), they don’t follow either standard.

I started by looking at the various car chargers I’d been trying. Some were Apple type, some were Android type. I even put power resistors on the output and measured how much current they could supply without the voltage dropping – lots (2.6 to 3.1 amps, depending on which charger).

But none would charge the Xyboard at faster than 640 mA.

Motorola uses their own scheme. When you plug in the USB charging cable, it gradually loads the charger over a period of about 2 seconds. If you watch the voltage on an oscilloscope, you can see it gradually dropping as the tablet pulls more current.

If at the full current draw of about 1.5 amps the voltage drops below about 5.3 volts, then the tablet decides the charger can’t supply that much, and drops the charge rate to about 640 mA. (The threshold was somewhere between 5.28 and 5.33 volts when I tested.)

Since USB ports are supposed to supply 5 volts DC, +/- 5%, 5.3 volts is slightly more than the maximum 5.25 volts allowed. So any conformant USB charger will be interpreted by the tablet as “low current”, even if D+ is shorted to D-, and no matter how much current it can actually supply.

I’m guessing only Motorola’s own chargers supply 5.3+ volts.

It’s a shame that Motorola’s devices can’t charge from standard Android-type USB chargers. I have one of the Motorola car chargers on order; I hope that works.

And I hope this info is useful to somebody.


[1] I’ve tried 7″ and 10.1″ tablets, and I really think the 8.2″ size is the sweet spot, at least for me.

I like the Xyboard 8.2 – Motorola priced it way too high so it didn’t sell.

As it ought to be for the price they asked, it’s very well built (they claim it’s waterproof), and the ICS implementation is good (except for the minor Bluetooth problem I mentioned in my last post). It’s getting old now – if you can find one at a cheap price, it’s a nice unit.

But be aware that it’s orphaned – ICS is the last version of Android you can put on it; it sold so few units that there aren’t any custom ROMs available (although you can root it). It’s called the “Xoom 2 ME” outside of North America.

Pairing a Bluetooth keyboard with a Motorola Xyboard (Xoom 2) tablet

I bought this rather nice Bluetooth keyboard for use with my Motorola Xyboard (Xoom 2) tablet.

BT_keyboard_IMG_6561

It was about $18, shipped, on eBay. It’s small, designed for Android (it has Android-specific keys instead of iPad keys), and runs on two AAA batteries, so I don’t have to worry about keeping it charged. (It uses about 2 mA – I measured – so should be good for about 500 hours of run time on a fresh set of alkaline AAAs.)

Unfortunately, I had trouble pairing it. I don’t think it’s the keyboard’s fault, since it paired perfectly with my Nexus 4.

After much fiddling, I got it to pair – here’s the trick:

  1. Before pairing, make sure the tablet does not already know about the keyboard. (That will happen if you had a previous unsuccessful attempt at pairing.) To clear the keyboard from the tablet, do a “scan for devices” on the tablet, with the keyboard powered off.
  2. In Settings>Input, select “SwiftKey Tablet X”.
  3. Then pair.

Then it works. At least it did for me, on Motorola’s stock Android 4.0.4 build for the Xyboard 8.2 (Xoom 2 ME).  I’d guess this might apply to other Motorola tablets, too.

I think this is Motorola’s fault, but given that this is an “orphan” tablet at this point, I don’t think they’re going to fix it.

DIY conformal coating

I’ve been having some problems with nasty black somewhat conductive sooty stuff getting onto my PCBs. I decided the quickest solution was conformal coating to protect the PCB.

But I’ve never done that before and don’t know how. At first I thought of painting on epoxy with a paintbrush. But I was worried that once I coat the board it’ll be difficult to work on if I need to replace a component or something.

So I decided to try it with hot glue. Hot glue is removable, and unlike epoxy, isn’t brittle. And if I get some on the wrong place (like a connector pin or PCB button), I can take it off again.

Board fresh out of oven

I don’t really know if this is a good idea or not, but I tried it and it seems pretty OK so far.

First, I cleaned the sooty stuff off the PCB the best I could with 100% ethanol and a toothbrush. Then I baked it dry in a convection oven at 210 F for 30 minutes. It still worked.

Board in oven, above aluminum foil drip tray

Then I covered all the parts and traces with hot glue with an industrial-type glue gun (a hobby type gun would probably work too, but that’s what I have). I used Bostik type 0130 glue, which I think is pretty much the standard stuff you get in a hardware store.

I did my best to avoid covering connector pins and moving parts (buttons, piezo sounder, etc.).

The result was really ugly. Since the oven had worked well for drying the board, I thought I’d try to reflow the glue in the oven to let excess glue drip off and even out the glue.

It seemed to work pretty well. After experimenting with temperature a little, I decided 260 F for half an hour was about right. I made a drip catcher out of aluminum foil and put that under the board.

Bottom of board after reflow in oven. Note the drips.

Once it cooled off, it was really difficult to get the board off the oven rack (that glue works well).

And I still haven’t found a great way to clean the dripped glue off the oven racks. The best I could do was reheat the oven to about 300 F and then wipe off the glue with paper towels while it’s hot (carefully!). (My wife never reads my blog postings anyway…)

Next time I think I’ll remove all but one oven rack first, and hang the board from that rack so no glue gets on the rack.

Bottom of board after unsticking it from the oven rack

Simple driver code for Microchip MRF24J40 radio

Update February 2017:

User “actondev” on the Microchip Forum has posted a version for the PIC16. I haven’t tested it.

Click this to download it: MRF24J40_actondev_forPIC16.zip.


Update November 2016:

I now have this working with the MRF24J40MD module. No changes at all were needed from the code for the MRF24J40MB.


Back in September 2011 I wrote about the rocket telemetry system I built using the Microchip MRF24J40MB radio module.

As I mentioned back then, I ended up re-writing Microchip’s “MiWi P2P” stack to vastly simplify it for my application. A few people have asked for a copy of my simplified driver code, and today I’m posting it (after having cleaned up a few loose ends).

The radio supports IEEE 802.15.4 on the 2.4 GHz ISM band. The “-MB” is Microchip’s long-range module – it has the radio, antenna, power amplifier (PA), and low noise amplifier (LNA), and it’s good for ranges of 2500 meters or more (line-of-sight, outdoors). It comes pre-approved by the FCC for unlicensed use. You can read my old post for more info about the module.

File package

To get started, download the ZIP file from here.

Update 2012-03: “maxruben” from the Microchip Forum has ported this driver to the PIC24. Click here to download his PIC24 version. I haven’t tested it, but he says it works. (Thanks for permission to post this!)

I’m also told the code has been successfully ported to the PIC18, but I don’t have a copy of that. (If someone sends me one, I’ll post it here.)

This contains a whole buildable project (for MPLAB IDE v8.83) that works on my PIC32MX440-based platform.  I’ve built it with C32 v1.11b and v2.02; it should be trivial to port it to other MCUs (see notes about that below).

The files include a very short demo program in main.c that shows how to use the driver to send and receive simple packets.

The driver itself consists of 3 files:

MRF24J40.c – Driver source code.
MRF24J40.h – Headers and public function declarations.
radioAddress.h – Sets the address for your radio.

Now would be a good time to unzip the files and have a quick look at the source code.

Oh, and:

Software rights: I hereby grant everyone and everything in the universe permission – to the extent I have rights to grant – to use and modify this software for any purpose whatsoever. In exchange, you agree not to sue me about it. I make no promises. By using the design you agree that if you’re unhappy the most I owe you is what you paid me (zip). That seems fair.

Be aware that the original MiWi P2P v3.1.3 code this started from (of which there might not be any code left) was copyrighted by Microchip – they offer it free for use with their hardware (which is all it’s useful for), and I doubt they’d want to sue their own customers over it, but talk to them if you have concerns.

That having been said, if you work for Microchip (this means you, Yifeng) and find this code useful enough to refer it to customers, or if you want to supply it directly, you are very welcome to do so. I’d appreciate (but do not demand) in return (a) credit in the source code to this posting on NerdFever.com, and (b) a small token of your appreciation. A RealICE would be great. If that’s too much, how about a Microchip T-shirt or coffee mug? (I already have a ICD3 and a Microchip bag; but swag is good. You know how to find me.)

Update: A free RealICE arrived about 2 weeks after I posted this.  Thank you, Microchip (and Yifeng)!

General concept – Initialization

Call RadioInit() to initialize the radio.

General concept – Transmission

To transmit a packet, fill out the “Tx” structure to describe the packet, then call RadioTxPacket().

General concept – Reception

Call RadioRXPacket(). If there is at least one received packet the return value is non-zero (it returns the number of un-processed received packets) and the next packet is described by structure “Rx”.

Do what you want with the packet, and then call RadioDiscardPacket() to throw away that packet. Now you can call RadioRXPacket() again to get the next one (if any).

API – Transmitting

void RadioTXRaw(void);

Low-level routine to transmit a single packet described by Tx.

The Tx structure must be completely setup before calling this routine. (Don’t set the lqi or rssi fields; these are used only on received packets.)
Continue reading

Notes on using Eagle PCB

These (link to PDF file) [updated 2012-06] are my notes for using Eagle PCB, an excellent CAD program for printed circuit board design with a free (but still fully functional) “light” version.  Most of the text is my own, but there are places where I’ve cut-and-pasted information from the Eagle documentation or material found online.

To go with the notes, here is a .ZIP file containing my customized EAGLE.SCR file (sets defaults on starting Eagle), default.dru (defaults for routing), and Dave-gerb274x(2layer).cam (for making gerber files; works fine with BatchPCB).

The notes are not meant as a replacement for the Eagle documentation, but rather as commentary and interpretation.

I’ve been using BatchPCB.com to manufacture boards; their design rules influence some of the notes.

I find Eagle’s user interface counter-intuitive in many ways.  It’s powerful, but the assumptions differ a lot from common GUI programs like MS Office and Photoshop.  The fact that the manual is a poor translation from German doesn’t help. So I have to refer to these notes to refresh my memory about how Eagle works after not using it for a while.

I make no promises that this material is accurate; I write what I learn but sometimes I may misunderstand.  Feedback with corrections and improvements are welcome; please post them on NerdFever.com or email to dave@nerdfever.REMOVE_THIS.com.

Last flights of rocket glider Autonomy

Back on 28 October I covered the first 3 flights of the “Autonomy” (now “Autonomy 1”) rocket glider.

We flew it six more times, four times on 5 November 2011, and twice more on 19 November. On the last flight I forgot to arm the electronics (sigh)1, so this winter we’re planning to build “Autonomy 2”.

At the moment, the main problem we’ve been having is that the GPS loses lock on the satellites a few seconds into boost, and never regains it during the glide. Without valid GPS fixes navigation is impossible, so this is a major problem.

By way of background – the glider is meant as a way to prove out the navigation and control software for autonomous steered-parachute recovery of rockets; see this post for more details. Fellow CMASS member Boris K. built the glider airframe; I did the electronics.

(This post is adapted from the thread on TRF [more details there].)

Review of first flights

From the logged data in flash, on flights 1 and 3 (the bad ones), the parachute ejection was triggered by the failsafe “TimeToImpact” calculation, well above the 200 foot (60 m) deployment altitude. The rocket decided it was less than 4 seconds from impact while descending at > 30 MPH (13 m/s actually) so it popped the chute, despite still being well above the deployment altitude.

Only on flight 2 (the good one) did the 200′ altitude trigger a flare and then deployment.

Unfortunately, on flight 2 it looks like the GPS signal dropped out partway thru the glide. At first I thought this was because the camera (wrapped in foil) shadowed the GPS antenna, but looking at it again I don’t think that’s it. I don’t know what it is – I haven’t seen this on prior flights (under a parachute).

Also the altimeter data was really noisy – it makes it very difficult to figure out the sink rate while gliding. (See graphs at the end of this post.)

After fiddling on the bench a lot, I concluded that the source of the noise (most of it anyway) is small variations in the power supply voltage (3.3v) caused by load from the servos and radio (which draw on the same battery, but prior to the 3.3v regulator). I could see the altitude readings jump around each time a servo draws current.

Prep for 2011-11-05 flights

In preparation for the 11/5 flights, I made the following adjustments to the glider:

  • Reduced parachute deployment altitude from 60 m (200′ AGL) to 45 m (150’ AGL) to get more glide time.
  • Reduced YAW_FACTOR from 1.0 to 0.1 (100 to 10) to make it less sensitive. This makes the servo response less sensitive by a factor of 10 in yaw – this is the most I think it can be reduced and still have positive control in yaw.
  • Tweaked the port elevon 3 half-turns down to try to trim out gentle left-turning tendency seen on flight 2 of 2011-10-22.
  • Adjusted YAW_STOWED_POSITION from 0 to -1 (50 to 0) to induce a slow roll during boost to counteract any pitch tendency during boost.
  • Adjusted PITCH_STOWED_POSITION from -0.4 to -0.54 (30 to 23) to counteract pitch-up tendency during boost seen in 2011-10-22 flights. I think AstronMike was correct in his suggestion on TRF – this is caused by differential drag on the rudder (hadn’t thought of that – thanks for pointing it out!).
  • Lengthened the flare period from 3.0 to 4.0 seconds.

Most of these parameters can be tweaked on the pad with telemetry commands.

Second set of flights

On 11/5 we flew four more times. All four flights resulted in nice glides; the software tweaks seemed to help a lot. Ascent was nice and vertical, the yaw over-control problem got solved.

Unfortunately, the logged data shows that the GPS signal dropped out – again – after a few seconds on each and every flight.

On flight 1, Boris steered in the “yaw” mode, where he directly controls the yaw input to the servos. We used a “YawFactor” value of 10 (out of 100), so it was 1/10th as sensitive as on the previous flights.

Here is the video (first from the ground, then from the onboard camera):

 

On flight 2 we enabled autonomous navigation. As you’ll see, it overcontrolled a little bit (and because of the GPS dropout, navigation was impossible).

Flight 2:

 

After flight 2, we reduced YawFactor from 10 to 5, making it half as sensitive in yaw. This reduced the overcontrolling in yaw.

One flight 3, Boris steered it in the “forced navigation” mode. Here his knob inputs were used to force the navigation system to choose a steering command – this results in steering updates that are coarser and less frequent than in the “yaw” mode, but it allows the navigation system to learn from the response of the glider. Again, since the GPS didn’t work, the nav system had nothing to work from.

Flight 3:

 

For the last flight of the day we tried a larger motor, hoping for more glide time and more data. We got lots more glide time (a great flight), but again the GPS failure meant no useful data. This altitude (1300+ feet AGL) is about as high as I’d want to go with manual steering – any higher and it becomes hard to see which way the glider is pointed.

Flight 4:

 

The loss of GPS sync was again frustrating.

One possibility was a bad GPS unit – this was a new unit that had only flown on the glider. But it performed fine on the ground.

Another possibility was something about the glider flight dynamics that the GPS firmware can’t handle. The glider flies much faster than a parachute glides, while descending at a faster rate than an automobile normally would. Maybe this confuses GPS firmware that’s tweaked for use in cars.

The last idea I thought of was possible RFI from the camera, despite the foil shielding.

Prep for 11/19 flights

I corresponded with the GlobalTop (GPS maker) people – they said there is a dynamics setting in the GPS chipset I didn’t know about:

Regarding the dynamic conditions, you can execute PMTK command for setting. Our output speed is horizontal speed not vertical speed. Also, we don’t have higher accelerations.
PMTK command:
$PMTK302, MODE
Mode: Dynamics mode.
0 : Default ( fixed status)
3 : Slow Ground Vehicle (tractor, boat etc)
4 : Fast Ground Vehicle (car, train etc)
5 : Airbourne Low dynamics (<1g)
$PMTK302,3*2C<CR><LF>
//
Query Dynamics type
$PMTK402*34<CR><LF>:API_Query_Dynamics

Sure enough, the GPS was set to $PTMK302,0 (default) when I checked, so I changed it to $PTMK302,5 (Airbourne Low dynamics). I also ordered some of their new “PA6C” GPS units (successor to the PA6B I’m using now) – they said it has some features that make it (a bit) more immune to noise (a lot lower power, too).

Separately – I finally found the source of the altimeter noise. I was using the internal AVdd as the ADC reference voltage instead of the external pin. You wouldn’t think it would matter, since they’re both supposed be at Vdd – but it makes a huge difference.

Here are the results from my testing – the numbers are the standard deviation of the altimeter noise, in meters AGL:

The radio draws lots of current (> 100 mA) each time it sends a packet; so I used that as a way to test what happens when something draws lots of current.

AVdd reference, DCDC supply: 0.4 meters idle, 4.0 meters w/radio running
AVdd reference, battery supply: 0.8 meters idle, 5.5 meters w/radio

VRef+ reference, DCDC supply: 0.2 meters idle, 0.36 meters w/radio
VRef+ reference, battery supply: 0.12 meters idle, 0.15 meters w/radio
VRef+ reference, LDO supply: 0.11 meters idle, 0.25 meters w/radio

(I used the battery – 2 alkaline ‘C’ cells in series – as a reference “clean” power source.)

So, as Adrian A. (of http://www.featherweightaltimeters.com/) said on the TRF forum, the LDO supply is cleaner, but only by a little – almost all of the difference comes from using the external VRef+ pin. I think the DCDC supply is clean “enough” once I use the VRef+ pin.

I also swapped out the GPS for another one, that I flew in rockets before (under a parachute) and had worked well there.

Final two flights – 2011-11-19

On the first flight I was optimistic that navigation would work. We flew it first on a ProX G125 because the day was extremely windy and we didn’t really know how that would affect things (we only flew it on calm days previously).

Here’s the flight as seen from the ground:

You can see the parachute ejected but didn’t inflate – it remained stuck in the nose cone. Luckily there wasn’t any damage on landing, but we’ll try to avoid this problem on the next glider.

It did about 400 feet AGL (as expected with that motor), but after apogee it just spun around, because the GPS lost satellite lock about 1.6 seconds into the boost (as expected) but never regained it after apogee (not as expected).

This is extremely frustrating. I don’t know why the GPS loses lock in the glider, but works fine under the parachute. I set the high-dynamics mode (as mentioned earlier) but it seems this didn’t make any difference.

I suppose it’s possible there is some interference from the camera electronics. We didn’t unplug the camera for this flight because I thought it would likely work OK with the dynamics setting. However the GPS works fine with the camera running on the ground.

I just got 5 new “PA6C” GPS units from GlobalTop. I won’t have a chance to fly them before spring, but they say they’re less sensitive to interference than the PA6B I’ve been flying. I hope that fixes it.

We have no video from the on-board camera because we haven’t recovered the glider (and camera) yet – the video is still in there.

This flight did serve as a test of the modified altimeter. The results are mixed. The altimeter readings seem to have much less noise on the ground and during boost, but just as bad as ever during glide.

The graph below shows time (seconds, X-axis) vs altitude (feet AGL, Y-axis) for 3 flights – dark blue is this flight, magenta is the very first flight of the glider (in October, similar motor) and yellow is the 2nd flight of the glider (also in October, obviously on a larger motor):

The rocket collects an altitude reading 25 times/second (every 40 milliseconds); that’s what’s plotted here.

You can see that post-modification (dark blue) there’s a lot less noise in the altimeter up until apogee. But after that there’s still very strong noise – the altitude jumps up/down by as much as 40 feet.

I think that perhaps what I’m seeing here is a ‘whistle’ effect of air blowing and vibrating across the vent hole on the bottom of the glider. If so, it only happens in the glide configuration (which is imaginable). There’s just the single vent hole, but the electronics bay hatch (opposite from the hole) is not airtight. Suggestions for how to rearrange things to avoid this (if indeed this is the cause) will be greatly appreciated.

At the top of the graph is the battery voltage (2 x LiIon) * 100 (in cyan). There are 4 distinct dips – these correspond to current drain from (1) servos driving the elevons to boost position upon launch detect, (2) servos going to glide position at apogee detect, (3) servos going to flare position at 150′ AGL, and (4) parachute ejection current.

For the second (and it turned out, last) flight, we went to a bigger Cesaroni 296H110 motor for more altitude. Here’s the video:

I realized about 5 seconds after the crash that I’d forgotten to arm the electronics before launch. That’s a bad feeling.

With the electronics disarmed, the elevons stayed in the boost position (streamlined) for the whole flight, and the parachute didn’t deploy. It crashed across the Pow Wow river in the swamp. I didn’t see where it ended up, but I know where it is within 30 feet or so. It didn’t seem worth risking pneumonia to wade across the near-freezing river to recover the wreckage, so it’s still there. (Boris thinks it might have landed in the river itself and gotten washed downstream.) Maybe once the river freezes solid this winter I’ll try to recover it.

Here is Curtis Heisey’s photo of Autonomy 1 on it’s last flight:

It looks like I have a busy winter ahead.

  1. This is the 2nd rocket I’ve lost in my rocketry career due to forgetting to arm the electronics. Like everyone, I’ve seen it happen to others too.

    So one of my winter projects is to build a box that will sit next to the launch pad. This will connect to the ignition leads from the LCO, and have a relay inside, with the motor igniter connected to the relay. The relay will not close unless the box gets a radio message from the rocket saying that it’s armed. I should have done it long ago.

MTK ($PMTK) GPS command summary

I’ve been collecting a summary of the proprietary extension commands for NMEA GPS modules based on the MediaTek (MTK) chipsets.

Here (click to download Excel file) is the summary of all the $PMTK commands I’ve found so far. The source documents (which you’ll need for details of the parameters) are on the Web – ask Google for them.

Not every command will work on every module. You can find out if yours supports a given command by sending it and watching for the response. $PMTK001,code,3 means it worked.

Many of the commands have three variants – a code that sets a parameter, another you can use to query the current setting, and a 3rd that the GPS uses to reply to the query.

If you know of others not in the list, please contact me (as much detail as possible please) and I’ll add it.

Rev 4.2.2 schematic and PCB

A long while back I posted a version of the schematic for the electronics for my project to build a GPS-steered parachute for rocket recovery.

Since then I’ve tweaked the board a bit, to the point where the hardware design is clean and bug-free (as far as I know).

So here is the current version of the board schematic and layout, including the original Eagle PCB files as well as a PDF version of the schematic. It runs nice and stably, and could be the basis for a lot of other PIC32-based projects.

Click here to download it (zip file).

Compared to earlier versions, this one uses a DC-DC step-down for much more efficient use of the battery, and includes the reed-switch driven power on/off system I described earlier.

You are welcome to do with this as you like (modify, republish, whatever).  To make it official:

Hardware rights: I hereby grant everyone and everything in the universe permission to use and modify this hardware design for any purpose whatsoever. In exchange, you agree not to sue me about it. I make no promises. By using the design you agree that if you’re unhappy the most I owe you is what you paid me (zip, zero, nothing, nada). That seems fair.

I do ask that you credit this site (https://nerdfever.com) and post as the source, just as a courtesy; but you don’t have to.

Eventually (maybe this winter), I hope to do a new spin that will run off a single LiIon cell (instead of 2 in series, as now), and that will provide a cleaner power supply to the pressure sensor and ADC; noise on the power supply is the main source of noise in the pressure sensor readings (as far as I can tell so far).  But this version works quite well as it is.

For more info about the board, leave a comment and/or see my earlier posts:

Rocket telemetry system (September 2011)

Update on latest Rev 4.2.1 PCB, tips and status (August 2011)

New Rev 4 hardware based on the PIC32 (December 2010)

Rev3 rocket electronics part 1: Hardware (December 2009)