udoklein / dcf77

Noise resilient DCF77 decoder library for Arduino
http://blog.blinkenlight.net/experiments/dcf77/dcf77-library/
GNU General Public License v3.0
93 stars 28 forks source link

Binning does not work as expected #21

Closed GavinAndrews closed 7 years ago

GavinAndrews commented 7 years ago

Whilst investigating poor lock performance of the MSF implementation I can see that the binning does not behave exactly as expected.

Consider the decoding of minutes (although it does not matter which measure is being considered)... an incorrect value should be replaced with a correct value after a period of time so consider...

receiving 11001001 five times... this is a representation of 13 with a paritiy bit and subsequently receiving the value 00101000 ten times which is the representation of 14 with parity. After ten good receptions the good value should have replaced the bad value but this behaviour is not seen with BCD binning

udoklein commented 7 years ago

No, after 10 good receptions of 13 the score for the good signal is "60". The score for the second best guess is "40". Now if 10 more good receptions of 14 follow, then the score for the best AND the second best guess are both 60. However if you wait for the 11th signal, then you will end up with 64 vs 60.

The question is how come? First of all we notice that the BCD encoding + parity of e.g. 12 is only 2 bits away from 13. And due to the parity this is the second best guess. After 10 passes this should be 20 counts behind. It should be 80 vs. 60 instead of 60 vs. 40 though. The point is that the BCD binner will normalize the "min" to 0. However there is no guess with the binary complement of 13 available (this would be 00110110. Any possible minute value has a least 2 correct bits. Hence the minimum match is 20. Thus the normalizations ends up with 60 vs. 40.

Now after sending 10 times 00101000 the guesses for 10, 11, 12, 13, 14, 15, 16, 17 all score 60. Hence it will not yet recover. In pass 11 it starts to recover as desired though.

This works as designed. A somewhat better approach might be to have some kind of decay function that emphasizes more recent values. However there are two issues against it:

1) It requires more memory and the AVRs have so little of it. 2) It performs better when a good signal comes in but poorer if a bad signal starts to overwhelm the good signal.

GavinAndrews commented 7 years ago

My scenario is five 13s Followed by ten 14s

udoklein commented 7 years ago

Sorry for that. I now changed the tests to 5 times 13 followed by 10 times 14. Result after feeding 5 times 11001001 is max = 30, noise = 20 and it locks to 13. Feeding it then with 10 times 00101000 gives max = 60, noise = 50 and it locks to 14. Seems everything is fine. I do not know why it would not lock to 14 in your setup. My tests are all OK.

GavinAndrews commented 7 years ago

That's weird How are you testing? Which branch/commit? On 23 Nov 2016 9:07 p.m., Udo Klein notifications@github.com wrote:Sorry for that. I now changed the tests to 5 times 13 followed by 10 times 14. Result after feeding 5 times 11001001 is max = 30, noise = 20 and it locks to 13. Feeding it then with 10 times 00101000 gives max = 60, noise = 50 and it locks to 14. Seems everything is fine. I do not know why it would not lock to 14 in your setup. My tests are all OK.

—You are receiving this because you authored the thread.Reply to this email directly, view it on GitHub, or mute the thread.

udoklein commented 7 years ago

I am testing on this https://github.com/udoklein/dcf77/releases/tag/v3.1.2 (commit ef11c19fa2ae656a63efefd1aef4be2afe666aa0 on branch master).

GavinAndrews commented 7 years ago

My PC has just failed...! But I was testing the development branch

GavinAndrews commented 7 years ago

Binning logic was generally correct however it did not work for Weekday which is actually zero based 0..6 for MSF60; my error. Closing issue.