/* Leen Skaf 05/29/2025 // This work may be reproduced, modified, distributed, performed, and displayed for any purpose, but must acknowledge this project. Copyright is retained and must be preserved. The work is provided as is; no warranty is provided, and users accept all liability. // // The following code is a draft for my final project - Drive a fan based on the mean temperature recorded by two DS18B20 temperature sensors - To control the speed of the fan, it is mapped to the PWM range of 170 to 255, where a minimum temperature threshold is set and an increment of 20% speed increase corresponds to 1°C temperature increased - Information about fan status and mean temperature is shown on an OLED01.3 display // */ #include #include #include #include // I2C OLED Setup #define I2C_ADDRESS 0x3C #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 // Initialize the OLED display using the default I2C bus (Wire) Adafruit_SH1106G display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire); // DS18B20 Temperature Sensors // Sensors are connected to GPIO26 and GPIO27 MicroDS18B20<26> sensor1; MicroDS18B20<27> sensor2; // LED and Fan Definitions #define LED_PIN 22 // LED to indicate temperature threshold #define FAN_PIN 16 // DC fan controlled via PWM // Temperature thresholds for fan control: const float tempThreshold = 22.0; // Fan starts running at 22°C const float maxTempForFan = 26.0; // Fan reaches 100% speed at 27°C // Global variable to track when the fan turns on (in m illiseconds) unsigned long fanOnStartTime = 0; void setup() { //delay(2000); Serial.begin(9600); // Initialize I2C bus Wire.begin(); // Initialize the OLED display; if not found, pause execution if (!display.begin(I2C_ADDRESS, true)) { Serial.println(F("OLED not found")); while (1); } // Configure the LED and Fan pins as outputs pinMode(LED_PIN, OUTPUT); pinMode(FAN_PIN, OUTPUT); // Display a startup message display.clearDisplay(); display.setTextSize(2); display.setTextColor(SH110X_WHITE); display.setCursor(0, 10); display.println("Starting..."); display.display(); //delay(2000); } void loop() { // Request temperature readings from both sensors sensor1.requestTemp(); sensor2.requestTemp(); // Wait for conversion. delay(1000); // Variables to hold temperature values and sensor status float temp1 = 0, temp2 = 0; bool sensor1_ok = false, sensor2_ok = false; // Read sensor1. if (sensor1.readTemp()) { temp1 = sensor1.getTemp(); sensor1_ok = true; } else { Serial.println("Error reading sensor1"); } // Read sensor2. if (sensor2.readTemp()) { temp2 = sensor2.getTemp(); sensor2_ok = true; } else { Serial.println("Error reading sensor2"); } // Validate sensor data. bool validData = sensor1_ok && sensor2_ok; float meanTemp = 0; if (validData) { meanTemp = (temp1 + temp2) / 2.0; } else { Serial.println("Cannot compute mean: one or more sensor readings failed."); } // Variables for fan control. bool fanOn = false; int fanSpeedPercent = 0; int pwmValue = 0; // PWM value (0 - 255) // Only control the fan if sensor data is valid if (validData && (meanTemp >= tempThreshold)) { digitalWrite(LED_PIN, HIGH); // Turn on LED // Calculate fan speed percentage based on temperature between threshold and maxTempForFan if (meanTemp >= maxTempForFan) { fanSpeedPercent = 100; } else { fanSpeedPercent = (int)(((meanTemp - tempThreshold) / (maxTempForFan - tempThreshold)) * 100); } // Map the fan speed percentage to PWM value in the range 170 to 255 pwmValue = map(fanSpeedPercent, 0, 100, 170, 255); analogWrite(FAN_PIN, pwmValue); fanOn = true; // Record fan activation time if it just started if (fanOnStartTime == 0) { fanOnStartTime = millis(); } } else { digitalWrite(LED_PIN, LOW); // Turn off LED analogWrite(FAN_PIN, 0); // Turn off fan fanSpeedPercent = 0; fanOnStartTime = 0; } // Send mean; temp1; temp2; fanSpeed% to Processing: Serial.print(meanTemp); Serial.print(';'); Serial.print(temp1); Serial.print(';'); Serial.print(temp2); Serial.print(';'); Serial.println(fanSpeedPercent); // Update the OLED display. display.clearDisplay(); display.setTextSize(2); display.setCursor(0, 0); if (validData) { // First line: Mean temperature with unit Celcius degrees display.print("Mean:"); display.print(meanTemp, 1); display.print("C"); // Second line: Fan status/speed display.setTextSize(2); display.setCursor(0, 35); if (fanOn) { // For the first 2 seconds, display "Fan: ON" if (millis() - fanOnStartTime < 2000) { display.println("Fan: ON"); } else { display.print("Speed:"); //Afterwards show the fan speed percentage display.print(fanSpeedPercent); display.println("%"); } } else { display.println("Fan: OFF"); } } else { display.println("Sensor error"); } display.display(); delay(1000); } // References: // // Adafruit Industries. (2025). Adafruit GFX graphics library. GitHub. // Retrieved March 27, 2025, from https://github.com/adafruit/Adafruit-GFX-Library // // Adafruit Industries. (2025). Adafruit SH110X library. GitHub. // Retrieved March 27, 2025, from https://github.com/adafruit/Adafruit_SH110X // // Arduino. (n.d.). microDS18B20 library. Arduino Library documentation. // Retrieved April 8, 2025, from https://docs.arduino.cc/libraries/microds18b20 // // Arduino. (2025). analogWrite() function. Arduino Documentation. // Retrieved March 29, 2025, from https://docs.arduino.cc/language-reference/en/functions/analog-io/analogWrite // // Wright, J. (2021). microDS18B20 library. GitHub. // Retrieved March 27, 2025, from https://github.com/jwright235/microDS18B20 //