Go Down

Topic: Check if some of the buttons was pressed while executing a "for" loop. HELP! (Read 6906 times) previous topic - next topic

RogerioBoscolo

Quote
I need help to check if the button "bt_2" has been pressed while the program executes a for loop, if the button is pressed then it needs to do something if not ir keeps repeating the "void rgb()" function, i already tried to use as many functions as i could understand but nothig solved.
this code is almost doing it but no matter what i do it dont work as well as expected. Please Help me, anything would be appreciated.
P.S: the thing here is, if i press one button it is runnig the rgb function as expected but once it runs it it forget to check if any other button is pressed, i dont know why this is happening, maybe i dont know how to make it keep looking. :~

Code: [Select]
#define LED1_R 11
#define LED1_G 10
#define LED1_B 9 
#define bt_1 digitalRead(2)
#define bt_2 digitalRead(3)
#define bt_3 digitalRead(4)
#define bt_4 digitalRead(5)
#define bt_5 digitalRead(6)
int ledLevel = 25.5;
int WAIT = 40;
int r = 255;
int g = 1;
int b = 1;
boolean lbt_1 = LOW;
boolean lbt_2 = LOW;
boolean lbt_3 = LOW;
boolean lbt_4 = LOW;
boolean lbt_5 = LOW;
boolean led_red = false;
boolean led_green = false;
boolean led_blue = false;
void setup(){
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(4, INPUT);
  pinMode(5, INPUT);
  pinMode(6, INPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
}
void loop(){
    if (bt_1 == HIGH && lbt_1 == LOW){
      lbt_1 = !lbt_1;
      rgb();
    }
    if (bt_2 == HIGH && lbt_2== LOW){
      lbt_2 = !lbt_2;
    }
    if (bt_2 == LOW && lbt_2 == HIGH){
      if (bt_3 == HIGH && lbt_3 == LOW){
        ledLevel = ledLevel - 25.5;
      }
      lbt_3 = bt_3;
      if (bt_4 == HIGH && lbt_4 == LOW){
        ledLevel = ledLevel + 25.5;
      }
      lbt_4 = bt_4;
        analogWrite(LED1_R, ledLevel);
        analogWrite(LED1_G, ledLevel);
        analogWrite(LED1_B, ledLevel);
      if (ledLevel > 255)ledLevel = 255;
      if (ledLevel < 25.5)ledLevel = 25.5;
    }
}
void rgb(){
  // Red to Orange to Yellow
  r = ledLevel; g = 1; b = 1;
  for(g = 1; g <= ledLevel; g++) {
    writeLED1();
  }
  // Yellow to Green
  r = ledLevel; g = ledLevel; b = 1;
  for(r = ledLevel; r > 1; r -= 1) {
    writeLED1();
  }
   // Green because blue is bright and a pause for green is good
  r = 1; g = ledLevel; b = 1;
  for(int i = 0; i < 20; i++) {
    writeLED1();
  }
  // Green to Blue
  r = 1; g = ledLevel; b = 1;
  for(g = ledLevel; g > 1; g -= 1) {
    b += 1;
    writeLED1();
  }
  // Blue to Purple
  r = 1; g = 1; b = ledLevel;
  for(r = 1; r < ledLevel; r += 1) {
    writeLED1();
  }
  // Purple to Red
  r = ledLevel; g = 1; b = ledLevel;
  for(b = ledLevel; b > 1; b -= 1) {
    writeLED1();
  }
   rgb();
}
void writeLED1(){
  analogWrite(LED1_R, r);
  analogWrite(LED1_G, g);
  analogWrite(LED1_B, b);
  delay(WAIT);
}

nickgammon

This sort of code is hard to follow:

Code: [Select]

#define bt_1 digitalRead(2)
#define bt_2 digitalRead(3)
#define bt_3 digitalRead(4)
#define bt_4 digitalRead(5)
#define bt_5 digitalRead(6)
...
void loop(){
    if (bt_1 == HIGH && lbt_1 == LOW){


Hiding away a function call in a define looks confusing. Just write:
Code: [Select]

void loop(){
    if (digitalRead(2) == HIGH && lbt_1 == LOW){

Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

Henry_Best

During delay() everything, except interupts, stops, so you'll not be able to read the switches when you've got a for loop with 40 * 40 millisecond (= 1.6 seconds) delays. Look up 'blink without delay' in the Playground to see how to overcome this.

RogerioBoscolo


During delay() everything, except interupts, stops, so you'll not be able to read the switches when you've got a for loop with 40 * 40 millisecond (= 1.6 seconds) delays. Look up 'blink without delay' in the Playground to see how to overcome this.

Thank you Henry_Best, do you have any idea of how can i do that withou the delay function? I was thinking about using Serial commands.
I think i already tried to use interupts but didn't worked. anyway i'll try to do it again. Thanks

boguz

the way to do that, as Henry_Best mentioned, is to look at the "Blink without delay()" example. You can find it here:
http://arduino.cc/en/Tutorial/BlinkWithoutDelay
This way you can achieve a "delay effect" without using the delay() function.
When you use the delay() it's kind of like having the arduino "pausing"; it won't read your inputs, so you can't give him new orders (except for the interrupts).
If you use the Blink Without Delay method, you will achive this by using the millis() function.
The millis() is like a clock that starts counting when you connect (or reset) your arduino.
So, let's say you want a 1second "delay" between pressing a button and having a LED light up, you can tell your arduino:
Code: [Select]

long interval = 1000; // 1 second interval

When I press a button {
  // save the time of press into a variable called pressMillis
  pressMillis = millis();
}

// Check for interval
if currentMillis - millis() = interval {
   light my LED
}

just to give you a rought idea. check the Blink without delay to really see how it works!  ;)

Also, if you explain us what you are trying to achieve with your code, maybe someone will have a different idea of how to do it.
Good luck!
8)

RogerioBoscolo


Also, if you explain us what you are trying to achieve with your code, maybe someone will have a different idea of how to do it.
Good luck!
8)

I'm trying to us use the millis function right now but seems that when i call the "rgb();" loop it stops working somehow.

My project is basically to make a remote control that control some RGB LED that so something if i press one button.
My idea was to make the led to fade between colors if i press bt_1, that was ok until i went to the next step that is meant to whenever i press bt_2 it
activates the tree colors and let me control the ledLevel (led brightness control with bt_3 and bt_4 (+ or -)), but the bad thing is: if i press the bt_2 after calling the rgb() loop it does nothing
i just stay stucked at rgb loop, i already had to stop using software debouncing in this project because of the delay() function. After solving those errors i still want to make an ON/OFF function
that activates/deactivates the whole circuit.

AWOL

Quote
but seems that when i call the "rgb();" loop it stops working somehow.

Well, if it is the "rgb()" you posted above, it is probably because of this
Code: [Select]
delay(WAIT);

boguz


I'm trying to us use the millis function right now but seems that when i call the "rgb();" loop it stops working somehow.

When you have something ready let us take a look at how your doce is looking, maybe we can help you from there...

RogerioBoscolo

Quote

So, i just made a few adjustments to use the attachInterrupt but it still not working.  =( maybe the problem still in the "delay(WAIT);"... i really don't know how to fix this code, i thought the interrupt would handle the delay and stop that rgb(); loop whenever the button was pressed but seems it doesn't.

Code: [Select]

#define red 11
#define green 10
#define blue 9
#define bt_1 digitalRead(2)
#define bt_3 digitalRead(4)
#define bt_4 digitalRead(5)
#define bt_5 digitalRead(6)
int ledLevel = 25.5;
int modo = 0;
int WAIT = 40;
int r=255;
int g=1;
int b=1;
boolean lbt_1 = LOW;
boolean lbt_2 = LOW;
boolean lbt_3 = LOW;
boolean lbt_4 = LOW;
boolean lbt_5 = LOW;
boolean led_red = LOW;
boolean led_green = LOW;
boolean led_blue = LOW;
void setup(){
  pinMode(2, INPUT);
  pinMode(4, INPUT);
  pinMode(5, INPUT);
  pinMode(6, INPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  attachInterrupt(1, modo0, RISING);
 
}
void loop(){
    if (bt_1 == HIGH && lbt_1 == LOW){
      lbt_1 = !lbt_1;
    modo=1;
    }
    switch(modo){
      case 0:
      if (bt_3 == HIGH && lbt_3 == LOW){
        ledLevel = ledLevel - 25.5;
      }
      lbt_3 = bt_3;
      if (bt_4 == HIGH && lbt_4 == LOW){
        ledLevel = ledLevel + 25.5;
      }
      lbt_4 = bt_4;
      analogWrite(red, ledLevel);
      analogWrite(green, ledLevel);
      analogWrite(blue, ledLevel);
      if (ledLevel > 255)ledLevel = 255;
      if (ledLevel < 25)ledLevel = 25.5;
      break;
      case 1:
      rgb();
      break;
    }
}
void rgb() {
  // Red to Orange to Yellow
  r = ledLevel; g = 1; b = 1;
  for(g = 1; g <= ledLevel; g++) {
    writeLED1();
  }
  // Yellow to Green
  r = ledLevel; g = ledLevel; b = 1;
  for(r = ledLevel; r > 1; r -= 1) {
    writeLED1();
  }
   // Green because blue is bright and a pause for green is good
  r = 1; g = ledLevel; b = 1;
  for(int i = 0; i < 20; i++) {
    writeLED1();
  }
  // Green to Blue
  r = 1; g = ledLevel; b = 1;
  for(g = ledLevel; g > 1; g -= 1) {
    b += 1;
    writeLED1();
  }
  // Blue to Purple
  r = 1; g = 1; b = ledLevel;
  for(r = 1; r < ledLevel; r += 1) {
    writeLED1();
  }
  // Purple to Red
  r = ledLevel; g = 1; b = ledLevel;
  for(b = ledLevel; b > 1; b -= 1) {
    writeLED1();
  }
  rgb();
}
void writeLED1(){
  analogWrite(red, r);
  analogWrite(green, g);
  analogWrite(blue, b);
  delay(WAIT);
}
void modo0() {
  modo = 0;
}

Henry_Best


Quote

So, i just made a few adjustments to use the attachInterrupt but it still not working.  =( maybe the problem still in the "delay(WAIT);"

Not maybe. It is the problem.
Code: [Select]

unsigned long startTime;  //add this line before setup()

setup(){
startTime = millis();  //add this line
}
.
.
.
void writeLED1(){
if(millis() - startTime >= WAIT){
  analogWrite(red, r);
  analogWrite(green, g);
  analogWrite(blue, b);
  startTime = millis(); //reset startTime for next iteration
  }
}

cypherrage

r += 1 is one shortcut, another would be r++, same with r -= 1 can be replaced with r--.


jack wp


RogerioBoscolo


Code: [Select]
int ledLevel = 25.5;
Novel take on an integer.

I think it is not the problem because the code was working fine until i put the rgb() functions.

AWOL

I didn't say it was a problem I said it was novel.
Recursion is now your problem.

Go Up