#include <Wire.
h>
#include <LiquidCrystal_I2C.h>
// Function to scan and print I2C addresses
void scanI2CDevices() {
Serial.println("Scanning I2C devices...");
byte count = 0;
Wire.begin();
for (byte i = 8; i < 120; i++) {
Wire.beginTransmission(i);
if (Wire.endTransmission() == 0) {
Serial.print("Found address: ");
Serial.print(i, DEC);
Serial.print(" (0x");
Serial.print(i, HEX);
Serial.println(")");
count++;
delay(1);
Serial.println("Done.");
Serial.print("Found ");
Serial.print(count, DEC);
Serial.println(" device(s).");
}
// Pin definitions
#define LDR_PIN A0
#define LAMPU_PIN 9
// Setpoint and PID constants
#define SETPOINT 500
#define KP 0.1
#define KI 0.01
#define KD 0.05
// LCD I2C address
#define LCD_I2C_ADDRESS 0x27 // Adjust this address according to your I2C module
LiquidCrystal_I2C lcd(LCD_I2C_ADDRESS, 20, 4); // Initialize the LCD with 20 columns and 4 rows
// PID variables
float error, error_prev, error_total, output;
// Timing variables
unsigned long waktu_sekarang, waktu_sebelum, interval;
void setup() {
// Start Serial communication
Serial.begin(9600);
// Call the function to scan and print I2C addresses
scanI2CDevices();
// Initialize LCD
lcd.begin(20, 4);
lcd.backlight(); // Turn on the backlight
// Display "Sistem Kendali Lampu" on the first line
lcd.print("Sistem Kendali Lampu");
// Set the cursor to the beginning of the second line
lcd.setCursor(0, 1);
// Display "Nilai LDR:" on the second line
lcd.print("Nilai LDR:");
// Set LDR pin as input
pinMode(LDR_PIN, INPUT);
// Set lamp pin as PWM output
pinMode(LAMPU_PIN, OUTPUT);
// Initialize timing variables
waktu_sebelum = millis();
void loop() {
// Read LDR sensor value
int nilai = analogRead(LDR_PIN);
// Display LDR value on LCD after "Nilai LDR:"
lcd.setCursor(10, 1);
lcd.print(nilai);
// Calculate error as the difference between setpoint and actual value
error = SETPOINT - nilai;
// Calculate current time
waktu_sekarang = millis();
// Calculate interval as the difference between current time and previous time
interval = waktu_sekarang - waktu_sebelum;
// Calculate total error as the accumulation of error over time
error_total += error * interval;
// Calculate PID output
output = KP * error + KI * error_total + KD * (error - error_prev) / interval;
// Set output as PWM value for the lamp
analogWrite(LAMPU_PIN, output);
// Update previous error as the current error
error_prev = error;
// Update previous time as the current time
waktu_sebelum = waktu_sekarang;
// Display information in Serial Monitor
Serial.print("Nilai LDR: ");
Serial.println(nilai);
Serial.print("Error: ");
Serial.println(error);
Serial.print("PID Output: ");
Serial.println(output);
Serial.println("------------------");
// Add a delay to avoid overwhelming the Serial Monitor
delay(1000);