Ruban Led ws2812b en fonction de la distance

Bonjours :slight_smile:
Je viens ici pour avoir des conseils et avis sur la marche a suivre pour réalisé un petit projet.
Tous juste débutant j'ai pour envie de concrétisé une idée

J'élabore un petit projet , un miroir infini piloté avec une arduino. Rien de bien ambitieux mais je suis débutant :confused:

Déjà je vais détaillé mon idée si vous ne l'avez pas déjà compris.
Un miroir lambda , sur le rebord interne le ruban led , une plaque de verre avec un films sans tain par dessus. Et hop une impression de profondeur du plus belle effet.
Pour géré les couleurs / animation j'ai trouvé 2 librairie intéressante Fast_LED et Adafruit_Neopixel.

Pour faire simple j'ai pensé à de simple bouton pour faire défilé les animations et pour diminué et augmenter la luminosité ... Mais j'ai à disposition un kit arduino avec deux détecteurs infrarouge et un détecteur à ultrason. J'aimerai les intégrés , l'un ou l'autre , ou les deux.
Ses derniers permettrait d'allumer et d’éteindre le dispositif ( si personne n'est proche ), De diminué la luminosité lorsqu'on est trop proche.

En soit faire varié Une led avec l'info du capteur je sais globalement faire.

Mais là j'utilise une librairie dont je comprends pas vraiment la structure. Oui je suis débutant =D je fait ctrl +c ctrl +v ...

Le miroir étant sur mesure je m'occupe encore du cadre , et le film sans tain n'est pas encore en ma possession.
Mais je prend de l'avance sur le reste et anticipe la fastidieuse programmation.

J'attends vos suggestion , notamment sur la méthode à utilisé pour faire varier les animations NeoPixel ou fast_LED via 1 , 2 ou même 3 détecteur de distance.

Bonjour,
Pour la librairie NeoPixel, tu peux définir la couleur de la LEDainsi

strip.setPixelColor(n, red, green, blue);

n le numéro de la led et Red,Green,Blue 3 octets,

tout dépend de ce que tu veux faire, toute les LEDs de la même couleur, ou de différentes couleurs.

Toujours est-il qu'il existe une fonction map(); qui permet de passer une valeur comprise dans un interval dans un autre.

ainsi tu peux passer ta valeur du capteur ultrason ou infrarouge dedans pour quelle te ressorte une valeur entre 0 et 255. auparavant il te faudra passer ta valeur dans la fonction constrain(), car la fonction pulseIn() peut te ressortir des valeurs étrange.

en réutilisant les exemples de chez Adafruit voici un petit sketch qui fait varier les bleu en fonction d'un capteur ultrason

#include <Adafruit_NeoPixel.h>
#define PIN 6
#define NBLED 60
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NBLED, PIN, NEO_GRB + NEO_KHZ800);

// pins du capteur a ultrason
int trig = 12; 
int echo = 13; 
long lecture_echo; 
// extremum des valeurs 
int val_min = 200;
int val_max = 12000;
byte couleur = 0;

void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  //initailisation des pins 
  pinMode(trig, OUTPUT); 
  digitalWrite(trig, LOW); 
  pinMode(echo, INPUT); 
}

void loop(){
 digitalWrite(trig, HIGH); 
 delayMicroseconds(10); 
 digitalWrite(trig, LOW); 
 lecture_echo = pulseIn(echo, HIGH); 
 lecture_echo =constrain(lecture_echo,val_min,val_max);
 couleur = map(lecture_echo,val_min,val_max,0,255); //couleur est maintenant entre 0 et 255 et depend lineairemnt de la valeur du capteur ultrason 
 for (int i = 0; i < NBLED; ++i)
 {
 strip.setPixelColor(i, 0, 0, couleur); // ici je change le bleu en fonction du capteur, mais tu peux ajouter des capteurs ou trouver une formule pour jouer avec les couleurs
 }
 delay(1000); 
}

demande si tu as des question :wink:

Yeah c'était environ l'idée , Grand merci a toi =D

Dans un premier temps je vais me concentré sur cette animation , à savoir Une couleur qui varie avec un capteur , j'ai 3 capteur donc 3 couleur :smiley:

:-[ Effectivement j'aurais deux trois question sur ton bout de code.
Pour ce qui est de généré une valeur entre 0 et 255 via le résultat du capteur.

bearcorrupted:
il existe une fonction map(); qui permet de passer une valeur comprise dans un interval dans un autre.
ainsi tu peux passer ta valeur du capteur ultrason ou infrarouge dedans pour quelle te ressorte une valeur entre 0 et 255. auparavant il te faudra passer ta valeur dans la fonction constrain(), car la fonction pulseIn() peut te ressortir des valeurs étrange.

J'étais partie sur la même idée mais sans le constrain() dont je ne connaissait ni l'existence ni l'utilité, je comprend pas pourquoi on ne map() pas directement sur lecture_echo ?

 lecture_echo = pulseIn(echo, HIGH); 
 lecture_echo =constrain(lecture_echo,val_min,val_max);
 couleur = map(lecture_echo,val_min,val_max,0,255); //couleur est maintenant entre 0 et 255 et depend lineairemnt de la valeur du capteur ultrason

Je vais continué dans ce sens pour chaqu'un des 3 capteurs pour tous les faire varié.

Un bouton seras sur la tranche du cadre pour basculé entre plusieurs animation + un mode éteint
La prochaine seras juste toute les leds blanche avec luminosité variable avec la distance =) simple avec strip.setBrightness() et map().

J'ai vu des exemples sublime comme des effets d'arc en ciel, des effets de scintillement que je trouve très jolie, même le code est beau :o
Pour l'instant le tous est sur breadboard et je me demmande comment je pourrais placé les capteurs sur le cadre pour avoir une info cohérente qui ne serait pas parasité par les reflets du miroir , mais ça c'est une autre histoire.

En tous cas merci :wink:
J'essayerais de tenir le post un peu à jours si ça peut aider quelqu'un aussi

Salut, en faite la fonction pulseIn() mesure de temps d'une impulsion, il se peut que ce temps soit hors de ton intervalle que tu rentre dans le map(), ce qui posera un problème. il est préférable que tu le force à être dans cet intervalle.

Aussi la fonction strip.setBrightness() ne s’appelle que dans le void setup() d’après la doc.

Et j'ai oublié

strip.show();

à la fin du void loop()

Merci de la précision , j'ai essayé avec et sans le constrain(). Si je l'enlève la valeur de echo est en dehors des clou pour le map().
Mais sa n'empèche que sa rend aussi jolie avec que sans :smiley:

#include <Adafruit_NeoPixel.h>
#define PIN 6 // DI ws2812b
#define NBLED 3 // proto sans alim supplementaire 28 au final
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NBLED, PIN, NEO_GRB + NEO_KHZ800);
int trig = 12; // Emission hcsr04
int echo = 13; // Reception hcsr04
// Sharps infrarouge  PIN 8 / 9 reserver
// switch incremente decremente pin A3 A4 Reserver

unsigned long lecture_echo; // valeur instantanne
unsigned long lecture_cumul; // faire une breve moyenne
int divi = 10; // moyenne sur 10 mesure
float moyenneD = 0;
long moyenneF = 0;
int val_min = 350;
int val_max = 4000;
byte couleurR = 0;
byte couleurB = 0;
byte couleurV = 0;
byte lum = 230;

void setup() {
  strip.begin(); // initialisation
  strip.show(); // affichage a zero , rappeler la fonction pour refresh les leds
  pinMode(trig, OUTPUT); // declaration pin sortie
  digitalWrite(trig, LOW);  // 0 sur trig
  pinMode(echo, INPUT); // declaration pin entre
  Serial.begin(9600); //debug
  strip.setBrightness(lum); // luminosite
}

void loop() {
  digitalWrite(trig, HIGH); // impulsion
  delayMicroseconds(10); // verrou de 10us
  digitalWrite(trig, LOW); // fin d'impulsion
  lecture_echo = pulseIn(echo, HIGH); // lecture de la reception en us
  for (int n = 0; n <= divi; n++) {
    lecture_cumul = lecture_cumul + lecture_echo; // boucle de 10 pour faire une moyenne
    moyenneD = lecture_cumul / n;
  }
  // moyenneD = lecture_cumul / divi;
  lecture_cumul = 0;

  moyenneF = constrain(moyenneD, val_min, val_max); // plafonne les valeurs pour le map
  couleurB = map(moyenneF, val_min, val_max, 0, 255); //couleur est maintenant entre 0 et 255 et depend lineairemnt de la valeur du capteur ultrason
  couleurR = map(moyenneF, val_max, val_min, 0, 255); // map la valeur sur une fourchette inversé de 255 à 0

  if (moyenneD > 11000 || moyenneD < 200) { // allume fortement la verte lorsque très loin
    couleurV = 250;
    couleurR = 0;
    couleurB = 0;
  }
  else couleurV = 0;

  for (int i = 0; i < NBLED; ++i) {
    strip.setPixelColor(i, couleurR, couleurV, couleurB); // ici je change le bleu en fonction du capteur, mais tu peux ajouter des capteurs ou trouver une formule pour jouer avec les couleurs
    strip.show();
  }
  Serial.println(".");
Serial.print(lecture_echo);
Serial.println(".");
  Serial.print(moyenneF);
  Serial.print("  F : D    ");
  Serial.print(moyenneD);


  delay(150);
}

Voila pour l'instant c'est encore un peu fouillis.
j'utilise constrain sur la moyenneF. J'ai compris son utilité d'une certaine façon.
Mais les valeurs en dehors du constrain() m'interesse , à terme ce seras l'indicateur que personne n'est proche du miroir donc éteindre toutes les leds. Mais j'ai besoin d'avoir fini le cadre pour faire des test et ne pas rentré des valeurs arbitraire qui rendre bien seulement sur ma breadboard.

Pour le strip.setBrightness() ducoup on va oublier mais map() toute les couleurs en même temps , se qui je pense aura le même effets
Par exemple , à 1:18 sur cette video https://www.youtube.com/watch?v=KaClIgAVuI8
On peut voir un effets que j'aimerais bien pouvoir codé , une couleur qui se répand led après led.

Les possibilités sont juste dingue , encore une animation sur ma liste :smiley: j'espere l'arduino aura assez de ram

pour l'animation ColorWipe() que tu cherche.

Merci Bearcorrupted mais j'ai pas tous pigé :confused:

Bon en essayant de m'inspiré de ce que j'ai compris avec ton lien voila ce que j'ai pondu.
La V0.2 en quelque sorte.

/*
 *
Teste avec organisation en fonction() dirigé par un switch case
_____________________________________________________________
*/
#include <Adafruit_NeoPixel.h>
#define BI 8 // incremente en mode pullup
#define BD 7 // decremente en mode pullup
#define PIXEL_PIN 6 // DI ws2812b
#define Trig 12 // emeteur hcsr04
#define Echo 13 // recepteur hcsr04
#define SharpD A3 // reception sharps droit
#define SharpG A4 // reception sharps gauche 
#define NBLED 3 // proto sans alim supplementaire 28 au final

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NBLED, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)


byte divi = 5;
int cumul = 0;
long rEcho = 0;
long mEcho = 0;
long dEcho = 0;
long bEcho;
byte bVb;
byte cVb;
bool etatI;
bool etatD;
bool oldI = HIGH;
bool oldD = HIGH;
int index = 0;
//Stock de variable

void setup() {
  Serial.begin(9600); //ouverture port com
  strip.begin(); // initialise ruban
  strip.show(); // refresh null
  pinMode(Trig, OUTPUT); // sortie hcsr04
  digitalWrite(Trig, LOW);  // 0 par defaut
  pinMode(Echo, INPUT); // reception hcsr04
  pinMode(SharpD, INPUT); // voltage sharp
  pinMode(SharpG, INPUT); // voltage sharp
  pinMode(BI, INPUT_PULLUP); // Boutton +
  pinMode(BD, INPUT_PULLUP); // Boutton -



}

void loop() {

  mEcho = lecture_echo(); // fonction pour lire "Divi" fois la valeur hcsr04 pour une moyenne
  rEcho = constrain(mEcho, 500, 1000); // renvoie uniquement les valeur comprise entre
  cVb = map(rEcho, 500, 1000, 255, 0); // 255 lorsque echo faible 0 si sup a 1000
  bEcho = constrain(mEcho, 1000, 3000); // renvoie uniquement les valeur comprise entre
  bVb = map(bEcho, 3000, 1000, 255, 0); // 255 lorsque 3000 et zero jusqua 1000
  

// boucle découte des switch
  etatI = digitalRead(BI);
  if (etatI == LOW && oldI == HIGH)  { // si nouvelle pression
    delay(10); // anti parasite
    etatI = digitalRead(BI); // enregistre le nouvelle etat 

    if (etatI == LOW)  { // si letat est appuyer incrementer l'index
      index++;
      if (index > 5) { // jusqua 5
        index = 0;
      }
    }
  }
  oldI = etatI; // memorise letat


  etatD = digitalRead(BD);
  if (etatD == LOW && oldD == HIGH)  { //idem pour décrementer l'index
    delay(10); // anti parasite
    etatD = digitalRead(BD);

    if (etatD == LOW) {   
      index--; 
      if (index < 0) {
        index = 5;
      }
    }
  }
  oldD = etatD;

// on affiche l'animation correspondante avec l'onglet 
  onglet(index);
 
  Serial.println(":");
  Serial.print(index);  // debug

}

void onglet(int i) {
  switch (i) {
    case 0: Serial.println("off"); delay(150); couleurSimple(strip.Color(0, 0, 0), 150);
      break;
    case 1: couleurSimple(strip.Color(bVb, 0, 0), 150);
 // si très loin s'allume fort , extinction lorsque inférieur a 1000
      break;
    case 2: couleurSimple(strip.Color(cVb, 0, 0), 50); 
// si très proche s'allumé fort. extinction lorsque plus loin que 1000
      break;
    case 3: couleurSimple(strip.Color(cVb , bVb, 0), 50);
// on joue avec les nuances
      break;
    case 4: couleurSimple(strip.Color(~cVb, 0, 0), 50);
// on essaye un peu tout et n'importe quoi
      break;
    case 5: couleurSimple(strip.Color(0, ~bVb-cVb, ~cVb), 150);
// vraiment n'importe quoi mais sa clignote quand entre 800 et 1200 c'est jolie 
      break;
  }
}


void couleurSimple(uint32_t c, uint8_t temp)  { // convertis c en 32bits et temp 8bit
  for (uint16_t i = 0; i < strip.numPixels(); i++) {
    // boucle pour chaque led
    strip.setPixelColor(i, c);
    strip.show();
    // envoie sur led X couleur Y puis l'affiche
    delay(temp);
  }
}

long lecture_echo()   {  // renvoie une moyenne de mesure
  for (int n = 0; n < divi; n++)  {
    digitalWrite(Trig, HIGH);
    delayMicroseconds(10);
    digitalWrite(Trig, LOW);
    dEcho = pulseIn(Echo, HIGH);
    cumul = cumul + dEcho;
  }
  mEcho = cumul / divi;
  cumul = 0;
  return mEcho;
}

Si quelqu'un peut me dire ce qu'il en pense.
Pour ce qui est des teste in situ j'ai noté 4 valeur clé avec le detecteur ultrason dans l'environnement et les situations qui m’intéresse.

De 200 à 700 :
Quelqu'un proche du capteur
De 700 à 1200 :
Quelqu'un se tien loin du capteur
De 1200 à environ 3000 :
Quelqu'un passe entre le mur et le capteur
Au dessus de 3000 rien n'est dans son champs.

Par contre après quelque test avec les capteurs infrarouge j'ai du grand n'importe quoi je suis passablement déçu.
Au mieux j'ai une valeur qui répond bien au variation de distance entre 15cm et 60cm.
Mais devoir être en dessous de 50~60cm ça ne m’intéresse pas dans mon fonctionnement , je ne veut pas avoir a " touché " le miroir.
Ducoup je crois que je vais commander un ou deux autre capteur ultrason.
:wink: D'ici la je continue à cherché des façons de bien géré mes couleurs.