MoreRSS

site iconAndreasModify

Electrical engineer, musician, out and about on two wheels, read a lot of books, coffee-addict.
Please copy the RSS to your reader, or quickly subscribe to:

Inoreader Feedly Follow Feedbin Local Reader

Rss preview of Blog of Andreas

Linkdump No 118

2026-07-31 08:00:00

an animated 90s style GIF that has the word Links in green font on black background

Only the good die young
All the Evil seem to live forever

That's taken from the Iron Maiden song Only the Good Die Young from the Seventh Son of a Seventh Son album. I've been thinking of this lyric a lot recently as I keep seeing good musicians and actors, people who spent their lives bringing joy to others, die relatively young, while all the horrible people in the world seem to thrive and live forever. It's kind of depressing to watch and think about. So maybe let's not think about it too much and listen to some music instead, because while the world might not be so great right now, one thing I'm sure of is that fifty or a hundred years from now art will still be there and still bring us joy and happiness, while the monsters and the wannabe dictators of our time will be nothing but footnotes in the history books.


Articles

Software/Services

Videos

Around the Small Web

Linkdump No 117

2026-07-24 08:00:00

an animated 90s style GIF that has the word Links in green font on black background

The Amiga turns 40 this week. I had an Amiga 500 as a kid, some time in the early 90s. And I remember being made fun of for having an Amiga, because PCs were supposedly so much cooler and better and whatnot. But the first time I visited a friend who had one of those amazing PCs and he proudly showed me his games with their EGA graphics colour palette and the PC speaker sounds I thought, are you kidding me? This is the thing you're going on and on about? Have you even seen an Amiga? I was truly underwhelmed by that. At the time it was released, and into the early 90s the Amiga was leaps and bounds ahead of the competition in terms of sound and graphics, and the more I learn about the history of Commodore the more disappointed I am that the company went the way it did. They were far ahead of the competition at the time, and had things gone differently they could be where Apple is today.
Unfortunately it wasn't meant to be, and Commodore turned into one of those companies that flourished for a while and then slowly withered away. It is what it is, but one can dream about what could have been. Maybe it's time to play some Amiga games this weekend.


Articles

Software/Services

Hardware Projects

Around the Small Web

Linkdump No 116

2026-07-17 08:00:00

an animated 90s style GIF that has the word Links in green font on black background

You know what, I was kind of busy last week with my OCC project, and I was also building a website for a friend who is opening her own doctor's office, and so I completely forgot that my blog turned three years old last Thursday! Well I actually didn't completely forget, but I was convinced that the date of my first post was July 19th, while it was actually July 9th. Whoops. The human brain is weird, I still remember the birthdays of people I haven't seen or spoken to in 25 years. But then other, much more recent things completely slip my mind.

Either way, three years of blogging! I just started this one day on a whim, but it has unexpectedly turned into one of my longest running projects and one my favourite hobbies, too. And thanks to obsessively versioning everything with Git, I can go back and look at how the website looked on day one.

The first version of my website

It wasn't great, I just used a default Hugo theme and I had no idea what I was even doing (as evidenced by the fact that the posts date shows up as July 5th, but the commit is from July 9th and that's also the date that shows up on the post today... no idea what's going on there), but it was a start. Three years later I'm building a website for a doctor's office, so it seems like I learned a thing or two along the way. So here's to year four, let's see what's going to happen!


Articles

Software/Services

Videos

  • The RAMpocalypse just got so much worse... - YouTube
    I'm gaining huge respect for this guy recently. He started out as a typical Apple fanboy, but recently he's been making videos where he digs deep into an issue and presents a really well researched take into what's going on. This time it's about how RAM prices got to where they are. Highly recommended.
  • GameBoy Emulator on ESP32 + Eink (M5Stack PaperS3) - YouTube
    Massively cool project - a GameBoy emulator running at full speed on an E-Ink display. The only thing I don't like are the touch controls, but E-Ink is perfect for the GameBoy's monochrome games.
  • I Powered a Car using 500 Disposable Vape Batteries - YouTube
    Also massively cool, but also kind of scary - the guy builds a car battery for a crappy old electric car out of batteries from disposable vapes. Disposable vapes are an abomination and should be made illegal, but at least tinkerers can make some cool things from them.

Around the Small Web

Misc

  • ObsoleteSony Archive
    I completely forgot this last week - as a response to my Walkman post Calishat sent me this. It's an archive of old Sony Walkmans, Discmans and MD players. It's a really nice and nostalgic site!

Linkdump No 115

2026-07-10 08:00:00

an animated 90s style GIF that has the word Links in green font on black background

This past week I've been writing a lot, first the Walkman post and then my IR sensor project. I've gotten some really nice feedback on both; the Walkman post in particular seems to have resonated with a lot of people, which is interesting. I wasn't even sure if writing a post about it was worth it because it was such a basic fix. But now I'm glad I did.

I'm sure if you have a blog, you know the doubts that sometimes creep into your mind. The feeling of "should I even write about this", "who even cares about what I have to say", "this is silly" etc. I have these thoughts too; a lot actually. But the answer is always "yes, I should write about it, even if I think it's silly" because you never know, your silly post about an old Walkman might brighten up someone's day, and if even one person enjoys it, it was worth it.

The lesson I keep learning is to not listen to the doubts and the negative voice in my head and just do it anyway. The voice lies. So thank you to everyone who's getting in touch with me, I truly appreciate it! On to the links.


Articles

  • Copy That Floppy! - Imaging floppy disks for long-term preservation
    This is an in-depth guide into how floppy disks work and how to archive them, because they don't last forever. If you still have some old floppies, it might be a good idea to buy a drive and archive them now before it's too late.
  • Bosses Horrified as "AI Native" College Graduates Hit the Workplace
    "Massive numbers of students are going to emerge from university with degrees, and into the workforce, who are essentially illiterate."
    It's sad to see that thanks to the overuse of AI we're currently creating a generation of essentially braindead drones who aren't capable of thinking for themselves, because they never learned how. (via Doug Merritt)
  • Google's New reCAPTCHA Wants Your Camera Access and 21 Points of Your Hand
    Apparently Google is planning a new captcha process where you have to turn on your camera and wave your hand around so they can biometrically scan it. And who wouldn't trust a company like Google with their biometric data! Every time you think that things can't possibly get any worse, big tech finds a way to make things worse. (via Emilis)

Software/Services

Hardware Projects

Videos

Around the Small Web

Misc

  • snr.dance
    I was browsing old OCC posts and found this mentioned in Andrei's post from last year. It's an internet radio station that broadcasts old Eurodance tracks. Check out the design of the site! Looks straight out of the 90s/00s, in a good way.

Old Computer Challenge 2026 Day 4 - Making a Case in FreeCAD

2026-07-09 08:00:00

Since the coding part is now done, I decided to solder the Arduino and IR sensor on a bit of perfboard, and then put it in a case. I don't have a case though; but what I do have is a 3D printer, so I'm going to try my hands at designing one.

This was interesting because I've never really designed anything before. I've always printed out models from Thingiverse or Printables, or if I needed something custom I kind of crudely put something together out of basic shapes in the slicer.

Today I thought now is the time to do it right and get into actual CAD design, so I downloaded FreeCAD. And boy does this thing have a learning cure, let me tell you! This is definitely not going to be a tutorial, because I really have no idea what I was doing there. I just watched a few tutorials and then started clicking around, and in the end I think I ended up with something halfway decent, even though I'm not fully happy with it. But hey, first try.

Anyway, here's the Arduino and the IR sensor, soldered on a piece of perfboard. I decided to put the filter cap in after all as per the datasheet, because why not.

The Arduino on a board

For the case design I took inspiration from this iPod dock, which I really like with the rounded off corners. It also has an IR sensor at the front.

An iPod Dock

The board the Arduino sits on has a certain size, so that determined the size of the case, which I made 5.5cm square and about 2cm tall.

After watching some tutorials and a lot of false starts and swearing and banging my head on the desk in frustration, I finally came up with this:

The case modeled in FreeCAD

It's not perfect, but I think for a first try it isn't bad. Here's my dusty trusty 3D printer building it:

Printing the case

Have I mentioned that I find 3D printers absolutely fascinating? You start out with nothing and then half an hour later you have an object in your hands that simply didn't exist before. Mind-blowing.

So here's the case with the Arduino board inside. It's definitely not perfect, I especially don't like how the USB port is just kind of sticking out of a round hole, but making this opening the right shape for the USB port and getting the position right is beyond my CAD design abilities at this point. Next time.

The final case The final case The final case

Overall though I think it turned out quite nice and from the front it looks decent. I made it in black so you can't see the inside through the hole in the front, which you would have been able to had the case been white (the first prototype I made was white, and that was the thing that was bugging me the most). Having some IR-transparent black plastic covering the hole like it is on the iPod dock would be ideal of course, but I don't have this kind of material, so a hole will have to do.

And so with this, I'm done! I know that wasn't a very difficult project, but it still went surprisingly well. I think what took the most time was writing this all down, otherwise that would have been a one afternoon project. But it's also fun to document everything, and I enjoy the writing just as much as the actual work. Maybe I should do this more often.

So now it's only Thursday, and the OCC still runs until Sunday. What am I going to do the rest of the time?

I think I'll play some games on Windows 98 to unwind and relax.

Old Computer Challenge 2026 Day 3 - Coding Part 2

2026-07-08 08:00:00

Now that the IR receiver is working and I can receive key presses from the remote on the Arduino, it's time to think about sending them to the PC somehow.

The remote I'm planning to use is the small Apple remote that came with old Macbooks. It has five buttons for Play/Pause, Vol +, Vol -, Next Track, Previous Track and Menu.

The Apple Remote

The keyboard library

For sending key presses from the Arduino to the PC via USB I found two libraries. One is actually already built into the IDE, and an example for how to have the Arduino act as a keyboard and send keycodes to the PC can be found in the IDE under File -> Examples -> USB -> Keyboard -> KeyboardReprogram.

This library allows sending pretty much all keys that can be found on a regular keyboard, but it can't send multimedia keys like volume up/down, play/pause and so on. For that there's an extended library called HID-Project which includes the multimedia keys and a ton of others, too.

I'm attempting to control the Kodi media centre software with my remote, and there the keyboard navigation is done via the arrow keys, Enter to select and Backspace to return to previous screen. Since I only have one set of keys on the remote, I think that's how I'm going to assign them for now. The keys on the outer ring will be Up/Down/Left/Right, the centre button will be Enter and Menu will be Backspace, so I can use the remote to navigate the interface. It would be nice to have the multimedia functions too, so maybe in the future I'll implement a mode switch by long pressing the menu key or something.

Putting it together

I decided to start from a slightly smaller example for the IR library called SimpleReceiver, and then add the correct codes for my particular remote and the keyboard commands it should send to that.

To get the keyboard functionality working, all I had to do was to include the header keyboard.h at the beginning of the file with

#include <keyboard.h>

and then add

Keyboard.begin();

to the setup function.

The loop() function contains this snippet of code

if (IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT) {
	Serial.println(F("Repeat received. Here you can repeat the same action as before."));
} else {
	if (IrReceiver.decodedIRData.command == 0x10) {
		Serial.println(F("Received command 0x10."));
		// do something
	} else if (IrReceiver.decodedIRData.command == 0x11) {
		Serial.println(F("Received command 0x11."));
		// do something else
	}
}

where i could add the logic to send the correct keyboard commands to the PC once I received a key press from the IR sensor.

Sending keyboard codes is done with

Keyboard.write(KEY_UP_ARROW);

and the defines for alle the keys can be found in the header file keyboard.h. (Btw, in the IDE you can hold the control key and then click on function names, header files, variables etc. and it will take you to the relevant file or definition.)

After a bit of fiddling and refactoring I got it to work and I ended up with this sketch; most of the functionality I implemented is near the bottom:

Full Arduino sketch
/*
 * SimpleReceiver.cpp
 *
 * Demonstrates receiving ONLY NEC protocol IR codes with IRremote
 * If no protocol is defined, all protocols (except Bang&Olufsen) are active.
 *
 *  This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
 *
 ************************************************************************************
 * MIT License
 *
 * Copyright (c) 2020-2025 Armin Joachimsmeyer
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is furnished
 * to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 ************************************************************************************
 */

#include <Arduino.h>
#include <Keyboard.h>

/*
 * Specify which protocol(s) should be used for decoding.
 * If no protocol is defined, all protocols (except BEO / Bang&Olufsen) are active.
 * This must be done before the #include <IRremote.hpp>
 * In alphabetic order
 */
//#define DECODE_DENON        // Includes Sharp - requires around 250 bytes of program memory on ATmega328
//#define DECODE_JVC          // ~ 200 bytes
//#define DECODE_KASEIKYO     // Includes Panasonic ~ 300 bytes
//#define DECODE_LG           // ~ 400 bytes
#define DECODE_NEC          // Includes Apple and Onkyo ~ 250 bytes
//#define DECODE_SAMSUNG      // ~ 300 bytes
//#define DECODE_SONY         // ~ 175 bytes
//#define DECODE_RC5          // RC5 + MARANTZ: ~ 425 bytes
//#define DECODE_RC6          // ~ 375 bytes

// Universal protocol decoder
//#define DECODE_DISTANCE_WIDTH // Universal decoder for pulse distance width protocols ~ 2275 bytes
//#define DECODE_HASH         // special decoder for all protocols ~ 250 bytes

// Exotic protocol decoder
//#define DECODE_BOSEWAVE     // ~ 140 bytes
//#define DECODE_FAST         // ~ 135 bytes
//#define DECODE_LEGO_PF      // ~ 300 bytes
//#define DECODE_MAGIQUEST    // ~ 270 bytes
//#define DECODE_MARANTZ      // RC5 + MARANTZ: ~ 425 bytes
//#define DECODE_OPENLASIR    // Modified NEC with 8-bit validated address + 16-bit command. ~ 175 bytes
//#define DECODE_WHYNTER      // ~ 90 bytes

//#define DECODE_BEO          // This protocol must always be enabled manually, i.e. it is NOT enabled if no protocol is defined. It prevents decoding of SONY! ~ 430 bytes

//#define DEBUG               // Activate this for lots of lovely debug output from the decoders.

//#define RAW_BUFFER_LENGTH  750 // For air condition remotes it may require up to 750. Default is 200.

#include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc. Sets FLASHEND and RAMSIZE and evaluates value of SEND_PWM_BY_TIMER.
#include <IRremote.hpp> // include the library

// Function prototype
void receiveIrAndSendKey(uint16_t command);

/*
 * Using the function printActiveIRProtocols() requires additional 318 bytes program memory
 * Using the function printIRResultShort() requires additional 1436 bytes program memory
 * Using the function printIRSendUsage() requires additional 2568 bytes program memory
 * Because these 3 functions all share common code, using all 3 functions requires only additional 2884 bytes program memory
 */
void setup() {
    Serial.begin(115200);

    // Just to know which program is running on my Arduino
    Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE));

    // Start the receiver and if not 3. parameter specified, take LED_BUILTIN pin from the internal boards definition as default feedback LED
    IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);

    Serial.print(F("Ready to receive IR signals of protocols: "));
    printActiveIRProtocols(&Serial); // Requires additional 318 bytes program memory
    Serial.println(F("at pin " STR(IR_RECEIVE_PIN)));

    Keyboard.begin();
}

void loop() {
    /*
     * Check if received data is available and if yes, try to decode it.
     * Decoded result is in the IrReceiver.decodedIRData structure.
     *
     * E.g. command is in IrReceiver.decodedIRData.command
     * address is in command is in IrReceiver.decodedIRData.address
     * and up to 32 bit raw data in IrReceiver.decodedIRData.decodedRawData
     */
    if (IrReceiver.decode()) {
        /*
         * Print a summary of received data
         */
        if (IrReceiver.decodedIRData.protocol == UNKNOWN) {
            Serial.println(F("Received noise or an unknown (or not yet enabled) protocol"));
            // We have an unknown protocol here, print extended info
            IrReceiver.printIRResultRawFormatted(&Serial, true);

            IrReceiver.resume(); // Do it here, to preserve raw data for printing with printIRResultRawFormatted()
        } else {
            IrReceiver.resume(); // Early enable receiving of the next IR frame

            IrReceiver.printIRResultShort(&Serial);   // Requires additional 1436 bytes program memory
            IrReceiver.printIRSendUsage(&Serial);     // Calls printIRResultShort() and other functions, if protocol is UNKNOWN
        }
        Serial.println();

        /*
         * Finally, check the received data and perform actions according to the received command
         */
        if (IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT) {
            Serial.println(F("Repeat received. Here you can repeat the same action as before."));
            if (IrReceiver.decodedIRData.address == 0x34) { // Apple remote address
                receiveIrAndSendKey(IrReceiver.decodedIRData.command);
            }
        } else {
            if (IrReceiver.decodedIRData.address == 0x34) { // Apple remote address
                receiveIrAndSendKey(IrReceiver.decodedIRData.command);
            }
        }
    }
}

/* Keycodes for Apple remote:
* Address: 0x34
*
* Commands:
*     Up: 0xA
*     Down: 0xC
*     Left: 0x9
*     Right: 0x6
*     Play: 0x5
*     Menu: 0x3    
*/
void receiveIrAndSendKey(uint16_t command) {
    switch (command) {
    case 0xA: // VOL+ / UP
        Serial.println(F("Received command UP"));
        Keyboard.write(KEY_UP_ARROW);
        break;

    case 0xC: // VOL- / DOWN
        Serial.println(F("Received command DOWN"));
        Keyboard.write(KEY_DOWN_ARROW);
        break;

    case 0x9: // PREV / LEFT
        Serial.println(F("Received command LEFT"));
        Keyboard.write(KEY_LEFT_ARROW);
        break;

    case 0x6: // NEXT / RIGHT
        Serial.println(F("Received command RIGHT"));
        Keyboard.write(KEY_RIGHT_ARROW);
        break;

    case 0x5: // PLAY/PAUSE / ENTER
        Serial.println(F("Received command PLAY"));
        Keyboard.write(KEY_RETURN);
        break;

    case 0x3: // MENU / BACKSPACE
        Serial.println(F("Received command MENU"));
        Keyboard.write(KEY_BACKSPACE);
        break;

    default:
        break;
    }
}

And with that, it works!

I'm sure I will keep working on this and change or refine some things in the future, but for now the basic functionality is there, and I'm happy with that.

Next step: Build a case. That's going to be interesting, because I have very little experience with 3D design. Wish me luck.