Sonometre.ino 3.9 KB
Newer Older
Damien OLIVIER's avatar
Damien OLIVIER committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
#include <Adafruit_NeoPixel.h>

#define DEBUG

#define N_LEDS  16                // Nombre de leds RGB dans l'anneau
#define BROCHE_ANNEAU 6          // Broche sur laquelle est connecté l'anneau (Data input)
#define BROCHE_MICRO  A0          // Le micro est connecté à une broche analogique


byte niveau = N_LEDS;                   // Nombre de leds allumées, pour la redescente
const int fenetreEchantillonnage = 50;  // Fenêtre d'échantillonnage (50 ms = 20Hz) fréquence audible

// Paramètre 3 =
//   NEO_KHZ800  800 KHz fréquence du flux (le plus souvent)
//   NEO_KHZ400  400 KHz
//   NEO_GRB     cablage GRB (le plus souvent)
//   NEO_RGB     cablage RGB
Adafruit_NeoPixel anneau = Adafruit_NeoPixel(N_LEDS, BROCHE_ANNEAU, NEO_GRB + NEO_KHZ800);


void setAll(int rouge, int vert, int bleu) {
  for (int i = 0; i < N_LEDS; i++ ) {
    anneau.setPixelColor(i, anneau.Color(rouge, vert, bleu));
  }
  anneau.show();
}

float teinte2RGB( float v1, float v2, float vH )
{
  if ( vH < 0 ) vH = vH + 1;
  if ( vH > 1 ) vH = vH - 1;
  if ( ( 6 * vH ) < 1 ) return ( v1 + ( v2 - v1 ) * 6 * vH );
  if ( ( 2 * vH ) < 1 ) return ( v2 );
  if ( ( 3 * vH ) < 2 ) return ( v1 + ( v2 - v1 ) * ( ( 2.0f / 3 ) - vH ) * 6 );
  return ( v1 );
}



uint32_t roueChromatique(float angle, float saturation, float lumiere) {
  unsigned short rouge, vert, bleu;
  float v1, v2;

  if (saturation == 0) {
    rouge = lumiere * 255;
    vert = lumiere * 255;
    bleu = lumiere * 255;
  }
  else
  {

    if (lumiere < 0.5)
      v2 = lumiere * (1 + saturation);
    else v2 = (lumiere + saturation) - (lumiere * saturation);

    v1 = 2. * lumiere - v2;
    rouge = (unsigned short) 255 * teinte2RGB(v1, v2, angle / 360. + (1.0f / 3));
    vert = (unsigned short) 255 * teinte2RGB(v1, v2, angle / 360.);
    bleu = (unsigned short) 255 * teinte2RGB(v1, v2, angle / 360. - (1.0f / 3));
  }
  return anneau.Color(rouge, vert, bleu);
}


void eteintEntre(uint8_t ledDepart, uint8_t ledArrivee) {
  uint8_t tmp;
  if (ledDepart > ledArrivee)
  {
    tmp = ledDepart;
    ledDepart = ledArrivee;
    ledArrivee = tmp;
  }
  for (int quelleLed = ledDepart; quelleLed <= ledArrivee; quelleLed++)
    anneau.setPixelColor(quelleLed,anneau.Color(0, 0, 0));
}

void allumeEntre(uint8_t ledDepart, uint8_t ledArrivee, unsigned int angleDepart, unsigned int angleArrivee) {
  uint8_t tmp;
  if (ledDepart > ledArrivee)
  {
    tmp = ledDepart;
    ledDepart = ledArrivee;
    ledArrivee = tmp;
  }
  for (int quelleLed = ledDepart; quelleLed <= ledArrivee; quelleLed++)
    anneau.setPixelColor(quelleLed,roueChromatique(map(ledArrivee - ledDepart + 1, 0, N_LEDS - 1, angleDepart, angleArrivee), 1, 0.5));
}


unsigned int acquisition()
{
  unsigned int echantillon;
  unsigned int signalMax = 0;
  unsigned int signalMin = 1024;

  unsigned long debutCrono = millis(); // Debut d'échantillonnage
  unsigned int creteACrete = 0;        // Niveau crête à crête

  while (millis() - debutCrono < fenetreEchantillonnage)
  {
    echantillon = analogRead(BROCHE_MICRO);
    if (echantillon < 1024)           // Valeur cohèrente ?
    {
      if (echantillon > signalMax)
      {
        signalMax = echantillon;
      }
      else if (echantillon < signalMin)
      {
        signalMin = echantillon;
      }
    }
  }
  creteACrete = signalMax - signalMin;  // Amplitude crête à crête
  return creteACrete;
}


void setup() {
#ifdef DEBUG
  Serial.begin(9600);
#endif
  anneau.begin();
  anneau.show();              // Toutes les leds sont éteintes.
}


void loop() {
  unsigned int amplitude = acquisition(); // Amplitude crête à crête
  unsigned int nbAAllumer = map(amplitude, 0, 1024, 0, 17 );

#ifdef DEBUG
  Serial.print("amplitude = "); Serial.println(amplitude);
  Serial.print("nbAAllumer = "); Serial.println(nbAAllumer);
#endif

  eteintEntre(nbAAllumer, N_LEDS - 1);   // On éteint les leds en trop ...  
  if (nbAAllumer > 0) allumeEntre(0, nbAAllumer - 1, 120, 0);
  anneau.show();
}