#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "time.h"
#include <WiFi.h>
#include <PubSubClient.h>
WiFiClient espClient;
PubSubClient client(espClient);
#include "DHT.h"
#define NTP_SERVER "pool.ntp.org"
#define gmtOffset_sec 7 * 3600 //offset in second
#define daylightOffset_sec 0 //offset in second
#define DHTTYPE DHT22
#define DHTPIN 13
DHT dht(DHTPIN, DHTTYPE);
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
//global variabel untuk membuat tulisan rata tengah
byte panjang, lebar;
int16_t x, y;
uint16_t w, h;
const int LED_PIN = 12;
const char* WIFI_NAME = "Wokwi-GUEST";
const char* WIFI_PASSWORD = "";
const char* mqtt_server = "test.mosquitto.org";// mosquitto server url
//pin sensor ultrasonik
byte trigPin1 = 17; // pin trigger
byte echoPin1 = 16; // pin echo
#define soundSpeed 0.034 //mengkonversi waktu untuk mendapatkan jarak
//#define digunakan untuk membuat sebuah konstanta
float jarakcm1, humidity, temperature;
bool statusSwitch;
byte pinSwitch = 12;
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}}
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
String clientId = "ESP32Client-";
clientId += String(random(0xffff), HEX);
if (client.connect(clientId.c_str())) {
Serial.println("Connected");
client.publish("/ThinkIOT/Publish", "Welcome");
client.subscribe("/ThinkIOT/Subscribe");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}}
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(pinSwitch, INPUT_PULLUP);
pinMode(trigPin1,OUTPUT);
pinMode(echoPin1,INPUT);
Serial.println("ESP32 Wokwi Monitoring Send Data to Ubidots");
display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE); // Draw white text
display.getTextBounds("ESP32", 0, 0, &x, &y, &w, &h); //untuk mendapatkan jumlah piksel dalam lebar dan tinggi untuk tulisan WELCOME
panjang = (SCREEN_WIDTH - w) / 2; // Untuk menentukan penempatan piksel pertama
display.setCursor(panjang, 0); // kursor diletakkan pada rata tengah kolom 0
display.print("ESP32");
display.display();
delay(500);
display.getTextBounds("MONITORING", 0, 0, &x, &y, &w, &h); //untuk mendapatkan jumlah piksel dalam lebar dan tinggi untuk tulisan WELCOME
panjang = (SCREEN_WIDTH - w) / 2; // Untuk menentukan penempatan piksel pertama
display.setCursor(panjang, 20); // kursor diletakkan pada rata tengah kolom 0
display.print("MONITORING");
display.display();
delay(500);
display.getTextBounds("Node-RED", 0, 0, &x, &y, &w, &h); //untuk mendapatkan jumlah piksel dalam lebar dan tinggi untuk tulisan WELCOME
panjang = (SCREEN_WIDTH - w) / 2; // Untuk menentukan penempatan piksel pertama
display.setCursor(panjang, 40); // kursor diletakkan pada rata tengah kolom 0
display.print("Node-RED");
display.display();
delay(2000);
//init DHT22
dht.begin();
display.clearDisplay();
display.getTextBounds("CHECK WIFI", 0, 0, &x, &y, &w, &h); //untuk mendapatkan jumlah piksel dalam lebar dan tinggi untuk tulisan WELCOME
panjang = (SCREEN_WIDTH - w) / 2; // Untuk menentukan penempatan piksel pertama
display.setCursor(panjang, 0); // kursor diletakkan pada rata tengah kolom 0
display.print("CHECK WIFI");
display.display();
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_NAME, WIFI_PASSWORD);
unsigned long waktu = 0;
while (WiFi.status() != WL_CONNECTED && waktu < 30000) {
delay(250);
Serial.println("Wifi not connected");
waktu = millis();
}
display.getTextBounds("Connected!", 0, 0, &x, &y, &w, &h); //untuk mendapatkan jumlah piksel dalam lebar dan tinggi untuk tulisan WELCOME
panjang = (SCREEN_WIDTH - w) / 2; // Untuk menentukan penempatan piksel pertama
display.setCursor(panjang, 30); // kursor diletakkan pada rata tengah kolom 0
display.print("Connected!");
display.display();
Serial.println("Wifi connected !");
Serial.println("Local IP: " + String(WiFi.localIP()));
//get time data from NTP
configTime(gmtOffset_sec, daylightOffset_sec, NTP_SERVER);
struct tm timeinfo;
getLocalTime(&timeinfo);
delay(2000);
//reset font size
display.clearDisplay();
display.setTextSize(1);
//make default display for monitor
display.setCursor(0, 20);
display.print("Temp");
display.setCursor(0, 35);
display.print("Humid");
display.setCursor(0, 50);
display.print("Dist");
display.setCursor(30, 20);
display.print(":");
display.setCursor(30, 35);
display.print(":");
display.setCursor(30, 50);
display.print(":");
display.display();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
printLocalTime();
//getData
getDistance();
getDataDHT();
statusSwitch = digitalRead(pinSwitch);
//display data
displayData();
sendData();
delay(5000);
}
void printLocalTime() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
return;
}
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
display.fillRect(0, 0, 128, 15, SSD1306_BLACK); // fill with Black
display.setCursor(0, 0);
display.print(&timeinfo, "%m/%d/%Y %H:%M");
display.display();
}
void displayData() {
Serial.print("Status Switch = ");
Serial.println(statusSwitch);
Serial.print("Temperature = ");
Serial.println(temperature);
Serial.print("Humidity = ");
Serial.println(humidity);
Serial.print("Distance = ");
Serial.println(jarakcm1);
//display to OLED
display.fillRect(35, 20, 20, 44, SSD1306_BLACK);
display.setCursor(40, 20);
display.print(temperature, 1);
display.setCursor(40, 35);
display.print(humidity);
display.setCursor(40, 50);
display.print(jarakcm1);
//display switch status ON/OFF
if(statusSwitch==1)display.fillCircle(105,40,20,SSD1306_WHITE);
else {
display.fillCircle(105,40,20,SSD1306_BLACK);
display.drawCircle(105,40,20,SSD1306_WHITE);
}
display.display();
}
void sendData() {
String temp = String(temperature, 2);
client.publish("/Thinkitive/temp", temp.c_str()); // publish temp topic /ThinkIOT/temp
String hum = String(humidity, 1);
client.publish("/Thinkitive/hum", hum.c_str()); // publish hum topic /ThinkIOT/hum
String dist = String(jarakcm1, 1);
client.publish("/Thinkitive/Levelbak", dist.c_str()); // publish hum topic /ThinkIOT/hum
}
void getDistance() {
unsigned long durasi = 0;//siapkan variabel durasinya
//memerintahkan sensor ultrasonik mengirimkan sinyal akustiknya
digitalWrite(trigPin1, LOW);
delayMicroseconds(2);
digitalWrite(trigPin1, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin1, LOW);
//get time duration
durasi = pulseIn(echoPin1, HIGH);
// calculate distance
jarakcm1 = durasi * soundSpeed / 2;
}
void getDataDHT() {
humidity = dht.readHumidity();
temperature = dht.readTemperature();
}