Go Down

Topic: millis() always returns 0 (Read 2764 times) previous topic - next topic

Malvineous

Hi all,

I have a strange problem.  When I call millis() it works fine, but if I put millis() inside another function it always returns zero:
Code: [Select]

clock_time_t clock_time(void)
{
     return millis();
}

Printing the return value of clock_time() is always zero.  clock_time_t is defined as unsigned long.

I tried making it return i++ and I got a number that kept incrementing, so it can't be any kind of optimising out that might be going on.

I also can't reproduce this in a sketch - clock_time() is part of a library function in a .c file, but I can't understand why this would make a difference.

Any ideas what might be going on?

PaulS

Do you need to cast the return from millis() to a clock_time_t? The millis function returns an unsigned long. How that relates to a clock_time_t is unclear.

Malvineous

#2
Feb 15, 2010, 12:08 am Last Edit: Feb 15, 2010, 12:24 am by Malvineous Reason: 1
Thanks for the suggestion.  Unfortunately that doesn't make a difference.  clock_time_t is defined as unsigned long so it shouldn't need a cast:
Code: [Select]
typedef unsigned long clock_time_t;
Strangely enough if I change the function to return millis()+5; then it always returns 5.

EDIT: Actually I just left it running like this and it seems that millis() does actually increment, only very slowly.  After about 10 minutes millis() returns 16...

Coding Badly

#3
Feb 15, 2010, 06:58 am Last Edit: Feb 15, 2010, 06:58 am by bcook Reason: 1

You're barking up the wrong tree.  This works fine...

clockstuff.h ...
Code: [Select]
#ifndef clockstuff_h
#define clockstuff_h

typedef unsigned long clock_time_t;

#endif


Sketch...
Code: [Select]
#include "clockstuff.h"

clock_time_t clock_time(void)
{
 return millis();
}

void setup( void )
{
 Serial.begin( 9600 );
}

void loop( void )
{
 Serial.println( clock_time() );
 delay( 1000 );
}

Malvineous

Yeah I know, that's why I said I was unable to reproduce the problem in a sketch.  It seems to have something to do with the external .c files.

At any rate this is the only thing stopping the library from working, so I might just post it as a beta release and you can try it out and see if you get the same behaviour.

mellis

Do you have #include <WProgram.h> in the external C file?  Or a declaration (prototype) for the millis function:

unsigned long millis(void);

C will let you use functions without prototypes, I believe, but it will assume that they return an int (I think), which can cause this kind of problem.

Malvineous

Ah, that was the problem!  I added the #include line and now millis() returns the correct value.  I'm surprised I didn't get any compiler warnings.  Maybe the Arduino IDE assumes the external libraries already work :-)

Thanks for the fix!

Coding Badly

Quote
I'm surprised I didn't get any compiler warnings

I think the C++ compiler does produce a warning for undefined functions.

jvincent

I had this same strange problem while building using eclipse AVR cross compiler. This is how I fixed it.

Added this on the Main.cpp

extern "C" void __cxa_pure_virtual() {
       cli();
       for (;;);
}

And called wiring.h init() function as the first line of code in main() method.

BTW, please don't call me stupid, I just started learning c/c++, Arduino

westfw

Quote
I just started learning c/c++, Arduino

Then why are you doing it the hard way?

The Arduino environment is not just a rather klutzy editor with code formatting and coloring capabilities.  It does a bunch of other stuff before handing a sketch to the compiler.
If you really want to use something like Eclipse for Arduino development, you had better be very sure that you have the Eclipse environment set up to do all the things that the arduino environment does: includes the right include files, calls the right initialization functions, handles the C vs C++ issues, etc.   This is, IMNSHO, not a "beginner" task, and I wouldn't trust random "Set up Eclipse like this" instructions you might find on the net; they are probably aimed at experienced Eclipse users with much more C/C++ background...

I mean, look at this:
Code: [Select]
extern "C" void __cxa_pure_virtual() {
      cli();
      for (;;);
}

No beginner should have to include "mysterious incantations" like that in their code.  The Arduino team has put some significant thought into what sort of magic the users should be able to leave out (declarations of forward referenced funcions), and what they still need to have ("void" declaration of setup() and loop()), and it goes largely unappreciated because the know-it-alls would have been used to it, and the newbies don't see what they're missing...

jvincent

Hi Westfw,

Thanks for your expert opinion and advice. When I write real production code, I will stick with Arduino IDE. I am a very early adapter of eclipse and got exploited by its powers for more than a decade, I simply couldn't resist the eclipse platform for learning, it works well for me for much faster learning. BTW, Arduino truly rocks, especially for a Java developer.

westfw

Ahh.  I have trouble giving up Emacs, too...   Well, be sure to look at http://arduino.cc/en/Hacking/BuildProcess for an explanation of what the build process does that is "special" and see the verbose build logs from the IDE (hold down SHIFT while compiling) to make sure you match the latest build options...

Perhaps with your background, you can fix up the Eclipse instructions and make it work better for others...

pluggy

Quote
a rather klutzy editor


Heresy !  ::)
http://pluggy.is-a-geek.com/index.html

Go Up