Build thread for custom fan controller. NERD alert.

DaMonkey

New member
My truck cools just fine. However I can't help but mod stuff.

Plan is an aluminum radiator with dual fans. I've seen arguments in here against electric fans, but whatever - I'm confident in what I'm doing and willing to make mistakes. The bigger capacity aluminum radiator is a more efficient cooling system. Properly designed shroud fans behind that will have much better air flow. It might not be totally necessary and will be $$, but style points are worth something as long as it works better. I do believe it will reduce the load on motor too, which some people may argue.

The mechanical fan is always running. Even with the clutch, it's running when it's not needed and I want to minimize the load.

I'll put the same dual Spal fans on that I've used before on another build, and they each draw 15-18 amps depending on how it's shrouded and and how much air is flowing on it's own. I have an upgraded alternator already.

I'll upload a video below and also continue to share the project. I'll be interested in any input on how the controller algorithm should be programmed. I'm tapping into the can bus from the OBD2 for most sensor inputs that already exist, and will add additional sensors. The can bus can be chained to leave the OBD2 still open for the Techstream or anything else. I'm waiting for the OBD2 adapter to arrive, but it's prototyped on a breadboard now and the logic works.

It's an Arduino based controller and I'll surely be adding more sensors if/when I put in a turbo. It will be fully user adjustable for inputs on temp thresholds and other features. It can and will likely be used to get and clear codes, as well as monitor other conditions. Might as well include data logging which isn't hard to include on Arduino.

I built a Megasquirt back when the only boards were through hole and user built from scratch. I'm pretty comfortable with this stuff. That controls fuel, spark, and fans on my 61 Pontiac. See car in vid below.

Let me know what features you think could or should be included. I'll update the project in here. My truck is in garage for the Winter salt which means it's available to work on it and get it installed, but it won't be in extreme testing conditions until the Spring.

- Staged fans at programmable temp thresholds

Shut off fans when not 'wanted':
- Fans off at WOT to take load off
- Fans off while cranking starter to take load off

Ways to take load off when not 'needed'
- AC switch based on condenser cooling need rather than simply when AC powered on
- Fan off when hit HWY speed to anticipate air flow takes over before waiting for temps to actually drop

*** YOUTUBE VID OF PROTOTYPE ***

.
 
Register to hide this ad
My dude!!! Just watched your YouTube vid. This is awesome! How can I get your code on an arduino nano??..really good stuff dude

Thanks man. Happy to share the sketch. Not sure best way to share code?

I'm new to c++ so my code is surely inefficient but it works with the logic. Still need to work through user inputs with buttons on front. I suppose it could just have variables uploaded when changed, but I'd like to develop it more.

Have you worked with the Arduino before?
 
Nice, proud to be your 2nd YouTube subscriber!

I have been collecting parts to try a dual electric fan setup as well. Really interested in how this turns out. I have been writing code since the 1980’s so if you need a code review?:juggle:
 
Nice, proud to be your 2nd YouTube subscriber!

I have been collecting parts to try a dual electric fan setup as well. Really interested in how this turns out. I have been writing code since the 1980’s so if you need a code review?:juggle:

Hey Andy - I just watched your Champion review the other day, thanks for posting that up. Yeah, those insert threads are pretty bogus, and I'll follow your lead on punching them out. I had a similar experience with fit into my Pontiac, but as soon as I starting running the aluminum, I was blown away how well it cooled and that's what really counts.

Do you have the stock fan in still? How were your temps this Summer? I'm wondering if the second fan will even get triggered much. I really do believe this setup will reduce overall loads noticeably with zero drag when fan isn't needed.

Below is the code I wrote. Right now, I've got the hardcodes in for the sensor and the coolant potentiometer. The OBD calls are untested because I don't have the adapter yet, and I deleted a couple hacks I had in to monitor some of this testing so I'm not sure if cut n past below will compile. This was my first time programming, so keep that in mind lol. A couple things I did I just tried some stuff until it worked and I figured I'd make some friends that knew how to tighten it up :)

Still need to add functionality for buttons for driver to input any variable adjustments, and need hysteresis coded in for AC trigger, and for MAX_OFF_TEMP. I'm sure everything below will evolve quite a bit as the project moves forward.
Code:
// *********** USER INPUTS **********
#define FAN1SETPOINT 195 // fan 1 trigger setpoint to turn on fan
#define FAN2SETPOINT 200 // fan 2 trigger setpoint to turn on fan
#define MAX_OFF_TEMP 205 // max temp before fans release on WOT or voltage or sufficient speed
#define HYSTERESIS 3 // number of degrees F below setpoint to turn fan back off after triggered
#define THROTTLE_LIMIT 80 // throttle threshold to determine if WOT mode - turn off fans during WOT
#define RPM_LIMIT 500 // RPM threshold to determine if in start mode - turn off fans during startup or engine off
#define AC_SPEED 20 // MPH threshold to turn on fan 1 if not moving
#define AC_DIFFERENTIAL 15 // difference in F between condenser and ambient to trigger AC
#define AC_WARNING 40 // difference in F between condenser and ambient to double fans and flash warning
#define NO_FAN_SPEED 50 // MPH threshold for fans not necessary
#define REQ_VOLTAGE 12.1 // minimum voltage threshold to turn on fans

char array[] = "Welcome Aboard!!                               "; //the string to place on first line of the LCD during setup
int arraylength = 32; // number of characters to scroll
int character_time = 250; //the value of delay time in mS between scroll characters

// THERMISTOR1 INPUTS - AMBIENT TEMPS
#define THERMISTORNOMINAL1 10000 // resistance at 25 degrees C
#define SERIESRESISTOR1 10000 // the value of the 'other' resistor
#define TEMPERATURENOMINAL1 25 // temp. for nominal resistance
#define BCOEFFICIENT1 3950 // The beta coefficient of the thermistor

// THERMISTOR2 INPUTS - CONDENSER TEMPS
#define THERMISTORNOMINAL2 10000 // resistance at 25 degrees C
#define SERIESRESISTOR2 10000 // the value of the 'other' resistor
#define TEMPERATURENOMINAL2 25 // temp. for nominal resistance
#define BCOEFFICIENT2 3950 // The beta coefficient of the thermistor

// BOTH THERMISTORS SAMPLES LOOP
#define NUMSAMPLES 10 // how many samples to take and average, more takes longer but is more 'smooth'


// **** PINS USED ****
int RelayDrive1 = 2; // pin 2 digital is for output relay1 drive connected to base of TIP122 through 1k resistor (emitter to board ground, collector to pin 86 on relay, 1N4002 diode from 86 to 85)
int RelayDrive2 = 3; // pin 3 digital is for output relay2 drive connected to base of TIP122 through 1k resistor (emitter to board ground, collector to pin 86 on relay, 1N4002 diode from 86 to 85)
int potPin = 3;
#define THERMISTOR1PIN A1 // pin A1 analog is for 10k thermistor temperature sensor input (10k resistor from A1 to vcc)
#define THERMISTOR2PIN A2 // pin A2 analog is for 10k thermistor temperature sensor input (10k resistor from A1 to vcc)
// input Tx Rx from OBD CAN to arduino
// pins A4 & A5 used for LCD I2C 16x2 outputs

#include <OBD2UART.h> // library for calls from OBD2
#include <Wire.h> // library for calls from OBD2
#include <LiquidCrystal_I2C.h> // library for LCD

// Set the LCD address to for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x3F, 16, 2); // try 0x27 if does not work

COBD obd;

// Establish loop variables
int fan1state = 0;
int fan2state = 0;
int threshold1 = FAN1SETPOINT;
int threshold2 = FAN2SETPOINT;

// CREATE DELTA CHARACTER FOR AC DISPLAY
byte delta[8] =
{
  B00000,
  B00000,
  B00100,
  B01010,
  B11111,
  B00000,
  B00000,
  B00000
};

// ***************** SETUP ****************

void setup() {
  Serial.begin(9600);


  pinMode(RelayDrive1, OUTPUT); // declare relaydrive1 as an output
  digitalWrite(RelayDrive1, LOW); //Turn the Relay1 Off
  pinMode(RelayDrive2, OUTPUT); // declare relaydrive2 as an output
  digitalWrite(RelayDrive2, LOW); //Turn the Relay2 Off

  // initialize the LCD
  lcd.init();

  // Turn on the backlight and print a message.
  lcd.backlight();
// ****  delay(2000);
  lcd.setCursor(15, 0); // set the cursor to column 15, line 0
  for (int positionCounter = 0; positionCounter < arraylength; positionCounter++)
  {
    lcd.scrollDisplayLeft(); //Scrolls the contents of the display one space to the left.
    lcd.print(array[positionCounter]); // Print a message to the LCD.
    delay(character_time); //wait for set microseconds
  }
  lcd.clear(); //Clears the LCD screen and positions the cursor in the upper-left corner.

  lcd.setCursor(0, 0);
  lcd.print("OBD");
  lcd.setCursor(0, 1);
  lcd.print("initiating...");

  // start serial communication
// ****** obd.begin();
  // initiate OBD-II connection until success
// ***** while (!obd.init());

lcd.createChar(0, delta);
lcd.clear();
}

// ****************** LOOP *******************

void loop() {

  // ** COLLECT LOOP DATA **

  // OBD variables
  int throttle;
  // save throttle position in variable 'throttle', return true on success
  if (obd.readPID(PID_THROTTLE, throttle)) {
    // do nothing
  }
  else {
    throttle = 0; // if throttle call is false, set throttle to zero
  }
  
  int rpm;
  // save RPM in variable 'rpm', return true on success
  if (obd.readPID(PID_RPM, rpm)) {
    // do nothing
  }
  else {
    rpm = 1500; // if rpm call is false, set RPM to 1500 (as if idle)
  }
  
  int VEHvoltage;
  // save vehicle voltage in variable 'VEHvoltage', return true on success
  if (obd.readPID(PID_CONTROL_MODULE_VOLTAGE * 10, VEHvoltage)) {
    // do nothing
  }
  else {
    VEHvoltage = 135;
  }
  
  int coolantC;
  // save coolant temperature in variable 'coolantC', return true on success
  if (obd.readPID(PID_COOLANT_TEMP, coolantC)) {
    // do nothing
  }
  else {
    coolantC = (max(max(FAN2SETPOINT, FAN2SETPOINT), MAX_OFF_TEMP)) * 9 / 5 + 32;
  }

  int speedK;
  // save vehicle speed in variable 'speedK', return true on success
  if (obd.readPID(PID_SPEED, speedK)) {
    // do nothing
  }
  else {
    speedK = (AC_SPEED /.621 - 2);
  }  

  int throttle = 50; // *** DELETE HARD CODE
  int rpm = 200; // *** DELETE HARD CODE
  int VEHvoltage = 142; // *** DELETE HARD CODE
  int speedK = 10; // *** DELETE HARD CODE
  
  float pot;  
pot = analogRead(potPin); // *** DELETE POT TESTING

pot = pot / 1000; // *** DELETE POT TESTING

float coolantC = 100 - pot * 25;  // *** DELETE POT TESTING

  // COLLECT THERMISTOR TEMPERATURES
  int i;
  float average;
  float average2;

  // take N samples in a row, with a slight delay
  int samples[NUMSAMPLES];
  int samples2[NUMSAMPLES];
  for (i = 0; i < NUMSAMPLES; i++) {
    samples[i] = analogRead(THERMISTOR1PIN);
    samples2[i] = analogRead(THERMISTOR2PIN);
    delay(10);
  }

  // average all the samples out
  average = 0;
  average2 = 0;
  for (i = 0; i < NUMSAMPLES; i++) {
    average += samples[i];
    average2 += samples2[i];
  }
  average /= NUMSAMPLES;
  average2 /= NUMSAMPLES;

  // convert the value to resistance
  average = 1023 / average - 1;
  average2 = 1023 / average2 - 1;
  average = SERIESRESISTOR1 / average;
  average2 = SERIESRESISTOR2 / average2;

  float steinhart;
  steinhart = average / THERMISTORNOMINAL1;     // (R/Ro)
  steinhart = log(steinhart);                  // ln(R/Ro)
  steinhart /= BCOEFFICIENT1;                   // 1/B * ln(R/Ro)
  steinhart += 1.0 / (TEMPERATURENOMINAL1 + 273.15); // + (1/To)
  steinhart = 1.0 / steinhart;                 // Invert
  steinhart -= 273.15;                         // convert to C

  float ambientC = steinhart;
  
  steinhart = average2 / THERMISTORNOMINAL2;     // (R/Ro)
  steinhart = log(steinhart);                  // ln(R/Ro)
  steinhart /= BCOEFFICIENT2;                   // 1/B * ln(R/Ro)
  steinhart += 1.0 / (TEMPERATURENOMINAL2 + 273.15); // + (1/To)
  steinhart = 1.0 / steinhart;                 // Invert
  steinhart -= 273.15;                         // convert to C
  
  float condenserC = steinhart;

  // Conversions
  float ambientF = ambientC * 9 / 5 + 32;
  float coolantF = coolantC * 9 / 5 + 32;
  float condenserF = condenserC * 9 / 5 + 32;
  float speedM = speedK * 0.621;
  int differential = condenserF - ambientF;
  
  differential = 5; // **** REMOVE HARDCODE
  
    // AC status
  int ACtrigger;
  
  Serial.print("*** differential: ");
  Serial.print(differential);
  Serial.print(" AC");
  
  if ((differential) < AC_DIFFERENTIAL) {
    ACtrigger = 0;
    Serial.println(" off");
  }
  else {
    ACtrigger = 1;
    Serial.println(" on");
  }
  
  // ACtrigger = 1; // **** REMOVE HARDCODE

  // Etablish thresholds based on current state
  if ((fan1state == 0) || (coolantF < (FAN1SETPOINT - HYSTERESIS))) {
    threshold1 = FAN1SETPOINT;
  }
  else {
    threshold1 = FAN1SETPOINT - HYSTERESIS;
  }

  if ((fan2state == 0) || (coolantF < (FAN2SETPOINT - HYSTERESIS))) {
    threshold2 = FAN2SETPOINT;
  }
  else {
    threshold2 = FAN2SETPOINT - HYSTERESIS;
  }

  // ** SET FANS BASED ON CONDITIONS **

  // TURN OFF FANS IF SUFFICIENT SPEED OR WOT OR INSUFFICIENT VOLTAGE OR INSUFFICIENT RPM AND TEMP BELOW RELEASE THRESHOLD AND AC DIFF BELOW MAX
  if (  ( (throttle >= THROTTLE_LIMIT)
          || (VEHvoltage < REQ_VOLTAGE * 10)
          || ((rpm < RPM_LIMIT) && (rpm > 0))
          || (speedM >= NO_FAN_SPEED)
        ) && (coolantF < MAX_OFF_TEMP) && (differential < AC_WARNING)) {
    digitalWrite(RelayDrive1, LOW); //Turn the Relay1 Off
    digitalWrite(RelayDrive2, LOW); //Turn the Relay2 Off
    fan1state = 0;
    fan2state = 0;
  }
  else {

    // CHECK FAN 1 FOR THRESHOLD (override if AC triggered on)
    if ((ACtrigger == 1) && (speedM < AC_SPEED) && (differential < AC_WARNING)  && (rpm >= RPM_LIMIT)) {
      digitalWrite(RelayDrive1, HIGH); //Turn the Relay1 On
      fan1state = 1;
    }

    else {
      if ((coolantF >= threshold1) || (differential >= AC_WARNING)) {
        digitalWrite(RelayDrive1, HIGH); //Turn the Relay1 On
        fan1state = 1;
      }
      else {
        digitalWrite(RelayDrive1, LOW); //Turn the Relay1 Off
        fan1state = 0;
      }
    }

    // CHECK FAN 2 FOR THRESHOLD (or if AC > max threshold)
    if ((coolantF >= threshold2) || (differential >= AC_WARNING)) {
      digitalWrite(RelayDrive2, HIGH); //Turn the Relay2 On
      fan2state = 1;
    }
    else {
      digitalWrite(RelayDrive2, LOW); //Turn the Relay2 Off
      fan2state = 0;
    }

  } // end else condition if not WOT
 

  // LCD READOUTS
  int ambient = ambientF;
  int coolant = coolantF;
  lcd.setCursor(0, 0); // set the cursor to column 0, line 0
  lcd.print("CLT");
  lcd.setCursor(4, 0);
  lcd.print(coolant);
  lcd.setCursor(0, 1); // set the cursor to column 0, line 1
  lcd.print("AMB");
  lcd.setCursor(4, 1);
  lcd.print(ambient);
  lcd.setCursor(10, 1);
  lcd.print(VEHvoltage / 10.0, 1);
  lcd.setCursor(14, 1);
  lcd.print("v ");
  
  // coolant
  if (coolant < -9) {
    lcd.setCursor(7,0);
    lcd.print((char)223);
  }
  else if (coolant <0) {
    lcd.setCursor(6,0);
    lcd.print((char)223);
    lcd.setCursor(7,0);
    lcd.write(254);
  }
  else if (coolant < 10) {
    lcd.setCursor(5,0);
    lcd.print((char)223);
    lcd.setCursor(6,0);
    lcd.write(254);
    lcd.setCursor(7,0);
    lcd.write(254);
  }
    else if (coolant < 100) {
    lcd.setCursor(6,0);
    lcd.print((char)223);
    lcd.setCursor(7,0);
    lcd.write(254);
  }
  else {
    lcd.setCursor(7,0);
    lcd.print((char)223);
  }
  
  // ambient
  if (ambient < -9) {
    lcd.setCursor(7,1);
    lcd.print((char)223);
  }
  else if (ambient <0) {
    lcd.setCursor(6,1);
    lcd.print((char)223);
    lcd.setCursor(7,1);
    lcd.write(254);
  }
  else if (ambient < 10) {
    lcd.setCursor(5,1);
    lcd.print((char)223);
    lcd.setCursor(6,1);
    lcd.write(254);
    lcd.setCursor(7,1);
    lcd.write(254);
  }
    else if (ambient < 100) {
    lcd.setCursor(6,1);
    lcd.print((char)223);
    lcd.setCursor(7,1);
    lcd.write(254);
  }
  else {
    lcd.setCursor(7,1);
    lcd.print((char)223);
  }

// AC WARNING FLASH
if (differential >= AC_WARNING) {
    lcd.setCursor(9,0);
    lcd.print(" AC");
    lcd.write(254);
    lcd.write(0);
    lcd.print(differential);
      if (differential < 10) {
      lcd.setCursor(15,0);
      lcd.write(254);
      }
    delay(1000);
    lcd.setCursor(9,0);
    lcd.print(" ******");
}
else {
  
    // if WOT or HWY or RPM or VLT
    if ((rpm < RPM_LIMIT) && (rpm > 0) && (fan1state == 0)) {
    lcd.setCursor(9,0);
    lcd.print("RPM< --");
    }
    else if ((rpm < RPM_LIMIT) && (rpm > 0) && (fan2state == 0)) {
    lcd.setCursor(9,0);
    lcd.print("RPM< *-");
    }
    else if ((rpm < RPM_LIMIT) && (rpm > 0)) {
    lcd.setCursor(9,0);
    lcd.print("RPM< **");
    }
    
    else if ((VEHvoltage / 10.0 < REQ_VOLTAGE) && (fan1state == 0)) {
    lcd.setCursor(9,0);
    lcd.print("VLT< --");
    }
    else if ((VEHvoltage / 10.0 < REQ_VOLTAGE) && (fan2state == 0)) {
    lcd.setCursor(9,0);
    lcd.print("VLT< *-");
    }
    else if (VEHvoltage / 10.0 < REQ_VOLTAGE) {
    lcd.setCursor(9,0);
    lcd.print("VLT< **");
    }    
    
    else if ((throttle >= THROTTLE_LIMIT) && (fan1state == 0)) {
    lcd.setCursor(9,0);
    lcd.print("WOT  --");
    }
    else if ((throttle >= THROTTLE_LIMIT) && (fan2state == 0)) {
    lcd.setCursor(9,0);
    lcd.print("WOT  *-");
    }
    else if (throttle >= THROTTLE_LIMIT) {
    lcd.setCursor(9,0);
    lcd.print("WOT  **");
    }
    
    else if ((speedM >= NO_FAN_SPEED) && (fan1state == 0)) {
    lcd.setCursor(9,0);
    lcd.print("HWY  --");
    }
    else if ((speedM >= NO_FAN_SPEED) && (fan2state == 0)) {
    lcd.setCursor(9,0);
    lcd.print("HWY  *-");
    }
    else if (speedM >= NO_FAN_SPEED) {
    lcd.setCursor(9,0);
    lcd.print("HWY  **");
    }
    
    // else if AC    
    else if ((ACtrigger == 1) && (fan1state == 1) && (coolantF < min(threshold1, threshold2))) {
    lcd.setCursor(9,0);
    lcd.print(" AC");
    lcd.write(254);
    lcd.write(0);
    lcd.print(differential);
      if (differential < 10) {
      lcd.setCursor(15,0);
      lcd.write(254);
      }
    }
    else if ((fan1state == 1) && (fan2state == 0)) {
    lcd.setCursor(9,0);
    lcd.print("FAN  *-"); 
    }
    else if ((fan1state == 1) && (fan2state == 1)) {
    lcd.setCursor(9,0);
    lcd.print("FANS **"); 
    }
    else if ((fan1state == 0) && (fan2state == 0)) {
    lcd.setCursor(9,0);
    lcd.print("fan off");
    }
    else {
    lcd.setCursor(9,0);
    lcd.print("missed?");
    }

  // FLASH IF HOT
  if (coolantF >= MAX_OFF_TEMP) {
    delay(500);
    lcd.setCursor(14,0);
    lcd.print("--");
    delay(200);
  }
}  

}
 
Last edited:
This is quite a project, and I'm all for projects! I'm no coder so this is way beyond me though!

I just have my electric fan on a Flex-a-lite controller lol.
 
I have the supercharger... just keep that in mind.

stock fan setup with a 180 deg Toyota therm, jiggle set in the 6 oc position it runs 188.6 - 190 pretty much no matter what. I will see 192 if I push it up to 75-80 out on the highway. 2300 rpm range I think?

stop and go August heat will bump up to 192-194 and I'm pretty sure that's because of the trans cooler portion. I have mine in series. once things are heated up the torque converter seems to give you a little spike when you stop.

I agree the Champion seems to cool better. not sure if that's because it's aluminum or because it has an extra gallon of capacity? most likely it's both. excess cooling capacity in this setup there is.

I will also say this, the Toyota engineers did a dam fine job and it's pretty much impossible to out do them. I'm sure doing an electric fan setup will give a bit of a bump but I'm not expecting much. I did headers/high flow exhaust all the way back, light weight crank pulley, super charger, electric fan setup(pending) and fake hood bulge! each little bit does add up to a difference, it's never going to be a V8 :(

so... one thing about AC... why would AC matter at all? I just want to run my ECT @ 195 deg. as long as the setup has the cooling capacity and can react quickly enough who cares about AC? since this is my first real attempt at cooling mods maybe I just don't understand. even if your calling for max cooling your really not adding load. all of the energy is coming out of the battery.

I'm also betting on the fact that going down the highway @ 65 the fan will not need to draw much power.
 
... it runs 188.6 - 190 pretty much no matter what. I will see 192 if I push it up to 75-80 out on the highway...

Radiator is certainly doing it's job. Very nice. Maybe too cool. Different sources have different opinions, but 200 may be a better target when you can program it. Some even say up to 210 I think. Nice part of my project is it should stick flat wherever programmed.

...
so... one thing about AC... why would AC matter at all? I just want to run my ECT @ 195 deg. as long as the setup has the cooling capacity and can react quickly enough who cares about AC? since this is my first real attempt at cooling mods maybe I just don't understand...

It's not about engine temps, but it's about your AC refrigerant temps. AC condenser needs to cool compressed gas into a liquid. Even if the engine does not need cooling, the condenser may need airflow. Typically it's just turned on with the AC switch, but actually measuring condenser temps would be better. Or measure pressure which is directly correlated with refrigerant temps.

... even if your calling for max cooling your really not adding load. all of the energy is coming out of the battery...

Whether a mechanical fan or electric, it has a load on motor. Electric fans load alternator and rob HP through the alt belt. I think it can be more efficient through electric fan, but a poor setup can be even worse. I believe properly shrouded, electric is more efficient, but even if it isn't, my point is that efficiency will be gained by turning off the load entirely when it's not needed.
 
Radiator is certainly doing it's job. Very nice. Maybe too cool. Different sources have different opinions, but 200 may be a better target when you can program it. Some even say up to 210 I think. Nice part of my project is it should stick flat wherever programmed.

It's not about engine temps, but it's about your AC refrigerant temps. AC condenser needs to cool compressed gas into a liquid. Even if the engine does not need cooling, the condenser may need airflow. Typically it's just turned on with the AC switch, but actually measuring condenser temps would be better. Or measure pressure which is directly correlated with refrigerant temps.

Whether a mechanical fan or electric, it has a load on motor. Electric fans load alternator and rob HP through the alt belt. I think it can be more efficient through electric fan, but a poor setup can be even worse. I believe properly shrouded, electric is more efficient, but even if it isn't, my point is that efficiency will be gained by turning off the load entirely when it's not needed.

right, sorry there is no free energy. wish there was of course it's going to cost you something. as long as you can optimize the energy use your going to see some return. I'm making the assumption that it can be optimized.

the one test I want to run but... I need to wait for the snow to melt is... can I just remove the mechanical fan and drive down the road @ 65 mph. I'm curious to know if the setup I have right now can passively cool at highway speeds. probably not but maybe?

I also have a stock 97 now and the temps I see are the same except when you ask for power the temps rise much more quickly than the champ radiator.

If I win the lotto I will setup a big lab and research stuff. passive engine cooling and heat recovery to get some of that lost energy back? but most importantly how to use that recovered heat energy to drive over stuff and beat others to the next red light.
 
Couple of thoughts:

- 36A at 14V is ~500W. At a 50% alternator power conversion ratio of crank HP to electricity, that is still less than 1.5hp drain on the engine at full fan load. I don't see much of a need to turn them off at full throttle (when you are creating max waste heat output).

- You will need ~60% fan drive or more when the AC is operating unless you *know* via sensors that the AC pressures are ok with unassisted airflow across the radiator.

- Use a temperature sensor on the water outlet of the radiator (bottom hose) for your temperature reference. Use a temperature below the engine operating temperature (say, 160*F) and let the thermostat control engine temp. This will leave some latent heat capacity in the coolant in case the electric fans can't keep up for momentary high loads.

- A well-running stock fan setup works VERY well (very reliable, very good temp control). It will be interesting to see if you can make something better...

I personally wouldn't go through the hassle of this unless I needed the engine bay space (motor swap or turbo, etc.)

-Charlie
 
Thx for comments Charlie

...36A at 14V is ~500W. At a 50% alternator power conversion ratio of crank HP to electricity, that is still less than 1.5hp drain on the engine at full fan load. I don't see much of a need to turn them off at full throttle (when you are creating max waste heat output)...

Yeah, it's trivial and certainly isn't the reason to do the project, but as long as controller is there, this feature is only a couple lines of code. It adds more HP than plastidipped trim anyway. I have the MS system on my Pontiac setup for WOT shutoff and full data logging, works awesome. There's a lag between WOT and when that heat shows up in the cooling system.

...You will need ~60% fan drive or more when the AC is operating unless you *know* via sensors that the AC pressures are ok with unassisted airflow across the radiator...

Measuring condenser output temperature is the same thing as pressure. It's a direct correlation. I thought about using a pressure sensor, but just easier to read temp of condenser output. I still might read pressure both from high and low side so I can monitor condition of the AC system.

Not sure what you mean ~60% fan drive or more? Idea is to read condenser temp differential and if condenser needs additional cooling, fan will go on. If it still needs more, the second fan will go on too. It's more than a disengaged clutch fan can do.

... Use a temperature sensor on the water outlet of the radiator (bottom hose) for your temperature reference. Use a temperature below the engine operating temperature (say, 160*F) and let the thermostat control engine temp. This will leave some latent heat capacity in the coolant in case the electric fans can't keep up for momentary high loads...

I think you are suggesting that the engine operating temperature should be the same as the thermostat opening temperature, and that the fans should maintain coolant in the uncirculated area at a temperature that is sandbagged below target operating temperature?

Thermostat is designed to provide a quick warm up and minimum operating temperature. Fans provide target operating temperature and maximum operating temperature. This is how all the modern cars are managed.

It's important to have as much coolant flow as possible through the engine block. If you were to choke back flow to maintain operating temperature, you will create a bigger difference in the hot areas and cold areas. You really want the thermostat all the way open for more even temps everywhere.

...A well-running stock fan setup works VERY well (very reliable, very good temp control). It will be interesting to see if you can make something better...

My stock setup cools fine. But actually, temp control is erratic with fan clutch (especially hot vs cold weather) and I'm certain that will improve.

...I personally wouldn't go through the hassle of this unless I needed the engine bay space (motor swap or turbo, etc.)...

I do expect to do a turbo but that's not why I'm doing it. The effort on these fans is totally unnecessary, same as the turbo and many of the things I do lol.
 
Yeah, it's trivial and certainly isn't the reason to do the project, but as long as controller is there, this feature is only a couple lines of code. It adds more HP than plastidipped trim anyway. I have the MS system on my Pontiac setup for WOT shutoff and full data logging, works awesome. There's a lag between WOT and when that heat shows up in the cooling system.
Much of my thinking on this has been for track (capable) cars. I would give up a couple (or less) HP to allow the fans to turn on max. Though, I suppose you could easily have a max temp override on the full throttle fan turn-off.

Not sure what you mean ~60% fan drive or more? Idea is to read condenser temp differential and if condenser needs additional cooling, fan will go on. If it still needs more, the second fan will go on too. It's more than a disengaged clutch fan can do.
Your fan will need a minimum duty cycle to guarantee turn-on. Also, once you need the fans, you can assume some minimum fan speed is needed to move enough air to make a difference in heat transfer. 60% is what other PWM controllers use for AC operation - you might be able to go less with experimentation.

I think you are suggesting that the engine operating temperature should be the same as the thermostat opening temperature, and that the fans should maintain coolant in the uncirculated area at a temperature that is sandbagged below target operating temperature?
Yes.

Thermostat is designed to provide a quick warm up and minimum operating temperature. Fans provide target operating temperature and maximum operating temperature. This is how all the modern cars are managed.

It's important to have as much coolant flow as possible through the engine block. If you were to choke back flow to maintain operating temperature, you will create a bigger difference in the hot areas and cold areas. You really want the thermostat all the way open for more even temps everywhere.
Ah, you are mistaking the 5VZ for a modern engine. It is a minor evolution of an engine designed in the early/mid 80s (2vz-fe introduced in the Camry in 1988). In all the vehicles this engine family was in that use electric fans, the engine fans keep the engine temp below 195*F. Compared to the 180*F thermostat installed, which gives a 'normal' water outlet temp just under 190*F, it doesn't seem that Toyota wanted the fans to control engine temp much above what the thermostat does.

My stock setup cools fine. But actually, temp control is erratic with fan clutch (especially hot vs cold weather) and I'm certain that will improve.
Any of us that have correctly working cooling systems will tell you that it should be 188 +/- 5*F for almost all conditions. If you are seeing temps above 195*F with any regularity, flip your thermostat so the jiggle valve is in the 6 o'clock position (yes, upside down from almost every other engine) and/or replace your fan clutch and maybe radiator cap. The only time I have seen 'low' temps (below 180*F) is on LOOOONG coasting down the Grapevine (~5 miles of coasting at 70+mph). Getting above 195*F takes a 105*F+ day and full AC blasting in traffic.

-Charlie
 
I have the TRD thermostat (170 degrees I think?) and my temps in 6 months out of the year are pegged in the 170 range. I only see over 180 on warmer days, and over 190 if I have the A/C on and am not travelling at highway speeds. Lower thermostat + e-fan keeps things nice and cool. If you are looking to get those lower temps, dropping to a cooler thermostat really does make a difference.

A good electric fan moves much more air at idle than the stock mechanical fan. I can actually feel a suction from outside the grill with an electric fan compared to when I had the mechanical fan.
 
Not a bad first program. Here's a few tips for the Arduino that I've picked up over the years.

1) Floats are expensive! Try to remove all the floats that you can. Arduino really doesn't like floats.
Code:
float pot; 
pot = analogRead(potPin); // *** DELETE POT TESTING
pot = pot / 1000; // *** DELETE POT TESTING
float coolantC = 100 - pot * 25; // *** DELETE POT TESTING

can be rewritten:
Code:
uint16_t pot = analogRead(potPin);  //  16 unsigned (0-65535), but analogRead is 10 bit (0-1023)
uint16_t coolantC = 10000 - ((pot * 25)/10);  //  2 decimal precision without the decimal -- temp 7443C - 10000C

2) When doing math, don't forget rollover and signed numbers. Let's take an averaging of 50 10-bit unsigned numbers averaged into an int.
The max 10-bit unsigned number is 2^10 - 1 or 1023. The max number that will fit into an int is 2^15 - 1 or 32,767. If we take 32 samples all at 1023 and add them together we get 32736, which is fine. If we add 1 more at 1023 we get -31777. To fix this problem, we can use an unsigned int (uint16_t). Now we can store 64 10-bit unsigned numbers. But if we try to store just one more we rollover into the 17th bit (which doesn't exist) and 65 10-bit numbers stored in a 16-bit unsigned int is 959 instead of 66,495.

Remember math is all binary in the Arduino.

3) Avoid the use of delays. Read and try this:
Arduino - BlinkWithoutDelay
Arduino Tutorial: Using millis() Instead of delay()

4) Streamline your loop.
Code:
uint32_t previousThermistor = 0;
uint32_t previousDisplay = 0;

typedef struct  { 
	uint16_t throttle;
	uint16_t rpm;
	uint16_t VEHvoltage;
	uint16_t speedK;
	uint16_t coolantC;
} CAR_DATA;

CAR_DATA data;

void loop() {
	uint32_t currentMillis = millis();
	readOBD(&data);
	if (currentMillis - previousThermistor > THERMISTOR_INTERVAL) {
		readThermistor();
		previousThermistor = millis();
	}
	setFanState(data);
	if (currentMillis - previousDisplay > DISPLAY_INTERVAL) {
		display(data);
		previousDisplay = millis();
	}
}

bool readOBD(CAR_DATA *data) {
	// read your OBD and store in data
}

uint8_t setFanState (CAR_DATA data) {
	// set the fan state based on data and return the fan states
	// 0 - 00b - both off
	// 1 - 01b - one on the other off
	// 2 - 10b - the other on and one off
	// 3 - 11b - both on
}

void display (CAR_DATA data) {
	// display the data...
}

Hope this helps. If you need general Arduino help, send me a PM.

** Note: None of my code in this post has been tested, it's purely informational.

*** Note 2: My preference is to use bite specific types (uint16_t, int32_t, etc) instead of the Arduino types (byte, int, unsigned long, etc). But, that's just a personal preference that comes in handy when working with different platforms.
 
I have the TRD thermostat (170 degrees I think?) and my temps in 6 months out of the year are pegged in the 170 range. I only see over 180 on warmer days, and over 190 if I have the A/C on and am not travelling at highway speeds. Lower thermostat + e-fan keeps things nice and cool. If you are looking to get those lower temps, dropping to a cooler thermostat really does make a difference.

A good electric fan moves much more air at idle than the stock mechanical fan. I can actually feel a suction from outside the grill with an electric fan compared to when I had the mechanical fan.

You may want to consider a warmer thermostat? A lot of info suggests that 180° should be a minimum operating temp to reduce cylinder wear.
 
I am interested in seeing how this all works out for you.

What you are trying to do seems kind of overly complicated for what you are trying to accomplish but I admire what you are doing. I wouldn't have the patience to try to work all this stuff out and write a program, etc.

I have run several different electric fan setups and have finally found something that works well for me for the most part but all in all I wish I had just stuck with the mechanical fan and saved all the money I have put into my electric fan setup.

I hope you are happier with the results than I ended up being with mine.
 
I am interested in seeing how this all works out for you.

What you are trying to do seems kind of overly complicated for what you are trying to accomplish but I admire what you are doing. I wouldn't have the patience to try to work all this stuff out and write a program, etc.

I have run several different electric fan setups and have finally found something that works well for me for the most part but all in all I wish I had just stuck with the mechanical fan and saved all the money I have put into my electric fan setup.

I hope you are happier with the results than I ended up being with mine.

Thx for the comment.

What have you learned from your fan setups? What did you have to change and what falls short for you now?
 

Members online

No members online now.

Forum statistics

Threads
278,309
Messages
3,554,068
Members
248,016
Latest member
Advally Service

Trending content

Back
Top