Pages: [1] 2   Go Down
Author Topic: Anfaenger sucht sowas wie ne WAIT funktion  (Read 1278 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Jr. Member
**
Karma: 1
Posts: 58
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

so, zu meinem problem,....

mit meinem "clockSpeed" kann ich mir dir geschwindigkeit einstellen. nun moechte ich aber, das mein "Step 1 bis Step 8" nach jedem neuen Impuls der Clock abgearbeitet wird.
so wie es jetzt laeuft, werden ja solange die einzelnen Steps ausgefuehrt solange der Clock-Impuls HIGH ist.
Ich brauch also was, wo ich zwischen den Steps sagen kann : warte bis gateState = LOW
und dann geht es normal weiter mit den Steps.


Wer kann mir bitte auf die Spruenge helfen ?

Hier noch der Code :
Code:
const int clockGateOut =  13;     
int gatePoti = 8;
int gateState = LOW;           
long previousClockMillis = 0;       
long clockSpeed = 0;

int greenLed = 11;
int gateStatus = LOW;

void setup() {

  pinMode(clockGateOut, OUTPUT);
  pinMode(gatePoti, INPUT);
 
 pinMode(greenLed, OUTPUT);
 
}

void loop()
{
 
  clockSpeed = analogRead(gatePoti);
 
  unsigned long currentClockMillis = millis();
 
  if(currentClockMillis - previousClockMillis > clockSpeed) {
    previousClockMillis = currentClockMillis;   
    if (gateState == LOW)
      gateState = HIGH;
    else
      gateState = LOW;

    digitalWrite(clockGateOut, gateState);
  }
  // Step 1
  gateStatus = digitalRead(clockGateOut);
  if(gateStatus == HIGH) {
    digitalWrite(greenLed,HIGH);
    delay(20);
    digitalWrite(greenLed,LOW);
   }
    // Step 2   
    gateStatus = digitalRead(clockGateOut);
  if(gateStatus == HIGH){
    digitalWrite(greenLed,LOW);
    delay(20);
    digitalWrite(greenLed,LOW);
  }
    // Step 3
    gateStatus = digitalRead(clockGateOut);
  if(gateStatus == HIGH){
    digitalWrite(greenLed,HIGH);
    delay(20);
    digitalWrite(greenLed,LOW);
  }
    // Step 4   
    gateStatus = digitalRead(clockGateOut);
  if(gateStatus == HIGH){
    digitalWrite(greenLed,LOW);
    delay(20);
    digitalWrite(greenLed,LOW);
  }
    // Step 5
    gateStatus = digitalRead(clockGateOut);
  if(gateStatus == HIGH) {
    digitalWrite(greenLed,HIGH);
    delay(20);
    digitalWrite(greenLed,LOW);
  }
    // Step 6 
    gateStatus = digitalRead(clockGateOut);
  if(gateStatus == HIGH){
    digitalWrite(greenLed,HIGH);
    delay(20);
    digitalWrite(greenLed,LOW);
  }
    // Step 7
    gateStatus = digitalRead(clockGateOut);
  if(gateStatus == HIGH){
    digitalWrite(greenLed,HIGH);
    delay(20);
    digitalWrite(greenLed,LOW);
  }
    // Step 8
    gateStatus = digitalRead(clockGateOut);
  if(gateStatus == HIGH){
    digitalWrite(greenLed,LOW);
    delay(20);
    digitalWrite(greenLed,LOW);
  }
 
}
Logged

Germany
Offline Offline
Jr. Member
**
Karma: 0
Posts: 64
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich könnte mir vorstellen, dass der folgende Link genau die Information enthält die Du suchst:

http://arduino.cc/playground/Main/PcInt
Logged

twitter: @darktom

Offline Offline
Sr. Member
****
Karma: 10
Posts: 359
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So ganz ist dein Code nicht nachvollziehbar.
Du machst ja 4 mal hintereinander das gleiche wenn ich das richtig sehe,
Step1 und 2 ist das gleiche wie 3 und 4, 5 und 6 sowie 7 und 8.
Das geht bestimmt wesentlich eleganter.
Du willst aber zwischen jedem Step auf ein Ereignis warten??
Ich weiß nicht wie es anderen geht ich versteh es nicht ganz.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 19
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wie du wartest siehst du hier:

https://www.instructables.com/answers/How-do-I-use-a-wait-until-command-in-the-ardui/

Lg
Logged

0
Offline Offline
Jr. Member
**
Karma: 1
Posts: 58
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

So ganz ist dein Code nicht nachvollziehbar.
Du machst ja 4 mal hintereinander das gleiche wenn ich das richtig sehe,
Step1 und 2 ist das gleiche wie 3 und 4, 5 und 6 sowie 7 und 8.
Das geht bestimmt wesentlich eleganter.
Du willst aber zwischen jedem Step auf ein Ereignis warten??
Ich weiß nicht wie es anderen geht ich versteh es nicht ganz.

das ist so gesehen nur ein teil meines programms.
das mit den steps isr schon ok so.
mir geht es nur darum zu verstehen wie ich es schaffe nach jedem clock-impuls den naechsten step zu starten.
Logged

0
Offline Offline
Jr. Member
**
Karma: 1
Posts: 58
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich könnte mir vorstellen, dass der folgende Link genau die Information enthält die Du suchst:

http://arduino.cc/playground/Main/PcInt



hab mir den code mal angeschaut,... versteh aber nur bahnhof !
das ist noch ne nummer zu gross fuer mich als anfaenger.
aber trotzdem danke fuer den versuch smiley-wink
Logged

0
Offline Offline
Jr. Member
**
Karma: 1
Posts: 58
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


auf den ersten blick sieht das ganz gut aus.
habs zwar noch nicht ganz geschnallt, aber ich werd es mir jetzt mal genauer anschaun.

danke !
Logged

0
Offline Offline
Jr. Member
**
Karma: 1
Posts: 58
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

ich hab das ganze jetzt mal mit der while-schleife versucht :

Code:
int clockGateOut =  13;     
int gatePoti = 8;
int gateState = LOW;           
long previousClockMillis = 0;       
long clockSpeed = 0;
int platzHalter = LOW;
int xz = 0;

int greenLed = 11;
int gateStatus = LOW;

void setup() {

  pinMode(clockGateOut, OUTPUT);
  pinMode(gatePoti, INPUT);
 
 pinMode(greenLed, OUTPUT);
 
}

void loop()

{
//--------------------------------------------------------------- 
  clockSpeed = analogRead(gatePoti);                            //
  unsigned long currentClockMillis = millis();                  //
 
  if(currentClockMillis - previousClockMillis > clockSpeed) {   //
    previousClockMillis = currentClockMillis;                   //
    if (gateState == LOW)                                       //   CLOCK
      gateState = HIGH;                                         //
    else                                                        //
      gateState = LOW;                                          //

    digitalWrite(clockGateOut, gateState);                      //
  }
//----------------------------------------------------------------

  // Step 1
  gateStatus = digitalRead(clockGateOut);
  if(gateStatus == HIGH) {
    digitalWrite(greenLed,HIGH);
    delay(20);
    digitalWrite(greenLed,LOW);
  }
    xz = gateStatus;                                           // hier soll die while-schleife
    while(xz == 1) {                                           // dafuer sorgen, das der naechste step erst
      xz = digitalRead(gateStatus);                            // augefuehrt wird wenn
   }
   
   
    // Step 2   
    gateStatus = digitalRead(clockGateOut);
  if(gateStatus == HIGH){
    digitalWrite(greenLed,LOW);
    delay(20);
    digitalWrite(greenLed,LOW);
  }
   
   
    xz = gateStatus;
    while(xz == 1) {
      xz = digitalRead(gateStatus);   
   }
 
    // Step 3
    gateStatus = digitalRead(clockGateOut);
  if(gateStatus == HIGH){
    digitalWrite(greenLed,HIGH);
    delay(20);
    digitalWrite(greenLed,LOW);   
   }
   
   xz = gateStatus;
    while(xz == 1) {
      xz = digitalRead(gateStatus);   
   }
 
    // Step 4   
    gateStatus = digitalRead(clockGateOut);
  if(gateStatus == HIGH){
    digitalWrite(greenLed,LOW);
    delay(20);
    digitalWrite(greenLed,LOW);
  }
 
  xz = gateStatus;
    while(xz == 1) {
      xz = digitalRead(gateStatus);   
   }
   
    // Step 5
    gateStatus = digitalRead(clockGateOut);
  if(gateStatus == HIGH) {
    digitalWrite(greenLed,HIGH);
    delay(20);
    digitalWrite(greenLed,LOW);
  }
    // Step 6 
    gateStatus = digitalRead(clockGateOut);
  if(gateStatus == HIGH){
    digitalWrite(greenLed,HIGH);
    delay(20);
    digitalWrite(greenLed,LOW);
  }
    // Step 7
    gateStatus = digitalRead(clockGateOut);
  if(gateStatus == HIGH){
    digitalWrite(greenLed,HIGH);
    delay(20);
    digitalWrite(greenLed,LOW);
  }
    // Step 8
    gateStatus = digitalRead(clockGateOut);
  if(gateStatus == HIGH){
    digitalWrite(greenLed,LOW);
    delay(20);
    digitalWrite(greenLed,LOW);
  }
 
}

doch leider funktioniert es nicht.
entweder ist mein code falsch, oder,.... gehe ich recht in der annahme, das die while funktion alles ausser kraft setzt ?
auch meine CLOCK ( die ja eigentlich die ganze zeit laufen  sollte.

bin fuer jeden tip dankbar !
Logged

Offline Offline
Edison Member
*
Karma: 21
Posts: 1419
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Außer Kraft setzen tut Dein while nichts. Aber ...

Der "normale" Programmablauf ist so, das "loop()" immer wieder aufgerufen wird. Damit wird auch Dein Clock-Code immer wieder ausgeführt. Was Du mit Deinem while machts ist innerhalb der Funktion loop() mit dem while solange zu warten, bis das Ergebnis "digitalRead(gateStatus);" den Wert "1" liefert. Damit bleibt Dein Programm an dieser Stelle stehen, bis das eintritt.
Logged

0
Offline Offline
Jr. Member
**
Karma: 1
Posts: 58
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

gibt es irrendwie eine loesung meinen clock-code uebergeordnet laufen zu lassen ?
also so, das er auch ausgefuehrt wird waehrend die while-schleife laeuft.
Logged

Offline Offline
Edison Member
*
Karma: 21
Posts: 1419
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich denke du solltest die Struktur Deines Programms überdenken. Nach Möglichkeit keine delay() Aufrufe verwenden, sondern das durch Zeitdifferenzen lösen.
Desweitern ist mir folgendes in Deinem Code aufgefallen:
Code:
      gateState = LOW;                                          //

    digitalWrite(clockGateOut, gateState);                      //
  }
//----------------------------------------------------------------

  // Step 1
  gateStatus = digitalRead(clockGateOut);
  if(gateStatus == HIGH) {
Du verwendest das Pin "clockGateOut" aus OUTPUT. In Deinem "Clock-Code" wird die Variable "gateStatus" nach dem Clock-Code aber per "digitalRead()" von einem als OUTPUT deklarierten Pin gelesen und in Abhängigkeit davon wird etwas gemacht. Das ergibt keinen Sinn.

Weiterhin verwendest Du die Variablen gateState and gateStatus für den auf einem Pin zu setzenden Wert, machst dann aber ein
Code:
    xz = gateStatus;                                           // hier soll die while-schleife
    while(xz == 1) {                                           // dafuer sorgen, das der naechste step erst
      xz = digitalRead(gateStatus);                            // augefuehrt wird wenn
   }
Also ein "digitalRead()" vom Wert, nicht vom Pin. Das der Compiler das akzeptiert, liegt daran das auch HIGH und LOW am Ende einfach nur 0 oder 1 sind. Leider verstehe ich auch nicht, was Du mit dem Programm eigentloch genau machen willst. Evtl. lieferst Du ja mal eine kurze Ablaufbeschreibung Deines Programms in Worten.
Mario.
Logged

0
Offline Offline
Jr. Member
**
Karma: 1
Posts: 58
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Also,

mein programm soll so ablaufen:

das gatePoti liesst eine poti aus, mit dem ich die geschwindigkeit einstellen kann.

Code:
  clockSpeed = analogRead(gatePoti);                            //
  unsigned long currentClockMillis = millis();                  //
 
  if(currentClockMillis - previousClockMillis > clockSpeed) {   //
    previousClockMillis = currentClockMillis;                   //
    if (gateState == LOW)                                       //   CLOCK
      gateState = HIGH;                                         //
    else                                                        //
      gateState = LOW;                                          //

    digitalWrite(clockGateOut, gateState);                      //
  }

der clockGateOut gibt mir zum einen eine visuelle bestaetigung durch eine blinkLed und zum anderen soll => gateStatus spaeter einen analog pin belegen. Entweder wird dieser durch clockGateOut, oder durch eine externe clock getriggert werden.
Der gateSatus soll dann die einzelnen steps aktivieren (nacheinander). Sprich :

gateStatus == HIGH
spiele Step 1 =>  digitalWrite(greenLed,HIGH);
                            delay
                            digitalwrite(greenLed,LOW);

jetzt geht gateStatus irgendwann auf LOW und dann wieder auf HIGH. Also das gleiche spiel von vorn, nur das jetzt step 2
spiele Step 2 =>  digitalWrite(greenLed,LOW);
                            delay
                            digitalwrite(greenLed,LOW);
ausgefuehrt werden soll. u.s.w

das zweite problem was kommen wird, aber ich mich erstmal an diesem problem festgefaheren habe ist, das meine clock ja immer die gleiche zeit lang HIGH und LOW hat. Spaeter muss ich es noch hinbekommen, das ich nur einen kurzen HIGH impulse habe um die steps zu starten.
Du hast ja schon das delay angesprochen. Das soll auch durch zeitdifferenzen geloest werden. Welches wiederum durch ein anderes poti die blinkzeit der greenLed steuert.

Ich hoffe du kannst so einigermassen erahnen was ich meine und vorhabe.
Das ganze soll spaeter mal ein simpler gate-sequencer fuer einen analog synthesizer werden.

Du hast am anfang geschrieben :

Ich denke du solltest die Struktur Deines Programms überdenken.

ja, mit der programmstruktur hab ich so meine problem. Hab es noch nicht so richtig geschnallt, wie auch so vieles andere wie man sieht smiley-wink
aber mit der zeit wird das schon noch kommen.
Ich hoffe du, oder ihr koennt mich in die richtige richtung lenken.
Logged

Offline Offline
Edison Member
*
Karma: 21
Posts: 1419
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, es gibt zwei Ansätze, die Du verfolgen kannst.

1) Alles Steps werden in einem Durchlauf der Funktion "loop()" abgearbeitet. Ist die Funktion durchgelaufen fängt alles wieder von vorn an.
    In diesem Fall würde ich den Clock-Code in eine Funktion packen und zwischendurch immer wieder aufrufen, da Du ja innerhalb von loop() immer wieder warten musst. GGf. per Timer-Interrupt. Allerdings halte ich das persönlich für die ungünstigere Lösung.

2) Pro Durchlauf von loop() wird nicht gewartet. Am Anfang wird einmal der Clock-Code ausgeführt und entsprechende Status-Variablen gesetzt. Zusätzlich merkst Du Dir in einer globalen Variable, welcher Step der aktuelle ist. Dazu kommen für die verschiedenen "Blink"- und Schalt-Stati die entsprechenden Zeiten die gespeichert werden müssen. In Abhängigkeit des ermittelten Status wird dann z.B.  entschieden im aktuellen Step die LED zu schalten, oder aufgrund des "Clock"-Status in den nächsten Step zu wechseln, also die Variable "step" um eins zu erhöhen. Es wird damit innerhalb von loop() immer nur der Code des aktuellen Steps ausgeführt und ggf. in den nächsten Step gewechselt. Da Du nur eine LED verwendest, musst Du Dir eigentlich nur zwei Variablen "greenLEDvalue (HIGH|LOW)" und "unsigned long greenLEDtime" für das Blinken anlegen. Letztere speichert die Zeit seit der letzen Änderung des Status. Bei jedem Step kannst Du nun vergleichen, ob millis() - "blinkzeit" >  greenLEDtime ist. Wenn ja, dann "greenLEDvalue = !greenLEDvalue;" und Wert auf das LED-Pin schreiben. Danach die aktuelle Zeit merken "greenLEDtime = millis()". Somit bekommst Du das Blinken ohne delay hin.
Logged

