7-Segment Ping Pong Scoreboard-Help!

Hello!

I have been working on a scoreboard project for some time now, and I have just now got around to the coding. The idea is to score a point, you swipe the paddle under the table, which is detected by the photoresistor. I am still fairly new to the Arduino language, and I didn’t know what to expect.

The issue is that when I power on the device, P1 shows 11 in the P1 11 loop, and shows a Game Score of 2-3. Then, the P2 display shows 11, and still reads a Game Score of 2-3. This goes on until I turn off the power. I’m not sure what to try!

Properly, it should run to 11, flash, and then show the game score for 10 seconds, as well as switch the Score LED off, and the Game LED on.Then, it should go back to 0-0, reversing the state of both of those LEDs. If both players swipe, the scoreboard should completely reset.

Here is the code, minus some of the void() 7-Segment statements, as this made it too lengthy to post.

/* Ping Pong Score Keeper


Uses photoresistors and LEDs to detect a swipe of a paddle under the table,
and then adds a point to the scoreboard, depending on which side was swiped.

Both players swipe at the same time to clear the scoreboard.

Schematic for 7 - Segments:


                        13/6
                   -------------
                   |           |
                8/1|           |  12/5
                   |     7/0   |
                   |-----------|
                   |           |
               9/2 |           |  11/4
                   |           |
                   |-----------|
                   
                         10/3
                         
Use a 10KOhm Pull-Down resistor to ground with the photoresistor, as well as standard current-limiting resistors.
 
Enjoy!
*/

int P1Photo = A0;    //Setup P1 and P2's photoresistor
int P2Photo = A1;

int P1PhotoVal = 0;
int P2PhotoVal = 0;

int P1Score = 0;    //Initialize the score
int P2Score = 0;

int P1GameScore = 0;
int P2GameScore = 0;

int P1OldScore = 0;    //Setup OldScore for use in the delay mechanism.
int P2OldScore = 0;

int scoreLED = A3;
int gameLED = A4;

void cleardisp1()   //Setup all of the commands for printing digits. I'm lazy, so I didn't use a shift register.
{
  digitalWrite(13, LOW);
  digitalWrite(12, LOW);
  digitalWrite(11, LOW);
  digitalWrite(10, LOW);
  digitalWrite(9, LOW);
  digitalWrite(8, LOW);
  digitalWrite(7, LOW);
}
  
void cleardisp2()
{
  digitalWrite(6, LOW);
  digitalWrite(5, LOW);
  digitalWrite(4, LOW);
  digitalWrite(3, LOW);
  digitalWrite(2, LOW);
  digitalWrite(1, LOW);
  digitalWrite(0, LOW);
  
}

void scorezero1()
{
  digitalWrite(13, HIGH);
  digitalWrite(12, HIGH);
  digitalWrite(11, HIGH);
  digitalWrite(10, HIGH);
  digitalWrite(9, HIGH);
  digitalWrite(8, HIGH);
  
}

void scoreone1()
{
  digitalWrite(12, HIGH);
  digitalWrite(11, HIGH);
}

void scoretwo1()
{
  digitalWrite(13, HIGH);
  digitalWrite(12, HIGH);
  digitalWrite(7, HIGH);
  digitalWrite(9, HIGH);
  digitalWrite(10, HIGH);
  
}

void scorethree1()
{
  digitalWrite(13, HIGH);
  digitalWrite(12, HIGH);
  digitalWrite(7, HIGH);
  digitalWrite(9, HIGH);
  digitalWrite(10, HIGH);
  
//That goes on for a long time...
//Put a 2 at the end for P2.




void setup () {
  
  //Serial.begin(9600);    //Initialize serial for easy debugging
  pinMode(P1Photo, INPUT);    //Setup the photoresistors as inputs
  pinMode(P2Photo, INPUT);
  
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(0, OUTPUT);
  
  pinMode(scoreLED, OUTPUT);
  pinMode(gameLED, OUTPUT);
  digitalWrite(scoreLED, HIGH);
  
  
  
}

void loop() {
  
  int P1PhotoVal = analogRead(P1Photo);    //Take a reading for P1's PR
  int P2PhotoVal = analogRead(P2Photo);  //Take a reading...
  
  if (P1PhotoVal<50 && P2PhotoVal<50){
    P1Score == 0;
    P2Score == 0;
    
    P1GameScore == 0;
    P2GameScore == 0;
    delay(5000);  
  }
   
  
  
  if (P1PhotoVal<350){    //NOTE: Change 000 to the value of a swipe
    P1Score ++;  //Add 1 to P1's count
    
  }
  

  
  
  
  if(P2PhotoVal<350) {  //Add points...
    P2Score++;
    
  }
  

  
  
  if(P1Score = 0) {
    cleardisp1();
    scorezero1();

  }

   if(P1Score = 1) {
    cleardisp1();
    scoreone1(); 
    
   }
   
   if(P1Score = 2) {
    cleardisp1();
    scoretwo1();
    
   }
   
   if(P1Score = 3) {
    cleardisp1();
    scorethree1();
    
   }
   
    if(P1Score = 4) {
    cleardisp1();
    scorefour1();
    
   }
  
    if(P1Score = 5) {
    cleardisp1();
    scorefive1();
    
   }

    if(P1Score = 6) {
    cleardisp1();
    scoresix1();
    
   }
    
    if(P1Score = 7) {
    cleardisp1();
    scoreseven1();
    
   }
  
    if(P1Score = 8) {
    cleardisp1();
    scoreeight1();
    
   }
  
    if(P1Score = 9) {
    cleardisp1();
    scorenine1();
    
   }

    if(P1Score = 10) {
    cleardisp1();
    scoreten1();
    
   }
   
    if(P1Score = 11) {
    cleardisp1();
    scoreeleven1();
    delay(1500);
    cleardisp1();
    delay(1000);
    scoreeleven1();
    delay(1000);
    cleardisp1();
    
    cleardisp2();
    delay(1000);
    digitalWrite(scoreLED, LOW);
    digitalWrite(gameLED, HIGH);
    P1GameScore++;
    
    if (P1GameScore=0) {
      cleardisp1();
      scorezero1();
      
    }
    
    if (P2GameScore=0) {
      cleardisp2();
      scorezero2();
      
    }
    
    if (P1GameScore=1) {
      cleardisp1();
      scoreone1();
      
    }
    
    if (P2GameScore=1) {
      cleardisp2();
      scoreone1();
      
    }
    
    if (P1GameScore=2) {
      cleardisp1();
      scoretwo1();
      
    }
    
    if (P2GameScore=2) {
      cleardisp2();
      scoretwo2();
      
    }
    
    if (P1GameScore=3) {
      cleardisp1();
      scorethree1();
      
    }
    
    if (P2GameScore=3) {
      cleardisp2();
      scorethree2();
      
    }
    
    delay(10000);
    digitalWrite(gameLED, LOW);
    digitalWrite(scoreLED, HIGH);
    P1Score = 0;
    P2Score = 0;
    
  }
  
  if(P2Score = 0) {
  cleardisp2();
  scorezero2();
    
  }
      
  if(P2Score = 1) {
  cleardisp2();
  scoreone2();
    
  }
  
  if(P2Score = 2) {
  cleardisp2();
  scoretwo2();
  
  }
  
  if(P2Score = 3) {
  cleardisp2();
  scorethree2();
  
  }
  
  if(P2Score = 4) {
  cleardisp2();
  scorefour2();
  
  }
  
  if(P2Score = 5) {
  cleardisp2();
  scorefive2();
  
  }
   
  if(P2Score = 6) {
  cleardisp2();
  scoresix2();
  
  }
  
  if(P2Score = 7) {
  cleardisp2();
  scoreseven2();
  
  }
  
  if(P2Score = 8) {
  cleardisp2();
  scoreeight2();
  
  }
  
  if(P2Score = 9) {
  cleardisp2();
  scorenine2();
  
  }
  
  if(P2Score = 10) {
  cleardisp2();
  scoreten2();
  
  }
  
  if(P2Score = 11) {
    cleardisp2();
    scoreeleven2();
    delay(1500);
    cleardisp2();
    delay(1000);
    scoreeleven2();
    delay(1000);
    cleardisp1();
    
    cleardisp2();
    delay(1000);
    digitalWrite(scoreLED, LOW);
    digitalWrite(gameLED, HIGH);
    P2GameScore++;
    
    if (P1GameScore=0) {
      cleardisp1();
      scorezero1();
      
    }
    
    if (P2GameScore=0) {
      cleardisp2();
      scorezero2();
      
    }
    
    if (P1GameScore=1) {
      cleardisp1();
      scoreone1();
      
    }
    
    if (P2GameScore=1) {
      cleardisp2();
      scoreone1();
      
    }
    
    if (P1GameScore=2) {
      cleardisp1();
      scoretwo1();
      
    }
    
    if (P2GameScore=2) {
      cleardisp2();
      scoretwo2();
      
    }
    
    if (P1GameScore=3) {
      cleardisp1();
      scorethree1();
      
    }
    
    if (P2GameScore=3) {
      cleardisp2();
      scorethree2();
      
    }
    delay(10000);
    digitalWrite(gameLED, LOW);
    digitalWrite(scoreLED, HIGH);
    P1Score = 0;
    P2Score = 0;
    
  }
  
    if(P1Score>P1OldScore) {  //Add a delay after a swipe until a new one can be registered.
    delay(3500);
    P1OldScore = P1Score;
    
  }
    if(P2Score>P2OldScore) {  //Cool the jets, hold the horses, land the drones...
    delay(3500);
    P2OldScore = P2Score;
    
  }
  
    
}

Any help is greatly appreciated in advance!

-Wizzrobes :slight_smile:

For starters,

int P1PhotoVal = analogRead(P1Photo);    //Take a reading for P1's PR
  int P2PhotoVal = analogRead(P2Photo);  //Take a reading...

P1 and P2PhotoVal's have already been defined before setup(), lose the int's.

P1PhotoVal = analogRead(P1Photo);    //Take a reading for P1's PR
P2PhotoVal = analogRead(P2Photo);  //Take a reading...
P1Score ++;  //Add 1 to P1's count

should be

P1Score++;  //Add 1 to P1's count

Thank you very much for the suggestion, but I still remain to have the same problem. My code now reflects your improvements, though.

Any help is still appreciated!

-Wizzrobes :)

Hi,

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png or pdf?

Tom...... :)

No problem! Here’s the attachment.

-Wizzrobes :slight_smile:

Hi,what are you using as your power supply, I'm not sure if driving all those segments directly and using the 5V regulated supply of the arduino is a good idea.

Tom... :)

Segments only need 20mA if properly current limited, should be okay with onboard regulator, as it looks like only 1 segment of each digit would be on at a time from the schematic.

Hi, hmm every segment has an output, don't think its mutliplexed.

Tom.... :)

 if(P1Score = 0) {

Oops

Code: [Select]

P1Score ++; //Add 1 to P1's count

should be Code: [Select]

P1Score++; //Add 1 to P1's count

@marmotjr; both are valid

Hi, if you read maximum ratings for the controller chip,

40mA per Output. BUT 200mA total at Vcc, so only 5 outputs can supply 40mA or 10 supplying 20mA at a time and thats not taking the chip running requirements into account.

Tom..... :)

I only see one current limit resistor per digit, thus my multiplexing assumption. If not multiplexed, need a current limit resistor per segment between the arduino pins and the anodes of the segments, with common cathode to Gnd. Overall current limit on the ports as already noted - specifics per the notes below Table 29-2 in the data sheet.

As AWOL pointed out, every IF statement that checks for equality is using the single equals assignment operator, not the double equals comparison operator. This will change the value of the variable being compared, and then execute every conditional block if the new value is non-zero. In every IF statement, change ‘=’ to ‘==’

Another issue is this construct near the top of loop():

 if (P1PhotoVal<350){    //NOTE: Change 000 to the value of a swipe
    P1Score ++;  //Add 1 to P1's count
  }

  if(P2PhotoVal<350) {  //Add points...
    P2Score++;
  }

loop() will (or at least should) execute very quickly, much faster than the player can swipe the paddle past the photoresistor, and probably faster than the photoresistor can react. The net result is that the score counters will increment very quickly while the sensor is active. You need some sort of debounce logic that looks for the sensor to go active, increments the value once, and then skips incrementing the counter until the sensor has been seen to be inactive.

Hi,

if(P1Score = 4) {
    cleardisp1();
    scorefour1();
     }

Apart from == error, it looks like very crude multiplex. But.

if(P1Score = 11) {
    cleardisp1();
    scoreeleven1();
    delay(1500);
    cleardisp1();
    delay(1000);
    scoreeleven1();
    delay(1000);
    cleardisp1();
}

Isn't 1.5 and 1 second flashing of digits going to give controller and onboard reg a hard time current wise.

OP, I think you need to revise your display system, to use external power supply for the digits, as the arduino outputs my be getting overloaded.

Tom....... :)

You bring up a good point with the power supply, as my adapter only supplies 7.5 volts at 200mA, so I will have to figure out a way to use an external supply.

What is your recommendation for an external source? I don’t think using relays, like I have in the past, would be practical.

Also, thank you, ShapeShifter for the fixes to the code. I will apply these after I figure out an external power source.

-Wizzrobes :slight_smile:

If not multiplexed, need a current limit resistor per segment between the arduino pins and the anodes of the segments,

That's the correct way to do it anyways. Unless you want lower brightness when you display "8".

This is how I did it, and it prevents a lot of weirdness with blocking code, etc.

tone(Cath_1, 50); // Make 50Hz Multiplex Clock on Cath_1

attachInterrupt(3, WriteDisplay, CHANGE); // Monitors state of Cath_1's TONE and writes Seven Segment

Of course you need to connect Cath_1 to an input to readback the state of the pulse.

// ************************ WriteDisplay ISR ******************** void WriteDisplay(void) { if (AVR_Port_D & 0b00001000){ // Send ONES digit SevenSeg(Ones); // Decode } if (!(AVR_Port_D & 0b00001000)) { // Send TENS digit SevenSeg(Tens); // Decode } }

Then I write the segments out on port "B", each desired number has its own case :

case 8: PORTB = 0b11111110; // Segments for "8" break;

Not going to list the entire block, but the segments are assigned "g,f,e,d,c,b,a,dec.