Arduino Projekt Solartracker

Guten Tag,

ich bin neu hier und arbeite derzeit an einem kleinen Schulprojekt. Da ich noch Anfänger im Programmieren bin, stoße ich auf einige Herausforderungen. Ich wäre sehr dankbar, wenn jemand Zeit und Lust hätte, meinen Code anzuschauen und mir Verbesserungsvorschläge zu geben.

In meinem Projekt habe ich einen Solartracker mit einem LCD-Display integriert, auf dem ich Werte anzeigen lasse. Allerdings flackert das Display stark. Woran könnte das liegen, und wie kann ich das beheben?

Vielen Dank im Voraus für eure Unterstützung!

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
// Servo-Definitionen
Servo servoVertical;
Servo servoHorizontal;
// LDR-Pins
float spannung = 4;
int ldrtopright = 0;                                
int ldrtopleft = 1;                                
int ldrbotleft = 3;                                
int ldrbotright = 2;
int differenceLimit = 20;
// LCD-Definitionen
LiquidCrystal_I2C lcd(0x27, 20, 4); // LCD mit I2C-Adresse 0x27, 20 Spalten, 4 Zeilen
void setup() {
  // Servos initialisieren
  servoVertical.attach(10);
  servoHorizontal.attach(9);
  servoVertical.write(90);  // Startposition: Mitte
  servoHorizontal.write(90); // Startposition: Mitte
  // LCD initialisieren
  lcd.begin(); // 20 Spalten, 4 Zeilen
  lcd.backlight();  // Hintergrundbeleuchtung einschalten
  // Begrüssungsnachricht
  lcd.setCursor(0, 0);
  lcd.print("System Startet...");
  delay(2000); 
  lcd.clear();
}
void loop() {
  static unsigned long previousMillis = 0;
  unsigned long currentMillis = millis();
  // Aktualisiert LDR werte und Spannung alle 2000 ms
  if (currentMillis - previousMillis >= 2000) {
    previousMillis = currentMillis;
    displayLDRValues(); // LCD aktualisieren
  }
  automaticsolartracker(); // Automatischer solartracker
}
// Solar Verfolgung Funktion
void automaticsolartracker() {
  // Invertiere die Werte der LDRs
  int topRight = 1023 - analogRead(ldrtopright);
  int topLeft = 1023 - analogRead(ldrtopleft);
  int botLeft = 1023 - analogRead(ldrbotleft);
  int botRight = 1023 - analogRead(ldrbotright);
  // Vertikale (hoch und runter) Steuerung: obere untere Sensoren berechnen
  int top = (analogRead(ldrtopright) + analogRead(ldrtopleft)) / 2;  // Durchschnitt obere LDR
  int bot = (analogRead(ldrbotright) + analogRead(ldrbotleft)) / 2; // Durchschnitt untere LDR
  int verticalDiff = bot - top;
  if (abs(verticalDiff) > differenceLimit) {
    if (verticalDiff < 0) {
      if (servoVertical.read() < 180) {
        delay(50); // Beweggung verlangsamen
        servoVertical.write(min(servoVertical.read() + 1, 180)); // Nach unten drehen, begrenzen auf 180 
      }
    } else {
      if (servoVertical.read() > 90) {
        delay(50); // Verlangsame Bewegung
        servoVertical.write(max(servoVertical.read() - 1, 90)); // Nach oben drehen, begrenzen auf 90
      }
    }
  }
  // Horizontale (links und rechts) Steuerung: rechte linke Sensoren berechnen
  int right = (analogRead(ldrtopright) + analogRead(ldrbotright)) / 2; // Durchschnitt rechte LDRs
  int left = (analogRead(ldrtopleft) + analogRead(ldrbotleft)) / 2;    // Durchschnitt linke LDRs
  int horizontalDiff = right - left;
  if (abs(horizontalDiff) > differenceLimit) {
    if (horizontalDiff < 0) {
      if (servoHorizontal.read() < 180) {
        delay(50); // Verlangsamete Bewegung
        servoHorizontal.write(min(servoHorizontal.read() + 1, 180)); // Nach rechts drehen
      }
    } else {
      if (servoHorizontal.read() > 0) {
        delay(50); // Verlangsamete Bewegung
        servoHorizontal.write(max(servoHorizontal.read() - 1, 0)); // Nach links drehen
      }
    }
  }
}
// Funktion zur Anzeige der Werte auf dem LCD
void displayLDRValues() {
  // Display komplett löschen
  lcd.clear();
  // Spannung berechnen
  float spannung = analogRead(A4) * (5.0 / 1023.0);
  // Invertiere die Werte der LDRs
  int ldrWertBL = 1023 - analogRead(ldrbotleft); // Bottom Left
  int ldrWertBR = 1023 - analogRead(ldrbotright); // Bottom Right
  int ldrWertTL = 1023 - analogRead(ldrtopleft);  // Top Left
  int ldrWertTR = 1023 - analogRead(ldrtopright); // Top Right
  // Spannung anzeigen (Zeile 0)
  lcd.setCursor(0, 0);
  lcd.print("Spannung:");
  lcd.setCursor(10, 0);
  lcd.print(spannung, 2); // Spannung mit 2 Dezimalstellen anzeigen
  lcd.print(" V");
  // LDR-Werte anzeigen
  // Zeile 1: Top Left (TL) und Top Right (TR)
  lcd.setCursor(0, 1);
  lcd.print("TL:");
  lcd.print(ldrWertTL);
  lcd.setCursor(10, 1);
  lcd.print("TR:");
  lcd.print(ldrWertTR);
  // Zeile 2: Bottom Left (BL) und Bottom Right (BR)
  lcd.setCursor(0, 3);
  lcd.print("BL:");
  lcd.print(ldrWertBL);
  lcd.setCursor(10, 3);
  lcd.print("BR:");
  lcd.print(ldrWertBR);
}

Wenn Du immer wieder die Anzeige löschst, dann flackert es.
Deshalb geht man dann meist folgendermaßen vor:

  1. nur schreiben, was sich wirklich geändert hat
  2. Werte immer auf eine feste Länge mit führenden Leerzeichen formatieren, so dass keine Restzeichen sichtbar bleiben.

Gruß Tommy

1 Like

Nimm eine lokale Uhr um das Servo zu drehen.

1 Like

Versuch mal den Codeteil:

void displayLDRValues()
{
  const uint8_t zeilenLen = 20;
  char buf[zeilenLen] = {" "};
  char *str = &buf[zeilenLen / 2];
  // Display komplett löschen
  // lcd.clear();
  // Spannung berechnen
  float spannung = analogRead(A4) * (5.0 / 1023.0);
  // Invertiere die Werte der LDRs
  int ldrWertBL = 1023 - analogRead(ldrbotleft); // Bottom Left
  int ldrWertBR = 1023 - analogRead(ldrbotright); // Bottom Right
  int ldrWertTL = 1023 - analogRead(ldrtopleft);  // Top Left
  int ldrWertTR = 1023 - analogRead(ldrtopright); // Top Right
  strcpy(buf, "Spannung: ");
  dtostrf(spannung, 2, 2, &buf[strlen(buf)]);
  strcat(buf, " V");
  // Spannung anzeigen (Zeile 0)
  lcd.setCursor(0, 0);
  lcd.print(buf);
  // LDR-Werte anzeigen
  // Zeile 1: Top Left (TL) und Top Right (TR)
  memset(buf, ' ', zeilenLen);
  snprintf(buf, zeilenLen, "TL: %i        ", ldrWertTL);
  snprintf(str, zeilenLen / 2, "TR:%i", ldrWertTR);
  lcd.setCursor(0, 1);
  lcd.print(buf);
  // Zeile 2: Bottom Left (BL) und Bottom Right (BR)
  memset(buf, ' ', zeilenLen);
  snprintf(buf, zeilenLen, "BL:%i        ", ldrWertBL);
  snprintf(str, zeilenLen / 2, "BR:%i", ldrWertBR);
  lcd.setCursor(0, 3);
  lcd.print(buf);
}

ungetestet.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.