1
\$\begingroup\$

My code:

#define MAX 50
const int LED1 = 2;
const int LED2 = 3;
const int LED3 = 4;
const int LED4 = 5;
int array[MAX];
int old_b = 0;
int val;
int counter = 0;
int i;
int temp;
int L1;
int L2;
void setup () {
 pinMode (A5, INPUT_PULLUP);
 Serial.begin(9600);
}
int readButtons (int pin) {
 int b, c;
 c = analogRead(pin);
 Serial.print("analogRead = ");
 Serial.println(c);
 delay(100);
 if (c > 1015) b = 0;
 else if (c > 70 && c < 76) b = 1;
 else if (c > 122 && c < 128) b = 2;
 else if (c > 169 && c < 175) b = 3;
 else if (c > 209 && c < 217) b = 4;
 else if (c > 247 && c < 256) b = 5;
 else if (c > 280 && c < 291) b = 6;
 else b = 0;
 if (b == old_b) {
 return 0;
 old_b = b;
 } else {
 return b;
 old_b = b; 
 } 
}
void loop () {
 while ((val = readButtons(5)) != 5) {
 if ((val == 1) || (val == 2) || (val == 3) || (val == 4)) {
 array[counter] = val;
 Serial.print("In ");
 Serial.print(counter); 
 Serial.print(" saving "); 
 Serial.println(val);
 delay(200);
 counter++;
 if (counter == MAX) {
 counter = 0;
 } 
 }
 }
 temp = counter;
 counter = 0;
 for (i = 0; i < temp; i++) {
 if (array[i] % 2 == 0) {
 L1 = 2;
 L2 = array[i] / 3 + 3; 
 } else {
 L2 = 5;
 L1 = array[i] % 3 + 3; 
 }
 if (readButtons(5) != 5) {
 digitalWrite (L1, HIGH);
 if (readButtons(5) != 5) {
 digitalWrite (L2, HIGH);
 delay(1000);
 digitalWrite (L1, LOW);
 digitalWrite (L2, LOW);
 if (readButtons(5) == 5) {
 i = temp;
 }
 } else {
 digitalWrite (L1, LOW);
 i = temp; 
 }
 }
 }
}

So I have a function which detects if a button was pressed. Prior to that, I have determined in which range are values for certain button and all buttons are connected on analog pin 5 like this, except I have them 6 and my resistors have 2200 ohms. In the while () {...} loop, while the 5th button isn't pressed, Arduino is "looking" if any of first four buttons was pressed. If it was store it in an array and if not keep "looking". When 5th button is pressed, we brake out and store last known place in array in which value was stored and set the place counter to zero so when starting again, Arduino stores values in the first place of array. Then based on that what is stored I determine which pin/LED will light up. If at any time during blinking LEDs 5th button is pressed again, Arduino stops the blinking and again waits for the presses from first four buttons. That is how it is supposed to work in theory. In practice I still can't get it to stop blinking every time 5th button is pressed again. I have to press it multiple times, sometimes two or sometimes even more presses are necessary if I want it to stop blinking. I don't think using interrupts will help, since I don't know how I should implement them in my problem. Here is my circuit (except I have Arduino Duemilanove Atmega 168). LEDs go 1 to 4 from right to left:

Schematics

asked Jan 15, 2014 at 13:42
\$\endgroup\$

3 Answers 3

1
\$\begingroup\$

From your description, it seems you need to debounce the switch.

You can do this

Since you seem to be using some kind of resistive ladder to read multiple buttons on one ADC port, this will be a little more complicated.

answered Jan 15, 2014 at 13:59
\$\endgroup\$
1
\$\begingroup\$

This section of your code looks strange to me:

 if (readButtons(5) != 5) {
 digitalWrite (L1, HIGH);
 if (readButtons(5) != 5) {
 digitalWrite (L2, HIGH);

Your readButtons(5) function will return 0 unless a change has occurred in the button state.

So for the digitalWrite (L2, HIGH); code to be executed you would need to detect two button presses in very rapid succession.

I think this must be a bug, as I cannot think of any plausible reason for the code to be like this.

Maybe you intend to have presses separated by one second (for example)?

Then surely the code should be:

 if (readButtons(5) != 5) {
 digitalWrite (L1, HIGH);
 delay(1000);
 if (readButtons(5) != 5) {
 digitalWrite (L2, HIGH);
answered Mar 18, 2014 at 17:15
\$\endgroup\$
0
\$\begingroup\$

I think the problem is the way you apply big delays that prevent the fast scan of the buttons.

In the following (untested) code I'm using small 1ms delays executed multiple times while the buttons keep being scanned

#define MAX 50
const int LED1 = 2;
const int LED2 = 3;
const int LED3 = 4;
const int LED4 = 5;
int array[MAX];
int old_b = 0;
int val;
int counter = 0;
int i;
int temp;
int L1;
int L2;
void setup()
{
 pinMode(A5, INPUT_PULLUP);
 Serial.begin(9600);
}
int readButtons(int pin)
{
 int b, c;
 c = analogRead(pin);
 Serial.print("analogRead = ");
 Serial.println(c);
 //delay(100);
 if(c > 1015)
 {
 b = 0;
 }
 else
 if(c > 70 && c < 76)
 {
 b = 1;
 }
 else
 if(c > 122 && c < 128)
 {
 b = 2;
 }
 else
 if(c > 169 && c < 175)
 {
 b = 3;
 }
 else
 if(c > 209 && c < 217)
 {
 b = 4;
 }
 else
 if(c > 247 && c < 256)
 {
 b = 5;
 }
 else
 if(c > 280 && c < 291)
 {
 b = 6;
 }
 else
 {
 b = 0;
 }
 if(b == old_b)
 {
 return 0;
 old_b = b;
 }
 else
 {
 return b;
 old_b = b;
 }
}
void loop()
{
 unsigned char counter_var = 0;
 val = readButtons(5); // read the buttons
 while(val != 5)
 {
 val = readButtons(5); // read the buttons
 if(counter_var == 0)
 {
 if((val == 1) || (val == 2) || (val == 3) || (val == 4))
 {
 counter_var == 200; // to apply ~200ms delay
 array[counter] = val;
 Serial.print("In ");
 Serial.print(counter);
 Serial.print(" saving ");
 Serial.println(val);
 //delay(200);
 counter++;
 if(counter == MAX)
 {
 counter = 0;
 }
 }
 }
 else
 {
 counter_var--; // if delay>0 then this decrements and counts delay ms
 delay(1);
 }
 }
 counter_var = 0;
 temp = counter;
 counter = 0;
 for(i = 0; i < temp; i++)
 {
 if(array[i] % 2 == 0)
 {
 L1 = 2;
 L2 = array[i] / 3 + 3;
 }
 else
 {
 L2 = 5;
 L1 = array[i] % 3 + 3;
 }
 if(readButtons(5) != 5)
 {
 digitalWrite(L1, HIGH);
 if(readButtons(5) != 5)
 {
 digitalWrite(L2, HIGH);
 delay(1000);
 digitalWrite(L1, LOW);
 digitalWrite(L2, LOW);
 if(readButtons(5) == 5)
 {
 i = temp;
 }
 }
 else
 {
 digitalWrite(L1, LOW);
 i = temp;
 }
 }
 }
}

The main change I have applied is in the following part ( start of loop() )

 unsigned char counter_var = 0;
 val = readButtons(5); // read the buttons
 while(val != 5)
 {
 val = readButtons(5); // read the buttons
 if(counter_var == 0)
 {
 if((val == 1) || (val == 2) || (val == 3) || (val == 4))
 {
 counter_var == 200; // to apply ~200ms delay
 array[counter] = val;
 Serial.print("In ");
 Serial.print(counter);
 Serial.print(" saving ");
 Serial.println(val);
 //delay(200);
 counter++;
 if(counter == MAX)
 {
 counter = 0;
 }
 }
 }
 else
 {
 counter_var--; // if delay>0 then this decrements and counts delay ms
 delay(1);
 }
 }

and I have removed the delay(100) from readButtons()

answered Jan 15, 2014 at 14:32
\$\endgroup\$
11
  • \$\begingroup\$ I have tired your code and unfortunately it didn't work. The one without the changes in loop would work perfectly, except it somehow always forgets to execute first pressed button command. For instance I press 1,2,2,3,4 it will execute like i have pressed 2,2,3,4. With the corrections in loop it doesn't recognizes presses of the 5th button that is it doesn't start/end blinking after pressing the 5th button. \$\endgroup\$ Commented Jan 15, 2014 at 17:39
  • \$\begingroup\$ @Mate so the cede for 1-4 buttons works and you only have a problem with button 5 detection in my code? \$\endgroup\$ Commented Jan 15, 2014 at 18:00
  • \$\begingroup\$ Yes, when in the loop is the code from the second part of your answer. \$\endgroup\$ Commented Jan 15, 2014 at 18:05
  • \$\begingroup\$ @Mate What you have used is the complete code of the first part of my reply, right? The second one is already a part of the first one and should be ignored. \$\endgroup\$ Commented Jan 15, 2014 at 18:11
  • 1
    \$\begingroup\$ @Ricardo proteus \$\endgroup\$ Commented Jan 17, 2014 at 13:33

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.