For those more clever than I

I’m attempting to come up with a routine that with each pass of checking sensors it will store an average value of the sensor readings in array element SensorName(10). In this routine, I read the sensors and place the values in a sensor array sensorName(0-9) and use sensorName(10) to hold the average. After the first 10 passes the sensor average stabilizes and the array elements for each sensorName (0-9) continue to be overwritten and sensorName(10) continues to be updated. I almost have this working except the first pass avg is not correct. This also feels complicated. Someone clever might show me an easier way to build an average on the first ten passes and then continue to maintain an average as the program real time continues to read sensors values.

This is the code I’m using:

Count and FirstTenCycles are stored properties in a method

[code]Var x,avg As Integer

If FirstTenCycles < 10 Then //get first 10 readings to build avg
ReadAllTempSensorsSub(FirstTenCycles)
FirstTenCycles = FirstTenCycles + 1
Elseif count < 10 Then //Continue after first 10 reads
ReadAllTempSensorsSub(count)
count = count + 1
End
If count > 9 Then // start over filling array
count = 0
End[/code]

ReadAllTempSensorsSub:

[code]Public Sub ReadAllTempSensorsSub(count as integer)
Var BK7TR As New SensorRead

StorageAreaTemp(count) = BK7TR.ReadSensor(“BK7”,2)
CaluculateAvg(StorageAreaTemp)

FloorIntakeTemp(count) = BK7TR.ReadSensor(“BK7”,3)
CaluculateAvg(FloorIntakeTemp)

CeilingTemp(count) = BK7TR.ReadSensor(“BK7”,4)
CaluculateAvg(CeilingTemp)

KitchenTemp(count) = BK7TR.ReadSensor(“BK7”,5)
CaluculateAvg(KitchenTemp)

UpstairsTemp(count) = BK7TR.ReadSensor(“BK7”,6)
CaluculateAvg(UpstairsTemp)

BedroomTemp(count) = BK7TR.ReadSensor(“BK7”,7)
CaluculateAvg(BedroomTemp)

End Sub[/code]

Caluculate Avg:

[code]Public Sub CaluculateAvg(byref TempZone() as integer)
Var x,avg As Integer

For x = 0 To FirstTenCycles-1 // will stay 10 after first 10 reads
Avg = Avg + TempZone(x)
Next
TempZone(10) = avg/FirstTenCycles-1

End Sub
[/code]

Not sure I qualify as more clever, but it looks like during the first 10 passes (FirstTenCycles < 10), the average is being divided by the wrong number. I would change your calculation to

Public Sub CaluculateAvg(byref TempZone() as integer)
  Var x,avg As Integer
  Var avgdivisor as Integer

  if FirstTenCycles < 10 then
     avgdivisor = FirstTenCycles + 1
  else
     avgdivisor = FirstTenCycles   // or just set it to 10
  end
  
  For x = 0 To avgdivisor-1 // will stay 10 after first 10 reads
    Avg = Avg + TempZone(x)
  Next
  TempZone(10) = avg/avgdivisor-1
  
  
End Sub

I recommend creating a class to hold your readings with a computed property that returns the average on-demand.

[quote=496925:@Tim Hare]Not sure I qualify as more clever, but it looks like during the first 10 passes (FirstTenCycles < 10), the average is being divided by the wrong number. I would change your calculation to

[code]
Public Sub CaluculateAvg(byref TempZone() as integer)
Var x,avg As Integer
Var avgdivisor as Integer

if FirstTenCycles < 10 then
avgdivisor = FirstTenCycles + 1
else
avgdivisor = FirstTenCycles // or just set it to 10
end

For x = 0 To avgdivisor-1 // will stay 10 after first 10 reads
Avg = Avg + TempZone(x)
Next
TempZone(10) = avg/avgdivisor-1

End Sub
[/code][/quote]

[quote=496925:@Tim Hare]Public Sub CaluculateAvg(byref TempZone() as integer)
Var x,avg As Integer
Var avgdivisor as Integer

if FirstTenCycles < 10 then
avgdivisor = FirstTenCycles + 1
else
avgdivisor = FirstTenCycles // or just set it to 10
end

For x = 0 To avgdivisor-1 // will stay 10 after first 10 reads
Avg = Avg + TempZone(x)
Next
TempZone(10) = avg/avgdivisor-1[/quote]
Okay Tim, I looked at this for the longest time and something just didn’t add up. What confuses me is on the first pass this code make no sence to me.

TempZone(10) = avg/avgdivisor-1

I say that because avgdivisor -1 = 0 on the first pass but I do get a good value in TempZone(10)
Now if I replace avgdivisor -1 with a 0 as a test I get a different # (the # I was getting) in TempZone(10) . They are both avg/0. What am I missing here?

I would like to understand this a little more. Do you have some kind of example or something you could point me to. I’m not familiar with a computed property.

[quote=496939:@Clifford Coulter]Okay Tim, I looked at this for the longest time and something just didn’t add up. What confuses me is on the first pass this code make no sence to me.

TempZone(10) = avg/avgdivisor-1

I say that because avgdivisor -1 = 0 on the first pass but I do get a good value in TempZone(10)
Now if I replace avgdivisor -1 with a 0 as a test I get a different # (the # I was getting) in TempZone(10) . They are both avg/0. What am I missing here?[/quote]
FirstTenCycles starts with 1, so

if FirstTenCycles < 10 then avgdivisor = FirstTenCycles + 1
avgdivisor = 2 (FirstTenCycles + 1)

[quote=496942:@Alberto DePoo]FirstTenCycles starts with 1, so

if FirstTenCycles < 10 then avgdivisor = FirstTenCycles + 1
avgdivisor = 2 (FirstTenCycles + 1)[/quote]

I do not believe this this the case:

Var x,avg,avgdivisor As Integer

If FirstTenCycles < 10 Then

MessageBox Str(FirstTenCycles) Reports it As 0

avgdivisor = FirstTenCycles + 1
Else
avgdivisor = 10 //FirstTenCycles // or just set it to 10
End

For x = 0 To avgdivisor-1 // will stay 10 after first 10 reads
Avg = Avg + TempZone(x)
Next

TempZone(10) = avg/avgdivisor-1

The debugger also shows it as 0.

For the first cycle: if FirstTenCycles = 0
FirstTenCycles - 1 will be 0 - 1 = -1

avgdivisor because is FirstTenCycles + 1 will be 0 + 1 = 1
avgdivisor - 1 = 1 - 1 = 0

I think

TempZone(10) = avg/avgdivisor-1

should be

TempZone(10) = avg/avgdivisor

Obviously, I’m making some assumptions here. IF FirstTenCycles in un-initialized, it will start at zero. What we’re trying to do is avoid an outofbounds situation, while simultaneously avoiding dividebyzero. The first round through, FirstTenCycles is 0. What we’re going to do is add the reading to TempZone(0) and then we want to add up all the values (there’s only one) and divide by 1 - that would be FirstTenCycles (which is 0) plus 1. The second time through, we want to add the new reading to TempZone(1) and add up the values (there are 2 of them) and divide by 2 - FirstTenCycles is 1 at this point, so FirstTenCycles + 1.

[quote=496946:@Alberto DePoo]I think

TempZone(10) = avg/avgdivisor-1

should be

TempZone(10) = avg/avgdivisor

You are correct. Forum code and all. I hope that correction makes it work. I don’t claim to be all that clever.

[quote=496946:@Alberto DePoo]I think

TempZone(10) = avg/avgdivisor-1

should be

TempZone(10) = avg/avgdivisor

Both ways work but after looking at the TempZone array in the debugger I see it (0) and (10) are the only elements being filled.

Both ways should not give the same results. (0) and (10) should be filled on the first pass, on second pass, count should be 1 and then (1) should be filled and (10) modified by the average, and so on until count is 9, and at that point you should have all elements filled, next pass count will be 0.

TempZone was not what I should have been looking at. All arrays are working as they should now. The questions still is unresolved as to why avg/avgDivisor when avgDivisor is 0 yields a good result (same as 1) and avg/0 yields a different result.

Yeah, I don’t understand how if you have avg / 0 you get a good result, avg / 0 can’t be = avg

If you keep avgDivisor - 1 or FirstTenCycles - 1, you should be getting wrong averages. 10 readings / 9 instead.

Sorry I can’t find what is missing just by looking at the posted code, I’m more a ‘Run and test’ person. If you have a sample code that you can share and I can play with it, maybe I can figure it out.