#include <Wire.h>
#include "MAX30105.h" // Heart rate sensor library
#include "Adafruit_MPR121.h" // Capacitive touch sensor library for stone interface
// Initialize sensors
MAX30105 particleSensor;
Adafruit_MPR121 capTouch = Adafruit_MPR121();
#define WHITE_PIN 3 // Pin for light blue (relaxation) color
#define BLUE_PIN 4 // Pin for indigo (stress) color
#define GREEN_PIN 5 // Pin for green (balance)
#define YELLOW_PIN 6 // Pin for yellow (nervous)
#define CORAL_PIN 7 // Pin for coral (alert)
int RRintervals[10]; // Array to store RR intervals
int rrIndex = 0; // Circular buffer index for RR intervals
void setup() {
Wire.begin();
Serial.begin(9600);
// Initialize the heart rate sensor
if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) {
Serial.println("MAX30102 sensor failed");
while (1);
}
// Initialize the touch sensor
if (!capTouch.begin(0x5A)) {
Serial.println("MPR121 not found");
while (1);
}
// Set up the color control pins
pinMode(WHITE_PIN, OUTPUT); // Light blue for calm
pinMode(BLUE_PIN, OUTPUT); // Indigo for stress
pinMode(GREEN_PIN, OUTPUT); // Green for balance
pinMode(YELLOW_PIN, OUTPUT); // Yellow for nervous
pinMode(CORAL_PIN, OUTPUT); // Coral for alert
// Start with all colors off
digitalWrite(WHITE_PIN, LOW);
digitalWrite(BLUE_PIN, LOW);
digitalWrite(GREEN_PIN, LOW);
digitalWrite(YELLOW_PIN, LOW);
digitalWrite(CORAL_PIN, LOW);
}
void loop() {
// Check for a touch on the stone
if (capTouch.touched() & (1 << 0)) { // Detect touch on pin 0
// Start measuring HRV when the stone is touched
int heartRate = getHeartRate();
int hrv = calculateHRV(heartRate);
// Map HRV to colors
if (hrv >= 60) {
setFeedbackColor("light blue"); // Calm state
} else if (hrv >= 50) {
setFeedbackColor("green"); // Balanced state
} else if (hrv >= 40) {
setFeedbackColor("coral"); // Alert state
} else if (hrv >= 30) {
setFeedbackColor("yellow"); // Nervous state
} else {
setFeedbackColor("indigo"); // Stress state
}
}
delay(1000); // Simple delay for polling
}
// Function to get heart rate from MAX30102
int getHeartRate() {
long irValue = particleSensor.getIR(); // Get infrared value from sensor
if (checkForBeat(irValue)) {
long delta = millis() - previousMillis;
previousMillis = millis();
int beatsPerMinute = 60 / (delta / 1000.0);
RRintervals[rrIndex] = delta;
rrIndex = (rrIndex + 1) % 10; // Store RR intervals in circular buffer
return beatsPerMinute;
}
return 0; // Return 0 if no beat detected
}
// Function to calculate HRV
int calculateHRV(int heartRate) {
int sumRR = 0;
int avgRR = 0;
// Calculate average RR intervals
for (int i = 0; i < 10; i++) {
sumRR += RRintervals[i];
}
avgRR = sumRR / 10;
// Calculate standard deviation of RR intervals as HRV
int hrv = 0;
for (int i = 0; i < 10; i++) {
hrv += abs(RRintervals[i] - avgRR);
}
return hrv / 10; // Return average HRV
}
// Function to change the necklace color based on mood
void setFeedbackColor(String mood) {
// Turn off all colors first
digitalWrite(WHITE_PIN, LOW);
digitalWrite(BLUE_PIN, LOW);
digitalWrite(GREEN_PIN, LOW);
digitalWrite(YELLOW_PIN, LOW);
digitalWrite(CORAL_PIN, LOW);
// Set the correct color based on HRV
if (mood == "light blue") {
digitalWrite(WHITE_PIN, HIGH); // Calm (relaxed) state
} else if (mood == "indigo") {
digitalWrite(BLUE_PIN, HIGH); // Stress state
} else if (mood == "green") {
digitalWrite(GREEN_PIN, HIGH); // Balanced state
} else if (mood == "yellow") {
digitalWrite(YELLOW_PIN, HIGH); // Nervous state
} else if (mood == "coral") {
digitalWrite(CORAL_PIN, HIGH); // Alert state
}
}