ATtiny84 Interrupt Not Working

Hi! I've been trying to get my ATtiny84 to compile which utilizes interrupt code but I can't seem to get it to work. Here's my code:

#include <EEPROM.h>
#include <SoftwareSerial.h>
#include <avr/interrupt.h>
#include <DFRobotDFPlayerMini.h>

// ---- MACROS/PINS ----
#define RX           0
#define TX           1
#define BLUE_LED     2
#define POWER_ENABLE 3
#define MOTOR        5
#define BUTTON       8

// ---- FUNCTION PROTOTYPES ----
void wait(float timeInSeconds);
void onOff(byte mode);
void activateDo();
void phraseSet();
void phraseChange();
void turnOff();

// ---- VARIABLES ----
SoftwareSerial mySoftSerial(TX, RX); // For audio
DFRobotDFPlayerMini myPlayer; // For audio

const byte phraseLength[] = {30, 25, 33, 24, 26, 26, 30};

byte phrase = 1;

// ---- FUNCTIONS ----
void setup() { // GOOD
  pinMode(BUTTON      , INPUT_PULLUP);
  pinMode(POWER_ENABLE, OUTPUT);
  pinMode(BLUE_LED    , OUTPUT);
  pinMode(MOTOR       , OUTPUT);

  digitalWrite(POWER_ENABLE, HIGH); // For latching

  // Enable interrupt
  PCMSK0 |= (1 << PCINT2);
  GIMSK |= (1 << PCIE0);
  sei();
  
  mySoftSerial.begin(9600);
  myPlayer.begin(mySoftSerial);
  myPlayer.volume(25);
  phraseSet();
  activateDo();
}

void wait(float timeInSeconds){ // GOOD
  delay(timeInSeconds * 1000);
}

void onOff(byte mode){ // GOOD
  analogWrite(MOTOR, (mode) ? (255):(0));
  digitalWrite(BLUE_LED, mode);
  if(!mode) myPlayer.pause();
}

void activateDo(){ // GOOD
  onOff(1);
  phraseChange();
  myPlayer.play(phrase);
  wait(phraseLength[phrase - 1]);
  turnOff();
}

/*
 * This function sets the phrase upon first activation or sets
 * phrase based on previous activation
 */
void phraseSet(){ // GOOD
  EEPROM.get(0, phrase);
  if(phrase == 255) phrase = 0; // If first ever activation
}

void phraseChange(){ // GOOD
  if(phrase >= 7) phrase = 0;
  phrase++;
  EEPROM.write(0, phrase);
}

/*
 * Simply turns off the microcontroller (assuming the circuit
 * utilizes a soft latching circuit)
 */
void turnOff(){ // GOOD
  onOff(0);
  digitalWrite(POWER_ENABLE, LOW); // Power off
}

ISR(PCINT0_vect){ // WIP
  turnOff();
}

I heard that the "AtlSoftSerial" is the way to go as it works with the ATtiny microcontrollers but I'm unable to get it to work either. Any suggestions? Many thanks! : )

Could it be that you have selected the PIN mapping "clockwise" under tools in the Arduino IDE?

If you want to trigger the interrupt with PIN 8, this is PCINT10. PCINT2 is pin2/A2.

I don't think so, I've been working with the IDE as normal assuming the regular mapping, and have had no problem. Also, I must've gotten the pins wrong while looking at the pinout but even with the correction, I get a compile error. The error message is "multiple definition of `__vector_2'" which is occurring due to the use of the SoftwareSerial library but I'm not sure what to do. Any suggestions?

Maybe it helps to use the external interrupt vector INT0 on pin 8 (or 2 depending on CW or CCW) instead of a pin change interrupt.

I did not find void loop() in your source code. The function should already be defined...

Untested:

#include <EEPROM.h>
#include <SoftwareSerial.h>
#include <avr/interrupt.h>
#include <DFRobotDFPlayerMini.h>

// ---- MACROS/PINS ----
#define RX           0
#define TX           1
#define BLUE_LED     2
#define POWER_ENABLE 3
#define MOTOR        5
#define BUTTON       8  // or 2?

// ---- FUNCTION PROTOTYPES ----
void wait(float timeInSeconds);
void onOff(byte mode);
void activateDo();
void phraseSet();
void phraseChange();
void turnOff();

// ---- VARIABLES ----
SoftwareSerial mySoftSerial(TX, RX);   // For audio
DFRobotDFPlayerMini myPlayer;          // For audio

const byte phraseLength[] = {30, 25, 33, 24, 26, 26, 30};

byte phrase = 1;

// ---- FUNCTIONS ----
void setup() {   // GOOD
  pinMode(BUTTON, INPUT_PULLUP);
  pinMode(POWER_ENABLE, OUTPUT);
  pinMode(BLUE_LED, OUTPUT);
  pinMode(MOTOR, OUTPUT);

  digitalWrite(POWER_ENABLE, HIGH);   // For latching

  //  ISC01 ISC00 Description
  //    0     0   The low level of INT0 generates an interrupt request.
  //    0     1   Any logical change on INT0 generates an interrupt request.
  //    1     0   The falling edge of INT0 generates an interrupt request.
  //    1     1   The rising edge of INT0 generates an interrupt request
  MCUCR &= ~((1 << ISC01) | (1 << ISC00));  // Low level
  GIMSK = 0 | (1 << INT0);   // Set GIMSK – General Interrupt Mask Register = enable INT0

// Enable interrupt
//  PCMSK0 |= (1 << PCINT2);
//  GIMSK |= (1 << PCIE0);
  sei();

  mySoftSerial.begin(9600);
  myPlayer.begin(mySoftSerial);
  myPlayer.volume(25);
  phraseSet();
  activateDo();
}

void loop() {}

ISR(INT0_vect) { turnOff(); }

void wait(float timeInSeconds) {   // GOOD
  delay(timeInSeconds * 1000);
}

void onOff(byte mode) {   // GOOD
  analogWrite(MOTOR, (mode) ? (255) : (0));
  digitalWrite(BLUE_LED, mode);
  if (!mode) myPlayer.pause();
}

void activateDo() {   // GOOD
  onOff(1);
  phraseChange();
  myPlayer.play(phrase);
  wait(phraseLength[phrase - 1]);
  turnOff();
}

/*
 * This function sets the phrase upon first activation or sets
 * phrase based on previous activation
 */
void phraseSet() {   // GOOD
  EEPROM.get(0, phrase);
  if (phrase == 255) phrase = 0;   // If first ever activation
}

void phraseChange() {   // GOOD
  if (phrase >= 7) phrase = 0;
  phrase++;
  EEPROM.write(0, phrase);
}

/*
 * Simply turns off the microcontroller (assuming the circuit
 * utilizes a soft latching circuit)
 */
void turnOff() {   // GOOD
  onOff(0);
  digitalWrite(POWER_ENABLE, LOW);   // Power off
}

Hi! I appreciate the corrections but this unfortunately does not work either as I'm still given the following error message:

It seems like the SoftwareSerial library is causing the issue but it's an essential part of the program. Any suggestions? Thanks in advance! : )

That surprises me. I was able to compile the code without an error message. I only did not test the functionality of the program, but compiled it. (ATTinyCore 1.5.2)

I just realized that you were using ATtinyCore which is different from what I was using (which explains why you mentioned the pin mapping). Anyway, after installing and configuring the settings, I still got the same compile error similar to the one I showed before. So it definitely has to do with the SoftWare serial but I'm not sure what to do. : (

EDIT: I forgot to make some more adjustments based on the corrected code you provided, it still hasn't been tested but it no longer gives any compile errors! : )

Hi! I just tested the code out and everything and it seems to work well! However, I'm having an issue with this line:

myPlayer.begin(mySoftSerial);

The issue is that, for some reason, it takes around 5 or slightly more seconds to finish execution which wasn't happening when I wasn't using ATtinyCore, any clue why this behavior is occurring? Thanks! : )

No, not an idea. You can try using the serial pins provided by the megaTinyCore. You can see what these are in the pin layout I linked to in post #2.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.