Solartracker zwei Achsen, mit Lichtsensoren

Benutzeravatar
Admin
Administrator
Beiträge: 1197
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Die Position der Sonne mit Sensoren bestimmen

Beitrag von Admin »

In dem Programm gibt es Teile, die übergreifend, aber auch gegeneinader arbeiten können, wenn da ein kleiner Logik-Fehler im Programm ist. Also der eine Teil vergleicht die Helligkeit von zwei Sensoren, verändert auf Grund dieser Daten die Stellung des Panels und wenn die sich durch die Stellungsveränderung dess Panels angeglichen haben, sagt dieser Programmteil über einen Merker (Kontrolle) dass dieser Teil nicht mehr verändert werden muss. Das sind 4 Merker für die 4, oder eigentlich 8 Licht-Sensoren. In einem anderen Programmteil kontrolliert das Programm, ob sich diese Werte wieder um mehr als 100 Punkte verändert haben, dann gibt es die Nachjustierung für den anderen Programmteil über den "Kontrolle" Merker 1-4 wieder frei. Dann wird im Einstellprogramm wieder nachjustiert, wenn das wieder gut justiert ist, sagt dieser Teil dem "Kontrolle" Merker wieder alles klar und stopp, keine Verstellung mehr. u.s.w.

Da kann man ganz schnell eine richtige Korrektur unmöglich machen, wenn die beiden Teile nicht korrekt ineinander greifen, sondern gegeneinander Arbeiten. Das war richtig Stressig. Ich habe mehr als einen Tag mit diesem Problem verbracht. Ich musste alle Messdaten und alle Reaktionen darauf per Serial.print() auf meinen Monitor bringen, diese Daten, von einer einzigen Fahrt mehrere Din.A4 Seiten am Drucker, auf Papier bringen, und mich dann lange Zeit in eine stille Ecke verziehen, um in Ruhe jeden kleinen Pfurz (jede Zeile des Ausdruckes) anhand des Steuer-Programmes nachzuvollziehen.

Das ist richtig Arbeit. Was der Arduino in 30 Sekunden alles macht, ein ganzer Datensatz wird in etwa 80ms produziert, muss dann analisiert werden, warum die Krücke das macht, was sie macht. Das ist seeeeeeehr mühsam. :O: ....und man möchte am liebsten das ganze Ding in die Tonne tretten. :xx:
Benutzeravatar
Admin
Administrator
Beiträge: 1197
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Die Position der Sonne mit Sensoren bestimmen

Beitrag von Admin »

Warum für jede Lichtmessung 2 Sensoren?
Ich hatte das Problem, dass der Sensor Werte von 0 - 4095 bringt, wenn ich nur im Zimmer die Beleuchtung ändere. Also ich habe es geschafft, mit einer sehr hellen Lampe diesem Sensor den Höchstwert 4095 zu entlocken. Das ist etwa das Tageslicht im freien, bei seeehr bedeckten Himmel. Jetzt muss ich aber auch das Licht bei voller Sonne noch unterscheiden können. Das kann dieser eine Sensor nicht leisten, wenn er bei einer guten Taschenlampe schon volles Licht anzeigt, was im Gegensatz zum Sonnenlicht ein läpisches kleines Lämpchen ist. Also habe ich den Sensor abgedeckt, zuerst mit matten Glas, das laut angaben des Herstelles nur 30% Licht durchlässt. Das war ein totaler Witz, brachte eigentlich keinen Unterschied. Auch mehr Schichten waren eher Lustig als Sinnvoll. Also habe ich mal ein Blatt weißes 100gr. Papier davor gehalten und dachte eigentlich, das wird wohl viel zu viel sein. Von wegen, es war eine gute Richtung, aber immer viel zu wenig. Also zwei Blätter Papier weiß 100gr. Schon besser, aber noch immer zu hell. Also drei Blätter Papier weiß 100gr. UNd siehe einer an, damit habe ich es geschafft, den Sensor so zu verdunkeln, dass ich in voller Sonne noch nicht an den max. Wert von 4095 kam.

Aber mit diesem Sensor, war es bei starker Bewölkung am Tag schon total finster, also Werte unter hundert. Wo aber das Panel noch gearbeitet hat. OK, ich brauchte also eine Möglichkeit, auch im unteren Lichtbereich, was aber z.B. am Arbeitplatz noch super Licht ist, auch noch klare Unterscheidungen treffen zu können. Ja, da war die Idee geboren, zwei Sensoren, einer ohne Abschattung und einer mit den drei Blättern Papier abgeschattet. Beide getrennt messen, und die beiden Werte addieren. Also wurde aus max. Wert 4095 -> 8190, und ich konnte alles abbilden, von schwarze Nacht = 0 bis volle Sonne = ~7500. Da ist noch etwas Luft nach oben, bis 8190.
Benutzeravatar
Admin
Administrator
Beiträge: 1197
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Die Position der Sonne mit Sensoren bestimmen

Beitrag von Admin »

Ich habe ja inzwischen zwei EchoSensoren nachgerüstet, um erst mal eine ZentrierungsFahrt machen zu können, bei der jeder der beiden Motoren erst mal auf Position Null fährt. Dann erst weiß die Kiste auf welcher Horizontal und Vertikal Position sich die Motoren gerade befindet. Das sind keine GPS Koordinaten!! sondern nur eine Info für die Software, über den möglichen Fahrweg der beiden Motoren. Wie ich diese Sensoren befestigt haben, sieht man hier.

Hier die Aktuelle Schaltung:
.
Sonnen_Nachführung_Solarpanel_V3_Schrittmotoren02.JPG
Sonnen_Nachführung_Solarpanel_V3_Schrittmotoren02.JPG (706.91 KiB) 505 mal betrachtet
Benutzeravatar
Admin
Administrator
Beiträge: 1197
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Die Position der Sonne mit Sensoren bestimmen

Beitrag von Admin »

Ich habe mal nach einem Forum gesucht für Solartechnik.

Und gefunden :)

Eine sehr inteessante Anlage hat da einer. Der Sistz offenbar in Östereich und heißt in dem Thema dort "Hinundher"
Franz
Benutzeravatar
Admin
Administrator
Beiträge: 1197
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Die Position der Sonne mit Sensoren bestimmen

Beitrag von Admin »

Ich hatte noch einen Fehler in der Software, der mir erst heute aufgefallen ist. Konrolle 2 wurde nicht "1" geschalten. Immer wenn der Tracker in dieser Richtung nachjustiert hat, wurde Kontrolle2 auf "1" geschalten, also auf Justierung abgeschlossen, und im Programmteil, indem kontrolliert wurde, ob eine neue Nachjustierung nötig ist, wurde Kontrolle2 sofort wieder auf "0" geschalten. Zwischen "1" und "0" ist höchstens eine Millisekunde :sad: Habe den Fehler gefunden und behoben. War jetzt nicht tragisch, es wurde halt laufend in Horizotaler Richtung nachjustiert.

Hier die aktuelle Software:

Code: Alles auswählen

#include <LiquidCrystal_I2C.h>
// Display Adresse 0x3F 0der 0x27
LiquidCrystal_I2C lcd(0x27, 20, 4);
#include <Adafruit_ADS1X15.h> // bindet Wire.h für I2C mit ein
Adafruit_ADS1115 ads;
Adafruit_ADS1115 ads2;
#define ADS_I2C_ADDR 0x48
#define ADS_I2C_ADDR2 0x49
//------------------------------------------------------
#include <MobaTools.h>
int Rampe = 10;
const int STEPS_REVOLUTION = 6400; //Schritte pro Umdrehung Treibereinstellung
//Stepper einrichten ( 6400 Schritte / Umdrehung - 1/4 Microstep )
MoToStepper myStepper1( STEPS_REVOLUTION, STEPDIR );  // 6400 Steps/ Umdrehung
MoToStepper myStepper2( STEPS_REVOLUTION, STEPDIR );  // 6400 Steps/ Umdrehung
// Die Enable Pin´s werden nicht benutzt, dass die Motoren auch in Ruhe gebremst werden
const byte dirPin1       = 6;
const byte stepPin1      = 7;
const byte enaPin1       = 5; // Wird hier nicht benutzt
const byte dirPin2       = 9;
const byte stepPin2      = 10;
const byte enaPin2       = 8; // Wird hier nicht benutzt
int vspeed = 0;                 //Steppergeschwindigkeit in U/min*10
//-----------------------------------------------------
byte ablauf = 3; //3 = Tagbetrieb /4 = Nachtbetrieb
const float multiplier = 0.125F; // ADS1115-Multiplikator bei einf. Verstärkung
const byte panel = A0;
int panelwert = 0;
float panelspannung = 0;
float ads_mv0 = 0;  // Sensor rechts
float ads_mv1 = 0;  // Sensor links
float ads_mv2 = 0;  // Sensor hinten
float ads_mv3 = 0;  // Sensor vorne
int adc0 = 0;
int adc1 = 0;
int adc2 = 0;
int adc3 = 0;
float ads_mv4 = 0;  // Sensor rechts
float ads_mv5 = 0;  // Sensor links
float ads_mv6 = 0;  // Sensor hinten
float ads_mv7 = 0;  // Sensor vorne
int adc4 = 0;
int adc5 = 0;
int adc6 = 0;
int adc7 = 0;
int Messung1 = 0;
int Messung2 = 0;
int Messung3 = 0;
int Messung4 = 0;
int MessAlt1 = 0;
int MessAlt2 = 0;
int MessAlt3 = 0;
int MessAlt4 = 0;
byte refhorizontal = 1;
const byte hallsensorH = 39;
byte refvertikal = 1;
const byte hallsensorV = 40;
byte Status = 0;
byte kontrolle1 = 0;
byte kontrolle2 = 0;
byte kontrolle3 = 0;
byte kontrolle4 = 0;
int posvertikal = 0;
int poshorizontal = 0;
const byte Servo1 = 5;
const byte Servo2 = 6;
unsigned long sekundenablauf1 = 0; // Messabstand 1 Sekunde
const unsigned long pausezeit1 = 1000;
unsigned long aktuellzeit = 0;
unsigned long oben = 0;
unsigned long unten = 0;
unsigned long sekundenablauf2 = 0; // SerialPrint_Ausgabe alle 30 Sekunden
const unsigned long pausezeit2 = 30000;
//==============================================================
//=========================SETUP================================
//==============================================================
void setup() {
  //----------------------------------------------------
  lcd.begin();
  lcd.backlight();
  lcd.clear();
  //----------------------------------------------------
  Serial.begin(9600);
  //----------------------------------------------------
  ads.begin(ADS_I2C_ADDR, &Wire);
  ads2.begin(ADS_I2C_ADDR2, &Wire);
  // Werte 1-fach verstärken (ESP32 liefert  max. 3,3V)
  ads.setGain(GAIN_ONE);
  ads2.setGain(GAIN_ONE);
  //----------------------------------------------------
  lcd.setCursor (0, 0);            // Zeile 1
  //----------------------------------------------------
  pinMode(panel, INPUT);         // Spannung vom Panel
  pinMode(hallsensorH, INPUT_PULLUP);
  pinMode(hallsensorV, INPUT_PULLUP);
  //----------------------------------------------------
  sekundenablauf1 = millis();
  //-----Stepper---------------------------------------
  myStepper1.attach( stepPin1, dirPin1 );
  myStepper1.attachEnable( enaPin1, 10, HIGH );  //Enable Pin deaktivieren ( LOW=aktiv )
  myStepper1.setSpeed( 10 );
  myStepper1.setRampLen( Rampe );                //Rampenlänge 100 Steps bei 20U/min
  myStepper2.attach( stepPin2, dirPin2 );
  myStepper2.attachEnable( enaPin2, 10, HIGH );  //Enable Pin deaktivieren ( LOW=aktiv )
  myStepper2.setSpeed( 10 );
  myStepper2.setRampLen( Rampe );                //Rampenlänge 100 Steps bei 20U/min
  //---------------------------------------------------
}
//==============================================================
//=========================LOOP=================================
//==============================================================
void loop() {
  oben = millis();
  aktuellzeit = millis();
  //-------------------Referenzfahrten_Horizont-----------------
  if (Status == 0)
  {
    lcd.setCursor (0, 0);            // Zeile 1
    lcd.print (F("Referenzfahrt Start "));
    Status = 1;
  }
  if (refhorizontal == 1)
  {
    myStepper1.doSteps( -10 );         // Stepper dreht vorwärts
    refhorizontal = digitalRead(hallsensorH);
    if (refhorizontal == 0)
    {
      myStepper1.stop();
      myStepper1.setZero();
      poshorizontal = 0;
    }
  }
  //---------------Referenzfahrten_Vertikal--------------------
  if (refvertikal == 1)
  {
    myStepper2.doSteps( -10 );         // Stepper dreht vorwärts
    refvertikal = digitalRead(hallsensorV);
    if (refvertikal == 0)
    {
      myStepper1.stop();
      myStepper2.setZero();
      posvertikal = 0;
    }
  }
  //===========================================================
  if ((refhorizontal == 0) && (refvertikal == 0))
  {
    if (Status == 1)
    {
      lcd.setCursor (0, 0);            // Zeile 1
      lcd.print (F("Hauptprogramm Start "));
      Status = 2;
    }
    //Jede Sekunde Spannung am Panel messen
    if (aktuellzeit - sekundenablauf1 >= pausezeit1) // Eine Sekunde abgelaufen?
    {
      panelwert = analogRead(panel);
      panelspannung = panelwert * 20.3 / 1024.0;

      if ((kontrolle1 == 1) && (kontrolle2 == 1) && (kontrolle3 == 1) && (kontrolle4 == 1))
      {
        lcd.setCursor (14, 0);            // Zeile 1
        lcd.print (panelspannung);
        if (ablauf == 3)
        {
          lcd.setCursor (0, 0);            // Zeile 1
          lcd.print (F("Panelspannung "));
        }
        if (ablauf == 4)
        {
          lcd.setCursor (0, 0);            // Zeile 1
          lcd.print (F("Nachtbetrieb  "));
        }
      }
      sekundenablauf1 = millis();
    }
    // -----Kanal 0 Messung------------------------------
    adc0 = ads.readADC_SingleEnded(0);
    ads_mv0 = ads.computeVolts(adc0) * 1000;
    // -----Kanal 1 Messung------------------------------
    adc1 = ads.readADC_SingleEnded(1);
    ads_mv1 = ads.computeVolts(adc1) * 1000;
    Messung1 = ads_mv0 + ads_mv1;
    // -----Kanal 2 Messung------------------------------
    adc2 = ads.readADC_SingleEnded(2);
    ads_mv2 = ads.computeVolts(adc2) * 1000;
    // -----Kanal 3 Messung------------------------------
    adc3 = ads.readADC_SingleEnded(3);
    ads_mv3 = ads.computeVolts(adc3) * 1000;
    Messung2 = ads_mv2 + ads_mv3 - 200;
    // -----Kanal 4 Messung------------------------------
    adc4 = ads2.readADC_SingleEnded(0);
    ads_mv4 = ads.computeVolts(adc4) * 1000;
    // -----Kanal 5 Messung------------------------------
    adc5 = ads2.readADC_SingleEnded(1);
    ads_mv5 = ads.computeVolts(adc5) * 1000;
    Messung3 = ads_mv4 + ads_mv5; //
    // -----Kanal 6 Messung------------------------------
    adc6 = ads2.readADC_SingleEnded(2);
    ads_mv6 = ads.computeVolts(adc6) * 1000;
    // -----Kanal 7 Messung------------------------------
    adc7 = ads2.readADC_SingleEnded(3);
    ads_mv7 = ads.computeVolts(adc7) * 1000;
    Messung4 = (ads_mv6 + ads_mv7) - 200;
    //---------------------------------------------------
    //---------Fahren_Horizontal_Licht_suchen------------
    //---------------------------------------------------
    if (ablauf == 3)
    {
      //--------Horizontal Kontrolle plus--------------
      if (kontrolle1 == 0)
      {
        if (Messung2 > Messung1) // Links dunkler als rechts
        {
          if (poshorizontal < 4500)
          {
            if (myStepper1.moving() == 0)
            {
              poshorizontal = poshorizontal  + 25; // Fahre nach rechts
              myStepper1.doSteps( 25 );         // Stepper dreht -1
            }
          }
          else
          {
            kontrolle1 = 1;
          }
        }
        else
        {
          kontrolle1 = 1;
        }
      }
      //--------Horizontal Kontrolle minus-------------
      if (kontrolle2 == 0)
      {
        if ((Messung2) < Messung1) // Links heller als rechts
        {
          if (poshorizontal > 0)
          {
            if (myStepper1.moving() == 0)
            {
              poshorizontal = poshorizontal - 25; // Fahre nacht Links
              myStepper1.doSteps( -25 );         // Stepper dreht +1
            }
          }
          else
          {
            kontrolle2 = 1;
          }
        }
        else
        {
          kontrolle2 = 1;
        }
      }
      //---------------------------------------------------
      //----------Fahren_Vertikal_Licht_suchen-------------
      //---------------------------------------------------
      //-----------Vertikale Kontrolle plus----------------
      if (kontrolle3 == 0)
      {
        if ((Messung4) < Messung3)  // Unten dunkler als Oben
        {
          if (posvertikal < 3000)
          {
            if (myStepper2.moving() == 0)
            {
              posvertikal = posvertikal + 25;  // Fahre runter
              myStepper2.doSteps( 25 ); // Stepper dreht +1
            }
          }
          else
          {
            kontrolle3 = 1;
          }
        }
        else
        {
          kontrolle3 = 1;
        }
      }
      //-------------Vertikal Kontrolle minus---------------
      if (kontrolle4 == 0)
      {
        if ((Messung4) > Messung3) // Unten heller als oben
        {
          if (posvertikal > 0)
          {
            if (myStepper2.moving() == 0)
            {
              posvertikal = posvertikal - 25; // Fahre hoch
              myStepper2.doSteps(-25 ); // Stepper dreht -1
            }
          }
          else
          {
            kontrolle4 = 1;
          }
        }
        else
        {
          kontrolle4 = 1;
        }
      }
      //---------Vertikale Kontrolle Ende-----------------

      //--------Fahren_Lichtquelle suchen Ende------------
    }
    //------------Kontrolle wieder aktivieren-------------
    //-------------Horizontal rechts / links--------------
    if (ablauf == 3)
    {
      if (kontrolle1 == 1)
      {
        if (Messung2 > Messung1 + 100) // Links dunkler als rechts
        {
          kontrolle1 = 0;
        }
      }
      if (kontrolle2 == 1)
      {
        if (Messung1 > Messung2 + 100) // Links heller als rechts
        {
          kontrolle2 = 0; 
        }
      }
      //------------Kontrolle wieder aktivieren-------------
      //----------------Vertikal auf / ab-------------------
      if (kontrolle3 == 1)
      {
        if ((Messung3) > Messung4 + 100)  // Oben dunkler als Unten
        {
          kontrolle3 = 0;
        }
      }
      if (kontrolle4 == 1)
      {
        if ((Messung4) > (Messung3 + 100)) // Unten heller als Oben
        {
          kontrolle4 = 0;
        }
      }
    }
    //-----------------------------------------------------
    //--------------Kontrolle ob schon zu Dunkel-----------
    if ((Messung1 < 1000) || (Messung2 < 1000) || (Messung3 < 1000) || (Messung4 < 1000))
    {
      ablauf = 4;
    }
    else
    {
      if ((Messung1 > 1400) && (Messung2 > 1400) && (Messung3 > 1400) && (Messung4 > 1400))
      {
        ablauf = 3;
      }
    }
    //-----------------------------------------------------
    //---------In die Nachtposition fahren-----------------
    if (ablauf == 4)
    {
      kontrolle1 = 1;
      kontrolle2 = 1;
      kontrolle3 = 1;
      kontrolle4 = 1;

      //ServoVertikal.write(startposvertikal);
      //ServoHorizontal.write(startposhorizontal);

    }
    // ---------------Ende Referenzpunkt suchen--------------
  }
  //-------------------Serial Print Kontrolldaten------------
  if (aktuellzeit - sekundenablauf2 >= pausezeit2) // 30 Sekunden abgelaufen?
  {
    Serial.print("Horizontal  - ");
    Serial.print(kontrolle1);
    Serial.print(" - ");
    Serial.print(kontrolle2);
    Serial.print(" - ");
    Serial.print(poshorizontal);
    Serial.print(" M1=");
    Serial.print(Messung1);
    Serial.print(" M2=");
    Serial.print(Messung2);
    Serial.print(" M2-M1=");
    Serial.println(Messung2 - Messung1);
    Serial.print("Vertikal    - ");
     Serial.print(kontrolle3);
    Serial.print(" - ");
    Serial.print(kontrolle4);
    Serial.print(" - ");
    Serial.print(posvertikal);
    Serial.print(" M3=");
    Serial.print(Messung3);
    Serial.print(" M4=");
    Serial.print(Messung4);
    Serial.print(" M3-M4=");
    Serial.println(Messung3 - Messung4);
    Serial.print("Panelspannung ");
    Serial.println(panelspannung);
    Serial.println("#######################################################");
    sekundenablauf2 = millis();
  }

  //---------------------Display alle Anzeigen---------------
  if ((kontrolle1 == 1) && (kontrolle2 == 1) && (kontrolle3 == 1) && (kontrolle4 == 1))
  {
    if (((Messung1 + 2) < MessAlt1) || ((Messung1 - 2) > MessAlt1))
    {
      lcd.setCursor (7, 3);            // Zeile 4
      lcd.print ("1-    ");
      lcd.setCursor (9, 3);            // Zeile 4
      lcd.print (Messung1);
      MessAlt1 = Messung1;
    }

    if (((Messung2 + 2) < MessAlt2) || ((Messung2 - 2) > MessAlt2))
    {
      lcd.setCursor (6, 1);            // Zeile 2
      lcd.print ("H2-    ");
      lcd.setCursor (9, 1);            // Zeile 2
      lcd.print (Messung2);
      MessAlt2 = Messung2;
    }

    if (((Messung3 + 2) < MessAlt3) || ((Messung3 - 2) > MessAlt3))
    {
      lcd.setCursor (0, 2);
      lcd.print ("V3-    ");
      lcd.setCursor (3, 2);            // Zeile 3
      lcd.print (Messung3);
      MessAlt3 = Messung3;
    }

    if (((Messung4 + 2) < MessAlt4) || ((Messung4 - 2) > MessAlt4))
    {
      lcd.setCursor (12, 2);
      lcd.print ("V4-    ");
      lcd.setCursor (15, 2);            // Zeile 3
      lcd.print (Messung4);
      MessAlt4 = Messung4;
    }

    lcd.setCursor (0, 3);
    lcd.print ("     ");
    lcd.setCursor (0, 3);
    lcd.print ("H-");
    lcd.print (poshorizontal);

    lcd.setCursor (14, 3);
    lcd.print ("     ");
    lcd.setCursor (14, 3);
    lcd.print ("V-");
    lcd.print (posvertikal);
  }
  //----------------------Ende Loop----------------------
  unten = millis();
  //Serial.println(unten - oben);
}
Antworten

Zurück zu „Hardware / Schaltungstechnik“

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste