Solarpanel

Hallo Arduino-Freunde, ich hab folgendes Problem: Ich möchte mit einem Arduino-Uno ein Solarpanel automatisch zur Sonne ausrichten lassen und natürlich auch gelegentlich nachjustieren lassen. Mechanisch ist alles fertig, H-Brücke als L293D absolviert und 4 Fotowiderstände ( ich weiß, 3 reichen auch) verbaut. Angesteuert wird die Mechanik über 2 DC-Getriebemotoren da sie sehr wenig Strom ziehen (max 60-80mA). Programm habe ich auch geschrieben aber er kommt einfach nicht zu Ruhe.. bzw. funktioniert es nicht richtig. Da es meine Facharbeit ist und ich diese in den Winterferien fertigstellen möchte wäre ich mehr als dankbar über Hilfe.

Warum denkt hier fast jeder Fragesteller, daß hier Hellseher sitzen?

Gruß Tommy

Bin neu hier, entschuldige, muss erstmal sehen wie ich meinen bisherigen Sketch posten kann.

void setup()
{
 pinMode( 11 , OUTPUT);
 pinMode( 10 , OUTPUT);
 pinMode( 6 , OUTPUT);
 pinMode( 5 , OUTPUT);
}

void loop()
{
 int FW1 = analogRead(0);
 int FW2 = analogRead(1);
 int FW3 = analogRead(2);
 int FW4 = analogRead(3);
 int diff1 = (FW1-FW3);
 int diff2 = (FW4-FW3);
 Serial.begin(9600);
if (diff1 > 20 )
   {
   digitalWrite( 11 , HIGH );
   digitalWrite( 10 , LOW );
   
   }
 if (diff1 < -20 ) 
   {
   digitalWrite( 11 , LOW );
   digitalWrite( 10 , HIGH );
   }
 if (diff2 > 20 )
   {
   digitalWrite( 6 , HIGH );
   digitalWrite( 5 , LOW );
   }
 if (diff2 < -20 )
   {
   digitalWrite( 6 , LOW );
   digitalWrite( 5 , HIGH );
   }

 Serial.println(String(FW1)+"-----"+String(FW2)+"-----"+String(FW3)+"-----"+String(FW4));
 delay(500);
 
}

Hab den Sketch einfach mal über Copy & Paste eingefügt.

Und jetzt noch More - Modify - alles markieren - </>

Preview


Mit den 4 Analogread liest du 4 LDR die in verschiedene Richtungen schauen. Richtig?

Und du denkst, deine Zweipunktregler mit Hysterese kommen an einem bewölkten Tag irgendwie zur Ruhe?

Durch die zwei Motoren verstellst du auch die Richtung der LDR, richtig?
Hast also eine Rückkopplung... Da musst du dich etwas mit Regelungstechnik beschäftigen.

Ein ganz kleiner Trost: Solche Regelungen sind erstmal immer zu zappelig. :wink:

Denk dran: du willst maximal das Panel in 12 Stunden um 180 Grad in Ost-West Richtung und hierzulande um max 60° horizontal in 6 Stunden bewegen.

Mit einer Uhr statt LDR wär es einfacher, da hast du keine Rückkopplung.

michael_x:
Denk dran: du willst maximal das Panel in 12 Stunden um 180 Grad in Ost-West Richtung und hierzulande um max 60° horizontal in 6 Stunden bewegen.

Wäre nicht Ost-West horizontal und die 60° eher vertikal?

Gruß Tommy

Danke Michael_X erstmal, ich fand das gerade so interessant, dass egal wie ich ihn stelle, er sich immer wieder ausrichten kann. Mit einer Uhr müsste ich ihn exakt einnorden oder? Habe die Motoren so angeordnet, dass er sich drehen kann bis ihm schlecht wird, ohne Kabel aufzuwickeln. Würde auch ein Foto reinstellen, muss nur schauen wie das geht. Vielen Dank dir trotzdem.

Ein mobiles Solarpanel ist natürlich interessanter.
Und Regelung ist interessanter als einfach eine bestimmte Position anfahren.

Was soll eigentlich nachts passieren? zurück, oder die zweiten 180° weiterdrehen ?
Ich denke, dem Ding ungeregelt morgens oder noch abends/nachts eine einigermassen passende Startposition geben, wäre nicht verkehrt.

@Tommy: klar, eine Bewegung un eine waagerechte Achse sollte man nicht "horizontal" nennen.
Gemeint habe ich natürlich, der Sonnenhöhe zu folgen.

