Go Down

Topic: projet Halloween avec lumière synchronisée a la musique  (Read 2308 times) previous topic - next topic

goldoseb


Slt a tous me revoilà avec un nouveau projet qui comme d'habitude fonctionne très bien mais pas comme je le voudrais.

donc pour faire court dans quelque jours les gosses vont débarquer pour avoir des bonbon.
 trop cool " ma famille et moi même sommes fan d'halloween "

cette année je voulais les effrayer un peu,

je donc trouvé le projet suivant :

avec un arduino uno , un dfplayer, un détecteur PIR, un HP 3W , et un led strip RGB plus quelques scary song

je veux détecter leurs arrivé, lire un MP3 et commander les led strip en fonction de cela. jusque la pas de souci et voici donc le programme qui fonctionne.

Code: [Select]


/*
    Projet d'annimation lumineuse halloween syncronisée en fonction
    du son emis par un HP de 3W sur un DFplayer
*/


#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;


const int buttonPin = 9;     // broche n9 sur PIR
int buttonState = 0;         // variable pour stocker le status du PIR
int busyPin = 5;             // broche n9 sur busy pin du MP3; // lecteur MP3 actif ou non
int busy = 0;
int LEDrouge = 6; //  broche n6 sur led strip rouge
int LEDverte = 7; //  broche n7 sur led strip vert
int LEDbleu  = 8; //  broche n6 sur led strip bleu

int sensorPin = A0;    // echantillonage de la sortie HP
int sensorValue = 0;  // variable pour stocker la valeur de l'echantillonage
int button = 0;

//***************************************SETUP*************************************


void setup () {
 
  pinMode(buttonPin, INPUT);
  pinMode(LEDrouge, OUTPUT);
  pinMode(LEDverte, OUTPUT);
  pinMode(LEDbleu, OUTPUT);
 
  pinMode(busyPin, INPUT);
  pinMode(buttonPin, INPUT);
 
  mySoftwareSerial.begin(9600);
  myDFPlayer.begin(mySoftwareSerial);  //utilisation de softwareSerial pour communiquer avec le mp3.
  myDFPlayer.volume(15);  //reglage volume. de 0 a 30

  static unsigned long temps = millis();
 

       //----Set different EQ----
 
  //  myDFPlayer.EQ(DFPLAYER_EQ_NORMAL);
  //  myDFPlayer.EQ(DFPLAYER_EQ_POP);
  //  myDFPlayer.EQ(DFPLAYER_EQ_ROCK);
  //  myDFPlayer.EQ(DFPLAYER_EQ_JAZZ);
  //  myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC);
    myDFPlayer.EQ(DFPLAYER_EQ_BASS);

 
}

//.................................BOUCLE PRINCIPALE.........................................
void loop () {

 

  digitalWrite(LEDbleu, HIGH);
  digitalWrite(LEDverte, HIGH);
  digitalWrite(LEDrouge, HIGH);
 
  do {
    button = digitalRead(buttonPin); // ataché au detecteur PIR
     } while (button == 1);




  //myDFPlayer.play (5);  //Play haunted mp3
  myDFPlayer.next();  // lis le prochain morceau.
 

  delay(100);
  do {
    sensorValue = analogRead(sensorPin);

   
   
            if (sensorValue >= 550) {

              digitalWrite(LEDrouge, LOW);
              digitalWrite(LEDbleu, LOW);
              digitalWrite(LEDverte, LOW);
              delay (50);
            }
           
                    if (sensorValue <= 500) {
               
                      digitalWrite(LEDrouge, LOW);
                      digitalWrite(LEDbleu, HIGH);
                      digitalWrite(LEDverte, HIGH);
                    }



   
    busy = digitalRead(busyPin);
  } while (busy == 0); // a zero quand le son est actif
}

//...................................... FIN DE LA BOUCLE ......................




Mon souci est que j'au un dizaine de titres , mais sont trop long : environ 6 minutes chaqun, je voulais donc
en lire qu'une parti environ 60 secondes , mais voila
mon prog se sert de la fonction Busy du DFplayer et donc je n'arrive pas a sortir de la boucle tant que le HP débité du son,

