added pin change interupt for chaninging animation state
This commit is contained in:
parent
4f7736b055
commit
f2e601bc66
8 changed files with 131 additions and 56 deletions
35
button.ino
Normal file
35
button.ino
Normal 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
3
config.h
3
config.h
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
typedef enum STATE {
|
||||
CHASETHEDOT,
|
||||
RANDOMRAINBOW,
|
||||
RAINBOWRANDOM,
|
||||
RAINBOWCORNER,
|
||||
PLANARFLOP3D
|
||||
};
|
||||
|
||||
|
|
|
|||
43
cubeplex.h
43
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 |
|
||||
|
|
|
|||
75
rainbow_corner.ino
Normal file
75
rainbow_corner.ino
Normal 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
/******************************* PLANAR FLOP 3D *******************************\
|
||||
/******************************* RAINBOW RANDOM *******************************\
|
||||
| Found on the internet.... |
|
||||
| |
|
||||
| Modified By: S. Dugre to use asynchronous timer |
|
||||
|
|
|
|||
12
timers.ino
12
timers.ino
|
|
@ -1,12 +0,0 @@
|
|||
|
||||
/*
|
||||
void timerInit() {
|
||||
animationDelay.setTimeout(100);
|
||||
animationDelay.setCallback(animationDelayCallback);
|
||||
}
|
||||
|
||||
void animationDelayCallback() {
|
||||
animationDelayTiming = false;
|
||||
//Serial.println("timed out");
|
||||
}
|
||||
*/
|
||||
Loading…
Add table
Add a link
Reference in a new issue