Capstone Project
Tutorial Link: https://www.youtube.com/watch?v=l3-y371RlI4&t=4s
created by youtuber: How to Mechatronics
Final Project Intro Paragraph
I decided to do a weather station. The reason why I chose this project is that I always want a mini weather station that can tell me the temperature and the humidity of my room so that I can adjust the air conditioner and decide what to wear to school everyday. It also helps me with my Fablab project since there is a display screen included in it. A successful weather station would tell me the temperature and the humidity of my room and detect the data every 20 seconds using the DHT22 sensor. It would display both of the data on the SSD1306 OLED display.
I used a video created by a youtuber: How to Mechatronics as my starting point and modified it as my own project.
Presentation of Final Product
Preparation Week: 11/18-11/22
Bill of Materials (11/18)
11/18: I spent the whole class period watching the video over and over again to make sure I did not miss any components I need.
Sole components of my project
Difference Between my project and the video
I used the same display and same DHT22 sensor as the video. However, I changed the chip from Arduino Nano to XIAO Seeed RP2040 because the volume of Arduino Nano is too large and I just wanted to make a tiny project. I also changed the case design as the wood case designed by the video was too huge and heavy. Instead, I used 3D printing to make my case. I also created my own code and my own PCB board without using the same design from the video.
Gantt Chart (11/19-11/20)
I built my Gantt Chart for my project from scratch following the video linked below:
https://www.youtubeeducation.com/watch?v=8eKk0M2zGIk
I did stick with the plan since I was changing my Gantt Chart while I was making progress. Once I deviated from my plan, I would change the following due dates accordingly. Except for my digital portfolio. I was planning on doing it from beginning. However, I was too busy focusing on the building part instead of the documentation. The process is messy so I need time after I finish my whole project to arrange the pictures and describe it.
11/19: I was making the Gantt Chart following the video my teacher provided me. He gave us a template. But I decided to actually learn how to make a Gantt chart since I believe it is useful to pain other thing in the future. I finished half of the Gantt Chart which is formatting and putting equations in it.
11/20: I was finishing up the second half of my Gantt chart following the video. Then, I started to put the to do list into the Gantt Chart. Later, I created the estimated due date for each part.
Using Wokwi to design my wiring (11/21-11/22)
11/21: I was trying to figure out how the display code work. So I started a simulation in Wokwi. I did not find RP2040 in Wokwi, so I decided to use a similar microcontroller which is esp32. I searched up the code online and find a website as a reference: https://forum.arduino.cc/t/esp32-s3-and-two-i2c-buses-with-adafruit-ssd1306-library-two-oled-128x64-displays/1290094 . There is a code foe two displays and esp32. I modified it and made it work in Wokwi.
11/22: The next day, I was doing the simulation with both DHT22 sensr and display. I did not find RP20240 in either Wokwi or Tinkercad. So I decided to use Raspberry Pi Pico instead. I tried to used the same code I tested out on my real thing to make the simulation work. However, while the code worked in real life, it did not work in the simulation. Wokwi was not able to compile the code.
Code for turning on the Display in Wokwi
// OLED
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//Define pins
#define I2C_B_SDA 17 // GPIO17
#define I2C_B_SCL 18 // GPIO18
// OLED parameters
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C // Change if required
#define ROTATION 0 // Rotates text on OLED 1=90 degrees, 2=180 degrees
// Define display object
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
Serial.begin(115200);
while (!Serial)
;
Wire.begin(I2C_B_SDA, I2C_B_SCL);
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("Display1 SSD1306 allocation failed"));
for (;;)
; // Don't proceed, loop forever
}
// Show splash screen
display.display();
delay(2000); // Pause for 2 seconds
// Display settings
display.clearDisplay();
display.setTextSize(2); // Normal 1:1 pixel scale
display.setTextColor(WHITE); // Draw white text
display.setCursor(0,0); // Start at top-left corner
display.setRotation(ROTATION); // Set screen rotation
display.print("Display 1");
display.display();
}
void loop() {
}
Week 2: 12/2-12/6
Pinout for RP2040
The pinout is help helpful when wiring. So I put a picture of the pinout of RP2040 so that I don't need to find it online everytime I need to use.
Building blinking built-in led

Video of Built-in LED Blinking
Testing My Sensor
Code for Sensor only
/* Circuits DIY
* For Complete Details Visit
* https://www.circuits-diy.com/interfacing-dht22-temperature-sensor-with-xiao-rp2040/
*/
#include "DHT.h"
#define DHTPIN 27 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22 // DHT 22
DHT dht(DHTPIN, DHTTYPE);
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup()
{
Serial.begin(115200);
Serial.println(F("DHTxx test!"));
dht.begin();
delay(2000);
}
void loop()
{
float h = dht.readHumidity();
float t = dht.readTemperature();
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t))
{
Serial.println(F("Failed to read from DHT sensor!"));
return;
}
Serial.print(F("Humidity: "));
Serial.print(h);
Serial.println("%");
Serial.print(F("Temperature: "));
Serial.print(t);
Serial.println(F("°C "));
Serial.println("");
delay(2000);
}
Wiring with Sensor Only

Video of Sensor working
12/2 : The electronic part is the most important part of the whole project. Therefore, I started from the electronic part. Since I did not know how to create the code for DHT22 sensor, I searched up online and used a code from the link below. I also used the pinout from the website and completed my wiring for the sensor. Then I imported the code into the Arduino and made sure that the libraries included in the code were installed. Then I uploaded the code into Arduino and made the data appear in the serial monitor.
Reference Link for Code: https://www.circuits-diy.com/interfacing-dht22-temperature-sensor-with-xiao-rp2040/#google_vignette
Testing Display
Code Example for Display
/**************************************************************************
This is an example for our Monochrome OLEDs based on SSD1306 drivers
Pick one up today in the adafruit shop!
------> http://www.adafruit.com/category/63_98
This example is for a 128x64 pixel display using I2C to communicate
3 pins are required to interface (two I2C and one reset).
Adafruit invests time and resources providing this open
source code, please support Adafruit and open-source
hardware by purchasing products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries,
with contributions from the open source community.
BSD license, check license.txt for more information
All text above, and the splash screen below must be
included in any redistribution.
**************************************************************************/
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library.
// On an arduino UNO: A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO: 2(SDA), 3(SCL), ...
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define NUMFLAKES 10 // Number of snowflakes in the animation example
#define LOGO_HEIGHT 16
#define LOGO_WIDTH 16
static const unsigned char PROGMEM logo_bmp[] =
{ 0b00000000, 0b11000000,
0b00000001, 0b11000000,
0b00000001, 0b11000000,
0b00000011, 0b11100000,
0b11110011, 0b11100000,
0b11111110, 0b11111000,
0b01111110, 0b11111111,
0b00110011, 0b10011111,
0b00011111, 0b11111100,
0b00001101, 0b01110000,
0b00011011, 0b10100000,
0b00111111, 0b11100000,
0b00111111, 0b11110000,
0b01111100, 0b11110000,
0b01110000, 0b01110000,
0b00000000, 0b00110000 };
void setup() {
Serial.begin(9600);
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
// Show initial display buffer contents on the screen --
// the library initializes this with an Adafruit splash screen.
display.display();
delay(2000); // Pause for 2 seconds
// Clear the buffer
display.clearDisplay();
// Draw a single pixel in white
display.drawPixel(10, 10, SSD1306_WHITE);
// Show the display buffer on the screen. You MUST call display() after
// drawing commands to make them visible on screen!
display.display();
delay(2000);
// display.display() is NOT necessary after every single drawing command,
// unless that's what you want...rather, you can batch up a bunch of
// drawing operations and then update the screen all at once by calling
// display.display(). These examples demonstrate both approaches...
testdrawline(); // Draw many lines
testdrawrect(); // Draw rectangles (outlines)
testfillrect(); // Draw rectangles (filled)
testdrawcircle(); // Draw circles (outlines)
testfillcircle(); // Draw circles (filled)
testdrawroundrect(); // Draw rounded rectangles (outlines)
testfillroundrect(); // Draw rounded rectangles (filled)
testdrawtriangle(); // Draw triangles (outlines)
testfilltriangle(); // Draw triangles (filled)
testdrawchar(); // Draw characters of the default font
testdrawstyles(); // Draw 'stylized' characters
testscrolltext(); // Draw scrolling text
testdrawbitmap(); // Draw a small bitmap image
// Invert and restore display, pausing in-between
display.invertDisplay(true);
delay(1000);
display.invertDisplay(false);
delay(1000);
testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); // Animate bitmaps
}
void loop() {
}
void testdrawline() {
int16_t i;
display.clearDisplay(); // Clear display buffer
for(i=0; i<display.width(); i+=4) {
display.drawLine(0, 0, i, display.height()-1, SSD1306_WHITE);
display.display(); // Update screen with each newly-drawn line
delay(1);
}
for(i=0; i<display.height(); i+=4) {
display.drawLine(0, 0, display.width()-1, i, SSD1306_WHITE);
display.display();
delay(1);
}
delay(250);
display.clearDisplay();
for(i=0; i<display.width(); i+=4) {
display.drawLine(0, display.height()-1, i, 0, SSD1306_WHITE);
display.display();
delay(1);
}
for(i=display.height()-1; i>=0; i-=4) {
display.drawLine(0, display.height()-1, display.width()-1, i, SSD1306_WHITE);
display.display();
delay(1);
}
delay(250);
display.clearDisplay();
for(i=display.width()-1; i>=0; i-=4) {
display.drawLine(display.width()-1, display.height()-1, i, 0, SSD1306_WHITE);
display.display();
delay(1);
}
for(i=display.height()-1; i>=0; i-=4) {
display.drawLine(display.width()-1, display.height()-1, 0, i, SSD1306_WHITE);
display.display();
delay(1);
}
delay(250);
display.clearDisplay();
for(i=0; i<display.height(); i+=4) {
display.drawLine(display.width()-1, 0, 0, i, SSD1306_WHITE);
display.display();
delay(1);
}
for(i=0; i<display.width(); i+=4) {
display.drawLine(display.width()-1, 0, i, display.height()-1, SSD1306_WHITE);
display.display();
delay(1);
}
delay(2000); // Pause for 2 seconds
}
void testdrawrect(void) {
display.clearDisplay();
for(int16_t i=0; i<display.height()/2; i+=2) {
display.drawRect(i, i, display.width()-2*i, display.height()-2*i, SSD1306_WHITE);
display.display(); // Update screen with each newly-drawn rectangle
delay(1);
}
delay(2000);
}
void testfillrect(void) {
display.clearDisplay();
for(int16_t i=0; i<display.height()/2; i+=3) {
// The INVERSE color is used so rectangles alternate white/black
display.fillRect(i, i, display.width()-i*2, display.height()-i*2, SSD1306_INVERSE);
display.display(); // Update screen with each newly-drawn rectangle
delay(1);
}
delay(2000);
}
void testdrawcircle(void) {
display.clearDisplay();
for(int16_t i=0; i<max(display.width(),display.height())/2; i+=2) {
display.drawCircle(display.width()/2, display.height()/2, i, SSD1306_WHITE);
display.display();
delay(1);
}
delay(2000);
}
void testfillcircle(void) {
display.clearDisplay();
for(int16_t i=max(display.width(),display.height())/2; i>0; i-=3) {
// The INVERSE color is used so circles alternate white/black
display.fillCircle(display.width() / 2, display.height() / 2, i, SSD1306_INVERSE);
display.display(); // Update screen with each newly-drawn circle
delay(1);
}
delay(2000);
}
void testdrawroundrect(void) {
display.clearDisplay();
for(int16_t i=0; i<display.height()/2-2; i+=2) {
display.drawRoundRect(i, i, display.width()-2*i, display.height()-2*i,
display.height()/4, SSD1306_WHITE);
display.display();
delay(1);
}
delay(2000);
}
void testfillroundrect(void) {
display.clearDisplay();
for(int16_t i=0; i<display.height()/2-2; i+=2) {
// The INVERSE color is used so round-rects alternate white/black
display.fillRoundRect(i, i, display.width()-2*i, display.height()-2*i,
display.height()/4, SSD1306_INVERSE);
display.display();
delay(1);
}
delay(2000);
}
void testdrawtriangle(void) {
display.clearDisplay();
for(int16_t i=0; i<max(display.width(),display.height())/2; i+=5) {
display.drawTriangle(
display.width()/2 , display.height()/2-i,
display.width()/2-i, display.height()/2+i,
display.width()/2+i, display.height()/2+i, SSD1306_WHITE);
display.display();
delay(1);
}
delay(2000);
}
void testfilltriangle(void) {
display.clearDisplay();
for(int16_t i=max(display.width(),display.height())/2; i>0; i-=5) {
// The INVERSE color is used so triangles alternate white/black
display.fillTriangle(
display.width()/2 , display.height()/2-i,
display.width()/2-i, display.height()/2+i,
display.width()/2+i, display.height()/2+i, SSD1306_INVERSE);
display.display();
delay(1);
}
delay(2000);
}
void testdrawchar(void) {
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.cp437(true); // Use full 256 char 'Code Page 437' font
// Not all the characters will fit on the display. This is normal.
// Library will draw what it can and the rest will be clipped.
for(int16_t i=0; i<256; i++) {
if(i == '\n') display.write(' ');
else display.write(i);
}
display.display();
delay(2000);
}
void testdrawstyles(void) {
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0,0); // Start at top-left corner
display.println(F("Hello, world!"));
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Draw 'inverse' text
display.println(3.141592);
display.setTextSize(2); // Draw 2X-scale text
display.setTextColor(SSD1306_WHITE);
display.print(F("0x")); display.println(0xDEADBEEF, HEX);
display.display();
delay(2000);
}
void testscrolltext(void) {
display.clearDisplay();
display.setTextSize(2); // Draw 2X-scale text
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 0);
display.println(F("scroll"));
display.display(); // Show initial text
delay(100);
// Scroll in various directions, pausing in-between:
display.startscrollright(0x00, 0x0F);
delay(2000);
display.stopscroll();
delay(1000);
display.startscrollleft(0x00, 0x0F);
delay(2000);
display.stopscroll();
delay(1000);
display.startscrolldiagright(0x00, 0x07);
delay(2000);
display.startscrolldiagleft(0x00, 0x07);
delay(2000);
display.stopscroll();
delay(1000);
}
void testdrawbitmap(void) {
display.clearDisplay();
display.drawBitmap(
(display.width() - LOGO_WIDTH ) / 2,
(display.height() - LOGO_HEIGHT) / 2,
logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);
display.display();
delay(1000);
}
#define XPOS 0 // Indexes into the 'icons' array in function below
#define YPOS 1
#define DELTAY 2
void testanimate(const uint8_t *bitmap, uint8_t w, uint8_t h) {
int8_t f, icons[NUMFLAKES][3];
// Initialize 'snowflake' positions
for(f=0; f< NUMFLAKES; f++) {
icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width());
icons[f][YPOS] = -LOGO_HEIGHT;
icons[f][DELTAY] = random(1, 6);
Serial.print(F("x: "));
Serial.print(icons[f][XPOS], DEC);
Serial.print(F(" y: "));
Serial.print(icons[f][YPOS], DEC);
Serial.print(F(" dy: "));
Serial.println(icons[f][DELTAY], DEC);
}
for(;;) { // Loop forever...
display.clearDisplay(); // Clear the display buffer
// Draw each snowflake:
for(f=0; f< NUMFLAKES; f++) {
display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, SSD1306_WHITE);
}
display.display(); // Show the display buffer on the screen
delay(200); // Pause for 1/10 second
// Then update coordinates of each flake...
for(f=0; f< NUMFLAKES; f++) {
icons[f][YPOS] += icons[f][DELTAY];
// If snowflake is off the bottom of the screen...
if (icons[f][YPOS] >= display.height()) {
// Reinitialize to a random position, just off the top
icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width());
icons[f][YPOS] = -LOGO_HEIGHT;
icons[f][DELTAY] = random(1, 6);
}
}
}
}

Video of Display Working
12/3: I was not sure if the display is a good one. So I decided to use an example code to test the display. I first connected each pin of the display to the correct pin of the RP2040 chip and upload the example code into the microcontroller. The result shows that the display is not broken.
Combining the Wiring
Whole wiring for both Display and DHT22 Sensor
Combining The Codes
Final Code
#include "DHT.h"
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Pin and type configuration for the DHT sensor
#define DHTPIN 27 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22 // Define DHT type (DHT22)
// DHT sensor object declaration
DHT dht(DHTPIN, DHTTYPE);
// OLED display configuration
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C // I2C address of the OLED display
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
Serial.begin(115200);
Serial.println(F("DHTxx test!"));
// Initialize the DHT sensor
dht.begin();
delay(2000);
// Initialize the OLED display
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
while (true); // Infinite loop if display initialization fails
}
// Display splash screen
display.display();
delay(2000); // Pause for 2 seconds
display.clearDisplay();
}
void loop() {
// Read temperature and humidity from DHT sensor
float temperature = dht.readTemperature(); // Temperature in Celsius
float humidity = dht.readHumidity(); // Humidity percentage
// Check if readings are valid
if (isnan(temperature) || isnan(humidity)) {
Serial.println(F("Failed to read DHT sensor!"));
display.clearDisplay();
display.setCursor(0, 0);
display.print(F("Failed to read DHT sensor!"));
display.display();
delay(2000);
return; // Retry on the next loop iteration
}
// Debug output to Serial Monitor
Serial.print(F("Temperature: "));
Serial.print(temperature);
Serial.print(F("°C "));
Serial.print(F("Humidity: "));
Serial.print(humidity);
Serial.println(F("%"));
// Display the sensor data on the OLED screen
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // White text color
display.setCursor(0, 0);
display.print(F("Temp: "));
display.print(temperature);
display.print(F(" C"));
display.setCursor(0, 16);
display.print(F("Humidity: "));
display.print(humidity);
display.print(F(" %"));
display.display();
delay(2000); // Wait 2 seconds before updating
}

Video of the whole Electronics
12/4: I combined the code together using ChatGPT. It helped me combined the code and helped me make the data collected from the sensor appear on the display.

Video of Display rotating 180 degrees
12/5: I started to think about designing my case and my PCB board. I figured out that I needed to rotate the display 180 degrees in order to make the screen face upward instead of downward. I asked ChatGPT for help again.
12/6: Building PCB Schematic using Kicad
Step 1: Creating Symbols
Go to Symbol Editor on the left column toolbar and search up the component you need to put the PCB board.
I put a DHT22 sensor, Xiao Seeed RP2040, and a 4-pin header to connect my display with my PCB Board.
Step 1.1: Import symbols to Kicad
Since there was no DHT22 sensor symbol in the symbol library for Kicad, I had to find one myself online.
I found a DHT22 sensor symbol in a website called Snap Magic.
The instructions of importing symbols into Kicad
I downloaded the file into Downloads
I went to Preference->Manage Symbol Library->Browse Library->Select the .kicad_sym file->open. The symbol was imported in Kicad.
Step 2: Connect the Components
After I found all the component, I use the wire function and connected the matching pin of one component to another to form a circuit.
Step 3: Draw the Border
I draw a box around the whole circuit as the edge to make sure I don't exceed the edge of the board.
Week3: 12/9-12/15
12/9: Creating the PCB file
I imported the schematic file to the PCB file. I started to wire between my profile. However, I always meet the problem that the wires are crossing eachother which is not allowed. Then I figured out a trick: I could actually go through where the component is gonna be after soldering. Eventually, I managed to fix the problem and created a PCB board.
Final wiring of my PCB board
Final 3D View of My PCB Board
12/10: Milling the PCB Board
Step 1: Download the drill files and imported them into Bantom. The top is the .F_Cu file. The Outline is the edge cut file. The Holes is the combined file of PTH and NPTH files.
Step 2: Add the bits you are using and chnage the settings as needed
Step 3: Put the copper board on the drilling platform using tape. Make sure it is sticked firmly to the platform.
Step 4: Press "Start" and chnage the bits when the app tells you to.

Video of milling the PCB board
Final look of my PCB board
12/11: Testing the PCB Board

After milling the board, in order to make sure the board work, I used the continuity test in order to test if there's conductivity through each pin using the multimeter. There's one place that the track was so thin that you can barely see the sopper on it. However, when I place the test on the pins, it worked. Next, I am going to solder my components on.
12/12: Soldering components onto the PCB Board
First, I decided to solder the chip first. I used solder paste to solder it. First, I put some solder paste on the board. Then, I put the chip onto the solder paste and then use the soldering iron to melt the solder paste.
The PCB board after I soldered 10k resistor, RP2040, and DHT22 sensor on.
Back side of the PCB
12/13: Troubleshooting the PCB
When I finished soldering the DHT22 sensor onto the PCB board, I found out that it did not pass the continuity test. Then I figured out that the copper was detached from the board. I tried to use solder to reconnect the PCB board and the copper. Unfortunately, it did not work. The thin copper track also came off next day I finished soldering.
12/14: Soldering using a PCB Port Board
Step 1: Put all the components onto the board to see if the circuit would work
Step 2: Strip the wire into the appropriate length and solder onto the board. Make sure the wire are connecting to the right place.
The board after I solder all of my components and wires
Back side of the board after soldering

Video of the Board working
Case Inspiration: https://www.youtube.com/watch?v=35zs2J3Prxo created by The Wrench
12/15: 3D Designing using Fusion 360 and 3D Printing
Creating the Box
Draft of my 3Ddesign
Before I started designing my case, I first drew a sketch in Notability. I measured all of the dimensions I needed for the case using a caliper. Then I took all the key factor into account, such as the thickness of box and calculated the final dimensions of my box and the cap.
Step1: Use caliper to measure the dimensions of the board and created a rectangle with the same dimension in Fusion 360 using "Create Sketch" feature.
Step 2: Extrude the rectangle and make it into a rectangular prism.
Step 3: Create a rectangle on top
Step 4: Extrude the rectangle and make the prism a box
Step 5: Create a rectangle in the front of the prism. In order to make sure the rectangle is in the middle, use construction feature to help.
Step 6: Extrude the rectangle for 2mm
Step 7: Create a rectangle on the side of the rectangle.
Step 8: Extrude the rectangle for 2mm
Step 9: Create a rectangle and use "Line" feature to separate the rectangle into congruent rectangles
Step 10: Extrude the selected rectangles
The look on the back of the box after extruding
Step 11: Add fillet to the edges of the box for 2.5mm
Final look of my box
Creating the Cap of the Box
Step1: Create a rectangle and extrude it using the dimensions measured by the caliper
Step2: Add an offset plane on the top of the rectangular prism
Step 3: Create a rectangle on the offset plane. I made the distance between the rectangle and the edge 2.1mm because I want to leave a little space between the cap and the case. It iseasier to open the cap.
Step 4: Extrude the rectangle for 5mm
Step 5: Add fillets to the edges of the cap
Final look of the cap
3D Printing
Step 1: Import the STL file into Bambu software
Step 2: Check all the settings and select the right printer and lick "Slice the plate". After checking, click "Print"

Video of 3D printing
Fron Side of the Final Product
Back side of the Final Product

Final Video of the Final Product
Problems Encountered

First Version of the Case (not working)
I printed different versions of my cases for 3 times. First time, the pace for the USB C is not matching. I thought it was because the width of the box is too small to make the board lay flat so that the USB C is in the wrong position.
I changed the width of the box and printed again and I found out it was not because of the small space of the box. It is because I calculated the position of the USB C wrong. Then I printed the third time. It was right this time.
Final Summary
This is my first time actually doing my project without any pre-designed instructions. The only thing I have is the video that I chose from the beginning of this project. Besides, there's a lot of changes I needed to change from the original video. It was a interesting challenge to me and I learned a lot of things from it.
Before, when I faced some problems or challenges, I would immediately ask my teacher for help. However, this time, the strategy did not work. Since everybody was doing a different project, we encountered different problems and it was impossible for teachers to know everything. I had to learn how to solve my problems myself. I figured out that searching up on the Internet is the best way to solve my problem when building this project.
The process of completing a big project is to plan first and then start to build the core of the project which is usually the electronic part and then troubleshoot the problems you encountered. I learned that I need to improve myself on time management. Besides, I also learned that it is better to do your documentation while you are doing your project since you are gonna remember more details at that time. This project teaches me the basics of building circuit, creating a code and how to code a display, which is very helpful for my Fablab project.