/* * Computer Switchboard * * Because interfacing with computers should be fun * and a keyboard is not enough. * * Let's turn a computer into an airplane (interface wise). * */ //todo: debounce, see neotimer //makes serial slower so it can be read #define DEBUGMODE 0 #include #include /* SevenSegmentLEDdisplay102a.ino * 2017-02-20 * Mel Lester Jr. * Simple example of using Shift Register with a * Single Digit Seven Segment LED Display */ // Globals const int dataPin = 4; // blue wire to 74HC595 pin 14 const int latchPin = 7; // green to 74HC595 pin 12 const int clockPin = 8; // yellow to 74HC595 pin 11 /* uncomment one of the following lines that describes your display * and comment out the line that does not describe your display */ const char common = 'a'; // common anode //const char common = 'c'; // common cathode bool decPt = true; // decimal point display flag //switch // digital pin 9 has a pushbutton attached to it. Give it a name: int pushButton = 9; //rotary // ----- // SimplePollRotator.ino - Example for the RotaryEncoder library. // This class is implemented for use with the Arduino environment. // Copyright (c) by Matthias Hertel, http://www.mathertel.de // This work is licensed under a BSD style license. See http://www.mathertel.de/License.aspx // More information on: http://www.mathertel.de/Arduino // ----- // 18.01.2014 created by Matthias Hertel // ----- // This example checks the state of the rotary encoder in the loop() function. // The current position is printed on output when changed. // Hardware setup: // Attach a rotary encoder with output pins to A2 and A3. // The common contact should be attached to ground. #include // Setup a RoraryEncoder for pins A2 and A3: //RotaryEncoder encoder(A2, A1); RotaryEncoder encoder(A1, A2); int difference = 0; uint8_t segdisp = 0; //Timer //http://maxembedded.com/2011/06/avr-timers-timer1/ // global variable to count the number of overflows volatile uint8_t tot_overflow; volatile uint8_t ClearTimer = 0; uint8_t buttonpressed = 0; // TIMER1 overflow interrupt service routine // called whenever TCNT1 overflows ISR(TIMER1_OVF_vect) { // keep a track of number of overflows tot_overflow++; //Serial.println("Timer works!1"); // check for number of overflows here itself // 61 overflows = 2 seconds delay (approx.) //EDIT: NO it's not in atmega328p nano. //if (tot_overflow >= 2) // NOTE: '>=' used instead of '==' if (tot_overflow >= 100) // NOTE: '>=' used instead of '==' { buttonpressed = 0; //PORTC ^= (1 << 0); // toggles the led // no timer reset required here as the timer // is reset every time it overflows if(DEBUGMODE){ Serial.println("Timer works!2"); } tot_overflow = 0; // reset overflow counter ClearTimer = 1; //clear interrupts / timer outside of interrupt delay(10); } } void setup() { // initialize I/O pins pinMode(dataPin, OUTPUT); pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); Serial.begin(9600); pinMode(pushButton, INPUT_PULLUP); timer1_init(); } void loop() { if (ClearTimer == 1){ cli(); if(DEBUGMODE){ Serial.println("Ready"); //this doesn't print correctly unless you remove ClearTimer to zero below. delay(50); } else{ //Serial.println("Ready"); //this doesn't print correctly unless you remove ClearTimer to zero below. delay(50); ClearTimer = 0; //comment this, and uncomment ready for debugging. } } //decPt = !decPt; // display decimal point every other pass through loop // generate characters to display for hexidecimal numbers 0 to F /* for (int i = 0; i <= 15; i++) { byte bits = myfnNumToBits(i) ; if (decPt) { bits = bits | B00000001; // add decimal point if needed } myfnUpdateDisplay(bits); // display alphanumeric digit delay(500); // pause for 1/2 second }*/ byte bits = myfnNumToBits(segdisp); if (decPt) { bits = bits | B00000001; // add decimal point if switch high } myfnUpdateDisplay(bits); //ROTARY static uint8_t pos = 0; encoder.tick(); uint8_t newPos = encoder.getPosition(); if (pos != newPos) { difference = pos - newPos; //Serial.print(newPos); //Serial.println(); //Serial.println(difference); pos = newPos; segdisp = (segdisp + difference); segdisp = segdisp & B00000111;//only give me the last three bits //if there is anything there, so and. //gives me 0-7 //Serial.println(segdisp); } //BUTTONS int resultb = 0; resultb = PINB; delay(100); if (resultb == 0 && buttonpressed == 0){ // turn on ~3 second delay, for debounce decPt = 1; buttonpressed = 1; Serial.print("User Pressed button: "); Serial.println(segdisp); delay(50); // delay to cheat interrupts stopping me. sei(); delay(100); } else{ decPt = 0; } // too fast, print serial when checking switch only // Serial.println(resultb,BIN); // noisy, but reads 0 when low. } void myfnUpdateDisplay(byte eightBits) { if (common == 'a') { // using a common anonde display? eightBits = eightBits ^ B11111111; // then flip all bits using XOR } digitalWrite(latchPin, LOW); // prepare shift register for data shiftOut(dataPin, clockPin, LSBFIRST, eightBits); // send data digitalWrite(latchPin, HIGH); // update display } byte myfnNumToBits(int someNumber) { switch (someNumber) { case 0: return B11111100; break; case 1: return B01100000; break; case 2: return B11011010; break; case 3: return B11110010; break; case 4: return B01100110; break; case 5: return B10110110; break; case 6: return B10111110; break; case 7: return B11100000; break; case 8: return B11111110; break; case 9: return B11110110; break; case 10: return B11101110; // Hexidecimal A break; case 11: return B00111110; // Hexidecimal B break; case 12: return B10011100; // Hexidecimal C or use for Centigrade break; case 13: return B01111010; // Hexidecimal D break; case 14: return B10011110; // Hexidecimal E break; case 15: return B10001110; // Hexidecimal F or use for Fahrenheit break; default: return B10010010; // Error condition, displays three vertical bars break; } } // initialize timer, interrupt and variable void timer1_init() { // set up timer with prescaler TCCR1B |= (1 << CS10); TCCR1B |= (1 << CS11); // initialize counter TCNT1 = 0; // enable overflow interrupt // TIMSK |= (1 << TOIE1); //doesn't work, not in atmega328p // but data sheet has... // in section 12 (why the f, isn't there a table of contents in my data sheet?) TIMSK1 |= (1 << TOIE1); // enable global interrupts // I'll do this when a button pressed // sei(); // initialize overflow counter variable tot_overflow = 0; }