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.

The Road to CNC (part 3: computer configuration)

Despite picking up a decent computer, compared to LinuxCNC’s minimum system requirements, I was still getting some awful results when running the latency test. At about over 100K for both servo thread and base thread max jitter values, I started to worry that the entire pc would be unusable for cnc work.

Luckily, with some light reading, I found a few settings to tweak that could improve these results. In short, here’s the list of changes I made

  • Disable all power-saving settings in the BIOS
  • Disable Hyperthreading in the BIOS
  • Enable all (4) cores in the BIOS
    • make sure the lscpu command returns the expected value.
  • add the isolcpus=1,2,3 option in the grub bootloader settings with a modified version of Kent Reed’s 07_rtai script
  • redirect all interrupt requests (IRQs) to one processor by means of spainmann’s script

With these tweaks, servo thread jitter is below 64K nanoseconds and base thread jitter is below 10K nanoseconds–woot, it’s usable for LinuxCNC!

There are some other settings worth investigating later, documented on IBM’s webpage on reducing jitter for real-time linux operating systems. I haven’t played around with them much yet because my system performance is far better (and now good enough) than before the initial listed tweaks.

The Road to CNC (part 2: custom kinematics)

As I kept reading about LinuxCNC, I figured I’d try it out with the CoreXY Laser Engraver I made a while back.

LinuxCNC supports a number of typical machine kinematics out of the box. (Kinematics are included for 3-axis mills, scaras, and pumas.) A CoreXY isn’t one of them, though, so I needed to write a new kinematics file for CoreXY gantries.

To add custom kinematics, I wrote a corexykins.c based on the “trivial kinematics” file, trivkins.c, and followed OOOVincentOOO’s guidelines on the forums for installation. The actual changes were staggeringly simple–only about 5 lines were changed!

To load my new configuration, I ran the StepGen Configuration Wizard, which output the needed *.ini and *.hal files. I had to edit these files manually in two places, though. In the *.hal file, to load the new kinematics, I switched the line:

loadrt trivkins

to

loadrt corexykins

Lastly, in the *.ini file, I also needed to bump up the FERROR and MIN_ERROR from 0.05 to 0.5; otherwise LinuxCNC would throw the error

 

joint 0 following error
joint 1 following error

when switching from joint mode to world mode, at which point it actually uses the inverse kinematics equations to see if the tool’s current location matches where the forward kinematics actually brought the tool. (I’m assuming that either rounding error or the fact that my pc’s software stepping can’t keep up with the desired input speed could be the reasons for this error.)

For more references on writing up custom kinematics (with examples), here’s a few links.

The Road To CNC (pt 1)

I always wanted to setup a garage workshop! Now that I’m finally living in a place with a spare garage, I decided to get started.

LinuxCNC was my first choice for numerical control of any machine that I thought I might want to setup. Since 1952 when the first CNC machine was made at MIT to crank out aircraft parts, numerical control (NC) has revolutionized the way parts are made in the modern day. Pre-1952, many, but not all, industrial fabrication machines (mills, lathes, and many more) were operated by hand; furthermore, the complexity of the part that could be fabricated was limited by the skill of the machinist. Nowadays, the instructions are defined as 2D or 3D lines and arcs and uploaded to a machine that makes cuts along these paths. Don’t worry, we still have machinists! They just have a far-more augmented toolset, and the limits of “what we can can make” have been redefined to be both the limits of what we can define parametrically and the precision of our cnc machine. (Here’s an article from Scientific American way back in 1952, when it all got started.)

LinuxCNC is one of many software packages for “numerical control” of fabrication machines. In a nutshell, it’s mature, open source, under constant improvement, and “generic enough” to extend control to all sorts of machines (lathes, mills, laser cutters) with a user-definable “hardware abstraction layer” for defining custom machine kinematics. In other words, as long as I can write down the “rules” (equations) for how my machine moves around its tool in 3D space, I can control it with LinuxCNC.

