Reducing power when idel Nano 33 BLE

Hello I have been using the Nano 33 BLE to control my cars radiator fan for for several years successfully now. I decided to upgrade the system to allow the fan to run a little while after engine shut down. That requires me to keep the Arduino powered up at all times. In my latest program I am using a delay() statement in the main loop. The delay is just outside a while loop to be performed when the fan is not running. While the fan is running I am recording a current draw of about 13-16ma. When the fan is not running I am recording about 9ma. That's not to bad as it would theoretically last about 1/2 a year on a car battery. But since car batteries rarely last that long on a shelf, I would like to get it reduced further.

I haven't been able to find a good example of how to work the sleep modes in the Nano and I am not even sure I can use them since this fan requires a signal of 10Hz with 10% duty cycle to stop. In this case, I'm not actually controlling the fan motor itself, but another controller built into the fan that powers the 600W fan motor.

I was hoping the Delay statements would reduce the power to the under 2ma region.

So I am looking for a better way to reduce the fan off power either with a sleep mode or within the code I have.

// Note this program uses a watchdog timer.
// It is required to reset the Arduino by two presses of the reset button and setting available com ports prior to upload.
// After upload the com port needs to be reset.

// Define Global Constants /////////////////////////////////////////////////////////////////

// constants that are desirable to adjust during debugging.
const bool SerialStatus = false;               // Set to true to hold serial printing until the serial printer is started. Set to false to release hold for stand alone use        
const bool WDTStatus = true;                  // Set to true to activate the Watch Dog Timmer, Set to false to deactivate for debugging
const unsigned long WDT = 30;                 // Watch Dog Timer max time seconds This must be greater than the time requird to complete a cycle

// Constant for voltage sensing
const unsigned long Resistor1 = 33000L;       // Voltage divider resistor #1
const unsigned long Resistor2 = 3300L;        // Voltage divider resistor #2
const float BoardV = 3.3;                     // Board operating voltage
const float VMult = BoardV*((Resistor1 + Resistor2)/Resistor2)/1023L;        // Voltage multiplier to get voltage from analogread pin "VsnPin"
const float EngineOnVoltage = 13.2;           // Voltage at which the engine is considered to be running
const long PostRunInterval = 30000;           // Time the fan will run after engine shut down msec

// Constanst for program control
const int frequency        = 10.0;            // Set fan frequency
const int NumberOfSamples  = 20;              // Sent number of data samples for averaging.
const int BlinkTimeOnTest  = 2000;            // Blink time on period for initial circuit test
const int BlinkTimeOn      = 500;             // Blink time on period
const int BlinkTimeOff     = 500;             // Blink time off period

// Constants for Arduino board configuration
const int VsnPin  = A0;                       // Circuite 15 Voltage level sensing pin
const int RadPin  = A1;                       // Radiator Input Thermistor
const int CndPin  = A2;                       // Condenser Input Thermistor
const int AuxPin  = A3;                       // Auxillary Input 
const int FanPin  = D9;                       // Set Fan pin
const int LED1Pin = D4;                       // Set Cooling Fan LED
const int LED2Pin = D3;                       // Set Condenser Fan LED
const int LED3Pin = D2;                       // Set Aux Fan LED

// 10 bit temperature equivalents for radiator sensor Delphi 12146312
const int Rad0   = 1015;   // - 20°C equivolent Sensor assumed open.
const int Rad20  = 579;    //85C
const int Rad30  = 557;    //88C
const int Rad40  = 534;    //91C
const int Rad50  = 511;    //94C
const int Rad60  = 487;    //97C
const int Rad70  = 463;    //100C
const int Rad80  = 439;    //103C
const int Rad90  = 415;    //106C
const int Rad100 = 355;    //115C This is an emergency mode either coolant is too hot or senser is shorted. Set duty cycle to 0 to activate emergency mode

// 10 bit temperature equivalents for condenser sensor Littelfuse USP7766
const int Cnd0   = 1004;   //-30C Sensor Test point
const int Cnd20  = 632;    //40C
const int Cnd30  = 583;    //45C
const int Cnd40  = 534;    //50C
const int Cnd50  = 486;    //55C
const int Cnd60  = 440;    //60C
const int Cnd70  = 396;    //65C
const int Cnd80  = 355;    //70C
const int Cnd90  = 317;    //75C
const int Cnd100 = 174;    //100C Sensor Test Point

// 10 bit temperature equivalents for temp sensor Delphi 25036751
const int Aux0   = 1015;   //-20C Sensor Test Point
const int Aux20  = 571;    //85C
const int Aux30  = 549;    //88C
const int Aux40  = 527;    //91C
const int Aux50  = 504;    //94C
const int Aux60  = 480;    //97C
const int Aux70  = 456;    //100C
const int Aux80  = 432;    //103C
const int Aux90  = 409;    //106C
const int Aux100 = 290;    //125C Sensor Test Point

#define _PWM_LOGLEVEL_                2
#define USING_MICROS_RESOLUTION       true        // false? 
#define HW_TIMER_INTERVAL_US          20L         
#define UPDATE_CHECK_INTERVAL_MS      15000L      // Interval of time for fan to run befor checking sensors and re adjusting fan speed

// Initialize Global Variables ///////////////////////////////////////////////////////

int RadVals [NumberOfSamples + 1];
int CndVals [NumberOfSamples + 1];
int AuxVals [NumberOfSamples + 1];

int RadValAvg = 0;
int CndValAvg = 0;
int AuxValAvg = 0;

int RadSpeed = 10;
int CndSpeed = 10;
int AuxSpeed = 10;

int RadTemp;
int CndTemp;
int AuxTemp;

int DutyCycle = 10;            // Set fan to 10% PWM = Fan off
int FanSpeed = 0;              // Fan speed is 0 with 10% PWM, Fan speed = 100% with 0% PWM

uint32_t startMicros = 0;

// You can assign pins here. Be careful to select good pin to use or crash
uint32_t PWM_Pin    = FanPin;

// Channel number used to identify associated channel
int channelNum;

//// End of Constants and Global Variables ///////////////////////////////////////////

#if !( ARDUINO_ARCH_NRF52840 && TARGET_NAME == ARDUINO_NANO33BLE )
  #error This code is designed to run on nRF52-based Nano-33-BLE boards using mbed-RTOS platform! Please check your Tools->Board setting.
#endif

// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
#include "nRF52_MBED_Slow_PWM.h"     // https://github.com/khoih-prog/nRF52_MBED_Slow_PWM
#include <ArduinoBLE.h>

// For mbed nRF52, you can only select NRF52 Hardware Timer NRF_TIMER_3-NRF_TIMER_4 (3 to 4)
// If you select the already-used NRF_TIMER_0-2, it'll be auto modified to use NRF_TIMER_3

// Init NRF52 timer NRF_TIMER3
NRF52_MBED_Timer ITimer(NRF_TIMER_3);

// Init nRF52_Slow_PWM, each can service 16 different ISR-based PWM channels
NRF52_MBED_Slow_PWM ISR_PWM;

// Define the Temperature Service for BLE
BLEService TempService("53436b3f-5f91-474b-963e-8b09b170c670");        //*** BLEService Class Any Hex Name 128-bit UUID in String format *********************************************************

// Define Temperature and Fan Speed Characteristics
BLEUnsignedIntCharacteristic RadLevelChar("694d181e-4421-47f3-9653-c4d6bb295a07",  // standard 128-bit characteristic UUID *******************************
    BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes
BLEUnsignedIntCharacteristic CndLevelChar("0407dd37-ae29-4ec7-ab40-a83898d610df",  // standard 128-bit characteristic UUID *******************************
    BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes
BLEUnsignedIntCharacteristic AuxLevelChar("ad43db8f-e3e6-4025-b745-43f2100f27e1",  // standard 128-bit characteristic UUID *******************************
    BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes
BLEUnsignedIntCharacteristic FanSpeedChar("8ed03f79-29c0-46d5-a2ca-bfddd629347e",  // standard 128-bit characteristic UUID *******************************
    BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes

//// End of Temperature and Fan Speed Characteristics ////////////////////////////////
void TimerHandler()
{ 
  ISR_PWM.run();
}
//// End of TimerHandler() //////////////////////////////////////////////////////////

void PrintData(const int& index = 0)
{
  // Subroutine to print each pin value to the serial monitor
  // Note this subroutine must be declared befor it is called?
  PWM_LOGINFO3("Rad(", index, ") input = ", RadVals[index]);
  PWM_LOGINFO3("Cnd(", index, ") input = ", CndVals[index]);
  PWM_LOGINFO3("Aux(", index, ") input = ", AuxVals[index]);
}
//// End of PrintData() /////////////////////////////////////////////////////////////////

void printAvg()
{
 // Subroutine to print the average values to the serial monitor
 // Note this subroutine must be declared befor it is called?
  PWM_LOGWARN1("RadAvg = ", RadValAvg);
  PWM_LOGWARN1("CndAvg = ", CndValAvg);
  PWM_LOGWARN1("AuxAvg = ", AuxValAvg);
  Serial.println();
  Serial.println("*********************************************************************************************");
  Serial.println("*********************************************************************************************");
  Serial.println("*********************************************************************************************");
  Serial.println();
}
/// End of printAvg() ///////////////////////////////////////////////////////////////

void setup() 
{
  // put your setup code here, to run once:
  pinMode(VsnPin, INPUT);
  pinMode(RadPin, INPUT);
  pinMode(CndPin, INPUT);
  pinMode(AuxPin, INPUT);
  pinMode(LED1Pin, OUTPUT);
  pinMode(LED2Pin, OUTPUT);
  pinMode(LED3Pin, OUTPUT);
  pinMode(FanPin, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  
  // Configure Low Power wake-up sources (optional)
  // Attach interrupts to wake from sleep on pin changes if necessary
  //LowPower.attachInterruptWakeup(digitalPinToInterrupt(VsnPin), NULL, RISING);

  if (SerialStatus)               // Set the SerialStatus bool variable in the main body as required for stand alone use or debugging
  {
    Serial.begin(115200);           
    while(!Serial);                        
  }

  
  Serial.print(F("\nStarting Car_Fan_Control using ")); Serial.println(BOARD_NAME);
  Serial.println(NRF52_MBED_SLOW_PWM_VERSION);
  Serial.println();
  
  Serial.print("Resistor 1 = "); Serial.println(Resistor1);
  Serial.print("Resistor 2 = "); Serial.println(Resistor2);
  Serial.print("BoardV = "); Serial.println(BoardV);
  Serial.print("VMult = "); Serial.println(VMult, 6);
  Serial.print("EngineOnVoltage = "); Serial.println(EngineOnVoltage);
  Serial.print("PostRunInterval = "); Serial.println(PostRunInterval);  
  Serial.println();

  delay(200); 
  
  digitalWrite(LED_BUILTIN, HIGH);

  // Interval in microsecs
  if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_US, TimerHandler))
  {
    startMicros = micros();
    Serial.print(F("Starting ITimer OK, micros() = ")); Serial.println(startMicros); Serial.println();
  }
  else Serial.println(F("Can't set ITimer. Select another freq. or timer")); Serial.println();

  channelNum = ISR_PWM.setPWM(PWM_Pin, frequency, DutyCycle);  // During setup DutyCycle will be set to initialized value of 10 = off.
  SetUpBLE();                       // Call the SetUpBLE routine
  
  Serial.println("Setup Complete *************************************************************"); Serial.println();
}   
//// End of setup() /////////////////////////////////////////////////////////////////

void loop()
{
  bool RunStatus;
  RunStatus = false;
  /*
   if (VMult*analogRead(VsnPin) > EngineOnVoltage)
    {
      Serial.println("Engine is running. Waking up...");
      // Wake up Nano 33 BLE from sleep (does nothing if already awake)
     // LowPower.idle(); // This just reduces power consumption without full sleep
    }
  if (RunFan() == false)
    {
      Serial.println("No need to run fan. Going to sleep...");
      // Go to deep sleep mode until an interrupt wakes it up
      //LowPower.sleep(); // Enter sleep mode, only external pin interrupts will wake it
    }
    */
    
  RunStatus = RunFan();
  Serial.print("RunStatus = "); Serial.print(RunStatus); Serial.println(" ****************************************************");

  while(RunStatus)                          // Run the fan if appropriate
  {
    StartEngine();
    // wait for a Bluetooth® Low Energy central
    BLEDevice central = BLE.central();
    // if a central is connected to the peripheral:
  
    static unsigned long update_timeout = 0;
    static bool LED_status = HIGH;

    // Take reading every update_timeout ms.
    if ((millis() > update_timeout) && (millis() > UPDATE_CHECK_INTERVAL_MS))
      {   
      LED_status = !LED_status;
      digitalWrite(LED_BUILTIN, LED_status);
    
      ReadAveragSensorsData();        // Read all the sensors and find the averages
      CalcDutyCycle();                // Call read sensors subroutine to calculate fan speed and print values to serial moniter
      CalculateTemperatures();        // Calculate the thermistor temperatures
      BlinkSpeed();                   // Call blink test to blink out speeds
    
      Serial.print("millis() = "); Serial.println(millis());
      NRF_WDT->RR[0] = WDT_RR_RR_Reload; // Reset WDT
      if (WDTStatus) Serial.println("Watchdog Reset *************************************************************");  
      update_timeout = millis() + UPDATE_CHECK_INTERVAL_MS;
    
      if (central)
      {
        Serial.print("Connected to central: ");
        // print the central's BT address:
        Serial.println(central.address());
        // turn on the LED to indicate the connection:
        digitalWrite(LED_BUILTIN, HIGH);
        UpdateTemperatures();         // Update temperature characteristics for BLE output 
       }
    
       // when the central disconnects, turn off the LED:
       digitalWrite(LED_BUILTIN, LOW);
       Serial.print("Disconnected from central: "); Serial.println(central.address());
    
       PrintData(); // Print every update_timeout ms.
      }
      RunStatus = RunFan();
      
    }
    
    Serial.print("Delayed *************************************************************");Serial.println();
    NRF_WDT->RR[0] = WDT_RR_RR_Reload; // Reset WDT
    if (WDTStatus) Serial.println("Watchdog Reset *************************************************************");  
    
    SetZeroFanSpeed();
    RunStatus = RunFan();
    Serial.print("RunFan = "); Serial.println(RunFan());Serial.println();
    Serial.print("RunStatus = "); Serial.print(RunStatus);Serial.println();
    delay (10000);
}
//// End of loop() //////////////////////////////////////////////////////////////////
  
void SetUpBLE()
{
  // begin initialization
  if (!BLE.begin()) {
    Serial.println("starting BLE failed!");

    while (1);
  }

  /* Set a local name for the Bluetooth® Low Energy device
     This name will appear in advertising packets
     and can be used by remote devices to identify this Bluetooth® Low Energy device
     The name can be changed but maybe be truncated based on space left in advertisement packet
  */

    BLE.setLocalName("Testing 123"); //******************************************************************************
    BLE.setAdvertisedService(TempService); // add the service UUID
    TempService.addCharacteristic(RadLevelChar); // add the radiator level characteristic
    TempService.addCharacteristic(CndLevelChar); // add the condenser level characteristic
    TempService.addCharacteristic(AuxLevelChar); // add the aux level characteristic
    TempService.addCharacteristic(FanSpeedChar); // add the fan Speed characteristic
    
    BLE.addService(TempService);  // Add the Temperature service
    RadLevelChar.writeValue(0);   // set initial value for this characteristic
    CndLevelChar.writeValue(0);   // set initial value for this characteristic
    AuxLevelChar.writeValue(0);   // set initial value for this characteristic
    FanSpeedChar.writeValue(0);   // set initial value for this characteristic

  // Start advertising Bluetooth® Low Energy.  It will start continuously transmitting Bluetooth® Low Energy
  // advertising packets and will be visible to remote Bluetooth® Low Energy central devices
  // until it receives a new connection

  BLE.advertise();  // start advertising

  Serial.println("Bluetooth® device active, waiting for connections...");Serial.println();
  Serial.print("Setup BLE Complete"); Serial.println();

} 
//// End of SetUpBLE() ///////////////////////////////////////////////////////////////

bool RunFan()
{
  float Voltage;                               // Voltage read on circuit 15 (Key Voltage)
  static bool EngineRunning;                   // Engine running status
  static bool RecentRunning;                   // Used to determine if the engine was running within a prescribed time
  static unsigned long KeyOffMillis;           // Time the key was sensed as being tuned off
  unsigned long CurrentKeyMillis = millis();   // Current time
  bool KeyOffEvent= false;                     // Used to determine whether or not the engine was tuned off
  
  Voltage = VMult*analogRead(VsnPin);          // Get the circuit 15 voltage

  if (Voltage < EngineOnVoltage && EngineRunning) // Engine was running untill this cycle
  {
    KeyOffMillis = millis();                   // Mark time of key off event
    KeyOffEvent = true;                        // The engine was just shut off
    EngineRunning = false;                     // Change status of engine
    RecentRunning = true; 
  }
  else if (CurrentKeyMillis - KeyOffMillis < PostRunInterval)
  {
    KeyOffEvent = false;
    RecentRunning = true;
  }
  else RecentRunning = false;

  if (KeyOffMillis == 0)                // Exception for engine never started, just plugged in, battery just connected etc. 
  {
    RecentRunning = false;
  }

  if (Voltage >= EngineOnVoltage) EngineRunning = true;
  else EngineRunning = false;

  /*
  Serial.println();
  Serial.print("KeyOffMillis      = "); Serial.print(KeyOffMillis);Serial.println();
  Serial.print("Voltage           = "); Serial.print(Voltage);Serial.println();
  Serial.print("EngineRunning     = "); Serial.print(EngineRunning);Serial.println();
  Serial.print("KeyOffEvent       = "); Serial.print(KeyOffEvent);Serial.println();
  Serial.print("RecentRunning     = "); Serial.print(RecentRunning);Serial.println();
  Serial.print("KeyOffMillis      = "); Serial.print(KeyOffMillis);Serial.println();
  Serial.print("CurrentKeyMillis  = "); Serial.print(CurrentKeyMillis);Serial.println();
  Serial.print("CurrentKeyMillis - KeyOffMillis  = "); Serial.print(CurrentKeyMillis - KeyOffMillis);Serial.println();
  Serial.print("PostRunInterval   = "); Serial.print(PostRunInterval);Serial.println();
  Serial.println();
  */
  Serial.print("RunFan Complete"); Serial.println();
  
  if (EngineRunning || RecentRunning) return true;
  if (EngineRunning == false && RecentRunning == false) return false;
 
}
///// End of RunFan() ////////////////////////////////////////////////////////////////

void StartEngine()
{
  float Voltage;                               // Voltage read on circuit 15 (Key Voltage)
  static bool EngineRunning;                   // Engine running status
  static bool KeyOnEvent;                      // Used to determine whether or not the engine was tuned on
  static unsigned long KeyOnMillis;            // Time the key was sensed as being tuned on

  Voltage = VMult*analogRead(VsnPin);          // Get the circuit 15 voltage
  if (Voltage >=  EngineOnVoltage && EngineRunning == false)
  {
    KeyOnEvent = true;                          // Engine was started
    ReadAveragSensorsData();                    // Read all the sensors and find the averages
    StartUpBlink();                             // Call the blink sensor StartUpBlink subroutine to test all sensors
  }
  else
  {
    KeyOnEvent = false;
  }
  
  if (Voltage >= EngineOnVoltage)
  {
    EngineRunning = true;
  }
  else
  {
    EngineRunning = false;
  }

  /*
  Serial.print("Voltage             = "); Serial.print(Voltage);Serial.println();
  Serial.print("EngineRunning       = "); Serial.print(EngineRunning);Serial.println();
  Serial.print("KeyOnEvent          = "); Serial.print(KeyOnEvent);Serial.println();
  Serial.print("KeyOnfMillis        = "); Serial.print(KeyOnMillis);Serial.println();
  Serial.print("CurrentKeyOnMillis  = "); Serial.print(CurrentKeyOnMillis);Serial.println();
  Serial.print("CurrentKeyOnMillis - KeyOnMillis  = "); Serial.print(CurrentKeyOnMillis - KeyOnMillis);Serial.println();
  */

  if (KeyOnEvent == true)
  {
    //Configure WDT.
    if (WDTStatus)                            // Set the WDTStatus booleen variable in the main body as required to turn on or off the WDT
    {
      NRF_WDT->CONFIG         = 0x01;         // Configure WDT to run when CPU is asleep
      NRF_WDT->CRV            = WDT*32769;    // CRV = WDT *(32768 + 1)
      NRF_WDT->RREN           = 0x01;         // Enable the RR[0] reload register
      NRF_WDT->TASKS_START    = 1;            // Start WDT           
      NRF_WDT->RR[0] = WDT_RR_RR_Reload;      // Reset WDT
      Serial.println("Watchdog iniialized and Set *************************************************************");Serial.println();  
    }
  }
  KeyOnEvent = false;                         // Reset KeyOnEvent
  Serial.println("StartEngine Complete"); Serial.println();
}
//// End of StartEngine() ////////////////////////////////////////////////////////////

void ReadAveragSensorsData() // Subroutine to read each pin and sum them
{
  int index = 0;

  RadValAvg = 0;
  CndValAvg = 0;
  AuxValAvg = 0;
     
  do 
  {
    // Read al data points

  RadVals[index]  = analogRead(RadPin);
  CndVals[index]  = analogRead(CndPin);
  AuxVals[index]  = analogRead(AuxPin);
  // sum all data points
  RadValAvg += RadVals[index];
  CndValAvg += CndVals[index];
  AuxValAvg += AuxVals[index];

    PrintData(index);               //Call the printData subroutine to print each reading to the serial monitor.

    index = index + 1;

  } while (index < NumberOfSamples);

  // Find Average of all data points
  RadValAvg  = RadValAvg  / NumberOfSamples;
  CndValAvg  = CndValAvg  / NumberOfSamples;
  AuxValAvg  = AuxValAvg  / NumberOfSamples;

  printAvg();                       //Call the printAvg function to print the average data to the serial monitor.
}

///// End of ReadAveragSensorsData() //////////////////////////////////////////////////

void StartUpBlink()                          // Blink LEDs at startup to test sensors are in range
{

  digitalWrite(LED1Pin, HIGH);  // turn the LED on 
  digitalWrite(LED2Pin, HIGH);  // turn the LED on  
  digitalWrite(LED3Pin, HIGH);  // turn the LED on
 
  delay(BlinkTimeOnTest);       // Time to leave LEDs on
  digitalWrite(LED1Pin, LOW);   // turn the LED off 
  digitalWrite(LED2Pin, LOW);   // turn the LED off
  digitalWrite(LED3Pin, LOW);   // turn the LED off

  Serial.print("StartUpBlink Complete");Serial.println();Serial.println();

}
///// nd of StartUpBlink() ///////////////////////////////////////////////////////////

void UpdateTemperatures() 
{
  // Update and Print the calculated temperatures used for the BLE Characteristics

  RadLevelChar.writeValue(RadTemp);                   // update the Radiator level characteristics
  CndLevelChar.writeValue(CndTemp);                   // update the Condenser level characteristics
  AuxLevelChar.writeValue(AuxTemp);                   // update the Aux level characteristics
  FanSpeedChar.writeValue(FanSpeed);                  // update the Fan Speed characteristics

  /*
  Serial.print("Rad Temp is now:  "); Serial.println(RadTemp);
  Serial.print("Cnd Temp is now:  "); Serial.println(CndTemp);
  Serial.print("Aux Temp is now:  "); Serial.println(AuxTemp);
  Serial.print("Fan Speed is now: "); Serial.println(FanSpeed);Serial.println();
  */
  
  Serial.println("UpdateTemperatures Completer");Serial.println(); 
}
//// End of UpdateTemperatures() //////////////////////////////////////////////////////////////////////////

void CalcDutyCycle()                  // Subroutine to do 1 cycle of reading the temperature data
{

  // Find the speed levels required by each sensor Not only rad temperature can initiate emergency mode.
  if (RadValAvg > Rad0) RadSpeed = 0;           // Open sensor assumed fan will run in emergency mode at 100%
  if (RadValAvg > Rad20 and RadValAvg <= Rad0) RadSpeed = 10;   // 10% duty cycle = fan off
  if (RadValAvg > Rad30 and RadValAvg <= Rad20) RadSpeed = 20;
  if (RadValAvg > Rad40 and RadValAvg <= Rad30) RadSpeed = 30;
  if (RadValAvg > Rad50 and RadValAvg <= Rad40) RadSpeed = 40;
  if (RadValAvg > Rad60 and RadValAvg <= Rad50) RadSpeed = 50;
  if (RadValAvg > Rad70 and RadValAvg <= Rad60) RadSpeed = 60;
  if (RadValAvg > Rad80 and RadValAvg <= Rad70) RadSpeed = 70;
  if (RadValAvg > Rad90 and RadValAvg <= Rad80) RadSpeed = 80;
  if (RadValAvg > Rad100 and RadValAvg <= Rad90) RadSpeed = 90;
  if (RadValAvg <= Rad100) RadSpeed = 100;        // Set PWM duty cycle to 0 for emergency mode

  if (CndValAvg > Cnd20) CndSpeed = 10;   // 10% duty cycle = fan off
  if (CndValAvg > Cnd30 and CndValAvg <= Cnd20) CndSpeed = 20;
  if (CndValAvg > Cnd40 and CndValAvg <= Cnd30) CndSpeed = 30;
  if (CndValAvg > Cnd50 and CndValAvg <= Cnd40) CndSpeed = 40;
  if (CndValAvg > Cnd60 and CndValAvg <= Cnd50) CndSpeed = 50;
  if (CndValAvg <= Cnd60) CndSpeed = 60;                // Condensor is limited to 60%

  if (AuxValAvg > Aux20) AuxSpeed = 10;   // 10% duty cycle = fan off
  if (AuxValAvg > Aux30 and AuxValAvg <= Aux20) AuxSpeed = 20;
  if (AuxValAvg > Aux40 and AuxValAvg <= Aux30) AuxSpeed = 30;
  if (AuxValAvg > Aux50 and AuxValAvg <= Aux40) AuxSpeed = 40;
  if (AuxValAvg > Aux60 and AuxValAvg <= Aux50) AuxSpeed = 50;
  if (AuxValAvg > Aux70 and AuxValAvg <= Aux60) AuxSpeed = 60;
  if (AuxValAvg > Aux80 and AuxValAvg <= Aux70) AuxSpeed = 70;
  if (AuxValAvg > Aux90 and AuxValAvg <= Aux80) AuxSpeed = 80;
  if (AuxValAvg <= Aux90) AuxSpeed = 90;
  
  // find the sensor with the highest speed requirement or set emergency mode
  if (RadSpeed == 100|| RadSpeed == 0){   
    DutyCycle = 0;                         // Emergency mode rad too hot or shorted sensor = 100, sensor open = 0
  }
  else {
    DutyCycle = max(RadSpeed, CndSpeed); // find the highest
    DutyCycle = max(DutyCycle, AuxSpeed);  // This is the duty Cycle
  }

  FanSpeed = DutyCycle;
  if (DutyCycle == 0){
    FanSpeed = 100;
  }

  PWM_LOGWARN1("Fan Speed  = ", FanSpeed);

  //write the PWM value to the pwm output pin
  PWM_LOGWARN5("Freq = ", frequency, ", DutyCycle % = ", DutyCycle, ", Pin = ", FanPin);

  if (!ISR_PWM.modifyPWMChannel(channelNum, PWM_Pin, frequency, DutyCycle))
  {
    Serial.print(F("modifyPWMChannel error"));
  }
  Serial.print("CalcDutyCycle Complete");
}
///// End of CalcDutyCycle() //////////////////////////////////////////////////////////

void CalculateTemperatures()
{
  //// Defining 6th order polynomial coefficients

  double RadCoeff0 =   1.660314E+03;
  double RadCoeff1 =  -1.669192E+01;
  double RadCoeff2 =   7.538496E-02;
  double RadCoeff3 =  -1.809468E-04;
  double RadCoeff4 =   2.411013E-07;
  double RadCoeff5 =  -1.684504E-10;
  double RadCoeff6 =   4.789740E-14;

  double CndCoeff0 =   1.656447E+02;
  double CndCoeff1 =  -5.855249E-01;
  double CndCoeff2 =   1.648293E-03;
  double CndCoeff3 =  -3.088415E-06;
  double CndCoeff4 =   3.244812E-09;
  double CndCoeff5 =  -1.670822E-12;
  double CndCoeff6 =   2.576671E-16;

  double AuxCoeff0 =   4.949081E+02;
  double AuxCoeff1 =  -3.724091E+00;
  double AuxCoeff2 =   1.595315E-02;
  double AuxCoeff3 =  -3.767238E-05;
  double AuxCoeff4 =   4.990923E-08;
  double AuxCoeff5 =  -3.498639E-11;
  double AuxCoeff6 =   1.000633E-14;

  //Calculate temperatures
  
  RadTemp = RadCoeff0 + RadCoeff1*RadValAvg + RadCoeff2*RadValAvg*RadValAvg + RadCoeff3*RadValAvg*RadValAvg*RadValAvg + RadCoeff4*RadValAvg*RadValAvg*RadValAvg*RadValAvg + RadCoeff5*RadValAvg*RadValAvg*RadValAvg*RadValAvg*RadValAvg + RadCoeff6*RadValAvg*RadValAvg*RadValAvg*RadValAvg*RadValAvg*RadValAvg;
  CndTemp = CndCoeff0 + CndCoeff1*CndValAvg + CndCoeff2*CndValAvg*CndValAvg + CndCoeff3*CndValAvg*CndValAvg*CndValAvg + CndCoeff4*CndValAvg*CndValAvg*CndValAvg*CndValAvg + CndCoeff5*CndValAvg*CndValAvg*CndValAvg*CndValAvg*CndValAvg + CndCoeff6*CndValAvg*CndValAvg*CndValAvg*CndValAvg*CndValAvg*CndValAvg;
  AuxTemp = AuxCoeff0 + AuxCoeff1*AuxValAvg + AuxCoeff2*AuxValAvg*AuxValAvg + AuxCoeff3*AuxValAvg*AuxValAvg*AuxValAvg + AuxCoeff4*AuxValAvg*AuxValAvg*AuxValAvg*AuxValAvg + AuxCoeff5*AuxValAvg*AuxValAvg*AuxValAvg*AuxValAvg*AuxValAvg + AuxCoeff6*AuxValAvg*AuxValAvg*AuxValAvg*AuxValAvg*AuxValAvg*AuxValAvg;   
  
  Serial.print("Calculate Temperatures Complete"); Serial.println();
}
///// End of CalculateTemperatures() /////////////////////////////////////////////////

void BlinkSpeed()                               // Blink LEDs to indicate speed called by each sensor
{
  int CountRadOn  = 0;    // Counter for number of radiator blinks on
  int CountCndOn  = 0;    // Counter for number of condenser blinks on
  int CountAuxOn  = 0;    // Counter for number of Aux blinks on

  int RadBlinks   = 0;    // Initialize number of blinks based on radiator temp
  int CndBlinks   = 0;    // Initialize number of blinks based on Condenser temp
  int AuxBlinks   = 0;    // Initialize number of blinks based on Aux temp
  int MaxBlinks   = 0;    // Maximum number of blinks for all channels
  
  int index = 0;
  
  RadBlinks = RadSpeed/10;      // Number of Blinks Based on Rad Temp
  CndBlinks = CndSpeed/10;      // Number of Blinks Based on Cnd Temp
  AuxBlinks = AuxSpeed/10;      // Number of Blinks Based on Aux Temp
  MaxBlinks = max(RadBlinks, CndBlinks);
  MaxBlinks = max(MaxBlinks, AuxBlinks);    // Find the total number of blinks required
    
  do {                                      // Do the blink loop until the max number of blinks has occured.
     
      CountRadOn = CountRadOn + 1;
      CountCndOn = CountCndOn + 1;
      CountAuxOn = CountAuxOn + 1;
      if (CountRadOn <= RadBlinks) {
        digitalWrite(LED1Pin, HIGH); // turn the LED on 
      }      
      if (CountCndOn <= CndBlinks) {
        digitalWrite(LED2Pin, HIGH); // turn the LED on 
      }      
      if (CountAuxOn <= AuxBlinks) {
        digitalWrite(LED3Pin, HIGH); // turn the LED on 
      }

      delay(BlinkTimeOn);           // Time to leave LEDs on
      digitalWrite(LED1Pin, LOW);   // turn the LED off 
      digitalWrite(LED2Pin, LOW);   // turn the LED off
      digitalWrite(LED3Pin, LOW);   // turn the LED off
      delay(BlinkTimeOff);          // Time to leave LEDs on
           
    index = index + 1;
  } while (index < MaxBlinks);

  Serial.print("Blink Speed Test Complete"); Serial.println();
}
///// End of BlinkSpeed() ////////////////////////////////////////////////////////////

void SetZeroFanSpeed()
{
  FanSpeed = 0;
  DutyCycle = 10;

  PWM_LOGWARN1("Fan Speed  = ", FanSpeed);

  //write the PWM value to the pwm output pin
  PWM_LOGWARN5("Freq = ", frequency, ", DutyCycle % = ", DutyCycle, ", Pin = ", FanPin);

  if (!ISR_PWM.modifyPWMChannel(channelNum, PWM_Pin, frequency, DutyCycle))
  {
    Serial.print(F("modifyPWMChannel error"));
  }
  Serial.print("SetZeroFanSpeed Complete");
}
///// End of ZeroFanSpeed() ////////////////////////////////////////////////////////////

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.