Central Heating controller using the real time clock, PHY module for internet, 1-wire interface for temperature sensors, a system log and a configuration file

Dependencies:   net 1-wire lpc1768 crypto clock web fram log

/media/uploads/andrewboyson/heating.sch

/media/uploads/andrewboyson/heating.brd

/media/uploads/andrewboyson/eagle.epf

Revision:
105:1899f7ed17ec
Parent:
104:46ce1aaf8be7
Child:
106:41ed3ea0bbba
--- a/heating/boiler.c	Wed Feb 10 17:24:36 2021 +0000
+++ b/heating/boiler.c	Tue Feb 23 20:35:07 2021 +0000
@@ -19,14 +19,22 @@
 #define BOILER_CALL_SET FIO2SET(5)
 #define BOILER_CALL_CLR FIO2CLR(5)
 
+#define PUMP_SPEED_CALLING_AUTO_ONLY  -1
+#define PUMP_SPEED_CALLING_AUTO_TWEAK -2
+
+#define MIN_SPEED  40
+#define MAX_SPEED 100
+
 static char*     tankRom; static int iTankRom;
 static char*   outputRom; static int iOutputRom;
 static char*   returnRom; static int iReturnRom;
 
-static int16_t tankSetPoint;       static int iTankSetPoint;
+static int8_t  fullSpeedSecs;      static int iFullSpeedSecs;
+
+static int8_t  tankSetPoint;       static int iTankSetPoint;
 static int16_t tankHysteresis;     static int iTankHysteresis;
 static int16_t runOnResidual16ths; static int iRunOnResidual;
-static uint8_t  runOnTime2s;       static int iRunOnTime;
+static uint8_t runOnTime2s;        static int iRunOnTime;
 
 static int8_t  boilerTarget;       static int iBoilerTarget;
 static int8_t  pumpSpeedCalling;   static int iPumpSpeedCalling;
@@ -36,71 +44,71 @@
 static int16_t rise16thsAt50;      static int iRiseAt50;
 static int16_t rise16thsAt100;     static int iRiseAt100;
 
-uint16_t BoilerGetTankDS18B20Value  () { return DS18B20ValueFromRom(tankRom);   } 
-uint16_t BoilerGetOutputDS18B20Value() { return DS18B20ValueFromRom(outputRom); } 
-uint16_t BoilerGetReturnDS18B20Value() { return DS18B20ValueFromRom(returnRom); } 
-int      BoilerGetTankSetPoint      () { return tankSetPoint;      }
-int      BoilerGetTankHysteresis    () { return tankHysteresis;    } 
-int      BoilerGetRunOnResidual16ths() { return runOnResidual16ths;}
-int      BoilerGetRunOnTime         () { return runOnTime2s << 1;  }
-int      BoilerGetPumpSpeedCalling  () { return pumpSpeedCalling;  }
-int      BoilerGetPumpSpeedRunOn    () { return pumpSpeedRunOn;    }
-int      BoilerGetOutputTarget      () { return boilerTarget;      }
-int      BoilerGetRise16thsAt0      () { return rise16thsAt0;      }
-int      BoilerGetRise16thsAt50     () { return rise16thsAt50;     }
-int      BoilerGetRise16thsAt100    () { return rise16thsAt100;    }
+//Set in main scan
+static int16_t _boilerOutput16ths   = DS18B20_ERROR_VALUE_NOT_SET;
+static int16_t _boilerReturn16ths   = DS18B20_ERROR_VALUE_NOT_SET;
+static int16_t _boilerRtnDel16ths   = DS18B20_ERROR_VALUE_NOT_SET;
+static int16_t _boilerDeltaT16ths   = DS18B20_ERROR_VALUE_NOT_SET;
+static bool    _boilerDeltaTisValid = false;
+
+int16_t  BoilerGetTankDS18B20Value  () { return DS18B20ValueFromRom(tankRom);   } 
+int16_t  BoilerGetOutputDS18B20Value() { return _boilerOutput16ths; } 
+int16_t  BoilerGetReturnDS18B20Value() { return _boilerReturn16ths; }
+int16_t  BoilerGetRtnDelDS18B20Value() { return _boilerRtnDel16ths; }
+int16_t  BoilerGetDeltaTDS18B20Value() { return _boilerDeltaT16ths; } 
+int      BoilerGetFullSpeedSecs     () { return fullSpeedSecs;      }
+int      BoilerGetTankSetPoint      () { return tankSetPoint;       }
+int      BoilerGetTankHysteresis    () { return tankHysteresis;     } 
+int      BoilerGetRunOnDeltaT       () { return runOnResidual16ths; }
+int      BoilerGetRunOnTime         () { return runOnTime2s << 1;   }
+int      BoilerGetPumpSpeedCalling  () { return pumpSpeedCalling;   }
+int      BoilerGetPumpSpeedRunOn    () { return pumpSpeedRunOn;     }
+int      BoilerGetOutputTarget      () { return boilerTarget;       }
+int      BoilerGetMinimumFlow       () { return rise16thsAt0;       }
+int      BoilerGetMidFlowSpeed      () { return rise16thsAt50;      }
+int      BoilerGetFullSpeedDeltaT   () { return rise16thsAt100;     }
 
 static void setTankRom          (char* value) { memcpy(tankRom,      value, 8); FramWrite(iTankRom,         8,  tankRom            ); }
 static void setOutputRom        (char* value) { memcpy(outputRom,    value, 8); FramWrite(iOutputRom,       8,  outputRom          ); }
 static void setReturnRom        (char* value) { memcpy(returnRom,    value, 8); FramWrite(iReturnRom,       8,  returnRom          ); }
-void BoilerSetTankSetPoint      (int   value) { tankSetPoint       = value;     FramWrite(iTankSetPoint,    2, &tankSetPoint       ); }
+void BoilerSetFullSpeedSecs     (int   value) { fullSpeedSecs      = value;     FramWrite(iFullSpeedSecs,   1, &fullSpeedSecs      ); }
+void BoilerSetTankSetPoint      (int   value) { tankSetPoint       = value;     FramWrite(iTankSetPoint,    1, &tankSetPoint       ); }
 void BoilerSetTankHysteresis    (int   value) { tankHysteresis     = value;     FramWrite(iTankHysteresis,  2, &tankHysteresis     ); }
-void BoilerSetRunOnResidual16ths(int   value) { runOnResidual16ths = value;     FramWrite(iRunOnResidual,   2, &runOnResidual16ths ); }
+void BoilerSetRunOnDeltaT       (int   value) { runOnResidual16ths = value;     FramWrite(iRunOnResidual,   2, &runOnResidual16ths ); }
 void BoilerSetRunOnTime         (int   value) { runOnTime2s        = value >> 1;FramWrite(iRunOnTime,       1, &runOnTime2s        ); }
 void BoilerSetPumpSpeedCalling  (int   value) { pumpSpeedCalling   = value;     FramWrite(iPumpSpeedCalling,1, &pumpSpeedCalling   ); }
 void BoilerSetPumpSpeedRunOn    (int   value) { pumpSpeedRunOn     = value;     FramWrite(iPumpSpeedRunOn,  1, &pumpSpeedRunOn     ); }
 void BoilerSetOutputTarget      (int   value) { boilerTarget       = value;     FramWrite(iBoilerTarget,    1, &boilerTarget       ); }
-void BoilerSetRise16thsAt0      (int   value) { rise16thsAt0       = value;     FramWrite(iRiseAt0,         2, &rise16thsAt0       ); }
-void BoilerSetRise16thsAt50     (int   value) { rise16thsAt50      = value;     FramWrite(iRiseAt50,        2, &rise16thsAt50      ); }
-void BoilerSetRise16thsAt100    (int   value) { rise16thsAt100     = value;     FramWrite(iRiseAt100,       2, &rise16thsAt100     ); }
+void BoilerSetMinimumFlow       (int   value) { rise16thsAt0       = value;     FramWrite(iRiseAt0,         2, &rise16thsAt0       ); }
+void BoilerSetMidFlowSpeed      (int   value) { rise16thsAt50      = value;     FramWrite(iRiseAt50,        2, &rise16thsAt50      ); }
+void BoilerSetFullSpeedDeltaT   (int   value) { rise16thsAt100     = value;     FramWrite(iRiseAt100,       2, &rise16thsAt100     ); }
 
 static int calculateBetweenTwoPoints(int x, int xA, int xB, int yA, int yB)
 {
     float m = (float)(yB - yA) / (xB - xA);
     return  yA + m * (x - xA);
 }
-static int oldcalculateBetweenTwoPoints(int point16ths, int pointBig16ths, int pointSmall16ths, int bigSpeed, int width) //width = 1 for 100; 2 for 50 and 4 for 25
-{
-    //Expected to have to compensate the slope for the reduced width but didn't need to.
-    int slope = pointBig16ths - pointSmall16ths;
-    int diff16ths = point16ths - pointSmall16ths;
-    int diffSpeed = (diff16ths * slope * width) >> 8; //points are in 16ths so multiplying them needs a division by 256
-    int requiredSpeed = bigSpeed - diffSpeed;
-    if (requiredSpeed > 100) requiredSpeed = 100;
-    if (requiredSpeed <   0) requiredSpeed = 0;
-    return requiredSpeed;
-}
-
-static int calculatePoint(int targetRise16ths)
+static int calculateSpeedFromDeltaT(int deltaT16ths)
 {
-    if (targetRise16ths > rise16thsAt0) //20
-    {
-        return 0;
-    }
-    else if (targetRise16ths > rise16thsAt50) //15
-    {
-        return calculateBetweenTwoPoints(targetRise16ths, rise16thsAt50, rise16thsAt0, 50, 0);
-        //return oldcalculateBetweenTwoPoints(targetRise16ths, rise16thsAt0, rise16thsAt50, 50, 2);
-    }
-    else if (targetRise16ths > rise16thsAt100) //10
-    {
-        return calculateBetweenTwoPoints(targetRise16ths, rise16thsAt100, rise16thsAt50, 100, 50);
-        //return oldcalculateBetweenTwoPoints(targetRise16ths, rise16thsAt50, rise16thsAt100, 100, 2);
-    }
-    else
-    {
-       return 100;
-    }
+    if (deltaT16ths < rise16thsAt100) return MAX_SPEED; //Needed in case deltaT16ths is negative or zero
+    int flow = MAX_SPEED * rise16thsAt100 / deltaT16ths; //eg for 20 deg ==> 100 * (10 << 4) / (20 << 4) == 50
+    if (flow > MAX_SPEED) flow = MAX_SPEED;
+    if (flow < MIN_SPEED) flow = MIN_SPEED;
+    return flow;
+    
+    //if      (deltaT16ths > rise16thsAt0  ) return MIN_SPEED;
+    //else if (deltaT16ths > rise16thsAt50 ) return calculateBetweenTwoPoints(deltaT16ths, rise16thsAt50,  rise16thsAt0,  MID_SPEED, MIN_SPEED);
+    //else if (deltaT16ths > rise16thsAt100) return calculateBetweenTwoPoints(deltaT16ths, rise16thsAt100, rise16thsAt50, MAX_SPEED, MID_SPEED);
+    //else                                   return MAX_SPEED;
+}
+static int calculateDeltaTFromSpeed(int speed)
+{
+    int deltaT16ths = MAX_SPEED * rise16thsAt100 / speed; //eg for speed = 50 ==> 100 * (10 << 4) / 50 == 20 << 4
+    //if      (speed >= MAX_SPEED) return rise16thsAt100;
+    //else if (speed >  MID_SPEED) return calculateBetweenTwoPoints(speed, MID_SPEED, MAX_SPEED, rise16thsAt50, rise16thsAt100);
+    //else if (speed >  MIN_SPEED) return calculateBetweenTwoPoints(speed, MIN_SPEED, MID_SPEED, rise16thsAt0,  rise16thsAt50 );
+    //else                         return rise16thsAt0;
+    return deltaT16ths;
 }
 
 int BoilerInit()
@@ -127,7 +135,8 @@
                   address = FramLoad( 8,  tankRom,                0); if (address < 0) return -1; iTankRom          = address;
                   address = FramLoad( 8,  outputRom,              0); if (address < 0) return -1; iOutputRom        = address;
                   address = FramLoad( 8,  returnRom,              0); if (address < 0) return -1; iReturnRom        = address;
-    def2 =    65; address = FramLoad( 2, &tankSetPoint,       &def2); if (address < 0) return -1; iTankSetPoint     = address;
+    def1 =   100; address = FramLoad( 1, &fullSpeedSecs,      &def1); if (address < 0) return -1; iFullSpeedSecs    = address;
+    def1 =    65; address = FramLoad( 1, &tankSetPoint,       &def1); if (address < 0) return -1; iTankSetPoint     = address;
     def2 =     5; address = FramLoad( 2, &tankHysteresis,     &def2); if (address < 0) return -1; iTankHysteresis   = address;
     def2 =     2; address = FramLoad( 2, &runOnResidual16ths, &def2); if (address < 0) return -1; iRunOnResidual    = address;
     def1 =   180; address = FramLoad( 1, &runOnTime2s,        &def1); if (address < 0) return -1; iRunOnTime        = address;
@@ -143,35 +152,33 @@
 
     PwmInit(400, 100);
 
-    for (int deltaT = 30; deltaT > 0; deltaT--)
-    {
-        LogF("DeltaT %d ==> speed %d\r\n", deltaT, calculatePoint(deltaT << 4));
-    }
-
     return 0;
 }
+bool BoilerCallEnable = true;
 bool BoilerCall = false;
 static void controlBoilerCall()
 {
-    int tankTemp16ths = DS18B20ValueFromRom(tankRom);
-    if (DS18B20IsValidValue(tankTemp16ths)) //Ignore values which are likely to be wrong
+    if (BoilerCallEnable)
     {
-        int  tankUpper16ths = tankSetPoint   << 4;
-        int hysteresis16ths = tankHysteresis << 4;
-        int  tankLower16ths = tankUpper16ths - hysteresis16ths;
-    
-        if (tankTemp16ths >= tankUpper16ths) BoilerCall = false;
-        if (tankTemp16ths <= tankLower16ths) BoilerCall = true;
+        int tankTemp16ths = DS18B20ValueFromRom(tankRom);
+        if (DS18B20IsValidValue(tankTemp16ths)) //Ignore values which are likely to be wrong
+        {
+            int  tankUpper16ths = tankSetPoint   << 4;
+            int hysteresis16ths = tankHysteresis << 4;
+            int  tankLower16ths = tankUpper16ths - hysteresis16ths;
+        
+            if (tankTemp16ths >= tankUpper16ths) BoilerCall = false;
+            if (tankTemp16ths <= tankLower16ths) BoilerCall = true;
+        }
+    }
+    else
+    {
+        BoilerCall = false;
     }
 }
 bool BoilerPump = false;
 static void controlBoilerPump()
 {
-    int16_t boilerOutput16ths   = DS18B20ValueFromRom(outputRom);
-    int16_t boilerReturn16ths   = DS18B20ValueFromRom(returnRom);
-    int16_t boilerResidual16ths = boilerOutput16ths - boilerReturn16ths;
-    bool    boilerTempsAreValid = DS18B20IsValidValue(boilerOutput16ths) && DS18B20IsValidValue(boilerReturn16ths);
-
     static uint32_t msTimerBoilerPumpRunOn = 0;
     if (BoilerCall)
     {
@@ -181,25 +188,21 @@
     else
     {
         if (MsTimerRelative(msTimerBoilerPumpRunOn,      runOnTime2s * 2000)) BoilerPump = false;
-        if (boilerTempsAreValid && boilerResidual16ths < runOnResidual16ths ) BoilerPump = false;
+        if (_boilerDeltaTisValid && _boilerDeltaT16ths < runOnResidual16ths ) BoilerPump = false;
     }
 }
-int BoilerPumpSpeed = 0;
+int BoilerPumpFlow  = MIN_SPEED;
+int BoilerPumpSpeed = MIN_SPEED;
 int BoilerPumpPwm   = 0;
 static int _autoSpeed = 0;
 static void calculateAutoSpeed()
 {
-    int16_t boilerOutput16ths   = DS18B20ValueFromRom(outputRom);
-    int16_t boilerReturn16ths   = DS18B20ValueFromRom(returnRom);
-    int16_t boilerResidual16ths = boilerOutput16ths - boilerReturn16ths;
-    bool    boilerTempsAreValid = DS18B20IsValidValue(boilerOutput16ths) && DS18B20IsValidValue(boilerReturn16ths);
-    
-    if (!boilerTempsAreValid) return;
+    if (!DS18B20IsValidValue(_boilerReturn16ths)) return;
     
     int target16ths = (int)boilerTarget << 4;
-    int targetRise16ths = target16ths - boilerReturn16ths; //eg 65 - eg 45 = 20*16 16ths
+    int targetRise16ths = target16ths - _boilerReturn16ths; //eg 65 - eg 45 = 20*16 16ths
     
-    _autoSpeed = calculatePoint(targetRise16ths);
+    _autoSpeed = calculateSpeedFromDeltaT(targetRise16ths);
 }
 static void controlBoilerPumpSpeed()
 {
@@ -207,8 +210,8 @@
     calculateAutoSpeed();
     if (BoilerCall)
     {
-        if (pumpSpeedCalling > 100 || pumpSpeedCalling < 0) BoilerPumpSpeed = _autoSpeed;        //Auto
-        else                                                BoilerPumpSpeed = pumpSpeedCalling;  //Manual
+        if (pumpSpeedCalling > MAX_SPEED || pumpSpeedCalling < MIN_SPEED) BoilerPumpSpeed = _autoSpeed;        //Auto
+        else                                                              BoilerPumpSpeed = pumpSpeedCalling;  //Manual
         msTimerReduction = MsTimerCount;
     }
     else
@@ -223,6 +226,10 @@
         }
     }
 }
+static void flowToSpeed()
+{
+    //Do nothing yet
+}
 static void speedToPwm()
 {
     /*
@@ -237,52 +244,118 @@
     Max speed 100 is at fitted = 74; pwm = 10
     Min speed   0 is at fitted =  0; pwm = 84
     */
-    int speed = BoilerPumpSpeed;
-    if (speed <   0) speed =   0;
-    if (speed > 100) speed = 100;
-    speed  *=  74;
-    speed <<=  16;
-    speed  /= 100;
-    speed >>=  16;
-    BoilerPumpPwm = 84 - speed;
+    int pwm = calculateBetweenTwoPoints(BoilerPumpSpeed, MIN_SPEED, MAX_SPEED, 84, 10);
+    if (pwm < 10) pwm = 10;
+    if (pwm > 84) pwm = 84;
+    BoilerPumpPwm = pwm;
 }
 #define TIME_BEFORE_TWEAK_SECS 120
 static void tweakDeltaTs()
 {
+    if (pumpSpeedCalling != PUMP_SPEED_CALLING_AUTO_TWEAK) return;
+    
     static uint32_t msTimerBoilerHeating = 0;
     if (!BoilerCall) msTimerBoilerHeating = MsTimerCount;
     if (!MsTimerRelative(msTimerBoilerHeating, TIME_BEFORE_TWEAK_SECS * 1000)) return;
     
-    int16_t boilerOutput16ths   = DS18B20ValueFromRom(outputRom);
-    int16_t boilerReturn16ths   = DS18B20ValueFromRom(returnRom);
-    int16_t boilerResidual16ths = boilerOutput16ths - boilerReturn16ths;
-    bool    boilerTempsAreValid = DS18B20IsValidValue(boilerOutput16ths) && DS18B20IsValidValue(boilerReturn16ths);
-    if (!boilerTempsAreValid) return;
+    if (!_boilerDeltaTisValid) return;
     
     static int speedLastScan = -1;
     
-    if (speedLastScan == 0 && BoilerPumpSpeed > 0)
-    {
-        if (rise16thsAt0 > boilerResidual16ths) rise16thsAt0--;
-        if (rise16thsAt0 < boilerResidual16ths) rise16thsAt0++;
-    }
-    
-    else if (speedLastScan <= 50 && BoilerPumpSpeed > 50)
+    if (speedLastScan < MAX_SPEED && BoilerPumpSpeed == MAX_SPEED)
     {
-        if (rise16thsAt50 > boilerResidual16ths) rise16thsAt50--;
-        if (rise16thsAt50 < boilerResidual16ths) rise16thsAt50++;
-    }
-    
-    else if (speedLastScan < 100 && BoilerPumpSpeed == 100)
-    {
-        if (rise16thsAt100 > boilerResidual16ths) rise16thsAt100--;
-        if (rise16thsAt100 < boilerResidual16ths) rise16thsAt100++;
+        if (rise16thsAt100 > _boilerDeltaT16ths) rise16thsAt100--;
+        if (rise16thsAt100 < _boilerDeltaT16ths) rise16thsAt100++;
     }
     
     speedLastScan = BoilerPumpSpeed;
 }
+
+#define TIME_BEFORE_DELTA_T_ALARM_SECS 300
+#define DELTA_T_LIMIT (3 << 4)
+static void checkDeltaTs()
+{   
+    static uint32_t msTimerDeltaTNonConform = 0;
+    if (!BoilerCall)
+    {
+        msTimerDeltaTNonConform = MsTimerCount;
+        return;
+    }
+    
+    int expectedDeltaT16ths = calculateDeltaTFromSpeed(BoilerPumpSpeed);
+    
+    bool deltaTisOk = _boilerDeltaTisValid &&
+                      _boilerDeltaT16ths > (expectedDeltaT16ths - DELTA_T_LIMIT) &&
+                      _boilerDeltaT16ths < (expectedDeltaT16ths + DELTA_T_LIMIT);
+    
+    
+    static bool deltaTwasOk = true;
+    
+    /*
+    if (deltaTwasOk != deltaTisOk)
+    {
+        LogTimeF("Boiler delta T ");
+        DS18B20Log(_boilerDeltaT16ths);
+        if (deltaTisOk)
+        {
+            Log(" is inside expected value ");
+        }
+        else
+        {
+            Log(" is outside expected value ");
+        }
+        DS18B20Log(expectedDeltaT16ths);
+        Log("\r\n");
+    }
+    
+    deltaTwasOk = deltaTisOk;
+    */
+    
+    static bool hadAlarm = false;
+    if (deltaTisOk) msTimerDeltaTNonConform = MsTimerCount;
+    bool haveAlarm = MsTimerRelative(msTimerDeltaTNonConform, TIME_BEFORE_DELTA_T_ALARM_SECS * 1000);
+    if (haveAlarm && !hadAlarm)
+    {
+        LogTimeF("Boiler delta T would have tripped after not being ok for %d seconds\r\n", TIME_BEFORE_DELTA_T_ALARM_SECS);
+    }
+    hadAlarm = haveAlarm;
+}
+#define NUMBER_OF_STEPS 10
+static int16_t _returns16ths[NUMBER_OF_STEPS]; //0 is last, 9th is first
+static void delayLine()
+{
+    static uint32_t msTimerDelay = 0;
+    if (BoilerPump)
+    {
+        int msTotal = 1000 * fullSpeedSecs * MAX_SPEED / BoilerPumpSpeed; //speed 10 ==> 10000; speed 100 ==> 1000
+        int msPerStep = msTotal / NUMBER_OF_STEPS;
+        if (MsTimerRelative(msTimerDelay, msPerStep))
+        {
+            for (int i = 0; i < NUMBER_OF_STEPS - 1; i++) _returns16ths[i] = _returns16ths[i + 1];
+            _returns16ths[NUMBER_OF_STEPS - 1] = _boilerReturn16ths;
+            msTimerDelay = MsTimerCount;
+            //LogTimeF("Ms per step = %d, delayed boiler return = ", msPerStep);
+            //DS18B20Log(_returns16ths[0]);
+            //Log("\r\n");
+        }
+    }
+    else
+    {
+        msTimerDelay = MsTimerCount;
+        for (int i = 0; i < NUMBER_OF_STEPS; i++) _returns16ths[i] = DS18B20_ERROR_VALUE_NOT_SET;
+    }
+}
+
 void BoilerMain()
 {
+    delayLine();
+    _boilerOutput16ths   = DS18B20ValueFromRom(outputRom);
+    _boilerReturn16ths   = DS18B20ValueFromRom(returnRom);
+    _boilerRtnDel16ths   = _returns16ths[0];
+    _boilerDeltaTisValid = DS18B20IsValidValue(_boilerOutput16ths) && DS18B20IsValidValue(_boilerRtnDel16ths);
+    if (_boilerDeltaTisValid) _boilerDeltaT16ths   = _boilerOutput16ths - _boilerRtnDel16ths;
+    else                      _boilerDeltaT16ths   = DS18B20_ERROR_VALUE_NOT_SET;
+    
     controlBoilerCall();
     if (BoilerCall) BOILER_CALL_SET;
     else            BOILER_CALL_CLR;
@@ -292,9 +365,10 @@
     else            BOILER_PUMP_CLR;
     
     controlBoilerPumpSpeed();
+    flowToSpeed();
     speedToPwm();
     PwmSet(BoilerPumpPwm);
     
     tweakDeltaTs();
-    
+    checkDeltaTs();
 }
\ No newline at end of file