Category Archives: Tech

Pentel Orenz Nero

These mechanical pencils automatically advance the lead and the nib slides and retracts as you write, to prevent the lead from breaking. This helps with thin leads like 0.3 mm, and it also has a 0.2 mm size. The automatic advance makes writing with these pencils a smooth flowing experience more like a pen, since you don’t have to pause to click the lead until you’ve consumed the entire stick.

TLDR: to form a car analogy, these pencils are like a vintage classic Triumph or MG. They’re fun to drive with unique road feel. Yet they are also less reliable and require more maintenance, so don’t drive one unless you’re handy with a wrench and enjoy working on your car as much as driving it.

Here’s how the auto-advance works. The clutch in a mechanical pencil is typically 2 or 3 arms arranged in a circle, trapped inside an outer circular ring. The lead goes through the center of the clutch. When you click the pencil, it pushes the clutch arms forward from the circular ring and they open, which advances the lead. When you release the click, a spring pulls the arms back together, grabbing the lead.

The Orenz Nero clutch is one-way. When closed (at rest), the clutch prevents the lead from sliding back into the pencil, but it doesn’t prevent the lead from pulling further out. The tip’s sliding nib is spring loaded to the fully extended position. When you write, as the lead wears down the nib slides down with it (against the spring force). When you lift the pencil, the spring-loaded nib jumps forward, pulling the lead forward with it due to friction in the nib barrel, and the fact that the 1-way clutch allows the lead to slip forward even when closed. This relies on the fact that the nib barrel has more friction against the lead, than the one-way clutch does.

The drawback of this design is its complexity and fragility. It depends on balancing the friction in the nib barrel, with its spring force, and the clutch spring tension and its arm friction. If any of these gets out of wack the pencil stops working.

The most common failure is that when you push down to write (even gently), the entire nib retracts into the pencil. In other words, the clutch slips. Either something (a tiny chunk of lead, too much graphite residue/dust) gets stuck in it preventing it from fully closing, or enough dust/residue has built up on the clutch teeth that even when closed, the lead can still slip both forward and back. Also, if you re-load a lead stick that has already been pulled through the pencil, it is more likely to slip – a small amount of lead rubbed off when it went through the pencil the first time, and the one-way clutch tolerances are so precise that even that tiny amount is enough to make it slip.

Either way, the solution is the same: disassemble the pencil and clean it. This is easy, especially if you’re familiar with mechanical pencils. Make sure to blast both nib and clutch with clean compressed air from both sides. Even if it’s not jammed, you need to clear out graphite dust/residue that will make it slip.

If you’re in the middle of writing and don’t have time to do this (which happens more often than one would like), there’s a workaround: click the pencil a few times to manually extend the lead a few mm beyond the tip, then break that lead off. This draws a fresh section of the lead stick into the clutch; it often happens that fresh section is not worn and is just a touch thicker so the clutch can grab it.

Some people say that harder lead (HB or B instead of 2B) reduces clutch slip and makes the pencil more reliable. My experience indicates this is not a complete fix but has some merit. My pencils (both 0.3 and 0.2) experience clutch slip almost as often with HB as with 2B lead – but not quite as often. Also, using high quality lead (such as AIN Stein or Uni NanoDia) does help and is a must, as it reduces the amount of dust/residue that builds up in the pencil.

A less common failure symptom is lead in the pencil not feeding into tip. I’ve seen leads stick to the inside walls of the internal plastic feed tube instead of falling into the load port. Even if the feed tube is perfectly clean, this can happen due to static electricity. The solution is to ground and demagnetize the pencil. I’ve had this happen only with the 0.2 mm pencil, because those leads are so thin and light. Thicker leads seem to have enough mass to overcome static cling.

Mike’s take: The Orenz Nero is more of a mechanical curiosity than a real pencil. Normal daily use becomes frustrating because they are so fragile and unreliable. And they are finicky about lead type and brand, which limits one’s choices. They also waste your valuable lead due to the frequent failures, disassembly and cleaning.

A better choice is the Pentel Orenz (not the Nero). It does not automatically advance the lead, and consequently its clutch grabs the lead firmly – no slipping. And it has a sliding nib, which has 3 benefits. First, it fully retracts which protects the fragile nib when not in use. Second, it protects the lead as you write, so even thin leads don’t break. Third, it reduces how often you need to click to advance it – each click gives you about 4mm of lead.

Another good alternative is the Kuru Toga Advance (or Advance Upgrade). It’s similar to the Orenz in function and price, with one advantage and one disadvantage. The advantage is that it rotates the lead as you write, keeping it sharp. This makes it comparable to a pencil having one grade thinner lead – 0.5 writes like 0.3, 0.3 writes like 0.2. The disadvantage is that the articulated nib – it rotates as well as slides – requires a slightly greater amount of clearance, which means the tip has some “wiggle”. This makes it less precise. The difference is small yet perceptible.

Between these two (Orenz vs. Advance) I prefer the Orenz. It has slightly higher build quality, using metal in places where the Advance uses plastic. This also makes it easier to disassemble for cleaning – though both are so reliable you won’t need to do this. The Orenz also has slightly better precision, since the nib has less wiggle. And it has a 0.2 mm size, which gives the ultra-sharp line that the 0.3 Advance has due to its rotation.

Stratux

Summary

Stratux is an ADS-B “In” device for pilots. I built one back in 2016 and still use it today. It’s served me reliably for more than 1000 hours of flying all over the western USA, Canada and Alaska.

Stratux features

  • FIS-B: Flight Information Services Bundle, which includes
    • ADS-B “In”: live traffic – other airplanes flying nearby
    • Weather: near-real-time
      • METAR and TAF
      • NEXRAD radar
      • AIRMETs and SIGMETs
      • PIREPs
    • TFRs: temporary flight restrictions
  • GPS: a built-in GPS that is faster and more accurate than the built-in GPS in most phones and tablets

How Stratux works

Stratux is open source software that runs on a Raspberry Pi computer. The Pi has some dongles plugged into its USB ports to handle the radios (ADS-B, GPS), and a couple of small antennas to pick up the radio signals. Parts include:

  • Raspberry Pi 3B (or later) with SD card
  • ADS-B 978 dongle
  • ADS-B 1090 dongle
  • GPS dongle
  • Barometric sensor dongle
  • Antennas for the dongles.

Mandatory minimum parts are in bold face.

The Stratux picks up data in real-time over the antenna, processes and converts the data, and transmits it on a local Wi-Fi broadcast from the Raspberry Pi.

How to Build a Stratux

Building a Stratux is simple:

  • Buy the parts
  • Plug them into each other
  • Download the software
  • Copy it to the SD Card
  • Plug the SD Card into the Raspberry Pi

How to Use a Stratux

Before using a Stratux you need to make 2 decisions about where it will fit in your airplane:

  1. How to get its antennas to see the sky
  2. How to feed it power (a USB cable)

The most common way is to put the Stratux on top of the aircraft panel, where small antennas plugged into it can see the sky. Stratux is small and light enough you can do this with velcro tape.

The next most common way is to put the Stratux behind the panel (where you can’t see it). Then you need to find another place to put the antennas with wires connecting them to the Stratux.

When the Stratux is in your airplane and turned on, it broadcasts a local WiFi signal. Connect to its WiFi on your phone or tablet. Virtually all EFB software can show the data, so whatever you already use on Apple or Android (Foreflight, Droid EFB, Garmin Pilot, etc.) will work.

How Much Does a Stratux Cost?

If you buy one pre-built ready to plug in and use, they start around $400, like this one.

If you build it yourself, the price starts around $115 and goes up from there depending on how much functionality you want.

Bill of Materials

  • Raspberry Pi 3B+: $53
  • UAT Radio: $40
  • Micro SD Card: $20
  • GPS dongle: $20
  • 1090ES & UAT Radios (pair): $75
  • AHRS sensors: $40
  • Fan & heat sink: $6

From the above, you can build a Stratux as cheap as about $115. Add another $20 if you want GPS. Add $35 ($75 – $40) if you want ADS-B on both UAT and 1090. Add another $40 if you want an AHRS sensor.

The software automatically detects and uses whatever is plugged in, so setup is simple to non-existent.

References

Stratux home: https://stratux.me

D&D Character App

Introduction

Like many nerds my age, I played D&D back in the early 80s. I started with the Basic and Expert rules, playing with my brother and sister. Somebody had to be the Dungeon Master (DM) and that ended up being me because I liked systems of logical rules, enjoyed imaginative thinking, and was fascinated by this unusual game.

A year or two later we were still playing. I had gotten more into the game which meant moving up to the “Advanced” rules called AD&D, which became the original canon as the popularity of other rules faded away. I saved up my allowance and bought the “holy trinity” of rulebooks: the Players Handbook, Dungeon Masters Guide, and Monster Manual, which were published in the late 1970s. And I invited some friends to play. In 7th through 9th grade the school librarian let us use the private conference room during lunch, which we did at least a couple times per week.

This was before computers were in common use. My family had a TRS-80 which I used and learned to program, but most families did not have a computer and kids still wrote homework and essays by hand. We played D&D old-school with paper and pencil. One of the challenges was keeping track of characters with all their attributes, equipment, etc. which was constantly changing as they adventured. I always wanted to write software to track characters, but the complexity of the data and relationships made this difficult. Rainbow magazine published a variety of programs every month (given as code listings to be typed in!), which once included a D&D character app, but it was over-simplified and unable to handle all the aspects of a character.

Later when I learned relational databases I thought they would be ideal for storing D&D characters. Yet even then, the relationships would be difficult to model. It’s not only 1:M and M:M, but also hierarchical, and relationships that are conditional based on several other attributes, with plenty of exceptions.

In the 1990s I wrote an app in C++ that ran in OS/2 using Borland OWL. It was an exercise in learning OO programming and using several Design Patterns. But I only got this app about 90% complete, since my D&D gaming was already tapering off.

Fast forward a couple of decades to late 2008 and D&D play had faded from my life. It is time consuming (especially for DMs, which was always my role) and after college it got replaced by so many other things that were happening in life, and also with my friends – jobs, marriages, kids, travel, etc. Meanwhile, Java 1.5 had been released which included Generics, a major improvement to its data modeling, followed by 1.6 which had major performance improvements. In order to bone up on this new tech, I decided to finally write the D&D character app that I always wanted. And to use these capabilities to make it fully capture all aspects. I still had over 100 characters (as paper character sheets) from old campaigns and the test would be whether I could fully store them in the app, with all their details and quirks.

Precis: the App

The app is in my public GitHub, open source under the very permissive MIT license. Anyone can download, build and run it using any version of Java 1.6 or later, on any computer (Linux, Mac or Windows). The app GUI is Java Swing. This gives it a vintage 1990s look but makes it functional and easy to program. I found Swing to be well designed and better than other GUI systems I learned in the past, including Microsoft Windows programming (with all those WM_ messages), MFC and Borland OWL.

The app not only stores characters that you create, but also generates characters. Auto-generation creates the character essentials and leaves it to you to fill in details. These essentials are a moving target as I occasionally enhance the program, but include:

  • Ability scores (generated by rolling 4d6 for each and taking the 3 highest)
  • Auto-generating all ability score adjustments.
  • Choosing the best class based on ability scores.
  • Choosing race consistent with class.
  • Choosing alignment consistent with class.
  • Auto-generating all class & race abilities & languages.
  • Randomly assigning gender, name, height, weight, etc.
  • Auto-generating starting wealth based on class.
  • Equipping the character randomly yet based on class, including armor & weapons.

The app also prints characters using a simple 2-column format. It uses the Java print service which abstracts the printer and works on any printer, on any operating system.

Much of what the app does is based on data config text files. This includes ability score adjustments, saving throws by class and level, default equipment lists (for auto-generated characters), and spell usage by class and level. Thus, some of the app behavior can be changed simply by editing these text files.

App Usage Details

The app is self-explanatory, a simple UI of tabbed panels. Yet it has some capabilities that require explanation.

The GUI layout is dynamic. As you resize the app, GUI elements may shrink, grow or move. If you find layout errors (such as text fields that are truncated), this is usually a limitation of Java Swing dynamic layout and resizing the app fixes them (grab a window corner and drag it).

All entry fields accept strings. While any text is accepted, some fields (such as ability scores and hit points) expect integers. If they are not integers, the app will still function but it won’t be able to automatically set adjustments.

Command Line Parameters

A typical app invocation looks like this:

java -jar DnD.jar

This assumes that an appropriate version of Java is in the path and you are in the app’s bin directory which contains its config files.

All of the parameters below can be combined.

Font Size

Java Swing was originally designed 20 years ago when a 1600×1200 monitor was considered high resolution. Consequently, the font size and overall GUI may be too small for modern monitors. To accommodate this, the app has a command-line parameter to adjust the font size, which also adjusts the rest of the GUI.

For example, to adjust the font 2 points larger than normal:

java -jar DnD.jar -font +2
File to Open

If you want the app to open a character file when it starts, use the -file parameter:

java -jar DnD.jar -file CHARACTERFILE

Disk Format

The app stores characters on disk using a compact binary format. A typical 1-5 level character takes about 2 kB of storage – more for higher level and multi-classed characters, but there is no arbitrary limit to the size. The first data it writes is a storage version number, for future compatibility. If I ever change the data format, this will enable future versions of the app to recognize and load characters stored in older formats.

The app remembers the last directory used to save or load a character. This is convenient, since when loading a file you only have to navigate through directories once. This also applies when you load a character on app startup.

Apply / Revert

The app uses a Model-View design. The Apply and Revert buttons transfer data between the model and view. For example, if you change the character’s name, it doesn’t apply until you click the Apply button. If you click the Revert button, it restores the UI to the state of the model, which reverses all changes you made since you last clicked Apply.

Apply and Revert buttons have different scopes. On each panel they pertain only to that panel. To do this globally, use the app menu: Edit|Apply All, Edit|Revert All.

Lists are an exception to this behavior. Changes made to lists take effect immediately.

Red Buttons

Red buttons indicate actions that might change or override user-entered data. They are used to automatically set adjustments for ability scores and classes.

For example, suppose a character earns 750 XP on a campaign. Enter 750 into the XPoints field and click the red Add XP Points button. The app will add any XP bonuses (for example, 10% bonus makes it 825), add the XP to the character’s total, and if it bumps him up a level, the app will change the level and apply relevant adjustments (new hit points, saving throws, spells, powers, etc.).

Equipment

Character equipment is modeled using a Composite design pattern. It is a tree that can be nested to any depth, indicating which items are contained within other items. Moving, copying or deleting any item affects all other items it contains.

The GUI is a drag and drop panel. Any item can be dragged and dropped anywhere else. This can also be used to reorder items at any level. The item and everything it contains comes with it. If you hold down the CTRL key while dragging, it makes a copy instead of moving it.

Class Info

The app has a panel for each of the 5 basic classes: Fighter, Cleric, Magic User, Thief, Monk. Each panel has a checkbox indicating whether it applies to the character. If it is not checked, the tab for the panel is greyed out (yet not disabled, so you can still click it). If a character already has a certain class, toggling the checkbox to disable does not delete it, but only flags it. If you disable it by mistake, simply check it again to enable it and no data will be lost – so long as you didn’t save the character or make other changes while it was disabled.

Class data starts as a zero-level placeholder. It does not become real until you set the level to some value 1 or more. Data for placeholder classes is not saved or printed, so if you enable a class for a character but you don’t set the level, that class data will not be saved or printed.

Each class has a name, which by default is the name of the Java class used to model it. You can (optionally) set this name to anything you want. If the name you use happens to be a subclass of that class, this subclass will be used in the data model. Subclass names include:

  • Ranger (subclass of Fighter)
  • Paladin (subclass of Fighter)
  • Druid (subclass of Cleric)
  • Illusionist (and MagicUser are both subclasses of MUBase)
  • Assassin (not yet implemented)

With these subclasses, the model handles a total of 9 character classes – and various combinations. Multiple class tabs can be enabled and each operates independently. For example, Fighter-MagicUser or Thief-Illusionist. However, each character can have only one of each base class, so Fighter-Ranger or Cleric-Druid is not possible (nor would it make sense).

When you give your own user-defined name for a class, your name does not have to match any of these. In this case the base class is used. For example, you could name a Cleric as “Shaman” and it would be modeled as a Cleric.

When first adding a class to a character:

  • Click on the class tab
  • Click the Enabled checkbox
  • Enter a name (optional – if you want a subclass or custom name)
  • Click the Reset/Init button (needed only if you are using a custom name)
  • Enter a level of 1 or more
    • Unless you are creating a multi-class character, in which case see below
  • Click the Level button

When you take that last step, if the level you entered is different from what was there before, it will change data on this tab, as well as on other tabs. For example, it will assign hit points and saving throws which you will see on the Combat tab. These changes apply directly to the model and cannot be reverted (which is why the buttons labels are red).

Multi-Class Characters

Multi-class characters are supported, including auto-generation of hit points and save throws. To create a multi-class character:

  • For each class tab:
    • Click on the tab
    • Click the Enabled checkbox
    • Optional: enter a custom name and click the Reset/Init button
  • After all classes have been enabled, apply all (menu Edit|Apply All)
  • Visit each class tab
    • Enter a level of 1 or more
    • Click the Level button

Hit points for multi-class characters are computed as follows: for each class, for each level, determine the hit points, add any constitution bonuses, then divide by the total number of classes. Round this number to the nearest integer (it may go up or down, depending on the fraction).

Each save throw for a multi-class character is the best (lowest) across all classes (per level of each individual class) for that category.

Class Abilities

Every class has certain abilities, which are stored in this list in the upper left of the panel. Some may be auto-generated by the app, others may be user-defined. The prefix “AG: ” (for auto-generated) is used to differentiate them. Any item that has this prefix is auto-generated. The app may remove or change it. Yet when the app manipulates this list, it ignores all items not having this prefix. This way, the app preserves any user-defined items in the list.

Spell Use

The app tracks how many spells can be cast daily by class and level. For Clerics and Druids, it also applies Wisdom bonuses. The casting of spells is different from the availability of spells. Clerics may pray or meditate for more spells than they can cast each day. Magic Users and Illusionists may know spells that aren’t in their spellbook, and memorize each day more spells than they can cast.

The casting of spells is stored in the upper Class Abilities list and the app automatically sets it.

The availability of spells is stored in the lower Spells list left for users to define.

The app configures spell use based on the class name and reverts to the default. For example, suppose the character has Cleric enabled yet named “Shaman”. The app doesn’t have a spell use config for that name, but the class is of type Cleric, so it will default to Cleric spell usage. The user can override default spell usage in the app (don’t use the AG: prefix), or he can create a data file called spells.Shaman.dat to define how he wants Shaman spells to be allocated by level. If this file exists, the app will use it to allocate spell usage for Shamans.

Paladins and Rangers gain spells only at higher levels (8th and above). Because Rangers gain two kinds of spells, Druid and MagicUser, they have 2 config files: spells.Ranger.Druid.dat and spells.Ranger.MagicUser.dat.

Printing

To print a character, use File|Print from the menu. A print dialog will appear, showing all available printers (both local and network). The printed character sheet is organized into sections and uses 2 columns. It defaults to 8.5″ x 11″ paper with 0.25″ margins, though users can change this in the print dialog.

Notes and Limitations

Assassins are not handled. They have been rare in my games (at least as player characters) so I deferred them to last and haven’t gotten around to it.

Paladins can turn the undead upon reaching 3rd level, and cast Cleric spells at 9th level. The app will show these GUI elements for characters of the appropriate level.

Rangers gain both Cleric and Magic User spells at 8th and 9th level respectively. Their spell usage will appear automatically under Ranger special abilities. When this happens, the corresponding spell lists will also appear in the GUI.

Druids cannot turn the undead, but have abilities that are otherwise the same as clerics. When the class Druid is used, the app will remove the portion of the GUI that shows turning undead.

The app GUI is dynamic, adding or removing elements as needed for the given character. This relies on Java Swing’s built-in dynamic layout. If the GUI elements don’t look right – such as squished text entry boxes – resizing the app window triggers the dynamic layout and usually fixes the problem.

Fixing the Oven

The oven in our house is a Jenn-Air model JJW 3830 about 5 years old with a touch screen interface. It recent showed an error: “F2E0 Keypad disconnected. Error enumeration 0x9.” The oven stopped working and said it needed service. It seems that modern appliances have so much delicate electronics they have become less reliable and serviceable.

I looked it up and this thing costs $7,200 ?!?! WTH !?! I couldn’t believe my eyes !?!? For that price, there is no way I’m replacing this thing before I at least try to fix it.

Before diving into the repair I did a little research. A web search on this revealed that the error message indicates a failing panel control and heat damage is common. They last 3-5 years until this problem happens. You can get a replacement board for about $800 (parts only – even more if you want Jenn Air to fix it for you) but after a while it will fail again due to heat damage.

Disassembly

After throwing the oven’s dual-pole 40 amp breaker I pulled it out from the wall with the goal of disconnecting and removing the top horizontal display controller. It turns out this was easy to do. A total of 6 screws on the unit, then unplugging 3 wires, and it was sitting on my counter. I’ll call this the “control box”. That wasn’t bad at all, a pleasant surprise, +1 for serviceability.

The safety shutoff thermistor measured 0 ohms, so it wasn’t blown. The root cause lay elsewhere.

When removing the control box, I noticed a vent for hot/moist oven air that exhausts out the front, left side, above the oven door and below the control box. The control box had been installed incorrectly with the vent inside its bottom edge. Instead of venting out below the control box, it vented directly into the control box! All that hot moist air was venting directly onto the circuit board. Ouch!

I don’t know whether this error was from the factory or from the installer – depends on how the oven is shipped and what assembly is done on site. Either way, it’s a serious mistake and an obvious root cause to the problem.

Cleaning

The circuit board was slightly heat discolored brown right where the exhaust vent hit it. Obvious heat damage, and no visible corrosion but all that moisture didn’t help it. But not melted or blown, and maybe fixable. I unplugged all the connectors on the board, sprayed them with electric contact cleaner, wiped them dry, plugged and unplugged them a few times to scrape off any light corrosion, made sure everything was clean.

Hopefully, this unplugging and cleaning would clear any corrosion that the vent caused and trigger the oven’s logic to reset itself and start working again.

Robustifying

Routing the exhaust vent properly should fix the problem. Yet despite its ridiculous price, where one might expect “price is no object” design, this oven does not have sufficient heat shielding inside between hot vents and its circuit boards. Since the control box board was already compromised, I wanted to ensure it was better protected from further heat damage.

Even when properly routed, the host moist air of the exhaust vents just below the control box. That’s better than venting directly into it, but even so, it will still get the control box toasty warm when the oven is on. Not the best design.

I bought a sheet of heat shielding that consists of a thick yet flexible aluminum reflecting surface with about 1/4″ thick fiberglass insulation glued to one side. It’s made to wrap car exhausts and protect nearby surfaces from the heat. I cut it to shape with tin snips (the kind made to cut aluminum roof gutters). I installed this shielding in two places:

  • Inside the oven, laying flat just above the exhaust vent to protect the circuit board directly above it. This sheet was about 10″ x 9″.
  • Inside the control box, along its inside bottom edge below the circuit board to protect it from the hot vent below. This sheet was about 2″ x 8″.

Note: remember to use PPE like a mask and gloves when cutting & handling fiberglass.

Conclusion

After reassembling, the oven started up and works fine. No more error messages, both top & bottom ovens work. Only time will tell whether this is a permanent fix, but I’ve at least addressed a known design deficiency and postponed a crazy expensive and premature replacement.

Room Response: Nulls and Distortion

When measuring equipment it’s important to understand some relationships between frequency response and distortion. This helps interpret results correctly and not go chasing ghosts.

Here is the distortion from my Magnepan 3.6/R speakers measured from the listener position using REW, and a Tascam DR40 recorder:

Overall it’s excellent for an in-room loudspeaker measurement. Distortion is below -40 dB (1%) above 60 Hz, drops to -50 dB (0.3%) by 200 Hz, and ranges from -50 to -60 dB (0.3 – 0.1%) in the mids & treble where our hearing is most sensitive to it. This is less distortion than most quality headphones. And it’s actually even lower than this because it includes the room’s ambient noise and distortion from the Tascam DR40 built-in mics.

However look at that big distortion bump around 170 Hz. What’s going on there? The short answer is nothing – it is a measurement error. To see this, look at the frequency response:

See that dip at 170 Hz? It’s caused by a null. Its wavelength matches twice the distance from the speakers to the front wall. With dipoles, the back radiation is inverted polarity from the front, so its cancels at that frequency, creating a null. Note that this null exactly matches the frequency where the distortion graph bumps. That’s no coincidence!

When REW runs the frequency sweep, the response picked up by the microphone dips at 170 Hz. Distortion is the ratio of higher frequencies to the fundamental, and when the fundamental drops, that ratio jumps even if the higher frequencies (distortion) remains constant.

On a similar vein, the graphs show small distortion bumps at 450 and 600 Hz, corresponding to frequency responds dips at the same places.

A closer look reveals more subtle effects of the same cause. If the response dips at 170 Hz, then any 2nd harmonic from half that frequency won’t get picked up either, so that frequency will show a dip in 2nd harmonic. This explains the dip in the red line (2nd harmonic) at 85 Hz. Same with 3rd harmonic, and we see a dip in the orange line (3rd harmonic) at 57 Hz.

To confirm, here’s that same distortion graph shown as dbFS: absolute level instead of relative to the fundamental:

The scale shifted about 20 dB down but the shape of the curve is the key point.

Pretty cool, huh?

Goodbye Evernote, Hello Obsidian

Summary

I’ve been an Evernote subscriber and daily user for the past 14 years. I recently switched to Obsidian. Key reasons:

  • Obsidian has native clients on all platforms: Windows, Mac, Linux, Android and iOS, while Evernote doesn’t support Linux.
  • The Obsidian clients are lightweight and fast, while the Evernote client is bloated and slow.
  • Obsidian stores your notes in text markup, using filesystem files & folders, while Evernote uses an opaque proprietary format and stores it on their servers.
  • Obsidian enables you to organize your notes into folders with no arbitrary limits to nesting depth or complexity, while Evernote limits you to a 2-level hierarchy of Stacks and Notebooks.
  • Obsidian enables you to store your notes anywhere you want on your device (even SD cards on Android devices), while Evernote stores it internally.
  • Obsidian cleanly separates the function of syncing data across devices, giving you several different options. Evernote’s syncing is built-in and proprietary.
  • Obsidian is free unless you want enterprise support or to use their data sync.

I had been using Evernote for so long, and had so much data in their system, I thought I was stuck with them for life. I dreaded switching tools because the effort of doing so seemed intimidating and risky. I am willing to pay for software and services, if they solve an important problem for me, I use them frequently, and they work well. But Evernote started failing on that last point.

The end state is that it took me 2 days to make the switch. This includes exporting all my data from Evernote, preserving its structure (stacks, notebooks, tags), getting into all my devices, running Obsidian clients on each device, synchronizing the data, and testing the system.

Part 1: Why Switch?

For the first few years Evernote was great. The only thing I didn’t like is they didn’t have a Linux client. I found the open source Nixnote2 project and even contributed some features to it in 2017. I used this for a few years until Evernote released their own Linux client, at which point I joined their beta program and started using it. It worked well and note taking life was good!

Later, Evernote not only stopped supporting their Linux client but also disabled it. And Nixnote2 didn’t work as well as it did before, due to changes Evernote made to their APIs. So I was stuck with using Evernote only in the browser. It worked OK, but not as nice as the desktop client.

Meanwhile, the Evernote Android clients were getting progressively bloated and slow with every release. Touch the app to start it, and wait up to a full minute before it’s usable. And even then it’s painfully slow. Almost unusable.

Also, Evernote was prone to sync errors when you work on more than 1 device. Edit a note and later a duplicate copy shows up because some other device hadn’t stored its changes, one got stale, Evernote couldn’t merge them so that is up to you to do manually. Ugh.

Finally, Evernote jacked up their prices, more than doubling the price of a basic personal subscription and limiting its functionality in an attempt to up-sell.

At this point my annual subscription was a few weeks away from renewing so I decided to check out alternatives.

Part 2: Pick an Alternative

There are many options for note takers. My most important requirements are support for Linux, data sync across devices, and lightweight fast clients. Also important to me is using accessible data formats and control over my data – where it resides, how I sync, etc. Last is price. Free is nice and I don’t mind setting things up on my own. But I’m willing to pay if necessary and it gives benefits worth the cost.

Obsidian met all these requirements so I gave it a whirl. My plan was to get it working and use it for a few weeks before I had to decide whether to renew Evernote.

Part 3: Setting up Obsidian

I found several great walk-throughs online about all of this, available to everyone, so I’m only going to outline the steps I followed and add a few tips.

Step 1: Export your Evernote Data

I used Evernote-Backup from GitHub. I installed and ran it inside a Python virtualenv just to be clean and safe.

This connects to the Evernote API to extract all your data, stores it in a local SQLite3 database, and exports ENEX files from that database. It preserves your Evernote stacks & folders too.

Note: the –single-notes flag is a bit confusing. It extracts each notebook to a separate file and it stores the files in folders representing their structure in Evernote. So far, so good. But when you import this into Obsidian, it ignores the directory structure, the stacks & notebooks are ignored, and all your notes appear in one big flat directory. Ugh!

The default behavior (without the –single-notes flag) creates an ENEX file for each notebook. Within each file are XML elements marking the individual notes it contains. This means it creates fewer files, yet larger ones. When you import this into Obsidian, it recreates the notebook structure and it also breaks the individual notes into separate .MD files. This is what I wanted!

At this point all my Evernote data was imported into Obsidian, preserving the folders. And I could also browse it in the filesystem. Any changes I made on one side (Obsidian or filesystem) appeared nearly instantly in the other. Very nice!

Step 2: Set up Sync

Next you need to decide how you want to synchronize your data across devices. You have several options:

  • Obsidian Sync: built-in, seamless, but opaque, and costs $10 / month.
  • Google Drive (DropBox, Box, etc.): copy your entire Obsidian data (directory tree) to the cloud storage system of your choice, and use the apps of your choice to synchronize it across your devices.
  • Git: copy your Obsidian data to GitHub/GitLab and use the apps of your choice to clone, push, branch, etc. across your devices.
  • Local: use Syncthing to sync devices on a local network.

All of these options are described in detail with tutorials you can find online. I chose Google Drive and it works nicely. My preferred sync apps:

FolderSync Pro is a great app that is highly configurable. The setup I’m using for Obsidian is a 2-way sync, including deletes and hidden files, scheduled daily, with instant sync of local changes on the mobile device. Using MD5 checksums makes the sync more efficient (both FolderSync and Google Drive support them).

Yet I have found that OverGrive is smarter & faster than FolderSync. For example if I move a directory, OverGrive handles it with a single operation – fast and efficient. Foldersync Pro handles it by downloading all the files in the new location and deleting them from the old location – much slower!

Update: Out with Google Drive!

The Problem

After a month of note-taking across 4 devices, a bunch of spurious files started appearing in Google Drive. After some testing I discovered what is going on, though I don’t know why. Here’s a simple example:

Suppose you have 2 devices, A and B. Your notes are in the cloud C. That makes 3 versions of your notes: C is the master with complete copies residing on A and B.

We start with A, B and C being identical. Now you edit a note N on device A, which uploads N to C. This should update and replace file N on C, but instead Google Drive creates a new file called “N (1)”. This downloads to device B as a new file.

Now if you edit note N on device B, you won’t see the changes made from A because they’re in a different file “N (1)”. If you don’t notice that N is out of date and you change it, device B uploads N to C and Google Drive duplicates the file again, to “N (2)”.

Now note N is split across 3 files, each having different changes that you need to manually merge and delete the duplicates.

The Solution

There is no solution. This behavior is built into Google Drive and cannot be changed. It’s been repeatedly reported as bug but they haven’t fixed it and never will.

Fortunately, we have several choices for cloud storage. I stopped using Google Drive and switched to S3.

In with Amazon S3

Obsidian has a community plug-in called Remotely Save. It is a free, open source GitHub project. Well, not entirely free. Most of its capabilities are free but it has extended capabilities if you pay for it. Fortunately, its basic free capabilities include bidirectional sync to a variety of cloud storage providers.

Using S3 to store Obsidian notes is a bit more complex to set up than consumer services like Google Drive or Dropbox. With S3 you need an AWS account, you need to create S3 buckets, set their security, create IAM users, etc. This is the kind of basic cloud stuff software engineers do every day, but normal people might find it confusing.

I did all that and it’s all working in S3 across 4 devices (desktop, laptop, phone, tablet). So far, so good!

This solution has the added benefit of relying on an Obsidian plug-in, which works seamlessly within Obsidian on all my devices, so I don’t need other software like OverGrive or FolderSync to do the job.

Conclusion

Obsidian is a better note taking experience than Evernote. Sync is the part of Obsidian that you must figure out on your own. Amazon S3 works well for me and the activity costs about 12 cents per month on my AWS bill. That’s pretty cheap considering I am a daily active user syncing across 4 devices.

Obsidian notes are in .MD format so I can read and write them with pretty much any app outside Obsidian if I want to. I can organize my notes (move folders around, etc.) from within Obsidian, or in a file manager, or at the command line, whatever tool is best for the task. And I have more confidence in my data, since I have total control over where it’s stored and how I back it up.

Windows 11

Windows Rant (Skippable)

I’ve had to use Windows since version 3.0 back in 1990. I’ve never liked it. It’s an unreliable, low performance, insecure buggy “toy” operating system. Even after Windows NT 3.51 which was the first somewhat reliable version (thanks to David Cutler because nobody at Microsoft could have pulled that off), it was still insecure and unreliable.

But plenty of software runs on Windows, so many of us are stuck with it. As Linux has advanced in maturity and popularity I’ve reached the point where it does 99% of what I need. But I still need Windows for a few things, namely running TurboTax, getting library books (Adobe Digital Editions) and printing to CDs and DVDs (Epson).

Windows version 10 to 11

Now that Windows 10 is being decommissioned, the upgrade to Windows 11 should be seamless – but it’s not. Every new version of Windows gets increasingly bloated with worse performance, and Windows 11 also requires TPM and Secure boot. I run Windows 10 in a VirtualBox VM and need to upgrade to version 11. But the Windows upgrader refuses to do this, saying TPM and Secure boot are required. This means starting with a new install on a new VM, losing all my data and apps, or having to move them over from the old VM to the new one.

Windows 11 can run just fine on this VM. There is absolutely no technical reason it can’t upgrade. It refuses due to an arbitrary decision Microsoft made, that everyone needs TPM and Secure Boot. Microsoft is like Apple – they think they know what their users need, better than the users themselves. So Microsoft does not allow users to override these artificial requirements, which adds a level of capricious arrogance to their decision. And leaves millions of users stranded.

Flyoobe to the Rescue!

Flyoobe “FLY-Oh-Bee” is an open source Github project that fixes this problem: https://github.com/builtbybel/Flyoobe

It runs the standard windows installer yet bypasses the unnecessary restrictions & requirements. But wait, there’s more! It also facilitates getting the Windows 11 upgrade files, providing several methods. And it improves the installation and customization, making it easier to remove the junk you don’t want, such as bloat-ware, spy-ware, AI and advertising.

The entire process is self-explanatory and there is plenty of info and reviews from reliable sources. Check it out and Google it.

Cut to the Chase

After the Windows 11 upgrader refused to upgrade my Windows 10 VM, I used Flyoobe to do it. It worked great, in place preserving my apps and data, and also enabled me to customize the Windows 11 to eliminate junk I didn’t want, saving disk space and improving performance.

The only drawback is that the upgrade took over 4 hours to run. This was due to the fact that the upgrade needs 30+ GB of free space that you don’t need after the upgrade is complete. I had to use an external USB stick for this, which slowed the process.

The net result is that I’m finally upgraded to Windows 11. Thanks to Flyobee, not to Microsoft.

LineageOS on Tablets (and Airplanes)

Introduction

When I first started flying airplanes we used paper charts and books for maps and airport information. Every couple months we bought updates and most of us subscribed so they were sent in the mail as soon as they were published. Soon afterward, electronic versions of this became available and eventually the FAA revised their rules to accept these electronic versions. We now call this an “Electronic Flight Bag” or EFB.

Since then, I have used Android tablets and software for my EFB. I fly with a kneeboard for ease of checklists and writing (paper & pencil) and use a tablet that fits into my kneeboard. In the early days big tablets were too thick and heavy so I used a 7″ tablet. That’s pretty small for reading charts and procedures. Over time tablets got thinner and lighter and now I use a 10.5″ tablet. This measures as 9.5″ tall and 6.5″ wide; Android tablets are less square than iPads, which is a good thing since they fit better into kneeboards.

An EFB device doesn’t need a fast processor or fancy graphics or the latest version of software. The most important factors are:

  • Size: fits where you want – whether your kneeboard or elsewhere
  • Battery life: lasts all day, or as long as you need for a day of flying
  • Screen: bright enough to see in daylight
  • Connectivity: has WiFi, Bluetooth, Mobile data, or whatever you need in your airplane
  • Software: can run your EFB applications, usually means no more than 5 years old

My Airplane

Years ago I built a Stratux, which is a Raspberry Pi that provides ADS-B “In” and precise GPS. It broadcasts this data over a local WiFi in my airplane. It does not have or need internet access. The ADS-B “In” includes traffic (airplanes in the sky near me), weather, and NEXRAD imagery all updated in near-real-time.

Because of the Stratux, my EFB device only needs WiFi. It doesn’t need its own GPS, Bluetooth, or Mobile data, though it’s nice to have built-in GPS in case the Stratux fails. It’s also nice to have an ambient light sensor so the screen can automatically adjust to flying at night.

EFB Tablets

For several years I’ve been using an old cheap Lenovo 8505F. It’s been abandoned by the manufacturer and stuck on Android 10 for a long time. The battery health is deteriorating. And it’s so slow it’s frustrating to use as newer software gets more bloated expecting ever faster devices.

I decided to get a tablet that is officially supported by LineageOS, since then I won’t be stuck with planned obsolescence on an ancient version of Android. This led me to the Samsung Galaxy Tab S5E. I found one on eBay for $100 in really nice condition, like new.

LineageOS

After booting up the new tablet and ensuring all its functions worked, I followed the procedure to install LineageOS. It typically goes like this:

  1. Unlock the device bootloader.
  2. Load a custom boot image.
  3. Load a custom recovery.
  4. Load the LineageOS operating system.
  5. Load the Google Apps.

Step 1 used to require hacking, but in recent years more manufacturers provide an official way to unlock the device.

Steps 2 through 5 are done using Google Android Tools ADB (free and open source) or manufacturer-specific tools like Samsung’s Odin. The steps can be tedious: one small mistake can cause the installation to fail or even brick the device.

LineageOS is the open source version of Android. It has a simple clean interface and no bloat-ware from manufacturers or carriers. Devices usually have better performance and longer battery life when running LineageOS, compared to their OEM software. And LineageOS offers support as long as developers care to maintain it – no planned obsolescence. For example, this Galaxy Tab S5E came out in 2019 on Android 9. Now in 2025, mine runs LineageOS 22 which is Android 15.

The biggest issue with LineageOS is device support. If you want to run it, you need to visit the site and check what devices (whether phones or tablets) are supported. Tablet support is more limited than phones: only the Google Pixel and various Samsung Galaxy models. Even so, Samsung made some of the best Android tablets and they work even better on LineageOS.

DME and its Limitations

What It is

DME means “Distance Measuring Equipment”. It is a navigation instrument used in airplanes. DME predates the era of GPS, but it still used. To understand what DME is, it helps to first understand what a VOR is, because DME facilitates navigation by VOR. I assume the reader is already familiar with VOR.

DME operates at frequencies in the 1 GHz range (960 to 1215 MHz), nearly 10x higher than VOR (108 – 117.95 MHz). DME ground stations are virtually always colocated with a VOR. To use the DME you tune it to the same frequency as the VOR. Yet how can that be, if the DME operates at a higher frequency? Every VOR frequency has a specific designated DME frequency. When you tune the VOR frequency into a DME, it looks up the corresponding DME frequency and uses that instead of what you tuned.

Why do things this way? Since VOR and DME stations are virtually always colocated, tuning the same frequency for both the VOR and the DME is convenient and reduces pilot workload.

How it Works

Unlike a VOR, which is receive-only, a DME both receives and transmits. The DME in the aircraft transmits a pulse, the DME ground station receives this pulse and transmits a reply. The DME in the aircraft receives this signal from the ground station and uses the time elapsed (the speed of light, plus a fixed latency) to compute the distance to the ground station.

The astute reader might wonder, what if several aircraft are all pinging the same DME ground station at the same time? How does each aircraft’s DME receiver know which transmission from the ground station is for itself? The answer, in a word, is jitter. The DME in the aircraft transmits multiple pulses uniquely jittered, or spaced pseudo-randomly in time. The DME ground station transmits the reply to each aircraft with pulses using that aircraft’s jitter. The DME in the aircraft listens only to replies that have its unique jitter, ignoring the rest.

One consequence of this is that each DME ground station can support only a limited number of aircraft. That limit is around 100.

What it Provides

Distance to the ground station. This is “slant distance” which includes your altitude. A nautical mile is 6,076 feet, so if you fly directly over the DME ground station at 6,076 of altitude it will show a distance of 1.0, not zero.

Ground speed. The DME computes this from the distance changing over time, so it is the speed relative to the station. But it’s based on slant distance. If you are flying directly to or from the station, it is your actual ground speed if you are far away from the station. Yet as you get closer to the station, when flying directly overhead it will show a ground speed near zero since you’re moving almost tangent to the station directly below you. If you are flying around the station in a circle, the DME speed will be zero, since your distance to the station is not changing.

Time to the station. Some DMEs compute and display how long it will take you to reach the station, based on your distance and speed, if you fly directly toward it.

Limitations, or Ways DME can Fail

Because the DME in an aircraft must transmit (unlike VOR which is receive-only), the transmitter power is limited. The power of a DME transmitter varies by model. I’ve seen it as low as 25 watts and as high as 100 watts.

When it comes to electrical devices and circuits, receivers usually last longer than transmitters. Transmitters use more power, which is current and heat, and over time those heat cycles take their toll. Thus, while many VORs still work when 40+ years old, this is less common for DMEs.

DME frequencies are in the GHz range which is direct line of sight. And the DME antenna on the airplane is usually on the bottom of the fuselage. Thus if you don’t have a direct line of sight to the station (you’re at a low altitude, there are mountains between you and the station) it won’t work.

ADS-B Out transmits on 978 or 1090 MHz, both of which are in the same range as DME. Thus, ADS-B Out may cause conflicts and prevent DME from working.

Each DME ground station can only support a limited number of airplanes at a time. If the station is in busy airspace, it may ignore your airplane’s DME signal and your DME won’t work. Having a low powered DME transmitter exacerbates this problem, since over-saturated DME ground stations prioritize the strongest signals and ignore weaker ones.

Bluetooth in a Windows 10 VirtualBox VM

Introduction

While all of my computers run Linux, sometimes it’s useful to have Windows – fortunately, not often. Due to the long wet grey dreary winters here in the WA state Puget Sound area, I recently got an indoor cycling trainer. You can use lots of different software with these. The software emulates rides in either the real world (based on video & GPS tracks) or the virtual world (like a video game). It connects to the trainer using Bluetooth or ANT+ to dynamically control the resistance (simulating hills) and measure the rider’s power output.

The only software I could find that runs natively on Linux is very basic and not well supported. These include Auuki and Golden Cheetah. I wanted something more full featured. The next best thing would be Android.

Android?

Most of the popular apps (Zwift, MyWhoosh, Rouvy, Kinomap, icTrainer, etc.) support Android. MyWhoosh was out of the question because it consumed 7 GB of space on my tablet before it could even start running. It is a big, slow, steaming pile of bloat-ware. Most of the others are too expensive for my frugal nature. So I started with icTrainer, which is less well known. At $30 per year, it is the least expensive of the non-free apps. They had great support, promptly answering a couple of questions I emailed them. Their Android app ran just fine on my old slow tablet. The rides I downloaded are huge since they have full video, and icTrainer stored them on the external SD card, which was a nice plus.

So far, so good. But I wondered if I could run indoor cycling software on my laptop, which runs Ubuntu 22. This would give me a bigger screen, and the ability to drive an even bigger external monitor. But it would require getting Windows to work.

Windows 10

First I installed VirtualBox on my Ubuntu 22 laptop, then unearthed an old Windows 10 installer ISO file and unused license key I had hanging around. The Win 10 install went fine and I installed the icTrainer Windows app, which also went fine. The problem was: how to get the Windows 10 VM to use the laptop’s Bluetooth so icTrainer could control the trainer?

I’ll cut to the chase. Start by ensuring that the Win10 VM is shut down.

First, shut down Ubuntu’s bluetooth service, so it releases the computer’s Bluetooth hardware.

sudo service bluetooth shutdown

Next, find the computer’s Bluetooth hardware. It’s considered a subset of the USB system, so list the USB devices:

lsusb

In the list, look for an entry related to Bluetooth. On mine, it is this:

Bus 001 Device 003: ID 8087:0a2b Intel Corp. Bluetooth wireless interface

Next, start the Win10 VM and then log into it.

In VirtualBox, go to USB Devices, look for that same device in the list, and check the box so VirtualBox so it can make it available to the VM.

Now in Win10, confirm that it’s there by going to “Device Manager” and finding the Bluetooth section. If it doesn’t appear, try rebooting the Win10 VM.

At this point, the Win10 VM has access to the computer’s Bluetooth and any apps that use Bluetooth (such as indoor cycling training programs) should work.