/*authors: Luiza Longo, Ali Zolfaghari and Ceren Tüfek
Computational Design and Fabrication, ITECH Uni Stuttgart SS2023
Teachers: T. Schwinn, N. Opgenorth, T. Stark, Y. Tahouni, X. Yang and Prof. A. Menges
References:
temperature sensor
https://www.makerguides.com/lm35-arduino-tutorial/

motor
https://docs.arduino.cc/tutorials/motor-shield-rev3/msr3-controlling-dc-motor

touch sensor
https://arduinogetstarted.com/tutorials/arduino-touch-sensor

alcohol sensor
https://circuitdigest.com/microcontroller-projects/interfacing-mq3-alcohol-sensor-with-arduino

ultrasonic sensor
https://howtomechatronics.com/tutorials/arduino/ultrasonic-sensor-hc-sr04/

motor
https://docs.arduino.cc/learn/electronics/transistor-motor-control

speakers
https://steemit.com/utopian-io/@kimp0gi/playing-music-in-arduino-using-sd-card-module


*/
//CODE START
//creating random nbr
long randNumber;
//booleans for interaction
bool touchSensor = false;
//bool interactionStart = false;
//_________________________________________________________ultrasonic sensor start
const int trigPin = 3;
const int echoPin = 6;
long duration;
int distance;
//_________________________________________________________ultrasonic sensor end
//_________________________________________________________alcohol sensor start
#define Sober 200   // Define max value that we consider sober
#define Drunk 400   // Define min value that we consider drunk
#define MQ3 1
float alcoholValue;  //variable to store sensor value
//_________________________________________________________alcohol sensor end
//_________________________________________________________touch sensor start 
const int touchPin = 7;
//_________________________________________________________touch sensor end
//_________________________________________________________temperature sensor start
#define temperaturePin A0
//_________________________________________________________temperature sensor end
//_________________________________________________________speaker and sd start
#include <pcmConfig.h>
#include <pcmRF.h>
#include <TMRpcm.h>
#include<SPI.h>
#include <SD.h>
#define SD_ChipSelectPin 4
TMRpcm tmrpcm;
//_________________________________________________________speaker and sd end
//_________________________________________________________motor start
int pushButton = 2; //button to control the motor with a physical button
int motorControl = 5;
//_________________________________________________________motor end

void setup() {
//generating random seed
  randomSeed(analogRead(4));
// initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
//_________________________________________________________ultrasonic sensor start 
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input
//_________________________________________________________alcohol sensor start
  Serial.println("mq3 is working");
//_________________________________________________________alcohol sensor end
//touchsensor start
  pinMode(touchPin, INPUT);
//_________________________________________________________touchsensor end
//_________________________________________________________speaker and sd start
  tmrpcm.speakerPin = 9;
  Serial.begin(9600);
  if (!SD.begin(SD_ChipSelectPin)){
    Serial.println("SD fail");
    return;
  } else {
    Serial.println("SD ok");
  }
  tmrpcm.setVolume(5);
//_________________________________________________________speaker and sd end
//_________________________________________________________motor start
// make the pushbutton's pin an input:
  pinMode(pushButton, INPUT);
// make the transistor's pin an output:
  pinMode(motorControl, OUTPUT);  
//_________________________________________________________motor end
}

void loop() {
//_________________________________________________________ultrasonic sensor start 
  // Clears the trigPin
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);
  // Calculating the distance
  distance = duration * 0.034 / 2;
  // Prints the distance on the Serial Monitor
  Serial.print("Distance: ");
  Serial.println(distance);
//_________________________________________________________ultrasonic sensor end
//user interaction will start if someone is close enough from the sensor. otherwise, the ultrasonic sensor will run on a loop waiting for someone to start.
//This ction also activates the motor.
if (distance <= 10){
  //play opening song
  tmrpcm.play("os1.wav");
  // ramp up the motor speed
  for(int x = 0; x <= 150; x++){

    analogWrite(motorControl, x);

    delay(50);

      }


      // ramp down the motor speed

  for(int x = 150; x >= 0; x--){

    analogWrite(motorControl, x);

    delay(50);

  }
  delay(20000);
  tmrpcm.play("os2.wav");
  delay(21000); 
  //play transition
  //tmrpcm.play("ts1.wav");
  //delay(15000); 
  while (touchSensor == false) {
    tmrpcm.play("ts3.wav");
    delay(5000); 
    int state = digitalRead(touchPin);
    // print state to Serial Monitor
    Serial.println("waiting for touch");
    Serial.println(state);
    touchSensor = true;
    tmrpcm.play("ts3.wav");
    delay(5000); 
  }  
  if (touchSensor == true){
    Serial.println("touched");
    //initiates once the person has touched it
    //randomizes between two sentences
    randNumber=random(10);
    if (randNumber < 5){
      Serial.println("random number:");
      Serial.println(randNumber);
      tmrpcm.play("ts4.wav");
      delay(7000);
    } else {
      tmrpcm.play("ts5.wav");
      Serial.println("random number:");
      Serial.println(randNumber);
      delay(7500);
    }
  }
  //moves on to alcohol sensor
    tmrpcm.play("tr1.wav");
    delay(12500); 
    tmrpcm.play("a1.wav");
    delay(5500); 
    //pause for the person to blow
    delay(5000);
//_________________________________________________________alcohol sensor start
    alcoholValue = analogRead(MQ3); // read analog input pin 0

    Serial.print("Sensor Value: ");

    Serial.print(alcoholValue);
    if (alcoholValue < Sober) {

      Serial.println("  |  Status: Sober");
      tmrpcm.play("a2.wav");
      delay(8000);

    } else if (alcoholValue >= Sober && alcoholValue < Drunk) {

      Serial.println("  |  Status: Drinking but within legal limits");
      tmrpcm.play("a3.wav");
      delay(10500);

    } else {

      Serial.println("  |  Status: DRUNK");
      //there are two audio options if the alcohol sensor detects if the person is drunk. they are randomized
        randNumber=random(10);
        Serial.println("random number:");
        Serial.println(randNumber);
      if (randNumber > 5){
        tmrpcm.play("a4.wav");
        delay(10000); 
      } else {
        tmrpcm.play("a5.wav");
        delay(11500);
      }

    }
    Serial.println("alcohol reading done");
  //_________________________________________________________alcohol sensor end
  //_________________________________________________________temperature sensor start
    //moves on to temperature sensor
    tmrpcm.play("tr2.wav");
    delay(10500); 
    delay(1500);
    // Get a reading from the temperature sensor:
    int reading = analogRead(temperaturePin);
    // Convert the reading into voltage:
    float voltage = reading * (5000 / 1024.0);
    // Convert the voltage into the temperature in degree Celsius:
    float temperature = (voltage / 10-32)*(5/9);
    // Print the temperature in the Serial Monitor:
    Serial.print(temperature);
    Serial.print(" \xC2\xB0"); // shows degree symbol
    Serial.println("C");
    //reading according to temperature level. there are four possible intervals and four possible answers
    if (temperature < 25) {

      Serial.println("  |  Status: Really Cold");
      tmrpcm.play("te1.wav");
      delay(18500);

    } else if (temperature >= 25 && temperature < 30) {

      Serial.println("  |  Status: Cold");
      tmrpcm.play("te2_1.wav");
      delay(4500);
      tmrpcm.play("te2_2.wav");
      delay(8500);

    } else if (temperature >= 30 && temperature < 35) {

      Serial.println("  |  Status: Hot");
      tmrpcm.play("te3.wav");
      delay(10500); 

    } else {

      Serial.println("  |  Status: Really Hot");
      tmrpcm.play("te4.wav");
      delay(15000);

    }
    //_________________________________________________________temperature sensor end
    delay (1500);
    //after the temperature sensor is done, the interaction is closed. closing sentence plays
    tmrpcm.play("cl1_1.wav");
    delay(17000);
    tmrpcm.play("cl1_2.wav");
    delay(4000);
    //motor plays once more
    for(int x = 0; x <= 150; x++){

    analogWrite(motorControl, x);

    delay(50);

      }


      // ramp down the motor speed

  for(int x = 150; x >= 0; x--){

    analogWrite(motorControl, x);

    delay(50);

  }
//portion of the code for motor testing, including physical button. inactive on main code
  /*motor start

    // read the state of the button and check if it is pressed

    if(digitalRead(pushButton) == HIGH){

      // ramp up the motor speed

      for(int x = 0; x <= 250; x++){

        analogWrite(motorControl, x);

        delay(50);

      }


      // ramp down the motor speed

      for(int x = 250; x >= 0; x--){

        analogWrite(motorControl, x);

        delay(50);

      }    

    }


    delay(1); 
    /motor end*/
  }
}