Is a 1D Kalman filter suitable to correct clock drift against an external, noisy, cyclical phenomenon?
Simon Merrett wrote 02/20/2020 at 20:21 • 0 pointsBear with.
In typical fashion, I've been wanting to do a project for a while, HaD runs a competition for it and I miss the boat. But that's fine. I ran into an issue in a design for a remote, low power sensor device last year which needed to roughly know what time of day it is. However, it would have been beyond the UI, the user or the deployment regime to set the time on an RTC so I had to omit it.
Since then, I've wondered if you could use periodic light readings from an LDR/fixed resistor voltage divider into an ADC to identify a daily period and keep the notoriously drifty watchdog oscillator on track and maintain an internal sense of time in the microcontroller that, over months, will only be out by roughly it's PPM * 1 day (plus a bit more for error in the light reading periodic matching).
So far I've found a reasonable algorithm to identify the daily light reading periods which appears to work with full year of UK solar pv data that I found (mapped to fixed point values) as a proxy for light readings. I'm currently logging some real readings to test it on more representative data using the hardware described above.
What I'd like to ask the stack is whether you think a one dimensional Kalman filter would be a good way to combine the expected/estimated duration of a day (based on the number of watchdog interrupt firings in the previous light period) with the measured duration of the day, based on the number of watchdog interrupt firings in the current light period.
Planning to put this project on HaD.io soon, once I have a little more to show for it.
Ps, the current day period measuring algorithm is _very_ lightweight and normalises 6hr and 12hr averages, dividing the minimum by the maximum. It then looks for a trough and measures the middle of the trough as a marker for the end of one day and beginning of the next. For a heavier processing burden, I may look into an autocorrelation routine, which should be more robust to some kinds of failure (like not dipping below the trough threshold for some reason).
I could not find anything like this on the Web when I looked so if you have seen something similar before, please link to it. I would have thought this would be a helpful way to keep coarse time on microcontroller sensor nodes for very little cost, components and processor resources.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.
Some phase locked loop could probably be better, but I think temperature variations between day/night and weather patterns could throw out your watchdog timer variancy too much. It would be nice but lengthy thing to investigate.
Are you sure? yes | no
Pll would be great - I suppose an autocorrelation approach would provide this. The wdt variation due to the kind of effects that you describe are exactly what I'm hoping to ignore "just the right amount" by using the kalman filter. The wdt variation would be factored in the filter as process noise. Do you have any tips on pll that isn't based on autocorrelation?
Are you sure? yes | no
I'm not sure how a Kalman filter would help you match a signal to an expected signal. If I read it up correctly, a Kalman filter is mainly just a way to combine given measurements to get a good estimate, so it's just an average.
I'm interested in figuring out how you'd then use this averaged data to calculate the current daytime?
A more fitting approach might be an Autocorrelation or even an FFT. You are worried about the comparison array size, but since we only need maybe five to ten measurements every day, running over ten or twenty days, that's only 100 measurements, which should be a very trivial amount of memory even for a small AVR.
Are you sure? yes | no
@Xasin I found it hard to describe the idea so let me try and clarify. The expected signal is the estimate part of the kalman input. It's using a model of the expected system behaviour (ie that x number of wdt interrupt firings should line up with 1 day). That prediction is combined with the measured duration of the day using the light readings.
I'd be very interested to understand a little more about how only a few light readings per day over several might be able to do this. Would you propose looking for multiple peaks and shifting several days? I wonder how this would work for different weather on different days, causing outlier readings. Should be able to try it though once I have my practice data recorded.
Are you sure? yes | no
Ah, alright!
The Kalman filter wouldn't be part of the estimation of the current daytime, it would just filter out those estimations to keep the Watchdog neatly tuned, correct?
Anyhow, since daylight is a very periodic phenomenon, if you were to draw a graph of the light it should, at least to some extent, look like half of a sine curve.
This means that a FFT should be very good at capturing the base period and phase of the light readings. I personally would assume a fixed frequency for the day time, and then use the phase of the base frequency FFT output to shift and adjust the oscillator timing.
It's basically just fitting a Sine curve to your light readings ^^
Are you sure? yes | no
@Xasin you're right - the kalman filter would combine the estimations (based on wdt) with the light readings to keep time.
If only the light measurements were a cleaner sine curve. The problem where I live (in South West UK) is that you can sometimes experience all four seasons in a day and the fluctuating light levels under clear skies and dark clouds probably adds too much noise for me to filter so I'm looking at a sine curve. The current filter of comparing the ratio of the max/min of the 12hr and 6hr mean seems to be fairly robust in this respect but if I get a chance to try an autocorrelation algorithm this will hopefully work too. I think an FFT might be a little susceptible to this noise (by which I mean it might identify frequency peaks that are pretty close and difficult to determine which peak reflects the real day) and would need a decent run of samples but I'm game to try this.
Are you sure? yes | no
As much as I love this idea, I'd honestly bite the bullet and buy an el-cheapo, low power external RTC :)
Most consume <2uA so I don't think this will show up adversely in your power consumption charts. Use the RTC accuracy to periodically adjust your WDT count so it keeps in sync.
Haven't heard anyone trying something like this so you may be the first. That said, I didn't think Kalman filters are particularly light weight to implement. Then again, I never implemented it in C code so I wouldn't know
Are you sure? yes | no
Thanks @Sree Harsha Angara . Even if I included the RTC, there's no way to set it when the device is deployed and a hold-up battery isn't really an option. The situation is rather hypothetical because that project is done but I can envisage similar requirements in future projects.
I think 3D kalman filters which need to fuse gyro and accelerometer data can get pretty heavy but a 1D should be fairly lightweight. I'd expect an autocorrelation routine to be more demanding of resource than the kalman filter, due to the arrays it has to create for comparison.
Are you sure? yes | no