Wie richtungsempfindlich sind eigentlich LDR? Ich würde mit 5 Stück

   o
o  o  o
   o

versuchen, den mittleren auf max Helligkeit zu bekommen.
Du arbeitest zur Zeit ohne den mittleren, und versuchst, die jeweils paarweise gleich hell zu kriegen, richtig?

In welchem Winkel zueinander richtest du die aus?

Michael3007:
Hallo Arduino-Freunde, ich hab folgendes Problem: Ich möchte mit einem Arduino-Uno ein Solarpanel automatisch zur Sonne ausrichten lassen und natürlich auch gelegentlich nachjustieren lassen. Mechanisch ist alles fertig, H-Brücke als L293D absolviert und 4 Fotowiderstände ( ich weiß, 3 reichen auch) verbaut. Angesteuert wird die Mechanik über 2 DC-Getriebemotoren da sie sehr wenig Strom ziehen (max 60-80mA). Programm habe ich auch geschrieben aber er kommt einfach nicht zu Ruhe.. bzw. funktioniert es nicht richtig.

Ein Fehler scheint die fehlerhafte Schaltlogik zu sein, die meiner Meinung nach so abläuft:

Wenn eine Fehlausrichtung erkannt wurde, schalte den Stellmotor zur Korrektur an.
Und der Fehler ist: Dieser Stellmotor läuft dann so lange, bis eine andere Fehlausrichtung erreicht ist.

Also Du hast es doch absichtlich so programmiert, das die Motoren von einer Fehlausrichtung zur nächsten Fehlausrichtung laufen, und dann ggf. die Laufrichtung wechseln.

Ich würde es eher so programmieren, dass die Stellmotoren sich mit einem kurzen Schaltintervall langsam an die richtige Position herantickern und nach jedem Tick abschalten.

Also in der loop eventuell

delay(500);
//und dann ALLE MOTOREN STOP

Und wenn dann im nächsten Schritt dieselbe Fehlausrichtung vorliegt, läut der Motor wieder eine halbe Sekunde und stoppt dann gleich wieder.
Tick für Tick für Tick für Tick

Das was Du beschreibst als "kommt einfach nicht zu Ruhe" verstehe ich so, dass der Motor aus einer Falschausrichtung heraus losläuft, bis eine andere Falschausrichtung erreicht ist, und dann dreht die Richtung. Das Herantickern an die richtige Ausrichtung kann ich in Deinem Sketch nicht erkennen: Motor kurz laufen lassen und stoppen. Dann neue Messung, dann ggf. Motor wieder kurz laufen lassen.

klingt logisch, vielen Dank. Wie würde so etwas programmiert aussehen? Wie gesagt, hab nicht so viel Ahnung davon? Immer ein Delay einfügen?

@Michael_x:
ja, arbeite paarweise:

O2 O4

O3 O1

1 vergleicht mit 3 , ob Drehrichtung mittig steht,
3 vergleicht mit 4 , ob Neigung stimmt

wie gesagt Sensor 2 kannst du dir wegdenken, ist installiert aber völliger Humbug.
Hab ich einen als Reserve..

Hallo,

kannst da LINK mal schauen, vielleicht hilft es dir weiter.

wie gesagt Sensor 2 kannst du dir wegdenken, ist installiert aber völliger Humbug.

wenns funktioniert...
Ich fürchte, wenn das Ding vom vorigen Abend noch total falschrum steht, brauchst du viel Glück.

Aber wie jurs richtig gesehen hat, fehlt dir generell der Fall, dass beide Werte einigermassen gleich sind, und du den Motor weder vor-, noch zurücklaufen lassen möchtest.

Und die Motoren sowieso immer wieder anzuhalten ist auch eine gute Idee, wenn du 12 Stunden Zeit hast.

So ist die Grundstellung erstmal: Motoren stehen

 if (diff1 > 20 ) {
    digitalWrite( 11 , HIGH );
    digitalWrite( 10 , LOW );
    delay ( 2000);  // 2 sec vorwärts
    digitalWrite( 11, LOW); 
 }

Das ist jetzt eine Primitiv-Variante, bei der die Motoren nur einzeln laufen. Sollte aber schon einen Unterschied zu vorher machen

kannst da LINK mal schauen, vielleicht hilft es dir weiter.

Das beantwortet auch die Frage nach dem Winkel zwischen den LDR, und der Richtungsabhängigkeit.
Genial einfach.

Serial.begin muß aus dem loop() heraus in den setup().
Grüße Uwe

Es gibt verschiedene Gründe, warum das optische Aurichten von Solarpanelen nach der Sonnenposition auf der Erde nicht unbedingt optimal ist. Einer davon ist die Tatsache, dass z.B. bei teilweise bewölktem Himmel, die hellste Stelle nicht auch zwangsläufig mit der Position der Sonne übereinstimmt. Wobei sich wiederum die "Helligkeit" im Sinne von Strahlungsintensität, auch noch je nach Wellenlänge unterscheidet. Solarpanele sind eher im nahen IR-Bereich (um 900nm) besonders ergiebig, normale Fotowiderstände (auf Basis CdS) im Grün (500nm) empfindlich.

Unabhängig davon, würde ich mich mal an einem SELBER geschriebenen, vereinfachten PID-Regler-Algorithmus (proportional, integral, differential) versuchen. Das ist weniger kompliziert, als zunächst vermutet, es geht darum, wie sich die Stellgröße (Motor-Speed und -Richtung) aus der Abweichung von Soll und Ist errechnet. Hast du das einmal kapiert, kommst du selber durch Probieren zügig zum Ziel.

Zunächst werden drei Werte (P, I u. D) nach unterschiedlichen Methoden ermittelt. Diese drei Werte werden danach mit jeweils einem "Gewicht" (Koeffizient) zwischen -1...+1 multipliziert und zur endgültigen Stellgröße zusammenaddiert.

Der Proportional-Teil ergibt sich aus ganz einfach aus der momentanen Differenz zwischen Soll und Ist (Differenz der Helligkeiten innehalb der 2 LDR-Paare, getrennt für Vertikal und Horizontal).

Den Integral-Teil kann man aus der Summe einer Anzahl von zurückliegenden Proportionalwerten bilden, z.B. den letzten 5..10.

Der Differential-Teil ergibt sich aus einfach aus der Differenz zwischem letztem und aktuellem Proportional-Wert.

Bei optimaler Abstimmung (sorgfältig probieren, evtl. per Poti u. ADC live anpassbar machen) erhält man ein zügiges und dennoch nicht überschwingendes Regelverhalten. Nur Mut!

So ihr Guten, absoluter Wahnsinn hier, werde mich gleich mal ran setzen und weiterprobieren, vielen Dank im voraus. Werde dann berichten ob ein weiterer Erfolg zustande kommt.

So, Maichael_X, war ein guter Tip von dir mit delay, funtkioniert im Kellerlicht perfekt, regelt sich zwar nicht sehr schnell ein, aber dafür recht genau und immer Stück für Stück. Hier nochmal der aktuelle Sketch, findet ihr Fehler oder eine Optimierung, lasst es mich wissen, bin für Kritik und Hinweise dankbar aber tu mich immer noch sehr schwer damit.. In dem Sinne ein schönes WE euch noch.
void setup()
{
pinMode( 11 , OUTPUT);
pinMode( 10 , OUTPUT);
pinMode( 6 , OUTPUT);
pinMode( 5 , OUTPUT);
Serial.begin(9600);
}

void loop()
{
int FW1 = analogRead(0);
int FW2 = analogRead(1); //Reserve
int FW3 = analogRead(2);
int FW4 = analogRead(3);
int diff1 = (FW1-FW3);
int diff2 = (FW1-FW4);

if (diff1 > 10 )
{
digitalWrite( 11 , HIGH );
digitalWrite( 10 , LOW );
delay (100);
digitalWrite(11 , LOW);
}
if (diff1 < -10 )
{
digitalWrite( 11 , LOW );
digitalWrite( 10 , HIGH );
delay (100);
digitalWrite(10 , LOW);
}
if (diff2 > 10)
{
digitalWrite( 6 , LOW );
digitalWrite( 5 , HIGH );
delay (5000);
digitalWrite(5 , LOW);
}
if (diff2 < -10)
{
digitalWrite( 6 , HIGH );
digitalWrite( 5 , LOW );
delay (5000);
digitalWrite(6 , LOW);
}

Serial.println(String(FW1)+"-----"+String(FW3)+"-----"+String(FW4));
delay(1000);

}

Das mit den Code-Tags konntest Du schon mal :wink: Bitte korrigieren.

Edit: Wenn der Speicher knapp werden sollte, verzichte auf die String() und nimm char-Arrays.

Gruß Tommy

verzichte auf die String() und nimm char-Arrays.

Wenn du schon print nimmst, kannst du auch gleich die Zahlenwerte ausgeben.

Serial.print(FW1); Serial.write('\t');Serial.print(FW3);Serial.write('\t');Serial.println(FW4);