#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>
Adafruit_ADXL345_Unified BSens=Adafruit_ADXL345_Unified(1);
uint8_t r_l, auf_led=1;
const uint8_t g_led=7;                              //Gesamte Anzahl LED´s
const uint8_t g_lz=30;                              //Gesamtlaufzeit: 30 Sekunden
const uint32_t dt_1=g_lz/3*1000-1, dt_2=dt_1*2+1, dt_3=dt_1*3+2; //Zeitintervalle berechnen
uint8_t ds_w;                                       //Drehschalterstellung
const uint8_t ds_l=8, ds_m=185, ds_s=255;           //Kalibrierte Drehschalterwerte
uint32_t start_zeit=0, d_zeit=0;
boolean r_l1, r_l2, r_l3;                           //Kontrollen für 10-Sekundentakt
const float d_x=-11.07, d_y=0.30, d_z=-1.51;        //Kalibrierte Mittelwerte
float d_xyz;                                        //Abweichungstoleranz
float b_x, b_y, b_z;

void setup() {
  /*
   *              Belegung der digitalen Pins:
   * 
   * Pin 2 als Eingang für Startknopf (Öffner!) mit aktivem Pull-up Widerstand
   * Pin 3 für Buzzer
   * Pins 4-6 für Restzeitanzeige
   * Pins 7-13 für Status der Anzahl der ausgelösten Erschütterungen
   */
  BSens.begin();
  for (uint8_t i=3; i<14; i++){
    pinMode(i, OUTPUT);
  }
  pinMode(2, INPUT_PULLUP);
}
void loop() {
  // Rücksetzen aller LED´s
   for (uint8_t i=4; i<14; i++){
    if (i<7){
      digitalWrite(i, HIGH);          // Einschalten der Zeit-Led´s
    }
    else {                            
      digitalWrite(i, LOW);           // Ausschalten der Erschütterungs-Led´s
    }
   }
   r_l=6;                             // Rücksetzen des Zeit-Led-Zählers
   auf_led=6;                         // Rücksetzen des Aufwachzählers
   r_l1=true;                         // Setzen
   r_l2=true;                         // der
   r_l3=true;                         // 10-Sekundenmarken
   noTone(3);
      if (digitalRead(2) == HIGH) {     // LOW setzen, wenn ein Schließtaster verwendet wird!
      ds_w=analogRead(A0);
      if (ds_w>ds_s-20) {d_xyz=1.1;}                  //schwer
      if (ds_w>ds_m-20 && ds_w<ds_m+20) {d_xyz=1.3;}  //mittel
      if (ds_w<ds_l+20) {d_xyz=2.0;}                  //leicht
      start_zeit=millis();
      for(uint8_t j = 1; j <= 3; j++) { // Start-Töne
         tone(3,100);  
         delay(400); 
         noTone(3);
         delay(50);    
      }
      tone(3,600);
      delay(400);
      noTone(3);
      do {
        sensors_event_t event;
        BSens.getEvent(&event);
        b_x=event.acceleration.x;
        delay(5);
        b_y=event.acceleration.y; 
        delay(5);
        b_z=event.acceleration.z;   
        delay(5);
        //Weichen Sensorwerte zu stark ab?
        if (abs(d_x-b_x)>d_xyz || abs(d_y-b_y)>d_xyz || abs(d_z-b_z)>d_xyz){
          auf_led+=1;
          digitalWrite(auf_led,HIGH);
        }
        delay(200);
        d_zeit=millis()-start_zeit;   
        if (d_zeit>dt_1 && r_l1){  //10 Sekunden abgelaufen
          r_l1=false;
          digitalWrite(r_l, LOW);
          r_l-=1;            
        }
        if (d_zeit>dt_2 && r_l2){  //20 Sekunden abgelaufen
          r_l2=false;
          digitalWrite(r_l, LOW);
          r_l-=1;            
        } 
        if (d_zeit>dt_3){          //Zeit abgelaufen
          r_l3=false;
          digitalWrite(r_l, LOW);
         }  
      }
      while (r_l3 && auf_led<13);
      if (!r_l3){                  //Zeitlimit geschafft!!  
        for (uint8_t l=7; l<14; l++){
          digitalWrite(l, LOW);      
        }
        for (uint8_t i=1; i<3; i++) {
          for(uint16_t j = 200; j <= 800; j++) {
            tone(3,j);  
            delay(5);     
         }
          for (uint8_t k=4; k<14; k++){
            digitalWrite(k, HIGH);          
            delay(200);
            digitalWrite(k, LOW);
          }
        }
       } 
      else {                          //Zeitlimit nicht geschafft
        for(uint16_t j = 800; j >= 200; j--) {
           tone(3,j);
           delay(10);
        }       
      }
   }
}

