I told you you were changing too much
I did try to tell you a few posts ago:
OK, a function in C (or C++, except it’s called a “method” there when it’s part of a ‘class’) can be invoked with no parameters, or many. When it’s done its job, it can return one or no value.
double squareRoot(double fg)
{
...
return n;
}
When you invoke it, you give it a number to work with, a double precision floating point variable. Outside of the function, that variable can be called anything. Inside, the value of the variable is assigned to fg. You can do what you like with it inside the function, it has absolutely no effect outside. (If you’ve got an fg outside the function, it is NOT the same variable! The two can exist entirely separately. If you want to learn more, the words are “scope of variables”.)
When the function has done its thing, it (the function itself) has the value of n, so you can use it wherever you can use a variable (or a constant).
Inside the function, you use fg in exactly the same way as any variable anywhere in a program, but it only exists inside the function. You can’t know anything about it outside.
So, when I wrote
followed by
what I was trying to tell you was to look at the 1480 in double current = calcIrms(1480); and work out how it uses that number to read 1480 samples inside calcIrms.
The answer is of course the parameter Number_of_Samples is assigned the value 1480 when you call the function, and so in the line
for (unsigned int n = 0; n < Number_of_Samples; n++)
Number_of_Samples is replaced by the number 1480, and it does the stuff inside the curly brackets 1480 times (from n = 0 to n = 1479), making n bigger by one (n++) each time.
Is it now clear what I did? I changed the 0 in ads.readADC_SingleEnded(0); into a variable so that I could vary it
, and then made that variable a parameter in the function call so that I could feed the channel number into the function from outside.
And the rest was hopefully obvious (now, if not then).
You should have noticed I wrote above “When the function has done its thing, it (the function itself) has the value of n, so you can use it wherever you can use a variable (or a constant).”
Can you see anything wrong with writing this at the end of loop():
Serial.print(calcIrms(1480, 0));
Serial.print(" ");
Serial.print(calcIrms(1480, 1));
Serial.println(" ");
The correct answer is NO, calcIrms(...)will get the samples and calculate the current, and return the value to Serial.print, which will print it. If you want the value again though, you can’t have it because it’s gone. That’s the only reason I created IrmsA & IrmsB because I reckoned you’d want the values again somewhere.
A function that doesn’t return a value is called a “void function” and it has to do something elsewhere to be useful. Quite often, functions that do something elsewhere, like writing to a disc or to EEPROM, do in fact return a value that will indicate success or failure.
You declare a void function with the keyword “void”, like this for setting values in emonLibDB:
void EmonLibDB_set_vInput(uint8_t input, double _amplitudeCal, double _phase) {... }
because there’s not a lot I can do even to mark an error - the emonTx4 can’t easily answer back and report it. You can’t use a void function like I suggested in Serial.print, it makes no sense (and the compiler would probably complain). It has to be a statement on its own.