Difference between Arduino IDE and TinkerCAD Simulator

I have this program, when I run it in TinkerCAD, it works well, when I downloaded it into Arduino UNO, nothing happened.

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

#define SET(port,bit) port|=(1<<bit)
#define CLR(port,bit) port&=~(1<<bit)
#define TOGGLE(PORT,BIT) PORT^=(1<<BIT)


int count=0;
void timer0_init()
{
  CLR(TCCR0A,WGM00);//SET TIMER0 TO NORMAL MODE
  CLR(TCCR0A,WGM01);
  CLR(TCCR0B,WGM02);
  TCNT0=0X00;
  SET(SREG,7);
  SET(TIMSK0,TOIE0); // overflow interrupt enable
}

void enable_timer()
{
  SET(TCCR0B,CS00);//set prescalar to 1024
  CLR(TCCR0B,CS01);
  SET(TCCR0B,CS02);
}

int main()
{
  DDRD|=(1<<PD6); //LED CONNECTED TO DIGITAL PIN 6 ,and all the
                  //bits of the port is set so as to make it an 
                  //output port
  timer0_init();
  enable_timer();
  while(1)
  {
     //if(count==62)
    if(count==31)
    {
      TOGGLE(PORTD,PD6);
      count=0;
    }	
  }
}

ISR(TIMER0_OVF_vect)
{
 count++; 
}

Anyone know why?

I don't. Go try the same code here;

I find to it be the most faithful simulator.

Which is to say my money is on the idea that Tinkercod is less than perfect.

Also I just noticed you are using your own main() function… any good reason for not using setup()/loop() like normal?

a7

OK, this has to be explained to me.

@MianQi's code works when I added a Serial.print to see what was going on on PORTD.

This is the code with only Serial.begin and one Serial.print added, blinks an LED on digital output 6:

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

#define SET(port,bit) port|=(1<<bit)
#define CLR(port,bit) port&=~(1<<bit)
#define TOGGLE(PORT,BIT) PORT^=(1<<BIT)


int count = 0;

void timer0_init()
{
  CLR(TCCR0A, WGM00); //SET TIMER0 TO NORMAL MODE
  CLR(TCCR0A, WGM01);
  CLR(TCCR0B, WGM02);
  TCNT0 = 0X00;
  SET(SREG, 7);
  SET(TIMSK0, TOIE0); // overflow interrupt enable
}

void enable_timer()
{
  SET(TCCR0B, CS00); //set prescalar to 1024
  CLR(TCCR0B, CS01);
  SET(TCCR0B, CS02);
}

int main()
{
  Serial.begin(9600);
  DDRD |= (1 << PD6); //LED CONNECTED TO DIGITAL PIN 6 ,and all the
  //bits of the port is set so as to make it an
  //output port
  timer0_init();
  enable_timer();
  while (1)
  {


    // the LED doesn't blink if this Serial.print is removed
    Serial.println(PORTD);

    //if(count==62)
    if (count == 31)
    {
      TOGGLE(PORTD, PD6);
      count = 0;
    }
  }
}

ISR(TIMER0_OVF_vect)
{
  count++;
}

It also fails if the printing line is moved to before the TOGGLE inside the if block.

Real UNO.

Rejiggering it as a traditional setup/loop sketch raises this error

wiring.c.o (symbol from plugin): In function __vector_16': (.text+0x0): multiple definition of __vector_16'
weird.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2: error: ld returned 1 exit status

Error during build: exit status 1

Which I make no sense of

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

#define SET(port,bit) port|=(1<<bit)
#define CLR(port,bit) port&=~(1<<bit)
#define TOGGLE(PORT,BIT) PORT^=(1<<BIT)


int count=0;

void timer0_init()
{
  CLR(TCCR0A,WGM00);//SET TIMER0 TO NORMAL MODE
  CLR(TCCR0A,WGM01);
  CLR(TCCR0B,WGM02);
  TCNT0=0X00;
  SET(SREG,7);
  SET(TIMSK0,TOIE0); // overflow interrupt enable
}

void enable_timer()
{
  SET(TCCR0B,CS00);//set prescalar to 1024
  CLR(TCCR0B,CS01);
  SET(TCCR0B,CS02);
}

void setup()
{
  Serial.begin(9600);
  DDRD|=(1<<PD6); //LED CONNECTED TO DIGITAL PIN 6 ,and all the
                  //bits of the port is set so as to make it an 
                  //output port
  timer0_init();
  enable_timer();
}

void loop() {


 Serial.println(PORTD); 

     //if(count==62)
    if(count==31)
    {
     TOGGLE(PORTD,PD6);
      count=0;
    }	
  }


ISR(TIMER0_OVF_vect)
{
 count++; 
}

Waiting on the heavies now...

a7

I was transferring from Arduino to avr-libc, and Arduino IDE was the verifying tool for this.

I found some advancement based on your finding - "_delay_ms(10);" added here, it was also OK.

So my guess for this: there is a short pause needed between iteration inside while(1).

and, it(_delay_ms(10):wink: was same - it didn't work either before "while(1)" or "TOGGLE".

what is the reason to involve the hassle of using your own main() function?

if there is a reason to use your own nain() function
what is the reason to use the arduino-ide instead of the "classical" gcc toolchain?

The arduino port couldn't be found by avrdude, so it was needed to use Atmel-ICE with Microchip Studio for programming, by Arduino IDE, the USB interface was OK.

I tried the same thing, in one version (main) or the other (setup/loop) and got the same odd compilation error, so eid not verify my intuitive feeling that it was the time the printing took that fixed things up.

I'll do it on the one I didn't just for fun.

Good experiment. Leaving us exactly remaining mystified, both as to the need for a pause and the weird error.

a7

The author forgot to declare 'count' as 'volatile'.

The author assumes that their main loop is running much faster than the timer interrupt. If it doesn't, it might miss the one interrupt between 30 and 32 where the equality check would work. They will then have to wait for the counter to run 65535 steps for it to again equal 31. The preferred version is:
if(count >= 31)

No I forgot nothing. What I did do is not look very closely or think too far beyond testing @MianQi's sketch.

a7

Sorry. I didn't notice that I was quoting your version of the sketch and not the original. I'll change that to say "the author".

THX. In any case, adding volatile to the declaration of count fixes things up. A good reminder for one who uses interrupts very rarely!

While you are looking closely, what am I not seeing here?

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

#define SET(port,bit) port|=(1<<bit)
#define CLR(port,bit) port&=~(1<<bit)
#define TOGGLE(PORT,BIT) PORT^=(1<<BIT)

volatile int count=0;

void setup() {
  DDRD|=(1<<PD6); //LED CONNECTED TO DIGITAL PIN 6 ,and all the
                  //bits of the port is set so as to make it an 
                  //output port
  timer0_init();
  enable_timer();
}

void loop() {
    if(count==31)
    {
     TOGGLE(PORTD,PD6);
      count=0;
    }	
}

void timer0_init()
{
  CLR(TCCR0A,WGM00);//SET TIMER0 TO NORMAL MODE
  CLR(TCCR0A,WGM01);
  CLR(TCCR0B,WGM02);
  TCNT0=0X00;
  SET(SREG,7);
  SET(TIMSK0,TOIE0); // overflow interrupt enable
}

void enable_timer()
{
  SET(TCCR0B,CS00);//set prescalar to 1024
  CLR(TCCR0B,CS01);
  SET(TCCR0B,CS02);
}

ISR(TIMER0_OVF_vect)
{
 count++; 
}

What doesn't compile:

wiring.c.o (symbol from plugin): In function __vector_16': (.text+0x0): multiple definition of __vector_16'
/var/folders/gz/t92bgl156gdf2066kn0xpc7w0000gq/T/arduino_build_669524/sketch/sketch_aug05a.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
exit status 1
Error compiling for board Arduino Uno.

With or without the (redundant?) # include files.

Oh, clue: commenting out the ISR(TIMER0_OVF_vect) thing (function) about which I must will learn, allows complikation to succeed.

Of course then the program does not function.

a7

Atmel / Arduino: ISR(TIMER0_OVF_vect) won't compile ("first defined" in __vector_16)

THX!

tl;dr:

[Using] the Arduino library [] already defines a handler for the TIMER0_OVF interrupt.

a7

I found some explanation here :
"TIMER0 is used by the Arduino library for the delay, micros and millis functions".

So I tried Timer2, it was OK:

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

int main(){ 
  TCCR2A = 0x00; // Wave Form Generation Mode 0: Normal Mode, OC2A disconnected
  TCCR2B = (1<<CS22) + (1<<CS21) + (1<<CS20); // prescaler = 1024
  TIMSK2 = (1<<TOIE2); // interrupt when TCNT2 is overflowed
  DDRD |= (1<<PD6);
  //sei();//enable global interrupt
  SREG |= (1<<7);//enable global interrupt

  while(1){
    ;
  }
} 

ISR(TIMER2_OVF_vect){  // Interrupt Service Routine 
  static int counter = 0;
  counter++;
  if(counter==60){
    PORTD ^= (1<<PD6); 
    counter = 0; 
  }
}

This is the tested code:

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

#define SET(port,bit) port|=(1<<bit)
#define CLR(port,bit) port&=~(1<<bit)
#define TOGGLE(PORT,BIT) PORT^=(1<<BIT)

volatile int count=0;


void timer0_init()
{
  CLR(TCCR0A,WGM00);//SET TIMER0 TO NORMAL MODE
  CLR(TCCR0A,WGM01);
  CLR(TCCR0B,WGM02);
  TCNT0=0X00;
  SET(SREG,7);
  SET(TIMSK0,TOIE0); // overflow interrupt enable
}

void enable_timer()
{
  SET(TCCR0B,CS00);//set prescalar to 1024
  CLR(TCCR0B,CS01);
  SET(TCCR0B,CS02);
}


int main()
{
  DDRD|=(1<<PD6); //LED CONNECTED TO DIGITAL PIN 6 ,and all the
                  //bits of the port is set so as to make it an 
                  //output port
  timer0_init();
  enable_timer();
  while(1)
  {
    //if(count==62)
    //if(count==31)
    if(count>=31)
    {
      TOGGLE(PORTD,PD6);
      count=0;
    }  
  }
}


ISR(TIMER0_OVF_vect)
{
 count++; 
}

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