#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <Servo.h>
#include <ezButton.h>
#define HALL_SENSOR_PIN 2
/* Servo motor
* https://arduinogetstarted.com/tutorials/arduino-servo-motor
*/
#define SERVO_PIN 3
/* DC motor control using L298N
* https://arduinogetstarted.com/tutorials/arduino-dc-motor
*/
#define MOTOR_IN1 11
#define MOTOR_IN2 10
#define MOTOR_EN 9
/* ezButton
* https://arduinogetstarted.com/library/button/example/arduino-single-button-all
*/
#define STOP_BUTTON_PIN 8
/* Keypad with LCD
* https://arduinogetstarted.com/tutorials/arduino-keypad-lcd
* LCD A4-A5
* Key pad D2-D9
*/
LiquidCrystal_I2C lcd(0x27, 16, 2); // I2C address 0x27, 16 columns and 2 rows
Servo treatServo;
const byte ROWS = 4; // Four rows
const byte COLS = 4; // Four columns
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {7, 6, 5, 4}; // Connect to the row pinouts of the keypad
byte colPins[COLS] = {A3, A2, A1, A0}; // Connect to the column pinouts of the keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
volatile unsigned int rotationCount = 0;
unsigned int targetRotations = 0;
int motorSpeed = 200; // Speed control (0-255)
bool systemRunning = false;
ezButton stopButton(STOP_BUTTON_PIN); // Create button object for stop button
void setup() {
lcd.init();
lcd.backlight();
treatServo.attach(SERVO_PIN);
treatServo.write(0); // Initial position of the servo
pinMode(MOTOR_IN1, OUTPUT);
pinMode(MOTOR_IN2, OUTPUT);
pinMode(MOTOR_EN, OUTPUT);
stopButton.setDebounceTime(50); // Set debounce time for the stop button
pinMode(HALL_SENSOR_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(HALL_SENSOR_PIN), countRotation, FALLING);
lcd.setCursor(0, 0);
lcd.print("Set Rounds:");
}
void loop() {
stopButton.loop(); // Continuously check the button state
if (!systemRunning) {
// Get the user input for the target rotations
char key = keypad.getKey();
if (key) {
if (key >= '0' && key <= '9') {
targetRotations = targetRotations * 10 + (key - '0');
lcd.setCursor(0, 1);
lcd.print(targetRotations);
} else if (key == '#') {
rotationCount = 0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Target:");
lcd.setCursor(8, 0);
lcd.print(targetRotations);
lcd.setCursor(0, 1);
lcd.print("Rounds:");
lcd.setCursor(8, 1);
lcd.print(rotationCount);
startMotor(); // Start the treadmill DC motor when target is set
systemRunning = true;
}
}
} else {
// Monitor the rotation count and compare with the target
lcd.setCursor(8, 1);
lcd.print(rotationCount);
if (rotationCount >= targetRotations) {
lcd.setCursor(0, 1);
lcd.print("Rounds:");
lcd.setCursor(8, 1);
lcd.print(rotationCount);
delay(500);
dispenseTreat();
rotationCount = 0; // Reset rotation count for the next loop
stopMotor();
resetSystem(); // Reset the system parameters
}
// Check if the stop button is pressed
if (stopButton.isPressed()) {
stopMotor();
resetSystem(); // Reset the system parameters
}
}
}
void clearRow(int row) {
lcd.setCursor(0, row); // Move the cursor to the beginning of the row
for (int i = 0; i < 16; i++) { // Assuming a 16x2 LCD; change 16 to the number of columns for your LCD
lcd.print(" "); // Print spaces to clear the row
}
lcd.setCursor(0, row); // Return cursor to the beginning of the cleared row
}
void countRotation() {
detachInterrupt(digitalPinToInterrupt(HALL_SENSOR_PIN));
rotationCount++;
attachInterrupt(digitalPinToInterrupt(HALL_SENSOR_PIN), countRotation, FALLING);
}
void dispenseTreat() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Dispense Treat...");
treatServo.write(90); // Move servo to dispense treat
delay(1000); // Wait for 1 second
treatServo.write(0); // Move servo back to the initial position
}
void startMotor() {
digitalWrite(MOTOR_IN1, HIGH);
digitalWrite(MOTOR_IN2, LOW);
analogWrite(MOTOR_EN, motorSpeed); // Set motor speed (0-255)
}
void stopMotor() {
digitalWrite(MOTOR_IN1, LOW);
digitalWrite(MOTOR_IN2, LOW);
analogWrite(MOTOR_EN, 0); // Stop the motor
}
void resetSystem() {
targetRotations = 0;
rotationCount = 0;
systemRunning = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Set Rounds:");
}