#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Define pin connections and initialize LCD display
const int fanPin = 3; // PWM control pin for fan
const int switch1Pin = 4; // Pin for switch 1 (100%)
const int switch2Pin = 5; // Pin for switch 2 (50%)
const int switch3Pin = 6; // Pin for switch 3 (0%)
const int emergencyStopPin = 7; // Pin for emergency stop switch
const int tachPin = 2; // Pin for tachometer signal
LiquidCrystal_I2C lcd(0x27, 16, 2); // Adjust address and size for your I2C module
// Variable declarations for RPM calculation and debouncing
volatile int rpmCount = 0;
unsigned int rpm = 0;
unsigned long lastRPMCalc = 0;
unsigned long lastDebounceTime1 = 0;
unsigned long lastDebounceTime2 = 0;
unsigned long lastDebounceTime3 = 0;
unsigned long lastDebounceTime4 = 0;
unsigned long debounceDelay = 50;
int fanState = 128; // Start with 50% speed
int lastSwitchState1 = HIGH;
int lastSwitchState2 = HIGH;
int lastSwitchState3 = HIGH;
int lastEmergencyStopState = HIGH;
int currentSwitchState1 = HIGH;
int currentSwitchState2 = HIGH;
int currentSwitchState3 = HIGH;
void rpmInterrupt() {
rpmCount++;
}
void setup() {
// Set pin modes
pinMode(fanPin, OUTPUT);
pinMode(switch1Pin, INPUT_PULLUP);
pinMode(switch2Pin, INPUT_PULLUP);
pinMode(switch3Pin, INPUT_PULLUP);
pinMode(emergencyStopPin, INPUT_PULLUP);
pinMode(tachPin, INPUT_PULLUP);
// Attach interrupt for tachometer
attachInterrupt(digitalPinToInterrupt(tachPin), rpmInterrupt, FALLING);
// Initialize LCD
lcd.init();
lcd.backlight();
// Set initial fan state
analogWrite(fanPin, fanState);
lastRPMCalc = millis();
}
void loop() {
// Read switch states
int reading1 = digitalRead(switch1Pin);
int reading2 = digitalRead(switch2Pin);
int reading3 = digitalRead(switch3Pin);
int emergencyStopReading = digitalRead(emergencyStopPin);
// Handle emergency stop
if (emergencyStopReading != lastEmergencyStopState) {
lastDebounceTime4 = millis();
}
if ((millis() - lastDebounceTime4) > debounceDelay) {
if (emergencyStopReading == LOW) {
setFanSpeed(0); // Immediately stop the fan
displayState("EMERGENCY STOP");
}
}
// Handle switch 1 (100% speed)
if (reading1 != lastSwitchState1) {
lastDebounceTime1 = millis();
}
if ((millis() - lastDebounceTime1) > debounceDelay && emergencyStopReading == HIGH) {
if (reading1 == LOW && currentSwitchState1 == HIGH) {
setFanSpeed(255); // Soft start to 100% speed
displayState("100%");
currentSwitchState1 = LOW;
currentSwitchState2 = HIGH;
currentSwitchState3 = HIGH;
}
}
// Handle switch 2 (50% speed)
if (reading2 != lastSwitchState2) {
lastDebounceTime2 = millis();
}
if ((millis() - lastDebounceTime2) > debounceDelay && emergencyStopReading == HIGH) {
if (reading2 == LOW && currentSwitchState2 == HIGH) {
setFanSpeed(128); // Soft start to 50% speed
displayState("50%");
currentSwitchState1 = HIGH;
currentSwitchState2 = LOW;
currentSwitchState3 = HIGH;
}
}
// Handle switch 3 (0% speed/off)
if (reading3 != lastSwitchState3) {
lastDebounceTime3 = millis();
}
if ((millis() - lastDebounceTime3) > debounceDelay && emergencyStopReading == HIGH) {
if (reading3 == LOW && currentSwitchState3 == HIGH) {
setFanSpeed(0); // Soft start to 0% speed (off)
displayState("OFF");
currentSwitchState1 = HIGH;
currentSwitchState2 = HIGH;
currentSwitchState3 = LOW;
}
}
// Update last states
lastSwitchState1 = reading1;
lastSwitchState2 = reading2;
lastSwitchState3 = reading3;
lastEmergencyStopState = emergencyStopReading;
// Calculate RPM every second
if (millis() - lastRPMCalc >= 1000) {
rpm = (rpmCount * 60) / 4; // Convert to RPM (4 pulses per revolution)
rpmCount = 0;
lastRPMCalc = millis();
displayRPM(rpm);
}
}
void setFanSpeed(int targetSpeed) {
int currentSpeed = analogRead(fanPin); // Read the current PWM value
int step = (targetSpeed > currentSpeed) ? 1 : -1;
while (currentSpeed != targetSpeed) {
currentSpeed += step;
analogWrite(fanPin, currentSpeed);
delay(10); // Adjust delay for smoother or faster transitions
}
}
void displayState(const char* state) {
lcd.setCursor(0, 0);
lcd.print("State: ");
lcd.print(state);
lcd.print(" "); // Clear any remaining characters
}
void displayRPM(unsigned int rpm) {
lcd.setCursor(0, 1);
lcd.print("RPM: ");
lcd.print(rpm);
lcd.print(" "); // Clear any remaining characters
}