Score counter with a photo sensor

Hello, I'm currently working on a school project in which I'm making a game with a laser, a photo sensor and a 7 segments display.

The goal is when the laser hit the photo sensor, it will add 1 to the current score.
But my problem is since the photo sensor is analogic, there is too much changes of value when the laser hit it.

Here is my code :

// include the library dedicated to the 4 digit display
#include "TM1637.h"
// define the connection pins for the clock and the data
#define CLK 8 // eg D8
#define DIO 9 // eg D9
TM1637 tm1637(CLK, DIO); //  attach our pins to the object used to manipulate our screen

// define the available characters
int8_t NumTab[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; //0~9,A,b,C,d,E,F
// define a variable that we will increase little by little to calculate the time
int num = 2;
int pinButton = 4;
int bestScore = 0;

bool valButton; //Pour stocker la valeur du bouton


void setup() {
  // initialize our screen and specify its brightness
  pinMode(pinButton, INPUT);
  tm1637.init();
  tm1637.set(BRIGHTEST);//BRIGHT_TYPICAL = 2,BRIGHT_DARKEST = 0,BRIGHTEST = 7;
}

void loop(){

  int value = analogRead(0); // read the value on the pin A0 and store it in an integer variable
  
  tm1637.display(3, NumTab[num]); // show the thousands digit on the leftmost segment 
   if (value > 100) {
    num ++; // increase the num value of 1

   }

I'm struggling in finding a way so when the value change, it will change only once and the score change only once.

If anyone have an idea on how I can make this work ?

Welcome to the forum

You need to detect when the input becomes active rather than when it is active
See the StateChangeDetection example in the IDE

Hi @astryal

welcome to the arduino-forum.
well done posting your code as a code-section in your first post.

You should describe in much more detail what your project is.

Does the laser do a short blink like a shot and then is switched off again?

Does the laser have to stay as long as possible on the photo-sensor?
or does the laser have to stay for a minimum of time for beeing counted as a hit?

Shall the laser-light-point wipe over the photosensor as often as possible and as fast as possible in a limited time?

These details will determine how the code looks like to detect the laser and counting up.

You should post a link to the datasheet of your photosensor or at least a link from where the photosensor was bought or at very very least a picture of how the sensor looks like.

best regards Stefan

If your sensor has really an anlog output
You need to write code that has a hysteresis
image
As long as the value is below 530 the code does not count up
only in case the value goes above 530 count-up one time

Then the value must go below 490 to change the mode for a new count-up 1
Here are example-numbers that show the behaviour what the code must do

values	
488	
487	
480	
489	
490	
495	
503	
527	
531	above 530 => +1
535 
640
870
530	
529	
…	
491	
490	
489	Below 490 get ready for counting up +1 in case value goes above 530
491	
498	
511	
525	
503	
532	above 530 => +1

As this is a school-project you should learn to write code.
You can have support and answers to specific questions.
Make an attempt to modify your code to work the way as described above.

Whenever you have specific questions. The questions will be answered

best regards Stefan

Hi Stefan,

When the game start, the laser is on and when the photo sensor is hit, I would like the laser to shut down (I don't find how to do it for now). So when the photo sensor is hit mean the laser pass over it and then it shut down.

Here is a picture of my sensor :

And here is the algo of my game :

Thank you @UKHeliBob

I didn't think that way and it seems more logic.

The thing is that with the Serial.Begin (9600) it shows every variations of the photo sensor. And it keep variating, so I put the if for when it change of luminosity but since there is like hundreds of value every second the score counter is out-numbered.

But I think the way @UKHeliBob show me might work.

Anyway I'll ask those questions at my school teacher to get some help.

Thank you Stefan & UKHeliBob

Hello astryal

Welcome to the world's best Arduino forum ever.

Copy, paste and test this part of your sketch:

void loop()
{
  static uint8_t interlock = LOW;
  int value = analogRead(0); // read the value on the pin A0 and store it in an integer variable

  tm1637.display(3, NumTab[num]); // show the thousands digit on the leftmost segment
  if ((value > 100) and (interlock == LOW))
  {
    interlock = HIGH;
    num ++; // increase the num value of 1
  }
  if (value < 50) interlock = LOW;
}

Have a nice day and enjoy coding in C++.

Your diagram describes the functionality very good.

I suggest that you use a programming-technique that is called "state-machine"

The functionality has different so called "states"

state 0 target is moving and laser is switched on

  • check if shooting-trigger is pulled. if shooting-trigger is pulled change to state 1

state 1:
check if LDR-value is above / below threshold

  • if LDR-value is above threshold change to state 2
  • if LDR-value is NOT above threshold change to state 4

state 2: blink LEDS then change to state 3

state 3 increment counter by one change to state 4

state 4: wait some time to pass by

  • if time has passed by change to state 0

Oh I forgot something. But with a state-machine this is no problem at all
we add a state 5

state 5 switch off laser, stop target-moving, manage high-score wait for hitting button "start game"

  • if start-button is hit. start timer change to state 0

outside the code of the state-machine you check if playing-time is over
when playing-time is really over change to state 5

I have written a tutorial about state-machines which you can read here.
If you have any questions about this demo-code then ask them.
This is what this forum is for

best regards Stefan

Thank you @paulpaulson & @StefanL38
I'll go check and test those things and I'll update you when it will work.

1 Like

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