[Résolu] Empêcher le "bruit" électronique/rebonds

Bonjour à tous !

Mon projet est une mini lecteur MP3 avec un bouton PLAY/STOP (Qd le bouton est appuyé, il lance la musique, si le bouton est rappuyé pdt la lecture, il arrête la musique et la remet au début)

Voici le code que j’utilise, je l’ai récupéré sur le net. (Je suis débutant donc mon travail a consisté à tester tous les codes que j’ai pu trouver jusqu’à ce que ça marche :sunglasses: )

#include <SoftwareSerial.h>



#define ARDUINO_RX 5 // TX - Arduino RX

#define ARDUINO_TX 6 // RX - Arduino TX



SoftwareSerial mySerial(ARDUINO_RX, ARDUINO_TX);



unsigned char playmode = 0; 

  #define PLAY  1

  #define PAUSE 0

static int8_t Send_buf[8] = {0} ;

  

/************Command byte**************************/

#define CMD_NEXT_SONG 0X01

#define CMD_PREV_SONG 0X02

#define CMD_PLAY_W_INDEX 0X03

#define CMD_VOLUME_UP 0X04

#define CMD_VOLUME_DOWN 0X05

#define CMD_SET_VOLUME 0X06

#define CMD_SINGLE_CYCLE_PLAY 0X08

#define CMD_SEL_DEV 0X09

#define DEV_TF 0X02

#define CMD_SLEEP_MODE 0X0A

#define CMD_WAKE_UP 0X0B

#define CMD_RESET 0X0C

#define CMD_PLAY 0X0D

#define CMD_PAUSE 0X0E

#define CMD_PLAY_FOLDER_FILE 0X0F

#define CMD_STOP_PLAY 0X16

#define CMD_FOLDER_CYCLE 0X17

#define CMD_SET_SINGLE_CYCLE 0X19

#define SINGLE_CYCLE_ON 0X00

#define SINGLE_CYCLE_OFF 0X01

#define CMD_SET_DAC 0X1A

#define DAC_ON  0X00

#define DAC_OFF 0X01

#define CMD_PLAY_W_VOL 0X22

/*********************************************************************/



#define ROTARY_ANGLE_SENSOR A0



#define ADC_REF 5//reference voltage of ADC is 5v

#define VCC     5    //the default value of VCC of the control interface is 5v

#define FULL_ANGLE 280//full value of the rotary angle is 280 degrees



void setup() 

{

  //pinMode(2, INPUT); // Button - Paluse&Play

  Serial.begin(9600);

  mySerial.begin(9600);

  delay(500);

  attachInterrupt(0, playOrPause, RISING);//pin2 -> INT0, and the Touch Sensor 

                                          //is connected with pin2 of Arduino

  sendCommand(CMD_SEL_DEV, DEV_TF);    

  delay(200);

  sendCommand(CMD_PLAY_W_VOL, 0X0F01);

}

static int8_t pre_vol = 0x0f; 

void loop() 

{

  int degrees;

  degrees = getDegree();


  int8_t volume;

  /*The degrees is 0~280, should be converted to be 0~255 to control the*/

  /*brightness of LED */

  volume = map(degrees, 0, 280, 30, 0); 

  if(volume != pre_vol)

  {

    sendCommand(CMD_SET_VOLUME, volume);

    pre_vol = volume;

  }

  delay(100);

}



void sendCommand(int8_t command, int16_t dat)

{

  delay(20);

  

  Send_buf[0] = 0x7e; //

  Send_buf[1] = 0xff; //

  Send_buf[2] = 0x06; //

  Send_buf[3] = command; //

  Send_buf[4] = 0x00;//

  Send_buf[5] = (int8_t)(dat >> 8);//datah

  Send_buf[6] = (int8_t)(dat); //datal

  Send_buf[7] = 0xef; //

  for(uint8_t i=0; i<8; i++)//

  {

    mySerial.write(Send_buf[i]);  

  }

  

}



int getDegree()

{

  int sensor_value = analogRead(ROTARY_ANGLE_SENSOR);

  float voltage;

  voltage = (float)sensor_value*ADC_REF/1023;

  float degrees = (voltage*FULL_ANGLE)/VCC;

  return 0;

}

/*Interrupt service routine*/

void playOrPause()

{

  cli();
  delay(1000);
  if(playmode == PLAY)

  {

    playmode = PAUSE;
    sendCommand(CMD_RESET,0);

  }

  else

  {

    playmode = PLAY;
    sendCommand(CMD_PLAY,0);

  }
  sei();

}

Alors, ce code fonctionne, si j’appuie sur le bouton pin 2, la musique se lance et si je rappuie elle se reset. Le problème c’est que cela ne fonctionne que sur ma breadboard…

Je m’explique, je branche mon montage sur mon automate, quand je passe mon relais de 0 à 1, au lieu de détecter UN seul changement d’état ( de 0=>1 d’où le RISING dans l’attachInterrupt ) le programme en détecte 10 ou 12 ou 15 ou 9 ou… voila, c’est aléatoire…

Pour résoudre ceci, j’avais pensé mettre un timer… quand je rentre dans mon interruption, j’envoie ma commande de lecture ou reset et je met en pause le code pendant 1 seconde par exemple… Le problème c’est j’ai découvert que la fonction ‘delay()’ ne marche pas dans un attachInterrupt()…

Est-ce que quelqu’un parmi vous aurait un idée… ?

Grosso modo, il faudrait qu’a la première impulsion détectée le code ne reçoive plus d’interruptions pendant 5 secondes puis reprenne son fonctionnement normal…

(Mon automate est un IPX 800 et je passe par des relais FINDER, et mon pin2 est raccordé au 3.5v au lieu du 5V [Est-ce un problème, J’ai raccordé mon bouton pin 2 comme sur le schéma du bouton du tutoriel de Arduino à l’exception qu’il est branché sur le 3.5V (Est-ce que du coup la résistance 10Kohm n’est pas trop résistante ? ^^)

Merci à tous ceux qui prendront le temps de me répondre,

Cordialement,

JC

Pour éviter que les rebonds d'un boutin vous pourissent la vie, je connais deux solutions
a) mettre un condensateur en parallèle sur le bouton (solution très laide)
b) gérer , selon votre idée un timer: ceci a été fait danshttps://www.arduino.cc/en/Tutorial/Debounce
(code très bien commenté, suffisamment vieux pour que, s'il y avait eu une horreur, des vagues de protestations l'aient retiré des tutoriels officiels d'arduino)

Bonjour,

Dans une interruption, il faut faire le minimum de chose pour quelle soit aussi courte que possible.

Pourquoi utiliser une interruption?
Tu peux très bien tester ton bouton dans la loop().

C'est ce que fait limor Fried dans le lien de #1

dbrion06:
Pour éviter que les rebonds d’un boutin vous pourissent la vie, je connais deux solutions
a) mettre un condensateur en parallèle sur le bouton (solution très laide)
b) gérer , selon votre idée un timer: ceci a été fait danshttps://www.arduino.cc/en/Tutorial/Debounce
(code très bien commenté, suffisamment vieux pour que, s’il y avait eu une horreur, des vagues de protestations l’aient retiré des tutoriels officiels d’arduino)

C’est parfait ! Merci 1000 fois !

<Polémique>

a) mettre un condensateur en parallèle sur le bouton (solution très laide)

Solution très laide pour un informaticien
Seule solution valable pour un électronicien.

L’informaticien cache la poussière sous le tapis en fermant les yeux et bloque son programme jusqu’à ce que les parasites dus aux rebonds s’arrêtent.
L’électronicien s’arrange pour supprimer à la base ces parasites et délivre instantanément l’information.

Comme le dit l’adage bien connu : il vaut mieux prévenir que guérir.

</Polémique>

J’aime bien les nouvelles balises de Bernard. Il faudrait ajouter un bouton dans l’éditeur du forum :grin:

Sinon, essayer la bibliothèque "Onebutton" qui fonctionne à merveille:
Ça gère les clics "normaux", les clics "longs", les double clics, etc

Solution très laide pour un informaticien
Seule solution valable pour un électronicien.

C'est une solution qui mérite d'être signalée.

Maintenant, que se passe-t-il à la mise sous tension d'un micro contrôleur avec à une de ses pattes, un condensateur encore chargé? N'étant pas électronicien, je pense que le micro va souffrir (ou alors, faut mettre une résistance de limitation: ça devient compliqué: les claviers, avant qu'il y ait une horloge intégrée, pouvaient être compliqués)
Dans l'étrange monde des bidouilleurs, je ne sais pas si le posteur original a des condensateurs idoines, un fer à souder (ou une broad beard). La solution de limor fried -entre des milliers d'autres, qui ont -ré-inventé une roue pas si vilaine- est acceptable.

"C'est parfait ! Merci 1000 fois !"

Non: la perfection n'est pas de ce monde (vous en avez la preuve); même si Lady Ada Limor Fried — Wikipédia essaye d'y arriver