Anfänger - Werte vor Programmstart abfragen

Hallo,
ich bin noch ziemlich neu, habe bis jetzt nur tutorials und als 1. Projekt eine kleine Bewässerung für meine Gurken umgesetzt, klappt aber ganz gut und hat Spaß gemacht es zu bauen und programmieren.

Würde bei meinem nächsten Projekt ein wenig Starthilfe benötigen. (wie ich da am besten anfange)

Den Ablauf stelle ich mir so vor.

  • Programm Start
  • Wert für Startverzögerung einstellen
  • Wert für 1. Pumpe einstellen
  • Wert für 2. Pumpe einstellen
  • Warten auf die Startverzögerung (ca. 10min)
  • Laufzeit 1. Pumpe (ca. 60min)
  • Laufzeit 1. Pumpe (ca. 90min)
  • alles abschalten und Programm ende

Dachte da an 1 oder eventuell auch 3 Potentiometer um die Werte einzustellen und einen Taster um es zu bestätigen. Später würde ich dann noch ein kleines Display dazu basteln.

Kann ich das mit einem Arduino Uno umsetzen? Oder was würdet ihr mir empfehlen?

Als Anfänger ist es schwer einen überblick zu bekommen. Hoffe ihr könnt mir da eventuell einen kleinen Schubs geben und die Richtung zeigen.

Schon mal vielen Dank und viele Grüße
Syndi

Einstellen ohne Rückmeldung (Display) halte ich für sehr schwierig. Wie oft müssen die Einstellungen geändert werden?

Ein Uno schafft so etwas locker. Anfangen kannst Du auch ohne Display und die Werte am PC (Serial Monitor) vorgeben. Dort kannst Du auch Debug-Ausgaben anzeigen lassen. Danach dann das Display in Betrieb nehmen und die Potentiometer.

Das ist für mich etwas unklar.
Wieso abschalten und Programm Ende ?

Normalerweise läuft ein Controller, so auch ein Arduino, immer durch. Das macht er mit der loop(). Und bestimmte Funktionen werden aus dieser loop heraus, zeitgesteuert aufgerufen.

nehme ich an.
Imho ist das eine klassische Schrittfolge

IDLE
WAIT
ON
OFF1
OFF2
(zurück nach IDLE)

Zum Thema "Poti" gibt es bei Thomann (Musikinstrumente) eine für Dich vielleicht hilfreiche Seite bzgl. der üblichen logarithmischen Potis, um keine unerwarteten Überraschungen zu erleben:

https://www.thomann.de/de/onlineexpert_page_potentiometer_charakteristik_und_drehrichtung.html

Man muss bei solchen Potis berücksichtigen, dass der nutzbare Winkelbereich deutlich kleiner ist als der mechanische. Dort sieht man - an einem konkreten Beispiel - dass von 300° noch ca. 210° unterscheidbar übrigbleiben.

Das kann genügen, hängt aber vom gewünschten bzw. erforderlichen Wertebereich (z.B. 0 bis 90 min) und der Auflösung (1 min, 5 min, 10 min) ab.

Lineare Potis würden sich hier ggf. eher empfehlen.

Den Programmablauf könnte ich mir so vorstellen, dass nach Abschalten der beiden Pumpen das Programm wieder auf die Eingaben der Werte wartet ... ("Abschalten" ginge natürlich auch, wenn der Controller seine Spannungsversorgung "kappt", z.B. per Relais mit Selbsthaltung oder per Funksteckdose).

Es gibt logaritmische und lineare Potentiometer. Man braucht nur die richtigen zu kaufen.

Du könntest die Potis mit einer Skala ausstatten, aber besser fände ich ein Display wo echte Zeiten angezeigt werden.

hier hätte ich einen Ablauf
IDLE, WAIT, A+B, B, retour ins IDLE:

// https://forum.arduino.cc/t/anfanger-werte-vor-programmstart-abfragen/1004723/

constexpr byte startPin {8};
constexpr byte relayA {9};
constexpr byte relayB {10};

// HIGH heißt, das Relay ist HIGH activ
constexpr byte relayOn {HIGH};     
constexpr byte relayOff {LOW};

// Variante wenn Relay LOW active sind:
//constexpr byte relayOn {LOW};     
//constexpr byte relayOff {HIGH};

//constexpr uint32_t factor {100UL}; // testweise von millisekunden auf Zehntel-Sekunden
constexpr uint32_t factor {1000UL}; // testweise von millisekunden auf Sekunden
//constexpr uint32_t factor {60*1000UL}; // am Schluss von millisekunden auf Minuten

uint16_t waittime {10};   // Startverzögerung
uint16_t runtimeA {60};   // Laufzeit Relay A
uint16_t runtimeB {90};   // Laufzeit Relay B

uint32_t previousMillis;

enum class Status {
  IDLE,            // warten auf Startbutton
  WAIT,            // Verzögerungszeit 
  ON_A_B,          // A und B sind ein
  ON_B,            // nur B ist ein
} status;


void setup() {
  Serial.begin(115200);
  digitalWrite(relayA, relayOff);
  digitalWrite(relayB, relayOff);
  pinMode(relayA, OUTPUT);
  pinMode(relayB, OUTPUT);
  pinMode(startPin, INPUT_PULLUP);

  // bestimmen der Startverzögerung
  // waittime = analogRead(A0);
  // bestimmen der Laufzeit Relay A
  // waittime = analogRead(A1);
  // bestimmen der Laufzeit Relay B
  // waittime = analogRead(A2); 
}

void loop() {
  switch (status)
  {
    case Status::IDLE :
      if (digitalRead(startPin) == LOW)
      {
        Serial.println(F("gestartet, Zeit merken und in den nächsten Status wechseln"));
        previousMillis = millis();
        status = Status::WAIT;
      }
      break;
    case Status::WAIT :
      if (millis() - previousMillis > waittime * factor)
      {
        Serial.println(F("die Wartezeit ist zu Ende, A und B einschalten, Zeit merken"));
        previousMillis = millis();
        digitalWrite(relayA, relayOn);
        digitalWrite(relayB, relayOn);
        status = Status::ON_A_B;
      }
      break;
    case Status::ON_A_B :
      if (millis() - previousMillis > runtimeA * factor)
      {
        Serial.println(F("Laufzeit A erreicht, A abschalten, B läuft weiter"));
        digitalWrite(relayA, relayOff);
        status = Status::ON_B;
      }
    case Status::ON_B :
      if (millis() - previousMillis > runtimeB * factor)
      {
        Serial.println(F("Laufzeit B erreicht, abschalten und zurück zu IDLE"));
        digitalWrite(relayB, relayOff);
        status = Status::IDLE;
      }
      break;
  }
}

sind halt aktuell 10, 60, 90 Sekunden.

edit:
oder mit schmutzigen delays, aber das gewöhnst dir aber am besten gleich gar nicht an:

// https://forum.arduino.cc/t/anfanger-werte-vor-programmstart-abfragen/1004723/
// dirty delay 

constexpr byte startPin {8};
constexpr byte relayA {9};
constexpr byte relayB {10};

// HIGH heißt, das Relay ist HIGH activ
constexpr byte relayOn {HIGH};     
constexpr byte relayOff {LOW};

// Variante wenn Relay LOW active sind:
//constexpr byte relayOn {LOW};     
//constexpr byte relayOff {HIGH};

//constexpr uint32_t factor {100UL}; // testweise von millisekunden auf Zehntel-Sekunden
constexpr uint32_t factor {1000UL}; // testweise von millisekunden auf Sekunden
//constexpr uint32_t factor {60*1000UL}; // am Schluss von millisekunden auf Minuten

uint16_t waittime {10};   // Startverzögerung
uint16_t runtimeA {60};   // Laufzeit Relay A
uint16_t runtimeB {90};   // Laufzeit Relay B

uint32_t previousMillis;

enum class Status {
  IDLE,            // warten auf Startbutton
  WAIT,            // Verzögerungszeit 
  ON_A_B,          // A und B sind ein
  ON_B,            // nur B ist ein
} status;

void setup() {
  Serial.begin(115200);
  digitalWrite(relayA, relayOff);
  digitalWrite(relayB, relayOff);
  pinMode(relayA, OUTPUT);
  pinMode(relayB, OUTPUT);
  pinMode(startPin, INPUT_PULLUP);

  // bestimmen der Startverzögerung
  // waittime = analogRead(A0);
  // bestimmen der Laufzeit Relay A
  // waittime = analogRead(A1);
  // bestimmen der Laufzeit Relay B
  // waittime = analogRead(A2); 
}

void loop() {
  if (digitalRead(startPin) == LOW)
  {
    Serial.println(F("gestartet, Zeit merken und in den nächsten Status wechseln"));
    delay(waittime * factor);
    //
    Serial.println(F("die Wartezeit ist zu Ende, A und B einschalten")); 
    digitalWrite(relayA, relayOn);
    digitalWrite(relayB, relayOn);
    delay(runtimeA * factor);
    // 
    Serial.println(F("Laufzeit A erreicht, A abschalten, B läuft weiter"));
    digitalWrite(relayA, relayOff);
    delay(runtimeA * factor);
    //
    Serial.println(F("Laufzeit B erreicht, abschalten und zurück zu IDLE"));
    digitalWrite(relayB, relayOff);
  }
}

Eben... Genau darauf wollte ich hinweisen :wink:

uhh das ging ja schnell, schon mal vielen Dank für die ganzen Antworten.

@DrDiettrich: ja, so habe ich es gedacht. Erstmal an pc mit Serial Monitor auslesen und wenn am Schluss alles funktioniert, noch ein Display dazu.

@HotSystems: Entschuldige bitte, war etwas schlecht ausgedrückt. Meinte damit, dass es danach warten soll bis wieder die Eingabewerte eingestellt und bestätigt sind.

@ec2021: es sollten je Poti 5 oder 6 Werte einstellbar sein, eventuell wäre ein kleiner Joystick die bessere wahl?

@noiasca: vielen dank, auf so ein Beispiel habe ich gehofft. Muss ich mir heute abend in aller ruhe mal genau ansehen um es zu verstehen.

Was ich noch vergesssen hatte, wärend der Laufzeit soll auch noch je ein Drucksensor/schalter abgefragt werden und bei zu viel Druck die jeweilige Pumpe so lange ausschalten bis der Druck wieder abgefallen ist.

Dann würde ich einen Drehschalter nehmen. Bekommst du typischerweise mit 12, 6, 3 Abstufungen. Mit jeder Stufe schaltest einen Widerstand dazu. Dann hast du haptisch 6 "eindeutige" Positionen und kannst auch mit einer Skala beschriften. Im Code machst du aus deinen gemessenen ADC Werten
10min, 30min, 60min, 90min, 120min, 180min, 300min oder was dir auch immer sinnvoll erscheint.

na dann die Version ohne delay ...

Solches Zubehör kostet doch nicht die Welt! Probiere einfach aus, was Dir am besten gefällt.

Da hast Du bereits eine ganze Reihe guter Vorschläge erhalten...

Wenn Du das Display gleich integrierst, wäre ein Drehencoder (Rotary Encoder) auch eine gute Alternative. Der ist einfach und flexibel einsetzbar.

Wer die Wahl hat, hat die Qual. :wink:

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