#include <dht.h>
#include <Servo.h>
// Define the pin you connected to the DHT sensor
// กำหนดขาเชื่อมต่อกับเซนเซอร์ DHT
#define dataPin (2) // Defines pin number to which the sensor is connected // กำหนดหมายเลขขาที่เชื่อมต่อกับเซนเซอร์
dht DHT; // Creates a DHT object // สร้างวัตถุ DHT
Servo myservo; // Create servo object to control a servo // สร้างวัตถุเซอร์โวเพื่อควบคุมเซอร์โว
// Define thermistor parameters for temperature measurement
// กำหนดพารามิเตอร์ของเทอร์มิสเตอร์สำหรับการวัดอุณหภูมิ
const int thermistorNominal = 10000;
const int temperatureNominal = 25;
const int betaValue = 3950;
// Define the pins for RGB LED
// กำหนดขาสำหรับ RGB LED
#define redPin (12)
#define greenPin (11)
#define bluePin (10)
// Define the pins for RGB LED
// กำหนดขาสำหรับ RGB LED
#define redPin1 (7)
#define greenPin1 (6)
#define bluePin1 (5)
#define servoPin (9)
#define adc_temp_min (-40) // ค่าควบคุมอนาล็อกต่ำสุด
#define adc_temp_max (80) // ค่าควบคุมอนาล็อกสูงสุด
#define adc_humi_min (0) // ค่าควบคุมอนาล็อกต่ำสุด
#define adc_humi_max (80) // ค่าควบคุมอนาล็อกสูงสุด
#define adc_res_min (0) // ความละเอียด ADC ต่ำสุด 2^11 บิต
#define adc_res_max (1023) // ความละเอียด ADC สูงสุด 2^11 บิต
#define adcPinA0 (A0) // ขาอนาล็อก
#define step_SetPointA0 (analogRead(adcPinA0)) // อ่านค่าจากขาอนาล็อก
#define tempSetPoint (map(step_SetPointA0, adc_res_min, adc_res_max, adc_temp_min, adc_temp_max)) // แปลงค่าอนาล็อกเป็นค่า การควบคุมอุณหภูมิ
#define adcPinA1 (A1) // ขาอนาล็อก
#define step_SetPointA1 (analogRead(adcPinA1)) // อ่านค่าจากขาอนาล็อก
#define humiSetPoint (map(step_SetPointA1, adc_res_min, adc_res_max, adc_humi_min, adc_humi_max)) // แปลงค่าอนาล็อกเป็นค่าความเร็ว การควบคุมความชื้น
float temp; // Gets the values of the temperature // รับค่าอุณหภูมิ
float humi; // Gets the values of the humidity // รับค่าความชื้น
// Setpoints for temperature and humidity control
// จุดตั้งสำหรับการควบคุมอุณหภูมิและความชื้น
//float tempSetPoint = 30.0;
//float humiSetPoint = 50.0;
// PID parameters // พารามิเตอร์ PID
double
Kp_temp = 1.0,
Ki_temp = 0.0,
Kd_temp = 0.0,
Kp_humi = 1.0,
Ki_humi = 0.0,
Kd_humi = 0.0;
// PID control variables // ตัวแปรควบคุม PID
double
input_temp = 0.0,
output_temp = 0.0,
lastInput_temp = 0.0,
integral_temp = 0.0,
input_humi = 0.0,
output_humi = 0.0,
lastInput_humi = 0.0,
integral_humi = 0.0;
// PID output limits // ขีดจำกัดเอาท์พุตของ PID
double
outputMin = 0.0,
outputMax = 100.0;
// Timing variables for PID calculation
// ตัวแปรเวลาในการคำนวณ PID
unsigned long prevTime = 0;
unsigned long deltaTime = 10000; // 10 seconds // 10 วินาที
int val; // Variable to read the value from the analog pin // ตัวแปรสำหรับอ่านค่าจากขาอนาล็อก
int position; // Variable to store the servo position // ตัวแปรสำหรับเก็บตำแหน่งเซอร์โว
// Ziegler-Nichols parameters for PID tuning
// พารามิเตอร์ Ziegler-Nichols สำหรับการปรับ PID
double L = 0.1; // Dead time // เวลาที่ไม่ตอบสนอง
double T = 1.0; // Time constant // ค่าคงที่ของเวลา
void setup()
{
Serial.begin(9600); // Initialize serial communication at 9600 baud rate // เริ่มการสื่อสารแบบอนุกรมที่ความเร็ว 9600 บอด
pinMode(redPin, OUTPUT); // Set red LED pin as output // กำหนดขา LED สีแดงเป็นขาเอาท์พุต
pinMode(greenPin, OUTPUT); // Set green LED pin as output // กำหนดขา LED สีเขียวเป็นขาเอาท์พุต
pinMode(bluePin, OUTPUT); // Set blue LED pin as output // กำหนดขา LED สีน้ำเงินเป็นขาเอาท์พุต
pinMode(redPin1, OUTPUT); // Set red LED pin as output // กำหนดขา LED สีแดงเป็นขาเอาท์พุต
pinMode(greenPin1, OUTPUT); // Set green LED pin as output // กำหนดขา LED สีเขียวเป็นขาเอาท์พุต
pinMode(bluePin1, OUTPUT); // Set blue LED pin as output // กำหนดขา LED สีน้ำเงินเป็นขาเอาท์พุต
myservo.attach(servoPin); // Attach the servo on pin 9 to the servo object // เชื่อมต่อเซอร์โวที่ขา 9 กับวัตถุเซอร์โว
// Calculate PID parameters using Ziegler-Nichols method
// คำนวณพารามิเตอร์ PID โดยใช้วิธี Ziegler-Nichols
Kp_temp = 1.2 * T / L;
Ki_temp = 2 * L;
Kd_temp = 0.5 * L;
Kp_humi = 1.2 * T / L;
Ki_humi = 2 * L;
Kd_humi = 0.5 * L;
}
void loop()
{
float currentTemperature = temperature(); // Get current temperature // รับค่าอุณหภูมิปัจจุบัน
float currentHumidity = humidity(); // Get current humidity // รับค่าความชื้นปัจจุบัน
unsigned long currentTime = millis(); // Get current time in milliseconds // รับค่าเวลาปัจจุบันในหน่วยมิลลิวินาที
if (currentTime - prevTime >= deltaTime) // Check if it's time to update the PID controller // ตรวจสอบว่าถึงเวลาที่จะอัพเดทตัวควบคุม PID หรือไม่
{
double dt = (double)(currentTime - prevTime) / 1000.0; // Calculate time difference in seconds // คำนวณความแตกต่างของเวลาในหน่วยวินาที
// Temperature control // การควบคุมอุณหภูมิ
input_temp = currentTemperature; // Update input with current temperature // อัพเดทค่าอินพุตด้วยอุณหภูมิปัจจุบัน
double error_temp = tempSetPoint - input_temp; // Calculate error // คำนวณข้อผิดพลาด
integral_temp += error_temp * dt; // Accumulate integral term // สะสมค่าตัวบูรณาการ
double dInput_temp = (input_temp - lastInput_temp) / dt; // Calculate derivative term // คำนวณค่าตัวอนุพันธ์
output_temp = Kp_temp * error_temp + Ki_temp * integral_temp + Kd_temp * dInput_temp; // Calculate PID output // คำนวณเอาท์พุตของ PID
output_temp = constrain(output_temp, outputMin, outputMax); // Constrain output to specified limits // จำกัดเอาท์พุตให้อยู่ในขีดจำกัดที่กำหนด
lastInput_temp = input_temp; // Update last input // อัพเดทค่าอินพุตครั้งสุดท้าย
// Humidity control // การควบคุมความชื้น
input_humi = currentHumidity; // Update input with current humidity // อัพเดทค่าอินพุตด้วยความชื้นปัจจุบัน
double error_humi = humiSetPoint - input_humi; // Calculate error // คำนวณข้อผิดพลาด
integral_humi += error_humi * dt; // Accumulate integral term // สะสมค่าตัวบูรณาการ
double dInput_humi = (input_humi - lastInput_humi) / dt; // Calculate derivative term // คำนวณค่าตัวอนุพันธ์
output_humi = Kp_humi * error_humi + Ki_humi * integral_humi + Kd_humi * dInput_humi; // Calculate PID output // คำนวณเอาท์พุตของ PID
output_humi = constrain(output_humi, outputMin, outputMax); // Constrain output to specified limits // จำกัดเอาท์พุตให้อยู่ในขีดจำกัดที่กำหนด
lastInput_humi = input_humi; // Update last input // อัพเดทค่าอินพุตครั้งสุดท้าย
prevTime = currentTime; // Update previous time // อัพเดทค่าเวลาครั้งก่อน
servo_control(output_temp,output_humi); // Control the servo based on PID output // ควบคุมเซอร์โวตามเอาท์พุตของ PID
// Print PID data to serial monitor // พิมพ์ข้อมูล PID ไปยังมอนิเตอร์อนุกรม
// Serial.print("Temp SP: ");
Serial.print(tempSetPoint); Serial.print(" ");
// Serial.print(" | Input Temp: ");
Serial.print(input_temp); Serial.print(" ");
// Serial.print(" | Output Temp : ");
Serial.print(output_temp); Serial.print(" ");
// Serial.print(" | Humi SP: ");
Serial.print(humiSetPoint); Serial.print(" ");
// Serial.print(" | Input Humi: ");
Serial.print(input_humi); Serial.print(" ");
// Serial.print(" | Output Humi: ");
Serial.print(output_humi); Serial.println(" ");
/*
Serial.print(" | Temp = ");
Serial.print(temp);
Serial.print(" *C ");
Serial.print(" | Humi = ");
Serial.print(humi);
Serial.println(" %RH ");
*/
// Control LEDs based on temperature // ควบคุม LED ตามอุณหภูมิ
if (tempSetPoint < currentTemperature)
{
redLED(); // Turn on red LED if temperature is above setpoint // เปิด LED สีแดงถ้าอุณหภูมิสูงกว่าจุดตั้ง
}
else
{
greenLED(); // Turn on green LED if temperature is below setpoint // เปิด LED สีเขียวถ้าอุณหภูมิต่ำกว่าจุดตั้ง
}
// Control LEDs based on temperature // ควบคุม LED ตามความชื้น
if (humiSetPoint < currentHumidity)
{
redLED1(); // Turn on red LED if temperature is above setpoint // เปิด LED สีแดงถ้าอุณหภูมิสูงกว่าจุดตั้ง
}
else
{
greenLED1(); // Turn on green LED if temperature is below setpoint // เปิด LED สีเขียวถ้าอุณหภูมิต่ำกว่าจุดตั้ง
}
}
}
void servo_control(double output_temp, double output_humit)
{
if((output_temp < input_temp) && (output_humit < input_humi))
{
val = output_temp; // Use PID output to control the servo // ใช้เอาท์พุตของ PID เพื่อควบคุมเซอร์โว
val = map(val, outputMin, outputMax, 0, 180); // Scale output to servo range (0-180) // ปรับเอาท์พุตให้อยู่ในช่วงเซอร์โว (0-180)
position = val; // Set position to scaled value // กำหนดตำแหน่งเป็นค่าที่ปรับแล้ว
myservo.write(position); // Set servo position // กำหนดตำแหน่งเซอร์โว
}
}
float temperature()
{
int readData = DHT.read22(dataPin); // Reads the data from the sensor // อ่านข้อมูลจากเซนเซอร์
float t = DHT.temperature; // Gets the values of the temperature // รับค่าอุณหภูมิ
temp = t;
return t; // Return the temperature value // คืนค่าอุณหภูมิ
}
float humidity()
{
int readData = DHT.read22(dataPin); // Reads the data from the sensor // อ่านข้อมูลจากเซนเซอร์
float h = DHT.humidity; // Gets the values of the humidity // รับค่าความชื้น
humi = h;
return h; // Return the humidity value // คืนค่าความชื้น
}
// Function to turn on the red LED and turn off others
// ฟังก์ชันเพื่อเปิด LED สีแดงและปิด LED อื่น ๆ
void redLED()
{
digitalWrite(redPin, LOW); // Turn on red LED // เปิด LED สีแดง
digitalWrite(greenPin, HIGH); // Turn off green LED // ปิด LED สีเขียว
digitalWrite(bluePin, HIGH); // Turn off blue LED // ปิด LED สีน้ำเงิน
}
// Function to turn on the green LED and turn off others
// ฟังก์ชันเพื่อเปิด LED สีเขียวและปิด LED อื่น ๆ
void greenLED()
{
digitalWrite(redPin, HIGH); // Turn off red LED // ปิด LED สีแดง
digitalWrite(greenPin, LOW); // Turn on green LED // เปิด LED สีเขียว
digitalWrite(bluePin, HIGH); // Turn off blue LED // ปิด LED สีน้ำเงิน
}
// Function to turn on the red LED and turn off others
// ฟังก์ชันเพื่อเปิด LED สีแดงและปิด LED อื่น ๆ
void redLED1()
{
digitalWrite(redPin1, LOW); // Turn on red LED // เปิด LED สีแดง
digitalWrite(greenPin1, HIGH); // Turn off green LED // ปิด LED สีเขียว
digitalWrite(bluePin1, HIGH); // Turn off blue LED // ปิด LED สีน้ำเงิน
}
// Function to turn on the green LED and turn off others
// ฟังก์ชันเพื่อเปิด LED สีเขียวและปิด LED อื่น ๆ
void greenLED1()
{
digitalWrite(redPin1, HIGH); // Turn off red LED // ปิด LED สีแดง
digitalWrite(greenPin1, LOW); // Turn on green LED // เปิด LED สีเขียว
digitalWrite(bluePin1, HIGH); // Turn off blue LED // ปิด LED สีน้ำเงิน
}