Question about setting internal timer and interrupts

Hi everyone, I am a rookie of Arduino.
I am now working on my project, but having problems about the setting of internal timer and interrputs.

Spec of my project:

  1. Arduino Mega 2560
  2. Arduion IDE 1.0
  3. Communication between Arduino and computer to transmit several non-time-sensitive information every 5 sec
  4. Function delay() will be used, but seems I will not use millis(), micros(), and delayMicroseconds()
  5. At least 2 PWM signal will be used

The situation is, I have to obtain a time-sensitive information every 1 sec.
Since it is very time-sensitive and the Arduino will have other works to do
polling for 1 sec notification from computer is not an option for me
and I think internal interrupt is my only choice

I have checked the datasheet and discovered that there are several registers to control different timer.
But the information is so complicated that I still don't understand the relationship and purposes of those registers.
I have also searched for relative topics in this forum, which confuse me more
It seems that those timers in the chips have different things to do, some for functions of Arduino, some for PWM signal
I am afraid that wrong setting on the timer (or setting on the wrong timer) will affect the original functions.

To summarize, I have the following questions:

  1. I cannot figure out the purposes and relationship of different types of timer registers
    I would like to ask for some explanation on that, for my project and for my knowledge on Arduino XD
  2. For those timer registers used , what are the settings to have a 1 sec timer?
  3. Can the timer trigger an interrupt without any polling on timer flag status?
    If yes, how to do that, and if it is impossible, is there any alternative solution that I can think about?

Thanks everyone :smiley:

not sure i understand it fully, but would you be able to use the micros() function to time it?

dumle29:
not sure i understand it fully, but would you be able to use the micros() function to time it?

Seems using micros() will make use of polling and not very suitable for time-sensitive operation? :cold_sweat:

What is the time sensitive part?

Is it time sensitive to get the serial data to the computer? That will have some inherent latency, from the computer serial drivers and operating system.

What is the source of the time sensitive data? Some external event?

Also, the "time insensitive" thing you do every 5 seconds may still affect the timing of the "time sensitive" part, because the Arduino serial driver uses interrupts, and while that's running, your timing sensitive code cannot run.

Finally, how timing sensitive is the "sensitive" part? How much "off" can you be? What is it?

The time sensitive job is to get the current flow, so to have charge counting
The current data will be represented by voltage through hall-effect sensor
The Arduino will get that data by analogread()
It is expected that for every second there should be one data
So that's why I need a 1 sec interrupts

For the serial communication, I know it is using interrupts in IDE1.0
But is there any priority for different priority?
As far as I know, the interrupts of higher priority should be OK even if an ISR is working
Also, is now the serial communication can be executed like an ISR?
I cannot found similar example on that

You should ask yourself just how time sensitive your data collecting needs to be, +/- how much. And if it's critical then look into a Real Time Clock module.
If it can be off by 1% then don't bother since you can print the data in less than 1 full second and use millis() to know when to make the next read within a few microseconds. The 1%... well you can probably beat that without an RTC but I dunno just how close Arduino Mega clocks are when Serial.print is used.

im359:
The time sensitive job is to get the current flow, so to have charge counting
The current data will be represented by voltage through hall-effect sensor
The Arduino will get that data by analogread()
It is expected that for every second there should be one data
So that's why I need a 1 sec interrupts

I think you'll do OK by just reading and reporting the data once every second, by polling millis(). You may be a millisecond or two off at times, but that's much less than your computer's serial port will vary. If you average over a few samples, you'll get a very stable reading, assuming the hall effect sensor is good.

The sketch would simply do something like:

unsigned long lastTime;
unsigned long periodicTask;

setup() {
  Serial.begin(9600);
  lastTime = millis();
  periodicTask = lastTime;
}

loop() {
  unsigned long now = millis();
  if (now - lastTime >= 1000) {
    lastTime += 1000;
    int value = analogRead(HALL_SENSOR_PIN);
    Serial.print("R%d\n", value);
  }
  else if ((now - lastTime) < 500 && (now - periodicTask) >= 5000) {
    periodicTask += 5000;
    // do your periodic task communication
  }
}

This will defer the periodic task if there's less than 500 milliseconds left until the next reading interval, which should be plenty to make sure that the reading happens on time.

Note that, if loop() is written right, it will be run several times per millisecond, so you will be very precise when writing it like this.

However my communication is initiated by the computer, but not Arduino
Also I cannot sure the loop() content can be finished within 1 second at the moment
The reason is I don't know the exact clock cycle required to finish one particular syntax

At the moment I still prefer the interrupt one
The above is one of the reason (execution time of the whole loop() function)
Another reason is, I would like to know first, is interrupt based serial communication stop all other interrupt,
despite of the late interrupt has a higher priority? :~

You can write a loop and check on how long it takes. At 16 MHz you have 16 million cycles per second though sending a serial transmission might take... well not very long actually since you can transmit 11520 characters a second over a good connect. Not that your Arduino chip is doing more than filling a serial buffer at the Arduino end, you'd probably need to time that in 100's of microseconds. If you're doing analog reads, a single read takes about 100 microseconds.

It really comes down to how closely you need to hit exact seconds.

An easy way of generating a regular timer interrupt is to use the MsTimer2 library, Arduino Playground - MsTimer2. But you should only do what you propose in a timer interrupt if the amount of work that needs to be done is small so that the ISR can execute and return quickly.