4 digit 7 segment mistake

I have all of the four digits lighting up, but when I press the button, the led is bright in one end and spins in circles around the digit. I am trying to make it a stopwatch and I don’t know how to fix it. Here is my code:

int d1 =2;
int d2 =3;
int d3 =4;
int d4 =5;

int a = 6;
int b = 7;
int c = 8;
int d = 9;
int e = 10;
int f = 11;
int g = 12;
int point = 13;

int button = A0; 
boolean lastbutton=LOW;
boolean currentbutton=LOW;
boolean ledon=false;

long count1 = 0; 
int x = 100;

int reset;
int count2=0; 
 
void setup()
{
pinMode(button, INPUT_PULLUP); 
  
  pinMode(d1, OUTPUT);
  pinMode(d2, OUTPUT);
  pinMode(d3, OUTPUT);
  pinMode(d4, OUTPUT);
  pinMode(a, OUTPUT);
  pinMode(b, OUTPUT);
  pinMode(c, OUTPUT);
  pinMode(d, OUTPUT);
  pinMode(e, OUTPUT);
  pinMode(f, OUTPUT);
  pinMode(g, OUTPUT);
  pinMode(point, OUTPUT);
  
  digitalWrite(d1, HIGH);
  digitalWrite(d2, HIGH);
  digitalWrite(d3, HIGH);
  digitalWrite(d4, HIGH);
  }

 boolean debounce(boolean last){
   boolean current=digitalRead(button);
  
   if(last !=current){
    delay(5);
    current=digitalRead(button);
}
   return current;
}
 
void loop()
{
  currentbutton=debounce(lastbutton);

  if(lastbutton==LOW && currentbutton==HIGH){
    ledon=!ledon;
  }
  lastbutton=currentbutton;

  
if(ledon==false){
  clearleds();
  pickDigit(1);
  pickNumber((count1/x/1000)%10);
  delayMicroseconds(65);
 
  clearleds();
  pickDigit(2);
  pickNumber((count1/x/100)%10);
  delayMicroseconds(65);
 
  clearleds();
  pickDigit(3);
  pickNumber((count1/x/10)%10);
  delayMicroseconds(65);
 
  clearleds();
  pickDigit(4);
  pickNumber(count1/x%10);
  delayMicroseconds(65);
 
  count1++; 
}

if(ledon==true){

  clearleds();
  pickDigit(1);
  pickNumber((count1/x/1000)%10);
  delayMicroseconds(65);
 
  clearleds();
  pickDigit(2);
  pickNumber((count1/x/100)%10);
  delayMicroseconds(65);
 
  clearleds();
  pickDigit(3);
  pickNumber((count1/x/10)%10);
  delayMicroseconds(65);
 
  clearleds();
  pickDigit(4);
  pickNumber(count1/x%10);
  delayMicroseconds(65);
  
   }

  reset= digitalRead(button);
  
  
  if(reset==LOW){
    count2=count2+1;
   }
    else{
    reset=HIGH;
    count2=0;
  }
  
  if(count2==1000){
  
  digitalWrite(d1, HIGH);
  digitalWrite(d2, HIGH);
  digitalWrite(d3, HIGH);
  digitalWrite(d4, HIGH);
  
  eight();
  delay(100);

  clearleds();
  delay(100);

  eight();
  delay(100);

  clearleds();
  delay(800);
  
    count2=0;
    count1=0;
    ledon=!ledon;
  }
  
}
 
void pickDigit(int pick1)
{
  digitalWrite(d1, LOW);
  digitalWrite(d2, LOW);
  digitalWrite(d3, LOW);
  digitalWrite(d4, LOW);
 
  switch(pick1)
  {
  case 1: 
    digitalWrite(d1, HIGH); 
    break;
  case 2: 
    digitalWrite(d2, HIGH); 
    break;
  case 3: 
    digitalWrite(d3, HIGH);
    digitalWrite(point,LOW);
    break;
  default: 
    digitalWrite(d4,HIGH); 
    break;
  }
}
 
void pickNumber(int pick2) 
{
  switch(pick2)
  {
  default: 
    zero(); 
    break;
  case 1: 
    one(); 
    break;
  case 2: 
    two(); 
    break;
  case 3: 
    three(); 
    break;
  case 4: 
    four(); 
    break;
  case 5: 
    five(); 
    break;
  case 6: 
    six(); 
    break;
  case 7: 
    seven(); 
    break;
  case 8: 
    eight(); 
    break;
  case 9: 
    nine(); 
    break;
  }
}
 
void clearleds() 
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
  digitalWrite(point, HIGH);
}
 
void zero()
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, HIGH);
}
 

void one(){
  digitalWrite(a,HIGH);
  digitalWrite(b,LOW);
  digitalWrite(c,LOW);
  digitalWrite(d,HIGH);
  digitalWrite(e,HIGH);
  digitalWrite(f,HIGH);
  digitalWrite(g,HIGH);
}
 

void two(){
  digitalWrite(a,LOW);
  digitalWrite(b,LOW);
  digitalWrite(c,HIGH);
  digitalWrite(d,LOW);
  digitalWrite(e,LOW);
  digitalWrite(f,HIGH);
  digitalWrite(g,LOW);
}
 
void three(){
  digitalWrite(a,LOW);
  digitalWrite(b,LOW);
  digitalWrite(c,LOW);
  digitalWrite(d,LOW);
  digitalWrite(e,HIGH);
  digitalWrite(f,HIGH);
  digitalWrite(g,LOW);
}
 
void four(){
  digitalWrite(a,HIGH);
  digitalWrite(b,LOW);
  digitalWrite(c,LOW);
  digitalWrite(d,HIGH);
  digitalWrite(e,HIGH);
  digitalWrite(f,LOW);
  digitalWrite(g,LOW);
}
 
void five(){
  digitalWrite(a,LOW);
  digitalWrite(b,HIGH);
  digitalWrite(c,LOW);
  digitalWrite(d,LOW);
  digitalWrite(e,HIGH);
  digitalWrite(f,LOW);
  digitalWrite(g,LOW);
}
 
void six(){
  digitalWrite(a,LOW);
  digitalWrite(b,HIGH);
  digitalWrite(c,LOW);
  digitalWrite(d,LOW);
  digitalWrite(e,LOW);
  digitalWrite(f,LOW);
  digitalWrite(g,LOW);
}
 
void seven(){
  digitalWrite(a,LOW);
  digitalWrite(b,LOW);
  digitalWrite(c,LOW);
  digitalWrite(d,HIGH);
  digitalWrite(e,HIGH);
  digitalWrite(f,HIGH);
  digitalWrite(g,HIGH);
}
 
void eight(){
  digitalWrite(a,LOW);
  digitalWrite(b,LOW);
  digitalWrite(c,LOW);
  digitalWrite(d,LOW);
  digitalWrite(e,LOW);
  digitalWrite(f,LOW);
  digitalWrite(g,LOW);
}
 
void nine(){
  digitalWrite(a,LOW);
  digitalWrite(b,LOW);
  digitalWrite(c,LOW);
  digitalWrite(d,LOW);
  digitalWrite(e,HIGH);
  digitalWrite(f,LOW);
  digitalWrite(g,LOW);
}

Any help is appreciated. Thank you!

(Code tags added by a Moderator. Please use the </> button on the menu next time. Thanks!)

What is the role of x in the above expression and the several others (8?) where it appears?

I don’t see that x is anything but 100, ever, I can make sense of most of how you are going about this but not all that dividing by x, dividing by 100.

a7

What you’ve done is admirable as a learning experience, but you’ve definitely done a LOT more work than is necessary for this LED project.

I’m sure there are some examples out there where you can squash all your logic down to a couple of simple functions - this will make your code more readable - and a lot more maintainable.

If I had more time right now, I’d put some time in, but there are a lot of existing examples.

What you have shows that you understand the concepts, now to find the example that develops your coding skills.

To be honest, I don’t know. How would x be represented though if it was something other than 100?

Yes, an amazing very literal program. I wonder if it is worth going what seems like it might be just a bit further to get this to work.

I too would spend time on it, but TBH it make my eyes hurt.

And rigging up enough circuit to test it would take time. I have no life, but there are limits.

It looks plausible, though, and I am curious about the flaw.

@steve_111 could you take a minute and describe what is supposed to happen

  1. no buttton pressed
  2. when you press the button, and is holding the button down different

and so forth, then as best you can describe what is actually happening?

TIA

a7

When I don’t press the button, everything is lit up and is perfectly normal. When I press the button, everything is still lit up, but one segment out of the 7 in each digit is a little bit brighter. That bright segment starts to go in loops throughout each digit. I know it sounds confusing, but do you understand it?

Yes, I can see it. Just to be clear,

the same segment in all digits is a bit brighter, and that bright segment is flying around through all seven segments?

If it is one of the digits only, which one you just said “one end” which remains a bit confusing.

And… what is the button supposed to do?

Other than the brightness, can you resc the digits you expect, so this is more like a cosmetic error (still important to fix, yes) but you could still land the Lunar Excursion Module if that displayed number was critical?

a7

Yes, the same segments fly around at the same time. It is happening to all of the digits. The button is supposed to start and stop it. I am not quite sure what you are asking in the last question, but I believe it is some bug or error in the system that won’t allow the digits to light up in the way it should be.

Hehe, yes, I was trying to be nice…
When OP gets the hang of it, he’ll be amazed at what he’s learned.

OK, I see that sort of. When you say

do you mean like after you have stabbed the button (press and release like changing channels) , or when you hold the button down?

The button also looks to be involved in reset somehow. Perhaps removing all the reset logic for now will make other things easier to see.

Yeah, me neither. That’s a sure sign I have to drop this for right now. If you aren’t pressing the button, and it is running, the numbers are fine and going up at some rate, legible?

What are you trying to do in this part, explain what this count2 is all about

  reset = digitalRead(button);

  if (reset == LOW) {
    count2 = count2 + 1;
  }
  else {
    reset = HIGH;
    count2 = 0;
  }

  if (count2 == 1000) {...

BTW most of the code in the two sections

  if (ledon == false) {...

and

  if (ledon == true) {...

is repeated, it would shorten your code but not change anything if you just did all the common part and then followed it

  if (ledon == false) {
    count1++;
  }

But I can’t see and need to sleep before I look again anything to explain the swirling segment thing.

Did any part of this come from somewhere (someone) else? I only ask because you can’t tell me the role of your variable x, which is never anything but 100, so it seems odd if it is all over the place… I can see what the effect of it is (maybe) but you should be able to say how it came to be there.

a7

When I hold down the button, it does reset. When I press it once, it becomes weird.

Note that the first three digits end with:

    pickNumber((count1 / x / 10) % 10);
    delayMicroseconds(65);

    clearleds();

and the fourth digit ends with:

     pickNumber((count1 / x) % 10);
     delayMicroseconds(65);
 
  }

Note the missing “clearleds();” after the 4th digit. This means that the 4th digit will stay on much longer and appear much brighter than the other three.

@johnwasser nice catch. A fifth clear should make each digit time identical.

There’s still the swirling segment thing, and @steve_111 has not said what count2 is doing nor the significance of 1000 in that section.

Srsly, what are you trying to do? The button is serving two roles, or more like misserving.

a7

You should use millis() instead of counting loops. Here is a 7-segment stopwatch example I wrote. Perhaps it will provide some inspiration.

/////////////////////////////////////
//  Seven-Segment Stopwatch Example
//
//  Written by: John Wasser
/////////////////////////////////////

// Bit maps for the seven segment display
// Segment Cathodes (0/LOW for on, 1/HIGH for off)
const byte Segments[] =
{
  0b11000000, // 0
  0b11001111, // 1
  0b10100100, // 2
  0b10000110, // 3
  0b10001011, // 4
  0b10010010, // 5
  0b10010000, // 6
  0b11000111, // 7
  0b10000000, // 8
  0b10000011, // 9
};


const byte ColonLowerDot = 12;
const byte ColonUpperDot = 13;

// List of digit select lines, least significant digit first
// Digit Common Anodes (HIGH for on, LOW for off)
const byte DigitCount = 4;
const byte DigitPins[DigitCount] = {A0, 2, 3, 4};

// Segment Cathodes (LOW for on, HIGH for off)
const byte SegmentCount = 7;
const byte SegmentPins[SegmentCount] = {5, 6, 7, 8, 9, 10, 11};

const byte StartButtonPin = A1;  // Button wired from pin to GND
const byte StopResetButtonPin = A2;  // Button wired from pin to GND
bool StartButtonWasPressed = false;
bool StopResetButtonWasPressed = false;

unsigned long DebounceTimer = 0;
const unsigned DebounceTime = 10;

bool IsRunning = false;
unsigned long ElapsedTime = 0;
unsigned long LastStartTime = 0;


void setup()
{
  pinMode(StartButtonPin, INPUT_PULLUP);
  pinMode(StopResetButtonPin, INPUT_PULLUP);

  for (int i = 0; i < DigitCount; i++)
  {
    pinMode(DigitPins[i], OUTPUT);
    digitalWrite(DigitPins[i], LOW);
  }

  for (int i = 0; i < SegmentCount; i++)
  {
    pinMode(SegmentPins[i], OUTPUT);
    digitalWrite(SegmentPins[i], HIGH);
  }

  digitalWrite(ColonLowerDot, HIGH);
  digitalWrite(ColonUpperDot, HIGH);

  pinMode(ColonLowerDot, OUTPUT);
  pinMode(ColonUpperDot, OUTPUT);
}



void loop()
{
  unsigned long currentTime = millis();

  bool startButtonIsPressed = digitalRead(StartButtonPin) == LOW;
  bool stopResetButtonIsPressed = digitalRead(StopResetButtonPin) == LOW;

  // State Change Detection and debounce
  if (startButtonIsPressed != StartButtonWasPressed &&
      currentTime - DebounceTimer > DebounceTime)
  {
    // Button has changed state
    StartButtonWasPressed = startButtonIsPressed;
    DebounceTimer = currentTime;

    if (startButtonIsPressed)
    {
      // Just Pressed START
      if (!IsRunning)
      {
        // Starting/Restarting the timer
        LastStartTime = currentTime;
        IsRunning = true;
      }
      else
      {
        // Pausing the timer
        IsRunning = false; // Paused
        ElapsedTime += currentTime - LastStartTime;
      }
    }
  }

  // State Change Detection and debounce
  if (stopResetButtonIsPressed != StopResetButtonWasPressed &&
      currentTime - DebounceTimer > DebounceTime)
  {
    // Button has changed state
    StopResetButtonWasPressed = stopResetButtonIsPressed;
    DebounceTimer = currentTime;

    if (stopResetButtonIsPressed)
    {
      // Just Pressed STOP/RESET
      if (IsRunning)
      {
        // Pausing the timer
        IsRunning = false; // Paused
        ElapsedTime += currentTime - LastStartTime;
      }
      else
      {
        // Was not running so reset everything
        ElapsedTime = 0;
        IsRunning = false;
      }
    }
  }

  // Get time since last reset
  unsigned long DisplayTime;
  if (IsRunning)
    DisplayTime = ElapsedTime + (currentTime - LastStartTime);
  else
    DisplayTime = ElapsedTime;

  unsigned long hundredths = DisplayTime / 10;
  unsigned long seconds = hundredths / 100;
  unsigned long minutes = seconds / 60;
  int hours = minutes / 60;
  int clock;

  if (seconds < 100)
    // Display seconds.hundredths up to 100 seconds, then minutes:seconds
    clock = (seconds % 100) * 100 + (hundredths % 100);
  else if (minutes < 100)
    // Display minutes:seconds up to 100 minutes, then hours/minutes
    clock = (minutes % 100) * 100 + (seconds % 60);
  else
    clock = (hours % 100) * 100 + (minutes % 60);

  // Clear all segments before enabling a digit
  for (int s = 0; s < SegmentCount; s++)
  {
    digitalWrite(SegmentPins[s], HIGH);
  }

  // Display each digit, right to left
  for (int i = 0; i < DigitCount; i++)
  {
    // Peel a digit off the low end of the number
    int digit = clock % 10;
    clock /= 10;

    // Blank the MSD if it is zero
    if (i == 3 && digit == 0)
    {
      for (int s = 0; s < SegmentCount; s++)
        digitalWrite(SegmentPins[s], HIGH);
    }
    else
    {
      // Display the digit on the seven segments
      unsigned char segments = Segments[digit];
      for (int s = 0; s < SegmentCount; s++)
      {
        digitalWrite(SegmentPins[s], segments & 1);
        segments >>= 1;
      }
    }

    if (seconds < 100)
    {
      // Steady decimal point when showing seconds and hundredths
      digitalWrite(ColonLowerDot, HIGH);
      digitalWrite(ColonUpperDot, LOW);
    }
    else if (minutes < 100)
    {
      // Steady colon when showing minutes and seconds
      digitalWrite(ColonLowerDot, LOW);
      digitalWrite(ColonUpperDot, LOW);
    }
    else
    {
      // Make the colon blink each second
      digitalWrite(ColonLowerDot, seconds & 1);
      digitalWrite(ColonUpperDot, seconds & 1);
    }

    // Turn on the digit briefly
    digitalWrite(DigitPins[i], HIGH);  // Select one digit
    delayMicroseconds(3000UL);  // Higher numbers give higher brightness but more flicker
    digitalWrite(DigitPins[i], LOW);
  }
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.