#include <Stepper.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
// LCD configuration
#define LCD_ADDRESS 0x27 // I2C address of the LCD
#define LCD_COLUMNS 20 // Number of columns of the LCD
#define LCD_ROWS 4 // Number of rows of the LCD
// Keypad configuration
const byte ROWS = 4; // Number of rows on the keypad
const byte COLS = 4; // Number of columns on the keypad
// Characters on the buttons of the keypad
char hexaKeys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
// Pin configuration for keypad rows and columns
byte rowPins[ROWS] = {2, 3, 4, 5}; // Connect to the row pinouts of the keypad
byte colPins[COLS] = {6, 7, 8, 9}; // Connect to the column pinouts of the keypad
// Create the Keypad
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
// Stepper motor configuration
const int stepPin = 12; // Pin for controlling steps
const int dirPin = 13; // Pin for controlling direction
const int stepsPerMilliliter = 100; // Hypothetical steps required to pump 1 mL
// Global variables
#define LENGTH 3 // Length of the dose input array
char dose[LENGTH]; // Array to store the dose input
int data_count = 0; // Counter for dose input
char customKey; // Variable to store the key pressed
int num = 0; // Variable to store the dose amount
int totalPumped = 0; // Variable to track total volume pumped
String currentDisplay = ""; // Variable to store the current display content
// Create the LCD
LiquidCrystal_I2C lcd(LCD_ADDRESS, LCD_COLUMNS, LCD_ROWS);
// Timing variables for non-blocking delays
unsigned long previousMillis = 0;
const long interval = 500; // Interval for delay
void setup() {
pinMode(stepPin, OUTPUT); // Set the step pin as output
pinMode(dirPin, OUTPUT); // Set the direction pin as output
Serial.begin(9600); // Initialize serial communication
lcd.begin(LCD_COLUMNS, LCD_ROWS); // Initialize the LCD with the given columns and rows
lcd.setCursor(0, 1); // Set cursor position on the LCD
lcd.print("Group B"); // Display "Group B" on the LCD
delay(2000); // Wait for 2 seconds
lcd.clear(); // Clear the LCD
lcd.print("Starting"); // Display "Starting" on the LCD
for (int i = 0; i < 8; i++) { // Loop to display dots
delay(500); // Wait for 500 milliseconds
lcd.print("."); // Display a dot
}
lcd.clear(); // Clear the LCD
lcd.setCursor(0, 0); // Set cursor position
lcd.print("do(ml)"); // Display "do(ml)" on the LCD
lcd.setCursor(0, 1); // Set cursor position
}
void loop() {
customKey = customKeypad.getKey(); // Get the key pressed on the keypad
if (customKey) { // If a key is pressed
dose[data_count] = customKey; // Store the key in the dose array
lcd.print(dose[data_count]); // Display the key on the LCD
Serial.println(dose[data_count]); // Print the key to the serial monitor
Serial.println(data_count); // Print the current data count to the serial monitor
data_count++; // Increment the data count
}
if (data_count == LENGTH - 1) { // If the expected length of input is reached
data_count = 0; // Reset the data count
delay(1000); // Wait for 1 second
updateLCD("dose is "); // Update the LCD with "dose is"
num = (dose[1] - '0') + ((dose[0] - '0') * 10); // Convert the dose input to an integer
updateLCD(String(num) + "mm"); // Update the LCD with the dose amount in mm
delay(4000); // Wait for 4 seconds
totalPumped += num; // Add the dose to the total pumped volume
if (totalPumped > 50) { // If total pumped volume exceeds 50 mL
totalPumped = 50; // Limit the total pumped volume to 50 mL
}
// Stepper motor operation using function
operateStepperMotor(num, LOW); // Pump the volume
if (totalPumped == 50) { // If the total pumped volume reaches 50 mL
delay(5000); // Wait for 5 seconds
operateStepperMotor(totalPumped, HIGH); // Retract the motor
totalPumped = 0; // Reset the total pumped volume
}
lcd.clear(); // Clear the LCD
lcd.begin(LCD_COLUMNS, LCD_ROWS); // Re-initialize the LCD
lcd.print("Starting"); // Display "Starting" on the LCD
for (int i = 0; i < 8; i++) { // Loop to display dots
delay(500); // Wait for 500 milliseconds
lcd.print("."); // Display a dot
}
lcd.clear(); // Clear the LCD
lcd.setCursor(0, 0); // Set cursor position
lcd.print("do(ml)"); // Display "do(ml)" on the LCD
lcd.setCursor(0, 1); // Set cursor position
}
}
void operateStepperMotor(int steps, int direction) {
digitalWrite(dirPin, direction); // Set the direction of the motor
for (int x = 0; x < steps * stepsPerMilliliter; x++) { // Loop to create the required number of steps
digitalWrite(stepPin, HIGH); // Set the step pin high
delayMicroseconds(2000); // Wait for 2 milliseconds
digitalWrite(stepPin, LOW); // Set the step pin low
delayMicroseconds(2000); // Wait for 2 milliseconds
}
}
void updateLCD(String message) {
if (message != currentDisplay) { // If the message is different from the current display
lcd.clear(); // Clear the LCD
lcd.print(message); // Print the new message
currentDisplay = message; // Update the current display variable
}
}