Final Project

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

Progress

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.

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

SHARP ANALOG SENSOR

Later, to be able to dodge people when they try to catch it, I tested the Sharp analog sensors.

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

STEP RESPONSE

Additionally, to be able to turn off the alarm, I thought I could use a capacitive sensor to detect when a hand is near. For more information about how I did this, you can check my WEEK 09.

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

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