From f2e601bc660d23ae52e7c231e485a46280adf551 Mon Sep 17 00:00:00 2001 From: Sean Date: Wed, 13 Apr 2022 21:09:44 -0400 Subject: [PATCH] added pin change interupt for chaninging animation state --- button.ino | 35 ++++++++++++++++++++++ charlieCube.ino | 11 ++++--- chaseTheDot.ino | 6 ---- config.h | 3 +- cubeplex.h | 43 +++++++------------------- rainbow_corner.ino | 75 ++++++++++++++++++++++++++++++++++++++++++++++ rainbow_random.ino | 2 +- timers.ino | 12 -------- 8 files changed, 131 insertions(+), 56 deletions(-) create mode 100644 button.ino create mode 100644 rainbow_corner.ino delete mode 100644 timers.ino diff --git a/button.ino b/button.ino new file mode 100644 index 0000000..7ba739b --- /dev/null +++ b/button.ino @@ -0,0 +1,35 @@ +#include + +void initButton() +{ + DDRC = 0x00; // all pins are inputs + PORTC = 0b00110000; // set PC4 & PC5 to INPUT_PULLUP + + cli(); + PCICR |= 0b00000010; // Enables Port C Pin Change Interrupts + PCMSK1 |= 0b00110000; // PCINT12 (pin 27) (PC4) + sei(); +} + +ISR(PCINT1_vect) +{ + static unsigned long lastInterruptTime_A4 = 0; + static unsigned long lastInterruptTime_A5 = 0; + + if(digitalRead(A4) == LOW){ + unsigned long interruptTime_A4 = millis(); + if(interruptTime_A4 - lastInterruptTime_A4 > 200) { + currentState = nextState(currentState); + animationTimer = 0; + } + lastInterruptTime_A4 = interruptTime_A4; + } + if(digitalRead(A5) == LOW){ + unsigned long interruptTime_A5 = millis(); + if(interruptTime_A5 - lastInterruptTime_A5 > 200) { + currentState = nextState(currentState); + animationTimer = 0; + } + lastInterruptTime_A5 = interruptTime_A5; + } +} diff --git a/charlieCube.ino b/charlieCube.ino index d6a3062..4011d86 100644 --- a/charlieCube.ino +++ b/charlieCube.ino @@ -1,8 +1,7 @@ -// WIP. 4/4/2022: started to implement delay timer asyncronously using existing timer2 interrupt. +// WIP. 4/13/2022: added pin change interrupt to handle changing animations #include "config.h" #include "cubeplex.h" -#include int color = red; @@ -10,7 +9,7 @@ void setup() { Serial.begin(115200); Serial.println("start program..."); initCube(); - //timerInit(); + initButton(); currentState = CHASETHEDOT; lastState = -1; @@ -27,10 +26,14 @@ void loop() { chaseTheDot(); break; - case RANDOMRAINBOW: + case RAINBOWRANDOM: rainbow_random(); break; + case RAINBOWCORNER: + rainbow_corner(); + break; + case PLANARFLOP3D: planarFlop3D(); break; diff --git a/chaseTheDot.ino b/chaseTheDot.ino index d05d5d3..dc1d19f 100644 --- a/chaseTheDot.ino +++ b/chaseTheDot.ino @@ -78,13 +78,7 @@ void chaseTheDot() { drawLed(color, xpos, ypos, zpos); flushBuffer(); clearBuffer(); - //delay(animationSpeed); - - //animationDelay.start(); - //animationDelayTiming = true; - //Serial.println("start timer"); - currentTimer = 0; timerReset = false; } } diff --git a/config.h b/config.h index 130f808..1e17c12 100644 --- a/config.h +++ b/config.h @@ -3,7 +3,8 @@ typedef enum STATE { CHASETHEDOT, - RANDOMRAINBOW, + RAINBOWRANDOM, + RAINBOWCORNER, PLANARFLOP3D }; diff --git a/cubeplex.h b/cubeplex.h index 0016500..d48218b 100644 --- a/cubeplex.h +++ b/cubeplex.h @@ -44,7 +44,7 @@ | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | POSSIBILITY OF SUCH DAMAGE. | \******************************************************************************/ - /*********** Modified by S. Dugre to work w/ my hardware***********************/ +/*********** Modified by S. Dugre to work w/ my hardware***********************/ #ifndef _CUBEPLEX_H_ #define _CUBEPLEX_H_ @@ -577,45 +577,24 @@ byte pinsD[] = {P1D, P2D, P3D, P4D, P5D, P6D, P7D, P8D, P9D, P10D, P11D, P12D, P #define FULL PWMMMAX #define HALF PWMMMAX/2 -// -// Idea courtesy Ganssle Group. Called from a 5ms timer, -// the debounced state only ever changes when the pin -// has been stable for 40ms. Initialize debounced_state -// to whatever is "inactive" for the system (HIGH or LOW) -// - -bool lastButtonState, buttonState = LOW; - -uint8_t DebouncePin(uint8_t pin) { - static uint8_t debounced_state = HIGH; - static uint8_t candidate_state = 0; - candidate_state = candidate_state << 1 | digitalRead(pin) & 0x07; - if (candidate_state == 0x07 ) - debounced_state = LOW; - else if (candidate_state == 0x00) - debounced_state = HIGH; - return debounced_state; -} int currentTimer = 0; int maxTimer = 6250; // 100ms delay / 16uS interrupt time -int nextState(int state) { return (state+1)%2; } +int nextState(int state) { + return (state + 1) % 2; +} // the interrupt function to display the leds (T2 = 8 bit timer) ISR(TIMER2_OVF_vect) { - if (not timerReset){ + if (not timerReset) { currentTimer++; - if (currentTimer >= maxTimer) { - timerReset = true; - currentTimer = 0; - } + if (currentTimer >= maxTimer) { + timerReset = true; + currentTimer = 0; + } } - if (DebouncePin(18)) { - currentState = nextState(currentState); - } - int pin1 = _cube_current_frame->pin1; int pin2 = _cube_current_frame->pin2; int count = (pin1 & 0xF0) | ((pin2 & 0xF0) >> 4); @@ -631,7 +610,7 @@ ISR(TIMER2_OVF_vect) { DDRD = pinsD[pin1] | pinsD[pin2]; PORTB = pinsB[pin1]; - PORTC = pinsC[pin1] | B00010000; // sets PC4 to INPUT_PULLUP + PORTC = pinsC[pin1] | B00110000; // sets PC4 & PC5 to INPUT_PULLUP for button PORTD = pinsD[pin1]; } @@ -642,7 +621,7 @@ ISR(TIMER2_OVF_vect) { } } - /**************************Applies to T2 (8 bit timer) only********************\ +/**************************Applies to T2 (8 bit timer) only********************\ | Some helpfull info for overflowing timers with different prescaler values | | 16000000 / ( 1*256) = 16000000 / 256 = 62500 Hz | | 16000000 / ( 8*256) = 16000000 / 2048 = ~7812 Hz | diff --git a/rainbow_corner.ino b/rainbow_corner.ino new file mode 100644 index 0000000..0343228 --- /dev/null +++ b/rainbow_corner.ino @@ -0,0 +1,75 @@ +/******************************* RAINBOW CORNER *******************************\ +| Found on the internet.... | +| | +| Modified By: S. Dugre to use asynchronous timer + + NOT WORKING GOOD. IT SCREWS UP ANIMATION PROGRESSION +\******************************************************************************/ + +byte spectrum2[24][3] = { + {8,0,0},{7,1,0},{6,2,0},{5,3,0},{4,4,0},{3,5,0},{2,6,0},{1,7,0}, + {0,8,0},{0,7,1},{0,6,2},{0,5,3},{0,4,4},{0,3,5},{0,2,6},{0,1,7}, + {0,0,8},{1,0,7},{2,0,6},{3,0,5},{4,0,4},{5,0,3},{6,0,2},{7,0,1}, +}; +byte offset = 0; +byte shift[3] = {0,0,0}; +bool mirror[3] = {false,false,false}; +byte anim[8] = {0,2,0,1,0,2,0,1}; + +void drawCube() { + for (byte x = 0; x <= 3; x++) { + for (byte y = 0; y <= 3; y++) { + for (byte z = 0; z <= 3; z++) { + byte xx = mirror[0] ? 3 - x : x; + byte yy = mirror[1] ? 3 - y : y; + byte zz = mirror[2] ? 3 - z : z; + xx = shift[0] > xx ? 0 : xx - shift[0]; + yy = shift[1] > yy ? 0 : yy - shift[1]; + zz = shift[2] > zz ? 0 : zz - shift[2]; + byte val = (offset + xx + yy + zz) % 24; + drawLed(red, spectrum2[val][0],x,y,z); + drawLed(green,spectrum2[val][1],x,y,z); + drawLed(blue, spectrum2[val][2],x,y,z); + } + } + } + flushBuffer(); + clearBuffer(); + offset = offset == 0 ? 23 : offset - 1; + //delay(75); + currentTimer = 0; +} + +void moveAxis(byte axis) { + for (int n = 1;n <= 3; n++) { + shift[axis] = n; + drawCube(); + } + mirror[axis] = not mirror[axis]; + drawCube(); + for (int n = 2;n >= 0; n--) { + shift[axis] = n; + drawCube(); + } +} + +void rainbow_corner() { + + if (currentState != lastState) { + + lastState = currentState; + Serial.print("New State = "); + Serial.println(currentState); + + currentTimer = 0; + maxTimer = 4687; // 75 ms + } + + if ( timerReset) { + for (byte n = 0;n <= 7;n++) { + for (byte m = 0;m < 50;m++) drawCube(); + moveAxis(anim[n]); + } + timerReset = false; + } +} diff --git a/rainbow_random.ino b/rainbow_random.ino index 3ef7ed0..f6d44d0 100644 --- a/rainbow_random.ino +++ b/rainbow_random.ino @@ -1,4 +1,4 @@ -/******************************* PLANAR FLOP 3D *******************************\ +/******************************* RAINBOW RANDOM *******************************\ | Found on the internet.... | | | | Modified By: S. Dugre to use asynchronous timer | diff --git a/timers.ino b/timers.ino deleted file mode 100644 index cc95c8b..0000000 --- a/timers.ino +++ /dev/null @@ -1,12 +0,0 @@ - -/* -void timerInit() { - animationDelay.setTimeout(100); - animationDelay.setCallback(animationDelayCallback); -} - -void animationDelayCallback() { - animationDelayTiming = false; - //Serial.println("timed out"); -} -*/