Hilfe bei Project

Ein Hallo an die Community :smiley:

Ich habe ein kleines Project erstellt das einen Vorhang automatisch per Helligkeitsfühler außen und

innen auf und zu fahren lässt. Zudem kann man das ganze auch manuell steuern.

Es existiert auch eine 2 Ebene in der man diverse Einstellungen vornehmen kann wie etwa die Empfindlichkeit der Fühler,Anlage rücksetzten, manuell auf und zu, und eine programmierbare Stellung.

Soll so etwas wie ne Fachmannebene sein wenn man enter länger als 5 Sekunden drückt.

Da ich ein kompletter Anfänger bin wollte ich fragen ob vll. ein Profi mal darüber schauen kann ob man gewisse Sachen leichter oder besser programmieren kann.

Das ganze funktioniert soweit schon.

Der Code ist sicherlich schrecklich und meine Namen Wahl für Variablen auch nicht die beste.

Mir geht es mehr darum ob man gewisse Sachen besser machen kann (außer die genannten :D)

Vielen Dank für die Hilfe :smiley:

bastlwastl

das ganze hat über 500 zeilen deswegen wollte ich eigentlich noch fragen ob ich das ganze auf einmal

posten soll oder abschnittsweise wie menu, automatik etc

Machs wie du willst, schimpfen werden die eh :smiley:

Schimpfen tut keiner, aber besser lesbar ist der Code wenn er in Code-Tags eingefügt wird.

Der Code ist zur freien Verwendung. Bitte nur darum falls jemand Fehler findet oder bessere Änderungen macht es hier zu posten :smiley:

Das ist das Menu. Es handelt sich um 4 Leds mit 3 taster wo einer davon enter ist.

int licht = 1;
int licht1 = 255;
int menu = 1;
int draussen = 0;
int drinnen = 0;
long zeitanfang6 = 0;
long zeitanfang5 = 0;
long zeitanfang2 = 0;
long zeitanfang1 = 0;
long zeitanfang = 0;
int zu = 1;
int n = 7;
int n1 =0;
int m = 0;
int o = 0;

int f = 1;
int g = 1;
int h = 0;
int j = 1;
int hand = 1;
int intervall1 = 200;

int tasterfenster = 2;
int endlinks = 3;
int endrechts = 4;
int menulinks = 5;
int menurechts = 6;
int ledauto = 7;
int ledauf = 8;
int ledmitte = 9;
int ledzu = 10;
int enter = 11;
unsigned long previousMillis = 0;
const long interval = 300000;         
long timer = 0;
int start = 1;
int halb = 0;
int sensordraussen = 0;
int sensordrinnen = 1;
int motor = 13;
int motordir = 12;
void setup() {
  Serial.begin(9600);
  delay(20);
  pinMode(tasterfenster, INPUT);
  pinMode(endlinks, INPUT);
  pinMode(endrechts, INPUT);
  pinMode(menulinks, INPUT);
  pinMode(menurechts, INPUT);
  pinMode(enter, INPUT);
  pinMode(ledauto, OUTPUT);
  pinMode(ledauf, OUTPUT);
  pinMode(ledmitte, OUTPUT);
  pinMode(ledzu, OUTPUT);
  pinMode(motor, OUTPUT);
  pinMode(motordir, OUTPUT);
  startanlage();

}


void loop() {
  
  
  
  if (digitalRead(tasterfenster) == LOW)
  {
    error();
  }
  // put your main code here, to run repeatedly:
  digitalWrite(n, HIGH);
  if (digitalRead(menurechts) == HIGH)
  {
    if (n < 10 && m == 0)
    {
      digitalWrite(n, LOW);
      n = n + 1;
      digitalWrite(n, HIGH);
      m = 1;
    }
  }
  if (digitalRead(menurechts) == LOW)
  {
    m = 0;
  }
  if (digitalRead(menulinks) == HIGH)
  {
    if (n > 7 && o == 0)
    {
      digitalWrite(n, LOW);
      n = n - 1;
      digitalWrite(n, HIGH);
      o = 1;
    }
  }
  if (digitalRead(menulinks) == LOW)
  {
    o = 0;
  }
  if (digitalRead(enter) == HIGH)
  {
    zeitanfang = millis();
    while (digitalRead(enter) == HIGH && digitalRead(tasterfenster) == HIGH)
    {
      zeitanfang1 = millis() - zeitanfang;
    }
    if (zeitanfang1 < intervall1)
    {
      if (n == 7 && menu == 1)
      {
        automatik();
      }
      if (n == 8 && menu == 1)
      {
        auf();
      }
      if (n == 9 && menu == 1)
      {
        mitte();
      }
      if (n == 10 && menu == 1)
      {
        zu1();
      }
      if (n == 7 && menu == 2)
      {
        Serial.println("Starte Anlage");
        j = 1;
        startanlage();
      }
      if (n == 8 && menu == 2)
      {
        auf();
      }
      if (n == 9 && menu == 2)
      {
        mitte();
      }
      if (n == 10 && menu == 2)
      {
        licht = 1;
        zu1();
         
      }
    }
    if ( zeitanfang1 > intervall1 && menu == 1)
    {
      for (int i = 0; i < 4; i++)
      {
        digitalWrite(ledauto, HIGH);
        digitalWrite(ledauf, HIGH);
        digitalWrite(ledmitte, HIGH);
        digitalWrite(ledzu, HIGH);
        delay(500);
        digitalWrite(ledauto, LOW);
        digitalWrite(ledauf, LOW);
        digitalWrite(ledmitte, LOW);
        digitalWrite(ledzu, LOW);
        delay (500);
        menu = 2;
        n = 7;
      }
      zeitanfang1 = 0;
    }
    if ( zeitanfang1 > intervall1 && menu == 2 )
    {
      for (int i = 0; i < 4; i++)
      {
        digitalWrite(ledauto, HIGH);
        digitalWrite(ledauf, HIGH);
        digitalWrite(ledmitte, HIGH);
        digitalWrite(ledzu, HIGH);
        delay(500);
        digitalWrite(ledauto, LOW);
        digitalWrite(ledauf, LOW);
        digitalWrite(ledmitte, LOW);
        digitalWrite(ledzu, LOW);
        delay (500);
        menu = 1;
        n = 7;
      }

    }




  }
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) 
  {
    
    previousMillis = currentMillis;
    if (menu == 1 && digitalRead(ledauto) == HIGH)
    {
    automatik();
    }
  }
}

Das ist Startanlage und Automatik betrieb

void startanlage()
{



  while (j == 1)
  {

    digitalWrite(ledauto, HIGH);
    digitalWrite(ledzu, HIGH);
    delay(500);
    digitalWrite(ledauto, LOW);
    digitalWrite(ledzu, LOW);
    delay (500);



    if (digitalRead(enter) == HIGH)
    {
      j = 0;
      delay(2000);
    }

  }
  if (digitalRead(tasterfenster) == LOW)
  {
    error();
  }
  if (digitalRead(endrechts) == HIGH && digitalRead(tasterfenster) == HIGH)
  {
    digitalWrite(motordir, HIGH);
    digitalWrite(motor, HIGH);
    while (zu == 1 )
    {
      if (digitalRead(tasterfenster) == LOW)
      {
        error();
      }
      if (digitalRead(endlinks) == HIGH )
      {
        digitalWrite(motordir, LOW);
        digitalWrite(motor, LOW);
        zu = 0;
      }
    }
    zu = 1;
  }
  if (digitalRead(endlinks) == LOW && digitalRead(endrechts) == LOW && digitalRead(tasterfenster) == HIGH)
  {
    digitalWrite(motordir, HIGH);
    digitalWrite(motor, HIGH);
    while (zu == 1 )
    {
      if (digitalRead(tasterfenster) == LOW)
      {
        error();
      }
      if (digitalRead(endlinks) == HIGH )
      {
        digitalWrite(motordir, LOW);
        digitalWrite(motor, LOW);
        zu = 0;
      }
    }
    zu = 1;
  }
}
void automatik()
{
  Serial.println("Automatik");
  if (digitalRead(tasterfenster) == LOW)
  {
    error();
  }
  draussen = analogRead(sensordraussen);
  drinnen = analogRead(sensordrinnen);
  if (draussen > drinnen && digitalRead(tasterfenster) == HIGH)
  {
    if (digitalRead(endlinks) == HIGH && digitalRead(tasterfenster) == HIGH )
    {
    }
    else
    {
      digitalWrite(motordir, HIGH);
      digitalWrite(motor, HIGH);
      while (zu == 1 )
      {
        if (digitalRead(tasterfenster) == LOW)
        {
          error();
        }
        if (digitalRead(endlinks) == HIGH )
        {
          digitalWrite(motordir, LOW);
          digitalWrite(motor, LOW);
          zu = 0;
        }
      }
      zu = 1;
    }
  }
  if (drinnen > draussen  && digitalRead(tasterfenster) == HIGH)
  {
    if (digitalRead(endrechts) == HIGH && digitalRead(tasterfenster) == HIGH )
    {
    }
    else
    {
      digitalWrite(motordir, LOW);
      digitalWrite(motor, HIGH);
      while (zu == 1 )
      {
        if (digitalRead(tasterfenster) == LOW)
        {
          error();
        }
        if (digitalRead(endrechts) == HIGH )
        {
          digitalWrite(motordir, LOW);
          digitalWrite(motor, LOW);
          zu = 0;
        }
      }
      zu = 1;
    }
  }
}

irgendwie fehlen da ein paar Funktionen ( error(), auf(), mitte(), zu1() )
Die Konstanten solltest du mit const deklarieren.
Deine Taster mußt du mit Pulldown Widerständen versehen, oder die internen Pullup's aktivieren und dann auf low abfragen.
Die boolschen Variablen als bool deklarieren.
Deine delay's solltest du über eine Zeitabfrage mit millis() ersetzen sonst stopt das Programm hier und es können z.B. keine Taster mehr abgefragt werden.
deine zeitanfang solltest du als unsigned long deklarieren, sonst hast du irgendwann einen negativen Überlauf.

hier sind noch auf und mitte

void auf()
{
  if (menu == 2)
  {
    hand = 1;
    while (hand == 1)
    {
      if (digitalRead(tasterfenster) == LOW)
      {
        error();
      }
      while (digitalRead(menulinks) == HIGH && digitalRead(endlinks) == LOW && digitalRead(tasterfenster) == HIGH)
      {
        digitalWrite(motordir, HIGH);
        digitalWrite(motor, HIGH);
      }
      digitalWrite(motordir, LOW);
      digitalWrite(motor, LOW);
      while (digitalRead(menurechts) == HIGH  && digitalRead(endrechts) == LOW && digitalRead(tasterfenster) == HIGH)
      {
        digitalWrite(motordir, LOW);
        digitalWrite(motor, HIGH);
      }
      digitalWrite(motordir, LOW);
      digitalWrite(motor, LOW);
      if (digitalRead(enter) == HIGH)
      {
        hand = 0;
        delay(2000);
      }
    }
  }
  if (menu == 1 && digitalRead(tasterfenster) == HIGH)
  {
    if (digitalRead(tasterfenster) == LOW)
    {
      error();
    }
    if (digitalRead(endlinks) == HIGH  && digitalRead(tasterfenster) == HIGH)
    {
    }
    else
    {
      digitalWrite(motordir, HIGH);
      digitalWrite(motor, HIGH);
      while (zu == 1 )
      {
        if (digitalRead(tasterfenster) == LOW)
        {
          error();
        }
        if (digitalRead(endlinks) == HIGH )
        {
          digitalWrite(motordir, LOW);
          digitalWrite(motor, LOW);
          zu = 0;
        }
      }
      zu = 1;
    }
  }
}
void mitte()
{
  if (digitalRead(tasterfenster) == LOW)
  {
    error();
  }
  Serial.println("mitte");
  if (menu == 1 && digitalRead(tasterfenster) == HIGH)
  {
    while (digitalRead(endlinks) == LOW )
    {
      Serial.println("fahre");
      digitalWrite(motordir, HIGH);
      digitalWrite(motor, HIGH);
    }
    Serial.println("angekommen");
    digitalWrite(motordir, LOW);
    digitalWrite(motor, LOW);
    delay(2000);
    //Serial.println("fahre auf");
    if (digitalRead(endlinks) == HIGH && digitalRead(tasterfenster) == HIGH )
      Serial.println("if erfüllt");
    zeitanfang6 = millis();
    Serial.println("zeit genommen");
    while ((millis() - zeitanfang6) < zeitanfang2 ) {
      digitalWrite(motordir, LOW);
      digitalWrite(motor, HIGH);
      Serial.println("fahre zu");
    }
    Serial.println("angekommen");
    digitalWrite(motordir, LOW);
    digitalWrite(motor, LOW);
  }
  if (menu == 2 && digitalRead(tasterfenster) == HIGH)
  {
    zeitanfang2 = 0;
    while (digitalRead(endlinks) == LOW && digitalRead(tasterfenster) == HIGH )
    {
      digitalWrite(motordir, HIGH);
      digitalWrite(motor, HIGH);
    }
    digitalWrite(motordir, LOW);
    digitalWrite(motor, LOW);
    g = 1;
    while (g == 1)
    {
      if (digitalRead(menurechts) == LOW)
      {
        f = 1;
      }
      while (digitalRead(menurechts) == HIGH  && digitalRead(endrechts) == LOW && digitalRead(tasterfenster) == HIGH)
      {
        if (f == 1)
        {
          zeitanfang5 = millis();
          f = 0;
        }
        digitalWrite(motordir, LOW);
        digitalWrite(motor, HIGH);
        h = 1;
      }
      if (h == 1)
      {
        zeitanfang2 = zeitanfang2 + ((millis() - zeitanfang5));
        h = 0;
      }
      digitalWrite(motordir, LOW);
      digitalWrite(motor, LOW);
      if (digitalRead(enter) == HIGH)
      {
        g = 0;
        delay(2000);
      }
    }
  }
}

Wenn du für die Motorbewegungen eigene Routinen einsetzt, wird dein Code übersichtlicher
und die Chance sich zu vertippen sinkt stark, also z.B.

void motorAus() {
  digitalWrite(motordir, LOW);
  digitalWrite(motor, LOW);
}
void motorLinks() {
  digitalWrite(motordir, HIGH);
  digitalWrite(motor, HIGH);
}
void motorRechts() {
  digitalWrite(motordir, LOW);
  digitalWrite(motor, HIGH);
}

zu und error

