/*
Sonnenstandberechnung und Solartracking,
jetzt mit Arduino-Motor-Shield Rev3.
und Nextion 5.0-Zoll-touch-Display.
Läuft nicht auf dem Arduino-UNO.
Wg. erhöhtem Speicherbedarf ist ein Arduino Mega erforderlich.
Positionsangaben für Ort: Rönkhausen.
Version 3.5, M. Schulte, 15. Januar 2023.
Achtung: Vin max. 7.5 Volt.
Änderung: Servo map-Funktion entfällt.
Neu: LED-Ampel (rot, gelb, grün) konfiguriert:
Ampel: rote LED = Rückwärtslauf, grüne LED = Vorwärtslauf, gelb = Zielposition
erreicht, gelb blinkend = schneller Rückwärtslauf.
Änderung: diverse Anpassungen, u.a.Definition Sonnenuntergang (Elevation <= -2).
Azimut-Ist (azimutHall): map-Funktionen neu kalbriert (Ost 252, Süd 488, West
738)
Änderung: neue Variablen: mvOst, mvSued, mvWest
*/
#include <TimeLib.h>
#include <DTutils.h>
#include <Time.h>
#include <Servo.h>
#include <Stepper.h> // Include the Stepper library
#include <Wire.h>
#include <DS3231.h>
#define RTC_I2C_ADDRESS 0x68 // I2C Adresse des RTC DS3231
#define pwmA 3
#define pwmB 11
#define dirA 12
#define dirB 13
const int stepsPerRevolution = 200; // Define number of steps per revolution
RTCDateTime dt;
DS3231 clock;
Servo servo2; // Servomotor für Elevation
Stepper myStepper = Stepper(stepsPerRevolution, dirA, dirB); // Initialize the
stepper library on the motor shield
void setup() {
Serial2.begin(9600);
pinMode(pwmA, OUTPUT); // Set the PWM and brake pins so that the direction pins
can be used to control the motor:
pinMode(pwmB, OUTPUT);
digitalWrite(pwmA, HIGH);
digitalWrite(pwmB, HIGH);
myStepper.setSpeed(80); // Set the motor speed (RPMs)
pinMode(A2, INPUT); // Hall-Sensor
pinMode(A15, INPUT); // PV-Panel
pinMode(4, OUTPUT); // grüne LED, Anschluss an D4
pinMode(6, OUTPUT); // gelbe LED, Anschluss an D6
pinMode(7, OUTPUT); // rote LED, Anschluss an D7
servo2.attach(5);
servo2.write(3); // Servo senkrechte Grundstellung
clock.begin(); // Starte RTC Uhr
// clock.setDateTime(2022, 11, 26, 19, 57, 30); // Hier Datum und aktuelle
Uhrzeit (MEZ) setzen, danach auskommentieren und sketch neu laden
// Alle Daten des Displays leeren (refresh)
Serial2.print("ref=page0.t0.txt"); // refresh Seite 0 Textfeld 0
endNextionCommand();
Serial2.print("ref=page0.t1.txt"); // refresh Seite 0 Textfeld 1
endNextionCommand();
Serial2.print("ref=page0.t2.txt"); // refresh Seite 0 Textfeld 2
endNextionCommand();
Serial2.print("ref=page0.t3.txt"); // refresh Seite 0 Textfeld 3
endNextionCommand();
Serial2.print("ref=page0.t4.txt"); // refresh Seite 0 Textfeld 4
endNextionCommand();
Serial2.print("ref=page1.t0.txt"); // refresh Seite 1 Textfeld 0
endNextionCommand();
Serial2.print("ref=page1.t1.txt"); // refresh Seite 1 Textfeld 1
endNextionCommand();
Serial2.print("ref=page1.t2.txt"); // refresh Seite 1 Textfeld 2
endNextionCommand();
Serial2.print("ref=page1.t3.txt"); // refresh Seite 1 Textfeld 3
endNextionCommand();
Serial2.print("ref=page1.t4.txt"); // refresh Seite 1 Textfeld 4
endNextionCommand();
Serial2.print("ref=page1.t5.txt"); // refresh Seite 1 Textfeld 5
endNextionCommand();
Serial2.print("ref=page1.t6.txt"); // refresh Seite 1 Textfeld 6
endNextionCommand();
Serial2.print("ref=page2.t0.txt"); // refresh Seite 2 Textfeld 0
endNextionCommand();
Serial2.print("ref=page2.t1.txt"); // refresh Seite 2 Textfeld 1
endNextionCommand();
Serial2.print("ref=page2.t2.txt"); // refresh Seite 2 Textfeld 2
endNextionCommand();
Serial2.print("ref=page2.t3.txt"); // refresh Seite 2 Textfeld 3
endNextionCommand();
Serial2.print("ref=page2.t4.txt"); // refresh Seite 2 Textfeld 4
endNextionCommand();
Serial2.print("ref=page2.t5.txt"); // refresh Seite 2 Textfeld 5
endNextionCommand();
Serial2.print("ref=page2.t6.txt"); // refresh Seite 2 Textfeld 6
endNextionCommand();
Serial2.print("ref=page3.t0.txt"); // refresh Seite 3 Textfeld 0
endNextionCommand();
Serial2.print("ref=page3.t1.txt"); // refresh Seite 3 Textfeld 1
endNextionCommand();
Serial2.print("ref=page3.t2.txt"); // refresh Seite 3 Textfeld 2
endNextionCommand();
}
// Beginn der Schleife
void loop() {
const int stepsV = 16; // Anzahl steps Vorwärtslauf, ca. +0.5°
const int stepsR = -16; // Anzahl steps Rückwärtslauf, ca. -0.5°
const int stepsSR = -500; // Anzahl steps schneller Rücklauf, ca. -15°
dt = clock.getDateTime(); // Zeitwert holen von RTC Echtzeituhr
String hour = clock.dateFormat("H", dt);
String minute = clock.dateFormat("i", dt);
String year = clock.dateFormat("z", dt);
String second = clock.dateFormat("s", dt);
int Jahr = (dt.year);
int Monat = (dt.month);
int Tag = (dt.day);
float Stunde = hour.toInt();
float Minute = minute.toInt();
float Sekunde = second.toInt();
int yearday = DayOfYear(Jahr, Monat, Tag);
// Kalibrierung Hall-Sensor
int mvOst = 252;
int mvSued = 488; // 06.12.22, neu kalibriert
int mvWest = 738;
float Elevation;
float elevation;
float Aufgang;
float Untergang;
float Deklination;
float AzS;
float Zeitgleichung;
float Zeitdifferenz;
float AufgangOrtszeit;
float UntergangOrtszeit;
float Tageslaenge;
float Refraktion;
float MEZ; // Mitteleuropäische Zeit
float MOZ; // Mittlere Ortszeit
float WOZ; // Wahre Ortszeit
float ZeitSeitMittag;
const float pi = 3.14159265;
const float kwert = pi / 180;
const float latitude = 51.222191;
const float longitude = 7.954169;
const float B = latitude * kwert; // geogr. Breite in Radians
const float h = -(50.0 / 60.0) * kwert; // Höhe des Sonnenmittelpunkts bei
Aufgang
const int Zeitzone = 1; // Zeitzone Greenwich + 1 (z.B. Berlin)
int Grenzwert;
int AzI;
int sensorValue; // Analoger Ist-Wert (Hall-Sensor)
int i2;
MEZ = Stunde + Minute / 60 + Sekunde / 3600; // Mitteleuropäische Zeit
Zeitgleichung = BerechneZeitgleichung (yearday); // Aufruf der Funktion: BerechneZeitgleichung
ZeitSeitMittag = MEZ + longitude / 15.0 - Zeitzone - 12 + Zeitgleichung; //
Berechne ZeitSeitMittag
Deklination = BerechneDeklination (yearday); // Aufruf der Funktion: BerechneDeklination
Zeitdifferenz = BerechneZeitdifferenz (h, pi, latitude, kwert, Deklination); //
Aufruf der Funktion: BerechneZeitdifferenz
AzS = SunAngles(Deklination, B, kwert, pi, ZeitSeitMittag, Elevation); // Aufruf
der Funktion: SunAngles
Tageslaenge = BerechneTageslaenge (Zeitdifferenz, Zeitgleichung, longitude,
Zeitzone, Aufgang, Untergang); // Aufruf der Funktion: BerechneTageslaenge
Elevation = Elevation / kwert;
Deklination = Deklination / kwert;
MOZ = MEZ - (-longitude / 15) - 1; // Berechne Mittlere Ortszeit aus MEZ
WOZ = MOZ + Zeitgleichung; // Berechne Wahre Ortszeit
int WOZdez = (int)WOZ;
int WOZmin = (WOZ - WOZdez) * 60;
int MOZdez = (int)MOZ;
int MOZmin = (MOZ - MOZdez) * 60;
int StdL = (int)Tageslaenge;
int MinL = (int)((Tageslaenge - StdL) * 60);
int StdA = (int)Aufgang;
int MinA = (int)((Aufgang - StdA) * 60);
int StdU = (int)Untergang;
int MinU = (int)((Untergang - StdU) * 60);
if (StdL >= 7 && StdL < 9) {
Grenzwert = 135;
}; // Grenzwerte für Rücklaufposition
if (StdL >= 9 && StdL < 10) {
Grenzwert = 120;
}; // abhängig von der Tageslänge (nur Stunde)
if (StdL >= 10 && StdL < 11) {
Grenzwert = 104;
};
if (StdL >= 11 && StdL < 13) {
Grenzwert = 90;
};
if (StdL >= 13 && StdL < 14) {
Grenzwert = 75;
};
if (StdL >= 14 && StdL < 15) {
Grenzwert = 60;
};
if (StdL >= 15 && StdL < 17) {
Grenzwert = 45;
};
sensorValue = analogRead(A2); // Auslesen Hall-Sensor an Pin A2
AzI = MotorenSteuerung (AzS, Elevation, sensorValue, Grenzwert, stepsV, stepsR,
stepsSR, mvOst, mvSued, mvWest); // Aufruf der Funktion: MotorenSteuerung
// Für Anzeige Windrichtung, abhängig von der Position des Drehtellers
const char* windrichtung[16] = {"Nord", "NNO", "NO", "ONO", "Ost", "OSO", "SO",
"SSO", "Sued", "SSW", "SW", "WSW", "West", "WNW", "NW", "NNW"};
int i1 = Windrichtung(AzI, AzS, i2); // Aufruf Funktion: Windrichtung
String wr1 = windrichtung[i1];
String wr2 = windrichtung[i2];
// 5-Volt-Solarpanel
const int analogPin = A15;
float pvmod = analogRead(analogPin);
float Volt = Solarspannung (pvmod); // Aufruf Funktion: Solarspannung
float Prozent = Volt / 4.75 * 100;
// für Anzeige: Stunden, Minuten, Deklination
int Std = (int)Tageslaenge;
int Min = (int)((Tageslaenge - Std) * 60);
// Ausgabe auf Nextion-Display 5.0""
// Seite 0: Home
Serial2.print("page0.t0.txt=\"");
Serial2.print("Nextion-Solartracker-Projekt");
Serial2.write('"');
endNextionCommand();
Serial2.print("ref=page0.t0.txt");
endNextionCommand();
Serial2.print("page0.t1.txt=\"");
Serial2.print("Version 3.5 vom 15.01.2023");
Serial2.write('"');
endNextionCommand();
Serial2.print("ref=page0.t1.txt");
endNextionCommand();
Serial2.print("page0.t2.txt=\"");
Serial2.print("Dr. Michael Schulte");
Serial2.write('"');
endNextionCommand();
Serial2.print("ref=page0.t2.txt");
endNextionCommand();
Serial2.print("page0.t3.txt=\"");
Serial2.print("http://wetterstation.mi-schu.de");
Serial2.write('"');
endNextionCommand();
Serial2.print("ref=page0.t5.txt");
endNextionCommand();
Serial2.print("page0.t4.txt=\"");
Serial2.print("E-Mail: wetter.roenkhausen@gmx.de");
Serial2.write('"');
endNextionCommand();
Serial2.print("ref=page0.t4.txt");
endNextionCommand();
// Seite 1: Time
Serial2.print("page1.t0.txt=\"");
Serial2.print(clock.dateFormat(" d. M. Y H:i:s", dt));
Serial2.print(" MEZ");
Serial2.write('"');
endNextionCommand();
Serial2.print("ref=page1.t0.txt");
endNextionCommand();
Serial2.print("page1.t1.txt=\"");
if (WOZmin >= 0 && WOZmin < 10) {
Serial2.print(" Wahre Ortszeit: " + String (WOZdez) + ":" + "0" + String (WOZmin)
+ " h");
}
else
{ Serial2.print(" Wahre Ortszeit: " + String (WOZdez) + ":" + String (WOZmin) +
" h");
}
Serial2.write('"');
endNextionCommand();
Serial2.print("ref=page1.t1.txt");
endNextionCommand();
Serial2.print("page1.t2.txt=\"");
if (MOZmin >= 0 && MOZmin < 10) {
Serial2.print(" Mittlere Ortszeit: " + String (MOZdez) + ":" + "0" + String (MOZmin)
+ " h");
}
else
{ Serial2.print(" Mittlere Ortszeit: " + String (MOZdez) + ":" + String (MOZmin)
+ " h");
}
Serial2.write('"');
endNextionCommand();
Serial2.print("ref=page1.t2.txt");
endNextionCommand();
Serial2.print("page1.t3.txt=\"");
Serial2.print(" Tag im Jahr: " + String(yearday));
Serial2.write('"');
endNextionCommand();
Serial2.print("ref=page0.t3.txt");
endNextionCommand();
Serial2.print("page1.t4.txt=\"");
if (MinA >= 0 && MinA < 10) {
Serial2.print(" Sonnenaufgang: " + String (StdA) + ":" + "0" + String (MinA) + "
h");
}
else
{ Serial2.print(" Sonnenaufgang: " + String (StdA) + ":" + String (MinA) + "
h");
}
Serial2.write('"');
endNextionCommand();
Serial2.print("ref=page1.t4.txt");
endNextionCommand();
Serial2.print("page1.t5.txt=\"");
if (MinU >= 0 && MinU < 10) {
Serial2.println(" Sonnenuntergang: " + String (StdU) + ":" + "0" + String (MinU)
+ " h");
}
else
{ Serial2.println(" Sonnenuntergang: " + String (StdU) + ":" + String (MinU) + "
h");
}
Serial2.write('"');
endNextionCommand();
Serial2.print("ref=page1.t5.txt");
endNextionCommand();
Serial2.print("page1.t6.txt=\"");
if (MinL >= 0 && MinL < 10) {
Serial2.print(" Tageslaenge: " + String (StdL) + ":" + "0" + String (MinL) + "
h");
}
else
{ Serial2.print(" Tageslaenge: " + String (StdL) + ":" + String (MinL) + " h");
}
Serial2.write('"');
endNextionCommand();
Serial2.print("ref=page1.t6.txt");
endNextionCommand();
// Seite 2: Data
Serial2.print("page2.t0.txt=\"");
Serial2.print(clock.dateFormat(" d. M. Y H:i:s", dt));
Serial2.print(" MEZ");
Serial2.write('"');
endNextionCommand();
Serial2.print("ref=page2.t0.txt");
endNextionCommand();
Serial2.print("page2.t1.txt=\"");
Serial2.print(" Azimut-Soll: " + String(AzS) + " Grd " + "(" + String(wr2) +
")");
Serial2.write('"');
endNextionCommand();
Serial2.print("ref=page2.t1.txt");
endNextionCommand();
Serial2.print("page2.t2.txt=\"");
Serial2.print(" Azimut-Ist (Panel): " + String(AzI) + ".00 Grd " + "(" +
String(wr1) + ")");
Serial2.write('"');
endNextionCommand();
Serial2.print("ref=page2.t2.txt");
endNextionCommand();
Serial2.print("page2.t3.txt=\"");
Serial2.print(" Elevation: " + String(Elevation) + " Grd");
Serial2.write('"');
endNextionCommand();
Serial2.print("ref = page2.t3.txt");
endNextionCommand();
Serial2.print("page2.t4.txt=\"");
Serial2.print(" Deklination: " + String(Deklination) + " Grd");
Serial2.write('"');
endNextionCommand();
Serial2.print("ref=page2.t4.txt");
endNextionCommand();
Serial2.print("page2.t5.txt=\"");
Serial2.print(" Zeitgleichung: " + String(Zeitgleichung * 60) + " min");
Serial2.write('"');
endNextionCommand();
Serial2.print("ref=page2.t5.txt");
endNextionCommand();
Serial2.print("page2.t6.txt=\"");
Serial2.print(" Solarspannung: " + String(Volt) + " V " + "(" + String (int
(Prozent)) + "% Vmax" + ")");
Serial2.write('"');
endNextionCommand();
Serial2.print("ref=page2.t6.txt");
endNextionCommand();
// Seite 3: Sun
Serial2.print("page3.t0.txt=\"");
Serial2.print(" Azimut-Soll: " + String(AzS) + " Grd");
Serial2.write('"');
endNextionCommand();
Serial2.print("ref = page3.t5.txt");
endNextionCommand();
Serial2.print("page3.t1.txt=\"");
Serial2.print(" Azimut-Ist: " + String(AzI) + " Grd");
Serial2.write('"');
endNextionCommand();
Serial2.print("ref=page2.t2.txt");
endNextionCommand();
Serial2.print("page3.t2.txt=\"");
Serial2.print(" Elevation: " + String(Elevation) + " Grd");
Serial2.write('"');
endNextionCommand();
Serial2.print("ref=page2.t5.txt");
endNextionCommand();
}
void endNextionCommand()
{
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
}
// Funktion: Windrichtung
int Windrichtung (float AzI, float AzS, int &i2) {
int i1;
if (AzI >= 0 && AzI < 11) {
i1 = 0;
}
if (AzS >= 0 && AzS < 11) {
i2 = 0;
}
if (AzI >= 11 && AzI < 34) {
i1 = 1;
}
if (AzS >= 11 && AzS < 34) {
i2 = 1;
}
if (AzI >= 34 && AzI < 56) {
i1 = 2;
}
if (AzS >= 34 && AzS < 56) {
i2 = 2;
}
if (AzI >= 56 && AzI < 79) {
i1 = 3;
}
if (AzS >= 56 && AzS < 79) {
i2 = 3;
}
if (AzI >= 79 && AzI < 101) {
i1 = 4;
}
if (AzS >= 79 && AzS < 101) {
i2 = 4;
}
if (AzI >= 101 && AzI < 124) {
i1 = 5;
}
if (AzS >= 101 && AzS < 124) {
i2 = 5;
}
if (AzI >= 124 && AzI < 146) {
i1 = 6;
}
if (AzS >= 124 && AzS < 146) {
i2 = 6;
}
if (AzI >= 146 && AzI < 169) {
i1 = 7;
}
if (AzS >= 146 && AzS < 169) {
i2 = 7;
}
if (AzI >= 169 && AzI < 191) {
i1 = 8;
}
if (AzS >= 169 && AzS < 191) {
i2 = 8;
}
if (AzI >= 191 && AzI < 214) {
i1 = 9;
}
if (AzS >= 191 && AzS < 214) {
i2 = 9;
}
if (AzI >= 214 && AzI < 236) {
i1 = 10;
}
if (AzS >= 214 && AzS < 236) {
i2 = 10;
}
if (AzI >= 236 && AzI < 259) {
i1 = 11;
}
if (AzS >= 236 && AzS < 259) {
i2 = 11;
}
if (AzI >= 259 && AzI < 281) {
i1 = 12;
}
if (AzS >= 259 && AzS < 281) {
i2 = 12;
}
if (AzI >= 281 && AzI < 304) {
i1 = 13;
}
if (AzS >= 281 && AzS < 304) {
i2 = 13;
}
if (AzI >= 304 && AzI < 326) {
i1 = 14;
}
if (AzS >= 304 && AzS < 326) {
i2 = 14;
}
if (AzI >= 326 && AzI < 349) {
i1 = 15;
}
if (AzS >= 326 && AzS < 349) {
i2 = 15;
}
return i1;
}
// Funktion: SunAngles für die Berechnung von Azimut und Elevation
float SunAngles (float Deklination, float B, float kwert, float pi, float
ZeitSeitMittag, float & Elevation) {
float DK = Deklination;
float cosdec = cos(DK);
float sindec = sin(DK);
float lha = ZeitSeitMittag * (1.0027379 - 1 / 365.25) * 15 * kwert;
float coslha = cos(lha);
float sinlha = sin(lha);
float coslat = cos(B);
float sinlat = sin(B);
float N = -cosdec * sinlha;
float D = sindec * coslat - cosdec * coslha * sinlat;
Elevation = asin(sindec * sinlat + cosdec * coslha * coslat); // Höhe des
Sonnenmittelpunktes über dem Horizont
float AzS = atan2(N, D);
if (AzS < 0) {
AzS += 2 * pi;
}
return (AzS / kwert);
}
// Funktion: BerechneZeitgleichung
float BerechneZeitgleichung (int yearday) {
float Zeitgleichung = -0.170869921174742 * sin(0.0336997028793971 * yearday +
0.465419984181394) - 0.129890681040717 * sin(0.0178674832556871 * yearday -
0.167936777524864);
return Zeitgleichung;
}
// Funktion: BerechneDeklination
float BerechneDeklination(int yearday) {
float Deklination = 0.409526325277017 * sin(0.0169060504029192 * (yearday -
80.0856919827619));
return Deklination;
}
// Funktion: BerechneZeitdifferenz
float BerechneZeitdifferenz(float h, float pi, float latitude, float kwert,
float Deklination) {
float Zeitdifferenz;
Zeitdifferenz = 12 * acos((sin(h) - sin(latitude * kwert) * sin(Deklination)) /
(cos(latitude * kwert) * cos(Deklination))) / pi;
return Zeitdifferenz;
}
// Funktion: BerechneTageslaenge
float BerechneTageslaenge (float Zeitdifferenz, float Zeitgleichung, float
longitude, int Zeitzone, float & Aufgang, float & Untergang) {
float AufgangOrtszeit = 12 - Zeitdifferenz - Zeitgleichung;
float UntergangOrtszeit = 12 + Zeitdifferenz - Zeitgleichung;
Aufgang = AufgangOrtszeit - longitude / 15 + Zeitzone;
Untergang = UntergangOrtszeit - longitude / 15 + Zeitzone;
float Tageslaenge = Untergang - Aufgang;
return Tageslaenge;
}
// Funktion: MotorenSteuerung, Ansteuerung von Steppermotor und Servo
int MotorenSteuerung (float AzS, float Elevation, int sensorValue, int
Grenzwert, const int stepsV, const int stepsR, const int stepsSR, const int
mvOst, const int mvSued, const int mvWest)
{
float AzI;
constrain(Elevation, 0, 120); // Begrenzung des Servo-Wertebereichs
if (sensorValue >= 0 && sensorValue < mvSued) {
AzI = map(sensorValue, mvOst, mvSued, 90, 180); // 03.12.22, neu kalibriert:
Skalierung der Hall-Sensorwerte in Gradwerte 90-180 Grad
}
if (sensorValue >= mvSued && sensorValue <= 900) {
AzI = map(sensorValue, mvSued, mvWest, 180, 270); // 03.12.22, neu kalibriert:
Skalierung der Hall-Sensorwerte in Gradwerte 180-270 Grad
}
constrain(AzI, 40, 320); // Begrenzung des Azimut-Soll-Wertebereichs
if (Elevation > -2) { // Solange Elevation > 0 --> Sonne steht über dem Horizont
servo2.write(Elevation - 3); // Schreiben der Servoposition (Nachführung)
if ((int)AzI < (int)AzS) { // Azimut-Nachführung: Wenn Hall-Sensorwert kleiner
als Azimut, dann:
digitalWrite(pwmA, HIGH); // Stepper Strom an
digitalWrite(pwmB, HIGH); // Stepper Strom an
digitalWrite(4, HIGH); // LED grün an
myStepper.step(stepsV); // Step one revolution in one direction
delay (500);
digitalWrite(4, LOW); // LED grün aus
digitalWrite(7, LOW); // LED rot aus
digitalWrite(6, LOW); // LED gelb aus
digitalWrite(pwmA, LOW); // Stepper stromlos schalten
digitalWrite(pwmB, LOW); // Stepper stromlos schalten
}
if ((int)AzI > (int)AzS) { // Azimut-Nachführung: Wenn Hall-Sensorwert grösser
als Azimut, dann:
digitalWrite(pwmA, HIGH); // Stepper Strom an
digitalWrite(pwmB, HIGH); // Stepper Strom an
servo2.write(Elevation - 3); // Schreiben der Servoposition (Nachführung)
digitalWrite(7, HIGH); // LED rot an
digitalWrite(6, LOW); // LED gelb aus
myStepper.step(stepsR); // Step one revolution in one direction
delay (500);
digitalWrite(7, LOW); // LED rot aus
digitalWrite(4, LOW); // LED grün aus
digitalWrite(pwmA, LOW); // Stepper stromlos schalten
digitalWrite(pwmB, LOW); // Stepper stromlos schalten
}
}
else { // Sonne ist untergegangen --> Rückführung auf Anfangsposition
if (Elevation <= -2 && (AzI - 2) >= Grenzwert) { // Azimut-Rückführung: Wenn
Elevation < -1 (Sonne ist vollständig untergegangen), dann:
delay(500);
digitalWrite(pwmA, HIGH);
digitalWrite(pwmB, HIGH);
digitalWrite(6, HIGH); // LED gelb an
myStepper.step(stepsSR); // Step one revolution in one direction
delay (500);
digitalWrite(6, LOW); // LED gelb aus
delay(500);
digitalWrite(6, HIGH); // LED gelb an
delay(500);
digitalWrite(6, LOW); // LED gelb aus
delay(500);
digitalWrite(6, HIGH); // LED gelb an
delay (500);
digitalWrite(6, LOW); // LED gelb aus
delay(500);
digitalWrite(6, HIGH); // LED gelb an
delay (500);
digitalWrite(6, LOW); // LED gelb aus
digitalWrite(pwmA, LOW); // Stepper stromlos schalten
digitalWrite(pwmB, LOW); // Stepper stromlos schalten
delay(500);
}
}
if (int(AzI) == int(AzS)) { // Stepper
aus gelbe LED an beim
Erreichen der Zielposition (AzI == AzS)
digitalWrite(6, HIGH);
digitalWrite(pwmA, LOW); // Stepper stromlos schalten
digitalWrite(pwmB, LOW); // Stepper stromlos schalten
}
return AzI; // Rückgabewert: AzimutIst
}
// Funktion: Solarspannung
float Solarspannung(float pvmod) // Funktion: Solarspannung
{
float Volt;
Volt = pvmod / 1023 * 4.75; // Umrechnung Analogwert in Spannungswert (Volt)
return Volt;
}