The drawback? There’s a learning curve that’s biased towards those familiar with Linux already–not to mention that LinuxCNC needs to run on its own computer with a parallel port (DB25 connector). While there’s work done on the hardware-compatibility end to run LinuxCNC on a (much cheaper!) BeagleBone, I figured it’d be great to get support from the forums with a familiar hardware setup, so I picked up a refurbished PC on the Neweggs and installed LinuxCNC 2.6 via a liveUSB key that I made with another computer. (BeagleBone, maybe next time, bub..)

I admit that before I committed to the desktop I first picked up a cheap solid-state drive, installed the latest LinuxCNC image onto it, and booted it up on my normal pc to play around with. The ethernet connection didn’t work (hardware was too new), but everything else checked out cleanly. From there, I picked up the refurbished desktop, dropped in the hard drive, and everything checked out OK (except for the parallel port which is recognized in Linux, but I haven’t yet verified if any of the I/O pins are sending signals.)

For reference, here’s the hardware list so far:

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!

Digital Design for a Digital World

Much of this writeup is founded on thoughts and words shared by Prof Neil Gershenfeld at MIT Media Labs. I owe him a sincere thanks in helping me grapple with the idea of “how to make things.”

Despite spending most of my free time “making things,” I keep asking myself the questions: how do I make things? How do I get better at making these things? Fortunately, scientists, philosophers, and engineers much smarter than me have inadvertently been asking and answering these questions for hundreds of years. (For more on that, check out Prof Gershenfeld’s talk on Digital Reality.) The answer is digital.

When I first think of digital, I think: binary. Zeros and ones. By assigning enough rules (Boolean Logic) to the world of interaction between these zeros and ones, complex machines can be designed and (these days) built. Digital Computers are a fantastic example of the success of digital, but digital is much more than just zeros and ones.

Digital is a principle.

If we revisit the idea behind a computer’s architecture, we have a structure built on top of rules that live in a boolean-logic based world. Logic gates give us a way of performing decision-making (output) based on a number of binary inputs. In reality, this architecture is encoded on top of voltage levels. We’ll say “Eh, if my voltage is above a certain threshold, let’s call that a 1,” and “Eh, if my voltage is below a certain threshold, let’s call that a 0.” Now that we have this restriction, we’ve assigned only two possible outputs to a very noisy input. The true analog voltage that gets received as input is a real number, and it’s a noisy one, too. It could be anywhere from -∞ to +∞, but we’ve assigned only two possible outputs, zero and one, to this entire range of inputs. (Aside: in real digital electronics, there’s a meta-stable range too, but it’s more tightly tied to implementation than the founding idea.) Now that we’ve encoded “what counts as a zero” and “what counts as a one” as voltages, real input signals only have two options for interpretation: zero or one. The consequences of this design choice are monumental. Given this noisy, analog medium of analog voltages, we can guarantee a clean digital interpretation, which allows us to design with boolean logic, rather than dirty analog signals. If we follow the rules, we get a structured world of only zeros and ones.

Digital exists far beyond computers though. In a nutshell, digital is a manner of encoding structure on top of an inherently analog medium. By doing so, designing complex systems (machines, buildings, etc) becomes much easier since digital guarantees are made at the foundational level. In the example above, digital is both the strict imposition that an noisy input may be interpreted only one of two ways and the guarantee that a noisy output will be interpreted only one of two ways.

Let’s consider the idea of building a skyscraper. The individual construction workers can’t independently build up the skyscraper on their own. It’s not because they physically can’t do it. Even if they physically could: let’s say–even if we had a godzilla-like construction worker on our side who was easily powerful enough (and had enough hands) to construct the entire building on his own will–he can’t. The construction workers (and Godzilla) can’t build up the skyscraper on their own because they lack the digital constraints inherent to the design. They need an architect to say “what goes where.” Without this head-designer to say how the shape of the building will go together, concrete might get poured, electronics might get wired, doors and windows might get installed, but everything would be in the wrong place. The building would be a chaotic mess of individual workers doing what they do very well, but in the wrong places and at the wrong times. The building would be a mess.

In the case of the construction workers, the actual construction tasks (laying the concrete, wiring the lights, etc) are analog, but the design is digital. Digital imposes the rules as to what should go where. A concrete foundation should be laid out on the foundation, not all over the windows and splattered on the ceilings. Electrical wires should go between the walls, not in the dirt, and not in the plumbing pipes.

In essence, we’ve assigned rules to “what goes where,” and these rules are the digital principles. If we follow the principles, then, functional components on the building go, more-or-less, in the right place.

Digital exists in the plumbing of the building as a separate example in itself! Plumbing, in one sense, is just fluids moving through pipes to the the right places. This is the range of design that Analog affords us. If we allow water to flow under random pressures to random places, however, perhaps faucets on the top floor just might not work from too little pressure, or toilets might constantly gush water out instead of flushing water elsewhere. The toilet, the faucet, and the water pressure are all components that digitize the idea of fluids just “flowing wherever they want” through the pipes.

Now that we have a grasp on what digital means, we can start to understanding on how digital makes us better at “making things.” With digital, we receive principles. In the mechanical world, we have mechanisms as the underlying principles from which complex moving vehicles can be created. In the computer-science world, we have data structures, from which we can organize our decision-making process (the algorithm). (It turns out that algorithms are also digital in that they have many common founding principles for decision-making too.) In digital electronics, we have our agreement that analog voltages should only exceed thresholds such that they are interpreted as digital information, rather than analog signals.

Without digital, design becomes much more difficult. If I’m laser-cutting sheets of plastic to assemble them together for a single purpose, I can laser-cut all I want, but if I don’t start adding mechanisms and properties (joints, links, slip-fits, press-fits) to my parts, I’m assembling mush. If I’m writing software, I can type gibberish into a text editor (and get it to compile!) as much as I want, but unless, I use common principles (saving values to variables, iterating through data with loops, recursing, using trees and hash tables) my code won’t do anything useful. Digital Design not only constrains us, but also enables us by giving us a structure.

So how do we get better at “making things?” If we can understand the digital principles that compose our world; if we design under the constraints of well-known principles (and open our eyes to creating new ones), we can design at a higher level of accuracy to create things that work.

After that, it’s all just practice.

The Delrin-Rubber Sandwich

Delrin is a fantastic material for laser-cut prototypes, but it’s also notoriously slippery. While building my desk, I needed an extra length of Rexroth (extruded aluminum) tubing mounted vertically. Rather than pick up a set of plates, I was able to mount the two tubes together with two laser-cut Delrin plates and a laser-cut sheet of santoprene (rubber) for added friction.

Behold–the Delrin sandwich! At this point my monitor is suspended nicely with the extra tubing fastened via this trick.

Using KiCad Offline

The default installation of KiCad on Linux will not actually store local copies of the KiCad default footprints. Instead, each time you run CvPCB to associate footprints to components, KiCad runs a script to download a zip of the relevant footprint libraries from Github directly. The pros to this method is that you’ll always work with the latest footprints. The cons: you must have an internet connection! This is impractical for me when I’m in for a long train ride.

Here’s the method for working with KiCad offline.

The KiCad footprints are available as separate repositories online, one repo per library. To use KiCad footprints offline, you’ll need to

  1. download each of these repositories (use the library-repos-install.sh script!) to a known directory
  2. edit the KIGITHUB environment variable (located in /etc/profile.d/kicad.sh) to point to that directory
  3. in your library table (in CvPCB), change the plugin type to KiCad, instead of Github.

From one perspective, it makes a lot of sense to mandate an internet connection when doing PCB design. I’ll almost always need to reference another datasheet, schematic, or package dimension–all reasons to have the internet handy. Nevertheless, I hope this method for offline KiCad work helps everyone else who’s laying out PCBs on their train-ride commute!