luci variabili alternate

Salve a tutti
ritorno su questo forum dopo circa un anno, ricominciando tutto daccapo.
Posseggo Arduino Uno.
Ho collegato due led, con altrettante resistenze, un’estremità ai pin analogici 3 e 9 e le altre al ground.
Ecco il listato

const int LED = 9;
const int LED1=3;
int i= 0;
int ii=0;
void setup() {
 pinMode(LED, OUTPUT);
 pinMode(LED1, OUTPUT);
 }
void loop() {;
for(ii=255; ii>0; ii--);
for(i=0; i<255; i++) {
analogWrite(LED1, ii);
delay (10);
analogWrite(LED, i);
 }
for(ii=0; ii<255; ii++);
for(i=255; i>0; i--) {
analogWrite(LED1, ii);
delay (10);
analogWrite(LED, i);
 }
}

Vorrei che gentilmente qualcuno mi spiegasse perché soltanto il led collegato al pin 9 si accende e si spegne con gradualità, mentre l’altro (sul pin 3) si accende e spegne di colpo.
C’è un altro modo per ottenere che mentre cresce la luminosità di un led, decresca comtemporaneamente quella di un altro?

pin_analogici.ino (384 Bytes)

Ciao, io non ho mica capito questo codice :o

Ciao, se noti hai i due cicli for con la variabile ii che vengono eseguiti completamente senza che il valore del pwm venga passato al relativo pin. Questo accade solo nel secondo for ma in questo modo ottieni un led che funziona correttamente, l’altro passa da 0 a 255, quindi on off.

Per rimediare puoi fare così

void loop() {

for(i=0; i<255; i++) {
ii--;
analogWrite(LED1, ii);
analogWrite(LED, i);
delay(10);
  }
for(i=255; i>0; i--) {
ii++;
analogWrite(LED1, ii);
analogWrite(LED, i);
delay (10);
  }
}

nel setup il valore di ii deve partire da 255.

Suggerimenti e precisazioni:

I pin 3 e 9 non sono analogici, sono pin digitali con la possibilità di avere la modalità pwm. I pin analogici sono da A0 ad A5

I pin puoi dichiararli come #define LED 3

Le variabili i e ii puoi dichiararle byte in quanto il loro valore non supera 255, non c’è bisogno di usare un int

p.s. edita il codice usando i tag code

sagittario0342:
Salve a tutti

Il codice devi racchiuderlo nei tag code, vedi sezione 7 del regolamento, spiega bene come fare ( pulsante </> ).
Altrimenti parte del codice può essere visualizzata male o mancare perchè interpretato come attributo del testo stesso.

sagittario0342:
C’è un altro modo per ottenere che mentre cresce la luminosità di un led, decresca comtemporaneamente quella di un altro?

Come detto il problema fondamentale del codice che hai scritto sono i for(ii…) che non eseguono nessuna altra operazione se non impostare la variabile ii al massimo e al minimo (in pratica conteggiano a vuoto).

Banalmente se si ha un valore i crescente da 0 a 255, e se ne vuole in contemporanea uno decrescente, basta calcolarlo con 255-i

Poi senza usare dei for multipli, e considerando che il mainloop è già un ciclo ripetuto senza fine, un modo comune per ottenere la rampa di valori da 0 a 255 e ritorno è quello di usare una variabile ‘direzione’ da “commutare” ogni volta raggiunto un estremo:

byte i = 0;
byte dir = 1;  // direzione 1=incremento

void setup() {
}

void loop() {
   if (dir == 1)
       i = i + 1;
   else
       i = i - 1;
   if (i == 0)      // se raggiunto il minimo inverte direzione
       dir = 1;
   if (i == 255)    // se raggiunto il massimo inverte direzione
       dir = 0;
}

il tutto condensabile in:

i = dir ? i+1 : i-1;
dir = (!i || i==255) ? !dir : dir;

Da cui si può ottenere il codice completo:

#define LED  9
#define LED1 3

byte i = 0;
byte dir = 1;  // direzione 1=incremento

void setup() {
    pinMode(LED, OUTPUT);
    pinMode(LED1, OUTPUT);
}

void loop() {
    analogWrite(LED, i);
    analogWrite(LED1, 255-i);

    i = dir ? i+1 : i-1;
    dir = (!i || i==255) ? !dir : dir;

    delay(5);
}

Ma c’è un piccolo difetto “estetico”. L’occhio umano non percepisce la luminosità in modo lineare, quindi i LED dopo poche “unità di PWM” sembreranno quasi accesi al massimo, in sostanza sembreranno sempre quasi completamente accesi, e alternativamente uno dei due si spegnerà per un breve attimo.

La soluzione è rendere esponenziale il valore di attivazione ‘i’, ad esempio elevandolo al cubo (e riportando poi il risultato nel range intero 0…255):

(int)(pow(i, 3.0) * 0.0000153787 + 0.5)

si ottiene così una variazione di luminosità gradevole meglio percepibile dall’occhio:

#define LED  9
#define LED1 3

byte i = 0;
byte dir = 1;  // direzione 1=incremento

void setup() {
    pinMode(LED, OUTPUT);
    pinMode(LED1, OUTPUT);
}

void loop() {
    analogWrite(LED, (int)(pow(i, 3.0) * 0.0000153787 + 0.5));
    analogWrite(LED1, (int)(pow(255-i, 3.0) * 0.0000153787 + 0.5));

    i = dir ? i+1 : i-1;
    dir = (!i || i==255) ? !dir : dir;

    delay(5);
}

Innanzitutto auguro un buon 2017 a tutti!
E ringrazio tutti per le tempestive risposte.
Come detto, sto ricominciando daccapo e quindi non sono prontissimo a capirvi. Intanto terrei per ora da parte la risposta di Claudio_F, ringraziandolo, che mi propone una soluzione più avanzata: in altre parole, giacché mi preme capire la logica del processo, vorrei per ora utilizzare solo gli elementi più elementari (sto seguendo i primi esempi dal testo "Arduino, la guida ufficiale").

doppiozero:
Ciao, se noti hai i due cicli for con la variabile ii che vengono eseguiti completamente senza che il valore del pwm venga passato al relativo pin. Questo accade solo nel secondo for ma in questo modo ottieni un led che funziona correttamente, l'altro passa da 0 a 255, quindi on off.

Ecco, doppiozero, purtroppo io "non noto": non capisco perché pur percorrendo l'identico percorso dei "for", con la variabile "i" funziona, mentre con la "ii" invece no.
Potresti cortesemente spiegarmi passo passo dove sbaglio, (lasciando per ora i "define" ecc, che ancora non ho studiato)?
Grazie ancora

Il primo è un ciclo “vuoto”, conteggia da 255 a 1 (eseguendo 255 volte l’istruzione vuota ‘;’ ) ed infine termina lasciando ‘ii’ con valore 0:

for(ii=255; ii>0; ii--);
              |
            ii=255
      .------>|
      |       |
      |       |
      |       |
      |      ii--
      |(si)   |
      '---[ii > 0?]
              |(no)
              |

Il secondo è un ciclo che ripete un certo numero di volte ‘qualcosa’, con ‘i’ che varia da 0 a 254, ed infine termina lasciando ‘i’ con il valore 255:

for(i=0; i<255; i++) {
  qualcosa
}
              |
             i=0
      .------>|
      |       |
      |    qualcosa
      |       |
      |      i++
      |(si)   |
      '---[i < 255?]
              |(no)
              |

Sono due cicli completamente separati e indipendenti, e in particolare non si possono far conteggiare due for contemporaneamente.

Se l’idea era mettere un ciclo dentro l’altro allora non andava scritto il ‘;’ alla fine del primo, ma anche in questo caso la logica non sarebbe quella attesa, perché ad ogni variazione di ‘ii’, la variabile ‘i’ effettuerebbe ogni volta da capo l’intero conteggio da 0 a 254 (in sostanza si ciclerebbe 65025 volte in totale, con ‘ii’ che diminuisce di 1 ogni volta che ‘i’ ha conteggiato da da 0 a 254):

              |
            ii=255
  .---------->|
  |           |
  |           |
  |           |
  |          i=0
  |   .------>|
  |   |       |
  |   |    qualcosa
  |   |       |
  |   |      i++
  |   |(si)   |
  |   '---[i < 255?]
  |           |(no)
  |           |
  |           |
  |           |
  |          ii--
  |(si)       |
  '-------[ii > 0?]
              |(no)
              |

Quoto quanto detto da Claudio_F.

Questo è il tuo codice:

void loop() {
for(ii=255; ii>0; ii–);
for(i=0; i<255; i++) {
analogWrite(LED1, ii);
delay (10);
analogWrite(LED, i);
}
for(ii=0; ii<255; ii++);
for(i=255; i>0; i–) {
analogWrite(LED1, ii);
delay (10);
analogWrite(LED, i);
}
}

il primo for(rosso) porta la variabile ii da 255 a 0, poi il programma passa al secondo for(verde) che ad ogni giro aumenta di 1 la i e pilota in pwm i led. Il primo sempre a 0(ii), il secondo con valori di i crescenti.
Terminato il secondo for il programma entra nel terzo for (rosso).
La considerazione è analoga (e inversa) al primo for (rosso). Terminato anche questo for si passa nel quarto e ultimo for(verde) che ad ogni giro diminuisce la i di 1 e pilota il primo led sempre a 255(ii), il secondo con valori di i decrescenti. Poi il loop riparte.

Questo è il mio:

void loop() {

for(i=0; i<255; i++) {
ii–;
analogWrite(LED1, ii);
analogWrite(LED, i);
delay(10);
}
for(i=255; i>0; i–) {
ii++;
analogWrite(LED1, ii);
analogWrite(LED, i);
delay (10);
}
}

Nel primo for(rosso) viene aumentata la i, diminuita la ii e passati i relativi valori ai led. L’inverso accade nel secondo for

Dato che continuate a postare codice come NON si deve, vi ricordo che in conformità al regolamento, punto 7, dovete editare i vostri post (in basso a destra del post, bottone More → Modify) e racchiudere il codice all’interno dei tag CODE (… sono quelli che in edit inserisce il bottone fatto così: </>, tutto a sinistra).

Guglielmo

@Guglielmo: Ho utilizzato i colori per chiarire le parti di codice. Utilizzando i tag code i colori non sono più visibili. Se lo ritieni necessario sistemo il post (anche se poi la spiegazione senza colori diventa inutile)

doppiozero:
@Guglielmo: Ho utilizzato i colori per chiarire le parti di codice. Utilizzando i tag code i colori non sono più visibili. Se lo ritieni necessario sistemo il post (anche se poi la spiegazione senza colori diventa inutile)

Ok, concesso :smiley:

>sagittario0342: sistema il tuo primo post come ho indicato nel mio post #8, grazie.

Guglielmo

gpb01:
Ok, concesso :smiley:

>sagittario0342: sistema il tuo primo post come ho indicato nel mio post #8, grazie.

Guglielmo

Chiedo scusa se vi sembro imbranato, ma non ho capito come fare per eliminare la lista comandi dal mio primo post. Non vedo alcun pulsante "more modify", ma solo "post", "preview" e "save draft".

Ho capito intanto che il mio loop girava a vuoto, senza far accendere o spegnere il led, perché mi era sfuggito di farlo seguire dalle parentesi graffe.

void loop() {
for(i=0; i<255; i++) {
ii–;

Non trovo da nessuna parte questo { ii–, messo lì da solo.
Equivale dunque ad un loop nidificato? in altre parole, sarebbe sostituibile con un loop con altra variabile?
Scusate ma in questa prima fase voglio chiarirmi al massimo la sintassi.

sagittario0342:
Non vedo alcun pulsante “more modify”, ma solo “post”, “preview” e “save draft”

Si trova sotto il messaggio da modificare.

Non trovo da nessuna parte questo { ii–, messo lì da solo.

Il ‘i–’ è nella riga di definizione del for. Questi sono i due cicli annidati corrispondenti al terzo schemino “ascii art”:

for(ii=255; ii>0; ii--)
{
    for(i=0; i<255; i++)
    {
        qualcosa
    }
}

sagittario0342:
Non vedo alcun pulsante "more modify", ma solo "post", "preview" e "save draft".

In basso a destra, sotto il tuo post, c'è : Quote Quick Edit More (con delle iconcine) ... se metti il mouse su More ti si apre una tendina con cui puoi modificare il tuo post !

Guglielmo

gpb01:
In basso a destra, sotto il tuo post, c’è : Quote Quick Edit More (con delle iconcine) … se metti il mouse su More ti si apre una tendina con cui puoi modificare il tuo post !

Guglielmo

Guglielmo
spero di aver fatto per bene la correzione

sagittario0342:
spero di aver fatto per bene la correzione

Si è giusta, però un suggerimento sulla scrittura del codice come ho scritto qui a partire da: "E a margine ma non meno importante se si vuole che altri leggano il proprio codice".

scusami ancora
in un reply, se voglio riportare solo il codice di un post, lo evidenzio e lo quoto con “</>”, ma mi vedo apparire quotato anche il testo extra codice?
Dove sbaglio?

Claudio_F:
Si trova sotto il messaggio da modificare.

Il ‘i–’ è nella riga di definizione del for. Questi sono i due cicli annidati corrispondenti al terzo schemino “ascii art”:

for(ii=255; ii>0; ii--)

{
   for(i=0; i<255; i++)
   {
       qualcosa
   }
}

Claudio
Scusami ma, se non ragiono male, l’annidamento come su scritto, mi riporta alla situazione che mi correggevi tu!
Cioè, dopo il primo valore di “ii” (255), si susseguono i 255 valori di “i” (e 255 volte “qualcosa”), e solo dopo si ottiene il 2° valore di “ii” (254), quindi nuovamente 255 valori di “i” e così via.
Per cui la gradualità non viene effettuata negli stessi tempi!
Oppure ho capito male?
Infine, perché, nelle definizioni che leggo in giro, della funzione “for”, non leggo alcun cenno alla forma da te scritta, come qui di seguito?

for(i=0; i<255; i++) {
ii–;

Dunque devo capire che, non essendo possibile l’annidamento di due cicli for, si può ottenere l’effetto cercato con quest’ultima forma?
E che significa “aschii art”?
Ti ringrazio per la pazienza.

ps
ti ho chiesto separatamente perché non riesco a riportare solo il codice di un post (per es il tuo), pur selezionando solo quello, ma appare anche il testo extra

Il ‘i–’ è nella riga di definizione del for. Questi sono i due cicli annidati corrispondenti al terzo schemino “ascii art”:

Claudio
giacché non mi hai ancora risposto, aggiungerei una domanda:
e se volessi aggiungere un altro LED, per es al pin ~5 ?
Aggiungendo la variabile “iii”, con il codice

for(i=0; i<255; 1++){
ii–;
iii++;
analogWrite(LED9), i);
analogWrite(LED3, ii);
analogWrite(LED5, iii);
ecc.

il LED5 seguirebbe l’andamento del LED9. Come fare per avere tre andamenti distinti ma contemporanei?
ancora ti ringrazio
Franco