Hi. I've got a problem with my function update() that updates the LEDs of my 4x4x4 cube. I wrote it for the loop() function and it works fine. Then I learnt about timer interrupts from here but when I move update() from loop() to my interrupt function ISR(TIMER1_OVF_vect), 3 layers are only intermittently on and the other is on fine. My code is below.
So what do I have to do to make the update() function work in a interrupt function? From the guide it talks about volatile global variables but is that it? What about #define variables?
Thanks
#include <avr/interrupt.h>
#define TIME 0
#define CUBE_WIDTH 4
#define BITS_PER_BYTE 8
#define NUM_BYTES CUBE_WIDTH*CUBE_WIDTH*CUBE_WIDTH/(BITS_PER_BYTE*sizeof(uint8_t))
#define NUM_DATA_PINS sizeof(dataPin)/sizeof(int)
volatile uint8_t cube[NUM_BYTES] = {
0};
volatile int previous_layer = CUBE_WIDTH;
volatile int dataPin[] = {
2, 3};
volatile int latchPin = 4;
volatile int clockPin = 5;
volatile int PlanePin[] = {
13,12,11,10};
void setup() {
int i;
for (i=0; i<NUM_DATA_PINS; i++) {
pinMode(dataPin[i], OUTPUT);
}
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
for (i=0; i<CUBE_WIDTH; i++) {
pinMode(PlanePin[i], OUTPUT);
digitalWrite(PlanePin[i], HIGH);
}
// initialize Timer1
cli(); // disable global interrupts
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
TCCR1B |= (1 << CS11); // Set CS11 & CS10 bits for 1024 prescaler:
TCCR1B |= (1 << CS10);
TIMSK1 = (1 << TOIE1); // enable Timer1 overflow interrupt:
sei(); // enable global interrupts:
cube[0] = 249; // This produces a wire frame cube
cube[1] = 159;
cube[2] = 144;
cube[3] = 9;
cube[4] = 144;
cube[5] = 9;
cube[6] = 249;
cube[7] = 159;
}
void shiftin(uint8_t data1, uint8_t data2) {
int b, i;
for (b=0; b<8; b++) {
digitalWrite(clockPin, LOW);
digitalWrite(dataPin[0], data1 & (1<<b));
digitalWrite(dataPin[1], data2 & (1<<b));
digitalWrite(clockPin, HIGH);
}
}
void update(void) {
int current_layer;
for (current_layer=0; current_layer<CUBE_WIDTH; current_layer++) {
digitalWrite(latchPin, LOW); // reset latches
delay(TIME);
shiftin(cube[current_layer*NUM_DATA_PINS], cube[current_layer*NUM_DATA_PINS+1]);
// shift in bits into both 74hc595N
delay(TIME);
digitalWrite(PlanePin[previous_layer], HIGH); // turn off previous layer
// all layers off
delay(TIME);
digitalWrite(latchPin, HIGH); // latch shifted bits
delay(TIME);
digitalWrite(PlanePin[current_layer], LOW); // turn on current layer
delay(TIME);
previous_layer = current_layer; // record previous layer
}
}
void loop() {
update(); //works fine here
}
ISR(TIMER1_OVF_vect) {
// update(); //doesn't work properly here
}