Using Timers for Delays

Hi Everyone,

I am working on a project that uses the Ping sensor to drive the speed of an analog clock. The idea is that the clock will move faster as someone approaches the sensor. I have everything work individually, but (as always) integration is not going well. I want to make sure that using a timer overflow to emulate a delay() call is operationally the same. I attached the code snippets and flow diagrams for what I am hoping to accomplish.

The short description is that the analog clock’s coil needs to be charged with a logic high for approximately 10ms, and then a logic low. Since the delay function interferes with my sensors, I made a control structure in the Timer2 overflow as a replacement, but the clock does not function properly. Adding code to flash the LED on pin 13 shows me that period changes in accordance with the other functions of the program. I would really appreciate any help you guys could provide. Thanks!

Proof of concept

void doTick() {
 
  // Energize the electromagnet in the correct direction.
  digitalWrite(tickPin, HIGH);
  delay(500);
  digitalWrite(tickPin, LOW);  
 
  // Switch the direction so it will fire in the opposite way next time.
  if (tickPin == clockA)
  {
    tickPin = clockB;
  } else {
    tickPin = clockA;
  }
}
 
 
// Main loop
void loop()
{
  unsigned long startTime = millis();
  unsigned long temp;
 
  // Pretend to be a regular clock, and tick once a second.
  while (true)
  {
    startTime += 1000;
 
    // Wait until a second has passed.  Note that this will do ugly things when millis()
    // runs over, so we only have about 9 hours before this version will stop working.
    while (startTime - millis() > 0) {}
 
    doTick();
  }
}

My Timer Overflow with correct timing preloading, etc

ISR(TIMER1_OVF_vect) {
TCNT1=timerOffset; // set initial value to remove time error (16bit counter register)
  x=!x;  
  
  if (chargeTimer < 10)
  {
    digitalWrite(tickPin, HIGH);
    chargeTimer++;
  }
  else 
  {
    digitalWrite(tickPin, LOW);
    chargeTimer = 0;
    
     if (tickPin == clock1)
     {
        tickPin = clock1;
      } 
     else 
     {
        tickPin = clock2;
      }  
  }
}

timer_ovf_flowdiagram.gif

There are so many misconceptions here, I do not know where to begin. Let's say there is plenty of opportunity to learn :)

1: A millis() based timer first overflows at 49 days, as long as you carefully use unsigned long data type

2:the while(1) construct is duplicating the loop.

void loop() {
  while (1) {
     something() ;
  }
}

loop() gets called again and again and again.... (some purist say they can save the cost of 2-3 instructions by doing their own loop, but who has a program that is sensitive to a fraction of lost microsecond per pass in the loop?)

3:while (startTime - millis() > 0) {}The structure repeats what delay() does. Stays here until the penalty-box-timer has expired.


A suggested layout for getting your ticks right.

void loop() {
  static unsigned long secTimer = 0 ;
  unsigned long now = millis() ;

  if (now - secTimer > 1000UL ) { // second has elapsed
    doTick() ; 
    secTimer = now ; // reset so we tick on next second
  }

 //repeat for the timers that control your coils.
  if (now - othertimer > otherinterval) {
    digitalWrite(
    :
  }

Hi Msquare - You didn't mention 'Blink without delay'. Do you think blhunter might have realized that the 'Blink without delay' tutorial held the solution to his problem if that tutorial had a more appropriate name?

Don

Doh... :disappointed_relieved:

http://arduino.cc/forum/index.php/topic,76140.0.html http://arduino.cc/en/Tutorial/BlinkWithoutDelay

It was my intention and somehow I got lost in the convoluted code on what it was really trying to do ...

Perhaps we should rename "Blink Without Delay" as "The Answer"!

Thanks for the replies! I'll try out your suggestion Msquare. I did a lot of work on an Atmel MEGA 16 in undergrad with a custom platform and IDE specific to the school, and this is my first real swing at Arduino dev.