Go Down

Topic: ATtiny85 Pin Change Interrupt Problem (Read 19 times) previous topic - next topic

bHogan

Feb 11, 2011, 12:07 am Last Edit: Feb 11, 2011, 12:12 am by BroHogan Reason: 1
I'm trying to use pin change interrupts with the ATtiny because I have to use the INT0 pin for SCK in I2C.

I can trigger the interrupt, but after it fires, it runs through setup() again. It may be just rebooting - with no bootloader it's hard to tell.

The attachInterrupt() with INT0 works fine.
I've tried a few different techniques and vectors [ISR (PCINT1_vect), SIGNAL (SIG_PCINT)] with similar results.

I may be doing something basically wrong here, but I can't figure out what.

Here is a sample that demonstrates the problem . . .
Code: [Select]
/* IR Receiver Test 2       GOES BACK TO MAIN WHEN I USE ISR
* SETUP:
* ATtiny Pin 1 = (RESET) N/U                      ATtiny Pin 2 = (D3) IR OUTPUT PIN
* ATtiny Pin 3 = (D4) to LED1                     ATtiny Pin 4 = GND
* ATtiny Pin 5 = D0/SDA on GPIO                   ATtiny Pin 6 = (D1) Piezo
* ATtiny Pin 7 = D2/INT0/SCK on GPIO              ATtiny Pin 8 = VCC (2.7-5.5V)
*/

#define LED1_PIN         4              // ATtiny Pin 3
#define PIEZO_PIN        1              // ATtiny Pin 6
#define IR_PIN           3              // IR sensor - ATtiny Pin 2

void setup(){
 pinMode(LED1_PIN,OUTPUT);             // for general DEBUG use
 pinMode(IR_PIN,INPUT);                // IR on pin 3
 digitalWrite(IR_PIN, HIGH);           // turn on pullup resistor
 Blink(LED1_PIN,3);                    // shows it's in setup
 //tone(PIEZO_PIN,2500,1000);          // shows it's in setup (not supported with MIT core)
 delay(1500);
 //  attachInterrupt(0,IR_ISR,FALLING); // THIS METHOD OF ISR WORKS

 // Setup pin change interrupt . . .
 // METHOD 4: *************
 PCMSK |= (1<<PCINT3);    //  tell pin change mask to listen to D3
 GIMSK  |= (1<<PCIE);     // enable PCINT interrupt in the general interrupt mask
 sei();                   // Enable all interrupts
}

void loop(){
 //tone(PIEZO_PIN,2000,200); // when used makes different pitch than in setup()
 delay (1500);
 digitalWrite(LED1_PIN,LOW);
}


SIGNAL (SIG_PCINT) {    // METHOD 4: *************
 //void IR_ISR(){      // STANDARD METHOD WORKS

 digitalWrite(LED1_PIN,HIGH);
}

void Blink(byte led, byte times){ // poor man's GUI
 for (byte i=0; i< times; i++){
   digitalWrite(led,HIGH);
   delay (400);
   digitalWrite(led,LOW);
   delay (175);
 }
}


I'm stumped. Any help is appreciated.




"Data is not information, information is not knowledge, knowledge is not understanding, understanding is not wisdom."
~ Clifford Stoll

Coding Badly

Rather than help troubleshoot, can I interest you in a working library?  It uses less memory and should be a bit faster than the "stock" pin-change interrupt code.

bHogan

Sure! A working library for what? Interrupts? IR?
If it's for IR, I'd prefer an int only when it receives a signal, rather than a timer int that going off every x ms.
As I said, I need pin 7 free for I2c.

In any case, I'll be happy to look at a lib.  : :D
"Data is not information, information is not knowledge, knowledge is not understanding, understanding is not wisdom."
~ Clifford Stoll

Coding Badly

I'm afraid you'll be a bit disappointed.  It's just for pin-change interrupts on tiny processors.  But it is well debugged.

The Tiny Core includes a write-only software Serial (Tiny Debug Serial).  All you need is a TTL serial converter (an Arduino will work).  It beats the heck out of LED debugging.   ;)

bHogan

Not disappointed at all! Pin change interrupts is exactly what I need.
(The ability to detect rising and falling would be great too!)

The serial sounds interesting. I have a cable. Yep, counting LED flashes is no fun. (Normally I use an I2C 2x20 display.)

In any case, thanks! I look forward to checking it out.

John
"Data is not information, information is not knowledge, knowledge is not understanding, understanding is not wisdom."
~ Clifford Stoll

Go Up