Hit My Tax with Assembly

Wow, Assembly is hard! I’ve been following that tutorial I mentioned a while back, and I’ve gotten to the point where I can’t follow along anymore. In lesson 6 about timer interrupts there’s quite a jump to new programming concepts and program structure, without much more guidance. So far, I’ve been able to follow along quite well, and though I wouldn’t be able to easily program something in Assembly just yet, I at least felt comfortable enough to read and understand an Assembly program. At this point, though, it’s becoming quite tricky to follow.

Part of the difficulty, I think, is that it’s clear that the website is originally written in German, and while I’m able to follow the text (fortunately, knowing some German helps me follow the sentence structure), the English translation can be a little rough. It’s terse and clipped prose, packed with information. The tutorial is also written more as a demonstration than a lesson plan. Educationally speaking, I would have put in exercises inbetween or some small challenges at the end of lessons with proposed answers at the back. At least something to provide a little more structure to the whole.

The other part, though, is the massive jump from lesson 5 to 6. The earlier lessons all involved a single pin goal (blinking or dimming it) with only a few registers. In lesson 6, though, suddenly we’re setting multiple registers, running two processes in parallel, on top of learning timer interrupts and the way it completely changes the program structure. Simply said, I’m lost!

I already knew that I wouldn’t end up actually programming much in Assembly – seeing how easy Arduino programming is predisposes me to trying C – but I figured to at least learn the basics so I can understand better what’s happening in C. At this point, the cost of investing time into learning this doesn’t really outweigh the benefit of understanding the workings. I figure that, at least for now, I understand more than I did before, and must rather work on the next project.

My First Makefile

Following that AVR Assembly tutorial I’ve been mentioning recently, I’m finding myself compiling and flashing programs to the ATtiny13 quite frequently. So, after doing that twice, I was done with repeating those steps over and over, when I could just automate that part. My first instinct was to use a simple Shell script to put the commands in, but Linux wouldn’t be Linux if somebody hadn’t already run into and solved that very same issue. So, today I learned about Makefiles.

The way I understand it, make is a program designed help in compiling – it checks whether any source files have changed and, if so, compiles them again. In programs of the size I’m writing, that’s really a negligible advantage, but I can see with larger programs that more than a second to compile having to wait over and over can get tiring quickly. The more interesting part for me is that I can use it to immediately say “flash this to the ATtiny13!” and the makefile will take care of the configuration of the commands to compile and send it. Right now, I have the following file, which I’m sure will expand as I learn about makefiles and how they work:

PROGRAMMER = usbtiny
INCPATH = /home/nextcloud/lib/avra
SRCFILE = 5_fast_pwm.asm

        avra -l $(SRCFILE).lst -I $(INCPATH) $(SRCFILE) -o $(SRCFILE).hex

flash: $(SRCFILE).hex
        avrdude -v -p $(MICROCONTROLLER) -c $(PROGRAMMER) -U flash:w:$(SRCFILE).hex:i

        rm -f $(SRCFILE).hex $(SRCFILE).obj $(SRCFILE).eep.hex $(SRCFILE).asm.lst

Right now, the filenames it creates are a little ugly (“5_fast_pwm.asm.hex”, for instance), so I’m sure I’ll learn how to deal with that better in time. One of my favorite features is the clean command, though. This way of doing it ends up with me having a lot of cluttering files in there, and having one command in the same set to clean it is great.

AVRDUDE Permissions for USB Programmer on Arch Linux

Thanks to a very helpful blog post, I managed to resolve the permissions issue for my USBtiny ISP programmer. As I mentioned in my previous post, I had a permissions error when using it with AVRDUDE, and I wasn’t sure where or how to resolve the issue. As it turns out, there’s a standard config folder where I could just edit a simple file that resolves everything.

Firstly, I needed to see what the vendor and product ID’s of the USB device where. That’s easy to get in Linux with the following command:

[paulo@deku ~]$ lsusb
. . .
Bus 002 Device 004: ID 1781:0c9f Multiple Vendors USBtiny
. . . 

That ID lists the vendor:product IDs. Once you have those, browse on over to /etc/udev/rules.d to make a file called 99-usbtiny.rules, and enter the following:

# Set Group for USBtiny
SUBSYSTEM=="usb", ATTRS{idVendor}=="1781", ATTRS{idProduct}=="0c9f", GROUP="uucp"

As long as you make sure that your user is a member of the group uucp, then you can now use the programmer without a hitch. As the original blog post lists, I have to note that uucp is a group for Arch Linux, and that this will no doubt be different for other distros. Either way, I’m happy to have another issue resolves, and another lesson learned.

Assemly Programming on Linux

As I mentioned a few posts back, I’ve been interested in following a tutorial on programming microcontrollers in Assembly. There’s been some interesting challenges to overcome, but this morning I’ve finally done it and can actually start the tutorial proper. Considering how tricky it was for an average schmuck like me to do this, I figured it’d be worth a small write-up for other people wanting to try this as well.

Firstly, I noticed that the originating pool of information on Assembly programming online now has a surprisingly small number of sources. Mostly, if you’ll look into the uses of AVRDUDE to upload programming to microcontrollers, it will be about uploading C code. The same goes for the main Arch Wiki article on compiling for AVR. That makes perfect sense, of course, because it’s easier to do more with C than with Assembly for the average person; and, from what I’ve read, the speed advantages of Assembly over C for a lot of these purposes are negligable. Apparently, AVR microchips are already optimized quite a bit for C, and the slight advantage that you may get by programming in Assembly pales in comparison to just getting a faster microchip to begin with. So, given that programming these in Assembly mostly seems to be a niche hobby (the programming equivalent of choosing off-the-grid survival rather than camping, perhaps?), there seem to be less than a dozen people online that are a solid source for programming in Assembly, and less when you want answers directly for Linux.

The issue there is that one of the main methods of doing Assembly coding and uploading seems to be Microchip Studio (formerly Atmel Studio, and often referred to as such online, still). The big issue being that this is online available for Windows. So, for Linux, you have to get a little creative. The actual programming, of course, isn’t that tough: use whatever editor or IDE you prefer; my favorite is still Vim, largely because my needs are small and this seems quite fine. The first problem is compiling your assembly, however.

As wonderful as the Arch Wiki usually is, the only relevant post I could find about Assembly is their listing of programming languages. All that tells me is that as is the compiler provided by the packages binutils, fasm, nasm, and yasm. Those, though, are general Assembly compilers. What it doesn’t mention is that there’s also a compiler available specified for the Atmel AVR microchips: avra. Furthermore, the person who wrote the tutorial I linked to at the start also coded his own assembler: gavrasm. Once you’ve written your Assembly file, compiling is ridiculously easy. For example, using gavrasm, you just type:

gavrasm -seb example_file.asm

Or for avra, it’s:

avra example_file.asm -o example_file.hex

Both will give you a hex file that you can upload to your microcontroller. A crucial difference in my case with the ATtiny13 is that gavrasm had its own definitions file for AVR microcontrollers, so didn’t need me to include those. Avra, however, doesn’t, and needed me to supply it. Fortunately, somebody has kindly provided a whole list of them over on GitHub, so I just downloaded the relevant one for me, which turned out to be “tn13def.inc”.

After compiling the .hex file, I needed to figure out how to upload it to the microcontroller via ISP. The tutorial linked above explained a good setup for an ISP header set, and the right connections to the microchip in the first lesson, but it used Microchip Studio for the uploading. So, I had to figure out the Linux alternative. AVRDUDE is that solution, but it took a little more fiddling to get working. Firstly, I needed to figure out what exactly my usb programmer was called (as there are multiple types). Using the command “lsusb” gave me the following output:

Bus 002 Device 013: ID 1781:0c9f Multiple Vendors USBtiny

So, I guessed that “usbtiny” would be the correct name. Using the information provided by Mitchel Davis in episode 5 of his YouTube playlist on Bare-Metal MCU, I ended up with the following command for AVRDUDE:

avrdude -v -p attiny13 -c usbtiny -U flash:w:2_led_on.hex:i

That calls AVRDUDE in verbose (-v) mode for more feedback, telling it we’re programming an attiny13 (-p attiny13) using a usbtiny programmer (-c usbtiny), and that we’re uploading and writing to flash memory, the hex file (-U flash:w:2_led_on.hex) and doing that immediately (:i). That looked great, except it didn’t work. Luckily, the verbose command let me know that it was a permissions issue for the USB programmer. So, sudo-ing the command made it work. Ideally, I’d like to find the correct permissions setting for my user so I wouldn’t have to use sudo for this, but I haven’t been able to find the right one yet. Neither adding uucp nor tty has helped, nor has installing usbasp-udev and avrisp-udev.

So, there’s more to learn still. Possibilities to improve the workflow, for instance, lie in using makefiles to set up some standard settings. And, of course, trying to fix those permissions errors. Either way, with the process described here, I managed to write, compile, and upload the relevant program from the tutorial linked above. So, more learning lies ahead!

Pomodoro Breadboard, Modified

As I discussed in my previous post about my pomodoro project, there were a few issues with the board as I’d soldered it. The first main issue was that the pomodoro LEDs weren’t lighting up. Well, as it turns out, there were two broken connections there. For one LED, the wire from the IC wasn’t connecting to the resistor, and for the other two, the wire to ground didn’t connect properly. A quick little resolder, and off we were.

The second main issue was that I hadn’t put in an ISP interface, because I’d messed up the first one, and didn’t have any easy pins available. However, as I considered later, what I did have was some tinned 0.6mm wire that is rather sturdy, so I figured to just solder those to the board. As you can see in the rightmost picture below, a sloppy soldering job later and the ISP is connected in green (along with a VCC and GND wire on there).

And, as you can see in the picture below, it’s up and running, now with a functioning ISP interface. That’ll be handy, because there is still that odd delay between pomodoros and pauses to sort. On top of that, I noticed that my code doesn’t actually use the third pomodoro. Normally, in a traditional pomodoro technique, you put a checkmark on some paper after each activity; once you reach four, then you take a bigger break. So, I’d set up the lights to have four “checkmarks” on. However, in my current code, it doesn’t put on the checkmark until you start the next pomodoro. That’s a sequence thing to fix as well.

The front side of a breadboard, showing the pomodoro timer with three LEDs lit up, and a prominent ISP cable at the top.
A shot of the pomodo timer in action, with the power coming via the ISP interface.

Fortunately, with the ISP interface in place, I can now quite easily reprogram the IC, and do a little bit of testing with each iteration of the program.

EDIT: well, that didn’t take long to fix at all. First of all, I programmed in my own little off-by-one problem. The reason that there was this extra minute between each state change was because I’d put it there: because I’d coded in an update to the LEDs only after an interval was elapsed, meant that the first minute was never displayed. My initial solution was to add an interval + 1 – that way, when the interval started, it started at the right number. Of course, when I was testing this, I was testing it at high speed, so I never noticed that the timing was so off. Now that I ran it at it’s proper minute interval speed, that little off-by-one second became an off-by-one minute. Fixed before you know it.

As for that binary 4 pomodoro LED that wasn’t being used? It actually is. Except I didn’t solder the right resistor to it . . . Instead of 220Ohm, there’s a 10kOhm resistor there. It’s on, it’s just very, very dim. Guess it’s time to replace that resistor!

Pomodoro Prototype Soldered

After the last failures of trying to bridige connections using a tinned wire, I spent some time browsing tutorials on soldering and point-to-point connections online. Most were not that useful, but I ended up finding one handy tutorial that showed a decent way to do wiring on the copper layer (sadly, it was hard to find and I didn’t save it, so I can’t retrace it right now). So, I went back to my perfboard and tried to solder again, resulting in the wiring you see below.

So, it’s not the cleanest of jobs, but it gets it done. Because I didn’t have any more connector pins of the right size, I couldn’t solder another ISP interface on the board; hence, there’s that odd gap in the components there. Secondly, you can notice a burn or two on the wires on the underside – I had to change soldering around a time or two, and wasn’t paying too close attention to my iron placement, resulting in a little melt right there. Lastly, in the topside picture, you may notice that the three small pomdoro lights aren’t lit up – tomorrow, I’ll have to track down the issue with my multimeter.

A last thing I noticed when testing it out is that there’s an odd bug: there’s a minute gap between every state change. So, once it runs through 25 minutes in one pomodoro, it waits a minute before it initiates the 5 minute pause. I’m sure that’s just a little bug in the software. Of course, when I was testing it, I tweaker the timer to count in seconds rather than minutes, to see all the state changes. Clearly, that also obscured the state-change bug, as it seemed a natural delay. However, now that it’s a minute long, it’s far more noticeable an error.

I’m quite pleased. Even though the soldering is sloppy, I learned so much doing it that I’m pretty sure I can do a much better job next time. Furthermore, it was quite relaxing to do all the soldering. And, lastly, I learned so much doing this, that I’m looking forward to my next project. I’m not too sure what it’ll be, but I’m sure I’ll come up with something soon enough.