void zu1()
{
  if (menu == 2)
  {
    n1 = n;
    digitalWrite(n, LOW);
    n = 7;
    while (licht == 1)
    {
     
     digitalWrite(n, HIGH);
  if (digitalRead(menurechts) == HIGH)
  {
    if (n < 10 && m == 0)
    {
      digitalWrite(n, HIGH);
      n = n + 1;
      digitalWrite(n, HIGH);
      m = 1;
    }
  }
  if (digitalRead(menurechts) == LOW)
  {
    m = 0;
  }
  if (digitalRead(menulinks) == HIGH)
  {
    if (n > 7 && o == 0)
    {
      digitalWrite(n, LOW);
      n = n - 1;
      digitalWrite(n, LOW);
      o = 1;
    }
  }
  if (digitalRead(menulinks) == LOW)
  {
    o = 0;
  }

  if (digitalRead(enter) == HIGH)
  {
    
      if (n == 7 && menu == 2)
      {
        licht1 = 255;
        
      }
      if (n == 8 && menu == 2)
      {
        licht1 = 510;
        
      }
      if (n == 9 && menu == 2)
      {
       licht1 = 765;
      }
      if (n == 10 && menu == 2)
      {
        licht1 = 1020;
      }
      licht = 0;
       n = n1;
    delay(2000);
    digitalWrite(ledauto, LOW);
    digitalWrite(ledzu, LOW);
    digitalWrite(ledmitte, LOW);
    digitalWrite(ledauf, LOW);
    }
    }
  }


    if (menu == 1)
{
  

    
  if (digitalRead(tasterfenster) == LOW)
  {
    error();
  }
  if (digitalRead(endrechts) == HIGH  && digitalRead(tasterfenster) == HIGH)
  {
  }
  else
  {
    digitalWrite(motordir, LOW);
    digitalWrite(motor, HIGH);
    while (zu == 1 )
    {
      if (digitalRead(tasterfenster) == LOW)
      {
        error();
      }
      if (digitalRead(endrechts) == HIGH )
      {
        digitalWrite(motordir, LOW);
        digitalWrite(motor, LOW);
        zu = 0;
      }
    }
    zu = 1;
  }
}
}
void error()
{
  if (digitalRead(tasterfenster) == LOW)
  {
    digitalWrite(motordir, LOW);
    digitalWrite(motor, LOW);
    while (digitalRead(tasterfenster) == LOW)
    {
      digitalWrite(ledauto, HIGH);
      digitalWrite(ledauf, HIGH);
      digitalWrite(ledmitte, HIGH);
      digitalWrite(ledzu, HIGH);
      delay(500);
      digitalWrite(ledauto, LOW);
      digitalWrite(ledauf, LOW);
      digitalWrite(ledmitte, LOW);
      digitalWrite(ledzu, LOW);
      delay(500);
    }
  }
}

Vielen Dank für die schnellen antworten!

Werde die sofort umsetzen :slight_smile:

Ich habe deinen Sketch mal ein wenig um gebastelt. Die Funktionen habe ich in Tabs gepackt, ich finde dadurch wird er überssichtlicher. Deine Delays solltest du aber noch ersetzen.

Vorhang.zip (4.13 KB)

Wäre es nicht auch einfacher den Vorhang zumindestens mit einer Zustandssteuerung zu betreiben?
(also Statemachine, FSM, endlicher Automat)

Um mehr zu deinem Programm zu sagen, oder gute Verbesserungsvorschläge zu machen,
müssten wir eine ganze Menge mehr wissen (z.B. wie ist alles verbunden bzw verschaltet).

Welche Bedeutung deine Variablen haben kann man teilweise nur erahnen,
was bedeutet zum Beispiel 'tasterfenster'?

Ein Taster am Fenster? Ein Taster der ein Fenster steuert?
Welche Funktion soll ein Betätigen genau haben?

Wenn du mal genau spezifizieren könntest was du genau erreichen möchtest,
würde das sehr helfen, ich kann am Code ja nur sehen was du machst.

Hallo :slight_smile:

Es handelt sich um einen vorhang der wie eine Schiebetüre betrieben wird. Es läuft oben eine umgelenkte Schleife wo der vorhang einmal vorne und einmal hinten an der schleife befestigt wird. Es existieren zwei endtaster einmal links und einmal sozusagen rechts in der mitte sprich ich überwache nur einen vorhang. Der Tasterfenster ist ein entschalter der überwacht ob das fenster oder balkontüre gschlossen ist. Der Vorhang soll ja nicht gegen eine offene türe fahren.

endlinks ist ein endtaster links auf vorhangschiene
endrechts ist das gleiche für rechts
tasterfenster überwacht das fenster obs geschlossen ist

für gekipptes fenster hab ich mir auch schon etwas überlegt . Man könnte vll. sogar einen winkel messer installieren der die position des fenster kennt.

den motor möchte ich auch noch überwachen. sollte der länger als eine gewisse zeit laufen schaltet die anlage auf störung. Das ganze mache ich so das er von 10 mal auf und zu fahren einen durchschnittswert erzeugt und so die schutzzeit bestimmt.

Was soll passieren wenn das Fenster geöffnet oder geschlossen wird (während irgendeine Aktion läuft)?
Hat der (statische) Zustand Fenster offen/zu Einfluss auf auf die Steuerung?

Wie hast du deine Taster verbunden (schließend gegen GND oder VCC)?
Benutzt du irgendwelche externen Widerstände an den Tastern?

Bist du sicher, dass deine Tasten nicht prellen?
(es gibt nichts was Prellen in deinem Code behandelt)

wird das fenster während dem fahren geöffnet dann schaltet die Anlage ab bis das fenster wieder geschlossen wird. Zur zeit ist es so das die anlage neu gestartet werden muss falls das fenster geöffnet wird. möchte das aber noch ändern das er den letzten zustand speichert das er nach dem fensterschluss wieder fährt. Ist das fenster offen dann fährt er erst gar nicht.

Die taster gehen gegen ground mit externem pullup widerstand.

Ich habe erst vor 3 Tagen mit dem Arduino angefangen.
Ich selber habe leider keinen Arduino. Ich mache das mit nem freund zusammen der das ganze equipment hat. Somit kann ich noch nicht sagen wie sich das prellen auf die Steuerung verhaltet. Habe das ganze in einem Simulator laufen lassen. da gibts kein prellen :smiley: Werde das aber heute ausprobieren.

Ok, vom Code her hatte ich aber eher den Eindruck, dass du HIGH als betätigt betrachtest,
oder ist die Verdrahtung der Menütasten anders?

Kondensatoren brauchst du keine, Entprellen kannst du in der Software.
Bei den vielen Tasten wäre wahrscheinlich auch die Nutzung einer Button Library sinnvoll bzw. praktisch,
da ist das Entprellen eingebaut.

'Schaltet die Anlage' ab heisst Motor wird einfach angehalten?

Zur Zeit heißt Anlage schaltet ab so das der Arduino resetet werden muss.

Die menutaster sind nur für die navigation durch das menu das einfach 4 rote leds nebeneinander darstellt. Darunter sind 3 taster links rechts enter. Drückt man Taster rechts wandert er zu led 2 ..... drückt man dann enter macht er das. im manuell betrieb kann man mit den tastern den vorhang solange fahren wie man rechts oder links drückt.
drückt man enter länger als 5 sekunden dann geht er in die fachmannebene. Da stehen dann weitere einstellungen zur verfügung.

Das menu sieht so aus:

Menu1:

automatik betrieb
auffahren
programmierte stellung anfahren
zufahren

Menu 2:
Neu start Anlage
Manuell fahren sprich rechts links wenn man taster drückt oder den vorhang nach installation kallibrieren muss
Stellung programmieren die im menu eins angefahren wird
Empfindlichkeit Fühler Einstellen.

bastlwastl:
Zur Zeit heißt Anlage schaltet ab so das der Arduino resetet werden muss.

Wie möchtest du es denn haben?

Beim Öffnen des Fensters Vorhang ganz auf? Einfach anhalten?

Ein Reset wäre meiner Ansicht nach eher etwas für echte Fehler,
wie z.B. nach der doppelten erwarteten Zeit ist der Endschalter immer noch nicht betätigt.

Die Menütasten schließen auch nach GND und haben externe Pullups?

Die Fühler (Licht) will ich so programmieren das sie einen gemischten wert bekommen sprich nur weil

nachts ein auto mit licht an vorbeifährt soll der vorhang ja nicht auffahren. die lichtänderung muss in

einer gewissen zeit passieren damit er den neuen wert übernimmt.