#include #include #include #include #include // ==================== پین‌ها ==================== #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); }