Week 3 · Embedded Programming
This week I worked with the QPAD21 board, based on the ATSAMD21E18. The process started with the kit of parts, and then moved into soldering everything together.


The hardest part was definitely the U1 ATSAMD21 chip with its tiny pins. Solder paste helped, but shorts still crept in — seriously annoying. With the patient help of the amazing TAs, I was able to clean things up and finally get the board running.
Once assembled, I tested the board with Arduino IDE. First with the flashing LED code provided in class:
#define PIN_LED 15
void setup() {
pinMode(PIN_LED, OUTPUT);
}
void loop() {
digitalWrite(PIN_LED, HIGH);
delay(500);
digitalWrite(PIN_LED, LOW);
delay(500);
}

After that, I wanted something more fun. I made a simpler version of the classic Dino game for my board. No ducking, just jumping squares as obstacles. Surprisingly addictive when it’s late at night and you only have two brain cells left.
The following codes are made up of 9 parts. Each bullet is followed by the relevant code snippet.
The following codes are made up of 9 parts. Each bullet is followed by the relevant code snippet.
-
Libraries and display.
#include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
-
Touch input. Set up one capacitive touch pad as a button.
// TODO: Touch input setup (capacitive pad as button) // configure touch sensing pin and read state
-
Game variables. playerY and vy simulate jump/fall; obsX slides obstacles; plus score.
int playerY = 0; // player vertical position int vy = 0; // vertical velocity int obsX = 128; // obstacle x position int score = 0; #define PIN_LED 15 // status LED
-
Reset and Restart. Called at the beginning and whenever player restarts after dying.
void resetGame() { playerY = /* ground */; vy = 0; obsX = 128; score = 0; }
-
Physics and input. Gravity makes you fall; touch makes you jump.
void updatePhysicsAndInput() { // if (touchPressed) vy = -JUMP; vy += GRAVITY; playerY += vy; // clamp to ground / ceiling }
-
Obstacles movement. Each time player dodges, score +1.
void updateObstacles() { obsX -= SPEED; if (obsX < -WIDTH) { obsX = 128; score++; } }
-
Collision check. If rectangles overlap, game over.
bool checkCollision() { // AABB overlap between player rect and obstacle rect return false; }
-
Drawing. Clear screen each frame; draw ground, player, obstacle, score, and Game Over.
display.clearDisplay(); display.setTextSize(2); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 15); display.println("Chill out,"); display.setCursor(0, 40); display.println("World!"); display.display();
-
Loop. Keep everything moving ~60 fps.
void loop() { // Blink LED just for fun digitalWrite(PIN_LED, !digitalRead(PIN_LED)); delay(500); updatePhysicsAndInput(); updateObstacles(); if (checkCollision()) { // handle game over } draw(); }
This game is very simple, but it can definatly become pretty addictive, here is my history record ʘ‿ʘ
