MoreRSS

site iconNicolas F. R. A. Prado

Nicolas F. R. A. Prado. Electrical Engineer from Brazil. Interested in hacker culture, embedded systems, Linux and electronics.
Please copy the RSS to your reader, or quickly subscribe to:

Inoreader Feedly Follow Feedbin Local Reader

Rss preview of Blog of Nicolas F. R. A. Prado

In search of the perfect pin necklace

2024-11-16 11:00:00

Last year, on the "Collecting pins" post, I mentioned that I usually wear my pins on a beanie, but was still looking for a good alternative for the warmer months.

After thinking more about it, I realized a necklace would be the way to go. It doesn't depend on any specific piece of clothing and it's pretty visible, not only to others but also to myself.

I started researching for pin necklaces and found a few different solutions for the pin-to-necklace converter:

The guide is great, but I don't feel rubber pin backs are safe enough. And neither the plastic nor the leather converters looked good in my opinion. But the locking pin back one seemed perfect! So I ordered one right away.

Actually, I ordered two. The reason is that some pins have two posts, side-by-side, so two pin backs would be needed to keep those pins correctly oriented on the necklace (see pictures at the end). By buying two necklaces I could transfer the converter from one of them over and have a necklace with two converters, allowing me to wear any pin in my collection.

Once the necklace arrived and I started using it, I quickly realized there was a big problem with it though: the pin kept getting turned around! That totally beats the purpose of the necklace. I concluded the problem was the chain, which needed to be switched for something stiff, like a leather cord. I settled on this braided leather necklace (the 20inch in length and 3mm in diameter variant): https://www.amazon.com/Flexible-Braided-Leather-Necklace-Pendants/dp/B095W7J7D7

Once that arrived, I took two pliers, two jump rings (since the original ones wouldn't close around this broader necklace) and used them to put the two pin back converters on the new necklace. And it worked perfectly, no more pins getting turned around! I also liked the way it looked much better, the chain was too shiny and thin for my taste.

On top of that, since the jump rings I used are much broader than the necklace, it's super easy to get the pin back converters in and out of it. That way, when I'm wearing a pin that only uses one back, I take the other out so it's not dangling and making noise.

Finally, here are the pictures of the end result:

One-post pin:

{image}/df-front.jpg{image}/df-back.jpg

Two-posts pin:

{image}/lotr-front.jpg{image}/lotr-back.jpg

Pins being worn:

{image}/df-wear.jpg{image}/lotr-wear.jpg

The only issue is that the one-post pins, like the Dwarf Fortress one above, always rest tilted to one side. I don't think there's a way to avoid that on a necklace though. In any case, that's a minor issue and I am incredibly happy with the result. I've been wearing pins everyday since!

CardOS: Now compiling without Arduino!

2024-07-31 11:00:00

In the "CardOS: Writing an OS for the Cardputer" post I shared about the OS that I'm writing for the Cardputer and that the next step was to move away from the Arduino toolchain. It took me two months but I finally did it. The end product was this commit but I'd like to go over the process to get there in this post.

I started by running the Arduino commands to build and flash with verbose output enabled and saving that output for reference. This way I could see what exactly Arduino was doing and understand the steps needed to get from a source to a binary flashed to the chip's memory.

I then got to doing the obvious needed changes to convert from Arduino to C: I renamed the single source of the project from cardOS.ino to cardOS.c, changed the setup and loop functions into a main function, and changed the compilation step in my Makefile to rather than calling Arduino, call the ESP32 C cross-compiler (xtensa-esp32s3-elf-gcc), which had been installed on my machine by Arduino and whose path I learned from Arduino's output.

Next I ran the compilation, and fixed each of the errors that were thrown by the compiler. Namely I had to add a few includes, function prototypes, change the way a couple variables were defined and pass the -fno-builtin flag to the compiler so it would allow me to define my own stdlib functions. With that, I had an ELF file and needed to figure out how to do the flashing.

From looking through Arduino's output, I learned that esptool.py was the command used to convert the ELF file into a binary, and then called again to flash the binary into the chip. Besides the application code, there were other things being flashed: a bootloader and a partition table. In order to keep things simple, I did a quick test to verify whether I could ignore them for now (that is, assume they were already flashed before): I tweaked the OS code and used the Arduino toolchain to build and flash just that and the tweak showed up on the Cardputer, so the answer was yes.

With that in mind, I updated the Makefile to call esptool.py to convert the ELF generated by the compiler and then flash it to the board. At this point I had the whole procedure to get from the source to the flashed binary on the board figured out (or so I thought), so I ran it with make upload. But it did not work, the screen on the cardputer just wouldn't turn on.

I realized assuming all the code would just work in the new setup was too optimistic and decided to simplify the test as much as possible: I changed the code in main to simply drive the GPIO1 pin high and connected an LED to that pin. But even then, the LED didn't turn on.

This is where I got stuck for a while. The issue was clearly somewhere in the application binary. My two main theories were that either the binary itself was malformed, or I was missing some initialization code, since Arduino included a bunch of extra files during compilation.

Configuring the addresses in the ELF file

Hoping the issue was in the binary itself, since identifying missing initialization code from Arduino could take a while, I started investigating it.

I used readelf to see the contents of both my ELF and the one generated by Arduino and compared them. The biggest change in the header was this:

Mine:

Entry point address:               0x40017d

Arduino's:

Entry point address:               0x40376778

Arduino's ELF had much more code in it, so I expected its address to be higher, but this was too much of a difference. It looked like some base address was intentionally set to something different.

I looked up the meaning of the "Entry point address" in an ELF and confirmed that this is the address where execution starts from. So getting it wrong could definitely make my code not work at all.

Looking further through the ELF's content:

Mine:

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x00400000 0x00400000 0x0183c 0x0183c R E 0x1000
  LOAD           0x00183c 0x0040283c 0x0040283c 0x001a1 0x0075c RW  0x1000

 Section to Segment mapping:
  Segment Sections...
   00     .text .rodata .eh_frame
   01     .ctors .dtors .data .bss

Arduino's:

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x001020 0x3c000020 0x3c000020 0x2a678 0x2a678 RW  0x1000
  LOAD           0x02c000 0x3fc88000 0x3fc88000 0x0c018 0x0d8a8 RW  0x1000
  LOAD           0x039000 0x40374000 0x40374000 0x0ca97 0x0ca98 RWE 0x1000
  LOAD           0x046020 0x42000020 0x42000020 0x1f347 0x1f347 R E 0x1000
  LOAD           0x000000 0x50000000 0x50000000 0x00000 0x00010 RW  0x1000

 Section to Segment mapping:
  Segment Sections...
   00     .flash_rodata_dummy .flash.appdesc .flash.rodata
   01     .dram0.dummy .dram0.data .dram0.bss
   02     .iram0.vectors .iram0.text .iram0.data
   03     .flash.text
   04     .rtc_noinit

After reading up online about ELF program headers and sections this started making sense.

Looking at the program headers on the Arduino ELF, there is indeed an address very close to the entry point address: 0x40374000 on segment 2. That is the base address I was suspecting. The code that starts executing then must be in the iram0.text section, since sections with text in the name represent code, and that one is mapped to segment 2. The questions that come to mind are:

  • Why is this address used?
  • How do I set this address in my ELF file?

To answer the first question, I went looking in the ESP32-S3 manual. Figure 4-1 shows a diagram with how each memory range is mapped. The starting address of the segment used for the entry point code in Arduino, 0x40374000, is inside the range 0x40370000 - 0x403dffff which is shown as mapped to SRAM through an instruction bus which totally makes sense!

But reading on, Table 4-1 further breaks down the memory regions and names the region containing 0x40374000 as "Internal SRAM0". In its description, it is mentioned the first 16KB of the space can be reserved as a cache for instructions stored in the flash memory. If we do the math, that means the usable instruction memory starts at... 0x40374000, exactly the address that was used for the code segment in Arduino's ELF! So that explains where this address came from.

To sum up, the problem I uncovered is that the ELF file I was generating had the code assigned to addresses that do not map to a memory region that can be accessed by the ESP32's processor to fetch instructions (ie accessible through an instruction bus) and therefore it couldn't be executed.

What was left was to answer the second question: How do I set the right address in my ELF file?

This was a big gap in my knowledge, I had no idea. But looking through Arduino's output, I saw that the compiler was being passed some .ld files through a -T parameter. Inside one of them called memory.ld I found addresses being defined! The -T flag entry in the compiler's manual page revealed these files were linker scripts, so I knew what I needed to learn about next.

I found this wonderful blog post about linker scripts that taught me everything I needed to know. With that information I was able to write my linker script to assign the right addresses to each ELF section: Not only for the code (.text), but also for the zero-initialized variables (.bss) and other variables (.data), whose addresses I figured out similarly by referencing the manual and the Arduino ELF. A few additional sections also had to be assigned to get rid of linker errors.

As you might have noticed from the ELF contents, Arduino has two code sections, iram0.text and flash.text, while I only have one, .text. For that reason, I decided to assign my .text section to flash since it has much more space. However, there was still no sign of life from the cardputer. Since I noticed that my code was small enough to fit entirely inside the SRAM, and Arduino's code started from SRAM, I decided to try that, and it worked!!

{image}/led.jpg

The ESP-IDF's application startup flow documentation describes what the second-stage bootloader (which is the one I'm relying on from Arduino) does and does not, and it mentions that it is the application's duty to finish setting up the flash MMU. That is probably why using the flash address for the code didn't work and why Arduino splits the code between an SRAM and a flash part. So at some point I will need to set up access to flash, but for now SRAM was enough.

Initialization code

Now that I had at least an LED turning on, I changed the code back to full operation, that is, initializing the display, rendering the shell and reading the keyboard.

The screen started getting cleared as usual but stopped midway. I removed the screen clearing routine temporarily and the shell prompt was written to the screen. I could type in, but after a short interval my position would go back to the intial one. I realized that the Cardputer was getting reset after a precise interval.

I remembered from the application startup flow documentation that the bootloader enabled the watchdog. And since now the application code was fully provided by me, I had to take care of it myself: either keep feeding the watchdog or disable it.

I chose to disable the watchdog for simplicity (as always), and after referencing the watchdog section in the ESP32-S3 manual and adding a few register writes to the code, it was done: the system no longer crashed. This allowed the shell to stay on screen but it was garbled:

{image}/bss.jpg

Again, remembering from the application startup flow page, the application code (me!) was responsible for initializing the .bss section to zero. Since the .bss section contains the zero-initialized variables, if I don't initialize it, those variables will contain trash, which is what I was seeing here.

I didn't know how to do this the proper way, but I could definitely do it the dirty way, that is, manually listing all global variables in a function and zeroing them out πŸ™ˆ. Which I did and it worked! (Note: I have figured out how to do it properly since and I did it in this commit)

Finally I had a working OS without needing Arduino to build! And that's the full story behind the "Move from Arduino to generic C build flow" commit.

There was still one difference from before the move though, it was much slower. That's because, for the last time referring back to the application startup flow page, the application is supposed to set the CPU clock frequency to the desired value. The default frequency is quite slow, but the startup code implicitly embedded by Arduino would set it to a higher value. I fixed that in a follow up commit.

Further improvements

With the move away from Arduino done, I was finally able to work on some much needed improvements.

The first thing I did was to split the monolithic source file into several different files in this commit. I was really looking forward to this and it felt great to finally do it 😌. Now the code is much more organized, it's easier to find things and to focus on a single component.

I also enabled all the main compiler warnings in this commit, including warning about implicit fallthrough in case switches, which would have saved me some minutes investigating a bug early in this project.

Conclusion

This was another great step for the project. I had a lot of fun and learned so much from it.

The next big thing to tackle is implementing SDcard read and write, and a file system. It will likely be a while before I get that done and come back with an update on the blog. Feel free to check the repository for the latest updates in the meantime if you're curious!

CardOS: Writing an OS for the Cardputer

2024-05-25 11:00:00

I recently got the M5Stack's Cardputer. I was motivated to get it because I knew other people personally that had it too, so we would be able to share our progress, but I was worried it might end up being just another board that sits in my closet forever untouched. Still I decided to give it a shot.

