1
votes

Entrée utilisateur bloquée en boucle

J'ai créé ce code sur Arduino où l'objectif est que l'utilisateur saisisse un temps de retard dans le moniteur série, puis la LED doit clignoter avec ce temps de retard. Par exemple, si je tape 1000, la LED doit être allumée pendant 1 seconde puis éteinte pendant 1 seconde, puis répétez.

Mon problème est que lorsque le code a fini de s'exécuter une fois, il attend une nouvelle entrée d'utilisateur, au lieu de continuer à clignoter. Je pense que je dois retirer le Serial.parseInt de la boucle, mais je ne sais pas comment, car chaque fois que j'ai essayé de le mettre ailleurs, la LED s'allume en permanence.

Voici le code:

int ledPin = 13;


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

  Serial.print(" Enter delay time: ");
  while (!Serial.available());

}

void loop() {
  // put your main code here, to run repeatedly
  int delayTime = Serial.parseInt();
  digitalWrite(ledPin, HIGH);
  delay(delayTime);
  digitalWrite(ledPin, LOW);
  delay(delayTime);

}


0 commentaires

3 Réponses :


0
votes

Lisez simplement le temps de retard dans votre setup avant d'entrer dans la boucle

int ledPin = 13;
int delayTime = 0;

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

  Serial.print(" Enter delay time: ");
  while (!Serial.available());
  delayTime = Serial.parseInt();

}

void loop() {
  // put your main code here, to run repeatedly

  digitalWrite(ledPin, HIGH);
  delay(delayTime);
  digitalWrite(ledPin, LOW);
  delay(delayTime);

}


0 commentaires

2
votes

Serial.parseInt est une fonction de blocage. Cela signifie qu'il attend une entrée série valide jusqu'à ce qu'il expire. Pour cette raison, toute autre action de la boucle doit également attendre. Cependant, la lecture de l'entrée utilisateur dans setup ne fonctionne qu'une seule fois, donc elle ne demande plus jamais à l'utilisateur de saisir une nouvelle fois.

Pour éviter cela, vous devrez vérifier le tampon série, puis lire chaque octet individuellement , tout en faisant clignoter la LED dans la boucle principale.

Une autre chose à éviter maintenant, est l'utilisation de la fonction delay , car elle bloque également toute la boucle principale les lectures en série) pour le temps de paramètre donné. Vous pouvez toujours faire clignoter la LED en utilisant des intervalles d'horodatage.

Pour un bel exemple de lecture série non bloquante, nous pouvons utiliser cet exemple de la documentation Arduino . De plus, pour un autre bel exemple d'esquisse clignotant par LED sans utiliser delay , nous pouvons utiliser le Exemple BlinkWithoutDelay de la documentation Arduino également.

String inString = "";
unsigned long previousMillis = 0;
int delayTime = 0;
int ledState = LOW;
int ledPin = 13;

void nonBlockingSerialReadDelayTime() {
  while (Serial.available() > 0) {
    int inChar = Serial.read();
    if (isDigit(inChar)) {
      // convert the incoming byte to a char and add it to the string
      inString += (char)inChar;
    }
    // if you get a newline (user pressed ENTER on the serial console)
    if (inChar == '\n') {
      // set our new delay time
      delayTime = inString.toInt();

      // clear the string for new input
      inString = "";

      // ask user again
      Serial.print(" Enter delay time: ");
    }
  }
}

void blinkLED() {
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= delayTime) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable
    digitalWrite(ledPin, ledState);
  }
}

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
  while (!Serial.available());
  Serial.print(" Enter delay time: ");
}

void loop() {
  nonBlockingSerialReadDelayTime();
  blinkLED();
}


0 commentaires

0
votes

Bien sûr que Serial.parseInt () bloque, mais vous pouvez le combiner avec Serial.available ()

const int ledPin = 13;
int delayTime = 1000;

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
  Serial.print(" Enter delay time: ");
}

void loop() {
  digitalWrite(ledPin, HIGH);
  delay(delayTime);
  digitalWrite(ledPin, LOW);
  delay(delayTime);

  if (Serial.available()) { 
     int temp = Serial.parseInt();
     if (temp  > 0) delayTime = temp;
     Serial.print(" Enter delay time: ");
  }  
}

Bien sûr, cette approche ne permet pas de faire un cycle de clignotement très lent immédiatement , mais c'est un problème différent.


0 commentaires