How to check current time?

Hi, I am new to using Arduino. What I want to do right now is interface a magnetic sensor that detects revolutions for a wheel. I want to be able to calculate the speed of the rotation. For this I would need distance/time.

Is there any way to easily check the time, or some signal related to time, using some C code? I would ideally like to check the time twice (interval between rotation).

Thanks for any help, much appreciated!
czhe

Hi,

have a read about the pulseIn command, it can tell you how much time has passed between revolutions of the wheels.

http://www.arduino.cc/en/Reference/PulseIn

Hi, thanks so much for the help!

I've ran into another problem since getting this to work. I can't seem to use 'print' or 'println' with numbers of type 'float'. I would actually like a precise display (with decimal places) of the final speed.

Is there a way to do this?

Thanks again,
czhe

I posted a solution in this thread http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1207226548

Hi, thanks for your help, I have that working now.

On the other hand, my code overall is very glitchy. Basically I want to detect the rotation of a wheel by using a magnetic sensor. There is a piece of magnet on the wheel that passes the sensor once every rotation.

I have the following code to detect the rotations and output the duration between each revolution using the function mentioned above called 'pulseIn'.

int switchPin = 4; // the pin that my switch uses
int check = 0; // check if the pin is high (1) or low (0)
unsigned long duration; // store the duration returned by the pulseIn function

void setup ()
{
  Serial.begin(9600);
  pinMode(switchPin, INPUT); // set pin 4 to input type
}

void loop ()
{

    duration = pulseIn(switchPin, HIGH, 10000000); // as soon as pin becomes HIGH, starts timer, as soon as pin goes to LOW, stop timer, return interval in microseconds
    Serial.print("duration is ");
    Serial.println(duration); // display duration in serial monitor
    
    check = digitalRead(switchPin); // check the switch signal
    Serial.print("check is ");
    Serial.println(check); // display switch signal in serial monitor
}


void printDouble( double val, unsigned int precision) {
// prints val with number of decimal places determine by precision
// NOTE: precision is 1 followed by the number of zeros for the desired number of decimial places
// example: printDouble( 3.1415, 100); // prints 3.14 (two decimal places)

    Serial.print (int(val));  //prints the int part
    Serial.print("."); // print the decimal point
    unsigned int frac;
    if(val >= 0)
        frac = (val - int(val)) * precision;
    else
        frac = (int(val)- val ) * precision;
    Serial.println(frac,DEC) ;
}

I think as soon as the pulseIn function is run once, my switchPin always shows as 0 in the monitor. But the rotations continue to be detected. However, everytime the magnet completely passes over the sensor, I get two returns of duration, one that is much larger than the other. I am not sure why this is happening. Also, sometimes a duration of 1 is outputted.

Can anyone help me out?

Thanks a bunch,
czhe

pulseIn (high) will time the duration of the high pulse, so it returns when the pulse has gone low. That's why your digitalRead gets a low value.

I think you want to measure the duration of a complete cycle, high to low and back to high again.

To do that you need to do two pulseIns and add the time together.

Duration1 = pulseIn(switchPin, HIGH, 10000000);
Duration2 = pulseIn(switchPin, LOW, 10000000);
Serial.print("total duration for one revolution is ");
Serial.println(duration1 + duration2); // display duration in serial monitor

Try it and see if it works.

BTW, a problem with this is that any processing or printing you do after the pulseIns will reduce the accuracy of the readings, but if the rotation is relativly slow it may be good enough.

If not, there ways to measure the time using timers, but it's a little more complicated the the solution above.

Thanks a lot for your help, I just tried the code. I am seeing much more reasonable numbers now but they always come in pairs.

This is all I have in my loop for now:

    duration1 = pulseIn(switchPin, HIGH, 10000000);
    duration2 = pulseIn(switchPin, LOW, 10000000);
    Serial.print("duration for one revolution is ");
    Serial.println(duration1 + duration2);

It seems that everytime I swipe the sensor over the magnet (during which the signal turns from 1 to 0 and back to 1 again), I get two readouts of the total duration. The sensor signal defaults as 1 (HIGH) when there is no magnet in the way, and goes to 0 if there is. I get the first readout of the duration when the magnet just comes into the range of the sensor, and the second when it successfully passes over it.

I am just trying to picture this in my head but I am not understanding why it is doing that.

Any ideas?

Thanks again,
czhe

Are you getting two outputs on the serial monitor of the same correct value. Or are you getting two different values, one very short and the other apparently the correct reading?

If the latter, there may be some 'bounce' in your sensor reading. You can address this many different ways. If there is a single bounce (always one short high-low-high duration) followed by the longer correct sequence, you could just add the duration of the two sequences together.

If you are seeing something else, then please say more about the characteristics of the readings you see.

Hi, thanks for your reply! I've tried as many things as I can but my outputs are still a bit strange.

This is what I see at the output, so I think it corresponds to the latter case you mentioned:

duration for one revolution is 9240105

duration1 is 9240094

duration2 is 11

difference is 9240083



duration for one revolution is 17568

duration1 is 17567

duration2 is 1

difference is 17566

I don't know why duration2 is so small...

And I see these two outputs in one revolution only.

Thanks for any advice,
czhe

p.s. and oh here is my current code:

int switchPin = 4;
unsigned long duration1;
unsigned long duration2;

void setup ()
{
  Serial.begin(9600);
  pinMode(switchPin, INPUT);
}

void loop ()
{
    duration1 = pulseIn(switchPin, HIGH, 10000000);
    duration2 = pulseIn(switchPin, LOW, 10000000);
    if (duration1 > duration2)
    {  
    Serial.print("duration for one revolution is ");
    Serial.println(duration1 + duration2);
    Serial.print("duration1 is ");
    Serial.println(duration1);
    Serial.print("duration2 is ");
    Serial.println(duration2);
    Serial.print("difference is ");
    Serial.println(duration1 - duration2);
    Serial.println("");
    }
}

Lets have a look at the actual durations. Try this sketch and post the results of about ten high and low readings (you can ignore the very first reading). Do the readings seem to match your movement of the magnet over the sensor?

int switchPin = 4;
unsigned long startTime = 0;
boolean State;

void setup ()
{
  Serial.begin(9600);
  pinMode(switchPin, INPUT);
  startTime = millis();
}

void loop ()
{
unsigned long dur;
    
    State = digitalread(switchPin); 
    while(digitalread(switchPin) == State)
        ;  // wait for pin state to change
    dur = millis() - startTime;    
    startTime = millis(); // get new start time        
    if(State == HIGH)
        Serial.print("HIGH dur is ");
    else
        Serial.print("LOW dur is ");    
    Serial.println(dur);
}