[solved ] ATTiny85 Interrupt Problem

I have been trying to use the interrupt in the ATTiny, but so far I have had only partial success. The ATTiny is programmed with its internal oscillator @ 8 Mhz. Basically, I have a couple of sensors, a LED and an output to a transistor. The core I'm using is the arduino-tiny-0100-0017.zip

Here is the code I'm using:

#include <PinChangeInterrupt.h>

const int Sensor1 = 0;
const int YellowLED = 1;
const int LDR = 2;
const int BJT = 3;
const int Switch = 4;

void setup() {
  pinMode(Sensor1, INPUT);
  pinMode(YellowLED, OUTPUT);
  pinMode(LDR, INPUT);
  pinMode(Switch, INPUT);
  pinMode(BJT, OUTPUT);

attachPcInterrupt(4,newlevel,FALLING);

}

//Main Program

void loop() {
//Chequear sensor de movimiento
  if (digitalRead(Sensor1) == 1) {
  darkness();
  }
} //END OF LOOP

void darkness() {
  int LDRValue = analogRead(LDR);
  if (LDRValue < LDRlimit) {
  turnon();
  delay(1000);
  turnoff();
    }
}

void newlevel() {
  digitalWrite(YellowLED,HIGH);
  int LDRNewValue = analogRead(LDR);
  digitalWrite(YellowLED,LOW);
}

void turnon() {
digitalWrite(YellowLED, HIGH)
}

void turnoff() {
digitalWrite(YellowLED, LOW)
}

I have also tried the following:
http://www.insidegadgets.com/2011/02/27/how-to-use-the-pin-change-interrupt-on-attiny85/
http://forum.arduino.cc/index.php?topic=51838.0#

But still can't make it work. Either the output (BJT) works only when I ground the pin 4 (Arduino Pins) or it doesn't affect the program at all, which is to set a new darkness level. I even had the problem that taking Sensor1 out of the circuit, the whole action of activating the interrupt by grounding the pin 4, made the output of the BJT go High, which of course shouldn't be. My assumption on some cases is that the Interrupt is acting as a clock or resetting the ATTiny. But I can't figure out why.

I found out I can't use the Reset pin (5) unless I have a High Power Programmer, afterwards, so I'm not using it. I also tried changing the register bits for Interrupts accoridng to the Datasheet and other comments from this forum, but still no luck. Any help is appreciated.

attachPcInterrupt(4,newlevel,FALLING);

The first argument is NOT a pin number. It is the interrupt number. Does the tiny 85 really have 4 external interrupt pins?

Thanks for your response PaulS, I definitely thought that the PinChangeInterrupt.h library worked as the attachinterrupt command. Unfortuneately, I did try using the INT0 as well as ISRs with Pin Change and Hardware Interrupts, but still I am not getting the hang of it.

I'll try using the hardware interrupt INT0 with this command then:

attachPcInterrupt(1,newlevel,FALLING);

I'll get back with results. Thanks! :slight_smile:

PaulS:

attachPcInterrupt(4,newlevel,FALLING);

The first argument is NOT a pin number. It is the interrupt number.

Actually, for that library I think the first argument is the pin number. I'll check after dinner.

Does the tiny 85 really have 4 external interrupt pins?

No, one. But all six pins support pin-change interrupts.

Actually, for that library I think the first argument is the pin number. I'll check after dinner.

I missed that Pc in there. Guess I'm not politically correct.

Ok, so I started from scratch (again =( ) and took it step by step, and found out that when the interrupt handler is called (using attachPcInterrupt) the reading of the analog value of the LDR is not working as expected, since it's always the same value; but curiously enough the calling of the interrupt and the interrupt handler seemed to work fine. So far this is what I've found. Any suggestions are most welcome.
** BTW this is just testing the LED, LDR and the interrupt handler, no BJT and Sensor1. I'm starting to grow gray hair here!

Post the current version of your sketch.

Thanks for your response Coding Badly. I've strippe down the original code and started from scratch trying to find out where the problem could be. The code is show below. In this case, on the BJT output I have connected a LED to visually see when it goes High.
The problem I see is that the LDR value is not being read, since it is not changing at all. And even though the interrupt handler is working, it's timing is not correct, for the delays, and when it is called the output of the BJT goes High, which shouldn't happen, since there's no command telling it to do so. Finally, when the circuit is power the BJT output doesn't goes High at all or Low, it is 'On', since the LED is dimly bright, but I don't know why. The EEPROM section is working as expected. The interrupt pin is connected to a 10K resistor and between them the switch. I have also seen that if I take away that resistor the flow of the program seems to work properly (I tested this with the LDR). Therefore I am worried I am making something wrong and since this pin is also used for the xtal2 it just executes a step and stops waiting for a clock signal. Don't know if that might also be the reason the BJT goes high when the interrupt handler executes, although I tried it on pins D2, D0 and still happens. I know the RESET pin cannot be used, unless fuses are changed, but will not be able to program the tiny again unless a high voltage programmer is used, but I haven't heard anything about the D3 or D4 pins.

Any help is greatly appreciated.

VCC
VCC ^
| |
/ R=10k \ LDR
\ ----------------------- /
| (BJT) R =330 | D5,A0 VCC | |
| GND---(|<-)--///---- | D3,A3 D2,A1|-----------
|----------------------------| D4,A2 D1| |
| / | GND D0|
-------/ o------------ ----------------------- / R = 10k
SWITCH | |
GND GND

Here's the code:

/*
ATtiny85 IC Pins                            Arduino Pins                       Item Connected
            1                                         D5, A0
            2                                         D3, A3                                         BJT
            3                                         D4,A2
            4                                         GND
            5                                          D0
            6                                          D1                                              LED
            7                                          D2,A1                                         LDR
            8                                          VCC
*/


#include <PinChangeInterrupt.h>
#include <EEPROM.h>

const int LED = 1;
const int LDR = 2; //I've also tried using the Analog Pin Number (1)
const int BJT = 3;
const int SWITCH = 4;
int number;


void setup() {
pinMode (LED, OUTPUT);
pinMode (BJT, OUTPUT);
pinMode (LDR, INPUT);
pinMode (SWITCH,INPUT);
EEPROM.write(1,0);
attachPcInterrupt(SWITCH,blinky,FALLING);
}

void loop () {
digitalWrite(BJT, LOW);
int light = analogRead(LDR);
if (light > 700) {
  digitalWrite(BJT, HIGH);
  } else {
    digitalWrite(BJT, LOW); 
    }
}

void blinky() {
 delay(500);

// The value of the LDR doesn't change.
 int LDRNewValue = analogRead(LDR);
 //

   EEPROM.write(1,number);
}

First, some general comments about your interrupt service routine...

void blinky() {
 delay(500);
// The value of the LDR doesn't change.
 int LDRNewValue = analogRead(LDR);
 //
   EEPROM.write(1,number);
}

Calling delay in an interrupt service routine is a bad idea. Don't do it.

Writing to EEPROM in an interrupt service routine is a bad idea. Don't do it.

This declares a local variable...
int LDRNewValue
...which is assign a value from analogRead...
LDRNewValue = analogRead(LDR);
...which is never used.

You are absolutely right about the EEPROM and delay in the ISR, it beats the purpose of the ISR itself, but that's how I thought to solve the problem. I had already done the routine without them, with the same results. Regarding the LDRNewValue, it was my mistake not to include the part where I actually use it, as a comparison; but still I get the same results. I'm still trying to find out what is going on. It's the first time I use the ATtiny85, so I'm learning along the way. As with the 328P the code works flawless.

BTW, I tried another code I found which works fine with the LDR, but again if I connect a 10k resistor to the D4 the code stops. As soon as I take out the resistor, the program resumes. I still am trying to figure out if you can work and how with the digital pins 5,4,3 with problems or not. Even though, I now know that pin 5 is out of the question, unless I'm not worried to reprogram it again, using the Arduino shield as an ISP.

Thanks for your reply.

I am having a difficult time deciphering what you are trying to do. For example, you have not explained why you even need to include interrupts in your project. I suggest you describe your project from the perspective of the user. Then pick one small piece (like driving the LED) and run that piece to completion.

I'm sorry for the late reply Coding Badly. I finally got it working :sweat_smile:
In response to your question, the whole idea was to be able to control a 3W RGB LED. The interrupt is basically to set a point for the LED to turn on.
The whole problem was with the assignment of the analog variable, it needed to be referenced to the Analog Converter, strange since I thought I did it correctly in the various tests I carried out (go figure!). Anyway, it works. Thank you very much!