#include <stdio.h>
#include "esp_rom_gpio.h"
#include "driver/i2c.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/adc.h"
#define I2C_MASTER_SCL_IO 22 // Pin SCL
#define I2C_MASTER_SDA_IO 21 // Pin SDA
#define I2C_MASTER_NUM I2C_NUM_0 // I2C port number
#define I2C_MASTER_FREQ_HZ 100000 // I2C clock frequency
#define I2C_MASTER_TX_BUF_DISABLE 0
#define I2C_MASTER_RX_BUF_DISABLE 0
#define I2C_LCD_ADDR 0x27 // LCD I2C address
#define SENSOR_PIN 34 // Pin sensor gas (MQ2)
// LED pins
#define LED_RED_PIN 27
#define LED_YELLOW_PIN 26
#define LED_GREEN_PIN 25
// Fungsi untuk inisialisasi I2C
void i2c_master_init() {
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_MASTER_SDA_IO,
.scl_io_num = I2C_MASTER_SCL_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_MASTER_FREQ_HZ,
};
i2c_param_config(I2C_MASTER_NUM, &conf);
i2c_driver_install(I2C_MASTER_NUM, conf.mode,
I2C_MASTER_RX_BUF_DISABLE,
I2C_MASTER_TX_BUF_DISABLE, 0);
}
// Fungsi untuk mengirimkan command ke LCD
void lcd_send_cmd(char cmd) {
char upper = cmd & 0xF0;
char lower = (cmd << 4) & 0xF0;
char data_t[4];
data_t[0] = upper | 0x0C;
data_t[1] = upper | 0x08;
data_t[2] = lower | 0x0C;
data_t[3] = lower | 0x08;
i2c_cmd_handle_t handle = i2c_cmd_link_create();
i2c_master_start(handle);
i2c_master_write_byte(handle, (I2C_LCD_ADDR << 1) | I2C_MASTER_WRITE, true);
i2c_master_write(handle, (uint8_t *) data_t, 4, true);
i2c_master_stop(handle);
i2c_master_cmd_begin(I2C_MASTER_NUM, handle, 1000 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(handle);
vTaskDelay(5 / portTICK_PERIOD_MS);
}
// Fungsi untuk mengirimkan data ke LCD
void lcd_send_data(char data) {
char upper = data & 0xF0;
char lower = (data << 4) & 0xF0;
char data_t[4];
data_t[0] = upper | 0x0D;
data_t[1] = upper | 0x09;
data_t[2] = lower | 0x0D;
data_t[3] = lower | 0x09;
i2c_cmd_handle_t handle = i2c_cmd_link_create();
i2c_master_start(handle);
i2c_master_write_byte(handle, (I2C_LCD_ADDR << 1) | I2C_MASTER_WRITE, true);
i2c_master_write(handle, (uint8_t *) data_t, 4, true);
i2c_master_stop(handle);
i2c_master_cmd_begin(I2C_MASTER_NUM, handle, 1000 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(handle);
vTaskDelay(5 / portTICK_PERIOD_MS);
}
// Fungsi untuk inisialisasi LCD
void lcd_init() {
lcd_send_cmd(0x02); // Initialize LCD in 4-bit mode
lcd_send_cmd(0x28); // 2 lines, 5x7 matrix
lcd_send_cmd(0x0C); // Display ON, cursor OFF
lcd_send_cmd(0x06); // Entry mode
lcd_send_cmd(0x01); // Clear display
vTaskDelay(50 / portTICK_PERIOD_MS);
}
// Fungsi untuk menampilkan string pada LCD
void lcd_send_string(const char* str) {
while (*str) {
lcd_send_data(*str++);
}
}
// Fungsi untuk membaca nilai sensor gas
int read_gas_sensor() {
// Pastikan channel ADC benar-benar valid
adc1_config_width(ADC_WIDTH_BIT_12); // Set ADC resolution to 12-bit
adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_0); // No attenuation for this channel
return adc1_get_raw(ADC1_CHANNEL_6); // Read sensor value from channel 6 (GPIO34)
}
// Fungsi untuk mengendalikan LED berdasarkan pembacaan sensor
void control_led(int sensor_value) {
if (sensor_value < 1627) {
// Kualitas udara baik (LED hijau)
gpio_set_level(LED_GREEN_PIN, 1);
gpio_set_level(LED_YELLOW_PIN, 0);
gpio_set_level(LED_RED_PIN, 0);
} else if (sensor_value < 2410) {
// Kualitas udara sedang (LED kuning)
gpio_set_level(LED_GREEN_PIN, 0);
gpio_set_level(LED_YELLOW_PIN, 1);
gpio_set_level(LED_RED_PIN, 0);
} else {
// Kualitas udara buruk (LED merah)
gpio_set_level(LED_GREEN_PIN, 0);
gpio_set_level(LED_YELLOW_PIN, 0);
gpio_set_level(LED_RED_PIN, 1);
}
}
void app_main() {
// Inisialisasi GPIO untuk LED
esp_rom_gpio_pad_select_gpio(LED_RED_PIN);
gpio_set_direction(LED_RED_PIN, GPIO_MODE_OUTPUT);
esp_rom_gpio_pad_select_gpio(LED_YELLOW_PIN);
gpio_set_direction(LED_YELLOW_PIN, GPIO_MODE_OUTPUT);
esp_rom_gpio_pad_select_gpio(LED_GREEN_PIN);
gpio_set_direction(LED_GREEN_PIN, GPIO_MODE_OUTPUT);
// Inisialisasi I2C dan LCD
i2c_master_init();
lcd_init();
while (1) {
// Baca nilai sensor gas
int sensor_value = read_gas_sensor();
printf("Sensor Value: %d\n", sensor_value);
// Tampilkan status pada LCD
lcd_send_cmd(0x80); // Move to first line
lcd_send_string("Kualitas Udara:");
lcd_send_cmd(0xC0); // Baris kedua
lcd_send_string(" ");
lcd_send_cmd(0xC0); // Move to second line
if (sensor_value < 1790) {
lcd_send_string("Baik");
} else if (sensor_value < 2410) {
lcd_send_string("Sedang");
} else {
lcd_send_string("Buruk");
}
// Kendalikan LED berdasarkan pembacaan sensor
control_led(sensor_value);
vTaskDelay(500 / portTICK_PERIOD_MS); // Delay selama 2 detik
}
}