307 lines
7.6 KiB
C++
307 lines
7.6 KiB
C++
#include <Wire.h>
|
|
#include <Adafruit_GFX.h>
|
|
#include <Adafruit_SSD1306.h>
|
|
#include <Adafruit_SHT31.h>
|
|
#include <DHT.h>
|
|
|
|
// ==================== پینها ====================
|
|
#define SOIL_MOISTURE_PIN PA1
|
|
#define DHT11_PIN PA0
|
|
#define SHT31_SCL PB6
|
|
#define SHT31_SDA PB7
|
|
#define OLED_SCL PB10
|
|
#define OLED_SDA PB11
|
|
|
|
// ==================== OLED ====================
|
|
#define SCREEN_WIDTH 128
|
|
#define SCREEN_HEIGHT 64
|
|
#define OLED_ADDRESS 0x3C
|
|
|
|
TwoWire Wire2(OLED_SDA, OLED_SCL);
|
|
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire2, -1);
|
|
|
|
// ==================== سنسورها ====================
|
|
#define SHT31_ADDRESS 0x44
|
|
Adafruit_SHT31 sht31(&Wire);
|
|
#define DHTTYPE DHT11
|
|
DHT dht(DHT11_PIN, DHTTYPE);
|
|
|
|
// ==================== کالیبراسیون ====================
|
|
#define SOIL_WET_VALUE 520
|
|
#define SOIL_DRY_VALUE 800
|
|
|
|
// ==================== متغیرها ====================
|
|
int soilMoisturePercent = 0;
|
|
float dht11_temp = 0, dht11_humidity = 0;
|
|
float sht31_temp = 0, sht31_humidity = 0;
|
|
bool sht31Found = false;
|
|
unsigned long lastRead = 0;
|
|
|
|
// ==================== تنظیمات نمایش ====================
|
|
#define LARGE_FONT_SIZE 2 // فونت بزرگ برای اعداد
|
|
#define SMALL_FONT_SIZE 1 // فونت کوچک برای متن
|
|
|
|
void setup() {
|
|
Serial1.begin(115200);
|
|
delay(100);
|
|
|
|
Serial1.println("========================================");
|
|
Serial1.println("STM32F103 - Three Sensor System");
|
|
Serial1.println("========================================");
|
|
|
|
// I2C1 برای SHT31
|
|
Wire.setSDA(SHT31_SDA);
|
|
Wire.setSCL(SHT31_SCL);
|
|
Wire.begin();
|
|
|
|
// I2C2 برای OLED
|
|
Wire2.begin();
|
|
Wire2.setClock(400000);
|
|
|
|
// سنسورها
|
|
pinMode(SOIL_MOISTURE_PIN, INPUT_ANALOG);
|
|
dht.begin();
|
|
|
|
// OLED
|
|
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS)) {
|
|
Serial1.println("OLED initialization failed!");
|
|
while (1);
|
|
}
|
|
|
|
Serial1.println("OLED initialized successfully");
|
|
|
|
// SHT31
|
|
sht31Found = sht31.begin(SHT31_ADDRESS);
|
|
if (!sht31Found) {
|
|
sht31Found = sht31.begin(0x45); // تست آدرس دیگر
|
|
}
|
|
|
|
if (sht31Found) {
|
|
Serial1.println("SHT31 found!");
|
|
} else {
|
|
Serial1.println("SHT31 not found!");
|
|
}
|
|
|
|
displayStartup();
|
|
}
|
|
|
|
void loop() {
|
|
if (millis() - lastRead >= 2000) {
|
|
lastRead = millis();
|
|
readSensors();
|
|
updateDisplay();
|
|
printSerial();
|
|
}
|
|
delay(100);
|
|
}
|
|
|
|
void readSensors() {
|
|
// خاک - میانگینگیری برای دقت بیشتر
|
|
long soilSum = 0;
|
|
for (int i = 0; i < 5; i++) {
|
|
soilSum += analogRead(SOIL_MOISTURE_PIN);
|
|
delay(1);
|
|
}
|
|
int soilRaw = soilSum / 5;
|
|
|
|
if (soilRaw <= SOIL_WET_VALUE) {
|
|
soilMoisturePercent = 100;
|
|
} else if (soilRaw >= SOIL_DRY_VALUE) {
|
|
soilMoisturePercent = 0;
|
|
} else {
|
|
soilMoisturePercent = map(soilRaw, SOIL_DRY_VALUE, SOIL_WET_VALUE, 0, 100);
|
|
}
|
|
soilMoisturePercent = constrain(soilMoisturePercent, 0, 100);
|
|
|
|
// DHT11
|
|
dht11_temp = dht.readTemperature();
|
|
dht11_humidity = dht.readHumidity();
|
|
if (isnan(dht11_temp) || isnan(dht11_humidity)) {
|
|
dht11_temp = dht11_humidity = -999;
|
|
}
|
|
|
|
// SHT31
|
|
if (sht31Found) {
|
|
sht31_temp = sht31.readTemperature();
|
|
sht31_humidity = sht31.readHumidity();
|
|
if (isnan(sht31_temp) || isnan(sht31_humidity)) {
|
|
sht31_temp = sht31_humidity = -999;
|
|
}
|
|
}
|
|
}
|
|
|
|
void updateDisplay() {
|
|
display.clearDisplay();
|
|
display.setTextColor(SSD1306_WHITE);
|
|
|
|
// ==================== خط اول: خاک ====================
|
|
// عنوان خاک
|
|
display.setTextSize(SMALL_FONT_SIZE);
|
|
display.setCursor(0, 0);
|
|
display.print("Soil:");
|
|
|
|
// مقدار خاک (بزرگ)
|
|
display.setTextSize(LARGE_FONT_SIZE);
|
|
if (soilMoisturePercent < 10) {
|
|
display.setCursor(35, 0);
|
|
} else if (soilMoisturePercent < 100) {
|
|
display.setCursor(25, 0);
|
|
} else {
|
|
display.setCursor(15, 0);
|
|
}
|
|
display.print(soilMoisturePercent);
|
|
|
|
// علامت درصد
|
|
display.setTextSize(SMALL_FONT_SIZE);
|
|
display.print("%");
|
|
|
|
// ==================== خط دوم: DHT11 ====================
|
|
// عنوان DHT11
|
|
display.setTextSize(SMALL_FONT_SIZE);
|
|
display.setCursor(0, 20);
|
|
display.print("DHT:");
|
|
|
|
// دما DHT (بزرگ)
|
|
display.setTextSize(LARGE_FONT_SIZE);
|
|
if (dht11_temp != -999) {
|
|
if (dht11_temp >= 0 && dht11_temp < 10) {
|
|
display.setCursor(40, 20);
|
|
} else if (dht11_temp >= 10 && dht11_temp < 100) {
|
|
display.setCursor(30, 20);
|
|
} else {
|
|
display.setCursor(20, 20);
|
|
}
|
|
display.print(dht11_temp, 1);
|
|
} else {
|
|
display.setCursor(40, 20);
|
|
display.print("---");
|
|
}
|
|
|
|
// درجه سانتیگراد
|
|
display.setTextSize(SMALL_FONT_SIZE);
|
|
display.print("C");
|
|
|
|
// رطوبت DHT (بزرگ)
|
|
display.setTextSize(LARGE_FONT_SIZE);
|
|
display.setCursor(80, 20);
|
|
if (dht11_humidity != -999) {
|
|
if (dht11_humidity < 10) {
|
|
display.setCursor(85, 20);
|
|
} else if (dht11_humidity < 100) {
|
|
display.setCursor(80, 20);
|
|
} else {
|
|
display.setCursor(75, 20);
|
|
}
|
|
display.print(dht11_humidity, 0);
|
|
} else {
|
|
display.print("---");
|
|
}
|
|
|
|
// علامت درصد
|
|
display.setTextSize(SMALL_FONT_SIZE);
|
|
display.print("%");
|
|
|
|
// ==================== خط سوم: SHT31 ====================
|
|
// عنوان SHT31
|
|
display.setTextSize(SMALL_FONT_SIZE);
|
|
display.setCursor(0, 40);
|
|
display.print("SHT:");
|
|
|
|
// دما SHT (بزرگ)
|
|
display.setTextSize(LARGE_FONT_SIZE);
|
|
if (sht31Found && sht31_temp != -999) {
|
|
if (sht31_temp >= 0 && sht31_temp < 10) {
|
|
display.setCursor(40, 40);
|
|
} else if (sht31_temp >= 10 && sht31_temp < 100) {
|
|
display.setCursor(30, 40);
|
|
} else {
|
|
display.setCursor(20, 40);
|
|
}
|
|
display.print(sht31_temp, 1);
|
|
} else {
|
|
display.setCursor(40, 40);
|
|
display.print("---");
|
|
}
|
|
|
|
// درجه سانتیگراد
|
|
display.setTextSize(SMALL_FONT_SIZE);
|
|
display.print("C");
|
|
|
|
// رطوبت SHT (بزرگ)
|
|
display.setTextSize(LARGE_FONT_SIZE);
|
|
if (sht31Found && sht31_humidity != -999) {
|
|
if (sht31_humidity < 10) {
|
|
display.setCursor(85, 40);
|
|
} else if (sht31_humidity < 100) {
|
|
display.setCursor(80, 40);
|
|
} else {
|
|
display.setCursor(75, 40);
|
|
}
|
|
display.print(sht31_humidity, 0);
|
|
} else {
|
|
display.setCursor(80, 40);
|
|
display.print("---");
|
|
}
|
|
|
|
// علامت درصد
|
|
display.setTextSize(SMALL_FONT_SIZE);
|
|
display.print("%");
|
|
|
|
// ==================== خط جداساز ====================
|
|
display.drawFastHLine(0, 15, 128, SSD1306_WHITE); // بین خاک و DHT
|
|
display.drawFastHLine(0, 35, 128, SSD1306_WHITE); // بین DHT و SHT
|
|
|
|
display.display();
|
|
}
|
|
|
|
void printSerial() {
|
|
Serial1.print("Time: ");
|
|
Serial1.print(millis() / 1000);
|
|
Serial1.print("s | ");
|
|
|
|
Serial1.print("Soil: ");
|
|
Serial1.print(soilMoisturePercent);
|
|
Serial1.print("% | ");
|
|
|
|
Serial1.print("DHT: ");
|
|
if (dht11_temp != -999) {
|
|
Serial1.print(dht11_temp, 1);
|
|
Serial1.print("C ");
|
|
Serial1.print(dht11_humidity, 0);
|
|
Serial1.print("%");
|
|
} else {
|
|
Serial1.print("---");
|
|
}
|
|
|
|
Serial1.print(" | ");
|
|
|
|
Serial1.print("SHT: ");
|
|
if (sht31Found && sht31_temp != -999) {
|
|
Serial1.print(sht31_temp, 1);
|
|
Serial1.print("C ");
|
|
Serial1.print(sht31_humidity, 0);
|
|
Serial1.print("%");
|
|
} else {
|
|
Serial1.print("---");
|
|
}
|
|
|
|
Serial1.println();
|
|
}
|
|
|
|
void displayStartup() {
|
|
display.clearDisplay();
|
|
|
|
// نمایش عنوان
|
|
display.setTextSize(LARGE_FONT_SIZE);
|
|
display.setCursor(15, 10);
|
|
display.println("SENSOR");
|
|
display.setCursor(20, 30);
|
|
display.println("SYSTEM");
|
|
|
|
display.setTextSize(SMALL_FONT_SIZE);
|
|
display.setCursor(40, 50);
|
|
display.println("READY");
|
|
|
|
display.display();
|
|
delay(1500);
|
|
} |