Sketch-Driven CAD and a Fume-Extractor

Modeling a crude model for many stock parts that already exist isn’t too bad. Features are usually either consistently in imperial or metric units, and a good set of calipers can reveal these numbers to us as we try to recreate the part in CAD. A few cuts, fillets, and extrudes later, and we might have the spitting image of the part we’re holding in our hands.

But what about when we’re modeling a creative project? More realistically, what if we’re modeling a part who’s exact shape is undetermined but still needs to conform to certain size constraints?

Enter parametric modeling.

When the relationships between features and other mating parts start to matter, it’s handy to plant down some reference sketches and start using variables to ensure that size relationships are respected while we explore small tweaks in the overall shape of the part we’re modeling. Better yet, it may even be handy to model many parts as one part with Solidworks’ multibody part feature.

This past weekend, I thought I’d try to throw together a Soldering Fume Extractor for the garage bench with some cheap parts. I picked up a discarded 120 [V] AC server fan from an old surplus store and a 3-inch foil air duct from the local home-improvement shop. Alas, both parts didn’t just fit together…. Perfect–a chance to try out multibody parts in Solidworks!

multibody-solder-fan

The image below is my airflow adaptor to convert the output of the fan to a surface that I could easily attach to the air duct. The design is intended for 1/8th-inch laser-cut Delrin, and the brackets are all press-fit (also Delrin). Unlike most of the other models I’ve made, this piece is just one Solidworks *.sldprt file! Separate pieces are separate bodies in a single “multibody-part.” The beauty of designing multiple bodies into one part is that we can easily accommodate the relationships between separate mating pieces that “puzzle-piece” together into one airflow adapter. Best of all, multibody-part design is a major time-saver! Since I didn’t have to create the six different pieces as separate Solidworks files, the CAD model only took about 2 hours to design!

solder_fan_back

The final design is laser cut out of a sheet of 1/8th-inch Delrin. I wasn’t confident in the press-fit brackets, so I pasted some Sugru around each bracket’s edges. (Heads-up: most glues don’t adhere to Delrin at all. Even Sugru can be scratched off.) I also filled in the seams with Sugru to keep the fumes from escaping prematurely. The final result holds itself together quite nicely!

I’ve seen a few excellent “bathroom fan” implementations for fume-extractor builds. Bathroom fans are pretty cheap as-is, and they can move air around at a respectable 50(ish) [CFM].  That said, my surplus fan was only $12.50 and labeled as kicking out a whopping 85 [CFM]! If you’re interested in rigging an old server fan as a fume extractor, I’d highly recommend the “120-V-AC-Server-Fan” method. In case you’re a bit far from an electronic surplus store, I also discovered a similar fan at AllElectronics, although the CFM rating is a bit lower.

Not a bad weekend for about four hours of design-and-assembly and a resurrected piece of junk from the scrap heap!

 

 

Arduino Clones 101: Essential Schematic Features

Making our own Arduino Clone is actually pretty straightforward! We just need to include a few necessary features on the schematic and PCB Layout. Below, I’ve listed a collection of all the schematic features that need to be included to get a successful Arduino Clone up-and-running.

The Clock Source

clock_sourceHere’s the heartbeat of our system, the clock source. This design has a 16 [MHz] crystal oscillator, but frequencies up to 20 [MHz] are fair game for an atmega328p. (I’d recommend sticking with 8 or 16 [MHz], though, such that all of the delay functions in the Arduino IDE work as expected.) The clock source here requires two capacitors at 8 [pF] each. More details on what cap values to choose are listed here.

You can actually omit the external oscillator from the design entirely if you choose to do so, since the atmega328p (and most other AVR chips) have a built-in internal oscillator that can be used as a clock source.  Regardless of whether or not you omit an external clock, you’ll still need to configure the fuse bits such that the microcontroller recognizes and uses the correct clock configuration that you’ve chosen.

The Bypass Caps

bypass_capsIf you’ve stared at schematics often in the past, it’s not uncommon to see these “rogue capacitors” that seem to be just “dangling there” without any explanation. It turns out that these capacitors are vital for correct board behavior. I don’t have a set of equations for this one, but in a nutshell, these caps dissipate small voltage fluctuations on the input power supply, ensuring that the microcontroller has a clean, “noise-free” power source.  On the PCB layout, place these capacitors (0.1 [uF]) physically as close as possible to each of the micocontroller’s VCC pins. (Heads up: we’re only dealing with a 16 [MHz] system here, so we don’t need to be too terribly scientific about the equations behind this governing proper noise dissipation.)

The Programming Header

programming_headerUnless your chip is pre-programmed, any Arduino clone needs a way to upload the program. There are three options here.

The first option is to add a 6-pin programming header through which you can connect an AVR In-System-Programmer (ISP). The shape of this connector on the PCB is up to you. You’ll just need to make whatever adapter cable needed such that the other end plugs into an ISP. Here’s a picture of my tiny 6-pin programming header on a SMD Arduino clone.

isp_header

 

My configuration here has a voltage supply input on the programming header, but if your PCB is powered elsewhere while programming, this Vcc pin may be omitted. It’s also good practice to put a pullup resistor (~10[K] is fine) on the RESET line to prevent accidental reset from noise on that pin.

The second and third option is serial programming, enabling you to upload codeM through the TX and RX pins. The catch is that you’ll need a bootloader, a small snippet of code already living on the chip, that essentially reroutes the incoming serial data into program memory. Depending on your setup, you may also need a method of resetting the board and putting it into “programming mode.”

While this method requires only two(ish) pins (TX and RX… plus RESET, GND, and maybe VCC), you’ll still need a way of configuring the fuse bits and uploading the bootloader. If a bootloader is not yet uploaded to the chip, then only the ISP method can be used for programming. Many companies pre-program the chip with the bootloader directly before they place it on the PCB by means of a ZIF socket. This method is convenient for consumers in that you don’t have to buy an ISP (~$15) before you can start uploading code. The downfall is that this method is a bit more difficult for consumers to achieve since they need their atmega328p chips to already have the bootloader flashed and fuse bits set before they install it on the pcb. (If you go with this method, you can actually buy chips with the bootloader pre-flashed.) For this reason, I prefer programming via the first method, although I did need to pick up that $15 programmer.

The AVCC and AREF Pins

avcc_and_arefAVCC and AREF are the analog input voltage and external analog reference pins respectively. If you aren’t measuring analog signals with the onboard Analog-to-Digital Converter (ADC), you’ll need to connect AVCC to VCC, as I did above. If you are using the ADC, you’ll need to connect VCC to AVCC with a low-pass filter on AVCC. Folks on the forums suggest just a 0.1 [uF] capacitor from AVCC to GND.

the AREF pin is for providing an external analog reference for measuring analog signals. (This method must be enabled in software and defaults to using the internal reference.) My circuit above didn’t use the external analog reference, so the AREF pin could’ve been left floating. If you do use the AREF pin, you’ll want to create a reference voltage value on that pin by means of a voltage divider or some other method.

 

That’s about it! Make sure your board has a source of input power that falls below the maximum operating voltage (+6[V]), and you should be good to go!

Cheers–and best-of-luck making your own clones!

Arduino Clones 101: Fuse Bits

The Arduino toolchain does a wonderful job of hiding away unnecessary complexity that would otherwise prevent us from building up projects quickly. The compilation procedure with avr-g++, the uploading process with an ISP (in-system programmer), and the pre-configuration of the chip via its fuse bits are all hidden parts of this process. But what happens when you need to “go off the deep end” and build an Arduino-compatible circuit board from scratch? In these cases we need to dig down to the level of embedded systems engineers and understand how things work at the low level so that we can put together a working system.

In this post, I thought I’d get started introducing the Arduino toolchain and then drop down a few notes about the fuse bits.

What is AVR?

AVR refers to an entire family of 8-bit (and some 32-bit) microcontrollers produced by Atmel. Within this family is a collection of microcontrollers (let’s call ’em chips), like the

  • atmega328p
  • atmega32u4
  • attiny85
  • attiny2313

and many more….

Some of  these chips we may have even been inadvertently working with all-along without even realizing it. For instance, the atmega328p is the microcontroller on the Arduino Uno. The atmega32u4 is the main chip on the Arduino Leonardo and the Teensy 2.0. These chips are the “main brains” on the development boards. Everything else on their respective boards is mostly additional circuitry that enables easy access to the pins and programming over USB.

What’s a Toolchain?

A software “toolchain” refers to a collection of software “tools” that, together, allow you to take C or C++ source code, turn it into an executable file that the microcontroller can understand, and upload it to the microcontroller’s onboard memory so that the microcontroller can run our program. In the case of Arduino, the toolchain is “all the complicated things that happen under the hood” when you press the upload button on the Arduino IDE up until our code starts running on the Arduino board.

For slightly longer-term original projects where we want to spin our own printed circuit board (PCB) populated with the atmega328p, in many cases it still makes sense to use many of the tools provided to us by the Arduino IDE. My reasoning for this judgement call is that I’d prefer not to write my own toolchain just to upload code to an Arduino board. In this sense, I’d like to program this custom Arduino-compatible PCB with code written in Arduino and compiled with the Arduino-provided toolchain.

Before we can take a home-made Arduino board and start uploading code to it through the same toolchain, though, we need to do some pre-configuration. First, we need to design and fab our original PCB that enables programming via the In-System-Programmer (ISP) pins on the chip. (I’ll cover how to design an Arduino-compatible PCB in another post.) Next, we need to properly configure the fuse bits.

What are these Fuse Bits and why do they matter?

Fuse bits are a concept hidden to us if we’re programming Arduino Boards through the IDE. If we’re making our own Arduino-compatible PCB, though, we need to know what they are and how they affect our board.

Fuse bits refer to programmable settings for the microcontroller that tell it information about its hardware configuration. While they’re not one-time-programmable it is possible to (more-or-less) brick your setup if you upload the wrong fuse bits. Put another way, since these fuse bits tell the microcontroller important things such as: “what is my clock source?” and “should I disable reprogramming?”–it is possible to tell the microcontroller that it’s configured in a way that doesn’t match its actual configuration, in which case it may or may not listen to you.

Rest assured, there are calculators, forums, and blog posts that can give us an idea of what fuse bits we want to set before we actually write them over.

Which fuse bits do I set?

Which fuse bits you’ll want to set depend on your configuration. These fuse bits give the chip information as to

  • what clock source
  • disable programming
  • enable/disable clock prescaling for a slower processor speed
  • enable/disable brownout detection to reset the device below certain input voltage supply thresholds
  • set the starting address of program memory.

Which features to enable/disable are up to you and your configuration. Here’s some general guidelines:

  • Disable brown-out detection unless you really want to reset your circuit below certain voltage thresholds.
  • Keep the starting address of program memory at the default value.
  • Enable programming (otherwise you wont be able to program the chip after setting these fuse bits.)
  • Enable/Disable clock prescaling as you see fit. I generally put an external oscillator on my boards and disable prescaling unless I need to save power.
  • Choose the clock source that you’re actually using, and give it 65 [ms] delay time unless you can be sure that the oscillator is stable and ready before that window when the system first boots up.

It’s worth double-checking that (a) programming is enabled and (b) the correct clock source is selected before writing over the fuse bits. If not, you may not be able to communicate with the chip and render it “unprogrammable” unless you change the current configuration to whatever you set it to via the most recent fuse bit settings.

Writing over the fuse bits