Offline Offline
Edison Member
*
Karma: 21
Posts: 1419
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
jetzt geht gateStatus irgendwann auf LOW und dann wieder auf HIGH. Also das gleiche spiel von vorn, nur das jetzt step 2
spiele Step 2 =>  digitalWrite(greenLed,LOW);
                            delay
                            digitalwrite(greenLed,LOW);
Das verstehe ich auch noch nicht so ganz? Außer die LED auf LOW setzen, brauchst Du doch im Step 2 nix machen, oder? warum dann noch ein delay und dann nochmal die LED auf LOW setzen? Um sicher zu sein, das sie wirklich aus ist?  smiley

Richtig verstanden habe ich Dein Ziel leider immer noch nicht, isgt es richtig, das Du über das clockGateOut irgendetwas externes triggern willst? Die Geschwindigkeit soll dabei von einem Wert abhängen, die über ein Poti am analogen Eingang eingestellt wird?
Dazu die erste Frage, über welche Zeiten für den Clock-Impuls reden wir? analogRead() liefert maximal den Wert 1023, das wäre dann knapp eine Sekunde, wenn Du mit millis() arbeitest. Bis auf die Steps zum blinken der LED sehe ich im orginalem Sketch keine weiteren Funktionen. Daher würde ich erstmal schrittweise anfangen.

Code:
#define CLOCK_OUT 13
#define LED_OUT 11
#define POTI_PIN A2

int clockState = LOW;
unsigned long previousTime = 0;
int clockSpeed = 0;

void setup() {
  Serial.begin(9600);
  pinMode(CLOCK_OUT, OUTPUT);
  pinMode(LED_OUT, OUTPUT);
 
}


void loop() {
  clockSpeed = getSpeed(POTI_PIN);
  if(millis() - clockSpeed > previousTime) {
   
      // LOW <-> HIGH     
      clockState = !clockState;
     
      //Clock Out schreiben
      digitalWrite(CLOCK_OUT,clockState);
     
      //LED blinkt im Takt von Clockout
      digitalWrite(LED_OUT,clockState);
     
      //zeit merken
      previousTime = millis();
  }
}


int getSpeed(int pin) {
   //spaeter kann hier noch zusätzlicher code zum setzen der geschwindigkeit rein
   return analogRead(pin);
}

Das kann als Basis für Erweiterungen dienen. Im o.g. Beispiel blinkt die LED immer im Takt von Deinem ClockSpeed. Wenn die LED häufiger blinken soll, und das vom Clock-Wechsel getriggert werden soll, dann kann man das auch recht einfach ergänzen.
Logged

0
Offline Offline
Faraday Member
**
Karma: 24
Posts: 3487
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Schau Dir mal die MsTimer2 Library an. Damit kannst Du Code "übergeordnet" laufen lassen. Allerdings solltest Du Dir dazu verschiedene Beispiele anschauen die funktionieren und versuchen zu verstehen warum die überhaupt Funktionieren. Das Zauberwort heißt Interrupt. Das ist nicht schwer zu lernen, aber man muß sich schon ein bischen anstrengen.

Ein einfaches Beispiel habe ich auf meiner Webseite: http://blog.blinkenlight.net/experiments/basic-effects/persistence-of-vision/. loop() bleibt dabei völlig leer. Im Playground finden sich noch ähnliche Libs wie die MsTimer2 (falls Du anderes Timing benötigst).
Logged

Check out my experiments http://blog.blinkenlight.net

Pages: [1] 2   Go Up
Jump to: