Introduction: FPGA Smart Fan


This guide will teach you how to build a homemade, environmentally friendly Smart Fan. This project is dedicated to Professor Danowitz CPE 133 course at Cal Poly San Luis Obispo. This project was designed and carried out by Kenneth Doran, Mark Williams, and Ashesh Patel. We felt that many college students don’t have a good way to control their room temperature and wanted to do so in an eco-friendly way. For this project we wrote VHDL code to program a FPGA to turn a window fan on or off based off the temperature inside the apartment, the outside temperature, and a desired internal temperature.

Step 1: Gathering Material


  • Arduino Uno
  • Basys 3 Xilinx Artix-7 FPGA (XC7A35T-ICPG236C)
  • 2 TMP36 sensors
  • Fan (we used a 5v DC fan)
  • NPN Transistor
  • Micro-USB to USB type A for Basys 3 Board
  • USB type B to USB type A to upload arduino code
  • Arduino jumper cables for wiring
  • Computer
    • Vivado - Free VHDL Software
    • Arduino IDE

Step 2: Grand Architecture of FPGA

The majority of the logic of this project is done on a Basys3 board, and the black box of the Smart Fan has 6 inputs and 4 outputs. All 5 buttons on the board are used, 4 of the buttons control what the seven segment display should show, while the right button forwards the Desired Temperature and Tolerance to the logic of the board. The Smart Fan uses a tolerance value, represented in binary by the 4 rightmost switches on the board, which is added to the inside and outside temperatures to detect if the difference between the outside and inside is more than the specified tolerance. If the fan being on would bring the inside temperature closer to the desired temperature, represented in binary by the 8 leftmost switches on the board, then the JA1 pin will be high, and turn on the connected fan through the transistor.

At this point download the SmartFan.bit and program the Basys 3 board.

Step 3: Individual Modules of FPGA

DFF: This project uses 2 8-bit D-Flip Flops, used to store the Desired Temperature and the Tolerance. This allows the user to configure their switches to a new setting without causing sporadic behavior in the fan. The DFF has 3 inputs: clk (clock), d(7 downto 0) (input value), en (enable); and 1 output: f(7 downto 0) (output value). Upon the rising edge of the clock, if the enable input is high, then the DFF sets the output value to the current input value.

RCA: This project uses 2 8-bit Ripple Carry Adders, used to adjust the input temperatures by the amount of tolerance specified by the user. The RCA has 2 inputs: A(7 downto 0), B(7 downto 0); and 1 output: S(7 downto 0) (sum). The RCA uses 7 Full Adders and 1 Half Adder to add the two input values by comparing their same magnitude bits, resulting in a sum that represents the input numbers added together.

Comparator: This project uses 3 8-bit Comparators, used to detect the current state of the temperature balance. The Comparator has 2 inputs: A(7 downto 0), B(7 downto 0); and 2 outputs: LT (Less Than), GT (Greater Than). The Comparator will output a high to LT if AB is true.

Multiplexer: This project uses an 8-bit Multiplexer, to choose what should be displayed on the seven segment display, using a one-hot encoded select signal. The Multiplexer has 4 inputs: A(7 downto 0), B(7 downto 0), C(7 downto 0), D(7 downto 0); 1 select signal: sel(4 downto 0); and 1 output: out(7 downto 0). The multiplexer outputs: D when the 4th select bit is high, C when the 3rd select bit is high, B when the 2nd select bit is high, A when the 1st select bit is high, and x”00” the rest of the time.

sseg_dec: This project uses a Seven Segment Decoder, to display information to the user about the current temperature values and settings from the stored binary values into easily readable decimal. The sseg_dec has 4 inputs: ALU_VAL(7 downto 0) (input binary number), SIGN (signed), VALID, CLK (clock); and 2 outputs: DISP_EN(3 downto 0) (digit anodes), SEGMENTS(7 downto 0). This module was provided by our instructor in a lab, and was made by Bryan Mealy. In our project we only used unsigned valid numbers, so SIGN was set to ‘0’, and VALID to ‘1’. Normally, the input binary number is converted into binary-encoded decimal, and then the correct segments and digit anodes are turned off, however for this project we changed the display to be completely off if the input binary number was 0, to conserve energy should nothing needs to be displayed.

If you would like to make any changes to the program, the source code is listed below.

Step 4: Attaching Fan to FPGA

Connect the JA1 pin of the Basys3 board to the middle pin of the transistor to control when the fan should be on or off.

Find the fan’s power and ground connections, then connect the power of the fan to the 3.3V pin or to a different power source if you have a larger fan.

Connect the fan’s ground to rightmost pin of the transistor, and connect the leftmost pin of the transistor to the board’s ground, or another ground.

Step 5: Arduino Hardware and Code

For this project we used 2 TMP36 temperature sensors which are low voltage temperature sensors. They output voltage that is linearly proportional to the Fahrenheit temperature. Refer to the TMP36 datasheet for more info.

Mount one sensor in the apartment and another sensor outside the apparent. The voltage inputs from the sensors are read from the 0 and 2 Analog Input pins on the arduino. These values are then converted to temperature integers based off a calibrated formula. We converted the temperature to a binary number and output that to 6 different Arduino pins for each sensor:

(pins: 2, 3, 4, 5, 6, 7 and 8, 9, 10, 11, 12, 13).

The basys board read this input through the JB and JC pin slots:

(pins: JB 1, 2, 3, 7, 8, 9 and JC- 1, 2, 3, 7, 8, 9).

Connect each of the corresponding pins above with wires as shown above. Also, download and upload the Arduino TempReadings.ino file.

Step 6: Using the Smart Fan

When using the Smart Fan, the 5 buttons allow the user to Display Outside Temp, Set Tolerance and Desired Temp, Display Inside Temp, Display Desired Temp, and Display Tolerance. The 8 left most switches set the desired temperature using binary while the 4 right most switches allow the user to set the tolerance in binary.

At this point you can download and upload the FanTester.ino file to test that the Basys 3 board is correctly connected to the Arduino board as it should cycle through the temperature pairings (outside,inside).

You now have a fully functioning, environmentally-friendly, Smart Fan!