LDR et détection de pics

La gestion d'un écran OLED, la mis en On/Off par le passage de la main devant une cellule LDR.

attention il y a peut être des erreurs (dites- moi), il n'a pas beaucoup d'heure de marche, mais cella fonctionne.

le branchement sur un Arduino Uno (10k résistance variable)
+5v ------LDR-----A0-----1K-------10k
-------Gnd

le croquis

/*
 * Exemple de programme de détection d'un pic* Lumineux , une LDR comme capteur.
 * Pour une mis a On/Off d'un écran OLED (ou autres) 
 * 
 * partage sur forum : https://forum.arduino.cc/t/ldr-et-detection-de-pics/1103317
 * 
 * sur des bases: 
 * https://forum.arduino.cc/t/for-dans-une-fonction/380743/12
 * https://arduino.stackexchange.com/questions/72650/how-to-find-the-peak-value-of-analog-signal
 * https://passionelectronique.fr/photoresistance/
 * 
 */

 /* *Un pic est un maximum donc la valeur qui le précède et celle qui le suit sont inférieures*/

// pour test, commande Led 13
  #include <Timers.h> 
  Timer timer0;   

  const byte sensor_LDR = A0;   //pin photoresistance

//calcul de la moyenne
  int current_LUX = 0 ;
  int diff_LUX = 0;
  int pics ;


// tempo des lectures 
  unsigned long previousMillis ; 
  unsigned long lecture = 30L;  // 30millis ??

//----------------- SETUP ----------------------
  void setup() {
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);   //Led13
  timer0.begin(SECS(6));          // tempo Led
  }

//----------------- LOOP ----------------------
  void loop() {
  
 // unsigned long currentMillis = millis();    //tempo lecture
  
  int val_LDR = analogRead(sensor_LDR);        //lecture sensor LDR
  int current_LUX = val_LDR * (5.0 /1023.0);   // mis a l'echelle de 0 a 5

  if( millis() - previousMillis >= lecture) {
    previousMillis = millis();  
    diff_LUX = Moyenne(val_LDR) ;         //apl fonction Moyenne
    }
   
  if (diff_LUX >= 10) {    // seuil différence valeur
    pics = 1;            // On change l'état de la variable pics
    }
  else {
    pics = 0;
    }
    
//------- action pour visu sur la Led 13 -------
  if (pics == 1) {
  digitalWrite(LED_BUILTIN, HIGH);

  Serial.print ("pics : "); Serial.println (pics);
  Serial.print ("val_LDR : "); Serial.println (val_LDR);
  Serial.print ("current_LUX : "); Serial.println (current_LUX);
  Serial.print ("diff_LUX : "); Serial.println (diff_LUX);
  
   }
 
  if (timer0.available() )  //tempo Led13
  {
   digitalWrite(LED_BUILTIN, LOW);
    timer0.restart();
      }

//Serial.print ("current_LUX : "); Serial.println (current_LUX);

  }//loop

//---------------- calcul de la moyenne avec opérateur binaire "bricoleau"---------------------
  int Moyenne(int param1) {//param1 = sonde
    static int tab[4] = {0, 0, 0, 0}; //création du tableau
    static byte nbvalindex = 0;
    byte index = nbvalindex & 3;
    byte nbval = nbvalindex >> 4;      //taille utile du tableau

    if (nbval < 5) nbval++;
    int moyenne = (tab[0]+tab[1]+tab[2]+tab[3] + param1 ) / nbval;   //on calcule la moyenne

    tab[index++]=param1;
 
    nbvalindex = (nbval << 4) | index;  // << décaler les bits vers la gauche 

    diff_LUX =  param1 - moyenne ;      // calcul difference des valeurs 

    return diff_LUX ;
    
}

//----------------- Fin Pgm ----------------------

//------------- INFO --------------------------------
/*
 * 
 * la sensibilité d'un pont diviseur (R1-R2) est optimale pour deux résistances de valeurs proches
 * donc LDR "R1" en lux ambiant = 2k alors "R2" = 2k
 * 
 * schema pour un Arduino Uno (10k et une résistance variable)
 *      +5v ------LDR-----pin:A0-----1K-------10k-------Gnd
 * 
 */

re-Edit : croquis modifier

Mais alors, si cela fonctionne, pourquoi créer un topic ? :thinking:
Le principe du forum, c'est que si tu as une question ou un problème, tu l'a poses, en donnant des informations, et on essaye d'y répondre. Mais si tu présentes un objets fini, il faut le mettre dans la partie "projets finis : "
ici : Réalisations et Projets Finis - Arduino Forum
Merci de prendre en compte les recommandations listées dans Les bonnes pratiques du Forum Francophone
Pandaroux007 :fox_face:
P.S : je trouve votre projet pas mal du tout :smile:, merci pour le partage !

bah voila "projets finis" cella est peut être prématuré.
et un croquis qui fonctionne venant de ma pars cella m’inquiète .

Mais oui c'est un partage  aussi

Mais nonnn... :smile:

Ça me fait ma meme chose chaque fois que j'ai fini un code!

Au fait,tu as terminé ton graphique?(je m'interroge,cela fait plus d'un mois que je suis sans nouvelle... :wink:)

@flix09 tu parle de https://forum.arduino.cc/t/il-est-lib-plot/1067677
Non je suis passé a autre choses, un thermostat pour la gestion d'un convecteur électrique
(bientôt ici sur écran large :slight_smile: )

Sympa comme projet :grin:
P.S : C'est quoi un convecteur électrique ? :thinking:

oui
un mini bus RS485* , d'un coté le thermostat sur pro_mini , Oled , sonde et gestion horaire
et de l'autre coté, un Nano , mesure Linky (délestage) et expander i2C Pcf8574 pour le relay de commande du Convecteur Electrique .

  • du NodeToNode Mysensors

Bonjour

élément chauffant . souvent rangé dans la catégorie 'radiateurs'

permet de faire une distinction entre les éléments qui chauffent principalement par rayonnement et ceux qui chauffent principalement par convection

....ceci dit il n'est pas interdit de clancer un moteur de recherche pour voir , sans attendre, à quoi ça ressemble :wink:

Ohhhh... D'accord, si j'ai bien compris, c'est un radiateur en acier dans lequel il y a une résistance qui chauffe l'air et naturellement, l'air chaud remonte et chauffe la pièce :smile:
Merci beaucoup, @al1fch :+1:
Pandaroux007 :fox_face:

Un (gros) fer a souder en quelques sorte... :grin:

@flix09 :clap:

C'est un peu tordu et cela ne fait pas gagner de place en RAM puisque les variables sont recrées à chaque fois que tu rentres dans la fonction. Autant mettre index et nbval en static et virer nbvalindex et en plus tu gagneras en lisibilité.

Donc, tu limites index dans la fourchette 0 à 3 avec le & 3
Puis tu fais +1 donc index peut valoir 4 or tab est déclaré tab[4] donc tu tapes en dehors du tableau.

Cette conversion est inutile elle n'apporte rien. Autant travailler directement avec valLDR.

Merci @fdufnews pour les infos

oui pour la partie Calcul de la moyenne , c'est une recopie direct de l'exemple donné par Bricoleau
https://forum.arduino.cc/t/for-dans-une-fonction/380743/10
mais oui cella peut être optimisé

pour "mettre index et nbval en static "
cella me donne en mémoire, stockage et dynamique

  • avant modif :1852 octets (5%) et 28 octets (1%)
  • avec modif : 1906 octets (5%) et 46 octets (2%)

tu dit .." donc tu tapes en dehors du tableau" donc l'exemple donner est pas top ??

et pour " travailler directement avec valLDR" cella me donne des valeurs qui font oscillé les calculs , avec un on/off pas nette :frowning:

Merci
( je me disais bien que c’était top facile )

Au temps pour moi c'est une post incrémentation. Donc on écrit jamais dans 4.

Actuellement, cette ligne

retourne une valeur entre 0 et 5.
Si tu travailles directement avec valLDR il suffit de mettre une valeur de seuil plus élevée.
Ta conversion divise valLDR par 200 environ donc au final le test

est équivalent à
if (diff_LUX > 200)

j'ai fait les test avec l'utilisation de val LDR , les résultats

le passage de la mains devant la LDR doit être plus rapide pour le déclenchement, les passages lent ne donne rien, mais cella est bien.

mais suivant la luminosité de la pièce , du local , de l'éclairement de la cellule , c kapout
je suis obligé de retouché les réglages du potar 10K et les valeurs de seuil "diff_LUX"

bref dilaté l’échelle des valeurs LDR ..... pas top :frowning:

j'ai cherché sur le web autres version possible pour "peak detection algorithm arduino" .... une chose très demandé, la un truc sympa , mais coté mémoire un peux plus gourmand
https://github.com/leandcesar/PeakDetection

https://raw.githubusercontent.com/leandcesar/PeakDetection/master/docs/assets/example.gif

Ne pas perdre de vue que la moyenne est calculée à chaque itération de loop() et que loop() tourne pleine balle car il n'y a aucun délai dans la boucle. Ce qui fait que la moyenne est calculée sur une période de quelques millisecondes seulement. je pense que tu pourrais n'appeler Moyenne() que toute les 10 ou 20ms par exemple.

Très bonne remarque, oui lorsque des Serial.print sont activé le comportement est différent .

la je test la librairie "PeakDetection" de Leandro César .
le comportement est plus régulier :slight_smile:

@fdufnews une question ( lorsque t'a un moment)

dans l'exemple https://github.com/leandcesar/PeakDetection/blob/master/examples/PeakDetection/PeakDetection.ino

// convertit la valeur du capteur en une plage entre -1 et 1
  double data = (double)analogRead(A0)/512-1;

pourquoi un double data ?? et le 512-1 ??? comprend pas :slight_smile:

alors ça sera surtout: (valeur lue/512) -1, pour ramener entre -1 et 1 comme précisé dans le commentaire.
par contre pour le "double" j'attends aussi la réponse :grin: