Week 2

This was a fun week - we got to solder and make a microcontroller interface with a screen.

Acknowledgements

I used ChatGPT to write the sketches.

https://chatgpt.com/share/68d0a44e-7550-8007-8cb2-84cd161344a8

Quentin, Alan and Jake helped on some of the soldering! Anthony taught us the technique at the start of class.

I have worked with Arduinos before, but I only understood them at the surface level. This class taught me the deeper details and how to build my own. I skimmed the ATmega328P chip details here: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf. Something I was curious about is how do you upload a program to the chip: so I asked ChatGPT. https://chatgpt.com/c/68d0a835-3e58-8328-ae49-5e20bb4930e5. I learned how the program goes to the flash memory of the chip.

Here is the soldering journey.

Only one more component left to go!
Anthony teaching us!

The challenges were the main chip, after using the hot air gun couple of the pins were shorted so I needed TA help to separate them. Finally since I choose the hard usb C version, I also needed some help with soldering those pins. Then Quentin helped flash the program and my board worked without having to trouble shoot anything!

Here is Conways game of life! - the code is from the ChatGPT link I attached.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define SCREEN_ADDRESS 0x3C

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

// Pack 8 cells per byte
uint8_t grid[SCREEN_HEIGHT][SCREEN_WIDTH / 8];
uint8_t nextGrid[SCREEN_HEIGHT][SCREEN_WIDTH / 8];

inline bool getCell(uint8_t g[SCREEN_HEIGHT][SCREEN_WIDTH / 8], int x, int y) {
  return (g[y][x >> 3] >> (x & 7)) & 1;
}

inline void setCell(uint8_t g[SCREEN_HEIGHT][SCREEN_WIDTH / 8], int x, int y, bool val) {
  if (val) g[y][x >> 3] |= (1 << (x & 7));
  else     g[y][x >> 3] &= ~(1 << (x & 7));
}

void randomizeGrid() {
  for (int y = 0; y < SCREEN_HEIGHT; y++) {
    for (int x = 0; x < SCREEN_WIDTH; x++) {
      setCell(grid, x, y, random(2));
    }
  }
}

int countNeighbors(int x, int y) {
  int count = 0;
  for (int dy = -1; dy <= 1; dy++) {
    for (int dx = -1; dx <= 1; dx++) {
      if (dx == 0 && dy == 0) continue;
      int nx = x + dx;
      int ny = y + dy;
      if (nx >= 0 && nx < SCREEN_WIDTH && ny >= 0 && ny < SCREEN_HEIGHT) {
        if (getCell(grid, nx, ny)) count++;
      }
    }
  }
  return count;
}

void stepAutomaton() {
  for (int y = 0; y < SCREEN_HEIGHT; y++) {
    for (int x = 0; x < SCREEN_WIDTH; x++) {
      int neighbors = countNeighbors(x, y);
      if (getCell(grid, x, y)) {
        setCell(nextGrid, x, y, (neighbors == 2 || neighbors == 3));
      } else {
        setCell(nextGrid, x, y, (neighbors == 3));
      }
    }
  }
  // swap buffers
  for (int y = 0; y < SCREEN_HEIGHT; y++) {
    for (int b = 0; b < SCREEN_WIDTH / 8; b++) {
      grid[y][b] = nextGrid[y][b];
    }
  }
}

void drawGrid() {
  display.clearDisplay();
  for (int y = 0; y < SCREEN_HEIGHT; y++) {
    for (int x = 0; x < SCREEN_WIDTH; x++) {
      if (getCell(grid, x, y)) {
        display.drawPixel(x, y, SSD1306_WHITE);
      }
    }
  }
  display.display();
}

void setup() {
  Serial.begin(115200);
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    for (;;);
  }
  display.clearDisplay();
  display.display();

  randomSeed(analogRead(0));
  randomizeGrid();
}

void loop() {
  stepAutomaton();
  drawGrid();
  delay(100);
}

My board stopped working after some time, likely due to a loose pin so I need to return to fix that.