SIGN IN YOUR ACCOUNT TO HAVE ACCESS TO DIFFERENT FEATURES

FORGOT YOUR PASSWORD?

FORGOT YOUR DETAILS?

AAH, WAIT, I REMEMBER NOW!
  • LOGIN

ProtoSupplies

  • HOME
  • SHOP
    • Arduino, Teensy & IOT
    • Audio & Video
    • Breadboards & Supplies
    • Breakout Modules
    • Cables and Wires
    • Communications & Interfacing
    • Connectors & Headers
    • Displays, LEDs & Panel Meters
    • Fans & Hardware
    • ICs & Semiconductors
    • Passive Components
    • PCBs – Prototype & Adapter
    • Power Supplies & Converters
    • Proximity, Distance and Collision
    • Relays, MOSFETs & Power Ctrl
    • Robotics, Motors & Motion
    • Sensors
    • Supplies & Consumables
    • Switches & User Input
    • Temperature & Humidity
    • Test, Tools & Test Accessories
  • LEARN
  • TECH
    • Guide To Solderless Breadboards
    • Determining Unknown I2C Addresses
    • Determining LED Resistor Values
    • DC-DC Step-Down Converter Overview
    • s
  • BLOG
  • INFO
    • About Us
    • FAQ
    • My Account
    • Contact Us
  • Wishlist –
  • MY CART
    No products in cart.

Home » BLOG » Counter For Reloading Ammo

March 29, 2023

Counter For Reloading Ammo

Sunday, 27 January 2019 / Published in Projects

Counter For Reloading Ammo

Jeffs Ammo Counter

We recently had a customer, Jeff, looking for a way to count the amount of ammo produced by his reloading equipment.

The manufacturer of the reloader equipment offers a counter that uses a mechanical switch to increment the count when you pull down the handle of the reloader.  If the round doesn’t load properly, it will still count and the final count will be off.  His goal was to have something that would count the ammo as it fell into the bin after it was successfully ejected by the reloader.

Looking for a solution, and with mechanics as his strong suit, Jeff reached-out to us for electronics guidance.  I gave him a shopping list, and once purchased, I did the assembly and programming, since it was a fun and easy little project.  I figured I would share it on our blog in case anyone else finds it useful.  This basic setup is generic.  You can use it in a number of different applications or expand on it in a number of ways.

Project Definition:

  1. Keep the scope of the project small so it can be complete in about half a day.
  2. Use a sensor that will be easy to mount into the final application.
  3. Provide a display to show the count.
  4. Include some buttons to clear the count or manually adjust the count if needed.
  5. Provide an audible indicator as to identify a count, so there is no need to watch the display.
  6. Assemble it to ship as a complete unit that will work out of the box, only requiring power plug-in.

Component list

With our project definition complete, we were able to create the list of part requirements.

​

 $7.95 For a microcontroller, the Uno R3 SMD was selected as it is inexpensive and will support a shield board.

The picture shows the optional male headers installed, but we didn’t use them for this project.

Arduino Uno R3 SMD - With Headers Installed
$5.95 For a display and buttons, the LCD1602 16×2 Blue LCD with Keypad Shield was an easy choice since it not only provided the display we needed, but it also includes some built-in buttons that we could use for thinks like clearing the display.

Since it is a shield, it stacks neatly on top of the Uno board.

LCD1602 Blue Shield with Buttons
 $6.95 For the sensor to detect the ammo, the E18-D80NK Infrared Proximity Sensor Module was selected.

These are nice industrial grade sensors that incorporate both an IR transmitter and receiver in the end of it.  The sensor transmits an IR pulse at 490Hz and the receiver looks for it to bounce back off an object.

The sensor detection range is adjustable from a couple of inches to a couple of feet.

The round threaded-body and knurled-nuts allow for easy mounting through a round hole.  A long attached cable allows mounting of the sensor and display up to 45″ apart, though easily extendable if needed.

E18-D80NK Adjustable IR Proximity Sensor Module
 $1.49 The E18-D80NK Proximity Sensor Mounting Bracket was included to provide a possible mounting option, but was not used in the final install. E18-D80NK Mounting Bracket
 $0.75 For the audible feedback, we just went with a Passive Buzzer that we could send a tone to using PWM.  By using PWM, we could adjust the frequency of the tone.  Active buzzers tend to have an annoying note to them.

We did end up cobbling a transistor driver on the back of the module to increase the sound volume (a bit).

Buzzer Passive 5V
$4.95 For powering the setup, we used our AC Adapter 7.5V 1A wall bug.

These are really nice as the lower voltage puts less strain on the downstream 5V regulators.  In this application it didn’t really matter.

AC Adapter 7.5V 1A
 $1.49 Lastly, we decided to put everything on an Uno and Breadboard Acrylic Base.

With this, we’re able to prevent any shorting-out should placement be on a conductive surface.  This also allows the ability to drill for mounting and provides a handy spot for button labels.

Uno Acrylic Platform
Incidentals for the buzzer driver.  We used the same or similar parts out of our spare parts bins for this build.

2N3904 NPN Transistor
330 Ohm Resistor
10uF Capacitor

The Build

The actual build was very straightforward!  We were able to borrow much of the code from our examples for each of the parts we did use.  The little buzzer feature gave the most difficulty.  In hindsight, while writing this post, I realize that a small design error got by me.

E18-D80NK Sensor

Since this was a dedicated application, we did solder the sensor pig-tail cable directly to the Uno board.  We also added a strain relief using one of the mounting holes.  The blue wire is going to Ground, the brown wire to 5V and the black wire, which is the sensor output, connects to digital pin 2.  We chose Pin 2 because it has interrupt capability.

The E18-D80NK sensor output is normally HIGH and goes LOW when an object is detected.  It stays low as long as it detects the object, so the interrupt is setup to trigger on the falling edge of the waveform.

The back of the sensor has a small screw which adjusts a potentiometer that sets the detection distance.  Originally designed for counting objects moving on a conveyor belt, this feature is handy for adjustment to avoid seeing objects behind what you are targeting.  For our application, we set the detection distance to give the shortest range possible which was about 1.5-2″, as to not see the operator or mechanical parts of the machine in its field of view.

Jeffs Ammo Counter - Sensor Wiring

E18-D80NK Sensor Connections

Audible Buzzer

The buzzer sound output was too weak if driven directly off the Uno digital output.  Also, it can draw more current from the output pin than is safe.  The addition of a small driver circuit to the back of the buzzer was able to address both issues.

This driver consists of a small 2N3904 NPN transistor, 330 ohm current limiting resistor to protect the Uno pin and a 10uF filter capacitor.  None of these component values are critical.  The transistor can be any small NPN transistor, the resistor should work fine in the 330-1K range at least and the capacitor can be larger, but there is some space constraints.  I didn’t bother testing a smaller cap to see if it would work, but it might.

Due to physical mounting considerations, we decided to power the circuit off the VIN rather than the 5V, which was our original intent.  The power spike of the buzzer kicking-on caused an occasional power glitch, thus the addition of a filter capacitor at the buzzer to keep things happy.

In hind-sight, part of the problem was over-driving the buzzer with the increase of the operating voltage from 5V to over 7V.  I should have added a small value series resistor on the buzzer power leg to lower the maximum current and to reduce any power-on voltage spikes.

Ammo Counter Buzzer Schematic

Passive Buzzer Driver Circuit

We just soldered these extra components onto the backside of the module.

Using a couple of holes with solder pads, the buzzer module was soldered directly to the LCD shield board.  The module was soldered to the VIN and Ground points.  The 3rd pin, which is the signal input pin, was cut off and a blue wire routed through the hole and under the board to connect to the D3 pin on the other side of the shield.  D3 was selected because it has PWM capability.

Jeffs Ammo Counter - Buzzer FrontJeffs Ammo Counter - Buzzer Back

The buzzer is driven using the tone(pin, frequency, duration) command.  I finally settled on 200Hz for 300mSec as being a decent ‘Beep’ sound that wouldn’t drive me crazy too quickly.  I did add a pushbutton feature to turn the buzzer off – just in case it became annoying.

A bit on the loud side, for my taste, adding tape over the hole in the buzzer did dampen it to just about the right level.  Again, lowering the current through the device would have been the better solution for lowering the volume.

LCD, Keypad & Mounting

The LCD uses a 4-bit parallel data bus to automatically connect to the necessary Uno pins when the shield is installed.  Operation is fairly simple using the LiquidCrystal.h library.

The keys on the keypad connect to analog input A0 through the shield connections.

For those not familiar with this LCD w/ keypad, the keys are arranged in a voltage divider network using resistors, quite a novel technique.  The output is then fed to the A0 analog input on the Uno.  As you push the different buttons, the voltage divider, and therefore the output voltage, changes.  By measuring the voltage against approximate voltage ranges, you can determine a button push and which button is pushed. While more complicated than simply using a digital input for each button, it does free up digital inputs which might be helpful in some applications.

The shield occupies the following pins on the Arduino with the rest being available for other uses.  We use D2 for the sensor interrupt input and D3 for the buzzer output:

  • D4 = LCD DB4
  • D5 = LCD DB5
  • D6 = LCD DB6
  • D7 = LCD DB7
  • D8 = RS
  • D9 = LCD Enable
  • D10 = Backlight Control
  • A0 = Analog value of the button pushed

Some final touches; mounting the assembly on an acrylic Uno base in case it’s set on something conductive and to allow for drilling to mount on a wall.  And not to be forgotten, the creation and addition of the button graphic.  The graphic was created in MS Paint just to irritate my wife who does a lot of fancy graphics in Illustrator and thinks I am the only person left in the world crazy enough to still use MS Paint for some stuff.

Jeffs Ammo Counter Kit

Final Kit Assembled

Here is a little better view of the functionality of the buttons and the display layout.  Since there was an extra button, the ability to turn the backlight On & Off was added.  The far right button is tied to the Reset of the Uno, taking everything back to the power-on state.

Jeffs Ammo Counter - Buttons

Button Functionality

Below is the software created for this application.

Ammo Counter Application

/*
   Jeffs Ammo Counter Application

   Uses Uno, LCD shield and E18-D80NK  infrared module to implement a counter
   for ammo in a reloading station as it falls into a bucket.

   Note that there are some Serial.Println statements sprinked about. 
    These are simply for debugging purposes.
*/
#include <LiquidCrystal.h>

// Define the pins used by the LCD panel.  These are fixed by the shield.
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

const int BTN_RIGHT = 0;
const int BTN_UP = 1;
const int BTN_DOWN = 2;
const int BTN_LEFT = 3;
const int BTN_SELECT = 4;
const int BTN_NONE = 5;
const int BACKLIGHT_PIN = 10;
const int OFF = 0;
const int ON = 1;

int lcd_key = BTN_NONE;
int adc_key_in = 0;
int backlight_state = ON;
int tone_on = ON;

int TonePin = 3;               // Pin connected to Passive Buzzer
int Freq = 200;                // Frequency to play buzzer at

unsigned int counter = 0;    // Holds the current count
unsigned int old_count = 0;  // Holds last count displayed

//===============================================================================
//  Initialization
//===============================================================================
void setup() {
  pinMode(TonePin, OUTPUT);

  Serial.begin(9600);
  lcd.begin(16, 2);              // Initialize LCD for 16 character x 2 line
  lcd.setCursor(0, 0);           // Position cursor to 1st col, 1st line
  lcd.print("Jeff's Ammo Cntr"); // print a message on the 1st line
  lcd.setCursor(0, 1);          // Position cursor 1st col, 2nd line
  lcd.print("Count: ");         // Print 'Count'
  lcd.setCursor(15, 1);         // Position cursor 15th col, 2nd line
  lcd.print("B");               // Print 'B' as buzzer is ON by default
  lcd.setCursor(7, 1);          // Position cursor to the count location

  digitalWrite(BACKLIGHT_PIN, LOW); // We set this pin LOW just once then set
  // to input or output to turn the backlight on/off

  attachInterrupt(0, Do_Count, FALLING);  // Create interrupt handler to count
  // pulses on falling edge of Int0 as sensor goes LOW when object is detected
}
//===============================================================================
//  Main
//===============================================================================
void loop() {
  if (counter > old_count) {    // Check the counter variable to see if interrupt
    Update_Count();             // handler incremented it. If so update display
  }                                    
  lcd_key = Read_Buttons();    // read the buttons

  if (lcd_key != BTN_NONE) Do_Buttons();  // If a button is pressed, handle it
}

//===============================================================================
//  Subroutine - Increments the ammo counter when interrupt pin goes low
//===============================================================================
void Do_Count()
{
  counter++;  // increment the counter value
}

//===============================================================================
//  Subroutine - Updates the count on the display
//===============================================================================
void Update_Count()
{
  Serial.println (counter);
  lcd.setCursor(7, 1);
  lcd.print("      ");    // Clear current count space
  lcd.setCursor(7, 1);
  lcd.print(counter);     // Print new count
  old_count = counter;    // Set the old_count to our new count
  if (tone_on == ON) tone(TonePin, Freq, 300);  // If buzzer on, send tone
}

//===============================================================================
//  Read Buttons - Subroutine to read the ADC and return the button value
//===============================================================================
int Read_Buttons()
{
  adc_key_in = analogRead(0);      // read analog value from the button array
  // The buttons are connected to voltage divider that feeds into analog input A0
  // By looking at the voltage level, we can tell which button has been pressed
  // With no button pressed, the voltage will be pulled up to Vcc.
  if (adc_key_in >= 1000) return BTN_NONE; // Most likely result, so checked first
  if (adc_key_in < 50)   return BTN_RIGHT; // Work our way up the voltage ladder
  if (adc_key_in < 195)  return BTN_UP;    // And return first valid result found
  if (adc_key_in < 380)  return BTN_DOWN;
  if (adc_key_in < 555)  return BTN_LEFT;
  if (adc_key_in < 790)  return BTN_SELECT;

  return BTN_NONE;  // when all others fail, return this...
}

//===============================================================================
//  Do Buttons - Subroutine to act on the button pushes
//===============================================================================
int Do_Buttons()
/*
 * Note that we are using a delay(500) on the buttons to debounce them.  
 * Since the buttons probably aren't going to be pushed while also using the 
 * reloading machine, we don't expect this hard delay to cause any missed counts.
 */
{
  switch (lcd_key)           
  { 
    case BTN_RIGHT:   // Turns buzzer ON/OFF and sets a 'B' if it is ON
      {
        tone_on = (tone_on == ON) ? OFF : ON;
        Serial.println(tone_on);
        if (tone_on == ON) {
          lcd.setCursor(15, 1);
          lcd.print("B");
        }
        else {
          lcd.setCursor(15, 1);
          lcd.print(" ");
        }
        delay(500);     // Button debounce delay
        break;
      }
    case BTN_LEFT:      // Sets counter to zero
      {
        counter = 0;
        Update_Count();
        delay(500);     // Button debounce delay
        break;
      }
    case BTN_UP:        // Increments counter
      {
        counter++;
        Update_Count();
        delay(500);    // Button debounce delay
        break;
      }
    case BTN_DOWN:      // Decrements counter
      {
        if (counter > 0) {
          counter--;
          Update_Count();
          delay(500);    // Button debounce delay
        }
        break;
      }
    case BTN_SELECT:   // Toggles backlight ON / OFF
      {
        if (backlight_state == ON) {
          pinMode(BACKLIGHT_PIN, OUTPUT);
          backlight_state = OFF;
        }
        else if (backlight_state == OFF) {
          pinMode(BACKLIGHT_PIN, INPUT);
          backlight_state = ON;
        }
        delay(500);    // Button debounce delay
        break;         
      }
    case BTN_NONE:
      {
        break;
      }
  }
}

Installation and Lessons Learned

Once the setup was complete, a cardboard mock-up chute and 9mm ammo drops were our functional tests.  Everything worked perfectly in my simple test setup.

After shipment to the customer, he ran into a significant problem.  The system was getting multiple counts per round on an almost continual basis.  This of course defeats the whole purpose of the device.

Our customer took some pictures of the setup and I was able to locate a YouTube video of the same equipment in operation.  I noticed immediately how tight the space was where the sensor needs to go.  Specifically, how close to the sensor the handle and hand came while operating the machine.  My first assumption was the sensor field-of-view was too big and it was seeing things other than just the passing ammo.

After a couple of emails and phone calls and some general brainstorming, I came to a different conclusion.  The vigorous nature of the ejection of the ammo into the hard chute was causing the ammo to bounce aggressively.   Since the sensor connects to a very fast interrupt input on the Uno, the ammo was moving in and out of its detection beam several times as it came into view of the sensor resulting in multiple counts.Jeffs Ammo Counter - Chute Wedge

Fortunately Jeff has strong mechanical skills and was able to come up with a fix.   A wedge block inserted in the chute helped settle the ammo before exiting the chute where the sensor was located.  This is a picture of his prototype to verify the fix before building something more permanent.  This feature will need to be able to be changed-out depending on the size of the ammo being reloaded.

The mistake I made in my testing was that my non-slick cardboard chute and easy ammo drop-down did not represent the true nature of how the ammo was actually being ejected.  A more representative fixture would have caught this issue in my testing.

A possible design fix for the counter itself could be to add a bit of debouncing to the sensor interrupt counter routine.  This could work since the ammo won’t be coming down the chute faster than a couple of seconds apart.  Also, since this isn’t doing much other than waiting around for the sensor to be tripped and monitor the button status, the counting could probably be done using a polling scheme and debounced with something like a simple delay(500) statement to avoid multiple triggers on the same ammo.

Tagged under: Ammo Counter

What you can read next

Mega Breadboard with Mega 2560 Pro
Mega Breadboard

3 Comments to “ Counter For Reloading Ammo”

  1. Jeff says :Log in to Reply
    January 27, 2019 at 3:41 pm

    Great write up Ken. Thanks for your help. I will send you some pictures when I get it finalized.

  2. Brian says :Log in to Reply
    November 19, 2020 at 7:19 pm

    I’ve been working on adding in a delay, but have not been successful, as a noob, where should I be looking to slow the possible readings down to 1 a second?

  3. Ken Hahn says :Log in to Reply
    November 20, 2020 at 8:25 am

    Brian, it is a little tricky because the program is using interrupts to detect when an object is detected and then increments a counter. This happens even if a delay(); is being used in the main loop.

    If you just want to read the sensor only once every second, I would make the following basic changes:
    1. Remove the interrupt by deleting attachInterrupt(0, Do_Count, FALLING);
    2. Check if pin 2 which has the sensor attached is low in the main loop and if it is increment the counter. Something like
    if (digitalRead(2)==LOW) counter++;
    3. Delay program execution for 1 second by adding delay(1000); at bottom of the loop.

    Main loop would look something like this

    void loop() {
    if (digitalRead(2)==LOW) counter++;
    if (counter > old_count) { // Check the counter variable to see if interrupt
    Update_Count(); // handler incremented it. If so update display
    }
    lcd_key = Read_Buttons(); // read the buttons

    if (lcd_key != BTN_NONE) Do_Buttons(); // If a button is pressed, handle it
    delay(1000);
    }

You must be logged in to post a comment.

Categories

  • Internet Resources
  • New Products
  • Projects
  • Technology
  • Uncategorized

Recent Posts

  • Prototyping System for Teensy 4.1 Baseboard

    Prototyping System for Teensy 4.1 Now Available

    It’s hard not to love the Teensy 4.1 with its 6...
  • Teensy 4.1 Fully Loaded

    Teensy 4.1 Fully Loaded Products Available

    As we expand our Teensy product offerings, we n...
  • Shipping Cost Update – Part 2

    We continue to strive to keep our shipping rate...
  • Shipping Cost Update

    We strive to keep our shipping rates low and ma...
  • ProtoSupplies.com will not be shipping week of Oct 18th

    We are taking a short vacation the week of Oct ...

Recent Comments

  • Ken Hahn on Counter For Reloading Ammo
  • Brian on Counter For Reloading Ammo
  • EJ on The Problem with M&Ms
  • Anton on Inferior Counterfeit FOTEK SSR-25 Solid State Relays on the Market
  • Alex Bobotek on Inferior Counterfeit FOTEK SSR-25 Solid State Relays on the Market

Archives

  • May 2022
  • January 2022
  • October 2021
  • August 2021
  • September 2020
  • July 2019
  • June 2019
  • May 2019
  • January 2019
  • December 2018
  • March 2018
  • February 2018

Featured Posts

  • Prototyping System for Teensy 4.1 Baseboard

    Prototyping System for Teensy 4.1 Now Available

    0 comments
  • Teensy 4.1 Fully Loaded

    Teensy 4.1 Fully Loaded Products Available

    0 comments
  • Shipping Cost Update – Part 2

    0 comments
  • Shipping Cost Update

    0 comments
  • ProtoSupplies.com will not be shipping week of Oct 18th

    0 comments

Fine Print

  • Terms of Service
  • Shipping & Returns
credit-card-paypal-logos
RapidSSL_SEAL-90x50

GET IN TOUCH

Email: support@protosupplies.com

ProtoSupplies.com
Veteran Owned and Operated
Lake Stevens WA 98258, USA

  • Terms of Service
  • Shipping & Returns

© 2022 All rights reserved.

TOP