Advertisement
dlwestab

Ammo Counter v1.3.4

Jan 2nd, 2014
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.31 KB | None | 0 0
  1. /*
  2. Copyright 2013 Dustin L. Westaby
  3.  
  4. ----------------------------------------------------------------------
  5.         Decrement Counter for ATtiny2313
  6. ----------------------------------------------------------------------
  7. Title:      Ammo_Counter_1_2.c
  8. Author:     Dustin Westaby
  9. Date Created:   11/15/09
  10. Last Modified:  08/15/13
  11. Purpose:  Counter down program for two digit display. Firing modes
  12.           make for an ideal ammo counter.
  13.  
  14. Compiled with cloud based Clang Compiler on codebender.cc
  15.  
  16. Revisions List:
  17. 11/15/09  Initial program, Display pins configured, Count loops added
  18. 11/16/09  Firing modes added, Low Power loops added
  19. 11/17/09  SHOT1 & SHOT3 are now combined in BURST mode
  20. 12/01/09  Header comments added
  21. 12/09/09  Added device select for different Board Revisions
  22. 12/10/09  Split project folders, VMUSIC revision is now a seperate project
  23. 07/25/13  Re-wrote display subroutines to be more efficient - http://pastebin.com/7wjmQj6H
  24. 08/12/13  Converted to Arduino Compiler
  25. 09/01/13  Added FX extended timing code.
  26.  
  27. ATTiny2313 Pinouts [Arduino]
  28.  
  29.                 +----v---+
  30.     [17]   (RST)| 20   1 |(VCC)         [-]
  31.     [0]     PD0 | 19   2 | PB7 (SCL)    [16]
  32.     [1]     PD1 | 18   3 | PB6 (MISO)   [15]
  33.     [2]     PA1 | 17   4 | PB5 (MOSI)   [14]
  34.     [3]     PA0 | 16   5 | PB4          [13]
  35.     [4]     PD2 | 15   6 | PB3          [12]
  36.     [5]     PD3 | 14   7 | PB2          [11]
  37.     [6]     PD4 | 13   8 | PB1          [10]
  38.     [7]     PD5 | 12   9 | PB0          [9]
  39.     [-]    (GND)| 11   10| PD6          [8]
  40.                 +--------+
  41.                  17 Total
  42.  
  43. 7-Segment Display Layout
  44.  
  45.          1A            2A
  46.        ------        ------
  47.       |      |      |      |
  48.     1F|      |1B  2F|      |2B
  49.       |  1G  |      |  2G  |
  50.        ------        ------
  51.       |      |      |      |
  52.     1E|      |1C  2E|      |2C
  53.       |  1D  |      |  2D  |
  54.        ------  .     ------  .
  55.  
  56. Pinout Mapping
  57.  
  58. Arduino  Port   Bit  I/O  Signal Type      Name
  59. -------------------------------------------------
  60.    0     PORTD   0    O   Display Output   2C
  61.    1     PORTD   1    O   Display Output   2G
  62.    2     PORTA   1    O   Display Output   2D
  63.    3     PORTA   0    O   Display Output   2E
  64.    4     PORTD   2    O   Display Output   1C
  65.    5     PORTD   3    O   Display Output   1D
  66.    6     PORTD   4    O   Display Output   1E
  67.    7     PORTD   5    I   Switch Input     Fire
  68.    8     PORTD   6    O   Display Output   1F
  69.    9     PORTB   0    O   Display Output   1G
  70.    10    PORTB   1    O   Display Output   1A
  71.    11    PORTB   2    O   Display Output   1B
  72.    12    PORTB   3    I   Reserved         FX Output Pulse
  73.    13    PORTB   4    I   LED              Bottom LED
  74.    14    PORTB   5    O   Display Output   2F
  75.    15    PORTB   6    O   Display Output   2A
  76.    16    PORTB   7    O   Display Output   2B
  77.    17    (RST)   -    I   Switch Input     Reload
  78.  
  79.  Note: The FX output pulses with each decrement of the counter.  Intent is
  80.        to use this output to synchronize other circuits.
  81.  
  82. ----------------------------------------------------------------------
  83. */
  84.  
  85. //--------------------------------------
  86. //              Includes               |
  87. //--------------------------------------
  88. #include <EEPROM.h>
  89.  
  90. //--------------------------------------
  91. //         Globals & Constants         |
  92. //--------------------------------------
  93.  
  94. #define COUNT_DELAY_MS 60 /* Time between shots */
  95. #define FX_DELAY_MS 500     /* Time FX output */
  96.  
  97. /* Common Ground Display, HIGH is ON */
  98. #define ON  (HIGH)
  99. #define OFF (LOW)
  100.  
  101. #define CONT   (0)
  102. #define BURST  (1)
  103. #define NUMBER (2)
  104. #define TEXT   (3)
  105.  
  106. #define MODE1 (1)
  107. #define MODE2 (2)
  108. #define MODE3 (3)
  109. #define MODE4 (4)
  110. #define MODE5 (5)
  111.  
  112. #define MODE_ADDRESS 46
  113. #define MIN_MODE (MODE1)
  114. #define MAX_MODE (MODE5)
  115.  
  116. volatile int current_mode    = MODE1;
  117. int Fire_Signal_Pin = 7;
  118. int LED_Bottom_Pin  = 13;
  119. int FX_Pin          = 12;
  120.  
  121. /* Look Up Tables */
  122. byte pinMap_digit1[7] = {
  123.    10,   // 1A
  124.    11,   // 1B
  125.    4,    // 1C
  126.    5,    // 1D
  127.    6,    // 1E
  128.    8,    // 1F
  129.    9,    // 1G
  130. };
  131. byte pinMap_digit2[7] = {
  132.    15,   // 2A
  133.    16,   // 2B
  134.    0,    // 2C
  135.    2,    // 2D
  136.    3,    // 2E
  137.    14,   // 2F
  138.    1     // 2G
  139. };
  140.  
  141. //--------------------------------------
  142. //              Functions              |
  143. //--------------------------------------
  144.  
  145. void setup()
  146. {
  147.    int segment;
  148.    
  149.    /* Set Pin Directions */
  150.    for (segment = 0; segment < 7; segment++)
  151.    {
  152.       pinMode( pinMap_digit1[segment], OUTPUT);
  153.       pinMode( pinMap_digit2[segment], OUTPUT);
  154.    }
  155.  
  156.    pinMode(Fire_Signal_Pin, INPUT);
  157.    pinMode(LED_Bottom_Pin, OUTPUT);
  158.    pinMode(FX_Pin, OUTPUT);
  159.  
  160.    /* Verify read EEPROM value is within mode range */
  161.    eeprom_verify();
  162.    
  163. }
  164.  
  165. void loop()
  166. {
  167.    /* Variables */
  168.    int shotmode = CONT;
  169.    int countup = 0;
  170.    int burst_value = 1;
  171.    int continuous_bust = OFF;
  172.    int counter_value = 32;
  173.    
  174.    long startFXmillis = 0;
  175.    long currentFXmillis = millis();
  176.  
  177.    /* ====================================
  178.                  Starting Values
  179.       ==================================== */
  180.  
  181.    if (current_mode == MODE1)
  182.    {
  183.      shotmode = CONT;
  184.      burst_value = 1;
  185.      counter_value = 32;
  186.    }
  187.    else if (current_mode == MODE2)
  188.    {
  189.      shotmode = BURST;
  190.      burst_value = 3;
  191.      counter_value = 36;
  192.    }
  193.    else if (current_mode == MODE3)
  194.    {
  195.      shotmode = BURST;
  196.      burst_value = 3;
  197.      counter_value = 36;
  198.      continuous_bust = ON;
  199.    }
  200.    else if (current_mode == MODE4)
  201.    {
  202.      shotmode = BURST;
  203.      burst_value = 1;
  204.      counter_value = 12;
  205.    }
  206.    else /* MODE5 */
  207.    {
  208.      shotmode = BURST;
  209.      burst_value = 1;
  210.      counter_value = 15;
  211.    }
  212.  
  213.    /* ====================================
  214.                Startup Animation
  215.       ==================================== */
  216.  
  217.    /* Display Animation */
  218.    for( int i = 0; i < counter_value; i++) {
  219.       display_num( NUMBER, i, OFF, ON );
  220.       delay(500 / counter_value);
  221.    }
  222.    display_num( NUMBER, counter_value, ON, ON );
  223.  
  224.    /* ====================================
  225.                 Program Run
  226.       ==================================== */
  227.  
  228.    while(counter_value > 0)
  229.    {
  230.       /* Wait for Button Press */
  231.       while (fire_button_is_pressed())
  232.       {
  233.         /* Check FX timing */
  234.         currentFXmillis = millis();
  235.         if(currentFXmillis - startFXmillis > FX_DELAY_MS)
  236.         {
  237.             /* Turn off FX */
  238.             display_num( NUMBER, counter_value, ON, ON );
  239.         }
  240.       } /*end while not button press */
  241.  
  242.       /* Save timing for FX */
  243.       startFXmillis = millis();
  244.    
  245.       /* Decrement hit count */
  246.       if (burst_value > 1)
  247.       {
  248.         for( int i = 1; i <= burst_value; i++)
  249.         {
  250.           display_num( NUMBER, --counter_value, ON, OFF );
  251.           delay(COUNT_DELAY_MS);
  252.          
  253.         }
  254.       }
  255.       else
  256.       {
  257.         /* Update display and send flash to FX */
  258.         counter_value--;
  259.         display_num( NUMBER, counter_value, ON, OFF );
  260.       }
  261.  
  262.       /* Delay before next shot allowed */
  263.       if( shotmode == CONT )
  264.       {
  265.          /* Delay between full auto shots */
  266.          delay(COUNT_DELAY_MS);
  267.       }
  268.       else if (continuous_bust == OFF)
  269.       {
  270.         /* Wait for Button Release */
  271.         while ( !fire_button_is_pressed() )
  272.         {
  273.             /* Check FX timing */
  274.             currentFXmillis = millis();
  275.             if(currentFXmillis - startFXmillis > FX_DELAY_MS)
  276.             {
  277.                 /* Turn off FX */
  278.                 display_num( NUMBER, counter_value, ON, ON );
  279.             }
  280.         } /*end while still button pressed */
  281.       }
  282.    } /* end main program */
  283.  
  284.    /* ====================================
  285.                  Program End
  286.       ==================================== */
  287.  
  288.    /* One last display update, ensure zeros */
  289.    display_num( NUMBER, 0x00, OFF, ON );
  290.    delay(2000);
  291.  
  292.    while(1);
  293. }
  294.  
  295. //--------------------------------------
  296. //          EEPROM Subroutines         |
  297. //--------------------------------------
  298. void eeprom_verify()
  299. {
  300.    /* Variables */
  301.    int eeprom_byte_read = EEPROM.read(MODE_ADDRESS);
  302.  
  303.    /* Reset mode in EEPROM if unknown */
  304.    if ( !( ( eeprom_byte_read >= MIN_MODE ) && ( eeprom_byte_read <= MAX_MODE ) ) )
  305.    {
  306.       EEPROM.write ( MODE_ADDRESS, MIN_MODE );
  307.    }
  308.  
  309.    /* Read last mode saved */
  310.    int last_mode = EEPROM.read(MODE_ADDRESS);
  311.    current_mode = last_mode; //mode stays the same unless modified by user input
  312.  
  313.    /* Check for fire button held during reset */
  314.    if (!fire_button_is_pressed())
  315.    {
  316.       /* User wants to change modes */
  317.       last_mode++;
  318.       if (last_mode > MAX_MODE)  //MAX Mode Check
  319.       {
  320.          /* Wrap back to MODE 1 */
  321.          last_mode = MIN_MODE;
  322.       }
  323.  
  324.       /* Save mode setting for next reset */
  325.       EEPROM.write (MODE_ADDRESS, last_mode);
  326.  
  327.       /* Set current mode */
  328.       current_mode = last_mode;
  329.  
  330.       /* Output to user for new mode ACCEPTED, example:F1 = Fire Mode 1 */
  331.       display_num( TEXT, 0xF0 + (current_mode & 0x0F), OFF, ON );
  332.  
  333.       /* Wait for fire button to be released */
  334.       while (!fire_button_is_pressed());
  335.    }
  336.  
  337. }
  338.  
  339. //--------------------------------------
  340. //          Button Subroutines         |
  341. //--------------------------------------
  342. int fire_button_is_pressed()
  343. {
  344.    /* Check if Button was Pressed for at least 1ms */
  345.    if (digitalRead(Fire_Signal_Pin))
  346.    {
  347.       delay(1);
  348.       if (digitalRead(Fire_Signal_Pin))
  349.       {
  350.          return true;
  351.       }
  352.    }
  353.    return false;
  354. }
  355.  
  356. //--------------------------------------
  357. //           Math Subroutines          |
  358. //--------------------------------------
  359.  
  360. /* Author: robtillaart */
  361. int dec2bcd(int dec)
  362. {
  363.   return (dec/10)*16 + (dec%10);
  364. }
  365.  
  366. //--------------------------------------
  367. //         Display Subroutines         |
  368. //--------------------------------------
  369. void display_num(int type, int disp_output, int bottom_led, int fx_out)
  370. {
  371.    /* Look Up Table */
  372.    byte seg_array[16] =
  373.    {
  374.     //  Segments  Hex Number
  375.     //   GFEDCBA
  376.       0b00111111, // 0  126
  377.       0b00000110, // 1  6
  378.       0b01011011, // 2  91
  379.       0b01001111, // 3  79
  380.       0b01100110, // 4  102
  381.       0b01101101, // 5  109
  382.       0b01111101, // 6  125
  383.       0b00000111, // 7  7
  384.       0b01111111, // 8  127
  385.       0b01100111, // 9  103
  386.       0b01110111, // A  119
  387.       0b01111100, // B  124
  388.       0b00111001, // C  57
  389.       0b01011110, // D  94
  390.       0b01111001, // E  121
  391.       0b01110110  // F  113
  392.       //0b01000000  // -  (This entry is impossible for BCD)
  393.    };
  394.  
  395.    /* Variables */
  396.    int segment;
  397.    int digit1;
  398.    int digit2;
  399.    
  400.    /* ====================================
  401.                  BCD Conversion
  402.       ==================================== */
  403.  
  404.    /* Decimal Numbers need to be in BCD form */
  405.    if( type == NUMBER )
  406.    {
  407.       disp_output = dec2bcd(disp_output);
  408.    }
  409.  
  410.    digit1 = (disp_output >> 4 ) & 0x0F;;
  411.    digit2 = disp_output & 0x0F;
  412.  
  413.    /* ====================================
  414.              Assemble Ouput Digits
  415.       ==================================== */
  416.  
  417.    for (int i = 0; i < 7; i = i + 1) {
  418.       digitalWrite( pinMap_digit1[i], (seg_array[digit1]>>i)&1);
  419.       digitalWrite( pinMap_digit2[i], (seg_array[digit2]>>i)&1);
  420.    }
  421.  
  422.    digitalWrite( FX_Pin, fx_out);             // FX Output [12]
  423.    digitalWrite( LED_Bottom_Pin, bottom_led); // Bottom LED output [13]
  424.  
  425. } /* End Display Num Function */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement