#include <Wire.h>
#include <LiquidCrystal_I2C.h> // Include the library for the LCD display
// Initialize the LCD (for I2C address 0x27, adjust based on your hardware)
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Define pins
const int irSensorPin = 2; // IR sensor pin for cartridge detection
const int buttonPin = 3; // Push button pin to start the process
const int solenoidValveIN1 = 4; // IN1 pin for solenoid valve control via L298N
const int solenoidValveIN2 = 5; // IN2 pin for solenoid valve control via L298N
const int vacuumPumpIN1 = 6; // IN1 pin for vacuum pump control via L298N
const int vacuumPumpIN2 = 7; // IN2 pin for vacuum pump control via L298N
const int vacuumPumpEN = 8; // Enable pin for vacuum pump
// Peristaltic pumps for channels 3, 4, 5
const int pump3IN1 = 9;
const int pump3IN2 = 10;
const int pump4IN1 = 11;
const int pump4IN2 = 12;
const int pump5IN1 = 13;
const int pump5IN2 = 14;
// Global variables for pump control
int pumpPWM3 = 128; // PWM value for pump on Channel 3
int pumpPWM4 = 150; // PWM value for pump on Channel 4
int pumpPWM5 = 180; // PWM value for pump on Channel 5
// Tunable time intervals (in milliseconds)
int forwardTime3 = 3000; // Forward time for pump on Channel 3
int forwardTime4 = 4000; // Forward time for pump on Channel 4
int forwardTime5 = 5000; // Forward time for pump on Channel 5
int backAndForthTime = 2000; // Time for each forward and backward motion during back-and-forth mixing
void setup() {
// Initialize serial communication
Serial.begin(9600);
// Initialize the LCD
lcd.begin(16, 2);
lcd.backlight(); // Turn on the backlight
// Set up IR sensor, button, and L298N control pins
pinMode(irSensorPin, INPUT);
pinMode(buttonPin, INPUT_PULLUP); // Use internal pull-up resistor for the button
// L298N Pins Setup
pinMode(solenoidValveIN1, OUTPUT);
pinMode(solenoidValveIN2, OUTPUT);
pinMode(vacuumPumpIN1, OUTPUT);
pinMode(vacuumPumpIN2, OUTPUT);
pinMode(vacuumPumpEN, OUTPUT);
// Peristaltic pump pins setup
pinMode(pump3IN1, OUTPUT);
pinMode(pump3IN2, OUTPUT);
pinMode(pump4IN1, OUTPUT);
pinMode(pump4IN2, OUTPUT);
pinMode(pump5IN1, OUTPUT);
pinMode(pump5IN2, OUTPUT);
// Initialize L298N outputs
digitalWrite(solenoidValveIN1, LOW);
digitalWrite(solenoidValveIN2, LOW);
digitalWrite(vacuumPumpIN1, LOW);
digitalWrite(vacuumPumpIN2, LOW);
analogWrite(vacuumPumpEN, 0); // Ensure the pump is off initially
// Display welcome message
lcd.setCursor(0, 0);
lcd.print("Biofluid System");
delay(2000); // Wait for 2 seconds before proceeding
}
void loop() {
// Check if the cartridge is loaded using the IR sensor
bool cartridgeDetected = digitalRead(irSensorPin);
if (cartridgeDetected == HIGH) { // Assuming HIGH means cartridge is loaded
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Cartridge Loaded");
lcd.setCursor(0, 1);
lcd.print("Load Sample");
Serial.println("Cartridge detected. Waiting for user to press start...");
// Wait for the user to press the push button to start
waitForButtonPress();
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("No Cartridge");
lcd.setCursor(0, 1);
lcd.print("Detected");
Serial.println("No cartridge detected. Please load the cartridge.");
delay(1000); // Wait and check again after 1 second
}
}
void waitForButtonPress() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Press Start Button");
// Loop until the button is pressed
while (digitalRead(buttonPin) == HIGH) {
// Button not pressed, do nothing
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Starting Process");
Serial.println("Button pressed. Starting the biofluid process...");
// Open the solenoid valve for the sample
digitalWrite(solenoidValveIN1, HIGH); // Activate solenoid valve
digitalWrite(solenoidValveIN2, LOW);
delay(1000); // Keep the valve open for 1 second to ensure it's fully open
// Activate the vacuum pump
activateVacuumPump();
// After the process, close the solenoid valve
digitalWrite(solenoidValveIN1, LOW); // Deactivate solenoid valve
digitalWrite(solenoidValveIN2, LOW); // Ensure both pins are LOW
Serial.println("Process completed.");
// Proceed with the next steps of your process
startMixingProcess();
}
void activateVacuumPump() {
digitalWrite(vacuumPumpIN1, HIGH); // Set direction
digitalWrite(vacuumPumpIN2, LOW); // Ensure correct direction
analogWrite(vacuumPumpEN, pumpPWM3); // Set the PWM value
delay(3000); // Run for 3 seconds
analogWrite(vacuumPumpEN, 0); // Turn off the pump
digitalWrite(vacuumPumpIN1, LOW); // Set direction
digitalWrite(vacuumPumpIN2, LOW); // Ensure correct direction
}
// Function to control the forward movement of pumps one by one
void startMixingProcess() {
Serial.println("Starting forward movement for all channels...");
// Move each pump forward one by one with tunable time intervals
movePumpForward(3, pump3IN1, pump3IN2, pumpPWM3, forwardTime3);
movePumpForward(4, pump4IN1, pump4IN2, pumpPWM4, forwardTime4);
movePumpForward(5, pump5IN1, pump5IN2, pumpPWM5, forwardTime5);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Mixing Fluid");
Serial.println("Mixing fluid forward process completed.");
delay(1000); // Short delay before starting back-and-forth mixing
// Now perform the back-and-forth movement
startBackAndForthMixing();
}
void movePumpForward(int channel, int pumpIN1, int pumpIN2, int pumpPWM, int forwardTime) {
// Forward movement
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Channel ");
lcd.print(channel);
lcd.setCursor(0, 1);
lcd.print("Forward Motion");
Serial.print("Channel ");
Serial.print(channel);
Serial.println(" Forward");
// Open solenoid valve SV1 (open to air)
digitalWrite(solenoidValveIN1, HIGH); // Activate solenoid valve to keep it open to air
digitalWrite(solenoidValveIN2, LOW); // Set correct direction
analogWrite(pumpIN1, pumpPWM); // Apply PWM for forward movement
digitalWrite(pumpIN2, LOW); // Ensure backward pin is LOW
delay(forwardTime); // Run pump forward for the specified time interval
// Stop the pump
digitalWrite(pumpIN1, LOW);
digitalWrite(pumpIN2, LOW);
delay(500); // Pause for a moment
}
// Function for back-and-forth movement for a tunable time period
void startBackAndForthMixing() {
Serial.println("Starting back-and-forth mixing process...");
// Open solenoid valve SV1 (open to air)
digitalWrite(solenoidValveIN1, HIGH); // Activate solenoid valve to keep it open to air
digitalWrite(solenoidValveIN2, LOW); // Set correct direction
// Back-and-forth movement for each channel
performBackAndForth(3, pump3IN1, pump3IN2, pumpPWM3, backAndForthTime);
performBackAndForth(4, pump4IN1, pump4IN2, pumpPWM4, backAndForthTime);
performBackAndForth(5, pump5IN1, pump5IN2, pumpPWM5, backAndForthTime);
// Close solenoid valve SV1 after mixing for channel 5 is done
digitalWrite(solenoidValveIN1, LOW); // Deactivate solenoid valve (closed)
digitalWrite(solenoidValveIN2, LOW); // Ensure both pins are LOW
Serial.println("Back-and-forth mixing process completed and SV1 closed.");
}
void performBackAndForth(int channel, int pumpIN1, int pumpIN2, int pumpPWM, int mixingTime) {
// Forward movement
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Channel ");
lcd.print(channel);
lcd.setCursor(0, 1);
lcd.print("Pump Forward");
Serial.print("Channel ");
Serial.print(channel);
Serial.println(" Forward");
digitalWrite(pumpIN1, HIGH); // Move forward
digitalWrite(pumpIN2, LOW);
delay(mixingTime); // Tunable forward mixing time
// Reverse movement
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Channel ");
lcd.print(channel);
lcd.setCursor(0, 1);
lcd.print("Pump Reverse");
Serial.print("Channel ");
Serial.print(channel);
Serial.println(" Reverse");
digitalWrite(pumpIN1, LOW); // Move backward
digitalWrite(pumpIN2, HIGH);
delay(mixingTime); // Tunable backward mixing time
// Stop pump after back-and-forth motion
digitalWrite(pumpIN1, LOW);
digitalWrite(pumpIN2, LOW);
}