Sonnen Tracker Arduino

Warum da? In #160 war er doch in der Funktion, die anderen hast Du doch auch da wieder hingebaut.

Ansonsten musst Du sehen, ob jetzt die Ausgabe mit der geplanten Umlaufzeit stimmt... :wink:

1 Like

So jetzt sieht es schon etwas besser aus:

15:27:38.906 -> Windgeschwindigkeit: 0.00 Km/h
15:27:38.906 -> Werte durchzaehlen:
15:27:38.953 -> 0	0	0	0	0	
15:27:38.953 -> LDRol:0 LDRor:0
15:27:38.953 -> LDRul:0 LDRur:0
15:27:39.006 -> LDRol2:0 LDRor2:0
15:27:39.006 -> GWO:0 GWU:0
15:27:39.006 -> GWL:0 GWR:0
15:27:39.053 -> Diff O & U:0 Diff L & R:0
15:27:39.053 -> LDR links Fix:0 LDR rechts Fix:0
15:27:39.107 -> Relais 1:0 Relais 2:1
15:27:39.107 -> Relais 3:0 Relais 4:1
15:27:39.153 -> Endschalter1VEVS:0
15:27:39.153 -> Endschalter2VEHS:0 Endschalter2VEOOE:0
15:27:39.207 -> Endschalter3HEVS:0
15:27:39.254 -> Endschalter4HEHS:0 Endschalter4HEHOE:0
15:27:39.254 -> Sturm Ausgelöst:0
15:27:39.307 -> 0

Und das mit dem int wind habe ich auch korrigiert!

// Forensketch - Sonnentracker Arduino
// basiert auf: https://forum.arduino.cc/t/sonnen-tracker-arduino/859643/137
// noch keine Endlösung - kompiliert fehler und warnungsfrei 15.01.2022

// Begin Variablen Wind
bool windAusgeloest = false;
const byte anemometerPin = 2;  //Definierter Interrupt Pin (2 oder 3 beim Arduino Uno)
volatile unsigned long windCounter;
float Windgeschwindigkeit;

const unsigned long messZeit = 2000; //Messzeit in ms
const byte windSchwelle = 25; // km/h
const byte sturmSchwelle = 35; // km/h
const unsigned long umlaufZeit = 10000; // 10 Sekunden
byte umlaufMerker[umlaufZeit / messZeit]; // Anzahl der benötigten Elemente des Array errechnet sich aus den Zeiten
// End Variablen Wind

// Begin Variablen SolarPanel
unsigned int OL, OR, UL, UR = 0;
unsigned int OL2, OR2 = 0;
unsigned int GWO, GWU, GWL, GWR = 0;
unsigned int LFix, RFix = 0;
unsigned int DVERT, DHORIZ = 0;
bool Endschalter1VEVSStatus = false;
bool Endschalter2VEHSStatus = false;
bool Endschalter2VEOOEStatus = false;
bool Endschalter3HEVSStatus = false;
bool Endschalter4HEHSStatus = false;
bool Endschalter4HEHOEStatus = false;

// Sonnen Verfolgung Vertikal und Horizontal v10.6 vom 25.10.2021

const byte Endschalter1VEVS = 3; // Vertikal Endschalter vorne, schließer
const byte Endschalter2VEHS = 4; // Vertikal Endschalter hinten, schließer
const byte Endschalter2VEOOE = 5; // Vertikal Endschalter hinten, öffner

const byte Relais1pin = 6; // Relais 1 für Vertikale Achse, Zylinder ausfahren
const byte Relais2pin = 7; // Relais 2 für Vertikale Achse, Zylinder einfahren

const byte Endschalter3HEVS = 8; // Horizontal Endschalter vorne, schließer
const byte Endschalter4HEHS = 9; // Horizontal Endschalter hinten, schließer
const byte Endschalter4HEHOE = 10; // Horizontal Endschalter hinten, öffner

const byte Relais3pin = 11; // Relais 3 für Horizontal Achse, Zylinder ausfahren
const byte Relais4pin = 12; // Relais 4 für Horizontal Achse, Zylinder einfahren

// LDR Stiftverbindungen am Analogpin, LDR5528, GL5528, 0,5-200kOhm, 5mm
const byte LDRol = A0; // LDR oben links
const byte LDRor = A1; // LDR oben rechts
const byte LDRul = A2; // LDR unten links
const byte LDRur = A3; // LDR unten rechts
const byte LDRol2 = A4; // LDR oben links 2
const byte LDRor2 = A5; // LDR oben rechts 2

// Feste Werte
const unsigned int START = 300; // Wert ab wann das Programm wieder Startet (jeder Einzelner LDR)
const unsigned int TOLV = 170; // Wert, ab wann die Position Veretikal geändert werden soll (Toleranz)
const unsigned int TOLH = 150; // Wert, ab wann die Position Horizontal geändert werden soll (Toleranz)
const unsigned int ENDEV = 10; // Wert zum Beenden der Ausrichtung Vertikal
const unsigned int ENDEH = 20; // Wert zum Beenden der Ausrichtung Horizontal
const unsigned int NACHT = 55; // Wert ab wann die Linearmotoren in Startposition fahren (Progamm bei Dunkelheit beendet, jeder Einzelner LDR)
const unsigned int HFix = 50; // Wert zum Abgleichen der LDR oben links, LDR oben links 2 und LDR oben rechts, LDR oben rechts 2
// End Variablen SolarPanel


void setup ()
{
  // Setup Wind
  pinMode(anemometerPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(anemometerPin), countup, RISING);
  Windmessung(messZeit);
  // Setup Solar
  pinMode(Endschalter1VEVS, INPUT); // Pin Modus definieren, Eingang, schließer
  pinMode(Endschalter2VEHS, INPUT); // Pin Modus definieren, Eingang, schließer
  pinMode(Endschalter2VEOOE, INPUT); // Pin Modus definieren, Eingang, öffner
  pinMode(Relais1pin, OUTPUT); // Pin Modus definieren, Ausgang
  pinMode(Relais2pin, OUTPUT); // Pin Modus definieren, Ausgang
  pinMode(Endschalter3HEVS, INPUT); // Pin Modus definieren, Eingang, schließer
  pinMode(Endschalter4HEHS, INPUT); // Pin Modus definieren, Eingang, schließer
  pinMode(Endschalter4HEHOE, INPUT); // Pin Modus definieren, Eingang, öffner
  pinMode(Relais3pin, OUTPUT); // Pin Modus definieren, Ausgang
  pinMode(Relais4pin, OUTPUT); // Pin Modus definieren, Ausgang
  Serial.begin(9600); // Serielle Schnittstelle initialisieren
}

void loop ()
{
  readPanelSensors();
  getWindSensors();
  // Ausrichtung bei Helligkeit, Wert "START"
  if ((OL > START) && (OR > START) && (UL > START) && (UR > START) && (OL2 > START) && (OR2 > START) && windAusgeloest == false)// LDR's alle über "START"
  {
    if (DVERT > TOLV) // "DVERT" größer "TOLV" Wert und Wind den Schwellwert nicht erreicht hat
    {
      // Vertikalachse ausrichten, Linearmotor 3000N 200mm
      if ((GWO < GWU) && ((Endschalter2VEHSStatus == LOW) || (Endschalter2VEOOEStatus == HIGH))) // Oben heller wie unten, Endschalter 2 schließer und öffner nicht betätigt
      {
        digitalWrite(Relais1pin, HIGH); // Zylinder ausfahren
        digitalWrite(Relais2pin, LOW); // Relais2 deaktivieren
      }
      else if ((GWO > GWU) && (Endschalter1VEVSStatus == LOW)) // Oben dunkler wie unten, Endschalter 1 schließer nicht betätigt ist
      {
        digitalWrite(Relais1pin, LOW); // Relais1 deaktivieren
        digitalWrite(Relais2pin, HIGH); // Zylinder einfahren
      }
    }
    // Vertikalachse ausrichten abgeschlossen und die Relais 1 und 2 deaktivieren
    if (DVERT <= ENDEV) // Oben und unten gleich hell sind oder eine max. Differnz von "ENDEV" haben
    {
      digitalWrite(Relais1pin, LOW); // Relais1 deaktivieren
      digitalWrite(Relais2pin, LOW); // Relais2 deaktivieren
    }
    else if (((Endschalter2VEHSStatus == HIGH) || (Endschalter2VEOOEStatus == LOW)) && (digitalRead(Relais1pin) == HIGH) && (digitalRead(Relais2pin) == LOW)) // Endschalter 2 schließer und öffner betätigt, Relais 1 betätigt und Relais 2 aus
    {
      digitalWrite(Relais1pin, LOW); // Relais1 deaktivieren
      digitalWrite(Relais2pin, LOW); // Relais2 deaktivieren
    }
    else if ((Endschalter1VEVSStatus == HIGH) && (digitalRead(Relais1pin) == LOW) && (digitalRead(Relais2pin) == HIGH)) // Endschalter 1 schließer betätigt, Relais 1 aus und Relais 2 betätigt ist
    {
      digitalWrite(Relais1pin, LOW); // Relais1 deaktivieren
      digitalWrite(Relais2pin, LOW); // Relais2 deaktivieren
    }
    // Horizontalachse ausrichten, Linearmotor 3000N 100mm
    if (DHORIZ > TOLH) // "DHORIZ" größer "TOLH" Wert
    {
      if ((LFix < HFix) && (RFix < HFix)) // LDR links oben und LDR links oben 2 subtrahiert, kleiner als HFix und LDR rechts oben und LDR rechts oben 2 subtrahiert, kleiner als HFix
      {
        if ((GWL > GWR) && ((Endschalter4HEHSStatus == LOW) || (Endschalter4HEHOEStatus == HIGH))) // Rechts heller wie links, Endschalter 4 schließer und öffner nicht betätigt
        {
          digitalWrite(Relais3pin, HIGH); // Zylinder ausfahren
          digitalWrite(Relais4pin, LOW); // Relais4 deaktivieren
        }
        else if ((GWL < GWR) && (Endschalter3HEVSStatus == LOW)) // Rechts dunkler wie links, Endschalter 3 schließer nicht betätigt
        {
          digitalWrite(Relais3pin, LOW); // Relais3 deaktivieren
          digitalWrite(Relais4pin, HIGH); // Zylinder einfahren
        }
      }
    }
    // Horizontalachse ausrichten abgeschlossen und die Relais 3 und 4 deaktivieren
    if (DHORIZ <= ENDEH) // Oben und unten gleich hell sind oder eine max. Differnz von "ENDEH" haben
    {
      digitalWrite(Relais3pin, LOW); // Relais3 deaktivieren
      digitalWrite(Relais4pin, LOW); // Relais4 deaktivieren
    }
    else if (((Endschalter4HEHSStatus == HIGH) || (Endschalter4HEHOEStatus == LOW)) && (digitalRead(Relais3pin) == HIGH) && (digitalRead(Relais4pin) == LOW)) // Endschalter 4 schließer und öffner betätigt, Relais 3 betätigt und Relais 4 aus
    {
      digitalWrite(Relais3pin, LOW); // Relais3 deaktivieren
      digitalWrite(Relais4pin, LOW); // Relais4 deaktivieren
    }
    else if ((Endschalter3HEVSStatus == HIGH) && (digitalRead(Relais3pin) == LOW) && (digitalRead(Relais4pin) == HIGH)) // Endschalter 3 schließer betätigt, Relais 3 aus und Relais 4 betätigt ist
    {
      digitalWrite(Relais3pin, LOW); // Relais3 deaktivieren
      digitalWrite(Relais4pin, LOW); // Relais4 deaktivieren
    }
  }
  // Grundstellung
  // bei Dunkelheit, Wert "NACHT"
  // oder bei Wind
  if (((OL < NACHT) && (OR < NACHT) && (UL < NACHT) && (UR < NACHT)) // LDR's alle unter "NACHT"
      || windAusgeloest)
  {
    if (!Endschalter1VEVSStatus)// Endschalter 1 schließer nicht betätigt, fährt die Vertikalachse in die Startposition
    {
      digitalWrite(Relais1pin, LOW); // Relais1 deaktivieren
      digitalWrite(Relais2pin, HIGH); // Zylinder einfahren, Vertikal
    }
    else
    {
      digitalWrite(Relais1pin, LOW); // Relais1 deaktivieren
      digitalWrite(Relais2pin, LOW); // Relais2 deaktivieren
    }
    if (!windAusgeloest)
    {
      if (!Endschalter3HEVSStatus) // Endschalter 3 schließer nicht betätigt, fährt die Horizontalachse in die Startposition
      {
        digitalWrite(Relais3pin, LOW); // Relais3 deaktivieren
        digitalWrite(Relais4pin, HIGH); // Zylinder einfahren, Horizontal
      }
      else
      {
        digitalWrite(Relais3pin, LOW); // Relais3 deaktivieren
        digitalWrite(Relais4pin, LOW); // Relais4 deaktivieren
      }
    }
  }
  serialMonitor();
}

void getWindSensors()
{
  //Ausgabe der Windwerte
  static unsigned long lastprint;
  static unsigned long lastausloeser = 0;
  const unsigned long sperrZeit = 1000UL * 60 * 15; // Wind Sperrzeit 15 Min.
  if (millis() - lastprint >= messZeit)
  {
    lastprint = millis();
    Serial.print("Windgeschwindigkeit: ");
    Serial.print(Windgeschwindigkeit); // Ausgabe der Windgeschwindigkeit in Km/h
    Serial.println(" Km/h");
  }
  Windmessung(messZeit);
  if (Auswertung(umlaufZeit))
  {
    Serial.println(F("Wind ausgelöst"));
    // Hier merken, das ausgelöst wurde:
    windAusgeloest = true;
    lastausloeser = millis();
    Serial.println(F("Auslöser gemerkt"));
  }
  if (windAusgeloest)
  {
    if (millis() - lastausloeser >= sperrZeit)
    {
      windAusgeloest = false;
      Serial.println(F("Ausloeser geloescht"));
    }
  }
}

bool Auswertung(unsigned long intervall)
{
  static unsigned long lastmillis = 0;
  unsigned int wind = 0;
  unsigned int sturm = 0;
  bool ausloeser = false;
  if (millis() - lastmillis >= intervall)
  {
    Serial.println(F("Werte durchzaehlen:"));
    for (byte i = 0; i < sizeof(umlaufMerker); i++)
    {
      if (umlaufMerker[i] >= windSchwelle) wind++;
      if (umlaufMerker[i] >= sturmSchwelle) sturm++;
      Serial.print(umlaufMerker[i]);
      Serial.print("\t");
    }
    Serial.println();
    lastmillis = millis();
  }
  if ((wind >= 3) || (sturm >= 2))
  {
    ausloeser = true;
  }
  return ausloeser;
}

void Windmessung(unsigned long intervall) // Initalisierung und Berechnung für die Windgeschwindigkeit
{
  static unsigned long lastMessung = 0;
  static unsigned int elementeZaehler = 0;
  if (millis() - lastMessung >= intervall)
  {
    detachInterrupt(digitalPinToInterrupt(anemometerPin));
    Serial.println(windCounter);
    Windgeschwindigkeit = (float)(windCounter * 1.2) / (float)((millis() - lastMessung) / 1000);
    windCounter = 0;
    lastMessung = millis();
    attachInterrupt(digitalPinToInterrupt(anemometerPin), countup, RISING);
    umlaufMerker[elementeZaehler] = (int)Windgeschwindigkeit;
    elementeZaehler++;
    if (elementeZaehler > (sizeof(umlaufMerker))) elementeZaehler = 0;
  }
}

void countup() // Zähler für die Impulse des Reed Kontakt
{
  windCounter++;
}

void readPanelSensors()
{
  OL = analogRead (0) * 1.0; // Oben links, Faktor 1.0 anpassen, wenn die Widerstände sehr unterschiedlich sind
  OR = analogRead (1) * 1.0; // Oben rechts, Faktor 1.0 anpassen, wenn die Widerstände sehr unterschiedlich sind
  UL = analogRead (2) * 1.0; // Unten links, Faktor 1.0 anpassen, wenn die Widerstände sehr unterschiedlich sind
  UR = analogRead (3) * 1.0; // Unten rechts, Faktor 1.0 anpassen, wenn die Widerstände sehr unterschiedlich sind
  OL2 = analogRead (4) * 1.0; // Oben links 2, Faktor 1.0 anpassen, wenn die Widerstände sehr unterschiedlich sind
  OR2 = analogRead (5) * 1.0; // Oben rechts 2, Faktor 1.0 anpassen, wenn die Widerstände sehr unterschiedlich sind
  GWO = (OL + OR); // Gesamtwert oben
  GWU = (UL + UR); // Gesamtwert unten
  GWL = (OL + UL); // Gesamtwert links
  GWR = (OR + UR); // Gesamtwert rechts
  LFix = abs((int)OL - (int)OL2); // Oben links - oben  links 2, immer Positiv setzen
  RFix = abs((int)OR - (int)OR2); // Unten rechts - unten rechts 2, immer Positiv setzen
  DVERT = abs((int)GWO - (int)GWU); // Überprüfen der Diffirenz zwischen oben und unten, Vertikal, immer Positiv setzen
  DHORIZ = abs((int)GWL - (int)GWR); // Überprüfen der Diffirenz zwischen links und rechts, Horizontal, immer Positiv setzen
  Endschalter1VEVSStatus = digitalRead(Endschalter1VEVS); // Zustand des Endschalter Vertikal vorne, schließer
  Endschalter2VEHSStatus = digitalRead(Endschalter2VEHS); // Zustand des Endschalter Vertikal hinten, schließer
  Endschalter2VEOOEStatus = digitalRead(Endschalter2VEOOE); // Zustand des Endschalter Vertikal hinten, öffner
  Endschalter3HEVSStatus = digitalRead(Endschalter3HEVS); // Zustand des Endschalter Horizontal vorne, schließer
  Endschalter4HEHSStatus = digitalRead(Endschalter4HEHS); // Zustand des Endschalter Horizontal hinten, schließer
  Endschalter4HEHOEStatus = digitalRead(Endschalter4HEHOE); // Zustand des Endschalter Horizontal hinten, öffner
}


void serialMonitor()
{
  // Die 4 LDR Werte, Berechnung der Helligkeitswerte, Relais und die Endschalterzustände zu Testzwecken an den PC übertragen
  static unsigned long lastprint;
  if (millis() - lastprint > 10000) // Testausgabe alle 10s
  {
    lastprint = millis();
    Serial.print("LDRol:"); Serial.print(OL); // LDR oben links
    Serial.print(" LDRor:"); Serial.println(OR); // LDR oben rechts
    Serial.print("LDRul:"); Serial.print(UL); // LDR unten links
    Serial.print(" LDRur:"); Serial.println(UR); // LDR unten rechts
    Serial.print("LDRol2:"); Serial.print(OL2); // LDR oben links 2
    Serial.print(" LDRor2:"); Serial.println(OR2); // LDR oben rechts 2
    Serial.print("GWO:"); Serial.print(GWO); // Gesamtwert oben
    Serial.print(" GWU:"); Serial.println(GWU); // Gesamtwert unten
    Serial.print("GWL:"); Serial.print(GWL); // Gesamtwert links
    Serial.print(" GWR:"); Serial.println(GWR); // Gesamtwert rechts
    Serial.print("Diff O & U:"); Serial.print(DVERT); // Diffirenze zwischen oben und unten
    Serial.print(" Diff L & R:"); Serial.println(DHORIZ); // Diffirenze zwischen links und rechts
    Serial.print("LDR links Fix:"); Serial.print(LFix); // Diffirenze zwischen links und links 2
    Serial.print(" LDR rechts Fix:"); Serial.println(RFix); // Diffirenze zwischen rechts und rechts 2
    Serial.print("Relais 1:"); Serial.print(digitalRead(Relais1pin)); // Zustand Relais 1
    Serial.print(" Relais 2:"); Serial.println(digitalRead(Relais2pin)); // Zustand Relais 1
    Serial.print("Relais 3:"); Serial.print(digitalRead(Relais3pin)); // Zustand Relais 1
    Serial.print(" Relais 4:"); Serial.println(digitalRead(Relais4pin)); // Zustand Relais 1
    Serial.print("Endschalter1VEVS:"); Serial.println(Endschalter1VEVSStatus); // Endschalter 1 schließer
    Serial.print("Endschalter2VEHS:"); Serial.print(Endschalter2VEHSStatus); // Endschalter 2 schließer
    Serial.print(" Endschalter2VEOOE:"); Serial.println(Endschalter2VEOOEStatus); // Endschalter 2 öffner
    Serial.print("Endschalter3HEVS:"); Serial.println(Endschalter3HEVSStatus); // Endschalter 3 schließer
    Serial.print("Endschalter4HEHS:"); Serial.print(Endschalter4HEHSStatus); // Endschalter 4 schließer
    Serial.print(" Endschalter4HEHOE:"); Serial.println(Endschalter4HEHOEStatus); // Endschalter 4 öffner
    Serial.print("Sturm Ausgelöst:"); Serial.println(windAusgeloest); // Sturm aufgelöst
  }
}
1 Like