j'ai essayer une boucle millis mais je n'arrive pas a trouver le bon endroit pour la couler

si someone a une idée


merci a tous.

seb

Zlika

Bonjour,

La fonction loop() n'est pas censée contenir des morceaux de code bloquant. Comment veux-tu gérer plusieurs actions en même temps si tu monopolises ton processeur sur une partie de code. Ta façon de structurer ton programme n'est pas bonne. Ta boucle loop() doit contenir une suite de fonctions qui teste rapidement les événements et agir en conséquence. Chaque fonction s'occupe d'une chose (boutons, gestion du lecteur mp3, détecteur, leds,...) et utilise les variables pour passer des informations aux autres.

goldoseb

merci a toi

je ne pense pas que mon code soit bloquant pour le moment

il utilise juste la fonction Busy du dfplayer qu'il test a chaque tour pour continuer a effectuer l'échantillonnage de la sortie HP.

d'une certaine manière je dis que c'est bloquant car tant que le morceau joué n'est pas fini et que le status de Busy ne change pas je n'arrive pas a sortir de cette boucle.

tandis que j'aimerais que seulement les 60 premiere seconde soit joué sans possibilité d'être coupé.
puis après les 60 premières secondes si le PIR capte un mouvement on passe le morceau suivant et ainsi de suite pour tous les autres morceaux.

après avoir bidouillé mon code dans tous les sens avec la fonction miles, la seule chose que j'arrive a faire
c'est par ex   jouer un morceau 60s puis attente de 60s et ainsi de suite.

a priori je n'ai pas tout saisi dans cette fonction, en temps normal je me creuserai la tete jusqu'as ce que cela fonction mais la Halloween arrive , et je n'ai pas avancé sur la partie hardware. " impression 3D et sur la partie amplification du son et la partie contrôle lumineuse des led 3W RGB par IRL 520 mosfet .

merci man

Artouste

merci a toi

je ne pense pas que mon code soit bloquant pour le moment

il utilise juste la fonction Busy du dfplayer qu'il test a chaque tour pour continuer a effectuer l'échantillonnage de la sortie HP.

d'une certaine manière je dis que c'est bloquant car tant que le morceau joué n'est pas fini et que le status de Busy ne change pas je n'arrive pas a sortir de cette boucle.

tandis que j'aimerais que seulement les 60 premiere seconde soit joué sans possibilité d'être coupé.
puis après les 60 premières secondes si le PIR capte un mouvement on passe le morceau suivant et ainsi de suite pour tous les autres morceaux.

après avoir bidouillé mon code dans tous les sens avec la fonction miles, la seule chose que j'arrive a faire
c'est par ex   jouer un morceau 60s puis attente de 60s et ainsi de suite.

a priori je n'ai pas tout saisi dans cette fonction, en temps normal je me creuserai la tete jusqu'as ce que cela fonction mais la Halloween arrive , et je n'ai pas avancé sur la partie hardware. " impression 3D et sur la partie amplification du son et la partie contrôle lumineuse des led 3W RGB par IRL 520 mosfet .

merci man
Bonjour
pourquoi utiliser la fonction busy du dfplayer ?
si tu detecte un mouvement tu lance le morceau N+1 que tu stop ( verif milli() - actuel) au bout de 60 secondes

hbachetti

Il suffit de stocker la valeur retournée de la fonction millis() dans une variable nommée par exemple start au démarrage du morceau.

Code: [Select]

    static unsigned long start = millis();


Ensuite au début de la boucle do while il faut comparer avec la durée voulue :

Code: [Select]

  do {
    if (millis() - start >= 60000)
        break;


@+
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

hbachetti

Ou faire comme dit Artouste, sauf si tu as des morceaux qui ont une durée inférieure à 60s.
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

goldoseb


merci pour vos commentaires

j'ai donc essayé d'inclure la fonction millis et comme dans mes essai cela donne toutes sortes de choses
mais pas celles attendues.

voici le code

Code: [Select]
do {
    button = digitalRead(buttonPin); // ataché au detecteur PIR
     } while (button == 1);




  //myDFPlayer.play (5);  //Play haunted mp3
  myDFPlayer.next();  // lis le prochain morceau.

   static unsigned long start = millis();
 
 
  do {


    if (millis() - start >= 5000)
        break;
   
    sensorValue = analogRead(sensorPin);

   
   
            if (sensorValue >= 550) {

              digitalWrite(LEDrouge, LOW);
              digitalWrite(LEDbleu, LOW);
              digitalWrite(LEDverte, LOW);
              delay (50);
            }
           
                    if (sensorValue <= 510) {
               
                      digitalWrite(LEDrouge, LOW);
                      digitalWrite(LEDbleu, HIGH);
                      digitalWrite(LEDverte, HIGH);
                    }



   
    busy = digitalRead(busyPin);
  } while (busy == 0); // a zero quand le son est actif
}/code]

pourtant j'ai bien mis la fonction millis juste après la ligne de lecture du dfplayer

et au début de la boucle do/while      le comparateur de temps

seb @+

hbachetti

Essaie d'afficher les valeurs : la valeur de start et de millis() sur le moniteur série, en ajoutant un petit delay(1000) avant le while pour éviter que cela s'affiche trop vite.
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

Artouste

merci pour vos commentaires

j'ai donc essayé d'inclure la fonction millis et comme dans mes essai cela donne toutes sortes de choses
mais pas celles attendues.

voici le code

Code: [Select]
do {
    button = digitalRead(buttonPin); // ataché au detecteur PIR
     } while (button == 1);




  //myDFPlayer.play (5);  //Play haunted mp3
  myDFPlayer.next();  // lis le prochain morceau.

   static unsigned long start = millis();
  
  
  do {


    if (millis() - start >= 5000)
        break;
    
    sensorValue = analogRead(sensorPin);

    
    
            if (sensorValue >= 550) {

              digitalWrite(LEDrouge, LOW);
              digitalWrite(LEDbleu, LOW);
              digitalWrite(LEDverte, LOW);
              delay (50);
            }
            
                    if (sensorValue <= 510) {
                
                      digitalWrite(LEDrouge, LOW);
                      digitalWrite(LEDbleu, HIGH);
                      digitalWrite(LEDverte, HIGH);
                    }



    
    busy = digitalRead(busyPin);
  } while (busy == 0); // a zero quand le son est actif
}/code]

pourtant j'ai bien mis la fonction millis juste après la ligne de lecture du dfplayer

et au début de la boucle do/while      le comparateur de temps

seb @+

Bonjour
Tu a un declencheur/initiateur  d'evenement = PIR  , c'est quoi exactement ?
les capteurs PIR  cheap à peanuts €  presentent un niveau "haut" aprés detection dont la durée peut etre +/- ajustée
ton souhait se resume à  :
detecter un changement d'etat "PIR" de LOW à HIGH
lancer la lecture du morceau N
stopper la lecture du morceau N  si durée > 60 seconde (si durée < le stop est automatique à la fin)
- préparer le prochain morceau à suivre
- attendre nouveau stimuli du PIR


goldoseb


slt   c'est bien un détecteur de mvt cheap a vraiment peanuts 2,30€

mais pour le moment j'utilise un capteur ir  encore plus cheap 0,50€ pour faire les tests

effectivement mon souhait et le suivant

-détecter un mouvement a plusieurs mètres avec mon PIR et donc un changement d'état High/Low

-lancer la lecteur d'un morceau

-ne pas pouvoir interrompre la lecture les 60 premières secondes puis pouvoir le faire seulement si il y as un changement d'état  high/low   et/ou interruption automatique a la fin du morceau

- jouer un autre morceau après une nouvelle detection si les 60 sec se sont écoulé ou si le morceau et fini


c'est pour cela que j'utilise la fonction Busy


je fais des essai sur la fonction millis mais comme je le dis cela donne des truc bizarres , comme indiqué par M hbachetti je fais des essaie aussi avec le moniteur maintenant. pour y voir plus clair

des que j'ai fais des test je vous les posts.

grand merci @+


goldoseb


voici le code avec le moniteur et millis

Code: [Select]

/*
    Projet d'annimation lumineuse halloween syncronisée en fonction
    du son emis par un HP de 3W sur un DFplayer
*/


#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;


const int buttonPin = 9;     // broche n9 sur PIR
int buttonState = 0;         // variable pour stocker le status du PIR
int busyPin = 5;             // broche n9 sur busy pin du MP3; // lecteur MP3 actif ou non
int busy = 0;
int LEDrouge = 6; //  broche n6 sur led strip rouge
int LEDverte = 7; //  broche n7 sur led strip vert
int LEDbleu  = 8; //  broche n6 sur led strip bleu

int sensorPin = A0;    // echantillonage de la sortie HP
int sensorValue = 0;  // variable pour stocker la valeur de l'echantillonage
int button = 0;

//***************************************SETUP*************************************


void setup () {
 
  pinMode(buttonPin, INPUT);
  pinMode(LEDrouge, OUTPUT);
  pinMode(LEDverte, OUTPUT);
  pinMode(LEDbleu, OUTPUT);
 
  pinMode(busyPin, INPUT);
  pinMode(buttonPin, INPUT);
 
  Serial.begin (9600);
  mySoftwareSerial.begin(9600);
  myDFPlayer.begin(mySoftwareSerial);  //utilisation de softwareSerial pour communiquer avec le mp3.
  myDFPlayer.volume(15);  //reglage volume. de 0 a 30

  static unsigned long temps = millis();
 

       //----Set different EQ----
 
  //  myDFPlayer.EQ(DFPLAYER_EQ_NORMAL);
  //  myDFPlayer.EQ(DFPLAYER_EQ_POP);
  //  myDFPlayer.EQ(DFPLAYER_EQ_ROCK);
  //  myDFPlayer.EQ(DFPLAYER_EQ_JAZZ);
  //  myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC);
    myDFPlayer.EQ(DFPLAYER_EQ_BASS);

 
}

//.................................BOUCLE PRINCIPALE.........................................
void loop () {

  Serial.println("");
  Serial.println("Attente de détection");

  digitalWrite(LEDbleu, HIGH);
  digitalWrite(LEDverte, HIGH);
  digitalWrite(LEDrouge, HIGH);

 
 
  do {
    button = digitalRead(buttonPin); // ataché au detecteur PIR
     } while (button == 1);
     delay (1000);

  Serial.println("Détection activée");


  //myDFPlayer.play (5);  //Play haunted mp3
  myDFPlayer.next();  // lis le prochain morceau.


  static unsigned long start = millis();
 

  delay(100);
  do {
    sensorValue = analogRead(sensorPin);


    if (millis() - start >= 10000)
        break;

    Serial.print(sensorValue);
    Serial.print(" ");

   
   
            if (sensorValue >= 550) {

              digitalWrite(LEDrouge, LOW);
              digitalWrite(LEDbleu, LOW);
              digitalWrite(LEDverte, LOW);
              delay (50);
            }
           
                    if (sensorValue <= 500) {
               
                      digitalWrite(LEDrouge, LOW);
                      digitalWrite(LEDbleu, HIGH);
                      digitalWrite(LEDverte, HIGH);
                    }



   
    busy = digitalRead(busyPin);


    Serial.print(millis());
    Serial.print(" ");

    Serial.print(start);
    Serial.print(" ");

   
    delay (1000);
   
  } while (busy == 0); // a zero quand le son est actif
}

//...................................... FIN DE LA BOUCLE ....................../code]

donc a priori tout ce passe bien pour la premiere boucle mais après le premier break
il ne rentre plus dans la boucle.

de se fais plus d'animation lumineuse  et plus de retour sur millis et Start

goldoseb

donc a priori tout ce passe bien pour la premiere boucle mais après le premier break
il ne rentre plus dans la boucle.

de se fais plus d'animation lumineuse  et plus de retour sur millis et Start

Zlika

Ce qui est normal puisque tu as déclaré ta variable start en static

Quote
static unsigned long start = millis();
De ce fait, la variable est mise à jour seulement au moment de sa création. Décompose ta ligne en deux.
1) déclaration de ta variable en static (sans valeur)
2) mise à jour de ta variable avec millis()

kamill

Ou enlève simplement le static car la variable ne doit pas être statique.

hbachetti

Quote
Ce qui est normal puisque tu as déclaré ta variable start en static
Oups ... désolé
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

Go Up