chottoshitahanashi’s diary

基本的に間違ったことばかり書いてるブログ。検索ひっかかるな

加湿器コントロールコード

#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);
}