Guest User

Untitled

a guest
Nov 18th, 2018
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.02 KB | None | 0 0
  1. /*
  2. * DartCounter
  3. *
  4. * Created on: Nov 18, 2018
  5. * Author: vishnujs
  6. * vijasu@gmail.com
  7. */
  8. #include "LowPower.h"
  9.  
  10. #define ON 1
  11. #define OFF 0
  12. #define DEBOUNCE_TIME 100 // 100ms
  13. #define IDLE_TIMEOUT 60000 // 1 min
  14.  
  15. #define COUNTER_INPUT 2
  16. #define BTN_RESET 3
  17. #define BTN_SET_MAG A4
  18. // A B C D E F G A B C D E F G
  19. volatile int SevenSegPins[2][7]={{10,11,12,13,A0,9,8},{6,7,A1,A2,A3,5,4}};
  20. volatile int counter;
  21. volatile unsigned long last_interrupt;
  22. volatile int display_state;
  23. volatile int mag_size;
  24.  
  25. /*
  26. * Since the Seven segment display is wired directly, use the following table for displaying numbers
  27. * +-A-+
  28. * F B
  29. * +-G-+
  30. * E C
  31. * +-D-+
  32. */
  33. int digits[10][7] = {//A,B,C,D,E,F,G
  34. {0,0,0,0,0,0,1}, // 0
  35. {1,0,0,1,1,1,1}, // 1
  36. {0,0,1,0,0,1,0}, // 2
  37. {0,0,0,0,1,1,0}, // 3
  38. {1,0,0,1,1,0,0}, // 4
  39. {0,1,0,0,1,0,0}, // 5
  40. {0,1,0,0,0,0,0}, // 6
  41. {0,0,0,1,1,1,1}, // 7
  42. {0,0,0,0,0,0,0}, // 8
  43. {0,0,0,0,1,0,0} // 9
  44. };
  45.  
  46. /*
  47. * Predifine MAG sizes here.
  48. */
  49. #define MAX_MAG_SIZES 4
  50. int mag_sizes[MAX_MAG_SIZES] = {6,10,12,18};
  51.  
  52. /*
  53. * Set a digit onto a seven segment display
  54. */
  55. void setDigit(int pinArray[7], int digit) {
  56. if (digit > 9) {
  57. return;
  58. }
  59. for(int i=0;i<7;i++) {
  60. digitalWrite(pinArray[i],digits[digit][i]);
  61. }
  62. }
  63.  
  64. /*
  65. * Set a number to the display
  66. */
  67. void setNumber(int num) {
  68. setDigit(SevenSegPins[0],num%10);
  69. setDigit(SevenSegPins[1],num/10);
  70. display_state = ON;
  71. }
  72.  
  73. /*
  74. * reset display to mag size
  75. */
  76. void resetCounter() {
  77. counter = mag_sizes[mag_size];
  78. setNumber(counter);
  79. }
  80.  
  81. /*
  82. * Timer 1 call back, timer1 is set to 1sec interval.
  83. * This is used to switch of the display and put the uC to deep sleep.
  84. * This helps in bringing down the power consumption from ~30mA to ~18mA.
  85. * Cannot bring it down further as the IR sensor, power LED and pin 13 LED will be on.
  86. * Power LED 3mA, pin 13 3mA, IR sensor with opAmp 12mA, uC in sleep takes only 0.3mA
  87. */
  88. ISR(TIMER1_COMPA_vect){//timer1 interrupt 1Hz
  89.  
  90. /*
  91. * Check if we have reached idle time.
  92. */
  93. if (((millis() - last_interrupt) > IDLE_TIMEOUT) && display_state != OFF) {
  94.  
  95. /*
  96. * Switch off the display
  97. */
  98. for(int i=0;i<2;i++) {
  99. for(int j=0;j<7;j++) {
  100. digitalWrite(SevenSegPins[i][j],1);
  101. }
  102. }
  103. display_state = OFF;
  104.  
  105. /*
  106. * Set uC to deep sleep for ever
  107. * It will wake up on interrupt.
  108. */
  109. LowPower.powerDown(SLEEP_FOREVER , ADC_OFF, BOD_OFF);
  110. }
  111. }
  112.  
  113. /*
  114. * handle pin change interrupt for A4 which is the set mag pin
  115. */
  116. ISR (PCINT1_vect) {
  117. unsigned long now = millis();
  118.  
  119. /*
  120. * SW Debounce
  121. */
  122. if (now - last_interrupt < DEBOUNCE_TIME) {
  123. return;
  124. }
  125.  
  126. /*
  127. * Tickle last interrupt
  128. */
  129. last_interrupt = now;
  130.  
  131. /*
  132. * Move Mag size to next and reset.
  133. */
  134. mag_size = (mag_size+1)% MAX_MAG_SIZES;
  135. resetCounter();
  136. }
  137.  
  138. ISR (PCINT2_vect) { // handle pin change interrupt for D2 which is the reset pin
  139. /*
  140. * Tickle last interrupt
  141. */
  142. last_interrupt = millis();
  143.  
  144. /*
  145. * Reset
  146. */
  147. resetCounter();
  148. }
  149.  
  150. void counterInterrupt() {
  151. /*
  152. * Tickle last interrupt
  153. */
  154. last_interrupt = millis();
  155.  
  156. /*
  157. * reduce counter,
  158. * If the counter is at 0 and we get an interrupt, that means the mag has been reloaded and a shot was fired.
  159. * if so, reset the counter and reduce 1
  160. */
  161. if (counter) {
  162. counter--;
  163. } else {
  164. counter = mag_sizes[mag_size] - 1;
  165. }
  166. setNumber(counter);
  167. }
  168.  
  169. /*
  170. * Enable pin change interrupt
  171. */
  172. void pciSetup(byte pin)
  173. {
  174. *digitalPinToPCMSK(pin) |= bit (digitalPinToPCMSKbit(pin)); // enable pin
  175. PCIFR |= bit (digitalPinToPCICRbit(pin)); // clear any outstanding interrupt
  176. PCICR |= bit (digitalPinToPCICRbit(pin)); // enable interrupt for the group
  177. }
  178.  
  179.  
  180. void setup() {
  181.  
  182. /*
  183. * set all seven segment display pins to output
  184. */
  185. for (int i=0;i<2;i++) {
  186. for(int j=0;j<7;j++){
  187. pinMode(SevenSegPins[i][j],OUTPUT);
  188. }
  189. }
  190.  
  191. /*
  192. * set counter input and button pins
  193. */
  194. pinMode(COUNTER_INPUT, INPUT);
  195. attachInterrupt(digitalPinToInterrupt(COUNTER_INPUT), counterInterrupt, FALLING);
  196.  
  197. pinMode(BTN_RESET, INPUT_PULLUP);
  198. pciSetup(BTN_RESET);
  199.  
  200. pinMode(BTN_SET_MAG, INPUT_PULLUP);
  201. pciSetup(BTN_SET_MAG);
  202.  
  203. /*
  204. * Set mag size to default
  205. */
  206. mag_size = 0;
  207. resetCounter();
  208.  
  209. //set timer1 interrupt at 1Hz
  210. TCCR1A = 0;// set entire TCCR1A register to 0
  211. TCCR1B = 0;// same for TCCR1B
  212. TCNT1 = 0;//initialize counter value to 0
  213. // set compare match register for 1hz increments
  214. OCR1A = 15624;// = (16*10^6) / (1*1024) - 1 (must be <65536)
  215. // turn on CTC mode
  216. TCCR1B |= (1 << WGM12);
  217. // Set CS10 and CS12 bits for 1024 prescaler
  218. TCCR1B |= (1 << CS12) | (1 << CS10);
  219. // enable timer compare interrupt
  220. TIMSK1 |= (1 << OCIE1A);
  221.  
  222. sei();//allow interrupts
  223.  
  224. }
  225.  
  226. void loop() {
  227. }
Add Comment
Please, Sign In to add comment