The Green Shed

ChatGPT and its ilk may well result in a better experience for searching than Google — for a while. But if you don’t think the shitty incentives that led to Google’s quality dropping off aren’t going to affect these LLMs in the exact same ways, I’ve got a bridge to sell you.

Docker is just terrible. The default options always seem wrong. The error output is often inscrutible. Debugging is a nightmare. This is just poorly designed software.

Enshittification

This is enshittification: Surpluses are first directed to users; then, once they’re locked in, surpluses go to suppliers; then once they’re locked in, the surplus is handed to shareholders and the platform becomes a useless pile of shit. From mobile app stores to Steam, from Facebook to Twitter, this is the enshittification lifecycle.

www.wired.com/story/tik…

This is it. The last 25 years in a nutshell.

There is no way that the people who work on docker actually ever use docker.

UPS Error LASSO_1010

For months I haven’t been able to login to “My UPS” (which is now the only way to get detailed tracking info). Attempting to login would give me error LASSO_1010. Attempting to reset my password would return an “Application error” and never send a reset email.

The solution (via this Reddit thread) was to install the UPS mobile app, and initiate a password reset from the app. In that case I did receive the reset email, and was able to update my password, and I can now login.

Replaced a thumb stick in a VR controller tonight. Required a full tear down, but cost $15 instead of $75 for a new controller, and I’m not sending a good controller to the landfill because one part was bad.

Was fiddly and took a while, but very gratifying.

On Personal Computing

… the impulse to repair arises from and is sustained by love — and that the particular form of love at work here is friendship. By repairing the things of this world we exhibit friendship towards them — and they become friends to us in return.

Alan Jacobs, the friendliness of objects

If you buy something off the shelf, like an iPhone, which you can’t change, you’re less likely to care for it, and it’s going to end up in a drawer. Back then you could go to Radio Shack and get parts for your computer, it was possible to customize it (for example, the Altair), and then you could know it in its entirety. Devices that were customized, or built from near-scratch, are still loved, but as for your old iPhone6, you don’t know where it is, and even if you did it’s probably unusable. Devices like the iPhone6 can’t be repaired, they are designed to fail in ways that are inscrutable.

Hundred Rabbits , Weathering Software Winter

These sound like different notes in the same chord to me. I want computers, and computing, to be personal again.

GPIO Button Handling on RaspberryPi in Ruby

I’ve working on adding some physical controls to my kitchen status display. The setup is very simple, and for a first-run all I wanted to be able to do was detect a button press, and run a script somewhere on the system.

I couldn’t find any existing code that does this (please point some out if you know of any), though there’s plenty of code out there for button handling in general.

Also, most of the code out there for doing GPIO work is either in C or Python, and I was hoping for a Ruby solution, or at least a solution that would be easy to wrap in Ruby.

In the end I learned about how to interface with the GPIO system on RPi via the filesystem.

From there, I found this code from Aaron Patterson using epoll to monitor for changes in the level on the monitored pin. That seemed like it would work, but the epoll gem seems to be unmaintained at this point. Instead, I went with the Sleepy Penguin gem, which provides an interface to the same underlying Linux filesystem events.

Lastly, I wanted my pin pulled high by default, and there’s no way to do that via Sysfs, so I ended up using the gpio utility to set the pin state and pull up resistor.

From there, I was able to run this little script, which will output the current state of the pin when it changes.

# install gpio command line tool
# gpio -g mode 16 up
require 'sleepy_penguin'

def watch pin, on:
  
  puts "Setup Export"
  File.binwrite "/sys/class/gpio/export", pin.to_s

  
  puts "Setup Edge"
  
  retries = 0
  begin
    
    File.binwrite "/sys/class/gpio/gpio#{pin}/edge", on
  rescue
    raise if retries > 3
    sleep 0.1
    retries += 1
    retry
  end

  puts "Read Value"
  
  fd = File.open "/sys/class/gpio/gpio#{pin}/value", 'r'
  yield fd.read.chomp

  puts "Setup epoll"

  epoll = SleepyPenguin::Epoll.new
  epoll.add fd, SleepyPenguin::Epoll::PRI

  puts "Start loop wait"
  loop do
    fd.seek 0, IO::SEEK_SET
    epoll.wait do
      # yield fd.read.chomp
      value = fd.read.chomp
      p value
    end
  end
ensure
  
  File.binwrite "/sys/class/gpio/unexport", pin.to_s
end

pin = 16

watch pin, on: 'both' do |value|
  p value
end

Still to come: debouncing, better handling of a change event, and hopefully wrapping it all up into something much easier to work with.

eInk Displays

For a long while now I’ve had a weather/calendar/status display on the wall in my kitchen. Powered by a Raspberry Pi, it updates every few minutes. Recently I started thinking about extending the interface, adding a few buttons to choose which “page” might be active at any given time.

My hope was that I would be able to do a quick update to the display while the button “selection” UI was being interacted with. The term for this in the eInk/ePaper world is “partial update.”

After spending a lot of time researching and experimenting, I haven’t yet been successful, though I learned a lot in the process. At this point I need to pause my project, but I thought it might be worthwhile to jot down my notes thus far, in case they might be helpful to anyone else trying to do the same sort of thing.


Last Updated January 2023

My Display

I have a 7.5” ePaper display (Black/White, 800x480) and board from Waveshare. The Spec Doc (PDF) is available on their site.

Most of the displays that Waveshare sells seem to be manufactured by Good Displays, then Waveshare builds some boards and code, and sells/distributes.

The Code

Waveshare provides demo code and documentation for this display (and their other displays) on wiki on their website.

My status display uses some Ruby libraries to generate a BMP image, which is then transferred as-is to the display every few minutes.

How These Displays Work

This video by Applied Sciences on YouTube is a great place to start in understanding how these displays work, and how they can be manipulated.

The fundamental principle to understand is that the display uses pulses of AC power to create a charge differential that pulls the white/black capsules to different sides of the silos they float in. The pulses are necessary because applying a constant DC voltage would induce a charge in the structure of the display itself, and further refreshes would not be possible anymore. So these waveforms must be effective both in moving the ink capsules, as well as avoiding unnecessary charge inducement. To some extend these waveforms are a “secret sauce” of good display drivers (and, from what I can tell at least, a good part of the reason that Kindle displays seem so far ahead of the rest of the eInk world — they’re using complicated, probably very high frequency updates, maybe driven by hardware of a higher complexity than these other hobbyist boards; I’d love to know more).

Partial/Fast Updates

Most of these displays can be manipulated in such a way that you can update only a subsection of the display, at a higher rate than is possible when refreshing all the pixels at once. (See Waveshare sample code for some examples on some of their smaller displays).

Custom LUTs

When a screen refresh is performed, the display executes a series of AC pulses based on stored waveform data. The waveforms vary depending on the pixel transition. White -> White, White -> Black, Black -> White, etc. can all have different waveforms in use.

The Waveshare boards support overriding the waveforms with custom LookUp Tables (LUTs). The format is complicated, but you can find documentation in their spec docs; the Applied Sciences video is another good reference for these.

GxEPD

ZinggJM has some custom code supporting many, many panels; many of these have custom LUTs for doing fast/partial updates. It’s worth digging into those for examples of how LUTs work; or, if you’re satisfied, just use his code to drive your display(s).

Other Resources

This huge thread in the Arduino forums has a ton of little gems and tidbits about using these displays.

This is another fast-update project with code that might be helpful.

This is the code that Ben Krasnow (Applied Sciences) shared in his video.

Ben’s eInk article with many great links

Winter Fire

Backlit clouds are illuminated by the afternoon sun, as misty clouds obscure the top of a snowy, tree-covered canyonside.
Backlit clouds are illuminated by the afternoon sun, as misty clouds obscure the top of a snowy, tree-covered canyonside.
Date Taken
December 28, 2022
Camera
SONY ILCE-7RM4A
Lens
FE 35mm F1.8
Focal Length
35.0 mm
Shutter Speed
1/2500
Aperture
f/9.0
ISO
100
Keywords
Landscape, Mountains, Snow, Winter

Setting BLTouch Z Offset

These are my notes to myself for adjusting the Z Offset for the BLTouch for my Ender 3V2 Printer.

I’m running OctoPrint and Klipper Firmware.

  1. Let the bed cool to room temperature.
  2. Get out a sheet of paper.
  3. G28
  4. G90 — Switch to absolute position mode.
  5. G1 Z3 — Move down to z +3mm.
  6. Verify that we aren’t about to hit the bed.
  7. Now, keep moving down (G1 Z2 etc.) until the get to the depth where the paper test passes.
  8. Set the BLTouch offset to current_bltouch_z_offset - current_z_position — So if our absolute Z position goes below zero, we want to add that difference to the existing offset.
  9. Set that value in printer.cfg and save it.
  10. restart
  11. Repeat again, until Z0 is at the right position.
  12. Do a test print to confirm.
  13. Once the depth seems right, you probably want to do a BED_MESH_CALIBRATE again.

I feel so torn about eBooks sometimes. I absolutely love my Kindle — it’s one of my favorite things. I love how small and portable it is, and I love having so many books always available, and I love how easy it is to find and get new books.

On the other hand I love physical books, especially used books. And I love being able to look at a real bookshelf and consider what I might want to read.

I want more analog experiences in my life, but alas, I just can’t get away from my Kindle. Though, the Kindle might be the most analog-esque digital device I own. Interesting.

Finally got my old bookshelf speakers out of a box in the garage and set them up in my bedroom. I should have done this a long time ago!

Golden Unicorn

Alpenglow illuminates Unicorn Peak just before sunset in Yosemite National Park, California.
Alpenglow illuminates Unicorn Peak just before sunset in Yosemite National Park, California.
Date Taken
October 04, 2022
Camera
SONY ILCE-7RM4A
Lens
FE 85mm F1.8
Focal Length
85.0 mm
Shutter Speed
1/20
Aperture
f/9.0
ISO
100
Keywords
Alpenglow, Landscape, Mountains, Sunset

AirPods Pro II

I got the first generation of AirPods Pro shortly after they came out, and I’ve loved them. They’re super small and portable, and while the noise cancelling isn’t quite up to the level of my Bose QC 35s, they are so light and easy to transport that I often grab them instead.

Unfortunately, my pair have been subject to the crackle of doom for a while now, and over the last few weeks it’s gotten noticibly worse.

It being Christmas time, I opted to get myself a little gift, and bought the second generation AirPods Pro — and they’re really great!

The noise cancellation in these is so good it feels like magic. The first generation ANC was great, especially for something so small. But it’s blown away by the new AirPods. I can have my music paused in the gym and it feels nearly silent. They’re amazing.

The new volume gesture on the “stick” is almost worth the upgrade on its own. I was always annoyed to have to reach for my phone to adjust the volume, but I didn’t realize just how often I was doing that until I had an alternative. The gesture feels natural, it works every time, and it really makes the experience of wearing the AirPods feel better.

The next big test will be wearing them during a flight. Typcially, I travel with my bulky QC 35s beacuse the quieting is so good, but with these new AirPods I think I can get away with leaving them at home.

All in all, this has been a really great upgrade! Highly recommended.

My question about all this is: And then? You rush through the writing, the researching, the watching, the listening, you’re done with it, you get it behind you — and what is in front of you? Well, death, for one thing. For the main thing.

Alan Jacobs, and then?

Recursive Regression

If tools like GPT result in the creation of large amounts of new content, and then that content gets ingested by the next generation of the models, at what point does that impact the quality of the new output?

Is all future output bounded by the quality of whatever was available broadly circa late 2021?

Thinking about ChatGPT Security

Imagine the attention these ML systems will attract once it becomes public that big companies/governments/individuals use them for any given task. Suddenly, there will be immense incentive to poison the datasets in subtle but impactful ways. Then we’ll see attacks that are both very direct (compromise the humans overseeing the “safety” of the system) as well as very indirect (massive content farms taking advantage of known weaknesses/limitations to poison the data pool(s)).

Imagine when someone hack’s one of these organization’s systems, then subtly alters the precedence used when ingesting information!

And then there’s figuring out how to inject the right prompts to leverage RCE vulnerabilities!

And the more “capable” they become, the bigger the attack surface!