#include <math.h>
#include <IRremote.h>
#include <Stepper.h>
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#define THERMISTOR_ANALOG 34 // Thermistor analog pin
#define RED_LED 2 // Red LED pin
#define GREEN_LED1 25 // Green LED1 pin
#define GREEN_LED2 33 // Green LED2 pin
#define GREEN_LED3 32 // Green LED3 pin
#define IR_RECV 16 // IR Receiver pin
/* Biaxial Stepper Motor Pins */
#define A1_MINUS 23
#define A1_PLUS 15
#define B1_PLUS 19
#define B1_MINUS 18
#define A2_MINUS 5
#define A2_PLUS 17
#define B2_PLUS 4
#define B2_MINUS 0
/* Board Grove OLED SH1107 Pins */
#define SDA 21
#define SCL_1 22
/* Board Grove OLED SH1107 Properties */
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
bool ventPower = 0; // Initial ventilator power on/off state
int speedLevel = 2; // Initial ventilator air speed level
int ventTemp = 18; // Initial ventilator air temperature
/* Steppers' rotation speeds (rpm) */
const int lowSpeed = 1000;
const int mediumSpeed = 2000;
const int highSpeed = 3000;
const int stepsPerRevolution = 200; // Steps per revolution for steppers
IRrecv receiver(IR_RECV);
Stepper frontStepper(stepsPerRevolution, B2_MINUS, B2_PLUS, A2_PLUS, A2_MINUS);
Stepper backStepper(stepsPerRevolution, B1_MINUS, B1_PLUS, A1_PLUS, A1_MINUS);
U8G2_SH1107_128X128_1_HW_I2C u8g2(U8G2_R0);
void setup() {
pinMode(RED_LED, OUTPUT);
pinMode(GREEN_LED1, OUTPUT);
pinMode(GREEN_LED2, OUTPUT);
pinMode(GREEN_LED3, OUTPUT);
receiver.enableIRIn(); // Initialize the IR receiver
/* Initial speeds for ventilator steppers when it's powered on */
frontStepper.setSpeed(mediumSpeed);
backStepper.setSpeed(mediumSpeed);
Serial.begin(115200);
u8g2.begin(); // begin the u8g2 library
u8g2.setContrast(255); // set display contrast/brightness
}
void loop() {
int sensorValue = analogRead(THERMISTOR_ANALOG);
int resistorValue = 10000;
float resistance = resistorValue / ((4095.0 / sensorValue) - 1.0);
// Steinhart-Hart equation
float steinhart;
steinhart = resistance / 10000.0;
steinhart = log(steinhart);
steinhart /= 3950.0;
steinhart += 1.0 / (25.0 + 273.15);
steinhart = 1.0 / steinhart;
// Kelvin to Celsius
float tempC = steinhart - 273.15;
// Celsius to Fahrenheit
float tempF = (tempC * 9.0 / 5.0) + 32.0;
Serial.print("\nVentilator Temperature: ");
Serial.print(tempC);
Serial.print(" °C | ");
Serial.print(tempF);
Serial.println(" °F");
// If ventilator is powered on and its temperature exceeds 40 °C, turn on the RED LED for warning the user
if (ventPower && tempC > 40.0)
digitalWrite(RED_LED, HIGH);
else
digitalWrite(RED_LED, LOW);
/************************/
// Read values from IR receiver
if (receiver.decode()) {
setTempAndSpeed();
receiver.resume(); // Read the next value
}
if (ventPower) {
frontStepper.step(-stepsPerRevolution);
backStepper.step(stepsPerRevolution);
}
else {
frontStepper.step(0);
backStepper.step(0);
}
printTextOLED();
if (!ventPower) { // If ventilator powered off
digitalWrite(GREEN_LED1, LOW);
digitalWrite(GREEN_LED2, LOW);
digitalWrite(GREEN_LED3, LOW);
}
else if (speedLevel == 1) {
digitalWrite(GREEN_LED1, HIGH);
digitalWrite(GREEN_LED2, LOW);
digitalWrite(GREEN_LED3, LOW);
}
else if (speedLevel == 3) {
digitalWrite(GREEN_LED1, HIGH);
digitalWrite(GREEN_LED2, HIGH);
digitalWrite(GREEN_LED3, HIGH);
}
else { // speedLevel == 2
digitalWrite(GREEN_LED1, HIGH);
digitalWrite(GREEN_LED2, HIGH);
digitalWrite(GREEN_LED3, LOW);
}
Serial.print("Ventilator air speed: ");
if (!ventPower)
Serial.println("0 rpm");
else if (speedLevel == 1)
Serial.println("1000 rpm");
else if (speedLevel == 3)
Serial.println("3000 rpm");
else // speedLevel == 2
Serial.println("2000 rpm");
}
void setTempAndSpeed() {
/* If ventilator is powered off, none of the IR Remote's buttons will work except the power button */
if (!ventPower && receiver.decodedIRData.command != 162)
return;
switch (receiver.decodedIRData.command) {
case 162: // Button Power -> Ventilator Power On/Off
ventPower = !ventPower;
break;
case 48: // Button 1 -> Low Ventilator Fan Speed
frontStepper.setSpeed(lowSpeed);
backStepper.setSpeed(lowSpeed);
speedLevel = 1;
break;
case 24: // Button 2 -> Medium Ventilator Fan Speed
frontStepper.setSpeed(mediumSpeed);
backStepper.setSpeed(mediumSpeed);
speedLevel = 2;
break;
case 122: // Button 3 -> High Ventilator Fan Speed
frontStepper.setSpeed(highSpeed);
backStepper.setSpeed(highSpeed);
speedLevel = 3;
break;
case 2: // Button Plus -> Increment Ventilator Air Temperature
if (ventTemp < 30)
ventTemp++;
break;
case 152: // Button Minus -> Decrement Ventilator Air Temperature
if (ventTemp > 18)
ventTemp--;
break;
default:
Serial.println("\nOther button pressed\n");
}
}
void printTextOLED() {
u8g2.firstPage(); // start the first page of the display
do {
u8g2.setFont(u8g2_font_fub49_tn); // set a large font for the number
u8g2.setCursor(25, 96); // set the position to center the number on the display
if (ventPower)
u8g2.print(ventTemp); // print the ventilator air temperature
} while (u8g2.nextPage()); // update all pages of the display
}