Planet Fitness Cancellation Template

Update: I put this in the mail on Tuesday and got cancellation confirmation less than 48 hours later.

Also, your mileage may vary, some locations are a little more of a stickler about certified mail, but you should get a confirmation from the location within a few days if they’ve accepted.

I needed to cancel Planet Fitness in the middle of the COVID-19 pandemic and I really didn’t want to be showing up at a gym in person right now (time and unnecessary risk) just to cancel.

I called up my local Planet Fitness and was told I could either come in in person *or* send a [yes, snail mail] letter to the Planet Fitness I signed up at.

So, I’ve thrown together a cheap template to help you include everything you need to cancel (it’s just name, date of birth, and signature, according to the person on the phone.)

You can download the doc I put together at: Planet Fitness Cancellation Word Doc template


Error on an M1 Mac loading Rails: node-sass refusing to compile.

M1 Mac specific error

In trying to transfer and restart development on a Rails 6.1.3 app and get it up-to-date, I got an error on an M1 Mac about node-sass not supporting my current environment (the M1 Mac’s ARM 64 architecture).

ERROR in ./app/assets/stylesheets/application.scss (./node_modules/css-loader/dist/cjs.js??ref--6-1!./node_modules/postcss-loader/src??ref--6-2!./node_modules/sass-loader/dist/cjs.js??ref--6-3!./app/assets/stylesheets/application.scss)
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
Error: Node Sass does not yet support your current environment: OS X Unsupported architecture (arm64) with Unsupported runtime (93)

Just yarn install?

Unsurprisingly, this didn’t work, but my first instinct was a yarn install: and a few errors presumably unique to the M1 Mac (or maybe Big Sur’s Xcode environment) showed up:

../src/libsass/src/ast.hpp:1616:14: note: use reference type 'const std::basic_string &' to prevent copying
for (const auto denominator : denominators)
     ^~~~~~~~~~~~~~~~~~~~~~

.
.

/Users/tpowell/.node-gyp/16.10.0/include/node/v8-internal.h:489:38: error: no template named 'remove_cv_t' in namespace 'std'; did you mean 'remove_cv'?
            !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
                                ~~~~~^~~~~~~~~~~
.
.
1 error generated.
make: *** [Release/obj.target/binding/src/binding.o] Error 1
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/Users/tpowell/projects/blog-post-debug/self-journal/node_modules/node-gyp/lib/build.js:262:23)
gyp ERR! stack     at ChildProcess.emit (node:events:390:28)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12)
gyp ERR! System Darwin 20.6.0
gyp ERR! command "/opt/homebrew/Cellar/node/16.10.0_1/bin/node" "/Users/tpowell/projects/blog-post-debug/self-journal/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
gyp ERR! cwd /Users/tpowell/projects/blog-post-debug/self-journal/node_modules/node-sass
gyp ERR! node -v v16.10.0
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok
Build failed with error code: 1

Upgrade to node-sass compatible with the M1 Mac via @rails/webpacker

The const auto denominator error led me to this StackOverflow answer. The last time I had downstream dependency issues, the cleanest resolution was upgrading the @rails/webpacker using outdated dependencies in package.json. The current version is 5.4.3:

9c9
<     "@rails/webpacker": "5.2.1",
---
>     "@rails/webpacker": "5.4.3",

After this a yarn install should work fine. (Your need to delete node_modules may vary). Now the assets are compiling and page rendering properly:

M1 Mac now rendering Bootstrap
I guess I’ve never been so happy to see Bootstrap-style buttons.

Remove an Obsolete Work Account from Email and Accounts in Windows 10

Trying to Delete from Settings -> Email and Accounts

I was trying to “fix a problem with one of my accounts” in Windows when I realized that it was an old work account that was complaining. The problem is that “Email and Accounts” in Windows 10 only provides a “Manage” option, which requires login:

Email and Accounts offers a manage button
Email and Accounts in Windows 10 with a work or school account

The answer: Settings -> Access work or school

