Pumpensteuerung mit "Finder OPTA"

Hallo erstmal, bin neu hier.

Es geht um eine Pumpensteuerung für eine Zentrifuge.
Es soll die Pumpe 1 & Ventil 1 für 30 min angesteuert werden.
Danach soll Pumpe 2 & Ventil 2 für 30 min angesteuert werden und dann wieder mit Pumpe 1 & Ventil 1 starten.

Ich bin Anfänger und es ist das erste Mal das ich mit Arduino programmiere. Ich habe folgenden Code schon mal geschrieben, aber ich schaffe es nicht, dass die Ausgänge für längere Zeit an sind.

Bitte um eure Hilfe.

int Auto = 0;

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);

pinMode(PI_4, OUTPUT); //Pumpe_2
pinMode(PI_5, OUTPUT); //Pumpe_1
pinMode(PI_3, OUTPUT); //Ventil_1
pinMode(PH_15, OUTPUT); //Ventil_2
pinMode(PF_6, INPUT); // Automatik_Switch
}

void loop() {

  Serial.println(Auto);
  

Auto = digitalRead(PF_6); //Switch ON
    if (Auto == 1) {digitalWrite(PI_5, HIGH);} // Pumpe_1 ON
    if (Auto == 1) {digitalWrite(PI_3, HIGH);} // Ventil_1 ON
  delay(1000);
    if (Auto == 1) {digitalWrite(PI_5, LOW);} // Pumpe_1 ON
    if (Auto == 1) {digitalWrite(PI_3, LOW);} // Ventil_1 ON
  delay(1000);
 
 
Auto = digitalRead(PF_6);

    if (Auto == 1) {digitalWrite(PI_4, HIGH);} // Pumpe_2 OFF
    if (Auto == 1) {digitalWrite(PH_15, HIGH);} // Ventil_2 OFF
  delay(1000);
    if (Auto == 1) {digitalWrite(PI_4, LOW);} // Pumpe_2 OFF
    if (Auto == 1) {digitalWrite(PH_15, LOW);} // Ventil_2 OFF
  delay(1000);

}


ungetestet, und nicht kompiliert weil ich Deine Pins nicht habe.
PI/PH gibts beim arduino so nicht.

Aber es sollte so ungefähr tun.

const bool automatik = false;
const bool manuell = !automatik;
bool pgmMode;
bool lastMode;
const uint32_t laufzeit = 1000UL; // *60*30 für 30 Minuten
void setup()
{
  Serial.begin(9600);
  pinMode(PI_4, OUTPUT); //Pumpe_2
  pinMode(PI_5, OUTPUT); //Pumpe_1
  pinMode(PI_3, OUTPUT); //Ventil_1
  pinMode(PH_15, OUTPUT); //Ventil_2
  pinMode(PF_6, INPUT); // Automatik_Switch
  lastMode = !digitalRead(PF_6);
}

void loop()
{
  pgmMode = digitalRead(PF_6); //Switch ON
  if (pgmMode != lastMode)
  {
    lastMode = pgmMode;
    Serial.print(F("Neuer Mode: "));
    if (pgmMode == automatik)
    {
      Serial.println(F("automatik"));
      automatikStart = millis();
    }
    else
    {
      Serial.println(F("manuell"));
    }
  }
  if (pgmMode == automatik)
  {
    if (millis() - automatikStart < laufzeit)
    {
      digitalWrite(PI_5, HIGH); // Pumpe_1 ON
      digitalWrite(PI_3, HIGH); // Ventil_1 ON
      digitalWrite(PI_4, LOW); // Pumpe_2 OFF
      digitalWrite(PH_15, LOW); // Ventil_2 OFF
    }
    else if (millis - automatikstart < laufzeit * 2)
    {
      digitalWrite(PI_5, LOW); // Pumpe_1 ON
      digitalWrite(PI_3, LOW); // Ventil_1 ON
      digitalWrite(PI_4, HIGH); // Pumpe_2 OFF
      digitalWrite(PH_15, HIGH); // Ventil_2 OFF
    }
    else
    {
      automatikstart = millis();
    }
  }
}

Guten Morgen,
Vielen Dank für deine schnelle Hilfe.
Hab den Code mal kompiliert, es wird mir die Fehlermeldung

 error: 'automatikStart' was not declared in this scope
       automatikStart = millis();
       ^~~~~~~~~~~~~: suggested alternative: 'automatik'
       automatikStart = millis();
       ^~~~~~~~~~~~~~
       automatik
error: 'automatikStart' was not declared in this scope
     if (millis() - automatikStart < laufzeit)
                    ^~~~~~~~~~~~~~
: note: suggested alternative: 'automatik'
     if (millis() - automatikStart < laufzeit)
                    ^~~~~~~~~~~~~~
                    automatik

: error: 'automatikstart' was not declared in this scope
     else if (millis - automatikstart < laufzeit * 2)
                       ^~~~~~~~~~~~~~

note: suggested alternative: 'automatik'
     else if (millis - automatikstart < laufzeit * 2)
                       ^~~~~~~~~~~~~~
                       automatik

exit status 1

Compilation error: 'automatikStart' was not declared in this scope

Hab die Fehler mal behoben es klappt soweit. Vielen Dank :+1:
Nur das Auschalten klappt nicht ganz. Wenn der Schalter LOW ist Startet ja der Automatik-Mode und wenn er HIGH ist der Manuell-Mode. Das ist soweit schon mal OK für mich. Aber im
Manuell-Mode sollten ja die Ausgänge auf LOW geschaltet sein damit man die Pumpen auschalten kann. Aber je nachdem welcher Eingang HIGH war bleibt auf HIGH geschalten.

Hallo kev_1992

Probier mal diesen Sketch für das Pumpen und Ventil - System aus.

Die Ein/Ausgabe-Pins und die Schaltzeiten müssen angepasst werden.

#define ProjectName "Pumpensteuerung mit Finder OPTA"
//names
enum Groups {One, Two};
enum OnOff {Off, On};
//variables
constexpr uint8_t PumpPins[] {9, 11};
constexpr uint8_t ValvePins[] {10, 12};
constexpr uint8_t ButtonPin {A0};
constexpr uint32_t RunTimes[] {1000, 1000};
//structures
struct TIMER
{
  uint32_t  intervalMillis;
  uint32_t  previousMillis;
  uint8_t   control;
};
struct BUTTON
{
  uint8_t   pin;
  uint8_t   stateOld;
  uint8_t   toggle;
  TIMER     debounce;
} knop
{
  ButtonPin, LOW, LOW, 20, 0, LOW,
};
struct PUMPCONTROLS
{
  String groupName;
  uint8_t pump;
  uint8_t valve;
  TIMER  runTime;
} pumpControls[]
{
  {
    "PumpValve_1", PumpPins[One], ValvePins[One], RunTimes[One] , 0, LOW
  },
  {
    "PumpValve_2", PumpPins[Two], ValvePins[Two], RunTimes[Two] , 0, LOW
  },
};

//support
void heartBeat(int LedPin, uint32_t currentMillis)
{
  static bool setUp = false;
  if (!setUp) pinMode (LedPin, OUTPUT), setUp = !setUp;
  digitalWrite(LedPin, (currentMillis / 500) % 2);
}
void setup()
{
  Serial.begin(115200);
  Serial.println(ProjectName);
  for (auto &pumpControl : pumpControls)
  {
    pinMode(pumpControl.pump, OUTPUT);
    pinMode(pumpControl.valve, OUTPUT);
  }
  pinMode (knop.pin, INPUT_PULLUP);
}

void loop()
{
  uint32_t currentMillis = millis();
  heartBeat(LED_BUILTIN, currentMillis);

  if (currentMillis - knop.debounce.previousMillis >= knop.debounce.intervalMillis)
  {
    knop.debounce.previousMillis = currentMillis;
    uint8_t stateNew = digitalRead(knop.pin) ? LOW : HIGH;
    if (knop.stateOld != stateNew)
    {
      knop.stateOld = stateNew;
      switch (stateNew)
      {
        case Off:
          Serial.println(F("switched to MANUAL"));
          for (auto &pumpControl : pumpControls)
          {
            pumpControl.runTime.control = LOW;
            digitalWrite(pumpControl.pump, LOW);
            digitalWrite(pumpControl.valve, LOW);
          }
          break;
        case On:
          Serial.println(F("switched to AUTO"));
          Serial.println(pumpControls[One].groupName);
          pumpControls[One].runTime.control = HIGH;
          pumpControls[One].runTime.previousMillis = currentMillis;
          digitalWrite(pumpControls[One].pump, HIGH);
          digitalWrite(pumpControls[One].valve, HIGH);
          break;
      }

    }
  }
  for (auto &pumpControl : pumpControls)
  {
    if (currentMillis - pumpControl.runTime.previousMillis >= pumpControl.runTime.intervalMillis and pumpControl.runTime.control)
    {
      pumpControl.runTime.control = LOW;
      digitalWrite(pumpControl.pump, LOW);
      digitalWrite(pumpControl.valve, LOW);
      static uint8_t group = One;
      group = (group + 1) % (sizeof(pumpControls) / sizeof(pumpControls[0]));
      Serial.println(pumpControls[group].groupName);
      pumpControls[group].runTime.previousMillis = currentMillis;
      pumpControls[group].runTime.control = HIGH;
      digitalWrite(pumpControls[group].pump, HIGH);
      digitalWrite(pumpControls[group].valve, HIGH);
    }
  }
}

Hallo @paulpaulson,
Danke werd ich mal Testen.

@my_xy_projekt
Hab mal versucht das Problem selbst zu lösen jetzt funktioniert es wie es soll.

Wünsche euch einen schönen Tag.

Naja, war ja nicht so schlimm... Ich ätt es noch ausgebaut, aber wenns geht, dann ist ja gut.
Sagst Du mal bitte, was für eine Boarddefinition Du benutzt?

Board Definition? Meinst du möglicherweise Arduino Uno?
Das Programm wird ja noch mehr ausgebaut.
Aber so wie es ist jetzt ist, wird es mal als Testprogramm verwendet, um die Anlage zu testen.
Es werden ja noch 2 Ultraschallsensoren verbaut, um die Wasserstände zu messen und die Pumpen und Ventile zu schalten.

Damit geht hochladen auf die Finder?
Das glaub ich nicht den die Finder kann auch OTA, also ist was Anderes eingebaut als ATmega 328
Ok Programmieren kann man damit, aber ob das funktioniert auf der Finder ist andere Sache

Ich meine, was Du eingestellt hast, damit so Sachen wie

  pinMode(PI_4, OUTPUT); //Pumpe_2

funktionieren.
Dazu muss es ja irgendwo eine (Board)Definition geben.

Aber möglicherweise hab ich die Erklärung selbst gefunden

Offensichtlich gibt es da auch noch Unterschiede, sodas nicht jeder dafür vorgesehen ist.
Allen gemein ist ein STM32H747XI

OK so weit habe nicht gesucht.

Au, da wird uns noch einiges ereilen.
Die versuchen dem Controllino Konkurenz zu machen und haben den Portenta auf Hutschine gebaut :slight_smile:
Gibt sogar eine eigene IDE für die PLC-Programmierung. (@Rentner vielleicht auch was für Dich? Du kommst doch da aus der Ecke, wenn mich nicht alles täuscht )

Wenn jetzt noch der neue UNO kommt, dann werden sich auch hier einige Fragenzeichen auftun...

Muss ich sagen kluger Schachzug :wink: Wahrscheinlich zusammen mit Finder entwickelt, Lizenz nur 16€ und Gerät fast umsonst :wink:
Also schätze mall da bekommt Siemens, Schneider (Telemecanique) und Andere leichte Probleme.
@my_xy_projekt kannst langsam PLC lernen :joy:

Da der auch ordinär programmiert werden kann: NEIN!
Ich hab ja schon beim Portenta meine Schwierigkeiten.... :crazy_face:

1 Like

Bei C und C++ geht das auch, also :wink:
Deshalb zeige meine Ergusse nicht, Hauptsache es funktioniert, einziges bei Displayansteuerung kann ich mir das nicht erlaben, ist sofort sichtbar :wink:

1 Like

Hallo,
das stimmt schon. PLC ist halt schon eine andere Welt .
Ich hab mal einen Blick auch die Doko aus dem Link #13 geworfen. Sieht ziemlich nach IEC aus, inklusive Symbolischer Namen für E/A. Deshalb sicher auch die eigene IDE zur grafischen Darstellung der Logik und Funktionsblöcke Wenn man jetzt was mit viel logischen Veknüpfungen machen will könnte es Sinn machen sowas zu nutzen. Allerdings wird man sich da komplett reinarbeiten müssen. Ich hab da erst mal keinen Bedarf. :face_with_raised_eyebrow:

Wenn ich was logisch zu verknüpfen habe geht das auch mit einem Sack bool Variable und den bekannten logischen Verknüpfungen. So tief kann die Verknüpfungstiefe gar nicht sein denke ich.

Heinz

1 Like

Hast du bestimmt selbst schon rausbekommen. Bin nach der Beschreibung vorgegangen.
https://docs.arduino.cc/tutorials/opta/getting-started.

Warum hälts du dich nicht nach den Beispielen?
Dort gibt es keine PI_4, wen du schon ein eignen Namen vergibts muss der auch deklariert werden.
Die Relais hängen doch auf DO bis D3.

/**
  Getting Started with Opta™
  Name: Output_Relay_Opta
  Purpose: Test output relays of the Opta™.

  @author Arduino
*/

void setup() {
  // Initialize Relays outputs
  pinMode(D0, OUTPUT);
  pinMode(D1, OUTPUT);
  pinMode(D2, OUTPUT);
  pinMode(D3, OUTPUT);

  // Initialize Opta LEDs
  pinMode(LED_D0, OUTPUT);
  pinMode(LED_D1, OUTPUT);
  pinMode(LED_D2, OUTPUT);
  pinMode(LED_D3, OUTPUT);
}

void loop() {
  // Closes and opens the contact of relay 1 and turns on/off led 1
  digitalWrite(D0, HIGH); // Sets the relay 1 on
  digitalWrite(LED_D0, HIGH);
  delay(1000);
  digitalWrite(D0, LOW); // Sets the relay 1 off
  digitalWrite(LED_D0, LOW);
  delay(1000);

  // Closes and opens the contact of relay 2 and turns on/off led 2
  digitalWrite(D1, HIGH); // Sets the relay 2 on
  digitalWrite(LED_D1, HIGH);
  delay(1000); 
  digitalWrite(D1, LOW); // Sets the relay 2 off
  digitalWrite(LED_D1, LOW);
  delay(1000);

  // Closes and opens the contact of relay 3 and turns on/off led 3
  digitalWrite(D2, HIGH); // Sets the relay 3 on
  digitalWrite(LED_D2, HIGH);
  delay(1000);
  digitalWrite(D2, LOW); // Sets the relay 3 off
  digitalWrite(LED_D2, LOW);
  delay(1000);  
  //  Closes and opens the contact of relay 4 and turns on/off led 4
  digitalWrite(D3, HIGH); // Sets the relay 4 on
  digitalWrite(LED_D3, HIGH);
  delay(1000);
  digitalWrite(D3, LOW); // Sets the relay 4 off
  digitalWrite(LED_D3, LOW);
  delay(1000);
}

Bin gerade an der OPTA Installation.
Na ja Kompilieren tut es trotz mM. falscher Deklaration

Für Interessierte OPTA Pinout. @kev_1992 Wen man schon Programm für definierte Hardware schreibt (OPTA) sollte man die Pin Bezeichnung benutzen, nicht Procesor Pin Namen