Mechanical engineering · UTRGV

Adrian Velaengineering student.

I'm a mechanical engineering student at the University of Texas Rio Grande Valley. Right now that means coursework, picking up MATLAB, tutoring math, and building software on the side to get more comfortable writing code that solves real problems.

Explore the projects

05 projects

Builds, work in progress and plans, labeled honestly

Selected projects

Open build notes on any card for the details

Auto desk fan on a breadboard: an Arduino Uno wired to a blue 16×2 LCD reading "Now 79.6°F, Set 82.4°F, OFF", with two blue knobs, the MOSFET, and the small DC motor beside the board.Working prototype

01 / Arduino

Auto desk fan

Builder

An Arduino thermostat that turns a small fan on above a temperature I choose and spins it faster the hotter the room gets.

Built with

Arduino · C++ · Breadboard prototyping · PWM motor control

Build notes
  • Built on a breadboard using only parts from the Arduino Starter Kit, following a wiring guide and sketch.
  • A TMP36 sensor reads the room temperature and a knob sets the target, anywhere from 64 to 90 °F.
  • The fan turns on 0.9 °F above the target and off 0.9 °F below it, so it doesn't flicker on and off when the room sits right at the target.
  • Speed climbs from a slow spin to full power at 7.2 °F over the target, using PWM on pin 9 through an IRF520 MOSFET, since an Arduino pin can't power a motor directly.
  • A 16×2 LCD screen shows the current temperature, the target, and the fan speed.

What went wrong and how I fixed it

  • My potentiometers didn't fit the planned layout. The guide assumed knobs with three legs in a straight line, but mine had a triangle footprint. Once I understood that parts connect by breadboard column, not by being next to each other, I moved both knobs to empty columns and ran one wire from each leg. I also ruled out a shortcut that would have tied the knobs into the LCD's data lines.
  • The screen showed a row of solid blocks on top and nothing on the bottom. That pattern means the LCD has power but was never started by the Arduino, so I left the power wiring alone and checked the upload, reset, and signal wires in order. Uploading the sketch correctly fixed it.

What I took away: Read a symptom for what it rules out before changing anything. The solid blocks proved the power was fine, which saved me from rewiring the one part that already worked.

View the fan code

desk_fan.ino

// Auto desk fan (thermostat) - Arduino Starter Kit parts only.
// Turn the knob to pick a target temperature. When the room is warmer than
// the target the fan turns on, and it spins faster the hotter it gets.
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // RS, E, D4, D5, D6, D7 (kit book wiring)

const int TEMP_PIN = A0;   // TMP36 middle leg
const int KNOB_PIN = A1;   // target-temperature knob (middle leg)
const int FAN_PIN = 9;     // MOSFET gate - must be a ~PWM pin

const bool SHOW_FAHRENHEIT = true; // false = show degrees C on the screen

const float SET_MIN_C = 18.0;     // knob turned fully left
const float SET_MAX_C = 32.0;     // knob turned fully right
const float HYSTERESIS_C = 0.5;   // on at target+0.5, off at target-0.5 (no flicker)
const float FULL_SPEED_C = 4.0;   // this many degrees over target = full speed
const int MIN_PWM = 100;          // slowest speed that keeps YOUR motor turning (tune)
const int KICK_MS = 200;          // full-power burst to get a stopped motor going

bool fanOn = false;
int lastPwm = 0;
unsigned long lastPrint = 0;

float readTempC() {
  long total = 0;
  for (int i = 0; i < 16; i++) total += analogRead(TEMP_PIN); // average out noise
  float volts = (total / 16.0) * 5.0 / 1024.0;
  return (volts - 0.5) * 100.0;               // TMP36: 0.5 V at 0 C, 10 mV per C
}

float readTargetC() {
  int raw = analogRead(KNOB_PIN);
  float t = SET_MIN_C + (SET_MAX_C - SET_MIN_C) * raw / 1023.0;
  return floor(t * 2 + 0.5) / 2.0;            // snap to half degrees
}

int fanSpeed(float tempC, float targetC) {
  float over = tempC - targetC;
  if (!fanOn && over >= HYSTERESIS_C) fanOn = true;
  if (fanOn && over <= -HYSTERESIS_C) fanOn = false;
  if (!fanOn) return 0;
  float fraction = constrain(over / FULL_SPEED_C, 0.0, 1.0);
  return MIN_PWM + (int)((255 - MIN_PWM) * fraction);
}

float toDisplay(float c) {
  if (SHOW_FAHRENHEIT) return c * 9.0 / 5.0 + 32.0;
  return c;
}

void printTemp(float c) {        // e.g. "76.5°F" (6 characters)
  float v = toDisplay(c);
  if (v >= 0 && v < 10) lcd.print(" ");
  lcd.print(v, 1);
  lcd.write(223);                // degree symbol built into the LCD
  if (SHOW_FAHRENHEIT) lcd.print("F");
  else lcd.print("C");
}

void setup() {
  pinMode(FAN_PIN, OUTPUT);
  analogWrite(FAN_PIN, 0);
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.print("Desk fan ready");
  delay(1000);
  lcd.clear();
}

void loop() {
  float tempC = readTempC();
  float targetC = readTargetC();
  int pwm = fanSpeed(tempC, targetC);

  if (pwm > 0 && lastPwm == 0) {   // starting from a stop: kick it
    analogWrite(FAN_PIN, 255);
    delay(KICK_MS);
  }
  analogWrite(FAN_PIN, pwm);
  lastPwm = pwm;
  int percent = pwm * 100 / 255;

  lcd.setCursor(0, 0);             // "Now  76.5°F     "
  // At 100°F or more this row is 17 characters; the last padding space
  // lands just past column 16, off-screen, so nothing visible changes.
  lcd.print("Now  ");
  printTemp(tempC);
  lcd.print("     ");
  lcd.setCursor(0, 1);             // "Set  73.0°F  62%"  or  "Set  73.0°F  OFF"
  lcd.print("Set  ");
  printTemp(targetC);
  if (pwm == 0) {
    lcd.print("  OFF");
  } else {
    lcd.print(" ");
    if (percent < 100) lcd.print(" ");
    if (percent < 10) lcd.print(" ");
    lcd.print(percent);
    lcd.print("%");
  }

  if (millis() - lastPrint >= 1000) { // one line per second for the laptop page
    lastPrint = millis();
    Serial.print("temp="); Serial.print(tempC, 1);
    Serial.print(",set="); Serial.print(targetC, 1);
    Serial.print(",fan="); Serial.println(percent);
  }
  delay(250);
}
Arduino interval timer on a breadboard in a dark room, with two of its six red LEDs lit and jumper wires arching over the board.Working prototype

02 / Arduino

10-minute interval timer

Builder

An Arduino timer that lights one of six LEDs every 10 minutes, prototyped on a breadboard.

Built with

Arduino · C++ · Breadboard prototyping

Build notes
  • Based on the Digital Hourglass project from the Arduino Starter Kit, then modified.
  • Uses millis() instead of delay() for timing, so the board keeps reading the tilt sensor while it counts.
  • When all six LEDs are lit (one hour), the row clears and the count starts over.
  • Tilting the board resets the timer.

What I tried after

  • Reprogrammed the LEDs to flash in the rhythm of the Jingle Bells chorus.
  • Changed the time periods to see how the timer behaved at different intervals.
  • Reworked the reset so it runs without the tilt sensor, making the timer fully automatic.
View the timer code

interval_timer.ino

const int switchPin = 8;
unsigned long previousTime = 0;
int switchState = 0;
int prevSwitchState = 0;
int led = 2;
unsigned long interval = 600000; // 10 minutes per LED

void setup() {
  for (int x = 2; x < 8; x++) {
    pinMode(x, OUTPUT);
  }
  pinMode(switchPin, INPUT);
}

void loop() {
  unsigned long currentTime = millis();

  // Every interval, light the next LED.
  if (currentTime - previousTime > interval) {
    previousTime = currentTime;
    digitalWrite(led, HIGH);
    led++;

    // After the sixth LED, clear the row and start over.
    if (led == 8) {
      delay(1000);
      for (int x = 2; x < 8; x++) {
        digitalWrite(x, LOW);
      }
      led = 2;
      previousTime = millis();
    }
  }

  // Tilting the board (tilt sensor on pin 8) resets the timer.
  switchState = digitalRead(switchPin);
  if (switchState != prevSwitchState) {
    for (int x = 2; x < 8; x++) {
      digitalWrite(x, LOW);
    }
    led = 2;
    previousTime = currentTime;
  }
  prevSwitchState = switchState;
}
View the Jingle Bells code

jingle_bells_lights.ino

const int beat = 350;  // Smaller = faster

// Relative note lengths for the chorus.
// 0 marks a pause between phrases.
const int rhythm[] = {
  1, 1, 2,  1, 1, 2,  1, 1, 1, 1, 4, 0,
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 0,
  1, 1, 2,  1, 1, 2,  1, 1, 1, 1, 4, 0,
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4
};

void setLights(int state) {
  for (int pin = 2; pin <= 7; pin++) {
    digitalWrite(pin, state);
  }
}

void setup() {
  for (int pin = 2; pin <= 7; pin++) {
    pinMode(pin, OUTPUT);
  }
}

void loop() {
  int count = sizeof(rhythm) / sizeof(rhythm[0]);

  for (int i = 0; i < count; i++) {
    if (rhythm[i] == 0) {
      setLights(LOW);
      delay(beat);
    } else {
      int duration = rhythm[i] * beat;

      setLights(HIGH);
      delay(duration * 3 / 4);

      setLights(LOW);
      delay(duration / 4);
    }
  }

  delay(1500);  // Pause before repeating
}
In active development

03 / AI-assisted development

Lamplight Planner

Developer

A personal planning application being developed with the help of AI coding tools.

Built with

AI-assisted development

Build notes
  • Built primarily as a way to learn real-world software development by shipping something and iterating on it.
  • Actively developed, so features and structure are still changing.
Member, details coming later

04 / Student organization

SARE UTRGV

Member

Member of SARE UTRGV.

Build notes
  • Joined the organization; specific subsystem contributions are not yet documented here.
  • This entry will be updated once concrete work can be described accurately.
Planned for a later phase

05 / Planned

Flagship engineering project

A more detailed engineering project showcase is planned for a later phase of this site.

Build notes
  • Intentionally left out for now rather than published before it's ready.

Try it in the browser

Open the full lab →

This runs the real 10-minute interval timer sketch on a simulated board. Change the code, press the parts, or speed up time.

Current focus

  • Coursework toward a mechanical engineering degree at UTRGV
  • Learning MATLAB for engineering analysis
  • Building foundational C++ experience
  • Tutoring precalculus through Calculus 3 on schoolhouse.world, helping students understand the concepts (since May 2026)
  • Developing Lamplight Planner using AI coding tools
  • Member of SARE UTRGV

Education

B.S., Mechanical Engineering

The University of Texas Rio Grande Valley (UTRGV)

In progress, current

Skills

MATLABLearning
Currently learning MATLAB for engineering coursework and analysis.
C++Foundational
Foundational experience. Comfortable with core syntax and basic programs, still building depth.
Math tutoring (precalculus through Calculus 3)Comfortable
Tutoring every level from precalculus through Calculus 3 on schoolhouse.world since May 2026, with a focus on helping students understand the concepts better.
AI-assisted software developmentFoundational
Building Lamplight Planner using AI coding tools and learning software development practices hands-on.

Experience

Math Tutor (Precalculus through Calculus 3) at schoolhouse.world

Since May 2026

Volunteer tutor covering precalculus, Calculus 1, 2 and 3 on schoolhouse.world, helping students understand the concepts better.

Member at SARE UTRGV

Current

Joined SARE UTRGV. Specific subsystem contributions are not yet documented.

Prefer exploring by typing? and try help.