#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_NeoPixel.h>
// Define OLED display dimensions
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
// Define OLED reset pin (or -1 if sharing Arduino reset pin)
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Define potentiometer pins
const int tempSetpointPotPin = A0;
const int hysteresisPotPin = A1;
// Define temperature sensor pin
const int tempSensorPin = A2;
// Define fan output pin
const int fanPin = 9;
// Define NeoPixel ring
#define LED_PIN 6
#define NUM_LEDS 16
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
// Define temperature thresholds
const int temp20CResistance = 2000; // 2K ohm
const int temp4CResistance = 4000; // 4K ohm
// Define potentiometer resistance
const int potResistance = 1200; // 1.2K ohm
// Variables for temperature control
int setpointTemp = 25; // Initial setpoint temperature
int hysteresis = 2; // Initial hysteresis
int currentTemp = 0;
void setup() {
// Initialize serial for debugging
Serial.begin(9600);
// Initialize OLED display
if (!display.begin(0x3c, OLED_RESET)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.display();
delay(2000); // Pause for 2 seconds
display.clearDisplay();
// Set fan pin as output
pinMode(fanPin, OUTPUT);
// Initialize NeoPixel ring
strip.begin();
strip.show(); // Initialize all pixels to 'off'
}
void loop() {
// Read potentiometer values
int tempSetpointReading = analogRead(tempSetpointPotPin);
int hysteresisReading = analogRead(hysteresisPotPin);
// Calculate setpoint temperature based on potentiometer reading
setpointTemp = map(tempSetpointReading, 0, 1023, 4, 25);
// Calculate hysteresis based on potentiometer reading
hysteresis = map(hysteresisReading, 0, 1023, 1, 5);
// Read temperature sensor
int sensorValue = analogRead(tempSensorPin);
// Convert sensor value to resistance
int sensorResistance = map(sensorValue, 0, 1023, 0, 5000);
// Convert resistance to temperature
currentTemp = map(sensorResistance, temp20CResistance, temp4CResistance, 20, 4);
// Display current temperature, setpoint temperature, hysteresis, and fan status on OLED
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print("Temp: ");
display.print(currentTemp);
display.print("C");
display.setCursor(0, 10);
display.print("Setpoint: ");
display.print(setpointTemp);
display.print("C");
display.setCursor(0, 20);
display.print("Hysteresis: ");
display.print(hysteresis);
display.print("C");
// Check if temperature is above setpoint + hysteresis
if (currentTemp > setpointTemp + hysteresis) {
digitalWrite(fanPin, HIGH); // Turn on fan
display.setCursor(0, 30);
display.print("Fan: ON ");
} else if (currentTemp < setpointTemp) {
digitalWrite(fanPin, LOW); // Turn off fan
display.setCursor(0, 30);
display.print("Fan: OFF");
}
// Update NeoPixel color based on temperature
updateNeoPixelColor(currentTemp, setpointTemp);
display.display();
delay(1000); // Update every second
}
void updateNeoPixelColor(int currentTemp, int setpointTemp) {
uint32_t color;
if (currentTemp < setpointTemp) {
// Blend from blue to green
color = blendColor(strip.Color(0, 0, 255), strip.Color(0, 255, 0), map(currentTemp, setpointTemp - hysteresis, setpointTemp, 0, 255));
} else {
// Blend from green to red
color = blendColor(strip.Color(0, 255, 0), strip.Color(255, 0, 0), map(currentTemp, setpointTemp, setpointTemp + hysteresis, 0, 255));
}
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, color);
}
strip.show();
}
uint32_t blendColor(uint32_t color1, uint32_t color2, uint8_t blend) {
uint8_t r1 = (color1 >> 16) & 0xFF;
uint8_t g1 = (color1 >> 8) & 0xFF;
uint8_t b1 = color1 & 0xFF;
uint8_t r2 = (color2 >> 16) & 0xFF;
uint8_t g2 = (color2 >> 8) & 0xFF;
uint8_t b2 = color2 & 0xFF;
uint8_t r = (r1 * (255 - blend) + r2 * blend) / 255;
uint8_t g = (g1 * (255 - blend) + g2 * blend) / 255;
uint8_t b = (b1 * (255 - blend) + b2 * blend) / 255;
return strip.Color(r, g, b);
}