Bonnes pratiques en C++

Blink sans delay() méthode plus « pro »

delay() bloque tout → mauvais en pratique

On utilise millis() → programme non bloquant

1
2
// constants won't change. Used here to set a pin number:
3
const int ledPin = LED_BUILTIN;  // the number of the LED pin
4
5
// Variables will change:
6
int ledState = LOW;  // ledState used to set the LED
7
8
// Generally, you should use "unsigned long" for variables that hold time
9
// The value will quickly become too large for an int to store
10
unsigned long previousMillis = 0;  // will store last time LED was updated
11
12
// constants won't change:
13
const long interval = 1000;  // interval at which to blink (milliseconds)
14
15
void setup() {
16
  // set the digital pin as output:
17
  pinMode(ledPin, OUTPUT);
18
}
19
20
void loop() {
21
  // here is where you'd put code that needs to be running all the time.
22
23
  // check to see if it's time to blink the LED; that is, if the difference
24
  // between the current time and last time you blinked the LED is bigger than
25
  // the interval at which you want to blink the LED.
26
  unsigned long currentMillis = millis();
27
28
  if (currentMillis - previousMillis >= interval) {
29
    // save the last time you blinked the LED
30
    previousMillis = currentMillis;
31
32
    // if the LED is off turn it on and vice-versa:
33
    if (ledState == LOW) {
34
      ledState = HIGH;
35
    } else {
36
      ledState = LOW;
37
    }
38
39
    // set the LED with the ledState of the variable:
40
    digitalWrite(ledPin, ledState);
41
  }
42
}
43

Avantages :

  • le programme peut faire plusieurs tâches en parallèle

Bouton poussoir + anti-rebond (debounce)

Problème :

Un bouton « rebondit » → plusieurs détections au lieu d’une.

Solution simple avec millis()

1
/*
2
  Debounce
3
4
*/
5
6
// constants won't change. They're used here to set pin numbers:
7
const int buttonPin = 3;  // the number of the pushbutton pin
8
const int ledPin = 13;    // the number of the LED pin
9
10
// Variables will change:
11
int ledState = HIGH;        // the current state of the output pin
12
int buttonState;            // the current reading from the input pin
13
int lastButtonState = LOW;  // the previous reading from the input pin
14
15
// the following variables are unsigned longs because the time, measured in
16
// milliseconds, will quickly become a bigger number than can be stored in an int.
17
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
18
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers
19
20
void setup() {
21
  pinMode(buttonPin, INPUT);
22
  pinMode(ledPin, OUTPUT);
23
24
  // set initial LED state
25
  digitalWrite(ledPin, ledState);
26
}
27
28
void loop() {
29
  // read the state of the switch into a local variable:
30
  int reading = digitalRead(buttonPin);
31
32
  // check to see if you just pressed the button
33
  // (i.e. the input went from LOW to HIGH), and you've waited long enough
34
  // since the last press to ignore any noise:
35
36
  // If the switch changed, due to noise or pressing:
37
  if (reading != lastButtonState) {
38
    // reset the debouncing timer
39
    lastDebounceTime = millis();
40
  }
41
42
  if ((millis() - lastDebounceTime) > debounceDelay) {
43
    // whatever the reading is at, it's been there for longer than the debounce
44
    // delay, so take it as the actual current state:
45
46
    // if the button state has changed:
47
    if (reading != buttonState) {
48
      buttonState = reading;
49
50
      // only toggle the LED if the new button state is HIGH
51
      if (buttonState == HIGH) {
52
        ledState = !ledState;
53
      }
54
    }
55
  }
56
57
  // set the LED:
58
  digitalWrite(ledPin, ledState);
59
60
  // save the reading. Next time through the loop, it'll be the lastButtonState:
61
  lastButtonState = reading;
62
}
63

Résultat :

  • 1 appui = 1 action

  • comportement stable

Interruptions

Principe :

Arduino interrompt le programme quand un événement arrive

Exemple : bouton → réaction immédiate

1
const byte ledPin = 13;
2
const byte interruptPin = 3;  // input pin that the interruption will be attached to
3
volatile byte state = LOW;  // variable that will be updated in the ISR
4
5
void setup() {
6
  pinMode(ledPin, OUTPUT);
7
  pinMode(interruptPin, INPUT);
8
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
9
}
10
11
void loop() {
12
  digitalWrite(ledPin, state);
13
}
14
15
void blink() {
16
  state = !state;
17
}

Règles importantes (très pro) :

Dans une interruption :

  • pas de delay()

  • pas de Serial.print()

  • code ultra court

  • utiliser volatile

TP : compteur de clique simulation sous Proteus

Télécharger le prpjet Proteus suivant.

Ce projet actuellement change l'état de la LED lorsque l'on appuie sur le bouton poussir.

Modifier le programme de tels sorte à ce qu'il affiche la vitesse des appuis successifs dur le bouton.

Même question en utilisant les interruptions.