0
Offline
Newbie
Karma: 0
Posts: 45
From birth to death, it is just like this.
|
 |
« on: November 15, 2010, 12:14:44 am » |
I'm pretty new to programming in C, so I tried to write a program to use with a 7 segment display, and the following is what I came up with. the only problem is that it is pretty touchy, and doesn't quite do what the button presses should be telling it to do every time, although sometimes it works with 1 to 3 button presses. Any suggestions would be greatly appreciated. /*While button2 is pressed (HIGH), the program counts the presses (HIGH) of button, then displays the count number with a 7 Segment Display*/
//Button Count Variables int state = LOW; int lastState = LOW; int count = 10;
//7 Segment Display Pins int segF = 4; int segG = 5; int segE = 6; int segD = 7; int segA = 8; int segB = 9; int segC = 10;
//Button Pins int button = 11; int button2 = 12;
void setup() { Serial.begin(9600); pinMode(button, INPUT); pinMode(button2, INPUT); state = digitalRead(button); pinMode(segA, OUTPUT); pinMode(segB, OUTPUT); pinMode(segC, OUTPUT); pinMode(segD, OUTPUT); pinMode(segE, OUTPUT); pinMode(segF, OUTPUT); pinMode(segG, OUTPUT); }
void loop() { while(digitalRead(button2) == HIGH) { if (state == HIGH && lastState == LOW) { count++; } lastState = state; state = digitalRead(button); } switch (count) { case 1: //Turns on and off the LEDs on the 7seg to display "1" digitalWrite(segA, LOW); digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, LOW); digitalWrite(segE, LOW); digitalWrite(segF, LOW); digitalWrite(segG, LOW); break; case 2: /*Same as 1, but this displays "2", and so on for the rest of these*/ digitalWrite(segA, HIGH); digitalWrite(segB, HIGH); digitalWrite(segC, LOW); digitalWrite(segD, HIGH); digitalWrite(segE, HIGH); digitalWrite(segF, LOW); digitalWrite(segG, HIGH); break; case 3: digitalWrite(segA, HIGH); digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, HIGH); digitalWrite(segE, LOW); digitalWrite(segF, LOW); digitalWrite(segG, HIGH); break; case 4: digitalWrite(segA, LOW); digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, LOW); digitalWrite(segE, LOW); digitalWrite(segF, HIGH); digitalWrite(segG, HIGH); break; case 5: digitalWrite(segA, HIGH); digitalWrite(segB, LOW); digitalWrite(segC, HIGH); digitalWrite(segD, HIGH); digitalWrite(segE, LOW); digitalWrite(segF, HIGH); digitalWrite(segG, HIGH); break; case 6: digitalWrite(segA, HIGH); digitalWrite(segB, LOW); digitalWrite(segC, HIGH); digitalWrite(segD, HIGH); digitalWrite(segE, HIGH); digitalWrite(segF, HIGH); digitalWrite(segG, HIGH); break; case 7: digitalWrite(segA, HIGH); digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, LOW); digitalWrite(segE, LOW); digitalWrite(segF, LOW); digitalWrite(segG, LOW); break; case 8: digitalWrite(segA, HIGH); digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, HIGH); digitalWrite(segE, HIGH); digitalWrite(segF, HIGH); digitalWrite(segG, HIGH); break; case 9: digitalWrite(segA, HIGH); digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, HIGH); digitalWrite(segE, LOW); digitalWrite(segF, HIGH); digitalWrite(segG, HIGH); break; case 10: digitalWrite(segA, HIGH); digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, HIGH); digitalWrite(segE, HIGH); digitalWrite(segF, HIGH); digitalWrite(segG, LOW); break; default: break; } count = 0; }
|
|
|
|
|
Logged
|
|
|
|
|
Lancashire, UK
Offline
Edison Member
Karma: 8
Posts: 1988
|
 |
« Reply #1 on: November 15, 2010, 12:22:53 am » |
The circuit you have connected to the 'button' pins would help. Are you using a pulldown resistor ?
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 45
From birth to death, it is just like this.
|
 |
« Reply #2 on: November 15, 2010, 12:29:00 am » |
I have a 10k resistor connected from ground to the button pins, and the buttons connected to 5v, so when it is pressed, it returns (HIGH), and unpressed returns (LOW).
|
|
|
|
|
Logged
|
|
|
|
|
Lancashire, UK
Offline
Edison Member
Karma: 8
Posts: 1988
|
 |
« Reply #3 on: November 15, 2010, 12:46:17 am » |
Is the intended behaviour that nothing happens until the first button is pressed and then the 2nd button increments the number displayed ? So you have to press both buttons to increment the count (the number displayed ?
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 45
From birth to death, it is just like this.
|
 |
« Reply #4 on: November 17, 2010, 06:58:15 pm » |
@pluggy, Yes. When the one button is pressed, it goes into the While loop, while it then counts the button presses of the other button. And when the first button is let go, it should display the number of times I pressed the second button. But it is very touchy, and only seems to work semi-consistently with 1 to 3.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 316
Posts: 35590
Seattle, WA USA
|
 |
« Reply #5 on: November 17, 2010, 07:16:43 pm » |
while(digitalRead(button2) == HIGH) { if (state == HIGH && lastState == LOW) { count++; } lastState = state; state = digitalRead(button); }
Do you have an idea how many times this while loop gets executed while you are holding the button2 pin switch down? There is no debouncing of either button happening, so the random results you are seeing are not surprising.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 45
From birth to death, it is just like this.
|
 |
« Reply #6 on: November 17, 2010, 07:29:45 pm » |
I hadn't though about the number of times affecting how it works, but it aside from interference, it shouldn't count any more or less than what I am pressing, right? I was thinking that a better way of doing this could be to use interrupts, and basically use one button to count, while the second button actually changes the displayed number to the correct number of presses. so that instead of cycling, a desired number of presses could be achieved, and then displayed.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 45
From birth to death, it is just like this.
|
 |
« Reply #7 on: November 17, 2010, 10:09:48 pm » |
Here is the program rewritten and modified with interrupts. The first button (interrupt 0) counts how many times it is pressed, and stores that to the variable [glow]countPress[/glow]. Then when the second button (interrupt 1) is pressed, it should display the correct number of presses on the first button. The buttons do not have to be pressed at the same time at all. int countPress = 0;
//7 Segment Display Pins int segF = 4; int segG = 5; int segE = 6; int segD = 7; int segA = 8; int segB = 9; int segC = 10;
//Button Pins int button = 2; int button2 = 3;
void setup() { Serial.begin(9600); attachInterrupt(0, count, RISING); attachInterrupt(1, disp, RISING); pinMode(segA, OUTPUT); pinMode(segB, OUTPUT); pinMode(segC, OUTPUT); pinMode(segD, OUTPUT); pinMode(segE, OUTPUT); pinMode(segF, OUTPUT); pinMode(segG, OUTPUT); }
void loop() { }
void count() { countPress = ++countPress; }
void disp() { switch (countPress) { case 1: //Turns on and off the LEDs on the 7seg to display "1" digitalWrite(segA, LOW); digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, LOW); digitalWrite(segE, LOW); digitalWrite(segF, LOW); digitalWrite(segG, LOW); break; case 2: /*Same as 1, but this displays "2", and so on for the rest of these*/ digitalWrite(segA, HIGH); digitalWrite(segB, HIGH); digitalWrite(segC, LOW); digitalWrite(segD, HIGH); digitalWrite(segE, HIGH); digitalWrite(segF, LOW); digitalWrite(segG, HIGH); break; case 3: digitalWrite(segA, HIGH); digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, HIGH); digitalWrite(segE, LOW); digitalWrite(segF, LOW); digitalWrite(segG, HIGH); break; case 4: digitalWrite(segA, LOW); digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, LOW); digitalWrite(segE, LOW); digitalWrite(segF, HIGH); digitalWrite(segG, HIGH); break; case 5: digitalWrite(segA, HIGH); digitalWrite(segB, LOW); digitalWrite(segC, HIGH); digitalWrite(segD, HIGH); digitalWrite(segE, LOW); digitalWrite(segF, HIGH); digitalWrite(segG, HIGH); break; case 6: digitalWrite(segA, HIGH); digitalWrite(segB, LOW); digitalWrite(segC, HIGH); digitalWrite(segD, HIGH); digitalWrite(segE, HIGH); digitalWrite(segF, HIGH); digitalWrite(segG, HIGH); break; case 7: digitalWrite(segA, HIGH); digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, LOW); digitalWrite(segE, LOW); digitalWrite(segF, LOW); digitalWrite(segG, LOW); break; case 8: digitalWrite(segA, HIGH); digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, HIGH); digitalWrite(segE, HIGH); digitalWrite(segF, HIGH); digitalWrite(segG, HIGH); break; case 9: digitalWrite(segA, HIGH); digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, HIGH); digitalWrite(segE, LOW); digitalWrite(segF, HIGH); digitalWrite(segG, HIGH); break; case 10: digitalWrite(segA, HIGH); digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, HIGH); digitalWrite(segE, HIGH); digitalWrite(segF, HIGH); digitalWrite(segG, LOW); break; default: break; } countPress = 0; }
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 316
Posts: 35590
Seattle, WA USA
|
 |
« Reply #8 on: November 19, 2010, 08:18:18 pm » |
countPress should be declared volatile, so that its value is fetched every time. countPress = ++countPress; As opposed to just countPress++;? Why? disp() does nothing but reset countPress is countPress is greater than 10. Is that reasonable? Since there is no debouncing of the buttons, a bounce could cause the interrupt to be fired again before the ISR has finished. Since countPress is an integer, it is possible for it to become corrupted if the ISR fires and suspends the ISR that is running. This couldn't happen if countPress were a byte. The ISR could fire while the ISR is still running, but it wouldn't corrupt countPress. In disp(), before you turn any segments on, you should turn them all off. Otherwise, displaying 4 after displaying 3 will look like a 9. Otherwise, it looks good. Of course, using interrupts to catch humans pressing buttons is silly. The Arduino loops often enough to catch every button press, no matter how quickly a human presses and releases a button. After all, at 16,000,000 instructions a second, you'd have to be awfully darn fast to get a switch pressed and released before the Arduino noticed.
|
|
|
|
« Last Edit: November 19, 2010, 08:18:50 pm by PaulS »
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 45
From birth to death, it is just like this.
|
 |
« Reply #9 on: December 01, 2010, 06:09:59 pm » |
I recently found out about the debounce library, implemented it, and now I have a program that works the way that the interrupt version should have worked, but this doesn't use interrupts. Here is my code: #include <Bounce.h>
//Button Count Variable int count = 0;
//7 Segment Display Pins int segF = 4; int segG = 5; int segE = 6; int segD = 7; int segA = 8; int segB = 9; int segC = 10;
//Button Pins int button = 11; int button2 = 12;
//Bounce Objects Bounce bouncer = Bounce(button, 25); Bounce bouncer2 = Bounce(button2, 25);
void setup() { Serial.begin(9600); pinMode(button, INPUT); pinMode(button2, INPUT); pinMode(segA, OUTPUT); pinMode(segB, OUTPUT); pinMode(segC, OUTPUT); pinMode(segD, OUTPUT); pinMode(segE, OUTPUT); pinMode(segF, OUTPUT); pinMode(segG, OUTPUT); digitalWrite(segA, HIGH); digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, HIGH); digitalWrite(segE, HIGH); digitalWrite(segF, HIGH); digitalWrite(segG, LOW); }
void loop() { bouncer.update(); //Updates bouncer int value = bouncer.risingEdge(); if (value == HIGH) { count++; } bouncer2.update(); //Updates bouncer2 int value2 = bouncer2.risingEdge(); if (value2 == HIGH) { switch (count) { case 1: //Turns on and off the LEDs on the 7seg to display "1" digitalWrite(segA, LOW); digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, LOW); digitalWrite(segE, LOW); digitalWrite(segF, LOW); digitalWrite(segG, LOW); break; case 2: /*Same as 1, but this displays "2", and so on for the rest of these*/ digitalWrite(segA, HIGH); digitalWrite(segB, HIGH); digitalWrite(segC, LOW); digitalWrite(segD, HIGH); digitalWrite(segE, HIGH); digitalWrite(segF, LOW); digitalWrite(segG, HIGH); break; case 3: digitalWrite(segA, HIGH); digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, HIGH); digitalWrite(segE, LOW); digitalWrite(segF, LOW); digitalWrite(segG, HIGH); break; case 4: digitalWrite(segA, LOW); digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, LOW); digitalWrite(segE, LOW); digitalWrite(segF, HIGH); digitalWrite(segG, HIGH); break; case 5: digitalWrite(segA, HIGH); digitalWrite(segB, LOW); digitalWrite(segC, HIGH); digitalWrite(segD, HIGH); digitalWrite(segE, LOW); digitalWrite(segF, HIGH); digitalWrite(segG, HIGH); break; case 6: digitalWrite(segA, HIGH); digitalWrite(segB, LOW); digitalWrite(segC, HIGH); digitalWrite(segD, HIGH); digitalWrite(segE, HIGH); digitalWrite(segF, HIGH); digitalWrite(segG, HIGH); break; case 7: digitalWrite(segA, HIGH); digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, LOW); digitalWrite(segE, LOW); digitalWrite(segF, LOW); digitalWrite(segG, LOW); break; case 8: digitalWrite(segA, HIGH); digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, HIGH); digitalWrite(segE, HIGH); digitalWrite(segF, HIGH); digitalWrite(segG, HIGH); break; case 9: digitalWrite(segA, HIGH); digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, HIGH); digitalWrite(segE, LOW); digitalWrite(segF, HIGH); digitalWrite(segG, HIGH); break; case 10: digitalWrite(segA, HIGH); digitalWrite(segB, HIGH); digitalWrite(segC, HIGH); digitalWrite(segD, HIGH); digitalWrite(segE, HIGH); digitalWrite(segF, HIGH); digitalWrite(segG, LOW); break; default: break; } count = 0; } }
|
|
|
|
|
Logged
|
|
|
|
|
|