// Servo Sweep example for the ESP32
// https://wokwi.com/arduino/projects/323706614646309460
#include <ESP32Servo.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <RTClib.h>
#include <pitches.h>
#include <ezButton.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
RTC_DS1307 rtc;
int melody[] = {
NOTE_B4, NOTE_B5, NOTE_FS5, NOTE_DS5,
NOTE_B5, NOTE_FS5, NOTE_DS5, NOTE_C5,
NOTE_C6, NOTE_G6, NOTE_E6, NOTE_C6, NOTE_G6, NOTE_E6,
};
int durations[] = {
16, 16, 16, 16,
32, 16, 8, 16,
16, 16, 16, 32, 16, 8,
};
unsigned long previousMillis;
unsigned long interval = 60000; // 10 or 20 milliseconds are common values
unsigned long mpreviousMillis;
const unsigned long minterval = 60000; // 1 minute
unsigned long dpreviousMillis;
const unsigned long dinterval = 86400000; // 1 day
unsigned long presssetupMillis;
const unsigned long pinterval = 5000; // 5 second
unsigned long lastDebounceTime_Act = 0; // the last time the output pin was toggled
unsigned long debounceDelay_Act = 5000; // the debounce time; increase if the output
int buttonState_Act; // the current reading from the input pin
int lastButtonState_Act = LOW; // the previous reading from the input pin
//wokwi pin
const int maxround = 10;
const int servoPin = 32;
const int swactpin = 19;
const int swuppin = 16;
const int swdownpin = 4;
const int swmodepin = 2;
const int ledservo = 14;
const int ledir = 12;
const int irpin = 35;
const int buzzerpin = 15;
boolean setupatime = false;
/* arduino pin
const int maxround = 10;
const int servoPin = 5;
const int swactpin = 13;
const int swuppin = 27;
const int swdownpin = 14;
const int swmodepin = 12;
const int ledservo = 15;
const int ledir = 17;
const int irpin = 35;
const int buzzerpin = 33;
boolean setupatime = false;*/
Servo servo;
int step = 0;
int pos = 0;
int numround = 0;
int curround;
int mode;
int swone;
int swup;
int swdown;
//Time of Auto mode
int curtime = 1;
int maxtime =60;
//button press
const int SHORT_PRESS_TIME = 2000; // 1000 milliseconds
const int LONG_PRESS_TIME = 4000; // 1000 milliseconds
ezButton buttonact(swactpin); // create ezButton object that attach to pin 2;
ezButton buttonup(swuppin);
ezButton buttondown(swdownpin);
unsigned long pressedTime = 0;
unsigned long releasedTime = 0;
bool isPressing = false;
bool isLongDetected = false;
void setup() {
Serial.begin(9600);
//button press
buttonact.setDebounceTime(50); // set debounce time to 50 milliseconds
buttonup.setDebounceTime(50);
buttondown.setDebounceTime(50);
//
//pinMode(swactpin, INPUT_PULLUP);
pinMode(swmodepin, INPUT_PULLUP);
//pinMode(swuppin, INPUT_PULLUP);
//pinMode(swdownpin, INPUT_PULLUP);
pinMode(irpin, OUTPUT);
pinMode(ledservo, OUTPUT);
pinMode(ledir, OUTPUT);
pinMode(buzzerpin, OUTPUT);
servo.attach(servoPin, 500, 2400);
lcd.init();
lcd.backlight();
rtc.begin();
displayDate();
displayTime();
//servo.write(pos);
curround = 5;
lcd.setCursor(0, 0);
lcd.print("DD167");
interval = curtime*60000;
//Check feed food
int val = digitalRead(irpin); //อ่านค่าสัญญาณ digital
Serial.print("val = "); // พิมพ์ข้อมความส่งเข้าคอมพิวเตอร์ "val = "
Serial.println(val); // พิมพ์ค่าของตัวแปร val
if (val == 1) { // ค่า เป็น 0 ตรวจจับเจอวัตถุ สั่งให้ไฟ LED ติด
lcd.setCursor(2, 3);
lcd.print("FISH FOOD EMPTY");
tone(buzzerpin, NOTE_B4, 80);
digitalWrite(ledir, HIGH);
delay(100);
}
}// end setup
void loop() {
buttonact.loop(); // MUST call the loop() function first
buttonup.loop();
buttondown.loop();
mode = digitalRead(swmodepin);
issetupatime();
if (setupatime == false) {
if ((mode == 0) and (setupatime == false)) {
lcd.setCursor(0, 1);
lcd.print("Manual: ");
lcd.print(curround);
lcd.print(" ");
lcd.print("Round ");
swone = digitalRead(swactpin);
if ( swone == LOW) {
numround = 1;
//presssetupMillis = millis();
//presssetup();
//debounceswt_Act();
}
else {
previousMillis = millis();
swone = HIGH;
numround = 0;
}
//
//
}
//swup
swup = digitalRead(swuppin);
if ((swup == 0) and (curround < maxround) and (setupatime == false)) {
curround++;
lcd.setCursor(8, 1);
lcd.print(curround);
lcd.print(" ");
lcd.print("Round ");
Serial.print("swup ");
Serial.print(swup);
Serial.print("curround ");
Serial.println(curround);
}
//swdown
swdown = digitalRead(swdownpin);
if ((swdown == 0) and (curround > 1) and (setupatime == false)) {
curround--;
lcd.setCursor(8, 1);
lcd.print(curround);
lcd.print(" ");
lcd.print("Round ");
Serial.print("swdown ");
Serial.print(swdown);
Serial.print("curround ");
Serial.println(curround);
}
if (mode == 0 and numround == 1 and setupatime == false) {//manual
//lcd.setCursor(3, 1);
//lcd.print("Servo Move");
numround = numround + 1;
servomove();
lcd.setCursor(3, 2);
lcd.print(" ");
}
else if (mode == 1 and setupatime == false) {//auto
lcd.setCursor(0, 1);
lcd.print("Auto : ");
lcd.print(curround);
lcd.print(" ");
lcd.print("Round ");
if (interval < 60000) {
//lcd.setCursor(3, 1);
// lcd.print("Servo Move");
}
else {
lcd.setCursor(3, 2);
int nummin = interval / 60000;
if (nummin < 10) {
lcd.print("Wait ");
lcd.print(nummin);
lcd.print(" ");
}
else {
lcd.print("Wait ");
lcd.print(nummin);
}
lcd.print("min ");
}
automode();
numround = 0;
lcd.setCursor(3, 2);
lcd.print(" ");
}
}
else if (setupatime == true) {
setupautotime();
}
displayDate();
displayTime();
} //end loop
void issetupatime(){
if(buttonact.isPressed()){
pressedTime = millis();
isPressing = true;
isLongDetected = false;
}
if(buttonact.isReleased()) {
isPressing = false;
releasedTime = millis();
long pressDuration = releasedTime - pressedTime;
// if( pressDuration < SHORT_PRESS_TIME )
// Serial.println("A short press is detected");
}
if(isPressing == true && isLongDetected == false) {
long pressDuration = millis() - pressedTime;
if( pressDuration > LONG_PRESS_TIME ) {
Serial.println("A long press is detected");
isLongDetected = true;
setupatime != setupatime;
}
}
}//end issetupatime
void packmansound(){
int size = sizeof(durations) / sizeof(int);
for (int note = 0; note < size; note++) {
//to calculate the note duration, take one second divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int duration = 1000 / durations[note];
tone(buzzerpin, melody[note], duration);
//to distinguish the notes, set a minimum time between them.
//the note's duration + 30% seems to work well:
int pauseBetweenNotes = duration * 1.30;
delay(pauseBetweenNotes);
//stop the tone playing:
noTone(buzzerpin);
}
}
void displayDate() {
DateTime now = rtc.now();
lcd.setCursor(6, 0);
if (now.day() > 9) {
lcd.print(now.day(), DEC);
} else {
lcd.print("0");
lcd.print(now.day(), DEC);
}
lcd.print("/");
if (now.month() > 9) {
lcd.print(now.month(), DEC);
} else {
lcd.print("0");
lcd.print(now.month(), DEC);
}
lcd.print("/");
int dyear = now.year() - 2000;
if (dyear > 9) {
lcd.print(dyear, DEC);
} else {
lcd.print("0");
lcd.print(dyear, DEC);
}
}//end displayDate
void displayTime() {
DateTime now = rtc.now();
lcd.setCursor(15, 0);
if (now.hour() > 9) {
lcd.print(now.hour(), DEC);
} else {
lcd.print("0");
lcd.print(now.hour(), DEC);
}
lcd.print(":");
if (now.minute() > 9) {
lcd.print(now.minute(), DEC);
} else {
lcd.print("0");
lcd.print(now.minute(), DEC);
}
}//end displaytime
void displayFTen(int col, int row, int inputnum, int count) {
lcd.setCursor(col, row);
for (int i = 0; i < count; i++) {
if (inputnum < 10) {
lcd.print(" ");
lcd.print(inputnum);
}
else if ((inputnum > 10) || (inputnum < 100)) {
lcd.print(inputnum);
}
}
}
void servomove() {
//Check feed food
int val = digitalRead(irpin); //อ่านค่าสัญญาณ digital ขา8 ที่ต่อกับ เซ็นเซอร์ตรวจจับวัตถุ IR Infrared
Serial.print("val = "); // พิมพ์ข้อมความส่งเข้าคอมพิวเตอร์ "val = "
Serial.println(val); // พิมพ์ค่าของตัวแปร val
if (val == 1) { // ค่า เป็น 0 ตรวจจับเจอวัตถุ สั่งให้ไฟ LED ติด
lcd.setCursor(2, 3);
lcd.print("FISH FOOD EMPTY");
tone(buzzerpin, NOTE_B4, 80);
digitalWrite(ledir, HIGH);
delay(100);
}
else {
lcd.setCursor(0, 3);
lcd.print(" ");
digitalWrite(ledir, LOW);
}
//End check food
digitalWrite(ledservo, HIGH);
for (int nmove = curround ; nmove >= 1; nmove--) { //number for move
lcd.setCursor(3, 2);
lcd.print("Servo Move ");
lcd.print(nmove);
lcd.print(" ");
Serial.print("nmove ");
Serial.println(nmove);
for (pos = 0; pos <= 180; pos += 1) {
servo.write(pos);
delay(15);
}
for (pos = 180; pos >= 0; pos -= 1) {
servo.write(pos);
delay(15);
}
}
digitalWrite(ledservo, LOW);
}
void automode() {
unsigned long currentMillis = millis();
if ( currentMillis - previousMillis >= interval)
{
previousMillis = currentMillis;
if (mode == 1) {//auto
servomove();
numround = 0;
}
}
}
void presssetup() {
unsigned long pcurrentMillis = millis();
if ( pcurrentMillis - presssetupMillis >= pinterval)
{
presssetupMillis = pcurrentMillis;
setupatime != setupatime;
tone(buzzerpin, NOTE_B4, 60);
setupautotime();
Serial.print("setupatime ");
Serial.println(setupatime);
if (setupatime == false) {
lcd.setCursor(0,4);
lcd.print(" ");
interval = curtime*6000;
}
}
}
void debounceswt_Act() {
// read the state of the switch into a local variable:
int reading_Act = digitalRead(swactpin);
// check to see if you just pressed the button
if (reading_Act != lastButtonState_Act) {
// reset the debouncing timer
lastDebounceTime_Act = millis();
}
if ((millis() - lastDebounceTime_Act) > debounceDelay_Act) {
// if the button state has changed:
if (reading_Act != buttonState_Act) {
buttonState_Act = reading_Act;
setupatime != setupatime;
tone(buzzerpin, NOTE_B4, 60);
// only toggle the LED if the new button state is HIGH
// if (buttonState_Light == HIGH) {
// lightSwitchState = !lightSwitchState;
// }
}
}
// set the LED:
//digitalWrite(RELAY_LIGHT, lightSwitchState);
// save the reading. Next time through the loop,
setupautotime();
lastButtonState_Act = reading_Act;
}//endfunction
void setupautotime(){
if (setupatime == true) {
lcd.setCursor(0,4);
lcd.print("Set auto time");
Serial.print("setupatime ");
Serial.println(setupatime);
//swup
swup = digitalRead(swuppin);
if ((swup == 0) and (curtime < maxtime) and (setupatime == true)) {
curtime++;
lcd.setCursor(13, 4);
lcd.print(curtime);
lcd.print(" ");
lcd.print("Min");
Serial.print("swup ");
Serial.print(swup);
Serial.print("curtime ");
Serial.println(curtime);
}
//swdown
swdown = digitalRead(swdownpin);
if ((swdown == 0) and (curtime > 1) and (setupatime == true)) {
curtime--;
lcd.setCursor(13, 4);
lcd.print(curtime);
lcd.print(" ");
lcd.print("Min ");
Serial.print("swdown ");
Serial.print(swdown);
Serial.print("curtime ");
Serial.println(curtime);
}
}
}//end setupautotime
void minutemillis() {
unsigned long mcurrentMillis = millis();
if ( mcurrentMillis - mpreviousMillis >= minterval)
{
mpreviousMillis = mcurrentMillis;
displayTime();
}
}
void datemillis() {
unsigned long dcurrentMillis = millis();
if ( dcurrentMillis - dpreviousMillis >= dinterval)
{
dpreviousMillis = dcurrentMillis;
displayDate();
}
}