//authors Clara Blum and Mohammad Jafari
/*
In the follwing the reader finds the code for the 2nd semester ITECH seminar CDDF Assignment 01 named "Useless Machine". 
The Code enables sensing certain values on the human body and allocates emotional states to these. 
Upon this a mechanical actuator in form of a moving fan visualizes these changes.
This code is to be used with an Arduino uno.
*/

/*---------------------------------------------------INCLUDING LIBRARIES----------------------------------------------------*/
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Servo.h>
#define ONE_WIRE_BUS 12
#define USE_ARDUINO_INTERRUPTS true     //Set-up low-level interrupts for most acurate BPM math.
#include <PulseSensorPlayground.h>
/*-----------------------------------------------------------------------------------------------------------------------------*/
//TEMPERATURE
const int tempPin = 12;
float temp;
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

//HUMIDITY
const int humPin = A0;
float hum_sensor_analog;


//PULSE
const int pulPin = A1;
float myBPM;
PulseSensorPlayground myPulseSensor;

//RGB LED
const int PIN_RED   = 6;
const int PIN_GREEN = 5;
const int PIN_BLUE  = 3;

//SERVO MOTOR
Servo servoFan;
/*---------------------------------------------------DEFINE EMOTION THESHOLDS----------------------------------------------------*/
//CALM
const float calmTempThreshold   = 19.75;  //AVERAGE
const float calmHumThreshold    = 20;     //AVERAGE
const float calmPulThreshold    = 230;    //AVERAGE

//ANGRY/NERVOUS
const float angryTempThreshold  = 22;     //HIGH
const float angryHumThreshold   = 30;     //HIGH
const float angryPulThreshold   = 231;    //HIGH

//TIRED
const float tiredTempThreshold  = 19.5;   //LOW
const float tiredHumThreshold   = 10;     //LOW
const float tiredPulThreshold   = 229;    //LOW
/*-----------------------------------------------------------------------------------------------------------------------------*/
void setup() {
  Serial.begin(9600);
  sensors.begin();
  servoFan.attach(9);

  pinMode(tempPin,   INPUT);
  pinMode(humPin,   INPUT);
  pinMode(pulPin,   INPUT);

  pinMode(PIN_RED,   OUTPUT);
  pinMode(PIN_GREEN, OUTPUT);
  pinMode(PIN_BLUE,  OUTPUT);

  //Configure the PulseSensor object, by assigning our variables to it 
  myPulseSensor.analogInput(pulPin);      
  //Double-check the "pulseSensor" object was created and "began" seeing a signal 
   if (myPulseSensor.begin()) {
    Serial.println("We created a pulseSensor Object !");  //This prints one time at Arduino power-up,  or on Arduino reset  
  }
}
  /*---------------------------------------------------------FUNCTIONS----------------------------------------------------------*/
void servoDegree(int degree){
  servoFan.write(degree);
  //delay(1000);
}
void openFan(){
  servoDegree(180);
}
void closeFan(){
  servoDegree(0);
}
 /*-----------------------------------------------------------------------------------------------------------------------------*/ 
void loop() {
  /*--------------------------------------------------REQUESTING SENSOR VALUES--------------------------------------------------*/
  sensors.requestTemperatures();
  temp = sensors.getTempCByIndex(0);
  
  hum_sensor_analog = analogRead(humPin);
  float moisture_percentage = ( 100 - ( (hum_sensor_analog/1023.00) * 100 ) );

  int pulValue = analogRead(pulPin);
  myPulseSensor.getBeatsPerMinute();
  float myBPM = myPulseSensor.getBeatsPerMinute();
  /*--------------------------------------------------PRINTING SENSOR VALUES WITH BMP--------------------------------------------------*/
 if (myPulseSensor.sawStartOfBeat()) {
    Serial.print("BPM: ");                        
    Serial.println(myBPM);                        
    Serial.print("TEMPERATURE = ");
    Serial.print(temp);
    Serial.print("°C");
    Serial.println();
    Serial.print("HUMIDITY = ");
    Serial.print(moisture_percentage);
    Serial.print("%");
    Serial.println();
  }
  delay(20);
  /*--------------------------------------------------PRINTING SENSOR VALUES WITHOUT BMP--------------------------------------------------*/
  /*Serial.print("TEMPERATURE = ");
  Serial.print(temp);
  Serial.print("°C");
  Serial.println();
  Serial.print("HUMIDITY = ");
  Serial.print(moisture_percentage);
  Serial.print("%");
  Serial.println();
  delay(20);*/
  /*--------------------------------------------------SENSOR VALUE REACTION WITH PULSE--------------------------------------------------*/
  if ((temp > tiredTempThreshold && temp < angryTempThreshold) || (moisture_percentage > tiredHumThreshold && moisture_percentage < angryHumThreshold) || (myBPM > tiredPulThreshold && myBPM < angryPulThreshold)) {
  Serial.print("CALM");
  servoDegree(15);
  delay(1000);
  servoDegree(30);
  delay(1000);
  servoDegree(45);
  delay(1000);
  servoDegree(60);
  delay(1000);
  servoDegree(75);
  delay(1000);
  servoDegree(90);
  delay(1000);
  closeFan();
  delay(2000);
}
  else if (temp > angryTempThreshold || moisture_percentage > angryHumThreshold || myBPM > angryPulThreshold) {
  Serial.print("ANGRY OR NERVOUS?");
  for (int i = 0; i < 3; i++) {
    openFan();
    delay(500);
    closeFan();
    delay(500);
  }
}
else if (temp < tiredTempThreshold || moisture_percentage < tiredHumThreshold || myBPM < tiredPulThreshold) {
  Serial.print("TIRED OR SAD?");
  closeFan();
}
  delay(1000);
}
