Our full technical support staff does not monitor this forum. If you need assistance from a member of our staff, please submit your question from the Ask a Question page.


Log in or register to post/reply in the forum.

Algorithm for Alarming on Variable


ariklee Oct 10, 2018 05:09 PM

Hi,

I'm setting up an early warning system that will send text/email based on changes in a variable collected by my CR300/CR6. The variable is a measure of ground movment, so it should be constant over time, with a bit of noise and thermal dependence. I will collect data for a few weeks, then use the data to inform my alarm threshold limits. I'd like alarm on two different conditions:

1. One alarm will be set on absolute difference or the current reading compared to the previous average (i.e., take long term average of values, then send alarm if the current value falls outside of x standard deviations of the long term). What is the best/most efficient CRBasic command for computing StDev of the previous n values in a data table?

2. The other alarm I want to set is based on the slope of the past values. If the ground is moving very slowly (slope of the previous 20 data values is relatively flat), I don't want to send an alarm. If the slope increases beyond a specified threshold, I want to send an alarm.

For the second case, in the past I've used the Theil-Sen Estimator https://en.wikipedia.org/wiki/Theil%E2%80%93Sen_estimator to calculate slope because it is robust to outliers, and so I like that very much. I'm curious if anyone has other ideas on how to set an alarm? What have you done in the past?

Thanks,

Eric


DAM Oct 10, 2018 11:03 PM

To compute the StdDev of the last N values from a data table. Here is one approach:

Dim RingBuff(N)

Dim ring_idx as Long  ' current index into RingBuff (starts at zero, so handle accordingly)

Public MyStdDev

If (MyTable.Output) then   ' only calculate the new StdDev when the table outputs

   RingBuff(ring_idx + 1) = MyTable.ValtoStdDev ' read the value to do StdDev out of the table and load into ring buffer

   ring_idx += 1 ' advance ring buffer index

   If ring_idx = N then ring_idx = 0  'Reset ring index at the end (zero based so no initialization is necessary)

  StdDevSpa(MyStdDev,N,RingBuff) ' do the running StdDev

EndIf

Just replace "MyTable" with the name of the table you are reading from and "ValtoStdDev" with the name of the field in the table that you want to do the StdDev on.

The value MyStdDev will contain the running Standard Deviation of the desired output field.


ariklee Oct 11, 2018 06:37 PM

Thanks, great! So... MyTable.Output gets set TRUE when the table is successfully populated, then resets to FALSE upon initializing the next scan sequence? Do I have to check it after the call to the table?

Just discovered the "median" function, that will help with the Theil-Sen calculation.


DAM Oct 11, 2018 09:58 PM

Yes, the "special" field output, will be set to true after calling the table, if the call resulted in a new record being written. It will only remain true until the next table call. So, as you pointed out, you should have the CallTable prior to the code block to do the StdDev.

Very interesting application.

Log in or register to post/reply in the forum.