Projet Arduino, lumière en fonction du son.

Bonjour à vous,
Je suis actuellement sur un projet, dans lequel un plafonnier est connecté à un smartphone via bluetooth, et peut sélectionner des modes de fonctionnement différents.
L'un de ces modes consistent à modifier le flux lumineux des lampes grâce au son ambiant (capté via un microphone), pour une utilisation "boite de nuit".
J'ai déjà réalisé un prototype via une modélisation Proteus, dont voici une vidéo :
Vidéo test youtube

(Proteus ne pouvant pas simuler en temps direct ce programme, j'ai du ralentir la bande sonore, et j'ai essayé de faire en sorte que ça colle le plus possible :/)
Mon code arduino est attaché en pièce jointe.
Mon problème (comme on peut le voir sur la vidéo), c'est que l'on voit mal les moments ou le son """explose""", mon projet doit plus """claquer""" (soit plus """punchy"""), et je me retrouve un peu bloqué :/,
Merci pour toute aide que vous pourrez m'apportez !
PS : je le fais avec la sortie du microphone et sa puissance, peut-être ce serait mieux en se fiant aux fréquences, mais je ne sais pas comment faire j'ai cherché et je suis un peu perdu !

RGB_proto.ino (2.54 KB)

en augmentant la sensibilité (seuils) cela ne suffit pas ?
sinon il y aurait aussi la notion de "trainée", une fois qu'une led s'allume, la laisser allumée un certain temps même si le volume descend, cela peut pas mal dynamiser l'animation en la rendant plus "franche"...

Le problème que j'ai c'est que justement il n'y a pas trop de différences entre les valeurs hautes (dans la vidéo après la "montée" et l'allumage des 3 LEDS) La trainée n'aurait lieue que sur une LED, ce qui ne marcherais pas... il faut donc que je pense à un moyen d'atténuer les moyens-hauts pour mettre en valeur les hauts... mais ça ... :confused:

et en utilisant une plage dynamique ? en fonction des min/max enregistrés sur une plage de temps relativement courte (mais pas trop) genre de quelques dizaines de secondes maxi ... (?)
edit : tu fais en fonction du volume ou t'as des filtres par frequence ?

Je fais en fonction du volume je ne sais pas comment faire en fonction de fréquence :/.
J'ai changé le programme pour que la plage évolue constament :

//***************** MODE 1 : MODE DJ ************************************

if (modeState == 1) { // mode 1 : en fonction du son ambient;
while (modeState == 1)
{
signalCurrent = analogRead(pinMicrophone);
if (signalCurrent < 1024) // supprime les échantillons trop grands
{
if (signalCurrent > signalMax)
{
signalMax = signalCurrent; // sauvegarde le niveau maximum
}
else if (signalCurrent < signalMin)
{
signalMin = signalCurrent; // sauvegarde le niveau minimum
}
Serial.print("signal : ");
Serial.println(signalCurrent);
ledRed = 0;
ledGreen = 0;
ledBlue = 0;
ledWhite = 0;
if (signalCurrent > 0.25signalMax) {
if (signalCurrent > 0.5
signalMax) {
if (signalMax > 0.75*signalMax) {
ledRed = 255;
ledGreen = 255;
ledBlue = 255;
ledWhite = signalMax - signalCurrent;
}
else {
ledRed = 255;
ledGreen = 255;
ledBlue = signalMax - signalCurrent;
}
}
else {
ledRed = 255;
ledGreen = signalMax - signalCurrent;
}
}
else {
ledRed = signalCurrent;
}
light(); // allume les LED en fonction de leur intensité
}
}
}
Je précise que signalMax est initialisé à 0 et signalMin à 1024.
PS : Je suis en train de voir comment je pourrais faire avec des fréquences

pense à mettre ton code dans des balises [ code ].
Pour le filtrage par fréquence je parlais en entrée (électronique analogique) mais en effet, au vu de ton code, non, tu ne le fais pas... pour filtrer par fréquences avec seulement du code tu risques d'ajouter une latence qui risque de rendre "retardé" le résultat affiché, donc ce n'est pas une bonne idée...

Concernant ton dernier code, ta plage est juste "plafonnée" par le min/max que t'auras entendu, c'est déjà mieux, mais il suffit d'une pause ou d'une coupure pour que ton min soit à 0 et y démeure tant que l'arduino n'est pas réinitialisé...
Il te faut ajouter une notion temporelle : garder dans un tableau les min/max des 10 dernières secondes (par exemple), avec un échantillonnage par seconde (tableau de 10 valeurs), t'utilises ce tableau pour calculer les min/max des 10 dernières secondes :

int tableMin[10] = {1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024 };
int tableMax[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int indexFenetre = 0;
int temps;

setup()
{
    // a la fin fin
    temps = millis();
}

loop()
{
    // t'utilises les fonctions getMin() / getMax() pour allumer tes LED, mais tu continues à calculer tes min/max pour alimenter la fenêtre temporelle d'échantillons

    [... ton code ...]

    // a faire à la fin de loop :
    if ( (millis() - temps) >= 1000 ) // une seconde s'est écoulée
    {
        indexFenetre = (indexFenetre + 1) % 10; // incrementation de l'index de la fenêtre d'échantillonage

        // stockage de tes valeurs min/max
        tableMin[indexFenetre] = signalMin;
        tableMax[indexFenetre] = signalMax;

        // réinitialisation de tes min/max
        signalMin = 1024;
        signalMax = 0;

        // réinitialisation du temps pour attendre une seconde de plus
        temps = millis();
    } 
}

// fonctions permettant de récupérer les min/max sur la fenêtre temporelle
int getMin()
{
    int min=1024;

    for (int i = 0; i< 10; i++)
    {
         if ( tableMin[i] < min )
         {
              min = tableMin[i];
         }
     }

     return min;
}

int getMax()
{
    int max=0;

    for (int i = 0; i< 10; i++)
    {
         if ( tableMax[i] > max )
         {
              max = tableMax[i];
         }
     }

     return max;
}

Ok merci pour ton aide :slight_smile:

bonjour , super ton idée Cryincat , quand il sera pleinement fonctionnel j espère que tu partageras , d'un point de vue pédagogique et ludique il est vraiment intéressant .

Bonne journée .

:slight_smile:

J'y penserais :slight_smile: