#include "DHT20.h" #define SERVO_PIN A3 #define LEVEL_UP_PIN A0 #define LEVEL_DOWN_PIN A1 #define HUMID_CHECK_PIN A2 #define LEVEL_CHECK_PIN 3 #define LED_PIN 2 #define ONBOARD_LED_PIN 13 // 0 blink ~ 40.0 // 1 blink 40.0 ~ 42.5 // 2 blinks 42.5 ~ 45.0 // 3 blinks 45.0 ~ 47.5 // 4 blinks 47.5 ~ 50.0 // 5 blinks 50.0 ~ 52.5 // 6 blinks 52.5 ~ 55.0 // 7 blinks 55.0 ~ 57.5 // 8 blinks 57.5 ~ 60.0 // 9 blinks 60.0 ~ 62.5 // 10 blinks 62.5 ~ 65.0 // 11 blinks 65.0 ~ #define NUM_LEVELS 11 #define INTERVAL 2.5f #define HUMID_LEVEL0 40.0f #define HUMID_LEVEL1 42.5f #define HUMID_LEVEL2 45.0f #define HUMID_LEVEL3 47.5f #define HUMID_LEVEL4 50.0f #define HUMID_LEVEL5 52.5f #define HUMID_LEVEL6 55.0f #define HUMID_LEVEL7 57.5f #define HUMID_LEVEL8 60.0f #define HUMID_LEVEL9 62.5f #define HUMID_LEVEL10 65.0f float LEVELS[NUM_LEVELS] = { HUMID_LEVEL0, // 40.0 ~ 42.5 1 blink HUMID_LEVEL1, // 42.5 ~ 45.0 2 blinks HUMID_LEVEL2, // 45.0 ~ 47.5 3 blinks HUMID_LEVEL3, // 47.5 ~ 50.0 4 blinks HUMID_LEVEL4, // 50.0 ~ 52.5 5 blinks HUMID_LEVEL5, // 52.5 ~ 55.0 6 blinks HUMID_LEVEL6, // 55.0 ~ 57.5 7 blinks HUMID_LEVEL7, // 57.5 ~ 60.0 8 blinks HUMID_LEVEL8, // 60.0 ~ 62.5 9 blinks HUMID_LEVEL9, // 62.5 ~ 65.0 10 blinks HUMID_LEVEL10}; // 65.0 ~ 67.5 11 blinks #define MIN_MODE_DURATION 180000 // 3 minutes DHT20 DHT; int currentLevel = 4; // 50.0 ~ 52.5 (5 blinks) long modeInTime = -MIN_MODE_DURATION; float getHumidity() { DHT.readStatus(); DHT.read(); #ifdef ARDUINO_AVR_UNO float h = DHT.getHumidity(); Serial.print("hum="); Serial.print(h); Serial.print(" currentlev="); Serial.print(currentLevel); Serial.print(" onvalue="); Serial.print(turnOnHumidityValue()); Serial.print(" offvalue="); Serial.println(turnOffHumidityValue()); return h; #else return DHT.getHumidity(); #endif } float turnOnHumidityValue() { return LEVELS[currentLevel]; } float turnOffHumidityValue() { return turnOnHumidityValue() + INTERVAL; } void moveToHomePosition(int numLoops=30, int delayPeriod=1000) { for (int j = 0; j < numLoops; ++j) { digitalWrite(SERVO_PIN, HIGH); delayMicroseconds(500); digitalWrite(SERVO_PIN, LOW); delayMicroseconds(20000 - 500); } delay(delayPeriod); } void ledBlink(int num) { for(int i = 0; i < num; ++i) { digitalWrite(LED_PIN, LOW); delay(300); digitalWrite(LED_PIN, HIGH); delay(300); } } void blinkHumidLevel(float humidity) { int humidLevel = 0; for (int i = 0; i < NUM_LEVELS; ++i) { if (humidity < LEVELS[i]) { break; } ++humidLevel; } ledBlink(humidLevel); } void pressSwitch() { for (int j = 0; j < 200; ++j) { digitalWrite(SERVO_PIN, HIGH); delayMicroseconds(2400); digitalWrite(SERVO_PIN, LOW); delayMicroseconds(20000 - 2400); } moveToHomePosition(); } bool isButtonPressed(int pin) { if (digitalRead(pin) == LOW) { delay(5); if (digitalRead(pin) == LOW) { return true; } } return false; } int numLevelChanges(float humidity) { int count = 0; unsigned long start = millis(); while(millis() - start < 500) { if (isButtonPressed(LEVEL_UP_PIN)) { ++count; while(digitalRead(LEVEL_UP_PIN) == LOW){} start = millis(); } else if (isButtonPressed(LEVEL_DOWN_PIN)) { --count; while(digitalRead(LEVEL_DOWN_PIN) == LOW){} start = millis(); } else if (isButtonPressed(HUMID_CHECK_PIN)) { blinkHumidLevel(humidity); return 0; } else if (isButtonPressed(LEVEL_CHECK_PIN)) { ledBlink(currentLevel + 1); return 0; } } return count; } void handleButtons(float humidity) { int numChanges = numLevelChanges(humidity); if (numChanges != 0) { currentLevel += numChanges; currentLevel = min(max(currentLevel, 0), NUM_LEVELS - 1); ledBlink(currentLevel + 1); } } void turnOnMode() { #ifdef ARDUINO_AVR_UNO static bool isOnBoardLedOn = false; #endif moveToHomePosition(); // beep; pressSwitch(); // turn on; float humidity = 0.0f; modeInTime = millis(); while(humidity < turnOffHumidityValue() || millis() - modeInTime <= MIN_MODE_DURATION) { #ifdef ARDUINO_AVR_UNO Serial.print("turnOnMode hum="); Serial.print(humidity); Serial.print(" off="); Serial.print(turnOffHumidityValue()); Serial.print(" durationSec="); Serial.println((millis() - modeInTime) / 1000); #endif isOnBoardLedOn = !isOnBoardLedOn; digitalWrite(ONBOARD_LED_PIN, isOnBoardLedOn); humidity = getHumidity(); handleButtons(humidity); } moveToHomePosition(); // beep; pressSwitch(); // turn off } void setup() { #ifdef ARDUINO_AVR_UNO Serial.begin(9600); Serial.println("setup"); pinMode(ONBOARD_LED_PIN, OUTPUT); digitalWrite(ONBOARD_LED_PIN, LOW); #endif pinMode(SERVO_PIN, OUTPUT); pinMode(LEVEL_UP_PIN, INPUT_PULLUP); pinMode(LEVEL_DOWN_PIN, INPUT_PULLUP); pinMode(HUMID_CHECK_PIN, INPUT_PULLUP); pinMode(LEVEL_CHECK_PIN, INPUT_PULLUP); pinMode(LED_PIN, OUTPUT); pinMode(SDA, INPUT); // LET DHT20 pull up the line pinMode(SCL, INPUT); // LET DHT20 pull up the line digitalWrite(LED_PIN, HIGH); moveToHomePosition(); // Test servo position pressSwitch(); delay(1000); pressSwitch(); DHT.begin(); Wire.setClock(400000); delay(1000); blinkHumidLevel(getHumidity()); } void loop() { #ifdef ARDUINO_AVR_UNO digitalWrite(ONBOARD_LED_PIN, LOW); #endif float humidity = getHumidity(); #ifdef ARDUINO_AVR_UNO Serial.print("turnOffMode hum="); Serial.print(humidity); Serial.print(" on="); Serial.print(turnOnHumidityValue()); Serial.print(" durationSec="); Serial.println((millis() - modeInTime) / 1000); #endif if (humidity < turnOnHumidityValue() && millis() - modeInTime > MIN_MODE_DURATION) { turnOnMode(); } handleButtons(humidity); }