Advertisement
dlwestab

Ammo_Counter_for_Trinket

Dec 22nd, 2015
199
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. Copyright 2015 Dustin L. Westaby
  3.  
  4. ----------------------------------------------------------------------
  5.         Decrement Counter for Arduino Trinket Pro
  6. ----------------------------------------------------------------------
  7. Title:      Ammo_Counter_1_2.c
  8. Author:     Dustin Westaby
  9. Date Created:   11/15/09
  10. Last Modified:  12/23/15
  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 - http://pastebin.com/nezr1ZxJ
  25. 09/01/13  Added FX extended timing code. - http://pastebin.com/0TdL6d6q
  26. 12/22/15  Reworked for Trinket Pro
  27.  
  28. Trinket Pro Pinouts [Arduino]
  29.  
  30.                         USB
  31.                 +------+-vv-+------+
  32.    2C    D9     |o ~9  |    | BAT o| 3.3 - 5 volt battery pack
  33.                 |      |    |      |
  34.    2B   D10     |o ~10 ------ GND o| Ground (CC)
  35.                 |                  |
  36.    2A   D11     |o ~11        BUS o|
  37.                 |                  |
  38.  Fire   D12     |o 12        3.3V o|
  39.                 |                  |
  40.   LED   D13     |o 13           8 o| D8        2D
  41.                 |                  |
  42.                 |o Ar          ~6 o| D6        2E
  43.                 |                  |
  44.    2F   D14     |o A0          ~5 o| D5        1C
  45.                 |                  |
  46.    2G   D15     |o A1           4 o| D4        1D
  47.                 |                  |
  48.    1B   D16     |o A2          ~3 o| D3        1E
  49.                 |                  |
  50.    1A   D17     |o A3          TX o|
  51.                 |                  |
  52.    1F   D18     |o A4          RX o|
  53.                 |                  |
  54.    1G   D19     |o A5         RST o| Reload
  55.                 |                  |
  56.                 |  o  o  o  o  o   |
  57.                 +------------------+
  58.  
  59.  
  60. Dual Digit Display (7-Segment, common cathode)
  61.  
  62.      1  1  1  1  C  C  2  2  2
  63.      F  G  A  B  C  C  F  A  B
  64.    +---------------------------+
  65.    | o  o  o  o  o  o  o  o  o |
  66.    |     1A            2A      |
  67.    |   ------        ------    |
  68.    |  |      |      |      |   |
  69.    |1F|      |1B  2F|      |2B |
  70.    |  |  1G  |      |  2G  |   |
  71.    |   ------        ------    |
  72.    |  |      |      |      |   |
  73.    |1E|      |1C  2E|      |2C |
  74.    |  |  1D  |      |  2D  |   |
  75.    |   ------  .     ------  . |
  76.    | o  o  o  o  o  o  o  o  o |
  77.    +---------------------------+
  78.      1  1  1  D  2  2  2  2  D
  79.      E  D  C  P  E  D  G  C  P
  80.  
  81. Two Single Digit Displays (7-Segment, common cathode)
  82.  
  83.        1 1 C 1 1         2 2 C 2 2
  84.        G F C A B         G F C A B
  85.    +--------------+  +--------------+
  86.    |   o o o o o  |  |   o o o o o  |
  87.    |      1A      |  |      2A      |
  88.    |    ------    |  |    ------    |
  89.    |   |      |   |  |   |      |   |
  90.    | 1F|      |1B |  | 2F|      |2B |
  91.    |   |  1G  |   |  |   |  2G  |   |
  92.    |    ------    |  |    ------    |
  93.    |   |      |   |  |   |      |   |
  94.    | 1E|      |1C |  | 2E|      |2C |
  95.    |   |  1D  |   |  |   |  2D  |   |
  96.    |    ------  . |  |    ------  . |
  97.    |   o o o o o  |  |   o o o o o  |
  98.    +--------------+  +--------------+
  99.        1 1 C 1 D         2 2 C 2 D
  100.        E D C C P         E D C C P
  101.  
  102. Pinout Mapping
  103.  
  104. Arduino  Trinket  I/O   Signal Type       Name
  105. -------------------------------------------------
  106. 3         ~3      O     Display Output    Digit 1, Segment E
  107. 4          4      O     Display Output    Digit 1, Segment D
  108. 5         ~5      O     Display Output    Digit 1, Segment C
  109. 6         ~6      O     Display Output    Digit 2, Segment E
  110. 8          8      O     Display Output    Digit 2, Segment D
  111. 9         ~9      O     Display Output    Digit 2, Segment C
  112. 10        ~10     O     Display Output    Digit 2, Segment B
  113. 11        ~11     O     Display Output    Digit 2, Segment A
  114. 12         12     I     Switch Input      Fire Switch
  115. 13         13     I     LED Output        LED
  116. 14         A0     O     Display Output    Digit 2, Segment F
  117. 15         A1     O     Display Output    Digit 2, Segment G
  118. 16         A2     O     Display Output    Digit 1, Segment B
  119. 17         A3     O     Display Output    Digit 1, Segment A
  120. 18         A4     O     Display Output    Digit 1, Segment F
  121. 19         A5     O     Display Output    Digit 1, Segment G
  122. RST       RST     I     Switch Input      Reload Switch
  123.  
  124. ----------------------------------------------------------------------
  125. */
  126.  
  127. //--------------------------------------
  128. //              Includes               |
  129. //--------------------------------------
  130. #include <EEPROM.h>
  131.  
  132. //--------------------------------------
  133. //         Globals & Constants         |
  134. //--------------------------------------
  135.  
  136. #define COUNT_DELAY_MS 60 /* Time between shots */
  137. #define FX_DELAY_MS 500     /* Time FX output */
  138.  
  139. /* Common Ground Display, HIGH is ON */
  140. #define ON  (HIGH)
  141. #define OFF (LOW)
  142.  
  143. #define CONT   (0)
  144. #define BURST  (1)
  145. #define NUMBER (2)
  146. #define TEXT   (3)
  147.  
  148. #define MODE1 (1)
  149. #define MODE2 (2)
  150. #define MODE3 (3)
  151. #define MODE4 (4)
  152. #define MODE5 (5)
  153.  
  154. #define MODE_ADDRESS 46
  155. #define MIN_MODE (MODE1)
  156. #define MAX_MODE (MODE5)
  157.  
  158. volatile int current_mode    = MODE1;
  159.  
  160. //--------------------------------------
  161. //               Pinouts               |
  162. //--------------------------------------
  163.  
  164. int Fire_Signal_Pin = 12;
  165. int LED_Bottom_Pin  = 13;
  166.  
  167. //Digit 1
  168. byte pinMap_digit1[7] =
  169. {
  170.     17,   // 1A
  171.     16,   // 1B
  172.     5,    // 1C
  173.     4,    // 1D
  174.     3,    // 1E
  175.     18,   // 1F
  176.     19,   // 1G
  177. };
  178.  
  179. //Digit 2
  180. byte pinMap_digit2[7] =
  181. {
  182.     11,   // 2A
  183.     12,   // 2B
  184.     9,    // 2C
  185.     8,    // 2D
  186.     6,    // 2E
  187.     14,   // 2F
  188.     15    // 2G
  189. };
  190.  
  191. //--------------------------------------
  192. //              Functions              |
  193. //--------------------------------------
  194.  
  195. void setup()
  196. {
  197.     int segment;
  198.  
  199.     /* Set Pin Directions */
  200.     for (segment = 0; segment < 7; segment++)
  201.     {
  202.         pinMode( pinMap_digit1[segment], OUTPUT);
  203.         pinMode( pinMap_digit2[segment], OUTPUT);
  204.     }
  205.  
  206.     pinMode(Fire_Signal_Pin, INPUT);
  207.     pinMode(LED_Bottom_Pin, OUTPUT);
  208.  
  209.     /* Verify read EEPROM value is within mode range
  210.        Check for fire button held down (enter mode selection) */
  211.     eeprom_verify();
  212.  
  213. }
  214.  
  215. void loop()
  216. {
  217.     /* Variables */
  218.     int shotmode = CONT;
  219.     int countup = 0;
  220.     int burst_value = 1;
  221.     int continuous_bust = OFF;
  222.     int counter_value = 32;
  223.  
  224.     long startFXmillis = 0;
  225.     long currentFXmillis = millis();
  226.  
  227.     /* ====================================
  228.                   Starting Values
  229.        ==================================== */
  230.  
  231.     if (current_mode == MODE1)
  232.     {
  233.         shotmode = CONT;
  234.         burst_value = 1;
  235.         counter_value = 32;
  236.     }
  237.     else if (current_mode == MODE2)
  238.     {
  239.         shotmode = BURST;
  240.         burst_value = 3;
  241.         counter_value = 36;
  242.     }
  243.     else if (current_mode == MODE3)
  244.     {
  245.         shotmode = BURST;
  246.         burst_value = 3;
  247.         counter_value = 36;
  248.         continuous_bust = ON;
  249.     }
  250.     else if (current_mode == MODE4)
  251.     {
  252.         shotmode = BURST;
  253.         burst_value = 1;
  254.         counter_value = 12;
  255.     }
  256.     else /* MODE5 */
  257.     {
  258.         shotmode = BURST;
  259.         burst_value = 1;
  260.         counter_value = 15;
  261.     }
  262.  
  263.     /* ====================================
  264.                 Startup Animation
  265.        ==================================== */
  266.  
  267.     /* Display Animation */
  268.     for( int i = 0; i < counter_value; i++)
  269.     {
  270.         display_num( NUMBER, i, OFF, ON );
  271.         delay(500 / counter_value);
  272.     }
  273.     display_num( NUMBER, counter_value, ON, ON );
  274.  
  275.     /* ====================================
  276.                  Program Run
  277.        ==================================== */
  278.  
  279.     while(counter_value > 0)
  280.     {
  281.         /* Wait for Button Press */
  282.         while (fire_button_is_pressed())
  283.         {
  284.             /* Check FX timing */
  285.             currentFXmillis = millis();
  286.             if(currentFXmillis - startFXmillis > FX_DELAY_MS)
  287.             {
  288.                 /* Turn off FX */
  289.                 display_num( NUMBER, counter_value, ON, ON );
  290.             }
  291.         } /*end while not button press */
  292.  
  293.         /* Save timing for FX */
  294.         startFXmillis = millis();
  295.  
  296.         /* Decrement hit count */
  297.         if (burst_value > 1)
  298.         {
  299.             for( int i = 1; i <= burst_value; i++)
  300.             {
  301.                 display_num( NUMBER, --counter_value, ON, OFF );
  302.                 delay(COUNT_DELAY_MS);
  303.  
  304.             }
  305.         }
  306.         else
  307.         {
  308.             /* Update display and send flash to FX */
  309.             counter_value--;
  310.             display_num( NUMBER, counter_value, ON, OFF );
  311.         }
  312.  
  313.         /* Delay before next shot allowed */
  314.         if( shotmode == CONT )
  315.         {
  316.             /* Delay between full auto shots */
  317.             delay(COUNT_DELAY_MS);
  318.         }
  319.         else if (continuous_bust == OFF)
  320.         {
  321.             /* Wait for Button Release */
  322.             while ( !fire_button_is_pressed() )
  323.             {
  324.                 /* Check FX timing */
  325.                 currentFXmillis = millis();
  326.                 if(currentFXmillis - startFXmillis > FX_DELAY_MS)
  327.                 {
  328.                     /* Turn off FX */
  329.                     display_num( NUMBER, counter_value, ON, ON );
  330.                 }
  331.             } /*end while still button pressed */
  332.         }
  333.     } /* end main program */
  334.  
  335.     /* ====================================
  336.                   Program End
  337.        ==================================== */
  338.  
  339.     /* One last display update, ensure zeros */
  340.     display_num( NUMBER, 0x00, OFF, ON );
  341.     delay(2000);
  342.  
  343.     while(1);
  344. }
  345.  
  346. //--------------------------------------
  347. //          EEPROM Subroutines         |
  348. //--------------------------------------
  349. void eeprom_verify()
  350. {
  351.     /* Variables */
  352.     int eeprom_byte_read = EEPROM.read(MODE_ADDRESS);
  353.  
  354.     /* Reset mode in EEPROM if unknown */
  355.     if ( !( ( eeprom_byte_read >= MIN_MODE ) && ( eeprom_byte_read <= MAX_MODE ) ) )
  356.     {
  357.         EEPROM.write ( MODE_ADDRESS, MIN_MODE );
  358.     }
  359.  
  360.     /* Read last mode saved */
  361.     int last_mode = EEPROM.read(MODE_ADDRESS);
  362.     current_mode = last_mode; //mode stays the same unless modified by user input
  363.  
  364.     /* Check for fire button held during reset */
  365.     if (!fire_button_is_pressed())
  366.     {
  367.         /* User wants to change modes */
  368.         last_mode++;
  369.         if (last_mode > MAX_MODE)  //MAX Mode Check
  370.         {
  371.             /* Wrap back to MODE 1 */
  372.             last_mode = MIN_MODE;
  373.         }
  374.  
  375.         /* Save mode setting for next reset */
  376.         EEPROM.write (MODE_ADDRESS, last_mode);
  377.  
  378.         /* Set current mode */
  379.         current_mode = last_mode;
  380.  
  381.         /* Output to user for new mode ACCEPTED, example:F1 = Fire Mode 1 */
  382.         display_num( TEXT, 0xF0 + (current_mode & 0x0F), OFF, ON );
  383.  
  384.         /* Wait for fire button to be released */
  385.         while (!fire_button_is_pressed());
  386.     }
  387.  
  388. }
  389.  
  390. //--------------------------------------
  391. //          Button Subroutines         |
  392. //--------------------------------------
  393. int fire_button_is_pressed()
  394. {
  395.     /* Check if Button was Pressed for at least 1ms */
  396.     if (digitalRead(Fire_Signal_Pin))
  397.     {
  398.         delay(1);
  399.         if (digitalRead(Fire_Signal_Pin))
  400.         {
  401.             return true;
  402.         }
  403.     }
  404.     return false;
  405. }
  406.  
  407. //--------------------------------------
  408. //           Math Subroutines          |
  409. //--------------------------------------
  410.  
  411. /* Author: robtillaart */
  412. int dec2bcd(int dec)
  413. {
  414.     return (dec / 10) * 16 + (dec % 10);
  415. }
  416.  
  417. //--------------------------------------
  418. //         Display Subroutines         |
  419. //--------------------------------------
  420. void display_num(int type, int disp_output, int bottom_led, int fx_out)
  421. {
  422.     /* Look Up Table */
  423.     byte seg_array[16] =
  424.     {
  425.         //  Segments  Hex Number
  426.         //   GFEDCBA
  427.         0b00111111, // 0  126
  428.         0b00000110, // 1  6
  429.         0b01011011, // 2  91
  430.         0b01001111, // 3  79
  431.         0b01100110, // 4  102
  432.         0b01101101, // 5  109
  433.         0b01111101, // 6  125
  434.         0b00000111, // 7  7
  435.         0b01111111, // 8  127
  436.         0b01100111, // 9  103
  437.         0b01110111, // A  119
  438.         0b01111100, // B  124
  439.         0b00111001, // C  57
  440.         0b01011110, // D  94
  441.         0b01111001, // E  121
  442.         0b01110110  // F  113
  443.         //0b01000000  // -  (This entry is impossible for BCD)
  444.     };
  445.  
  446.     /* Variables */
  447.     int segment;
  448.     int digit1;
  449.     int digit2;
  450.  
  451.     /* ====================================
  452.                   BCD Conversion
  453.        ==================================== */
  454.  
  455.     /* Decimal Numbers need to be in BCD form */
  456.     if( type == NUMBER )
  457.     {
  458.         disp_output = dec2bcd(disp_output);
  459.     }
  460.  
  461.     digit1 = (disp_output >> 4 ) & 0x0F;;
  462.     digit2 = disp_output & 0x0F;
  463.  
  464.     /* ====================================
  465.               Assemble Ouput Digits
  466.        ==================================== */
  467.  
  468.     for (int i = 0; i < 7; i = i + 1)
  469.     {
  470.         digitalWrite( pinMap_digit1[i], (seg_array[digit1] >> i) & 1);
  471.         digitalWrite( pinMap_digit2[i], (seg_array[digit2] >> i) & 1);
  472.     }
  473.  
  474.     digitalWrite( LED_Bottom_Pin, bottom_led); // Bottom LED output [13]
  475.  
  476. } /* End Display Num Function */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement