Automatic Control and User Interface for Central Tire Inflation System

#define BLYNK_DEBUG
#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
#include <EEPROM.h>
#include <wdt101.h> 
#include <inttypes.h>
#include <Wire.h>
#include <SimpleTimer.h>

//////////////////////////////////////
// Tire pressure : 1 bit = 0.01 PSI //
// Tank pressure : 1 bit = 0.01 PSI //
//////////////////////////////////////

//////// GLOBAL PARAMETERS /////
// Tire pressure control parameters:
const uint8_t TOLERANCE = 5;  //[Tire pressure storage unit] set point tolerance
const uint16_t ALL_WITHIN_TOL_WAIT_TIME = 8000;  //[ms]
const uint8_t TIME_BETW_MEAS = 50;  //[ms] 
const uint8_t NUM_OF_MEASUREMENTS_SHORT_FILTER = 6;  //Number of measurements averaged
const uint8_t NUM_OF_MEASUREMENTS_LONG_FILTER = 50;  //Number of measurements averaged
const uint16_t MAX_DEFLATION_TIME = 6000;  //[ms] 
const uint16_t MAX_INFLATION_TIME = 6000;  //[ms] 
const uint16_t WITHIN_TOL_SET_POINT_THRESHOLD = 10;  //[raw set point bits]
const uint8_t STAND_BY_THRESHOLD = 10; //Stand by threshold 
const uint8_t STAND_BY_MULTIPLAYER = 4;  //Stand by multiplier
const uint16_t SETTLING_TIME = 100;  //[ms] pressure settling time
const uint16_t VALVE_OPENING_TIME = 7; //[ms]
const float BITS_TO_PSIUNIT_MXP4250 = 2.5360; // 1 bit = 0,038425 psi 
const int16_t FILTER_THRESHOLD = 100;  // raw ADC value
const uint16_t FRONT_AXLE_OFFSET_ADJUST_TIME_LENGTH = 4000;
const uint16_t FRONT_AXLE_OFFSET_LOWER_POT_LIMIT = 50;
const uint16_t FRONT_AXLE_OFFSET_HIGER_POT_LIMIT = 950;

// Tank parameters:
const uint16_t TANKPRESSURE_BLINK_LIMIT = 3000;  //[Tank pressure storage unit]
const uint16_t TANK_PRESS_BLINK_DELAY = 3000;  //[ms]
const float BITS_TO_PSIUNIT_MXP5700 = 11.0135;  // 1 bit = 0,110135 psi
const uint16_t OFFSET_MPX5700 = 35;  // 0 - 1024, raw ADC unit

// Front panel parameters:
const uint16_t POT_NONLINEAR_THRES = 700;  // range (0-1023)
const uint16_t FRONT_PANEL_TIME_THRES_PERIOD = 500;
uint16_t MAX_POT_COUNT = 1020;  //(Not constant) Max output from POT  ATH hĂ©r ĂŸarf aĂ° lĂĄta lesa Ășr EEPROM
uint16_t MIN_POT_COUNT = 0;  //(Not constant) Min output from POT  ATH hĂ©r ĂŸarf aĂ° lĂĄta lesa Ășr EEPROM

const uint8_t SETPOINT_MAXIMUM_PSI = 35;      
const uint8_t PIN_GREEN_LED = V10;
const uint8_t PIN_ALL_INDI = 0;
//const uint8_t PIN_POT = A5;

// Control pins deceleration
const uint8_t PIN_VALVE0 = 5;
const uint8_t PIN_VALVE1 = 6;
const uint8_t PIN_VALVE2 = 7;
const uint8_t PIN_VALVE3 = 8;
const uint8_t PIN_VALVE4 = 9;
const uint8_t PIN_VALVE5 = 3;
const uint8_t PIN_PUMP = 1;

// Sensors
const uint8_t PIN_MPX4250 = A2; 
const uint8_t PIN_MPX5700 = A1;

// EEPROM and control parameters
const uint8_t SINGLE_CHANNEL_DEFLATION_PARAM_ADDRESS = 0;
const uint8_t SINGLE_CHANNEL_INFLATION_PARAM_ADDRESS = 4;
const uint8_t FRONT_CHANNELS_DEFLATION_PARAM_ADDRESS = 8;
const uint8_t FRONT_CHANNELS_INFLATION_PARAM_ADDRESS = 12;
const uint8_t REAR_CHANNELS_DEFLATION_PARAM_ADDRESS = 16;
const uint8_t REAR_CHANNELS_INFLATION_PARAM_ADDRESS = 20;
const uint8_t ALL_CHANNELS_DEFLATION_PARAM_ADDRESS = 24;
const uint8_t ALL_CHANNELS_INFLATION_PARAM_ADDRESS = 28;

// Other constants:
const uint16_t SERIAL_BAUDRATE = 9600;

////////// GLOBAL VARIABLES /////    
// Enum:
enum valveControlCommand {CLOSE_ALL, MEASURE, INFLATE, DEFLATE, CALIBRATION};
enum tireControlState {firstMeasurementOngoing, allWithinTolWaiting, firstMeasurementDone, inflationDeflationDone, secondMeasurementOngoing, secondMeasurementDone};

// Tire pressure control - global variables:
uint8_t activeTire = 0;  //Four tires: 0-3
tireControlState tireState = allWithinTolWaiting;  //Enum
uint16_t tireSensorOffset;  //Raw ADC value
int16_t setPoint = 0;  //[Tire pressure storage unit]
uint16_t currentPotRaw;  //Current set point POT raw value 
int16_t withinTolSetPoint;  //[Tire pressure storage unit]
int16_t summedPressure;  //Temp variable - used to accumulate measurements
boolean isAllWithinTol = false;  //Are all channels within tolerance
uint8_t allWithinTolCounter = 0;  //How many channels have been found in row within tolerance
uint8_t numOfMeasCounter = 0;  //Current number of measurements taken
uint32_t TireTimeThres = 0;  //Tire control time threshold
boolean isChBelow10PSI[4] = {true, true, true, true};
uint16_t firstMeasurementPressure = 0;
uint16_t secondMeasurementPressure = 0;
boolean isDeflating = false;
boolean isInflating = true;
uint16_t deflationTime = 0;
uint16_t inflationTime = 0; 
boolean isSetPointChanged = true;
uint16_t numberOfMeasurementsInUse = NUM_OF_MEASUREMENTS_SHORT_FILTER;
int8_t frontAxleOffset = 0;  // [psi*100] Range -4 to 4 psi ( -400 to 400)
int16_t maxPressureReading = 0;
int16_t minPressureReading = 1023;
uint8_t isShortFilterActive = true;

// Tank pressure control - global variables:
boolean isValve5Closed = true;
int16_t tankPress = 0;  //[Tank pressure storage unit] Current tank pressure
uint32_t tankPressureLCDTimeThres = 0;  //Tank pressure blink time threshold
uint32_t calibrationTankTimeThres = 0;
boolean tankBlink = false; 

// EEPROM and control parameters - global variables:
uint16_t singleChannelDeflationParam = 11000; 
uint16_t singleChannelInflationParam = 1200; 
uint16_t frontChannelsDeflationParam = 11000; 
uint16_t frontChannelsInflationParam = 1200; 
uint16_t rearChannelsDeflationParam = 11000; 
uint16_t rearChannelsInflationParam = 1200; 
uint16_t allChannelsDeflationParam = 11000; 
uint16_t allChannelsInflationParam = 1200; 
uint32_t EEPROMTimeThres = 20000;

// Other - global variables:
uint32_t backgroundTasksTimeThres = 0;  //Front panel time threshold
uint32_t blinkLEDTimeThres = 0;  //Front panel LED blink time threshold
boolean isIndependentEnabled = true;  //Independent channels enabled
uint16_t counter = 0;  //Temp variable for performance test

uint16_t channe6 = 0;
uint16_t channe7 = 0;
uint16_t channe8 = 0;
uint16_t channe9 = 0;

boolean estadoBotao3;
boolean estadoBotao4;
boolean estadoBotao5;
boolean estadoBotao6;
boolean estadoBotao7;
boolean estadoBotao8;
boolean estadoBotao9;

SimpleTimer timer;

// Global objects:
WidgetLCD lcd(V1);
WidgetLCD lcd2(V2);
WidgetLED led3(V3);
WidgetLED led4(V4);
WidgetLED led5(V5);
WidgetLED led6(V6);
WidgetLED led7(V7);
WidgetLED led8(V8);
WidgetLED led9(V9);

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "3295d2122335428a8a8877a04a64367b";

#define W5100_CS  10
#define SDCARD_CS 4



void setup()
{
  Serial.begin(SERIAL_BAUDRATE);
  
  pinMode(PIN_ALL_INDI, INPUT);
  pinMode(PIN_GREEN_LED, OUTPUT);
  pinMode(PIN_VALVE0, OUTPUT);
  pinMode(PIN_VALVE1, OUTPUT);
  pinMode(PIN_VALVE2, OUTPUT);
  pinMode(PIN_VALVE3, OUTPUT);
  pinMode(PIN_VALVE4, OUTPUT);
  pinMode(PIN_VALVE5, OUTPUT);
  pinMode(PIN_PUMP, OUTPUT);
  
  pinMode(SDCARD_CS, OUTPUT);
  digitalWrite(SDCARD_CS, HIGH); // Deselect the SD card
  Blynk.begin(auth, IPAddress(192,168,10,2)); // For more options, see Boards_Ethernet/Arduino_Ethernet_Manual example

  timer.setInterval(2000L, sendUptime);
  
  tireSensorOffset = tireOffsetCalibration();
  loadParamFromEEPROM();
}
 
BLYNK_CONNECTED() 
  {
    Blynk.syncAll();
  }


void loop()
{
  if(backgroundTasksTimeThres < millis())
  {
    backgroundTasks();
  } 
  if(TireTimeThres < millis())
  { 
    tirePressureControl();      
  }
  if(tankPressureLCDTimeThres < millis())
  {
    printTankPressureLCD();
  }

Blynk.run();
timer.run();
bool isReady();
}

void sendUptime()
{
  estadoBotao3 = digitalRead(1);
  if  (estadoBotao3 == HIGH ) {led3.on(); }else{led3.off();}

  estadoBotao4 = digitalRead(3);
  if  (estadoBotao4 == HIGH ) {led4.on(); }else{led4.off();}
  
  estadoBotao5 = digitalRead(5);
  if  (estadoBotao5 == HIGH ) {led5.on(); }else{led5.off();}
  
  estadoBotao6 = digitalRead(6);
  if  (estadoBotao6 == HIGH ) {led6.on(); }else{led6.off();}
  
  estadoBotao7 = digitalRead(7);
  if  (estadoBotao7 == HIGH ) {led7.on(); }else{led7.off();}
  
  estadoBotao8 = digitalRead(8);
  if  (estadoBotao8 == HIGH ) {led8.on(); }else{led8.off();}
  
  estadoBotao9 = digitalRead(9);
if  (estadoBotao9 == HIGH ) {led9.on(); }else{led9.off();}
}
////////////// Support functions: ///////////////////////////

void backgroundTasks()
{
  backgroundTasksTimeThres = millis() + FRONT_PANEL_TIME_THRES_PERIOD;
  readTankPress();
  updatingSetPoint();
  updatingALLOrIndividualSwitch();
  updatingFrontPanelLED();

  // Method to capture set point changes in all-within-tolerance mode where the period is very slow
  if (isAllWithinTol && (abs(setPoint - withinTolSetPoint) > WITHIN_TOL_SET_POINT_THRESHOLD))
  
  {
    TireTimeThres = 0; // Measure the next channel immediately
    withinTolSetPoint = setPoint; // So that this is only caught once - not four times
  }

  // Tank functions - only read sensor when tankValve is closed
  if (isValve5Closed == true)
  {
    readTankPress();
  }
}

void tirePressureControl()
{
  switch (tireState)
  {
    case firstMeasurementOngoing:
      takeOneMoreMeasurement();
      if (numOfMeasCounter >= numberOfMeasurementsInUse)
      {
        tireState = firstMeasurementDone;
      }
      break;

    case firstMeasurementDone:
      if (maxPressureReading - minPressureReading > FILTER_THRESHOLD && isShortFilterActive == true)
      {
        isShortFilterActive = false;
        tireState = firstMeasurementOngoing;
        numberOfMeasurementsInUse = NUM_OF_MEASUREMENTS_LONG_FILTER;
      }
      else
      {
        valveControl(CLOSE_ALL);
        isShortFilterActive = true;
        maxPressureReading = 0;
        minPressureReading = 1023;
        firstMeasurementPressure = calcAverage();
        numberOfMeasurementsInUse = NUM_OF_MEASUREMENTS_SHORT_FILTER;
        displayTirePress(firstMeasurementPressure);
        decideWhatToDo(firstMeasurementPressure);
        updateAllWithinTol();
      }
      break;

    case allWithinTolWaiting:
      valveControl(MEASURE);
      TireTimeThres = millis() + SETTLING_TIME;
      tireState = firstMeasurementOngoing;
      break;

    case inflationDeflationDone:


      if (activeTire == 60)
      {
        tireState = firstMeasurementOngoing;
      }
      else
      {
        tireState = secondMeasurementOngoing;
      }
      valveControl(MEASURE);
      TireTimeThres = millis() + SETTLING_TIME;
      break;

    case secondMeasurementOngoing:
      takeOneMoreMeasurement();
      if (numOfMeasCounter >= numberOfMeasurementsInUse)
      {
        tireState = secondMeasurementDone;
      }
      break;

    case secondMeasurementDone:
      if (maxPressureReading - minPressureReading > FILTER_THRESHOLD && isShortFilterActive == true)
      {
        isShortFilterActive = false;
        tireState = secondMeasurementOngoing;
        numberOfMeasurementsInUse = NUM_OF_MEASUREMENTS_LONG_FILTER;
      }
      else
      {
        isShortFilterActive = true;
        maxPressureReading = 0;
        minPressureReading = 1023;
        secondMeasurementPressure = calcAverage();
        numberOfMeasurementsInUse = NUM_OF_MEASUREMENTS_SHORT_FILTER;
        displayTirePress(secondMeasurementPressure);
        changeToNextChannel();
        updatingControlParameters();
        valveControl(MEASURE);
        TireTimeThres = millis() + SETTLING_TIME;
        tireState = firstMeasurementOngoing;
      }
      break;
  }
}

//Read tankPress from MPX5700 sensor
void readTankPress()
{
  tankPress = (float)(analogRead(PIN_MPX5700) - OFFSET_MPX5700) * BITS_TO_PSIUNIT_MXP5700;
}

void changeToNextChannel()
{
  // 0 - 3 = independent channels, 4 = front (0-1 ch), 5 rear (2-3 ch), 6 all channels
  if (isIndependentEnabled == true)
  {
    activeTire = (activeTire + 1) % 4;
  }
  else if (frontAxleOffset == 0)
  {
    activeTire = 6;
    
    Serial.print(F("activeTire 6: "));
    Serial.println(activeTire, 1);
  }
  else
  {
    if (activeTire == 5)
    {
      activeTire = 4;
    Serial.print(F("activeTire 4: "));
    Serial.println(activeTire, 1);
    }
    else
    {
      activeTire = 5;
    Serial.print(F("activeTire 5: "));
    Serial.println(activeTire, 1);
    }
  }
}

// Print tankPressure to LCD
void printTankPressureLCD()
{
  tankPressureLCDTimeThres = millis() + TANK_PRESS_BLINK_DELAY;
  
  if(tankPress > TANKPRESSURE_BLINK_LIMIT || tankBlink == false)
  { 
    if(tankPress < 995)
    {
      lcd.print(11, 1, "  ");
    }
    else if(tankPress < 9995)
    {
      lcd.print(11, 1, " ");
    }
    lcd.print(0, 1, "PSI Í TANK >");
    lcd.print(11, 1, (tankPress + 5)/100); // 5 is so the rounding will be correct and 100 is because of the way the pressure is stored
    //Serial.print(F("TankPressure 3: "));
    //Serial.println((tankPress + 5), 1);
    tankBlink = true;
  }
  else
  {
    tankBlink = false;
    lcd.print(11, 1, "   ");
  }
}

//Gets value from slider in Blynk app to choose SetPot
BLYNK_WRITE(V11) // Blynk press SET slider, where V11 is MY virtual pin (copy/paste)
{ 
  int pinValue = param.asInt();
  setPoint = constrain(pinValue, 200, 3500); //this is where you put your limits of psi, multiplied by 100 for increased resolution
  delay(50);  //you can omit this one - was needed in my specific case
  String setPoint_str = String((float)setPoint/100, 1); //Function to display a number with one decimal and divide in order to get the correct psi
  lcd.print( 0,0, "VALIÐ PSI >"); //Text for the selected psi
  lcd.print(11,0, setPoint_str);   //here you can send your setPoint to vLCD
  if(setPoint < 995)
      {
        lcd.print(14,0, " ");  // This is for clare of decimal point on screen 
      }  
}


void updatingSetPoint()
{
  uint16_t newPotRaw = setPoint;
  
  if(abs(newPotRaw - currentPotRaw) > 10 ) // POT hysteresis
  {
    uint16_t newSetPoint = potToPSI(newPotRaw);
    if( newSetPoint != setPoint) 
    {
      setPoint = newSetPoint;
      currentPotRaw = newPotRaw;
      isSetPointChanged = true;
    }
  }
}

uint16_t potToPSI(uint16_t potRaw)
{
  uint16_t output = 0;

  if (potRaw < POT_NONLINEAR_THRES)
  {
    output = map(potRaw, MIN_POT_COUNT, POT_NONLINEAR_THRES - 1, 0, 499);
  }
  else
  {
    output = map(potRaw, POT_NONLINEAR_THRES, MAX_POT_COUNT, 500, SETPOINT_MAXIMUM_PSI * 100);
  }
  // Round of numbers higher than 500 (5 PSI)
  if (output > 500)
  {
    output = (output / (int)100) * (int)100;
  }
  else
  {
    output = (output / (int)50) * (int)50;
   
  }
  if (output < 50)
  {
    output = 25;
  }
  return output;
}

void updatingALLOrIndividualSwitch()
{
  boolean allIndiSwitchEnabled = digitalRead(PIN_ALL_INDI);
  if (allIndiSwitchEnabled && !isIndependentEnabled)
  {
    activeTire = 0;
    isIndependentEnabled = true;
    TireTimeThres = 0;
    allWithinTolCounter = 0;
    isAllWithinTol = 0;
    valveControl(CLOSE_ALL);
    Serial.print(F("satt: "));
    Serial.println(PIN_ALL_INDI, 1);
  }
  else if (!allIndiSwitchEnabled && isIndependentEnabled)
  {
    activeTire = 6;
    isIndependentEnabled = false;
    TireTimeThres = 0;
    allWithinTolCounter = 0;
    isAllWithinTol = 0;
    valveControl(CLOSE_ALL);
    Serial.print(F("falst: "));
    Serial.println(PIN_ALL_INDI,1);
  }
  delay(500);
}

void updatingFrontPanelLED()
{
  if (isAllWithinTol)
  {
    digitalWrite(PIN_GREEN_LED, 1);
  }
  else
  {
    digitalWrite(PIN_GREEN_LED, 0);
  }
}

void takeOneMoreMeasurement()
{
  uint16_t temp = analogRead(PIN_MPX4250) - tireSensorOffset;
  if (temp > maxPressureReading)
  {
    maxPressureReading = temp;
  }
  if (temp < minPressureReading)
  {
    minPressureReading = temp;
  }
  summedPressure = summedPressure + temp;
  numOfMeasCounter += 1;
  TireTimeThres = millis() + TIME_BETW_MEAS;
}

uint16_t calcAverage()
{
  numOfMeasCounter = 0;
  int16_t currentPressure = (float)(summedPressure / numberOfMeasurementsInUse) * BITS_TO_PSIUNIT_MXP4250;
  if ( currentPressure < 0 )
  {
    currentPressure = 0;
  }
  summedPressure = 0;
  return currentPressure;
}
 
void displayTirePress(uint16_t currentPressure)
{
  float printOutPress = (float)currentPressure/(float)100;
  
  if(currentPressure > 37000) // This is to eliminate "negative" pressure
  {
    currentPressure = 0;
  }
  uint8_t isCurrentPressBelow10psi = currentPressure < 995; 
  uint8_t startChannel = 0;
  uint8_t endChannel = 0;
  switch (activeTire)
  {
  case 0:
    channe6 = currentPressure;
    startChannel = activeTire;
    endChannel = activeTire;
    isChBelow10PSI[activeTire] = isCurrentPressBelow10psi;
    break;
  case 1:
    channe7 = currentPressure;
    startChannel = activeTire;
    endChannel = activeTire;
    isChBelow10PSI[activeTire] = isCurrentPressBelow10psi;
    break;
  case 2:
    channe8 = currentPressure;
    startChannel = activeTire;
    endChannel = activeTire;
    isChBelow10PSI[activeTire] = isCurrentPressBelow10psi;
    break;
  case 3:
    channe9 = currentPressure;
    startChannel = activeTire;
    endChannel = activeTire;
    isChBelow10PSI[activeTire] = isCurrentPressBelow10psi;
    break;
  case 4:
    channe6 = currentPressure;
    channe7 = currentPressure;
    startChannel = 0;
    endChannel = 1;
    isChBelow10PSI[0] = isCurrentPressBelow10psi;
    isChBelow10PSI[1] = isCurrentPressBelow10psi;
    break;
  case 5:
    channe8 = currentPressure;
    channe9 = currentPressure;
    startChannel = 2;
    endChannel = 3;
    isChBelow10PSI[2] = isCurrentPressBelow10psi;
    isChBelow10PSI[3] = isCurrentPressBelow10psi;
    break;
  case 6:
    channe6 = currentPressure;
    channe7 = currentPressure;
    channe8 = currentPressure;
    channe9 = currentPressure;
    startChannel = 0;
    endChannel = 3;
    isChBelow10PSI[0] = isCurrentPressBelow10psi;
    isChBelow10PSI[1] = isCurrentPressBelow10psi;
    isChBelow10PSI[2] = isCurrentPressBelow10psi;
    isChBelow10PSI[3] = isCurrentPressBelow10psi;
    break;  
  }
  
  for(uint8_t i = startChannel; i < endChannel+1; i++)
  {
    String printOutPress_str = String((float)printOutPress, 1); //Function to display a number with one decimal
    lcd2.print(7, 0, "<>"); //symbols lcd
    lcd2.print(7, 1, "<>"); //symbols lcd
    lcd2.print(3, 0, printOutPress_str); //Printed on lcd air pressure for tires
    lcd2.print(0, 0, "VF"); //Which tire is measured in left front
    lcd2.print(3, 1, printOutPress_str); //Printed on lcd air pressure for tires
    lcd2.print(0, 1, "VA"); //Which tire is measured in left rear
    lcd2.print(10, 0, printOutPress_str); //Printed on lcd air pressure for tires
    lcd2.print(14, 0, "HF"); //Which tire is measured in right front
    lcd2.print(10, 1, printOutPress_str); //Printed on lcd air pressure for tires
    lcd2.print(14, 1, "HA"); //Which tire is measured in right back
  }
}


void updateAllWithinTol()
{
  uint8_t numberOfChannelsInUse = 0;
  switch (activeTire)
  {
    case 0:
    case 1:
    case 2:
    case 3:
      numberOfChannelsInUse = 3;
      break;
    case 4:
    case 5:
      numberOfChannelsInUse = 2;
      break;
    case 6:
      numberOfChannelsInUse = 1;
      break;
  }
  if (allWithinTolCounter >= numberOfChannelsInUse && !isAllWithinTol)
  {
    isAllWithinTol = true;
    withinTolSetPoint = setPoint;
    isSetPointChanged = false;
  }
  else if (allWithinTolCounter < numberOfChannelsInUse)
  {
    isAllWithinTol = false;
  }
}

uint16_t calculateDeflationTime(uint16_t currentPressure)
{
  uint16_t deflationParamInUse = 0;
  switch (activeTire)
  {
    case 0:
    case 1:
    case 2:
    case 3:
      deflationParamInUse = singleChannelDeflationParam;
      break;
    case 4:
      deflationParamInUse = frontChannelsDeflationParam;
      break;
    case 5:
      deflationParamInUse = rearChannelsDeflationParam;
      break;
    case 6:
      deflationParamInUse = allChannelsDeflationParam;
      break;
  }

  uint16_t timeMilliSec = ((deflationParamInUse * 10) / log( (float)currentPressure / (float)setPoint )) + VALVE_OPENING_TIME;
  if (timeMilliSec > MAX_DEFLATION_TIME)
  {
    timeMilliSec =  MAX_DEFLATION_TIME;
  }
  return timeMilliSec;
}

uint16_t calculateInflationTimeMS(uint16_t currentPressure)
{
  uint16_t inflationParamInUse = 0;
  switch (activeTire)
  {
    case 0:
    case 1:
    case 2:
    case 3:
      inflationParamInUse = singleChannelInflationParam;
      break;
    case 4:
      inflationParamInUse = frontChannelsInflationParam;
      break;
    case 5:
      inflationParamInUse = rearChannelsInflationParam;
      break;
    case 6:
      inflationParamInUse = allChannelsInflationParam;
      break;
  }

  uint16_t timeMilliSec = ((float)( setPoint - currentPressure ) * ( inflationParamInUse / 100 ) ) + VALVE_OPENING_TIME;
  if (timeMilliSec > MAX_INFLATION_TIME)
  {
    timeMilliSec =  MAX_INFLATION_TIME;
  }
  return timeMilliSec;
}

void decideWhatToDo(int16_t currentPressure)
{
  int16_t difference = currentPressure - setPoint;
  if (activeTire == 0 || activeTire == 1 || activeTire == 4)
  {
    difference = difference - frontAxleOffset;
  }
  if (abs(difference) > TOLERANCE) // Last measurement not within tolerance
  {
    allWithinTolCounter = 0;
    if (difference > 0)
    {
      valveControl(DEFLATE);
      deflationTime = calculateDeflationTime(currentPressure);
      TireTimeThres = millis() + deflationTime;
    }
    else if (1)  //tankPress > 0) // inflation only performed if tank press > 30 psi
    {
      valveControl(INFLATE);
      inflationTime = calculateInflationTimeMS(currentPressure);
      TireTimeThres = millis() + inflationTime;
    }
    tireState = inflationDeflationDone;
  }
  else // Last measurement within tolerance
  {
    allWithinTolCounter += 1;
    changeToNextChannel();

    if (isAllWithinTol && allWithinTolCounter > STAND_BY_THRESHOLD)
    {
      closeAllValves();
      TireTimeThres = millis() + (STAND_BY_MULTIPLAYER * ALL_WITHIN_TOL_WAIT_TIME);
      tireState = allWithinTolWaiting;
    }
    else if (isAllWithinTol)
    {
      closeAllValves();
      if (activeTire == 6)
      {
        openActiveTireValve();
      }
      TireTimeThres = millis() + ALL_WITHIN_TOL_WAIT_TIME;
      tireState = allWithinTolWaiting;
    }
    else
    {
      valveControl(MEASURE);
      TireTimeThres = millis() + SETTLING_TIME;
      tireState = firstMeasurementOngoing;
    }
  }
}

void openActiveTireValve()
{
  switch (activeTire)
  {
    case 0:
      digitalWrite(PIN_VALVE1, HIGH);
      break;
    case 1:
      digitalWrite(PIN_VALVE2, HIGH);
      break;
    case 2:
      digitalWrite(PIN_VALVE3, HIGH);
      break;
    case 3:
      digitalWrite(PIN_VALVE4, HIGH);
      break;
    case 4:
      digitalWrite(PIN_VALVE1, HIGH);
      digitalWrite(PIN_VALVE2, HIGH);
      break;
    case 5:
      digitalWrite(PIN_VALVE3, HIGH);
      digitalWrite(PIN_VALVE4, HIGH);
      break;
    case 6:
      digitalWrite(PIN_VALVE1, HIGH);
      digitalWrite(PIN_VALVE2, HIGH);
      digitalWrite(PIN_VALVE3, HIGH);
      digitalWrite(PIN_VALVE4, HIGH);
      break;
  }
}

void closeAllValves()
{
  digitalWrite(PIN_VALVE0, LOW);
  digitalWrite(PIN_VALVE1, LOW);
  digitalWrite(PIN_VALVE2, LOW);
  digitalWrite(PIN_VALVE3, LOW);
  digitalWrite(PIN_VALVE4, LOW);
  digitalWrite(PIN_VALVE5, LOW);
}

void valveControl(int command)
{
  closeAllValves();
  isValve5Closed = true;
  switch (command)
  {
    case CLOSE_ALL:
      // Empty on purpose
      break;
    case MEASURE:
      openActiveTireValve();
      break;
    case INFLATE:
      isInflating = true;
      openActiveTireValve();
      digitalWrite(PIN_VALVE5, HIGH);
      isValve5Closed = false;
      break;
    case DEFLATE:
      isDeflating = true;
      openActiveTireValve();
      digitalWrite(PIN_VALVE0, HIGH);
      break;
    case CALIBRATION:
      digitalWrite(PIN_VALVE0, HIGH);
      break;
  }
}

uint16_t tireOffsetCalibration()
{
  valveControl(CALIBRATION);
  //delay(250);
  uint16_t temp = 0;
  for (int8_t i = 0; i < NUM_OF_MEASUREMENTS_SHORT_FILTER; i = i + 1)
  {
    temp = temp + analogRead(PIN_MPX4250);
    delay(TIME_BETW_MEAS);
  }
  uint16_t tireSensorOffset = (temp / NUM_OF_MEASUREMENTS_SHORT_FILTER);
  valveControl(CLOSE_ALL);
  //delay(250);
  return tireSensorOffset;
}

void writeParamToEEPROM()
{
  // Unfinished function
}

void loadParamFromEEPROM()
{
  singleChannelDeflationParam = EEPROM.read(SINGLE_CHANNEL_DEFLATION_PARAM_ADDRESS);
  singleChannelInflationParam = EEPROM.read(SINGLE_CHANNEL_INFLATION_PARAM_ADDRESS);
  frontChannelsDeflationParam = EEPROM.read(FRONT_CHANNELS_DEFLATION_PARAM_ADDRESS);
  frontChannelsInflationParam = EEPROM.read(FRONT_CHANNELS_DEFLATION_PARAM_ADDRESS);
  rearChannelsDeflationParam = EEPROM.read(REAR_CHANNELS_DEFLATION_PARAM_ADDRESS);
  rearChannelsInflationParam = EEPROM.read(REAR_CHANNELS_DEFLATION_PARAM_ADDRESS);
  allChannelsDeflationParam = EEPROM.read(ALL_CHANNELS_DEFLATION_PARAM_ADDRESS);
  allChannelsInflationParam = EEPROM.read(ALL_CHANNELS_DEFLATION_PARAM_ADDRESS);
}

void updatingControlParameters()
{
  if (isDeflating && isInflating)
  {
    // Error: should not happen
  }
  else if (isDeflating && deflationTime > 0 && (firstMeasurementPressure - secondMeasurementPressure) > 0)
  {
    uint16_t newDeflationParam = deflationTime / log( (float)firstMeasurementPressure / (float)secondMeasurementPressure) / 10;

    switch (activeTire)
    {
      case 0:
      case 1:
      case 2:
      case 3:
        singleChannelDeflationParam = newDeflationParam;
        break;
      case 4:
        frontChannelsDeflationParam = newDeflationParam;
        break;
      case 5:
        rearChannelsDeflationParam = newDeflationParam;
        break;
      case 6:
        allChannelsDeflationParam = newDeflationParam;
        break;
    }

  }
  else if (isInflating && inflationTime > 0 && (secondMeasurementPressure > firstMeasurementPressure))
  {
    uint16_t newInflationParam = inflationTime / (float)(secondMeasurementPressure - firstMeasurementPressure) * 100;

    switch (activeTire)
    {
      case 0:
      case 1:
      case 2:
      case 3:
        singleChannelInflationParam = newInflationParam;
        break;
      case 4:
        frontChannelsInflationParam = newInflationParam;
        break;
      case 5:
        rearChannelsInflationParam = newInflationParam;
        break;
      case 6:
        allChannelsInflationParam = newInflationParam;
        break;
    }
  }
  isDeflating = false;
  isInflating = false;
  if ( EEPROMTimeThres < millis() )
  {
    EEPROMTimeThres = millis() + 5000;
    writeParamToEEPROM();
  }
}

int16_t updateFrontAxleOffset()
{
  closeAllValves();
  int16_t offset = 0;
  for (uint8_t i = 0; i < 20; i++)
  {
    offset = map(analogRead(setPoint),0,1023,-8,8) * 50; // range from -4 to 4 psi with 0,5 psi resolution
    if(offset >= 0)
    {
      lcd.print(11, 0, " ");
    }
    String offset_str = String((float)offset/100, 1);
    lcd.print(11, 0, offset_str);
    delay(250);
  }
  return offset;
}

OK, try if with this one the flood occurs.

A few quick notes:

  1. probably the flood occurred in displayTirePress()
  2. You shouldn’t have deleted the LCD_X[] and LCD_Y[] arrays. What you have done with multiple lcd2.print(..) within for loop was not correct (try to figure out why :wink: )
  3. why enabled the updatingSetPoint() ? this one was for manual pot input. Disabled here.
  4. you have included wdt101 (a watchdog timer) but no wdt handling in code. Either disable it (not include the wdt101) or complete basing on provided examples (at github for example)
#define BLYNK_DEBUG
#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
#include <EEPROM.h>
#include <wdt101.h> 
#include <inttypes.h>
#include <Wire.h>
#include <SimpleTimer.h>

//////////////////////////////////////
// Tire pressure : 1 bit = 0.01 PSI //
// Tank pressure : 1 bit = 0.01 PSI //
//////////////////////////////////////

//////// GLOBAL PARAMETERS /////
// Tire pressure control parameters:
const uint8_t TOLERANCE = 5;  //[Tire pressure storage unit] set point tolerance
const uint16_t ALL_WITHIN_TOL_WAIT_TIME = 8000;  //[ms]
const uint8_t TIME_BETW_MEAS = 50;  //[ms] 
const uint8_t NUM_OF_MEASUREMENTS_SHORT_FILTER = 6;  //Number of measurements averaged
const uint8_t NUM_OF_MEASUREMENTS_LONG_FILTER = 50;  //Number of measurements averaged
const uint16_t MAX_DEFLATION_TIME = 6000;  //[ms] 
const uint16_t MAX_INFLATION_TIME = 6000;  //[ms] 
const uint16_t WITHIN_TOL_SET_POINT_THRESHOLD = 10;  //[raw set point bits]
const uint8_t STAND_BY_THRESHOLD = 10; //Stand by threshold 
const uint8_t STAND_BY_MULTIPLAYER = 4;  //Stand by multiplier
const uint16_t SETTLING_TIME = 100;  //[ms] pressure settling time
const uint16_t VALVE_OPENING_TIME = 7; //[ms]
const float BITS_TO_PSIUNIT_MXP4250 = 2.5360; // 1 bit = 0,038425 psi 
const int16_t FILTER_THRESHOLD = 100;  // raw ADC value
const uint16_t FRONT_AXLE_OFFSET_ADJUST_TIME_LENGTH = 4000;
const uint16_t FRONT_AXLE_OFFSET_LOWER_POT_LIMIT = 50;
const uint16_t FRONT_AXLE_OFFSET_HIGER_POT_LIMIT = 950;

// Tank parameters:
const uint16_t TANKPRESSURE_BLINK_LIMIT = 3000;  //[Tank pressure storage unit]
const uint16_t TANK_PRESS_BLINK_DELAY = 3000;  //[ms]
const float BITS_TO_PSIUNIT_MXP5700 = 11.0135;  // 1 bit = 0,110135 psi
const uint16_t OFFSET_MPX5700 = 35;  // 0 - 1024, raw ADC unit

// Front panel parameters:
const uint16_t POT_NONLINEAR_THRES = 700;  // range (0-1023)
const uint16_t FRONT_PANEL_TIME_THRES_PERIOD = 500;
uint16_t MAX_POT_COUNT = 1020;  //(Not constant) Max output from POT  ATH hĂ©r ĂŸarf aĂ° lĂĄta lesa Ășr EEPROM
uint16_t MIN_POT_COUNT = 0;  //(Not constant) Min output from POT  ATH hĂ©r ĂŸarf aĂ° lĂĄta lesa Ășr EEPROM
const int LCD_X[] = {3, 10, 3, 10};  // The position coordinates of the tire pressure on the screen
const int LCD_Y[] = {0,  0, 1,  1};

const uint8_t SETPOINT_MAXIMUM_PSI = 35;      
const uint8_t PIN_GREEN_LED = V10;
const uint8_t PIN_ALL_INDI = 0;
//const uint8_t PIN_POT = A5;

// Control pins deceleration
const uint8_t PIN_VALVE0 = 5;
const uint8_t PIN_VALVE1 = 6;
const uint8_t PIN_VALVE2 = 7;
const uint8_t PIN_VALVE3 = 8;
const uint8_t PIN_VALVE4 = 9;
const uint8_t PIN_VALVE5 = 3;
const uint8_t PIN_PUMP = 1;

// Sensors
const uint8_t PIN_MPX4250 = A2; 
const uint8_t PIN_MPX5700 = A1;

// EEPROM and control parameters
const uint8_t SINGLE_CHANNEL_DEFLATION_PARAM_ADDRESS = 0;
const uint8_t SINGLE_CHANNEL_INFLATION_PARAM_ADDRESS = 4;
const uint8_t FRONT_CHANNELS_DEFLATION_PARAM_ADDRESS = 8;
const uint8_t FRONT_CHANNELS_INFLATION_PARAM_ADDRESS = 12;
const uint8_t REAR_CHANNELS_DEFLATION_PARAM_ADDRESS = 16;
const uint8_t REAR_CHANNELS_INFLATION_PARAM_ADDRESS = 20;
const uint8_t ALL_CHANNELS_DEFLATION_PARAM_ADDRESS = 24;
const uint8_t ALL_CHANNELS_INFLATION_PARAM_ADDRESS = 28;

// Other constants:
const uint16_t SERIAL_BAUDRATE = 9600;

////////// GLOBAL VARIABLES /////    
// Enum:
enum valveControlCommand {CLOSE_ALL, MEASURE, INFLATE, DEFLATE, CALIBRATION};
enum tireControlState {firstMeasurementOngoing, allWithinTolWaiting, firstMeasurementDone, inflationDeflationDone, secondMeasurementOngoing, secondMeasurementDone};

// Tire pressure control - global variables:
uint8_t activeTire = 0;  //Four tires: 0-3
tireControlState tireState = allWithinTolWaiting;  //Enum
uint16_t tireSensorOffset;  //Raw ADC value
int16_t setPoint = 0;  //[Tire pressure storage unit]
uint16_t currentPotRaw;  //Current set point POT raw value 
int16_t withinTolSetPoint;  //[Tire pressure storage unit]
int16_t summedPressure;  //Temp variable - used to accumulate measurements
boolean isAllWithinTol = false;  //Are all channels within tolerance
uint8_t allWithinTolCounter = 0;  //How many channels have been found in row within tolerance
uint8_t numOfMeasCounter = 0;  //Current number of measurements taken
uint32_t TireTimeThres = 0;  //Tire control time threshold
boolean isChBelow10PSI[4] = {true, true, true, true};
uint16_t firstMeasurementPressure = 0;
uint16_t secondMeasurementPressure = 0;
boolean isDeflating = false;
boolean isInflating = true;
uint16_t deflationTime = 0;
uint16_t inflationTime = 0; 
boolean isSetPointChanged = true;
uint16_t numberOfMeasurementsInUse = NUM_OF_MEASUREMENTS_SHORT_FILTER;
int8_t frontAxleOffset = 0;  // [psi*100] Range -4 to 4 psi ( -400 to 400)
int16_t maxPressureReading = 0;
int16_t minPressureReading = 1023;
uint8_t isShortFilterActive = true;

// Tank pressure control - global variables:
boolean isValve5Closed = true;
int16_t tankPress = 0;  //[Tank pressure storage unit] Current tank pressure
uint32_t tankPressureLCDTimeThres = 0;  //Tank pressure blink time threshold
uint32_t calibrationTankTimeThres = 0;
boolean tankBlink = false; 

// EEPROM and control parameters - global variables:
uint16_t singleChannelDeflationParam = 11000; 
uint16_t singleChannelInflationParam = 1200; 
uint16_t frontChannelsDeflationParam = 11000; 
uint16_t frontChannelsInflationParam = 1200; 
uint16_t rearChannelsDeflationParam = 11000; 
uint16_t rearChannelsInflationParam = 1200; 
uint16_t allChannelsDeflationParam = 11000; 
uint16_t allChannelsInflationParam = 1200; 
uint32_t EEPROMTimeThres = 20000;

// Other - global variables:
uint32_t backgroundTasksTimeThres = 0;  //Front panel time threshold
uint32_t blinkLEDTimeThres = 0;  //Front panel LED blink time threshold
boolean isIndependentEnabled = true;  //Independent channels enabled
uint16_t counter = 0;  //Temp variable for performance test

uint16_t channe6 = 0;
uint16_t channe7 = 0;
uint16_t channe8 = 0;
uint16_t channe9 = 0;

boolean estadoBotao3;
boolean estadoBotao4;
boolean estadoBotao5;
boolean estadoBotao6;
boolean estadoBotao7;
boolean estadoBotao8;
boolean estadoBotao9;

SimpleTimer timer;

// Global objects:
WidgetLCD lcd(V1);
WidgetLCD lcd2(V2);
WidgetLED led3(V3);
WidgetLED led4(V4);
WidgetLED led5(V5);
WidgetLED led6(V6);
WidgetLED led7(V7);
WidgetLED led8(V8);
WidgetLED led9(V9);

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "3295d2122335428a8a8877a04a64367b";

#define W5100_CS  10
#define SDCARD_CS 4



void setup()
{
  Serial.begin(SERIAL_BAUDRATE);
  
  pinMode(PIN_ALL_INDI, INPUT);
  pinMode(PIN_GREEN_LED, OUTPUT);
  pinMode(PIN_VALVE0, OUTPUT);
  pinMode(PIN_VALVE1, OUTPUT);
  pinMode(PIN_VALVE2, OUTPUT);
  pinMode(PIN_VALVE3, OUTPUT);
  pinMode(PIN_VALVE4, OUTPUT);
  pinMode(PIN_VALVE5, OUTPUT);
  pinMode(PIN_PUMP, OUTPUT);
  
  pinMode(SDCARD_CS, OUTPUT);
  digitalWrite(SDCARD_CS, HIGH); // Deselect the SD card
  Blynk.begin(auth, IPAddress(192,168,10,2)); // For more options, see Boards_Ethernet/Arduino_Ethernet_Manual example

  timer.setInterval(2000L, sendUptime);
  
  tireSensorOffset = tireOffsetCalibration();
  loadParamFromEEPROM();
}
 
BLYNK_CONNECTED() 
  {
    Blynk.syncAll();
  }


void loop()
{
  if(backgroundTasksTimeThres < millis())
  {
    backgroundTasks();
  } 
  if(TireTimeThres < millis())
  { 
    tirePressureControl();      
  }
  if(tankPressureLCDTimeThres < millis())
  {
    printTankPressureLCD();
  }

Blynk.run();
timer.run();
bool isReady();
}

void sendUptime()
{
  estadoBotao3 = digitalRead(1);
  if  (estadoBotao3 == HIGH ) {led3.on(); }else{led3.off();}

  estadoBotao4 = digitalRead(3);
  if  (estadoBotao4 == HIGH ) {led4.on(); }else{led4.off();}
  
  estadoBotao5 = digitalRead(5);
  if  (estadoBotao5 == HIGH ) {led5.on(); }else{led5.off();}
  
  estadoBotao6 = digitalRead(6);
  if  (estadoBotao6 == HIGH ) {led6.on(); }else{led6.off();}
  
  estadoBotao7 = digitalRead(7);
  if  (estadoBotao7 == HIGH ) {led7.on(); }else{led7.off();}
  
  estadoBotao8 = digitalRead(8);
  if  (estadoBotao8 == HIGH ) {led8.on(); }else{led8.off();}
  
  estadoBotao9 = digitalRead(9);
if  (estadoBotao9 == HIGH ) {led9.on(); }else{led9.off();}
}
////////////// Support functions: ///////////////////////////

void backgroundTasks()
{
  backgroundTasksTimeThres = millis() + FRONT_PANEL_TIME_THRES_PERIOD;
  readTankPress();
  //updatingSetPoint();
  updatingALLOrIndividualSwitch();
  updatingFrontPanelLED();

  // Method to capture set point changes in all-within-tolerance mode where the period is very slow
  if (isAllWithinTol && (abs(setPoint - withinTolSetPoint) > WITHIN_TOL_SET_POINT_THRESHOLD))
  
  {
    TireTimeThres = 0; // Measure the next channel immediately
    withinTolSetPoint = setPoint; // So that this is only caught once - not four times
  }

  // Tank functions - only read sensor when tankValve is closed
  if (isValve5Closed == true)
  {
    readTankPress();
  }
}

void tirePressureControl()
{
  switch (tireState)
  {
    case firstMeasurementOngoing:
      takeOneMoreMeasurement();
      if (numOfMeasCounter >= numberOfMeasurementsInUse)
      {
        tireState = firstMeasurementDone;
      }
      break;

    case firstMeasurementDone:
      if (maxPressureReading - minPressureReading > FILTER_THRESHOLD && isShortFilterActive == true)
      {
        isShortFilterActive = false;
        tireState = firstMeasurementOngoing;
        numberOfMeasurementsInUse = NUM_OF_MEASUREMENTS_LONG_FILTER;
      }
      else
      {
        valveControl(CLOSE_ALL);
        isShortFilterActive = true;
        maxPressureReading = 0;
        minPressureReading = 1023;
        firstMeasurementPressure = calcAverage();
        numberOfMeasurementsInUse = NUM_OF_MEASUREMENTS_SHORT_FILTER;
        displayTirePress(firstMeasurementPressure);
        decideWhatToDo(firstMeasurementPressure);
        updateAllWithinTol();
      }
      break;

    case allWithinTolWaiting:
      valveControl(MEASURE);
      TireTimeThres = millis() + SETTLING_TIME;
      tireState = firstMeasurementOngoing;
      break;

    case inflationDeflationDone:


      if (activeTire == 60)
      {
        tireState = firstMeasurementOngoing;
      }
      else
      {
        tireState = secondMeasurementOngoing;
      }
      valveControl(MEASURE);
      TireTimeThres = millis() + SETTLING_TIME;
      break;

    case secondMeasurementOngoing:
      takeOneMoreMeasurement();
      if (numOfMeasCounter >= numberOfMeasurementsInUse)
      {
        tireState = secondMeasurementDone;
      }
      break;

    case secondMeasurementDone:
      if (maxPressureReading - minPressureReading > FILTER_THRESHOLD && isShortFilterActive == true)
      {
        isShortFilterActive = false;
        tireState = secondMeasurementOngoing;
        numberOfMeasurementsInUse = NUM_OF_MEASUREMENTS_LONG_FILTER;
      }
      else
      {
        isShortFilterActive = true;
        maxPressureReading = 0;
        minPressureReading = 1023;
        secondMeasurementPressure = calcAverage();
        numberOfMeasurementsInUse = NUM_OF_MEASUREMENTS_SHORT_FILTER;
        displayTirePress(secondMeasurementPressure);
        changeToNextChannel();
        updatingControlParameters();
        valveControl(MEASURE);
        TireTimeThres = millis() + SETTLING_TIME;
        tireState = firstMeasurementOngoing;
      }
      break;
  }
}

//Read tankPress from MPX5700 sensor
void readTankPress()
{
  tankPress = (float)(analogRead(PIN_MPX5700) - OFFSET_MPX5700) * BITS_TO_PSIUNIT_MXP5700;
}

void changeToNextChannel()
{
  // 0 - 3 = independent channels, 4 = front (0-1 ch), 5 rear (2-3 ch), 6 all channels
  if (isIndependentEnabled == true)
  {
    activeTire = (activeTire + 1) % 4;
  }
  else if (frontAxleOffset == 0)
  {
    activeTire = 6;
    
    Serial.print(F("activeTire 6: "));
    Serial.println(activeTire, 1);
  }
  else
  {
    if (activeTire == 5)
    {
      activeTire = 4;
    Serial.print(F("activeTire 4: "));
    Serial.println(activeTire, 1);
    }
    else
    {
      activeTire = 5;
    Serial.print(F("activeTire 5: "));
    Serial.println(activeTire, 1);
    }
  }
}

// Print tankPressure to LCD
void printTankPressureLCD()
{
  tankPressureLCDTimeThres = millis() + TANK_PRESS_BLINK_DELAY;
  
  if(tankPress > TANKPRESSURE_BLINK_LIMIT || tankBlink == false)
  { 
    if(tankPress < 995)
    {
      lcd.print(11, 1, "  ");
    }
    else if(tankPress < 9995)
    {
      lcd.print(11, 1, " ");
    }
    lcd.print(0, 1, "PSI Í TANK >");
    lcd.print(11, 1, (tankPress + 5)/100); // 5 is so the rounding will be correct and 100 is because of the way the pressure is stored
    //Serial.print(F("TankPressure 3: "));
    //Serial.println((tankPress + 5), 1);
    tankBlink = true;
  }
  else
  {
    tankBlink = false;
    lcd.print(11, 1, "   ");
  }
}

//Gets value from slider in Blynk app to choose SetPot
BLYNK_WRITE(V11) // Blynk press SET slider, where V11 is MY virtual pin (copy/paste)
{ 
  int pinValue = param.asInt();
  setPoint = constrain(pinValue, 200, 3500); //this is where you put your limits of psi, multiplied by 100 for increased resolution
  delay(50);  //you can omit this one - was needed in my specific case
  String setPoint_str = String((float)setPoint/100, 1); //Function to display a number with one decimal and divide in order to get the correct psi
  lcd.print( 0,0, "VALIÐ PSI >"); //Text for the selected psi
  lcd.print(11,0, setPoint_str);   //here you can send your setPoint to vLCD
  if(setPoint < 995)
      {
        lcd.print(14,0, " ");  // This is for clare of decimal point on screen 
      }  
   isSetPointChanged = true;
}

/*
void updatingSetPoint()
{
  uint16_t newPotRaw = setPoint;
  
  if(abs(newPotRaw - currentPotRaw) > 10 ) // POT hysteresis
  {
    uint16_t newSetPoint = potToPSI(newPotRaw);
    if( newSetPoint != setPoint) 
    {
      setPoint = newSetPoint;
      currentPotRaw = newPotRaw;
      isSetPointChanged = true;
    }
  }
}

uint16_t potToPSI(uint16_t potRaw)
{
  uint16_t output = 0;

  if (potRaw < POT_NONLINEAR_THRES)
  {
    output = map(potRaw, MIN_POT_COUNT, POT_NONLINEAR_THRES - 1, 0, 499);
  }
  else
  {
    output = map(potRaw, POT_NONLINEAR_THRES, MAX_POT_COUNT, 500, SETPOINT_MAXIMUM_PSI * 100);
  }
  // Round of numbers higher than 500 (5 PSI)
  if (output > 500)
  {
    output = (output / (int)100) * (int)100;
  }
  else
  {
    output = (output / (int)50) * (int)50;
   
  }
  if (output < 50)
  {
    output = 25;
  }
  return output;
}
*/

void updatingALLOrIndividualSwitch()
{
  boolean allIndiSwitchEnabled = digitalRead(PIN_ALL_INDI);
  if (allIndiSwitchEnabled && !isIndependentEnabled)
  {
    activeTire = 0;
    isIndependentEnabled = true;
    TireTimeThres = 0;
    allWithinTolCounter = 0;
    isAllWithinTol = 0;
    valveControl(CLOSE_ALL);
    Serial.print(F("satt: "));
    Serial.println(PIN_ALL_INDI, 1);
  }
  else if (!allIndiSwitchEnabled && isIndependentEnabled)
  {
    activeTire = 6;
    isIndependentEnabled = false;
    TireTimeThres = 0;
    allWithinTolCounter = 0;
    isAllWithinTol = 0;
    valveControl(CLOSE_ALL);
    Serial.print(F("falst: "));
    Serial.println(PIN_ALL_INDI,1);
  }
  delay(500);
}

void updatingFrontPanelLED()
{
  if (isAllWithinTol)
  {
    digitalWrite(PIN_GREEN_LED, 1);
  }
  else
  {
    digitalWrite(PIN_GREEN_LED, 0);
  }
}

void takeOneMoreMeasurement()
{
  uint16_t temp = analogRead(PIN_MPX4250) - tireSensorOffset;
  if (temp > maxPressureReading)
  {
    maxPressureReading = temp;
  }
  if (temp < minPressureReading)
  {
    minPressureReading = temp;
  }
  summedPressure = summedPressure + temp;
  numOfMeasCounter += 1;
  TireTimeThres = millis() + TIME_BETW_MEAS;
}

uint16_t calcAverage()
{
  numOfMeasCounter = 0;
  int16_t currentPressure = (float)(summedPressure / numberOfMeasurementsInUse) * BITS_TO_PSIUNIT_MXP4250;
  if ( currentPressure < 0 )
  {
    currentPressure = 0;
  }
  summedPressure = 0;
  return currentPressure;
}
 
void displayTirePress(uint16_t currentPressure)
{
  float printOutPress = (float)currentPressure/(float)100;
  
  if(currentPressure > 37000) // This is to eliminate "negative" pressure
  {
    currentPressure = 0;
  }
  uint8_t isCurrentPressBelow10psi = currentPressure < 995; 
  uint8_t startChannel = 0;
  uint8_t endChannel = 0;
  switch (activeTire)
  {
  case 0:
    channe6 = currentPressure;
    startChannel = activeTire;
    endChannel = activeTire;
    isChBelow10PSI[activeTire] = isCurrentPressBelow10psi;
    break;
  case 1:
    channe7 = currentPressure;
    startChannel = activeTire;
    endChannel = activeTire;
    isChBelow10PSI[activeTire] = isCurrentPressBelow10psi;
    break;
  case 2:
    channe8 = currentPressure;
    startChannel = activeTire;
    endChannel = activeTire;
    isChBelow10PSI[activeTire] = isCurrentPressBelow10psi;
    break;
  case 3:
    channe9 = currentPressure;
    startChannel = activeTire;
    endChannel = activeTire;
    isChBelow10PSI[activeTire] = isCurrentPressBelow10psi;
    break;
  case 4:
    channe6 = currentPressure;
    channe7 = currentPressure;
    startChannel = 0;
    endChannel = 1;
    isChBelow10PSI[0] = isCurrentPressBelow10psi;
    isChBelow10PSI[1] = isCurrentPressBelow10psi;
    break;
  case 5:
    channe8 = currentPressure;
    channe9 = currentPressure;
    startChannel = 2;
    endChannel = 3;
    isChBelow10PSI[2] = isCurrentPressBelow10psi;
    isChBelow10PSI[3] = isCurrentPressBelow10psi;
    break;
  case 6:
    channe6 = currentPressure;
    channe7 = currentPressure;
    channe8 = currentPressure;
    channe9 = currentPressure;
    startChannel = 0;
    endChannel = 3;
    isChBelow10PSI[0] = isCurrentPressBelow10psi;
    isChBelow10PSI[1] = isCurrentPressBelow10psi;
    isChBelow10PSI[2] = isCurrentPressBelow10psi;
    isChBelow10PSI[3] = isCurrentPressBelow10psi;
    break;  
  }

    lcd2.print(0, 0, "VF     <>     HF"); //Which tire is measured in left front
    lcd2.print(0, 1, "VA     <>     HA"); //Which tire is measured in left rear
  for(uint8_t i = startChannel; i < endChannel+1; i++)
  {
    String printOutPress_str = String((float)printOutPress, 1); //Function to display a number with one decimal
    lcd2.print(LCD_X[i], LCD_Y[i], printOutPress_str); //Printed on lcd air pressure for tires
   delay(50);
  }
}


void updateAllWithinTol()
{
  uint8_t numberOfChannelsInUse = 0;
  switch (activeTire)
  {
    case 0:
    case 1:
    case 2:
    case 3:
      numberOfChannelsInUse = 3;
      break;
    case 4:
    case 5:
      numberOfChannelsInUse = 2;
      break;
    case 6:
      numberOfChannelsInUse = 1;
      break;
  }
  if (allWithinTolCounter >= numberOfChannelsInUse && !isAllWithinTol)
  {
    isAllWithinTol = true;
    withinTolSetPoint = setPoint;
    isSetPointChanged = false;
  }
  else if (allWithinTolCounter < numberOfChannelsInUse)
  {
    isAllWithinTol = false;
  }
}

uint16_t calculateDeflationTime(uint16_t currentPressure)
{
  uint16_t deflationParamInUse = 0;
  switch (activeTire)
  {
    case 0:
    case 1:
    case 2:
    case 3:
      deflationParamInUse = singleChannelDeflationParam;
      break;
    case 4:
      deflationParamInUse = frontChannelsDeflationParam;
      break;
    case 5:
      deflationParamInUse = rearChannelsDeflationParam;
      break;
    case 6:
      deflationParamInUse = allChannelsDeflationParam;
      break;
  }

  uint16_t timeMilliSec = ((deflationParamInUse * 10) / log( (float)currentPressure / (float)setPoint )) + VALVE_OPENING_TIME;
  if (timeMilliSec > MAX_DEFLATION_TIME)
  {
    timeMilliSec =  MAX_DEFLATION_TIME;
  }
  return timeMilliSec;
}

uint16_t calculateInflationTimeMS(uint16_t currentPressure)
{
  uint16_t inflationParamInUse = 0;
  switch (activeTire)
  {
    case 0:
    case 1:
    case 2:
    case 3:
      inflationParamInUse = singleChannelInflationParam;
      break;
    case 4:
      inflationParamInUse = frontChannelsInflationParam;
      break;
    case 5:
      inflationParamInUse = rearChannelsInflationParam;
      break;
    case 6:
      inflationParamInUse = allChannelsInflationParam;
      break;
  }

  uint16_t timeMilliSec = ((float)( setPoint - currentPressure ) * ( inflationParamInUse / 100 ) ) + VALVE_OPENING_TIME;
  if (timeMilliSec > MAX_INFLATION_TIME)
  {
    timeMilliSec =  MAX_INFLATION_TIME;
  }
  return timeMilliSec;
}

void decideWhatToDo(int16_t currentPressure)
{
  int16_t difference = currentPressure - setPoint;
  if (activeTire == 0 || activeTire == 1 || activeTire == 4)
  {
    difference = difference - frontAxleOffset;
  }
  if (abs(difference) > TOLERANCE) // Last measurement not within tolerance
  {
    allWithinTolCounter = 0;
    if (difference > 0)
    {
      valveControl(DEFLATE);
      deflationTime = calculateDeflationTime(currentPressure);
      TireTimeThres = millis() + deflationTime;
    }
    else if (1)  //tankPress > 0) // inflation only performed if tank press > 30 psi
    {
      valveControl(INFLATE);
      inflationTime = calculateInflationTimeMS(currentPressure);
      TireTimeThres = millis() + inflationTime;
    }
    tireState = inflationDeflationDone;
  }
  else // Last measurement within tolerance
  {
    allWithinTolCounter += 1;
    changeToNextChannel();

    if (isAllWithinTol && allWithinTolCounter > STAND_BY_THRESHOLD)
    {
      closeAllValves();
      TireTimeThres = millis() + (STAND_BY_MULTIPLAYER * ALL_WITHIN_TOL_WAIT_TIME);
      tireState = allWithinTolWaiting;
    }
    else if (isAllWithinTol)
    {
      closeAllValves();
      if (activeTire == 6)
      {
        openActiveTireValve();
      }
      TireTimeThres = millis() + ALL_WITHIN_TOL_WAIT_TIME;
      tireState = allWithinTolWaiting;
    }
    else
    {
      valveControl(MEASURE);
      TireTimeThres = millis() + SETTLING_TIME;
      tireState = firstMeasurementOngoing;
    }
  }
}

void openActiveTireValve()
{
  switch (activeTire)
  {
    case 0:
      digitalWrite(PIN_VALVE1, HIGH);
      break;
    case 1:
      digitalWrite(PIN_VALVE2, HIGH);
      break;
    case 2:
      digitalWrite(PIN_VALVE3, HIGH);
      break;
    case 3:
      digitalWrite(PIN_VALVE4, HIGH);
      break;
    case 4:
      digitalWrite(PIN_VALVE1, HIGH);
      digitalWrite(PIN_VALVE2, HIGH);
      break;
    case 5:
      digitalWrite(PIN_VALVE3, HIGH);
      digitalWrite(PIN_VALVE4, HIGH);
      break;
    case 6:
      digitalWrite(PIN_VALVE1, HIGH);
      digitalWrite(PIN_VALVE2, HIGH);
      digitalWrite(PIN_VALVE3, HIGH);
      digitalWrite(PIN_VALVE4, HIGH);
      break;
  }
}

void closeAllValves()
{
  digitalWrite(PIN_VALVE0, LOW);
  digitalWrite(PIN_VALVE1, LOW);
  digitalWrite(PIN_VALVE2, LOW);
  digitalWrite(PIN_VALVE3, LOW);
  digitalWrite(PIN_VALVE4, LOW);
  digitalWrite(PIN_VALVE5, LOW);
}

void valveControl(int command)
{
  closeAllValves();
  isValve5Closed = true;
  switch (command)
  {
    case CLOSE_ALL:
      // Empty on purpose
      break;
    case MEASURE:
      openActiveTireValve();
      break;
    case INFLATE:
      isInflating = true;
      openActiveTireValve();
      digitalWrite(PIN_VALVE5, HIGH);
      isValve5Closed = false;
      break;
    case DEFLATE:
      isDeflating = true;
      openActiveTireValve();
      digitalWrite(PIN_VALVE0, HIGH);
      break;
    case CALIBRATION:
      digitalWrite(PIN_VALVE0, HIGH);
      break;
  }
}

uint16_t tireOffsetCalibration()
{
  valveControl(CALIBRATION);
  //delay(250);
  uint16_t temp = 0;
  for (int8_t i = 0; i < NUM_OF_MEASUREMENTS_SHORT_FILTER; i = i + 1)
  {
    temp = temp + analogRead(PIN_MPX4250);
    delay(TIME_BETW_MEAS);
  }
  uint16_t tireSensorOffset = (temp / NUM_OF_MEASUREMENTS_SHORT_FILTER);
  valveControl(CLOSE_ALL);
  //delay(250);
  return tireSensorOffset;
}

void writeParamToEEPROM()
{
  // Unfinished function
}

void loadParamFromEEPROM()
{
  singleChannelDeflationParam = EEPROM.read(SINGLE_CHANNEL_DEFLATION_PARAM_ADDRESS);
  singleChannelInflationParam = EEPROM.read(SINGLE_CHANNEL_INFLATION_PARAM_ADDRESS);
  frontChannelsDeflationParam = EEPROM.read(FRONT_CHANNELS_DEFLATION_PARAM_ADDRESS);
  frontChannelsInflationParam = EEPROM.read(FRONT_CHANNELS_DEFLATION_PARAM_ADDRESS);
  rearChannelsDeflationParam = EEPROM.read(REAR_CHANNELS_DEFLATION_PARAM_ADDRESS);
  rearChannelsInflationParam = EEPROM.read(REAR_CHANNELS_DEFLATION_PARAM_ADDRESS);
  allChannelsDeflationParam = EEPROM.read(ALL_CHANNELS_DEFLATION_PARAM_ADDRESS);
  allChannelsInflationParam = EEPROM.read(ALL_CHANNELS_DEFLATION_PARAM_ADDRESS);
}

void updatingControlParameters()
{
  if (isDeflating && isInflating)
  {
    // Error: should not happen
  }
  else if (isDeflating && deflationTime > 0 && (firstMeasurementPressure - secondMeasurementPressure) > 0)
  {
    uint16_t newDeflationParam = deflationTime / log( (float)firstMeasurementPressure / (float)secondMeasurementPressure) / 10;

    switch (activeTire)
    {
      case 0:
      case 1:
      case 2:
      case 3:
        singleChannelDeflationParam = newDeflationParam;
        break;
      case 4:
        frontChannelsDeflationParam = newDeflationParam;
        break;
      case 5:
        rearChannelsDeflationParam = newDeflationParam;
        break;
      case 6:
        allChannelsDeflationParam = newDeflationParam;
        break;
    }

  }
  else if (isInflating && inflationTime > 0 && (secondMeasurementPressure > firstMeasurementPressure))
  {
    uint16_t newInflationParam = inflationTime / (float)(secondMeasurementPressure - firstMeasurementPressure) * 100;

    switch (activeTire)
    {
      case 0:
      case 1:
      case 2:
      case 3:
        singleChannelInflationParam = newInflationParam;
        break;
      case 4:
        frontChannelsInflationParam = newInflationParam;
        break;
      case 5:
        rearChannelsInflationParam = newInflationParam;
        break;
      case 6:
        allChannelsInflationParam = newInflationParam;
        break;
    }
  }
  isDeflating = false;
  isInflating = false;
  if ( EEPROMTimeThres < millis() )
  {
    EEPROMTimeThres = millis() + 5000;
    writeParamToEEPROM();
  }
}

int16_t updateFrontAxleOffset()
{
  closeAllValves();
  int16_t offset = 0;
  for (uint8_t i = 0; i < 20; i++)
  {
    offset = map(analogRead(setPoint),0,1023,-8,8) * 50; // range from -4 to 4 psi with 0,5 psi resolution
    if(offset >= 0)
    {
      lcd.print(11, 0, " ");
    }
    String offset_str = String((float)offset/100, 1);
    lcd.print(11, 0, offset_str);
    delay(250);
  }
  return offset;
}

ok thanks

I was trying :)[quote=“marvin7, post:163, topic:12034”]
3) why enabled the updatingSetPoint() ? this one was for manual pot input. Disabled here.
[/quote]

I was trying to find these errors and I forget to take out :)[quote=“marvin7, post:163, topic:12034”]
4) you have included wdt101 (a watchdog timer) but no wdt handling in code. Either disable it (not include the wdt101) or complete basing on provided examples (at github for example)
[/quote]

If disable this then come errors we put the code into the Arduino
so I think I’ll leave this to be in!

No error now begin testing in the next few days or week,
But and again thanks for your help

That is strange
 On my setup it compiles just fine without wdt
 (see the shoot)
But OK, it doesn’t hurt the code, just not necessary until properly implemented.

yes this is weird but this function now!

I tried again and it works, probably lies this with me, sorry :slight_smile: