Black Lives Matter - Action and Equality. ... Adafruit is open and shipping.
0

timing an application
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

timing an application

by LLavigne on Fri May 30, 2008 2:27 am

I want my arduino to be second accurate
I use delays to get a blink every second and I put all that in a series of for loops so I get 12 blinks 12 times 12 times (144 blinks)
At the end of the 144 blinks, I need it to have spanned 28 minutes 48 seconds - will the controller be this accurate, do control loops eat up enough cycles that I will be off by say 1/10s of a second ?

Thanks

(I'm lovin' it)
_____________
www.previs.org
LLavigne
 
Posts: 6
Joined: Thu May 08, 2008 4:52 pm

by ahoeben on Fri May 30, 2008 6:51 am

If you're only using delay()s, the inevitable timing errors you are going to get will accumulate. This will never be very precise.

Have a look at this alternative way of making 'delays' between actions:
http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

This depends on the 'millis()' function, which is a lot more accurate than stacking up delay()s. There's an issue after about 9 hours, but your requirements seem to be well within that limit.

ahoeben
 
Posts: 21
Joined: Fri Apr 25, 2008 3:18 pm

by mtbf0 on Fri May 30, 2008 7:47 am

yeah, but arduino milliseconds are actually a little short, so don't go expecting miracles.
User avatar
mtbf0
 
Posts: 1645
Joined: Sat Nov 10, 2007 12:59 am
Location: oakland ca

by LLavigne on Fri May 30, 2008 3:45 pm

Akin to creating my own event handler - is there a smart way to create co-routines ?
_____________
www.previs.org
LLavigne
 
Posts: 6
Joined: Thu May 08, 2008 4:52 pm

by mtbf0 on Sat May 31, 2008 8:51 am

LLavigne wrote:Akin to creating my own event handler - is there a smart way to create co-routines ?


timer interrupts. it's kind of beyond the scope of regular arduino programming, since they try to obfuscate all the fun stuff. you will have to refer to the mega168 datasheet. it's 376 pages but you only need to read the bits about timers and interrupts.

the problem with one second is that you can't get it by dividing the arduino clock by a power of two. for example, if you look at the arduino sources you will find that timer 0 is set up with a prescaler of 64 to count from 0 to 255. this is the basis of the millis() function, but if you do the math 16MHz / 64 / 256 is 976.5625Hz, which makes your milliseconds 1.024ms long.

you can do better, but it takes a little work.
User avatar
mtbf0
 
Posts: 1645
Joined: Sat Nov 10, 2007 12:59 am
Location: oakland ca

by LLavigne on Mon Jun 02, 2008 3:14 pm

Thanks,

I went the millis() route and I am getting some odd behaviour, the beeper stop being in sync with the second beep after it hits the first 12 iterations
I wonder what causes that

Code: Select all | TOGGLE FULL SIZE
// samadhi

int ledPinBeat = 13;                // LED connected to digital pin 13
int ledPin12Seconds = 12;
int ledPin12Iterations = 11;
int ledPinFullSequence = 10;
int beepPin = 3;

int valueBeat = LOW;                // previous value of the LED
int value12Seconds = LOW;   
int value12Iterations = LOW;
int valueFullSequence = LOW;   

long timeBeep = 0;

long previousBeat = 0;
long previous12Seconds = 0;
long previous12Iterations = 0;
long previousFullSequence = 0;

long intervalBeat = 1000;   
long interval12Seconds = 12000;
long interval12Iterations = 144000;
long intervalFullSequence = 1728000;

long m = 0;

void setup()
{
  pinMode(ledPinBeat, OUTPUT);
  pinMode(ledPin12Seconds, OUTPUT);
  pinMode(ledPin12Iterations, OUTPUT);
  pinMode(ledPinFullSequence, OUTPUT);
  pinMode(beepPin, OUTPUT);
  m=millis();
  previousBeat = m;
  previous12Seconds = m;
  previous12Iterations = m;
  previousFullSequence = m;
}

void loop()
{
  m=millis();
 
  // beat every second ledPinBeat
  if (m - previousBeat > intervalBeat)
  {
    previousBeat = m;
    if (valueBeat == LOW)
      valueBeat = HIGH;
    else
      valueBeat = LOW;
//    digitalWrite(ledPinBeat, valueBeat);
    timeBeep = m+2L;
  }
 
  // beat every 12 seconds ledPin12Seconds
  if (m - previous12Seconds > interval12Seconds)
  {
    previous12Seconds = m;
    if (value12Seconds == LOW)
      value12Seconds = HIGH;
    else
      value12Seconds = LOW;
    digitalWrite(ledPin12Seconds, value12Seconds);
    timeBeep = m+50L;
  }
 
  // beat every 12 iterations ledPin12Iteratuibs
  if (m - previous12Iterations > interval12Iterations)
  {
    previous12Iterations = m;
    if (value12Iterations == LOW)
      value12Iterations = HIGH;
    else
      value12Iterations = LOW;
    digitalWrite(ledPin12Iterations, value12Iterations);
    timeBeep = m+100L;
  }
 
    // beat every full sequence ledPinFullSequence
  if (m - previousFullSequence > intervalFullSequence)
  {
    for (int i = 0 ; i<20 ; i++)
    {
       analogWrite(beepPin, 8);
       digitalWrite(ledPinFullSequence, HIGH);
       delay (100);
       analogWrite(beepPin, 0);
       digitalWrite(ledPinFullSequence, LOW);
       delay (100);
    }
  }
 
  if (timeBeep > m)
  {
        analogWrite(beepPin, 2);
  }
  else
  {
        analogWrite(beepPin, 0);
  }
 
}
 
_____________
www.previs.org
LLavigne
 
Posts: 6
Joined: Thu May 08, 2008 4:52 pm

Please be positive and constructive with your questions and comments.