rgb led

Ciao!
Possiedo qualche led rgb con anodo comune, e non capisco come posso farli funzionare. In realta' ho qualche problema nel capire come posso variare la corrente sulla parte negativa...

C'e' un esempio in giro? Qualcuno sa darmi un input per capire come accendere e variare il colore di un led rgb con anodo comune?

Grazie mille, Fede

Era una scemenza ma non ci arrivavo, bastava attaccare i piedini R,G,B ai pin pwm come output e il catodo alla corrente.

Ho scritto anche un po' di codice per generare un colore desiderato:

/*
 * Set RGB Led Color
 * Use only pwm pins and common anode rgb leds
 */

int ledPin[] = {9, 10,11};

void setup() {
  for (int i=0; i<3; i++){
    pinMode(ledPin[i], OUTPUT);
  } 
}

short * RGB(short r,short g, short b){
  //short tmp[3];
  short *tmp=(short *)malloc(sizeof(short)*3);
  tmp[0]=abs(255-r);
  tmp[1]=abs(255-g);
  tmp[2]=abs(255-b);
  return tmp;
}

void led(int *pin,short *color) {
  for(int i=0;i<3;i++) {
    analogWrite(pin[i],color[i]);
  }
}

void loop() {
  led( ledPin, RGB(255,255,0) );
}

grandissimo!
stavo proprio cercando questa cosa perchè sto lavorando con un tlc e mi mancava un led che accendo via pwm.. !

se mi permetti di usurpare il tuo topic, anch'io in questi giorni ho fatto esperienza con pezzettino di strip led RGB. Per adesso faccio variare il colore con un solo potenziometro, dopo un po' di tentativi ho scoperto che per ottenere tutti i colori basta mixare i colori RGB solo due alla volta, è un codice semplice ma secondo me può tornare utile a qualcuno.

#define LED_RED 9
#define LED_GREEN 10
#define LED_BLUE 11
#define POT 5

unsigned long interval = 1000;
unsigned long previousMillis = 0;

void setup()
{
  Serial.begin(9600);

}

void loop()
{

  color_wheel();

}// Loop...


void RGB_led(int red_led, int green_led, int blue_led)
{
  analogWrite(LED_RED, red_led);
  analogWrite(LED_GREEN, green_led);
  analogWrite(LED_BLUE, blue_led);
}

void color_wheel()
{
  int red_val = 255;
  int green_val = 0;
  int blue_val = 0;
  int offset;

  int wheel = map(analogRead(POT), 0, 1023, 0, 1535);

  if( wheel <= 255 )  //Rosso al max + Verde in crescita
    green_val = wheel;  // ottengo al max il Giallo
  else if( wheel <= 511 )  //Verde al max + Rosso in diminuzione
  {
    red_val = abs(wheel - 511);  //Rosso va da 255 a 0
    green_val = 255;  //Verde lo tengo al max
  }
  else if( wheel <= 767 )  //Verde al max + Blu in crescita
  {                        //(0, 255, 255) = Ciano
    red_val = 0;
    green_val = 255;  //Verde al max
    blue_val = wheel - 511;  //Blu in crescita da 0 a 255
  }
  else if( wheel <= 1023 )  //Blu al max + Verde in diminuzione
  {     //(0, 0, 255) = Blu
    red_val = 0;
    green_val =  abs(wheel - 1023); //Verde in diminuzione da 255 a 0
    blue_val = 255;  //Blu fisso al max
  }
  else if( wheel <= 1279 )   //Blu al max + Rosso in crescita
  {                          //(255, 0, 255) = Magenta
    red_val = wheel - 1023;  //Rosso aumenta da 0 a 255
    blue_val = 255;  //Blu fisso al max
  }
  else {       //Rosso al max + Blu in diminuzione
    blue_val = abs(wheel - 1535);
  }


  if(millis() - previousMillis > interval) 
   {
   previousMillis = millis();
   
   Serial.print("pot: ");
   Serial.print(wheel);
   Serial.print(", red: ");
   Serial.print(red_val);
   Serial.print(", green: ");
   Serial.print(green_val);
   Serial.print(", blue: ");
   Serial.println(blue_val);
   
   }

  RGB_led(red_val, green_val, blue_val);

}

Magari prossimamente scrivo un articoletto con qualche foto.

Bello come hai scritto tu il codice !!!
E' di una compattezza incredibile, non ho capito una cosa però, cosa fa:

short *tmp=(short *)malloc(sizeof(short)*3);

?

Sera a tutti...
negli ultimi giorni anche io ho smanacciato un po' con dei led rgb a catodo comune, quindi devo pilotare i tre colori dal polo positivo.

avevo in casa dei uln2004 e uln2803 ma vanno bene per led ad anodo comune.

Ho testato un circuito di pilotaggio con degli IRF9540, che pero' mi sono sembrati esagerati per il lavoro che gli richiedevo (i led che ho al momento in casa sono da 1W - 150mA per colore).

Ho ordinato dei transistor PNP, i bd140 e sto aspettando che mi arrivino.

nel frattempo ho costruito un circuito (con dei 2n3906) per poter giocare con il sw mentre aspetto i bd140

ho collegato anche un ricevitore IR per poter controllare la futura lampada in produzione con un telecomando.

qui trovate il circuito di pilotaggio con IRF9540:

http://blog.lampugnani.org/arduino/pilotare-elevati-correnti/

e questo è il codice a cui sto lavorando:

#include <IRremote.h>
//#include <avr/pgmspace.h>
#include "ir_rgb.h"
#include <util/delay.h>
#define LEDPP 13 //LED POWER PIN
int gnd_pin = 16;
int vcc_pin = 17;
int RECV_PIN = 19;


char cmd[] = {
  0, 0, 0};
char arg[]= {
  0,0};
int incomingByte = 0;
//store value of any color
int r=0;
int g=0;
int b=0;
//store status of dev
//0 = static color
//1 = rand_col function
//2 = flash function
int system_stat = 0;

IRrecv irrecv(RECV_PIN);

decode_results results;

unsigned long decode(unsigned long value){
  unsigned int b0 = (value&0xff00)>>8;
  unsigned int b1 = (value&0x00ff);
  //  Serial.println(b0, HEX);
  //  Serial.println(b1, HEX);
  unsigned int ret = -1;
  for (int i=0; i < 24; i++) {
    if(b0 == myBtn[i][0] && b1 == myBtn[i][1]){
      if (myBtn[i][5] <= 3 || myBtn[i][5] == 11 || myBtn[i][5] == 15 || myBtn[i][5] == 19 || myBtn[i][5] == 23) {
        switch(myBtn[i][5]){
        case 0: 
          {
            r=r+10;
            g=g+10;
            b=b+10;
            rgb();
            break;
          }
        case 1: 
          {
            r=r-10;
            g=g-10;
            b=b-10;
            rgb();
            break;
          } 
        case 2: 
          {
            analogWrite(9,0);
            analogWrite(10,0);
            analogWrite(5,0);
            break;
          }
        case 3: 
          {
            rgb();
            break;
          } 
        case 11: //FUNCION flash button
          {
            system_stat = 2;
            break;
          }
        case 19: //FUNCION fade button
          {
            system_stat = 1;
            break;
          }
        }
      } 
      else {
        r=myBtn[i][2];
        g=myBtn[i][3];
        b=myBtn[i][4];
        rgb();
        //rgb(myBtn[i][2], myBtn[i][3], myBtn[i][4]);
      }
      ret = myBtn[i][5];
      continue;
      //ret = i;
    }
  }
  return ret;
  //return value;
}


void rgb() {
  analogWrite(9,r);
  analogWrite(10,g);
  analogWrite(5,b);
}

void rand_col() {
  randomSeed(analogRead(0));
  //  randomSeed((r+0)*(g+0)*(b+0));
  int color,i,value,time=10;  // how long does it take each step
  color=random(1,4);    // which color to dim now 
  value=random(0,256);  // new value of that color
  switch(color) {
  case 1: 
    if(r>value) for(i=r;i>value;i--) {
      r = i;
      rgb(); 
      delay(time); 
    }
    else for(i=r;i<value;i++) {
      r = i;
      rgb(); 
      delay(time); 
    }
    r=value;
    break;
  case 2: 
    if(g>value) for(i=g;i>value;i--) {
      g = i;
      rgb(); 
      delay(time); 
    }
    else for(i=g;i<value;i++) {
      g = i;
      rgb(); 
      delay(time); 
    }
    g=value;
    break;
  case 3: 
    if(b>value) for(i=b;i>value;i--) {
      b = i;
      rgb(); 
      delay(time); 
    }
    else for(i=b;i<value;i++) {
      b = i;
      rgb(); 
      delay(time); 
    }
    b=value;
    break;
  } 
  //  delay(3000);   // some time before next change
}

void bedazzle(int ledmax, int pulselensec, int freqmin, int freqmax) {
  long pulses;

  r=0;
  g=0;
  b=0;
  rgb();
  //  analogWrite(redpin1, 0);
  //  analogWrite(redpin2, 0);
  //  analogWrite(greenpin1, 0);
  //  analogWrite(greenpin2, 0);
  //  analogWrite(bluepin1, 0);
  //  analogWrite(bluepin2, 0);
  //  
  // note we dont use red LEDs in this
  int freq = random(freqmin, freqmax+1);
  int pulsedelay = 1000/freq;
  pulsedelay /= 2;

  pulses = pulselensec;
  pulses *= 100;
  pulses /= 2*pulsedelay;


//  Serial.print("pulsing at ");
//  Serial.print(freq, DEC);
//  Serial.print(" Hz (");
//  Serial.print(pulsedelay, DEC);
//  Serial.println(" ms on/off)");
//  Serial.print(pulses);
//  Serial.println(" pulses");

  while (pulses--) {
    r=random(0,ledmax);
    g=random(0,ledmax);
    b=random(0,ledmax);
    rgb();
    _delay_ms(pulsedelay);
    r=0;
    g=0;
    b=0;
    rgb();
    //_delay_ms(pulsedelay); 
    if (system_stat != 2) return; 
  }

}

void setup()
{
  pinMode(gnd_pin, OUTPUT);
  digitalWrite(gnd_pin, LOW);
  pinMode(vcc_pin, OUTPUT);
  digitalWrite(vcc_pin, HIGH);
  Serial.begin(9600);
  Serial.print("enabling IR ");
  irrecv.enableIRIn(); // Start the receiver
  pinMode(LEDPP, OUTPUT);
  digitalWrite(LEDPP,HIGH);
  //  rgb(0,0,255);
  //delay(3000);
  //  Serial.begin(9600);
}

void loop()
{
  if (irrecv.decode(&results)) {
    Serial.print("Pressed button: ");
    //Serial.println(results.value, HEX);
    int result = decode(results.value);
    if (result != -1 && result != 11 && result != 15 && result != 19 && result != 23){
      system_stat = 0; 
    }
    Serial.println(result);
    irrecv.resume(); // Receive the next value
  }

  if (system_stat == 1) {
    rand_col();
  }

  if (system_stat == 2) {
    bedazzle(255, 10, 7, 11);
  }

  if (Serial.available() > 0) {
    incomingByte = Serial.read();
    for (int i=0; i < 3; i++){
      cmd[i] =  cmd[i+1];
      cmd[3] = '\0';
    }
    cmd[2] = incomingByte;
    if(cmd[0] == 's' && cmd[1] == 'e' && cmd[2] == 't'){
      Serial.println("setting");
      if (Serial.available() > 0) {
        for(int i=0; i<2;i++){
          arg[i]=Serial.read();
        }
      }
      if(arg[1] == '1') {
        r=255;
        g=255;
        b=255;
        rgb();
      }
      if(arg[1] == '0') {
        r=0;
        g=0;
        b=0;
        rgb();
      }
    }
    if(cmd[0] == 't' && cmd[1] == 'r' && cmd[2] == 'i'){
      Serial.println("tricolor");
      if (Serial.available() > 0) {
        for(int i=0; i<2;i++){
          arg[i]=Serial.read();
        }
      }
      if(arg[1] == 'r') {
        r=255;
        g=0;
        b=0;
        rgb();
      }
      if(arg[1] == 'g') {
        r=0;
        g=255;
        b=0;
        rgb();
      }
      if(arg[1] == 'b') {
        r=0;
        g=0;
        b=255;
        rgb();
      }
      if(arg[1] == 'w') {
        r=255;
        g=255;
        b=255;
        rgb();
      }
    }
  }
}

il file ir_rgb.h contiene i codici dei tasti del mio telecomando...
se interessa posto anche quello...

sempre se interessa prossimamente posto foto del prototipo già funzionante.

vi do un'idea, ma fare un sistemsa simile ma che accetti stringhe di colori esadecimali, ad esempio per capirci quelli che si usano su web #05FF2C ?

ed è anche molto semplice, funziona cosi :

i primi 2 bit sono il rosso, i secondi 2 sono il verde, i terzi 2 sono il blu

il codice esadecimale si ottiene facendo rosso * verde * blu e convertendolo a esadecimale.

il valore massimo che possono prendere i colori è FF ovvero 255

prendiamo il bianco ad esempio, ci vorranno come componente cromatica, tutti e 3 i colori al massimo, quindi 255255255

che fa quindi 16.777.216 > convertito in hex #FFFFFF che è (se vi capita di usare css html o programmi di ritocco) l'esadecimale del bianco.

noi per avere la conversione in valori accettabili da arduino faremo convertiremo le coppie di bit in DEC e con la funzione MAP da 0,255 a 0,1024 .
dopo basterà fare un bel analogWrite col valore sul piedino corretto e otterrete il vostro RGB con valori standard ( quindi non dovrete piu testarli tutte le volte, ma basterà un semplice color picker di windows)

io l'ho spiegato, voi realizzatelo :wink:

Innanzitutto mi sono dimenticato di dire nel post precedente che il codice che ho postato è parte farina del mio sacco, parte preso in giro per il web ( ad esempio una funzione arriva da uno sketch di ladyada).
BTW
Come puoi vedere dal codice (ma abbiamo postato quasi insieme), il mio sketch prende già alcune cose da seriale, ora si possono solo settare 4 colori RGBW,ma non dovrebbe essere particolarmente complicato fare quel che dici.

La mia intenzione è arrivare ad un dispositivo che puo' essere controllato con il telecomando o tramite comandi da seriale, magari con una GUI, tipo in processing, che ti permetta di scegliere il colore che vuoi con un semplice click...

beh se non devi fare un'applicazione che si interfaccia col pc, usare il codice esadecimale è solo uno sbattimento in più!

Non ho colto cosa intendevi con la storia del map da 0-255 a 0-1024, le uscite pwm sono a 8 bit, quindi già perfette a ricevere valori da 0 a 255 o intendevi qualcos'altro?

no, era tardi ed ero ancora in ufficio davanti a mille datasheet e avevo la testa in pappa :smiley:

La mia intenzione è arrivare ad un dispositivo che puo' essere controllato con il telecomando o tramite comandi da seriale, magari con una GUI, tipo in processing, che ti permetta di scegliere il colore che vuoi con un semplice click...

fico. beh, innanzitutto darei un occhiata al post sull'input da IR che ho messo online un mesetto fa.

Di qualunque cosa abbiate bisogno sul controllo di led RGB, date un occhiata ai codici delle Lampade di Hackea.

Se solo avessi il tempo di infilare un po' di cose nella mia mega lampada rgb...

@t30

:wink: sketch testato e funzionante :smiley:

grandi raga ottima sperimentazione :stuck_out_tongue:

@Calamaro
quelli di instructables vogliono la registrazione per scaricare il codice..
prossimamente mi registro e provo.. e naturalmente poi posto...
magari mi torna utile parte del codice... o anche solo vedere com'è fatto...
grazie..

che problema c'è? instrutables è un ottimo sito e la registrazione è gratuita... se vuoi il pdf del progetto paghi ma alla fine ti puoi scaricare tutto stepbystep...

non mi piacciono per nulla i siti dove per accedere a delle info devi obbligatoriamente iscriverti...
in ogni caso sospettavo ci fosse roba a pagamento (nn ho mai indagato a fondo...)

Io sono iscritto da un bel po e scarico i pdf senza pagare nulla.

si ma il pdf completo del progetto mi pare che lo paghi, oppure sono stronzo io e lo fanno pagare solo a me ;D

ho finito di mettere insieme qualcosa di funzionante qualche giorno fa....

ho fatto degli scatti e creato una gif da mettere online....

il circuito e tutto il resto sta dentro una classica palla per illuminazioni esterne, spesso si trovano nei giardini...

prossimamente vedo di mettere online foto del circuito.. e schemi elettrici...

il codice nell'MCU è quello che ho postato in precedenza, anzi, se qualcuno più scaltro di me con il sw avesse un pochino voglia di implementare qualche funzione carina per il cambio dei colori...

MODIFICA: scusate, mi rendo conto solo ora che l'immagine che ho inserito è pesante come tutti i sassi del ticino...