Can't Run Function Only Once from setup()

How do I get a function call to run only once? I'm reading the value of a pot to set a parameter that the code will use to decide which functions to execute. Since I have some time-critical things happening in loop(), don't want it to execute continuously in loop(), just once. Tried putting the call to readStyle() function in setup() but can't get it to work properly... "style" is always "0" and never gets set to the appropriate value for the pot position. If I put everything in loop(), readStyle() works fine and sets "style" correctly.

Also, is there an alternative to all the "if" statements? Switch/Case wants an integer value for "Case" and not an equation.

void setup()  {
  /* Do init stuff here, runs once per reset cycle */
  Serial.begin(9600);        // Initialize the connection to Serial Monitor

//  int style;                 // Style read from Style Knob
//  void readStyle();
  //Serial.print("Style is " );
  //Serial.println(style);

}

  int style;                 // Style read from Style Knob
  void readStyle();
  //void readStyle();
  //Serial.print("Style is " );
 // Serial.println(style);
  
/**********************************************************/
/********************* Begin Main Loop ********************/
/**********************************************************/
void loop() {       // Program execution returns here after each sequence

//  readStyle();
Serial.print("Style is " ); 
Serial.println(style);
delay(1000);

} /********************* End Main Loop *************************/

/*********************************************/
/* Read Style Knob and Set Style Type                      */
/*********************************************/
void readStyle() {
 /* Check the style control */
 int styleRead;
 
  styleRead = analogRead(5);              // Read Style input pot level
  //Serial.print("Style Value Read is " );
  //Serial.println(styleRead);
  
  if (styleRead >= 1006 && styleRead <= 1023) style = 10;
  if (styleRead >= 928 && styleRead <= 1005)  style = 9;
  if (styleRead >= 806 && styleRead <= 927)   style = 8;
  if (styleRead >= 685 && styleRead <= 805)   style = 7;
  if (styleRead >= 573 && styleRead <= 684)   style = 6;
  if (styleRead >= 469 && styleRead <= 572)   style = 5;
  if (styleRead >= 362 && styleRead <= 468)   style = 4;
  if (styleRead >= 241 && styleRead <= 361)   style = 3;
  if (styleRead >= 111 && styleRead <= 240)   style = 2;
  if (styleRead >= 23 && styleRead <= 110)    style = 1;
  if (styleRead >= 0 && styleRead <= 22)      style = 0;

} // end readStyle

Put it in "setup()" runs once per reset cycle

If you define "style" in setup(), it's only in scope in setup()

Also, is there an alternative to all the "if" statements? Switch/Case wants an integer value for "Case" and not an equation.

Some dialects of C/C++ allow you to specify numeric ranges in case statements using ellipsis.
The one used for Arduino is one such dialect.

The one used for Arduino is one such dialect.

Remember to put a space each side of the ellipsis in the case statement otherwise the compiler will complain about "too many decimal points"

rickso234:
Also, is there an alternative to all the "if" statements? Switch/Case wants an integer value for "Case" and not an equation.

Yes, just code whatever math you used to derive the ranges in the first place. A close approximation is:

style = styleRead / 10;

You just need to get the right scale and offset.

Slice the possibilities off from one end to the other.

// style can only be 0 to 1023.
  int style = styleRead();

  if style <= 22)               style = 0;
  else if (style <= 110)     style = 1;
  else if (style <= 240)     style = 2;
  else if (style <= 361)     style = 3;
  else if (style <= 468)     style = 4;
  else if (style <= 572)     style = 5;
  else if (style <= 684)     style = 6;
  else if (style <= 805)     style = 7;
  else if (style <= 927)     style = 8;
  else if (style <= 1005)   style = 9;
  else                               style = 10;

If you define "style" in setup(), it's only in scope in setup()

But I want to use "style" in loop() and in another function called from loop().
Defining style and having it in correct scope seems to be the problem here. Where do I define "style" to maintain scope outside of setup() but still be callable from setup()?

Where do I define "style" to maintain scope outside of setup() but still be callable from setup()?

"style" is a variable, so it isn't "callable", but if you put the definition outside loop() or setup(), it has global scope.

Yes, after I posted I realized that "style" isn't callable. What I meant was calling styleRead(), which uses "style", from setup().

Believe I tried to "put the definition outside loop() or setup()" but either "style" still was not populated or I got another error, can't recall which. Will try again though.

Switch/Case using ellipsis is exactly what I want to do ... will try it!
This is a good description of using ellipsis:

Made some fixes above. What I want to show is how to trim your selection logic some.
It's less typing than a ranged switch-case and it should be less cycles with only 1 condition per branch.

Tried all three methods of checking the pot voltage and returning the selected style... , if, switch/case, and trimed logic.

Elapsed time to read the style pot is the same for each method... 116usec.

start = micros();
style = readStyle();
elapsed = micros() - start;

Still cannot read "style" at other than "0" when the call is outside of void loop(). Think it's due to the "style" return param and inability to define it in the correct scope. THink I may be forced to use an "if" and read it only once on the first pass of the void loop().

Post the code you have now,and the scope can be fixed. style would need to be declared global and before the setup function.

I missed that one.

void readStyle()
{
// should work if style is global, but it's pretty crappy and there's a catch
}

int x
x = readStyle(); // likely assigns void/NULL/0 to x
x = style; // if style is a global int

There's better ways.

...style would need to be declared global and before the setup function.
That did it! Never thought of declaring anything before setup().
readStyle() runs once and correct value of "style" pot can be read and printed from loop().

int style;

void setup()  {
  /* Do init stuff here, runs once per reset cycle */
  Serial.begin(9600);        // Initialize the connection to Serial Monitor

  style =  readStyle();
//  Serial.print("Style is " );
//  Serial.println(style);

}

void loop() {

}

You should learn how to make proper returns

not

void readStyle() {};

but

int readStyle() {};

with caveat, don't try to return a variable declared local to the function.

Another thing to learn is passing info to functions through

int myFunction( int X, char C ) {}; // you pass values this way.

int otherFunction( int &X ) {}; // you pass references this way, a connection to a variable instead of just the value in it.

int readStyle() {};

with caveat, don't try to return a variable declared local to the function.

No, don't return a pointer to a variable declared local to the function.
You can return the value of a variable or even a whole "struct" declared within the function.

That's because local variables are kept on the stack and when the function is done those are left go and the stacked return address is used.

GoForSmoke:
That's because local variables are kept on the stack and when the function is done those are left go and the stacked return address is used.

Are you suggesting that this:

int doNothing(int x)
{
int y = x * 2;
return y;
}

will not work? If so, I think you need to try it....

Regards,
Ray L.

Not any more. Somewhere I got mixed up. Just tried a version in 0022 and it works.

Thanks! I'd far rather be corrected than to stay ignorant. Now if only I can remember!

Maybe the hitch came when the variable holding the value to be returned is one that is passed, I do recall some sort of "can't return that, it goes out of scope" problem that's come up here more than a couple times before, that's why I tried 0022.

rickso234:
Also, is there an alternative to all the "if" statements? Switch/Case wants an integer value for "Case" and not an equation.

initialise an array with your bounds, then scan through it until you find a boundary in which your value sits.