Help with loop function

hello, I'm a noob and I'm not sure where or how to post. I'm modifying some code for a project I'm doing and I can't figure where to add the loop function for void singleclick() to keep it running. I would like it to run infinitely till i call the next function. other than the repeat issue the code is working more or less ok.

#include <OneButton.h>                              //we need the OneButton library
 
OneButton button(A1, true);                         //attach a button on pin A1 to the library

  
void setup() {
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);                             
  pinMode(10, OUTPUT);                              
  pinMode(9, OUTPUT);
  
     
  button.at
tachClick(singleclick);                  // link the function to be called on a singleclick event.
  button.attachLongPressStop(longclick);            // link the function to be called on a longpress event.
  button.attachDoubleClick(doubleclick);            // link the function to be called on a doubleclick event.
} 
  


void loop() {
  
  button.tick();                                    // check the status of the button


  delay(10);                                        // a short wait between checking the button
} // loop



void singleclick(){// what happens when the button is clicked
     
  // fade in from min to max in increments of 5 points:
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue = fadeValue+1) {
    // sets the value (range from 0 to 255):
    analogWrite(9, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(10);
  }

  // fade out from max to min in increments of 5 points:
  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue = fadeValue-1) {
    // sets the value (range from 0 to 255):
    analogWrite(9, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(10);
  }

  // fade in from min to max in increments of 5 points:
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue = fadeValue+1) {
    // sets the value (range from 0 to 255):
    analogWrite(10, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(10);
  }

  // fade out from max to min in increments of 5 points:
  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue = fadeValue-1) {
    // sets the value (range from 0 to 255):
    analogWrite(10, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(10);
  }

  // fad// fade in from min to max in increments of 5 points:
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue = fadeValue+1) {
    // sets the value (range from 0 to 255):
    analogWrite(11, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(10);
  }

  // fade out from max to min in increments of 5 points:
  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue = fadeValue-1) {
    // sets the value (range from 0 to 255):
    analogWrite(11, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(10);
  }
}

void doubleclick() {                            
  digitalWrite(9,HIGH);
  digitalWrite(10,HIGH);                                                          
  digitalWrite(11,HIGH);
  digitalWrite(12,HIGH);
} 

void longclick(){                                 
  digitalWrite(9,LOW);
  digitalWrite(10,LOW);                                                             
  digitalWrite(11,LOW); 
  digitalWrite(12,LOW);
}

ebritt121, welcome to the forum. Thank you for posting the complete code, but could you please enclose it in [CODE] tags? It makes it so much easier for everyone to read.

1 Like

singleclick is an interrupt service routine or ISR. It will perform it's function and you will resume running from wherever you were when the interrupt took over.

type or#include <OneButton.h>                              //we need the OneButton library
 
OneButton button(A1, true);                         //attach a button on pin A1 to the library

  
void setup() {
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);                             
  pinMode(10, OUTPUT);                              
  pinMode(9, OUTPUT);
  
     
  button.attachClick(singleclick);                  // link the function to be called on a singleclick event.
  button.attachLongPressStop(longclick);            // link the function to be called on a longpress event.
  button.attachDoubleClick(doubleclick);            // link the function to be called on a doubleclick event.
} 
  


void loop() {
  
  button.tick();                                    // check the status of the button


  delay(10);                                        // a short wait between checking the button
} // loop



void singleclick(){// what happens when the button is clicked
     
  // fade in from min to max in increments of 5 points:
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue = fadeValue+1) {
    // sets the value (range from 0 to 255):
    analogWrite(9, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(10);
  }

  // fade out from max to min in increments of 5 points:
  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue = fadeValue-1) {
    // sets the value (range from 0 to 255):
    analogWrite(9, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(10);
  }

  // fade in from min to max in increments of 5 points:
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue = fadeValue+1) {
    // sets the value (range from 0 to 255):
    analogWrite(10, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(10);
  }

  // fade out from max to min in increments of 5 points:
  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue = fadeValue-1) {
    // sets the value (range from 0 to 255):
    analogWrite(10, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(10);
  }

  // fad// fade in from min to max in increments of 5 points:
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue = fadeValue+1) {
    // sets the value (range from 0 to 255):
    analogWrite(11, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(10);
  }

  // fade out from max to min in increments of 5 points:
  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue = fadeValue-1) {
    // sets the value (range from 0 to 255):
    analogWrite(11, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(10);
  }
}

void doubleclick() {                            
  digitalWrite(9,HIGH);
  digitalWrite(10,HIGH);                                                          
  digitalWrite(11,HIGH);
  digitalWrite(12,HIGH);
} 

void longclick(){                                 
  digitalWrite(9,LOW);
  digitalWrite(10,LOW);                                                             
  digitalWrite(11,LOW); 
  digitalWrite(12,LOW);
}
 paste code here
1 Like

I hope I did it right this time. I'm not quite sure what a interrupt service routine means. I'm still pretty new. but i will definitely look more into it. The code is working for the most part. I'm just struggling with getting the fade effect "singleclick" to repeat in a cycle. it only runs once then stops. I think I'm supposed to add a loop somewhere in that part of the code or some kind of counter. but that's where I'm stuck. I appreciate your fast response and help. Thank you.

An interrupt is a little like it sounds, a signal to the MCU that causes it to interrupt what it is normally and perform a specific interrupt request servicing function.

Generally, interrupt servicing functions should be very short, perhaps just setting a variable that to indicate that an interrupt has been received, that the main program then does something with.

Your singleclick() function has rather a lot going on within it an should probably be part of the main program. You would have a global variable e.g.:

volatile bool singleclickinterrupt = false;

Then in your main loop you might have something like:

if (singleclickinterrupt) then singleclick();
singleclickinterrupt = false;

Note the use of the 'volatile' keyword when declaring the variable, and resetting the 'singleclickinterrupt' variable to false immediately after the change has been detected and processed by the singleclick() servicing function. Obviously you can call the variable whatever you like.

The other two functions are probably short enough although there may be other opinions.

I'm sorry for sounding incompetent. I'm very new at all this and am trying to understand. The main program is where I have my void loop, correct? Is this where I would put my volatile statement? Or is it the void setup part. Again I am very sorry. I really am trying to get a hang of this.

Not at all! By all means ask questions. It was me that wasn't being very clear.

To clarify, this would be placed before void setup():

volatile bool singleclickinterrupt = false;

Then this would go into void loop():

if (singleclickinterrupt) then singleclick();
singleclickinterrupt = false;

sorry for the late reply. I tried adding the code but I think I did something wrong. I get "Compilation error: 'singleclickinterrupt' was not declared in this scope". I tried looking it up but I'm confused on what I'm supposed to do with it. Do I do singleclickinterrupt = singleclick or int singleclickinterrupt under setup? I'm happy to post what I have if it helps.

C:\Users\STRIX\Documents\Arduino\switch2\switch2.ino: In function 'void loop()':
C:\Users\STRIX\Documents\Arduino\switch2\switch2.ino:23:7: error: 'singleclickinterrupt' was not declared in this scope
if (singleclickinterrupt) then singleclick();
^~~~~~~~~~~~~~~~~~~~
C:\Users\STRIX\Documents\Arduino\switch2\switch2.ino:23:7: note: suggested alternative: 'singleclick'
if (singleclickinterrupt) then singleclick();
^~~~~~~~~~~~~~~~~~~~
singleclick
C:\Users\STRIX\Documents\Arduino\switch2\switch2.ino:23:29: error: 'then' was not declared in this scope
if (singleclickinterrupt) then singleclick();
^~~~
C:\Users\STRIX\Documents\Arduino\switch2\switch2.ino:23:29: note: suggested alternative: 'tan'
if (singleclickinterrupt) then singleclick();
^~~~
tan
C:\Users\STRIX\Documents\Arduino\switch2\switch2.ino:24:3: error: 'singleclickinterrupt' was not declared in this scope
singleclickinterrupt = false;
^~~~~~~~~~~~~~~~~~~~
C:\Users\STRIX\Documents\Arduino\switch2\switch2.ino:24:3: note: suggested alternative: 'singleclick'
singleclickinterrupt = false;
^~~~~~~~~~~~~~~~~~~~
singleclick

exit status 1

Compilation error: 'singleclickinterrupt' was not declared in this scope

Thought the error messages might help. Sorry if it's obnoxious.

Not at all. We def need to see the error messages. You can post that in code tags, too but it matters a bit less.

But we can't see how you applied the advices, which may haven't been exactly what anyone thought they were telling you to do.

In general, new problems or questions, please post the latest code. Even if you cou,d say I exactly did this and that. Because we are human too and we might not get your this and that just right...

