0

This might be more a general programming question, but I am using the Arduino compiler, and I've created my own ISR driven version of millis(), which I simply call myMillis(). So let's say I'd like to use this addition to a working project. Rather than do a global search and replace, I got the idea to simply put this define near the top of the program...

#define millis myMillis

uint32_t myMillis() 
  { // my code ...
  }

So when I compile, every instance of millis() does indeed compile as if I did a global search and replace. I like that, because it means I don't have to make the change permanent, and can easily comment out my defines to compare program operation.

My question is, if I do as I just explained, what if, for whatever reason, there is some place within the project where I actually WANT to call the original version. A simple example might be if I wanted to occasionally output a message via serial.println(), comparing the returned value of millis() and myMillis(). I think there is a way to specify such an exception to my #define MACRO, but I'm not sure how.

10
  • google c++ fully qualified function name or c++ name visibility or c++ name scope .... i think that may be what you are looking for ...... i think that your question relates to namespace
    – jsotola
    Commented Mar 16, 2018 at 20:03
  • Why did you create your own ISR function? What was wrong with the normal millis function?
    – Jot
    Commented Mar 16, 2018 at 20:07
  • @Jot: 2 reasons... 1) I created an ISR that counts time based on the pulsating DC from a transformer powered by AC, which over a course of days will be more accurate than the board clock, and 2) it makes it very easy to quickly detect detect when AC power is lost, so I can save some key date to EEPROM before the board power is completely lost. I'm leaving out some circuit details obviously.
    – Randy
    Commented Mar 16, 2018 at 20:19
  • The Arduino millis is very accurate, it uses the accuracy of the 16 MHz crystal or resonator of the Arduino board (when a Arduino Uno is used). The mains AC is in Europe 6 minutes behind at the moment. The resolution of your myMillis will be very course with 50 Hz or 60 Hz, some libraries might no longer work. To detect a power lost, about anything is better than using millis. I suggest to make your own functions and own interrupt, but keep millis as it is.
    – Jot
    Commented Mar 16, 2018 at 20:27
  • @jsotola No luck. For a moment I though specifying ::millis() would force a reference to the original, but it doesn't help. To prove it, I added an argument to myMillis with a default values (myMillis(uint8_t reset = 0); So now, if a subsequent call to ::millis(1) should fail to compile if I were referencing the system's millis(), because it would be one argument too many. But it compiles, so that won't do it. I couldn't see any other way.
    – Randy
    Commented Mar 16, 2018 at 20:31

2 Answers 2

3

There is no way to suppress define substitution. You could use #undef and then #define again in required section.

Name the define MILLIS and use this name in code, except where you want the original millis() function.

2
  • Thanks, but a global search/replace is just what I'm trying to avoid. And if I did, I wouldn't want to use the same name in caps, because it would make finding them with the search box impossible. Plus, putting my defines BEFORE includes of some of my own library routines lets me swap out the millis() calls in them too, but only in projects that need the replacement. Still, if you are correct that there is no reasonable way to suppress a #define sub, at least I know to move on. :-)
    – Randy
    Commented Mar 16, 2018 at 21:11
  • I guess I will do the opposite though, I'll create a separate _millis() that calls millis(), and put it before before my new define. Then I can substitute the very few places that need it with the underscore version, and still be able to replace all other uses without editing. Thanks again!
    – Randy
    Commented Mar 16, 2018 at 21:13
1

Not related to your problem, but it is worth noting that your define only exists in your sketch (known as a translation unit). Other translation units (the core, libraries, etc) never get to see it.

To make everything see it youould have to place the define in a location that everything sees, such as Arduino.h in the core, for it to affect anything other than your sketch.

Once you have replaced millis there is no way to unreplace it. You could, though, make use of the scope limiting I talk about above to make a separate translation unit (maybe a small library) with a single function in it that calls millis. As long as that never sees the define it will still see the original function name.

1
  • It seems that if I make the define BEFORE including any of my own saved library processes that use millis(), they do indeed re-compile with just my version. Thats good enough for me, and again a very convenient way of substituting a LOT without permanent editing. So perhaps I should just create a separate _millis() call that calls millis(), before my new definition, and just substitute the few places that need it with the underscore version.
    – Randy
    Commented Mar 16, 2018 at 20:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.