follow ft86club on our blog, twitter or facebook.
FT86CLUB
Ft86Club
Speed By Design
Register Garage Community Calendar Today's Posts Search

Go Back   Toyota GR86, 86, FR-S and Subaru BRZ Forum & Owners Community - FT86CLUB > Technical Topics > DIY (Do-It-Yourself) Guides

DIY (Do-It-Yourself) Guides For all DIYs.

Register and become an FT86Club.com member. You will see fewer ads

User Tag List

Reply
 
Thread Tools Search this Thread
Old 11-07-2016, 02:13 AM   #1
Aussie
Member
 
Join Date: Nov 2014
Drives: 2013 Scion FR-S 6MT
Location: South Bay
Posts: 71
Thanks: 23
Thanked 40 Times in 21 Posts
Mentioned: 6 Post(s)
Tagged: 1 Thread(s)
Garage
Automating a manual air conditioning system including an ethanol content display

In this guide I will describe the steps I took to automate the manual AC system in my FR-S using an Arduino Uno R3, a relay, a temperature sensor, a potentiometer and a 2 line LCD display.


Overview

The Arduino based system operates by measuring the ambient temperature using a LM35 temperature sensor and comparing that with a target temperature set using a potentiometer. If the ambient temperature is higher than 1 degree C from the target temperature the controller will cause the relay to switch the AC on. If the ambient temperature is lower than 1 degree C from the target temperature the controller will cause the relay to switch the AC off. This done approximately every 30 seconds to avoid cycling the AC too often.

If the target temperature potentiometer is turned either fully clockwise of anti clockwise the system will no longer control the AC. In this state the controller will simply display the ambient temperature.

Bonus feature

If you have a flex fuel kit installed and the kit provides a 0.5-4.5v signal indicating the ethanol content 0-100% the system can use this to calculate the current ethanol content of the fuel and add this information to the display.


Background

I am one of those people that hates to blend in hot air when the AC is on to maintain a desired temperature. It is a waste of energy and as a result, since I have never had a car with automatic climate control, I have had to manually turn the AC on and off. This is a nuisance that can be overcome with the aid of a simple controller.

While this write-up is specific to GT86, BRZ and FR-S vehicles with manual AC it can be used in all vehicles with manual AC. Also the instructions I give are specific to a 2013 FR-S and I take no responsibility for any damage to your car if you choose to follow my guide.


Hardware Parts list:
  1. Arduino Uno R3
  2. Arduino compatible relay
  3. LCD 1602
  4. LM35 temperature sensor
  5. 10K Ohm linear potentiometer
  6. 220 Ohm resistor
  7. 10K Ohm linear micro potentiometer
  8. 12v cigarette lighter to USB power adapter
  9. ~ 75cm USB to USB A cable
Note: most, if not all, of these components can be bought as part of an Arduino sensor starter kit available on eBay or Amazon.

Sundries:
  1. Insulated wire
  2. Heat shrink tubing
  3. solder
  4. soldering iron


Wiring

The following circuit diagram shows how I wired the sensors, relay and display together. Note 5V and ground are available on the Arduino board.





Software Environment
I used Arduino software environment 1.6.9 running on a Mac. There are versions that run on other operating systems.


Code
The Arduino is quite straight forward to program. I have attempted to comment the code to describe how it functions. For those who are not familiar with the Arduino, two functions are all you really need to know: setup(), this is called once to initialize the system; loop(), this routine is called regularly by the supervisor code and this is where most of the controller is implemented.

Rather than explain the code line by line I would encourage you to study the code starting with the definitions of constants and global variables and the setup and loop functions.


Code:
/*
 * Airconditioning Controller with Ethanol content display
 *
 * Author: Rob Esser 
 * Date: Version 1.0 5th of November 2016
 *
 * This SOFTWARE is provided "as is" and "with all faults." 
 * I make no representations or warranties of any kind concerning the safety, suitability, inaccuracies, 
 * typographical errors, or other harmful components of this SOFTWARE. There are inherent dangers in the 
 * use of any software, and you are solely responsible for determining whether this SOFTWARE is compatible 
 * with your equipment and other software installed on your equipment. You are also solely responsible 
 * for the protection of your equipment and backup of your data, and I will not be liable for any damages
 * you may suffer in connection with using, modifying, or distributing this SOFTWARE.
 *
 * Resources used
 * OpenSource 16x2 LCD display code from: http://www.arduino.cc/en/Tutorial/LiquidCrystal
 * Watchdog timer code from https://bigdanzblog.wordpress.com/2014/10/24/arduino-watchdog-timer-wdt-example-code/
 * 
 * The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * LCD VSS pin to ground
 * LCD VCC pin to 5V
 * 10K potentiometer: ends to +5V and ground, wiper to LCD VO pin (pin 3)
 * Backlight LCD 15 to 220 Ohm resister to 5V
 * LCD 16 to ground
 * 
 * LM35 temperature sensor input          analog pin 1
 * Target temperature potentiometer input analog pin 2
 * Ethanol fuel content input             analog pin 4
 * Relay output                          digital pin 10
 * 
 */

// include the library code:
#include <LiquidCrystal.h>
#include <avr/wdt.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int actualTempPin = 1;     // Analog input 1
const int targetTempPin = 2;     // Analog input 2
const int ethanolPin    = 4;     // Analog input 4 from flex fuel kit
const int relayPin      = 10;    // Digital Output 10
const int pinReadDelay  = 10;    // ms delay to stabilize reading on Arduino ADC when switching pin-to-pin?

const float TEMPDELTA   = 1.0;   // The amount of temperture hysteresis / 2
const float VOFF        = 0.5;   // The minimum voltage with 0% Ethanol
const float VRANGE      = 4.0;   // The active range of Ethanol values (0.5 - 4.5v)

bool relayState         = false; // Keep track of the relay state
int iteration           = 0;     // the current iteration
const int windowSize    = 5;     // how many samples to average
int actualTemp[windowSize];
int actualTempIndex     = -1;
int actualEthanol[windowSize];
int actualEthanolIndex  = -1;

const int MAXITERATIONS = 29;    // 0..29 at 1 second per iteration ~= 30 seconds

int analogReadWithDelays(int pin) { 
  analogRead(pin);
  delay(pinReadDelay);
  int val = analogRead(pin);
  delay(pinReadDelay);
  return val;
}

float getActualTemp() {
  // get value from pin
  int analogVal = analogReadWithDelays(actualTempPin);
  // store in appropriate spot in window of values
  int i;
  if (actualTempIndex < 0) {
    // First time just replicate first value
    for ( i = 0; i < windowSize; i = i + 1 ) {
      actualTemp[i] = analogVal;
    }
    actualTempIndex = 0;
  } else {
    // store the latest value
    actualTemp[actualTempIndex] = analogVal;
    // point to next value
    actualTempIndex = (actualTempIndex + 1) % windowSize;
  }
  // get the sum of samples
  int sum = 0;
  for ( i = 0; i < windowSize; i = i + 1 ) {
    sum += actualTemp[i];
  }
  // calculate the average
  float average = float(sum) / windowSize;
 
  // 10 bit A/D converter
  float mv = (average / 1024.0) * 5000;
  float cel = mv / 10;
  return cel; 
}

float getTargetTemp() {
  int analogVal = analogReadWithDelays(targetTempPin);
  // 10 bit A/D converter
  float targetTemp = 0.0;
  if ((analogVal > 10) and (analogVal < 1013)) {
    // we have a range of 15-40 degrees C
    targetTemp = (analogVal / 40.0) + 15;
  }
  return targetTemp;
}

//get the Ethanol value from the flex-fuel sensor (0.5 - 4.5v)
float getEthanol() {
  int analogVal = analogReadWithDelays(ethanolPin);
  // store in appropriate spot in window of values
  int i;
  if (actualEthanolIndex < 0) {
    // First time just replicate first value
    for ( i = 0; i < windowSize; i = i + 1 ) {
      actualEthanol[i] = analogVal;
    }
    actualEthanolIndex = 0;
  } else {
    // store the latest value
    actualEthanol[actualEthanolIndex] = analogVal;
    // point to next value
    actualEthanolIndex = (actualEthanolIndex + 1) % windowSize;
  }
  // get the sum of samples
  int sum = 0;
  for ( i = 0; i < windowSize; i = i + 1 ) {
    sum += actualEthanol[i];
  }
  // calculate the average
  float average = float(sum) / windowSize;
 
  // 10 bit A/D converter
  float v = (average/1024.0) * 5;
  float eth = (v - VOFF) * 100.0 / VRANGE;
  // Clamp the Ethanol value to be within 0..100%
  if (eth < 0.0) {
    eth = 0.0;
  } else if (eth > 100.0) {
    eth = 100.0;
  }
  return eth;
}

String getTempText(float degrees) {
  String txt = "";
  txt.concat(String(degrees, 0));
  // Add in the degree symbol
  txt.concat((char)223); 
  // Celcius
  txt.concat("c");  
  if (degrees < 10.0) {
    txt.concat(" ");  
  }
  return txt;
}

String getEthanolText(float percent) {
  String txt = " ";
  txt.concat(String(percent, 0));
  // Add enough characters to write to end of line
  txt.concat("%  ");         
  return txt;
}

/////////////////////////////////////////////////////////////////////////////////////

void setup() {
  // immediately disable watchdog timer so set will not get interrupted
  wdt_disable();
  // the following forces a pause before enabling WDT. This gives the IDE a chance to
  // call the bootloader in case something dumb happens during development and the WDT
  // resets the MCU too quickly. Once the code is solid, remove this.
  delay(2L * 1000L);
  // enable the watchdog timer. There are a finite number of timeouts allowed (see wdt.h).
  // Notes I have seen say it is unwise to go below 250ms as you may get the WDT stuck in a
  // loop rebooting.
  // Reasonable timeouts for this project are:
  // WDTO_1S
  // WDTO_2S
  // WDTO_4S
  // WDTO_8S
  wdt_enable(WDTO_4S);
  
  // Setup analog input pins (these are setup as inputs by default)
  pinMode(actualTempPin,INPUT);
  pinMode(targetTempPin,INPUT);
  pinMode(ethanolPin,INPUT);

  // initialize digital relayPin as the relay output.
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, LOW);   // turn the LED/Relay OFF (LOW is the voltage level)
  relayState = false;
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.setCursor(0, 0);
  lcd.print("Rob's Climate   ");
  lcd.setCursor(0, 1);
  lcd.print("Controller V1.0 ");
  //A delay to make the welcome text visib;e
  delay(2000);
}

void loop() {
  //kick the (watch) dog
  wdt_reset();
  // Get analog values
  float targetTemp = getTargetTemp();
  float actualTemp = getActualTemp();
  // get the Ethanol value from the flex-fuel sensor (0.5 - 4.5v)
  float actualEthanol = getEthanol();
  
  // Write data to the display
  lcd.setCursor(0, 0);
  if (targetTemp < 1.0) {
    lcd.print("           ");
  } else {
    lcd.print("Target ");
    lcd.print(getTempText(targetTemp));
  }
  //Now add in the Ethanol header to line 0
  lcd.print(" Eth ");
  // set the cursor to column 0, line 1
  lcd.setCursor(0, 1);
  lcd.print("Actual ");
  lcd.print(getTempText(actualTemp));
  lcd.print(getEthanolText(actualEthanol));
    
  if (iteration >= MAXITERATIONS) {
    // Only change relay state at most every 30 seconds
    iteration = 0;
    if (targetTemp < 1.0) {
      relayState = false;
      digitalWrite(relayPin, LOW);
    } else if (actualTemp > (targetTemp + TEMPDELTA)) {
      // Turn relay on
      relayState = true;
      digitalWrite(relayPin, HIGH);
    } else if (actualTemp < (targetTemp - TEMPDELTA)) {
      // Turn relay off
      relayState = false;
      digitalWrite(relayPin, LOW);
    }
  } else {
    // Turn off immediately if we switch it off
    if (targetTemp < 1.0) {
      relayState = false;
      digitalWrite(relayPin, LOW);
    }
    iteration ++;
  }
  // set the cursor to column 15, line 1
  lcd.setCursor(15, 1);
  // Now add an indication if the AC is on
  if (relayState) {
    lcd.print((char)62);  // 62 = Arrow, 45 = minus sign
  } else {
    lcd.print(" "); 
  }

  //wait a sec
  delay(1000);
}
Gaining access to the AC Switch

To gain access to the AC switch you will need to dismantle the center console and the lower center section of the dash. It sounds more daunting than it actually is. I followed the excellent instructions at:

http://www.ft86club.com/forums/showthread.php?t=8336

Attaching the wires

Once you have access you will need to detach the plug from the temperature dial/AC switch assembly. The wires you are after are pin 2 (pink) and pin 3 (yellow). On the FR-S shorting these 2 pins together when the fan is on will turn the AC on. I carefully removed the insulation from each wire without cutting the wire and soldered a new wire sufficiently long to reach the handbrake (~ 50cm) to the exposed section of each. I then used shrink tubing to cover the bare wires and soldered joints to protect them and prevent shorts.

Unfortunately I forgot to take a photo showing how I attached the wires to the back of the AC switch / temperature dial - sorry.

Note: If you have an analog ethanol signal wire going to your ECU, also tap this wire and route it through the lower dash along with the other wires.








I chose to install the unit in the space made free by removing the small storage bin and the USB connector at the bottom of the center console.




Creating a front panel

I cut a piece of aluminum to match the shape of the storage bin surround. I then cut a hole to fit the LCD display using a Dremel tool with a cutting wheel. I also drilled holes to mount the target temperature potentiometer and another hole to mount the LM35 temperature sensor in the upper left hand corner of the front panel. (not shown)








The following photo shows the Arduino Uno with a prototype shield to mount the wiring and resistors. It also shows the relay board and the wiring to the front panel. I mounted the boards using cable ties to the base of a plastic container. This protects the circuit boards and fits snuggly into the space where the storage bin was located. The USB cable is then routed through the back of the center console and behind the glove box to a USB charger that plugs into the 12v socket in the glove box. This is a switched socket and has the advantage that if the software ever needs to be updated it is simply a matter of unplugging the USB cable from the socket and inserting it into a laptop.





Before installing the system into the car I tested it. As can be seen from the photo I covered the front panel with black faux carbon fiber vinyl. It improved the looks somewhat.






How the system looks when installed in the car.




Thanks

Last edited by Aussie; 11-07-2016 at 02:35 AM.
Aussie is offline   Reply With Quote
The Following 4 Users Say Thank You to Aussie For This Useful Post:
BRZyJ (11-09-2016), dj2020 (11-12-2016), mrjj (01-31-2020), zc06_kisstherain (11-08-2016)
Old 11-09-2016, 01:02 PM   #2
Crazy Asylum
Member
 
Crazy Asylum's Avatar
 
Join Date: May 2016
Drives: 2016 FR-S Raven
Location: Northern VA
Posts: 29
Thanks: 1
Thanked 4 Times in 4 Posts
Mentioned: 0 Post(s)
Tagged: 0 Thread(s)
For those of us that experience all 4 seasons, would this work for heat as well or would additional steps need to be taken for that?
Crazy Asylum is offline   Reply With Quote
Old 11-09-2016, 05:12 PM   #3
Aussie
Member
 
Join Date: Nov 2014
Drives: 2013 Scion FR-S 6MT
Location: South Bay
Posts: 71
Thanks: 23
Thanked 40 Times in 21 Posts
Mentioned: 6 Post(s)
Tagged: 1 Thread(s)
Garage
Unfortunately the heater on the manual system is operated by cables. It will require a servo motor and position encoder that can be mated to the appropriate parts to work. If this functionality is important to you there are guides showing how to retrofit the automatic climate control system into your car. I've seen replacement front panels from wrecked cars on eBay.
Aussie is offline   Reply With Quote
Old 11-09-2016, 06:39 PM   #4
86Boyz
Senior Member
 
Join Date: Oct 2016
Drives: on the highway to hell
Location: SoCal
Posts: 307
Thanks: 60
Thanked 177 Times in 98 Posts
Mentioned: 4 Post(s)
Tagged: 0 Thread(s)
I only saw a portion of the title of this thread in my browser and thought it was going to say how to make your manual car drive like an automatic.
86Boyz is offline   Reply With Quote
 
Reply

Tags
ac controller, ethanol display


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
DIY - Ethanol content display in OEM clock. PIC HEAVY xkalelx DIY (Do-It-Yourself) Guides 24 03-06-2017 04:18 PM
Zeitronix Ethanol Content Analyzer and Display Kit Red + Flex Fuel Sensor with Fuel L BRZ_HaVoKx Engine, Exhaust, Bolt-Ons 9 01-15-2017 10:40 PM
Zeitronix Ethanol Content Analyzer and Display Kit Red + Flex Fuel Sensor with Fuel L BRZ_HaVoKx Audio/Visual, Electronics, Infotainment, NAV 4 07-16-2016 07:43 PM
FS- Bluetooth ETHANOL CONTENT ANALYZER (ECA) Jetbill Engine, Exhaust, Bolt-Ons 0 07-20-2015 07:15 PM
Zeitronix Ethanol Content Analyzer - E85! No Limit Motorsport Engine, Exhaust, Bolt-Ons 7 05-03-2013 04:04 PM


All times are GMT -4. The time now is 11:45 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2025, vBulletin Solutions Inc.
User Alert System provided by Advanced User Tagging v3.3.0 (Lite) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.

Garage vBulletin Plugins by Drive Thru Online, Inc.