Go Down

Topic: Void -> how it returns values to the main programm (Read 3073 times) previous topic - next topic

herctrap

Hallo

i am new to C and the arduino

i have  a question

i am bulding a vu meter

and i want to find the max and the min analog read from my microphone

so i write a "void"

Code: [Select]
void analog_calibration (int analoginput)
{
 
 timecounter = millis();
 timerunning = 0;
 mini = 1030;
 maxi = 0;
 
 for (i=1; ((timerunning-timecounter) < calibrationtime); i++ )
   {
     
     value = analogRead(analoginput);
     
     if (value < mini) mini = value;
     if (value > maxi) maxi = value;
     
     timerunning = millis();
     
   }

}


so in my programm sometime i will write

analog_calibration(microphone);


how can i make return me the min and the max value?
to the main programm


Groove

#1
May 05, 2010, 04:48 pm Last Edit: May 05, 2010, 04:52 pm by GrooveFlotilla Reason: 1
"void" means "nothing".
A "void" function returns no value.

A function can return only a single value, so if you want to pass back two values from a function, you can use:
1) a structure
2) pointers
3) references.

I'd probably go with 3).

Code: [Select]
void analog_calibration (int analoginput, int& maxVal, int& minVal))


Quote
so i write a "void"

You don't write a "void", you write a function of type void.
Per Arduino ad Astra

AlphaBeta

#2
May 05, 2010, 04:54 pm Last Edit: May 05, 2010, 05:04 pm by AlphaBeta Reason: 1
Code: [Select]
void analog_calibration(int analoginput, unsigned long calibrationtime, int *detectedMini, int *detectedMaxi)
{
 //reset these to ensure a new reading
 detectedMini = 1030;
 detectedMaxi = 0;
 
 //local variables used to time the calibration
 unsigned long timecounter = millis();
 unsigned long timerunning = 0;
 int value = 0; //store the current read
 while ((timerunning-timecounter) < calibrationtime)
 {
     value = analogRead(analoginput);

     if (value < *detectedMini) *detectedMini = value;
     if (value > *detectedMaxi) *detectedMaxi = value;

     timerunning = millis();
 }
}


Call it like:
Code: [Select]

int micMin;
int micMax;
analog_calibration(microphone,1000,&micMin,&micMax); //calibrate min and max for mic over a period of 1000 ms


[edit]Groove beat me to it.
Since we ended up 'recommending' different solutions I'll explain why I used the pointer method: It is simply because the the code that calls the function will have to explicitly say that the adress of a variable is to be sent. This is a way to tell the coder 'remember that these variables may, or may not, be altered when you call this function'. The reference method provides the caller no visual cues as to what might happen to the original variable (not just the value of it).[/edit]
[edit]WHOOPS!
Thank you Groove!

I forgot that 'tiny' detail in the midst of everything  :-[(I forgot to dereference the min/max variables in the function body)[/edit]

PaulS

Quote
so i write a "void"


No. You wrote a function. Functions can have many different return types. The function you wrote was defined to not return a value (that's what the void in front means).

Had you defined the function to return an int, you could (and should) have had a return statement, to return the appropriate value.

Functions can return only a single value, though.

You could declare the function like this:

Code: [Select]
void analog_calibration(int analoginput, int &mini, int &maxi)
{
  // Compute mini and maxi
}


Then, call it like this:
Code: [Select]
int minVal;
int maxVal;
int inVal = 27;
analog_calibration(inVal, minVal, maxVal);
// minVal contains the value defined in the function as mini
// maxVal contains the value defined in the function as maxi


However, mini and maxi are not typed in the function you wrote, so they must be global variables. In which case, there is not need to return them.

Groove

Code: [Select]
void analog_calibration(int analoginput, unsigned long calibrationtime, int *detectedMini, int *detectedMaxi)

...
if (value < detectedMini) detectedMini = value;


Ahem.   ;)
Per Arduino ad Astra

herctrap

#5
May 05, 2010, 05:10 pm Last Edit: May 05, 2010, 05:12 pm by herctrap Reason: 1
thanks

so the & means that the value goes back

PaulS

The & means that you are passing by reference, instead of by value. In other words, the address of the memory location referred to by that name (the location to read from/write to) is passed to the function, instead of the value at that address.

Having the address, instead of the value, means that the function can modify the value and that modified value will be seen by the caller when the function ends.

herctrap

Code: [Select]
void analog_calibration (int analoginput, int &mini, int &maxi )
{
 long value;
 
 long timecounter = millis();
 long timerunning = 0;
 mini = 1030;
 maxi = 0;
 
 for (i=1; ((timerunning-timecounter) < calibrationtime); i++ )
   {
     
     value = analogRead(analoginput);
     
     if (value < mini) mini = value;
     if (value > maxi) maxi = value;
     
     timerunning = millis();
     
   }

}


then i call

analog_calibration (int microphone, minval, maxval )

and below this line

in minval i will have the last value of the mini
and on the maxval the last value of the maxi

?

sry but the arduino is still on the way and i cant test it

PaulS

Code: [Select]
for (i=1; ((timerunning-timecounter) < calibrationtime); i++ )


The variable i is not typed. This will not compile, unless i is a global variable. If it is, using a global variable as a loop counter is not appropriate.

Typically, a for loop is used when the number of iterations is known. In this case, the termination of the loop is not dependent on i, so a for loop is not really appropriate.

calibrationtime is not typed, so it must be a global variable.

millis() returns an unsigned long, not a long. So, timecounter and timerunning are not typed appropriately.

As a side note, camel case is preferred for variable names, so timeCounter, timeRunning, and calibrationTime would be better names.

Finally, analogRead does not return a long, so value is mis-typed.

herctrap

i didnt find a way to loop something for a amount of time(sec) not an amount o times ( repeats )

yes i use i j k as global for many void functions

about the unsigned long

its gone work ?


PaulS

Quote
i didnt find a way to loop something for a amount of time


Look at the while statement.

Quote
yes i use i j k as global for many void functions


Stop that. And get rid of the word there. The term is function(s). void is a return type.

Quote
about the unsigned long


What about it?

wayoda

Quote

A function can return only a single value, so if you want to pass back two values from a function, you can use:
1) a structure
2) pointers
3) references.

I'd probably go with 3).

The Arduino-preprocessor cannot handle reference parameters in sketches (yet?).
There is a bug-report for this (google-code-servers are currently down  :( I can't set a link to the issue).

So only structure and pointer solutions will work.
Eberhard


herctrap

#12
May 05, 2010, 06:27 pm Last Edit: May 05, 2010, 06:30 pm by herctrap Reason: 1
i made the changes

it is a knight rider project

i have write the most of my patterns

but i dont have write the main programm

----------------------------

how can we fase an led and the same check if a button is pressed

can the arduino goes over two loops at the same time

---------------------------

the whole code

run out of  Remaining characters on post

-------------------------


int led[ ] = {54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8};

is this correct

the led[0] is equal to 54
and led[45] is equal to 8

"45" is the total numbers minus one for the zero

they have to be 46 - i havent count them

AWOL

Quote
The Arduino-preprocessor cannot handle reference parameters in sketches (yet?).


Arduino 0017:
Code: [Select]
void myProc (int& a, int& b)
{
 a = 2;
 b = 7;
}

int myA = 0;  //Belt AND braces.
int myB = 0;

void setup ()
{
 myProc (myA, myB);
 Serial.begin (9600);
 Serial.println (myA);
 Serial.println (myB);
}

void loop ()
{
}


seems to work perfectly.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

AlphaBeta

This has become a long thread!
Quote
Stop that! And get rid of the word there. The term is thread(s). long is an adjective


OK, so I put it on the edge, but I think it is perfectly fine to say 'void function', it is easier to say and understand than 'a function that returns void' which is kind of a paradox, really.

Pun slightly intended PaulS  8-)

Go Up