Ash 发表于 2017-11-2 14:45:35

物联网植物土壤湿度通知器

在植物湿度过低时向你发送短信或拨打电话,还能通过精美的液晶显示屏 (LCD) 提供植物健康的相关信息。创建日志
简介
DFRobot的妙想家们找到我,想要用他们开发的神奇的土壤湿度传感器和12C LCD1602做一个项目。认真思考后,我决定创造一个植物监测仪,而DFRobot则为我提供必要的硬件。我决定制作一个仅由Particle Photon物联网开发板驱动的简易盒子。
该装置每隔30分钟就会检测一次土壤的湿度状况,判断其是否过于干燥。如果检测到湿度较低,装置会触发一个事件,然后由IFTTT通过短信、电话或电子邮件通知你土壤缺水。装置上方还配有一个RGB LED灯,其中绿灯表示植物土壤湿度状况良好,蓝色表示植物土壤湿度过低。

LCD1602可指示植物土壤湿度状况的好坏。
组件
所需硬件组件:
[*]Particle Photon
[*]土壤湿度传感器(兼容Arduino)
[*]I2C LCD1602液晶模块(兼容Arduino)
[*]散射型RGB LED灯
[*]Micro USB连接器
[*]Uxcell万能电路板 (4x6 cm)

应用程序与在线服务:
[*]Particle云集成开发环境
[*]IFTTT Maker 服务

手工工具与制作设备:
[*]焊铁(通用型)
[*]Millright数控雕刻机M3


设计
首先,将各个组件以及Micro USB电源连接器连接到Particle Photon上。我加载了一些可在LCD上简略显示湿度的测试代码。代码运行成功后,我开始使用Fusion 360建模。我将此装置的形状设计为矩形棱柱,其正面、顶部以及背面分别配有LCD、LED和Micro USB接口。


我还留了一个小洞,土壤湿度传感器可通过此孔布线。至于图案设计,我想以绿色为底,其上绘制一些黄色花卉图案。
制作
我的Fusion 360设计可用于数控雕刻,所以我把所有部件平稳地放在一个平面上,并从加工路径生成Gcode。接下来,我把准备的一张10.5" x 10.5" x 1/4"胶合板,放置于Millright数控机床上,开始切割各个部件。我还对各个部件进行打磨,使其边缘更为平滑,更具美感。
文件链接:https://gallery.autodesk.com/pro ... -plant-soil-monitor
美化
首先,准备材料:经过数控雕刻的胶合板、一罐绿色喷漆、一罐虫胶、一小瓶黄色丙烯酸漆、若干150-400目砂纸、一瓶木胶和一个砂光机。

我先依次使用低目数和高目数砂纸彻底打磨各个部件。

在所有部件已被充分打磨后,我将底部、侧面和背面粘合在一起。接下来,我为各个部件喷涂了两层虫胶,之后再均匀喷上几层绿漆。
组装
所有部件都喷漆上色后,把电子元件放于外壳内部,并用热胶将其固定。我还通过侧面的小孔将土壤湿度传感器的电线与Photon相连接。我还专门隔出了一小块区域,以便在装置停用时存放传感器和电线。

编程
我在Particle Photon的云集成开发环境中加载了附图,并将其发送到我的Photon。顶部的RGB LED灯闪烁5次,表示Photon已成功启动并连接。编写代码时,我设置的是当湿度低于15%时,Photon会生成一个名为“浇水”的事件,触发IFTTT小程序。

用法
使用此装置时,只需把湿度传感器放入盆栽植物的土壤中,并将Micro USB数据线插入连接器,为装置供电 (5V)。之后,设置好IFTTT小程序,使其在收到Particle Photon服务发送的名为“干燥”的事件时发短信通知我。

它会通过电子邮件发送:“您的植物需要浇水!”。此外,装置上的LCD会显示土壤水分的百分比以及植物的健康状况。现在,你再也不用担心植物是否缺水了。

连线图

代码//DFRobot.com
//Compatible with the Arduino IDE 1.0
//Library version:1.1


#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define BLUE_PIN A3
#define GREEN_PIN A4
#define SOIL_SENSOR A1

//#define RESOLUTION 1024 //Use for 10 bit resolution ADC (Arduino)
#define RESOLUTION 4096 //Use for 12 bit resolution ADC (Particle Photon)

#define DEBUG_VALS //Comment if you don't want values published to the Particle Cloud

LiquidCrystal_I2C lcd(0x20,16,2);// set the LCD address to 0x20(Cooperate with 3 short circuit caps) for a 16 chars and 2 line display
int level;

/*byte one_bar = {
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    B11111
};

byte two_bar = {
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    B11111,
    B11111
};

byte three_bar = {
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    B11111,
    B11111,
    B11111
};

byte four_bar = {
    B00000,
    B00000,
    B00000,
    B00000,
    B11111,
    B11111,
    B11111,
    B11111
};

byte five_bar = {
    B00000,
    B00000,
    B00000,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111
};

byte six_bar = {
    B00000,
    B00000,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
};

byte seven_bar = {
    B00000,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111
};

byte eight_bar = {
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111
}; */

bool is_spam = false;
   
void debug_values(int raw_value){
    Particle.publish("soil_values_raw", String(raw_value));
}

