411214323林時寬
本學期在上一次的基礎裡改善了感測器的距離,新增濕度模組以防飼料放太久發霉長細菌,並且改善設備(如擋板以及黏貼在牆壁的可靠度等等)
運作邏輯:
當感測器在範圍內(我設定成10cm),沒有偵測到東西(剩餘飼料高度不夠時),使上方飼料桶的伺服馬達旋轉90度使飼料落下直到感測器重新偵測到東西。
當濕度模組偵測濕度為60%(含以上)超過24小時,使飯盆裡下方的伺服馬達旋轉90度,持續十秒(清空飯盆中可能已經產生黴菌、細菌等的飼料),十秒後旋轉回來蓋住底部,並使上方伺服馬達旋轉90度(打開飼料桶),直到感測器重新偵測到飼料。
程式碼:
#include <Servo.h>
#include <DHT.h>
#define DHTPIN 2
#define DHTTYPE DHT11
#define TRIG_PIN 9
#define ECHO_PIN 10
#define SERVO_TOP_PIN 5
#define SERVO_BOTTOM_PIN 6
#define HUMIDITY_THRESHOLD 60.0
#define FOOD_DISTANCE_THRESHOLD 10.0
#define DUMP_DURATION 10000UL
#define ONE_DAY 86400000UL
Servo servoTop;
Servo servoBottom;
DHT dht(DHTPIN, DHTTYPE);
unsigned long lastDumpTime = 0;
bool dumping = false;
unsigned long dumpStartTime = 0;
float getDistance() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH, 30000);
if (duration == 0) return 999;
return duration * 0.034 / 2;
}
void setup() {
Serial.begin(9600);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
servoTop.attach(SERVO_TOP_PIN);
servoBottom.attach(SERVO_BOTTOM_PIN);
servoTop.write(0);
servoBottom.write(0);
dht.begin();
lastDumpTime = millis();
}
void loop() {
unsigned long currentTime = millis();
float humidity = dht.readHumidity();
if (isnan(humidity)) return;
if (!dumping &&
humidity > HUMIDITY_THRESHOLD &&
(currentTime - lastDumpTime > ONE_DAY)) {
dumping = true;
dumpStartTime = currentTime;
servoBottom.write(90);
servoTop.write(0);
}
if (dumping) {
if (currentTime - dumpStartTime >= DUMP_DURATION) {
servoBottom.write(0);
dumping = false;
lastDumpTime = currentTime;
}
return;
}
float distance = getDistance();
if (distance > FOOD_DISTANCE_THRESHOLD) {
servoTop.write(90);
} else {
servoTop.write(0);
}
delay(500);
}
線路圖:
紅線:5V
綠線:訊號
黑線:接地
電源:行動電源或是電池
成品:
飼料桶
伺服馬達(擋板)
飯盆
(
超音波測距模組
濕度模組
)
飯盆
伺服馬達(擋板)