#include #include #include #include #define DHTPIN D2 #define DHTTYPE DHT11 #define SERVO_PIN D9 DHT dht(DHTPIN, DHTTYPE); Servo myServo; U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE); // U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE); int currentMode = 0; int servoAngle = 0; bool sweeping = true; bool servoEnabled = true; unsigned long lastSensorRead = 0; unsigned long lastServoMove = 0; const unsigned long SENSOR_INTERVAL = 2000; const unsigned long SERVO_INTERVAL = 15; // ────────────────────────────────────────── // OLED display functions // ────────────────────────────────────────── void showFabLab() { u8g2.clearBuffer(); u8g2.setFont(u8g2_font_ncenB14_tr); u8g2.drawStr(18, 24, "Hello"); u8g2.setFont(u8g2_font_ncenB18_tr); u8g2.drawStr(8, 54, "Fab Lab!"); u8g2.sendBuffer(); } void showHumidity(float h) { char valStr[10]; dtostrf(h, 4, 1, valStr); strcat(valStr, " %"); u8g2.clearBuffer(); u8g2.setFont(u8g2_font_ncenB10_tr); u8g2.drawStr(28, 14, "Humidity"); u8g2.drawHLine(0, 18, 128); u8g2.setFont(u8g2_font_ncenB24_tr); u8g2.drawStr(14, 52, valStr); u8g2.sendBuffer(); } void showTempC(float t) { char valStr[10]; dtostrf(t, 4, 1, valStr); strcat(valStr, " C"); u8g2.clearBuffer(); u8g2.setFont(u8g2_font_ncenB10_tr); u8g2.drawStr(18, 14, "Temperature"); u8g2.drawHLine(0, 18, 128); u8g2.setFont(u8g2_font_ncenB08_tr); u8g2.drawStr(44, 32, "Celsius"); u8g2.setFont(u8g2_font_ncenB24_tr); u8g2.drawStr(14, 62, valStr); u8g2.sendBuffer(); } void showTempF(float t) { float f = (t * 9.0 / 5.0) + 32.0; char valStr[10]; dtostrf(f, 4, 1, valStr); strcat(valStr, " F"); u8g2.clearBuffer(); u8g2.setFont(u8g2_font_ncenB10_tr); u8g2.drawStr(18, 14, "Temperature"); u8g2.drawHLine(0, 18, 128); u8g2.setFont(u8g2_font_ncenB08_tr); u8g2.drawStr(30, 32, "Fahrenheit"); u8g2.setFont(u8g2_font_ncenB24_tr); u8g2.drawStr(14, 62, valStr); u8g2.sendBuffer(); } void showServoOff() { u8g2.clearBuffer(); u8g2.setFont(u8g2_font_ncenB10_tr); u8g2.drawStr(28, 14, "Servo Status"); u8g2.drawHLine(0, 18, 128); u8g2.setFont(u8g2_font_ncenB18_tr); u8g2.drawStr(22, 48, "STOPPED"); u8g2.sendBuffer(); } void showServoOn() { u8g2.clearBuffer(); u8g2.setFont(u8g2_font_ncenB10_tr); u8g2.drawStr(28, 14, "Servo Status"); u8g2.drawHLine(0, 18, 128); u8g2.setFont(u8g2_font_ncenB18_tr); u8g2.drawStr(18, 48, "RUNNING"); u8g2.sendBuffer(); } // ────────────────────────────────────────── // Sensor read + display // ────────────────────────────────────────── void readAndDisplay() { float humidity = dht.readHumidity(); float temperature = dht.readTemperature(); if (isnan(humidity) || isnan(temperature)) { Serial.println("DHT11 read error!"); u8g2.clearBuffer(); u8g2.setFont(u8g2_font_ncenB08_tr); u8g2.drawStr(10, 35, "Sensor error!"); u8g2.sendBuffer(); return; } if (currentMode == 1) { showHumidity(humidity); Serial.print("Humidity: "); Serial.print(humidity, 1); Serial.println(" %"); } else if (currentMode == 2) { showTempC(temperature); Serial.print("Temperature: "); Serial.print(temperature, 1); Serial.println(" C"); } else if (currentMode == 3) { showTempF(temperature); float f = (temperature * 9.0 / 5.0) + 32.0; Serial.print("Temperature: "); Serial.print(f, 1); Serial.println(" F"); } } // ────────────────────────────────────────── // Servo sweep // ────────────────────────────────────────── void updateServo() { if (!servoEnabled) return; if (millis() - lastServoMove < SERVO_INTERVAL) return; lastServoMove = millis(); myServo.write(servoAngle); if (sweeping) { servoAngle++; if (servoAngle >= 180) sweeping = false; } else { servoAngle--; if (servoAngle <= 0) sweeping = true; } } // ────────────────────────────────────────── // Setup // ────────────────────────────────────────── void setup() { Serial.begin(115200); dht.begin(); u8g2.begin(); myServo.setPeriodHertz(50); myServo.attach(SERVO_PIN, 500, 2400); myServo.write(0); showFabLab(); Serial.println("DHT11 Monitor ready."); Serial.println("0 = Hello Fab Lab | 1 = Humidity | 2 = Temp C | 3 = Temp F"); Serial.println("5 = Servo OFF | 6 = Servo ON"); } // ────────────────────────────────────────── // Loop // ────────────────────────────────────────── void loop() { updateServo(); if (Serial.available() > 0) { char input = Serial.read(); if (input == '0') { currentMode = 0; showFabLab(); Serial.println("Mode: Hello Fab Lab"); } else if (input == '1') { currentMode = 1; Serial.println("Mode: Humidity"); readAndDisplay(); lastSensorRead = millis(); } else if (input == '2') { currentMode = 2; Serial.println("Mode: Temperature (Celsius)"); readAndDisplay(); lastSensorRead = millis(); } else if (input == '3') { currentMode = 3; Serial.println("Mode: Temperature (Fahrenheit)"); readAndDisplay(); lastSensorRead = millis(); } else if (input == '5') { servoEnabled = false; myServo.write(0); // return to rest delay(500); // wait to reach position myServo.detach(); // cut signal — no jitter servoAngle = 0; sweeping = true; showServoOff(); Serial.println("Servo: OFF"); } else if (input == '6') { servoEnabled = true; servoAngle = 0; sweeping = true; myServo.attach(SERVO_PIN, 500, 2400); myServo.write(0); delay(300); showServoOn(); Serial.println("Servo: ON"); } else if (input != '\n' && input != '\r') { Serial.println("Invalid. Send 0, 1, 2, 3, 5 or 6."); } } // Auto-refresh sensor display every 2 seconds if (currentMode >= 1 && currentMode <= 3 && millis() - lastSensorRead >= SENSOR_INTERVAL) { lastSensorRead = millis(); readAndDisplay(); } }