Utilisation d'un bouton pour plusieurs actions

Bonjour,
Je dois faire un projet pour mes cours mais je me retrouve bloqué avec un problème que je n'arrive pas a résoudre.
Mon objectif est de créer un thermomètre IR avec une carte arduino nano every.
Voici mon circuit:


Je souhaite supprimer 2 des 3 boutons et que si j'appui 1x prise de mesure, 2x changement d'unité, 1 appui long pour éteindre l'écran.
J'ai beau utilisé les Library qui sont proposé dans les autres forum soit ça ne marche pas soit je ne l'a trouve pas dans la bibliothèque.
Voici mon code pour avoir une idée de ce que je fait.

#include <Adafruit_MLX90614.h>
Adafruit_MLX90614 mlx = Adafruit_MLX90614();


#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

#define OLED_RESET -1
#define SCREEN_ADDRESS1 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);


#include "Adafruit_VL6180X.h"
Adafruit_VL6180X vl = Adafruit_VL6180X();

enum etat_t {
  init_e,
  eteindre_e,
  mesure_e,
  unit_e
};
etat_t etat_present = eteindre_e;

bool Bouton1, Bouton1Sauv, Bouton2, Bouton2Sauv, Bouton3, Bouton3Sauv = false;
int Unit = 0;

const float TensionMin = 3.2;
const float TensionMax = 4.2;

void Celsius(void);
void Fahrenheit(void);
void Kelvin(void);
void Distance(void);

void setup() {
  Serial.begin(9600);
  while (!Serial)
    ;
  Serial.println("serial initiated!");

  Serial.println("Adafruit MLX90614 test!");
  if (!mlx.begin()) {
    Serial.println("Error connecting to MLX sensor. Check wiring.");
    while (1)
      ;
  };
  Serial.println("Sensor found!");

  Serial.println("Adafruit SSD1306 test!");
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS1)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ;
  }
  Serial.println("Sensor found!");

  Serial.println("Adafruit VL6180x test!");
  if (!vl.begin()) {
    Serial.println("Failed to find sensor");
    while (1)
      ;
  }
  Serial.println("Sensor found!");

  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(4, INPUT);
}

void loop() {
  Bouton1 = digitalRead(2);
  Bouton2 = digitalRead(3);
  Bouton3 = digitalRead(4);

  switch (etat_present) {
    case init_e:
      if (Bouton1 != Bouton1Sauv) {
        if (Bouton1 == true) {
          delay(20);
          if (Bouton1 == true) {
            etat_present = eteindre_e;
          }
        }
        Bouton1Sauv = Bouton1;
      }

      if (Bouton2 != Bouton2Sauv) {
        if (Bouton2 == true) {
          delay(20);
          if (Bouton2 == true) {
            etat_present = mesure_e;
          }
        }
        Bouton2Sauv = Bouton2;
      }
      if (Bouton3 != Bouton3Sauv) {
        if (Bouton3 == HIGH) {
          delay(20);
          if (Bouton3 == true) {
            Unit++;
            if (Unit == 3) {
              Unit = 0;
            }
            etat_present = unit_e;
          }
        }
        Bouton3Sauv = Bouton3;
      }
      break;

    case eteindre_e:
      display.ssd1306_command(SSD1306_DISPLAYOFF);
      if (Bouton1 != Bouton1Sauv) {
        if (Bouton1 == true) {
          delay(20);
          if (Bouton1 == true) {
            Unit == 0;
            etat_present = mesure_e;
            display.ssd1306_command(SSD1306_DISPLAYON);
          }
        }
        Bouton1Sauv = Bouton1;
      }
      break;

    case mesure_e:
      if (Unit == 0) {
        Celsius();
        delay(100);
        etat_present = init_e;
      }
      if (Unit == 1) {
        Fahrenheit();
        delay(100);
        etat_present = init_e;
        break;
      }
      if (Unit == 2) {
        Kelvin();
        delay(100);
        etat_present = init_e;
        break;
      }
    case unit_e:
      if (Unit == 0) {
        Celsius();
        delay(100);
        etat_present = init_e;
      }
      if (Unit == 1) {
        Fahrenheit();
        delay(100);
        etat_present = init_e;
        break;
      }
      if (Unit == 2) {
        Kelvin();
        delay(100);
        etat_present = init_e;
        break;
      }
  }
}


void Celsius(void) {
  display.clearDisplay();
  affichageBattery();
  display.setRotation(1);
  display.setTextSize(1);
  display.setCursor(20, 0);
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.drawRoundRect(0, 0, 32, 20, 15, WHITE);
  display.setCursor(4, 0);
  display.write(9);
  display.setCursor(15, 3);
  display.println("C");
  display.setTextSize(1);
  display.drawRoundRect(0, 22, 64, 30, 5, WHITE);
  display.setCursor(6, 25);
  display.print("Ambient = ");
  display.setTextSize(2);
  display.setCursor(3, 34);
  display.print(mlx.readAmbientTempC());

  display.setTextSize(1);
  display.drawRoundRect(0, 54, 64, 30, 5, WHITE);
  display.setCursor(9, 57);
  display.print("Object = ");
  display.setCursor(3, 66);
  display.setTextSize(2);
  display.print(mlx.readObjectTempC());

  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(3, 110);
  Distance();
  display.display();
  display.clearDisplay();
}

void Fahrenheit(void) {
  display.clearDisplay();
  affichageBattery();
  display.setRotation(1);
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.drawRoundRect(0, 0, 32, 20, 15, WHITE);
  display.setCursor(4, 0);
  display.write(9);
  display.setCursor(15, 3);
  display.println("F");
  display.setTextSize(1);
  display.drawRoundRect(0, 22, 64, 30, 5, WHITE);
  display.setCursor(6, 25);
  display.print("Ambient = ");
  display.setTextSize(2);
  display.setCursor(3, 34);
  display.print(mlx.readAmbientTempF());

  display.setTextSize(1);
  display.drawRoundRect(0, 54, 64, 30, 5, WHITE);
  display.setCursor(9, 57);
  display.print("Object = ");
  display.setCursor(3, 66);
  display.setTextSize(2);
  display.print(mlx.readObjectTempF());

  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(3, 110);
  Distance();
  display.display();
  display.clearDisplay();
}

void Kelvin(void) {
  display.clearDisplay();
  affichageBattery();
  display.setRotation(1);
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.drawRoundRect(0, 0, 32, 20, 15, WHITE);
  display.setCursor(4, 0);
  display.write(9);
  display.setCursor(15, 3);
  display.println("K");
  display.setTextSize(1);
  display.drawRoundRect(0, 22, 64, 46, 5, WHITE);
  display.setCursor(6, 25);
  display.print("Ambient = ");
  display.setTextSize(2);
  display.setCursor(3, 34);
  display.print(mlx.readAmbientTempC() - 273.15, 2);

  display.setTextSize(1);
  display.drawRoundRect(0, 70, 64, 46, 5, WHITE);
  display.setCursor(9, 73);
  display.print("Object = ");
  display.setCursor(3, 82);
  display.setTextSize(2);
  display.print(mlx.readObjectTempC() - 273.15, 2);
  display.display();
  display.clearDisplay();
}

void Distance(void) {
  uint8_t distance = vl.readRange();
  uint8_t etat = vl.readRangeStatus();
  if (etat == VL6180X_ERROR_NONE) {
    display.print("Distance = ");
    display.print(distance);
    display.println(" mm");
  }
  if ((etat >= VL6180X_ERROR_SYSERR_1) && (etat <= VL6180X_ERROR_SYSERR_5)) {
    display.println("System error");
  } else if (etat == VL6180X_ERROR_ECEFAIL) {
    display.println("ECE failure");
  } else if (etat == VL6180X_ERROR_NOCONVERGE) {
    display.println("No convergence");
  } else if (etat == VL6180X_ERROR_RANGEIGNORE) {
    display.println("Ignoring range");
  } else if (etat == VL6180X_ERROR_SNR) {
    display.println("Signal/Noise error");
  } else if (etat == VL6180X_ERROR_RAWUFLOW) {
    display.println("Raw reading underflow");
  } else if (etat == VL6180X_ERROR_RAWOFLOW) {
    display.println("Raw reading overflow");
  } else if (etat == VL6180X_ERROR_RANGEUFLOW) {
    display.println("Range reading underflow");
  } else if (etat == VL6180X_ERROR_RANGEOFLOW) {
    display.println("Range reading overflow");
  }
}

int getBattery() {
  float b = analogRead(A3);
  int minValue = (1023 * TensionMin) / 5;
  int maxValue = (1023 * TensionMax) / 5;
  b = ((b - minValue) / (maxValue - minValue)) * 100;
  if (b > 100)
    b = 100;
  else if (b < 0)
    b = 0;
  int valeur = b;
  return b;
}

void affichageBattery(void) {
  display.clearDisplay();
  display.setRotation(1);
  display.fillRect(37, 5, 3, 10, WHITE);
  display.drawRect(41, 2, 23, 16, WHITE);
  if (getBattery() >= 75) {
    display.fillRect(43, 4, 4, 12, WHITE);
    display.fillRect(48, 4, 4, 12, WHITE);
    display.fillRect(53, 4, 4, 12, WHITE);
    display.fillRect(58, 4, 4, 12, WHITE);
  } else if (getBattery() >= 50) {
    display.fillRect(48, 4, 4, 12, WHITE);
    display.fillRect(53, 4, 4, 12, WHITE);
    display.fillRect(58, 4, 4, 12, WHITE);
  } else if (getBattery() >= 25) {
    display.fillRect(53, 4, 4, 12, WHITE);
    display.fillRect(58, 4, 4, 12, WHITE);
  } else if ((getBattery() < 25) && (getBattery() > 5)) {
    display.fillRect(58, 4, 4, 12, WHITE);
  } else {}
  display.display();
  delay(100);
}

Je suis complètement bloquer, Pouvez vous m'aidez?

Voir ici:

Sinon cela se bricole en utilisant millis() et en comptant le temps entre un appui et le relâché et une succession d'appui dans un temps donné.

Cette librairie fait partie de celle que je ne trouve pas dans la bibliothèque

hello
comme c'est un devoir, je ne te donne pas un prg complet
juste la gestion du BP pour te montrer le principe
à toi de l'adapter dans ton programme

le BP est raccordé à la pin D4 et ramene le GND. l'entrée est en PULLUP
le moniteur est à 115200 bauds

#define BP 4
unsigned long chrono_BP   = millis();
unsigned long BP_appui    =    0;
unsigned long appui_court = 1000;//moins de 1 seconde
unsigned long appui_long  = 1000;//plus de 1 seconde
byte flip_flop = 0;
void setup() {
  Serial.begin(115200);
  pinMode(BP, INPUT_PULLUP);
}

void loop() {
  if (digitalRead(BP) == LOW) {
    BP_appui = millis();
    while (!digitalRead(BP)) {
      delay(100) ;
    }
    if ((millis() - BP_appui) < appui_court) {
      Serial.println(millis() - BP_appui);
      Serial.println(F("c'est un appui court"));
      if ((flip_flop++) % 2) {
        Serial.println(F("OFF"));
      }
      else {
        Serial.println(F("ON"));
        flip_flop = 1;
      }
    }
    else {
      if ((millis() - BP_appui) > appui_long) {
        Serial.println(millis() - BP_appui);
        Serial.println(F("c'est un appui long"));
      }
    }
  }
}

La librairie est en pièce jointe dans le premier post du fil de discussion il suffit de l'installer à la main dans le sous-répertoire libraries de ton répertoire de travail.

éventuellement utilisez la bibliothèque Button dans easyRun de @bricoleau ou OneButton de Matthias Hertel ou encore Toggle de @dlloyd.

OneButton donne très facilement accès au simple click, double click et appui long.

Je le fait mais impossible de l'utiliser sur arduino.

Merci bcp pour toute ces librairies, je vais pas te mentir que je les avait toutes déjà tester, mais ça ne marchait pas.

Finalement j'ai repris la librairie OneButton hier soir et ça a enfin marché.
Merci à tous pour votre aide.

OK vous aviez dû faire des erreurs, fallait demander :slight_smile:

par exemple avec easyRun le code c'est

#include <easyRun.h>
const int pin = 2;

void click() {
  Serial.println("click");
}
void appuiLong() {
  Serial.println("click Long");
}
void doubleClick() {
  Serial.println("double click");
}

press2Button bouton(pin, click, appuiLong, doubleClick, nullptr);

void setup() {
  Serial.begin(115200);
}

void loop() {
  easyRun();
}

il y a des d'exemples à regarder ici

Voici, la partie de mon code qui gérait les boutons.
Petite explication: -1 clic --> Mesure de température
-2 clic --> Changement unité
-3 clic --> Eteindre l'écran

PS: si vous copier le code, il ne fonctionnera pas car les fonctions comme AFFCelsius() ne sont pas copier dans ce code.

#include <Arduino.h>
#include <OneButton.h>

#define BUTTON_PIN 2
OneButton btn = OneButton(BUTTON_PIN, false, false);

unsigned long chrono;
unsigned long Delay = 120000;

bool Bouton1 = false;
int AE = 1;


void setup() {
  Serial.begin(9600);
  btn.attachClick(oneclick);
  btn.attachDoubleClick(doubleclick);
  btn.attachLongPressStart(longclick);

  pinMode(3, OUTPUT);
}

void loop() {
  btn.tick();
  if (millis() - chrono >= Delay) {
    display.ssd1306_command(SSD1306_DISPLAYOFF);
  }
}


void oneclick() {
  if (AE == 1) {
  } else {
    chrono = millis();
    digitalWrite(3, HIGH);
    delay(100);
    if (Unit == 0) {
      AFFCelsius();
      Celsius();
      delay(100);
    } else if (Unit == 1) {
      AFFFahrenheit();
      Fahrenheit();
      delay(100);

    } else if (Unit == 2) {
      AFFKelvin();
      Kelvin();
      delay(100);
    }
    digitalWrite(3, LOW);
  }
}
void doubleclick() {
  if (AE == 1) {
  } else {
    chrono = millis();
    Unit++;
    if (Unit == 3) {
      Unit = 0;
    }
    if (Unit == 0) {
      AFFCelsius();
      delay(100);
    } else if (Unit == 1) {
      AFFFahrenheit();
      delay(100);

    } else if (Unit == 2) {
      AFFKelvin();
      delay(100);
    }
  }
}
void longclick() {
  chrono = millis();
  if (AE == 1) {
    AE--;
    display.ssd1306_command(SSD1306_DISPLAYON);
    delay(100);
    AFFCelsius();
  } else if (AE == 0) {
    AE++;
    display.ssd1306_command(SSD1306_DISPLAYOFF);
  }
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.