Props Working ammo counter based on atmega8 (schematics and source code)

Toby

Member
Okay, been a while. I made an ammo counter way back (waaay back) and promised to post source and schematics. Sorry, but I never did. So I'm here now to correct this, especially since the new forums is so new and shiny and different.

Development pictures: LED Displays, Glowing Display, Development Board and Development Board, Vid:

The schematics:
ammo.png


Notice that the LED segments are common anode, the Pads 1-4 are actually the fire and reload triggers respectively, LED is muzzle flash and DIP controls which rifle is selected in the firmware/software.

I'm cleaning up the source code as we speak. I may be able to help some people out with parts, but I'd be surprised if someone else hadn't filled this void (I know Goku/Gokussj5okazu was making kits, good man, but it's 2010 after all).

btw, how's everyone doing? comments and questions are - as always - very welcome.
 
Last edited by a moderator:
Wow, that is extremely helpful! I don't even work with those materials(that is more my fiance's department), but this diagram is very easy to understand just by looking at it. :) I know this will definitely help out alot of people.
 

Toby

Member
Cheers cortana, I started from zero for this project, so it's simple (i hope). It'd be cool if someone manages to build it.

I've just finished cleaning up and commenting the source code as much as I can. It compiles in avrstudio, but I haven't tested if it still works (it should though, I haven't changed it from the last flash). Some of the code is incredibly dodgy, meaning it works but there's probably a better way to do it. The hardware plans work 100% though.

This is extremely basic stuff, but enjoy anyway.

Code:
#include <avr/io.h>
#include <avr/interrupt.h>

#ifndef F_CPU
#define F_CPU	1000000
#endif

// fire key port
#define KEY_FIRE	(1 << PC2)

// reload key port
#define KEY_RELOAD	(1 << PC3)

#define KEYS		KEY_FIRE | KEY_RELOAD

// LED muzzle flash port
#define LED_MUZZLE	(1 << PB2)

// define PORTD bit mask for digits...
const uint8_t digits[] = {
	(0 << PD0) | (1 << PD1) | (1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5) | (1 << PD6) | (0 << PD7),
	(0 << PD0) | (0 << PD1) | (0 << PD2) | (1 << PD3) | (0 << PD4) | (0 << PD5) | (1 << PD6) | (0 << PD7),
	(1 << PD0) | (0 << PD1) | (1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5) | (0 << PD6) | (0 << PD7),
	(1 << PD0) | (0 << PD1) | (1 << PD2) | (1 << PD3) | (0 << PD4) | (1 << PD5) | (1 << PD6) | (0 << PD7),
	(1 << PD0) | (1 << PD1) | (0 << PD2) | (1 << PD3) | (0 << PD4) | (0 << PD5) | (1 << PD6) | (0 << PD7),
	(1 << PD0) | (1 << PD1) | (1 << PD2) | (0 << PD3) | (0 << PD4) | (1 << PD5) | (1 << PD6) | (0 << PD7),
	(1 << PD0) | (1 << PD1) | (1 << PD2) | (0 << PD3) | (1 << PD4) | (1 << PD5) | (1 << PD6) | (0 << PD7),
	(0 << PD0) | (0 << PD1) | (1 << PD2) | (1 << PD3) | (0 << PD4) | (0 << PD5) | (1 << PD6) | (0 << PD7),
	(1 << PD0) | (1 << PD1) | (1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5) | (1 << PD6) | (0 << PD7),
	(1 << PD0) | (1 << PD1) | (1 << PD2) | (1 << PD3) | (0 << PD4) | (1 << PD5) | (1 << PD6) | (0 << PD7)
};

// MA5B: 32, MA5C: 48, BR55: 48
#define DELAY 48

// MA5B: 60, MA5C: 32, BR55: 36
#define MAX_AMMO 32

// number of segments max
#define NUM_SEG 2


// current ammo in mag
volatile uint8_t ammo;

// current segment for multiplexing
volatile uint8_t segment;

// this is the multiplier for the different rifle types,
// the timer is set up the same for all, and the multiplier
// controls how fast the rifle fires
volatile uint8_t multi;


int main(void)
{
	DDRC	&= ~KEYS;
	DDRB	|= (1 << PB0) | (1 << PB2) | (1 << PB6) | (1 << PB7);	
	DDRD	|= 0xFF;

	PORTC	= KEYS;
	PORTB	= 0xFF;

	PORTB	&= ~LED_MUZZLE;

	ammo			= MAX_AMMO;
	segment			= 0;

	// multiplexer, debouncer
	TCCR0	= (1 << CS01); // prescaler 8
	TIMSK	= (1 << TOIE0);

	// interrupts are go
	sei();

	while (1)
	{
		asm volatile("nop" ::);
	}
}

ISR(TIMER0_OVF_vect)
{
	// multiplex off
	PORTB &= ~(1 << (PB3 + segment));

	// leds dark (~0x00)
	PORTD = 0xFF;
	
	// reload pressed?
	if (!(PINC & KEY_RELOAD))
	{
		ammo = MAX_AMMO;
	}

	// increment the multiplier
	multi++;

	// fire pressed?
	if (!(PINC & KEY_FIRE))
	{
		// we could fire again
		if (multi > DELAY)
		{
			// ammo left?
			if (ammo > 0)
			{
				// one less round
				ammo--;

				 // turn on flash LED
				PORTB |= LED_MUZZLE;
			}

			multi = 0; // reset
		}
		else
		{
			// turn of LED after 15 timer cycles
			// too fast and you can't see it
			// too slow and it's not a flash
			if (multi == 15)
			{
				PORTB &= ~LED_MUZZLE;
			}
		}
	}
	else
	{
		// fire not pressed, DODGY DEBOUNCE LOGIC (!!!)

		// if button released, but not yet indicated in the multiplier count
		if (multi < 100)
		{
			// add 100 to signalize release
			multi += 100;
		}

		// button was released more than 20 cycles ago
		if (multi > 120)
		{
			// set to 20 again, wait for fire trigger
			multi--;
		}
		else
		{
			// turn of LED after 15 timer cycles
			// too fast and you can't see it
			// too slow and it's not a flash
			if (multi == 115)
			{
				PORTB &= ~LED_MUZZLE;
			}
		}
	}

	// multiplex on
	segment++;

	// end of segment?
	if (segment >= NUM_SEG)
	{
		segment = 0;
	}

	uint8_t temp = ammo;

	// this is basically shifting the digit of the segment
	// to the first digit so we can read it
	for (int i = 0; i < segment; i++)
	{
		temp = temp / 10;
	}

	// get the bitmask for the segment digit
	PORTD = ~(digits[temp % 10]);

	// go for multiplexing
	PORTB |= (1 << (PB3 + segment));
}
I should probably say how the multiplier values are calculated, the atmega8 is running at 1MHz in my setup, the prescaler for the timer is set at 8, the timer counts from 0 to 255 before the overflow is triggered, and the multiplier value in the code is set to say 32 (MA5B), that's

MA5B = (1MHz) / (8 * 256 * 32) = 15.3 Hz or about 15 rounds per second/900 rounds per minute
MA5C = (1MHz) / (8 * 256 * 48) = 10.2 Hz or about 10.8 rounds per second/650 rounds per minute

the rest should be straightforward except for the wierd debounce logic, which I might rewrite. ask away if anything is unclear.
 

SchizophrenicMC

Well-Known Member
I've just finished cleaning up and commenting the source code as much as I can. It compiles in avrstudio, but I haven't tested if it still works (it should though, I haven't changed it from the last flash). Some of the code is incredibly dodgy, meaning it works but there's probably a better way to do it. The hardware plans work 100% though.


MA5B = (1MHz) / (8 * 256 * 32) = 15.3 Hz or about 15 rounds per second/900 rounds per minute
MA5C = (1MHz) / (8 * 256 * 48) = 10.2 Hz or about 10.8 rounds per second/650 rounds per minute

the rest should be straightforward except for the wierd debounce logic, which I might rewrite. ask away if anything is unclear.
Holy C, Batman! I barely caught any of that code, by experience. Of course, I only took a single year of Java, but you'd think the similarities would have made me understand some of that.

But, if your code works, and is elegant enough, go for it.

Looks cool, though I have seen smaller units around.
 

Toby

Member
Holy C, Batman! I barely caught any of that code, by experience. Of course, I only took a single year of Java, but you'd think the similarities would have made me understand some of that.

But, if your code works, and is elegant enough, go for it.

Looks cool, though I have seen smaller units around.
Lol, Java. Sorry, seriously though, microcontroller programming is a bit different, but I think the essentials are the same... (Java was originally made for different platforms including embedded stuff, but the Java VM is quite hefty, still, may mobile phones have JVMs).

About the size, it would be a lot smaller if it was made on it's own circuit board, but mine is assembled on a prototype board, which is for - you guessed it - prototyping. The biggest thing is the display. Of course, with all the details published, you could attempt to build it on an attiny which are smaller than the atmegas, the source code is not big, I just have a load of atmegas lying around.

Nice work can u help me with mine when i get to it
That really depends how much you know about electronics or microcontrollers and your commitment, it's not trivial, but that's what the 405th and armour building is about - learning new skills.
 

thatdecade

Well-Known Member
I do like your code because it is so different than my own counter code to accomplish the same task. Like how you are using a timer interrupt to setup each count.

I'd be surprised if someone else hadn't filled this void (I know Goku/Gokussj5okazu was making kits, good man, but it's 2010 after all).
Me! me, I do! lol, I also have goku's halo circuit project files if your interested in a copy. As far as I know, I am the only one selling circuit kits specifically for halo props. My kits use the smaller attiny2313v chip. So there is no options input. All the options are hardcoded in the software before I assemble the circuit.

Here is my schematic and a recent photo of one assembled. I love the AVR platform, it allows you to simplify the circuit design.

counter11.png


4516380907_99d57312d7_m.jpg

Edit:
About the size, it would be a lot smaller if it was made on it's own circuit board, but mine is assembled on a prototype board, which is for - you guessed it - prototyping.
I can also point you to an inexpensive pcb fab house. Takes about a month to receive, but are the cheapest and highest quality around.
 

Toby

Member
Sooo where can I buy this stuff?
Hmm, I hope you realise it's a bit out of line to ask to buy stuff in an weapons and props CREATION forum, that's reserved for classified. Also, I probably would never ship to the US. Luckily for you, the poster after you, thatdecade, sells very professional looking kits for very, very reasonable prices.

I do like your code because it is so different than my own counter code to accomplish the same task. Like how you are using a timer interrupt to setup each count.
thanks, yeah I thought I'd free up the main loop, turns out I didn't need to, but still super useful for debouncing and stuff. I like the concept of timers, because in assembly it's easier keeping time, but in c it's just one less thing to consider. btw, I've cleaned up the code a bit and might be posting it soon, depending on how much time I find.

Me! me, I do! lol, I also have goku's halo circuit project files if your interested in a copy. As far as I know, I am the only one selling circuit kits specifically for halo props. My kits use the smaller attiny2313v chip. So there is no options input. All the options are hardcoded in the software before I assemble the circuit.
I would be interested in goku's files, although I doubt I'll be working on this any more. I'll pm you.

Yeah, the attiny makes more sense, as the atmega is way too big (physically and memory wise), but I have a stockpile and a working prototype board. Also, the price difference is negligible with the number of chips i buy. Luckily, AVR code is very portable, unlike those nasty PIC chips.

However, the attiny2313 should have enough pins for an option switch, after all, it only needs two input pins... 7 segment out (PD0-6) + 2 multiplex out (PA1+2) + 2 led out (PB0+1) + 1 fire in (PB2) + 1 reload in (PB3) + 2 option in (PB4-5) + 3 reset/vcc/gnd = 18, but the attiny has 20 pins (PB6+7)? I don't know enough about attinys to say...

Here is my schematic and a recent photo of one assembled. I love the AVR platform, it allows you to simplify the circuit design.
That looks like a great product! Cool stuff, and much cheaper than I could manufacture anything.

Yeah, especially for hobbyists the AVR plattform is godsent, it's unreal how well thought out and versatile it is. The only thing lacking is hardware USB support, really, but there's software USB I guess. RS232 is just too old...

I can also point you to an inexpensive pcb fab house. Takes about a month to receive, but are the cheapest and highest quality around.
I always love knowledge, but I'm in Europe (England and Germany back and forth), so US based services really aren't that useful, plus for small batches I would ask a favour from some uni contacts, probably (haven't built more of 2 of anything [yet]). I'm not planning on starting a business/making a profit, but you never know!


BTW, I'm currently working on a laser tag system, I think this would be great for halo weapons (and messing about in general). I've got IR transmission/receiving sorted, now I'm working on optics, gameplay and LCD screen. But yeah, I'll post here if/when I finish it, when uni kicks in I'll have no time left -.-
 

Toby

Member
yeah, but it's PIC based and the source code is nowhere to find, but I have taken inspiration from it. the sensor design and optics are top notch.

my transmission code is based on the RC5 protocol up till now, easier to implement than Sony or NEC imo, and player number will be programmable over remote controls, instead of an expensive PC based interface, although I might add some sort of I2C base station for programming player number and resetting health. it won't have as many options, I really only want a simple version for learning more about stuff. so no sound, only different players (no teams), same health, uniform weapons... I might even do away with different players, who knows.

really then, the milestag is great product, but I'm just here for the fun and learning. and AVR compatibility is always a plus.
 
Top