Final Project¶
The concept for my final project is a motion activated light that slowly opens and closes.
Mechanical Mechanisms¶
Auxetic Material¶
Example Material
Sensors and software¶
Basic functionality of the circuit:
-
When motion is detected the LED turns on slowly
-
Brightness of the LED is controled through PWM
-
The color of the LED is determined from the temperature reading on TRD termperature sensor
Code for the prototype sensors
#include <Arduino.h>
#include <DHTesp.h>
// ----- Pins (adjust if needed) -----
static const int PIN_PIR = 4;
static const int PIN_DHT = 15;
// Common-cathode RGB LED pins (each via resistor)
static const int PIN_RED = 12;
static const int PIN_GREEN = 13;
static const int PIN_BLUE = 14;
// ----- PWM settings -----
static const int PWM_FREQ = 5000;
static const int PWM_BITS = 8; // 0..255
// ----- Motion/LED behavior -----
static const uint32_t HOLD_MS = 2000;
static const uint8_t TARGET_BRIGHT = 255;
static const uint8_t FADE_STEP = 3;
static const uint16_t STEP_DELAY_MS = 10;
// ----- DHT -----
DHTesp dht;
uint32_t lastDhtReadMs = 0;
static const uint32_t DHT_PERIOD_MS = 2000;
// ----- Temperature -> color tuning -----
static const float COLD_C = 18.0;
static const float HOT_C = 28.0;
// State
uint32_t lastMotionMs = 0;
uint8_t currentBright = 0;
float lastTempC = NAN;
// Clamp helpers
static inline uint8_t clamp8(int v) {
if (v < 0) return 0;
if (v > 255) return 255;
return (uint8_t)v;
}
static inline float clampf(float v, float lo, float hi) {
if (v < lo) return lo;
if (v > hi) return hi;
return v;
}
// COMMON CATHODE: no inversion needed
void writeLed(int pin, uint8_t brightness) {
ledcWrite(pin, brightness);
}
// Apply global brightness scaling
void setRgbScaled(uint8_t r, uint8_t g, uint8_t b, uint8_t globalBright) {
uint8_t rs = (uint8_t)((r * (uint16_t)globalBright) / 255);
uint8_t gs = (uint8_t)((g * (uint16_t)globalBright) / 255);
uint8_t bs = (uint8_t)((b * (uint16_t)globalBright) / 255);
writeLed(PIN_RED, rs);
writeLed(PIN_GREEN, gs);
writeLed(PIN_BLUE, bs);
}
// Temperature -> RGB gradient
void colorFromTemp(float tC, uint8_t &r, uint8_t &g, uint8_t &b) {
if (isnan(tC)) {
r = 180; g = 0; b = 180;
return;
}
float t = clampf(tC, COLD_C, HOT_C);
float x = (t - COLD_C) / (HOT_C - COLD_C);
if (x <= 0.5f) {
float u = x / 0.5f;
r = 0;
g = clamp8((int)(255.0f * u));
b = clamp8((int)(255.0f * (1.0f - u)));
} else {
float u = (x - 0.5f) / 0.5f;
r = clamp8((int)(255.0f * u));
g = clamp8((int)(255.0f * (1.0f - u)));
b = 0;
}
}
void setup() {
Serial.begin(115200);
pinMode(PIN_PIR, INPUT_PULLDOWN);
ledcAttach(PIN_RED, PWM_FREQ, PWM_BITS);
ledcAttach(PIN_GREEN, PWM_FREQ, PWM_BITS);
ledcAttach(PIN_BLUE, PWM_FREQ, PWM_BITS);
setRgbScaled(0,0,0,0);
dht.setup(PIN_DHT, DHTesp::DHT11);
Serial.println("Common Cathode version running.");
}
void loop() {
uint32_t now = millis();
// PIR
bool motionNow = (digitalRead(PIN_PIR) == HIGH);
if (motionNow) lastMotionMs = now;
bool motionActive = (now - lastMotionMs) < HOLD_MS;
uint8_t targetBright = motionActive ? TARGET_BRIGHT : 0;
// DHT read
if (now - lastDhtReadMs >= DHT_PERIOD_MS) {
lastDhtReadMs = now;
TempAndHumidity th = dht.getTempAndHumidity();
if (!isnan(th.temperature)) {
lastTempC = th.temperature;
Serial.print("Temp: ");
Serial.print(lastTempC, 1);
Serial.print(" C Humidity: ");
Serial.println(th.humidity, 0);
}
}
// Determine base color
uint8_t baseR, baseG, baseB;
colorFromTemp(lastTempC, baseR, baseG, baseB);
// Smooth fade
if (currentBright < targetBright) {
currentBright = (uint8_t)min((int)targetBright, (int)currentBright + (int)FADE_STEP);
}
else if (currentBright > targetBright) {
currentBright = (uint8_t)max((int)targetBright, (int)currentBright - (int)FADE_STEP);
}
setRgbScaled(baseR, baseG, baseB, currentBright);
delay(STEP_DELAY_MS);
}