这个电路并不难。这里我们使用了4个传感器,即DHT11,DS18B20传感器探头,LDR和土壤湿度传感器,一个12VLED灯条,12V水泵,7805稳压器,以及两个TP122晶体管来控制LED灯条和水泵。7805用于从12V适配器获得稳压5V,DHT11传感器用于获取温度和湿度读数。DS18B20传感器探头用于获取土壤温度,土壤湿度传感器用于读取土壤湿度,以便自动打开/关闭水泵。
AdafruitIO设置
要使用AdafruitIO,首先,您必须在AdafruitIO上创建一个帐户。为此,请访问AdafruitIO网站并单击屏幕右上角的“免费入门”。
当您“AIO密钥”时,将弹出一个窗口,其中包含您的AdafruitIOAIO密钥和用户名。复制此密钥和用户名。您稍后将在代码中使用它。
现在,在此之后,您需要创建一个提要。要创建提要,请单击“提要”。然后单击“操作”,您将看到一些选项,从中单击“创建新提要”。
之后,将打开一个新窗口,您需要在其中输入提要的名称和描述。书写描述是可选的。
点击“创建”;在此之后,您将被重定向到新创建的提要。
对于这个项目,我们总共为水泵、LED灯条、湿度数据、温度、湿度、天气数据和土壤温度创建了8个源。按照与上述相同的过程创建其余的提要。
创建提要后,现在我们将创建一个AdafruitIO仪表板,以在单个页面上显示所有这些提要。为此,首先创建一个仪表板,然后在该仪表板中添加所有这些提要。
要创建仪表板,请单击仪表板选项,然后单击“操作”,然后单击“创建新仪表板”。
在下一个窗口中,输入仪表板的名称,然后单击“创建”。
创建仪表板后,现在我们将块添加到仪表板。要添加块,请单击右上角的“齿轮”,然后单击“创建新块”。
首先,我们将添加两个切换按钮块来手动打开/关闭LED灯条和水泵,然后添加四个滑块来显示温度、湿度、土壤温度和水分值,最后,两个图表块来显示最近30天的水分和土壤温度数据。要在仪表板上添加按钮,请单击Toggle块。
在下一个窗口中,它将要求您选择提要,因此单击LED提要。
在此之后,按照相同的过程添加其余的块。添加所有块后,我的仪表板如下所示:
您可以通过单击设置按钮来编辑仪表板。
如前所述,我们还将在AdafruitIO仪表板上显示天气预报,为此,我们将使用OpenWeatherMapAPI请求所选位置的当天天气预报。OpenWeatherMap提供了高度可识别的天气产品,使处理天气数据变得更加容易。可以通过遵循行业标准并与不同类型的企业系统兼容的快速、可靠的API访问这些数据。OpenWeatherMap提供付费和免费计划,在这个项目中,我们将使用它的免费计划来获取天气预报数据。
现在我们将使用5天/3小时的预测数据API。此API包含间隔3小时的天气预报数据,并且预报数据以JSON或XML格式提供。要获取您选择的位置的天气数据,请输入以下URL,将大括号中的部分替换为城市和您的唯一API密钥:
例如,我们的APIURL将是:
将此URL粘贴到浏览器的搜索栏中,它应该会为您提供一堆与您当地的天气预报信息相对应的信息。
然后在下一部分中,粘贴JSON数据。
然后在最后一步,您将获得读取天气预报数据的代码。我们不会使用助手生成的完整代码。
将库安装到ArduinoIDE后,通过包含所需的库文件来启动代码。
#include#include<达拉斯温度.h>#include#include"DHT.h"#include"Adafruit_MQTT.h"#include"Adafruit_MQTT_Client.h"#include
constchar*ssid="Wi-Fi名称";constchar*pass="Wi-Fi密码";#defineMQTT_SERV"io.adafruit.com"#defineMQTT_PORT1883#defineMQTT_NAME"AdafruitIO用户名"#defineMQTT_PASS"AIO密钥"
然后设置用于存储传感器数据和控制LED和水泵的AdafruitIO馈送。在我的例子中,我定义了四个馈送来存储不同的传感器数据,即:土壤温度、温度、湿度和湿度,一个用于显示天气数据的馈送和两个用于控制LED灯条和水泵的馈送。
现在在setup()函数中,以9600的波特率初始化串行监视器以进行调试。同时使用begin()函数初始化DHT传感器和DS18B20传感器。
无效设置(){序列号.开始(9600);延迟(10);dht.begin();传感器.开始();………………..}
现在是voidloop()。这是执行所有任务的地方。因此,在这个循环中,首先我们将从OpenWeatherMapAPI获取天气预报数据,然后我们将读取传感器数据,最后一步,我们将在AdafruitIO仪表板上发布所有这些数据。
阅读天气预报:
读取传感器数据:
现在获取天气数据后,接下来我们将读取所有传感器数据。这里我们使用DHT11、DS18B20、LDR和土壤湿度传感器。LDR和土壤湿度传感器数据将用于自动化LED灯条和水泵。所以首先我们将读取LDR状态,如果LDR读数小于200,则LED将自动打开。同样,如果土壤水分百分比小于35,则水泵将打开。
在AdafruitIO上发布数据:
现在我们已经收集了所有数据,是时候在AdafruitIO仪表板上发布这些数据了,以便我们可以从任何地方对其进行监控。在这里,我们会将不同的传感器数据发布到各自的提要中。
if(currentTime-previousTime>=间隔){if(!Moisture.publish(moisturePercentage))如果(!温度。发布(温度))如果(!湿度。发布(湿度))if(!SoilTemp.publish(soiltemp))如果(!WeatherData.publish(图标))}
用于智能农业系统的3D打印外壳
由于这个项目将用于农业应用,我决定3D打印一个外壳。我用游标测量了装置的尺寸来设计外壳。完成后,我的设计看起来像这样:
对设计满意后,我将其导出为STL文件,根据打印机设置对其进行切片,最后打印出来。STL文件也可以从Thingiverse下载,您可以使用它打印自己的外壳。
打印完成后,我继续将项目设置组装在一个永久外壳中以备将来使用。完成连接后,我将电路组装到我的外壳中,一切都非常合适,如下所示:
测试智能农业系统
为了测试这个项目,我在塑料托盘中发了一些种子,如下图所示:
#include
#include"DHT.h"
#include"Adafruit_MQTT.h"
#include"Adafruit_MQTT_Client.h"
constchar*ssid="银河-M20";//输入您的WiFi名称
WiFiClient客户端;
#defineMQTT_SERV"io.adafruit.com"
#defineMQTT_PORT1883
#defineMQTT_NAME"aschoudhary"//你的AdafruitIO用户
名#defineMQTT_PASS"1ac95cb8580b4271bbb6d9f75d0668f1"//AdafruitIOAIOkey
constcharserver[]="api.openweathermap.org";
字符串apiKey="e8b22b36da932dce8f31ec9be9cb68a3";
字符串文本;
intjsonend=0;
布尔startJson=假;
int状态=WL_IDLE_STATUS;
#defineJSON_BUFF_DIMENSION2500
constunsignedlongpostInterval=10*60*1000;//发布间隔10分钟(10L*1000L;测试延迟10秒)
constintldrPin=D1;
常量intledPin=D0;
常量int湿气Pin=A0;//湿度传感器引脚
constintmotorPin=D8;
漂浮水分百分比;//湿度读数
int温度,湿度,土壤温度;
#defineONE_WIRE_BUS4//nodemcu的D2引脚
#defineDHTTYPEDHT11//DHT11
#definedht_dpinD4
DHTdht(dht_dpin,DHTTYPE);
单线单线(ONE_WIRE_BUS);
constunsignedlong间隔=50000;
unsignedlongpreviousTime=0;
//设置您要发布到
Adafruit_MQTT_Clientmqtt(&client,MQTT_SERV,MQTT_PORT,MQTT_NAME,MQTT_PASS);
Adafruit_MQTT_PublishMoisture=Adafruit_MQTT_Publish(&mqtt,MQTT_NAME"/f/Moisture");//Moisture是将发布数据的源名称
Adafruit_MQTT_PublishTemperature=Adafruit_MQTT_Publish(&mqtt,MQTT_NAME"/f/Temperature");
Adafruit_MQTT_PublishHumidity=Adafruit_MQTT_Publish(&mqtt,MQTT_NAME"/f/Humidity");
Adafruit_MQTT_PublishSoilTemp=Adafruit_MQTT_Publish(&mqtt,MQTT_NAME"/f/SoilTemp");
Adafruit_MQTT_PublishWeatherData=Adafruit_MQTT_Publish(&mqtt,MQTT_NAME"/f/WeatherData");
//设置您订阅的订阅
源Adafruit_MQTT_SubscribeLED=Adafruit_MQTT_Subscribe(&mqtt,MQTT_NAME"/f/LED");
Adafruit_MQTT_SubscribePump=Adafruit_MQTT_Subscribe(&mqtt,MQTT_NAME"/f/Pump");
无效设置()
{
序列.开始(9600);
延迟(10);
dht.begin();
传感器.开始();
mqtt.subscribe(&LED);
mqtt.subscribe(&Pump);
pinMode(ledPin,输出);
pinMode(ldrPin,输入);
(ledPin,HIGH);
text.reserve(JSON_BUFF_DIMENSION);
Serial.println("正在连接");
序列号.println(ssid);
WiFi.开始(ssid,通过);
而(WiFi.status()!=WL_CONNECTED)
延迟(500);
Serial.print(".");//打印...直到没有连接
}
Serial.println("");
Serial.println("WiFi连接");
voidloop()
unsignedlongcurrentTime=millis();
MQTT_connect();
if(millis()-lastConnectionTime>
lastConnectionTime=millis();
//}
if(ldrStatus<=200){
digitalWrite(ledPin,HIGH);
Serial.print("天黑了,打开LED:");
Serial.println(ldrStatus);
else{
digitalWrite(ledPin,LOW);
Serial.print("它很亮,关闭LED:");
湿度百分比=(100.00-((analogRead(moisturePin)/1023.00)*100.00));
Serial.print("土壤水分=");
序列号.print(moisturePercentage);
序列号.println("%");
if(moisturePercentage<35){
digitalWrite(motorPin,HIGH);//调整电机
if(moisturePercentage>38){
digitalWrite(motorPin,LOW);//关闭电机
temperature=dht.readTemperature();
湿度=dht.readHumidity();
//Serial.print("温度:");
//Serial.print(温度);
//Serial.println();
//Serial.print("湿度:");
//Serial.print(湿度);
传感器.requestTemperatures();
土壤温度=传感器.getTempCByIndex(0);
//Serial.println("土壤温度:");
//Serial.println(soiltemp);
if(currentTime-previousTime>=Interval){
if(!Moisture.publish(moisturePercentage))//此条件用于在adafruitIO上发布变量(moisturePercentage)。根据你的改变变量。
if(!Temperature.publish(temperature))
if(!Humidity.publish(humanity))
//delay(30000);
if(!SoilTemp.publish(soiltemp))
if(!WeatherData.publish(icon))
Adafruit_MQTT_Subscribe*订阅;
while((subscription=mqtt.readSubscription(5000)))//在控制某些东西或从AdafruitIO获取数据之前不要使用这个。
if(subscription==&LED)
//将新值打印到串口监视器
Serial.println((char*)LED.lastread);
if(!strcmp((char*)LED.lastread,"OFF"))
if(!strcmp((char*)LED.lastread,"ON"))
if(subscription==&Pump)
Serial.println((char*)Pump.lastread);
if(!strcmp((char*)Pump.lastread,"OFF"))
digitalWrite(motorPin,HIGH);
if(!strcmp((char*)Pump.lastread,"ON"))
digitalWrite(motorPin,LOW);
延迟(9000);
//client.publish(WeatherData,icon)
voidMQTT_connect()
int8_tret;
//如果已经连接则停止。
if(mqtt.connected())
返回;
uint8_t重试次数=3;
while((ret=mqtt.connect())!=0)//connect将返回0连接
mqtt.disconnect();
延迟(5000);//等待5秒
重试--;
if(retries==0)
//基本上死了,等待WDT重置我
while(1);
//在发送新请求之前关闭任何连接以允许客户端与服务器建立连接
client.stop();
//如果连接成功:
if(client.connect(server,80)){
client.println("主机:api.openweathermap.org");
client.println("用户代理:ArduinoWiFi/1.1");
client.println("连接:关闭");
客户端.println();
无符号长超时=毫秒();
while(client.available()==0){
if(millis()-timeout>5000){
Serial.println(">>>ClientTimeout!");
客户端.stop();
字符c=0;
while(client.available()){
c=client.
//由于json包含相同数量的打开和关闭大括号,这意味着我们可以通过计算
打开和关闭出现次数来确定何时完全接收到json,//
Serial.print(c);
if(c=='{'){
startJson=true;//设置startJsontrue表示json消息已经开始
jsonend++;
if(c=='}'){
jsonend--;
if(startJson==true){
text+=c;
//如果jsonend=0那么我们收到了相同数量的花括号
if(jsonend==0&&startJson==true){
parseJson(text.c_str());//在parseJson函数中解析c字符串文本
text="";//下次清空字符串
startJson=false;//将startJson设置为false,表示新消息尚未开始
//如果没有建立连接:
Serial.println("connectionfailed");
//解析从OWM接收的json数据
voidparseJson(constchar*jsonString){
//StaticJsonBuffer<4000>jsonBuffer;
constsize_tbufferSize=2*JSON_ARRAY_SIZE(1)+JSON_ARRAY_SIZE(2)+4*JSON_OBJECT_SIZE(1)+3*JSON_OBJECT_SIZE(2)+3*JSON_OBJECT_SIZE(4)+JSON_OBJECT_SIZE(5)+2*JSON_OBJECT_SIZE(7)+2*JSON_OBJECT_SIZE(8)+720;
DynamicJsonBufferjsonBuffer(bufferSize);
//DynamicJsonDocument(bufferSize);
//在JSON树中查找
字段JsonObject&root=jsonBuffer.parseObject(jsonString);
if(!root.success()){
Serial.println("parseObject()failed");
JsonArray&list=root["list"];
JsonObject&nowT=list[0];
JsonObject&稍后=列表[1];
JsonObject&tommorow=list[2];
//字符串条件=list.weather.main;
//包括温度和湿度,供那些可能想破解它的人使用
Stringcity=root["city"]["name"];
字符串weatherNow=nowT["天气"][0]["描述"];
StringweatherLater=later["weather"][0]["description"];