Setbacks and new hurdles

I’d left the pomodoro project in the freezer for quite a while. Last week, I figured I’d pick up on it again, and make some time for that hobby. It’s been challenging to pick it up again, however. KiCad, apparently, has had an update, and currently does not work on my PC. However, the error message that I get does not seem to be a common enough experience to warrant many questions about it online. It might be that it’s too recent for it to become an issue (it was a few days ago); it might be that the problem is unique to my setup; or, alternatively, it might be that the problem is really so trivial that most people have just applied some solution that I do not know.

Regardless, I figured to just work directly on the programming of the new uC, as that is a thing I can experiment with on the go without needing KiCad. Everything works fine for a few iterations as I test the LEDs by blinking them all in order, and I test various waiting functions, and so on. As I was testing out interrupt states, I started getting an odd message – for some reason, Avrdude was setting new fuses. On the next flash, it mentions that fuses have changed, and asks whether I want to reset them. Naturally, I do. However, the fuse setting issue seems to repeat, and then I can’t seem to connect at all anymore.

So, I figure to test some alternatives. Can I upload something else to the chip? Can I use the USBTiny to upload something to my first prototype? Is it the connections on the breadboard, is it the USBTiny PCB itself? What’s going on? All tests fail. So, a new challenge presents itself. I need to figure out where the problem is, followed by what the problem is, and then whether or not this is something that I can fix.

I use Arch, BTW

This week was a holiday for me, fortunately. Technically, my work doesn’t offer standard holidays, except for the usual summer break in university education. However, after the merger with another local university, our new colleagues brought with them a lovely cultural shift: the assumption that the education-free weeks are holidays. So many of them take this as just a right, that our employer has basically given up and accepted this is a holiday week for educational staff. Part of that, I suspect, is the fact that 1 in 5 employees in education suffers from some sort of burn-out, according to the Dutch national statistics centre, CBS (at the top of that first graph, “Onderwijs” means “Education”). I imagine that this certain lax attitude towards the enforcement of certain policies is just considered risk management – the potential damage of formally enforcing this as not being a holiday would likely outweigh the financial benefits of having teaching staff available during this week.

So, I finally had some time and energy on my hands to do some things I’d been looking forward to for a while. One of which was to transfer my desktop PC over to Arch from Manjaro Linux. I’d originally kept my main PC on Manjaro based on the idea that I wanted a PC that just worked without much fuss, and assumed that personally maintaining Arch would cause more issues than having a more curated OS. Ironically, over time, my Manjaro-based desktop ended up having issues more often than my Arch-based laptop. Every so often, an update to Manjaro would prevent me from logging in to the X Server (an update to NVidia drivers would end up conflicting with lightdm-slick-greeter, or reset a configuration file), and I’d be left fixing that. Alternatively, I’d set things up exactly the way I wanted to on my laptop, and when I’d go back to using my desktop, I realized that it had a different setting or program that I did not prefer at all. So, with some more time on my hands, it was time for a change.

As I’d written before, I’ve installed Arch Linux a number of times over the past years, so the installation itself wasn’t that much of a problem. I was, of course, irrationally worried that I’d irreparably mess something up but that’s just usual nerves; the reality is that very little in Linux is irreparable. In fact, the process was surprisingly smooth and easy. Particularly given how Linux separates out files in its system hierarchy, it was incredibly easy to change the OS and still keep my old files and even installed games. So, now I finally fully run Arch Linux as a main driver, and I’m happily configuring and customizing when I want and as I see fit.

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:

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

$(SRCFILE).hex: $(SRCFILE)
        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

clean:
        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!

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.

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 . . .

Linux Milestone?

I feel like I’ve passed some kind of Linux milestone today. I was reading up on i3wm configurations, and the unique situation that I have where I want to share a single configuration between a desktop environment with two screens, and a laptop which may be plugged into an external screen. I’ve been meaning to further configure this situation, and make it a little more flexible. I managed to get that working in an XMonad install, since you program that in Haskell and so have some more flexibility than i3wm’s configuration gives you, but doing the same in i3wm is still a little tricky.

The key difference is that i3wm is configured via its own configuration syntax. That makes it easier to configure for somebody who isn’t familiar or comfortable with programming, so it becomes more accessible. The natural trade-off, however, is that it becomes less flexible in what it can do for the user. XMonad, however, essentially is just a framework for a window manager, and you, the user, have to code everything you want in Haskell. Great for customization, but not so good for accessibility for new users. This is also the main reason I didn’t go far in it, because I also don’t know how to program in Haskell!

