Sketch pour ruban rgb

programmation

a marqué ce sujet comme résolu.

Bjr, Nouveau dans le monde de la programmation, je me suis mis à étudier le langage C++ pour commander des modules Arduino(ou autres). J’épluche depuis 2 mois tous les tutos, les cours que je trouve très bien fait (vraiment bravo) et je pensais pouvoir avancer mais là je bloque :euh: Je m’explique: je cherche à allumer une led rgb (cathode C) sur une couleur définie avec un effet brightness au début et en fin. Pour ça je suis partie de 2 codes qui fessait chacun une fonction (l’un allume une couleur, l’autre allume une led avec un brightness. voici les codes:

const int PIN_RED   = 9;
const int PIN_GREEN = 11;
const int PIN_BLUE  = 10;

void setup() {
  pinMode(PIN_RED,   OUTPUT);
  pinMode(PIN_GREEN, OUTPUT);
  pinMode(PIN_BLUE,  OUTPUT);
}

void loop() {
  // color code Red
  analogWrite(PIN_RED,   255);
  analogWrite(PIN_GREEN, 0);
  analogWrite(PIN_BLUE,  0);

  delay(1000); // keep the color 1 second

  // color code Green
  analogWrite(PIN_RED,   0);
  analogWrite(PIN_GREEN, 255);
  analogWrite(PIN_BLUE,  0);

  delay(1000); // keep the color 1 second

  // color code Blue
  analogWrite(PIN_RED,   0);
  analogWrite(PIN_GREEN, 0);
  analogWrite(PIN_BLUE,  255);

  delay(1000); // keep the color 1 second
}
et
int  led = 9; // la broche PWM à laquelle la LED est attachée 
int brightness = 0; // la luminosité de la LED 
int fadeAmount = 5; // de combien de points doit faire disparaître la LED 

// la routine de configuration s'exécute une fois lorsque vous appuyez sur reset : 
void  setup () { 
  // déclare la broche 9 comme une sortie : 
  pinMode ( led , OUTPUT ); 
} 

// la routine de boucle s'exécute encore et encore pour toujours : 
void  loop () { 
  // définit la luminosité de la broche 9 : 
  analogWrite ( led , brightness); 

  // changer la luminosité pour la prochaine fois dans la boucle : 
brightness = brightness + fadeAmount; 

  // inverse le sens du fondu aux extrémités du fondu : 
  if (brightness <= 0 || brightness >= 255) { 
fadeAmount = -fadeAmount; 
} 
  // attendez 30 millisecondes pour voir le effet de gradation 
  delay(30) ; 
} 
Après nombreuses tentatives, je n'arrive pas comment insérer le brightness dans le 1er code ou inversement.
Je sais que je suis ridicule mais ça c'est pas grave car je pense faire un pas si je comprends ça.
Alors je m'en remet à vous car je ne veux pas copier des codes mais pouvoir les articuler comme je veux.

Si je comprends bien, tu veux passer d’une couleur à l’autre avec une transition?

Comme une arduino ne peut faire qu’une chose à la fois, il va falloir arrêter d’utiliser delay, car si elle attend, elle ne peut pas changer la luminosité d’une LED.

Il faut donc trouver un moyen d’attendre un certain temps, sans delay

Il est donc intéressant de connaître l’instant actuel. Pour cela, il y a les fonctions millis() et micros() qui renvoient le temps écoulé depuis l’allumage de l’arduino en millisecondes et microsecondes respectivement.

On peut donc faire ce type de programmes, avec une machine à états:

int state = 0;
unsigned long lastChange = 0;
int brightness = 0;
millis()
void loop() {
  unsigned long now = millis();

  // Chaque état
  if (state == 0) { // Allumage de la led rouge
    analogWrite(RED, brightness);
    if (now % 3 == 0) brightness++;
    
    if (brightness == 255) { // changement d'état
      state++;
      lastChange = now;
    }
    
  } else if (state == 1) { // Maintien de la led rouge
    // ne rien faire, elle est déjà allumée
    
    // changement d'état
    // inégalité car le code n'est pas appelé toutes les millisecondes
    // on pourrait donc rater l'instant d'égalité
    if (now - lastChange >= 30) { 
      state++;
      lastChange = now;
    }
    
  } else if (state == 2) { // Extinction de la led rouge
    if (now % 3 == 0) brightness--;
    analogWrite(RED, brightness);
    
    if (brightness == 0) { // changement d'état
      state++;
      lastChange = now;
    }
    
  } else if (state == 3) { // Allumage de la led verte
    if (now % 3 == 0) brightness++;
    analogWrite(GREEN, brightness);
    
    if (brightness == 255) { // changement d'état
      state++;
      lastChange = now;
    }
    
  } else if (state == 4) { // Maintien de la led verte
    // ne rien faire, elle est déjà allumée
    
    // changement d'état
    // inégalité car le code n'est pas appelé toutes les millisecondes
    // on pourrait donc rater l'instant d'égalité
    if (now - lastChange >= 30) { 
      state++;
      lastChange = now;
    }
    
  } else if (state == 5) { // Extinction de la led verte
    if (now % 3 == 0) brightness--;
    analogWrite(GREEN, brightness);
    
    if (brightness == 0) { // changement d'état
      state = 0; // retour au début
      lastChange = now;
    }
  }
}

EDIT: La ligne 4 est en trop, millis() ne devrait pas être présent à cet endroit là.

+0 -0

Merci Amael pour ton aide. je comprends ton idée avec l’utilisation de la fonction millis(). Par contre après avoir intégré ton bout de code, le compilateur m’indique une erreur. voilà comment j’ai fait :o

const int PIN_RED   = 9;
const int PIN_GREEN = 11;
const int PIN_BLUE  = 10;


void setup() {
  pinMode(PIN_RED,   OUTPUT);
  pinMode(PIN_GREEN, OUTPUT);
  pinMode(PIN_BLUE,  OUTPUT);
}

int state = 0;
unsigned long lastChange = 0;
int brightness = 0;
millis()
void loop() {
  unsigned long now = millis();

  // Chaque état
  if (state == 0) { // Allumage de la led rouge
    analogWrite(PIN_RED, brightness);
    if (now % 3 == 0) brightness++;
    
    if (brightness == 255) { // changement d'état
      state++;
      lastChange = now;
    }
    
  } else if (state == 1) { // Maintien de la led rouge
    // ne rien faire, elle est déjà allumée
    
    // changement d'état
    // inégalité car le code n'est pas appelé toutes les millisecondes
    // on pourrait donc rater l'instant d'égalité
    if (now - lastChange >= 30) { 
      state++;
      lastChange = now;
    }
    
  } else if (state == 2) { // Extinction de la led rouge
    if (now % 3 == 0) brightness--;
    analogWrite(PIN_RED, brightness);
    
    if (brightness == 0) { // changement d'état
      state++;
      lastChange = now;
    }
    
  } else if (state == 3) { // Allumage de la led verte
    if (now % 3 == 0) brightness++;
    analogWrite(PIN_GREEN, brightness);
    
    if (brightness == 255) { // changement d'état
      state++;
      lastChange = now;
    }
    
  } else if (state == 4) { // Maintien de la led verte
    // ne rien faire, elle est déjà allumée
    
    // changement d'état
    // inégalité car le code n'est pas appelé toutes les millisecondes
    // on pourrait donc rater l'instant d'égalité
    if (now - lastChange >= 30) { 
      state++;
      lastChange = now;
    }
    
  } else if (state == 5) { // Extinction de la led verte
    if (now % 3 == 0) brightness--;
    analogWrite(PIN_GREEN, brightness);
    
    if (brightness == 0) { // changement d'état
      state = 0; // retour au début
      lastChange = now;
    }
  }
}

Effectivement, je n’ai pas essayé de compiler mon code, il y a une ligne en trop, la 4 dans mon code et la 15 dans le tien.

C’est d’ailleurs ce que le compilateur indique dans ses erreurs:

sketch_dec13a:16:1: error: expected constructor, destructor, or type conversion before 'void'
   16 | void loop() {
      | ^~~~
exit status 1
expected constructor, destructor, or type conversion before 'void'

Ici il pointe le début de la ligne 16, donc l’erreur se trouve autour de la ligne 16. Ici, ligne 15.

+1 -0

Slt Amael, après modif ton code fonctionne bien, merci!

Ce que je comprends:

  • millis(); est un "top" compteur (que tu appelles "now") qui tourne tout le temps.
  • Tu crées des états (6), état1:j’allume, état2:je maintien allumé, état3: j’éteins,…etc).
  • Dans un état, une fois la condition remplie, tu passes à l’état suivant.

On peut donc modifier le temps de maintien allumé avec cette ligne:

if (now - lastChange >= 30) { state++; j’ai mis 1000 (1s) pour passer à l’état suivant.

Par contre je ne comprends pas bien le début de cette ligne:if (now % 3 == 0) brightness++;

Je constate aussi que le Brightness ne se voit pas!

Comment faire pour contrôler dans le temps la progression de l’incrémentation positive (ou négative) de la valeur brightness? Avec "fadeAmount" peut-être?

Slt Amael, après modif ton code fonctionne bien, merci!

Ce que je comprends:

  • millis(); est un "top" compteur (que tu appelles "now") qui tourne tout le temps.
  • Tu crées des états (6), état1:j’allume, état2:je maintien allumé, état3: j’éteins,…etc).
  • Dans un état, une fois la condition remplie, tu passes à l’état suivant.

On peut donc modifier le temps de maintien allumé avec cette ligne:

if (now - lastChange >= 30) { state++; j’ai mis 1000 (1s) pour passer à l’état suivant.

C’est bien ça.

Par contre je ne comprends pas bien le début de cette ligne:if (now % 3 == 0) brightness++;

Je constate aussi que le Brightness ne se voit pas!

Comment faire pour contrôler dans le temps la progression de l’incrémentation positive (ou négative) de la valeur brightness? Avec "fadeAmount" peut-être?

tts06

L’objectif est de n’incrémenter brightness que pour les millisecondes multiples de 3, pour obtenir la même progression que dans ton scriptqui incrémente de 5 toutes les 30ms.

Le souci, c’est que le code est exécuté plusieurs fois par ms, et donc que brightness est incrémenté plein de fois…

C’est pour ça que le changement de brightness ne se voit pas. Il pourrait être intéressant d’ajouter un état pour incrémenter une seule fois par ms.

+0 -0

Dsl Amael mais je n’arrive pas à incrémenter le brightness sur 1s (par exemple)

L’objectif est de n’incrémenter brightness que pour les millisecondes multiples de 3, pour obtenir la même progression que dans ton scriptqui incrémente de 5 toutes les 30ms.>

Je me demande si l’utilisation de (millis) me complique pas le code pour ce que je veux faire et mon niveau de programme.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte