Esercitazione su" void "

Buona sera a tutti sto cercando di capire alcune cose che x voi saranno sicuramente banale ma potrebbe essere di aiuto forse ad altri neofiti come me, ho compilato il seguente codice x verificare di aver capito il "void" ma mi trovo ad avere un comportamento del sistema per me strano:
ho tre led di diverso colore che voglio comandare in base al valore di un potenziometro.
con il codice compilato ottengo però che nel primo if sono tutti spenti e fin qui bene, poi si verifica questo i led si accendono a coppie di due nonostante i digitalWrite indichino il contrario,
non riesco a capire dove sbaglio.Grazie


#define ledrosso 4    //definisco i pin dei 3 led
#define ledverde 2
#define ledgiallo 3

const int POT = A0;
//int value = 0;// Variabile dove e' memorizzato la lettura del segnale analogico
int Vpot = 0;// Variabile  dove e' memorizzatala conversione in tensione del valore digitale


void setup() {
  pinMode(POT, INPUT);
  pinMode(ledrosso, OUTPUT);
  pinMode(ledverde, OUTPUT);
  pinMode(ledgiallo, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int Vpot = analogRead(0);
  Vpot = map(Vpot , 0, 1023 , 0, 1023);

  //  value = analogRead(POT); // leggo valore potenziometro
  // Vpot = map( myValue, 0, 1023, 0, 1023);

  Serial.println( Vpot ); // scrivo il valore sulla seriale come debugging


  if  ((Vpot == 0) && (Vpot <= 100)) {
    SPENTO();
    //delay(500);
  }
  else if  ((Vpot >= 150) && (Vpot <= 300)) {
    LEDROSSO();
    //delay(500);
  }
  else if ((Vpot >= 350) && (Vpot <= 599)) {
    LEDGIALLO();
    //delay(500);
  }

  else  if ((Vpot >= 650) && (Vpot <= 899)) {
    LEDVERDE();
    //delay(500);
  }

  else (Vpot >= 900); {
    EXT();
    //delay(500);
  }
}

void LEDROSSO() {
  digitalWrite(ledrosso, HIGH);
  digitalWrite(ledgiallo, LOW);
  digitalWrite(ledverde, LOW);
delay(500);
}

void LEDVERDE() {
  digitalWrite(ledrosso, LOW);
  digitalWrite(ledgiallo, LOW);
  digitalWrite(ledverde, HIGH);
  delay(500);
}

void LEDGIALLO() {
  digitalWrite(ledrosso, LOW);
  digitalWrite(ledgiallo, HIGH);
  digitalWrite(ledverde, LOW);
  delay(500);
}

void EXT() {
  digitalWrite(ledrosso, HIGH);
  digitalWrite(ledgiallo, HIGH);
  digitalWrite(ledverde,  HIGH);
  delay(500);
  
}
void SPENTO() {
  digitalWrite(ledrosso, LOW);
  digitalWrite(ledgiallo, LOW);
  digitalWrite(ledverde, LOW);
}

Perdona, ma ... per evitare incomprensioni di linguaggio ti prego di osservare che quelle che tu indichi sono funzioni che, non resistuendo un valore, sono di tipo void.

La parolina void identifica il fatto che una funzione non ritorna un valore al chiamante. Se la funzione ritornasse un valore, al posto di "void" avresti dovuto mettere il "tipo" di valore tornato (byte, int, long, ecc.).

Quindi quelle che scrivi sono funzioni che, se non ritornano nulla, sono di tipo void, altrimenti si deve specificare il tipo del valore che ritornano. :slight_smile:

Giusto per chiarire bene i "termini" del linguaggio che si usa :wink:

Guglielmo

ok torno a studiare e riprovo!

C'è qualche cosa che non va...

Vpot = map(Vpot , 0, 1023 , 0, 1023);
E' inutile, perché Vpot rimane tra 0 e 1023.

if (Vpot == 0 && Vpot <= 100)
E' vera solo per Vpot==0!

I LED sono collegati (ognuno con una resistenza in serie) verso massa o verso i +5V?

Da 101 a 149, da 301 a 349 e da 600 a 649 i LED rimangono nello stato precedente: aumentando da LEDROSSO, da 301 a 349 rimane lo stato di LEDROSSO; diminuendo da LEDGIALLO, da 349 a 301 rimane lo stato di LED GIALLO. E' proprio questo che desideri?

C'è anche quel punto e virgola dopo la condizione che termina l'else:

else (Vpot >= 900); {
    EXT();
  }

Quindi la funzione 'EXT' è fuori da ogni condizione e viene richiamata sempre ad ogni ciclo.

Qualcosa?... :wink:
Oltre a quanto hai giustamente segnalato tu, aggiungo:

int Vpot = analogRead(0);

Ha definito correttamente la costante "POT" che punta al pin analogico del potenziometro A0, ma poi non la usa e nella analogRead() legge da 0 invece di "analogRead(POT)"

Poi nella if();

if  ((Vpot == 0) && (Vpot <= 100)) {

il primo termine (Vpot == 0) va tolto o almeno impostata come "if ((Vpot >= 0) && (Vpot <= 100)) {)

Poi nelle if() la prima verifica i valori da 0 a 100, ma tra 101 e 149 non deve fare nulla? Non è che magari la prima dovrebbe essere "if (Vpot <= 149)"? Stessa cosa per i valori da 301 a 349, e da 600 a 649.

E nell'ultima c'è un punto e virgola di troppo, deve essere:

 else (Vpot >= 900) {

EDIT: si, e manca pure la if():

 else if (Vpot >= 900) {

Grazie Maurotec. :smiley:

Infatti: ci sono delle zone non definite in cui rimane lo stato precedente: in questo caso, SPENTO in salita e LEDROSSO in discesa.

Ci manca pure if :smile:

Insomma ne avesse azzeccata una, incluso il titolo.

"Eilà" grazie x le risposte , gli intervalli tra un valore e l'altro erano impostati così per vedere cosa cambiava e mi sono scordato di correggerli ( decisamente cotto ero!!! lavoro pesante ho!!!) , i led devono passare da uno stato all'altro in modo repentino accendendosi come specificato nei digitalWrite , ho corretto il codice ma ottengo sempre questo comportamento:
pot =0 a 100 tutti accesi
pot =101 a 300 led verde e giallo accesi
pot=301 a 599 led verde e rosso accesi
pot=da 600 a 899 led rosso e giallo accesi
pot = oltre 900 tutti spenti

I led sono collegati con singole resistenze verso +5vcc


#define ledrosso 4    //definisco i pin dei 3 led
#define ledverde 2
#define ledgiallo 3

const int POT = A0;
//int value = 0;// Variabile dove e' memorizzato la lettura del segnale analogico
int Vpot = 0;// Variabile  dove e' memorizzatala conversione in tensione del valore digitale


void setup() {
  pinMode(POT, INPUT);
  pinMode(ledrosso, OUTPUT);
  pinMode(ledverde, OUTPUT);
  pinMode(ledgiallo, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int Vpot = analogRead(POT);
  Vpot = map(Vpot , 0, 1023 , 0, 1023);

  //  value = analogRead(POT); // leggo valore potenziometro
  // Vpot = map( myValue, 0, 1023, 0, 1023);

  Serial.println( Vpot ); // scrivo il valore sulla seriale come debugging


  if  ((Vpot >= 0) && (Vpot <= 100)) {
    SPENTO();
    //delay(500);
  }
  else if  ((Vpot >= 101) && (Vpot <= 300)) {
    LEDROSSO();
    //delay(500);
  }
  else if ((Vpot >= 301) && (Vpot <= 599)) {
    LEDGIALLO();
    //delay(500);
  }

  else if ((Vpot >= 600) && (Vpot <= 899)) {
    LEDVERDE();
    //delay(500);
  }

  else if (Vpot >= 900) {
    EXT();
    //delay(500);
  }
}

void LEDROSSO() {
  digitalWrite(ledrosso, HIGH);
  digitalWrite(ledgiallo, LOW);
  digitalWrite(ledverde, LOW);

}

void LEDVERDE() {
  digitalWrite(ledrosso, LOW);
  digitalWrite(ledgiallo, LOW);
  digitalWrite(ledverde, HIGH);
  
}

void LEDGIALLO() {
  digitalWrite(ledrosso, LOW);
  digitalWrite(ledgiallo, HIGH);
  digitalWrite(ledverde, LOW);
 
}

void EXT() {
  digitalWrite(ledrosso, HIGH);
  digitalWrite(ledgiallo, HIGH);
  digitalWrite(ledverde,  HIGH);
  
}
void SPENTO() {
  digitalWrite(ledrosso, LOW);
  digitalWrite(ledgiallo, LOW);
  digitalWrite(ledverde, LOW);
}

Quindi i led hanno già la 5 volt, ciò che gli manca per accendersi è il GND.
Quando scrivi:

void SPENTO() {
  digitalWrite(ledrosso, LOW);
  digitalWrite(ledgiallo, LOW);
  digitalWrite(ledverde, LOW);
}

Da ogni pin esce GND e quindi i led si accendono tutti.
Quindi per spegnerli HIGH al posto di LOW.
Ovviamente, LOW per accenderli.

Ciao.

Ora capisco grazie mille è come se mi avessi acceso la famosa lampadina in poche parole!! mi sembrava talmente banale da non poter essere!!

Per inciso e l'altro problema dove sono riuscito a sbagliare?

All'inizio è così e nulla è banale. L'utente arduino non solo deve imparare a programmare ma deve capirci anche di elettronica per cui si è impegnati su due fronti, fronti o materie davvero complesse anche quando semplificate.

Ad esempio se colleghi i led al contrario, cioè la resistenza su GND, poiché il GND al led gli arriva attraverso la resistenza all'altro pin del led gli devi dare 5 volt per accendersi e quindi:

digitalWrite(pinNumber, HIGH);

Così al pin pinNumber ci saranno 5 volt rispetto a GND.

Se sei agli inizi ti consiglio proprio di fare l'esperimento di collegare i led come suggerito.

Ciao.

Ok provato e capito grazie mille

Buona sera a tutti, purtroppo ho ancora dei dubbi: allego lo sketch che" fa quello che deve fare" accendere i led in una sequenza precisa sia a salire con i valori del pot che a scendere, continuo a non capire perchè con il prog precedente ottengo l'accensione in coppia dei led!!! qualcuno mi può spiegare l'arcano per me misterioso mistero???


#define ledrosso 4    //definisco i pin dei 3 led
#define ledverde 2
#define ledgiallo 3

const int POT = A0;
//int value = 0;// Variabile dove e' memorizzato la lettura del segnale analogico
int Vpot = 0;// Variabile  dove e' memorizzatala conversione in tensione del valore digitale


void setup() {
  pinMode(POT, INPUT);
  pinMode(ledrosso, OUTPUT);
  pinMode(ledverde, OUTPUT);
  pinMode(ledgiallo, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int Vpot = analogRead(POT);
  Vpot = map(Vpot , 0, 1023 , 0, 980);

  Serial.println( Vpot ); // scrivo il valore sulla seriale come debugging


  if  ((Vpot >= 0) && (Vpot <= 100)) {
    //SPENTO();
    //delay(500);
    digitalWrite(ledrosso, LOW);
    digitalWrite(ledgiallo, LOW);
    digitalWrite(ledverde,  LOW);
  }
  else if  ((Vpot >= 101) && (Vpot <= 300)) {
    // LEDROSSO();
    //delay(500);
    digitalWrite(ledrosso, LOW);
    digitalWrite(ledgiallo, HIGH);
    digitalWrite(ledverde, HIGH);
  }
  else if ((Vpot >= 301) && (Vpot <= 599)) {
    //LEDGIALLO();
    //delay(500);
    digitalWrite(ledrosso, HIGH);
    digitalWrite(ledgiallo, LOW);
    digitalWrite(ledverde, HIGH);
  }

  else if ((Vpot >= 600) && (Vpot <= 899)) {
    // LEDVERDE();
    //delay(500);
    digitalWrite(ledrosso, HIGH);
    digitalWrite(ledgiallo, HIGH);
    digitalWrite(ledverde, LOW);
  }

  else if (Vpot >= 900) {
    // EXT();
    //delay(500);
    digitalWrite(ledrosso, HIGH);
    digitalWrite(ledgiallo, HIGH);
    digitalWrite(ledverde, HIGH);
  }
}

  void LEDROSSO() {
    delay(1000);
  //digitalWrite(ledrosso, LOW);
  //digitalWrite(ledgiallo, HIGH);
  //digitalWrite(ledverde, HIGH);

  }
/*
  void LEDVERDE() {
  // digitalWrite(ledrosso, HIGH);
  // digitalWrite(ledgiallo, HIGH);
  digitalWrite(ledverde, LOW);

  }

  void LEDGIALLO() {
  //digitalWrite(ledrosso, HIGH);
  digitalWrite(ledgiallo, LOW);
  // digitalWrite(ledverde, HIGH);

  }

  void EXT() {
  digitalWrite(ledrosso, LOW);
  digitalWrite(ledgiallo, LOW);
  digitalWrite(ledverde,  LOW);

  }
  void SPENTO() {
  digitalWrite(ledrosso, HIGH);
  digitalWrite(ledgiallo, HIGH);
  digitalWrite(ledverde, HIGH);
  }
*/

Te l'hanno detto: se i LED si accendono con logica inversa ossia mettendolo LOW, tu facendo:

void LEDROSSO() {
  digitalWrite(ledrosso, HIGH);
  digitalWrite(ledgiallo, LOW);
  digitalWrite(ledverde, LOW);
}

accendevi il giallo ed il verde, non il solo rosso.

Posso darti un consiglio? Soprattutto all'inizio, per sperimentare ed apprendere più rapidamente certi concetti abbastanza di base, usa un simulatore di circuiti con Arduino come ad esempio TinkerCad, che oltre a non costringerti a preparare e modificare fisicamente i collegamenti e non rischiare di bruciare componenti mentre fai prove, ti permette di simulare il circuito e relativo software da qualsiasi PC via web.

ok grazie