Detect a small object traveling in high speed using a Photomicrosensor

Hey everyone!
I'm making a sensor to detect the travel of airsoft BBs coming out of my airsoft rifle. I've found some great help on other threads on this forum already from others who have tried this in the past.
I'm doing this thing to learn more about electronics and coding.
But as I'm pretty shit at electronics I've gotten myself stuck.

I'm currently using a MEGA 2560 for the prototype but will switch to a Nano later.

So the project is to detect a BB traveling in 300-500+fps, and then count down from how many you set it to. The ammo count being visible on a screen.

But I'm currently stuck at detecting it when i shoot my rifle. I can detect the BBs just fine if i drop them through the sensor with my hand, but if i shoot them through the sensor with an airsoft rifle, they wont register.

Ok so for more specs.
Mega 2560
Photomicrosensor (Transmissive)

I've used the wiring setup from here

The code is a mesh from different posts that i adapted for myself.

const int PhotoIn = 2; //input pin for Photomicrosensor
const int LED = 13; //output pin for LED

volatile byte stateShotTaken = 0;

// Variables will change:
int shotsFired = 0; //a variable to write how many BBs have gone past

void setup()

attachInterrupt(0, photoGateTrigger, RISING );


void photoGateTrigger() {
  stateShotTaken = 1;
void loop() {

  if (stateShotTaken) {
      stateShotTaken = 0;
      Serial.print("number of shots taken: ");

As i said, this code works on slow objects, dropping a BB through it with my hand or sticking your finger in there and it counts up. But not when i shoot the BBs out of the airsoft rifle.

I'm stuck on if this is a software problem (shit coding) or a hardware problem.

The Photomicrosensor (Transmissive)
Should have a rising time of 4 μs. And from what i've seen on other posts, that should be enough.
I have contemplated about switching to a IR phototransistor and a IR LED. But isn't the photomicrosensor basically the same thing?

Is there anyone that could help me find what's wrong?

Have you calculated the approximate expected pulse time? i.e. the time the BB will actually be in sensor range?

From other posts i read, it should be about 40-60µs it takes for the BB to travel through the sensor.

... and how long does it take to execute 'loop()'?

I'm sorry, I'm not sure how to check that.

This doesn't look like the right syntax. Are you trying to use the interrupt input pin, or a digitalRead() of the pin? You shouldn't have both.

Oh, digitalRead that is from an old version before i had interrupt. I'm currently not using it, just forgot to remove that part form the code.

Can you please clean up the code and re-post? It's going to be time consuming guessing what is and isn't relevant code.

Ye sorry, I cleaned it up and edited the post.

Thanks! Just, next time repost instead of editing... I will be away for a while but others will chime in, I'm sure.

try FALLING instead of RISING in the interrupt.... the 10k pullup in combination with pin input capacitance means a rising edge is slower.

Thanks for the tip, will try it out.

Edit: It didn't work sadly.

What you are looking to build is a ballistic chronograph using an Arduino or any micro-controller. Normally two sensors are employed at a known spacing. The first sensor starts the count and the second stops the count. Velocity = Distance / Time. A Google of ballistic chronograph Arduino should get you more examples. The problem with a single sensor is you have a light and dark time so you only get a single pulse the duration of which is the dark time or the time the projectile (a BB) is blocking the emitter to the detector. While this will work I would not have high expectations of the uncertainty of the readings. This is why a good ballistic chronograph uses at least two sensors at a known distance (spacing).


Thanks, but I'm not looking to make a chronograph. I only want to see a passing BB and count it, not get its speed. And have a display like in a video game that shows the current ammo in the magazine.

But i will look take a look at how they have been made too, it might help. Thanks for the tip.

@fishythefish Just chipping in here, but it's not clear from reading your posts if you are getting any shots counted at all or only some shots counted.

I don't know much about BB guns, but can you get it to fire a single BB? If it counts a single BB, then can you can fire several BBs with about a second gap between them? Does that count correctly?

If it does count correctly, then that might indicate that you're losing count when firing several BBs quickly because of the time spent printing. The Arduino serial buffer can hold 32 (or is it 64?) characters. If you fill it up before it has a chance to empty, then I think it will block your code from running until there's space.

Another thing you can do is modify your interrupt handler to detect if stateShotTaken is a '1' before setting it to a '1'. If it is already a '1', then that means that your main loop hasn't had a chance to clear it and you're losing count.

Oh, sorry. Will edit it to make it clearer.
It can count slow going objects, like me putting a piece of paper infront of it.
But if a fast moving BB shot from an airsoft rifle at about 300 feet/s, it wont register it.

I've tried single shot, burst fire and full auto. It wont register any of it.

Ok, so if single shot isn't working, then that suggests the problem may be more to do with the electrical side of things rather than how your code is structured.

The fact that it can count slow moving objects suggests that the basics are working and it could be a response time problem, or maybe an alignment issue between the end of the BB gun barrel and the sensor. If there's an alignment issue, then it may be that the BB round isn't completely blocking the beam.

Another weird thought, do you have different coloured BB balls? Might be nothing to do with the issue but I wonder if the balls are sufficiently transparent at the wavelength used by the sensor? (Told you I knew little about BB stuff :laughing:)

Oh OK and my bad on the chronograph thing. That would be cool, a round count based on shots fired.


Hey no worries man, you still gave me something too look at.

I have it mounted on a 3D printed "holder" and have moved it around and dropped BBs by hand through it. So i don't think it is an alignment issue. But i agree that it probably is an electrical issue. That's what I'm the worst with XD

haha no worries. They are all the same color, White. I doubt it is a transparency issue, but that would be interesting. They are made of a biodegradable plastic, based on corn i think.

Unless I'm misreading it, the datasheet says over 100µs response time (rising or falling) at 10K load resistance. Note also the common emitter configuration. Is your sensor wired like this?