Go Down

Topic: come funziona void (Read 15850 times) previous topic - next topic

pippopippoli

salve a tutti ho scoperto che oltre al void setup e void loop posso creare un void tutto mio tipo void gianluca ,
ma non sono riuscito a capire come farlo partire e chiudere
non ho trovato niente su google come funziona?

PaoloP

Il linguaggio utilizzato da Arduino sono il C e il C++.
Le funzioni sono parte di questo linguaggio.
Per capirne il funzionamento puoi dare uno sguardo qui --> http://www.html.it/pag/15409/le-funzioni/
oppure qui --> http://cpiupiu.altervista.org/
Qui c'è un buona guida al C in generale ma è applicabile con alcuni accorgimenti ad Arduino --> http://blacklight.gotdns.org/guidac.pdf

nid69ita


salve a tutti ho scoperto che oltre al void setup e void loop posso creare un void tutto mio tipo void gianluca ,
ma non sono riuscito a capire come farlo partire e chiudere
non ho trovato niente su google come funziona?


Dato il nome deciso da te, dove vuoi eseguirlo, scrivi il nome e poi apri e chiudi la tonda.
Esempio stupido:
Code: [Select]

const byte pinLed=13;
void setup()
{ delay(1000);
  pinMode(pinLed,OUTPUT);
}

void ledOn()
{ digitalWrite(pinLed,HIGH);
}

void ledOff()
{ digitalWrite(pinLed,LOW);
}

void loop()
{ ledOn();
  delay(1000);
  ledOff();
  delay(1000);
}
my name is IGOR, not AIGOR

leo72

Aggiungo a quanto ti hanno già detto: "void" da solo significa "nulla", e messo prima del nome di una funzione indica che tale funzione non restituisce al chiamante nessun valore, vuol dire che vengono chiamate, eseguono il codice che contengono e poi restituiscono il controllo al programma chiamante.


Etemenanki

Scusa se mi inserisco, forse e' una domanda stupida, ma poniamo il caso che io voglia farmi delle funzioni tipo quella, ma che devono restituire qualcosa (ad esempio, una funzione che, richiamata solo quando mi serve, mi vada a leggere dei sensori analogici, esempio, NTC o fotocellula o volt, quello che vuoi, e che sia in grado di riportare il valore letto al programma principale sotto forma di variabile) ... quale sarebbe il modo migliore di farlo ? ... intendo, sempre come funzione richiamabile a comando come la void, non come parte del programma che continua a girare ...
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

PaoloP

Hai vari modi.
Se ti serve un solo parametro dichiari la funzione in base al tipo di parametro da restituire e usi il comando return all'interno della funzione.
Se sono più parametri li puoi passare alla funzione come puntatori e la funzione li manipola poi restituendoli modificati.
Potresti infine usare dei parametri globali singoli o organizzati in una struttura (C) o in una classe (C++).

gpb01


Scusa se mi inserisco, forse e' una domanda stupida, ma poniamo il caso che io voglia farmi delle funzioni tipo quella, ma che devono restituire qualcosa ...


Così :

Code: [Select]
tipo_da_restituire nome_funzione(tipo_parametri parametri) {
  ....
  ....
  <<implementazione>>
  ....
  ....
  return valore_da_restituire;
}


... o non ho capito la domanda ???  :smiley-roll:

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

Etemenanki

#7
Dec 20, 2013, 12:19 pm Last Edit: Dec 20, 2013, 12:21 pm by Etemenanki Reason: 1
gpb01: Fondamentalmente mi chiedevo se c'erano funzioni tipo la "void" (che non restituisce nulla), ma gia previste per restituire valori ... oppure se era necessario usare sempre "void", ma trasferendo i valori in un modo diverso, dato che di per se non lo fa (a quanto ho capito)

O in alternativa, se per fare una cosa simile, fosse necessario scriversi una specifica libreria ... cosa molto piu complessa ...


EDIT: PaoloP, potrebbe essere anche un solo parametro, al limite ... ad esempio, se fosse una funzione per leggere una temperatura solo quando serve, il dato sarebbe, alla fine, solo una variabile numerica contenente un singolo valore ...
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

gpb01


gpb01: Fondamentalmente mi chiedevo se c'erano funzioni tipo la "void" (che non restituisce nulla), ma gia previste per restituire valori ... oppure se era necessario usare sempre "void", ma trasferendo i valori in un modo diverso, dato che di per se non lo fa (a quanto ho capito) ...


Scusa, sarò io che non capisco ... ma quando, ad esempio, usi analogRead() ... quella è una funzione che ti ritorna un valore ... per l'esattezza un int ... quindi ... tu che vuoi sapere esattamente ???

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

nid69ita

#9
Dec 20, 2013, 01:56 pm Last Edit: Dec 20, 2013, 01:57 pm by nid69ita Reason: 1
@Guglielmo, credo @Eteme voglia fare una procedura (funzione con void) a cui passa dei parametri modificabili ma non ritorna nulla.

Si, @Eteme puoi, come detto da @PaoloP

Riassumendo:
1. se non devi restituire nulla fai una funzione void (che in altri linguaggi si chiamano procedura o sub)
2. se devi ritornare un solo valore fai una funzione dichiarando davanti al posto del void il tipo del ritorno (e in altri linguaggi le chiamano funzioni)
3. se devi ritornare più valori, di solito fai una funzione (void oppure no) che manipola i parametri (alcuni o tutti) che passi. Quindi quei parametri saranno dal punto di vista della funzione sia in input che in output. Alcuni parametri però in C vengono passati per valore (sono una copia del valore originale) perciò bisogna usare i puntatori per permettere alla funzione di cambiare i valori della variabile passata.
my name is IGOR, not AIGOR

Etemenanki

Se esiste il modo di scriversi una funzione "complessa", diversa da quelle gia esistenti, in grado di eseguire piu comandi, e trasferire anche valori, all'occorrenza ...

Ad esempio, il tuo riferimento all'analogread, quella e' una funzione gia esistente, che legge un valore analogico da un'ingresso (se non sbaglio), e lo mette in una variabile, ma fondamentalmente fa solo quello ... poniamo invece, ad esempio, il caso che tu debba eseguire anche altre funzioni connesse alla tua lettura, funzioni per le quali non hai un comando gia pronto ... se ho capito bene il discorso della "void", questa ti permette di crearti delle funzioni (chiamiamole "pacchetti di comandi", se vuoi), e di richiamarle quando ti servono, ma non restituisce nulla al programma ...

Se invece io volessi, sempre come esempio, eseguire diverse funzioni, il cui risultato finale e' una lettura analogica, e poi avere questo risultato trasferito indietro al corpo principale del programma, ma senza doverle riscrivere ogni volta che servono, e senza che rimangano sempre in esecuzione, il modo piu semplice che mi viene in mente e' di metterle in una "funzione" (o insieme di funzioni), e richiamarla solo nei momenti in cui mi serve ... in questo caso, per restituire il valore ad una variabile nel corpo principale una volta che la "funzione" e' terminata, il sistema migliore quale sarebbe ? ... creare una funzione specifica, o usare un "return" che spedisca il valore ad una variabile "esterna" alla mia "funzione" ?

Faccio un'esempio stupido, metti che debba campionare una serie di temperature dopo aver spostato una sonda ed atteso un tempo di stabilizzazione, ma che il tutto lo debba fare solo quando premi un pulsante (era una cosa che avevo fatto secoli fa in basic, e' il primo esempio che mi e' venuto in mente :P) ... dovrei fare qualcosa di simile:

un "corpo" principale
....
....
.... (istruzioni)
quando  il pulsante 1 e' premuto, richiama "funzione1"
elabora "x"
....
....
.... (altre istruzioni)
ecc

ed una sottofunzione tipo:

"funzione1"
   sposta la sonda
   attendi 10 secondi
   (loop) leggi 10 valori e mettili in un'array
   fai la media del contenuto dell'array
   "x"=risultato
   ritira la sonda
   torna a principale (ovviamente nel punto da cui e' stata lanciata "funzione1")
fine "funzione1"

che venga richiamata dal corpo principale solo quando serve (potrebbero anche essere piu funzioni differenti, per eventi diversi) ... e cosi via ... (scusa il linguaggio "da profano" ... lo so che magari a voi la domanda sembra stupida, come quando chiedono a me che differenza c'e' fra tensione e corrente :P ... ma sto ancora cercando di impararla, la programmazione delle MCU) ... a livello di programmazione Arduino, o comunque MCU Atmel, e' una cosa possibile, o non e' supportata e bisogna usare una struttura completamente differente ?
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

gpb01

Etem,
come fare te l'ho fatto vedere 3 post sopra, inoltre ...
... non hai limiti al numero di funzioni che puoi creare e le chiami solo quando ti servono.

Ogni funzione, può o non può tornare un valore.  Se NON torna alcun valore, per farlo capire al compilatore, si usa la parolina magica "void" che, appunto, indica che il compilatore NON deve aspettarsi indietro nessun valore dalla funzione.  Se la funzione ritorna un valore, allora devi dire quale è il tipo di valore che ritorna : byte, char, int, long int. .... e così via.

La funzione è quindi un blocchetto che fa sempre una determinata cosa ... la analogRead() legge il valore del convertitore ADC e ti ritorna questo valore in un int che tu assegni ad una variabile, quindi ... nel tuo programma, quando ti serve di leggerlo farai :

mio_valore = analogRead(Ax);

il controllo passerà temporaneamente alla funzione che, fatta la lettura, restituirà il valore che verrà assegnato alla tua variabile.

Allo stesso identico modo tu ti crei la TUA funzione che, nel tuo esempio, campiona la temperatura e ti ritorna il risultato ...
... quando ti serve la chiami, quella va in esecuzione, ritorna indietro il valore e tu assegni questo valore ad una tua variabile e prosegui con il tuo programma. Se ti riserve, la richiami di nuovo e così via ...

Più chiaro adesso ?

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

nid69ita

@Eteme  non capisco bene.
Quello che fa la tua funzione dipende da te e può essere complessa quanto vuoi. Può richiamare a sua volta altre funzioni da te create.
L'istruzione return si usa solo nel caso di funzione non void che deve ritornare un dato del tipo dichiarato.

Scusa @Guglielmo se mi sovrappongo  :)
my name is IGOR, not AIGOR

PaoloP

Per incasinare il discorso  ]:D diciamo pure che il C++ permette l'overloading delle funzioni.
Ovvero puoi avere più funzioni con lo stesso nome ma parametri in ingresso diversi e il compilatore sceglie quella che corrisponde ai parametri.
Il tipo di funzione (int, float, ecc), il parametro restituito e il codice interno può essere diverso da funzione a funzione.

Etemenanki


Se la funzione ritorna un valore, allora devi dire quale è il tipo di valore che ritorna : byte, char, int, long int. .... e così via.


Questo lo devo dichiarare nel "setup", solo all'inizio, se non ho capito male :P

Quote

... mio_valore = analogRead(Ax);

il controllo passerà temporaneamente alla funzione che, fatta la lettura, restituirà il valore che verrà assegnato alla tua variabile.
...

Più chiaro adesso ?


Un po piu chiaro, si (abbi pazienza, io sono cresciuto a gwbasic e basta :P) ... era la struttura della chiamata che mi fregava nel ragionamento ... quindi, secondo il tuo esempio, la chiamata della funzione (analogread) e' l'azione stessa di assegnarla come valore alla variabile ... io invece ragionavo (sbagliando) con la sequenza "chiama funzione > esegui funzione > funzione assegna valore a variabile > ritorna > usa variabile", (e li mi incasinavo :P) ... mentre il tuo esempio "mio_valore = analogRead(Ax);", chiama la funzione semplicemente assegnando il valore della funzione alla variabile ... inizia a calare la nebbia ;)

Solo un dubbio, questo tipo di struttura di richiamo comporta sempre che la funzione restituisce il controllo al punto in cui e' stata chiamata, giusto ? ... se invece dovesse condizionare il punto di rientro al valore restituito, dovrei farlo dopo il rientro usando degli if o dei case, non potrei farlo dall'interno della funzione stessa ...


Quote
L'istruzione return si usa solo nel caso di funzione non void che deve ritornare un dato del tipo dichiarato.


Questa devo studiarmela con calma ...



Quote
Per incasinare il discorso   ]:) diciamo pure che il C++ permette l'overloading delle funzioni.
Ovvero puoi avere più funzioni con lo stesso nome ma parametri in ingresso diversi e il compilatore sceglie quella che corrisponde ai parametri.
Il tipo di funzione (int, float, ecc), il parametro restituito e il codice interno può essere diverso da funzione a funzione.


Grazie, mi mancava un'altro po di confusione ... :P XD
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

Go Up