Inspirată de designurile emotionally-responsive din filmele SF, vreau să realizez o rochie cu un inel de leduri ce va lumina în mod idferit în funcție de pulsul persoanei care o poartă, temperatură, intensitate luminoasă și sunet. Scopul este pur de divertisment, menit să creeze o legătură între mediul înconjurător și persoana care poartă rochia.
Prezentarea pe scurt a proiectului:
Exemplu de schemă bloc: http://www.robs-projects.com/mp3proj/newplayer.html
Listă de piese
#include <Wire.h> #include "MAX30105.h" #include "heartRate.h" #include <LiquidCrystal_I2C.h> #include <FastLED.h> MAX30105 particleSensor; const byte RATE_SIZE = 8; byte rates[RATE_SIZE]; byte rateSpot = 0; long lastBeat = 0; float beatsPerMinute; int beatAvg; int color; const int buzzerPin = 9; const int soundSensorPinDigital = 12; const int soundSensorPinAnalog = A1; LiquidCrystal_I2C lcd(0x27, 16, 2); const int buttonPin = 5; int buttonPressCounter = 0; // Contor pentru apăsările butonului const int REST = 4; // Update to include the new state bool isNight = false; bool isDay = false; unsigned long lastLightUpdate = 0; const unsigned long lightUpdateInterval = 1000; bool lastButtonState = HIGH; // Starea anterioară a butonului #define LED_PIN 7 #define NUM_LEDS 24 #define BRIGHTNESS 69 // Ajustează nivelul de luminozitate (0-255) CRGB leds[NUM_LEDS]; enum DisplayState { LIGHT_INTENSITY, PULSE_RATE, LED_COLOR, SOUND_LEVEL }; DisplayState currentState = LIGHT_INTENSITY; void setup() { Serial.begin(115200); Serial.println("Initializing..."); // Configurare LED-uri FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); FastLED.setBrightness(BRIGHTNESS); // Setează luminozitatea generală // Configurare senzor puls if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) { Serial.println("MAX30102 was not found. Please check wiring/power. "); while (1); } Serial.println("Place your index finger on the sensor with steady pressure."); particleSensor.setup(); particleSensor.setPulseAmplitudeRed(0x0A); particleSensor.setPulseAmplitudeGreen(0); // Inițializare LCD lcd.init(); lcd.backlight(); pinMode(buttonPin, INPUT_PULLUP); displayLightIntensity(); // Afișează starea inițială a intensității luminii pinMode(buzzerPin, OUTPUT); digitalWrite(buzzerPin, LOW); } void loop() { bool buttonState = digitalRead(buttonPin); if (buttonState != lastButtonState) { lastButtonState = buttonState; if (buttonState == LOW) { buttonPressCounter++; currentState = static_cast<DisplayState>(buttonPressCounter % REST); updateDisplay(); buzzBuzzer(100); } } // Măsurare puls și actualizare valori long irValue = particleSensor.getIR(); if (checkForBeat(irValue) == true) { long delta = millis() - lastBeat; lastBeat = millis(); beatsPerMinute = 60 / (delta / 1000.0); if (beatsPerMinute < 255 && beatsPerMinute > 20) { rates[rateSpot++] = (byte)beatsPerMinute; rateSpot %= RATE_SIZE; beatAvg = 0; for (byte x = 0; x < RATE_SIZE; x++) beatAvg += rates[x]; beatAvg /= RATE_SIZE; } } // Afișare valori în serial monitor Serial.print("IR="); Serial.print(irValue); Serial.print(", BPM="); Serial.print(beatsPerMinute); Serial.print(", Avg BPM="); Serial.print(beatAvg); if (irValue < 50000) Serial.print(" No finger?"); Serial.println(); // Actualizează afișajul corespunzător în timp real updateDisplay(); } // Actualizează afișajul LCD în funcție de starea curentă void updateDisplay() { static DisplayState lastState = currentState; static unsigned long lastUpdate = 0; unsigned long currentMillis = millis(); // Actualizează afișajul la fiecare 500 ms pentru a evita refresh-ul excesiv if (currentMillis - lastUpdate >= 500 || lastState != currentState) { lastUpdate = currentMillis; lastState = currentState; switch (currentState) { case LIGHT_INTENSITY: displayLightIntensity(); break; case PULSE_RATE: displayPulseRate(); break; case LED_COLOR: displayLEDColor(); break; case SOUND_LEVEL: displaySoundLevel(); break; } } } // Afișează pulsul mediu pe LCD void displayPulseRate() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Puls mediu: "); lcd.setCursor(0, 1); lcd.print(beatAvg); lcd.print(" BPM"); Serial.print("Puls mediu: "); Serial.print(beatAvg); Serial.println(" BPM"); } // Afișează intensitatea luminii pe LCD void displayLightIntensity() { float volts = analogRead(A0) * 5.0 / 1024.0; float amps = volts / 10000.0; float microamps = amps * 1000000; float lux = microamps * 2.0; if (lux < 60 && !isNight) { isNight = true; isDay = false; } else if (lux >= 60 && !isDay) { isNight = false; isDay = true; } lcd.clear(); lcd.setCursor(0, 0); lcd.print("Lux Intensity: "); lcd.setCursor(0, 1); lcd.print("Lux: "); lcd.print(lux, 1); lcd.setCursor(11, 1); if (isNight) { lcd.print("Night "); } else if (isDay) { lcd.print("Day "); } } // Afișează culoarea LED pe LCD și pulsul mediu void displayLEDColor() { // Determinăm culoarea în funcție de valoarea BPM if (beatAvg < 55) { color = 9; // indigo } else if (beatAvg >= 55 && beatAvg < 60) { color = 8; // Violet } else if (beatAvg >= 60 && beatAvg < 65) { color = 7; // albastru } else if (beatAvg >= 65 && beatAvg < 70) { color = 6; // cyan } else if (beatAvg >= 70 && beatAvg < 75) { color = 5; // bleu } else if (beatAvg >= 75 && beatAvg < 80) { color = 4; // verde } else if (beatAvg >= 80 && beatAvg < 85) { color = 3; // galben } else if (beatAvg >= 85 && beatAvg < 90) { color = 2; // potocaliu } else if (beatAvg >= 90 && beatAvg < 95) { color = 1; // rosu } else { color = 0; // Roșu } Serial.println(color); // Trimite valoarea culorii prin portul serial lcd.clear(); lcd.setCursor(0, 0); lcd.print("Culoare:"); switch(color) { case 0: lcd.print(" rosu!!"); break; case 1: lcd.print(" rosu"); break; case 2: lcd.print(" portocaliu"); break; case 3: lcd.print(" galben"); break; case 4: lcd.print(" verde"); break; case 5: lcd.print(" bleu"); break; case 6: lcd.print(" cyan"); break; case 7: lcd.print(" albastru"); break; case 8: lcd.print(" violet"); break; case 9: lcd.print(" indigo"); break; } lcd.setCursor(0, 1); lcd.print(beatAvg); lcd.print(" BPM"); setColor(color); // Setează culorile LED-urilor } // Afișează nivelul sunetului pe LCD void displaySoundLevel() { int soundLevel = analogRead(soundSensorPinAnalog); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Sound Level: "); lcd.setCursor(0, 1); if (soundLevel > 800) lcd.print("zgomot!!"); else lcd.print("liniste..."); //lcd.print(soundLevel); Serial.print("Sound Level: "); Serial.println(soundLevel); } // Setează toate LED-urile la culoarea determinată în funcție de valoarea lui 'color' void setColor(int color) { CRGB colorValue; switch(color) { case 0: // rosu!!! colorValue = CRGB::Red; break; case 1: // rosu colorValue = CRGB::Red; break; case 2: // portocaliu colorValue = CRGB::Orange; break; case 3: // galben colorValue = CRGB::Yellow; break; case 4: // verde colorValue = CRGB::Green; break; case 5: // bleu colorValue = CRGB::LightBlue; break; case 6: // cyan colorValue = CRGB::Cyan; break; case 7: // albastru colorValue = CRGB::Blue; break; case 8: // violet colorValue = CRGB::Violet; break; case 9: // indigo colorValue = CRGB::Indigo; break; default: colorValue = CRGB::White; // Setează implicit la alb dacă 'color' este în afara intervalului break; } for (int i = 0; i < NUM_LEDS; i++) { leds[i] = colorValue; } FastLED.show(); Serial.println("LED color updated"); // Mesaj de debug pentru confirmare } void buzzBuzzer(int duration) { digitalWrite(buzzerPin, HIGH); // buzzer on delay(duration); digitalWrite(buzzerPin, LOW); // buzzer off }
Mediu de dezvoltare:
Librării şi surse 3rd-party:
Algoritmi şi structuri:
(Etapa 3) Surse şi funcţii implementate: 1. Setup:
2. Loop:
3. Funcții de afișare:
4. Funcții auxiliare:
Am descoperit că îmi face plăcere să fac mici proiecte de genul și plănuiesc să exploatez acest domeniu, într-un mod din ce în ce mai creativ.
Fişierele se încarcă pe wiki folosind facilitatea Add Images or other files. Namespace-ul în care se încarcă fişierele este de tipul :pm:prj20??:c? sau :pm:prj20??:c?:nume_student (dacă este cazul). Exemplu: Dumitru Alin, 331CC → :pm:prj2009:cc:dumitru_alin.