added pin change interupt for chaninging animation state

This commit is contained in:
Sean 2022-04-13 21:09:44 -04:00
parent 4f7736b055
commit f2e601bc66
8 changed files with 131 additions and 56 deletions

35
button.ino Normal file
View file

@ -0,0 +1,35 @@
#include <avr/interrupt.h>
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;
}
}

View file

@ -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 <timer.h>
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;

View file

@ -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;
}
}

View file

@ -3,7 +3,8 @@
typedef enum STATE {
CHASETHEDOT,
RANDOMRAINBOW,
RAINBOWRANDOM,
RAINBOWCORNER,
PLANARFLOP3D
};

View file

@ -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 |

75
rainbow_corner.ino Normal file
View file

@ -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;
}
}

View file

@ -1,4 +1,4 @@
/******************************* PLANAR FLOP 3D *******************************\
/******************************* RAINBOW RANDOM *******************************\
| Found on the internet.... |
| |
| Modified By: S. Dugre to use asynchronous timer |

View file

@ -1,12 +0,0 @@
/*
void timerInit() {
animationDelay.setTimeout(100);
animationDelay.setCallback(animationDelayCallback);
}
void animationDelayCallback() {
animationDelayTiming = false;
//Serial.println("timed out");
}
*/