Arduino:自己动手打造一款红外遥控自动浇花神器

关于自动浇花估计很多Arduino的爱好者都玩过,原理也很简单,就是通过土壤湿度检测来自动给植物浇水。那么今天波波为朋友们分享的原理基本接近,但比之前的更好玩儿。

首先看下波波完工的视频:


Arduino:手工DIY红外遥控自动浇花

准备材料:

1、Arduino开发板,本例采用的是 Arduino uno r3

2、传感器:DH11、DS1302、土壤湿度传感器、红外接收模块、遥控器(可以用家中电视机的都行)

4、其他材料:按键一个、5v继电器一个、5v隔膜小水泵一个、1602显示屏、导线若干。

5、本例中使用了9v1A的太阳能电池板,(这个电池板跟共享单车是一样的)电池板后面需要接一个TPP稳压输入输出电路,保障电池的安全。没有这个电路板电池很可能一天不到就损坏了。

实现功能:

1、按键:按键按下的时候可以切换1602屏幕亮暗状态。平时不用的时候可以让屏幕休眠,节约用电。

2、自动浇水:根据室内当前的温度、湿度、土壤的水分来实现自动浇水。只要电源充足,无需人工干预。

3、装逼模式:这是为了给来家里玩儿的小朋友们演示专门添加的。就是如果内置模式达不到浇水条件的时候,我们可以通过遥控器为花短暂浇水,按下遥控器,1602屏幕亮起,开始浇水。再按一下屏幕熄灭,浇水停止。

在此之前波波曾经是采用播放音乐的方式,但是开发过程中播放音乐的tone()函数与IRremote库产生了冲突,所以去掉了音乐播放,大家在开发过程中可以通过MP3模块来增加音乐播放,而不要采用蜂鸣器。

相关代码:

这是我优化之前的代码,放出来。现在正在用的代码暂时不方便公开。因为还有联网控制,自己写的服务器前后端。

```cpp

#include

#include

#include

#include

#include  

#include

#include

LiquidCrystal_I2C lcd(0x27,16,2);//初始化LCD屏幕地址信息

int temprature;  //温度

int humi;  //湿度

int ohumi;  //土壤湿度

uint8_t wendu[8] = {0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00};//温度符号

dht11 DHT11;

#define DHT11PIN 12

#define Tu_A0 0  //土壤模拟信号

#define Tu_D0 7  //土壤数字信号

#define speaker 4  //无源蜂鸣器

#define ssrPin 8  //继电器

#define buttonPin 9 //按钮按键

boolean isPlay = false;

boolean isWatering = false;

int buttonStat = 0;

boolean isLightening = false; //Lcd背光状态

const int kCePin  = 1;

const int kIoPin  = 2;

const int kSclkPin = 3;

ThreeWire myWire(kIoPin,kSclkPin,kCePin); // IO, SCLK, CE

RtcDS1302 Rtc(myWire);

int RECV_PIN = 11;

IRrecv irrecv(RECV_PIN);

decode_results results;

#define countof(a) (sizeof(a) / sizeof(a[0]))

//音乐节拍

#define D0 -1

#define D1 262

#define D2 293

#define D3 329

#define D4 349

#define D5 392

#define D6 440

#define D7 494

#define M1 523

#define M2 586

#define M3 658

#define M4 697

#define M5 783

#define M6 879

#define M7 987

#define H1 1045

#define H2 1171

#define H3 1316

#define H4 1393

#define H5 1563

#define H6 1755

#define H7 1971

//列出全部D调的频率

#define WHOLE 1

#define HALF 0.5

#define QUARTER 0.25

#define EIGHTH 0.25

#define SIXTEENTH 0.625

int tune[]=

{

  M3,M3,M4,M5,

  M5,M4,M3,M2,

  M1,M1,M2,M3,

  M3,M2,M2,

  M3,M3,M4,M5,

  M5,M4,M3,M2,

  M1,M1,M2,M3,

  M2,M1,M1,

  M2,M2,M3,M1,

  M2,M3,M4,M3,M1,

  M2,M3,M4,M3,M2,

  M1,M2,D5,D0,

  M3,M3,M4,M5,

  M5,M4,M3,M4,M2,

  M1,M1,M2,M3,

  M2,M1,M1

};

float durt[]={

  1,1,1,1,

  1,1,1,1,

  1,1,1,1,

  1+0.5,0.5,1+1,

  1,1,1,1,

  1,1,1,1,

  1,1,1,1,

  1+0.5,0.5,1+1,

  1,1,1,1,

  1,0.5,0.5,1,1,

  1,0.5,0.5,1,1,

  1,1,1,1,

  1,1,1,1,

  1,1,1,0.5,0.5,

  1,1,1,1,

  1+0.5,0.5,1+1,

};

int mlength;

void setup(){

  Serial.begin(115200);

  lcd.init();

  lcd.backlight();

  //lcd.noBacklight();

  lcd.clear();

  lcd.createChar(0, wendu);


  //初始化时间日期

  Rtc.Begin();

  Rtc.SetIsWriteProtected(true);

  //Rtc.SetDateTime(RtcDateTime(2019, 11, 19, 14, 20, 0));

  Rtc.SetIsRunning(true);

  //土壤模块接口

  pinMode(Tu_A0, INPUT);

  pinMode(Tu_D0, INPUT);

  //蜂鸣器

  pinMode(speaker,INPUT);

  mlength = sizeof(tune)/sizeof(tune[0]);

  //继电器

  pinMode(ssrPin,OUTPUT);

  //按键按钮

  pinMode(buttonPin,INPUT_PULLUP);

  // Start the receiver

  irrecv.enableIRIn();

}

void loop(){

  RtcDateTime now = Rtc.GetDateTime();

  //获取DHT11数据

  int chk = DHT11.read(DHT11PIN);

  temprature = (int)DHT11.temperature;

  humi = (int)DHT11.humidity;

  //获取时钟数据

  const String nowTime = printTime(now);

  lcd.setCursor(0,0);

  lcd.print(nowTime);

  lcd.setCursor(0,1);

  lcd.print(String("")+"T:"+temprature);

  lcd.write(byte(0));

  lcd.setCursor(6,1);

  lcd.print(String("")+"H:"+humi+"%");

  //获取土壤数据

  ohumi = (int)analogRead(Tu_A0);

  lcd.setCursor(12,1);

  lcd.print(ohumi,DEC);

  //按键控制LCD背光

  buttonStat = digitalRead(buttonPin);

  if(buttonStat == LOW){

    delay(80);

    if(buttonStat == LOW && !isLightening){

      lcd.backlight();

      isLightening = true;

      }

    }else{

      lcd.noBacklight();

      isLightening = false;

  }

  //蜂鸣器报警

  /*

  if(!isPlay && ohumi > 300 && (int)digitalRead(Tu_D0) == 0){

    pinMode(speaker,OUTPUT);

    playMusic();

  }

  */

  //浇水设定

  if(!isWatering && ohumi > 300 && (int)digitalRead(Tu_D0) == 0){

    //goWater();

    lcd.backlight();

    isWatering = true;

    digitalWrite(ssrPin,HIGH);

    Serial.println("Watering Start!");

  }else if(isWatering && ohumi <= 240 && (int)digitalRead(Tu_D0) == 0){

    lcd.noBacklight();

    isWatering = false;

    digitalWrite(ssrPin,LOW);

    Serial.println("Watering Stop!");

  }else{

    //nothing to do

  }

  if (irrecv.decode(&results)) {

    Serial.println(results.value, HEX);

    irrecv.resume();

  }


  Serial.println(String("")+"OH:"+ohumi+"  D0:"+(int)digitalRead(Tu_D0));

  delay(200);

}

/*

void playMusic(){

    isPlay = true;

    Serial.println("Music Start!");

    for(int x=0;x

    tone(speaker,tune[x]);

    delay(500*durt[x]);

    noTone(speaker);

  }

  pinMode(speaker,INPUT);

  Serial.println("Music Stop!");

}

*/

void goWater(){

  isWatering = true;

  while(ohumi > 500 && (int)digitalRead(Tu_D0) == 0){

    digitalWrite(ssrPin,HIGH);

    ohumi = (int)analogRead(Tu_A0);

    lcd.setCursor(12,1);

    lcd.print(ohumi,DEC);

    Serial.println("Watering!");

    }

}

String printTime(const RtcDateTime& dt) {

  char buf[17];

  snprintf_P(buf,

            countof(buf),

            PSTR("%04u-%02u-%02u %02u:%02u"),

            dt.Year(),

            dt.Month(),

            dt.Day(),

            dt.Hour(),

            dt.Minute()

          );

  return buf;

}

```

这是写的第二版的代码,编译如果报错,注意看文中加粗文字。如果大家想优化的话,可以加入线程控制。这里我就不分享相关代码了。以上内容仅供初学者练手,高手们可以直接飘过。

你可能感兴趣的:(Arduino:自己动手打造一款红外遥控自动浇花神器)