When to use which wiring.c files

This may be a question about programming style as much as substance. I have been programming C on PICs for years but I am new to Arduino.

There are many wiring_xxx.c or .h files supplied with arduino 1.0. None of the example files seem to load any of them. Without searching through each one to create my own index, how do I tell when I need one on more?

I want to use the timer interrupt used by millis() to count down some software timers of my own. To do this it seems I need to modify wiring.c. But the 'Blink" example program uses delay() which is located in wiring.c without #including it. Does that mean wiring.c is precompiled and invisibly linked when Blink is compiled? If I change wiring.c do I need to explicitly pre-compile it, or do I need to #include it, or will the compiler mystically handle this on its own?

Should I make my own differently named copy of wiring.c that has my modifications? How do I know the compiler will use SIGNAL(TIM0_OVF_vect) from my copy instead of the same named SIGNAL(TIM0_OVF_vect) from the original wiring.c?

There are many wiring_xxx.c or .h files supplied with arduino 1.0. Without searching through each one to create my own index, how do I tell when I need one on more?

All are included as part of the automatic include of Arduino.h.

If I change wiring.c do I need to explicitly pre-compile it

No. All of the 'core' files are compiled each time they are needed. If you think you need to edit the Arduino core to get something done it usually means that you are trying to do something the hard way. If you need a timer it's probably best to use one of the OTHER timers rather than Timer0 which the Ardiuno core uses.

How do I know the compiler will use SIGNAL(TIM0_OVF_vect) from my copy instead of the same named SIGNAL(TIM0_OVF_vect) from the original wiring.c?

Use one of the other timers.

Thanks, maybe I am doing this the hard way.

What I think I want is to set a variable for say 1 hour in the future (3600,000ms) and have a timer interrupt decrement the variable until it hits zero. The main loop can then do its own work and test the variable as a flag at its own convenience. When the flag tests zero the main loop executes the delayed function. Actually 1 second resolution would be fine but since a 1ms interrupt already exists I though it would be easy to use it.

Is there a cleaner way to do this?

Use millis(). Basis of blink without delay.

unsigned long duration = 3600000UL;

capture the starting time

unsigned long startTime = millis();

then see if enough time elapsed:

if ((millis() - startTime)) >=duration){ // do something }

unsigned long startTimer = 0;

void loop()
   {
   unsigned long currentTime = millis();
   if (currentTime - startTimer > 60UL*60UL*1000UL)  // 1 hour in milliseconds
       {
       //  This executes 1 hour after the Arduino starts
       startTimer = currentTime;  // And again every hour after that.
       }
    }

If you want the Arduino to just do nothing for an hour: delay(60UL60UL1000UL);

Note: Timer0 does not interrupt every millisecond (16,000 cycles). From wiring.c: “// the prescaler is set so that timer0 ticks every 64 clock cycles, and the overflow handler is called every 256 ticks.” So that’s 16384 cycles or 1.024 milliseconds.

That requires two long subtractions each time through Loop. At least I would do this to use only 1 subtraction:

unsigned long duration = 3600000UL;

capture the starting time

unsigned long endTime = millis() + duration;

then see if enough time elapsed:

if (millis() - endtime < 0){
// do something
}

What I want is to have a timer that will create a short PWM burst about every hour or two for about 10 seconds. The exact interval, duration, and PWM level will be set by serial input and can be changed on the fly. So I need to check for serial input at any time while I am waiting for the burst time.

Eventually I will want to monitor voltages too and use the voltage readings to influence to PWM burst timings.

SherpaDoug: That requires two long subtractions each time through Loop.

Two?

Yes, two.

if ((millis() - startTime)) >=duration){

First the CPU must subtract startTime from millis.

Then it must compare the result to duration. Every CPU I have seen does a compare of two numbers by subtracting them and then looking at the status bits. The only compare you can do without subtracting is a compare to zero.

Ah yes. The comparison.

Your version is certainly more "efficient". In your attempt to shave off four one cycle machine instructions you've created code that does not work correctly. The compiler recognizes that your if-condition can never be true so the entire if is optimized away. You may want to reconsider using @CrossRoads' version or @johnwasser's version (with the comparison changed to >=).

What are you expecting to gain with your 4 cycles per loop? You're going to spend far far longer waiting on the A/D each time than you'll spend testing the loop condition.

Oh yes, I missed the "unsigned". As long as endTime is declared as signed it should work.

I guess my instinct for efficiency has developed from trying to get the most from 2k of BASIC in the 1970's, 68HC11 assembler programming in the 1980's, and squeezing the utmost from PICs in C in the 1990's. I ALWAYS have my loops end at zero unless there is a compelling reason to do otherwise. I don't even think about it anymore. Sometime is it pointless. Sometime it can buy you battery life or let you use a smaller battery which saves size, weight, cost, market share, etc.

unsigned long duration = 3600000UL;
// capture the starting time
unsigned long endTime = millis() + duration;
// then see if enough time elapsed:
if (millis() - endTime < 0){
// do something
}

One major problem there. Since millis() and endTime are both unsigned, the result of the subtraction will never be less than 0.

You might try to fix that with this:

if (millis() > endTime){
// do something
}

That works until millis() gets up to about 0xFCA00000… then endTime = millis() + duration; wraps around and produces a small number. For the next hour millis() will ALWAYS be greater than endTime. So every ~47 days your code will go crazy for an hour. :slight_smile:

The only thing that works is (millis() - previousTime > interval). Sorry.