When the variance goes above 1, or whatever preset threshold, I turn on the presence register which shows in green. You can see that it definitely does work to know when I’m coming and going, but at this sample rate, buffer size and threshold it also comes on randomly with non-people moving through the room wifi interference.
In order to register anything reasonable at all you have to have the device very close to the person you want to know if they are there. This may be of use for this particular application as I plan to have the device sitting on my desk to provide some display of info for me while sitting here. It might even be able to blank and wake up it’s own display based on that. That would be useful and fun. Unfortunately if I sit very still it eventually thinks I’ve gone away. It’s decided that while I’ve been typing this paragraph actually. Lost of tweaking of settings would be necessary to make it at all useful.
I’m not sure that it will ever be useful as a generic motion sensor. You just have to be too close to the device to get it to see enough variance in the signal. Still an interesting experiment and I will keep fiddling with it to see if something useful can be done with it. It’s also possible that with the newer ESP32’s or other devices you could get better resolution or even access to things like the path being used to send the info or other similar data that would let you do a much better job. But for something that wakes up when you walk up to it and then goes to sleep shortly after nobody is standing next to it this could potentially be used.
Calculating a variance is a standard statistical technique so that you can gauge if you’ve got enough data points to realistically represent what you’re looking for among other thing. The formula is:
S2 = ∑(xi - x̄)2 / (n-1)
Which translates to the Variance squared being equal to the sum of each value in the dataset minus the average of the dataset squared and then divided by the number of points in the dataset minus one. So the first thing you need is an average of the dataset. It’s slightly complicated by the fact that my buffer array of read RSSI values may contain 0’s or values that are not a valid RSSI. As I place the values into the buffer I am making them all positive as I am not worrying about the actual db value, only the variance of the data. So the first thing you need to do is to call the scanRSSI function every second. To do this you need to compare millis() with the calculated next time you want to do something inside the loop. You can’t just compare simple unsigned longs as are returned from millis() as they will overflow back to 0 at some point which will break everything. So you can do the clever trick of casting it to a long and then subtracting it later which will yield the proper result of timing even during an overflow condition.
the code above sets up the buffer array as bytes, since the numbers will never be more than 255 there is no reason to waste memory by using 2 byte ints or anything else. We also need an index into the array so we know where to save the next value and the nextPresenceScan value which is where the trick comes in. Casting the value of millis() + 5000 as a long integer and then putting it into an unsigned long variable we get around the overflow problem as far as the comparisons later are concerned. Very clever and described in great detail on the Arduino website if you’re interested.
Next we need some code to run inside the loop() to check the time and call us when it’s time to run. Something like:
Same trick as before, sets up the nextPresenceScan and then calls the function to do the work.
That is actually pretty horrible code. I also do realize that I’m never taking the square root of the variance as calculated. That doesn’t seem necessary at this point and the poor arduino is already working hard with all those floats. If I make the value even smaller it will be harder to watch whats happening. It’s also not memory compact as it needs a full buffer. I’m sure some other kind of rolling average could be used. To get anything useful you’ll have to adjust the threshold and the scanning frequency and probably a lot of other stuff too. An interesting starting point to something potentially useful.
The device in question here is sending it’s values back to XTension for graphing and potential use. The graph above was generated by that program. XTension: Home Automation for the Mac, is my day job.