Routage d'effet audio contrôlé par un Arduino Nano

Bonjour à tous, j'espère que vous allez bien !

Je me suis lancé il y a quelque semaines dans un projet sur lequel je coince depuis plusieurs jours au niveau de la programmation, je commence à me demander si ce que je souhaite faire est réellement faisable.

Il s'agit d'un rack audio 1U permettant de router des tranches audio vers des effets audio externes.

Il est composé de 7 entrées / sorties commutées vers 2 bus SEND / RETURN grâce à des relais.

Voici un exemple de comment sont connectés les relais :

et voici comment est connecté le Nano :

Le principe de fonctionnement souhaité est relativement simple :

  1. quand une des entrées analogique détecte un niveau 3.3V, elle active une sortie qui active une paire de relais afin de router le son vers le bus n°1;
  2. quand elle détecte un niveau 5V, elle active une autre sortie qui active 2 paires de relais afin de router le son dans le bus n°2.

Le problème, c'est que je n'arrive pas à obtenir le résultat souhaité, je me heurte soit à des rebonds, soit à des changements d'états non désirés, ou alors avec un programme qui "marche à peu près", mais qui est une usine à gaz complètement ridicule qui ne me permettra pas d'ajouter les petites fonctions que j'aimerai pour peaufiner mon projet.

Je précise que je suis extrêmement novice dans le domaine de la programmation avec des Arduinos, j'ai joué un peu avec il y a quelque années avec l'aide de la communauté, mais bien que j'ai révisé les tutoriels de base, je n'ai pas de connaissances approfondies.

Si l'un d'entre vous pourrait me lancer sur la bonne piste, je pourrais probablement m'en sortir par moi même, mais pour le moment j'avance à tâtons, pour ne pas dire que je fais carrément du stationnaire.

Merci beaucoup d'avance pour votre aide et passez une excellente journée !

Cordialement,

Jérôme.

Bonjour
Postez le code

Bonjour J-M-L et merci pour la réponse rapide.

J'ai recommencé le code à 0 pour y aller pas à pas, donc voici le peu qu'il y a pour le moment :

// Constantes d'entrées :
const int CH1 = A1;     // Bouton de contrôle du canal 1
const int CH2 = A2;     // Bouton de contrôle du canal 2
const int CH3 = A3;     // Bouton de contrôle du canal 3
const int CH4 = A4;     // Bouton de contrôle du canal 4
const int CH5 = A5;     // Bouton de contrôle du canal 5
const int CH6 = A6;     // Bouton de contrôle du canal 6
const int MST = A7;     // Bouton de contrôle du canal Master

// Constantes de sorties :
const int CH1_FX1=  0;      // Sortie pour router le canal 1 sur le bus FX1
const int CH1_FX2=  1;      // Sortie pour router le canal 1 sur le bus FX2

const int CH2_FX1=  2;      // Sortie pour router le canal 2 sur le bus FX1
const int CH2_FX2=  3;      // Sortie pour router le canal 2 sur le bus FX2

const int CH3_FX1=  4;      // Sortie pour router le canal 3 sur le bus FX1
const int CH3_FX2=  5;      // Sortie pour router le canal 3 sur le bus FX2

const int CH4_FX1=  6;      // Sortie pour router le canal 4 sur le bus FX1
const int CH4_FX2=  7;      // Sortie pour router le canal 4 sur le bus FX2

const int CH5_FX1=  8;      // Sortie pour router le canal 5 sur le bus FX1
const int CH5_FX2=  9;      // Sortie pour router le canal 5 sur le bus FX2

const int CH6_FX1=  10;      // Sortie pour router le canal 6 sur le bus FX1
const int CH6_FX2=  11;      // Sortie pour router le canal 6 sur le bus FX2

const int MST_FX1=  12;      // Sortie pour router le canal Master sur le bus FX1
const int MST_FX2=  13;      // Sortie pour router le canal Master sur le bus FX1

// Définition des variables :
int CH1_State = 0;         // Variable CH1
int CH2_State = 0;         // Variable CH2
int CH3_State = 0;         // Variable CH3
int CH4_State = 0;         // Variable CH4
int CH5_State = 0;         // Variable CH5
int CH6_State = 0;         // Variable CH6
int MST_State = 0;         // Variable CH7

void setup() {

  // Initialisation des boutons comme étant des entrées :
  pinMode(CH1, INPUT);
  pinMode(CH2, INPUT);
  pinMode(CH3, INPUT);
  pinMode(CH4, INPUT);
  pinMode(CH5, INPUT);
  pinMode(CH6, INPUT);
  pinMode(MST, INPUT);
  
  // Initialisation des sorties :
  pinMode(CH1_FX1, OUTPUT);
  pinMode(CH1_FX2, OUTPUT);

  pinMode(CH2_FX1, OUTPUT);
  pinMode(CH2_FX2, OUTPUT);

  pinMode(CH3_FX1, OUTPUT);
  pinMode(CH3_FX2, OUTPUT);

  pinMode(CH4_FX1, OUTPUT);
  pinMode(CH4_FX2, OUTPUT);

  pinMode(CH5_FX1, OUTPUT);
  pinMode(CH5_FX2, OUTPUT);

  pinMode(CH6_FX1, OUTPUT);
  pinMode(CH6_FX2, OUTPUT);

  pinMode(MST_FX1, OUTPUT);
  pinMode(MST_FX2, OUTPUT);
}

void loop() {
  // Lecture de l'état des entrées :
  CH1_State = digitalRead(CH1);
  CH2_State = digitalRead(CH2);
  CH3_State = digitalRead(CH3);
  CH4_State = digitalRead(CH4);
  CH5_State = digitalRead(CH5);
  CH6_State = digitalRead(CH6);
  MST_State = digitalRead(MST);

  if (CH2_State == LOW) {
    // Si le bouton n'est pas appuyé :
    digitalWrite(CH2_FX1, HIGH);
    digitalWrite(CH2_FX2, LOW);   
  } else {
    // Si le bouton est appuyé :
    digitalWrite(CH2_FX1, LOW);
    digitalWrite(CH2_FX2, HIGH);
  }
}

J'ai aussi regardé ton tutoriel sur les machines à état, mais je ne pense pas que cela s'applique à mes besoins.
Je continue à chercher sur internet comment "mémoriser l'état des entrées / sorties" (désolé pour ma terminologie) à savoir que le but recherché est :

Si A1 = 0V : CH1_FX1= 0 et CH1_FX2=0
Si A1 = 3.3V : CH1_FX1= 1 et CH1_FX2=0
Si A1 = 5V : CH1_FX1= 0 et CH1_FX2=1

Je pourrais soit utiliser un switch à levier à 3 positions, mais dans l'idéal j'aimerais que ce soit deux boutons poussoirs qui activent ou désactivent les sorties au besoin.

Le programme actuel est vraiment extrêmement basique, je m'en sert pour tester les entrées et sorties, je continue de chercher comment atteindre mon but.
A ce propos, est ce que c'est possible d'utiliser les sorties 0 et 1 ? (TX et RX) Parce que sur ma plaquette d'essai ça n'a pas l'air de fonctionner...

Merci énormément pour ton aide et passes une excellente journée !

Jérôme.

Tu veux discriminer 3 états différents 0, 3,3V et 5V. Donc il ne faut pas faire

mais plutôt
CH1_State = analoglRead(CH1);
et ensuite faire les tests sur trois fourchettes de valeurs.
Sur l'arduino la référence de tension de l'ADC est à 5V et le résultat de la conversion analogique numérique est compris entre 0 et 511 avec 0 pour 0V en entrée et 511 pour 5V en entrée.
Donc, pour tenir compte du bruit sur les signaux, des erreurs intrinsèques de l'ADC:
Si analogRead() retourne

  • une valeur < à 50 cela correspond à l'entrée à 0V.
  • une valeur comprise entre 300 et 350 cela correspond à l'entrée à 3,3V.
  • une valeur supérieure à 450 cela correspond à l'entrée à 5V.

En reprenant ta spécification

Le code donnerait

CH1_State = analogRead(CH1);
if (CH1_State < 50){
   CH1_FX1= 0;
  CH1_FX2=0;
} else if (CH1_State > 300 && CH1_State < 350){
   CH1_FX1= 1;
   CH1_FX2=0;
} else if (CH1_State > 450){
   CH1_FX1= 0;
   CH1_FX2=1;
}

Edit: mais pourquoi je suis parti sur un codage sur 9 bits???
5V = 1023.
Toutes les valeurs sont à multiplier par 2.

Salut Fdufnews et merci beaucoup pour les précieuses informations !

J'ai du faire quelque ajustements aux valeurs que tu m'a donné, mais tu m'a mis sur la voie et maintenant un de mes principaux problèmes est réglé !

Voici le code dans l'état actuel :

// Constantes d'entrées :
const int CH1 = A1;     // Bouton de contrôle du canal 1
const int CH2 = A2;     // Bouton de contrôle du canal 2
const int CH3 = A3;     // Bouton de contrôle du canal 3
const int CH4 = A4;     // Bouton de contrôle du canal 4
const int CH5 = A5;     // Bouton de contrôle du canal 5
const int CH6 = A6;     // Bouton de contrôle du canal 6
const int MST = A7;     // Bouton de contrôle du canal Master

// Constantes de sorties :
const int CH1_FX1=  0;      // Sortie pour router le canal 1 sur le bus FX1
const int CH1_FX2=  1;      // Sortie pour router le canal 1 sur le bus FX2

const int CH2_FX1=  2;      // Sortie pour router le canal 2 sur le bus FX1
const int CH2_FX2=  3;      // Sortie pour router le canal 2 sur le bus FX2

const int CH3_FX1=  4;      // Sortie pour router le canal 3 sur le bus FX1
const int CH3_FX2=  5;      // Sortie pour router le canal 3 sur le bus FX2

const int CH4_FX1=  6;      // Sortie pour router le canal 4 sur le bus FX1
const int CH4_FX2=  7;      // Sortie pour router le canal 4 sur le bus FX2

const int CH5_FX1=  8;      // Sortie pour router le canal 5 sur le bus FX1
const int CH5_FX2=  9;      // Sortie pour router le canal 5 sur le bus FX2

const int CH6_FX1=  10;      // Sortie pour router le canal 6 sur le bus FX1
const int CH6_FX2=  11;      // Sortie pour router le canal 6 sur le bus FX2

const int MST_FX1=  12;      // Sortie pour router le canal Master sur le bus FX1
const int MST_FX2=  13;      // Sortie pour router le canal Master sur le bus FX1

// Définition des variables :
int CH1_State = 0;         // Variable CH1
int CH2_State = 0;         // Variable CH2
int CH3_State = 0;         // Variable CH3
int CH4_State = 0;         // Variable CH4
int CH5_State = 0;         // Variable CH5
int CH6_State = 0;         // Variable CH6
int MST_State = 0;         // Variable CH7

int I0V = 587;
int I3VL = 637;
int I3VH = 737;
int I5VL = 973;
int I5VH = 1073;

void setup() {
  
  // Activation du port série afin de tester les entrées analogiques
  // Serial.begin(9600);
  
  // Initialisation des entrées :
  pinMode(CH1, INPUT);
  pinMode(CH2, INPUT);
  pinMode(CH3, INPUT);
  pinMode(CH4, INPUT);
  pinMode(CH5, INPUT);
  pinMode(CH6, INPUT);
  pinMode(MST, INPUT);
  
  // Initialisation des sorties :
  pinMode(CH1_FX1, OUTPUT);
  pinMode(CH1_FX2, OUTPUT);

  pinMode(CH2_FX1, OUTPUT);
  pinMode(CH2_FX2, OUTPUT);

  pinMode(CH3_FX1, OUTPUT);
  pinMode(CH3_FX2, OUTPUT);

  pinMode(CH4_FX1, OUTPUT);
  pinMode(CH4_FX2, OUTPUT);

  pinMode(CH5_FX1, OUTPUT);
  pinMode(CH5_FX2, OUTPUT);

  pinMode(CH6_FX1, OUTPUT);
  pinMode(CH6_FX2, OUTPUT);

  pinMode(MST_FX1, OUTPUT);
  pinMode(MST_FX2, OUTPUT);
}

void loop() {

  // Test de la lecture analogique du bouton :
  int sensorValue = analogRead(CH3);
  float voltage = sensorValue * (5.0 / 1023.0);
  float value = sensorValue;
  Serial.println(value);
  
  // Lecture de l'état des entrées :
  CH1_State = analogRead(CH1);
  CH2_State = analogRead(CH2);
  CH3_State = analogRead(CH3);
  CH4_State = analogRead(CH4);
  CH5_State = analogRead(CH5);
  CH6_State = analogRead(CH6);
  MST_State = analogRead(MST);

// Channel 1 :
  if (CH1_State < I0V)                           // Si l'entrée est à 0V :
  { digitalWrite(CH1_FX1, LOW);
    digitalWrite(CH1_FX2, LOW); }
  else if (CH1_State > I3VL && CH2_State < I3VH)   // Si l'entrée est à 3.3V :
  { digitalWrite(CH1_FX1, HIGH);
    digitalWrite(CH1_FX2, LOW); }
  else if (CH1_State > I5VL && CH2_State < I5VH) // Si l'entrée est à 5V :
  { digitalWrite(CH1_FX1, LOW);
    digitalWrite(CH1_FX2, HIGH);}

// Channel 2 :
  if (CH2_State < I0V)                           // Si l'entrée est à 0V :
  { digitalWrite(CH2_FX1, LOW);
    digitalWrite(CH2_FX2, LOW); }
  else if (CH2_State > I3VL && CH2_State < I3VH)   // Si l'entrée est à 3.3V :
  { digitalWrite(CH2_FX1, HIGH);
    digitalWrite(CH2_FX2, LOW); }
  else if (CH2_State > I5VL && CH2_State < I5VH) // Si l'entrée est à 5V :
  { digitalWrite(CH2_FX1, LOW);
    digitalWrite(CH2_FX2, HIGH);}

// Channel 3 :
  if (CH3_State < I0V)                           // Si l'entrée est à 0V :
  { digitalWrite(CH3_FX1, LOW);
    digitalWrite(CH3_FX2, LOW); }
  else if (CH3_State > I3VL && CH2_State < I3VH)   // Si l'entrée est à 3.3V :
  { digitalWrite(CH3_FX1, HIGH);
    digitalWrite(CH3_FX2, LOW); }
  else if (CH3_State > I5VL && CH2_State < I5VH) // Si l'entrée est à 5V :
  { digitalWrite(CH3_FX1, LOW);
    digitalWrite(CH3_FX2, HIGH);}

// Channel 4 :
  if (CH4_State < I0V)                           // Si l'entrée est à 0V :
  { digitalWrite(CH4_FX1, LOW);
    digitalWrite(CH4_FX2, LOW); }
  else if (CH4_State > I3VL && CH2_State < I3VH)   // Si l'entrée est à 3.3V :
  { digitalWrite(CH4_FX1, HIGH);
    digitalWrite(CH4_FX2, LOW); }
  else if (CH4_State > I5VL && CH2_State < I5VH) // Si l'entrée est à 5V :
  { digitalWrite(CH4_FX1, LOW);
    digitalWrite(CH4_FX2, HIGH);}

// Channel 5 :
  if (CH5_State < I0V)                           // Si l'entrée est à 0V :
  { digitalWrite(CH5_FX1, LOW);
    digitalWrite(CH5_FX2, LOW); }
  else if (CH5_State > I3VL && CH2_State < I3VH)   // Si l'entrée est à 3.3V :
  { digitalWrite(CH5_FX1, HIGH);
    digitalWrite(CH5_FX2, LOW); }
  else if (CH5_State > I5VL && CH2_State < I5VH) // Si l'entrée est à 5V :
  { digitalWrite(CH5_FX1, LOW);
    digitalWrite(CH5_FX2, HIGH);}

// Channel 6 :
  if (CH6_State < I0V)                           // Si l'entrée est à 0V :
  { digitalWrite(CH6_FX1, LOW);
    digitalWrite(CH6_FX2, LOW); }
  else if (CH6_State > I3VL && CH2_State < I3VH)   // Si l'entrée est à 3.3V :
  { digitalWrite(CH6_FX1, HIGH);
    digitalWrite(CH6_FX2, LOW); }
  else if (CH6_State > I5VL && CH2_State < I5VH) // Si l'entrée est à 5V :
  { digitalWrite(CH6_FX1, LOW);
    digitalWrite(CH6_FX2, HIGH);}

// Master :
  if (MST_State < I0V)                           // Si l'entrée est à 0V :
  { digitalWrite(MST_FX1, LOW);
    digitalWrite(MST_FX2, LOW); }
  else if (MST_State > I3VL && CH2_State < I3VH)   // Si l'entrée est à 3.3V :
  { digitalWrite(MST_FX1, HIGH);
    digitalWrite(MST_FX2, LOW); }
  else if (MST_State > I5VL && CH2_State < I5VH) // Si l'entrée est à 5V :
  { digitalWrite(MST_FX1, LOW);
    digitalWrite(MST_FX2, HIGH);}

// Marqueur de fin de programme
}

C'est certainement pas très impressionnant, mais c'est une avancée majeure pour moi !!

Il me reste à trouver comment faire pour que l'état soit mémorisé, à savoir par exemple :
Si A1 = 3.3V CH1_FX1 = ON (et reste à on)
Si A1 = 3.3V CH1_FX1 = OFF
SI A1 = 3.3V CH1_FX1 = ON (et reste à on)
SI A1 = 5V CH1_FX1 = OFF et CH1_FX2 = ON (et reste à on)
Ect...

Je pense avoir vu des tutos là dessus sur le net, je vais essayer de les retrouver et de comprendre comment les implanter dans le code qui est un peu plus compliqué que ce qu'avec quoi j'ai l'habitude de jouer.

Merci encore et bonne journée !!

Voici les progrès effectués, je ne sais pas si c'est la meilleure façon de faire, mais "ça marche à peu près".


// Constantes d'entrées :
const int CH1 = A1;       // Bouton de contrôle du canal 1
const int CH2 = A2;       // Bouton de contrôle du canal 2
const int CH3 = A3;       // Bouton de contrôle du canal 3
const int CH4 = A4;       // Bouton de contrôle du canal 4
const int CH5 = A5;       // Bouton de contrôle du canal 5
const int CH6 = A6;       // Bouton de contrôle du canal 6
const int MST = A7;       // Bouton de contrôle du canal Master

// Constantes de sorties :
const int CH1_FX1=  0;    // Sortie pour router le canal 1 sur le bus FX1
const int CH1_FX2=  1;    // Sortie pour router le canal 1 sur le bus FX2

const int CH2_FX1=  2;    // Sortie pour router le canal 2 sur le bus FX1
const int CH2_FX2=  3;    // Sortie pour router le canal 2 sur le bus FX2

const int CH3_FX1=  4;    // Sortie pour router le canal 3 sur le bus FX1
const int CH3_FX2=  5;    // Sortie pour router le canal 3 sur le bus FX2

const int CH4_FX1=  6;    // Sortie pour router le canal 4 sur le bus FX1
const int CH4_FX2=  7;    // Sortie pour router le canal 4 sur le bus FX2

const int CH5_FX1=  8;    // Sortie pour router le canal 5 sur le bus FX1
const int CH5_FX2=  9;    // Sortie pour router le canal 5 sur le bus FX2

const int CH6_FX1=  10;   // Sortie pour router le canal 6 sur le bus FX1
const int CH6_FX2=  11;   // Sortie pour router le canal 6 sur le bus FX2

const int MST_FX1=  12;   // Sortie pour router le canal Master sur le bus FX1
const int MST_FX2=  13;   // Sortie pour router le canal Master sur le bus FX1

// Définition des variables :
int CH1_State = 0;        // Variable CH1
int CH1_FX1_state = LOW;      // the current state of the output pin
int CH1_FX1_reading;           // the current reading from the input pin
int CH1_FX1_previous = HIGH;    // the previous reading from the input pin
int CH1_FX2_state = LOW;      // the current state of the output pin
int CH1_FX2_reading;           // the current reading from the input pin
int CH1_FX2_previous = HIGH;    // the previous reading from the input pin

int CH2_State = 0;        // Variable CH2
int CH2_FX1_state = LOW;      // the current state of the output pin
int CH2_FX1_reading;           // the current reading from the input pin
int CH2_FX1_previous = HIGH;    // the previous reading from the input pin
int CH2_FX2_state = LOW;      // the current state of the output pin
int CH2_FX2_reading;           // the current reading from the input pin
int CH2_FX2_previous = HIGH;    // the previous reading from the input pin

int CH3_State = 0;        // Variable CH3
int CH3_FX1_state = LOW;      // the current state of the output pin
int CH3_FX1_reading;           // the current reading from the input pin
int CH3_FX1_previous = HIGH;    // the previous reading from the input pin
int CH3_FX2_state = LOW;      // the current state of the output pin
int CH3_FX2_reading;           // the current reading from the input pin
int CH3_FX2_previous = HIGH;    // the previous reading from the input pin

int CH4_State = 0;        // Variable CH4
int CH4_FX1_state = LOW;      // the current state of the output pin
int CH4_FX1_reading;           // the current reading from the input pin
int CH4_FX1_previous = HIGH;    // the previous reading from the input pin
int CH4_FX2_state = LOW;      // the current state of the output pin
int CH4_FX2_reading;           // the current reading from the input pin
int CH4_FX2_previous = HIGH;    // the previous reading from the input pin

int CH5_State = 0;        // Variable CH5
int CH5_FX1_state = LOW;      // the current state of the output pin
int CH5_FX1_reading;           // the current reading from the input pin
int CH5_FX1_previous = HIGH;    // the previous reading from the input pin
int CH5_FX2_state = LOW;      // the current state of the output pin
int CH5_FX2_reading;           // the current reading from the input pin
int CH5_FX2_previous = HIGH;    // the previous reading from the input pin

int CH6_State = 0;        // Variable CH6
int CH6_FX1_state = LOW;      // the current state of the output pin
int CH6_FX1_reading;           // the current reading from the input pin
int CH6_FX1_previous = HIGH;    // the previous reading from the input pin
int CH6_FX2_state = LOW;      // the current state of the output pin
int CH6_FX2_reading;           // the current reading from the input pin
int CH6_FX2_previous = HIGH;    // the previous reading from the input pin

int MST_State = 0;        // Variable Master
int MST_FX1_state = LOW;      // the current state of the output pin
int MST_FX1_reading;           // the current reading from the input pin
int MST_FX1_previous = HIGH;    // the previous reading from the input pin
int MST_FX2_state = LOW;      // the current state of the output pin
int MST_FX2_reading;           // the current reading from the input pin
int MST_FX2_previous = HIGH;    // the previous reading from the input pin

// Réglage de la sensibilité des boutons :
int I0V = 587;            // Input 0V : Limite haute de l'information 0V
int I3VL = 637;           // Input 3V Low : limite basse de l'information 3.3V
int I3VH = 737;           // Input 3V High : limite haute de l'information 3.3V
int I5VL = 973;           // Input 5V Low : limite basse de l'information 5V
int I5VH = 1073;          // Input 5V High : limite haute de l'information 5V

long time = 0;         // the last time the output pin was toggled
long debounce = 200;   // the debounce time, increase if the output flickers

void setup() {
  
  // Activation du port série afin de tester les entrées analogiques
  // Serial.begin(9600);
  
  // Initialisation des entrées :
  pinMode(CH1, INPUT);
  pinMode(CH2, INPUT);
  pinMode(CH3, INPUT);
  pinMode(CH4, INPUT);
  pinMode(CH5, INPUT);
  pinMode(CH6, INPUT);
  pinMode(MST, INPUT);
  
  // Initialisation des sorties :
  pinMode(CH1_FX1, OUTPUT);
  pinMode(CH1_FX2, OUTPUT);

  pinMode(CH2_FX1, OUTPUT);
  pinMode(CH2_FX2, OUTPUT);

  pinMode(CH3_FX1, OUTPUT);
  pinMode(CH3_FX2, OUTPUT);

  pinMode(CH4_FX1, OUTPUT);
  pinMode(CH4_FX2, OUTPUT);

  pinMode(CH5_FX1, OUTPUT);
  pinMode(CH5_FX2, OUTPUT);

  pinMode(CH6_FX1, OUTPUT);
  pinMode(CH6_FX2, OUTPUT);

  pinMode(MST_FX1, OUTPUT);
  pinMode(MST_FX2, OUTPUT);
}

void loop() {

  // Test de la lecture analogique du bouton :
  int sensorValue = analogRead(CH3);
  float voltage = sensorValue * (5.0 / 1023.0);
  float value = sensorValue;
  Serial.println(value);
  
  // Lecture de l'état des entrées :
  CH1_State = analogRead(CH1);
  CH2_State = analogRead(CH2);
  CH3_State = analogRead(CH3);
  CH4_State = analogRead(CH4);
  CH5_State = analogRead(CH5);
  CH6_State = analogRead(CH6);
  MST_State = analogRead(MST);

// Channel 1 :
  if (CH1_State > I3VL && CH1_State < I3VH && CH1_FX1_previous == LOW && millis() - time > debounce) // Si l'entrée est à 3.3V ET que l'état précédent était à LOW ET que le temps anti rebond est passé :
 {if (CH1_FX1_state == HIGH)CH1_FX1_state = LOW;
  else CH1_FX1_state = HIGH;
  time = millis();}
 {digitalWrite(CH1_FX1, CH1_FX1_state);
  CH1_FX1_previous = CH1_FX1_reading;}

  if (CH1_State > I5VL && CH1_State < I5VH && CH1_FX1_previous == LOW && millis() - time > debounce) // Si l'entrée est à 5V :
 {if (CH1_FX2_state == HIGH)CH1_FX2_state = LOW;
  else CH1_FX2_state = HIGH; time = millis();}
 {digitalWrite(CH1_FX2, CH1_FX2_state);
  CH1_FX2_previous = CH1_FX2_reading;}

// Channel 2 :
  if (CH2_State > I3VL && CH2_State < I3VH && CH2_FX1_previous == LOW && millis() - time > debounce) // Si l'entrée est à 3.3V ET que l'état précédent était à LOW ET que le temps anti rebond est passé :
 {if (CH2_FX1_state == HIGH)CH2_FX1_state = LOW;
  else CH2_FX1_state = HIGH;
  time = millis();}
 {digitalWrite(CH2_FX1, CH2_FX1_state);
  CH2_FX1_previous = CH2_FX1_reading;}

  if (CH2_State > I5VL && CH2_State < I5VH && CH2_FX1_previous == LOW && millis() - time > debounce) // Si l'entrée est à 5V :
 {if (CH2_FX2_state == HIGH)CH2_FX2_state = LOW;
  else CH2_FX2_state = HIGH; time = millis();}
 {digitalWrite(CH2_FX2, CH2_FX2_state);
  CH2_FX2_previous = CH2_FX2_reading;}

// Channel 3 :
  if (CH3_State > I3VL && CH3_State < I3VH && CH3_FX1_previous == LOW && millis() - time > debounce) // Si l'entrée est à 3.3V :
 {if (CH3_FX1_state == HIGH)CH3_FX1_state = LOW;
  else CH3_FX1_state = HIGH;
  time = millis();}
 {digitalWrite(CH3_FX1, CH3_FX1_state);
  CH3_FX1_previous = CH3_FX1_reading;}

  if (CH3_State > I5VL && CH3_State < I5VH && CH3_FX1_previous == LOW && millis() - time > debounce) // Si l'entrée est à 5V :
 {if (CH3_FX2_state == HIGH)CH3_FX2_state = LOW;
  else CH3_FX2_state = HIGH; time = millis();}
 {digitalWrite(CH3_FX2, CH3_FX2_state);
  CH3_FX2_previous = CH3_FX2_reading;}

// Channel 4 :
  if (CH4_State > I3VL && CH4_State < I3VH && CH4_FX1_previous == LOW && millis() - time > debounce) // Si l'entrée est à 3.3V :
 {if (CH4_FX1_state == HIGH)CH4_FX1_state = LOW;
  else CH4_FX1_state = HIGH;
  time = millis();}
 {digitalWrite(CH4_FX1, CH4_FX1_state);
  CH4_FX1_previous = CH4_FX1_reading;}

  if (CH4_State > I5VL && CH4_State < I5VH && CH4_FX1_previous == LOW && millis() - time > debounce) // Si l'entrée est à 5V :
 {if (CH4_FX2_state == HIGH)CH4_FX2_state = LOW;
  else CH4_FX2_state = HIGH; time = millis();}
 {digitalWrite(CH4_FX2, CH4_FX2_state);
  CH4_FX2_previous = CH4_FX2_reading;}

// Channel 5 :
  if (CH5_State > I3VL && CH5_State < I3VH && CH5_FX1_previous == LOW && millis() - time > debounce) // Si l'entrée est à 3.3V :
 {if (CH5_FX1_state == HIGH)CH5_FX1_state = LOW;
  else CH5_FX1_state = HIGH;
  time = millis();}
 {digitalWrite(CH5_FX1, CH5_FX1_state);
  CH5_FX1_previous = CH5_FX1_reading;}

  if (CH5_State > I5VL && CH5_State < I5VH && CH5_FX1_previous == LOW && millis() - time > debounce) // Si l'entrée est à 5V :
 {if (CH5_FX2_state == HIGH)CH5_FX2_state = LOW;
  else CH5_FX2_state = HIGH; time = millis();}
 {digitalWrite(CH5_FX2, CH5_FX2_state);
  CH5_FX2_previous = CH5_FX2_reading;}

// Channel 6 :
  if (CH6_State > I3VL && CH6_State < I3VH && CH6_FX1_previous == LOW && millis() - time > debounce) // Si l'entrée est à 3.3V :
 {if (CH6_FX1_state == HIGH)CH6_FX1_state = LOW;
  else CH6_FX1_state = HIGH;
  time = millis();}
 {digitalWrite(CH6_FX1, CH6_FX1_state);
  CH6_FX1_previous = CH6_FX1_reading;}

  if (CH6_State > I5VL && CH6_State < I5VH && CH6_FX1_previous == LOW && millis() - time > debounce) // Si l'entrée est à 5V :
 {if (CH6_FX2_state == HIGH)CH6_FX2_state = LOW;
  else CH6_FX2_state = HIGH; time = millis();}
 {digitalWrite(CH6_FX2, CH6_FX2_state);
  CH6_FX2_previous = CH6_FX2_reading;}

// Master :
  if (MST_State > I3VL && MST_State < I3VH && MST_FX1_previous == LOW && millis() - time > debounce) // Si l'entrée est à 3.3V :
 {if (MST_FX1_state == HIGH)MST_FX1_state = LOW;
  else MST_FX1_state = HIGH;
  time = millis();}
 {digitalWrite(MST_FX1, MST_FX1_state);
  MST_FX1_previous = MST_FX1_reading;}

  if (MST_State > I5VL && MST_State < I5VH && MST_FX1_previous == LOW && millis() - time > debounce) // Si l'entrée est à 5V :
 {if (MST_FX2_state == HIGH)MST_FX2_state = LOW;
  else MST_FX2_state = HIGH; time = millis();}
 {digitalWrite(MST_FX2, MST_FX2_state);
  MST_FX2_previous = MST_FX2_reading;}


// Marqueur de fin de programme
}

Est ce que vous pourriez me dire comment je devrais m'y prendre pour que quand par exemple FX1 est activé et que j'active FX2, FX1 soit coupé, et vice versa ?

J'ai gratté un peu partout toute la soirée, sans trouver d'information probante.

Merci d'avance !

Jérôme.

Exactement comme vous le dites en français. Lors de la détection de l’activation de FX2 vous devrez tester l’état courant et prendre les décisions nécessaires avant d’activer le nouveau mode. Et bien sûr mémoriser le nouveau état courant.

Si vous lisez mon tuto sur les machines à états vous verrez ce qu’on appelle un type enuméré enum, vous pouvez vous en servir pour mémoriser l’état courant

Bonjour Jérôme
Cà fais un "bail"
Toujours à survoler "la belle province" ? :helicopter:

Comme conseillé par @J-M-L et @fdufnews
Je t'incite à prendre un peu de temps pour te familiariser avec la technique des machines à états, une fois assimilé, tu gagneras énormément de temps en codage.

et utilisez une structure et un tableau quand vous commencez à numéroter les variables...

par exemple

// Réglage de la sensibilité des boutons :
const int I0V  = 587;           // Input 0V      : Limite haute de l'information 0V
const int I3VL = 637;           // Input 3V Low  : limite basse de l'information 3.3V
const int I3VH = 737;           // Input 3V High : limite haute de l'information 3.3V
const int I5VL = 973;           // Input 5V Low  : limite basse de l'information 5V
const int I5VH = 1073;          // Input 5V High : limite haute de l'information 5V

struct t_route {
  const byte  channelPin;
  const byte  busFX1Pin;
  const byte  busFX2Pin;
  bool        auRepos;
} routes[] {
  {A1,  0,  1, true},
  {A2,  2,  3, true},
  {A3,  4,  5, true},
  {A4,  6,  7, true},
  {A5,  8,  9, true},
  {A6, 10, 11, true},
  {A7, 12, 13, true},
};
const byte nbRoutes = sizeof routes / sizeof routes[0];

void activateFX1(
void setup() {
  for (byte i = 0; i < nbRoutes; i++) {
    pinMode(routes[i].channelPin, INPUT);
    pinMode(routes[i].busFX1Pin,  OUTPUT);
    pinMode(routes[i].busFX2Pin,  OUTPUT);
    routes[i].auRepos = analogRead(routes[i].channelPin) < I0V;
  }
}

void loop() {
  for (byte i = 0; i < nbRoutes; i++) {
    byte etat = analogRead(routes[i].channelPin));
    ...

  }

}

sinon pour simplifier votre gestion des boutons, éventuellement utilisez la librairie de @bricoleau ou alors la librairie OneButton de Matthias Hertel.

Bonjour à tous les deux et merci pour les suggestions. J'ai regardé la librairie de Bricoleau, mais je ne suis pas certain que je puisse l'utiliser étant donné que mes entrées sont en "analogRead" pour différencier la lecture du 3.3V ou 5V.

Je vais re regarder le tuto sur la machine à état, c'était le premier tuto que j'ai regardé à l'origine, mais je ne pensais pas qu'il s'appliquerait à mes besoin.

Je vais également tâcher de comprendre comment me servir des tableaux, ce n'est pas la première fois que je vois ça, mais j'avoue que c'est un peu obscur pour moi encore pour le moment.

Artouste, en effet ça fait un bail ! Je vole encore un peu même si la pandémie à fait mal. Je vais t'envoyer un petit mail prochainement pour te donner quelques nouvelles.

Je vous reviens bientôt avec mes progrès (j'espère :stuck_out_tongue: )

Bonne journée !

Oui effectivement ce n’est pas fait pour. J’avais oublié ce point

Bonjour Jérôme

tu veux soit utiliser du switch à 3 position 2 position à contact

  • avec retour auto au centre ? = contact momentané
  • pas de retour auto au centre ? = contact maintenu

ou mieux pour toi 2 simple BP NO, c'est çà ?

Salut Artouste, exactement, des boutons poussoir momentanés avec un Led intégrée.

la led des bp s'alimente comment ? lien vers les bp/led ?
pour que l'on soit bien d'accord :
là ton projet consiste à mettre dans un 1U

  • 1 nano
  • 14 BP
  • 28 relay 2R/T

Salut Artouste, les leds des BPs iraient sur les connecteurs visible au centre du montage sur le premier screenshot (J12).

Ca permet d'avoir une LED qui indique FX1 et l'autre qui indique FX2. Sachant que FX2 doit commuter les 4 relais par tranche.

Pour ce qui est du reste, tu as vu pas mal juste en effet. C'est pas mal de relais pilotés par un Nano.

en fait pour 1 tranche tu a 3 options de config et tu veux l'organisation suivante :

au reset RAZ aucun relais n'est activé c'est la config 0

si tu appui sur le BP FX1 tu passe en config 1
si tu appui sur le BP FX2 tu passe en config 2
si tu appui une seconde fois sur le BP FX actif tu reviens en config0

Bonjour à tous, j'espère que vous allez bien !

J'ai pas mal progressé dans le programme que j'essaye de mettre en place, voici un petit résumé du fonctionnement car le code est "gros et pas optimisé" (je débute) :

Quand j'appuie sur le bouton poussoir, l'entrée analogique lit une tension qu'elle converti en variable "bf1" allant de 0 à 7, 0 étant le GND et 7 le +5V.
Dépendamment de la tension lue, on va dire que BF1 = 1.
Tant que le bouton poussoir est enfoncé, BF1 = 1 et lorsqu'il est relâché, BF1 = 0

Ensuite, j'ai une autre variable F1 qui est pilotée comme suit :

// Modification de la valeur de FX1 en fonction du bouton poussoir qui est appuyé et de l'état précédent de FX1 :
//Si BP FX1 = X, alors FX1 = X Si BP FX1 = X ET que l'état précédent était à X, alors FX1 = 0
if (bf1 == 1)  {f1 = 1;}      if (bf1 == 1  &&         f1_prec == 1)             {f1 = 0;}
if (bf1 == 2)  {f1 = 2;}      if (bf1 == 2  &&         f1_prec == 2)             {f1 = 0;}
if (bf1 == 3)  {f1 = 3;}      if (bf1 == 3  &&         f1_prec == 3)             {f1 = 0;}
if (bf1 == 4)  {f1 = 4;}      if (bf1 == 4  &&         f1_prec == 4)             {f1 = 0;}
if (bf1 == 5)  {f1 = 5;}      if (bf1 == 5  &&         f1_prec == 5)             {f1 = 0;}
if (bf1 == 6)  {f1 = 6;}      if (bf1 == 6  &&         f1_prec == 6)             {f1 = 0;}
if (bf1 == 7)  {f1 = 7;}      if (bf1 == 7  &&         f1_prec == 7)             {f1 = 0;}

ça me permet de "toggle" un état de FX1 allant de 1 à 7, ce qui correspond à la tranche audio à laquelle je veux assigner le bus d'effet FX1.

Le problème, c'est que quand j'appuie sur le bouton et que BF1 = 3 par exemple, F1 passe de 0 à 3 à 0 à 3 en boucle super rapidement.

La solution, ça serait que je puisse avoir un résultat qui dirait :
"Si le front montant de BF1 == 3, alors BF1 = 3. Si le front montant de BF1 == 3 et que l'état précédent de F1 == 3, alors F1 = 0"

J'ai trouvé sur internet des solution pour capter le front montant d'un bouton poussoir, mais je n'ai pas été en mesure de l'appliquer à une variable.

Si vous avez une solution "à mon niveau" à me proposer, je suis très intéressé.
Encore une fois, je débute, et pour vos donner un ordre d'idée, j'en suis à un stade ou je dois "dessiner" le programme sur une feuille, le traduire en phrases dans le logiciel de programmation et enfin le traduire en code en dessous du "modèle" en français.

En espérant avoir été assez explicite, je vous remercie d'avance pour vos suggestions et vous souhaite une excellente journée !

Jérôme.

Moi l'électronicien j'ai partagé un bureau avec un chef de groupe de programmeurs : les professionnels ne travaillent pas autrement. Avant de coder ils analysent le sujet et écrivent des documents de plusieurs dizaines de pages.

Tu as pris la bonne méthode, le codage sans analyse préalable peut mener dans une impasse.

1 Like

Bonjour à tous, j'espère que vous allez bien.

Est ce que quelqu'un parmi vous a une suggestion pour détecter le front montant d'une variable ?

Voici une image concrète de mon problème :


Ce sont les allés retours entre 0 et 1 de la variable F1 que j'aimerais corriger.

Voici le code :

// Constantes d'entrées :
const int IN1 = A5;     // Défini IN1 comme entrée

// Définition des variables :
//  FX1
int val_IN1 = 0;    // Valeur de l'entrée analogique allant de 0 à 1023
int bf1 = 0;        // Valeur du bouton poussoir en fonction de la valeur de l'entrée analogique
int f1 = 0;         // état des FX1, 2 et 3 en fonction des boutons poussoirs
int f1_prec = 0;    // état précédent des bus FX pour les ramener à 0 en cas d'activation d'un bus déjà activé

long time = 0;      // the last time the output pin was toggled
long debounce = 200;// the debounce time, increase if the output flickers

void setup()
{
Serial.begin(9600);
pinMode(IN1, INPUT);
}

void loop()
{
// Test du programme :
int sensorValue = analogRead(IN1);
float volt = sensorValue * (5.0 / 1023.0);
float val = sensorValue;
Serial.println(f1);

// Lecture de l'état des entrées :
val_IN1 = analogRead(IN1); // La valeur de IN1 dépend de la lecture analogique de IN1


// Valeur du bouton poussoir de FX1 en fonction de la valeur de la tension lue sur IN1 :
if (val_IN1 > 950                  && millis() - time > debounce) {bf1 = 1;}
if (val_IN1 > 750 && val_IN1 < 850 && millis() - time > debounce) {bf1 = 2;}
if (val_IN1 > 570 && val_IN1 < 670 && millis() - time > debounce) {bf1 = 3;}
if (val_IN1 > 430 && val_IN1 < 530 && millis() - time > debounce) {bf1 = 4;}
if (val_IN1 > 310 && val_IN1 < 410 && millis() - time > debounce) {bf1 = 5;}
if (val_IN1 > 200 && val_IN1 < 300 && millis() - time > debounce) {bf1 = 6;}
if (val_IN1 > 80  && val_IN1 < 180 && millis() - time > debounce) {bf1 = 7;}
if (val_IN1 < 50                   && millis() - time > debounce) {bf1 = 0;}

// Modification de la valeur de FX1 en fonction du boutton poussoir qui est appuyé et de l'état précédent de FX1 (toggle mode):
//Si BP FX1 = X,alors FX1 = X Si BP FX1 = X ET que l'état précédent était à X, alors FX1 = 0
if (bf1 == 1)  {f1 = 1;}      if (bf1 == 1  &&         f1_prec == 1)             {f1 = 0;}
if (bf1 == 2)  {f1 = 2;}      if (bf1 == 2  &&         f1_prec == 2)             {f1 = 0;}
if (bf1 == 3)  {f1 = 3;}      if (bf1 == 3  &&         f1_prec == 3)             {f1 = 0;}
if (bf1 == 4)  {f1 = 4;}      if (bf1 == 4  &&         f1_prec == 4)             {f1 = 0;}
if (bf1 == 5)  {f1 = 5;}      if (bf1 == 5  &&         f1_prec == 5)             {f1 = 0;}
if (bf1 == 6)  {f1 = 6;}      if (bf1 == 6  &&         f1_prec == 6)             {f1 = 0;}
if (bf1 == 7)  {f1 = 7;}      if (bf1 == 7  &&         f1_prec == 7)             {f1 = 0;}

if (f1 == 0){f1_prec = 0;}
if (f1 == 1){f1_prec = 1;}
if (f1 == 2){f1_prec = 2;}
if (f1 == 3){f1_prec = 3;}
if (f1 == 4){f1_prec = 4;}
if (f1 == 5){f1_prec = 5;}
if (f1 == 6){f1_prec = 6;}
if (f1 == 7){f1_prec = 7;}
}

Merci à tous pour vos suggestions et bonne journée,

Jérôme.