Category Archives: Tech

Getting the Mouse Right on Ubuntu

I recently posted about my Elecom thumb trackball and how to set it up in Ubuntu to auto-configure whenever it is plugged in. Since then I’ve learned a few new things.

The mouse would occasionally stutter, by which I mean briefly stop moving (while I was moving the ball), or jump a few pixels, or across the screen. Not often enough to be completely unusable, but enough to be frustrating.

Since the Logitech mouse never did this, I thought it was a problem with the Elecom mouse itself. But it might also be a software issue. So I explored that and learned a couple of new things.

First: both libinput and synaptics were installed and conflicting with each other. This computer was a desktop not having a touchpad, so I removed synaptics and installed libinput:

sudo apt install xserver-xorg-input-libinput
sudo apt purge xserver-xorg-input-synaptics

NOTE: on my laptop, synaptics was called xserver-xorg-input-synaptics-hwe-16.04.

NOTE: I was not able to install xserver-xorg-input-libinput on my Ubuntu 16 laptop. Apparently it has a version conflict:

The following packages have unmet dependencies:
xserver-xorg-input-libinput : Depends: xorg-input-abi-22
Depends: xserver-xorg-core (>= 2:

If I check the versions, this message seems to be true:

ii xserver-xorg-core-hwe-16.04 2:1.19.6-1ubuntu4.1~16.04.2 amd64 Xorg X server - core server

This helped: the mouse still occasionally stuttered, but less frequently. So I looked for other possible software conflicts.

I noticed that using xset with different values, like this which should really slow down the mouse:

xset m 1/64 100

sometimes had an effect, sometimes did not. This suggested that evdev and libinput were both trying to control the mouse.

Since I was setting my mouse with xinput, I disabled xset. I considered the opposite, but the Elecom trackball has very high DPI (750 or 1500) and I couldn’t get xset to turn down the mouse sensitivity. Yet xinput does this nicely. Disabling xset is a simple command:

xset m 0 0

You can check what xset is doing with the mouse using the command:

xset q

Look for the section called “Pointer Control”. If acceleration and threshold are both 0, it’s disabled.

Now things got a bit more complex because I discovered every time the mouse is unplugged and replugged, xset starts up again. So I added this xset command to the script that udev fires when the mouse is plugged in.

Next, I found that I needed to ensure libinput controlled the mouse instead of evdev. In directory /usr/share/X11/xorg.conf.d I saw config files for both evdev and libinput. One thing that helped was to rename 90-libinput.conf to 05-libinput.conf so it is read first, before anything else.

Finally, to slow the mouse down I used different libinput settings. I had been using the Coordinate Transform Matrix property with values less than 1.0. This works OK, but causes a problem in some Steam games where the mouse is completely unusable. Setting this property to the identity matrix (its default value) eliminates that problem. This suggested to me that this feature might have a bug. So I use the Accel Speed property instead, setting it to negative values to slow down the mouse. This seems to be smoother and more reliable.

Another point: on my laptop, I disabled horizontal 2-finger scrolling. To my surprise, this was causing the mouse to occasionally jump across the screen when I clicked a button. I have no idea why these settings were related, but they were.

Problem solved: no more mouse stutter!

Bits and Dynamic Range

When digital audio came out I wondered how the number of bits per sample correlated to the amplitude of waves. I imagined that the total expressible range was independent of the size of the smallest discernible gradation. Since this appeared to be a trade-off, I wondered how anyone decided what was a good balance.

Later I realized this is a false distinction. First: the number of bits per sample determines the size of the smallest gradation. Second: total expressible range is not a “thing” in the digital domain. Third: if the total range is a pie of arbitrary size, dynamic range is the number of slices. The smaller the slices, the bigger the dynamic range.

Regarding the first: to be more precise, bits per sample determines the size of the smallest amplitude gradation, as a fraction of full scale. Put differently: what % of full scale is the smallest amplitude gradation. But full scale is the amplitude of the analog wave, which is determined after D/A conversion, so it’s simply not part of the digital specification.

Amplitude swings back and forth. Half the bits are used for negative, the other for positive, values. Thus 16 bit audio gives 2^16 = 65,536 amplitudes, which is 32,768 for positive and negative each (actually one of the 65,536 values is zero, which leaves an odd number of values to cover the + and – amplitude swings, making them asymmetric by 1 value, which is a negligible difference). Measuring symmetrically from zero, we have 32,768 amplitudes in either direction. So the finest amplitude gradation is 1/32,768 of full scale in either direction, or 1/65,536 of peak-to-peak. 16-bit slices the amplitude pie into 65,536 equal pieces.

Here’s another way to think about this: the first bit gives you 2 values and each additional bit doubles the number of values. Amplitude is measured as voltage, and doubling the voltage is 6 dB. So each bit gives 6 dB of range, and 16 bits gives 96 dB of range. But this emphasizes the total range of amplitude, which can be misleading because what we’re really talking about is the size of the finest gradation.

So let’s follow this line of reasoning but think of it as halving, rather than doubling. We start with some arbitrary amplitude range (defined in the analog domain after the D/A conversion). It can be anything; you can suppose it’s 1 Volt but it doesn’t matter. The first digital bit halves it into 2 bins, and each additional bit doubles the number of bins, slicing each bin to half its size. Each of these halving operations shrinks the size of the bins by 6 dB. So 16 bits gives us a bin size 96 dB smaller than full scale. Put differently, twiddling the least significant bit creates noise 96 dB quieter than full scale.

To check our math, let’s work it backward. For any 2 voltages V1 and V2, the definition of voltage dB is:

20 * log(V1/V2) = dB

So 96 dB means for some ratio R,

20 * log R = 96

where R is the ratio of full scale to the smallest bin. This implies that

R = 10 ^ (96/20) = 63,096

That’s almost the 65,536 we expected. The reason it’s slightly off, is that doubling the voltage is not exactly 6 db. That’s just a convenient approximation. To be more precise:

20 * log 2 = 6.0206

So doubling (or halving) the voltage changes the level by 6.0206 dB. If we use this more precise figure, then 16 bits gives us 96.3296 dB of dynamic range. If we compute:

20 * log R = 96.3296

We get

R = 10 ^ (96.3296 / 20) = 65,536

When the math works, it’s always a nice sanity check.


The term dynamic range implies how “big” the signal can be. But it is both more precise and more intuitive to imagine the concept of dynamic range as the opposite: the size of the smallest amplitude gradation or “bin”, relative to full scale. Put differently: dynamic range is defined as the ratio of full scale, to the smallest amplitude bin.

With 16 bits, that smallest bin is 1/65,536 of full scale, which is 96 dB quieter. With 16-bit amplitudes, if you randomly wiggle the least significant bit, you create noise that is 96 dB below full scale.

With 24 bits, that smallest bin is 1/16,777,216 of full scale, which is 144 dB quieter. With 24-bit amplitudes, if you randomly wiggle the least significant bit, you create noise that is 144 dB below full scale.

Typically, the least significant bit is randomized with dither, so we get half a bit less dynamic range, so for 16-bit we get 93 dB and 24-bit we get 141 dB.

Practical Dynamic Range

Virtually nothing we record, from music to explosions, requires more than 93 dB of dynamic range, so why does anyone use 24-bit recording? With more bits, you slice the amplitude pie into a larger number of smaller pieces, which gives more fine-grained amplitude resolution–and, consequently, a larger range of amplitudes to play with. This can be useful during live recording, when you aren’t sure exactly how high peak levels will be. More bits gives you the freedom to set levels conservatively low, so peaks won’t overload, but without losing resolution.

However, once that recording is completed, you know what the peak level recorded was. You can up-shift the amplitude of the entire recording to set the peak level to 0 dB (or something close like -0.1 dB). So long as the recording had less than 93 dB of dynamic range, this transforms the recording to 16-bit without any loss of information (such as dynamic range compression).

In the extremely rare case that the recording had more than 93 dB of dynamic range, you can keep it in 24-bit, or you can apply a slight amount of dynamic range compression while in the 24-bit domain, to shrink it to 93 dB before transforming it. There are sound engineering reasons to use compression in this situation, even for purist audiophiles!

To put this into perspective: 93 dB of dynamic range is beyond what most people can pragmatically enjoy. Consider: a really quiet listening room has an ambient noise level around 30 dB SPL. If you listened to a recording with 93 dB of dynamic range, and you wanted to hear the quietest parts, the loud parts would would peak at 93 + 30 = 123 dB SPL. That is so loud as to be painful; the maximum safe exposure is only a couple of seconds. And whether your speakers or amplifier can do this at all, let alone without distortion, is a whole ‘nuther question. You’d have to apply some amount of dynamic range compression simply to make such a recording listenable.

Mechanical Keyboards: Why the Buckling Spring Rules!

I have quite a bit of experience with high quality keyboards. I learned to type on a manual typewriter, later graduated to electrics. My first computer was a TRS-80 CoCo which had a cheap chicklet type keyboard, up there with Apple’s laptops as one of the worst keyboards I’ve ever used. We soon upgraded it to one that had buckling spring mechanical key switches. It typed like an electric typewriter, which was awesome. Largely due to hours spent on that computer, I was typing 90+ wpm as a teenager (less common in the 1980s than it is now). In college I had a PC-XT clone, a Leading Edge Model D, which had another excellent buckling spring keyboard. All through the 1980s, just about every PC had this kind of keyboard. This keyboard defined “the sound of work” in offices across the USA.

Over the 90s cheap bubble dome keyboards became more common, until the turn of the century they were ubiquitous and it became nigh impossible to find a mechanical buckling spring keyboard. In 1999 I special ordered one from Unicomp and I still have it today; it works perfectly though it has an outdated PS/2 connector.

Later I discovered the ergonomic joy of ten-key-less 87-key keyboards. Chop off the numpad that you hardly ever used, and the mouse (trackball in my case) gets closer. The rest of the keyboard has the exact same layout (including home,end,arrows) as the classic IBM 101, so your hands and fingers know where to go without thinking. But it’s more comfortable because you don’t have to stretch your right arm as far to reach the mouse.

Problem: nobody makes an 87-key buckling spring keyboard. I own and have extensively used a few 87-key keyboards with other mechanical switches: Cherry, Oetmu, Zorro. They’re way better than bubble dome switches (no double or missed strikes), but not as nice as buckling springs. Why? Two key differences:

  • Crisp: a buckling spring has a crisp snap when the key strikes. You can type with confidence, nary any doubt whether a light key hit struck.
  • Force: a buckling spring requires a bit more force to actuate than other mechanical switches, which can accidentally strike when you are just resting your fingers on them.

It sounds small, but these two points make all the difference in the world. There is nothing like a buckling spring keyboard. Cherry and other mechanical switches are better than bubble domes, but pale in comparison.

Virtualbox and /usr/lib: FIXED

I ran Virtualbox today and nothing happened, as if I had not clicked its icon. There was no error message but I figured it was failing so I ran it from the command line and got the following error:

VirtualBox: Error -610 in supR3HardenedMainInitRuntime!
VirtualBox: dlopen("/usr/lib/virtualbox/",) failed: <NULL>
VirtualBox: Tip! It may help to reinstall VirtualBox.

When I Googled this I found all kinds of ideas, none of which worked. I checked the package versions, there were no version mis-matches. Finally I found an obscure thing that fixed it:

My /usr/lib directory was set to root:staff, mode 775. I had been working on Nixnote, an open source Evernote client, and needed to install some stuff there, so I changed the ownership so I wouldn’t have to sudo to copy new files there.

Well it turns out Virtualbox won’t run unless /usr/lib is root:root. Don’t ask me why, I don’t know and it doesn’t make sense. And Virtualbox doesn’t tell you this, nor is it mentioned in their docs. But setting it back fixed the problem.

LineageOS: Home Screen Setup

LineageOS is the open source version of Android. Combined with OpenGApps, it has all the functionality of Android, without any of the bloat-ware, crapplets or customized skins that manufacturers and carriers add to Android. And, it’s supported by a community of developers so you can get the latest version of Android on your device long after the manufacturer abandons it to planned obsolescence.

The LineageOS home screen launcher is called Trebuchet. It is more configurable than most stock ROMs. There’s a particular setup I like that combines a dark background (which saves battery on OLED screens) with big icons. Setting this up is simple:

First, long-touch a blank spot on the home screen. The home setup screen appears. Your icons will be different from shown, but the bottom area will be the same with the WALLPAPERS, triple-dot button, and WIDGETS:


Touch WALLPAPERS in the lower left. A screen like below will appear asking you how you want to pick wallpaper. Pick the one circled in RED:


A screen like below appears asking which wallpaper you want. Pick the one shown below:


A screen appears asking where you want to use this wallpaper. I usually pick both home screen and lock screen:


Next, we’ll tell the home screen to use large icons. So go back to the home screen and long-touch a blank spot again to get the home setup screen. Then touch the triple-dot button:


The following menu will appear. You can set a bunch of stuff here; icon size is at the bottom:


Cool Mouse Stuff with Linux

Linux has built-in tools for programming the buttons on your mouse or trackball. You don’t need any drivers or proprietary software. Just a few simple tools you can install from the repos. I’m doing this on Ubuntu 16 and 18, but it should work on any recent Linux distro.

First, use xev to detect how your system is recognizing the mouse buttons. Start xev from a command prompt, then hover over its window, click each button, and look at the text in the command prompt window. This will tell you the # for each button. The first 3 buttons are always defined the same way: left-click is button 1, middle-click 2, right-click 3. Extra buttons are “non-standard” and can be defined in any way.

To change what a button does, use xbindkeys. Its control script is a file in your home directory called .xbindkeysrc. The app xte fabricates keystrokes and mouseclicks.

For example: here’s an .xbindkeysrc that does 2 things:

  • Single click of button 2 (middle button) causes double-click of button 1 (left)
  • Single click of button 9 causes Control-click of button 1.
# button 2 (scroll wheel) is double click
"/usr/bin/xte 'mouseclick 1' 'mouseclick 1'"
b:2 + release

# button 9 (upper left alternate) is control + left click
"/usr/bin/xte 'keydown Control_L' 'mouseclick 1' 'keyup Control_L'"
b:9 + release

This should work everywhere in all apps. It does work in some apps (like Thunar), but not in others (like Firefox). I wondered – why?

Limitation 1

After experimenting, I discovered that xte is too fast for some apps. I added a few strategically located brief (10 ms) delays and it worked everywhere.

Example: change the above to this:

# button 2 (scroll wheel) is double click
"/usr/bin/xte 'mouseclick 1' 'usleep 10000' 'mouseclick 1'"
b:2 + release

# button 9 (upper left alternate) is control + left click
"/usr/bin/xte 'keydown Control_L' 'mousedown 1' 'usleep 10000' 'mouseup 1' 'keyup Control_L'"
b:9 + release

The usleep param is in microseconds, so 10,000 is 10 milliseconds. This now works in all apps.

Limitation 2

Another limitation: it’s hard to make the same button duplicate itself from xbindkeys. If you do this, it can lead to infinite loops. For example: xbindkeys can easily make a single click of button 2, cause a double-click of button 1. But xbindkeys can’t make a single click of button 1, cause a double-click of the same button. This will fail or cause an infinite loop.

For that, use imwheel. Originally intended to adjust the sensitivity of the scroll wheel, it is also useful for other things. This is because internally, a scroll wheel is just 2 buttons: up and down. To make it more sensitive, imwheel duplicates each click of those buttons. But imwheel can do this with any buttons, not just the scroll wheel. Its config file is .imwheelrc, in your home directory.

Here’s an imwheel config that doubles the scroll wheel sensitivity:

# Apply to all apps (individual apps can be customized)
# Amplify scroll up/down
None,    Up,    Button4,    2
None,    Down,    Button5,    2
# Amplify scroll left/right
None,    Left,    Button6,    10
None,    Right,    Button7,    10

On my trackball, the scroll wheel is Button 4 and Button 5. The scroll wheel tilts L and R; these are buttons 6 and 7. Yours may be different; check it with xev.

Elecom Trackball, IOGear GCS1102 KVM Switch, Ubuntu 18

My Logitech Trackman thumb trackball is so old it has a PS/2 plug. Its buttons are finally starting to fail and I needed to replace it. But Logitech doesn’t make wired trackballs anymore. I must have wired because (1) I use an IOGear GCS1102 KVM Switch, and (2) I prefer the instantaneous smoother response of wired devices.

I Googled around and discovered the Elecom M-XT3URBK, worth a try. At first it didn’t work. On a whim, I checked my GCS1102 (open a text editor, hit Ctrl-F12, press F4, and it prints its settings) and found it was in mouse emulation mode. I disabled mouse emulation mode (Ctrl-F12, press m) and the Elecom worked perfectly. Xev detected all buttons except the far right, which I don’t need anyway.

Good stuff:

  • Tracks at least as well (smooth, fast, accurate) as the Logitech Marble
  • Switch-adjustable DPI (low is still pretty high and works best)
  • Buttons
    • Standard L and R
    • Scroll wheel clicks like a button (without occasionally moving, like the Logitech did)
    • Scroll wheel clicks L and R to scroll horizontally
    • Two small buttons to the L of the L button
  • It’s comfortable to use
  • Elecom makes a mirror image left-handed version
  • Price: only $40 – half Logitech’s prices!

Bad stuff:

  • The cable is a bit on the short side, but still long enough I didn’t need an extension.
  • It’s a bit small for my large hands

So far, no problem. It works, scroll wheel and all buttons, without any drivers. Just plug and play. But there’s more…


The Elecom is so much more sensitive than my old Logitech, I had to turn down the settings. But with the GCS1102’s mouse emulation disabled, every time I switch, each computer sees the mouse being un-plugged and re-plugged. When this happens, Ubuntu doesn’t restore the mouse settings. When I switch away and back, the mouse is back to its hyper-sensitive default setting.

I wrote a shell script /apps/bin/ that uses xinput to set the mouse:

#!/usr/bin/env bash
# The UI for setting mouse track speed in Ubuntu 18 is broken.
# Do it manually here
# NOTE: as of June 2018, the mouse was device 12.
# You can check this with: xinput --list --short
# To show device settings: xinput --list-props 12

echo "`date`, $USER, $DISPLAY, $XAUTHORITY" >> /apps/bin/mouse.log

if [ -z "$1" ]
if [ -z "$2" ]
if [ -z "$3" ]
    d="`xinput | grep Mouse | grep pointer | cut -f 2 | cut -c4-5`"

aprop=`xinput --list-props $d | grep 'Accel Speed (' | cut -f2 | cut -c23-25`
if ! [ -z "$aprop" ]
    xinput set-prop $d $aprop "$a"
mprop=`xinput --list-props $d | grep 'Coordinate Transform' | cut -f 2 | cut -c35-37`
if ! [ -z "$mprop" ]
    xinput set-prop $d $mprop "$m", 0.0, 0.0, 0.0, "$m", 0.0, 0.0, 0.0, 1.0

echo "`date` Mouse set up $a $m $d" >> /apps/bin/mouse.log
xinput --list-props "$d" >> /apps/bin/mouse.log

But I don’t want to have to run this script every time I switch the GCS1102. The Linux Udev system should do the job!


First, I needed a Udev rule to trigger my script. The rule must detect the USB device being plugged in, so I need its vendor and product IDs. To get these, run lsusb:

Bus 003 Device 122: ID 056e:00fb Elecom Co., Ltd

Now add a Udev rule. Mine was /etc/udev/rules.d/61-elecom-mouse.rules:

SUBSYSTEM=="usb", ATTR{idVendor}=="056e", ATTR{idProduct}=="00fb", ACTION=="add", RUN+="/apps/bin/"

But it didn’t work. The script was running (I could see the log entry it creates). But the mouse sensitivity wasn’t being set.


My first thought was that the Udev event was firing before the device was registered and ready to be configured. So I added a sleep to the command. But, you can’t sleep while Udev is running your command. So I had Udev run a script that returns immediately, while sleeping a few seconds then running setMouse. A command like this:

(sleep 3 ; /apps/bin/ &

But that didn’t work. It worked from the command line, but when run from Udev, the background was ignored and Udev waited for the entire time. That’s bad for 2 reasons: (1) hangs Udev for 3 seconds, (2) Udev is still waiting, so the sleep is pointless because the device won’t be ready until Udev is done.

In short, Udev is too smart by half. I needed a way to trick Udev into returning immediately, while my script pauses a few seconds then runs. I found this with the at command. First, install it:

sudo apt install at

Then, make the Udev rule look like this:

SUBSYSTEM=="usb", ATTR{idVendor}=="056e", ATTR{idProduct}=="00fb", ACTION=="add", RUN+="/usr/bin/at -M -f /apps/bin/ now"

This tells at to trigger the script to run immediately, but at returns to Udev immediately. The script doesn’t run under Udev but under at. The script looks like this:

#!/usr/bin/env sh
# Called by Udev when Elecom trackball is plugged in
sleep 2
/apps/bin/ 0.1 0.4

Note: at can only run sh scripts, not bash.

But, it still didn’t work. The script ran, but its xinput commands always failed.


I guessed it might be that at, running as root, didn’t have permission for my X session. I had to somehow make it join my X session before the xinput commands would work. I made a script called

#!/usr/bin/env bash

# Get the number of the active terminal (requires root)

# Set env vars needed to simulate the user
export DISPLAY=:${TTY}.0
USER=`who -s | grep "(:$TTY)" | cut -d' ' -f1`
export XAUTHORITY=/home/$USER/.Xauthority

echo "`date`, $USER, $DISPLAY, $XAUTHORITY: $1" >> /apps/bin/joinXandRun.log
sudo -H -u $USER bash -c "$1 $2 $3 $4 $5 $6 $7 $8 $9"

This script finds the active X console, and its user and display. Then it sets the critical DISPLAY  and XAUTHORITY environment vars to “join” that X session. Then it runs another script passed into it, as the given user.

Then I made call this script:

#!/usr/bin/env sh
# Called by Udev when Elecom trackball is plugged in
sleep 2
/apps/bin/ /apps/bin/ 0.1 0.4

Guess what — this worked!

The really cool thing about this is that the Udev rule is device-specific, and takes parameters. I could set this up to auto-detect and configure several different kinds of mice or trackballs. Each would have a different Udev rule, matching different vendor and device IDs, firing different scripts that pass different mouse setting params to This will be useful for my laptop, which uses the Elecom at work but another Logitech Trackman at home.

It turns out all the pieces are essential. Lessons learned:

  • When Udev triggers the add event, the device being added cannot yet be configured. So if your Udev script configures the device, it has to:
    • Return immediately to Udev, so Udev can finish its processing
    • Meanwhile, trigger its config processing to run after a few seconds
  • To configure devices that are part of the X session, you need to “join” the session. Otherwise, the X system won’t let your code configure the device.

PS: none of this is specific to Ubuntu 18. It should work on any recent Linux distro.

Calibre, Amazon Books, DeDRM

I’ve been a big reader since I was a kid, all kinds of books from many sources. I was an early Kindle adopter, but as Android tablets came out I found them better for reading:

  • Configurable: you can set a wider variety of fonts, sizes, margins, colors, layouts.
  • Open: you can install any number of reading apps for every eBook format available. You’re not locked into any single book ecosystem.
  • Graphics: books with pictures, diagrams, etc. are much better on a tablet. Even a large eInk reader lacks color and renders slower.

Due to the variety of books I read, no single ecosystem would do the job. Plus, I take a principled opposition to any company that tries to lock customers into its ecosystem. When I buy a book I don’t believe I’ve bought it to read on a particular device, in a particular format, to access whenever some corporation thinks I should be able to. I’ve bought the right to read it on any device, in any format, whenever I want to, forever. Just like a real book. Indeed, eBooks often cost as much as real books even though the marginal cost of the next eBook sold is zero. And, I run native Linux on all my computers.

All of this all led me to start using Calibre to manage my eBooks. Calibre is simply great – it meets all these needs and more. It’s a great organizer, supports all devices, all formats, can convert between them, and has many plugins with an active open source development community.

Without owning a Kindle, how does one buy books from Amazon, store them on your own computer and read them on any device in any format? Here’s how:

Even though I run Linux, I have a VM running Windows. I don’t use it for much, only those few apps that I can run natively on Linux or in a browser. Unfortunately, Amazon Kindle is one of those. In this VM I have the Kindle for PC app registered to my Amazon account.

I’ll assume you already have Calibre running and you’ve installed Apprentice Alf’s DeDRM plug-in.

Next, do a one-time configuration step: capture the Kindle key from your Windows PC and copy it to Calibre so it can DeDRM Kindle books.

  • On Windows
    • Install Python 2.7 and Pycrypto 2.6 for Python 2.7.
    • Unzip the Calibre DeDRM plug-in ZIP file
    • In this zip, find the file
      • This zip file has several directories and files in it. In DeDRM_6.6.0, this file is here: \DeDRM_Windows_Application\DeDRM_App\DeDRM_lib\lib
    • Open a command prompt and run this file:
    • You’ll see something like this:
      • Using Library AlfCrypto DLL/DYLIB/SO
        searching for kinfoFiles in C:\Users\USERNAME\AppData\Local
        Found K4PC 1.9+ kinf2011 file: C:\Users\USERNAME\AppData\Local\Amazon\Kindle\storage\.kinf2011
        Decrypted key file using IDString ‘406xxxxxxx’ and UserName ’63xxxxxx’
    • It creates a new file: kindlekey1.k4i
    • Copy this file to a directory your Linux Calibre app can see
  • On Linux
    • Run Calibre
    • Click Configure, Plugins, File type plugins, DeDRM
    • Click Customize plugin
    • Click Kindle for Mac/PC ebooks
    • Click Import Existing Keyfiles
    • In the file dialog that pops up, pick your kindlekey1.k4i file

You’re done: Calibre DeDRM is configured to be able to DeDRM ebooks you drop on it, so long as they come from your Kindle for PC reader.

After I buy a book on Amazon, I deliver it to my Kindle for PC device.

  • In Windows:
    • Open Kindle for PC, refresh your library. The book should appear.
    • Double-click it to download it.
    • After the book opens, close it and the Kindle for PC app.
    • Open folder Users\USERNAME\Documents\My Kindle Content
    • Your book will be one of these folders named B….._EBOK
    • Sort by date to put the most recent files on top
    • Open the folder and you’ll see an azw file having the same filename as the folder.
    • Copy this azw file to a directory that your Linux Calibre can see.
  • In Linux
    • Run Calibre and drag/drop the azw file on it.
    • Calibre will strip the DRMs and add it to your library

You now own the book. It’s stored on your own hard drive, you can read it on your PC, convert it to any format you want, copy it to any device or app you want to use to read it.

Escape Velocity

Escape Velocity is commonly described as the minimum speed an object must reach to escape the Earth (or other celestial body) into space. But this definition is ambiguous and can be misleading.

You can escape the Earth at walking speed, if you could walk straight up; you don’t need anywhere near escape velocity. Imagine a rocket launch; in the first few seconds just as it starts to move, it’s going up at walking speed. Theoretically, it could throttle back the engines to maintain that slight upward speed all the way into space, so long as it didn’t run out of fuel or become unstable. A space elevator could also leave Earth at mundane speeds.

The key to this ambiguity is escape velocity applies to a free body, an object that is passively moving according to the laws of physics, having no thrust of its own. In other words, if a rocket achieves escape velocity, it could at that point turn off its engines and it would still escape the Earth. Intuitively it seems the higher the altitude, the slower the escape velocity. This turns out to be correct.

Escape velocity is easy to understand and derive mathematically with some creative thinking. Imagine 2 objects in space (a big one and a much smaller one, like the Earth and a stone) surrounded by vacuum, no other objects. So there is no friction and no other bodies exerting gravitational pull. Suppose the stone is at rest relative to the Earth and almost infinitely far away. The gravitational pull is effectively zero. Imagine the stone precariously balanced just on the outer rim of Earth’s gravity well. Then you nudge the stone just a smidge toward the Earth, so it crosses that rim and the Earth starts pulling on it (and vice versa). It starts out slow, but accelerates toward the Earth incrementally faster and faster.

Eventually, when the stone reaches the Earth it will be moving very fast. Escape velocity is the speed it is going just before it smashes into the Earth. Or if it misses the Earth, it’s the speed at its point of closest approach. More correctly and completely, the stone is always traveling at escape velocity at every moment along its path. The escape velocity for that distance from the Earth, is the speed at which the stone is moving when it’s that far away.

Note: the bold face statement above is the nut of this explanation. When you grok its fullness, you grok the fullness of escape velocity.

That’s because of conservation of energy. When the stone was at the rim of Earth’s gravity well, it had a lot of potential energy. At the point of closest approach, all that potential energy has been converted into kinetic energy. Assuming no atmosphere, no losses, the two energies are equal. So as the stone speeds past the Earth, slowing down due to the same gravitational pull that sucked it in, that kinetic energy is converted back into potential energy. So it must reach the exact same distance away when it peters out and eventually stops.

The direction of motion is irrelevant to escape velocity. Normally this seems counterintuitive, but understanding escape velocity with our theoretical example, you can easily see why direction doesn’t matter. At that point of closest approach, it doesn’t matter what direction the stone is moving relative to the Earth. It could be nearly straight up (can’t be exactly straight up, or it wouldn’t have missed), or nearly horizontal. If it’s going horizontal, it has to travel further to escape, but being horizontal, gravity isn’t pulling it as hard. These conflicting factors are equal and cancel each other. All that matters is the altitude (distance of closest approach), because the speed depends only how much energy it’s gained from Earth’s gravity field.

If, at that point of closest approach, the stone were moving any slower, then it would have less kinetic energy, and it will not go as far away. That means it won’t make it to the rim of Earth’s gravity well, so it will still be inside the well, reverse direction and eventually come back to Earth. So escape velocity is the minimum speed a free body can have, and escape the Earth.

Of course, in the real world direction does matter. The Earth has an atmosphere that creates a lot of friction and energy loss at high speeds. If you go straight up, you’re in the atmosphere for a shorter time, less energy loss. If you go horizontal, you’re in the atmosphere longer and will lose more energy.

Here is the mathematical derivation:


Updating Celestron Telescope Firmware

Here’s how I update the firmware in my Celestron 6SE telescope from my Ubuntu Linux system. There’s another nice guide here, but it didn’t work on my computer until I figured out the trick below of changing the port name.

Kudos to Celestron for writing the software in Java so it can run on any computer, Windows, Mac or Linux!

My scope has a phone-type connector to the handset and came with a cable that is a 9-pin serial on the other end. Plug this cable into your computer’s serial port and into the bottom of the handset. While the scope is off, hold down the handset Celestron & Menu buttons while turning it on. The handset will say Boot Loader Serial or something like that to indicate it’s in firmware update mode.

Now, find the Linux device file for your serial port by entering this command: dmesg | grep tty

My output looks like this; yours may be different:

[    0.000000] console [tty0] enabled
[    0.671956] 00:06: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A

On my computer, the serial port is /dev/ttyS0

Check this device file’s permissions and ensure you can read & write it. Typically you need to be in the dialout group, or just chmod the device file to 666 to open it to anyone.

Follow Celestron’s instructions to download the CFM software from their web site. You’ll get a file named something like CFM.jar. Once installed, go to its directory and run it with Java: java -jar CFM.jar

When it starts it will tell you it can’t find the serial port. Select Options|Connections from the menu. In the dialog that appears, you’ll notice it says COM4 (or something similar) as the serial port name. Replace this with ttyS0 (or whatever your port’s name is, from above).

Now click Seek Devices from the app main screen and it will find your telescope. Click the main screen Update button and CFM will find and download the latest firmware for your scope and install it.