//Project 5 kolam ikan
/*
ruang lingkup:
makan ikan sebanyak tiga kali dalam sehari (6,12,18)
monitoring sisa makanan yang telah kita berikan
apakah masih tersedia atau telah habis
*/
#include <WiFi.h> // WiFi control for ESP32
#include "ThingsBoard.h"
#include "RTClib.h"
#include <ESP32Servo.h>
RTC_DS1307 rtc; //default sda(gpio21) scl(gpio22)
#define SERIAL_DEBUG_BAUD 115200
#define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
#define WIFI_AP_NAME "Wokwi-GUEST"
#define WIFI_PASSWORD ""
#define THINGSBOARD_MQTT_SERVER "thingsboard.cloud"
#define THINGSBOARD_MQTT_ACESSTOKEN "juMjv3CUNuA6BY9c7Cuv" // kikanr1
#define THINGSBOARD_MQTT_PORT 1883
#define SERIAL_DEBUG_BAUD 115200
WiFiClient espClient;
ThingsBoard tb(espClient);
int status = WL_IDLE_STATUS;
uint8_t leds_control[] = {27};
// Main application loop delay
int quant = 20;
// Initial period of LED cycling.
int led_delay = 1000;
// Period of sending a temperature/humidity data.
int send_delay = 2000;
// Time passed after LED was turned ON, milliseconds.
int led_passed = 0;
// Time passed after temperature/humidity data was sent, milliseconds.
int send_passed = 0;
// Set to true if application is subscribed for the RPC messages.
bool subscribed = false;
int mhour = 0;
boolean manual = false;
boolean ismulai = false;
int lamamakan = 600;//10 menit * 60 secon lamanya kasih pakan
unsigned long prevmakan = 0;
uint8_t jam[] = {6, 12, 18}; //jam kasih pakan
//uint8_t jam[] = {2, 3, 4};
int iter = 0;
int skrg = 0;
const int echoPin = 32;
const int trigPin = 33;
const int tinggiwadahdsensor = 110; //tinggi kolam 100 + posisi sensor ultrasonik 10
int tinggipakan = 0;
const int servoPin = 13; //servo pwm
Servo myServo;
RPC_Response processDelayChange(const RPC_Data &data)
{
Serial.println("Received the set delay RPC method");
// Process data
led_delay = data;
Serial.print("Set new delay: ");
Serial.println(led_delay);
return String(led_delay);
}
RPC_Response processGetDelay(const RPC_Data &data)
{
Serial.println("Received the get value method");
return String(led_delay);
}
RPC_Response processSetGpioState(const RPC_Data &data)
{
Serial.println("Received the set GPIO RPC method");
int pin = data["pin"];
bool enabled = data["enabled"];
Serial.print("Setting LED ");
Serial.print(pin);
Serial.print(" to state ");
Serial.println(enabled);
digitalWrite(pin, enabled);
if (pin == 27 && enabled == true) {
manual = true;
} else {
manual = false;
}
return String("{\"" + String(pin) + "\": " + String(enabled ? "true" : "false") + "}");
}
RPC_Response processGetGpioState(const RPC_Data &data)
{
Serial.println("Received the get GPIO RPC method");
String respStr = "{";
for (size_t i = 0; i < COUNT_OF(leds_control); ++i) {
int pin = leds_control[i];
Serial.print("Getting LED ");
Serial.print(pin);
Serial.print(" state ");
bool ledState = digitalRead(pin);
Serial.println(ledState);
respStr += String("\"" + String(pin) + "\": " + String(ledState ? "true" : "false") + ", ");
}
respStr = respStr.substring(0, respStr.length() - 2);
respStr += "}";
return respStr;
}
// RPC handlers
RPC_Callback callbacks[] = {
{ "setValue", processDelayChange },
{ "getValue", processGetDelay },
{ "setGpioStatus", processSetGpioState },
{ "getGpioStatus", processGetGpioState },
};
void setup() {
Serial.begin(SERIAL_DEBUG_BAUD);
WiFi.begin(WIFI_AP_NAME, WIFI_PASSWORD);
InitWiFi();
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
abort();
}
if (! rtc.isrunning()) {
Serial.println("RTC is NOT running, let's set the time!");
// When time needs to be set on a new device, or after a power loss, the
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
rtc.adjust(DateTime(2014, 1, 21, 5, 59, 30));
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
//Serial.println(rtc.now().unixtime());
pinMode(27, OUTPUT);
digitalWrite(27, LOW);
myServo.attach(servoPin, 500, 2400);
myServo.write(90);
}
void loop()
{
delay(quant);
led_passed += quant;
send_passed += quant;
// Check if next LED should be lit up
if (led_passed > led_delay) {
led_passed = 0;
}
//distance
float distance = readDistanceCM();
//Serial.println(distance);
tinggipakan = tinggiwadahdsensor - distance;
//Serial.println(tinggipakan);
DateTime time = rtc.now();
mhour = time.hour();
//Serial.println(time.timestamp(DateTime::TIMESTAMP_TIME));
//Serial.println(mhour);
//Logic
if (mhour == jam[iter]) {
iter++;
if (iter >= 3) {
iter = 0;
}
if (tinggipakan > 0) {
ismulai = true;
digitalWrite(27, HIGH);
myServo.write(0);
prevmakan = rtc.now().unixtime();
}
}
if (ismulai) {
//Serial.println("");
//Serial.print("jam :");
//Serial.print(mhour);
skrg = rtc.now().unixtime();
//--skrg = rtc.now().minute() * 60 + rtc.now().second();
//Serial.print(", ");
//Serial.print("stopmakan=");
//Serial.println(skrg - prevmakan);
if (skrg - prevmakan >= lamamakan) {
ismulai = false;
Serial.println("cukup makannya");
prevmakan = skrg;
digitalWrite(27, LOW);
myServo.write(90);
}
}
// Reconnect to WiFi, if needed
if (WiFi.status() != WL_CONNECTED) {
reconnect();
return;
}
// Reconnect to ThingsBoard, if needed
if (!tb.connected()) {
subscribed = false;
// Connect to the ThingsBoard
Serial.print("Connecting MQTT to: ");
Serial.print(THINGSBOARD_MQTT_SERVER);
Serial.print(" at port no. ");
Serial.println(THINGSBOARD_MQTT_PORT);
Serial.print(" with access token ");
Serial.println(THINGSBOARD_MQTT_ACESSTOKEN);
if (!tb.connect(THINGSBOARD_MQTT_SERVER, THINGSBOARD_MQTT_ACESSTOKEN, THINGSBOARD_MQTT_PORT)) {
Serial.println("Failed to connect");
return;
}
}
// Subscribe for RPC, if needed
if (!subscribed) {
Serial.println("Subscribing for RPC... ");
// Perform a subscription. All consequent data processing will happen in
// callbacks as denoted by callbacks[] array.
if (!tb.RPC_Subscribe(callbacks, COUNT_OF(callbacks))) {
Serial.println("Failed to subscribe for RPC");
return;
}
Serial.println("Subscribe done");
subscribed = true;
}
if (send_passed > send_delay) {
Serial.println();
Serial.print("Sending data... ");
tb.sendTelemetryInt("tinggipakan", tinggipakan);
send_passed = 0;
}
tb.loop();
}
void InitWiFi()
{
Serial.println("Connecting to AP ...");
// attempt to connect to WiFi network
WiFi.begin(WIFI_AP_NAME, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(WiFi.localIP());
Serial.println("Connected to AP");
}
void reconnect() {
// Loop until we're reconnected
status = WiFi.status();
if ( status != WL_CONNECTED) {
WiFi.begin(WIFI_AP_NAME, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(WiFi.localIP());
Serial.println("Connected to AP");
}
}
float readDistanceCM() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
int duration = pulseIn(echoPin, HIGH);
return duration * 0.034 / 2;
}