Problème de code pour un projet avec capteur de son

Bonjour à tous !

Je travaille sur un projet utilisant un capteur de son, un arduino, une source sonore et un moteur.
Mon but est qu’en fonction du bruit ambiant, le capteur sonore ordonne soit un moteur, soit la source sonore ( en l’occurrence, le système à l’intérieur des poupées qui pleurent branché à l’arduino).

De la manière suivante : Il ne se passe rien, je frappe dans mes mains, le son s’active 20 secondes puis s’arrête. A son arrêt, un moteur tourne pendant deux secondes puis s’arrête.

J’ai tester d’abord le capteur avec la source sonore seule et le code fonctionne, utilisant les commande “if” et “else” (ci-joint un screen du code).
Je frappe, la source sonore s’active 20 secondes puis s’arrête.

De même avec le moteur seul. (2ème screen)
Je frappe, la moteur s’active 2 secondes puis s’arrête.

Mais lorsque j’essais de mixer les deux codes (3ème screen), ça ne marche pas.
Le moteur tourne s’en s’arrêter, et le capteur de son ne reconnait pas le son de mes mains qui frappent.

Sauriez-vous me dire ce qui cloche dans mon code ?

par avance merci

Tu parles de trois codes on en voit qu'un. En plus les images ne sont pas toujours bien lisibles pour les personnes qui suivent le forum sur des terminaux mobiles.
Merci de mettre le code entre balise code comme expliqué ici.
Dans ton explication il y a 3 cas:

  • il ne se passe rien
  • on frappe dans les mains la poupée pleure 20s
  • le moteur tourne 2s
    Dans le code que tu donnes, tu ne traites que 2 cas exclusifs l'un de l'autre:
  • on frappe dans les mains la poupée pleure 20s
  • le moteur tourne 2s
    ce qui fait que si tu ne frappes pas dans les mains, le moteur tourne.
    Ce que tu voudrais faire se prête bien à la programmation par machine à états

Merci pour ta réponse ! Je vais regarder ce tuto de machine à état.

En attendant voici les codes

code moteur/capteur son :

const int motor=12;
const int arret=9;

void setup() {
 //Configuration du Canal A
 pinMode(12, OUTPUT); // Broche Arduino réservée pour le sens de rotation du moteur A
 pinMode(9, OUTPUT); // Broche Arduino réservée pour le freinage du moteur A

}

void loop(){
 digitalWrite(12, LOW); // Le moteur A tourne dans le sens normal
 digitalWrite(9, HIGH); // Désactivation du frein moteur A
 analogWrite(3, 255); // Vitesse maximale pour le moteur A
delay (2000); // Attente de 5 secondes
 
 digitalWrite(9, LOW); // Activation du freinage du moteur A 
 delay (1000); // Attente de 5 secondes
 
}

code son bébé/capteur son :

const int babycry=13; 
const int soundpin=A2;
const int threshold=26; // sets threshold for sound sensor

void setup () {
Serial.begin(9600);
pinMode(babycry, OUTPUT);
pinMode(soundpin, INPUT);
}

void loop () {
  int soundsens=analogRead(soundpin); //read analog data from sensor
  if (soundsens>=threshold) {
    digitalWrite(babycry, HIGH); // turns babycry on
    delay(20000);
  }
  else{
    digitalWrite(babycry, LOW);
  }
}

Code final :

const int babycry=13;  // led pin and sound pin are not changed throughout the process
const int soundpin=A2;
const int threshold=150;// sets threshold for sound sensor
const int motor=12;
const int arret=9;


void setup () {
  Serial.begin(9600);
pinMode(babycry, OUTPUT);
pinMode(soundpin, INPUT);
pinMode(motor, OUTPUT); // Broche Arduino réservée pour le sens de rotation du moteur A
pinMode(arret, OUTPUT); // Broche Arduino réservée pour le freinage du moteur A

}
void loop () {
  int soundsens=analogRead(soundpin); //read analog data from sensor
  
  if (soundsens>=threshold) {
    digitalWrite(babycry, HIGH); // turns led on
    delay(20000);
    digitalWrite(arret, LOW); // Activation du freinage du moteur A 

  }

  else {
 digitalWrite(babycry, LOW);
 digitalWrite(motor, LOW); // Le moteur A tourne dans le sens normal
 digitalWrite(arret, HIGH); // Désactivation du frein moteur A
 analogWrite(3, 255); // Vitesse maximale pour le moteur A
  delay (2000); // Attente de 5 secondes
  }
}

Si je comprend bien, je dois donner à mon code trois états plutôt que deux ?

par exemple en utilisant if , else if et else ?

Bonjour

D'après ce que je comprends je ne vous pas de machine a état mais une succession d'action (comme un automate du XIXe siècle)

Je mettrais schématiquement (c'est compliqué a taper sur un téléphone) :

Dans loop :

  1. mesure du capteur

  2. si la valeur est supérieure a une limite
    2.1) déclanchement du cri
    2.2) arrêt du cri
    2.3) déclanchement du moteur
    2.4) arrêt du moteur

Il n'y aurait qu'une seule boucle if, en 2), et pas de else, comparé au code final du message précédent

Je serais curieuse d'avoir plus d'informations sur les parties du montage (détecteur, moteur, automate)

