Solar-Tracker

Mehr Licht in der Wohnung dank intelligentem Spiegel

Wenn die Wohnung kleine Fenster hat und zu dunkel ist, denken viele vermutlich daran, entweder die Fenster zu vergrößern oder umzuziehen.
Es gibt jedoch noch eine dritte technische Möglichkeit, dass mehr Sonnenlicht in die Wohnung fällt: Man nehme einen Spiegel, montiert ihn beweglich mit zwei Motoren in Kombination mit einem Solartracker.
Gesagt getan habe ich einen 80x5o0cm Spiegel gekauft. Für das Gestänge habe ich 20x20 Aluprofile (Nut 6) und für den "Mast" ein 30x30 Aluprofil gewählt. Die Maße lauten wie folgend:
Zusätzlich benötigt man noch: Der Spiegel lässt sich einfach in den Profilen einschieben, welche mit vier Winkeln von außen zusammengehalten werden.
Für den Mast habe ich als Fuß das 50cm Profil genommen und zur Hälfte auf der Südseite der Wohnung einbetoniert. An dem Fuß kann das 1m Stück mit vier Profilen befestigt werden.
Die Winkel besitzen herausstehende Nuten, welche ich vorher am Schleifstein abgeschliffen habe. Für die Motoren habe ich zwei Linearantriebe verwendet. Diese besitzen bereits Endschalter.


Nun zur Ansteuerung. Die beiden Motoren liegen Orthogonal zueinander. Die günstigste und einfachste Variante ist es, einen Motor am Masten zu befestigen. Dieser steuert die Roll-Achse. D. h. Wenn man von Süden auf den Siegel schaut, das "Kippen" nach Links und Rechts. Der Motor bildet ein Dreieck mit den Seitenlängen a, b, und c. Aus den fixen Längen a1 und a2 bzw. b1 und b2 lassen sich die Seiten a und b bestimmen. Wenn man nun den Winkel an einen bestimmen Winkel platzieren möchte, zieht man erst die Winkel der Dreiecke A und B ab und berechnet anschließend die Seitenlänge c.
Das selbe gilt für den Motor in Pitch-Richtung. Dieser ist so montiert, dass er sich in Roll-Richtung mitdreht. Das vereinfacht die Mechanik der Gelenke an denen er befestigt ist und die Software zum Umrechnen der Winkel.
Der Solartracker funktioniert folgendermaßen:
0) Da ich keinen NodeMCU da hatte, habe ich einen Arduino Mega genommen und verwende die Compilezeit. So lange es keinen Stromausfall gibt, funktioniert es ganz gut, ich plane jedoch, mir die aktuelle Uhrzeit via WLAN oder Funkuhrmodul zu holen.

1) Hierfür wird eine extrene Library verwendet. Die Sonnenposition wird in Azimuth (im Uhrzeigersinn von Norden aus) und Elevation (Winkel über dem Horizont) berechnet. Für die Umrechnung in Kugelkoordinaten muss Azimuth auf Phi (Gegen den Uhrzeigesinn, beginnend bei x Achse, welche Richtung Süden zeigt) und Elevation auf Theta (vom zenith aus nach unten gehend) umgerechnet werden. Zusätzlich wird der Offset des Spiegels mit berücksichtigt, da das Fundament nicht exakt nach Norden ausgerichtet ist.

2) Die Winkelhalbierende zwischen Sonnenvektor und Fenstervektor ist der Normalenvektor der Spiegelebene und lässt sich in Kartesischen Koordinaten wesentlich leichter berechnen.

3) Dreht man ein Koordinatensystem indem man x und z vertauscht, so entsprechen in Kugelkoordinaten die Winkel cRoll und cPitch den Winkeln Phi und Theta. Es muss lediglich noch ein konstanter Offset aufgerechnet werden.

4) Da die Motoren keine Positionsgeber haben, wird zur Initialisierung einfach die (bekannte) Endposition angefahren. Bei den auftretenden Lasten kann die Motorgeschwindigkeit bei gleichbleibender Spannung als Konstant angesehen werden. Wenn man eine bestimmte Strecke ausfahren möchte, muss man die aktuelle Position per Software mitloggen. Da die Relais eine gewisse Schaltzeit haben, habe ich nach Tests 200ms als untere Mindestanschaltdauer festgelegt. Daher bleibt der SPiegel immer ein paar Minuten stehen, ehe er zur nächsten Position fährt. Nachts wird wieder die Nullposition angefahren zur Initialisierung.


Die Elektronik habe ich in einer kleinen Box am Mast befestigt. der darüberliegende Spiegel schützt zusätzlich vor Regen. Die Anschlüsse für die Motoren und Stromversorgung habe ich auf die Unterseite der Box gemacht. Das Netzteil befindet sich in der Wohnung, so dass das Erdkabel nur 12V Spannung hat.
Dank des neuen Reflektors im Garten kommt nun doppelt so viel Licht durch das kleine Küchenfenster, jedoch nur bei direkter Sonneneinstrahlung. Wenn man nicht da ist, kann man den Spiegel ausschalten, damit sich die Wohnung nicht zu sehr aufheizt.



sunReflector.ino
#include "sunReflector.hpp"

void setup() {
  Serial.begin(9600); // for debugging
  // testVec3(); // Test vector class
  //testMotorPin(4); // Test motor pin
  //testMotorPin(6); // Test motor pin
}

void loop() {
  
  const int utcOffset = 2; // +2 hours (European summer time)
  setTime(toUtc(compileTime()+60UL, utcOffset)); // add one minute because we need time beween compiling until we plug in the arduino

  const int motorRollPinContract  = 5; // left/right (west/east)
  const int motorRollPinExpand    = 6;
  const double motorRollA1        = 54.8; // all length units for one motor must be the same, I use cm here.
  const double motorRollA2        = 6.0;
  const double motorRollB1        = 25.7;
  const double motorRollB2        = 4.3-4.0;
  const double motorRollCMin      = 42.2;// according to datasheet 44.0cm but I meassured 42.2cm by hand
  const double motorRollCMax      = motorRollCMin + 30.0; // 30cm stroke from datasheed, not meassured yet
                                  // how to meassure motor speed: run motor via software for 10 seconds. Meassure traveled distance and devide by 10s. Voila.
  const double motorRollSpeed     = 1.37e0; // Datasheet said 1.4 but this motor is only 1.37 length units per second (here: cm/s)
  
  const int motorPitchPinContract = 3; // forward/backward (north/south)
  const int motorPitchPinExpand   = 4;
  const double motorPitchA1       = 36.5+3.4; // (in cm) You could use other lenth units for the other motor or the window if you feel so
  const double motorPitchA2       = 4.0+8.0;
  const double motorPitchB1       = 40.4;
  const double motorPitchB2       = 4.0-2.3;
  const double motorPitchCMin     = 37.1;// according to datasheet 36.9cm but I meassured 37.1cm by hand
  const double motorPitchCMax     = motorPitchCMin + 25.0; // 25cm stroke from datasheed, not meassured yet
  const double motorPitchSpeed    = 1.2314e0; // Datasheet said 1.4cm/s but I meassured 1.23
  
  vec3 windowPosition(-142,-10,65); // window position relative to mirror in cartesian coordinates (depth, sideways, vertical)
  const double wallOffsetAngle    = -5;//-5; // wall rotation relative to the mirror (negative value means wall rotated clockwise relative to mirror)
  const double mirrorOffsetAngle  = -25; // mirror rotation relative to north

  const double latitude = 49.5614939; // now you know where I live but you could have just looked into the legal notice of my website
  const double longitude = 10.9122589;

  // Dont edit the code below this line if your name isn't Veit Goetz
  /* -------------------------------------------------------------------------------------------------------- */
  
  InverseCinematics motorRollGeometry(motorRollA1, motorRollA2, motorRollB1, motorRollB2);
  InverseCinematics motorPitchGeometry(motorPitchA1, motorPitchA2, motorPitchB1, motorPitchB2);
  Motor motorRoll(motorRollPinContract, motorRollPinExpand, motorRollCMin, motorRollCMax, motorRollSpeed, motorRollGeometry);
  Motor motorPitch(motorPitchPinContract, motorPitchPinExpand, motorPitchCMin, motorPitchCMax, motorPitchSpeed, motorPitchGeometry);

  //testGeometry(motorRollGeometry);
  //testMotor(motorRoll);
  //testGeometry(motorPitchGeometry);
  //testMotor(motorPitch);
  
  Reflector mirror(motorRoll, motorPitch);
  mirror.setWindowCoordinates(windowPosition, wallOffsetAngle);
  mirror.setMirrorOffsetAngle(mirrorOffsetAngle);
  mirror.setCoordinates(latitude, longitude);

  Serial.println("Init done");
  
  while(true){
    mirror.updateMotors(); // move mirror
    Serial.println("wait one minute");
    // the sun moves 1° per 4 minutes, so by waiting 1 minutes we are max. 1/4 degree behind
    delay(60UL*1000UL); // unsigned long because we could get an overflow otherwise
    Serial.println("wake up");
  }
}

Weitere Artikel

© Veit Götz 2012 - 2024
Impressum
Datenschutz
Statistiken
Spenden