Pages: [1]   Go Down
 Author Topic: Measuring phase diff - RTC's seconds vs. millis()  (Read 2707 times) 0 Members and 1 Guest are viewing this topic.
Rapa Nui
Offline
Edison Member
Karma: 60
Posts: 2061
Pukao hats cleaning services
 « on: July 11, 2013, 05:56:25 pm » Bigger Smaller Reset

I want to measure "the phase difference" between the millis() and my RTC's seconds (external). The assumption is both millis and RTC's seconds are relatively stable.

So what I've done:
Code:
in a loop for example:
..
// sampling the two signals (RTC secs and millis)
rtc_sec = t.sec;    // I get RTC's seconds 0..59
mil_sec = millis();  // I get millis

// I am trying to measure the diff as: rtc_sec%10 - mil_sec%10000/1000, so the "window" is 10 secs
// I do filtering here - exponential moving average (EMA), because the diff jumps up and down

aver_dt = ( ( (float)(rtc_sec%10) - ( (float)(mil_sec%10000) / 1000.0) ) * 0.005 ) + (aver_dt * 0.995);
After some time the aver_dt shows something like -0.634 (an example) and it is relatively stable. Not sure the algorithm is ok, however.

Now, as my approach is somehow hairy - do you have any idea how to do it better?
 « Last Edit: July 12, 2013, 06:23:52 am by pito » Logged

Massachusetts, USA
Offline
Tesla Member
Karma: 201
Posts: 8667
 « Reply #1 on: July 11, 2013, 09:47:53 pm » Bigger Smaller Reset

The phase difference will depend on the time of day that the Arduino was started plus the drift over time from the difference from the RTC clock and the system clock.

What I would do is connect the 1 PPS signal from your RTC to an interrupt pin and use that interrupt to sample the millis() value.  The millis() mod 1000 would be the phase difference.
 Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Rapa Nui
Offline
Edison Member
Karma: 60
Posts: 2061
Pukao hats cleaning services
 « Reply #2 on: July 12, 2013, 01:48:47 am » Bigger Smaller Reset

Quote
The phase difference will depend on the time of day that the Arduino was started..
No problem with that - I want to see just the drift, the absolute value is not important at this stage.

Interestingly, after several starts (random against RTC) the number I get after a while (I am sampling the diff in a loop every aprox. 1.2secs) is always around -0.6 (the aver_dt is still noisy, but clearly around -0.6). So there must be some hidden "principle" in it. Trying to understand that..

Quote
What I would do is connect the 1 PPS signal from your RTC to an interrupt pin
Still looking for a way how to do it with "RTC's seconds" and some math..
 « Last Edit: July 12, 2013, 05:03:57 am by pito » Logged

Rapa Nui
Offline
Edison Member
Karma: 60
Posts: 2061
Pukao hats cleaning services
 « Reply #3 on: July 12, 2013, 05:29:22 am » Bigger Smaller Reset

What I want to measure basically is a phase between two saw-tooth shaped signals (see below):
1. first signal - with discrete values 0..9 (rtc_sec MOD 10),
2. the second one - a "linear" 0.000 .. 9.999 ( (mil_sec MOD 10000) / 1000).

My working assumption to the process is following:
Let us have stable RTC and millis signals. When we sample both signals (we get rtc_sec and mil_sec values) ANYTIME, the difference (rtc_sec - mil_sec) shall be constant.  In order to "normalize" both signals (as the rtc_secs run 0..59) we do MOD with the signals to get them into the same range. When we provide a moving average over a large number of differences (after the MOD, and even the first signal has discrete values), the result shall be constant.

The red colored are sampling times (for example). What I do is simply the difference between the values sampled, and the diff is then averaged by a moving average filter with a "time constant" of about ~400 sampling periods. Not sure I do understand the results yet, however.. (moreover the algorithm is just my first guess...)
PS: corrected MOD 10, and MOD 10000 (for 0 .. 9 and 0.000 .. 9.999).
 sawtooth1.bmp (383.62 KB, 430x304 - viewed 53 times.) « Last Edit: July 12, 2013, 07:47:32 am by pito » Logged

Offline
Newbie
Karma: 0
Posts: 1
 « Reply #4 on: August 10, 2013, 01:00:33 am » Bigger Smaller Reset

I am new to Arduino and forgive me if I am in the wrong discussion to ask this question.  Is it possible to generate a very long wavelength (say 5 kilometers long) and measure the change in phase of the wavelength of the return signal (say from a reflector) and turn this into a distance measurement?

I remember for my Uni days (studying Engineering) that this was a technique used by early survey instruments.  This gave an approximate length (say to the nearest kilometer).  But then the wavelength was halved and then the phase difference in this signal was also measured which refined the distance and allowed someone to know the distance to the nearest 100 meters, then again halved to know to the nearest 10 meters etc.  then it was a matter of adding the numbers obtained together to get the distance.  This was the general principal (may not be the exact numbers of course).
 Logged

Offline
Karma: 57
Posts: 2775
 « Reply #5 on: September 18, 2013, 02:08:02 am » Bigger Smaller Reset

Your graph there with the dots for the RTC output,  should really look like a staircase,    because when you have your red sampling times,  they will be measuring the same value on the "flat" part of each step.

Your millis() value also increases in steps,  but they are much more tiny.

So whenever you take a measurement,  you are effectively calculating the vertical size of a very small triangle (  one tenth as high and wide as your big triangles ).   The average size of these triangles is going to dominate your result more than the difference caused by the "phase difference"  you are trying to measure, I think.
 Logged

Offline
Full Member
Karma: 2
Posts: 197
 « Reply #6 on: October 16, 2013, 11:08:49 am » Bigger Smaller Reset

I really don't understand why use of millis() is so common. It skips numbers. Use micros() instead.(Well, yes, micros() skips numbers too: it counts in steps of 4 microseconds. But better to skip 4 microseconds than a whole millisecond.)
 « Last Edit: October 16, 2013, 11:10:37 am by odometer » Logged

 Pages: [1]   Go Up