Zwei Programme kombinieren

Hallo,

ich habe zwei getrennt funktionierende Programme, möchte aber eins daraus machen. Wie funktioniert das?

#define eingang  A1 //Das Wort „eingang" steht jetzt für den Wert „A0" (Bezeichnung vom Analogport 0)
#define obenEnde 7 //Pins am besten immer mit define definieren da mit int zuviel Speicher unnötigt verbraucht wird.
#define untenEnde 8
#define Runter 10
#define Hoch 11
int sensorWert = 0; //Variable für den Sensorwert mit 0 als Startwert

void setup()//Hier beginnt das Setup.
{
  Serial.begin(9600); //Die Kommunikation mit dem seriellen Port wird gestartet. Das benötigt man, um sich den tatsächlich ausgelesenen Wert später im serial monitor anzeigen zu lassen.
  pinMode (Hoch, OUTPUT); //Der Pin mit der Relais für die Motorrichtung Oben
  pinMode (Runter, OUTPUT); //Der Pin mit der Relais für die Motorrichtung Unten
  pinMode(obenEnde, INPUT); //Der Pin mit dem Endschalter oben
  pinMode(untenEnde, INPUT);  //Der Pin mit dem Endschalter unten
  //Der analoge Pin muss nicht definiert werden.
}

void loop()
{ //Mit dieser Klammer wird der Loop-Teil geöffnet.
  sensorWert = analogRead(eingang); //Die Spannung an dem Fotowiderstand auslesen und unter der Variable „sensorWert" abspeichern.
  Serial.print("Sensorwert = " ); //Ausgabe am Serial-Monitor: Das Wort „Sensorwert: „
  Serial.println(sensorWert); //Ausgabe am Serial-Monitor. Mit dem Befehl Serial.print wird der Sensorwert des Fotowiderstandes in Form einer Zahl zwischen 0 und 1023 an den serial monitor gesendet.

  if (sensorWert > 512 ) //Wenn der Sensorwert über 512 beträgt….
  {
    while (digitalRead(untenEnde) == LOW) //Solange der Endschalter unten nicht gedrückt wurde
    {
      digitalWrite(Runter, LOW);   //fährt der Rolladen runter
    }
    digitalWrite(Runter, HIGH);  //Danach schält das Relais aus
    digitalWrite(Hoch, HIGH);    //Danach schält das Relais aus
  }
  else //andernfalls…
  {
    while (digitalRead(obenEnde) == LOW)  //Solange der Endschalter oben nicht gedrückt wurde
    {
      digitalWrite(Hoch, LOW);   //fährt der Rollladen hoch
    }
    digitalWrite(Runter, HIGH);  //Danach schält das Relais aus
    digitalWrite(Hoch, HIGH);    //Danach schält das Relais aus
  }
delay (50);
}
void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  Serial.begin(9600);
}

void loop() {
  int sensorValue = analogRead(A0);
  float voltage = sensorValue * (4.68 / 1023.00);
  Serial.println(voltage);
  if (voltage < 2.15)
  {
    digitalWrite(13, LOW);
  }
  else
  {
    digitalWrite(13, HIGH);
  }
  delay(1000);

}

Ich habe versucht einfach beide hintereinander zu schreiben aber das funktioniert nicht.

#define eingang  A1 //Das Wort „eingang" steht jetzt für den Wert „A0" (Bezeichnung vom Analogport 0)
#define obenEnde 7 //Pins am besten immer mit define definieren da mit int zuviel Speicher unnötigt verbraucht wird.
#define untenEnde 8
#define Runter 10
#define Hoch 11
int sensorWert = 0; //Variable für den Sensorwert mit 0 als Startwert



void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  Serial.begin(9600); //Die Kommunikation mit dem seriellen Port wird gestartet. Das benötigt man, um sich den tatsächlich ausgelesenen Wert später im serial monitor anzeigen zu lassen.
  pinMode (Hoch, OUTPUT); //Der Pin mit der Relais für die Motorrichtung Oben
  pinMode (Runter, OUTPUT); //Der Pin mit der Relais für die Motorrichtung Unten
  pinMode(obenEnde, INPUT); //Der Pin mit dem Endschalter oben
  pinMode(untenEnde, INPUT);  //Der Pin mit dem Endschalter unten
}

void loop() {
  int sensorValue = analogRead(A0);
  float voltage = sensorValue * (4.68 / 1023.00);
  Serial.println(voltage);
  if (voltage < 2.15)
  {
    digitalWrite(13, LOW);
  }
  else
  {
    digitalWrite(13, HIGH);
  }
  delay(1000);

  sensorWert = analogRead(eingang); //Die Spannung an dem Fotowiderstand auslesen und unter der Variable „sensorWert" abspeichern.
  Serial.print("Sensorwert = " ); //Ausgabe am Serial-Monitor: Das Wort „Sensorwert: „
  Serial.println(sensorWert); //Ausgabe am Serial-Monitor. Mit dem Befehl Serial.print wird der Sensorwert des Fotowiderstandes in Form einer Zahl zwischen 0 und 1023 an den serial monitor gesendet.

  if (sensorWert > 512 ) //Wenn der Sensorwert über 512 beträgt….
  {
    while (digitalRead(untenEnde) == LOW) //Solange der Endschalter unten nicht gedrückt wurde
    {
      digitalWrite(Runter, LOW);   //fährt der Rolladen runter
    }
    digitalWrite(Runter, HIGH);  //Danach schält das Relais aus
    digitalWrite(Hoch, HIGH);    //Danach schält das Relais aus
  }
  else //andernfalls…
  {
    while (digitalRead(obenEnde) == LOW)  //Solange der Endschalter oben nicht gedrückt wurde
    {
      digitalWrite(Hoch, LOW);   //fährt der Rollladen hoch
    }
    digitalWrite(Runter, HIGH);  //Danach schält das Relais aus
    digitalWrite(Hoch, HIGH);    //Danach schält das Relais aus
  }
  delay (50);

}

Grüße Kai

Zuerst schauen, ob es doppelte Bezeichner gibt. Wenn ja, umbenennen.

Dann den Inhalt von setup 2 in setup 1 einfügen, und den Inhalt von loop2 in loop 1.

Eine andere Möglichkeit wäre, Funktionen zu benutzen.

Gruß Tommy

Schau doch in meinen letzten Code, da hab ich das so gemacht. Funktioniert aber nicht, so wie ich jetzt gelesen hab, hat das was mit dem delay zu tun.

kai2310:
Funktioniert aber nicht, so wie ich jetzt gelesen hab, hat das was mit dem delay zu tun.

Sehr richtig erkannt!
Das ist sicherlich ein Problem.

Du möchtest 2 Programme verschmelzen.
Diese beiden Hälften, des neuen Ganzen, sollen weiterhin die alten 2 Aufgaben erledigen.
Unabhängig voneinander.
Quasi parallel.
Das nennt sich Multitasking.

Dein Delay in der einen Hälfte blockiert die andere Hälfte gleich mit.

Hier im Forum findest du einige Threads zu kooperativem Multitasking, delay() Vermeidung und endlichen Automaten.
Ich schätze mal, das werden einige Lesestunden für dich!

Klar, könnte sein, dass dir einer dein Programm repariert.
Aber das hilft dir nicht beim lernen, und sehr Wahrscheinlich ist das auch nicht unbedingt.

Vielleicht kannst du ja mal beschreiben, was das fertige Programm machen soll.
Es sieht ja irgendwie aus, als sollte eine Rollladen gesteuert werden und da gibt es einen oder mehrere Sensoren...

Also die Rollladensteuerung funktioniert mit einem Fotowiderstand und einem Taster für oben und einem für unten. Das zweite ist eine automatische Bewässerung die durch eine Spannungsmessung geregelt wird.

Ich bin sowieso grade dabei mich in die Materie einzulesen, aber ich brauch das Programm demnächst für die Schule und wäre sehr dankbar wenn mir jemand das Programm verbessern könnte.

Gruß,
Kai

kai2310:
Ich bin sowieso grade dabei mich in die Materie einzulesen, aber ich brauch das Programm demnächst für die Schule und wäre sehr dankbar wenn mir jemand das Programm verbessern könnte.

Ach, du möchtest, dass wir deine Hausaufgaben machen ?

Das ist keine Hausaufgabe sondern freiwillige Arbeit.

Hab es jetzt damit mal versucht: GitHub - DrDiettrich/ALib0: Arduino library for button handling and parallel execution.

Funktioniert aber immer noch nicht.

Funktioniert aber immer noch nicht.

Du hast mein volles Mitgefühl!

Aber leider sehe ich nicht, was du getan hast.
Also kann ich dir auch nicht sagen, was du evtl. falsch gemacht haben könntest.

#include <ALib0.h>

#define eingang  A1 //Das Wort „eingang" steht jetzt für den Wert „A0" (Bezeichnung vom Analogport 0)
#define obenEnde 7 //Pins am besten immer mit define definieren da mit int zuviel Speicher unnötigt verbraucht wird.
#define untenEnde 8
#define Runter 10
#define Hoch 11
int sensorWert = 0; //Variable für den Sensorwert mit 0 als Startwert

void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  Serial.begin(9600); //Die Kommunikation mit dem seriellen Port wird gestartet. Das benötigt man, um sich den tatsächlich ausgelesenen Wert später im serial monitor anzeigen zu lassen.
  pinMode (Hoch, OUTPUT); //Der Pin mit der Relais für die Motorrichtung Oben
  pinMode (Runter, OUTPUT); //Der Pin mit der Relais für die Motorrichtung Unten
  pinMode(obenEnde, INPUT); //Der Pin mit dem Endschalter oben
  pinMode(untenEnde, INPUT);  //Der Pin mit dem Endschalter unten
}

void bewaesserung() {
  taskBegin();
  int sensorValue = analogRead(A0);
  float voltage = sensorValue * (4.68 / 1023.00);
  Serial.println(voltage);
  if (voltage < 2.15)
  {
    digitalWrite(13, LOW);
  }
  else
  {
    digitalWrite(13, HIGH);
  }
  delay (1000);
  taskEnd();
  }

void rollladen() {
  //Variables must be static, to preserve their values across invocations.
  static unsigned long wait;

  taskBegin();
  sensorWert = analogRead(eingang); //Die Spannung an dem Fotowiderstand auslesen und unter der Variable „sensorWert" abspeichern.
  Serial.print("Sensorwert = " ); //Ausgabe am Serial-Monitor: Das Wort „Sensorwert: „
  Serial.println(sensorWert); //Ausgabe am Serial-Monitor. Mit dem Befehl Serial.print wird der Sensorwert des Fotowiderstandes in Form einer Zahl zwischen 0 und 1023 an den serial monitor gesendet.

  if (sensorWert > 512 ) //Wenn der Sensorwert über 512 beträgt….
  {
    while (digitalRead(untenEnde) == LOW) //Solange der Endschalter unten nicht gedrückt wurde
    {
      digitalWrite(Runter, LOW);   //fährt der Rolladen runter
    }
    digitalWrite(Runter, HIGH);  //Danach schält das Relais aus
    digitalWrite(Hoch, HIGH);    //Danach schält das Relais aus
  }
  else //andernfalls…
  {
    while (digitalRead(obenEnde) == LOW)  //Solange der Endschalter oben nicht gedrückt wurde
    {
      digitalWrite(Hoch, LOW);   //fährt der Rollladen hoch
    }
    digitalWrite(Runter, HIGH);  //Danach schält das Relais aus
    digitalWrite(Hoch, HIGH);    //Danach schält das Relais aus
  }
  taskDelay (50);
  taskEnd();
}


void loop() {
  bewaesserung();
  rollladen();
}

Hier ist der Code

#define obenEnde 7 //Pins am besten immer mit define definieren da mit int zuviel Speicher unnötigt verbraucht wird.

Hier ist zumindest der Kommentar falsch!
Besser:

const byte obenEnde = 7;

#define eingang A1 //Das Wort „eingang" steht jetzt für den Wert „A0" (Bezeichnung vom Analogport 0)

Hier gibt es eine Diskrepanz zwischen Code und Kommentar.
Das ist übrigens der Punkt, wo ich normaler weise aufhöre den Code zu lesen.


delay (1000);

Es ist eine Ehre für mich, dass du die TaskMakros gefunden hast!
Aber dass da noch ein delay() auftaucht, ist ein Schock für mich.
Mein Tipp: Das muss weg!

while (digitalRead(obenEnde) == LOW)

Das ist blockierend.
Also genau so schlimm wie ein delay().
Vielleicht sogar noch schlimmer, denn bei einem delay() weiß man, dass es irgend wann endet.

Jetzt weiß ich woran es liegt. Aber ich bekomm es trotzdem nicht zum laufen. Gibt es keine einfachere Möglichkeit für Multitasking mit dem Arduino?

kai2310:
Jetzt weiß ich woran es liegt. Aber ich bekomm es trotzdem nicht zum laufen. Gibt es keine einfachere Möglichkeit für Multitasking mit dem Arduino?

Wo dran liegt es denn ?
Informiere uns doch mal, damit wir auch helfen können.

Und nein, der Arduino ist nicht "multitaskingfähig".

Gibt es keine einfachere Möglichkeit für Multitasking mit dem Arduino?

Dummer Weise, wird es erst einfacher, wenn man es verstanden hat.
Und das auch erst nach einer Übungsphase.

Ist ein bisschen, wie beim Fahrrad fahren lernen.
Hat man es einmal verinnerlicht, kann man es kaum noch jemandem erklären, der es noch nicht kennt.
Beispiel: Du musst nach rechts lenken, wenn du nach links abbiegen willst.

Soweit ich das erkennen kann brauchst du:

  1. Zeitsteuerung (ähnlich BlinkWithoutDelay)
  2. Ablaufsteuerung (endlicher Automat)
  3. Multitasking (kooperatives Multitasking!?!?)

Und diese 3 Punkte(Design Pattern) schön verwoben, so dass das Programm deinen Anforderungen gerecht wird.

HotSystems:
Und nein, der Arduino ist nicht "multitaskingfähig".

Man freeRTOS.
https://create.arduino.cc/projecthub/feilipu/using-freertos-multi-tasking-in-arduino-ebc3cc

Hallo,

hab mal den Code geändert.
Die Rolladenfunktion gefällt mir aber noch nicht.
Es fehlt noch eine Hysterese für die Umschalten hoch/runter. Sonst kann es dir passieren der Rolladen macht den ganzen Tag nichts anderes als lustig hoch und runter zu fahren. Übertrieben gesagt.
Das ganze if while Kontrukt würde ich nochmal umbauen.
Möglicherweise in ein switch case Konstrukt verwandeln. Zustände mit Klarnamen benennen. Stichwort enum.
Oder du lebst damit das der Sketch während der Rolladen fährt und auf seinen Endschalter wartet nichts anderes macht.
Die Hysterese benötigst du dennoch.

ungetestet:

//  https://forum.arduino.cc/index.php?topic=534678.0

const byte eingang = A1;   //Das Wort „eingang" steht jetzt für den Wert „A0" (Bezeichnung vom Analogport 0)
const byte obenEnde = 7;    
const byte untenEnde = 8;
const byte Runter = 10;
const byte Hoch = 11;
int sensorWert = 0;   //Variable für den Sensorwert mit 0 als Startwert

void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  Serial.begin(9600); 
  pinMode (Hoch, OUTPUT);     //Der Pin mit der Relais für die Motorrichtung Oben
  pinMode (Runter, OUTPUT);   //Der Pin mit der Relais für die Motorrichtung Unten
  pinMode(obenEnde, INPUT);   //Der Pin mit dem Endschalter oben
  pinMode(untenEnde, INPUT);  //Der Pin mit dem Endschalter unten
}


void loop() {
  bewaesserung();
  rollladen();
}


void bewaesserung() {
  
  static unsigned long last_millis = 0;

  if (millis() - last_millis < 1000) return;  // Zeit noch nicht erreicht >> abbrechen
  last_millis = millis();
  
  
  int sensorValue = analogRead(A0);
  float voltage = sensorValue * (4.68 / 1023.00);
  Serial.println(voltage);
  if (voltage < 2.15) {
    digitalWrite(13, LOW);
  }
  else {
    digitalWrite(13, HIGH);
  }
  
}

void rollladen() {
  static unsigned long last_millis = 0;

  if (millis() - last_millis < 50) return;  // Zeit noch nicht erreicht >> abbrechen
  last_millis = millis();

  sensorWert = analogRead(eingang); //Die Spannung an dem Fotowiderstand auslesen und unter der Variable „sensorWert" abspeichern.
  Serial.print("Sensorwert = " ); //Ausgabe am Serial-Monitor: Das Wort „Sensorwert: „
  Serial.println(sensorWert); //Ausgabe am Serial-Monitor. Mit dem Befehl Serial.print wird der Sensorwert des Fotowiderstandes in Form einer Zahl zwischen 0 und 1023 an den serial monitor gesendet.

  if (sensorWert > 512 ) { //Wenn der Sensorwert über 512 beträgt….
    
    while (digitalRead(untenEnde) == LOW) //Solange der Endschalter unten nicht gedrückt wurde
    {
      digitalWrite(Runter, LOW);   //fährt der Rolladen runter
    }
    digitalWrite(Runter, HIGH);  //Danach schält das Relais aus
    digitalWrite(Hoch, HIGH);    //Danach schält das Relais aus
  }
  else { //andernfalls…
    while (digitalRead(obenEnde) == LOW) {  //Solange der Endschalter oben nicht gedrückt wurde
      digitalWrite(Hoch, LOW);   //fährt der Rollladen hoch
    }
    digitalWrite(Runter, HIGH);  //Danach schält das Relais aus
    digitalWrite(Hoch, HIGH);    //Danach schält das Relais aus
  }
  
}
void loop() {

bewaesserung();
  rollladen();
}

Rolladen und Bewässerung wird gleichzeitig gesteuert.
Es kann passieren, dass in der gleichen Millisekunde sowohl die Bewässerung wie die Rolladensteuerung etwas neues unternimmt.

Mehrmultitaskingbraucht man auf einem Arduino nicht, finde ich.
Beide Funktionen im obigen Beispiel müssen sich natürlich ordentlich benehmen, also hauptsächlich keine Zeit brauchen. Aber das sollte eigentlich kein Problem sein.

Da es überhaupt keine Tasks gibt, gibt es auch kein Multitasking, da hat HotSystems natürlich recht.

Danke für eure Hilfe. Hab es jetzt so hinbekommen, dass es so läuft wie ich mir das vorstelle.

Fein!