

// Agrivoltaika - skript na řízení natáčení panelů
// vytvořil: Milan Huf
// 20.5.2022

// připojení knihoven

#include <Servo.h>                                        // zahrnutí knihovny pro ovládání servo motoru
Servo myservo;                                            // definice proměnné pro servomotor

#include <Wire.h>
#include "RTClib.h"                                       // zahrnutí knihovny pro modul reálneho casu
RTC_DS1307 DS1307;                                        // vytvoření instalace DS1307 z knihovny RTClib


#define dioda1 A2                                         // deklarace analogového signálu z diody 1 
#define dioda2 A3                                         // deklarace analogového signálu z diody 2 
#define cidlo A1                                          // deklarace analogového signálu z modulu deště 
#define anemometr A0                                      // deklarace analogového signálu z anemometru 

int pos = 75;                                             // proměnná obsahující pozici motoru (úhel natočení)
int tolerance = 20;                                       // tolerance rozdílných hodnot analogových signálů z fotodiod
int c;                                                    // uložení hodin z modulu času do proměnné

void setup()
{
  Serial.begin(9600);                                     // nastavení komunikace přes sériovou linku 
  myservo.attach(9);                                      // připojení motoru na pin 9 Arduino desky
  pinMode(dioda1, INPUT);                                 // zadefinování pinu diody 1 jako vstupu 
  pinMode(dioda2, INPUT);                                 // zadefinování pinu diody 2 jako vstupu 
  myservo.write(pos);                                     // natočení motoru do výchozí pozice
  delay(500);                                             // časové zpoždění, než se motor natočí na daný úhel (v ms)
 
  DS1307.adjust(DateTime(2022, 4, 27, 22, 29, 00));       // nastavení počátečního data v pořadí rok, měsíc, den, hodina, minuta, vteřina
}

void loop() {
 
  int val1 = analogRead(dioda1);                          // uložení analogového signálu z diody 1 do proměnné
  int val2 = analogRead(dioda2);                          // uložení analogového signálu z diody 2 do proměnné
  int dest = analogRead(cidlo);                           // uložení analogového signálu z čidla deště do proměnné
  int vitr = analogRead(anemometr);                       // uložení analogového signálu z anemometru do proměnné
  float voltage = vitr * (5.0 / 1023.0);                  // přeočet analogového signálu na hodnotu generovaného napětí
  float rychlost_vetru = mapfloat(voltage, 0, 1, 0, 60);  // přepočet napětového signálu na ryhlost větru v km/h
  float rychlost_kmh = (rychlost_vetru * 3.6);            // přepočet rychlosti z m/s na km/h
  DateTime datumCas = DS1307.now();                       // načtení aktuálního času a data do proměnné datumCas
  c = datumCas.hour();
 
  
  // vypsání informací o aktuálním čase a datu do sériového monitoru
  
  Serial.print("Aktualni cas ");
  Serial.print(datumCas.hour());
  Serial.print(':');
  Serial.print(datumCas.minute());
  Serial.print(':');
  Serial.print(datumCas.second());
  Serial.print(", ");
  Serial.print(datumCas.day());
  Serial.print('.');
  Serial.print(datumCas.month());
  Serial.print('.');
  Serial.print(datumCas.year());
  Serial.println();

  // vypsání informací o rychlosti větru, intenzitě deště, pozici motoru a hodnot z obou fotodiod do sériového monitoru
  
  Serial.print("vitr = ");
  Serial.print(rychlost_kmh);
  Serial.print(" dest = ");
  Serial.print(dest);
  Serial.print(" pozice = ");
  Serial.print(pos);
  Serial.print(" dioda1 = ");
  Serial.print(val1);
  Serial.print(" dioda2 = ");
  Serial.println(val2);

 delay (200);                                      // pauza mezi výpisy dat v ms

 
// nastavení panelů do vodorovné polohy v případě vysoké rychlosti větru nebo intenzivního deště

  if (rychlost_kmh > 15 or dest < 100) {           // deklarace podmíek 
    pos = 80;                                      // deklarace vodorovné pozice
    myservo.write(pos);                            // nastavení úhlu natočení do požadované pozice
    delay(20); 
    }
  
  
  // nastavení úhlu natočení pro potřebu rostlin většího množství dopadajícího světla 
  
  else  {
    if ((c = 7) or (c = 8) or (c = 9) or (c = 10) or (c = 11) or (c = 14) or (c = 15) or (c = 16) or (c = 17) or (c = 18)) {   // nastavení hodin, kdy se mají panely do tohoto úhlu natočit
      myservo.write(pos+90);                                                                                                   // nastavení polohy (ideální + 90°)
      delay(600000);                                                                                                           // nastavení celkového času této akce
    }

 // sledování sluneční dráhy 
    
    if((abs(val1 - val2) <= tolerance) || (abs(val2 - val1) <= tolerance)) { 
  
        if(val1 > val2) {                         // porovnání hodnot signálů z diod, v případě překročení tolerance připočtení 1° k současné hodnotě natočení motoru
          pos = pos+1;
           }
        if(val1 < val2) {                         // porovnání hodnot signálů z diod, v případě překročení tolerance odečtení 1° k současné hodnotě natočení motor
          pos = pos-1; 
           }
         myservo.write(pos);
         delay(1); 
         }
       } 
  
  // nastavení koncové polohy otáčení motoru 
  
  if(pos > 175) { 
    pos = 175;                                    
    } 
  if(pos < 5)  {                                  
    pos = 5;
    } 

}
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)         // definice parametrů pro funkci mapfloat
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;                // funkce zaišťující přepočet z jednoho číselného rozsahu do druhého
}
