0
votes

I'm measuring the CPU temperature in Raspberry Pi 3 and getting very noisy values. Raw values from Temperature sensor in Raspberry Pi 3 The temperature is measured every second, should be put through moving average (aka Sliding Window). Each 5 seconds a new Temp.value should be put into SQLite Database. Till now I've found solutions only for static arrays of Data. Can anyone help with the problem? I need a function that takes a value each second and returns averaged value every 5 seconds. The algorithm could be then applied to values like humidity, voltage and so on. Temp sensor in Raspberry Pi 3 have a Precision of 0.538°C.

Here's what I have at the moment:

 #!/usr/bin/python
# -*- coding: utf-8 -*-

# Das Programm speist Temperaturen von CPU ins SQLite Datenbank für spätere
# Darstellung auf einer Webseite

from subprocess import check_output
import sqlite3
import time
import numpy

# Pfad zur Datenbank
dbname = "/var/www/cpuTemp_Database.db"
temp_array = []

def log_temperature(currentTemp):
    """ Speichern in die Datenbank"""
    myConnection = sqlite3.connect(dbname)
    myCursor = myConnection.cursor()
    myCursor.execute("INSERT INTO temps VALUES (datetime('now', 'localtime'), (?))", (currentTemp,))
    myConnection.commit()
    myConnection.close()
        

def abfrage():
    """ Macht CPU-Temperaturabfrage und gibt das Wert zurück wie 53.692 """
    output = check_output(['cat', '/sys/class/thermal/thermal_zone0/temp'])
    stripedVal = output.strip()
    tempVal = float(stripedVal)/1000
    return tempVal
    
def main():
    """ Main Function"""
    while True:
        for i in range(5):
            tempValue = abfrage()
            temp_array.append(tempValue)
            time.sleep(1)
        meanTemp = numpy.median(temp_array)
        log_temperature(meanTemp)
        temp_array [:] = []
    
if __name__ == "__main__":
    main()
1
SQLite can calculate the averages for you. See this question. You'll just have to set up the sorting magic yourself. - Kraay89
I thought a 5-point moving average was the average of a data point and the 4 on either side of it? For instance, the list 1,2,3,4,5,6,7 would have 5-point moving averages of x,x,3,4,5,x,x - Liam Bohl
Thanks for the input! Writing an averaged value every 5 seconds to Database reduces workload on SD-Card and increases accuracy of the Graph. While CPU has a big Radiator, temperature don't change itself that fast. However under extreme conditions, sliding window could be reduced to 3 values. - AlexBaker

1 Answers

1
votes

I think what you are asking for is every 5 seconds to get the average reading from the last 5 seconds, which is not a true moving average. This should give you that behavior.

import numpy

# Once you input enough new data points into this function, it will calculate
# and log the average of the last several data points.
def log_periodic_average(new_data_point, window, frequency):
  window.append(new_data_point)
  if (len(window) >= frequency): # Now is the only time we calculate an average
    average = numpy.mean(window)
    log_temperature(average) # Using your function to save the average
    window = [] # Clear window to collect the next 5 seconds of data
  return window

window = []
while True:
  point = abfrage() # using your function to get current temperature 
  window = log_periodic_average(point, window, 5)
  sleep(1000)