Data averaging fluctuation [SOLVED]

I'm creating a data logger and diagnostics device for temperature and the float state in a water tank. I made the averaging code a while ago, which should be fine:

(the cumulative sum of all readings divided by the number of samples taken).

This should be fine, but I'm having trouble with the data on the serial monitor output. This is an example of the serial data:

Time: 14:48:22 | Runtime: 00d 00h 00m 01s | Sample: 1 at  1.00s | Sw: 1 | temp(°C):  21.44 | Ave:  21.44 | Tot:  21.44
Time: 14:48:23 | Runtime: 00d 00h 00m 02s | Sample: 2 at  2.00s | Sw: 1 | temp(°C):  21.44 | Ave:  21.44 | Tot:  42.88
Time: 14:48:24 | Runtime: 00d 00h 00m 03s | Sample: 3 at  3.00s | Sw: 1 | temp(°C):  21.37 | Ave:  21.44 | Tot:  64.31
Time: 14:48:25 | Runtime: 00d 00h 00m 05s | Sample: 4 at  5.00s | Sw: 1 | temp(°C):  21.44 | Ave:  21.44 | Tot:  85.69
Time: 14:48:27 | Runtime: 00d 00h 00m 06s | Sample: 5 at  6.00s | Sw: 1 | temp(°C):  21.44 | Ave:  21.42 | Tot: 107.12
Time: 14:48:28 | Runtime: 00d 00h 00m 07s | Sample: 6 at  7.00s | Sw: 1 | temp(°C):  21.44 | Ave:  21.42 | Tot: 128.56
Time: 14:48:29 | Runtime: 00d 00h 00m 08s | Sample: 7 at  8.00s | Sw: 1 | temp(°C):  21.37 | Ave:  21.43 | Tot: 150.00
Time: 14:48:31 | Runtime: 00d 00h 00m 10s | Sample: 8 at 10.00s | Sw: 1 | temp(°C):  21.44 | Ave:  21.43 | Tot: 171.37

 LOG NO.1
| Time(s) | Float Switch State | Average Temperature(°C) |
|  53311  |         1          |          21.43          |

As you can see, the current temperature, average, and total do not match up.

I'm using 12-bit resolution and only 2 decimal places, but that only makes my readings slightly inaccurate due to rounding, which is not the issue.

I've been trying to mess about with this for a while but I'm losing my patience with trying to find the answer.

The code is 700 lines long, but the code for sample averaging is in the datalog and diagnostics function, near the end. This is my code:

#include <Triogen.h>

/*    _______________________________________________________________________________________________________________________________________________________________________
ㅤㅤ /\             \                                                                                                                                          /            /\
ㅤ ㅤ|_\             \                                                               DATALOGGER                                                               /            /_|
ㅤㅤ |__\             \________________________________     20x4 LCD, SD ADAPTER, DS3231, DS18B20 (5.1kPU), FLOAT SWITCH     ________________________________/            /__| 
ㅤㅤ |___\                                             \____________________________________________________________________/                                            /___|  
ㅤㅤ |____\                                                                                                                                                             /____|
ㅤ ㅤ|_____\                  _______________________________________________________________________________________________________________________                  /_____|
ㅤㅤ \______\                /                                                                                                                       \                /______/                                            
ㅤㅤ  \_____/\______________/  THIS PROGRAM MAY ALSO BE USED AS A GENERAL DATA LOGGER BY MODIFYING THE SENSOR CODE AND INPUTTING THE NECESSARY CODE   \______________/\_____/
ㅤ ㅤ                        \________________________________________________________________________________________________________________________/                     

___________________________________________________________________________________________________________________________________________________________________________________
ㅤ  ㅤ   ㅤ           ㅤ/   (ALL VCC AND GND TO BE WIRED TO VCC AND GND)    \                           /
HARDWARE WIRING LIST: /                                                     \   PROGRAM DESCRIPTION:  /   
_____________________/                                                       \_______________________/
ㅤ                                                      
_________________________________                        _________________________________________________________________
FOR 20X4 LIQUID CRYSTAL DISPLAY: \                      /                                                                 \
............_____________________/                     /  This program is designed to log data from a DS18B20 temperature  \
-VSS GND   /                                           | sensor and read a  float  switch  value.  Once the  SD  card  is  | 
-VDD 5V    \____                                       |  initialised and  the RTC reads the set time, the  program  will  | 
-V0 2k RESISTOR \                                      |  create a file in the SD card and name it according to the  date  | 
-RS PIN A0  ____/                                      |  (the date is retrieved using a DS3231 RTC). once the  file  and  | 
-RW GND    /                                           |  file name is created, 8 data samples from all  DS18B20  sensors  | 
-E PIN A1  |                                           |  are  averaged,  formatted  and  logged   within   the   logging  | 
-D0 X     /                                            |  interval into the created file, as well as the time of the  day  | 
-D1 X    /                                             |  in seconds and the current state of the  float  switch.  If  the | 
-D2 X    \                                             |  program is ran  until  the  next  day,  data  logging  will  be  | 
-D3 X     \                                            |  stopped, and another file will be created and  named  according  | 
-D4 PIN A2 \                                           |  to the date. The liquid  crystal  display  and  serial  monitor  | 
-D5 PIN A3  \                                          |  will show all relevant info, and can be used to ensure that the  | 
-D6 PIN D2  |                                          |  program runs correctly, displaying SD card initialisation,  RTC  | 
-D7 PIN D7  /                                          |  initialisation, the filename the data is writing to,  the  time  | 
-A 10K POT /                                           |  the data started logging in DHHMMSS, and the  current  time  of  | 
-K GND    /                                            \  the RTC. If any Errors occur, the LCD or  serial  monitor  will  / 
_________/                                              \__________________  display an Error message.  __________________/ 
ㅤ                                                                         \___________________________/
____________________________
FOR SD CARD ADAPTER MODULE: \
....................________/
-chipSelect PIN D10 \
-MOSI PIN D11  _____/
-MISO PIN D12 /
-SCK PIN D13 /
____________/

_________________
FOR DS3231 RTC:  \
..................\
-SCL PIN SCL OR A5 \
-SDA PIN SDA OR A4  |
-SQW X  ___________/
_______/

________________________________
FOR DS18B20 TEMPERATURE SENSOR: \
........._______________________/
-POS 5V  \
-NEG GND  \__
-DQ 5.1kPU   \________________
-5.1kPU LINKING PIN D9 AND 5V \______________
-104pF CERAMIC CAPACITOR LIKNING POS AND NEG \
_____________________________________________/

__________________
FOR FLOAT SWITCH: \
............._____/
-POS PIN D4 /
-NEG GND __/
________/

// INCLUDE LIBRARIES AND DEFINED CONSTANTS:                                                                                      
*********************************************************************************************************************************************************************************/
#include <Triogen.h>
#include <LiquidCrystal.h>
#include <Wire.h>
#include <SD.h>
#include <SPI.h>
#include <FS.h>
#include <RTClib.h>
#include <WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <Time.h>
#define BLUE 6
#define GREEN 8
#define RED 9
#define chipSelect 21
#define buzzer 17
#define buzzerTogglePin 13

// used as general global variables
/********************************************************************************************************************************************************************************/

LiquidCrystal lcd(1, 2, 3, 4, 5, 10);
File dataFile;

RTC_DS3231 rtc;
time_t now; 
struct tm myTimeInfo;
unsigned long tStart = millis();
unsigned long totMillis;
unsigned long lastMillis = 0;
unsigned long logTm = 10000;
unsigned long sampleTm = 1250;
unsigned long tLog = totMillis + logTm;
unsigned long tSample = totMillis + sampleTm;
int year;
int month;
int day;
int hour;
int minute;
int second;
int newDay = day + 1;
int WiFiTimeout;

int buzzerState = 1;
int BTstate;
int buzzerOutState;
byte errCount = 0;

char dirName[9] = "/TANKLOG";
char fileName[16];
char fullPath[22];

const char* NTPserver = "pool.ntp.org";
const long GMToffsetSec = 0;  
const int daylightOffsetSec = 3600;
const char* time_zone = PSTR("GMT0BST,M3.5.0/1,M10.5.0");

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", GMToffsetSec);

void (*resetFunc)(void) = 0;

// variables only used for the specific type of datalogging
/********************************************************************************************************************************************************************************/
#include <OneWire.h>
#include <DallasTemperature.h>
#define floatSw 7
#define tempResolution 12
#define ONE_WIRE_BUS 18
OneWire oneWire(ONE_WIRE_BUS);
DeviceAddress tankTempSensor;
DallasTemperature sensors(&oneWire);

// function runs if a hardware error occurs
/********************************************************************************************************************************************************************************/
void hardwareErr() {

  while (!SD.begin() || !rtc.begin() || SD.cardType() == CARD_NONE) {
    digitalWrite(buzzer, 1);
    digitalWrite(GREEN, LOW);
    digitalWrite(RED, HIGH);
    digitalWrite(BLUE, HIGH);
    delay(100);
    digitalWrite(buzzer, 0);
    digitalWrite(GREEN, LOW);
    digitalWrite(RED, LOW);
    digitalWrite(BLUE, LOW);
    delay(1900);
  }

  if (SD.begin(chipSelect) && rtc.begin() && SD.cardType() != CARD_NONE) {
    lcd.clear();
    resetFunc();
  }
}

int printResetReason() {

  int reason = esp_reset_reason();
  Serial.printf("CPU reset reason: %d ", reason);

  switch (reason) {
    case ESP_RST_UNKNOWN: Serial.println("unknown");
    break;
    case ESP_RST_POWERON: Serial.println("POWER ON RESET"); 
    break;
    case ESP_RST_SW: Serial.println("SOFTWARE RESET"); 
    break;
    case ESP_RST_PANIC: Serial.println("PANIC RESET"); 
    break;
    case ESP_RST_TASK_WDT: Serial.println("TASK WDT RESET"); 
    break;
    case ESP_RST_WDT: Serial.println("OTHER WDT RESET"); 
    break;
    case ESP_RST_DEEPSLEEP: Serial.println("EXIT DEEP SLEEP RESET"); 
    break;
    case ESP_RST_BROWNOUT: Serial.println("BROWNOUT RESET"); 
    break;
    case ESP_RST_SDIO: Serial.println("SDIO RESET"); 
    break;
  }
  
  return(reason);
}

void printAddress(DeviceAddress tankTempSensor) {

  for (byte i = 0; i < 8; i++) {

    if (tankTempSensor[i] < 16) Serial.print("0");
      Serial.print(tankTempSensor[i], HEX);
    }
}

// initialises most of the hardware
/********************************************************************************************************************************************************************************/
void initialisation() {

  pinMode(buzzer, OUTPUT);
  pinMode(buzzerTogglePin, INPUT);
  pinMode(floatSw, INPUT_PULLUP);
  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(BLUE, OUTPUT);

  Wire.begin();
  SD.begin(chipSelect);
  lcd.begin(20, 4);
  sensors.begin();
  sensors.setWaitForConversion(false);
  sensors.requestTemperatures();
  Serial.print("DS18B20 Address: ");
  sensors.getAddress(tankTempSensor, 0);
  printAddress(tankTempSensor);
  Serial.println();
  sensors.setResolution(tankTempSensor, tempResolution);

  Serial.println();
  lcd.clear();

  printAll("Initialising SD...");

  if (!SD.begin()) {
    lcd.clear();
    printAll("SD card mount failed");
    Serial.println("Check that SD card is mounted and all wiring and connections have been made and are correct.");
    hardwareErr();
  }

  uint8_t cardType = SD.cardType();

  if (cardType == CARD_NONE) {
    lcd.clear();
    printAll("No SD card attached");
    hardwareErr();
  }

  Serial.print("SD Card Type: ");

  if (cardType == CARD_MMC) {
    Serial.println("MMC");
  } 

  else if (cardType == CARD_SD) {
    Serial.println("SDSC");
  } 

  else if (cardType == CARD_SDHC) {
    Serial.println("SDHC");
  } 
  
  else {
    Serial.println("UNKNOWN");
  }

  uint64_t cardSize = SD.cardSize() / (1024 * 1024);
  Serial.printf("SD Card Size: %lluMB\n", cardSize);

  lcd.setCursor(0, 1);
  printAll("Initialising RTC...");

  if (!rtc.begin()) {
    lcd.clear();
    printAll(F("RTC failed."));
    Serial.println("Check that the RTC is mounted and all wiring and connections have been made and are correct");
    hardwareErr();
  }

  lcd.clear();
  lcd.setCursor(0, 0);

  Serial.print("Connecting to WiFi...");
  lcd.print("Connecting to WiFi..");
  WiFi.begin(Triogen_ssid, Triogen_password);

  while(WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(1000);
    WiFiTimeout+=1;

    if(WiFiTimeout == 10) {
      Serial.print("\nCannot connect to WiFi. time will be derived from last time set on RTC and offline mode will be used instead.\n\n");
      lcd.clear();
      lcd.print("No WiFi available");
      lcd.setCursor(0,2);
      lcd.print("Offline mode will");
      lcd.setCursor(0,3);
      lcd.print("be used instead");
      delay(5000);
      DateTime now = rtc.now();
      year = now.year() - 2000;
      month = now.month();
      day = now.day();
      hour = now.hour();
      minute = now.minute();
      second = now.second();
      break;
    }
  }

  if(WiFi.status() == WL_CONNECTED){
    lcd.setCursor(0, 1);
    Serial.println();
    printAll("WIFI CONNECTED");
    timeClient.begin();
    timeClient.update();
  
    lcd.setCursor(0, 3);
    Serial.printf("Getting time from %s...", NTPserver);
    lcd.setCursor(0, 2);
    lcd.print("Getting time from   ");
    lcd.setCursor(0, 3);
    lcd.print(NTPserver);
    lcd.print("...     ");
    time(&now);
    localtime_r(&now, &myTimeInfo);
    configTime(GMToffsetSec, daylightOffsetSec, NTPserver);

    while(!getLocalTime(&myTimeInfo)) {
      Serial.print(".");
    }

    int year   = myTimeInfo.tm_year + 1900; 
    int month  = myTimeInfo.tm_mon + 1;    
    int day    = myTimeInfo.tm_mday;
    int hour   = myTimeInfo.tm_hour;
    int minute = myTimeInfo.tm_min;
    int second = myTimeInfo.tm_sec; 

    char NTPtime[70];
    rtc.adjust(DateTime(year, month, day, hour, minute, second));
    sprintf(NTPtime, "Date: %02d-%02d-%02d Time: %02d:%02d:%02d", day, month, year, hour, minute, second);
    Serial.println();
    Serial.println(NTPtime);
  }
}
  

// creates the file and name, and prints lcd info if the file is available to write to
/*******************************************************************************************************************************************************************************/
void createFileAndName() {

  if(WiFi.status() == WL_CONNECTED) {
    year   = myTimeInfo.tm_year + 1900 - 2000;
    month  = myTimeInfo.tm_mon + 1;   
    day    = myTimeInfo.tm_mday;
  }

  else {
    DateTime now = rtc.now();
    year   = now.year() - 2000;
    month  = now.month();
    day    = now.day();
  }
  sprintf(fileName, "%02d-%02d-%d.dat", day, month, year);
  strlcpy(fullPath, dirName, sizeof fullPath);
  strlcat(fullPath, "/", sizeof fullPath);
  strlcat(fullPath, fileName, sizeof fullPath);
  SD.mkdir(dirName);

  // INITIALISE LCD DISPLAY DATA
  /********************************************************************************************************************************************************************************/
  Serial.printf("Full File Path: X:%s \n\n", fullPath);
  lcd.clear();
  lcd.print("TANKLOG");
  lcd.print("     ");
  lcd.print(fileName);
  lcd.setCursor(0, 1);
  lcd.print(F("TEMP:"));
  lcd.setCursor(0, 2);
  lcd.print(F("TANK LVL:"));
  lcd.setCursor(17, 2);

}

void firstWrite() {

  byte txt = strlen(fileName)-4;
  fileName[txt] = '\0';
  dataFile = SD.open(fullPath, FILE_APPEND);
  dataFile.printf("Date: %s\n", fileName);
  dataFile.println("Time(s),Float Switch,Temp(°C)");
  dataFile.close();
}

//  DATA AND DIAGNOSTICS:
/********************************************************************************************************************************************************************************/
void DatalogAndDiagnostics() {

  // TIME INFO:
  /********************************************************************************************************************************************************************************/
  char displayTime[24];
  DateTime now = rtc.now();
  int year = now.year();
  int month = now.month();
  int day = now.day();
  int hour = now.hour();
  int minute = now.minute();
  int second = now.second();

  if (!rtc.begin()) {
    lcd.clear();
    printAll(F("RTC failed"));
    hardwareErr();
  }


  if (day == newDay) {
    createFileAndName();
    firstWrite();
    newDay+=1;
    delay(750);
    
  } 

  unsigned long totMillis = millis() - tStart;
  unsigned long totSeconds = (millis() - tStart) / 1000;
  unsigned long totMinutes = totSeconds / 60;
  unsigned long totHours = totMinutes / 60;
  unsigned long totDays = totHours / 24;

  totSeconds %= 60;
  totMinutes %= 60;
  totHours %= 24;
  totDays %= 7;

  char chardays[2];
  char charhours[3];
  char charminutes[3];
  char charseconds[3];

  dtostrf(totDays, 1, 0, chardays);
  dtostrf(totHours, 2, 0, charhours);
  dtostrf(totMinutes, 2, 0, charminutes);
  dtostrf(totSeconds, 2, 0, charseconds);

  sprintf(displayTime, "%02d:%02d:%02d %sd%sh%sm%ss", hour, minute, second, chardays, charhours, charminutes, charseconds);
  lcd.setCursor(0, 3);
  lcd.print(displayTime);

  unsigned long hToM = hour * 60;
  unsigned long hToS = hToM * 60;
  unsigned long mToS = (minute * 60);
  unsigned long sToS = second;
  unsigned long tmdayInS = hToS + mToS + sToS;

  //SPECIFIC DATALOGGING CODE:
  /********************************************************************************************************************************************************************************/
  dataFile = SD.open(fullPath, FILE_APPEND);

  static int floatSwState;
  static byte nSample = 0;
  const int highTempTm = 1000;
  const int tempErrTm = 1500;
  const int floatSwTm = 500;

  lcd.setCursor(6, 1);
  lcd.print(sensors.getTempCByIndex(0));
  lcd.print("\337C");

  lcd.setCursor(10, 2);

  if (digitalRead(floatSw) == 1) {
    lcd.print("OK    ");
    floatSwState = 1;
  } 
  
  else if (digitalRead(floatSw == 0)) {
    lcd.print("NOT OK");
    floatSwState = 0;

    if (totMillis - lastMillis > floatSwTm) {
      lastMillis = totMillis;

      if (buzzerOutState == 1) {
        digitalWrite(buzzer, 1);
      }

      digitalWrite(RED, 0);
      digitalWrite(GREEN, 0);
      digitalWrite(BLUE, 1);

    } 
    
    else {
      digitalWrite(buzzer, 0);
    }

  }

  if (sensors.getTempCByIndex(0) >= 0 && sensors.getTempCByIndex(0) <= 22) {
    digitalWrite(RED, 0);
    digitalWrite(GREEN, 1);
    digitalWrite(BLUE, 0);
  } 
  
  else if (sensors.getTempCByIndex(0) > 22 && sensors.getTempCByIndex(0) <= 23) {
    analogWrite(RED, 255);
    analogWrite(GREEN, 255);
    digitalWrite(BLUE, 0);
  } 
  
  else if (sensors.getTempCByIndex(0) > 23 && sensors.getTempCByIndex(0) <= 24) {
    analogWrite(RED, 255);
    analogWrite(GREEN, 90);
    digitalWrite(BLUE, 0);
  } 
  
  else if (sensors.getTempCByIndex(0) > 24 && sensors.getTempCByIndex(0) <= 25) {
    digitalWrite(RED, 1);
    digitalWrite(GREEN, 0);
    digitalWrite(BLUE, 0);
  } 
  
  else if (sensors.getTempCByIndex(0) > 25) {

    if (totMillis - lastMillis > highTempTm) {
      lastMillis = totMillis;

      if (buzzerOutState == 1) {
        digitalWrite(buzzer, 1);
      }

      digitalWrite(RED, 1);
      digitalWrite(GREEN, 0);
      digitalWrite(BLUE, 0);
    }
    
    else {
      digitalWrite(buzzer, 0);
      digitalWrite(RED, 0);
      digitalWrite(GREEN, 0);
      digitalWrite(BLUE, 0);
    } 
  }
  
 /* else {
    
    lcd.setCursor(6, 1);
    lcd.print("ERROR  ");
    
    if (totMillis - lastMillis > tempErrTm) {
      lastMillis = totMillis;

      if (buzzerOutState == 1) {
        digitalWrite(buzzer, 1);
      }

      digitalWrite(RED, 1);
      digitalWrite(GREEN, 1);
      digitalWrite(BLUE, 1);
    } 
    
    else {
      digitalWrite(buzzer, 0);
      digitalWrite(RED, 0);
      digitalWrite(GREEN, 0);
      digitalWrite(BLUE, 0);
    }
  } */

  static float aveT1 = sensors.getTempCByIndex(0);
  static float totT1 = aveT1;
  static char charAveT1[6];
  static char charTotT1[8];
  static char charTemp[8];
  static char charTsampleInS[6];

  dtostrf(aveT1, 5, 2, charAveT1);
  dtostrf(totT1, 7, 2, charTotT1);
  dtostrf(sensors.getTempCByIndex(0), 7, 2, charTemp);

  if((sensors.getTempCByIndex(0) == -127 && errCount <=1) || (sensors.getTempCByIndex(0) == 85  && errCount <=1)) {
    dataFile.print("ERROR:");
    dataFile.close();
    errCount+=1;
  } 

  //This part is for code averaging 

  if (totMillis > tSample) {
    nSample +=1;
    aveT1 = totT1 / nSample;
    totT1 += sensors.getTempCByIndex(0);
    Serial.printf("Time: %02d:%02d:%02d | Runtime: %02dd %02dh %02dm %02ds | Sample: %d | Sw: %d | temp(°C):%s | Ave:  %s | Tot:%s\n",
    hour, minute, second, totDays, totHours, totMinutes, totSeconds,
    nSample, floatSwState, charTemp, charAveT1, charTotT1);

    tSample += sampleTm;
    sensors.requestTemperatures();
  }

  char aveData[20];
  char charTmDayInS[7];
  dtostrf(tmdayInS, 5, 0, charTmDayInS);
  sprintf(aveData, "%s,%d,%s", charTmDayInS, floatSwState, charAveT1);

  if (!dataFile) {
    lcd.clear();
    printAll(F("File write Err"));
    hardwareErr();
  }

  static int logCount = 0;
  if (totMillis > tLog) {
    dataFile.println(aveData);
    dataFile.close();
    logCount+=1;
    Serial.printf("\n LOG NO.%d\n", logCount);
    Serial.println("| Time(s) | Float Switch State | Average Temperature(°C) |");
    Serial.printf("|  %s  |         %d          |          %s          |\n\n",
    charTmDayInS, floatSwState, charAveT1);
    tLog += logTm;
  }

  if (nSample > 7) {
    nSample = 0;
    aveT1 = sensors.getTempCByIndex(0);
    totT1 = aveT1;
    errCount = 0;
  }

  // ALARM
  /********************************************************************************************************************************************************************************/
  static bool buzzerState = 1;
  static bool lastBTstate = 0;
  unsigned long lastDebounceTime = 0;
  const byte debounceDelay = 50;
  lcd.setCursor(15, 1);
  lcd.print("ALARM");
  int newBTstate = analogRead(buzzerTogglePin) < 300 ? 1 : 0;

  if (newBTstate != lastBTstate) {
    lastDebounceTime = totMillis;
  }

  if ((totMillis - lastDebounceTime) > debounceDelay) {

    if (newBTstate != BTstate) {
      BTstate = newBTstate;

      if (BTstate == 1) {
        buzzerState = !buzzerState;
      }
    }
  }

  lcd.setCursor(17, 2);

  if (buzzerState == 1) {
    buzzerOutState = 1;
    lcd.print(" ON");
  }

  else if (buzzerState == 0) {
    buzzerOutState = 0;
    lcd.print("OFF");
  }

  lastBTstate = newBTstate;
}

// SETUP() FUNCTION
/********************************************************************************************************************************************************************************/
void setup() {

  Serial.begin(BAUD);
  delay(2000);
  Serial.print("\n\n\n");
  printResetReason();
  initialisation();
  createFileAndName();
  firstWrite();
  tStart = millis();
}

// LOOP() FUNCTION
/********************************************************************************************************************************************************************************/
void loop() {

  DatalogAndDiagnostics();
}

// END OF PROGRAM
/********************************************************************************************************************************************************************************/

These lines do not appear to be in the correct order.

But, you forgot to explain why you think the printed values are not correct, and what "do not match up" means.

I know this is not the problem, I warn you that you included the Triogen.h library twice.

If you go through the samples and add the temp together, the total temp is not equal to the sum of the temperature samples. The total and average seem to be delayed. I didn't explain exactly how because I thought if you look at the data I have shown, it appears to be self explanatory.

Time: 15:25:02 | Runtime: 00d 00h 36m 41s | Sample: 1 at 2201.00s | Sw: 1 | temp(°C):  21.94 | Ave:  21.94 | Tot:  21.94
Time: 15:25:03 | Runtime: 00d 00h 36m 42s | Sample: 2 at 2202.00s | Sw: 1 | temp(°C):  21.87 | Ave:  21.94 | Tot:  43.87
Time: 15:25:04 | Runtime: 00d 00h 36m 43s | Sample: 3 at 2203.00s | Sw: 1 | temp(°C):  21.87 | Ave:  21.94 | Tot:  65.75
Time: 15:25:05 | Runtime: 00d 00h 36m 45s | Sample: 4 at 2205.00s | Sw: 1 | temp(°C):  21.94 | Ave:  21.92 | Tot:  87.62
Time: 15:25:07 | Runtime: 00d 00h 36m 46s | Sample: 5 at 2206.00s | Sw: 1 | temp(°C):  21.94 | Ave:  21.91 | Tot: 109.56
Time: 15:25:08 | Runtime: 00d 00h 36m 47s | Sample: 6 at 2207.00s | Sw: 1 | temp(°C):  21.94 | Ave:  21.91 | Tot: 131.50
Time: 15:25:09 | Runtime: 00d 00h 36m 48s | Sample: 7 at 2208.00s | Sw: 1 | temp(°C):  21.87 | Ave:  21.92 | Tot: 153.44
Time: 15:25:11 | Runtime: 00d 00h 36m 50s | Sample: 8 at 2210.00s | Sw: 1 | temp(°C):  21.87 | Ave:  21.92 | Tot: 175.31

 LOG NO.221
| Time(s) | Float Switch State | Average Temperature(°C) |
|  55511  |         1          |          21.92          |

How are they not in the correct order?

The computer does not make math mistakes, other than roundoff in the last significant decimal place of a floating point operation. If it does not do what you expect, your code is simply wrong.

The total and average seem to be delayed.

Go through the convoluted code to figure out why. Insert Serial.print() lines to directly reveal current values of any variable, at any point in the code.

I suggest to implement a moving average instead of what you have now.

Thanks for that, I didn't notice! I have no idea how that got up there

If it does not do what you expect, your code is simply wrong.

Hence me creating this topic in the first place.

Thanks for the help!

You are welcome.

Since you seem to be unable to explain why you think the results are not what you expect, the best approach to get help is to write and post the minimum code that reproduces the problem. In the process, you are likely to find the mistake.

I did explain, in post #4.

To elaborate, the total and average data both correlate, but they are behind the current temp data.

Time: 16:21:31 | Runtime: 00d 00h 02m 01s | Sample: 1| Sw: 1 | temp(°C):  21.56 | Ave:  21.56 | Tot:  21.56
Time: 16:21:32 | Runtime: 00d 00h 02m 02s | Sample: 2| Sw: 1 | temp(°C):  21.56 | Ave:  21.56 | Tot:  43.13
Time: 16:21:33 | Runtime: 00d 00h 02m 03s | Sample: 3| Sw: 1 | temp(°C):  21.56 | Ave:  21.56 | Tot:  64.69
Time: 16:21:35 | Runtime: 00d 00h 02m 05s | Sample: 4| Sw: 1 | temp(°C):  21.56 | Ave:  21.56 | Tot:  86.25
Time: 16:21:36 | Runtime: 00d 00h 02m 06s | Sample: 5| Sw: 1 | temp(°C):  21.75 | Ave:  21.56 | Tot: 107.81
Time: 16:21:37 | Runtime: 00d 00h 02m 07s | Sample: 6| Sw: 1 | temp(°C):  22.37 | Ave:  21.56 | Tot: 129.56
Time: 16:21:38 | Runtime: 00d 00h 02m 08s | Sample: 7| Sw: 1 | temp(°C):  23.31 | Ave:  21.59 | Tot: 151.94
Time: 16:21:40 | Runtime: 00d 00h 02m 10s | Sample: 8| Sw: 1 | temp(°C):  24.44 | Ave:  21.71 | Tot: 175.25

as you can see, as soon as the temp (temp(°C)) increases, the average and total should both increase accordingly within the same sample, but the average and total only increase 2 readings after the temp(°C) reading. You can see this at sample 5, where temp(°C) increases from 21.56 to 21.75. The average and total should then increase to ~21.60 (21.59 or 21.60 due to rounding) and 107.99, respectively, but they only start to increase at sample 7, which is delayed by 2 readings.

As pointed out in post #2, "aveT1" and "totT1" are not synchronized, because the mathematical operations (lines of code) are not in the order used by everyone else. This can easily lead to confusion.

What order should I put the code in? I tried a few methods, but I’m not at my computer anymore, so I can’t access the code until tomorrow morning.

I have only been coding for a few months, so I’m not sure of the correct lines of code used by everyone else.

Hi Chris,

Can you really not figure that out yourself?

You seem to be the lazy type...

Most helpers here are more keen to help the people that are willing to learn and do some efforts...

Where did you get all the other code? It is probably not yours...

Most people compute an average by adding up a few values then dividing the sum by the count.

The code you posted divides the sum by the count, then adds some new value to the sum.

So, the sum and the average are inconsistent, which seems to explain your complaint.

However, that is just the first thing that I noticed, and the posted code is so convoluted and hard to follow that I lost interest in trying to find other mistakes.

Here's a thermometer program I wrote, look at how i did the "smoothing", works great for it's intended purpose.

/*
 LM35, TMP36 thermometer for Nano, no floats, no delays
*/
const bool t36 = true; // set false for LM35, true for TMP36
const byte numSamples = 8, // number of samples for smoothing
           aInPin = A7; // analog input pin
const int calValue = -15, // adjust for calibration, +/-0.1 degree
          hAref = 110, // analog ref voltage * 100
                       // measured with accurate DMM
          hnumSamples = numSamples * 100,
          tEnd = 3000; // update time in mS
int val,
    tempC,
    tempF;
uint32_t total,  // sum of samples
         tStart; // timer start
byte cnt = 10;
        
const char header[] = "\nRaw    Total   Temp C  Temp F";
         
void setup()
{
  Serial.begin(9600);
  analogReference(INTERNAL); // use 1.1V internal ref
  analogRead(aInPin);
  for(int i = 0;i < numSamples;i++) // for smoothing, fill total
    total += analogRead(aInPin);   // with numSamples * current
                                   // reading
}
void loop()
{
  if(millis() - tStart > tEnd)
  {
    tStart = millis(); // reset timer
    if(++cnt >= 10)
    {
      Serial.println(header); // every 10 lines
      cnt = 0;
    }
    val = analogRead(aInPin);
    // smoothing ***************************************
    total -= (total / numSamples); // make room for new reading
    total += val; // add new reading
    tempC = total * hAref / hnumSamples + calValue;
    //*************************************************
    if(t36)
      tempC -= 500;
    tempC = antiDither(tempC);
    tempF = tempC * 9 / 5 + 320;
    Serial.print(val);
    Serial.print("\t");
    Serial.print(total); // sum of samples
    Serial.print("\t");
    prntTemp(tempC);
    prntTemp(tempF);
    Serial.println();
  }
}
void prntTemp(int temp)
{
  Serial.print(temp / 10); // whole degrees
  Serial.print(".");
  Serial.print(temp % 10); // tenths
  Serial.print("\t");
}
int antiDither(int newVal) // prevents +1 <-> -1 dither
{                       
  static int val = 0, oldVal = 0;
  if(newVal != val && newVal != oldVal)
  {
    oldVal = val;
    val = newVal;
  }
  return val;
} 

Could you give me an example of how my code is convoluted? This is my first actual project with arduino, and I don't want my code to be hard to follow.

Did you post a response to try and help or to be condescending?

I got some parts of code from examples, but most of it, I wrote myself. As you can see from my account, I'm still new to arduino and coding in general; I've never wrote a line of code before I started using Arduino around December of last year.

I am not lazy, I've been trying to write a python script and get college work completed at the same time, as well as 3D modelling, and a few other things, so I'm doing multiple tasks at once, and I did try to figure it out myself too. A lot of the problems in my code was where I was requesting the temperatures, the location of the variables, and the sampling, so it wasn't as if it was a 'one change fixes all' type of situation.

I figured out the problem anyway.

I took your advice and wrote a code that only averages the temperature readings, and found what I was doing wrong. Thank you!

Hi Chris,

I am definitely not trying to be condescending.
If this code is what you made since December then you have my compliments.

Sometimes it is very difficult to find out what the intention of posters is.
Some just get angry if they are not given 'the code' immediately.

I still do not really get why (if you were able to write a quite complicated program), you did not solve your problem from the hint given in post #2. Those are three lines. It was suggested to change the order of those lines. How many options are there? Which ones make sense?
But I know from experience, that sometimes, you are too far in and need to take a bit of rest and need to come back to solve the problem really quickly...
I saw that you have also found out that it can be very useful to isolate your problem in small program. Glad that that worked for you.

Good luck with your project!

Really?

Your code could be improved by chopping up your functions.
Generally one function should be responsible for one thing.

DatalogAndDiagnostics()

The name says it all. This function does 2 things...
Actually 3, since it also reads the temperature and the time.

It is better to read the temperature once, store it in a variable and do all the comparisons with that variable... Otherwise there is a danger that the reading changes during the analysis with all your if else if... And that could lead to unexpected behaviour... (basically all could evaluate as false...).

If you would put all this in a function, you could add a return after each else if. You would not have to test for < and > in one comparison.
You could start with:

if (x>25) {
  blabla;
  return;
if (x>24) { 
  blalblabla;
  return;

See how that improves readability?