Semi passive fan control

Hi all. This is my first real project after playing around with the Arduino for some time.
I want to implement a semi-passive fan control for fans in a PC, where I read the PWM duty cyle as an analog voltage and then switch the +12V line with a high-side mosfet switch.

Reading the duty cycle, converting and switching the fan on or off below or above a defined value works fine. But I want to have some kind of hysteresis.

Now my problem: I can't figure out how to switch off below a level of 15% and then back on above 35%, but only if the fan was off before.

My current code just switches off below 15%, turns the fan on and off repeatedly between 15-35% and then off at any higher value.

I'm stuck at this problem and would really appreciate any help and suggestions.

const int     inputPin = A0;              // PWM input
const int     mosfetPin = 9;              // Fan output
const int     lowLimit =15;               // Lower PWM limit
const int     highLimit = 35;             // Upper PWM limit
int           pwmValue;                   // Hold input value
boolean       mosfetOn;                   // Turn mosfet on? "true" or "false"

void setup()
{

  mosfetOn = true;                // Start with mosfet on
  pinMode(mosfetPin, OUTPUT);     // Define as output
  
  Serial.begin(9600);
}

void loop()
{
  pwmValue   = analogRead(inputPin);              // Read value
  int pwmLevel = pwmValue * (100 / 1023.0);       // Convert to percent

  Serial.println(pwmLevel);                       // Print value


  if (pwmLevel < lowLimit)                         //Is pwmLevel lower than lower limit?
    {
        mosfetOn = false;
      }
    else if (mosfetOn == true && pwmLevel < highLimit)       //Is mosfet HIGH and pwmlevel lower than upper limit?
      {
          mosfetOn = false;
        }
      else 
        {
            mosfetOn = true;
          }


  if (mosfetOn == true)                         //Turn mosfet on or off
    {
        digitalWrite(mosfetPin, HIGH);
      }
    else
      {
          digitalWrite(mosfetPin, LOW);
        }
    
  delay(100);
}

fan_control.ino.ino (1.29 KB)

where I read the PWM duty cyle

The duty cycle of what? If it is of a pin that YOU set the duty cycle for, why on earth would you need to read that? Just remember what you set it to.

I can't figure out how to switch off below a level of 15% and then back on above 35%,

15% of what? 35% of what?

    else if (mosfetOn == true && pwmLevel < highLimit)       //Is mosfet HIGH and pwmlevel lower than upper limit?

You won't get to evaluating this if statement unless the value is above lowLimit, where you set mosfetOn to true, so there is no need to test the value of mosfetOn.

Why do you turn the mosfet off if you are between lowLimit and highLimit? I would expect the mosfet to be on if you are between lowLimit and highLimit.

// global variable
bool FanPower = false;

// testing logic
if( pwmLevel > highLimit )
  FarPower = true;

if( pwmLevel < lowLimit )
  FanPower = false;

No need to over-complicate things. 8)

PaulS:
The duty cycle of what? If it is of a pin that YOU set the duty cycle for, why on earth would you need to read that? Just remember what you set it to.
...15% of what? 35% of what?...
Why do you turn the mosfet off if you are between lowLimit and highLimit? I would expect the mosfet to be on if you are between lowLimit and highLimit.

I guess that was badly explained by me. I'm not trying to control the fans RPM, just cutting of its power.
The PWM signal is the pc's fan speed read of the mainboard's fan header via analogRead and gets converted to a percentage value. Those 15% and 35% values then represent the respective duty cycle.

If that "interpreted" duty cycle goes below 15% it should turn off the mosfet so the fan is in passive mode. And to avoid that the fan constantly spins up and down, it should only turn on again if the duty cycle is above 35%.

Jiggy-Ninja:

// global variable

bool FanPower = false;

// testing logic
if( pwmLevel > highLimit )
  FarPower = true;

if( pwmLevel < lowLimit )
  FanPower = false;




No need to over-complicate things. 8)

Of course, that's it. I didnt see the wood for the trees...
Thank you.