Bonjours, désolé de ne pas avoir pu répondre plus tôt. Je peux à nouveau me concentrer sur ce projet.

Je pense qu'il serais utile de vous l'expliquer puisqu'il est amener à se complexifier d'avantage.

Dans une pièce j'ai : mon arduino auquel serait relié un motorshield (deux sortie moteur) un capteur de son et un capteur de mouvement et un light dimmer.
Ce système de commande est relié deux moteurs 12V alimentés, une source sonore ( Le système de la poupée qui pleure), une autre source sonore (une berceuse disons) et une ampoule.

Ce que je souhaite mettre en place se déroule ainsi :

Etat n°1

Le 1er moteur tourne 5 secondes et s'arrête
Le 2eme moteur tourne en continu
La lumière de l'ampoule est tamisée
La berceuse joue
Le pleure de bébé est eteint.

1ère réaction : L'ambiance sonore est trop forte, le capteur de son réagit. On passe de l'état 1 à l'état 2

Etat n°2

Le 1er moteur est arrêté (ou s'arrête si le capteur sonore réagit avant qu'il ai terminé ses 5 secondes de rotations)
Le 2eme moteur s'arrête
La lumière de l'ampoule est forte
La berceuse s'arrête
Le pleure de bébé s'allume.

2ème réaction : Le capteur de mouvement réagit à un mouvement. On passe de l'état 2 à l'état 1 (avec juste la lumière de l'ampoule qui se tamise doucement grâce au light dimmer).

Les problèmes que je rencontre en essayant differents code peuvent être des érreurs de language (que j'essais de comprendre petit à petit) mais peut être aussi de mes cablages qui peuvent être incohérent sans que je le sache... Jusque la, lorsque j'essais le code de chaque pour chaque capteur/shield pour une action simple, ca fonctionne. Mais dés que j'essai de les adapter dans un seul avec les commandes If,Else If et/ou Else, ca se complique.

Je mettrais des interruptions sur les capteurs, faisant varier un paramètre "état". Ça me parait simplifier l'écriture du code et le rendre plus réactif a un changement. Et je découperais la fonction loop en fonctions pour chaque système (moteur, lumière, musique)

De manière schematique et tapé sur mon téléphone, j'écrirais :

void loop (
motor1(etat);
motor2(etat);
light(etat);
Music(etat);
)

Et des fonctions pour chaque système du type :

void motor2(etat)(
If (etat)
Motor on
Else
Motor off
)

Les fonctions pour le moteur 1 et la lumière seront sans doute un peu plus compliquée (enregistrement de la date du début de rotation du moteur 1, du taux de modulation de la Led ...) Mais devraient rester assez compréhensibles.

Il faut vérifier que les fonctions utilisées ne sont pas blocantes Et regarder si elles réagissent a un état précis ou un changement d'état. Par exemple, il suffit de lancer une fois la musique de berceuse pour qu'elle se joue en boucle, pas besoin de le faire a chaque passage dans la boucle

Merci Fantoche ! oui j’ai commencé à travailler en séparant le void. Là pour l’instant, je me concentre sur le code pour un moteur, un sound sensor ( où j’utilise la fonction milli pour pourvoir le rendre plus précis) et un PIR sensor. Mon seul soucis est que je n’arrive pas à arrêter complètement le moteur lorsque le son ambiant dépasse la valeur que je lui indique, pour pouvoir ensuite le relancer avec le mouvement détecté. Il ne s’arrête que durant un dixième de seconde, ce qui est logique vu le code que je lui implante. Comment pourrais-je lui indiquer de s’arrêter complètement, et dans l’idéal sans lui mettre un delay d’arrêt, juste lui indiquer que la détection d’un mouvement fait repartir le moteur ?

En pièce jointe le montage.

voici le code :

const int MotorPinA = 12; // for motor A
const int MotorSpeedPinA = 3; // for motor A
const int MotorBrakePinA = 9; // for motor A


const int soundpin = 7;
const int SAMPLE_TIME = 10;
unsigned long millisCurrent;
unsigned long millisLast = 0;
unsigned long millisElapsed = 0;
int sampleBufferValue = 0;

int inputPin = 4;               // choose the input pin (for PIR sensor)
int pirState = LOW;             // we start, assuming no motion detected
int val = 0;                    // variable for reading the pin status


void setup() 
{
  Serial.begin(9600);           //  seial monitor initialized 
  pinMode (soundpin, INPUT);
  pinMode(inputPin, INPUT);     // declare sensor as input
  
  pinMode(MotorPinA, OUTPUT);
  pinMode(MotorSpeedPinA, OUTPUT);
  pinMode(MotorBrakePinA, OUTPUT);
}

void loop() {

motorgo();
motorstop();

}

void motorgo () {

  val = digitalRead(inputPin);  // read input value

  if (val = HIGH) {  
        
    digitalWrite(MotorPinA, HIGH);    // set direction
    analogWrite(MotorSpeedPinA, 200); // set speed at maximum
    digitalWrite(MotorBrakePinA,LOW); // release brake 

           if (pirState == HIGH)
  {
 
      Serial.println("Motion ended!");  // print on output change
      pirState = LOW;
    }

  }   
}

void motorstop () {


    millisCurrent = millis();
    millisElapsed = millisCurrent - millisLast;
    
    if (digitalRead(soundpin) == LOW) {
    sampleBufferValue++;
    }
  
    if (millisElapsed > SAMPLE_TIME) {
    Serial.println(sampleBufferValue);
    sampleBufferValue = 0;
    millisLast = millisCurrent;
    }
  
    if (sampleBufferValue >= 30) {
    digitalWrite(MotorBrakePinA,HIGH);//  brake

    
    }
      if (pirState == HIGH)
  {
 
      Serial.println("Motion ended!");  // print on output change
      pirState = LOW;
    }
  
   
}

Mhh je crois qu’il y a pas mal d’erreur dans le gestion des millis et des changements d’états (notamment PIRState, dont l’état n’a pas l’air mis a jour).

Il existe quelques règles (que l’on est libre d’appliquer ou non) pour la programmation qui facilitent la lecture des codes : les noms des constantes en majuscules, les variables commencent par une minuscule, les noms les plus explicites possibles (éviter val)… Je te conseille de jeter un coup d’oeil au PEP20 de python ou à ce site.

Dans un premier temps, pour modéliser le PIR et le son, je te conseille d’utiliser des composants simples :

  • des interrupteurs ON-OFF (ou des interrupteurs monostables avec un système de bascule, ou d’utiliser arduino pour changer l’état - comme les exemples pour allumer ou éteindre une LED par pression sur un interrupteur). En cas de besoin, compense les rebonds par le programme Arduino ou par un filtre physique passe bas (circuit RC).
  • des potentiomètres. C’est peut-être plus simple à utiliser pour simuler un volume sonore notamment.
    Et puis si tu ne l’as jamais fait, tu peux aussi, regarder à quoi ressemble le signal de sortie de tes capteurs avec le traceur serie de l’IDE. Le PIR peut être un peu surprenant.

Voici ma proposition. J’ai supposé que les commandes du moteur étaient justes. J’ai supposé que les deux entrées son et PIR donnaient directement des signaux numériques (son fort = 5V, mouvement = 5V)

const int MotorPinA = 12; // for motor A
const int MotorSpeedPinA = 3; // for motor A
const int MotorBrakePinA = 9; // for motor A

const int soundpin = 7;     // micro, supposé binairec
const int inputPin = 4;               // PIR, supposé binaire

// les variables que j'ai ajoutées

unsigned long motor1_starting_date = millis(); //date ou demarre le moteur 1
unsigned long running_motor1_duration = 5000; //duree pendant laquelle le moteur 1 tourne
bool state = true; // etat 1 (true) ou 2 (false) du montage
bool motor1State = false; // si le moteur 1 tourne (true) ou pas (false)
  // demarre dès le premier passage par loop



// les variables qui ne me sont pas utiles

// int pirState = LOW;             // we start, assuming no motion detected
// int val = 0;                    // variable for reading the pin status
//const int SAMPLE_TIME = 10; // ??? pas compris
//unsigned long millisCurrent; // toujours millis()
//unsigned long millisLast = 0; // remplacé par motor1_starting_date
//unsigned long millisElapsed = 0; // millis() - millisLast
//int sampleBufferValue = 0; // pas compris



void setup()
{
  Serial.begin(9600);           //  seial monitor initialized
  pinMode (soundpin, INPUT);
  pinMode(inputPin, INPUT);     // declare sensor as input

  pinMode(MotorPinA, OUTPUT);
  pinMode(MotorSpeedPinA, OUTPUT);
  pinMode(MotorBrakePinA, OUTPUT);
}



void loop() {

  // MODIFICATION DE L'ETAT SI NECESSAIRE

  if ( (state) && digitalRead(soundpin)) { // etat 1 & son fort
    /* 1ère réaction : L'ambiance sonore est trop forte,
      le capteur de son réagit.
      On passe de l'état 1 à l'état 2
    */
    state = false; // passage a l'état 2
  }
  else if ((!state) && digitalRead(inputPin)) { // etat 2 et mouvement
    /*2ème réaction : Le capteur de mouvement réagit à un mouvement.
       On passe de l'état 2 à l'état 1
       (avec juste la lumière de l'ampoule
       qui se tamise doucement grâce au light dimmer).
    */
    state = true; // passage a l'état 1
  }

  // ACTION SUR LE MOTEUR
  motor1(); // demarrage et arret du moteur 1

} // loop



void motor1() {
  /* gère les arrets et demarrage du moteur 1

  */
  if (state && !(motor1State)) {
    // declanchement de l'etat 1
    // lancement du moteur qui est à l'arret
    digitalWrite(MotorPinA, HIGH);    // set direction // <--- A faire dans le setup ?
    analogWrite(MotorSpeedPinA, 200); // set speed at maximum // <--- dans le setup ?
    digitalWrite(MotorBrakePinA, LOW); // release brake, demarrage
    motor1State = true; // le moteur 1 tourne
    motor1_starting_date = millis(); // enregistre la date de demarrage du moteur
    Serial.println("Demarrage du moteur 1 après un changement d'état");
  }
  
  else if (state && motor1State) {
    // pendant l'état 1, le moteur est lancé
    // arret du moteur après X s
    if (millis() - motor1_starting_date > running_motor1_duration) {
      digitalWrite(MotorBrakePinA, HIGH); // arret du moteur
      motor1State = false; // le moteur ne tourne plus
      Serial.println("Arret du moteur 1 après 5s");
    }
  }
  
  else if (!state && motor1State) {
    // déclanchement de l'état 2
    // arret du moteur 1 s'il tourne
    digitalWrite(MotorBrakePinA, HIGH); //  brake
    motor1State = false; // le moteur ne tourne plus
    Serial.println("Arret du moteur 1 après un changement d'état");
  }
} // motor1

Again : merci beaucoup Fantoche !

Ton code marche nickel
j'admet que suis encore étranger à pas mal de déclarations comme "bool" "true" "false"... Tout ca est encore un peu abstrait pour moi, je vais faire en sorte de le déchiffrer pour pouvoir l'adapter si besoin.

J'avais introduit au code les lignes

unsigned long millisCurrent;
unsigned long millisLast = 0;
unsigned long millisElapsed = 0;
int sampleBufferValue = 0;

tirées de ce tutorial (SOUND SENSOR DATA ON ARDUINO SERIAL PLOTTER - Arduino tutorial #30 - YouTube) pour pouvoir avoir une lecture plus développer de mon sound sensor.

Ah, je viens de comprendre le "Else if" que tu as introduit pour dire au moteur de s'arrêter après 5 secondes, et il semblerait que ca ne fonctionne pas. L'arret est bien notifié dans le moniteur, mais il redémarre direct. Je pensais que le code correspondait au moteur qui tourne sans arret (which is great puisque j'ai un moteur dans ce cas là).

C'est bon, j'ai rajouté un "else if" dans le void loop et ça marche :

void loop() {

  // MODIFICATION DE L'ETAT SI NECESSAIRE

  if ( (state) && digitalRead(soundpin)) { // etat 1 & son fort
    /* 1ère réaction : L'ambiance sonore est trop forte,
      le capteur de son réagit.
      On passe de l'état 1 à l'état 2
    */
    state = false; // passage a l'état 2
  }

  else if ( (state) && (millis() - motor1_starting_date >= running_motor1_duration)) {

   state = false; // passage a l'état 2
  }
  
  else if ((!state) && digitalRead(inputPin)) { // etat 2 et mouvement
    /*2ème réaction : Le capteur de mouvement réagit à un mouvement.
       On passe de l'état 2 à l'état 1
       (avec juste la lumière de l'ampoule
       qui se tamise doucement grâce au light dimmer).
    */
    state = true; // passage a l'état 1
  }

  // ACTION SUR LE MOTEUR
  motor1(); // demarrage et arret du moteur 1

} // loop

Ahh oui je vois c'est ma faute. Mon motor1State n'est pas très malin. Quand le moteur a fini de tourner, motor1State passe a false, ce qui redéclanche le début du mode 1, Il ne faut donc pas indiquer si le moteur tourne mais aussi s'il a fini de tourner.

  • Une énumération serait sans doute mieux qu'un bool.
  • Ou une seconde variable bool indiquant si le moteur a déjà tourné.
  • un trigger par changement d'état

Je ne mettrais pas la gestion du chronométre du moteur 1 dans la gestion des états car les états serviront pour toutes les fonctions berceuse, moteur 2, lumière. Et puis ça permet de dissocier clairement les entrées et les sorties, c'est plus simple pour les tests, pour rajouter d'autres elements sonores/mobiles/lumineux.

Pour avoir un contrôle plus fin du capteur de son, c'est mieux de rajouter une partie dans la gestion des états uniquement (en utilisant éventuellement des fonctions pour que ce soit plus lisible)

EDIT : je viens de voir la video pour le micro. Il s'agit en fait juste de mesurer une valeur moyenne après avoir rendu un signal binaire et de façon non bloquante (sans utiliser les delays). Il existe de nombreuses autres façons de faire ça. Certaines seront plus simples, ou plus adaptées

  • tu peux mesurer le valeur du capteur sur une "courte" durée avec un code bloquant, et calculer la moyenne. L'idée c'est que la durée pendant laquelle tu mesures est suffisamment représentative des sons que tu recherches (evolution brusque ou lente du niveau sonore). Je pense que tes variations sonores et tes mouvements peuvent être très lent à l'échelle d'un circuit électronique, surtout si les fonctions des différents moteurs et autre ne s'exécutent que si il y a un changement d'état. Je considère que 0,5s à 1s, c'est l'échelle de temps minimale pour un humain.
  • tu peux essayer de rajouter un filtre passe bas (numerique - moyenne mobile - ou analogique) sur ton signal de son binaire. Personnellement je choisirais un simple filtre electronique avec une resistance et un condensateur, pour ne pas alourdir le code et je vérifiais avec le traceur série que j'ai bien ce que je veux. Mais c'est mon choix.

Voici ma proposition. J’ai finalement mis une variable pour enregistrer l’état au tour de loop precedent (previousState) et déclenché le démarrage du moteur 1 par le passage de l’état 2 à l’état 1

const int MotorPinA = 12; // for motor A
const int MotorSpeedPinA = 3; // for motor A
const int MotorBrakePinA = 9; // for motor A

const int soundpin = 7;     // micro, supposé binairec
const int inputPin = 4;               // PIR, supposé binaire

// les variables que j'ai ajoutées

unsigned long motor1_starting_date = millis(); //date ou demarre le moteur 1
unsigned long running_motor1_duration = 5000; //duree pendant laquelle le moteur 1 tourne
bool state = true; // etat 1 (true) ou 2 (false) du montage
bool previousState = false; // etat au tour de loop precedent <--- MODIFIE
bool motor1State = false; // si le moteur 1 tourne (true) ou pas (false)
  // demarre dès le premier passage par loop


void setup()
{
  Serial.begin(9600);           //  seial monitor initialized
  pinMode (soundpin, INPUT);
  pinMode(inputPin, INPUT);     // declare sensor as input

  pinMode(MotorPinA, OUTPUT);
  pinMode(MotorSpeedPinA, OUTPUT);
  pinMode(MotorBrakePinA, OUTPUT);
}



void loop() {

  // MODIFICATION DE L'ETAT SI NECESSAIRE

  if ( (state) && digitalRead(soundpin)) { // etat 1 & son fort
    /* 1ère réaction : L'ambiance sonore est trop forte,
      le capteur de son réagit.
      On passe de l'état 1 à l'état 2
    */
    state = false; // passage a l'état 2
  }
  else if ((!state) && digitalRead(inputPin)) { // etat 2 et mouvement
    /*2ème réaction : Le capteur de mouvement réagit à un mouvement.
       On passe de l'état 2 à l'état 1
       (avec juste la lumière de l'ampoule
       qui se tamise doucement grâce au light dimmer).
    */
    state = true; // passage a l'état 1
  }

  // ACTION SUR LE MOTEUR
  motor1(); // demarrage et arret du moteur 1

  // ACTUALISATION DES VARIABLES
  previousState = state;

} // loop



void motor1() {
  /* gère les arrets et demarrage du moteur 1

  */
  if (state && !previousState) { // <--- MODIFIE
    // passage de l'état 2 à l'état 1
    // lancement du moteur qui est à l'arret
    digitalWrite(MotorPinA, HIGH);    // set direction // <--- A faire dans le setup ?
    analogWrite(MotorSpeedPinA, 200); // set speed at maximum // <--- dans le setup ?
    digitalWrite(MotorBrakePinA, LOW); // release brake
    motor1State = true; //
    motor1_starting_date = millis();
    Serial.println("Demarrage du moteur 1 après un changement d'état");
  }
  
  else if (state && motor1State) {
    // pendant l'état 1, le moteur est lancé
    // arret du moteur après X s
    if (millis() - motor1_starting_date > running_motor1_duration) {
      digitalWrite(MotorBrakePinA, HIGH); // arret du moteur
      motor1State = false;
      Serial.println("Arret du moteur 1 après 5s");
    }
  }
  
  else if (!state && motor1State) {
    // passage de l'état 1 à l'état 2
    // arret du moteur 1 s'il tourne
    digitalWrite(MotorBrakePinA, HIGH); //  brake
    motor1State = false;
    Serial.println("Arret du moteur 1 après un changement d'état");
  }
} // motor1

Merci Fantoche !
Pardon de n’avoir pas répondu plus tôt. J’ai essayé d’avancer le projet au mieux quand j’avais un peu de temps.
Mon échéance pour celui-ci arrivant mardi prochain, j’ai l’impression d’être pas trop loin d’un résultat satisfaisant.
J’ai du faire des choix cela dit : J’ai décidé de ne pas dimmer la lumière mais de la remplacer par un relai (essayer de dimmer la lumière à l’air bien complexe, surtout avec les ampoules Led, et trop peu de tutorial pour mon cas précis. Dans le doute je préfère jouer la sureté.)
J’ai également décidé de séparé les actions sur trois arduinos, pour pouvoir gérer seulement deux actions sur chaque.

1er arduino : Capeur Son, Capteur mouvement, Motorshield + un moteur et un relai

2eme arduino :Capeur Son, Capteur mouvement, Motorshield + deux moteurs

3eme arduino Capeur Son, Capteur mouvement, deux relais

Bien entendu il faudra calibrer les Capteurs Son

Maintenant, j’ai essayer de retravailler sur ce que tu m’avais dis concernant la simultanéité des actions
en créants plusieurs void.

Et cela à plutôt l’air de marcher, en tout cas pour le 1er Arduino :

const int MotorPinA = 12; // for motor A
const int MotorSpeedPinA = 3; // for motor A
const int MotorBrakePinA = 9; // for motor A
const int Relai = 5;

const int soundpin = 7;     // micro, supposé binairec
const int inputPin = 4;               // PIR, supposé binaire

// les variables que j'ai ajoutées

unsigned long motor1_starting_date = millis(); //date ou demarre le moteur 1
unsigned long running_motor1_duration = 5000; //duree pendant laquelle le moteur 1 tourne
bool state = true; // etat 1 (true) ou 2 (false) du montage
bool motor1State = false; // si le moteur 1 tourne (true) ou pas (false)
bool relaiState = false;
  // demarre dès le premier passage par loop



// les variables qui ne me sont pas utiles

// int pirState = LOW;             // we start, assuming no motion detected
// int val = 0;                    // variable for reading the pin status
//const int SAMPLE_TIME = 10; // ??? pas compris
//unsigned long millisCurrent; // toujours millis()
//unsigned long millisLast = 0; // remplacé par motor1_starting_date
//unsigned long millisElapsed = 0; // millis() - millisLast
//int sampleBufferValue = 0; // pas compris



void setup()
{
  Serial.begin(9600);           //  seial monitor initialized
  pinMode (soundpin, INPUT);
  pinMode(inputPin, INPUT);     // declare sensor as input

  pinMode(MotorPinA, OUTPUT);
  pinMode(MotorSpeedPinA, OUTPUT);
  pinMode(MotorBrakePinA, OUTPUT);
  pinMode(Relai, OUTPUT);
}



void loop() {

  // MODIFICATION DE L'ETAT SI NECESSAIRE
Serial.println(digitalRead(soundpin));

  if ( (state) && digitalRead(soundpin)) { // etat 1 & son fort
    /* 1ère réaction : L'ambiance sonore est trop forte,
      le capteur de son réagit.
      On passe de l'état 1 à l'état 2
    */
    state = false; // passage a l'état 2
  }
  else if ((!state) && digitalRead(inputPin)) { // etat 2 et mouvement
    /*2ème réaction : Le capteur de mouvement réagit à un mouvement.
       On passe de l'état 2 à l'état 1
       (avec juste la lumière de l'ampoule
       qui se tamise doucement grâce au light dimmer).
    */
    state = true; // passage a l'état 1
  }

  // ACTION SUR LE MOTEUR
  motor1(); // demarrage et arret du moteur 1
  relai1();
  
} // loop



void motor1() {
  /* gère les arrets et demarrage du moteur 1

  */
  if (state && !(motor1State)) {
    // declanchement de l'etat 1
    // lancement du moteur qui est à l'arret
    digitalWrite(MotorPinA, HIGH);    // set direction // <--- A faire dans le setup ?
    analogWrite(MotorSpeedPinA, 60); // set speed at maximum // <--- dans le setup ?
    digitalWrite(MotorBrakePinA, LOW); // release brake, demarrage
    motor1State = true; // le moteur 1 tourne
    motor1_starting_date = millis(); // enregistre la date de demarrage du moteur
    Serial.println("Demarrage du moteur 1 après un changement d'état");
  }

 
  else if (!state && motor1State) {
    // déclanchement de l'état 2
    // arret du moteur 1 s'il tourne
    digitalWrite(MotorBrakePinA, HIGH); //  brake
    motor1State = false; // le moteur ne tourne plus
    Serial.println("Arret du moteur 1 après un changement d'état");
  }
} // motor1

void relai1() {
  /* gère les arrets et demarrage du moteur 1

  */
  if (state && !(relaiState)) {
    // declanchement de l'etat 1
    // lancement du moteur qui est à l'arret
    digitalWrite(Relai, LOW); 
    relaiState = true; // le moteur 1 tourne
    Serial.println("Demarrage du relai après un changement d'état");
  }

 
  else if (!state && relaiState) {
    // déclanchement de l'état 2
    // arret du moteur 1 s'il tourne
    digitalWrite(Relai, HIGH);
    delay(5000);
    digitalWrite(Relai, LOW); 
    delay(1000);    
    relaiState = false; // le moteur ne tourne plus
    Serial.println("Arret du relai après un changement d'état");
  }
} // babycry1

Pour le 3eme arduino (deux relais) j’ai pu faire sans.

const int Light1 = 5;
const int Light2 = 6;

const int soundpin = 7;     // micro, supposé binairec
const int inputPin = 4;               // PIR, supposé binaire


bool state = true; // etat 1 (true) ou 2 (false) du montage
bool lightState = false;


void setup()
{
  Serial.begin(9600);           //  seial monitor initialized
  pinMode (soundpin, INPUT);
  pinMode(inputPin, INPUT);     // declare sensor as input

  pinMode(Light1, OUTPUT);
  pinMode(Light2, OUTPUT);
  
}



void loop() {

  // MODIFICATION DE L'ETAT SI NECESSAIRE

  if ( (state) && digitalRead(soundpin)) { // etat 1 & son fort
    /* 1ère réaction : L'ambiance sonore est trop forte,
      le capteur de son réagit.
      On passe de l'état 1 à l'état 2
    */
    state = false; // passage a l'état 2
  }
  else if ((!state) && digitalRead(inputPin)) { // etat 2 et mouvement
    /*2ème réaction : Le capteur de mouvement réagit à un mouvement.
       On passe de l'état 2 à l'état 1
       (avec juste la lumière de l'ampoule
       qui se tamise doucement grâce au light dimmer).
    */
    state = true; // passage a l'état 1
  }

  // ACTION SUR LE MOTEUR
  
  light();
  // ACTUALISATION DES VARIABLES

} // loop



void light() {
  /* gère les arrets et demarrage du moteur 1

  */
  if (state && !lightState) { // <--- MODIFIE
    // passage de l'état 2 à l'état 1
    // lancement du moteur qui est à l'arret
    digitalWrite(Light1, HIGH);    // set direction // <--- A faire dans le setup ?
    digitalWrite(Light2, LOW);   
    lightState = true;
    Serial.println("Arret Light2, Demarrage Light1 après un changement d'état");
  }
 

  
 
  else if (!state && lightState) {
    digitalWrite(Light1, LOW);    // set direction // <--- A faire dans le setup ?
    digitalWrite(Light2, HIGH);
    lightState = false;
    Serial.println("Arret Light1, Demarrage Light2 après un changement d'état");
  }
} // light

Donc un grand merci Fantoche ! J’espère que je vais pouvoir finir le projet sans complication.
Si jamais je devais me retrouver en difficulté, j’espère que je pourrais revenir vers toi une dernière fois.

Ah si tient ! J’ai probablement parler trop vite. Dans ce code :

const int MotorPinA = 12; // for motor A
const int MotorSpeedPinA = 3; // for motor A
const int MotorBrakePinA = 9; // for motor A
const int Relai = 5;

const int soundpin = 7;     // micro, supposé binairec
const int inputPin = 4;               // PIR, supposé binaire

// les variables que j'ai ajoutées

unsigned long motor1_starting_date = millis(); //date ou demarre le moteur 1
unsigned long running_motor1_duration = 5000; //duree pendant laquelle le moteur 1 tourne
bool state = true; // etat 1 (true) ou 2 (false) du montage
bool motor1State = false; // si le moteur 1 tourne (true) ou pas (false)
bool relaiState = false;
  // demarre dès le premier passage par loop



// les variables qui ne me sont pas utiles

// int pirState = LOW;             // we start, assuming no motion detected
// int val = 0;                    // variable for reading the pin status
//const int SAMPLE_TIME = 10; // ??? pas compris
//unsigned long millisCurrent; // toujours millis()
//unsigned long millisLast = 0; // remplacé par motor1_starting_date
//unsigned long millisElapsed = 0; // millis() - millisLast
//int sampleBufferValue = 0; // pas compris



void setup()
{
  Serial.begin(9600);           //  seial monitor initialized
  pinMode (soundpin, INPUT);
  pinMode(inputPin, INPUT);     // declare sensor as input

  pinMode(MotorPinA, OUTPUT);
  pinMode(MotorSpeedPinA, OUTPUT);
  pinMode(MotorBrakePinA, OUTPUT);
  pinMode(Relai, OUTPUT);
}



void loop() {

  // MODIFICATION DE L'ETAT SI NECESSAIRE
Serial.println(digitalRead(soundpin));

  if ( (state) && digitalRead(soundpin)) { // etat 1 & son fort
    /* 1ère réaction : L'ambiance sonore est trop forte,
      le capteur de son réagit.
      On passe de l'état 1 à l'état 2
    */
    state = false; // passage a l'état 2
  }
  else if ((!state) && digitalRead(inputPin)) { // etat 2 et mouvement
    /*2ème réaction : Le capteur de mouvement réagit à un mouvement.
       On passe de l'état 2 à l'état 1
       (avec juste la lumière de l'ampoule
       qui se tamise doucement grâce au light dimmer).
    */
    state = true; // passage a l'état 1
  }

  // ACTION SUR LE MOTEUR
  motor1(); // demarrage et arret du moteur 1
  relai1();
  
} // loop



void motor1() {
  /* gère les arrets et demarrage du moteur 1

  */
  if (state && !(motor1State)) {
    // declanchement de l'etat 1
    // lancement du moteur qui est à l'arret
    digitalWrite(MotorPinA, HIGH);    // set direction // <--- A faire dans le setup ?
    analogWrite(MotorSpeedPinA, 60); // set speed at maximum // <--- dans le setup ?
    digitalWrite(MotorBrakePinA, LOW); // release brake, demarrage
    motor1State = true; // le moteur 1 tourne
    motor1_starting_date = millis(); // enregistre la date de demarrage du moteur
    Serial.println("Demarrage du moteur 1 après un changement d'état");
  }

 
  else if (!state && motor1State) {
    // déclanchement de l'état 2
    // arret du moteur 1 s'il tourne
    digitalWrite(MotorBrakePinA, HIGH); //  brake
    motor1State = false; // le moteur ne tourne plus
    Serial.println("Arret du moteur 1 après un changement d'état");
  }
} // motor1

void relai1() {
  /* gère les arrets et demarrage du moteur 1

  */
  if (state && !(relaiState)) {
    // declanchement de l'etat 1
    // lancement du moteur qui est à l'arret
    digitalWrite(Relai, LOW); 
    relaiState = true; // le moteur 1 tourne
    Serial.println("Demarrage du relai après un changement d'état");
  }

 
  else if (!state && relaiState) {
    // déclanchement de l'état 2
    // arret du moteur 1 s'il tourne
    digitalWrite(Relai, HIGH);
    delay(5000);
    digitalWrite(Relai, LOW); 
    delay(1000);    
    relaiState = false; // le moteur ne tourne plus
    Serial.println("Arret du relai après un changement d'état");
  }
} // babycry1

dans le dernier Else If, comment pourrais-je dire à l’arduino de looper l’action du Relai (5sec allumé, 1sec éteint) jusqu’au changement d’état du relaiState ?

Je pense que les codes sont facilement assemblables en un seul fichier. Mais bon, si ça marche pour toi, c'est ce qui importe

Les commentaires permettent de faciliter la compréhension du code. C'est bien de les mettre à jour après un copier-coler. Meme si le code n'est que pour toi, ca peut t'aider.

Maintenant, j'ai essayer de retravailler sur ce que tu m'avais dis concernant la simultanéité des actions
en créants plusieurs void.

Quand on écrit un truc comme :
void function(){}
ça veut juste dire que la fonction en renvoie rien.

La méthode a utiliser pour dimmer une led dépend des cas :

  • pour une led simple, directement sortie de la boite de composant électronique, il suffit d'utiliser un PWM. Dans ton cas, la difficulté consiste à contrôler la vitesse à laquelle l'intensité lumineuse varie, sans rendre ton code bloquant.
  • pour une ampoule à LED, comme dans les lampes d'apparement actuelles il faut utiliser un triac, car les ampoules LED possèdent un circuit qui les rend compatible avec du 220V alternatif. J'avoue que je m'étais decouragée, dans un de mes projets.

Quand veux-tu exactement que ton relais fasse ? Je n'arrive pas à suivre quand il doit être allumé ou éteint.

“Je pense que les codes sont facilement assemblables en un seul fichier.”

J’imagine que oui, après j’ai peur de pas être dans les temps pour le terminer. Si j’ai un peu d’extra time j’essaierai de voir.
Mais j’ai aussi un souci avec le hardware. J’ai plusieurs motorshield, mais ils sont tous 2 channels au max. Je peux peut-être m’arranger pour en monter deux sur un arduino uno (je n’ai que ce modèle là, quatre fois) et faire en sorte de séparer les pin. A voir.
Mais surtout juste en termes d’esthétique globale, tout le système sera apparent et je pense que se sera pas mal s’il y a beaucoup de materiel.

“void function(){}
ça veut juste dire que la fonction en renvoie rien.”

Je suis pas sûr d’avoir compris ça :confused: .

Pour dimmer la lumière j’ai acheté ça:

Mais le peu de tutos que j’ai trouvé pour ce light dimmer étaient sur des ampoules dimmables à filament, (difficilement trouvable dans le commerce, de nos jours). Un peu difficile et chronophage d’adapter les autres tutos qui se concentrent sur les ampoules à Led. Et enfin, l’avertissement sur tous “attention, vous travailler avec un courant mortel…” qui à fini par me refroidir (bien que j’ai l’impression que travailler avec un relai qui prend du 220v est un peu similaire… maybe, maybe not).
Du coup pas grave, j’approfondirai quand j’aurais du time.
Toi, tu avais fini par réussir à dimmer ?

Pour le relai :
Comme tu le sais, le système est :
Etat 1 > réaction capteur son > état 2 > réaction capteur mouvement > état 1…

Je veux que le relai soit OFF dans l’état 1. Et dans l’état 2, il soit ON pendant 5 sec, OFF 1sec, en boucle jusqu’au prochain changement d’état causé par un capteur.

Et tant qu’on est dans le materiel, as-tu déjà utilisé ce genre de motorshield ?

J’en ai besoin pour controller un moteur à fort ampérage. Mais il semble qu’il n’ai pas de pin break prévu pour stopper le moteur, come sur les autres que j’utilise.

Update :

Concernant le motorshield, il est pas super simple effectivement.
On dirait qu'il ne fonctionne que sur sa vitesse et sa direction. Donc l'action "break" correspond à "speed=0".

J'ai réussi à peu près à faire ce que je veux dans ce code (j(ai laisser juste quelque commentaire en note pour moi) :

#include "CytronMotorDriver.h"

CytronMD motor(PWM_DIR, 3, 4);  // PWM = Pin 3, DIR = Pin 4


const int soundpin = 7;    
const int inputPin = 5;               

bool state = true;  /* etat 1 (true) ou 2 (false) du montage*/
bool motor1State = false;   /* si le moteur 1 tourne (true) ou pas (false)*/




void setup() {

  Serial.begin(9600);           
  pinMode (soundpin, INPUT);
  pinMode(inputPin, INPUT); 

}

void loop() {

Serial.println(digitalRead(soundpin));

  
  if ( (state) && digitalRead(soundpin)) { // etat 1 & son fort
    
    /* 1ère réaction : L'ambiance sonore est trop forte, le capteur de son réagit.*/
      
    state = false; // passage a l'état 2

         /* On passe de l'état 1 à l'état 2*/
    
  }
  else if ((!state) && digitalRead(inputPin)) { // etat 2 et mouvement
    
    /*2ème réaction : Le capteur de mouvement réagit à un mouvement*/
   
    state = true; // passage a l'état 1
    
    /* On passe de l'état 2 à l'état 1 */

  }

  
  motor1(); 

}

void motor1() {

if (state && !(motor1State)) {

  
  motor.setSpeed(128);
  digitalWrite(4, HIGH);  
  delay(2000);
  motor.setSpeed(0);  
  delay(5000);
  motor.setSpeed(128);
  digitalWrite(4, LOW);  
  delay(2000);
  motor.setSpeed(0);  
  delay(5000);  
  motor1State = true;   

  Serial.println("Demarrage du moteur 1 après un changement d'état");
  
}

else if (!state && motor1State) {
    
    
    motor.setSpeed(0);
    motor1State = false; 
    Serial.println("Arret du moteur 1 après un changement d'état");
 
  }
  
}

Le seule problème étant : bien que j'ai l'impression d'avoir entré la bonne commande, le moteur ne change pas de sens ...

Si tu regardes le code de la librairie, tu verras que c'est elle qui pilote le sens de rotation.
Si la vitesse est positive le moteur tourne dans un sens, si la vitesse est négative il tourne dans l'autre.
Donc si tu envoies comme paramètre une vitesse positive, la librairie remet la broche 4 à 0 quoi que tu fasses.