Luci Auto Soft-on Soft-off

Salve a tutti, premetto che prima di chiedere aiuto qui ho interrogato google in tutti i modi, ma non ho trovato nulla, o meglio nulla di funzionale al mio progetto.

Espongo il progetto:

volevo implementare in una auto le luci sopra i poggiapiedi, possibilmente led, che quando si aprono le porte si accendano in dissolvenza (2 o 3 sec max), e quando si chiudono si spengano in dissolvenza (sempre 2 o 3 sec).
Praticamente un Fade-in e Fade-out nel momento che l'arduino rileva lo stato delle porte.
Il segnale delle porte chiude verso massa del veicolo, e l'alimentazione l'avrei presa da una fonte costante sulla piastra fusibili.
Avevo valutato l'idea del circuito RC, ma non mi piace, tempi strani e fade non lineare, e poi avrei utilizzato un attiny85 anche per avere maggior flessibilità di implementazione in futuro.
Per la parte hardware ho le idee chiare, qualche transistor in configurazione darlington (2n3904 a volontà) e qualche resistenza completano il tutto, alimentazione al microcontrollore fornita da lm7805 o affini e qualche filtro per i picchi di tensione ed effetti elettrostatici.

So che sembra una sciocchezza, ma ho provato diversi codici e diverse strade, ma nessuna mi porta ad un risultato che mi soddisfi, il massimo che ho realizzato funzionava abbastanza bene ma i led rimanevano sempre un po' accesi (non chiedetemi di postare il codice, ho spento il pc dalla frustrazione e addio).
Ho provato di tutto, ma credo di ignorare qualcosa...

Quindi chiedo aiuto a voi del forum :slight_smile:

Ringrazio anticipatamente qualunque buona anima e qualunque buon consiglio.

Grazie.

Devi usare la funzione millis per implementare un fading sia in salita che in discesa (a seconda dello stato delle portiere, se aperte o chiuse), ed una variabile per capire se devi fare appunto la salita o la discesa del fading, variabile che sarà legata allo stato delle portiere.

Hai cercato sul forum? Si trovano delle discussioni in merito, tipo questa:

Ciao Leo e grazie per l’aiuto,
per il fade ho trovato tutte le strade possibili e con ottimi risultati, con millis, senza millis, con e senza il delay etc…
Il mio problema è che quando implemento, o provo ad implemetare la funzione “se la porta è aperta”, tradotto “if door == HIGH” il codice non mi lavora più come sperato, mi fa il fade solo in o solo out, e in continuo loop a prescindere dalla variabile della porta…

Posto un codice che ho trovato qua e la, ma che mi tiene sempre i led leggermente accesi alla fine del fade-out, cosa che non mi piace…

int domeLightIn = 7;
int domeLightOut = 9;
int brightness = 0;
int fadeAmount = 5;

void setup() {
  pinMode(domeLightOut, OUTPUT);
  pinMode(domeLightIn, INPUT);
  digitalRead(domeLightIn);

}

void loop() {
  // Case 1: State of Door: Open/Closed
  // Case 2: State of Switch: On/Off
  // Case 3: State of KES: Active/Inactive

  //Case 1: If door is closed and led is off, brightness remains 0;
  //Case 2: If switch is off and led is off, brightness remains 0;
  //Case 3: If KES is inactive and led is off, brightness remains 0;
  if (digitalRead(domeLightIn) == LOW && brightness != 255){
    brightness = 0;
  }

  //Case 1: If door is open and led is off, brightness will fade in;
  //Case 2: If switch is on and led is off, brightness will fade in;
  //Case 3: If KES is active and led is off, brightness will fade in;
  if (digitalRead(domeLightIn) == HIGH && brightness != 255) {
    for (brightness = 0; brightness < 255; brightness = brightness + fadeAmount) {
      analogWrite(domeLightOut, brightness);
      delay(10);
    }
  }

  //Case 1: If door is closed and led is on, brightness will fade out;
  //Case 2: If switch is off and led is on, brightness will fade out;
  //Case 3: If KES is inactive and led is on, brightness will fade out;
  if (digitalRead(domeLightIn) == LOW && brightness == 255) {
    for (brightness = 255; brightness > 0; brightness = brightness - fadeAmount) {
      analogWrite(domeLightOut, brightness);
      delay (30);
//      analogWrite(domeLightOut, 0);
  //    delay (35);
    }
  }
}

ho provato anche a cambiare pin pensando fosse il mio arduino in tilt… (dopo anni di cazzate :D)

P.S.: mi sembra di ricordare che qualcuno usasse un sistema di fade basato su coseno e seno, con risultati di fade non lineari ma migliori a loro dire, è possibile?

Ciao e Grazie

Prova con questo codice (non occorre il resistore di pullup):

#define SwitchPin  7
#define LampPin    9

const byte FadeStep = 5; 
byte SwitchStatus = LOW;

void setup() {
  pinMode(LampPin, OUTPUT);
  pinMode(SwitchPin, INPUT_PULLUP);
  SwitchStatus = digitalRead(SwitchPin);  // switch close ===> SwitchStatus = LOW 
}

void loop() {
  if (SwitchStatus != digitalRead(SwitchPin)) {
    SwitchStatus = digitalRead(SwitchPin);
    if (SwitchStatus == LOW) {            // switch close ===> fade in
      for (byte I = 0; I < 256; I =+ FadeStep) {
        analogWrite(LampPin, I);
        delay(10);
      }
    }
    else {                                // switch open ===> fade out
      for (byte I = 255; I < 1; I =- FadeStep) {
        analogWrite(LampPin, I);
        delay(10);
      }
    }
  }
}

Ciao e grazie per la risposta, ma non funziona…
Mi da più meno gli stessi risultati di un mio precedente sketch :s
mi vien da pensare che la scheda non sia esattamente in bolla :smiley:
sai se c’è un modo per provare in maniera decente la scheda arduino? non so qualche tipo di test?

In ogni caso grazie per la dritta, punto primo perchè non sapevo come dichiarare una variabile del tipo LOW/HIGH, gli davo “int” e provavo a sostituire LOW con 0 e HIGH con 1 ma non funzionava (forse riconducibile ad arduino fuso, boh);
l’input_pullup non lo conscevo :smiley: molto utile.

Nel frattempo provo a vedere se riesco a rimediare un altra scheda da provare :slight_smile:

EDIT:
provato con un MEGA2560, stesso risultato, quindi escluderei un malfunzionamento della scheda.
Cambianto il valore a
FadeStep = 5 con FadeStep = 50 o superiore, mi fa notare che il led rimane acceso fioco nella condizione di FadeStep, cioè con valore 5 è appena visibile, con valore 255 è acceso completamente, quindi credo che il loop si blocchi al valore di FadeStep.
Ho provato a modificare
for (byte I = 0; I < 256; I =+ FadeStep) con
for (byte I = 0; I < 256; I++) e a questo punto, a prescindere dal pin dello switch mi fa il loop dello fade-in.

So che dimentico qualcosa, questo progetto è una cavolata, ma non arrivo a comprendere cosa dimentico :expressionless:

Secondo me non è corretto un ciclo for fatto con un incremento "i+=fadestep" dove "fadestep=5", perché nel momento in cui fa 255+5 ottiene 260. Byte può contenere un valore che va da 0 a 255, 256 o più non può gestirli, quindi "i" va in overflow.

LOW e HIGH sono 2 costanti predefinite che valgono rispettivamente 0 e 1, quindi mettere LOW per 0 o viceversa per il compilatore è equivalente. Attento solo che devi scriverle tutte maiuscole perché il compilatore C è sensibile alle maiuscole, quindi Low è diverso da low che è diverso da loW che è diverso da LOW ecc...

Ho pensato anche io a questo fattore, in quanto non sapevo se dichiarare “i” come byte o int, non sapendo appunto se con byte arrivato a 255 cosa facesse arduino, idem per int, che oltre i 32000 va in negativo…
Però dandogli un tetto con “i<=255” non dovrebbe fermarsi?

Ho provato a fare un esperimento, codice base da bambino e ripetitivo:

if (SwitchStatus == HIGH){
analogWrite(LampPin, 2);
analogWrite(LampPin, 4);
analogWrite(LampPin, 8);

in base 2, fino ad arrivare a 255 (256) e delay alla fine, ma senza risultati…

Se allo sketc tolgo la variabile “if” diventa un fade led normale e funziona benissimo, ma provando ad aggiungere “if” si incasina tutto, idem per “for”…
Perché se all’interno di un ciclo di “if” metto un’operazione d’incremento si blocca li?

Ciao e Grazie

Ciao,

Una cosa del genere?

#define Led 6
#define Porta 3
#define Luce_Accesa HIGH
#define Luce_Spenta LOW
int stato = Luce_Spenta;

void setup() {
  pinMode(Led, OUTPUT);
  pinMode(Porta, INPUT_PULLUP);
}

void loop() {
  if (digitalRead(Porta)==LOW && stato==Luce_Spenta) { // Porta Aperta
    for(int x=0; x<256; x++){
      analogWrite(Led,x);
      delay(10);
    }
    digitalWrite(Led,HIGH);
    stato = Luce_Accesa;
  }
  if (digitalRead(Porta)==HIGH && stato==Luce_Accesa) {  // Porta Chiusa
    for(int x=255; x>-1; x--){
      analogWrite(Led,x);
      delay(10);
    }
    digitalWrite(Led,LOW);
    stato = Luce_Spenta;
  }
}

Porca P...aletta :smiley: funziona a meraviglia!

ecco che forse ho scoperto quello che mi mancava

}
digitalWrite(Led, LOW);
stato = Luce_Spenta;
}

Avevo provato aggiungendo più variabili ad "if" e in tutte le salse "for" ma non avevo mai aggiunto niente (o meglio niente di elaborato) all' "else"...

Faccio leggermente fatica a seguirlo come codice, è tutto un susseguirsi di negazione degli stati, però è esattamente quello che avevo in mente, ma non avendo abbastanza esperienza non riuscivo a venirne fuori :slight_smile:

Comunque è perfetto, da qui posso già buttarlo nell'attiny85, sperando vada tutto bene. :wink:

Ringrazio Tutti per il prezioso aiuto. Riporterò appena possibile gli esiti del progetto e se si adatta alla vettura.

Leo ha ragione da vendere: non mi ero accorto dello step uguale a 5 e del compound errato (ci casco sempre).

Perciò, ho commesso due errori:

for (int = 0; I < 256; I += FadeStep)

Maechen:
Porca P...aletta :smiley: funziona a meraviglia!

ecco che forse ho scoperto quello che mi mancava

}

digitalWrite(Led, LOW);
stato = Luce_Spenta;
}




Avevo provato aggiungendo più variabili ad "if" e in tutte le salse "for" ma non avevo mai aggiunto niente (o meglio niente di elaborato) all' "else"...

Faccio leggermente fatica a seguirlo come codice, è tutto un susseguirsi di negazione degli stati, però è esattamente quello che avevo in mente, ma non avendo abbastanza esperienza non riuscivo a venirne fuori :)

Comunque è perfetto, da qui posso già buttarlo nell'attiny85, sperando vada tutto bene. ;)

Ringrazio Tutti per il prezioso aiuto. Riporterò appena possibile gli esiti del progetto e se si adatta alla vettura.

Quello non è l'else dell'if, ma il proseguo dopo il ciclo for.
Praticamente è una ridondanza, in quanto analogWrite(Led, 0) già dovrebbe spegnere il led, ma per sicurezza lo fai con digitalWrite(Led, LOW), e stessa cosa per quando il pwm è 255 e metti l'uscita HIGH.

In pratica hai due if, senza else, che contengono un for ed un digital write.

La variabile stato, serve per eseguire il pezzo di programma una sola volta, altrimenti avresti le luci che continuano a fare il fade.

Con quei delay(10) il fade dura circa 2,5 secondi, con delay(12) arrivi a 3. :wink:

Praticamente è una ridondanza, in quanto analogWrite(Led, 0) già dovrebbe spegnere il led, ma per sicurezza lo fai con digitalWrite(Led, LOW), e stessa cosa per quando il pwm è 255 e metti l'uscita HIGH.

Confermo. Nel core di Arduino c'è proprio il trucco sopra esposto.