安全设备/系统
NodeMCU ESP8266 板可监控植物的土壤水分,并在需要浇水时通过 Telegram 通知您!
为什么要做这个项目?
我可能是万千个一直忘记给植物浇水的人其中的一份子,有多少植物因为你忘记了你甚至在家里有它们而枯萎?
我就是其中之一,因此我决定创建一个项目,让我知道我什么时候没有给我的鳄梨植物浇水。
目标
起初的目标只是需要知道我什么时候需要给植物浇水。但既然我正在开发这个工具,为什么不添加一些额外的选项,比如能够按需检查鳄梨的表现。
硬件
我使用了一个 Arduino 兼容板“WeMos D1 NodeMcu Lua V3 CH340G ESP8266”,可以在 eBay 上购买。
还选择了“ESP8266板”,因为内置wifi功能和便宜的价格。我们不需要太多的电力,所以没有必要使用 ESP-32 板。
要知道鳄梨是否需要浇水,我使用了土壤湿度传感器 YL-69(或 YL-39)。通过它的电极,我们可以确定植物土壤的干燥程度。该传感器也可在 eBay 上购买。
传感器有一个电位器,可以校准返回的值。
该板将使用 VIN 和 GND 引脚由 9V 电池供电。
注意:根据您使用的威廉希尔官方网站 板,输入电压可能会有所不同。在某些情况下,允许的输入会写在板上。
软件
Arduino IDE 用于该项目。
第一步是创建一个 Telegram 机器人。由于网上已经有很多关于如何做到这一点的教程,这一步我就不做过多解释。请参阅下面的链接以开始使用。
如果您不想使用 Telegram 机器人,可以使用IFTTT 。
为了与机器人通信,我使用了 Giancarlo Bacchio 开发的“ ESP8266-TelegramBot ”库,该库可在此找到。
为了能够在我需要给植物浇水时收到通知,我设置了一个 Telegram 机器人来向我发送通知。每隔 24 小时,系统会检查状态并在达到关键限制时通知我。
由于 Telegram 机器人为我们提供了相当大的自由度,因此我实现了一个额外的命令来随时读取传感器值。
根据土壤的不同,从传感器读取的值可能与我的示例不同。以下是电位器完全逆时针旋转(最小值)时返回的值。
浇水后: 460
24 小时后:420
48 小时后:380
我通常每 2 天给鳄梨浇一次水,所以我决定使用400作为临界值。一旦读取的值低于此值,我将收到通知。
警告
为避免损坏传感器,我们仅在读取土壤湿度时才将其通电。因此,它不是直接连接到 3.3V 引脚,而是连接到数字引脚之一。
未来的拓展
这个项目的一个改进是添加一些视觉效果,也许是一个 LED,它可以通过将颜色从绿色变为黄色再变为红色来为您提供状态。
另一种选择是通过使用运行在 3.3V/8MHz 的 Arduino Pro Mini 和 ESP-01 来延长电池寿命。
如果您想更在此基础上更进一步,您还可以使用水泵构建一个自动浇水系统!
Avocado Watering Monitor:
/*
Avocado Watering Monitor
Board used: WeMos D1 NodeMcu Lua V3 ESP8266
Sensor: YL-69 / YL-39 Soil Moisture Sensor
By g4x - 01/2018
*/
#include
#include
#include
// YL-69 sensor
#define moistureCriticalLevel 400
byte pinMoistureSensor = A0;
byte pinMoistureVCC = 4; // D2
int moistureValue;
// protothreading
int moistureReadingInterval = 86400; // interval in seconds between sensor reading (every 24h)
long moistureLastRead = 0; // last time the moisture was read
int botScanInterval = 1; // interval time between scan messages (seconds)
long botLastScan; // last time messages' scan has been done
long nowMillis;
// WiFi connection
const char* ssid = "Mr.Robot"; // wifi name
const char* password = "********"; // wifi password
// Telegram bot
#define botMyChatID "********" // reference to my phone's chat
#define botToken "********"
#define botName "********";
#define botUsername "********"
TelegramBOT bot(botToken, botName, botUsername);
String botCommand;
String botResponse;
void setup() {
Serial.begin(9600);
delay(1000);
// init the moisture sensor
pinMode(pinMoistureSensor, INPUT);
pinMode(pinMoistureVCC, OUTPUT);
digitalWrite(pinMoistureVCC, LOW); // by default, we do not power the sensor
// connect to wifi
Serial.print("Connecting to \"");
Serial.print(ssid);
Serial.println("\"");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("WiFi connected (");
Serial.print(WiFi.localIP());
Serial.println(")");
Serial.println("");
// start bot
bot.begin();
}
void loop() {
checkSoilMoisture();
handleBotMessages();
}
void checkSoilMoisture() {
nowMillis = millis();
if ((nowMillis > moistureLastRead + (moistureReadingInterval * 1000)) or moistureLastRead == 0) {
moistureLastRead = nowMillis;
moistureValue = readMoisture();
if (moistureValue < moistureCriticalLevel) {
// send value to Telegram chat
botResponse = "Avocado: Water me! (Humidity Level [0-1023]: ";
botResponse.concat(moistureValue);
botResponse.concat(")");
bot.sendMessage(botMyChatID, botResponse, ""); // send notification to my phone
}
Serial.print("*************** Humidity Level (0-1023): ");
Serial.println(moistureValue);
Serial.println("");
}
}
int readMoisture() {
digitalWrite(pinMoistureVCC, HIGH); // power up sensor
delay(500);
int value = analogRead(pinMoistureSensor);
digitalWrite(pinMoistureVCC, LOW); // power down sensor
return 1023 - value;
}
/* Check if the bot received any message */
void handleBotMessages() {
nowMillis = millis();
if (nowMillis > botLastScan + (botScanInterval * 1000)) {
botLastScan = millis();
bot.getUpdates(bot.message[0][1]); // launch API GetUpdates up to xxx message
// loop at messages received
for (int i = 1; i < bot.message[0][0].toInt() + 1; i++) {
handleBotCommands(i);
}
bot.message[0][0] = ""; // All messages have been replied - reset new messages
}
}
/* Execute command sent to the bot */
void handleBotCommands(int line) {
botCommand = bot.message[line][5]; // message reiceived
botCommand.toUpperCase(); // not case sensitive anymore
if (botCommand.equals("/READ")) {
// read data
moistureValue = readMoisture();
//botResponse = "Sensor value: ";
botResponse = "Humidity Level (0-1023): ";
botResponse.concat(moistureValue);
if (moistureValue < moistureCriticalLevel) {
botResponse.concat(" (critical)");
}
} else if (botCommand.equals("/HELP")) {
botResponse = "Allowed commands are:";
bot.sendMessage(bot.message[line][4], botResponse, "");
botResponse = "/read - Read soil moisture";
bot.sendMessage(bot.message[line][4], botResponse, "");
botResponse = "/ip - Get local IP address";
} else if (botCommand.equals("HI") or botCommand.equals("HELLO") or botCommand.equals("COUCOU") or botCommand.equals("SALUT")) {
botResponse = "Hello " + bot.message[line][2] + " !"; // user's name
} else if (botCommand.equals("/IP")) {
botResponse = "Local IP address: ";
botResponse.concat(WiFi.localIP().toString());
} else {
botResponse = "Unknown command, use /help for command list.";
}
bot.sendMessage(bot.message[line][4], botResponse, ""); // bot.message[line][4] is chat ID
}
全部0条评论
快来发表一下你的评论吧 !