dimanche 23 mars 2014

contrôle d'une bande LED RVB par un arduino mini

Après plusieurs semaines d'hésitation, je me lance pour un premier article! Au menu:

le contrôle d'une bande LED RVB par un arduino mini .

Le cahier des charges:

edit du 03/05/14: mise à jour du code pour corriger un bug, et ajout d'un delay() pour le mode automatique qui passe en mode 'par défaut'

- suffisamment petit et discret pour être intégré dans un meuble
- offrir plusieurs modes de fonctionnement :
          - un automatique, qui faite varier lentement toutes les couleurs
          - un manuel qui permet de choisir sa couleur
          - un sonore qui transforme le salon en discothèque.... (en cours de développement)
          - un 'blanc' qui permet d'utiliser la bande led comme source de lumière
          - un OFF
- fonctionner avec tout type de bandes LED RVB à cathode commune (un +, 3 masses...)

Choix des composants

Le montage va s'articuler autours d'un arduino, d'une carte électronique que nous allons fabriquer, et d'un bloc alim 12V de récup. Attention à l'ampérage! pour une bande de 2 mètres, compter 1,5 à 2A.

le bandeau LED est alimenté en 12V via des transistor de type BC547. Attention, ils conviennent pour un maximum de 100mA: pas de problème avec 2 ou 3 mètres de bandeau LED mais au delà.... vous risquez de voir vos transistors partir en fumée!

Schéma

Le cahier des charges imposait une petite taille.  Le schéma est simpliste, et s'articule autours d'un arduino mini pro. Pour info, ça fonctionne pareille avec un arduino uno. Les composants peuvent être remplacés par des valeurs approchantes et les transistors par n'importe quel type de "grand classique", comme un 2N2222.
Vous verrez que mon montage combine les deux..... récup oblige!



Il n'est pas utile d'insérer une résistance au niveau du collecteur des transistors car les bandeaux contiennent déjà ce qu'il faut.

Réalisation

La carte contient 3 connecteur:
- un pour le bandeau LED (il s'agit d'un connecteur d'alimentation récupéré sur vieux lecteur de disquette)
- un pour l'alimentation 12V
- un pour de futures extensions, notamment la partie "son"

Quelques photos:

vues sans l'arduino mini:


 Vues avec l'arduino mini:





Partie programmation

Les fonctions complexes sont déclarées au préalable par un void(). Le Loop() permet de contrôler l'état du bouton et d'appeler la fonction void() correspondante.

fonction "variation automatique" Void Automatique()

Je ne rentrerais pas dans les explications car elles sont dispo à l'aresse : Variation RGB by Jojo Bricolo  http://www.proftnj.com/RGB3.htm . Je me suis largement inspiré de son projet pour l'automatisme. Je le remercie, grâce à lui, pas besoin de réinventer la roue!

fonction "choix de couleur"  Void Potentiometre ()

la fonction potentiomètre permet de choisir la couleur du bandeau en faisant varier le potentiomètre


fonction "son" : en cours de développement....

les fonction "blanc" et "off" sont directement implémentées dans le loop.

Une communication série est mise en place pour les petits curieux, ou pour déboguer le programme...

Code:

/* Controle bandeau RGB
 visitez mon blog  http://alexelec52.blogspot.com
 */


// Définition des broches
int ledRouge = 5;
int ledVerte = 6;
int ledBleu = 3;

// Broche potentiomètre
int Tmpin = A1;
int TmpVal; // Mesure de tension du potentiomètre

// Switch
int switchPin = A2;  // broche du switch
int switchState = 0;
int switchTemp = 0;

int prevSwitchState = 0;

// variable du mode de fonctionnement
int mode = 0;

// Variable des leds
byte RougeVal = 0;
byte VertVal = 0;
byte BleuVal = 0;


void setup()
{

  Serial.begin (9600);

  pinMode(ledRouge, OUTPUT);
  pinMode(ledVerte, OUTPUT);
  pinMode(ledBleu, OUTPUT);

}


// *****************************************************
// *****************************************************

void Automatique(){
  //while ((digitalRead (switchPin) == LOW)){

  if (switchTemp = HIGH) {

    for (int i=0; i<=1024; i++) { // défile valeur 0 à 1024

      Serial.println (i);

      delay (100);

      switchTemp = digitalRead (switchPin);

      if (switchTemp == LOW){

        // Mélange rouge vert

        if (i > 0 && i < 170) { // si la valeur de la TMP est supérieur a 0 et inférieur a 170
          RougeVal = 255; // Rouge au max
          //BleuVal = 0; // bleu a 0 avec possibilité d'en rajouter un peu valeur a donner entre 0 et 255.
          analogWrite(ledRouge, RougeVal);
          VertVal = map(i, 0, 170, 0, 255); // variation du vert par la fonction de conversion map on dit donc que 0 a 170 (maxi 1023) est égal a 0 a 255, 255 étant la puissance max de la couleur séléctionnée.
          analogWrite(ledVerte, VertVal);
          //analogWrite(ledBleu, BleuVal);
        }

        // // Teinte 2
        if (i > 170 && i < 341) {
          VertVal = 255; // vert max
          // BleuVal = 0;
          analogWrite(ledVerte, VertVal);
          RougeVal = map(i, 341, 170, 0, 255); // variation rouge
          analogWrite(ledRouge, RougeVal);
          // analogWrite(ledBleu, BleuVal);
        }

        // Teinte 3
        if (i > 341 && i < 511) {
          VertVal = 255; // vert max
          //RougeVal = 0;
          analogWrite(ledVerte, VertVal);
          BleuVal = map(i, 341, 511, 0, 255); //variation du bleu
          analogWrite(ledBleu, BleuVal);
          //analogWrite(ledRouge, RougeVal);
        }

        // Teinte 4
        if (i > 511 && i < 681) {
          BleuVal = 255;
          //RougeVal = 0;
          analogWrite(ledBleu, BleuVal);
          VertVal = map(i, 682, 511, 0, 255);
          analogWrite(ledVerte, VertVal);
          //analogWrite(ledRouge, RougeVal);
        }

        // // Teinte 5
        if (i > 682 && i < 852) {
          BleuVal = 255;
          //VertVal = 0;
          analogWrite(ledBleu, BleuVal);
          RougeVal = map(i, 682, 852, 0, 255);
          analogWrite(ledRouge, RougeVal);
          //analogWrite(ledVerte, VertVal);
        }

        // // Teinte 6
        if (i > 852 && i < 1023) {
          RougeVal = 255;
          // VertVal = 0;
          analogWrite(ledRouge, RougeVal);
          BleuVal = map(i, 1023, 852, 0, 255);
          analogWrite(ledBleu, BleuVal);
          //analogWrite(ledVerte, VertVal);
        }
      }
      else{
        break;
      }
    }
  }
}







// **********************************************************
// **********************************************************

void Potentiometre(){
  TmpVal = analogRead(A1); 


  // Teinte 1 >>>>>>>> Les teintes varient selon les leds

  // Mélange rouge vert

  if (TmpVal > 0 && TmpVal < 170) { // si la valeur de la TMP est supérieur a 0 et inférieur a 170
    RougeVal = 255; // Rouge au max
    //BleuVal = 0; // bleu a 0 avec possibilité d'en rajouter un peu valeur a donner entre 0 et 255.
    analogWrite(ledRouge, RougeVal);
    VertVal = map(TmpVal, 0, 170, 0, 255); // variation du vert par la fonction de conversion map on dit donc que 0 a 170 (maxi 1023) est égal a 0 a 255, 255 étant la puissance max de la couleur séléctionnée.
    analogWrite(ledVerte, VertVal);
    //analogWrite(ledBleu, BleuVal);
  }

  // // Teinte 2 
  if (TmpVal > 170 && TmpVal < 341) {
    VertVal = 255; // vert max
    // BleuVal = 0;
    analogWrite(ledVerte, VertVal);
    RougeVal = map(TmpVal, 341, 170, 0, 255); // variation rouge
    analogWrite(ledRouge, RougeVal);
    // analogWrite(ledBleu, BleuVal);
  }

  // Teinte 3
  if (TmpVal > 341 && TmpVal < 511) {
    VertVal = 255; // vert max
    //RougeVal = 0;
    analogWrite(ledVerte, VertVal);
    BleuVal = map(TmpVal, 341, 511, 0, 255); //variation du bleu
    analogWrite(ledBleu, BleuVal);
    //analogWrite(ledRouge, RougeVal);
  }

  // Teinte 4  
  if (TmpVal > 511 && TmpVal < 681) {
    BleuVal = 255;
    //RougeVal = 0;
    analogWrite(ledBleu, BleuVal);
    VertVal = map(TmpVal, 682, 511, 0, 255);
    analogWrite(ledVerte, VertVal);
    //analogWrite(ledRouge, RougeVal);
  }

  // // Teinte 5 
  if (TmpVal > 682 && TmpVal < 852) {
    BleuVal = 255;
    //VertVal = 0;
    analogWrite(ledBleu, BleuVal);
    RougeVal = map(TmpVal, 682, 852, 0, 255);
    analogWrite(ledRouge, RougeVal);
    //analogWrite(ledVerte, VertVal);
  }

  // // Teinte 6
  if (TmpVal > 852 && TmpVal < 1023) {
    RougeVal = 255;
    // VertVal = 0;
    analogWrite(ledRouge, RougeVal);
    BleuVal = map(TmpVal, 1023, 852, 0, 255);
    analogWrite(ledBleu, BleuVal);
    //analogWrite(ledVerte, VertVal);
  }



void loop()
{

  // lire le bouton
  switchState = digitalRead(switchPin);

  if (switchState != prevSwitchState) {
    mode = mode + 1;
    delay (1000);
    prevSwitchState = switchState - 1;

  }

  if (mode > 3) {
    mode = 0; 
    prevSwitchState = 0;
    switchState = 0;
  }



  Serial.print ("mode: ");
  Serial.print (mode);

  switch (mode) {
  case 0:
    Serial.println(" Automatique");
    Automatique();
    break;    
  case 1:     
    Serial.println(" ON Blanc");
    digitalWrite (ledBleu, HIGH);
    digitalWrite (ledVerte, HIGH);
    digitalWrite (ledRouge, HIGH);
    break;
  case 2:
    Serial.println(" potentiometre");
    Potentiometre();
    break;
  case 3:
    Serial.println(" Off");
    digitalWrite (ledBleu, LOW);
    digitalWrite (ledVerte, LOW);
    digitalWrite (ledRouge, LOW);
    break;



  }
}



Il ne me reste plus qu'à développer la partie audio. C'est en cours. Je compléterais mon article dès que ça fonctionnera!











Aucun commentaire:

Enregistrer un commentaire