Author Topic: Digispark Tinypinchange (for interupt) changes the delay speed when enteringISR  (Read 3774 times)

Emielkosse

  • Newbie
  • *
  • Posts: 3
Hi Guys,

I have this problem on which I cannot find any answers. I use the digispark with the tinypinchange.h for my ISR.
I also use delay for some other functions. When no interrupt has been triggered this delay works as expected. When the ISR has been triggered the delay has gone much faster, as if somewhere in this include file the clocksource/frequency has been changed.

In order to identify this problem I placed a ledblink routine in my setup{}, here it works correct.
below is my code.
In the TinyPinChange.h I do see that another include file is used, <avr/interrupts>  can this file somehow change the CPU settings and makes it the settings for the ATtiny85?

Please help me out, looking hours for this :o

Code: [Select]
#include <TinyPinChange.h>

#define SW    0
#define POS   2
#define CLOSE 1

uint8_t virtPort0;
//uint8_t virtPort1;



// the setup routine runs once when you press reset:
void setup() {   
  TinyPinChange_Init();
  pinMode(POS, INPUT);
  pinMode(SW, INPUT);
  pinMode(CLOSE, OUTPUT);
  virtPort0 = TinyPinChange_RegisterIsr(SW, SW_Interrupt);
  TinyPinChange_EnablePin(SW);
  blinkled(20);
}

// the loop routine runs over and over again forever:
void loop() {
 
  delay(2000);               // wait for a second
  //TinyPinChange_Init();
}

void blinkled(int times){
  int i;
  for (i=0; i < times; i++){
    digitalWrite(CLOSE, HIGH);
    delay(100);
    digitalWrite(CLOSE,LOW);
    delay(200);
  }
}

void SW_Interrupt(void){
  //TinyPinChange_DisablePin(SW); // debounce
  noInterrupts();
  //if(TinyPinChange_RisingEdge(virtPort0, SW)) {
    //if (digitalRead(POS)==HIGH && digitalRead(SW)== HIGH){
        blinkled(5);
    //}
  //}
  interrupts();
  //TinyPinChange_EnablePin(SW);   
}

Emielkosse

  • Newbie
  • *
  • Posts: 3
I the meanwhile I have figured out a work-around.

I added a boolean variable "int_found" and this bool is set to TRUE when the ISR occurs. In the mainloop I check for this bool and do my thing.


Horolf

  • Newbie
  • *
  • Posts: 1
I the meanwhile I have figured out a work-around.

I added a boolean variable "int_found" and this article on appetite suppressants bool is set to TRUE when the ISR occurs. In the mainloop I check for this bool and do my thing.

Where did you add the boolean?
« Last Edit: June 14, 2018, 08:49:46 am by Horolf »

PeterF

  • Hero Member
  • *****
  • Posts: 881
Horolf, he has probably set a flag in the ISR function (SW_Interrupt in this case), and the main loop reacts when this flag is set high, and the loop then sets it low again so the ISR can raise it again.

Emielkosse, I haven't run that code, but I believe the problem you are having is because you can't use delay() when interrupts are disabled - as it relies on interrupts to function! If you want to have a delay in an interrupt function, use delayMicroseconds() instead - just note it is microseconds, not milliseconds (i.e. 1000 micro in 1 milli). Also, don't just jump in and swap out delays() for delayMicroseconds(), as it disables interrupts, so your ISR function won't trigger  and set it's flag whilst a delayMicroseconds delay is happening. You should really use the interrupt function how it seems you are using it now... to set a flag, so control can pass back immediately to your main loop, and the main loop can respond to the interrupt via the flag.