a7

#include <OneButton.h>                              //we need the OneButton library
 
OneButton button(A1, true);                         //attach a button on pin A1 to the library

  
void setup() {
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);                             
  pinMode(10, OUTPUT);                              
  pinMode(9, OUTPUT);
  
  volatile bool singleclickinterrupt = false;
  button.attachClick(singleclick);                  // link the function to be called on a singleclick event.
  button.attachLongPressStop(longclick);            // link the function to be called on a longpress event.
  button.attachDoubleClick(doubleclick);            // link the function to be called on a doubleclick event.
} 
  


void loop() {
  
  button.tick();                                    // check the status of the button                     
if (singleclickinterrupt) then singleclick();
  singleclickinterrupt = false;

  delay(10);                                        // a short wait between checking the button
} // loop



void singleclick(){// what happens when the button is clicked
     
  // fade in from min to max in increments of 5 points:
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue = fadeValue+1) {
    // sets the value (range from 0 to 255):
    analogWrite(9, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(10);
  }

  // fade out from max to min in increments of 5 points:
  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue = fadeValue-1) {
    // sets the value (range from 0 to 255):
    analogWrite(9, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(10);
  }

  // fade in from min to max in increments of 5 points:
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue = fadeValue+1) {
    // sets the value (range from 0 to 255):
    analogWrite(10, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(10);
  }

  // fade out from max to min in increments of 5 points:
  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue = fadeValue-1) {
    // sets the value (range from 0 to 255):
    analogWrite(10, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(10);
  }

  // fad// fade in from min to max in increments of 5 points:
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue = fadeValue+1) {
    // sets the value (range from 0 to 255):
    analogWrite(11, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(10);
  }

  // fade out from max to min in increments of 5 points:
  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue = fadeValue-1) {
    // sets the value (range from 0 to 255):
    analogWrite(11, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(10);
  }
}

void doubleclick() {                            
  digitalWrite(9,HIGH);
  digitalWrite(10,HIGH);                                                          
  digitalWrite(11,HIGH);
  digitalWrite(12,HIGH);
} 

void longclick(){                                 
  digitalWrite(9,LOW);
  digitalWrite(10,LOW);                                                             
  digitalWrite(11,LOW); 
  digitalWrite(12,LOW);
}

I can't thank everyone for their help so much. I'm hoping I can get to the point some day I can repay the service. Again, thank you.

Quickie
move that above void setup(), not within.

There is no then in C/C++

if (singleclickinterrupt) singleclick();

And that statement isn't what you want, I don't think.

Interrupts are not beginner-friendly. In this code, singleclick is a function that gets called automatically, asynchronously to anything you are doing in the other code.

The suggestion was, I think, to have singleclick do nothing more than set the flag you've called singleclickinterrupt.

Literally one line of code in the ISR.

Then in your loop, recognize that the flag was set, and call a function that does all the work you want done because the button got pushed. Its body will be most of what singleclick once contained.

So you could… use the flag and keep calling that work function until something else cleared the flag, like having done the work N times or whatever.

I can't just now, but maybe a second press of the button could clear the flag, sounds like what you were going for, on/off control of the operation.

There are ways to do this without the complexity of involving interrupts. I'll check later and post a demo that might help you get back on the noob track. Interrupts have their place; some of us never advertently use them.

HTH

a7

I removed the "then which cleared the error. Thank you for the advice. you are right that I want the fist function to repeat X number of times. In this case till I change it. I'm making a bedroom lamp/nightlight if that helps. I want it to have 3 functions rainbow, reading and off.

My apologies for the error. Indeed the word 'then' should not have been in that statement.

No worries. I appreciate all your help and patience. I'm still trying to get the first part of my code to loop/repeat. I'm stuck with it running through only once. I'm sure it's something small. I just don't know what.

Set the flag on the ISR. That's all it has to do.

In the loop

  if the flag is set
    put some number N in a variable like nTimes
    clear the flag

  if nTimes is greater than zero
    do whatever you wanna do once
    subtract one from nTimes

That's not code. It is pseudocode, a way to talk about code without getting the pesky syntax and stuff exact.

The first if statement see the flag and sets a number to be how any times to do the thing.

The second if statement checks to see if there is any reason to do the thing, and counts the doing down and won't after it counts down to zero meaning it has done the thing N times.

a7