Go Down

Topic: [4 x 4 LED RGB MATRIX] Sincronizzare frequenza PWM con loop (Read 924 times) previous topic - next topic

Elius94

Ciao ragazzi, sto realizzando un  firmware per pilotare via pwm, usando il metodo delle matrici, ad alta frequenza, 16 led rgb!

All'arduino sono collegati i 12 cavi che controllano il le singole file di anodi dei led, 4 file rosse, 4 file blu, e 4 verdi! per determinare quale dei 4 led venga acceso, le masse comuni a tutte le file (4 masse) vengono controllate tramite 4 transistor!

In sostanza, l'arduino accende i led, con il loro valore pwm, in ordine, da destra a sinistra, e una volta terminato fa la fila sotto.
In questo modo, ad altissime velocità (quella del ciclo dell'arduino stesso), i led risultano tutti accesi, con il relativo colore!
Finche non uso il pwm, ma uso solamente i 3 colori (r,G,B), quindi usando la funzione digitalWrite, funziona a meraviglia, e i led sembra che siano controllati singolarmente! senza sfarfallamenti ecc.

Quando invece utilizzo la funzione analorWrite, con le 12 uscite PWM dell'arduino mega, si crerano fastidiosi sfarfallamenti, e anche se i colori si vedono bene, "fa schifo" (sono pignolo) :)

Conosco la modulazione di larghezza dell'impulso (PWM), l'ho studiata bene, e quindi posso dedurre che si creano degli asincronismi fra il periodo di oscillazione del PWM, e quello di esecuzione del loop!

Come mi consigliereste di risolvere questo problema?

P.s, nel codice, uso un delayMicroseconds, per aspettare pochissimi microsecondi, prima che si spengano i led precedenti, in modo da dare tempo al led di accendersi del tutto, e questo ad alta velocità non crea problemi!

Ecco il codice :

Quote

int ledGND[] = {17,16,15,14};
int red[] = {2,3,4,5};
int green[] = {6,7,8,9};
int blue[] = {10,11,12,13};
int n = 0;
int n2 = 0;

byte REDvalue[4][4] = {
  {127,127,127,127},
  {127,127,127,127},
  {84,84,84,84},
  {0,0,0,0}
};

byte GREENvalue[4][4] = {
  {127,127,127,127},
  {0,0,0,0},
  {84,84,84,84},
  {127,127,127,127}
};
byte BLUEvalue[4][4] = {
  {0,0,0,0},
  {127,127,127,127},
  {84,84,84,84},
  {127,127,127,127}
};

void setup() {
  // initialize the digital pin as an output.
  for (int thisPin = 0; thisPin < 4; thisPin++)  {
    pinMode(ledGND[thisPin], OUTPUT); 
  }
  for (int thisPin = 0; thisPin < 4; thisPin++)  {
    pinMode(red[thisPin], OUTPUT);
  } 
    for (int thisPin = 0; thisPin < 4; thisPin++)  {
    pinMode(green[thisPin], OUTPUT);
  } 
    for (int thisPin = 0; thisPin < 4; thisPin++)  {
    pinMode(blue[thisPin], OUTPUT);
  } 
  Serial.begin(9600);
}


void loop() {
  for(n2=0; n2<4; n2++){
  digitalWrite(ledGND[n2], HIGH);
    for(n=0; n<4; n++) {
    analogWrite(red[n],REDvalue[n2][n]);
    analogWrite(green[n], GREENvalue[n2][n]);
    analogWrite(blue[n], BLUEvalue[n2][n]);
    //delayMicroseconds(200);
    //digitalWrite(green[n], LOW);
    }
  delayMicroseconds(995);
  digitalWrite(ledGND[n2], LOW);
  
  digitalWrite(red[0], LOW);
  digitalWrite(red[1], LOW);
  digitalWrite(red[2], LOW);
  digitalWrite(red[3], LOW);
  
  digitalWrite(green[0], LOW);
  digitalWrite(green[1], LOW);
  digitalWrite(green[2], LOW);
  digitalWrite(green[3], LOW);
  
  digitalWrite(blue[0], LOW);
  digitalWrite(blue[1], LOW);
  digitalWrite(blue[2], LOW);
  digitalWrite(blue[3], LOW);
  }
}



Grazie mille :D

Elius94

vedo che molta gente utilizza dell'hardware aggiuntivo, degli shift register, o dei pot digitali... però considerando che il mio arduino mega, ha più di 12 uscite PWM ed a me ne servono 12, dovrebbe bastare! anche perchè se accendo i led singolarmente, il pwm va benissimo, il problema è appunto nel farli "frullare " in un loop ;)

Qualche idea?

Elius94


uwefed

Lo sfarfalio deriva dalla frequenza di PWM che é 490Hz. Se fai il multiplexing in modo non sincronizzato con i PWM otterai dei tempi di accensione dei vari LED non dipendenti dal PWM.

Le 2 soluzioni sono:
* sincronizzare il multiplexing con il PWM
* aumentare la frequenza di PWM

Ciao Uwe

leo72

@Elius:
Immagino che per "frullare" tu intenda di farli accendere in sequenza.
Con il PWM puoi regolare la luminosità dei led poi devi farti una routine che alternativamente accende i led interessati.
Vedo tante soluzioni, se vuoi usare uno o più shift register potresti usare il PWM per pilotare gli anodi dei led e poi dare massa ai catodi con degli shift register.
Inizia a studiarti questa pagina:
http://arduino.cc/en/Tutorial/ShiftOut

Ovviamente per fare come ti ho detto devi mettere un transistor sull'alimentazione e pilotarlo col segnale PWM.
Così l'alimentazione è stabile ed i led si accendono solo quando vengono messi a massa.
Se vuoi usare elevate correnti per i led, ti consiglio di interporre degli Uln2803 fra gli shift register ed i catodi perché un 74HC595 mi pare lavori max a 100 mA e con 8 led a 20 mA l'uno lo friggi

Go Up