Temperature Controlled Fan – Overview

The idea for this project was to build an enclosed device that would actively attempt to cool itself as temperatures inside increased. The main components for the project were the ATmega328P Xplained Mini microcontroller, a temperature sensor, and a 5 volt DC fan. The device was placed into a small plastic enclosure. A circular hole was cut into the top to mount the fan, a rectangle was cut to fit an LCD screen for displaying the temperature, and two rectangles were cut on the side for ventilation and USB power. This project utilized variations of analog to digital conversion (ADC) from Lab 3 and pulse width modulation (PWM) from Lab 4.

The ADC on the microcontroller was used to convert readings from the temperature sensor into a temperature value. A separate temperature value was set as a target temperature. As the temperature inside the case increased beyond the target temperature, the fan would switch on to ventilate the hot air out of the case to cool it down. Additionally, a transistor was used along with PWM via the board’s Timer Counter 1 and Compare Match Interrupt to limit the voltage to the fan and control its speed. The fan would start at a 40 percent duty cycle and increase by 10 percent for every degree above the target temperature, maxing out at a 100 percent duty cycle. Conversely, the fan would decrease its duty cycle as the temperature decreased, turning back off after reaching below the target temperature.

Top View of the Case

Inside View of the Case

 

Temperature-Controlled Fan

To create our circuit for the temperature controlled DC fan, we built off the existing schematics used in labs 3 and 4. Our hardware includes an LCD, AtMega 328p board, temperature controlled sensor, fan, battery pack, transistor, two diodes, and multiple resistors at varying resistances. Challenges encountered wile wiring the circuit included changing our original plan to run the whole circuit off of the 6V battery pack. We found that this set up was not achievable due to the fan needing to pull more voltage from the circuit than we intended. To combat this issue, we decided to run just the fan off of the 6V battery pack and run the remainder of the circuit off of the USB. After much trial and error working with our circuit and varying resistors, we were able to find the optimal set up for the transistor used in the circuit while also finding that we needed to replace our original fan with a smaller spare fan that was in the lab room.

Temperature-Controlled Fan: ADC-Reading Code

I’ve got something super exciting to share: our temperature sensor code! The code retrieves the current ADC value by calling the function ADC_Get() , then interprets that data based on the temperature sensor documented output voltage.  ‘t’ is a global float variable. ‘fanSpeed’ is a global int value. Possible applications: converting float and integer types to character strings for output over serial connections or LCD output.

void Get_Temp(void) 
{
 
 int k = 0; //used to offset output, in case of negative temperatures
 float celcius; // Anders C.
 float fahrenheit; // Daniel Gabriel F.
 float kelvin; // William Thompson, 1st Barron K. 
 float v = 0.0; //voltage
 char temp[17]; //string for output to LCD
 
 for (int i = 0; i< 16; i++)
 {
      temp[i] = 32; //pad output string with spaces
 }
 temp[16]='\0'; //null terminator for c-style string
 
 ADC_Get();
 Acc = (((int)HADC) * 0x100 + (int)(LADC));
 //temperature sensor rated output range: 
 //  100mV to 1750mV (-40 to 125°C)
 if (Acc > 20 && Acc < 359) 
 {
      // Convert ADC output to fraction of Vcc. (5V)
      v = (Acc/1023.0)*(5.0); 
      // per specifications 10mV / °C (100° = 1 Volt, 750mV @ 25°C)
      celcius = (v - 0.5)*100.0; 
      kelvin = 273.15 + celcius; // celcius to kelvin
      fahrenheit = celcius * 9.0/5.0 + 32.0; // celcius to fahrenheit
      t = fahrenheit;
 
      if(t<0)
      {
           t*=-1;
           k = 1; //offset display by 1, to make way for minus sign
           temp[0] = '-';
      }
      else
      {
           k = 0;
           temp[6] = 32;
      }
 
      int p = (int)(t*100.0); // float * 100, then cast to type int.
 
      //Note: 48 is the ASCII offset of '0' (49 = '1', 50 = '2', etc.)
      temp[(5+k)] = p % 10 + 48; //pull off hundredths decimal place. 
      p /= 10;
      temp[(4+k)] = p % 10 + 48; //pull off tenths decimal place
      p /= 10;
      temp[(3+k)] = '.';
      temp[(2+k)] = p%10 + 48;
      p/=10;
      if (p>=0) {
           temp[1+k] =p%10 +48;
           p/=10;
      }
      else
           temp[1+k]='0';
      if (p>=0){
           temp[0+k] = p +48;
      }
      else
           temp[0+k] = '0';

      if (t > targetTemp) // max operating temperature has been exceeded
      {
           //display fan output speed
           temp[13]= fanSpeed / 10 % 10 +48;
           temp[14]= fanSpeed % 10 + 48;
           char msgStrFan[5] = {"Fan=%"};
           for (int i = 9; i < 16; i++)
           {
                temp[i] = msgStrFan[i];
                if(i == 12) i = 15; //skip index 13,14
                temp[i]= msgStrFan[i];
           }
      }
      if (fanSpeed > 99) //fanspeed has reached maximum
      {
           //for a little fun, after the fan has reached
           //maximum speed, we output text to the display
           //until the fan speed reaches <60% load
 
           iZombie = 1; //locks output until fan speed < 60%
           char msgStr1[16] = {"He's dead, Jim."};
           for (int i = 0; i < 16; i++)
           {
                temp[i] = msgStr1[i];
           }
      }
      if (iZombie == 1)
      {
           if (fanSpeed >80)
           {
                char msgStr1[16] = {"He's dead, Jim."};
                for (int i = 0; i < 16; i++)
                {
                     temp[i] = msgStr1[i];
                }
 
           } else if (fanSpeed >60)
                {
                     char msgStr2[16] = {"... could he be?"};
                     for (int i = 0; i < 16; i++)
                          {
                               temp[i] = msgStr2[i];
                          }
 
                } else if (fanSpeed >0)
                     {
                          char msgStr3[16] = {"He. Is. ALIVE !!"};
                          for (int i = 0; i < 16; i++)
                          {
                               temp[i] = msgStr3[i];
                          }
                          iZombie = 0;
                     }
           }
      LCD_Puts(temp); //output character string to LCD
      Wait(); // This function just limits the refresh rate of the LCD
      Wait(); // If the refresh rate is too fast, the characters are dim
  } 
}