This is a pretty simple one but I eventually found the answer here. By going to Settings -> Access work or school, you can [Disconnect]:

Settings -> Access work or school
Settings -> Access work or school

Click on the account that you want to disconnect:

Settings -> Access work or school -> [click account]

Click [Disconnect]:

[Disconnect]

After clicking [Yes], Windows will churn for a bit and then you should be all done:

All better
All done

Lowe’s Service Advantage extended protection plan 20% premium is not Worth It

We bought a 4.2 cubic foot Maytag MVWC565FW washer in September of 2019 and paid $130 for the 5 year extended protection plan (Lowe’s Service Advantage) for major appliances $400-699.

Note: if it takes more than fourteen days from first scheduled appointment to resolution, you may be able to receive a one-time $50 payment from your Lowe’s Service Advantage plan.

Interactions with Lowe’s Service Advantage and their service provider

We called for service on August 24, 2021.

September 1, 2021 – initial visit from contract service provider. They diagnosed the problem and repair person said they scheduled a visit for September 15, 2021 after the part came in.

September 15, 2021 – called contract service provider after no one showed for the appointment I cleared my morning calendar for. They said that couldn’t get one of the parts (shift actuator), but I should call Lowe’s to see if they could locate a part.

September 15, 2021 – called Lowe’s, waited 90 minutes for a call back and requested they look for the part. They said it could be up to five business days before the business unit that did that might respond to them.

September 17, 2021 – called Lowe’s Service Advantage back to follow-up (90+ min wait for call back), the part was supposedly going to be sent out to service provider on 9/20.

September 20, 2021 – called contract service provider to see if they received any update from Lowe’s. They said would be at least September 24 before it would be sent/arrive (was not completely clear which end of the transaction it was).

September 23, 2021 – called Lowe’s Service Advantage back for follow-up (90+ min wait for call back). They said they would ask their supplier to give status on parts, with up to a 5 business day wait to hear back.

September 24, 2021 – reached out to Lowe’s on social media channels, and the response was to call Lowe’s Protection Plan phone number. Called contract service provider instead, and they said that they’re still waiting on a part, but that it supposedly got shipped September 23.

September 27, 2021 – received an email from Lowe’s that the part was delivered to the service provider.

September 28, 2021 – Called contract service provider, but they couldn’t make appointment because their systems were down but they’d call me when they came back up.

September 29, 2021 – Called contract service provider. Their first available appointments were 10/5 or 10/6. Scheduled for 10/6. $50 payment for delay was in today’s mail, which seems like a bit of a slap in the face at this point.

October 5, 2021 – Called service provider to try to confirm appointment for the next day. Robocall came through 15 minutes prior to their leaving the office for the day.

October 6, 2021 – Service technician was able to replace actuator, but hub could not be replaced without ordering a new agitator. Washer is now working otherwise.

It took 43 days to get back to a working washing machine.

So far, I’ve spent 5+ hours waiting for call backs, 4 hours waiting for service appointments that were apparently never made or canceled without my knowledge, and my wife has spent 12-14 hours at the laundromat and well over $100 (maybe even $200?) at the laundromat.

Log of interactions with the Lowe's Service Advantage service provider
Service provider logs.

Not the First Time

This has been the second appliance/equipment purchase in the last two years that has subpar support. We also bought a Craftsman Cordless Electric Mower that we couldn’t get a replacement battery for.


Trying Out the Ringo R-470, a Brazilian ZX-81 Clone

I’ve also recorded a video on YouTube where can you see a demonstration of the Ringo R-470 emulation on the EightyOne emulator:

Demonstrating the Ringo R-470 emulation in EightyOne

The Jupiter ACE was an obscure machine, partly for the fact that the primary programming environment was the Forth programming language. I found out after my Jupiter ACE post that it enjoys a small but faithful following. You can also find them for purchase on eBay if you’re willing to spend $1,000+ on a unique and obscure ZX-81 clone.

The Ringo R-470

I really only stumbled upon Ringo R-470 because there’s a ROM for it packaged with the EightyOne Sinclair Emulator. There are various copies of its original manual floating around (also available on Scribd) and a very brief wikipedia page. The emulation in the emulator mostly works, but virtual peripheral support (including the tape loader) seems shaky at best. You’re not likely to find one available for sale online, either.

R-470 Ringo - Frente

The above image which is also on the Wikipedia page is pretty standard in terms of being able to see the features of the computer clearly. This Sinclair Clones page has a few better photos, but you still can’t completely see the keyboard layout. (You can find a clearer picture of the layout on page 12 of the original manual linked above.)

Using with the EightyOne emulator

Edit cursor [>] and [K]eyword/command mode at the bottom

The functionality of the R-470 is mostly similar to the ZX-81, but the placement of the keywords and symbols (which still use English) is completely different from the ZX-81 layout. For example, L in keyword mode is LIST on the R-470 and LET on the ZX-81 (and K is LET on the R-470 and LIST on the ZX-81). However, the two layers of command mode keys and function mode keys and the graphics mode are similar, and the displayed listing has a [>] cursor for highlighting which key will get picked up if you select edit mode.

If this is your first try with a Sinclair clone (that speaks BASIC), you’ll need to keep in mind that the keywords are whole symbols on their own as opposed to being parsed from strings like Microsoft-derived BASICs. It’s actually kind of nice for editing and I’m sure it greatly simplifies the parsing, but even “TO” cannot be specified with the letters T and O and must instead be typed with the [left shift + T] (or [left shift + 4] on the ZX-81).

Another shock to the system for those unacquainted with the Sinclair way is that you get an error code + line number that it happened on at the end of execution (0 is no error/OK):

B (Integer out of range) on line 120 (because I tried to plot on row 44, and y coordinates only go up to 43)

An alphabetical guide to the keyboard mapping of keywords and symbols:

I’ve compiled an alphabetical listing of the symbols/commands below (also available in markdown here) if you want to try your hand at typing a BASIC program into the the R-470 inside the EightyOne emulator. I’m sure that typing on a modern keyboard is more functional than typing on rubber chiclet keys, but the layout is pretty challenging:

symbolkeycursor modemodifier
P[K]eyword/command modeleft shift
“”2[K]eyword/command modeleft shift
$O[K]eyword/command modeleft shift
(X[K]eyword/command modeleft shift
(edit mode)1[K]eyword/command modeleft shift
(graphics mode)9[K]eyword/command modeleft shift
)C[K]eyword/command modeleft shift
*G[K]eyword/command modeleft shift
**F[K]eyword/command modeleft shift
+K[K]eyword/command modeleft shift
J[K]eyword/command modeleft shift
/H[K]eyword/command modeleft shift
:N[K]eyword/command modeleft shift
;M[K]eyword/command modeleft shift
<V[K]eyword/command modeleft shift
<=Y[K]eyword/command modeleft shift
<>U[K]eyword/command modeleft shift
=L[K]eyword/command modeleft shift
>B[K]eyword/command modeleft shift
>=I[K]eyword/command modeleft shift
?Z[K]eyword/command modeleft shift
ABSG[F] function modeleft CTRL (and release) from [K]eyword/command mode
ACSR[F] function modeleft CTRL (and release) from [K]eyword/command mode
ANDA[K]eyword/command modeleft shift
ARCTANY[F] function modeleft CTRL (and release) from [K]eyword/command mode
ASNW[F] function modeleft CTRL (and release) from [K]eyword/command mode
ATM[F] function modeleft CTRL (and release) from [K]eyword/command mode
CHR$D[F] function modeleft CTRL (and release) from [K]eyword/command mode
CLEARZ[K]eyword/command modedefault
CLSX[K]eyword/command modedefault
CODEC[F] function modeleft CTRL (and release) from [K]eyword/command mode
CONTC[K]eyword/command modedefault
COPYQ[K]eyword/command modedefault
COSE[F] function modeleft CTRL (and release) from [K]eyword/command mode
DIMD[K]eyword/command modedefault
EXPK[F] function modeleft CTRL (and release) from [K]eyword/command mode
FASTR[K]eyword/command modeleft shift
FORF[K]eyword/command modedefault
GOSUBH[K]eyword/command modedefault
GOTOG[K]eyword/command modedefault
IFW[K]eyword/command modedefault
INKEY$I[F] function modeleft CTRL (and release) from [K]eyword/command mode
INPUTI[K]eyword/command modedefault
INTH[F] function modeleft CTRL (and release) from [K]eyword/command mode
LENX[F] function modeleft CTRL (and release) from [K]eyword/command mode
LETK[K]eyword/command modedefault
LISTL[K]eyword/command modedefault
LLIST4[K]eyword/command modeleft shift
LNL[F] function modeleft CTRL (and release) from [K]eyword/command mode
LOADA[K]eyword/command modedefault
LPRINT3[K]eyword/command modeleft shift
NEWM[K]eyword/command modedefault
NEXTN[K]eyword/command modedefault
NOTN[F] function modeleft CTRL (and release) from [K]eyword/command mode
ORQ[K]eyword/command modeleft shift
PAUSEE[K]eyword/command modedefault
PEEKB[F] function modeleft CTRL (and release) from [K]eyword/command mode
PLOTY[K]eyword/command modedefault
POKEB[K]eyword/command modedefault
PRINTP[K]eyword/command modedefault
RANDO[K]eyword/command modedefault
REMT[K]eyword/command modedefault
RETURNJ[K]eyword/command modedefault
RNDO[F] function modeleft CTRL (and release) from [K]eyword/command mode
RUNR[K]eyword/command modedefault
SAVES[K]eyword/command modedefault
SCROLLV[K]eyword/command modedefault
SGNJ[F] function modeleft CTRL (and release) from [K]eyword/command mode
SINQ[F] function modeleft CTRL (and release) from [K]eyword/command mode
SLOWE[K]eyword/command modeleft shift
SQRF[F] function modeleft CTRL (and release) from [K]eyword/command mode
STEPD[K]eyword/command modeleft shift
STOPS[K]eyword/command modeleft shift
STR$S[F] function modeleft CTRL (and release) from [K]eyword/command mode
TAB,[F] function modeleft CTRL (and release) from [K]eyword/command mode
TANT[F] function modeleft CTRL (and release) from [K]eyword/command mode
THENW[K]eyword/command modeleft shift
TOT[K]eyword/command modeleft shift
UNPLOTU[K]eyword/command modedefault
USRU[F] function modeleft CTRL (and release) from [K]eyword/command mode
VALV[F] function modeleft CTRL (and release) from [K]eyword/command mode
πP[F] function modeleft CTRL (and release) from [K]eyword/command mode

The Unique Jupiter ACE Experience: Programming Forth on a ZX-81 Like System

What’s the Jupiter ACE?

The Jupiter ACE was an early 1980s home computer that had similarities to the Sinclair ZX-81, especially in the bottom input entry

Jupiter ACE emulated in the EightyOne emulator
Entering commands and code on the bottom line of the Jupiter ACE (using EightyOne emulator), much like the ZX-80 and ZX-81

in the keyboard layout (By the way, symbol shift can be shift to right-shift in EightyOne emulator or is otherwise the right CTRL key… also note that the double quote, /, *, and others are reached by the symbol shift + a letter key.)

Keyboard Layout view from SpudACE emulator

and the extremely limited 1KB of base RAM.

What’s Forth?

Forth is a stack-based programming language that relies on a data stack and reverse Polish notation, much like the HP calculators are known for. A basic example would be 6 2 * which would perform the operation 6 * 2 and push the value 12 back onto the data stack. If you wanted to actually retrieve/pop the result off the stack, you would issue a 6 2 * . sequence, in which the . would pop the last value and return/print it.

Special considerations for the Jupiter ACE’s Forth

The data stack on the Jupiter ACE assumes 16-bit values, and the default data type assumed is a signed integer, so you have values from -32768 to 32767 that are allowed per single stack slot:

256 * 256 is 0 (because that would require 17 bits. 128 * 256 is -32768. 128 * 256 – 1 is 32767

Floating point numbers are possible, but they require two stack slots, so you have on operate on two consecutive stack locations at the same time to work with floating point numbers. Another challenge with the Jupiter ACE’s Forth implementation is that you’re missing some advanced math functions and you have to write your own. The following is an annotated version (the comments are in parentheses) of the SIN routine found on page 93 from the first edition Jupiter ACE manual found here:

: SIN
    (x - sine of x)
    2DUP 2DUP 2DUP F* FNEGATE ([x,x,-x*x])
    2ROT 2ROT ([-x*x,x,x])
    27 2 ([-x*x,x,x, 27 2])

    DO (initial value of 2, limit 27)
        ([-x*x,x,x])
        6 PICK 6 PICK ([-x*x,x,x,-x*x])
        F* I I 1+ * ([-x*x,x,-x^3,6])
        UFLOAT F/ ([-x*x,x,-x^3/6.])
        2DUP 2ROT F+ 2SWAP ([-x*x,-x^3/6.+x,-x^3/6.])

        (3 down the stack of floats is the multiplier of the
        numerator terms for the Newton method, 2 down the
        stack is the total sum, top of the stack is the last
        term, and the counter (I) tracks the denominator 
        multipliers (I and I+1))

        2 (add 2 to the stack for the loop increment)
    +LOOP
    2DROP 2SWAP 2DROP ([x-x^3/6. ... etc])
;  

2DUP, 2ROT, and 2SWAP are methods that are defined on previous pages to basically work with floats on the stack in the same way as 16-bit integers. The algorithm is Newton’s method to estimate a sine, through 14 terms of the method. If you map out the stack locations by hand, you can follow how the method is making creative use of the top 3 – 4 (6 – 8) stack positions to keep the progress, the multiplicand of the numerator of the terms, and the current term. However, due to floating point representation, this information is harder to trace through in the emulator because you will see 16-bit values in the data stack.

Trying for yourself

I’ve tried out the SpudACE emulator (strictly Jupiter ACE) and the EightyOne emulator (Sinclair, Timex, and others also emulated) which can be found on this Jupiter ACE Emulators for Windows page. I’ve found the EightyOne emulator a bit more stable and usable. You’ll want to make sure to mute your sound when saving to tape, because sound *may* output when saving to your virtual tape. Watch a demonstration here and see the source code for the demo in this folder.


Astrolokeys and a Vortex Tab 90M

If you found this helpful and are planning on purchasing a Drop keycap set, please use my referral link and we’ll both get $10.

Astrolokeys with the Vortex Tab 90M base

I initially built a Drop CTRL keyboard combo with the Halo Clear switches and Astrolokeys Base set for the 15% discount, but after a while I felt myself missing my Cherry MX Silent Black switches and the full keyboard layout of the Vortex Tab 90M.

Transferring the Astrolokeys to Vortex Tab 90M

After transferring the keys, only the right [CTRL] [SHIFT] [ALT] and the [FN] [PN] and [CALC] keys were missing “in theme” keys. After spending a week with the old primary color key caps, I got the “Nonstandard Icon Mods” and the “Ortho Icons” from the Astolokeys page. Ultimately getting those sets plus the base kit instead of the Drop CTRL would have been $150 for the key caps only vs. $250 for the original keyboard base, switches, and base keycap set. But now someone else in the family has a very nice tactile keyboard with the old Tab 90M keycaps until they get their own custom keycaps someday.

Oh, and the Drop CTRL looks pretty cool with the Vortex Tab 90M keycaps, too…

Drop CTRL keyboard with Vortex Tab 90M keycaps

Getting a Count of Occurrences of Items in a Ruby Array (and a Caveat for Rails)

I feel like I’m often wanting to count occurrences of items in an array (Rails has its own special case as well), and I’m always trying to do it the “long way.”

I finally stumbled upon this answer on StackOverflow that details the version-by-version options:

  • Ruby 2.7+ use .tally directly on the array:
irb(main):006:0> %i{a b c c d c e b a a a b d}.tally<br>=> {:a=>4, :b=>3, :c=>3, :d=>2, :e=>1}
irb(main):011:0> %i{a b c c d c e b a a a b d}.group_by(&:itself).transform_values(&:count)
=> {:a=>4, :b=>3, :c=>3, :d=>2, :e=>1}
irb(main):012:0> %i{a b c c d c e b a a a b d}.group_by(&:itself).map { |k,v| [k, v.length] }.to_h<br>=> {:a=>4, :b=>3, :c=>3, :d=>2, :e=>1}

The Rails Exception

It’s a pretty common temptation, especially once you start thinking in terms of the list of items you want to count, to try to use a pure Ruby solution for things. But what if your source is from the your database?

The key here is the database. You probably don’t want to load all of the records from the database just to count them using the above methods, and SQL has a GROUP BY clause which is just called .group.

irb(main):013:0> Entry.group(:user_id).count
D, [2021-08-26T02:49:43.996743 #4] DEBUG -- :    (1.2ms)  SELECT COUNT(*) AS count_all, "entries"."user_id" AS entries_user_id FROM "entries" GROUP BY "entries"."user_id"
=> {1=>231, 4=>15, 2=>2}

This output is tallying entries by what User (via user_id) entered them. More importantly, the SQL used did the counts within the database without retrieving any data contained into the application except what was counted. (This used to be a pun on the :what column in the entries table, but apparently we’re not there with proper rendering and cutting and pasting of emojis between apps and OSes and well, I enter emoji as part of my entries in this app.

This original example in extreme wide screen glory

8563 Chip: Plotting Characters to the Commodore 128’s 80-column Mode

Source Code for this 8563 Demonstration

You can find the below source code at https://github.com/stringsn88keys/unnecessary-computer-things/blob/main/episodes/2021/001/commodore-128/CHASXYCOSINE.BAS and watch here for demonstration of the run time vs. the TRS-80 Model 16 emulator (a computer for which I never realized had a graphics mode when I had access to one). The BASIC and disassembly is also available on page 312 of the Commodore 128: Programmer’s Reference Guide… but beware, the OCR versions translate the “1”s occasionally to lowercase “l”s (which wouldn’t exist in a Commodore program listing unless all lowercase) and the “O”s to “0”s (but inconsistently).

8563 graphing text characters

Why is this a post?

If you’re here, you probably wrote some Commodore screen plotting code in which the screen was mappable via POKE commands for the contiguous video RAM (22×23 for VIC-20, 80×25 for Commodore 64/128) or by DRAW commands in graphics mode for the Commodore 128. (Also bitmap POKEable for the Commodore 64, if I recall correctly… haven’t sorted out the VIC-20’s situation yet… that’s another day.)

Well, the 80-column MOS 8563 chip has its own video ram. And given the 16-bit address space (yeah, there are BANKs to switch for the 128), it’s not readily addressable in contiguous address pointer space. Actually, it’s NOT ADDRESSABLE AT ALL by address space. Instead, there’s a convoluted process to write to it. (Thanks to this video for helping me “get it” fully)

Sending Data to the 8563

  • High memory byte write
    • Store video register number 18 for the 8563 high memory address byte in register X (register X = 18)
    • Store 8563 high memory address in register A (register A = [8563 address] / 256)
    • Write value of X to location $D600 (location 54784 in decimal)
    • Wait until $D600‘s high bit flips (instructions: do a bit test, check for “bit plus” (sign bit is bit 7, so loop if it’s still zero)
    • Write value of A to location $D601 (location 54785 in decimal)
  • Low memory byte write
    • Store video register number 19 for the 8563 low memory address byte in register X (register X = 19)
    • Store 8563 high memory address in register A (register A = [8563 address] AND 255)
    • Write value of X to location $D600
    • Wait until $D600‘s high bit flips
    • Write value of A to location $D601
  • Write the actual content!
    • Store video register number 31 in register X to signal that you want to interact with data in the address set by the last two steps.
    • Store byte you want to write in register A
    • Write value of X to location $D600
    • Wait until $D600‘s high bit flips
    • Write value of A to location $D601

The code

This can probably be done with POKE and PEEK, but this process is tedious enough for machine code. You can assemble it this way:

0180c 8e 00 d6  stx $d600
0180f 2c 00 d6  bit $d600
01812 10 fb     bpl $180f
01814 8d 01 d6  sta $d601
01817 60        rts

Or store it in data and have your basic routine load it into memory. The former is a lot saner for actual entry because you at least get the assembly mnemonics.

Invoking the code

100 addr = (x * 80) + y : rem x = 0 to 79, y = 0 to 24
110 c = 209 : rem the filled disc
120 gosub 11010
9999 end
10000 vo=dec("180c")
11000 rem vo is output routine location, addr address, c character to output
11010 sys vo, addr/256,18
11020 sys vo, addrand255,19
11030 sys vo, c, 31
11040 return

Further Challenges

You’ll notice in the video that the filled disc characters are reversed. That’s because while the characters in video RAM are in $0000$07FF (0-2047), the attributes are in $0800$0FFF. I haven’t confirmed, but I believe there are three different registers to set those as well.


Microphone Crackle and Distortion on Windows 10 with New ASUS Motherboard

I’ve had to remedy microphone crackle and distortion twice on two different builds/rebuilds of Windows 10 PCs, and somehow forgot from the last time how to remedy.

In my case, the problem was the onboard sound for the ASUS Motherboard (ASUS ROG Strix B550-E and ASUS ROG Strix B550-A motherboards.) The solution is to get the audio drivers for the Realtek Audio that come on the board and install them (B550-A and B550-E downloads.)


Craftsman V60 Mower (Cordless Electric) – Disappointing Value 2 Years Later

We’ve had mixed results with our Craftsman V60 Mower (CMCMW270) after a little over two years of ownership.

UPDATE: After a back and forth on a response to a review on their page, I appear to have gotten a check for the cost of the larger battery that’s still available (5.0Ah, though, not the original 7.5Ah). Still trying to decide whether to get a couple of batteries or upgrade mower.

The Good – V60 battery beats gas fumes

While we’ve had plenty of cordless lawn equipment such as trimmers and blowers, this was our first lawn mower that wasn’t gas powered. Being able to mow without breathing in gas fumes for an hour is a huge benefit to an electric mower, and not having a cord attached seems like the only way to go.

Another huge benefit is that it starts and stops pretty easily. The initial battery life on the V60 was only about an hour or so for our cutting needs, but you could start and stop the mower in an instant in cases in which you might keep a gas mower running just to not have to fight with starting it back up again.

The bad – Declining V60 battery life and no availability

The biggest drawback is that the battery life of the 7.5AH battery now only lasts long enough for at most 2/3rds of the yard to be cut. This is only 2 years after purchase. You’ll also notice that if you search for CMCB6075 (the 7.5AH battery) or go to the above link, there are no sellers of the brand new battery, only the occasional eBay listing. We did get a decent discount over brands that weren’t dying out, but didn’t expect the support for this thing to disappear so quickly.

The CMCB6025 2.5AH battery is still available on Amazon (affiliate link) or Lowes, but it’s a whopping $150 for 15-20 minutes of battery life. Still, we manage to juggle the CMCB6025 for our blower with the CMCB6075 to get the job done.

A similar nuisance that is compounded by the abysmal battery life is the fact that the blade doesn’t quite spin up to the speed of a gas mower, which left us with missed blades of grass everywhere, even when the blade was fresh and sharp.

The 7.5AH V60 batteries are rarely available on eBay

Conclusion

I’ve liked the experience enough with this mower to not really want to go back to gas-powered, but I don’t look forward to paying the premium and being on the hook for replacement batteries.