Controllo striscia led con arduino

Ciao, ho una striscia led bianca la quale vorrei controllarla con arduno. Il mio scopo sarebbe quello di accendere e spegnere la striscia con 2 pulsanti (ognuno accende e spegne) e controllare la luminosità con altri due pulsanti, uno abbassa la luce mentre l'altro la alza. Per la prima parte dovrei esserci riuscito, per il controllo della luminosità invece non riesco a farla funzionare, non ho trovato neanche nessun esempio su internet.
Come potrei fare?

ciao davide12 :slight_smile:

Allora per controllare la striscia LED avrai usato un transistor, dato che arduino da solo non la può alimentare..
Per il controllo dell'intensità di luminosità devi usare il PWM, e con i due pulsanti vai a variare il duty cycle.

QUI è spiegato come funziona il PWM e come gestirlo con arduino :slight_smile:

fai delle prove con un led singolo e vedi bene come funziona :slight_smile:

se hai bisogno siamo qui :slight_smile:

MD

Grazie per la risposta, la striscia led l'ho già collegata ad un'uscita PWM tramite un transistor, ho fatto delle prove e riesco ad accenderla e spegnerla tramite un pulsante ed a variare la luminosità modificando il valore del PWM.
Ora quello che non riesco a fare è variare la luminosità tramite la pressione del pulsante.
La logica che avevo pensato è che ad ogni pressione del tasto una variabile (che va da 0 a 255, i valori possibili per il PWM) si incrementi o decrementi di 5 punti così che il valore di luminosità del led si aggiorni ogni volta che tale valore cambia. Il problema è che non riesco a farlo funzionare. La logica sarebbe giusta almeno?

Posta il codice che hai scritto così possiamo vedere dove potrebbe essere l'errore

forse una cosa del tipo dovrebbe funzionare:

while tasto_lum_+ == premuto

if luminosità < 255

luminosità = luminosità +5

else
qui ci puoi mettere cosa deve succedere quanto la liminosità è al massimo, tipo far suonare un buzzer per mezzo secondo, ecc.

magari scritta con la sintasse corretta… e inserito un delay da mezzo secondo altrimenti come tocchi il pulsante schizza subito a 255 :-[

Posta il codice :slight_smile:

secondo me c'è solo un problema di lettura del pulsante , si risolve molte velocemente :slight_smile:
hai messu una pause da almeno 500 ms tra una lettura e l'altra del pulsante? magari non te ne accorgi e in un secondo di pressione hai già fatto 2 o 3 cicli da 0 a 255 :slight_smile:

Posta che vediamo , ricordati di usa il comando adatto per postare... :slight_smile:

MD

Ho provato a scrivere qualcosa del genere:

    {if (lettura_pulsante_led_sopra == 1) {if( luminosita<250){luminosita=luminosita+5;}}
    analogWrite(led_sopra, luminosita);}

Ho inizializzato la variabile luminosita=0
Appena premo il pulsante i led si accendono alla massima luminosità e rimangono così anche se premo di nuovo il pulsante.
Preciso che il pulsante è di un telecomando ir, aggiungerò più tardi il ritardo alla pressione del pulsante ma finora ho notato che non servirebbe.

Bene che ci dai 2 righe del Tuo Sketch.
Ma senza le altre righe non serve a niente.
Cioa Uwe

Ho scritto solo quelle 2 righe perchè pensavo che il setup e il resto del programma è inutile per comprendere il problema. Riporto tutto:

#include <Time.h>
#include <TimeAlarms.h>
#include <DS3231.h>
#include <DS3232RTC.h>
#include <Wire.h> 
#include <LEDFader.h>
#include <IRremote.h>
DS3231  rtc(SDA, SCL);
Time t;


//DEFINISCO RICEVITORE E TRASMETTITORE IR
int RECV_PIN = 13;
IRrecv irrecv(RECV_PIN);
IRsend irsend;
decode_results results;


//DEFINISCO I PIN UTILIZZATI
     #define router                  A0                                                           //RELE' 1
     #define voip                    A1                                                           //RELE' 2
     #define wii                     A3                                                           //RELE' 3
     //                              3                                                            //TRASMETTITORE IR 
     #define pc                      4                                                            //RELE' 4
     #define led_sopra               5                                                            //TRANSISTOR GRANDE
     #define led_tv                  6                                                            //TRANSISTOR GRANDE                             
     #define stereo                  7                                                            //RELE' 5
     #define giradischi              8                                                            //RELE' 6
     //#define led_stato             9                                                            //TRANSISTOR PICCOLO                   
     #define ventola_alimentatore    10                                                           //TRANSISTOR GRANDE 
     //                              11                                                           //RICEVITORE IR 
     #define lampada                 12                                                           //RELE' 7                                                                                            
     #define ventola_generale        11                                                           //TRANSISTOR GRANDE                                       

     #define amp_giradischi          A2
     //#define SVILUPPI FUTURI                                                                    //RELE' 8, NON UTILIZZATO
     #define pulsante                A5
     #define interr_3luci            2


//FADE LED

     LEDFader led_stato = LEDFader(9);


//COSTANTI VOIP E ROUTER
     unsigned long time;
     unsigned long tempoCorrente_Router_Voip;
     unsigned long tempo_Router_Voip=0;
     int stato_Router_Voip = 0;
     int Avvio_Router_Voip = 1;
     int Riavvio_Router_Voip = 0;


//FUNZIONE LED 
     int stato_led_fade = 0;
     int contatore_led_fade = 0;     
     int numero_fade = 0;
     int stato_led_blink = 0;
     int contatore_led_blink = 0;
     int numero_blink = 0;

//INTERRUTTORE E PULSANTE
     int lettura_interruttore_3luci;



//PULSANTI IR
     #define ritardo_pulsante 5000 

     
//FUNZIONE PER RIAVVIARE ARDUINO
     void(* Riavvia)(void) = 0; 


//--------------------------------------------------------------------------------------------------SETUP-------------------------------------------------------------------------------------------


void setup(){
 
//AVVIO IR
     irrecv.enableIRIn();


//IMPOSTAZIONE LE VARIABILI TEMPO  
     rtc.begin();
     tempoCorrente_Router_Voip=millis();
     tempoCorrente_wii=millis();
     tempoCorrente_pc=millis();
     tempoCorrente_stereo=millis();
     tempoCorrente_giradischi=millis();

  
//IMPOSTAZIONE INGRESSI E USCITE  
      pinMode(router, OUTPUT);
      pinMode(voip, OUTPUT);
      pinMode(wii, OUTPUT);
      pinMode(pc, OUTPUT);
      pinMode(led_sopra, OUTPUT);
      pinMode(led_tv, OUTPUT);
      pinMode(stereo, OUTPUT);
      pinMode(giradischi, OUTPUT);
      pinMode(ventola_alimentatore, OUTPUT);
      //pinMode(led_stato, OUTPUT);
      pinMode(lampada, OUTPUT);
      pinMode(ventola_generale, OUTPUT);
      pinMode(amp_giradischi, OUTPUT);

      pinMode(pulsante, INPUT);
      pinMode(interr_3luci, INPUT);
    


//IMPOSTAZIONE DEI PIN ALL'AVVIO      
      digitalWrite(router, LOW );                                                   //RELE' 1 -------- LOW
      digitalWrite(voip, LOW );                                                     //RELE' 2 -------- LOW                
      digitalWrite(wii, LOW );                                                      //RELE' 3 -------- LOW
      digitalWrite(pc, LOW );                                                       //RELE' 4 -------- LOW
      analogWrite(led_sopra, 0 );
      analogWrite(led_tv, 0 );
      digitalWrite(stereo, LOW );                                                   //RELE' 5 -------- LOW
      digitalWrite(giradischi, HIGH );                                              //RELE' 6 -------- HIGH
      //analogWrite(led_stato, LOW );
      analogWrite(ventola_alimentatore, LOW );
      digitalWrite(lampada, HIGH );                                                 //RELE' 7 -------- HIGH
      digitalWrite(ventola_generale, LOW );
      //digitalWrite(SVILUPPI FUTURI, HIGH );                                       //RELE' 8 -------- HIGH
      digitalWrite(amp_giradischi, LOW );
      digitalWrite(2, INPUT_PULLUP);
      digitalWrite(A5, INPUT_PULLUP);
     
}



void loop() {

//AVVIO RECEZIONE CODICI IR
     {if (irrecv.decode(&results)) {Serial.println(results.value, HEX); irrecv.resume();}}

     
//AVVIO DEI PROGRAMMI
     Router_Voip();
     Interruttore_3luci();

     

//PULSANTI
     lettura_interruttore_3luci = analogRead (interr_3luci);
     lettura_pulsante_giradischi = results.value == 0xFF22DD;
     lettura_pulsante_wii = results.value == 0xFFE21D;
     lettura_pulsante_pc = results.value == 0xFF629D;
     lettura_pulsante_stereo = results.value == 0xFFA25D;
     lettura_pulsante_conferma_azione = results.value == 0xFF38C7;
     lettura_pulsante_riavvio_router_voip = results.value == 0xFF906F;
     lettura_pulsante_led_sopra = results.value == 0xFF4AB5;
//     lettura_pulsante_DIMINUISCE_led_sopra = results.value == 0xFF4AB5;FF6897
     lettura_pulsante_modem = results.value == 0xFFE01F;
     lettura_pulsante_voip = results.value == 0xFFA857;




}




//---------------------------------------------------------------------------------------------------ALTRI PROGRAMMI---------------------------------------------------------------------------------------------

//PROGRAMMA AVVIO ROUTER E VOIP
  void Router_Voip() 
     {if((Avvio_Router_Voip==1)||(Riavvio_Router_Voip==1)) {stato_Router_Voip=1; Avvio_Router_Voip=0; Riavvio_Router_Voip = 0; digitalWrite(router,LOW); digitalWrite(voip,LOW); stato_router = 0; stato_voip = 0; stato_led_fade=1;numero_fade=5;}
     tempoCorrente_Router_Voip=millis();
     if((tempoCorrente_Router_Voip-tempo_Router_Voip>=5000)&&stato_Router_Voip==1) {digitalWrite(router,HIGH); stato_router = 1; stato_Router_Voip=2; tempo_Router_Voip=millis();}
     else if (stato_Router_Voip==2) {if(tempoCorrente_Router_Voip-tempo_Router_Voip>=2000) {digitalWrite(voip,HIGH); stato_voip = 1; stato_Router_Voip=0;}}}




void Interruttore_3luci()
    {if (lettura_pulsante_led_sopra == 1) {if( luminosita<250){luminosita=luminosita+5;}}
    analogWrite(led_sopra, luminosita);}

subito dopo che aumenti la luminosità devi inserire un piccola pausa con delay, altrimenti nemmeno il tempo di toccarlo il pulsante che va subito a 255. Altra cosa, ma se identi il codice non ti sarà anche per te più facile leggerlo? Tipo:

void Interruttore_3luci()
    {
    if (lettura_pulsante_led_sopra == 1) 
        {
        if( luminosita<250)
            {
            luminosita=luminosita+5;
            delay(200);
            }
        }
    analogWrite(led_sopra, luminosita);
    }

Ho provato ad inserire un delay come mi hai consigliato, ma i led si accendono quasi alla massima luminosità, ripremo il pulsante e la luminosità aumenta di poco portandosi al massimo, se continuo a premere il led rimane non varia la luce e rimane al massimo.

mah strano, con il delay come l'ho scritto io ogni volta che incrementa la luminosità di +5 deve fare una pausa di 200mS, quindi da zero per arrivare a 255 ci dovrebbe mettere circa 10 secondi, rimetti tutto il listato :slight_smile:

p.s. rivedendo il tuo listato noto che la variabile luminosita non è stata dichiarata da nessuna parte... difficile possa funzionare in questo modo :wink:

Ho controllato bene il programma e avevo dimenticato di inserire quel void nel loop… Funziona anche se ha ancora qualche problema. Ho subito sostituito il delay con millis scrivendo il seguente codice:

void Led_sopra()

    {tempoCorrente_led_sopra=millis();
    if (lettura_pulsante_led_sopra == HIGH && valore_precedente_pulsante_led_sopra == LOW && tempoCorrente_led_sopra - tempo_led_sopra > 200) 
        {
        if( luminosita<250)
            {
            luminosita=luminosita+5;
           
            }
        tempo_led_sopra=millis();lettura_pulsante_led_sopra = LOW;valore_precedente_pulsante_led_sopra=lettura_pulsante_led_sopra;}
    analogWrite(led_sopra, luminosita);
    }

appena premo il pulsante il led si accende alla minima luminosità, se lo premo un’altra volta la luminosità si incrementa di altri 5 punti e si ferma, oppure aumenta di altri 5 punti, attende il tempo di 200ms e incrementa ancora fino ad arrivare alla massima luminosità. Il tutto avviane in modo casuale (può capitare alla seconda pressione oppure alla decima)
Non riesco proprio a capire perchè faccia così, ad ogni pressione del pulsante non si dovrebbe fermare il tutto? Lo stesso problema avviene con delay.

  1. la tecnica di "debouncing" che hai usato NON mi sembra sia delle migliori ... cerca con Google "Arduino debouncing" e vedi come devi fare

  2. millis() usato in quel modo NON mi sembra serva a molto ... studiati bene come si usa, prima QUI, poi QUI ed infine leggi anche QUI e QUI ...

Guglielmo

Sono riuscito a scrivere uno sketch funzionante. Funziona in questo modo: accendo e spengo i led premendo un pulsante sul telecomando e per variare la luminosità devo prima premere un pulsante ed entro 10 secondi premerne un’altro che mi permetta di scegliere il livello di PWM.
Tale codice funziona perfettamente per una striscia led ma se aggiungo una seconda striscia la prima continua a funzionare mentre la seconda si accende e spegne come da comando sul telecomando ma se provo a variare la luminosità con un valore diverso da 255 essa si spegne.
Ho testato tutto l’hardware e non ci sono problemi o errori quindi è un problema software. Secondo voi dove sbaglio (riporto solo la parte del loop poichè sipero il limite dei 9000 caratteri, nel setup vengono solo definite le variabili)?

void loop() {    {if (irrecv.decode(&results)) {Serial.println(results.value, HEX); irrecv.resume();}}

     Luminosita_Led_sopra();
     Led_sopra();
     Luminosita_Led_tv();
     Led_tv();

     lettura_pulsante_riavvio_router_voip = results.value == 0xFF906F;
     lettura_pulsante_led_sopra = results.value == 0xFF6897;                                             // *   
     lettura_pulsante_led_tv = results.value == 0xFFB04F;                                                // #

     lettura_pulsante_5 = results.value == 0xFF02FD;
     lettura_pulsante_luminositaSOPRA_ = results.value == 0xFF18E7;                                      //SOPRA
     lettura_pulsante_luminositaSOPRA__ = results.value == 0xFF4AB5;                                     //SOTTO
     lettura_pulsante_luminositaTV_ = results.value == 0xFF5AA5;                                         //DESTRA
     lettura_pulsante_luminositaTV__ = results.value == 0xFF10EF;                                        //SINISTRA
}
void Led_sopra()
     {tempoCorrente_led_sopra=millis();
     if (lettura_pulsante_led_sopra == HIGH && valore_precedente_pulsante_led_sopra == LOW && tempoCorrente_led_sopra - tempo_led_sopra > 1000) 
     {if (stato_led_sopra == 0) stato_led_sopra = 1; else stato_led_sopra = 2; tempo_led_sopra = millis(); }
     if (stato_led_sopra == 1) {analogWrite(led_sopra, luminositaSOPRA);stato_led_sopra = 1;}
     if (stato_led_sopra == 2) {analogWrite(led_sopra, 0);stato_led_sopra = 0;}
     valore_precedente_pulsante_led_sopra = lettura_pulsante_led_sopra;}    

void Luminosita_Led_sopra()

     {if (stato_led_sopra == 1 && (lettura_pulsante_luminositaSOPRA_ == HIGH || lettura_pulsante_luminositaSOPRA__ == HIGH)){ tempo_Lled_sopra = millis() + 10000; stato_luminosita_led_sopra = 1; led_stato.fade(255, 500);}
     if (stato_luminosita_led_sopra == 1 && lettura_pulsante_stereo == HIGH && millis() < tempo_Lled_sopra) {luminositaSOPRA = 10; analogWrite (led_sopra, luminositaSOPRA);}
     if (stato_luminosita_led_sopra == 1 && lettura_pulsante_pc == HIGH && millis() < tempo_Lled_sopra) {luminositaSOPRA = 20; analogWrite (led_sopra, luminositaSOPRA);}
     if (stato_luminosita_led_sopra == 1 && lettura_pulsante_wii == HIGH && millis() < tempo_Lled_sopra) {luminositaSOPRA = 30; analogWrite (led_sopra, luminositaSOPRA);}
     if (stato_luminosita_led_sopra == 1 && lettura_pulsante_giradischi == HIGH && millis() < tempo_Lled_sopra) {luminositaSOPRA = 60; analogWrite (led_sopra, luminositaSOPRA);}
     if (stato_luminosita_led_sopra == 1 && lettura_pulsante_5 == HIGH && millis() < tempo_Lled_sopra) {luminositaSOPRA = 100; analogWrite (led_sopra, luminositaSOPRA);}
     if (stato_luminosita_led_sopra == 1 && lettura_pulsante_riavvio == HIGH && millis() < tempo_Lled_sopra) {luminositaSOPRA = 140; analogWrite (led_sopra, luminositaSOPRA);}
     if (stato_luminosita_led_sopra == 1 && lettura_pulsante_modem == HIGH && millis() < tempo_Lled_sopra) {luminositaSOPRA = 180; analogWrite (led_sopra, luminositaSOPRA);}
     if (stato_luminosita_led_sopra == 1 && lettura_pulsante_voip == HIGH && millis() < tempo_Lled_sopra) {luminositaSOPRA = 220; analogWrite (led_sopra, luminositaSOPRA);}
     if (stato_luminosita_led_sopra == 1 && lettura_pulsante_riavvio_router_voip == HIGH && millis() < tempo_Lled_sopra) {luminositaSOPRA = 255; analogWrite (led_sopra, luminositaSOPRA);}
     if (stato_luminosita_led_sopra == 1 &&  millis() > tempo_Lled_sopra) {stato_luminosita_led_sopra = 2;}
     if (stato_luminosita_led_sopra == 2) {stato_luminosita_led_sopra = 0; led_stato.fade(0, 500);}}



void Led_tv()
     {tempoCorrente_led_tv=millis();
     if (lettura_pulsante_led_tv == HIGH && valore_precedente_pulsante_led_tv == LOW && tempoCorrente_led_tv - tempo_led_tv > 1000) 
     {if (stato_led_tv == 0) stato_led_tv = 1; else stato_led_tv = 2; tempo_led_tv = millis(); }
     if (stato_led_tv == 1) {analogWrite(led_tv, luminositaTV);stato_led_tv = 1;}
     if (stato_led_tv == 2) {analogWrite(led_tv, 0);stato_led_tv = 0;}
     valore_precedente_pulsante_led_tv = lettura_pulsante_led_tv;}    

void Luminosita_Led_tv()

     {if (stato_led_tv == 1 && (lettura_pulsante_luminositaTV_ == HIGH || lettura_pulsante_luminositaTV__ == HIGH)){ tempo_Lled_tv = millis() + 10000; stato_luminosita_led_tv = 1; led_stato.fade(255, 500);}
     if (stato_luminosita_led_tv == 1 && lettura_pulsante_stereo == HIGH && millis() < tempo_Lled_tv) {luminositaTV = 10; analogWrite (led_tv, luminositaTV);}
     if (stato_luminosita_led_tv == 1 && lettura_pulsante_pc == HIGH && millis() < tempo_Lled_tv) {luminositaTV = 20; analogWrite (led_tv, luminositaTV);}
     if (stato_luminosita_led_tv == 1 && lettura_pulsante_wii == HIGH && millis() < tempo_Lled_tv) {luminositaTV = 30; analogWrite (led_tv, luminositaTV);}
     if (stato_luminosita_led_tv == 1 && lettura_pulsante_giradischi == HIGH && millis() < tempo_Lled_tv) {luminositaTV = 60; analogWrite (led_tv, luminositaTV);}
     if (stato_luminosita_led_tv == 1 && lettura_pulsante_5 == HIGH && millis() < tempo_Lled_tv) {luminositaTV = 100; analogWrite (led_tv, luminositaTV);}
     if (stato_luminosita_led_tv == 1 && lettura_pulsante_riavvio == HIGH && millis() < tempo_Lled_tv) {luminositaTV = 140; analogWrite (led_tv, luminositaTV);}
     if (stato_luminosita_led_tv == 1 && lettura_pulsante_modem == HIGH && millis() < tempo_Lled_tv) {luminositaTV = 180; analogWrite (led_tv, luminositaTV);}
     if (stato_luminosita_led_tv == 1 && lettura_pulsante_voip == HIGH && millis() < tempo_Lled_tv) {luminositaTV = 220; analogWrite (led_tv, luminositaTV);}
     if (stato_luminosita_led_tv == 1 && lettura_pulsante_riavvio_router_voip == HIGH && millis() < tempo_Lled_tv) {luminositaTV = 255; analogWrite (led_tv, luminositaTV);}
     if (stato_luminosita_led_tv == 1 &&  millis() > tempo_Lled_tv) {stato_luminosita_led_tv = 2;}
     if (stato_luminosita_led_tv == 2) {stato_luminosita_led_tv = 0; led_stato.fade(0, 500);}}

Io continuo ostinatamente a suggerire di usare un debounce hardware ... un condensatore ed una resistenza in piu non rovinano il budget, ma semplificano di molto la vita in parecchie situazioni in cui e' coinvolto un pulsante :wink:

Non è il classico pulsante ma il comando di un telecomando ir il quale se premo una volta restituisce un codice mentre e tengo premuto ne restituisce un'altro quindi non ho problemi di debounce in questo caso