Setup
In this first part of my code, I included all necessary libraries and defined all of the pins that I will be using for the laptop cooling pad.
The LiquidCrystal.h library allows me to declare an LCD object with the pins that I have designated on the Arduino. It also allows me to write commands to the LCD.
The temperature sensors output a voltage based off of the temperature that they detect. I used two analog pins on the Arduino to be able to read this information.
The fans required two pwm-capable digital pins on the Arduino, I used pins 6 and 7.
In my void setup() function, I initialized my LCD along with the serial monitor to display information, I also declared my fan pins as outputs.
Also in the setup function, I called my loading_screen() function, which displays before the loop function begins. The lcd is cleared after this loading screen is displayed.
User-Defined Functions
I used many different user-defined functions to reduce the complexity of my code. The first few of these were simple functions to perform arithmetic operations and drive the fans.
cels_to_fahr
This function simply takes in an integer x, which is supposed to be a temperature reading in celsius, and converts it to fahrenheit. The fahrenheit reading is returned.
average
This function takes in two integers that we wish to know the average value. It does this by adding them and dividing the result by two. The average is then returned.
fans_on()
This function has no parameters. When it is called, it uses pulse-width modulation to send a signal to the fan pins. A value of 255 is the maximum value, and this is similar to outputting a 5V signal. By using pulse-width modulation, we can input a value between 0 and 255 and this corresponds to a voltage of 0-5V.
fans_off()
This is also a void function and has no parameters. When it is called, it outputs 0V to the fan pins, which turns the fans off.
The laptop cooler wouldn't be useful without any input data or functions to tell it how to respond to this data. These two functions allow it to do those things.
get_temperature
This function reads the temperature from one of the TMP36 sensors. It has one parameter, which is the specific temperature sensor that we are trying to read from.
The variable tempVal stores the raw reading from the analog pin. This reading has to be converted into a voltage and then into a temperature reading (in Celsius).
This process is repeated 10 times and the average of these readings is returned by the function. I found that there was a large variance between subsequent readings by the TMP36, so doing this would produce more consistent readings. This is shown in the Testing section.
get_fan_speed
Now that we know the temperature of the laptop, we need to determine whether the fans need to be on or off. I chose 25 degrees Celsius as my cutoff temperature, when the fans would be enabled.
The function has one input parameter which a temperature reading. It will then enter an if statement to determine if this temperature is below 25 degrees Celsius. If so, it will call the fans_off() function and set a variable named fan_state equal to 0. If not, it will call the fans_on() function and set fan_state equal to 1.
The fan_state variable will be discussed in more detail when we talk about printing to the LCD. The value of fan_state is returned by the function.
The point of including a liquid crystal display in the project was to relay information to the user, particularly the temperature observed by the microcontroller and the status of the fans. This is accomplished by the following function:
prnt_to_lcd
This function does not return anything, it simply writes information to the LCD. It has two parameters, which are temperature (in Celsius) and the state of the fans (which was returned by the get_fan_speed() function).
First, the temperature is converted from Celsius to Fahrenheit and stored in a variable temperature_F, so that both values are displayed to the user. This is done by utilizing the cels_to_fahr() function discussed earlier.
The function then enters an if statement. This if statement was not there originally, it resulted from a bug with displaying the information on the LCD. If the temperature was 100 degrees or greater, it would require an additional segment of the LCD to display. Before the if statement was implemented it would always display the first two digits, but this issue is now fixed to accommodate for three digits.
For each piece of information, the LCD cursor needs to be set to a specific segment on the LCD. This is accomplished by the setCursor() function included in the LiquidCrystal library. The information is then printed in order.
After printing the temperature information, the LCD also displays whether or not the fans are on. This is what the fan_state variable is for. A fan_state value of 0 corresponds to the fans being off, and a fan_state value of 1 corresponds to the fans being on.
There is a switch case statement that tests for each of these outcomes, and displays the proper output.
As mentioned in the setup part of the code section, there is a function called loading_screen() that runs during the void setup of the Arduino code.
This function runs once (as it is in the void setup function) before the loop function.
It displays to the user that the laptop cooling pad has been successfully powered up and is loading.
First, the LCD prints the word "Initializing" to the screen.
After that, to implement some blinking dots, I used a for loop that runs three times and prints a dot in three different positions after the word.
Loop
Now that the functionality of void setup and user-defined functions have been discussed, it is time to cover the loop function, that runs indefinitely after the setup has been executed and the microcontroller has power.
First, three integer variables are declared. These are left_temp, right_temp, and fan_state. The left_temp and right_temp variables store the temperature readings of the two TMP36 temperature sensors on the top of the cooler. The fan_state stores the state of the fans: 0 or 1 corresponding to the fans being off or on, respectively.
After the variables have been declared, the left_temp and right_temp variables are assigned to the value returned by the get_temperature() function. The argument given to the function is the specific pin we are trying to read from. To get the temperature reading for the sensor on the left, we must read from its corresponding analog pin, and same for the sensor on the right.
Following the acquisition of the two temperature readings, an average_temp variable is defined that stores average of the two readings. We pass the average() function the values of left_temp and right_temp and it returns the average to average_temp. I printed this value to the serial monitor to help with debugging.
The fan_state variable then gets the value returned by the get_fan_speed() function. By passing this function the value of average_temp, it decides whether or not to turn on the fans. If the fans are turned off, it returns the value 0 and if they are turned on it returns the value 1. The value of fan_state is important because it tells the print command whether the fans are on or off.
The prnt_to_lcd() function is then called and passed the current values of average_temp and fan_state. These values are needed to display the two pieces of information given by the LCD: the current temperature and the state of the fans.