#include <Wire.h>
#include <DS3231.h>
#include <Servo.h>
//switch on top simulates tank full sensor reading, click on it to change state in simulation
//switch state does nothing as code is setup for water level sensor, left just for visiual and wiring
//green LED is pump
//red LED is HIGH when pump is off
// !!!!! this setup will activate relay regardless of servo motor !!!!!!!
// timer for servo motor is setup/hardcoded in main loop
//Servo object
const int servoPin = 9;
Servo servo;
int angle; // servo position in degrees
int flag1; // flag for motor movement
int lowerThreshold = 280;
int upperThreshold = 350;
// Value for storing water level
int val;
int level;
DateTime dt; // DateTime object from DS3231 library
const int RELAY_PIN = 8; // the Arduino pin, which connects to the IN pin of relay
#define sensorPower 7 //pin for sensor reading (to avoid corrosion, sensor is active only when needed)
#define sensorPin A4 // sensor pin (switch in simulation)
void sensor_lvl()
{
if (level <= 100) {
Serial.println("Water Level: Empty");
digitalWrite(RELAY_PIN, HIGH);
}
else if (level > 100 && level <= lowerThreshold) {
Serial.println("Water Level: Low");
digitalWrite(RELAY_PIN, HIGH);
}
else if (level > lowerThreshold && level <= upperThreshold) {
Serial.println("Water Level: Medium");
digitalWrite(RELAY_PIN, HIGH);
}
else if (level > upperThreshold) {
Serial.println("Water Level: High");
digitalWrite(RELAY_PIN, LOW);
}
delay(1000);
}
void readSensor() {
digitalWrite(sensorPower, HIGH);
delay(10);
val = analogRead(sensorPin);
digitalWrite(sensorPower, LOW);
//return val;
}
//motor movement operation 0->180 and 180->0
void servo_move() {
// scan from 0 to 180 degrees
for (angle = 0; angle < 180; angle++)
{
servo.write(angle);
delay(10); // this delay controlls how fast motor will move, also needed for stability of program
}
// now scan back from 180 to 0 degrees
for (angle = 180; angle > 0; angle--)
{
servo.write(angle);
delay(10); // this delay controlls how fast motor will move, also needed for stability of program
}
}
void serial_display() {//to display time and flag1 in serial in simulation/debug
Serial.print(dt.hour()) ;
Serial.print(":") ;
Serial.print(dt.minute()) ;
Serial.print(":") ;
Serial.print(dt.second()) ;
Serial.print(" / ");
Serial.print("flag1 = ");
Serial.print(flag1);
Serial.print("/ val = ");
Serial.print(val);
Serial.print("\n") ;
//delay(1000);
}
// one time loop run
void setup()
{
flag1 = 0;
Serial.begin(9600); // needed for debuging
Serial.println("Servo World!\n"); // needed for debuging
servo.attach(servoPin);
pinMode(RELAY_PIN, OUTPUT); // initialize relay pin
digitalWrite(RELAY_PIN, HIGH); // without this line NC LED in simulation does not work, have to be tested IRL
digitalWrite(RELAY_PIN, LOW);
pinMode(sensorPower, OUTPUT); // initialize sensor power pin
pinMode(sensorPin, INPUT); // initialize sensor reading pin
digitalWrite(sensorPower, LOW);
// Start the I2C interface
Wire.begin();
//initialize robot for angle 0
servo.write(angle); // this angle can be changed to what ever you need (instead of angle you can use value from 0 to 180)
delay(100);
}
// constant loop
void loop()
{
// time reading and serial output is stopped as long as flag1 is 1 and pump/servo is working
dt = RTClib::now(); // variable dt for actual time, RTCLib::now() is special function to get present time from DS3231
serial_display(); //to display time and flag1 in serial in simulation/debug
readSensor();
level = val;
sensor_lvl();
//flag setup, can be added multiple times, but if time difference between alarms is lower than operation time, second alarm will not activate
if (dt.hour() == 8 && dt.minute() == 0 && dt.second() == 0) // servo_move will delay time update by how long it takes to perform full servo_move, flag1 cannot be "1" for less than that, but trigger is instant
{
flag1 = 1;
}
if (dt.hour() == 19 && dt.minute() == 0 && dt.second() == 0) // second timer, more can be added after this, if needed
{
flag1 = 1;
}
// servo/relay code, added twice, can be adjusted or servo speed can be adjusted by changing delay in servo_move at start of code
if (flag1 == 1) //activate this code only when time is right (setup above)
{
servo_move(); // code outside of void loop, so doesn't have to be twice in code
servo_move();
flag1 = 0; // reset flag to allow set it again in future
}
}