Setting up interrupts in the ATTiny85 Digispark Digistump

I am trying to use this code to use the timer0 for a countdown interrupt.

Are the AVR includes the problem as my target processor is the USB Digistump?

I found this code and it shows errors that I am not familiar with:

#define F_CPU 16500000UL
#include<avr/io.h>
#include <avr/interrupt.h>
#include<util/delay.h>

int intr_count=0;
int sec=0;

ISR (TIMER0_OVF_vect)      //Interrupt vector for Timer0
{
  if (intr_count==63) //waiting for 63 because to get 1 sec delay
  {
    PORTB^=(1<<PB1); //toggling the LED
    intr_count=0; //making intr_count=0 to repeat the count
    ++sec;
  }
  else  intr_count++; //incrementing c upto 63
}

void timer_setup()
{
  DDRB |= (1<<PB1); // set PB1 as output(LED)
  TCCR0A=0x00;   //Normal mode
  TCCR0B=0x00;
  TCCR0B |= (1<<CS00)|(1<<CS02);   //prescaling with 1024
  sei(); //enabling global interrupt
  TCNT0=0;
  TIMSK|=(1<<TOIE0); //enabling timer0 interrupt
  PORTB|=(1<<PB1);
}

int main () 
{
  timer_setup();
  while(1)
  {
    
  }
}

The errors are:

C:\Users\phyzx\Documents\Arduino\AtTiny85InterruptTimer\AtTiny85InterruptTimer.ino:5:0: internal compiler error: Segmentation fault

Please submit a full bug report,
with preprocessed source if appropriate.
See https://gcc.gnu.org/bugs/ for instructions.
exit status 1

Compilation error: exit status 1

Not sure about the F_CPU line either.

Thank you in advance.

I’m not very familiar with the Digistump/Digispark toolchain specifics, but an “internal compiler error: Segmentation fault” usually points more towards a compiler/toolchain problem than a normal sketch error.

Since this is an ATtiny85/Digispark setup, I would probably first check:

  • which Digistump core/package version is installed
  • which IDE version is being used
  • whether this still happens with a very small/minimal interrupt example

Thanks. I remmed out the AVR tools since I am not on that platform and remmed ou the F_CPU since I am not changing speed. It had problems on the first 2 comples that I tried and magically on the 3rd it compiled. Now whether that works on the processor is a different effort. I go there next having seen the last compile worked. But is the IDE platform unstable? I ask because the compiles all do serious error reporting but then the compiles work?

1. Are you using the following Dev Board?

2. have you written the sketch of post #1? If not, post the link from whee you have copied it.

3. What is the purpose of the sketch of post Development Tools > IDE 1.x

4. An Arduino sketch begins with the followig two functions and then the user functions are added as needed.

void setup()
{

}

void loop()
{

}

Yes. That is the board I am using. Am I posting in the wrong forum?

I made the necessary changes to the default routines:

//#define F_CPU 16500000UL //
#include<util/delay.h>

int intr_count=0;
int sec=0;

ISR (TIMER0_OVF_vect)      //Interrupt vector for Timer0
{
  if (intr_count==13) //waiting for 63 because to get 1 sec delay
  {
    PORTB^=(1<<PB1); //toggling the LED
    intr_count=0; //making intr_count=0 to repeat the count
    ++sec;
  }
  else  intr_count++; //incrementing c upto 63
}

void setup()
{
  DDRB |= (1<<PB1); // set PB1 as output(LED)
  TCCR0A=0x00;   //Normal mode
  TCCR0B=0x00;
  TCCR0B |= (1<<CS00)|(1<<CS02);   //prescaling with 1024
  sei(); //enabling global interrupt
  TCNT0=0;
  TIMSK|=(1<<TOIE0); //enabling timer0 interrupt
  PORTB|=(1<<PB1);
}


void loop () 
{
  //timer_setup();
  while(1)
  {/*forever*/}
}

I dont have the link for the code.

The IDE 2.3.8 produces numerous error reports for each compile cycle. Then when is works the uploading never takes off. Instead the digistump goes into the original BLINK sketch.

Here is one of the errors:

c:\users\phyzx\appdata\local\arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7\avr\include\math.h:1:0: internal compiler error: Segmentation fault
/* Copyright (c) 2002,2007-2009 Michael Stumpf

Please submit a full bug report,
with preprocessed source if appropriate.
See https://gcc.gnu.org/bugs/ for instructions.
exit status 1

Compilation error: exit status 1

I have programmed on this device before.

Anyway, the sketch with ISR(TIMER0_OVF_vect){} does not compile. So, I am giving you a sketch below which toggles the onboard LED at 1-sec interval. The sketch is compiled without error. Upload it n your board and chcek if the onboard LED toggles. In my seup, the USB link frequentlt gets interrupted and the process is not complete. So, I have no result of execution.

//togggle onboard LED at 1-sec interval

byte cntr = 0;

void setup()
{
  pinMode(1, OUTPUT); //DDRB |= (1 << PB1); // set PB1 as output(LED)
  digitalWrite(1, LOW);  //onboard LED is Off
  TCCR0A = 0x00; //Normal mode
  TCCR0B = 0x00;
  TCNT0 = 175; // 5 ms rollover time, 200; 256 = n + 0.005 x 16.5 MHz/1024
  TCCR0B |= (1 << CS00) | (1 << CS02); //start TC0 wit prescaling with 1024
}


void loop ()
{
  while (bitRead(TIFR, TOV0) != HIGH)
  {
    ;  //wait
  }
  bitSet(TIFR, TOV0);//flag is cleared
  TCNT0 = 175;
  cntr++;
  if (cntr == 200)
  {
    cntr = 0;
    digitalWrite(1, !digitalRead(1));//toggle onboard LED
  }
}

Thank you but I need to use an interrupt.

I was originally going to use the pb4 pwm but I couldnt get that to compile either.

This is the first time I tried these two approaches since I have been using these digistumps for 4 years now.

Plain vanilla ATtiny85 with the ATTinyCore.

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

int intr_count = 0;
int sec = 0;

ISR(TIMER0_OVF_vect)  //Interrupt vector for Timer0
{
   if( intr_count == 63 )  //waiting for 63 because to get 1 sec delay
   {
      PORTB ^= (1 << PB1);  //toggling the LED
      intr_count = 0;       //making intr_count=0 to repeat the count
      ++sec;
   } else intr_count++;  //incrementing c upto 63
}

void timer_setup() {
   DDRB |= (1 << PB1);  // set PB1 as output(LED)
   TCCR0A = 0x00;       //Normal mode
   TCCR0B = 0x00;
   TCCR0B |= (1 << CS00) | (1 << CS02);  //prescaling with 1024
   sei();                                //enabling global interrupt
   TCNT0 = 0;
   TIMSK |= (1 << TOIE0);  //enabling timer0 interrupt
   PORTB |= (1 << PB1);
}

int main() {
   timer_setup();
   while( 1 ) {
   }
}
arduino-cli compile -b ATTinyCore:avr:attinyx5:chip=85,clock=8internal --warnings all --output-dir ~/tmp --no-color (in directory: /home/me/Documents/sketchbook/ATtiny85/test)
Sketch uses 182 bytes (2%) of program storage space. Maximum is 8192 bytes.
Global variables use 4 bytes (0%) of dynamic memory, leaving 508 bytes for local variables. Maximum is 512 bytes.
Compilation finished successfully.

Edit: and BTW, the LED blinked.

I see sei() but no cli() before it. Those are AVR commands where noInterrupts() and interrupts() are for all supported chips.

Timers for micros and millis are already started at setup().

Nick Gammon tutorial blog on Interrupts includes code.

Did you have Digispark selected as the processor? It wasnt mentioned so I ask.

Actually, I did mention what processor was selected.

But here you are with the Digispark selected. Same result. I can't verify that the LED blinks for this configuration as I only have ATtiny85 in standalone DIPs. Hence the reason I used that.

arduino-cli compile -b ATTinyCore:avr:attinyx5micr --warnings all --output-dir ~/tmp --no-color (in directory: /home/me/Documents/sketchbook/ATtiny85/test)
Sketch uses 182 bytes (2%) of program storage space. Maximum is 6586 bytes.
Global variables use 4 bytes (0%) of dynamic memory, leaving 508 bytes for local variables. Maximum is 512 bytes.
Compilation finished successfully.

What is that?

When setup(){} and loop(){} functions are inserted in your sketch and discarding the main(){} function, it is no more compiled.

This is the error message:

(.text+0x0): multiple definition of `__vector_5'
C:\Users\GOLAMM~1\AppData\Local\Temp\arduino_build_979266\sketch\blinkA.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status

Don't you know that Arduino setup() and loop() are laid over standard C/C++? Seems that your AI doesn't either.

@giantkiller

The following sketch is compiled in ATTinyCore without error and uploaded into Digispark ATtiny85 Dev Board (colone) and works. (The onboard LED blinks at 1-sec interval).

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

int intr_count = 0;
int sec = 0;

ISR(TIMER0_OVF_vect)  //Interrupt vector for Timer0
{
   if( intr_count == 63 )  //waiting for 63 because to get 1 sec delay
   {
      PORTB ^= (1 << PB1);  //toggling the LED
      intr_count = 0;       //making intr_count=0 to repeat the count
      ++sec;
   } else intr_count++;  //incrementing c upto 63
}

void timer_setup() {
   DDRB |= (1 << PB1);  // set PB1 as output(LED)
   TCCR0A = 0x00;       //Normal mode
   TCCR0B = 0x00;
   TCCR0B |= (1 << CS00) | (1 << CS02);  //prescaling with 1024
   sei();                                //enabling global interrupt
   TCNT0 = 0;
   TIMSK |= (1 << TOIE0);  //enabling timer0 interrupt
   PORTB |= (1 << PB1);
}

int main() {
   timer_setup();
   while( 1 ) {
   }
}

void setup(){}

void loop(){}

Why does the sketch of post #15 works when there are Arduino setup() and loop() functions along with C++ int main() function? In normal Arduino sketch, we don't show the C++ int main() funnction; we show only thesetup() and loop)() functions.

1.
I am aware about the following code that is executed after treating the globals of an Arduino sketch:

#include <Arduino.h>
int main(void) 
{
    init();
#if defined(USBCON)
    USBDevice.attach();
#endif

    setup();
    
    for (;;) {
        loop();
        if (serialEventRun) serialEventRun();
    }
    return 0;
}

2. Why the following sketch works for ATtiny85 in ATTinyCore to blink oonboard LED at 1-sec interval without explicit Arduinisetup() and loop() functions.

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

int intr_count = 0;
int sec = 0;

ISR(TIMER0_OVF_vect)  //Interrupt vector for Timer0
{
   if( intr_count == 63 )  //waiting for 63 because to get 1 sec delay
   {
      PORTB ^= (1 << PB1);  //toggling the LED
      intr_count = 0;       //making intr_count=0 to repeat the count
      ++sec;
   } else intr_count++;  //incrementing c upto 63
}

void timer_setup() {
   DDRB |= (1 << PB1);  // set PB1 as output(LED)
   TCCR0A = 0x00;       //Normal mode
   TCCR0B = 0x00;
   TCCR0B |= (1 << CS00) | (1 << CS02);  //prescaling with 1024
   sei();                                //enabling global interrupt
   TCNT0 = 0;
   TIMSK |= (1 << TOIE0);  //enabling timer0 interrupt
   PORTB |= (1 << PB1);
}

int main() {
   timer_setup();
   while( 1 ) {
   }
}

Why shouldn't it?

Sorry! The sketch of post #15 works well with and without Arduino setup() and loop() functions.

My question is:
Why does the following Arduino styled sketch (does not contain C++ main()) give compilaton error.

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

int intr_count = 0;
int sec = 0;

ISR(TIMER0_OVF_vect)  //Interrupt vector for Timer0
{
  if ( intr_count == 63 ) //waiting for 63 because to get 1 sec delay
  {
    PORTB ^= (1 << PB1);  //toggling the LED
    intr_count = 0;       //making intr_count=0 to repeat the count
    ++sec;
  } else intr_count++;  //incrementing c upto 63
}

void timer_setup() {
  DDRB |= (1 << PB1);  // set PB1 as output(LED)
  TCCR0A = 0x00;       //Normal mode
  TCCR0B = 0x00;
  TCCR0B |= (1 << CS00) | (1 << CS02);  //prescaling with 1024
  sei();                                //enabling global interrupt
  TCNT0 = 0;
  TIMSK |= (1 << TOIE0);  //enabling timer0 interrupt
  PORTB |= (1 << PB1);
}

void setup()
{
  timer_setup();
}

void loop() {}

This is the error message:

wiring.c.o (symbol from plugin): In function `__vector_5':
(.text+0x0): multiple definition of `__vector_5'

I get vector_4 sometimes but the error report is always what seem as random errors.

without int main() function, the sketch does not compile. The sketch of post #15 works well.

The inclusion of int main() in the Arduino sketch stops the excution of the background C++ in main(); as a result, the pre-initializations of timers and oher modules are not done. We get a clean environment where ISR(TINER0_OVF_vect){} is compiled withour any error and the sketch runs.

Because Arduino IDE runs C++!

And you #include <Arduino.h> in that sketch, it's almost like you know what you do, but don't.