You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

322 lines
7.3 KiB

5 years ago
  1. /*
  2. * Computer Switchboard
  3. *
  4. * Because interfacing with computers should be fun
  5. * and a keyboard is not enough.
  6. *
  7. * Let's turn a computer into an airplane (interface wise).
  8. *
  9. */
  10. //todo: debounce, see neotimer
  11. //makes serial slower so it can be read
  12. #define DEBUGMODE 0
  13. #include <avr/io.h>
  14. #include <avr/interrupt.h>
  15. /* SevenSegmentLEDdisplay102a.ino
  16. * 2017-02-20
  17. * Mel Lester Jr.
  18. * Simple example of using Shift Register with a
  19. * Single Digit Seven Segment LED Display
  20. */
  21. // Globals
  22. const int dataPin = 4; // blue wire to 74HC595 pin 14
  23. const int latchPin = 7; // green to 74HC595 pin 12
  24. const int clockPin = 8; // yellow to 74HC595 pin 11
  25. /* uncomment one of the following lines that describes your display
  26. * and comment out the line that does not describe your display */
  27. const char common = 'a'; // common anode
  28. //const char common = 'c'; // common cathode
  29. bool decPt = true; // decimal point display flag
  30. //switch
  31. // digital pin 9 has a pushbutton attached to it. Give it a name:
  32. int pushButton = 9;
  33. //rotary
  34. // -----
  35. // SimplePollRotator.ino - Example for the RotaryEncoder library.
  36. // This class is implemented for use with the Arduino environment.
  37. // Copyright (c) by Matthias Hertel, http://www.mathertel.de
  38. // This work is licensed under a BSD style license. See http://www.mathertel.de/License.aspx
  39. // More information on: http://www.mathertel.de/Arduino
  40. // -----
  41. // 18.01.2014 created by Matthias Hertel
  42. // -----
  43. // This example checks the state of the rotary encoder in the loop() function.
  44. // The current position is printed on output when changed.
  45. // Hardware setup:
  46. // Attach a rotary encoder with output pins to A2 and A3.
  47. // The common contact should be attached to ground.
  48. #include <RotaryEncoder.h>
  49. // Setup a RoraryEncoder for pins A2 and A3:
  50. //RotaryEncoder encoder(A2, A1);
  51. RotaryEncoder encoder(A1, A2);
  52. int difference = 0;
  53. uint8_t segdisp = 0;
  54. //Timer
  55. //http://maxembedded.com/2011/06/avr-timers-timer1/
  56. // global variable to count the number of overflows
  57. volatile uint8_t tot_overflow;
  58. volatile uint8_t ClearTimer = 0;
  59. uint8_t buttonpressed = 0;
  60. // TIMER1 overflow interrupt service routine
  61. // called whenever TCNT1 overflows
  62. ISR(TIMER1_OVF_vect)
  63. {
  64. // keep a track of number of overflows
  65. tot_overflow++;
  66. //Serial.println("Timer works!1");
  67. // check for number of overflows here itself
  68. // 61 overflows = 2 seconds delay (approx.) //EDIT: NO it's not in atmega328p nano.
  69. //if (tot_overflow >= 2) // NOTE: '>=' used instead of '=='
  70. if (tot_overflow >= 100) // NOTE: '>=' used instead of '=='
  71. {
  72. buttonpressed = 0;
  73. //PORTC ^= (1 << 0); // toggles the led
  74. // no timer reset required here as the timer
  75. // is reset every time it overflows
  76. if(DEBUGMODE){
  77. Serial.println("Timer works!2");
  78. }
  79. tot_overflow = 0; // reset overflow counter
  80. ClearTimer = 1; //clear interrupts / timer outside of interrupt
  81. delay(10);
  82. }
  83. }
  84. void setup() {
  85. // initialize I/O pins
  86. pinMode(dataPin, OUTPUT);
  87. pinMode(latchPin, OUTPUT);
  88. pinMode(clockPin, OUTPUT);
  89. Serial.begin(9600);
  90. pinMode(pushButton, INPUT_PULLUP);
  91. timer1_init();
  92. }
  93. void loop() {
  94. if (ClearTimer == 1){
  95. cli();
  96. if(DEBUGMODE){
  97. Serial.println("Ready"); //this doesn't print correctly unless you remove ClearTimer to zero below.
  98. delay(50);
  99. }
  100. else{
  101. //Serial.println("Ready"); //this doesn't print correctly unless you remove ClearTimer to zero below.
  102. delay(50);
  103. ClearTimer = 0; //comment this, and uncomment ready for debugging.
  104. }
  105. }
  106. //decPt = !decPt; // display decimal point every other pass through loop
  107. // generate characters to display for hexidecimal numbers 0 to F
  108. /* for (int i = 0; i <= 15; i++) {
  109. byte bits = myfnNumToBits(i) ;
  110. if (decPt) {
  111. bits = bits | B00000001; // add decimal point if needed
  112. }
  113. myfnUpdateDisplay(bits); // display alphanumeric digit
  114. delay(500); // pause for 1/2 second
  115. }*/
  116. byte bits = myfnNumToBits(segdisp);
  117. if (decPt) {
  118. bits = bits | B00000001; // add decimal point if switch high
  119. }
  120. myfnUpdateDisplay(bits);
  121. //ROTARY
  122. static uint8_t pos = 0;
  123. encoder.tick();
  124. uint8_t newPos = encoder.getPosition();
  125. if (pos != newPos) {
  126. difference = pos - newPos;
  127. //Serial.print(newPos);
  128. //Serial.println();
  129. //Serial.println(difference);
  130. pos = newPos;
  131. segdisp = (segdisp + difference);
  132. segdisp = segdisp & B00000111;//only give me the last three bits
  133. //if there is anything there, so and.
  134. //gives me 0-7
  135. //Serial.println(segdisp);
  136. }
  137. //BUTTONS
  138. int resultb = 0;
  139. resultb = PINB;
  140. delay(100);
  141. if (resultb == 0 && buttonpressed == 0){
  142. // turn on ~3 second delay, for debounce
  143. decPt = 1;
  144. buttonpressed = 1;
  145. Serial.print("User Pressed button: ");
  146. Serial.println(segdisp);
  147. delay(50); // delay to cheat interrupts stopping me.
  148. sei();
  149. delay(100);
  150. }
  151. else{
  152. decPt = 0;
  153. }
  154. // too fast, print serial when checking switch only
  155. // Serial.println(resultb,BIN); // noisy, but reads 0 when low.
  156. }
  157. void myfnUpdateDisplay(byte eightBits) {
  158. if (common == 'a') { // using a common anonde display?
  159. eightBits = eightBits ^ B11111111; // then flip all bits using XOR
  160. }
  161. digitalWrite(latchPin, LOW); // prepare shift register for data
  162. shiftOut(dataPin, clockPin, LSBFIRST, eightBits); // send data
  163. digitalWrite(latchPin, HIGH); // update display
  164. }
  165. byte myfnNumToBits(int someNumber) {
  166. switch (someNumber) {
  167. case 0:
  168. return B11111100;
  169. break;
  170. case 1:
  171. return B01100000;
  172. break;
  173. case 2:
  174. return B11011010;
  175. break;
  176. case 3:
  177. return B11110010;
  178. break;
  179. case 4:
  180. return B01100110;
  181. break;
  182. case 5:
  183. return B10110110;
  184. break;
  185. case 6:
  186. return B10111110;
  187. break;
  188. case 7:
  189. return B11100000;
  190. break;
  191. case 8:
  192. return B11111110;
  193. break;
  194. case 9:
  195. return B11110110;
  196. break;
  197. case 10:
  198. return B11101110; // Hexidecimal A
  199. break;
  200. case 11:
  201. return B00111110; // Hexidecimal B
  202. break;
  203. case 12:
  204. return B10011100; // Hexidecimal C or use for Centigrade
  205. break;
  206. case 13:
  207. return B01111010; // Hexidecimal D
  208. break;
  209. case 14:
  210. return B10011110; // Hexidecimal E
  211. break;
  212. case 15:
  213. return B10001110; // Hexidecimal F or use for Fahrenheit
  214. break;
  215. default:
  216. return B10010010; // Error condition, displays three vertical bars
  217. break;
  218. }
  219. }
  220. // initialize timer, interrupt and variable
  221. void timer1_init()
  222. {
  223. // set up timer with prescaler
  224. TCCR1B |= (1 << CS10);
  225. TCCR1B |= (1 << CS11);
  226. // initialize counter
  227. TCNT1 = 0;
  228. // enable overflow interrupt
  229. // TIMSK |= (1 << TOIE1); //doesn't work, not in atmega328p
  230. // but data sheet has...
  231. // in section 12 (why the f, isn't there a table of contents in my data sheet?)
  232. TIMSK1 |= (1 << TOIE1);
  233. // enable global interrupts
  234. // I'll do this when a button pressed
  235. // sei();
  236. // initialize overflow counter variable
  237. tot_overflow = 0;
  238. }