Comprendre et manipuler un signal PWM avec Arduino
Do not index
Do not index
Hide CTA
Hide CTA
Video preview

Objectifs

Manipulation d’une LED RGB au travers d’un signal PWM à l’aide d’une Arduino.

Explications

L’étude d’un signal PWM a de nombreuse application et dans cette première vidéo sur le sujet nous explorons comment utiliser les ports réservé de l’Arduino qui permettent l’émission d’un signal PWM et s’en servir pour contrôler une LED RGB.

Premiere partie : contrôles basiques

Dans la première partie de la vidéo, nous effectuons un contrôle élémentaire de la LED pour passer en revue les bases du concept du signal PWM.
//Declaration des 3 ports PWM correspondant à chaque couleur
int redpin = 11;
int greenpin = 10;
int bluepin = 9; 
//Utiliser dans la boucle principal pour interpreter la couleur à emettre
int redLevel = 0;
int greenLevel = 0;
int blueLevel = 0;
//Valeur de la quantité de lumiere emise par la LED correspondante
int redAmount = 0;
int greenAmount = 0;
int blueAmount = 0;
void setup() {
  //Initialiation de la communication série
  Serial.begin(9600);
  //Parametrage des ports en mode SORTIE
  pinMode(redpin, OUTPUT);
  pinMode(greenpin, OUTPUT);
  pinMode(bluepin, OUTPUT);
  
  //On commence par eteindre completement la LED
  analogWrite(redpin, 0);
  analogWrite(greenpin, 0);
  analogWrite(bluepin, 0);
  
}

void loop() 
{
  //Boucle pour naviguer entre 3 niveaux de rouge
  for(redLevel = 0; redLevel < 3; redLevel++){
    //Conversion du niveau de rouge en valeur analogique comprise entre 0 et 255
    redAmount = map(redLevel, 0, 2, 0, 255);
    //Boucle pour naviguer entre 3 niveaux de vert
    for(greenLevel = 0; greenLevel < 3; greenLevel++){
      //Conversion du niveau de vert en valeur analogique comprise entre 0 et 255
      greenAmount = map(greenLevel, 0, 2, 0, 255);
      //Boucle pour naviguer entre 3 niveaux de bleue
      for(blueLevel = 0; blueLevel < 3; blueLevel++){
        //Conversion du niveau de bleu en valeur analogique comprise entre 0 et 255
        blueAmount = map(blueLevel, 0, 2, 0, 255);
        //On envoie sur le moniteur serie la valeur actuelle de chaque couleur
        Serial.print("R:");
        Serial.print(redAmount);
        Serial.print(" G:");
        Serial.print(greenAmount);
        Serial.print(" B:");
        Serial.println(blueAmount);
        //On ecrit la valeur analogique sur les ports de l'Arduino
        analogWrite(redpin, redAmount);
        analogWrite(greenpin, greenAmount);
        analogWrite(bluepin, blueAmount);
        //Pause de 500ms avant de passer à la couleur suivante
        delay(500);
      }
    }
  }
}

Seconde partie : Pouvoirs psychédéliques

Dans la seconde partie, je fais évoluer le code pour proposer plusieurs fonctions clés en main pour se servir d’une LED RGB de manière plus rapide et efficace. Pour la démo finale et la vision psychédélique de mes joyeux dessins feutrés, je fais l’exploitation de toutes ces fonctions plus avancées pour le plaisir de vos yeux. Attention, personnes sensibles aux crises d’épilepsie, s’abstenir !
int redpin = 11;
int greenpin = 10;
int bluepin = 9; 
//Déclaration d'une structure pour stocker une couleur sous ses 3 composants rouge, vert, bleu.
struct RGB {
   byte r;
   byte g;
   byte b;
};
//Facilite le parametrage d'une variable de type RGB
RGB getColor(byte red, byte green, byte blue){
  RGB new_color;
  new_color.r = red;
  new_color.g = green;
  new_color.b = blue;
  return new_color;
}
//Applique a la LED le signal correspondant à une couleur fournit en parametre
void applyColor(RGB color){
  analogWrite(redpin, color.r);  //Applique un signal PWM pour le rouge
  analogWrite(greenpin, color.g); //Applique un signal PWM pour le vert
  analogWrite(bluepin, color.b); //Applique un signal PWM pour le bleu
}
//Eteint la LED
void switchOff(){
  analogWrite(redpin, 0);
  analogWrite(greenpin, 0);
  analogWrite(bluepin, 0);
}
//Attend une seul couleur et permet de faire clignoter la LED 
void flashOneColor(RGB color, int count_flash=1, int up_delay=150, int down_delay=150){
  for(int i = 0; i < count_flash; i++){
    applyColor(color);
    delay(up_delay);
    switchOff();
    delay(down_delay);
  }
}
//Permet de faire clignoter la LED dans des couleurs aléatoires
void flashRandomColor(int count_flash=1, int up_delay=150, int down_delay=150){
  RGB next_color;
  
  for(int i = 0; i < count_flash; i++){
    next_color.r = random(0,255);
    next_color.g = random(0,255);
    next_color.b = random(0,255);
    
    applyColor(next_color);
    delay(up_delay);
    switchOff();
    delay(down_delay);
  }
}
//Attend un tableau de couleurs et permet de faire clignoter la LED en faisant une rotation des couleurs du tableau.
void flashCycleColor(RGB cycle_color[], int size_cycle, int count_cycle=1, int up_delay=150, int down_delay=150){
  for (int c = 0; c < count_cycle; c++){
    for (byte i = 0; i < size_cycle; i++) {
      applyColor(cycle_color[i]);
      delay(up_delay);
      switchOff();
      delay(down_delay);
    }
  }
}
//Permet de faire une transition progressive entre 2 couleurs sur une periode de temps donné.
void twoColorTransition(RGB from_color, RGB to_color, int action_delay=1000){
  RGB current_color;
  //Calcule de la difference entre la couleur de destination et la couleur de point de départ
  long red_diff = from_color.r - to_color.r;
  long green_diff = from_color.g - to_color.g;
  long blue_diff = from_color.b - to_color.b;
  //Variable d'interuption de la boucle while ci dessous
  bool transitionProcess = true;
  //Variable utile pour le calcul du pourcentage de progression entre la couleur d'origine et la couleur de destination
  long elapsed_time = 0;
  long start_time = millis();
  //Commence la transition entre les 2 couleurs
  while(transitionProcess){
    //On regarde combien de temps s'est ecoulé depuis le lancement de la fonction de transition
    elapsed_time = millis() - start_time;
    //Si le temps ecoulé est supérieure au delai de l'action de transition, alors inutile de continuer
    if(elapsed_time >= action_delay){
       transitionProcess = false;
       elapsed_time = action_delay;
    }
    //ici on applique la proportion de temps ecoulé au temps ciblé pour savoir a quel niveau devrai etre la LED
    int red_add = (((double)elapsed_time / (double)action_delay) * (double)red_diff) * (-1.0);
    int green_add = (((double)elapsed_time / (double)action_delay) * (double)green_diff) * (-1.0);
    int blue_add = (((double)elapsed_time / (double)action_delay) * (double)blue_diff) * (-1.0);
    //On applique les corrections calculées a l'étape precedente a la couleur d'origine
    current_color.r = from_color.r + red_add;
    current_color.g = from_color.g + green_add;
    current_color.b = from_color.b + blue_add;
    //On applique la nouvelle couleur sur la LED
    applyColor(current_color);
    //On attend 17ms, (Correspond grossierement à une frequence de rafraichissement de 70 Hz)
    delay(17);
  }
}
//Declaration d'un lot de 5 couleurs de type RGB
RGB color_red;
RGB color_yellow;
RGB color_green;
RGB color_cyan;
RGB color_blue;
RGB color_purple;
RGB color_black;
RGB color_white;
//Declaration de tableau de type RGB pour stoker des cycles de couleur
RGB cycle_color_RYGCBP[6];
RGB cycle_color_RBG[3];
RGB cycle_color_RGBG[4];
RGB cycle_color_RBGB[4];
void setup() {
  Serial.begin(9600);
  randomSeed(analogRead(0));
  color_red = getColor(255, 0, 0);
  color_yellow = getColor(255, 2555, 0);
  color_green = getColor(0, 255, 0);
  color_cyan = getColor(0, 255, 255);
  color_blue = getColor(0, 0, 255);
  color_purple = getColor(255, 0, 255);
  color_black = getColor(0, 0, 0);
  color_white = getColor(255, 255, 255);
  cycle_color_RYGCBP[0] = color_red;
  cycle_color_RYGCBP[1] = color_yellow;
  cycle_color_RYGCBP[2] = color_green;
  cycle_color_RYGCBP[3] = color_cyan;
  cycle_color_RYGCBP[4] = color_blue;
  cycle_color_RYGCBP[5] = color_purple;
  cycle_color_RGBG[0] = color_red;
  cycle_color_RGBG[1] = color_green;
  cycle_color_RGBG[2] = color_blue;
  cycle_color_RGBG[3] = color_green;
  cycle_color_RBGB[0] = color_red;
  cycle_color_RBGB[1] = color_blue;
  cycle_color_RBGB[2] = color_green;
  cycle_color_RBGB[3] = color_blue;
  applyColor(color_white);
  delay(5000);
}
void loop() {
  /*flashRandomColor(50, 75, 75);
  switchOff();
  delay(2000);
  
  flashCycleColor(cycle_color_RYGCBP, 6, 10, 500, 150);
  switchOff();
  delay(2000);
  flashOneColor(color_green, 50, 75, 75);
  switchOff();
  delay(2000);*/
  for(byte i = 0; i < 10; i++){
    twoColorTransition(color_red, color_yellow, 30);
    twoColorTransition(color_yellow, color_green, 30);
    twoColorTransition(color_green, color_cyan, 30);
    twoColorTransition(color_cyan, color_blue, 30);
    twoColorTransition(color_blue, color_purple, 30);
    twoColorTransition(color_purple, color_red, 30);
  }
  switchOff();
  delay(200);
  
  for(byte i = 0; i < 10; i++){
    twoColorTransition(color_red, color_green, 55);
    twoColorTransition(color_green, color_blue, 55);
    twoColorTransition(color_blue, color_red, 55);
  }
  switchOff();
  delay(200);
  for(byte i = 0; i < 10; i++){
    twoColorTransition(color_red, color_green, 75);
    twoColorTransition(color_green, color_blue, 75);
    twoColorTransition(color_blue, color_red, 75);
  }
  switchOff();
  delay(200);
  for(byte i = 0; i < 10; i++){
    twoColorTransition(color_red, color_green, 95);
    twoColorTransition(color_green, color_blue, 95);
    twoColorTransition(color_blue, color_red, 95);
  }
  switchOff();
  delay(200);
  for(byte i = 0; i < 10; i++){
    twoColorTransition(color_red, color_green, 115);
    twoColorTransition(color_green, color_blue, 115);
    twoColorTransition(color_blue, color_red, 115);
  }
  switchOff();
  delay(200);
  for(byte i = 0; i < 10; i++){
    twoColorTransition(color_red, color_green, 135);
    twoColorTransition(color_green, color_blue, 135);
    twoColorTransition(color_blue, color_red, 135);
  }
  switchOff();
  delay(1000);
  for(byte i = 0; i < 10; i++){
    twoColorTransition(color_red, color_blue, 115);
    twoColorTransition(color_blue, color_green, 115);
    twoColorTransition(color_green, color_red, 115);
  }
  switchOff();
  delay(200);
  for(byte i = 0; i < 10; i++){
    twoColorTransition(color_red, color_blue, 135);
    twoColorTransition(color_blue, color_green, 135);
    twoColorTransition(color_green, color_red, 135);
  }
  switchOff();
  delay(1000);
  for(byte i = 0; i < 10; i++){
    twoColorTransition(color_red, color_blue, 55);
    twoColorTransition(color_blue, color_red, 55);
  }
  switchOff();
  delay(200);
  
  for(byte i = 0; i < 10; i++){
    twoColorTransition(color_red, color_blue, 115);
    twoColorTransition(color_blue, color_red, 115);
  }
  switchOff();
  delay(200);
  for(byte i = 0; i < 10; i++){
    twoColorTransition(color_red, color_blue, 135);
    twoColorTransition(color_blue, color_red, 135);
  }
  switchOff();
  delay(1000);
  for(byte i = 0; i < 10; i++){
    twoColorTransition(color_red, color_green, 55);
    twoColorTransition(color_green, color_red, 55);
  }
  switchOff();
  delay(200);
  
  for(byte i = 0; i < 10; i++){
    twoColorTransition(color_red, color_green, 115);
    twoColorTransition(color_green, color_red, 115);
  }
  switchOff();
  delay(200);
  for(byte i = 0; i < 10; i++){
    twoColorTransition(color_red, color_green, 135);
    twoColorTransition(color_green, color_red, 135);
  }
  switchOff();
  delay(1000);
  for(byte i = 0; i < 10; i++){
    twoColorTransition(color_blue, color_green, 55);
    twoColorTransition(color_green, color_blue, 55);
  }
  switchOff();
  delay(200);
  
  for(byte i = 0; i < 10; i++){
    twoColorTransition(color_blue, color_green, 115);
    twoColorTransition(color_green, color_blue, 115);
  }
  switchOff();
  delay(200);
  for(byte i = 0; i < 10; i++){
    twoColorTransition(color_blue, color_green, 135);
    twoColorTransition(color_green, color_blue, 135);
  }
  switchOff();
  delay(1000);
  flashCycleColor(cycle_color_RGBG, 4, 10, 55, 55);
  switchOff();
  delay(200);
  flashCycleColor(cycle_color_RBGB, 4, 10, 55, 55);
  switchOff();
  delay(200);
  flashCycleColor(cycle_color_RGBG, 4, 10, 100, 100);
  switchOff();
  delay(200);
  flashCycleColor(cycle_color_RBGB, 4, 10, 100, 100);
  switchOff();
  delay(200);
  flashCycleColor(cycle_color_RYGCBP, 6, 10, 100, 100);
  switchOff();
  delay(200);
  flashCycleColor(cycle_color_RYGCBP, 6, 10, 50, 50);
  switchOff();
  delay(1000);
}
Cyril

Written by

Cyril

Hobbyiste en électronique, programmation et IA