void setup(){

   /*lcd.createChar(0, one_bar);
   lcd.createChar(1, two_bar);
   lcd.createChar(2, three_bar);
   lcd.createChar(3, four_bar);
   lcd.createChar(4, five_bar);
   lcd.createChar(5, six_bar);
   lcd.createChar(6, seven_bar);
   lcd.createChar(7, eight_bar);*/

pinMode(BLUE_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
pinMode(SOIL_SENSOR, INPUT);
lcd.init();                      // initialize the lcd
lcd.backlight();

lcd_clear();

lcd.setCursor(0, 0);
lcd.print("Plant hydration");
lcd.setCursor(0, 1);
lcd.print("monitor");
delay(4000);
}

void loop(){

int reading2 = take_reading();

float reading = reading2;

lcd.print("Water level:");
lcd.setCursor(0,1);
lcd.print(reading);
delay(1000);

#ifdef DEBUG_VALS
debug_values(reading);
#endif

Particle.publish("level", String(reading));

if(reading >= .95*RESOLUTION){
      lcd_clear();
      lcd.print("Did you water");
      lcd.setCursor(0,1);
      lcd.print("too much?");
      level = 16;
}
else if(reading >= .85*RESOLUTION){
      lcd_clear();
      lcd.print("That's plenty");
      level = 14;
}
else if(reading >= .78*RESOLUTION){
      lcd_clear();
      lcd.print("Thanks for all");
      lcd.setCursor(0,1);
      lcd.print("of that water");
      level = 13;
}
else if(reading >= .70*RESOLUTION){
      lcd_clear();
      lcd.print("Woah, that's");
      lcd.setCursor(0,1);
      lcd.print("a good drink");
      level = 12;
}
else if(reading >= .65*RESOLUTION){
      lcd_clear();
      lcd.print("That makes me");
      lcd.setCursor(0,1);
      lcd.print("very happy");
      level = 11;
}
else if(reading >= .60*RESOLUTION){
      lcd_clear();
      lcd.print("I love you");
      lcd.setCursor(0,1);
      lcd.print("more now");
      level = 10;
}
else if(reading >= .55*RESOLUTION){
      lcd_clear();
      lcd.print("Meh, almost");
      lcd.setCursor(0,1);
      lcd.print("time for more");
      level = 9;
}
else if(reading >= .50*RESOLUTION){
      lcd_clear();
      lcd.print("Did you water");
      lcd.setCursor(0,1);
      lcd.print("too much?");
      level = 8;
}
else if(reading >= .45*RESOLUTION){
      lcd_clear();
      lcd.print("Still pretty");
      lcd.setCursor(0,1);
      lcd.print("content");
      level = 7;
}
else if(reading >= .40*RESOLUTION){
      lcd_clear();
      lcd.print("Get ready for");
      lcd.setCursor(0,1);
      lcd.print("some watering!");
      level = 6;
}
else if(reading >= .35*RESOLUTION){
      lcd_clear();
      lcd.print("I'm still");
      lcd.setCursor(0,1);
      lcd.print("waiting");
      level = 5;
}
else if(reading >= .30*RESOLUTION){
      lcd_clear();
      lcd.print("OK, water me");
      lcd.setCursor(0,1);
      lcd.print("I'm very thirsty");
      level = 4;
}
else if(reading >= .22*RESOLUTION){
      lcd_clear();
      lcd.print("Still no water?");
      lcd.setCursor(0,1);
      lcd.print("You're mean");
      level = 3;
}
else if(reading >= .15*RESOLUTION){
      lcd_clear();
      lcd.print("Water please");
      lcd.setCursor(0,1);
      lcd.print("it's dry here!");
      level = 2;
}
else if(reading >= .08*RESOLUTION){
      lcd_clear();
      lcd.print("I'm about");
      lcd.setCursor(0,1);
      lcd.print("to die");
      level = 1;
}
else if(reading >= .04*RESOLUTION){
      lcd_clear();
      lcd.print("Blahhh :(");
      lcd.setCursor(0,1);
      lcd.print("you killed me");
      level = 0;
}
delay(3000);
eval_level();
delay(4000);
lcd_clear();
no_green();

}

void eval_level(){
    if(level>8){
      solid_green();
    }
    else if(level<8 && level != 0){
      blink_blue(8, 250);
      if(is_spam==false){
      Particle.publish("dry", "True");
      }
      is_spam = true;
    }
    else if(level==8){
      blink_blue(3, 250);
    }
    else if(level==0){
      blink_blue(10, 250);
    }
}

int take_reading(){
    lcd_clear();
    lcd.print("Taking reading");
    int amount = analogRead(SOIL_SENSOR);
    delay(1000);
    lcd_clear();
    return amount;
}

void blink_blue(int number_of_loops, int duration){
    for(int i=0; i< number_of_loops; i++){
      digitalWrite(BLUE_PIN, 1);
      delay(duration);
      digitalWrite(BLUE_PIN, 0);
      delay(duration);
    }
}

void solid_green(){
    digitalWrite(GREEN_PIN, 1);
}

void no_green(){
    digitalWrite(GREEN_PIN, 0);
}

void lcd_clear(){
    lcd.clear();
    lcd.setCursor(0,0);
}
此项目制作人为Arduino “having11” Guy,请点击这里查看原帖。来自DFRobot英文网站,转载需私信授权。

Miko 发表于 2021-4-17 22:27:05

这真不戳。。。。。。
页: [1]
查看完整版本: 物联网植物土壤湿度通知器