Before going any further, make sure you’ve got avrdude, the flash utility, installed. Luckily, if the Arduino IDE is installed, then you get avrdude with it for free. I’m using the command line on Linux for this one. (You can do this on Mac and Windows, also.) It’s a three-line incantation, one for each group of fuse bits. Assuming our desired lfuse, hfuse, and efuse are 0xe2, 0xd9, and 0xff respectively, our command-line input would look like this:

avrdude -c usbtiny -p atmega328p -U lfuse:w:0xe2:m
avrdude -c usbtiny -p atmega328p -U hfuse:w:0xd9:m
avrdude -c usbtiny -p atmega328p  -U efuse:w:0xff:m

As each line is written, you’ll get a verification from avrdude. If you get something that says rc=-1, then avrdude can’t connect to your board for some reason. Either the power isn’t connected, the fuse bits are misconfigured to begin with, or there’s something wrong with the pcb design.

Keep in mind that these fuse bits are specific to the microcontroller. (i.e: An atmega32u4, the chip one on the Leonardo, will have different fuse bits from an atmega328p, the chip on the Uno.)

Atmega328p with Internal Oscillator:

For an 8-bit Arduino Clone using its internal oscillator, instead of a crystal (or external clock reference), the fuse bits are likely:

  • lfuse: 0xe2
  • hfuse: 0xd9
  • efuse: 0xff

Specifically, the settings are:

  • internal oscillator as clock source with 65 [ms] startup delay. (more info on the startup delay)
  • no clock division
  • default boot starting address
  • enable programming over SPI
  • disable brown-out detection

Atmega328p with External Crystal Oscillator:

For an 8-bit Arduino Clone using its internal oscillator, instead of a crystal (or external clock reference), the fuse bits are likely:

  • lfuse: 0xff
  • hfuse: 0xd9
  • efuse: 0xff

Specifically, the settings are:

  • external crystal oscillator as clock source with 65 [ms] startup delay (more info on the startup delay)
  • no clock division
  • default boot starting address
  • enable programming over SPI
  • disable brown-out detection

 

If you have need for brown-out detection, or any of the other settings for that matter, I’d recommend the AVR Fuse Calculator.

Creating Webpages Quickly

It’s about time that I redo the way I put together my website of project logs. At last: gone are the days of static html pages and ugly file structures. With a big thanks to Matt Keeter, this new workflow should make project documentation much faster.

The core idea is that the underlying content should be easy to type up, and the page typesetting should be handled automatically (a la: a LaTeX mindset). From now on, page layout is defined once in two html files called header.hmtl and footer.html, and page content is documented in a markdown (*.md) file. From there, a modified version of Matt’s Makefile converts the content file in markdown to html and then concatenates header.html, the converted content file, and the footer.html together into one html file. Woohoo! (Markdown conversion is handled with multimarkdown.)

From this point on, tweaking header.html and footer.html is all it takes to adjust the site layout. Overall, this workflow makes content much faster to push up to the site.

Thanks Matt!

The Hackaday Prize 2015

Last year, Hackaday.io pulled both the projects and the engineer-by-night out of their garages and into broad daylight where all could see. As a community, these night-time-tinkerers refresh us with their new ideas as they use-and-abuse their tools to provide a great insight. This year, the Hackaday community encourages you to get out there once more as it launches The Hackaday Prize 2015.

Hopefully, if you’re out to save the world, you’re in luck! This year’s theme looks at the worlds problems and asks you to build something that turns around and takes a stab at solving them. So go out there: burn something–learn something! In the name of science (uh, safety first), let’s use what we have (and have yet to acquire) to build something awesome.

Form1+ Test Transmission Print

I’ve avoided 3D printing for as long as I can. Now that I’m away from a marvelous school machine shop, though, I thought I’d finally take the dive after some of the success that [JB] has been having with functional prints.

