#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ThingSpeak.h>
#include <WiFi.h>
#include <DHTesp.h> // Thêm thư viện DHT22
const int DHT_PIN = 15;
DHTesp dht;
#define ENCODER_A_PIN 21 // Chân nối encoder A
#define ENCODER_B_PIN 22 // Chân nối encoder B
#define LCD_ADDRESS 0x27 // Địa chỉ I2C của màn hình LCD
#define LCD_COLS 16 // Số cột của màn hình LCD
#define LCD_ROWS 2 // Số hàng của màn hình LCD
LiquidCrystal_I2C lcd(LCD_ADDRESS, LCD_COLS, LCD_ROWS); // Khởi tạo màn hình LCD
DHTesp dhtSensor;
volatile int encoderPos = 0; // Biến lưu trữ vị trí của encoder
int encoderLastPos = 0; // Biến lưu trữ vị trí trước đó của encoder
unsigned long lastMillis = 0; // Biến lưu trữ thời điểm cuối cùng
float rpm = 0.0; // Biến lưu trữ giá trị RPM
const char *ssid = "Wokwi-GUEST"; // Tên mạng Wi-Fi
const char *password = ""; // Mật khẩu Wi-Fi
const char *thingSpeakApiKey = "VVY72GUDW2D3T8HW"; // API Key của ThingSpeak
const long YourChannelNumber = 2307281; // Số kênh ThingSpeak
const char* server = "api.thingspeak.com"; // Địa chỉ máy chủ ThingSpeak
WiFiClient client; // Đối tượng Wi-Fi Client
const int POTENTIOMETER_PIN = 13; // Chân Potentiometer
const int CURRENT_SENSOR_PIN = A0; // Chân đo PH
void IRAM_ATTR encoderISR() {
static int8_t last_AB = 0x00;
static const int8_t table[16] = {0, 1, -1, 0, -1, 0, 0, 1, 1, 0, 0, -1, 0, -1, 1, 0};
last_AB <<= 2;
last_AB |= ((digitalRead(ENCODER_A_PIN) << 1) | digitalRead(ENCODER_B_PIN)) & 0x03;
encoderPos += table[last_AB & 0x0f];
}
void setup() {
lcd.init(); // Khởi tạo màn hình LCD
lcd.backlight(); // Bật đèn nền của màn hình LCD
lcd.print("Encoder "); // Hiển thị thông điệp trên màn hình LCD
pinMode(ENCODER_A_PIN, INPUT_PULLUP); // Cấu hình chân encoder A là INPUT_PULLUP
pinMode(ENCODER_B_PIN, INPUT_PULLUP); // Cấu hình chân encoder B là INPUT_PULLUP
pinMode(POTENTIOMETER_PIN, INPUT); // Cấu hình chân Potentiometer là INPUT
attachInterrupt(digitalPinToInterrupt(ENCODER_A_PIN), encoderISR, CHANGE); // Kết nối ngắt cho encoder A
attachInterrupt(digitalPinToInterrupt(ENCODER_B_PIN), encoderISR, CHANGE); // Kết nối ngắt cho encoder B
// Kết nối Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
dht.setup(DHT_PIN, DHTesp::DHT22);
// Khởi tạo ThingSpeak
ThingSpeak.begin(client);
}
void loop() {
float temperature = dht.getTemperature();
float humidity = dht.getHumidity();
// Kiểm tra xem dữ liệu từ cảm biến DHT22 có hợp lệ không
if (!isnan(temperature) && !isnan(humidity)) {
// Gửi NH4 và TSS lên ThingSpeak
ThingSpeak.setField(3, temperature); // Đặt giá trị trường 3
ThingSpeak.setField(4, humidity); // Đặt giá trị trường 4
}
unsigned long currentMillis = millis();
if (currentMillis - lastMillis >= 500) {
lastMillis = currentMillis;
int delta = encoderPos - encoderLastPos;
encoderLastPos = encoderPos;
rpm = (delta * 30) / 16.0;
lcd.setCursor(0, 1);
lcd.print("COD ");
lcd.print(rpm);
// Đọc giá trị DO PH từ cảm biến dòng điện
int current = analogRead(CURRENT_SENSOR_PIN);
// Hiển thị giá trị PH lên màn hình LCD
lcd.setCursor(0, 0);
lcd.print("Do PH ");
lcd.print(current);
// Gửi giá trị COD và PH lên ThingSpeak
ThingSpeak.setField(1, rpm); // Đặt giá trị trường 1
ThingSpeak.setField(2, current); // Đặt giá trị trường 2
int x = ThingSpeak.writeFields(YourChannelNumber, thingSpeakApiKey); // Gửi dữ liệu lên ThingSpeak
if (x == 200) {
Serial.println("Data pushed successfully to ThingSpeak");
} else {
Serial.println("Push error " + String(x));
}
}
}