Once I got it in my hands, it really won me. It has all that's required to be a computer: full keyboard for input, display for output, battery for portability, microSD card slot for persistent storage, plus WiFi and Bluetooth for connectivity. The fact that it's a very limited computer, and that it's so tiny, only makes it more charming to me.

I am really interested in the idea of implementing a full system from scratch in order to understand all the different layers and interactions. I've also always wanted to make my own operating system (OS). So before I knew it, I had set on a goal: I was going to make an OS from scratch for the Cardputer.

Now, when I say from scratch, I don't mean necessarily starting from an empty file, just that eventually all the code should have been written by me. One thing I remember from Andreas Kling's (creator of SerenityOS) videos is that he didn't start writing his OS from the bootloader, but from the user interface, and that allowed him to see his changes take effect right away and work in small steps towards the full OS. I also remember Tarn Adams (co-creator of Dwarf Fortress) giving the same tip about how to keep motivation when developing a game. And both of those are people I dearly admire, so I took their advice.

So with that in mind, I started my project from one of the Cardputer's demo code which already had a working display and keyboard, and I wrote a basic shell on top of that.

Only after that did I start implementing my own keyboard and display support from scratch and removing the code from the demo.

Getting the display to work

Implementing display support was much trickier than I expected and got me stuck for a while. By then I had already implemented my own keyboard support, tested it and it worked. But I couldn't even get the display to light up, even after carefully reading its datasheet many times and implementing the whole initialization procedure.

Eventually I took a step back and tested more basic functionality and realized I did not have output GPIOs figured out. This was really surprising as it was needed for the keyboard, which I had already tested. But what I hadn't realized was that even though my code was able to toggle output pins to scan the keyboard, it was implicitly relying on the demo's initialization code to have working pin output, which is why when I replaced all that code with my own display implementation neither the display nor the keyboard worked.

But as often times is the case for unexplainable behaviors, that wasn't the only issue. As it turns out, the ESP32 manual also showed the wrong address for one of the registers needed to configure the GPIOs. Luckily it also showed the right address in a different place, so I eventually noticed it.

So after I implemented support for enabling the output GPIOs, and corrected the register address, I was able to fix the keyboard support to be completely self-contained, and was finally, after a lot of sweat, able to implement display support and remove the dependency from the external library.

This has been the biggest achievement on the project so far, and I'm really proud of it!

Current status

This is where the project is right now:

{image}/cardos_demo.mp4

In other words, keyboard and display support are there without relying on third party libraries. The display communication is quite slow, so there's a lot of room for future improvement πŸ™‚. There's a shell with just a couple commands, including help to show the commands, clear to clear the screen, read to read an arbitrary memory address and led to turn the built-in RGB LED to the desired color. It's possible to cycle through the shell's history to repeat a previous command. And once the terminal fills the screen it automatically clears it.

I've also spent some time fixing bugs. At this point it felt like the OS was finally in a usable state, so I've tagged it v0.1.

Next steps

The next thing I'm working on is to move away from the Arduino toolchain. The main reason is that there's some code that gets implicitly added to the binary when using it, and I want to keep removing dependencies from my code.

Besides that, Arduino basically enforces the usage of a single source file. The cardOS source is currently a single file that is 1900 lines long (with almost 600 being the struct for the font characters) and I'm starting to get lost in it, so it's time to split the code to multiple files.

Finally, Arduino uses C++, and since I'm coding in C, moving away would allow me to use a C compiler instead, which will improve the error messages.

After that I'm going to keep making cardOS more of an actual OS. I want it to feel like a real hackable computer, so what I'm aiming at is to be able to open a text editor, edit a shell initialization file, save, reboot and see the effects of that change. That already gives me enough work: I need to make a text editor, a shell script language, and implement SDcard reader and filesystem support.

Further in the future I'm really curious about implementing support for the WiFi and maybe be able to send and receive IRC messages, if that's feasible. I'm sure it'll be hard, but should be fun too πŸ˜ƒ.

And that's what this is all about: fun! It's been two months since I started the project, and I can confidently say this is the project I've had the most fun ever. So as long as it stays fun I'll keep going with it. There's no rush to get anything done, I'm just enjoying the ride πŸ™‚.

vCard + RSS as an alternative to social media

2024-03-22 11:00:00

Last year after talking for a while with someone during a conference they asked me for my LinkedIn to be able to connect with me, to which I answered I didn't have one.

It was many years ago when I decided to leave social media. I don't miss it. Instant messaging allows me to keep in touch with the people that really matter to me in a much more personal way.

Still, this interaction stayed in the back of my mind. It would indeed be nice to keep track of these connections too. The people you had an interesting conversation with for just a few minutes. To be able to check how they're doing every now and then, who they're working for and what they're hacking on.

Essentially I would like for everyone to have an online profile and feed, which I could easily check and subscribe to, and that this subscription data could be stored locally. Why should that be exclusive to social media?

It's not. In fact, the feed part has already been solved for quite a long time with RSS/Atom. So by just having the URL for someone's RSS/Atom feed, you can add it to your feed reader and easily follow the person's updates wherever they're published to.

The profile part, a place with the key points about a person's current status (name, photo, location, employer, etc), is the one that has historically been tied to social media. Personal websites do many times have an "about" page with such information, but I find the lack of structure makes it way less useful than a social media's profile.

However, there's actually a widely used open standard for encoding profiles as well: vCard. It's mainly known as the format used on email clients to store contacts, where they're even synchronized between server and clients using the CardDAV protocol. But vCards are also used for contacts in your phone: it's possible to import and export contacts on iOS and Android using vCards.

So that's when I realized, if there's a widely used open standard for feeds, and another for profiles, why not join the two? By embedding an RSS/Atom feed URL in a vCard, it becomes a single file that has all the information needed to identify a person and follow their updates. Since it's a single file, it's easy to share it with others as well as store the vCards for all your connections locally.

Now one interesting bit is that though the profile information on the vCard might get outdated, there is actually a SOURCE property which is meant to contain the URL where the latest version of the vCard can be retrieved. So by hosting your vCard in a public URL, say your personal website, it's possible for people that have already downloaded it to keep it up to date.

As for how the feed URL can be encoded in the vCard, after skimming over the latest version of the spec, I originally intended to have it as a plain URL property. But I wanted the main URL in the vCard to still be the person's website, so some mechanism would be needed to differentiate between the two URLs. At first I thought of using a MEDIATYPE parameter in the URL, but the spec explicitly said that for protocols such as HTTP the Content-type HTML header should be used instead. However, as it seems, despite RSS/Atom feeds having standardized media types (application/rss+xml and application/atom+xml respectively), in practice, text/xml is used instead. In the end, this means that in order to tell that an URL in the vCard is for an RSS/Atom feed, the URL would need to be fetched and read. To avoid that complication, I decided, reluctantly, to use a non-standard property instead, X-FEED, for the feed.

Trying it out

In order to try the idea out, I created this repository with a couple simple scripts. First there's a vcard-render script that parses vCards and renders them using a provided jinja template. The idea is that you can use it to render your vCard and your connections' vCards in your website for example, which is exactly what I use it for in this page I've added to the website (it can be found from the About page). If you're curious as to how I integrated the script into my website, see this commit.

The other script is vcard-to-opml which extracts the RSS feed from the vCards supplied and generates an OPML file with them, which can then be imported into a feed reader. The idea here is to run this script on the vCards of all the people you have downloaded (your connections) so you can easily follow their feeds. I use newsboat as my feed reader, so I would add the following command to a crontab to run it periodically (as soon as I get some real connections!):

newsboat -i <(awk 1 ~/ark/etc/dav/contacts/5DEB-65D21680-2F1-4AEA3480/* | ./vcard-to-opml.py)

Note: awk is used here instead of a simple cat because apparently those vCards don't have a newline at the end of the file. I'm not sure if it's my email provider's fault, where I store my vCards, or vdirsyncer's fault, which is the program I use to have a local copy of my vCards.

Conclusion

If you're interested in trying out using vCards and RSS to connect to people as well, check out the repository that contains those scripts. And feel free to reach out if you do so, you can find my email on... you guessed it, my vCard πŸ˜‰.

Even if no one ever uses this, at least I now have a proper answer for the next person that asks for my LinkedIn. "Just scan this QR code and you'll see my profile" πŸ™‚.

{image}/qrcode.png

Collecting pins

2023-11-23 11:00:00

It started innocently about one year ago as I was looking for a gift for a friend. We played a lot of League of Legends and Ragnarok Online back in the day, so I wanted to give him something to remember that. Eventually I came across these pins:

They were exactly what I was looking for so I bought them. That was going to be it, but I am still personally a huge fan of Ragnarok Online, and those pins were so cute that I thought, I should buy them for me too!

But after that I couldn't stop looking for more pins. I was hooked! I kept browsing Etsy, searching for pins from games I like, and favoriting them so I could find them later.

I also started looking for pins at every merchandise store I came by, which I'd never given much attention previously. I now actually had something of interest to buy! So after a few weeks I got a small collection:

{image}/pins-before-pax.jpg

Around that time I was thinking about attending PAX east. When I found out the event attracted a big community of pin collectors and hosted pin trading events, from this video, I knew I had to go.

In order to be able to conveniently bring my pins to PAX, and to bring back the ones I would get there, I bought a PinFolio Classic.

On my first day at PAX I didn't hold back and bought every nice pin I saw:

{image}/pins-bought-1st-day-pax.jpg

After lucking out and winning two golden cassette pins in a row from a carnival wheel that was setup there, I went to the pin trading room to trade some pins and meet new people. It was fun to recognize some of the same people that showed up on the video.

With PAX over, this was my collection:

{image}/pinfolio-after-pax.jpg

(the Deviruchi pin is missing since it was pinned to my beanie)

Now, many months later I have finally filled up a display case with my collection. Note that I have some more pins, but I plan to use those for trading in future events, so they're stored in the pinfolio. So without further ado, here is my collection, labeled:

{image}/pins-full-labeled.jpg
  1. Poring. From Ragnarok Online. Fan-made (Teaberryhouse). The one that started it all! Link
  2. Poporing. See 1.
  3. /gg Emote. Came with 4.
  4. Deviruchi. From Ragnarok Online. Fan-made (FinniChang). Bought together with 1 and 2. Link
  5. Eevee. From Pokemon. Fan-made (Jackalandhare). I was buying two pins for a friend that loves Pokemon and the third was cheaper, so I got one for myself as well. Link
  6. Fairy bottle. From Zelda. Fan-made (FinniChang). Link
  7. Van Gogh's The Starry Night. Got it while visiting the Museum of Modern Art in NYC, where they keep the real painting.
  8. Prince & Katamari. From Katamari Damacy. I played Katamari Damacy Reroll last year and thought it was really cool! And who can resist a spinning pin? Bought at the Fangamer stand at PAX. Link
  9. King. See 8. Link
  10. Ravenclaw. From Harry Potter. I bought it at a Harry Potter store in the London airport, where I had a connection. I don't really care about Ravenclaw, but it was the best-looking pin there.
  11. Junimos. From Stardew Valley. Bought at the Fangamer stand at PAX. Link
  12. Came with 11.
  13. Babaa (Apparently that's its name!). From Neopets. I played a lot of Neopets when I was younger, so when I saw these available at a Geekify stand at PAX, I just had to buy some.
  14. Strawberry & Chocolate Paintbrush. See 13.
  15. Wraith Paintbrush. See 13.
  16. Fight Button. From Undertale. Big Undertale fan, as will be obvious from this list, so I just went crazy. Bought at Fangamer stand at PAX. Link
  17. Mercy Button. Came with 16.
  18. Annoying dog. See 16. Link
  19. Wonderville Arcade machine. Bought while visiting Wonderville with a friend, which is really a unique and awesome place!
  20. Psychokinetic Raz. From Psychonauts 2. I haven't played the game yet, just the first one, but I had just finished watching the PsychOdyssey documentary and was blown away so I had to buy something to remember it. Bought at Fangamer stand at PAX. Link
  21. Phantom of the Opera. Bought it on the way out after watching the play on Broadway. It was great!
  22. Canada Wilderness. Gifted from a friend. He bought it during our trip to Toronto (at the store on the base of the tower, I believe)
  23. Loto. Gifted from a friend. It's an old one got from the second hand market, unlike all the others in this collection. I love how it has actual numbers for each tiny square.
  24. Frisk. From Undertale. Bought at Fangamer stand at PAX. Link
  25. Toriel. Came with 24.
  26. Sans. Came with 24.
  27. Flowey. Came with 24.
  28. Papyrus. See 24. Link
  29. Undyne. Came with 28.
  30. Alphys. Came with 28.
  31. Mettaton. Came with 28.
  32. Mask. From Mr Robot. Bought it second-hand online. It's from a 2016 Loot Crate. I really wish it was smaller.
  33. Software Freedom Conservancy's Logo. Gifted from a friend.
  34. L's Logo. From Death Note. Bought at a geek store in Antwerp.
  35. Dwarf. From Dwarf Fortress. One of the reasons I went to PAX was to meet the creators of the game in person (and I did!). Shortly after a Dwarf Fortress pin was announced and I was sure to buy one online. Link
  36. PAX East VHS. Bought at PAX. People at PAX will mostly only trade Pinny Arcade pins, so I bought this as a part of a 4-pin set to kick start my collection and be able to trade at the event.
  37. East 2023 Logo. Came with 36.
  38. Diamond Ore Block. From Minecraft. Got this from trading at PAX. Minecraft was one of the most influential games in my life, so I was super happy!
  39. ATLAS and P-Body. From Portal 2. Got this from trading at PAX. I love Portal, but this is my least favorite pin out of the set, so I hope to trade it for one of others next PAX.
  40. Raz. From Psychonauts. I was given this one for free by someone at the trading room at PAX. She said she already had too many pins and since I was just starting out and liked this one, she was kind enough to give it to me πŸ™‚.
  41. ? Block. From Super Mario Bros. Bought at PAX as part of a 4-pin set to start my Pinny Arcade collection and be able to trade. Link
  42. Mario. Came with 41.
  43. Fairly OddParents. I watched tons of hours of this cartoon, so was really happy to find a pin for it. To my knowledge the only official pin. Made by Zen Monkey Studios. Link
  44. ParanaguΓ‘ train. Gifted from a friend, who took that train. I really need to go there one day wearing this pin πŸ˜ƒ.
  45. Kerbal Space Program. Gifted from the same person as 40.
  46. Green Flame. From Acquisitions Inc. It's a tabletop RPG campaign played live during PAX. I watched it during PAX and got this pin to remember the moment. Link
  47. Mae. From Night in the Woods. I bought it at PAX before even playing the game. I just really loved the style. Possibly my favorite pin.
  48. Los Andes. Gifted from a friend who visited that place, and he's really into rock climbing so it's very fitting.
  49. Goose. From Kickstarter. During PAX the Kickstarter folks had geese scattered across the stands of each project funded by kickstarter. If you found all of them you would get a pin. It was incredibly hard but I did it.
  50. PAX Gold Mixtape. During PAX there was a carnival wheel that you could pay Pinny Arcade pins to spin and get one of the mixtape pins. I was extremely lucky and managed to get two of the golden ones. I traded one and kept this one.
  51. Portuguese tile. Bought during a trip to Portugal.
  52. Collabora's logo. Got it during the company meetup. Unfortunately it's magnetic, so I'm too scared to wear it on the streets and lose it.
  53. Ecuador. Gifted from a friend who visited that place, the same rock climber as 48, see a pattern? 😝

So far I've been keeping my pins in a display case on a side table. I've thought about having them on a board on the wall to make them more visible but I'm worried they might get damaged over time being constantly exposed like that.

However I don't like to just leave my pins locked up in a case either, since that seems like a waste, so I wear them. I've found what works best for me is to wear them on a beanie. (See first photo) As a result I can't wear them during Summer (I'm still looking for an alternative here). I always keep it to a single pin, since more than that looks too noisy to me, and switch it quite frequently and when possible to match the occasion.

Now that this display case is full I'll need to buy a new one (or maybe I'll try a board this time). I'll probably make another post when that one gets full too, though that might take a while. I do have many pins on my wishlist, but I'm trying not to go too crazy with it. It's about the quality not the quantity after all, and I don't want it to get to a point where I can't appreciate every single one.