Arduino's init() stops Timer/Counter2 after 47 interupts

Go To Last Post
12 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

 

For a school assignment I am trying to get Timer2 working. I need to "wait" a couple seconds at some point in the program and we are not allowed to use Delay(), _ms_delay(), or millis() or similar functions.

So, I need to use a Timer. Timer0 and 1 are already occupied for other purposes. Timer2 needs to give an interrupt every 0.5 ms and while it works, it only works for 47 times. It just halts after. I know this is because of init(), but I do not know what it is what makes it stop. This is my code I have currently:

 

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <Arduino.h>
#include <Wire.h>
#include "Source Files/Move.cpp"

#define BAUD 9600
#define WAIT 500

// Setup function that initializes the game.
void GameSetup()
{
    init();
    Wire.begin();
    Serial.begin(BAUD);
    Move.begin();

    //reset Timer2
    TCCR2A = 0x00;
    TCCR2B = 0x00;
    OCR2A = 0;
    TIMSK2 = 0x00;

    // Reset external interrupt registers.
    EICRA = 0x00;
    EIMSK = 0x00;

    //set Timer2
    OCR2A |= 125;           // Timer 0.5ms.
    TCCR2A |= (1 << WGM21); // CTC mode.
    TCCR2B |= (1 << CS22);  // Prescaler: 64.

    TIMSK2 |= (1 << OCIE2A);

    sei();

    _delay_ms(WAIT);
}

// Function that contains everything that needs to run within the gameloop.
void GameLoop()
{
    Move.doMove();
}

// Main function that runs the game.
int main()
{
    GameSetup();

    while (1)
    {
        GameLoop();
    }

    return (0);
}

ISR(TIMER2_COMPA_vect)
{
    Serial.print("x");
    Move.Timer2Interrupt();
}

 

It runs just "fine" when I remove init(), but I need it for Serial, Wire and some other libraries. So my question is: What in init() is making Timer2 stop?

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Welcome to AVRFreaks!

 

I'm a bit confused, the topic is arduino, but I don't see setup() Loop() functions???

 

So suggest you zip up your entire project so others can build and help you trouble shoot your project.

Just as a hint, interrupts are best kept short, things like Print is too slow and should be avoided with in ISR()'s.

Bettter to set a flag and let main() handle background printing.

As for Arduino functions, it is open source so nothing is hidden, it just take a little research to determine what a function does/does not do.

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Jim, 

 

Thank you for your reply.

You are right, there are no setup() and Loop() functions. I am not using the Arduino language (.ino), but just C++. However, I am using the Arduino library and because this question is about the library I figured to ask it here.

 

I know to keep interrupts short and let main() do the work, but for this should be fine for testing purposes.

There is a zip attached to this post with all the files. This should build just fine.

And I have not yet figured out what in init(), or the methods called by init() is causing this behavior.

Attachment(s): 

Last Edited: Wed. Dec 4, 2019 - 06:55 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Luuk777w wrote:
replay

* reply

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Whoooops, thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Luuk777w wrote:

//set Timer2
    OCR2A |= 125;           // Timer 0.5ms.
    TCCR2A |= (1 << WGM21); // CTC mode.
    TCCR2B |= (1 << CS22);  // Prescaler: 64.

    TIMSK2 |= (1 << OCIE2A);

This may not be your problem, but it is best to just set device registers using "="  rather then using "|=" in the above code.

 

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh okay, I did not know it's better setting it that way, although I can see why it might be. My teacher toughed us using the bitwise operators.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Luuk777w wrote:
. My teacher toughed us using the bitwise operators.

I'll refrain myself from saying what I think of your teacher, but bitwise operators have their place and are useful to know, but not appropriate for use when init'ing a register where you need to set all the bits to known values.   It makes sense when say, setting the ADC reg to start a conversion, or to change a port bit, etc.

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Calling functions that rely on interrupts from an isr can be a recipe for disaster. Doing a serial.print might be causing the issue you observe. I have no idea of what your move object does, so you might be doing something suspect there as well.

The isr is a separate thread of execution as are callbacks from libraries like Wire. You need to be careful of what your code does.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Boy, this is weird code.   It is really difficult to follow.  Does the code work inside the standard Arduino format {with setup() and loop() }?

 

I can't find the code for  init().    Where is it?    If you can't find it, how do you know that it is needed?   Avoid using overly-generalized names for functions like init().  Be specific,  like initGameModule().  Is it in wire.h, serial.h, or arduino.h?

 

Since the problem is not likely in the game part of the main code, disable all the game code and see if it changes the timer2 operation.   Try printing a "+" on the screen for every 1000 times that the Timer2 IRQ is called.

 

There is a variable called "counter" that should be declared as volatile because it is examined and changed from inside an interrupt service routine.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Okay, turns out, I am just a big dummy... I thought init() was the problem because it caused problems in the past. When I removed init() I couldn't use the Serial library anymore, so I just used usart without the library. Printing using Serial(the library) caused the behavior. I only add to count in my ISR now and it works just fine. Apologies for wasting your time guys.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for feeding back with the solution - now see Tip #5.

 

Apologies for wasting your time guys

Never a waste of time when you've learned something in the process!

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...