Go Down

Topic: Multiplexare dei LED... sfarfallio!! (Read 1 time) previous topic - next topic

Guglio

Aug 26, 2013, 05:16 pm Last Edit: Aug 26, 2013, 05:18 pm by Guglio Reason: 1
Ciao ragazzi, ho 4 pezzi di striscia led che volevo pilotare mediante l'arduino...
I 4 spezzoni hanno i pin R,G,B in comune, quindi le multiplexo alimentanto singolarmente ogni striscia

Il problema è che ho un odioso sfarfallio quando le comando in PWM!!
Se utilizzo questo codice NON ho problemi:
Quote

void loop() {

 digitalWrite(A2, LOW);// Tolgo il positivo alla striscia 1
 digitalWrite(9, 0);// Spengo il Verde
 digitalWrite(10, 1);// Accendo il Rosso

 digitalWrite(A0, HIGH);// Collego il positivo della striscia 0

 delay(4);
 
 digitalWrite(A0, LOW);//  Tolgo il positivo alla striscia 0  
 digitalWrite(10, 0);// Spengo il rosso
 digitalWrite(9, 1); //Accendo il verde

 digitalWrite(A2, HIGH);//  Collego il positivo della striscia 1
 delay(4);
}




Se al posto del "digitalWrite(pin, 1)" metto "analogWrite(pin, 255)" ottengo ugualmente il flicker!!


Quote

void loop() {

 digitalWrite(A2, LOW);// Tolgo il positivo alla striscia 1
 analogWrite(9, 0);// Spengo il Verde
 analogWrite(10, 255);// Accendo il Rosso

 digitalWrite(A0, HIGH);// Collego il positivo della striscia 0

 delay(4);
 
 digitalWrite(A0, LOW);//  Tolgo il positivo alla striscia 0  
 analogWrite(10, 0);// Spengo il rosso
 analogWrite(9, 255); //Accendo il verde

 digitalWrite(A2, HIGH);//  Collego il positivo della striscia 1
 delay(4);
}


Com'è possibile!?

Le strip led sono collegate così: http://imageshack.com/scaled/medium/692/li4t.jpg
ArduMAP: Mappa degli utenti che utilizzano Arduino.
http://www.guglio.net/ArduMAP

leo72

Probabilmente perché la funzione analogWrite esegue altre cose prima di scrivere materialmente lo stato sul pin, come controllare se su quel pin c'è un PWM e se sì, lo stacca.

Questo introduce un allungamento dei tempi di risposta della funzione, che diminuiscono la frequenza di lampeggio arrivando a valori precepibili dall'occhio umano.
Quando usi analogWrite prova diminuendo l'intervallo specificato dal delay.

Guglio

Sto provando a velocizzare tutto usando le PORT... ma sto modificando dei tutorial su internet con scarsi risultati!! Addirittura molti degli esempi proposti se caricati non funzionano >.<

Ad esempio con questo codice:
PORTB &= ~( ( 1 << 1 ) | ( 1 << 2 ) );
Non dovrebbe portare il pin 1 e 2 della PORTB (quindi pin 9-10) ad high?

Grazie mille Leo per la risposta!
ArduMAP: Mappa degli utenti che utilizzano Arduino.
http://www.guglio.net/ArduMAP

gingardu

]:D    manca il delay   tra l'accensione e lo spegnimento
Le cose si possono considerare facili in due casi: quando le si conosce bene o quando non le si conosce affatto...

leo72


Ad esempio con questo codice:
PORTB &= ~( ( 1 << 1 ) | ( 1 << 2 ) );
Non dovrebbe portare il pin 1 e 2 della PORTB (quindi pin 9-10) ad high?


No, fa l'opposto. Li porta a LOW.
Il segno di complemento "~" inverte lo stato dei pin, poi viene fatto un AND bit a bit con il valore della porta col risultato che spenge solo i pin 1 e 2.

Leggi questo:
http://www.leonardomiliani.com/2013/manipoliamo-direttamente-le-porte-logiche-di-una-mcu/

leo72


]:D    manca il delay   tra l'accensione e lo spegnimento

Veramente c'è.

Guglio

Ho provato a mettere un delay(1) fra i due analogWrite.. in effetti funziona... il problema è che le funzione è troppo lenta e come provo a collegare tutte e 4 le strisce flickera un casino... e poi con tutti quei delay si illuminano meno...

Al momento ho risolto così
Code: [Select]

#define BINARY(a,b,c,d,e,f,g,h)  (a<<7|b<<6|c<<5|d<<4|e<<3|f<<2|g<<1|h)

void setup() {        
/** Blabla */
}

// Struttura Array:

////           S1       S2    S3    S4
/// Rosso
/// Verde
/// Blu

int r[4] = {
 1, 0, 1, 1};
int g[4] = {
 1, 1, 0, 0};
int b[4] = {
 0, 1, 0, 1};

unsigned long timer = 0;
int strip = 14;// i positivi sono sui pin 14, 15, 16, 17
int wait = 4000;

void loop() {
 if ((micros()-timer) > wait){
   //    PORTC = 0x00;// Spegne tutti gli analog
   PORTC = 1 << (strip-14);//spegne tutti gli analog accendendo solo il pin desiderato
   PORTB = BINARY(0,0,0,0,b[(17-strip)],r[(17-strip)],g[(17-strip)],0);//Accende e spegne i pin dell'rgb
   timer = micros();
   strip++;
   if (strip>17){
     strip = 14;
   }
 }
}



Il codice funziona... solo che come vedete non posso usare l'rgb... si riesce ad implementare il PWM così via software agendo sulle porte?
ArduMAP: Mappa degli utenti che utilizzano Arduino.
http://www.guglio.net/ArduMAP

leo72

Il PWM altro non è che un segnale generato da un timer interno. Puoi attivare il PWM su un pin con una determinata frequenza e poi scegliere tu il duty cycle semplicemente modificando il registro OCR del timer interessato. Non devi per forza passare dalla funzioni dell'Arduino.

Guglio

Ciao Leo! Sto facendo qualche prova con i timer del PWM, a quanto mi consigli di mettere la frequenza? E' meglio alta o bassa per il lavoro che devo fare io?
Ad esempio ho provato a mettere il divisore a 1, ottenendo 31250hz e l'alimentatore fischiava come se non ci fosse un domani!

Grazie mille per l'aiuto
ArduMAP: Mappa degli utenti che utilizzano Arduino.
http://www.guglio.net/ArduMAP

leo72

L'Arduino regola il PWM a ~490 Hz per il timer 1 e 2 e ~980 Hz per il timer 0. Usa questi valori, tanto a te non serve una frequenza eccessiva.

Guglio

Ciao Leo, pilotando le strip led senza multiplexarle sui 490Hz non ho problemi...
Invece se le utilizzo accendendole una per volta per cambiare il colore molto velocemente non funziona! Ho dovuto impostare gli Hz massimi a 31250 altrimenti sfarfallava tutto...

Al momento anche se con un lieve sfarfallio funziona tutto tranne la libreria VirtualWire!!
Come provo a modificare i registri OCR per impostare il PWM questa smette di funzionare!!
idee?

Il codice è questo se può servire!!

Grazie mille per l'aiuto!

Code: [Select]

#include <VirtualWire.h>
#define BINARY(a,b,c,d,e,f,g,h)  (a<<7|b<<6|c<<5|d<<4|e<<3|f<<2|g<<1|h)

boolean SettingMinTime = false;
int mintimeon = 100;
void setup()
{
  TCCR1A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
  TCCR1B = _BV(CS22);

  TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
  TCCR2B = _BV(CS22);

  TCCR1A = TCCR1A & 0b11111000 | 0x01;//3
  TCCR2A = TCCR1A & 0b11111000 | 0x01;//4
  TCCR1B = TCCR1B & 0b11111000 | 0x01;//3
 
  Serial.begin(115200); // Debugging only
  Serial.println("setup");
 

  // Controllo Spezzoni 
  pinMode(A3, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(A1, OUTPUT);
  pinMode(A0, OUTPUT);
  // RGB
  pinMode(9, OUTPUT);//Verde
  pinMode(10, OUTPUT);//Rosso
  pinMode(11, OUTPUT);//Blu
  pinMode(12, OUTPUT);//Relè
  pinMode(13, OUTPUT);//Debug
  pinMode(A5, INPUT);//Sensore FLash
  digitalWrite(A3, 0);
  digitalWrite(A2, 0);
  digitalWrite(A1, 0);
  digitalWrite(A0, 0);
 
 
  vw_set_ptt_inverted(true); // Required for DR3100
  vw_setup(2000); // Bits per sec
  vw_set_rx_pin(7);
  vw_set_tx_pin(8);
  vw_rx_start();       // Start the receiver PLL running
}

int r[4] = {
  1, 1, 1, 1};
int g[4] = {
  1, 1, 1, 1};
int b[4] = {
  1, 1, 1, 1};

unsigned long timer = 0;
unsigned long timer1 = 0;
int strip = 14;// 14, 15, 16, 17
int wait = 5000;


void loop()
{
 
 
  if ((micros()-timer) > wait){
    //PORTC = 0x00;// Spegne tutti gli analog
    PORTB = BINARY(0,0,0,0,b[(17-strip)],r[(17-strip)],g[(17-strip)],0);//Accende e spegne i pin dell'rgb
    //OCR1B = r[(17-strip)];// 10 rosso   Usando queste 3 funzioni non va la virtualwire!
    //OCR1A = g[(17-strip)];// 9 verde
    //OCR2A = b[(17-strip)];// 11 blu
    PORTC = 1 << (strip-14);//spegne tutti gli analog accendendo solo il pin desiderato

    timer = micros();
    strip++;
    if (strip>17){
      strip = 14;
    }
  }
///*** Gestione dati in ingresso con VW ***/
}
ArduMAP: Mappa degli utenti che utilizzano Arduino.
http://www.guglio.net/ArduMAP

lucaleo



Ad esempio con questo codice:
PORTB &= ~( ( 1 << 1 ) | ( 1 << 2 ) );
Non dovrebbe portare il pin 1 e 2 della PORTB (quindi pin 9-10) ad high?


No, fa l'opposto. Li porta a LOW.
Il segno di complemento "~" inverte lo stato dei pin, poi viene fatto un AND bit a bit con il valore della porta col risultato che spenge solo i pin 1 e 2.

Leggi questo:
http://www.leonardomiliani.com/2013/manipoliamo-direttamente-le-porte-logiche-di-una-mcu/


OT

leo se provo a vedere la tua guida nod32 segnala cavallo di troia
errore?

gpb01


...
leo se provo a vedere la tua guida nod32 segnala cavallo di troia
errore?


Confermo Leo ... anche a me segnala : "http://www.leonardomiliani.com/2013/manipoliamo-direttamente-le-porte-logiche-di-una-mcu - JS/Kryptik.AOC trojan" ... falso positivo o ... server violato ???

Guglielmo
Search is Your friend ... or I am Your enemy !

leo72


falso positivo o ... server violato ???

Più probabile la seconda.... è un calvario...  :smiley-roll-sweat:

leo72

Uh... ho addirittura trovato una bellissima backdoor russa. Il KGB mi sta spiando   :smiley-yell: :smiley-yell:

Code: [Select]
/******************************************************************************************************/
/*
/*                                     #    #        #    #                             
/*                                     #   #          #   #
/*                                    #    #          #    #
/*                                    #   ##   ####   ##   #
/*                                   ##   ##  ######  ##   ##
/*                                   ##   ##  ######  ##   ##
/*                                   ##   ##   ####   ##   ##
/*                                   ###   ############   ###
/*                                   ########################
/*                                        ##############
/*                                 ######## ########## #######
/*                                ###   ##  ##########  ##   ###
/*                                ###   ##  ##########  ##   ###
/*                                 ###   #  ##########  #   ###
/*                                 ###   ##  ########  ##   ###
/*                                  ##    #   ######   #    ##
/*                                   ##   #    ####   #    ##
/*                                     ##                 ##
/*
/*
/*
/*  r57shell.php - ?????? ?? ??? ??????????? ??? ????????? ???? ???????  ?? ??????? ????? ???????
/*  ?? ?????? ??????? ????? ?????? ?? ????? ?????: http://rst.void.ru
/*  ??????: 1.24 (New Year Edition)
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*  (c)oded by 1dt.w0lf
/*  RST/GHC http://rst.void.ru , http://ghc.ru
/*  ANY MODIFIED REPUBLISHING IS RESTRICTED
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*  ????????? ????????????? ?? ?????? ? ????: blf, virus, NorD ? ???? ?????? ?? RST/GHC.
/******************************************************************************************************/
/* ~~~ ????????? | Options  ~~~ */

Go Up