Creare una funzione,help!

Buon giorno,
ho un problema che faccio fatica ad uscirne,e non essendo propriamente un programmatore,spero che qualcuno mi aiuti a chiarirmi le idee e risolvere il problema.
Vorrei creare una funzione che si ripete all'interno dello sketch, in cui gli metto un indice dove pescare il dato e restituisca due dati elaborati in due variabili; mi spiego meglio...
Ho un array chiamato T di tipo int formato da 5 clust, la funzione prende il dato della posizione i e lo elabora restituendo x e y in funzione di T.
Questo perchè lo devo fare diverse volte all'interno dell loop e ripetere il codice con le stesse istruzioni mi sembra assurdo...
Come posso fare??
Io pensavo di fare tipo

void mia_funzione (int T[i],int x, int y){
                               x=T[i]*60;
                               y=T[i]/60;
}

void loop(){
........
i=0;
mia_funzione();
Serial.print(x);
Serial.print(y);
.......
i=1;
mia_funzione();
Serial.print(x);
Serial.print(y);
......
i=5;
mia_funzione();
Serial.print(x);
Serial.print(y);
....
}

Che ne pensate?Dove sbaglio?
Grazie

Se l'array T è globale come penso la definizione della funzione diventa così:

void mia_funzione (byte i,int *x, int *y){
  x=T[i]*60;
  y=T[i]/60;
}

e la chiamata:

mia_funzione(1,&valX, &valY);
Serial.print(valX);
Serial.print(valY);

valX e valY sono due variabili di tipo int definite o nel loop o come globali

Riporto questa risposta che avevo dato al tuo post di ieri che è stato rimosso:

Intanto, per calcolare Tmin dovrebbe bastare:

Tmin = T % 60;

Poi non ti conviene passare l’intero array alla funzione, ma solo l’elemento che ti interessa.

Infine, il problema più grande è che in C non puoi facilmente ritornare due valori da una funzione. Per aggirare questo limite puoi usare una struct, tipo:

struct OreMin {
  int h;
  int m;
}

OreMin scomponi (const int t) {
  OreMin om;

  om.h = t / 60;
  om.m = t % 60;

  return om;
}

Oppure, puoi passare i valori da restituire tramite argomenti, che devono essere puntatori o, meglio in C++, reference:

void scomponi (const int t, int& h, int& m) {
  h = t / 60;
  m = t % 60;
}

Spero di essere stato chiaro.

fabpolli:
Se l'array T è globale come penso la definizione della funzione diventa così:

void mia_funzione (byte i,int *x, int *y){

*x=T[i]*60;
 *y=T[i]/60;
}

Se vuoi usare questa soluzione, nota che mancavano due asterischi, che ho aggiunto. :-*

SukkoPera:
Se vuoi usare questa soluzione, nota che mancavano due asterischi, che ho aggiunto. :-*

Si, errore mio :slight_smile:

Grazie ragazzi, infatti ieri ho scritto un post simile ma nn l'ho più trovato...
Quindi se non ho capito male le funzioni restituiscono un solo valore alla volta, giusto?
L'array T è stato dichiarato inizialmente come globale, nello sketch lo devo "elaborare", controllare...Le struct sono per me terreno minato, ho iniziato da poco e faccio fatica a capire come lavorano; in realtà, mi sorge una domanda: nelle struct dopo che ho raggruppato le variabili, posso modificarle singolarmente? come faccio??Qualche link che possa aiutarmi a capire bene come si usano??
Ritornando a noi...
Penso che la funzione di sukkopera mi piace un bel po'....

void mia_funzione (byte i,int *x, int *y){
  *x=T[i]*60;
  *y=T[i]/60;
}

e a chiamata

mia_funzione(1,&valX, &valY);
Serial.print(valX);
Serial.print(valY);

Altra domanda banale:&valX esattamente cosa fa?
Se poi x volessi passarla ad un'altra variabile posso fare come segue?

int variabile=valX;

L'istruzione &valX passa per riferimento (ovvero posizione della variabile in memoria e non il suo valore) la variabile alla funzione che nella sua definizione ha che tale variabile è un puntatore alla posizione di memoria della variabile stessa (l'asterisco che trovi nella definizione) quindi quando dentro la funzione modifichi il valore usando

*x=T[i]*60;

di fatto modifichi il valore della varibile valX che è definita esternamente alla funzione, es:

void loop()
{
byte valX = 10;
mia_funzione(&valX);
//Da qui in poi valX vale 20
}

void mia_funzione(byte *x)
{
  *x = 20;
}

Quella funzione è di @fabpolli e usa i puntatori, la mia è simile ma usa i reference, una novità del C++.

Se guardi il mio esempio con le struct vedi subito come fare a modificare le singole variabili contenute. Ovviamente questo si può fare, altrimenti sarebbero del tutto inutili :D.

Chiedo scusa Fabpolli per l'errore di persona...Sto leggendo velocemente e mi sono perso...
Ok, credo di aver capito...
Vediamo se ho capito mettendo un'ulteriore array...

int array [5];
void mia_funzione (byte i,int *x, int *y){
  *x=T[i]/60;     // in *x ho le ore
  *y=T[i]%60;   // in *y ho i minuti
}

void loop()
{

mia_funzione(1,&valx,&valy);

array[0]=*x;        //in array[0] ho il valore ore
array[1]=*y;       //in array [1] ho il valore minuti

}

Sbaglio???

Non esattamente, nel loop x e y non esistono (esistono solo dentro la funzione mia_funzione) nel loop devi usare
valx e valy (ho usato appositamente due nomi differenti per cercare di non crearti confusione) e per assegnare il loro valore a due posizioni dell'array, ma più in generale ad altre variabili o per fare confronti ecc, devi usarle senza asterisco o e commeciale ovvero:

array[0]=valx;

Quindi se scrivo

int array [5];
void mia_funzione (byte i,int *x, int *y){
  *x=T[i]/60;     // in *x ho le ore
  *y=T[i]%60;   // in *y ho i minuti
}

void loop()
{

mia_funzione(1,&valx,&valy);

array[0]=valx;        //in array[0] ho il valore ore
array[1]=valy;       //in array [1] ho il valore minuti

}

dovrebbe girare??
Toglimi una curiosità:&val all'interno della dichiarazione della funzione e val quando la richiami, è un comando del tipo "dammi il valore di x"??

&val = “dammi l’indirizzo di val”.

Il valore di val è semplicemente val.

Nota anche che devi dare un valore sensato a T[1] prima di chiamare mia_funzione(), per come hai strutturato il programma.

Si così dovrebbe "giarare"
Allora nella definizione della funzione dichiari che una o più variabili devono essere passate per riferimento con il carattere asterisco.
Quando richiami la funzione devi passare le variabili per riferimento e lo fai con il carattere della e commerciale.
Es.
La variabile valx contiene il valore 10 e è memorizzata nella locazione di memoria 12388, se la funzione prevede di passare per valore (ovvero senza asterisco nella definizione) x varrà 10 ma tutte le modifiche al valore di x dentro la funzione non modificano il valore di valx:

{
  byte valx = 10;
  mia_funzione(valx);
  //Qui valx vale ancora 10
}
void mia_funzione(byte x)
{
  x = 20;
}

nel tuo caso la variabile x ha il solito riferimento di memoria di valx quindi se cambi il valore di x dentro la funzione di fatto stai variando il valore contenuto nella solita cella di memoria di valx pertanto all'uscita della funzione se controlli valx avrai il valore modificato dalla funzione come nell'esempio precedente
[EDIT]
Anticipato di poco da @sukkoPera
[/EDIT]

Mi da errore...valx e valy non esistono..
Come giustamente dici...
Ma,io allora non capisco come devo scrivere per farla funzionare...
Scusate ma ho la testa dura...

In effetti non li hai mai dichiarati...

int valx, valy;

manolomao:

void mia_funzione (int T[i],int x, int y)

{ x=T[i]*60;
  y=T[i]/60;
}
void loop()
{ i=0;
  mia_funzione();
  Serial.print(x); Serial.print(y);
  i=5;
  mia_funzione();
  Serial.print(x); Serial.print(y);
}



Che ne pensate ?

Premetto che i vari consigli che ti hanno dato vanno bene.
Mi pare, però, hai sottovalutato il consiglio di @sukko al post #2 e quindi stai facendo un errore macroscopico. Il dato che vuoi elaborare è un numero int, che sia contenuto dentro ad un vettore T frega solo al momento della chiamata alla funzione.
O crei una funzione a cui passi un vettore e il numero di quale elemento devi considerare, oppure MOLTO più semplicemente passi un int (tipo di ogni elemento del vettore) e basta. Cosa passi lo decidi nella chiamata/e nel loop

void mia_funzione (int val,int& x, int& y)
{ x=val*60;
  y=val/60;
}
void loop()
{ i=0;
  mia_funzione(T[i],x,y);          // ovvero passo val=T[0]
  Serial.print(x); Serial.print(y);
  mia_funzione(T[4],x,y);
  Serial.print(x); Serial.print(y);
  int v=T[5];
  mia_funzione(v,x,y);
  Serial.print(x); Serial.print(y);

Nid69ita, grazie...
Credo di aver capito un po' come funziona...
Anche i tuoi tre esempi di come chiamarli sono chiari, tre modi diversi di fare la stessa cosa...
Poi per passarli ad un altro array basta fare come segue??

int T[5];               //array di valori in minuti
int arr_prova[10];//destinazione valori divisi tra ore e minuti
void mia_funzione (int T[i],int x, int y)
{ x=T[i]/60;
  y=T[i]%60;
}
void loop()
{ mia_funzione(T[0],x,y);
   arr_prova[0]=x;              //in array_prova[0] ho le ore
   arr_prova[1]=y;              // in array_prova[1] ho i minuti
  
}

Invece a me sembra che non hai capito niente. Continui a non aver dichiarato le variabili, e di almeno 4 soluzioni corrette e funzionanti che ti abbiamo dato tra tutti, ne hai messa in piedi una non funzionante, senza preoccuparti di capire tutto il discorso che ti abbiamo fatto su reference e puntatori :confused:.

Io non vi capisco proprio. Invece di dedicare una settimana a capire i concetti basilari del C, preferite perdere mesi a fare cose a caso finché non funzionano per miracolo, e al progetto dopo siete da capo. Ma contenti voi...

Ok, mio errore di trascrizione...

int T[5];               //array di valori in minuti
int arr_prova[10];//destinazione valori divisi tra ore e minuti
int x,y;

void mia_funzione (int val,int& x, int& y)
{ x=val/60;
  y=val%60;
}
void loop()
{
  mia_funzione(T[0],x,y);          // 
   
arr_prova[0]=x;              //paso ore
arr_prova[1]=y;             //passo minuti

Scusate

Dovrebbe funzionare, ma a questo punto x e y è meglio che siano variabili locali a loop(), non globali.