Go Down

Topic: Timer1 - how do you set a 1 minute timer? (Read 17367 times) previous topic - next topic

Ps991

I posted code above showing you how to use the prescalers and that code works if you want it to check every 1 minute. Did you miss that or are you saying that it still doesn't work with your code?
If you can't write your program in plain english where anyone could understand it then you have no hope of writing code for it.  -Delta_G

Ps991

#16
Aug 21, 2016, 03:56 am Last Edit: Aug 21, 2016, 03:57 am by Ps991
The first bit of code takes about 2.3268 uS to execute just the if statement because the condition was always false.

The second bit of code takes about 0.3144 uS to execute.

Code: [Select]

volatile int i = 0;
volatile unsigned long lastTime = 0;
volatile boolean flag = false;
unsigned long startTime = 0;
void setup() {
  Serial.begin(115200);
  startTime = micros();
  for(i = 0; i < 10000; i++) {
    //if(millis() - lastTime > 60000)
    //  lastTime = 0;
    if(flag)
      flag = false;
  }
  Serial.println((micros() - startTime));
}

void loop() {
  // put your main code here, to run repeatedly:

}

//11948 for statement
//15092 boolean flag
//35216 millis - unsigned long
If you can't write your program in plain english where anyone could understand it then you have no hope of writing code for it.  -Delta_G

boylesg

I posted code above showing you how to use the prescalers and that code works if you want it to check every 1 minute. Did you miss that or are you saying that it still doesn't work with your code?
OK I get what you are doing.

Instead of setting a flag in the ISR you add to a counter, and then just check the value of the counter instead of the value of a flag.

It has not occurred to me to implement INTs like this previously so thanks for the idea - all the examples I have seen involve boolean flags.

But I could do that with my roughly 8 second ISR because I don't need absolute precision.

And I would need to disable INTs if a HTTP request is detected because my web page takes about 10 seconds or so to download.

So which would you suggest is the best solution for the situation below?

Polling millis() as others have suggested or your method?

Code: [Select]
void loop()
{
  nElapsedMillis = millis() - nLastMillis;
  if (nElapsedMillis < 0)
    nElapsedMillis = ((uint32_t)-1 - nLastMillis) + millis();
   
  // If a minute has elapsed...
  if (nElapsedMillis >= 60000L)
  {
    debugS(String((double)nElapsedMillis / 1000));
/*
    noInterrupts();
   
    // Then iterate through all the programs, for all stations and for today's date, and we need to run any of them based on the current time.
    program.run();

    // If start of a new day then....
    if (rtc.getHours() == 0)
    {
      // Read in the program for each station for the new date.
      if (!program.read())
        printError(__FILE__, __LINE__);
    }
    interrupts();
*/
  }
  if (serialHC05.available() > 0)
    processBTData(serialHC05);

  // Listen for incoming clients
  WiFiEspClient WifiClient = WifiServer.getClient();
 
  if (WifiClient)
  {
    WifiServer.processHTTPRequest(WifiClient);
  }
}



Ps991

It still depends, mainly on what you are doing every 1 minute.

If you really want it to poll every 1 minute, or your download has the possibility of taking longer (such as a slower connection or larger file), then use the interrupt.

If using interrupts breaks your code or causes problems in the downloading process, then don't use it.

Another option would be to make the download process non-blocking, but that may be quite a process or even not possible.

Just be aware that interrupts are not made for large chunks of code that take a lot of time, they are made for quick little snippets of code that are generally sensitive to when they are executed.
If you can't write your program in plain english where anyone could understand it then you have no hope of writing code for it.  -Delta_G

Robin2

#19
Aug 21, 2016, 09:51 am Last Edit: Aug 21, 2016, 09:52 am by Robin2
Because if I did it that way I would be continuously polling for a few different things in my loop() and it may start degrading performance.
That implies {a} that you don't know, {b} that it is not very probable and {c} that you have not told us everything.

If it was my project I would wait until I had a problem before I tried to fix it. :)

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

boylesg

#20
Aug 21, 2016, 01:10 pm Last Edit: Aug 21, 2016, 01:12 pm by boylesg
That implies {a} that you don't know, {b} that it is not very probable and {c} that you have not told us everything.

If it was my project I would wait until I had a problem before I tried to fix it. :)

...R
It is not really broken - I had a very specific problem as I posted.

I didn't realise that you couldn't set any timers for 1 minute, at least not directly.

Everything else in the project is working fine and I am merely trying to work out the best strategy to use with my timed (1 minute) function calls in loop().

I.E. Use the interrupt plus counter or simply poll millis() in loop() as has been suggested.

And after just trying the first method it appears that setting an interrupt on TimerOne interferes with WifiESP some how so I can't use that method.

AWOL

Don't forget to factor-in the interrupt pre and post-amble.

Ps991

#22
Aug 21, 2016, 09:02 pm Last Edit: Aug 21, 2016, 09:02 pm by Ps991
The ESP uses Serial, so you have 2 options for interrupts.
1) Make the serial buffer larger, which will take more time to fill it up and you interrupt has more time to execute before it becomes a problem. This method is not recommended b/c it could pose problems in the future
2) After the interrupt happens, check to see if there is 64? bytes of data in the buffer and if there is, then that is most likely an overflow. Throw away that data, empty the buffer, and re-request the data.
If you can't write your program in plain english where anyone could understand it then you have no hope of writing code for it.  -Delta_G

MorganS

I suppose I could stick my bluetooth polling inside the above check as well, because I don't really need to poll for incoming bluetooth data every X microseconds.
That already sounds like a bad idea. Most Arduino bluetooth devices are plain serial. Even at the relatively pedestrian 9600 baud, you get about 960 characters per second. That means you need to check the serial buffer at least 15 times per second to prevent the buffer overflowing. With a properly constructed loop, it is simple to do this check hundreds or thousands of times per second.

Remember the computers work for us. We don't have to make their job easy. The basic Arduinos have 16 million instructions every second, whether they are doing useful work or just waiting for the next serial character to arrive. "Hey! You! I want you to look at this input 16 million times and let me know if it changes, okay?"
"The problem is in the code you didn't post."

Robin2

If you are receiving Serial data have a look at the examples in Serial Input Basics - simple reliable ways to receive data. There is also a parse example.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Go Up