Final Project

Hamster Sketch







My favorite activity is sleeping. I often turn off my alarm to keep sleeping, but because of that, I sometimes arrive late to places. That is why I wanted to make an alarm for my project that would be harder for me to turn off, so I thought of an alarm that tries to escape.

My boyfriend always says I am like a hamster (small and easily scared), so I thought I would love for my project to be shaped like a hamster to make it funny.

Hamster Sketch

I think I could do the electronics with a Xiao, use molds to make the hamster shape, and laser cutting for the internal structure, as well as 3D printing. I also want to make an interface to set the alarms.

This is a bit of what I think I could do, but as I advance in the Fab path, I will clarify my ideas.

Systems integrating my project:

Plan for the next weeks:

APRIL 2026

SUN
MON
TUE
WED
THU
FRI
SAT
1
2
3
4
5
6
7
Buy material
8
Buy material
9
Buy material
10
11
12
13
14
15
Gather material
16
17
18
19
20
Test sensors
21
Test sensors
22
23
24
25
26
27
3D modeling
28
3D modeling
29
30

MY FINAL PROJECT

3D DESIGN

SOLIDWORKS

The first thing I did for my project was the shell in Blender to be able to visualize the available space I had, I made the base in SolidWorks to be able to add dimensions to my hamster, the base turned out like this:

RTC datasheet

To be able to see a little more about how to use SolidWorks you can check my WEEK02.

Where each of the parts has a function which is the following:

Then in SolidWorks I made a small sketch for the shell shape taking into account the size of the base, this is how my small sketch turned out.

Proyecto 2
Proyecto 3

As you can see it looks too square this is because I did it in SolidWorks and here it is hard to make more organic shapes, so I saved it as an STL following these steps:

  1. Files> Save As..
  2. RTC datasheet
  3. In the type menu we select STL.
  4. RTC datasheet

BLENDER

  1. We download the Blender application and open a new file and do the following: File > Import > STL
  2. RTC datasheet
  3. In the Sculpting menu we can start to modify the square shape we made in SolidWorks, we do this with the bottom tools we have underneath.
    RTC datasheet


    The result was the following:
    Proyecto 2
    Proyecto 3
  4. But I needed the figure to be hollow and of greater thickness to be able to 3D print it, so to be able to have those modifications I did the following:
    1. Press the TAB key to switch modes, where we have two EDIT MODE and OBJECT MODE, to be able to give thickness to our shell we have to go to OBJECT mode and select the entire mesh.
    2. RTC datasheet
    3. Then in the right menu on the blue wrench a modifiers menu will open.
    4. RTC datasheet
    5. Generate > Solidify
    6. RTC datasheet
    7. We change the thickness according to the one we need which to be able to print it correctly can be between 0.8 to 1.2 mm but since the units are different in Blender we can see this by observing the change that our piece has.
    8. RTC datasheet
    9. To confirm this operation on our figure we must press Ctrl + A and that's it we already have the first part of our hamster, only that we also must make the holes to put the sensors and the joints where we will put the screws to fit the base.
    10. In object mode we press Shift + A > Mesh > Cube.
    11. RTC datasheet
    12. A cube will appear in the middle of our piece and in the right menu we can modify the dimensions of the cube.
    13. RTC datasheet
    14. We position where we are going to want the holes for the sensors and again we go to the blue wrench > Add Modifier > Generate > Boolean.
    15. RTC datasheet
    16. We select Difference in Operand Type our main figure is selected and then with the eyedropper we select the cube we made to make the hole, this cube has to go through the whole figure and to confirm the operation Ctrl + A.
    17. RTC datasheet
    18. Then we delete the cube and that is how my piece turned out with the holes for the three sensors.
    19. RTC datasheet
    20. The only step we are missing is to put the screw joints where we do the following: Shift + A > Mesh > Cylinder. In the dimensions menu we put the radius according to the screws we are going to use.
    21. Then in edit mode we select the top face of the cylinder and press I and move our cursor inwards to make a new circle, then we press E and move the cursor downwards to make the hole.
    22. RTC datasheet
      RTC datasheet
    23. This is how the screw joints turned out and to fully join them to the main body what I did was select the main body > Modifier > Boolean > Union > With the eyedropper we select all the screw joints and to confirm it Ctrl + A.
    24. RTC datasheet

3D PRINTING

I exported my finished Blender model as STL: File> Export> STL and opened it in Prusa Slicer, to know more about the settings to 3D print you can see my WEEK05

RTC datasheet
RTC datasheet

The result of my print was this

RTC datasheet

VIDEO TIMELAPSE

Since I had the 3D printed shell what I did was cover it with plush type fabric to give it a cuter touch the first version was this.

RTC datasheet

Although because of the color they told me it looked more like a rat so I decided to change the fabric and this is how it ended up, this is the version before I trimmed the excess fabric.

RTC datasheet

LASER CUTTING

For the base I decided to cut it with black acrylic to know more about how the laser cutter works you can see my WEEK03, the parameters to cut acrylic were the following:

RTC datasheet
Proyecto 2
Proyecto 3

INPUT

For inputs I used three things a capacitive sensor so that this serves as a button so that when it detects an increase in capacitance when the user grabs the hamster it turns off besides an RTC with which we can detect the time so that the speaker begins to sound and the motors move when it is equal to the time that the user set in the interface and finally the sensors that help prevent the hamster from getting trapped.

CAPACITIVE SENSOR

First I did some tests which I did during my WEEK09, this is the schematic of how the sensor works.

RTC datasheet

CODE


long result;            // Stores the total sum of samples
int analog_pin = A2;    // Receiver pin where capacitance is measured
int tx_pin = D10;       // Transmitter pin 
 
void setup() {
  // Configures the transmitter pin as data output
  pinMode(tx_pin, OUTPUT);      
  
  Serial.begin(115200);
  
  delay(1000); 
}
 
long tx_rx() {
  int read_high;    // Variable for reading with active pulse
  int read_low;     // Variable for reading with deactivated pulse
  int diff;         // Difference between charge and discharge
  long sum = 0;     // Accumulator for all samples
  int N_samples = 100; // Number of measurements to average and reduce noise
 
  for (int i = 0; i < N_samples; i++) {
    
    digitalWrite(tx_pin, HIGH);
    read_high = analogRead(analog_pin);
    
    delayMicroseconds(100); 
 
    digitalWrite(tx_pin, LOW);
    read_low = analogRead(analog_pin);
    
    diff = read_high - read_low;
 
    sum += diff;
  }
  
  return sum; // Returns the total of the 100 samples
}
 
void loop() {
  result = tx_rx();
 
  // Converts the summed value (approx range 15000-25000) to a scale of 0 to 1024
  long mapped_result = map(result, 15000, 25000, 0, 1024); 
 
  Serial.print("Raw (Crudo): ");
  Serial.print(result);
  Serial.print(" | Mapped (Escalado): ");
  Serial.println(mapped_result);
 
  delay(50); 
}

RESULT

Then I placed it on the internal part of my shell and did some tests of how much the values change when you place your hand over the hamster.

I2C SENSOR (RTC)

The first thing I did was test the Real-Time Clock (RTC) sensor for my hamster alarm clock, since with this reading the hamster will start ringing. This uses I2C communication. During WEEK09 you can find more information.

I used the dedicated pins on the XIAO (SDA and SCL). The microcontroller requests information from a specific address (e.g., 0x68), and the RTC responds by sending packets of bytes representing seconds, minutes, and hours.

The image below shows the registers through which the RTC operates; you can find this map in the datasheet.

RTC datasheet

#include <stdio.h>
#include "hardware/i2c.h"
#include "pico/binary_info.h"

// Hardware Configuration
#define I2C_PORT i2c1
#define PIN_SDA 6
#define PIN_SCL 7
#define DS3231_ADDR 0x68

// BCD conversion functions
uint8_t bcdToDec(uint8_t val) { return ((val / 16 * 10) + (val % 16)); }

void setup() {
  Serial.begin(115200);
  
// Wait for serial monitor
  while (!Serial && millis() < 3000);

// Initialize I2C
  i2c_init(I2C_PORT, 100 * 1000);
  gpio_set_function(PIN_SDA, GPIO_FUNC_I2C);
  gpio_set_function(PIN_SCL, GPIO_FUNC_I2C);
  
// Active pull-ups
  gpio_pull_up(PIN_SDA);
  gpio_pull_up(PIN_SCL);

  Serial.println("--- MODO LECTURA: Reloj DS3231 Activo ---");
}

void loop() {
  uint8_t reg = 0x00; // Start recording (seconds)
  uint8_t data[3];    // Buffer for [0]=sec, [1]=min, [2]=hours

  i2c_write_blocking(I2C_PORT, DS3231_ADDR, ®, 1, true);
  
  int bytes_read = i2c_read_blocking(I2C_PORT, DS3231_ADDR, data, 3, false);

  if (bytes_read < 0) {
    Serial.println("Error: No se detecta el reloj. Revisa cables.");
  } else {
// Convert data from BCD to Decimal
    uint8_t segundos = bcdToDec(data[0]);
    uint8_t minutos  = bcdToDec(data[1]);
    uint8_t horas    = bcdToDec(data[2] & 0x3F); // Mask for 24h format

    Serial.print("\nHora actual: ");
    
    if (horas < 10) Serial.print('0');
    Serial.print(horas);
    Serial.print(':');
    
    if (minutos < 10) Serial.print('0');
    Serial.print(minutos);
    Serial.print(':');
    
    if (segundos < 10) Serial.print('0');
    Serial.print(segundos);
    
    Serial.print("\t");
  }

  delay(1000);
}

RESULT

ANALOGIC SENSOR

The Sharp sensor is connected as follows: the blue arrow can also be connected to a programming pin so that we can activate and deactivate it in operation; having it connected to VCC, the sensor will always be active.

RTC datasheet

CODE


const int sensorPin = A2;

void setup() {
  Serial.begin(115200);
  
  // Use the native resolution of the RP2350 (12-bit)
  analogReadResolution(12); 
  
  pinMode(sensorPin, INPUT);
  Serial.println("GP2Y0E02A Sensor ready...");
}

void loop() {
  // 1. Read raw value (0 - 4095)
  int rawValue = analogRead(sensorPin);
  
  // 2. Convert to Voltage (3.3V Reference)
  float voltage = rawValue * (3.3 / 4095.0);

  // 3. Calculate distance in cm using the datasheet slope
  // Using the linear equation: y = mx + b
  // Based on datasheet points: (0.55V, 50cm) and (2.2V, 4cm)
  float distanceCm = (voltage - 2.2) * (50.0 - 4.0) / (0.55 - 2.2) + 4.0;

  Serial.print("Voltage: ");
  Serial.print(voltage, 2);
  Serial.print("V | Distance: ");
  
  // 4. Range validation and output
  if (distanceCm > 55) {
    Serial.println("Fuera de rango (Lejos)");
  } else if (distanceCm < 3) {
    Serial.println("Fuera de rango (Cerca)");
  } else {
    Serial.print(distanceCm, 1);
    Serial.println(" cm");
  }

  delay(100); 
}

RESULT

Although since I used the xiaoesp32 c6 and it only has three analog pins and one of the analog pins was already occupied by the capacitive button I didn't have any more left so I decided to make a board with an attiny that would be in charge of reading the value of the three sensors and then communicating it via I2C to my xiao.

ESQUEMATICO

PLACA TERMINADA

HOW TO PROGRAM THE ATTINY

To program it it is important that we have these three pins to connect it to an Arduino uno: VCC, GND AND UPDI.

The steps to program the attiny are the following:

  1. We have to make the following connection with the Arduino uno
  2. RTC datasheet
  3. Then we download from github the jtag2updi file that we have to unzip and open in Arduino.
  4. When we open it a file will appear that will have many files inside.
  5. RTC datasheet
  6. We upload this file to our Arduino.
  7. Then in File> Preferences.
  8. In the "Additional Boards Manager URLs" section, we paste the following link: http://drazzy.com/package_drazzy.com_index.json
  9. In Tools > Board > Boards Manager, we search for “megaTinyCore” and install it.
  10. We go to Tools > Board > megaTinyCore and select "ATtiny412/402/212/202".
  11. RTC datasheet
  12. In Tools > Programmer, we select "jtag2updi (megaTinyCore)".
  13. To program it we go to Sketch> Upload Using Programmer
  14. RTC datasheet

The code I uploaded to my attiny to detect the distance of our sensors was the following:

CODE


#include <Wire.h>
const int SLAVE_ADDRESS = 8;

void setup() {

  Serial.begin(115200);
  
  delay(2000); 
  Serial.println("Iniciando maestro I2C en ESP32-C6...");

  Wire.begin();
}

void loop() {

  Wire.requestFrom(SLAVE_ADDRESS, 3);

  if (Wire.available() == 3) {

    uint8_t distIzq = Wire.read();
    uint8_t distDer = Wire.read();
    uint8_t distAtras = Wire.read();

    Serial.print("Izquierda: ");
    Serial.print(distIzq);
    Serial.print(" cm | Derecha: ");
    Serial.print(distDer);
    Serial.print(" cm | Atrás: ");
    Serial.print(distAtras);
    Serial.println(" cm");
  } else {
    Serial.println("Error: No se recibieron los datos del ATtiny412.");
  }


  delay(100); 
}

OUTPUT

For output I have my motors and the speaker, in WEEK 10 I tested making the board for one motor.

MOTORS

I'm going to use small DC motors for when I escape, so do the following; for more information you can see my WEEK 10.

For my DC motor, I made the H-bridge using the TB67H451AFNG; this is the schematic of my H-bridge.

RTC datasheet

CODE


const int IN1 = 27; // PINS WHERE WE ARE GOING TO CONNECT THE MOTOR INPUTS 
const int IN2 = 28; 

void setup() {  // We configure both pins as OUTPUT
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  detenerMotor();
}

void loop() {

  moverMotor(200); // We move the motor at a power of 
  // in one direction for 2 seconds
  delay(2000);
  
  detenerMotor();// We stop the motor 
  delay(1000);
  
  moverMotor(-200);// We start turning in the other direction
  delay(2000);
  
  detenerMotor();
  delay(1000);
}

void moverMotor(int velocidad) {
  if (velocidad > 0) {
    analogWrite(IN1, velocidad); // Function to make it turn to the right
    analogWrite(IN2, 0);// Sends IN2 to 0, so that one has no signal
  } else if (velocidad < 0) {
    analogWrite(IN1, 0); // Sets IN1 to 0, so that one has no signal
    analogWrite(IN2, abs(velocidad));// Function to make it turn to the left
  } else {
    detenerMotor();
  }
}

void detenerMotor() {
  analogWrite(IN1, 0);// Sets both IN to 0 so the motor does not turn
  analogWrite(IN2, 0);
}  

RESULT

But for my project I took charge of making my board for two motors where my schematic is the following:

The code I tested for the operation of the H-bridge was the following:

SPEAKER

For the speaker to sound what I used was the DFplayer Mini MP3 Player module which I connected in the following way with my XIAO.

RTC datasheet

The steps you have to follow to play sounds are the following:

CODE

SYSTEM INTEGRATION

To avoid having so many jumpers for what I did was align the connection pins of the H-bridge with the output pins of my main board where my xiao and my speaker module are located.

This is how the assembly of my boards turned out

Since I couldn't avoid the cables for my distance sensors what I did was make a third board where the attiny is that is in charge of reading the sensors processes the values and communicates it with I2C to the main board where I tried to have the fewest cables possible which were VCC, GND,SCL AND SDA.

ASSEMBLY

I did some tests of how the structure moves

RESULT

PACKAGING

FILES

Here you can download the source files created during this week: