Pages: [1] 2   Go Down
Author Topic: Mehrere Funktionen gleichzeitig ansteuern (Threads)?  (Read 2780 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

kann man auch 3 oder 4 Aktionen (Pins) gleichzeitig und unabhängig von einander ansteuern?

Ein Bekannter meinte was von "Threads", aber da diese Frage mit den darauffolgenden Antworten ebenfalls so bezeichnet wird, komme ich mit der Suche nciht weiter... smiley-sad
Logged

Germany, Osnabrück
Offline Offline
God Member
*****
Karma: 30
Posts: 658
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mikrocontroller (außer sie haben zwei Kerne) arbeiten ihr Programm von oben nach unten ab. Echt paralleles arbeiten ist nur mit FPGAs /CPLDs (werden in VHDL Programmiert / synthetisiert) oder Mehrkernprozessoren möglich.
Das Threading beschreibt ein Verfahren bei dem auch nicht "echt" parallel gearbeitet wird, sondern sehr schnell hintereinander. Wobei die einzelnen Threads über ein Scheduler gesteuert werden.
Im Prinzip wird jeder Funktion / jedem Programm ein Intervall zugewiesen. Vom Scheduler wird dann die Funktion in diesem Intervall aufgerufen, wobei auch überprüft wird ob eine andere Funktion eine wichtigere Priorität hat. Es kommt auch vor, dass die Ausgeführte Funktion unterbrochen wird um eine Wichtigere Funktion auszuführen.

http://de.wikipedia.org/wiki/Prozess-Scheduler

Auf dem Arduino ist dies diese Struktur nur ansatzweise umsetzbar.

Es gibt mittlerweile ein Lib die eine ähnliche Funktionalität umsetzt:

simpleThreads for arduino
« Last Edit: September 14, 2013, 12:58:08 pm by Jomelo » Logged

Munich/Germany
Offline Offline
God Member
*****
Karma: 11
Posts: 643
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Beschreib doch mal, was Du vorhast. Dann kann man ev. Lösungswege vorschlagen.
Logged

_______
Manfred

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 269
Posts: 21839
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mehrere Pins können gleichzeitig angesteuert werden, wenn sie auf dem gleichen PORT liegen und Du den Port direkt ansteuerst (siehe http://playground.arduino.cc/Learning/PortManipulation ) Damit ändern sie gleichzeitig den Zustand und nicht hintereinander wie wenn Du sie mit zB mit 2 igitalWrite() änderst.Du kannst aber immer nur einen Sketch abarbeiten.
Grüße Uwe
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 160
Posts: 3161
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

kann man auch 3 oder 4 Aktionen (Pins) gleichzeitig und unabhängig von einander ansteuern?

Völlig "gleichzeitig" geht nicht, also ein paar millionstel oder tausendstel Sekunden werden zwischen den Aktionen immer liegen. Bei grottenschlechter Programmierung auch Sekunden. Unabhängig voneinander ist allerdings kein Problem.

Das Prinzip ist, für jede der Aktionen in der Loop eine Funktion zu haben:

void loop()
{
  unter_loop1();
  unter_loop2();
  unter_loop3();
  unter_loop4();
}

Und jede der unter_loop Funktionen arbeitet für sich selbst hin, und zwar OHNE die Verwendung irgendwelcher delay Funktionen. Stattdessen müssen delays über die Auswertung von Timern oder millis oder Timer-Interrupts realisiert werden.

Bei längerdauernden Aktionen mußt Du mit Statusvariablen arbeiten. Beispiel Blinken: Du schaltest den Blinker an und ermittelst den Zeitpunkt, wann er wieder ausgehen soll. Dann wird die Loopfunktion zum Blinken zwischendurch hunderte, tausende oder millionen mal aufgerufen und nichts passiert, bis die Zeit zum Ausschalten da ist. Dann schaltet die Blinkfunktion aus und setzt wieder die neue Aktionszeit für den Start des nächsten Blinkvorgangs.

Bei anderen "länger dauernden" Aktionen entsprechend.

Funktionen, die "länger dauern" als Du es unter "gleichzeitig" verstehst, sind in dem Programm dann komplett verboten und dürfen nicht verwendet werden.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Beschreib doch mal, was Du vorhast. Dann kann man ev. Lösungswege vorschlagen.

Hi zusammen,

also ich möchte im ersten Schritt ein Aquarium ansteuern, und irgendwann ggf. sogar regeln....

Im ersten Schritt habe ich 2 Leuchtquellen und 4 Pumpen, die ich wie folgt starten will:

von 6.00 Uhr bis 6.30 Uhr läuft Leuchte 1
von 6.30 Uhr bis 18.00 Uhr läuft Leuchte 2
von 7.oo Uhr bis 17.00 Uhr läuft Leuchte 1 (zusätzlich)
von 18.00 Uhr bis 19.00 Uhr läuft Leuchte 1 (nochmal)

Zusätzlich soll im Rhythmus von 5 Stunden eine der 4 Pumpen über einen Zufallsgenerator starten.



Ich glaube, ich könnte auch die Millisekunden "counten" und dann mit "if-else" arbeiten und das permanent durchlaufen lassen...
Logged

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 269
Posts: 21839
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Muß da wirklich was GLEICHZEITIG gesteuert werden? Genügt da nicht eine Genauigkeit von einigen Sekunden / Minuten?

Zur Steuerung der Lampen/Pumpen:

Nimm eine RTC, wandle die Zeit (stunden, minuten sekunden) in Sekunden und steuere damit das einschalten bzw asschalten der einzenlen Leuchten / Pumpen.

Grüße Uwe
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ach, auf eine Sekunde, oder 2 kommt es nciht an.

Ich dachte, dass ich, wenn ich den ersten Befehl einschalte, warten muss, bis ich wieder ausschalte...


Was ist RTC ?
Logged

Austria
Offline Offline
Full Member
***
Karma: 2
Posts: 107
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

RTC steht für Real Time Clock.

siehe hier:
http://playground.arduino.cc/Main/DS1302

Grüße,
J3RE
Logged

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 269
Posts: 21839
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ach, auf eine Sekunde, oder 2 kommt es nciht an.

Ich dachte, dass ich, wenn ich den ersten Befehl einschalte, warten muss, bis ich wieder ausschalte...


Was ist RTC ?
Es kann nur eine Funktion in einem bestimmten Zeitpunkt ausgeführt werden, der "Zeitpunkt" ist aber sehr kurz.
zB
Code:
loop ()
{
  if (time >lampe1an1 && time < lampe1aus1&&statuslampe1==0;)
   {
   digitalWrite(lampe1,HIGH);
   statuslampe1=1;
   }
  if (time > lampe1aus1&&statuslampe1==1;)
   {
   digitalWrite(lampe1,LOW);
   statuslampe1=0;
   }
...
}
braucht zur Ausführung weniger als 1mS und schaltet die Lampe 1 zur Zeit lampe1an ein und zur Zeit lampe1aus aus. Es können viele solcher if- Bedingungen im loop() stehen.

Grüße Uwe


Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

@J3RE

Danke für den Link!

@Uwe,

so in etwa hatte ich das gedacht, mit dem "if"...
Logged

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 269
Posts: 21839
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

so in etwa hatte ich das gedacht, mit dem "if"...
Ok, dann versuch mal Deinen Sketch zu schreiben. Wir sind bei Problemen hier zu finden. Grüße Uwe
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Alles klar, danke.

ich habe gerade mal fix den Code getippt, so wie ich mit den vorstelle.

In das RTC mit den dazugehörigen Variablen und Formaten muss ich mir noch mal ansehen, aber im groben könnte es so aussehen:
Code:
//Lampe 1
  int lampe_1 = 13;         //Port im Arduino one
  //int lampe_dimmer_1 = 11;  //Port im Arduino one
  int lampe_an_1 = 0000;    //Startzeit
  int lampe_aus_1 = 0000;   //Endzeit
//Lampe 2
  int lampe_2 = 12;         //Port im Arduino one
  //int lampe_dimmer_2 = 10;  //Port im Arduino one
  int lampe_an_2 = 0000;    //Startzeit
  int lampe_aus_2 = 0000;   //Endzeit
// Motor 1
  int motor_1 = 2;          //Port im Arduino one
  int motor_an_1 = 0000;    //Startzeit
  int motor_aus_1 = 0000;   //Endzeit
// Motor 2
  int motor_2 = 4;          //Port im Arduino one
  int motor_an_2 = 0000;    //Startzeit
  int motor_aus_2 = 0000;   //Endzeit
// Motor 3
  int motor_3 = 7;          //Port im Arduino one
  int motor_an_3 = 0000;    //Startzeit
  int motor_aus_3 = 0000;   //Endzeit
// Motor 4
  int motor_4 = 8;          //Port im Arduino one
  int motor_an_4 = 0000;    //Startzeit
  int motor_aus_4 = 0000;   //Endzeit

//Status
int status_lampe_1 = "0";
int status_lampe_2 = "0";
int status_motor_1 = "0";
int status_motor_2 = "0";
int status_motor_3 = "0";
int status_motor_4 = "0";

void setup(){
  pinMode(lampe_1, OUTPUT); // Digitaler Pin als Ausgang
  pinMode(lampe_2, OUTPUT);
  pinMode(lampe_dimmer_2 , OUTPUT);
  pinMode(lampe_dimmer_2 , OUTPUT);
  pinMode(motor_1 , OUTPUT);
  pinMode(motor_2 , OUTPUT);
  pinMode(motor_3 , OUTPUT);
  pinMode(motor_4 , OUTPUT);
}


loop ()
{
  //Lampe 1
  if (time >lampe_an_1 && time < lampe_aus_1 && status_lampe_1==0;)
  // Wenn die Zeit größer ist, als in "lampe_an_1"
  // und
  // Wenn die Zeit kleiner ist, als in "lampe_aus_1"
  // und
  // Wenn der Status auf "0" (aus) steht
   {
   digitalWrite(lampe_1,HIGH);
   status_lampe_1=1;
   }
  if (time > lampe_aus_1 && status_lampe_1==1;)
   {
   digitalWrite(lampe_1,LOW);
   status_lampe_1=0;
   }
  //Lampe 2
  if (time >lampe_an_2 && time < lampe_aus_2 && status_lampe_2==0;)
   {
   digitalWrite(lampe_1,HIGH);
   status_lampe_2=1;
   }
  if (time > lampe_aus_2 && status_lampe_2==1;)
   {
   digitalWrite(lampe_1,LOW);
   status_lampe_2=0;
   }
   
   
   
  //Motor 0
  if (status_motor_1==0 && status_motor_2==0 && status_motor_3==0 && status_motor_4==0;)
   {
   int motor_0 = random(1, 20);
   // Nur Motor 1 läuft
   if (motor_0==1 || motor_0==2)
    {
    aktuelle_zeit = get(time);
    motor_an_1 = aktuelle_zeit;
    motor_aus_1 = aktuelle_zeit + /*5 Stunden*/;
    }
   // Nur Motor 2 läuft
   if (motor_0==3 || motor_0==4)
    {
    aktuelle_zeit = get(time);
    motor_an_2 = aktuelle_zeit;
    motor_aus_2 = aktuelle_zeit + /*5 Stunden*/;
    }
   // Nur Motor 3 läuft   
   if (motor_0==5 || motor_0==6)
    {
    aktuelle_zeit = get(time);
    motor_an_3 = aktuelle_zeit;
    motor_aus_3 = aktuelle_zeit + /*5 Stunden*/;
    }
   // Nur Motor 4 Läuft
   if (motor_0==7 || motor_0==8)
    {
    aktuelle_zeit = get(time);
    motor_an_4 = aktuelle_zeit;
    motor_aus_4 = aktuelle_zeit + /*5 Stunden*/;
    }
   // Nur Motor 1+2 laufen
   if (motor_0==9)
    {
    aktuelle_zeit = get(time);
    motor_an_1 = aktuelle_zeit;
    motor_aus_1 = aktuelle_zeit + /*5 Stunden*/;
    aktuelle_zeit = get(time);
    motor_an_2 = aktuelle_zeit;
    motor_aus_2 = aktuelle_zeit + /*5 Stunden*/;
    }
   // Nur Motor 1+3 laufen
   if (motor_0==10)
    {
    aktuelle_zeit = get(time);
    motor_an_1 = aktuelle_zeit;
    motor_aus_1 = aktuelle_zeit + /*5 Stunden*/;
    aktuelle_zeit = get(time);
    motor_an_3 = aktuelle_zeit;
    motor_aus_3 = aktuelle_zeit + /*5 Stunden*/;
    }
   // Nur Motor 1+4 laufen
   if (motor_0==11)
    {
    aktuelle_zeit = get(time);
    motor_an_1 = aktuelle_zeit;
    motor_aus_1 = aktuelle_zeit + /*5 Stunden*/;
    aktuelle_zeit = get(time);
    motor_an_4 = aktuelle_zeit;
    motor_aus_4 = aktuelle_zeit + /*5 Stunden*/;
    }   
   // Nur Motor 2+3 laufen
   if (motor_0==12)
    {
    aktuelle_zeit = get(time);
    motor_an_2 = aktuelle_zeit;
    motor_aus_2 = aktuelle_zeit + /*5 Stunden*/;
    aktuelle_zeit = get(time);
    motor_an_3 = aktuelle_zeit;
    motor_aus_3 = aktuelle_zeit + /*5 Stunden*/;
    }
   // Nur Motor 2+4 laufen
   if (motor_0==13)
    {
    aktuelle_zeit = get(time);
    motor_an_2 = aktuelle_zeit;
    motor_aus_2 = aktuelle_zeit + /*5 Stunden*/;
    aktuelle_zeit = get(time);
    motor_an_4 = aktuelle_zeit;
    motor_aus_4 = aktuelle_zeit + /*5 Stunden*/;
    }
   // Nur Motor 3+4 laufen
   if (motor_0==14)
    {
    aktuelle_zeit = get(time);
    motor_an_3 = aktuelle_zeit;
    motor_aus_3 = aktuelle_zeit + /*5 Stunden*/;
    aktuelle_zeit = get(time);
    motor_an_4 = aktuelle_zeit;
    motor_aus_4 = aktuelle_zeit + /*5 Stunden*/;
    }
   // Nur Motor 1+2+3 laufen
   if (motor_0==15)
    {
    aktuelle_zeit = get(time);
    motor_an_1 = aktuelle_zeit;
    motor_aus_1 = aktuelle_zeit + /*2 Stunden*/;
    aktuelle_zeit = get(time);
    motor_an_2 = aktuelle_zeit;
    motor_aus_2 = aktuelle_zeit + /*2 Stunden*/;
    aktuelle_zeit = get(time);
    motor_an_3 = aktuelle_zeit;
    motor_aus_3 = aktuelle_zeit + /*2 Stunden*/;
    }
   // Nur Motor 1+2+4 laufen
   if (motor_0==16)
    {
    aktuelle_zeit = get(time);
    motor_an_1 = aktuelle_zeit;
    motor_aus_1 = aktuelle_zeit + /*2 Stunden*/;
    aktuelle_zeit = get(time);
    motor_an_2 = aktuelle_zeit;
    motor_aus_2 = aktuelle_zeit + /*2 Stunden*/;
    aktuelle_zeit = get(time);
    motor_an_4 = aktuelle_zeit;
    motor_aus_4 = aktuelle_zeit + /*2 Stunden*/;
    }
   // Nur Motor 1+3+4 laufen
   if (motor_0==17)
    {
    aktuelle_zeit = get(time);
    motor_an_1 = aktuelle_zeit;
    motor_aus_1 = aktuelle_zeit + /*2 Stunden*/;
    aktuelle_zeit = get(time);
    motor_an_3 = aktuelle_zeit;
    motor_aus_3 = aktuelle_zeit + /*2 Stunden*/;
    aktuelle_zeit = get(time);
    motor_an_4 = aktuelle_zeit;
    motor_aus_4 = aktuelle_zeit + /*2 Stunden*/;
    }
   // Nur Motor 2+3+4 laufen
   if (motor_0==8)
    {
    aktuelle_zeit = get(time);
    motor_an_2 = aktuelle_zeit;
    motor_aus_2 = aktuelle_zeit + /*2 Stunden*/;
    aktuelle_zeit = get(time);
    motor_an_3 = aktuelle_zeit;
    motor_aus_3 = aktuelle_zeit + /*2 Stunden*/;
    aktuelle_zeit = get(time);
    motor_an_4 = aktuelle_zeit;
    motor_aus_4 = aktuelle_zeit + /*2 Stunden*/;
    }
   // Alle Motoren laufen
   if (motor_0==19)
    {
    aktuelle_zeit = get(time);
    motor_an_1 = aktuelle_zeit;
    motor_aus_1 = aktuelle_zeit + /*1 Stunden*/;
    aktuelle_zeit = get(time);
    motor_an_2 = aktuelle_zeit;
    motor_aus_2 = aktuelle_zeit + /*1 Stunden*/;
    aktuelle_zeit = get(time);
    motor_an_3 = aktuelle_zeit;
    motor_aus_3 = aktuelle_zeit + /*1 Stunden*/;
    aktuelle_zeit = get(time);
    motor_an_4 = aktuelle_zeit;
    motor_aus_4 = aktuelle_zeit + /*1 Stunden*/;
    }
   }
   
   
  //Motor 1
  if (time >motor_an_1 && time < motor_aus_1 && status_motor_1==0;)
   {
   digitalWrite(motor_1,HIGH);
   status_motor_1=1;
   }
  if (time > motor_aus_1 && status_motor_1==1;)
   {
   digitalWrite(motor_1,LOW);
   status_motor_2=0;
   } 
  //Motor 2 
  if (time >motor_an_2 && time < motor_aus_2 && status_motor_2==0;)
   {
   digitalWrite(motor_2,HIGH);
   status_motor_2=1;
   }
  if (time > motor_aus_2 && status_motor_2==1;)
   {
   digitalWrite(motor_2,LOW);
   status_motor_2=0;
   } 
  //Motor 3 
  if (time >motor_an_3 && time < motor_aus_3 && status_motor_3==0;)
   {
   digitalWrite(motor_3,HIGH);
   status_motor_3=1;
   }
  if (time > motor_aus_3 && status_motor_3==1;)
   {
   digitalWrite(motor_3,LOW);
   status_motor_3=0;
   } 
  //Motor 4
  if (time >motor_an_4 && time < motor_aus_4 && status_motor_4==0;)
   {
   digitalWrite(motor_4,HIGH);
   status_motor_4=1;
   }
  if (time > motor_aus_4 && status_motor_4==1;)
   {
   digitalWrite(motor_4,LOW);
   status_motor_4=0;
   }   
}


Bei der Variante "Motor 0", in der die Zufallszahlen ermittelt werden habe ich überlegt, ob ich das nach den Antrieben oder nach den Antriebskonstellationen anordne, ich habe mich für letzteres entschieden, da ich so individuell die Dauer beeinflussen kann, wenn mehrere Antriebe geschaltet werden.

Was meint ihr zum Code?  smiley
Logged

Austria
Offline Offline
Full Member
***
Karma: 2
Posts: 107
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
// Nur Motor 2+3+4 laufen
   if (motor_0==8)
    {
    aktuelle_zeit = get(time);
    motor_an_2 = aktuelle_zeit;
    motor_aus_2 = aktuelle_zeit + /*2 Stunden*/;
    aktuelle_zeit = get(time);
    motor_an_3 = aktuelle_zeit;
    motor_aus_3 = aktuelle_zeit + /*2 Stunden*/;
    aktuelle_zeit = get(time);
    motor_an_4 = aktuelle_zeit;
    motor_aus_4 = aktuelle_zeit + /*2 Stunden*/;
    }

Bei der if-Abfrage hast du dich vertippt, hier sollte 18 statt 8 stehen.
Die aktuelle Zeit brauchst du auch nur einmal pro Programmdurchlauf abfragen, so ein Durchlauf dauert nur einen Bruchteil einer Sekunde.

Code:
//Motor 1
  if (time >motor_an_1 && time < motor_aus_1 && status_motor_1==0;)
   {
   digitalWrite(motor_1,HIGH);
   status_motor_1=1;
   }
  if (time > motor_aus_1 && status_motor_1==1;)
   {
   digitalWrite(motor_1,LOW);
   status_motor_2=0;
   } 
Hier setzt du den falschen Status zurück, hier sollte status_motor_1 zurückgesetzt werden.

Ansonsten ist mir nichts aufgefallen.

Grüße,
J3RE
« Last Edit: April 14, 2013, 04:49:10 pm by J3RE » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,

das Thema ist schon ein bisschen älter, aber ich hatte damals keine Zeit, es weiter vorran zu treiben.  smiley-red

Ich hatte mit damals den DS1302 geholt, und das dort angegebene Script ausprobiert. Es scheint soweit zu funktionieren.

In den dortigen void loop integriere ich meine Zeilen, aus meinen void loop, das selbe beim void setup.
Allerdings komme ich nicht an die Uhrzeit ran.


Soweit ich den Code verstehe, definiere ich eine Start-Zeit:
Code:
  // Example for april 15, 2013, 10:08, monday is 2nd day of Week.
  // Set your own time and date in these variables.
  seconds    = 0;
  minutes    = 8;
  hours      = 10;
  dayofweek  = 2;  // Day of week, any day can be first, counts 1...7
  dayofmonth = 15; // Day of month, 1...31
  month      = 4;  // month 1...12
  year       = 2013;

Das sollten dann doch auch die Variablen sein, die im im Code abfrage, oder?
Logged

Pages: [1] 2   Go Up
Jump to: