# Programming loop and buttons

I am writing a program that whenever a particular button is pressed adds for example 9 to the end of a value so if it was pressed 55 would become 559. However whenever I press the button it adds multiple "9" 5599... and overflows. Is there a way to control the loop so that it runs once per button press and only runs if a button has been pressed? To clarify a little is there a way to have an infinite delay until button #1 == true, but the loop does not repeatedly run through while button #1 == true? To complicate it some more there are going to be multiple buttons that do the same thing, but add different numbers to the end.

Seeing code woud be useful, but look for the transition of the button state from "not pressed" to "pressed", rather than (as it sounds like you have it) when it "is pressed"

I am trying to write a program for a simple calculator. Let me know if you have any questions as to what anything does

``````const int n0 = 0;
const int n1 = 1;
const int n2 = A0;
const int n3 = A1;
const int n4 = 6;
const int n5 = 7;
const int n6 = 8;
const int n7 = 9;
const int n8 = 10;
const int n9 = 13;

const int second = A2; // second function
const int pm = A3; // plus minus
const int dt = A4; // divide times
const int me = A5; // minus equals

int valueA = 0; // value of first integer
int valueB = 0;
int AB = 0; // which integer are we editing
int operation = 0; // what operation will be performed to a and b ex. a*b=?
int fpa = 0; // the first press to initialize everything for value a
int fpb = 0; // the first press to set the value for value b

int sn0 = 0; //state of number 0 - s=state
int sn1 = 0;
int sn2 = 0;
int sn3 = 0;
int sn4 = 0;
int sn5 = 0;
int sn6 = 0;
int sn7 = 0;
int sn8 = 0;
int sn9 = 0;
int ssecond = 0;
int spm = 0;
int sdt = 0;
int sme = 0;

void setup(){
pinMode(n0, INPUT);
pinMode(n1, INPUT);
pinMode(n2, INPUT);
pinMode(n3, INPUT);
pinMode(n4, INPUT);
pinMode(n5, INPUT);
pinMode(n6, INPUT);
pinMode(n7, INPUT);
pinMode(n8, INPUT);
pinMode(n9, INPUT);
pinMode(second, INPUT);
pinMode(pm, INPUT);
pinMode(dt, INPUT);
pinMode(me, INPUT);
Serial.begin(9600);
}

void loop(){

if (sn0 == HIGH) {
if (AB == 0 ){ // A we working with value A or B
if  (fpa == 0){ //Has the initial value for value A been set
valueA = 0;
fpa = 1; // The initial value for value A has been set
}
if (fpa == 1 ){ //There is a value for value A
valueA = ((valueA*10)+0); //Multiply by 10 and add 0. For example value A was 15 so ((15+10)+0)=150
}
}
if (AB == 1){ //The same checks for value B as value A went through
if  (fpb == 0){
valueB=0;
fpb = 1;
}
if (fpb == 1 ){
valueB=((valueB*10)+0);
}

}

}
if (sn1 == HIGH) {
if (AB == 0 ){
if  (fpa == 0){
valueA = 1;
fpa = 1;
}
if (fpa == 1 ){
valueA = ((valueA*10)+1);
}
}
if (AB == 1){
if  (fpb == 0){
valueB=1;
fpb = 1;
}
if (fpb == 1 ){
valueB=((valueB*10)+1);
}
}
}
if (sn2 == HIGH) {
if (AB == 0 ){
if  (fpa == 0){
valueA = 2;
fpa = 1;
}
if (fpa == 1 ){
valueA = ((valueA*10)+2);
}
}
if (AB == 1){
if  (fpb == 0){
valueB=2;
fpb = 1;
}
if (fpb == 1 ){
valueB=((valueB*10)+2);
}
}
}
if (sn3 == HIGH) {
if (AB == 0 ){
if  (fpa == 0){
valueA = 3;
fpa = 1;
}
if (fpa == 1 ){
valueA = ((valueA*10)+3);
}
}
if (AB == 1){
if  (fpb == 0){
valueB=3;
fpb = 1;
}
if (fpb == 1 ){
valueB=((valueB*10)+3);
}
}
}
if (sn4 == HIGH) {
if (AB == 0 ){
if  (fpa == 0){
valueA = 4;
fpa = 1;
}
if (fpa == 1 ){
valueA = ((valueA*10)+4);
}
}
if (AB == 1){
if  (fpb == 0){
valueB=4;
fpb = 1;
}
if (fpb == 1 ){
valueB=((valueB*10)+4);
}
}
}
if (sn5 == HIGH) {
if (AB == 0 ){
if  (fpa == 0){
valueA = 5;
fpa = 1;
}
if (fpa == 1 ){
valueA = ((valueA*10)+5);
}
}
if (AB == 1){
if  (fpb == 0){
valueB=5;
fpb = 1;
}
if (fpb == 1 ){
valueB=((valueB*10)+5);
}
}
}
if (sn6 == HIGH) {
if (AB == 0 ){
if  (fpa == 0){
valueA = 6;
fpa = 1;
}
if (fpa == 1 ){
valueA = ((valueA*10)+6);
}
}
if (AB == 1){
if  (fpb == 0){
valueB=6;
fpb = 1;
}
if (fpb == 1 ){
valueB=((valueB*10)+6);
}
}
}
if (sn7 == HIGH) {
if (AB == 0 ){
if  (fpa == 0){
valueA = 7;
fpa = 1;
}
if (fpa == 1 ){
valueA = ((valueA*10)+7);
}
}
if (AB == 1){
if  (fpb == 0){
valueB=7;
fpb = 1;
}
if (fpb == 1 ){
valueB=((valueB*10)+7);
}
}
}
if (sn8 == HIGH) {
if (AB == 0 ){
if  (fpa == 0){
valueA = 8;
fpa = 1;
}
if (fpa == 1 ){
valueA = ((valueA*10)+8);
}
}
if (AB == 1){
if  (fpb == 0){
valueB=8;
fpb = 1;
}
if (fpb == 1 ){
valueB=((valueB*10)+8);
}
}
}
if (sn9 == HIGH) {
if (AB == 0 ){
if  (fpa == 0){
valueA = 9;
fpa = 1;
}
if (fpa == 1 ){
valueA = ((valueA*10)+9);
}
}
if (AB == 1){
if  (fpb == 0){
valueB=9;
fpb = 1;
}
if (fpb == 1 ){
valueB=((valueB*10)+9);
}
}
}

if (spm ==HIGH){
operation = 1; // plus is the operation
AB = 1;
}
if ((spm == HIGH) && (ssecond == HIGH)){
operation = 2; // minus is operation
AB = 1;
}
if (sdt == HIGH){
operation = 3; // divide is the operation
AB = 1;
}
if ((sdt == HIGH) && (ssecond == HIGH)){
operation = 4; // times is operation
AB = 1;
}

if ((sme == HIGH) && (ssecond == HIGH)){
if (AB == 0){
valueA=(valueA*-1);
}
if (AB == 1){
valueB=(valueB*-1);
}
}

if (sme == HIGH){
if (operation = 1){
valueA = valueA+valueB;
}
if (operation = 2){
valueA = valueA-valueB;
}
if (operation = 3){
valueA = valueA/valueB;
}
if (operation = 4){
valueA = valueA*valueB;
}
AB = 0;
fpb = 0;
fpa = 1;
}
if (AB == 0){
Serial.println(valueA);
}
if (AB == 1){
Serial.println(valueB);
}
delay(500);
}
``````

How would you go about the transition from pressed to not pressed?

How would you go about the transition from pressed to not pressed?

``````int currState;
int prevState = LOW; // Or HIGH, depending on which means not pressed
``````
``````void loop()
{
if(currState != prevState)
{
// A transition occurred
}

prevState = currState;
}
``````

Inside the if block, then, you can determine if the transition was to pressed or to released (whichever currState now is).

Would that keep the loop from running multiple times through while the button is pressed?

Yes, it would tend to do that (you may need some debounce logic).

I'd look at ways of shortening and factoring your code.
Storing a binary state in an "int" is very wasteful.

I just got it. Thanks. Took me a moment to realize the last part.

What form do you think would be best other than an integer?

What form do you think would be best other than an integer?

byte, boolean, char...

Even better is to store multiple bits in one byte, boolean, char, or int.

For a calculator, though, wouldn't I just want the one that could hold the biggest number in both the positive and negative direction? So how would I do that?

wouldn't I just want the one that could hold the biggest number in both the positive and negative direction?

The status of an input pin is normally HIGH or LOW, which doesn't require an "int" to store.
A single bit suffices.

The problem that I am getting with PaulS's suggestion is that it adds 2 numbers, because it detects the transition from LOW to HIGH and then from HIGH to LOW. Any thoughts?

Any thoughts?

See the comment I made about you needing to test WHICH transition occurred?

How did you implement the changes I suggested?

What I meant with the biggest number is for the actual values printed, like what valueA*valueB= . I will be sure to change the ints though for HIGH and LOW to something else.

What I meant with the biggest number is for the actual values printed, like what valueA*valueB= .

If valueA and valueB are ints, the result would be a long.

This is what I tried implementing for each button

``````if (sn2 != prevstate2) {
if (sn1 == HIGH){
if (AB == 0 ){
if  (fpa == 0){
valueA = 2;
fpa = 1;
}
if (fpa == 1 ){
valueA = ((valueA*10)+2);
}
}
if (AB == 1){
if  (fpb == 0){
valueB=2;
fpb = 1;
}
if (fpb == 1 ){
valueB=((valueB*10)+2);
}
}
}
prevstate2 = sn2;
}
``````

That's going to lead to an awful lot of typing.
Suggest you start looking at using arrays.

I already have it typed out. This is just an example of what I have for each button. You are right, though, after this project I am going to start using arrays. At first this project seemed simple...

At first this project seemed simple...

Functions are your friend, too. You have huge blocks of code that are similar, except for pin number and current and previous state variable names. Create a function with three arguments, instead of cutting/pasting/editing.