// Hysteresis: https://en.wikipedia.org/wiki/Hysteresis
// Schmitt Trigger: https://en.wikipedia.org/wiki/Schmitt_trigger
// analogRead: https://www.arduino.cc/reference/en/language/functions/analog-io/analogread/
// analogWrite: https://docs.arduino.cc/learn/microcontrollers/analog-output/
// map: https://www.arduino.cc/reference/en/language/functions/math/map/
// Thermistor: https://docs.wokwi.com/parts/wokwi-ntc-temperature-sensor
// Pins for hysteresis control
// for setting the range location
#define LOCATION_POTENTIOMETER_PIN A1
// for measured parameter
#define THERMISTOR_PIN A2
// for signal outpu
#define RELAY_PIN 8
// Pins for open loop control
// controled LED
#define LED_PIN 5
// controller
#define LED_POTENTIOMETER_PIN A0
// I2C LCD
#define LCD_ADDRESS 0x27
#define LCD_COLUMNS 16
#define LCD_ROWS 2
#define LOOP_DELAY 100
// Extremities for the hysteresis
#define HYSTERESIS_MIN 0
#define HYSTERESIS_MAX 100
// Size of hysteresis range
#define HYSTERESIS_RANGE 5
#include <LCD_I2C.h>
LCD_I2C lcd(LCD_ADDRESS, LCD_COLUMNS, LCD_ROWS);
// To check if the temperature has reached the low point
bool reachedLow = true;
// Data variables
int midPointLocation;
int tempCelsius;
int getMidPoint(){
// Get the analog value of the potentiometer
int potentiometerValue = analogRead(LOCATION_POTENTIOMETER_PIN);
// Map the potentiometer value between min and max values for the hysteresis
int midPoint = map(potentiometerValue, 0, 1023, HYSTERESIS_MIN, HYSTERESIS_MAX);
return midPoint;
}
int getThermistorCelsius(){
// Get the analog value of the thermistor reading
int reading = analogRead(THERMISTOR_PIN);
// Convert analog value to celsius
int celsius = (1 / (log(1 / (1023. / reading - 1)) / 3950 + 1.0 / 298.15) - 273.15);
return celsius;
}
void setup(){
// Pin setup
pinMode(LOCATION_POTENTIOMETER_PIN, INPUT);
pinMode(THERMISTOR_PIN, INPUT);
pinMode(RELAY_PIN, OUTPUT);
pinMode(LED_PIN, OUTPUT);
pinMode(LED_POTENTIOMETER_PIN, INPUT);
// LCD Setup
lcd.begin();
// Initial data
midPointLocation = getMidPoint();
tempCelsius = getThermistorCelsius();
// Print initial data to LCD
lcd.print(midPointLocation - HYSTERESIS_RANGE);
lcd.print(" - ");
lcd.print(midPointLocation + HYSTERESIS_RANGE);
lcd.setCursor(0, 1);
lcd.print("Temp: ");
lcd.print(tempCelsius);
lcd.print(" C");
}
void loop(){
// Hysteresis check and write
// Get data as local variables
int midPoint = getMidPoint();
int celsius = getThermistorCelsius();
// If data has changed, update the LCD
if(midPoint != midPointLocation){
midPointLocation = midPoint;
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print(midPointLocation - HYSTERESIS_RANGE);
lcd.print(" - ");
lcd.print(midPointLocation + HYSTERESIS_RANGE);
}
// If data has changed, update the LCD
if(celsius != tempCelsius){
tempCelsius = celsius;
lcd.setCursor(6, 1);
lcd.print(" ");
lcd.setCursor(6, 1);
lcd.print(tempCelsius);
lcd.print(" C");
}
// Hysteresis logic
if(tempCelsius > midPointLocation - HYSTERESIS_RANGE && tempCelsius < midPointLocation + HYSTERESIS_RANGE){
// If the temperature is within the range
if(reachedLow){
// If the temperature has reached the low point turn on the LED
digitalWrite(RELAY_PIN, HIGH);
}else{
// If the temperature has not reached the low point turn off the LED
digitalWrite(RELAY_PIN, LOW);
}
}else if(tempCelsius <= midPointLocation - HYSTERESIS_RANGE){
// If the temperature is below the range turn on the LED and set the reachedLow flag
digitalWrite(RELAY_PIN, HIGH);
reachedLow = true;
}else if(celsius >= midPointLocation + HYSTERESIS_RANGE){
// If the temperature is above the range turn off the LED and reset the reachedLow flag
digitalWrite(RELAY_PIN, LOW);
reachedLow = false;
}
// LED open loop check and write
// Get the analog value of the potentiometer
int ledPotentiometerValue = analogRead(LED_POTENTIOMETER_PIN);
// Map the analog value of the potentiometer to valid PWM range
int ledPWM = map(ledPotentiometerValue, 0, 1023, 0, 255);
// Send PWM signal to the led
analogWrite(LED_PIN, ledPWM);
delay(LOOP_DELAY);
}