Arch Linux and Regular People

Often, when I read about Arch Linux online, there is an odd sense of gatekeeping in comment threads and articles. Arch Linux is seen as a hardcore OS to use. In fact, a common post on /r/archlinux is a proud post describing how somebody spent several hours, trying multiple times to install Arch until they finally managed to make it work. Hardcore fans disparage users of Manjaro as though using Manjaro is a display of weakness. It’s gotten to the point where “btw I use Arch” has become an Internet meme. And yet, I would really recommend Arch.

It’s easy to think that Arch Linux is for programmers; many of the posters online are, or at the least work in IT or have studied Computer Science, or something similar. I am no such thing. In fact, Linux use has taught me some basic programming skills. A common point of praise for Arch is the ability to tweak the system completely to your liking. For some, that means squeezing the absolute most out of their machines: I once read a post where people almost competed to have the quickest boot-up times, arguing over miliseconds as though it was a speedskating event. For me, it’s more about knowing what’s on my laptop. I enjoy the experience of wanting to do something, then just immediately installing a program to do it, and then to go and do that thing. What’s on my laptop is what I put on there, because I wanted it to be.

Doing things this way has taught me about computers, however. Having to learn to program taught me a little about how computers work. Having to understand the Linux filesystems has taught me about the implicit choices in filesystem hierarchies. Having to learn about user and group permissions have made me consider sharing options in Windows as well. Basically, using Linux has made me think about things that I never bothered to think about, even though it’s good to have done so.

I find I reap the benefits of this at work. Now, when we have to switch to a new system, such as when we had to make full use of Office365 when the COVID-19 lockdowns hit last March, I found it easy to adjust to new systems, because I was used to analysing how they interacted. When we needed to set up new interactions between these (such as, let’s say, Microsoft Planner and Microsoft Lists), I could see some analogues to Linux systems, and I could recognize a type of WYSIWYG-interface that tried to abstract code in the background. Despite not working in an IT environment, understanding just a little more of how these systems work has helped me bridge gaps there that I couldn’t have before.

And, on top of that, using Linux is just fun. When I’m back to using Windows 10 on my day-to-day work laptop, it surprises me how clunky Windows is as a system, and how I never noticed that before I really started optimizing my workflow on Linux using i3WM. Let alone that I never bothered to think about workflow before doing that. So, even for us non-programmer, non-IT, non-computery people, I really recommend using Linux.

Point-to-Point failings and lessons

Well, I tried soldering the pomodoro timer from the underside, and, essentially, my skills were lacking – though I suspect I also tried to do something you just shouldn’t really do. You see, I was going to attempt to solder wires directly from a point on the underside to another point. The problem I run into is that I can’t really add a wire on top of a solder point like that. Have a gander at the image below to see some of what happened.

The underside of a perfboard with solder blobs for a set of components.
There are three things to note in this image: firstly, there’s a nice, direct wire running at the top; secondly, right in the middle, there’s a lot of sloppy solder on the two central rails; and, thirdy, in the bottom middle you can see a section where three copper islands have come off the board.

The first thing that went rather wrong was when I was trying to solder an ISP header on the perfboard. I’m talking about those three missing islands at the bottom center of that perfboard. I noticed, after soldering, that what I had soldered was skewed and wouldn’t hold my connector. So, I tried to bend it a little so that it would stick – big mistake there. What I ended up doing was tearing the copper islands off the perfboard, rendering that connector pretty much useless.

The second big problem is right in the middle of the photo. You can see some sloppy soldering there, and what looks to be a loose bit of metal in the middle of that solder. I was attempting to make a nice bridge between the central rail and a pin using a tin wire. However, by trying to put it on top of an already soldered pin, I ended up just trying to smush it next to it, which quickly became very messy. In part, I think my tin wire is too thick. If it were a little thinner, I could have it wrap around the pin and then solder the two together. Secondly, I tried to do this the wrong way around: I first soldered the pin, and then tried to lay out the wire. As a result, it started shifting. I think I need to solder the other end down first, and then either wrap the other end around the island awaiting the pin for the final soldering, or wrap it tightly around the soldered pin and try to melt that in.

The top part is something I’m more pleased with, despite the top right being a little messy. I should have planned this better and laid out the rail first, but either way, I decided to put a single ground rail there to connect all the LEDs to. Sloppy as it is, I think it would have made a really stable connection.

Overall, I think I need to conclude two things: firstly, in trying to make these connections work out, I ended up using far too much solder in places, causing these unsightly bumps. Secondly, I tried to be a little to flexible in this process at this point, which didn’t work out at all. What I need to do is plan out the perfboard in far more detail before starting to solder. Perhaps I’ll put it all on a much larger space. Alternatively, maybe I’ll add another dimension to it by using two bits of perfboard and a connection between them – if I screw them together it’ll be someting of an open box, as it were. That would certainly give me some more space.

Either way, this failure gives me a great opportunity to redesign and improve what I have here. I’m looking forward to making this thing work after all.

Experiments in Arch Linux

For the past couple of years, every so often I try to install Arch Linux on one of my laptops to see if I can reasonably work with it. Over time, every time I’ve installed it, I’ve made it more and more functional. Usually, I would into some practical problem that would prevent me from doing what I’d want with it, and I’d end up installing Manjaro on it to just have a working system. The first time, I got stuck on trying to get networking to work (NetworkManager or iproute2 are the answer); the next, I was stuck in the commandline interface (installing xorg-server ended up being the answer); after that, I got an Xorg server running, but couldn’t properly install a desktop environment (I ended up going to i3wm); and so on, and so on. This time, however, I’ve gotten farther than I ever have.

Ever since I fully switched my desktop over to Linux, I’ve had to solve more and more issues myself. Pretty much every time, the real issue was just my ignorance – I’d have updated something without properly reading what the consequences where, or something would break because I didn’t do a simple fix, or things along those lines. The consequence of solving these, though, is that this time around when I installed Arch Linux, I didn’t really run into many issues anymore. Or, more accurately, I encountered the same thresholds, but I’m not getting stuck on them anymore. Sure, I had no sound after the first boot, but that just made sense, because I had no drivers installed. So, a quick install later, some referencing of the Arch Wiki, and I was done.

Similarly, this time around, when I ran into features that I was lacking, I at least had some idea of what I’d want. I’ve experimented a little bit, so I know a program or two that does what I need, and I can more accurately decide which of those I want. Or, as I have been noticing now, I have obtained decent enough skills to implement a minimal fix myself. Running i3wm from a basic install meant I didn’t have my media buttons active yet. No big problem, I just needed to reference the i3wm documentation to see what the syntax was, reference my keyboard layout to see what my key names are (just to confirm it was the default), and them implement a simple volume-up and volume-down key combo. Then I noticed there was no feedback to using those. Well, install a notification daemon, use pactl to list a bunch of info that includes my current volume, grep out the volume, awk out the exact number, pass that to dunst, and done.

Implementing that made me really feel comfortable with Linux. That was a moment when I really saw a set of separate skills come together into a single solution to a simple problem that just a year ago would have me reinstall Manjaro Linux rather than work it out myself. This is the point where there’s a Souls-like enjoyment: I’ve butted my head against the problems long enough, and thanks to my perseverance, I’ve now gained enough experience to start netting a win here and there.

Now, on to solving the next little thing I want to improve in this setup . . .

Point-to-Point Pomodoro

Today I tried laying out the pomodoro timer on a small breadboard I had lying around.In the end, I could fit everything on the board, so that was good news. There are two major drawbacks to this, however: firstly, as you may notice, there’s no power laid out here yet; and, secondly, I’m going to have to solder this point-to-point.

Components of the pomodoro circuit on a breadboard
The initial layout for my pomodoro timer. At least, this seemed like a decent way to have everything on a breadboard I had lying around. It looks reasonably functional, though the downside will be that I’ll have to do a point-to-point soldering, as there’s too little room to properly place the wires on the board.

As far as power is concerned, I’m planning to use a 3.3V coin battery, which I was hoping to mount somewhere on the back. However, given how tight everything is mounted, that may not be an option. I’ll pretty much be using every little bit of real estate there. Firstly, of course, for the leads of the components, but as they’re all placed so close to each other, I’ll have to do point-to-point soldering, I’m assuming right now. That will also imply I won’t have a surface left to glue a coin battery mount to. I may have to resort to leaving that just trailing on a side.

Either way, I’m looking forward to soldering these components on soon, now that I have a basic layout going.