In any case, in XMonad I managed to get a simple script working that scanned what my setup was—how many monitors, what resolutions, and so on—and adjusted window sizes based on that. In i3wm, however, that information is loaded up when i3wm starts, and so it’s not a thing you can easily do on the fly. So, I’m searching on DuckDuckGo to see if anybody’s solved this problem (after all, why reinvent the wheel here?). I found a post where somebody hacked together a Python 3 script to edit his configurations (sound familiar?) and I had An Opinion. Before, I tended to read and absorb, assuming that the poster would have a good idea. Now, though, I realized I had solved the problem in a way that I felt was more efficient.

To me, that’s always been a good sign of learning something: realizing that you’ve solved something; recognising a moment where you can help somebody else make things better. I’ve never considered myself a very technical person (a consequence, I believe, of knowing people who work in IT professions, and comparing myself to what they know and can do), but this was the first time I felt like an amateur versus a person just hoping not to screw up their install whenever they do something.

Linux Upskill Challenge

A week ago, I started with something called the Linux Upskill Challenge. It’s a monthly set of lessons posted by /u/snori74 (as far as I am aware, not the Icelandic poet come back to life with a passion for Linux). The set of lessons are to teach you about being the administration of a Linux server, with practical challenges. You start off by getting a server online (as suggested by /u/snori74, I chose a $5 server package), and weekday-by-weekday, there are short lessons on how commandline administration of the server.

I figure that, by now, I can call myself an average Linux user: I know enough to solve quite a few problems by myself and I know enough to search for the right solutions to my issues; however, I’m also clearly not to the level of the Linux users who will program their own widget to create an alternative to this or that program that they have an issue with. This program has really worked for me so far. I know enough to easily progress through the first couple of lessons, and yet each had really new information for me in the extensions.

I can really recommend it to anyone that wants to learn a little more about Linux.

My First Sed Script (That Became a Bash Script?)

Last post, I wrote about a Sed script I wrote to help me switch configurations. As always, I’ve learned a little in the meantime, and I’ve updated the script to reflect that. As a result, it’s not a Sed script anymore, but a Bash script that calls on Sed directly to perform tasks.

I noticed that I was not being very efficient. For one, I created three files to do something that could be done in one. For another, two of those files (the Sed scripts) were virtually identical, with only two words being changed in four instances. When saw what I had done, I was reminded of a thing I read somewhere, but sadly cannot recall where:

If you’re doing something more than once, you’re not using a computer correctly.

Anonymous?

It’s a little provocative, of course, but I like the central idea of it. A computer is meant to automate tasks, and if you, the human user, are repeatedly performing the same task, surely you should let the computer handle that? Furthermore, there’s an added risk of error: I could edit one file and forget to edit the others to match. Or, of course, were I to write a much, much larger program, copy-pasting the same code only leads to a less legible program in the end.

So, I figured to replace the repeated words with a variable, set in the Bash script, and that reduced the need for two separate Sed scripts. Now that I was down to just the one small script, I realized I could just put it directly in Bash. I would lose the Sed syntax highlighting in Vim (as it would be highlighting Bash), but to be fair the Sed highlights aren’t that great anyway. So, long story short, I ended up with the following, single script:

#!/bin/bash
# switch_config.sj -- Bash script to switch over i3wm configs
# $1 = switch argument

# Check what file to change
case $1 in
    -d|--desktop) to=Desktop
	    	  from=Laptop
		  ;;
    -l|--laptop)  to=Laptop
	    	  from=Desktop
		  ;;
    *) echo "Select either -d, --desktop, -l, or --laptop"; exit 1
	    	  ;;
esac

# Back up file, using \cp to avoid interactive alias
\cp config -f config.old

# Catch potential errors
if [ $# != 1 ]
	then echo "Error: please provide one argument."; exit 1
fi


echo "Swapping i3wm configuration over from $from to $to."

# Using sed, comment out one set, and uncomment the other
sed -i '
/# '"$from"'/,/^$/{
	/# '"$from"'/b
	/^$/b
	/^#/!s/\(.*$\)/\#\1/
}

/# '"$to"'/,/^$/{
	/# '"$to"'/!s/#//
}
' config