This project is a bit of an old hat. Since [JB] first pointed us to using servo replacement gears as mini-combat-robot transmissions, I’ve been dropping them into project after project whenever I need a little gear reduction. Compound gears–especially the kind that can take a bit of torque in small projects–are pretty annoying to source. This all-in-one set of servo replacement gears gives us a kit that works pretty well for many simple applications.

These replacement gears have a bit of magic “zen” in that the rest of the parts needed to work with them are all stock from McMaster-Carr. It just so happens that M2 and M3 dowel pins will slip-fit into the gear bores almost perfectly (the smaller bore needs to be hand-widened with a 2mm drill bit), and two metric bearings on the output gear enable smooth and high-speed output via the spline.

(For more details on actually doing something with that spline, see [JB’s] spline adapter post.)

Continue reading Form1+ Test Transmission Print

Timers, Encoders, Rollover, and the Magic of Two’s Complement (pt 1 of 2)

In the Arduino world, delay functions are convenient.

void loop()
{
    doSomeCoolStuff();
    delay(1000);
}

Unfortunately, they’re also impractical.

Let’s say we tried to doSomeCoolStuff once per second. The code snippet above doesn’t actually behave that way because it ignores how much time the doSomeCoolStuff function call takes to return. If doSomeCoolStuff takes 15 ms, then the loop actually runs at a rate of 1.015 ms, not 1.000 ms.

One solution is to use a timer. Arduino’s hardware-abstraction layer actually makes using timers strikingly easy. milis and micros return the respective milliseconds and microseconds since the program first elapsed. Now, provided that doSomeCoolStuff() takes less than one second to complete, we might try writing the code like this:

const int LOOP_TIME = 1000;
unsigned long lastTime = 0;

void loop()
{
    unsigned long elapsedTime = millis() - lastTime;
    if (elapsedTime == LOOP_TIME)
    {
        lastTime = millis();
        doSomeCoolstuff();
    }
}

There are two subtleties here, though, but first let’s see what the code does.  Since loop repeats itself as long as the Arduino is powered, elapsedTime continues to get reassigned and checked against LOOP_TIME. If they’re equal, a new lastTime gets assigned and doSomeCoolStuff happens.

The first problem here is that code is rarely this simple. Let’s say we call some other function in the loop:

const int LOOP_TIME = 1000;
unsigned long lastTime = 0;

void loop()
{
    unsigned long elapsedTime = millis() - lastTime;
    if (elapsedTime == LOOP_TIME)
    {
        lastTime = millis();
        doSomeCoolstuff();
    }
    doSomeOtherStuff();
}

In this case, we’re also calling doSomeOtherStuff at every single loop iteration. I haven’t timed how long doSomeOtherStuff will take, but it might fall just outside the millisecond range such that 1001 or more milliseconds have elapsed before the if case is queried. If such a case happens, then doSomeCoolStuff will miss its chance to run and elapsedTime will increase until it rolls over, a very long time from now.

The fix? Check against an inequality:

    if (elapsedTime >= LOOP_TIME)

Now, even if 1001 seconds elapse, doSomeOtherStuff will indeed trigger.

Ok, now for the last point worth mentioning: can we guarantee that this line works in all edge cases? i.e: will elapsedTime always return a number between 0 and LOOP_TIME, or will it return a huge number in some weird overflow-error case?

    unsigned long elapsedTime = millis() - lastTime;

The short answer: actually yes! The longer answer is in that the binary number two’s complement representation actually handles this very gracefully.

More on that in part 2….

 

Brave New World

On the quest to build my next robot, no one mentioned that I was going to have some metastability issues, noisy data, and undefined references to main(). (Look, bub, I just signed up for the robots–what’s with all this extra stuff I ended up learning along the way?)

To fellow tinkers, engineers, and DIY-enthusiasts, this brain dump of notes and tricks are for you. May they spare you many headaches in your future endeavors.

Cheers!