Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Copyright 2013 Dustin L. Westaby
- ----------------------------------------------------------------------
- Decrement Counter for ATtiny2313
- ----------------------------------------------------------------------
- Title: Ammo_Counter_1_2.c
- Author: Dustin Westaby
- Date Created: 11/15/09
- Last Modified: 08/15/13
- Purpose: Counter down program for two digit display. Firing modes
- make for an ideal ammo counter.
- Compiled with cloud based Clang Compiler on codebender.cc
- Revisions List:
- 11/15/09 Initial program, Display pins configured, Count loops added
- 11/16/09 Firing modes added, Low Power loops added
- 11/17/09 SHOT1 & SHOT3 are now combined in BURST mode
- 12/01/09 Header comments added
- 12/09/09 Added device select for different Board Revisions
- 12/10/09 Split project folders, VMUSIC revision is now a seperate project
- 07/25/13 Re-wrote display subroutines to be more efficient - http://pastebin.com/7wjmQj6H
- 08/12/13 Converted to Arduino Compiler
- 09/01/13 Added FX extended timing code.
- ATTiny2313 Pinouts [Arduino]
- +----v---+
- [17] (RST)| 20 1 |(VCC) [-]
- [0] PD0 | 19 2 | PB7 (SCL) [16]
- [1] PD1 | 18 3 | PB6 (MISO) [15]
- [2] PA1 | 17 4 | PB5 (MOSI) [14]
- [3] PA0 | 16 5 | PB4 [13]
- [4] PD2 | 15 6 | PB3 [12]
- [5] PD3 | 14 7 | PB2 [11]
- [6] PD4 | 13 8 | PB1 [10]
- [7] PD5 | 12 9 | PB0 [9]
- [-] (GND)| 11 10| PD6 [8]
- +--------+
- 17 Total
- 7-Segment Display Layout
- 1A 2A
- ------ ------
- | | | |
- 1F| |1B 2F| |2B
- | 1G | | 2G |
- ------ ------
- | | | |
- 1E| |1C 2E| |2C
- | 1D | | 2D |
- ------ . ------ .
- Pinout Mapping
- Arduino Port Bit I/O Signal Type Name
- -------------------------------------------------
- 0 PORTD 0 O Display Output 2C
- 1 PORTD 1 O Display Output 2G
- 2 PORTA 1 O Display Output 2D
- 3 PORTA 0 O Display Output 2E
- 4 PORTD 2 O Display Output 1C
- 5 PORTD 3 O Display Output 1D
- 6 PORTD 4 O Display Output 1E
- 7 PORTD 5 I Switch Input Fire
- 8 PORTD 6 O Display Output 1F
- 9 PORTB 0 O Display Output 1G
- 10 PORTB 1 O Display Output 1A
- 11 PORTB 2 O Display Output 1B
- 12 PORTB 3 I Reserved FX Output Pulse
- 13 PORTB 4 I LED Bottom LED
- 14 PORTB 5 O Display Output 2F
- 15 PORTB 6 O Display Output 2A
- 16 PORTB 7 O Display Output 2B
- 17 (RST) - I Switch Input Reload
- Note: The FX output pulses with each decrement of the counter. Intent is
- to use this output to synchronize other circuits.
- ----------------------------------------------------------------------
- */
- //--------------------------------------
- // Includes |
- //--------------------------------------
- #include <EEPROM.h>
- //--------------------------------------
- // Globals & Constants |
- //--------------------------------------
- #define COUNT_DELAY_MS 60 /* Time between shots */
- #define FX_DELAY_MS 500 /* Time FX output */
- /* Common Ground Display, HIGH is ON */
- #define ON (HIGH)
- #define OFF (LOW)
- #define CONT (0)
- #define BURST (1)
- #define NUMBER (2)
- #define TEXT (3)
- #define MODE1 (1)
- #define MODE2 (2)
- #define MODE3 (3)
- #define MODE4 (4)
- #define MODE5 (5)
- #define MODE_ADDRESS 46
- #define MIN_MODE (MODE1)
- #define MAX_MODE (MODE5)
- volatile int current_mode = MODE1;
- int Fire_Signal_Pin = 7;
- int LED_Bottom_Pin = 13;
- int FX_Pin = 12;
- /* Look Up Tables */
- byte pinMap_digit1[7] = {
- 10, // 1A
- 11, // 1B
- 4, // 1C
- 5, // 1D
- 6, // 1E
- 8, // 1F
- 9, // 1G
- };
- byte pinMap_digit2[7] = {
- 15, // 2A
- 16, // 2B
- 0, // 2C
- 2, // 2D
- 3, // 2E
- 14, // 2F
- 1 // 2G
- };
- //--------------------------------------
- // Functions |
- //--------------------------------------
- void setup()
- {
- int segment;
- /* Set Pin Directions */
- for (segment = 0; segment < 7; segment++)
- {
- pinMode( pinMap_digit1[segment], OUTPUT);
- pinMode( pinMap_digit2[segment], OUTPUT);
- }
- pinMode(Fire_Signal_Pin, INPUT);
- pinMode(LED_Bottom_Pin, OUTPUT);
- pinMode(FX_Pin, OUTPUT);
- /* Verify read EEPROM value is within mode range */
- eeprom_verify();
- }
- void loop()
- {
- /* Variables */
- int shotmode = CONT;
- int countup = 0;
- int burst_value = 1;
- int continuous_bust = OFF;
- int counter_value = 32;
- long startFXmillis = 0;
- long currentFXmillis = millis();
- /* ====================================
- Starting Values
- ==================================== */
- if (current_mode == MODE1)
- {
- shotmode = CONT;
- burst_value = 1;
- counter_value = 32;
- }
- else if (current_mode == MODE2)
- {
- shotmode = BURST;
- burst_value = 3;
- counter_value = 36;
- }
- else if (current_mode == MODE3)
- {
- shotmode = BURST;
- burst_value = 3;
- counter_value = 36;
- continuous_bust = ON;
- }
- else if (current_mode == MODE4)
- {
- shotmode = BURST;
- burst_value = 1;
- counter_value = 12;
- }
- else /* MODE5 */
- {
- shotmode = BURST;
- burst_value = 1;
- counter_value = 15;
- }
- /* ====================================
- Startup Animation
- ==================================== */
- /* Display Animation */
- for( int i = 0; i < counter_value; i++) {
- display_num( NUMBER, i, OFF, ON );
- delay(500 / counter_value);
- }
- display_num( NUMBER, counter_value, ON, ON );
- /* ====================================
- Program Run
- ==================================== */
- while(counter_value > 0)
- {
- /* Wait for Button Press */
- while (fire_button_is_pressed())
- {
- /* Check FX timing */
- currentFXmillis = millis();
- if(currentFXmillis - startFXmillis > FX_DELAY_MS)
- {
- /* Turn off FX */
- display_num( NUMBER, counter_value, ON, ON );
- }
- } /*end while not button press */
- /* Save timing for FX */
- startFXmillis = millis();
- /* Decrement hit count */
- if (burst_value > 1)
- {
- for( int i = 1; i <= burst_value; i++)
- {
- display_num( NUMBER, --counter_value, ON, OFF );
- delay(COUNT_DELAY_MS);
- }
- }
- else
- {
- /* Update display and send flash to FX */
- counter_value--;
- display_num( NUMBER, counter_value, ON, OFF );
- }
- /* Delay before next shot allowed */
- if( shotmode == CONT )
- {
- /* Delay between full auto shots */
- delay(COUNT_DELAY_MS);
- }
- else if (continuous_bust == OFF)
- {
- /* Wait for Button Release */
- while ( !fire_button_is_pressed() )
- {
- /* Check FX timing */
- currentFXmillis = millis();
- if(currentFXmillis - startFXmillis > FX_DELAY_MS)
- {
- /* Turn off FX */
- display_num( NUMBER, counter_value, ON, ON );
- }
- } /*end while still button pressed */
- }
- } /* end main program */
- /* ====================================
- Program End
- ==================================== */
- /* One last display update, ensure zeros */
- display_num( NUMBER, 0x00, OFF, ON );
- delay(2000);
- while(1);
- }
- //--------------------------------------
- // EEPROM Subroutines |
- //--------------------------------------
- void eeprom_verify()
- {
- /* Variables */
- int eeprom_byte_read = EEPROM.read(MODE_ADDRESS);
- /* Reset mode in EEPROM if unknown */
- if ( !( ( eeprom_byte_read >= MIN_MODE ) && ( eeprom_byte_read <= MAX_MODE ) ) )
- {
- EEPROM.write ( MODE_ADDRESS, MIN_MODE );
- }
- /* Read last mode saved */
- int last_mode = EEPROM.read(MODE_ADDRESS);
- current_mode = last_mode; //mode stays the same unless modified by user input
- /* Check for fire button held during reset */
- if (!fire_button_is_pressed())
- {
- /* User wants to change modes */
- last_mode++;
- if (last_mode > MAX_MODE) //MAX Mode Check
- {
- /* Wrap back to MODE 1 */
- last_mode = MIN_MODE;
- }
- /* Save mode setting for next reset */
- EEPROM.write (MODE_ADDRESS, last_mode);
- /* Set current mode */
- current_mode = last_mode;
- /* Output to user for new mode ACCEPTED, example:F1 = Fire Mode 1 */
- display_num( TEXT, 0xF0 + (current_mode & 0x0F), OFF, ON );
- /* Wait for fire button to be released */
- while (!fire_button_is_pressed());
- }
- }
- //--------------------------------------
- // Button Subroutines |
- //--------------------------------------
- int fire_button_is_pressed()
- {
- /* Check if Button was Pressed for at least 1ms */
- if (digitalRead(Fire_Signal_Pin))
- {
- delay(1);
- if (digitalRead(Fire_Signal_Pin))
- {
- return true;
- }
- }
- return false;
- }
- //--------------------------------------
- // Math Subroutines |
- //--------------------------------------
- /* Author: robtillaart */
- int dec2bcd(int dec)
- {
- return (dec/10)*16 + (dec%10);
- }
- //--------------------------------------
- // Display Subroutines |
- //--------------------------------------
- void display_num(int type, int disp_output, int bottom_led, int fx_out)
- {
- /* Look Up Table */
- byte seg_array[16] =
- {
- // Segments Hex Number
- // GFEDCBA
- 0b00111111, // 0 126
- 0b00000110, // 1 6
- 0b01011011, // 2 91
- 0b01001111, // 3 79
- 0b01100110, // 4 102
- 0b01101101, // 5 109
- 0b01111101, // 6 125
- 0b00000111, // 7 7
- 0b01111111, // 8 127
- 0b01100111, // 9 103
- 0b01110111, // A 119
- 0b01111100, // B 124
- 0b00111001, // C 57
- 0b01011110, // D 94
- 0b01111001, // E 121
- 0b01110110 // F 113
- //0b01000000 // - (This entry is impossible for BCD)
- };
- /* Variables */
- int segment;
- int digit1;
- int digit2;
- /* ====================================
- BCD Conversion
- ==================================== */
- /* Decimal Numbers need to be in BCD form */
- if( type == NUMBER )
- {
- disp_output = dec2bcd(disp_output);
- }
- digit1 = (disp_output >> 4 ) & 0x0F;;
- digit2 = disp_output & 0x0F;
- /* ====================================
- Assemble Ouput Digits
- ==================================== */
- for (int i = 0; i < 7; i = i + 1) {
- digitalWrite( pinMap_digit1[i], (seg_array[digit1]>>i)&1);
- digitalWrite( pinMap_digit2[i], (seg_array[digit2]>>i)&1);
- }
- digitalWrite( FX_Pin, fx_out); // FX Output [12]
- digitalWrite( LED_Bottom_Pin, bottom_led); // Bottom LED output [13]
- } /* End Display Num Function */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement