4 leds aléatoires avec la fonction millis

Bonjour à toutes et tous,

Je me présente brièvement car nouveau parmi vous. J'ai 51ans, de Haute-Savoie, je travail dans un théâtre de marionnettes comme technicien.

Pour notre prochain spectacle, je dois concevoir un groupe de 4 étoiles qui s'allument et s'éteignent. Jusque la, rien de sorcier, mais ! je souhaiterai que chaque étoiles s'allument et s'éteignent de manière aléatoire et indépendante. J'ai longuement surfé pour chercher des bouts de codes de ci, de la, mais jamais j'ai trouvé comment écrire un code satisfaisant. Je ne suis pas du tout programmateur, j'ai une certaine logique qui me permet de comprendre mais j'ai un niveau zéro en codage et mes différentes greffes de codes ne donne rien de satisfaisant.

Je viens vers vous en désespoir de cause et j'espère trouvé parmi vous une bonne âme qui pourrait m'aider à réaliser ce projet. Côté hardware c'est tout prêt, la planche à pain, une carte arduino nano, mes 4 leds.

Voilà ce que je souhaite :
chaque led est sur une borne PWM pour gérer la variation de luminosité.
les bornes sont les 6 / 9 / 10 / 11

chaque étoiles devra s'allumer aléatoirement les unes des autres, donc d'après mes recherches ce serai la fonction millis et non delay qui a un effet bloquant sur les autres fonctions.
en terme de "variables" je souhaite que le temps d'allumage : de zéro à HIGH soit aléatoire mais avec une donnée que je puisse changer. Pareille pour le temps de HIGH à zéro et évidement aussi le temps qu'elle reste allumée et le temps ou elle est éteinte.

Donc je pense qu'une fonction du genre random(0,255) serait à utiliser. j'ai mis zéro virgule 255 pour montrer que je souhaite pouvoir agir sur l'intensité lumineuse. Les étoiles ne vont pas s'éteindre complètement.

Bon, voila, j'espère ne pas vous sembler trop gonfler de vous demander cela ! mais qui ne tente rien ...
Sur ce je vous remercie de m'avoir lu ...

Passez une bonne journée,

c'est cool.


essayez le code dans cette simulation

le code

enum EtatLed : byte {STOP, ETEINTE, EN_ALLUMAGE, ALLUMEE, EN_EXTINCTION} ;

class LedGradient {
    byte brocheLed;
    byte pasDuPwm;
    unsigned long deltaT;
    unsigned long dureeAuxExtremes;
    int pwm;
    unsigned long dernierTick;
    EtatLed etat;

    void generationAleatoire() {
      dureeAuxExtremes = random(500, 1000);   // le temps qu'on attend entre deux gradients
      pasDuPwm = random(1, 10);               // vitesse de progression du PWM
      deltaT = random(5, 20);                 // durée d'attente entre deux changements de PWM
    }

  public:
    LedGradient(const byte pin) : brocheLed(pin) {}

    void demarrer() {
      generationAleatoire();
      digitalWrite(brocheLed, LOW);
      pwm = 0;
      etat = EN_ALLUMAGE;
      dernierTick = millis();
    }

    void arreter() {
      pwm = 0;
      digitalWrite(brocheLed, LOW);
      etat = STOP;
    }

    void begin() {
      pinMode(brocheLed, OUTPUT);
      arreter();
    }

    void tick() {
      switch (etat) {
        case STOP: break;

        case ETEINTE:
          if (millis() - dernierTick >= dureeAuxExtremes) {
            generationAleatoire();
            etat = EN_ALLUMAGE;
            dernierTick = millis();
          }
          break;

        case EN_ALLUMAGE:
          if (millis() - dernierTick >= deltaT) {
            pwm += pasDuPwm;
            if (pwm >= 255) {
              pwm = 255;
              etat = ALLUMEE;
            }
            analogWrite(brocheLed, pwm);
            dernierTick = millis();
          }
          break;

        case EN_EXTINCTION:
          if (millis() - dernierTick >= deltaT) {
            pwm -= pasDuPwm;
            if (pwm <= 0) {
              pwm = 0;
              etat = ETEINTE;
            }
            analogWrite(brocheLed, pwm);
            dernierTick = millis();
          }
          break;

        case ALLUMEE:
          if (millis() - dernierTick >= dureeAuxExtremes) {
            etat = EN_EXTINCTION;
            dernierTick = millis();
          }
          break;
      }
    }
};

LedGradient lesLeds[] = {6, 9, 10, 11};

void setup() {
  randomSeed(analogRead(A0)); // on génère un peu d'aléatoire
  for (auto& l : lesLeds) {
    l.begin();
    l.demarrer();
  }
}

void loop() {
  for (auto& l : lesLeds) l.tick();
}

il y a trois variables aléatoires qui vont définir ce qu'il se passe

    void generationAleatoire() {
      dureeAuxExtremes = random(500, 1000);   // le temps qu'on attend entre deux gradients
      pasDuPwm = random(1, 10);               // vitesse de progression du PWM
      deltaT = random(5, 20);                 // durée d'attente entre deux changements de PWM
    }

la génération aléatoire a lieu au début d'un cycle (après une phase d'allumage et extinction)

A l'époque j'avais fait ça, je peux te le refaire avec des LED "normales"

Cordialement
jpbbricole

OH ! alors la !
je ne sais pas comment vous remercier !
C'est exactement ce que je cherchais !
Je vais faire mes essais en changeant les valeurs

mais encore mille merci !!

on attend le petit film du système en place :slight_smile:

bonne continuation

Bonsoir;

Pour avoir fait déja plusieur essais de gradation de lumiére avec des LED, j'ai constaté que l'effet PWM (si on peut l'appeler ainsi) n'est pas fameux s'il est utilisé de façon linéaire.

La caractéristique d'une diode n'est pas une droite (Idiode en fonction de Vdiode est exponentiel, si on augmente un peu Vd, ou augmente beaucoup Id et la puissance de la diode.

Donc si on gére la valeur moyenne de Vd par un PWM, il ne faut pas croire que entre à et 255, la puissance d'éclairage de la diode va varier linairement.
Genre
0= éteinte
64= 1/4 de puissance
127= 2/4 de puissance
190= "/4 de puissance
255 = pleine puissance

Ce sera plutôt
0= éteinte
64= 0,5/4 de puissance
127= 1/4 de puissance
190= 2/4 de puissance
255 = pleine puissance

Si on n'en tient pas compte, on peut-etre vite décut du résultat., surtout pour un effet theatrale je crois.

le mieux est de faire des essais avec différente valeur de PWM et de définir une map (carte des valeurs)
330px-Diode-IV-Curve.svg

oui

il suffit de faire une petite fonction qui va prendre le PWM théorique entre 0 et 255 et qui va le modifier pour qu'il soit représentatif de la luminosité souhaitée

Bonjour,

Effectivement la variation de la luminosité perçue est logarithmique. Mais je ne pense pas que ce soit du principalement du à la caractéristique de la led car avec le pwm la tension n'augmente pas quand le rapport cyclique augmente.

C'est du à une loi physiologique qui dit que la sensation est proportionnelle au logarithme de l'excitation (c'est pour ça que par exemple pour le son on utilise des potentiomètres logarithmiques).
Quand je veux une variation lumineuse ressentie (à peu près) linéaire je multiplie le rapport cyclique par deux entre chaque échelon
0,1,2,4,8,16,32,64,128,255
Si on veut une variation plus fine on peut multiplier par racine(2) ce qui donne
0,1,2,3,4,6,8,11,16,...
Mais en général la première série de valeurs suffit.

1 Like

Je ne mets pas en doute vos compétences sur le ressenti.

Mais pour info, un signal PWM est un signal à frrequence constante, c'est le rapport cyclique qui varie.

Et avec le rapport cyclique, la valeur moyenne du signal, donc la valeur moyenne de la tension qui alimente les LED.

Bien entendu, a faible fréquence, vous verrez la LED s'alumer et s'éteindre.

Mais il me semble qu'à haute fréquence, c'est la valeur moyenne qui est perceptible.

C'est cela la subtilité du PWM non?

@kamill
@anon96738448
svp, arrêtez de vous battre : vous dites la même chose !
DIAPH-F-NOMBRE
que ce soit en optique ou en audio, les rapports qui donnent un "ressenti par l'humain" sont tous régis par une fonction mathématique qui fait intervenir un coefficient "2" ou "racine de 2" ...
vous avez tous les deux raison ... et tort ... dans votre antagonisme ! ...

Je revenais juste sur une loi mathématique que beaucoup de ceux qui découvrent les joies de l'Arduino n'ont pas forcément perçut.

La valeur MOYENNE d'un signal PWM varie avec le rapport cyclique du signal.

C'est la caractéristique principale d'un signal PWM.

A cela s'ajoute le filtre physiologique de l'oeil humain (que je ne conteste absolument pas).

Il y a donc 2 VARIABLES à ne pas négliger qui créent l'effet variation de lumiére.

Si vous utilisez un PWM pour alimenter une LED, à très basse fréquence, (par exemple à 0,1Hz) vous percevrait les valeurs crêtes et leurs durées.

A haute fréquence, et selon votre filtre physio perso, (ET celui de la LED), vous ne percevrait que la valeur moyenne.

Là c'est trés bien expliqué pour celui qui veut faire un effet trés "pro" à sa variation de lumiére.

https://arduino-france.site/pwm-arduino/

La led n'est pas alimentée par une tension moyenne. Il suffit de connecter un oscillo aux bornes pour s'en rendre compte.
C'est l'oeil qui intègre la luminosité et la luminosité perçue est une valeur "moyenne".

Tout à fait - la led clignote

" La led n'est pas alimentée par une tension moyenne. Il suffit de connecter un oscillo aux bornes pour s'en rendre compte. C'est l'oeil qui intègre la luminosité et la luminosité perçue est une valeur "moyenne".

Vous avez tout dit, sans vous en rendre compte.

Intégrer (mathématiquement parlant) un signal périodique de fréquence variable donnera toujours la même valeur moyenne quelle que soit la valeur de la fréquence, OK?

Intégrer (mathématiquement parlant) un signal périodique de rapport cyclique variable donnera une valeur moyenne variable en fonction du rapport cyclique, OK?

Donc c'est ce que je voulais vous faire comprendre, C'est l'oeil ET LE RAPPORT CYCLIQUE du PWM qui alimente les LED qui donnent la sensation d'une lumiére variable.

Il ne faut pas le négliger.

[PS: l'intégrale d'un signal périodique, c'est sa valeur moyenne]

La discutions est intéressante, même si au final je ne sais si @kamill et @anon96738448 ne disent pas la même chose ?

@anon96738448 de ce que je comprends de la remarque de @kamill, c'est qu'il prévient de faire attention car un facteur 2 sur le rapport cyclique, n'implique pas le même facteur sur le ressentie de la puissance d'éclairage de la LED.

Si j'ai pas compris, je veux bien que tu me réexplique @kamill :laughing:

Salut.
JeanFranc, calme toi un peu.
Si tu penses expliquer à un des piliers du forum depuis de nombreuses années, j'ai nommé kamill, ce qu'est le PMW et la persistance rétinienne, passe ton chemin.

@terwal
Oui je crois que @kamill et moi sommes à peu prés sur la même longueur d'onde.

Si je me permet d'insister sur ces points, ce n'est pas pour les pilliers qui j'ai bien compris savent déja tout cela, et même plus que je n'en sais.

Mais beaucoup de gens qui découvrent l'électronique, le PWM, les LED ne connaissent pas ces petites subtilité qu'il est interessant parfois de comprendre quand on ne veut pas faire que du "0 ou 1", "ouvert ou fermé", "bloqué ou passant".

Et selon le projet, c'est interessant de developper certains points.

Par exemple ici la non linéarite des LED, le rapport cyclique du PWM, la persistance rétinienne.

(Ce n'est pas une atteinte aux pilliers du forum (comme le pense @hbachetti), c'est juste un apport de connaissance qui peuvent servir au projet de @iTooms je crois)

PS: @terwal un rapport 2 sur la rapport cyclique est aussi +/- influencé par la non linearité de la LED.

Peut-être il faut s'entendre sur les définitions

La non-linéarité d'une LED se réfère généralement au fait que la relation entre la tension (ou le courant) appliquée à la LED et la luminosité résultante n'est pas proportionnelle de manière constante (linéaire). En d'autres termes, de petites variations dans la tension ou le courant ne produiront pas nécessairement des variations équivalentes dans la luminosité émise.

Certes la caractéristique courant-tension d'une LED est généralement modélisée comme une courbe exponentielle : à des tensions ou courants plus faibles, la LED peut ne pas émettre de lumière du tout. Ensuite, à mesure que la tension ou le courant augmente, la luminosité de la LED augmentera, mais pas de manière linéaire.

Cependant ici on parle de PWM et donc on ne parle pas de tension variable, la LED est toujours sous 5V ou 0V ➜ donc quand elle est allumée — quel que soit le rapport cyclique — la luminosité est identique.

C'est le phénomène de persistance rétinienne (lié à la fréquence élevée du PWM - 490 ou 980 Hz sur UNO suivant les pins) qui fait que l'on voit la LED constamment allumée, l'oeil percevant une luminosité liée au rapport de tout éteint et tout allumé.

Ce que tout le monde dit ici, c'est que l'évolution de cette luminosité perçue n'est pas linéaire avec le PWM.

Ce que dit @kamill en exprimant que la sensation est proportionnelle au logarithme de l'excitation. donc dans mon code au lieu de faire

ou

je devrais faire une multiplication ou division pour en tenir compte.

J'ai compris le probléme, beaucoup considérent que le PWM est un signal à fréquence variable, hors c'est faux.

Moi je suis de nature très bordélique, mais quand 1 informaticien (qui selon moi est quelqu'un de très rigoureux) écrit
"la LED est toujours sous 5V ou 0V" je dis que c'est incohérent.

Avec un PWM, la led est pendant (mais pas toujours) un temps aT sous 5V et (1-a)T sous 0V, avec T la période CONSTANTE du PWM et "a" variant de 0 à 1 par ligne de commande.

SI "a" tend vers 0.
C'est un signal de période constante et de faible largeur qui sera peu visible par l'oeil.
Et la VALEUR MOYENNE tend vers 0

SI "a" tend vers 1.
C'est un signal de période constante et de grande largeur qui sera bien visible par l'oeil.
Et la VALEUR MOYENNE tend vers 5V.

Traduisez cela comme vous voulez, LAIS en tenant compte que la fréquence du KWL est CONSTANTE, et SA VALEUR MOYENNE varie.

Je ne peux pas dire mieux.

Je veux bien faire des mesures bricoles avec les petits tiroirs, mais en ce moment je suis nomade et j'ai vudé ceux-ci, et je crois que le dernier MIS qui me reste (pour commander une LED un peu puissante) est HS.

Pour mesurer l'eclairement, il y a bien des appli, il faut je crois mesurer des lumens lais pas des lux.

Dites moi et je fais une petite manip adéquate pas de soucis, je sais faire le code, l'électronique)

Merci de nous expliquer ce qu'est le pwm. :laughing:
Je pense que personne sur ce forum (peut être à part quelques noobs) ne pense que le pwm est à fréquence variable.

C'est simplifié. C'est l'ensemble led+résistance qui est à (environ) 0 ou 5V.
C'est tellement évident que la tension sera 0 pendant la partie de la période ou le signal est à LOW et à 5V pendant la partie de la période il est à HIGH que @J-M-L n'a pas cru bon de le préciser.