Archive for category Software

MPCNC Drag Knife: Ground Shaft in LM12UU Bearing

The 12 mm drag knife holder on the left slides nicely in an LM12UU bearing:

Drag Knife holders - detail
Drag Knife holders – detail

However, its aluminum body isn’t really intended as a bearing surface and it extends only halfway through the LM12UU, so I finally got around to modifying the 11.5 mm body on the right to fit into a section of 12 mm ground shaft:

Drag Knife - turning 11.5 mm body to 10 mm
Drag Knife – turning 11.5 mm body to 10 mm

The general idea is to turn the body down to 10 mm OD; the picture shows the first pass over the nose after turning the far end down and removing the flange in the process. Exact concentricity of both ends isn’t important (it gets epoxied into a 10 mm hole through the 12 mm ground shaft), but it came out rather pretty:

Drag Knife - 11.5 mm body - turned to 10 mm
Drag Knife – 11.5 mm body – turned to 10 mm

The ground shaft started as a pen holder:

DW660 Pen Holder - ground shaft
DW660 Pen Holder – ground shaft

I knocked off the ring and bored the interior to fit the 10 mm knife body. The large end of the existing bore came from a 25/64 inch = 9.92 mm drill, so it was just shy of 10.0 mm, and I drilled the small end upward from 0.33 inch = 8.4 mm.

The smallest trio of a new set of cheap carbide boring bars allegedly went into a 5/16 inch = 7.9 mm bore, but I had to file the bar body down and diamond-file more end relief into the carbide for clearance inside the drilled hole:

Modified boring bar vs original
Modified boring bar vs original

I blued the bit, kissed it against the drilled bore, filed off whatever wasn’t blued, and iterated until the carbide edge started cutting. Sissy cuts all the way, with no pix to show for all the flailing around.

Epoxying the turned-down drag knife body into the shaft: anticlimactic.

The solid model features a stylin’ tapered snout:

Drag Knife LM12UU holder - tapered end
Drag Knife LM12UU holder – tapered end

Which gets an LM12UU bearing rammed into place:

Drag Knife - LM12UU holder - inserting bearing
Drag Knife – LM12UU holder – inserting bearing

The steel block leaves the bearing flush with the plastic surface, rather than having it continue onward and indent itself into the wood; I can learn from my mistakes.

The new idea: a single spring pressing the knife holder downward, reacting against a fixed plastic plate:

Drag Knife - LM12UU ground shaft - assembled
Drag Knife – LM12UU ground shaft – assembled

Unlike the previous design, the upper plate doesn’t move, so there’s no problem caused by sliding along the screw threads. I should run nylock nuts up against the plate to keep it in place, stiffen the structure, and provide some friction to keep the screws from loosening.

The top of the knife holder now has a boss anchoring the spring:

Drag Knife - turning spring recess
Drag Knife – turning spring recess

As you’d expect, the ground shaft slides wonderfully in the bearing, because that’s what it’s designed to do, and the knife has essentially zero stiction and friction at any point along the bearing, which is exactly what I wanted.

The spring, from the same assortment as all the others, has a 48 g/mm rate.

The OpenSCAD source code as a GitHub Gist:


, , ,


MPCNC Drag Knife: LM12UU Linear Bearing

The anodized body of the drag knife on the left measures exactly 12.0 mm OD:

Drag Knife holders - detail
Drag Knife holders – detail

Which happy fact suggested I might be able to use a standard LM12UU linear bearing, despite the obvious stupidity of running an aluminum “shaft” in a steel-ball bearing race:

Drag Knife - LM12UU holder - solid model
Drag Knife – LM12UU holder – solid model

The 12 mm section extends about halfway through the bearing, with barely 3 mm extending out the far end:

Drag Knife - LM12UU - knife blade detail
Drag Knife – LM12UU – knife blade detail

Because the knife body isn’t touching the bearing for the lower half of its length, it’ll probably deflect too much in the XY plane, but it’s simple enough to try out.

As before, the knife body’s flange is a snug fit in the hole bored in the upper disk:

Drag Knife - spring plate test fit
Drag Knife – spring plate test fit

This time, I tried faking stripper bolts by filling the threads of ordinary socket head cap screws with epoxy:

Ersatz stripper bolts - epoxy fill
Ersatz stripper bolts – epoxy fill

Turning the filled section to match the thread OD showed this just wasn’t going to work at all, so I turned the gunked section of the threads down to about 3.5 mm and continued the mission:

Drag Knife - LM12UU holder - assembled
Drag Knife – LM12UU holder – assembled

Next time, I’ll try mounting the disk on telescoping brass tubing nested around the screws. The motivation for the epoxy nonsense came from the discovery that real stainless steel stripper bolts run five bucks each, which means I’m just not stocking up on the things.

It slide surprisingly well on the cut-down screws, though:

Drag Knife - applique templates
Drag Knife – applique templates

Those appliqué templates came from patterns for a block in one of Mary’s current quilting projects, so perhaps I can be of some use whenever she next needs intricate cutouts.

The OpenSCAD source code as a GitHub Gist:

, , ,


Epson R380 Printer: Waste Ink Counter Reset

Following the same drill as before, the Epson R380 printer once again thinks I’ve changed its diaper before resetting its waste ink counter. Instead, I’ve poured what would be a moderate fortune of waste ink down the drain from the external tank, had I not grafted a continuous flow ink supply onto the thing.

To judge from how often I must reset the counters, I’m expected to buy a new printer every three years. For sure, it’s uneconomical to have anybody else (the nearest Epson Authorized Customer Care Centers is 68 miles away on Long Island) do the deed. As Epson delicately puts it “replacement of ink pads may not be a good investment for lower-cost printers”.

Epson now provides a utility allowing you to reset the counters exactly one time. Having a scrap Windows PC ready to go, I didn’t bother capturing the partition before firing off the previous Sketchy Utility™, nor did I restore it, so the whole process took about half an hour.

The hard drive platters will eventually become nightlights.



Xiaomi Dafang Hacks: Hostname for OSD and Filename

The config/hostname.conf file (found under /system/sdcard/when the camera is running) file defines the camera’s name:


That file overrides the contents of the usual etc/hostname.conf file, somewhat to my surprise, which remains the default Ingenic-uc1_1.

The bin/hostname utility returns the hostname:

[root@Cam4 ~]# which hostname
[root@Cam4 ~]# hostname

You can automagically get the hostname in the on-screen display by modifying the OSD formatting variable in config/osd.conf:

OSD="$(/bin/hostname) %Y-%m-%d %H:%M:%S"

Which works because the main OSD script sources the config file to set the variable:

Xiaomi Dafang - 15-04-2019_13.26.18
Xiaomi Dafang – 15-04-2019_13.26.18

It’s also helpful (at least for my purposes) to add the hostname to the image filenames. A one-line tweak in the scripts/ script does the trick:

snapshot_filename=$(/bin/hostname)_$(date "$snapshot_pattern")

Which produces names along these lines:

-rwxr-xr-x  1 ed   root 246K Apr 23  2019 Cam4_2019-04-23_17.51.02.jpg*

Having source code makes simple changes like this … simple!

Leave a comment

Xiaomi Dafang Hacks: Motion Detection

Given a camera running Xiaomi Dafang Hacks software, you can set up motion-triggered image capture and save the images either locally or on an FTP server. The latter makes sense, as it automatically plunks the images where they’re more generally available.

Define the FTP server parameters in config/motion.conf:

# Configure FTP snapshots and videos

The FTP server should have the Cam4 directory in place and shared for read-write access before attempting to plunk files therein. Ahem.

The camera’s Services menu leads to the motion configuration page:

Xiaomi Dafang - Motion Settings page
Xiaomi Dafang – Motion Settings page

Limiting the detection region to the lower-left corner cuts out all the waving-in-the-breeze foliage in the yard, while covering the driveway. High sensitivity detects squirrel-sized objects in the foreground, although your mileage will certainly differ.

The camera seems rate-limited at 5 s/image, which may come from FTP transfer overhead; I don’t know if the code includes a built-in delay or if it just works like that. The NAS drive requires upwards of 7 s to spin up if it hasn’t been used for a while, but afterwards the transfers don’t take that long.

Mounting the NAS drive’s CIFS shared directory from my desktop PC works as before:

sudo mount -v -o rw,credentials=/root/.nas-id,vers=1.0,uid=ed -t cifs // /mnt/part

Then view / edit / delete images as needed:

Xiaomi Dafang - IR motion capture - 15-04-2019_20.02.06
Xiaomi Dafang – IR motion capture – 15-04-2019_20.02.06

The camera has built-in IR LEDs, but they’re nowhere near powerful enough to illuminate the entire yard.

Motion detection works better in daylight:

Xiaomi Dafang - Daylight motion capture - 16-04-2019_09.53.51
Xiaomi Dafang – Daylight motion capture – 16-04-2019_09.53.51

Unlike the original Wyze firmware, the Xiaomi Dafang Hacks firmware & software keep all the images & metadata within my network and under my control.


Xiaomi Dafang Hacks: Timelapse Images

With the Wyze and Xiamoi Dafang cameras running the Xiaomi-Dafang Hacks firmware and software, I tried the timelapse functions on the yard camera.

The config/timelapse.conf file:

# Interval between snaps, in seconds
# Duration of the script should run, in minutes, set to 0 for unlimited
# Save dir config
# Enable compression

The images, named along the lines of 13-04-2019_191810_001.jpg, appear in the DCIM/timelapse directory, tucked into daily directories with names like 2019-04-13, a mismatch obviously in need of tweaking. There’s also a time_lapse directory which seems like cruft from an earlier revision; you can configure the target directory in scripts/

Start the script manually or from a crontab entry, wait until it’s done, then transfer the images to somewhere more convenient with a Bash one-liner:

find /system/sdcard/DCIM/timelapse/ -name \*jpg -exec curl -s -n -T {} \; 

The -s silences all curl output; omit it until you’re sure the lashup works as you expect. I always forget the backslash before the semicolon terminating the -exec command.

The -n pulls the userID and password from the ~/.netrc file you previously set up for manual ftp sessions:

login ftp-user-id
password secret-password

The IP address corresponds to my ancient NAS drive; your mileage may vary.

From my desktop box, mount the NAS drive:

sudo mount -t cifs -o "credentials=/root/.nas-id,vers=1.0,uid=ed" "//nasty/Timelapse" /mnt/part

The drive’s credentials aren’t particularly secret, but tucking them into /root/.nas-id means you could automount the drive with no hassle. The NAS drive requires the oldest possible CIFS version, of course.

Then view the pix:

Xiaomi Dafang - 15-04-2019_13.26.18
Xiaomi Dafang – 15-04-2019_13.26.18

You could set up the camera as an NFS share, but having all the cameras deposit their pix in a common location seems more convenient, particularly after I get around to automating the image transfer. Regrettably, the NAS drive doesn’t support subdirectories.


Multiprocess Book-on-CD Ripping

The most recent iteration of ripping a book-on-CD to bits suitable for a small MP3 player begins by defining the metadata:

author="Whoever Wrote It"
title="Whatever It May Be About"

Set up a suitable directory for the MP3 files, with a subdirectory for the WAV files direct from the CD:

mkdir "$author - $title"
cd "$author - $title"
mkdir waves

Then unleash cdparanoia on each disk, but with its error checking dialed back to a minimum because most errors don’t produce much audible damage:

d=01 ; cdparanoia -v -Y --never-skip=1 -B "1-" waves/D$d.wav ; eject cdrom

In some cases, however, a nasty gouge (the previous owners being careless, alas) can jam cdparanoia midway through a track, so I fetch all the remaining tracks:

d=10 ; cdparanoia -v -Y --never-skip=1 -B "6-" waves/D$d.wav

Sometimes re-cleaning the disc and re-reading the offending track produces a better outcome:

d=10 ; cdparanoia -v -Y --never-skip=1 -B "5-5" waves/D$d.wav

With all the WAV files collected, I now know how to unleash multiple lame conversions for all the tracks on each disc:

for d in {01..12} ; do for t in {01..19} ; do if [[ -f waves/track$t.D$d.wav ]] ; then lame --silent --preset tape --tt "D${d}:T${t}" --ta "$author" --tl "$title" --tn $t --tg "Audio Book" --add-id3v2 waves/track${t}.D${d}.wav D${d}-T${t}.mp3  & fi ; done ; wait ; done

The disc and track ranges correspond to notes written on paper while ripping the CDs, there being no automagic way to collect the information.

That may be easier to read with the control structures spread out:

for d in {01..12}
 do for t in {01..19}
  do if [[ -f waves/track$t.D$d.wav ]]
    lame --silent --preset tape --tt "D${d}:T${t}" --ta "$author" --tl "$title" --tn $t --tg "Audio Book" --add-id3v2 waves/track${t}.D${d}.wav D${d}-T${t}.mp3  &

Affixing an ampersand (&) to the lame command drops it into the background, where it runs as CPU time becomes available. The wait after the first loop stalls until all of the lame instances for each CD finish.

The kernel scheduler manages to keep the GUI responsive while a four-core CPU makes short work of the entire CD.

When it’s all done, transfer the MP3 files to the player:

cd ..
sudo mount -o uid=ed /dev/sde1 /mnt/part
rsync -vrtu --progress --exclude="waves" "$author - $title"  /mnt/part/Music
sudo umount /mnt/part

Fetching commands from history eliminates the need to remember all that, but now it’s written down where I can find it for the next desktop box.

Life is good!

Leave a comment