curious skipping of cases in arduino project

Hey guys,

I’m developing an alarm clock by building the circuit and code step by step. Now im stuck with a little problem:
In this stage of the project, I want to have an arduino uno controlling a one-digit-seven-segment-display with common anode . It has two buttons. When you start the Arduino, the display displays ‘0’. When you click the one button, it will count up and vice versa.

Somehow sometimes some digits (and thus cases in the code) are skipped. I don’t understand, how this happens. Do You have any idea or hint?

Thanks in advance!

here goes the build:

countUpAndDown_Steckplatine.jpg

and here goes the code:

int button0 = 0;
int button1 = 0;
int previous0 = 0;
int previous1 = 0;
int currentState = 0;
long time = 0;
long debounce = 10;

void setup() {
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  
  pinMode(10, INPUT);
  pinMode(11, INPUT);
  
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);
  digitalWrite(8, HIGH);

}


void loop() {
  switch (currentState) {
    case 0:
      //0
      digitalWrite(2, LOW);
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
      digitalWrite(5, LOW);
      digitalWrite(6, LOW);
      digitalWrite(7, LOW);
      digitalWrite(8, HIGH);
    break;
    case 1:
      //1
      digitalWrite(2, HIGH);
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
      digitalWrite(5, HIGH);
      digitalWrite(6, HIGH);
      digitalWrite(7, HIGH);
      digitalWrite(8, HIGH);
    break;
    case 2:
      //2
      digitalWrite(2, LOW);
      digitalWrite(3, LOW);
      digitalWrite(4, HIGH);
      digitalWrite(5, LOW);
      digitalWrite(6, LOW);
      digitalWrite(7, HIGH);
      digitalWrite(8, LOW);
    break;
    case 3:
      //3
      digitalWrite(2, LOW);
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
      digitalWrite(5, LOW);
      digitalWrite(6, HIGH);
      digitalWrite(7, HIGH);
      digitalWrite(8, LOW);
    break;
    case 4:
      //4
      digitalWrite(2, HIGH);
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
      digitalWrite(5, HIGH);
      digitalWrite(6, HIGH);
      digitalWrite(7, LOW);
      digitalWrite(8, LOW);
    break;
    case 5:
      //5
      digitalWrite(2, LOW);
      digitalWrite(3, HIGH);
      digitalWrite(4, LOW);
      digitalWrite(5, LOW);
      digitalWrite(6, HIGH);
      digitalWrite(7, LOW);
      digitalWrite(8, LOW);
    break;
    case 6:
      //6
      digitalWrite(2, LOW);
      digitalWrite(3, HIGH);
      digitalWrite(4, LOW);
      digitalWrite(5, LOW);
      digitalWrite(6, LOW);
      digitalWrite(7, LOW);
      digitalWrite(8, LOW);
    break;
    case 7:
      //7
      digitalWrite(2, LOW);
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
      digitalWrite(5, HIGH);
      digitalWrite(6, HIGH);
      digitalWrite(7, HIGH);
      digitalWrite(8, HIGH);
    break;
    case 8:
      //8
      digitalWrite(2, LOW);
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
      digitalWrite(5, LOW);
      digitalWrite(6, LOW);
      digitalWrite(7, LOW);
      digitalWrite(8, LOW);
    break;
    case 9:
      //9
      digitalWrite(2, LOW);
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
      digitalWrite(5, LOW);
      digitalWrite(6, HIGH);
      digitalWrite(7, LOW);
      digitalWrite(8, LOW);
    break;
  }
  
  button0 = digitalRead(10);
  button1 = digitalRead(11);
  
  if (button0 == HIGH && previous0 == LOW && millis() - time > debounce) {
    if (currentState == 9) {
      currentState = 0;
    }
    else {
      currentState = currentState + 1;   
    }
  }
  if (button1 == HIGH && previous1 == LOW && millis() - time > debounce) {
    if (currentState == 0) {
      currentState = 9;
    }
    else {
      currentState = currentState - 1;
    }
  }
  
  previous0 = button0;
  previous1 = button1;
}

btw: this is my first post and my first project with arduino :smiley:

have you tried a longer debounce time

I see some signed variables. I see a call to millis. Maybe the two don't go together.

funny issue is: I did experiment with the debounce variable. It didn’t make any difference and I don’t really know, what it changes… xD

[quote author=Coding Badly link=msg=2237892 date=1431994913] I see some signed variables. I see a call to millis. Maybe the two don't go together. [/quote]

What do you mean with signed variables? Is this a hint (as a statement) or a suggestion (because you are not sure)?

You never update the time variable by assigning millis() to it. So the debounce time is always zero. All your timing variables except for the debounce variable should be unsigned long type (but that is not what is causing the problem here).

Also, if you don't use current limiting resistors on the LEDs you can burn out the Arduino outputs.

As aarg said, the time variable is never set, and you should use unsigned long instead, or uint32_t. Signed integers (i.e., int) will work until millis() wraps around to 0. Coding Badly was nudging you to go search for the answer.

There's also a logic problem in the if statement:

  if (button0 == HIGH && previous0 == LOW && millis() - time > debounce) {
    ...
  }

  previous0 = button0;

When button0 goes HIGH and previous0 was LOW, you then check if the debounce time has passed. The first time through, it hasn't been that long (just a few microseconds, actually!). That's ok so far. However, a few lines later, you set previous0 to HIGH as well. The if condition won't be true next time, because the 2nd term is false.

To fix the problem, you should review button debouncing examples again.

Also, I would suggest some parentheses for clarity:

  if ((button0 == HIGH) && (previous0 == LOW) && (millis() - time > debounce)) {

Cheers, /dev

aarg(H), you are right. after putting time = millis(); in the code twice it works now great.

  if (button0 == HIGH && previous0 == LOW && millis() - time > debounce) {
    if (currentState == 9) {
      currentState = 0;
    }
    else {
      currentState = currentState + 1;   
    }
    time = millis();
  }
  if (button1 == HIGH && previous1 == LOW && millis() - time > debounce) {
    if (currentState == 0) {
      currentState = 9;
    }
    else {
      currentState = currentState - 1;
    }
    time = millis();
  }

thanks guys! :D

Don't forget those resistors or the LED, or the Arduino, or both, will be damaged.

Should I use only one resistor before the anode? Or rather seven resistors on the green wires? And how many Ohms should I use, when I have no idea on the values of the display...? :confused:

200 -300 ohm on each individual led(all seven) should be fine it's not really super critical you just need to limit the current

http://www.evilmadscientist.com/2012/resistors-for-leds/

.

I note that you set previous0 and previous1 irrespective of any debouncing?

xamiax: Should I use only one resistor before the anode? Or rather seven resistors on the green wires? And how many Ohms should I use, when I have no idea on the values of the display...? :confused:

One resistor would make the brightness vary wildly depending on how many segments are lit. You need the seven resistors as Hutkikz said.