本帖最后由 暮光 于 2024-4-7 18:49 编辑
上次做了一个物联网氛围灯,有点太简单了。想到FireBeetle 2 ESP32 C6是有太阳能接口和锂电池接口的,应当物尽其用啊。正好最近买了一盆郁金香,天天浇水有点烦正好可以做一个自动浇花系统。用18650电池供电,太阳能板给它充电。理论上可以实现免费充电了。
有句老话说得好“世界上的发明创造都是懒人做出来的”
一 物料准备:
1. FireBeetle 2 ESP32 C6 开发板
2. 土壤湿度传感器。(电容式的更耐用不容易生锈)
3. 继电器模块
4. 抽水泵
5. 杜邦线 若干
6. 18650 3.7v 锂电池, (pH2.0 2p接口的,因为C6板子的接口是这种)
7. 太阳能电池板 5v 200ma (我在室内测得有点不准,在室外太阳直射时 电压能到5.8V)
理论上是可以为锂电池充电的。
二 工作原理
自动浇花的原理是通过土壤湿度传感器监测土壤湿度,低于设定值时,继电器设置高电平给水泵供电,水泵抽水3秒钟,给花浇水。
当土壤湿度高于设定值时,继电器设置低电平给水泵断电,水泵不工作。
当然也可以加入手动控制浇水。
收集的土壤湿度数据通过巴法云 mqtt 回传到手机,用appinventor 编写一个简单的安卓app 可以实时查看土壤湿度,和手动浇水。
三线路设计
线路连接其实很简单,跟上一篇一样正极 接3v3 负极接gnd 信号线接自定义的引脚,这回多了一个土壤传感器的引脚。
四 代码分享
- #include <WiFi.h>
- #include <PubSubClient.h>
-
- // WiFi设置
- const char* ssid = "ssid"; //替换自己的wifi
- const char* password = "password";
-
- // MQTT设置
- const char* mqttServer = "bemfa.com";
- const int mqttPort = 9501;
- const char* mqttUID = "xxxxxxxxxxxxxxxxxxxxxxxxxxx"; //替换自己的巴法云密钥
- const char* mqttUserName = "xxxxxxxx"; //巴法云账号
- const char* mqttPassWord = "xxxxxxxx"; //巴法云密码
- const char* mqttTopic = "manualwatering"; //订阅主题
-
- WiFiClient espClient;
- PubSubClient client(espClient);
- bool subTopicCenterFlag = false;
-
- // 土壤湿度设置
- const int soilHumidityPin = 5;
- const int relayPin = 23;
- const int LED_PIN = LED_BUILTIN;
- int soilHumidityThreshold = 50;
-
- void setup() {
- Serial.begin(9600);
- pinMode(soilHumidityPin, INPUT);
- pinMode(relayPin, OUTPUT);
- pinMode(LED_PIN, OUTPUT);
- digitalWrite(relayPin, HIGH);
- digitalWrite(LED_PIN, LOW);
-
- // 连接WiFi
- WiFi.begin(ssid, password);
- while (WiFi.status() != WL_CONNECTED) {
- delay(500);
- Serial.print(".");
- }
- Serial.println("WiFi Connected");
- digitalWrite(LED_PIN, HIGH);
-
- // 设置MQTT服务器和回调函数
- client.setServer(mqttServer, mqttPort);
- client.setCallback(callback);
- }
-
- void loop() {
- if (!client.connected()) {
- reconnect();
- }
- client.loop();
-
- // 土壤湿度检测和控制逻辑
- int rawSoilHumidity = analogRead(soilHumidityPin);
- int soilHumidity = map(rawSoilHumidity, 950, 2250, 100, 0);
- Serial.print(rawSoilHumidity);
- Serial.print("土壤湿度: ");
- Serial.print(soilHumidity);
- Serial.println("%RH");
-
- if (soilHumidity < soilHumidityThreshold) {
- digitalWrite(relayPin, LOW);
- Serial.println("正在浇水...");
- delay(3000);
- digitalWrite(relayPin, HIGH);
- }
- delay(3000);
- }
-
- void manualWatering() {
- digitalWrite(relayPin, LOW); // 打开继电器,开始浇水
- Serial.println("手动浇水开始...");
- delay(3000); // 浇水3秒钟
- digitalWrite(relayPin, HIGH); // 关闭继电器,停止浇水
- Serial.println("手动浇水结束.");
- }
- void reconnect() {
- while (!client.connected()) {
- Serial.print("Attempting MQTT connection...");
- if (client.connect(mqttUID, mqttUserName, mqttPassWord)) {
- Serial.println("connected");
- subTopicCenterFlag = true;
- } else {
- Serial.print("failed, rc=");
- Serial.print(client.state());
- Serial.println(" try again in 5 seconds");
- delay(5000);
- }
- }
- if (subTopicCenterFlag) {
- subTopicCenterFlag = false;
- client.subscribe(mqttTopic);
- }
- }
-
- void callback(char* topic, byte* payload, unsigned int length) {
- String message;
- for (int i = 0; i < length; i++) {
- message += (char)payload[i];
- }
- publishSoilHumidity(); //添加这一行代码,将土壤湿度实时监测并回传至mqtt的manualwatering主题。
- Serial.print("Message arrived [");
- Serial.print(topic);
- Serial.print("] ");
- Serial.println(message);
-
- if (message == "00") {
- manualWatering();
- }
- }
- void publishSoilHumidity() {
- int rawSoilHumidity = analogRead(soilHumidityPin);
- int soilHumidity = map(rawSoilHumidity, 950, 2250, 100, 0);
- String soilHumidityStr = String(soilHumidity);
- client.publish("manualwatering", soilHumidityStr.c_str());
- }
-
复制代码
其中因为土壤湿度传感器输出的是模拟信号它转换成的数字信号是四位的,要用个map函数把它转换成(0-100)然后再去判断。 把它放到水中会输出一个数值 就当作100,把它擦干放到空气中就是0,代码中有体现。
五实际效果演示请看视频
app的功能很简单 大家可以自行搜索相关教程。
六写在最后
通过这次试用,对编程 物联网 app 的相关知识有了不少了解和收获,再次感谢DF官方给了这次试用机会!后续还会持续开发新功能。
不断学习无限进步!
|