const byte OC1A_PIN = 11;
const byte OC1B_PIN = 12;

#include <EEPROM.h>

const word PWM_FREQ_HZ = 28000; //Adjust this value to adjust the frequency
const word TCNT1_TOP = 16000000/(2*PWM_FREQ_HZ);

#include <FastLED.h>
#define NUM_LEDS 4
#define DATA_PIN 34
CRGB leds[NUM_LEDS];

#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into analog pin 12 on the Arduino
#define ONE_WIRE_BUS A12
// Setup a oneWire instance to communicate with any OneWire device
OneWire oneWire(ONE_WIRE_BUS);
// Pass oneWire reference to DallasTemperature library
DallasTemperature sensors(&oneWire);

const int ledCount = 10;
int ledPins[] = {36,37,38,39,40,41,42,43,44,45};

int oninput = A15;
int SpeedDec = 33;
int SpeedInc = 35;
int Lighton = 32;
int Mainpower = 24;       //check for main power failure
int ShutterPos = A14;        //Potentiometer output for shutter position
int ShortTimer = 28;         //input from ATtiny timer for Short Timer
int LongTimer = 20;          //input from ATtiny timer for Long Timer

int PSUenable = 6;
int ShutterFwd = 3;
int ShutterRev = 5;
int Light1 = 2;
int Light2 = 4;
int HVrelay = 8;
int ShortTimerstart = 30;     //Power supply for Short Timer
int LongTimerstart = 22;      //Power supply for Long Timer
int Fanonoff = 10;            //Exhaust Fan on off Relay(30A)
int TouchPower1 = A8;
int TouchPower2 = A9;
int TouchPower3 = A10;
int TouchPower4 = A11;

int systemon1;
int systemon2;
int Potvalue;
int Touchplus;
int Touchminus;
int Lighttoggle;
int Mainpowerchk;
int Speedvalue;
int Lightvalue = 0;           //switch on with light off
int sensitivity = 0;
int ledpin = -1;
int delayTime = 700;
int pwm;
int LEDbar;
int leddisp;
int ledLevel;

const long sensinterval = 1200000;
const long offinterval = 1200000;
unsigned long prevsensMillis = 0;
unsigned long prevoffMillis = 0;
float tempC;
float avgtemp;
float sensor11;
float sensor22;
float sensor33;
int pwmOutput;
int deviceCount = 0;
//int automaticbit;
int autochk;

void setup() {
  // put your setup code here, to run once:
  pinMode(OC1A_PIN, OUTPUT);

  // Clear Timer1 control and count registers
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;
  TCCR1A |= (1 << COM1A1) | (1 << WGM11);
  TCCR1B |= (1 << WGM13) | (1 << CS10);
  ICR1 = TCNT1_TOP;
  
  Serial.begin(9600);

  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);

  for (int thisLed = 0; thisLed < ledCount; thisLed++) 
      {
        pinMode(ledPins[thisLed], OUTPUT);
      }
  
  pinMode(oninput, INPUT);
  pinMode(SpeedDec, INPUT);
  pinMode(SpeedInc, INPUT);
  pinMode(Lighton, INPUT);
  pinMode(Mainpower, INPUT);
  digitalWrite(Mainpower, LOW);
  pinMode(ShutterPos, INPUT);
  pinMode(ShortTimer, INPUT);
  pinMode(LongTimer, INPUT);
  
  pinMode(PSUenable, OUTPUT);   //also input for 12v 30A relay
  pinMode(ShutterFwd, OUTPUT);
  pinMode(ShutterRev, OUTPUT);
  pinMode(Light1, OUTPUT);
  pinMode(Light2, OUTPUT);
  pinMode(TouchPower1, OUTPUT);
  pinMode(TouchPower2, OUTPUT);
  pinMode(TouchPower3, OUTPUT);
  pinMode(TouchPower4, OUTPUT);
  pinMode(Fanonoff, OUTPUT);
  pinMode(HVrelay, OUTPUT); 
  pinMode(ShortTimerstart, OUTPUT);
  pinMode(LongTimerstart, OUTPUT);

  EEPROM.update(2, 10);      /*update EEPROM value 10 for auto 
                               when switching on for first time*/
  sensors.begin();  // Start up the library  
  // locate devices on the bus
  Serial.print("Locating devices...");
  Serial.print("Found ");
  deviceCount = sensors.getDeviceCount();
  Serial.print(deviceCount, DEC);
  Serial.println(" devices.");
  Serial.println("");

}

void loop()
  {
   digitalWrite(TouchPower1, HIGH);
   digitalWrite(TouchPower2, HIGH);
   digitalWrite(TouchPower3, HIGH);
   digitalWrite(TouchPower4, HIGH);
   Serial.println(systemon1);
   Serial.println(systemon2);
   delay (100);

   digitalWrite(PSUenable, LOW);
   digitalWrite(Light1, LOW);
   digitalWrite(Light2, LOW);
   digitalWrite(Fanonoff, LOW);
   digitalWrite(HVrelay, HIGH);

   Speedvalue = 2;
   Lightvalue = 0;   
     
     for (int thisLed = 0; thisLed < ledCount; thisLed++)
       {    
         if (thisLed < 10) 
           {
             digitalWrite(ledPins[thisLed], LOW);
           }
       }
   leds[0] = CRGB::Black;
   FastLED.show();
   leds[1] = CRGB::Black;
   FastLED.show();
   leds[2] = CRGB::Black;
   FastLED.show();
   leds[3] = CRGB::Red;
   FastLED.show();

   Potvalue = analogRead(ShutterPos);
   Serial.println(Potvalue);      

    /*  while (Potvalue < 1012)
        {
          digitalWrite(ShutterFwd, HIGH);
          Potvalue = analogRead(ShutterPos);
          Serial.println(Potvalue);
          delay(20);
        }
    
    digitalWrite(ShutterFwd, LOW); 
    */  
    systemon1 = digitalRead(oninput);
    systemon2 = digitalRead(oninput);

    while ((systemon1 == LOW)||(systemon2 == LOW))
        {
          leds[3] = CRGB::Red;
          FastLED.show();
          digitalWrite(LongTimerstart, LOW);     //Power supply for Long Timer
          digitalWrite(ShortTimerstart, LOW);   //Power supply off for Short timer
          systemon1 = digitalRead(oninput);
          Serial.println(systemon1);
          Serial.println("Off");
          delay(800);
          
             // Send command to all the sensors for temperature conversion
             sensors.requestTemperatures(); 
             // Display temperature from each sensor
              for (int i = 0;  i < deviceCount;  i++)
                 {
                   Serial.print("Sensor ");
                   Serial.print(i+1);
                   Serial.print(" : ");
                   tempC = sensors.getTempCByIndex(i);
                   Serial.print(tempC);
                   Serial.print("C  |  ");
                   Serial.print(DallasTemperature::toFahrenheit(tempC));
                   Serial.println("F");
                   if(i==0 && tempC>20)
                   sensor11 = tempC;
                   else if(i==1 && tempC>20)
                   sensor22 = tempC;
                   else if(i==2 && tempC>20)
                   sensor33 = tempC;
                 }
             avgtemp = ((sensor11 + sensor22 + sensor33)/3);
             Serial.print("Average Tempperature:");
             Serial.println(avgtemp);
             autochk = EEPROM.read(2);
             if((avgtemp > 32)&&(autochk == 10))
                {
                  goto skip_2;
                }          
          systemon2 = digitalRead(oninput);          
          Serial.println(systemon2);
        }
     skip_2:

     leds[0] = CRGB::Red;
     FastLED.show();
     leds[1] = CRGB::White;
     FastLED.show();
     leds[2] = CRGB::White;
     FastLED.show();
     leds[3] = CRGB::Green;
     FastLED.show();
     digitalWrite(PSUenable, HIGH);
     digitalWrite(Light1, LOW);
     digitalWrite(Light2, LOW);
     digitalWrite(Fanonoff, HIGH);
     digitalWrite(HVrelay, LOW);

     Potvalue = analogRead(ShutterPos);
     Serial.println(Potvalue);
     delay(1000);

    /* while (Potvalue > 780)
        {
         digitalWrite(ShutterRev, HIGH);
         Potvalue = analogRead(ShutterPos);
         Serial.println(Potvalue);
         delay(20);
        }
     digitalWrite(ShutterRev, LOW);
     delay(100);
     */

     setPwmDuty(37);
     Serial.println("Startup 37PWM");
     delay(2000);
     systemon1 = digitalRead(oninput);
     systemon2 = digitalRead(oninput);

     if ((systemon1 == LOW)&&(systemon2 == LOW))
        {
          while ((systemon1 == LOW)||(systemon2 == LOW))
              {
                systemon1 = digitalRead(oninput);
                unsigned long currsensMillis = millis();
                unsigned long curroffMillis = millis();

                Mainpowerchk = digitalRead(Mainpower);
                Serial.print("Mainpowerchk");
                Serial.println(Mainpowerchk);
                  if (Mainpowerchk == 1)
                     {
                       Serial.println("Main power cut");
                       EEPROM.update(2, 20);    //update EEPROM value 2 to 20 so as to
                                                //prevent automatically switching on 
                                                //unit if temp is higher than 35C
                       goto skip_1;
                     }

                  for (int i = 0;  i < deviceCount;  i++)
                     {
                       Serial.print("Sensor ");
                       Serial.print(i+1);
                       Serial.print(" : ");
                       tempC = sensors.getTempCByIndex(i);
                       Serial.print(tempC);
                       Serial.print("C  |  ");
                       Serial.print(DallasTemperature::toFahrenheit(tempC));
                       Serial.println("F");
                       if(i==0 && tempC>20)
                       sensor11 = tempC;
                       else if(i==1 && tempC>20)
                       sensor22 = tempC;
                       else if(i==2 && tempC>20)
                       sensor33 = tempC;
                      }
                   avgtemp = ((sensor11 + sensor22 + sensor33)/3);
                   Serial.print("Average Tempperature:");
                   Serial.println(avgtemp);
                   pwm = map (constrain(avgtemp, 28, 50), 28, 50, 33, 86);
                   Touchplus = digitalRead(SpeedInc);
                   Touchminus = digitalRead(SpeedDec);
                   
                   if(Touchplus == HIGH)
                     {                          
                       while(Touchplus == HIGH)
                        {
                         sensitivity=sensitivity+2;
                           if (sensitivity == 12)
                             {
                               sensitivity = 10;
                             }
                         leddisp = sensitivity;
                         for (int thisLed = 0; thisLed < ledCount; thisLed++)
                           {
                             if (thisLed < leddisp) 
                               {                                
                                 digitalWrite(ledPins[thisLed], HIGH);
                               }
                                 else 
                               { 
                                 digitalWrite(ledPins[thisLed], LOW);
                               }
                           }
                          Touchplus = digitalRead(SpeedInc);
                          Serial.print("sensitivity:+");
                          Serial.println(sensitivity);
                          delay(1000);
                         }
                       prevsensMillis = currsensMillis;
                      }
                    if(Touchminus == HIGH)
                       {                          
                         while(Touchminus == HIGH)
                          {
                            sensitivity=sensitivity-2;
                             if (sensitivity == -2)
                               {
                                 sensitivity = 0;
                               }
                            leddisp = sensitivity;
                            for (int thisLed = 0; thisLed < ledCount; thisLed++)
                              {
                                if (thisLed < leddisp) 
                                  {                                
                                    digitalWrite(ledPins[thisLed], HIGH);
                                  }
                                    else 
                                  { 
                                    digitalWrite(ledPins[thisLed], LOW);
                                  }
                              }                           
                            Touchminus = digitalRead(SpeedDec);
                            Serial.print("sensitivity:-");
                            Serial.println(sensitivity);
                            delay(1000);
                           }
                         prevsensMillis = currsensMillis;
                        }
                                           
                   if(sensitivity == 0)
                      {
                        prevsensMillis = currsensMillis;
                      }
                   if (currsensMillis - prevsensMillis >= sensinterval)
                      {
                        Serial.println("interval exceeded");
                        sensitivity = 0;
                        prevsensMillis = currsensMillis;
                      } 
                                                           
                   Serial.print("sensitivity:");
                   Serial.println(sensitivity);                   
                   pwmOutput = pwm+sensitivity;
                   setPwmDuty(pwmOutput);           // output PWM to fan pin 11,12
                   ledLevel = map (pwmOutput, 33, 86, 1, 10);
                   if(ledLevel != 1)
                      {
                        prevoffMillis = curroffMillis;
                      }
                   if (curroffMillis - prevoffMillis >= offinterval)
                      {
                        EEPROM.update(2, 20);    //update EEPROM value 2 to 20 so as to
                                                //prevent automatically switching on 
                                                //unit if temp is higher than 35C
                         Serial.print("off timer");
                         goto skip_1;                        
                      }
                   for(int i = 0; i <= ledLevel-1; i++)
                      {
                        digitalWrite(ledPins[i], HIGH);    
                      }
                   for(int i = ledLevel; i <= ledCount; i++)
                      {
                        digitalWrite(ledPins[i], LOW);    
                      }
                   ledpin=ledpin+1;
                   if (ledpin == ledLevel)     
                      {        
                        ledpin = ledLevel-1; 
                        if (ledpin == ledLevel-1)
                           {
                             ledpin = -1;
                           }
                      }
                   digitalWrite(ledPins[ledpin], LOW);
                   delay(delayTime);
                   Serial.print("pwmOutput:");
                   Serial.println(pwmOutput);
                   Serial.print("ledLevel:");
                   Serial.println(ledLevel);
                   Serial.println("");

                   Lighttoggle = digitalRead(Lighton);
              
                   if (Lighttoggle == HIGH)
                     {
                        {
                         Lightvalue = Lightvalue + 1;
                         if (Lightvalue == 4)
                             {
                              Lightvalue = 0;
                             }                    
                         }
                     switch (Lightvalue)
                          {
                           case 0:                        
                           digitalWrite(Light1, LOW);
                           digitalWrite(Light2, LOW);
                           leds[0] = CRGB::Red;
                           FastLED.show();
                           Serial.println("Light 0");
                           delay (1000);
                           break;
                           case 1:
                           digitalWrite(Light1, HIGH);
                           digitalWrite(Light2, LOW);
                           leds[0].setRGB(130,255,130);
                           FastLED.show();
                           Serial.println("Light 1");
                           delay (1000);
                           break;
                           case 2:
                           digitalWrite(Light1, LOW);
                           digitalWrite(Light2, HIGH);
                           leds[0].setRGB(51,255,51);
                           FastLED.show();
                           Serial.println("Light 2");
                           delay (1000);
                           break;
                           case 3:
                           digitalWrite(Light1, HIGH);
                           digitalWrite(Light2, HIGH);
                           leds[0].setRGB(0,255,0);
                           FastLED.show();
                           Serial.println("Light 3");
                           delay (1000);
                           break;                       
                          }
                      }

                systemon2 = digitalRead(oninput);
              }
        }
      skip_1:
      ; 
  }

void setPwmDuty(byte duty) 
  {
    OCR1A = (word) (duty*TCNT1_TOP)/100;
  }