Week2
TLDR: The song we listened to on the first day
was stuck in my head for a painful amount of time so I made implemented Guitar Hero (“Arduino Hero”) to both free myself from my suffering as well as subject others to the same fate:
~~~~~~~ARDUINO HERO VIDEO~~~~~~~~
The big challenge for me for this week was getting all the knowledge I was sprayed with straight in my head - I’ve used microcontrollers before, but it was always like oh ok we’re using this one now do it, never here’s…every possible microcontroller known to humankind have fun choosing :)
So the first step for me was naturally trying to figure it all out - here’s what I got:
a microcontroller is basically a small computer -it has all the components for doing a number of tasks all in one place, which is what differentiates it from a microprocessor, which only has a CPU.
Microcontrollers have a number of pins, which is where output gets sent.
There’s a number of types, exploring which was the nature of the…
~GROUP ASSIGNMENT#
Ok so the most fundamental difference between the various types is the architecture, of which some of the main varieties we are dealing with are AVR8 and ARM32. Consulting some resources, I see that AVR is from the 90s and uses RISC instructions. It is the most popular and cheap. ARM tends to be more powerful, but more expensive and uses more power. Microcontrollers also have 8, 16, etc bit versions, of which the 16 bit ones are generally faster but more expensive.
On the AVR side of the spectrum, we have the ATTINY series.
For ARM32, we have SAMD, RP2040, and ESP32.
Raspberry Pi Pico RP2040#
This one seems to be the holy grail - documentation “readable by mortals”, amd is likely the one I will use. For uploading code, you can put it in “bootloader mode” by holding the BOOTSEL button where you can directly drag a u2f file into its storage. After entering bootloader mode that way once though, it seems you can simply just connect the micro USB as before and then hit upload.
Also note that the RP2040 can use MicroPython via “Thonny” which is the special IDE for this purpose.
Note: some older microcontrollers require “programmers” to get your code onto their chip. This one, such example.
There were a few others, like the SAMD and we talked about some of reasons to choose one over the other, etc.
DATASHEET BROWSING#
Since it’s most likely I will be using the Pi Pico RP2040, I decided to browse through its datasheet. I took a look at both the Pi Pico itself’s datasheet (~33 pages) and the RP2040’s datasheet (> 600 pages).
First sentence “Microcontrollers connect the world of software to the world of hardware” - that’s actually a very clear and helpful way to start an enourmous manual wow Neil was right.
It has many cool features 😮:
The chip itself looks like this, although honestly I’m too far removed from my old systems programming days to fully understand most of it:
Reading through more, we got more details on how the chip works, describing things like the bus fabric which “routes addresses and data across the chip.”. There’s also a lot of scary and confusing information on registers ahh:
Reading on to the Pi Pico’s manual, you get some highlighted features, some of which I already knew about, like the micro-usb port.
followed by the all important pinout:
The pins are all numbered, and each has at least one specialized purpose, although some are reserved for special board functionality and cannot be used by programmer.
For power, there’s a number of important pins to note: VBUS is 5V, while VSYS is the main system input voltage, and can be between 1.8V to 5.5V, and this can provide power to the board. 3.3V is the main 3.3V supply.
Finally, I spent some time learning to parse the datasheet for parts, like LEDs. The important numbers to note seem to be forward voltage and forward current. Forward voltage drop is the minimum voltage needed to power the thing, so you can calculate the resistor needed by doing: (supply voltage-forward voltage)/forward current. It seems like the Pi Pico only has three analog pins, 26,27, and 28, which is interesting to me.
ARDUINO HERO#
So my idea to create a program for a microcontroller to interact with was use a display and some buttons and LEDs to make a recreation of guitar hero.
The first order of business was to get a screen connected - I had started using the Arduino Nano and a SSD1306 OLED display, although neither ended up being a very good choice - the Nano as I learned has very little memory, and as soon as I started trying to use the screen + buttons + things like keeping track of scores I instantly ran into memory allocation errors. With that in mind, I switched to the Arduino Mega which worked much better, although the OLED display I chose only could do black and white (to my knowledge) which made my game slightly less pretty :( I got a bit stuck with nothing happening for a little because I learned later that the SCL and SDA pins on the two microcontrollers are actually different which confused me at first.
Then came the the trickier bit which was to actually program the game’s logic. Guitar Hero, as I learned, is actually a bit harder to implement than I would have expected. There’s a number of technical considerations like -how do you turn songs into guitar hero charts? -how do you keep track of each note as it descends from the sky and sync it so it arrives precisely when it sounds? -how do you the above things in ways that don’t require constantly searching for every single note everywhere, grinding your game into a standstill? And etc.
Basically, it seems that guitar hero songs are usually made by hand, which I thought was lame, so after transcribing the song above I wanted it to work automatically so I could put in any song and have a fun game come out of it. Basically, my idea was to bucket sort the entire song so that roughly lower notes are on lower strings, but do to repeated notes you often get the same note on adjacent strings, which I think is more fun to play.
Then I started with the absolute basic game setup - buttons, some squares to represent the “note hit zone” and lines for the strings:
Then I had to really think how I wanted to keep track of the notes - I spent a while writing a function to convert the song into a struct I defined that records the “hit time” of each note, as well as another that keeps track of the physical dot falling from the sky:
typedef struct Note {
int midi_note; // The integer value
double delta; // The delta time in milliseconds or microseconds
} Note;
typedef struct FallingNote {
int string_num;
double hit_time; // The delta time in when note actually occurs
double currentY; // where note currently is
} FallingNote;
Very annoyingly, there is no way to my knowledge of “redrawing” the old background when you move a circle, thus making it necessary to do a lot of silly draws of what you just undraw and the opposite to avoid your entire screen just turning white and you don’t actually move anything.
For the sound playing itself, I spent a little time playing with the simulated SD card reader which was both 1) a hassle and 2) a paid feature so I just used the “buzzer” element which gave a cute chip tune aesthetic so I didn’t really mind.
One bug I encountered was a very low frame rate and choppy movement of the dots, which was fixed by ensuring that the time values were the write datatype to handle the needed precision (so NOT integers obviously)
The last step was adding a little game over screen complete with high scores and the like for more playing. Overall, it was a tad more complicated than I thought, coming in at around ~600 ish lines when you tally the files, although I’m certain my implementation is not fully optimal.
Some things that were slightly confusing to me but the wonderful TAs explained:#
-Q: both the Xiao Seeed RP2040 and Pi Pico RP2040 both use the RP2040 chip and so name themselves after that, even though RP2040 is actually still made by Raspberry Pi? But then the manual says things like "RP2040 is the debut microcontroller from Raspberry Pi", implying that the RP2040 itself is a microcontroller?
-A: the chip IS the microcontroller - what's different is the BOARD
-Q: Why in many examples of basic LEDs like above there's no resistor, I thought it would explode without one?
A: yes, Wokwi is stupid and they have featured examples doing silly little things like that!
and as always:
NOTES FOR MYSELF/PROGENY#
-the TAs are all very wonderful and kind and I need to go to all office hours always -iterate fast, it’s ok to spend a day or two thinking about what you want to do, but nothing is a good substitute for just trying stuff -don’t read theory then try to apply it, try and apply it to gain an intuition then go back to theory to guide you