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 <SoftwareSerial.h>

#include <Wire.h>

#include <LiquidCrystal_I2C.h>

#include <dht11.h>

#include <ThreeWire.h> 

#include <RtcDS1302.h>

#include <IRremote.h>

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<ThreeWire> 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<mlength;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;

}

```

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355

推荐阅读更多精彩内容