首页 > 分享 > esp8266使用Arduino编程实现自动浇水、OTA升级功能

esp8266使用Arduino编程实现自动浇水、OTA升级功能

创作前情:

上海疫情已有一段时间,从三月初算起来已过了一个多月,当时用了泡沫箱种了些小香葱,这几天把它搬到了室外阳台,由于浇水不方便,想着做一个自动浇水的设备。

实现目的:

可以远程控制浇水可以实时查看湿度可以根据湿度设定自动校准太阳能供电远程升级(摆脱TTL束缚)

所用材料:

温湿度模块(之前淘宝买的垃圾佬光合未来温湿度计)主控 esp8266,选他主要是比较熟悉(其实是相对简单了,手上也有不少)水泵以及水管,这些之前也是淘宝垃圾佬买的太阳能板,同样垃圾佬的必备吧 

设计步骤:

远程控制以及数据查看,采用点灯平台,接入简单,有完善的文档以及例子可以参考,温湿度数据通过光合未来的设备,通过ESPNOW传给主控esp8266,测量设备设定休眠半小时,醒来一分钟,每十秒传送一次数据,晚上十点到次日六点每两个小时醒来一次,实测充电一次可以使用一周的时间。主控esp8266通过收到的数据来决定是否需要浇水,

这里介绍下espnow,感觉听有意思的,这里是接受端的代码

#include <ESP8266WiFi.h>

#include <espnow.h>

typedef struct struct_message

{

int id;

char ip[32];

int b;

float c;

String d;

bool e;

float rx_bat;

float rx_temp;

float rx_humi;

} struct_message;

struct_message myData;

struct_message board1;

struct_message board2;

struct_message board3;

struct_message Shuju[3] = {board1, board2, board3};

void OnDataRecv(uint8_t *mac_addr, uint8_t *incomingData, uint8_t len)

{

char macStr[18];

Serial.print("收到数据包来自: ");

snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);

Serial.println(macStr);

memcpy(&myData, incomingData, sizeof(myData));

Serial.println();

if (myData.id == 10)

{

rx_read.humi_one_read = myData.rx_humi;

rx_read.temp_one_read = myData.rx_temp;

rx_read.bat_one_read = myData.rx_bat;

}

}

void esp_now_setup()

{

Serial.println();

Serial.print("ESP8266 Board MAC Address: ");

Serial.println(WiFi.macAddress());

WiFi.mode(WIFI_STA);

if (esp_now_init() != 0)

{

Serial.println("初始化 ESP-NOW 出错");

return;

}

esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);

esp_now_register_recv_cb(OnDataRecv);

}

void esp_now_loop()

{

}

这里是发射端的代码

#include <ESP8266WiFi.h>

#include <espnow.h>

char ownmacStr[18];

uint8_t broadcastAddress[] = {0x5C, 0xCF, 0x7F, 0x99, 0xB8, 0x57};

typedef struct struct_message {

int id;

char ip[32];

int b;

float c;

String d;

bool e;

float f;

float g;

float h;

} struct_message;

struct_message myData;

void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {

if (sendStatus == 0) {

}

else {

}

}

void esp_now_setup() {

WiFi.mode(WIFI_STA);

Serial.print("ESP8266 Board MAC Address: ");

Serial.println(WiFi.macAddress());

if (esp_now_init() != 0) {

Serial.println("初始化 ESP-NOW 出错");

return;

}

esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);

esp_now_register_send_cb(OnDataSent);

esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);

}

void esp_now_loop() {

myData.id = 0;

strcpy(myData.ip, WiFi.localIP().toString().c_str());

myData.b = bat_num;

myData.c = 1.2;

myData.d = ip.c_str();

myData.e = false;

myData.f = bat_read;

myData.g = temp_read;

myData.h = humi_read;

esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));

}

由于自己做的esp8266板子没有放置自动下载电路,所以决定加入arduino ota功能,板子上有物理按键,当检测到有按键按下时,执行ota程序,等待新的固件上传,再次按下按键则取消ota,因板子放在室外,不可能每次下载都跑到室外去按下按键,所以在blinker里也定义一个按键,用来控制是否出于ota升级状态。

ota实现的部分

#include <Arduino.h>

#include <WiFiManager.h>

#include <ArduinoOTA.h>

#include <ESP8266WiFi.h>

#include <Ticker.h>

const int blinkInterval = 2;

Ticker ticker;

void tickerCount() {

led_on_flag = true;

}

#if defined(ARDUINO_AVR_UNO) || defined (ARDUINO_AVR_NANO_EVERY)

void key_press()

{

}

#elif defined(ESP8266)

ICACHE_RAM_ATTR void key_press()

{

otaflag = !otaflag;

if (otaflag)

b1 = 1;

else

b1 = 0;

ota_change_flag = true;

}

#endif

void otasetup() {

pinMode(LED_BUILTIN, OUTPUT);

ticker.attach(blinkInterval, tickerCount);

ArduinoOTA.setHostname("ESP8266");

ArduinoOTA.setPassword("1234");

ArduinoOTA.begin();

Serial.println("OTA ready");

pinMode(OTA_KEY_PIN, INPUT_PULLUP);

attachInterrupt(OTA_KEY_PIN, key_press, FALLING );

}

void otaconnectWifi() {

while (WiFi.status() != WL_CONNECTED)

{

delay(500);

Serial.print(".");

if (!(WiFi.status() != WL_CONNECTED)) {

break;

} else {

WiFiManager wifiManager;

wifiManager.autoConnect("ESP8266");

}

}

}

void otaloop() {

ArduinoOTA.handle();

Serial.println("OTA start");

if (led_on_flag == true) {

led_on_flag = false;

ota_OLED();

digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));

}

if (ota_change_flag == true) {

ota_change_flag = false;

u8g2.setContrast(100);

u8g2.setPowerSave(0);

}

}

{¨config¨{¨headerColor¨¨transparent¨¨headerStyle¨¨dark¨¨background¨{¨img¨¨assets/img/bg/1.jpg¨}}¨dashboard¨|{¨type¨¨num¨¨t0¨¨室外湿度¨¨ico¨¨fal fa-humidity¨¨clr¨¨#6010E4¨¨min¨É¨max¨¢1c¨uni¨¨%RH¨¨bg¨É¨cols¨Ë¨rows¨Ë¨key¨¨humi¨´x´Ë´y´Ë¨speech¨|÷¨lstyle¨É}{ß9ßAßB¨室外温度¨ßD¨fal fa-thermometer-three-quarters¨ßF¨#076EEF¨ßHÉßI¤oßJ´℃´ßLÉßMËßNËßO¨temp¨´x´É´y´ËßQ|÷ßRɨrt¨«}{ß9¨cha¨ßLʨsty¨¨line¨ßFßU¨sty1¨ßZ¨clr1¨ßG¨sty2¨ßZ¨clr2¨¨#389BEE¨ßMÑßNÌßO´´´x´É´y´ÏßQ|÷ßRɨkey1¨ßPßBßS¨t1¨ßC¨key0¨ßV¨key2¨´´¨t2¨´´}{ß9ßAßB¨信号强度¨ßD¨fal fa-signal¨ßFßeßHÉßIº0ßJ¨db¨ßLÊßMËßNËßO¨num-xinhao¨´x´Ï´y´ËßQ|÷ßRÉ}{ß9¨tex¨ßB¨0.0.0.0¨ßg¨IP地址¨ßLÉßD´´ßMÍßNËßO¨tex-ip¨´x´Í´y´¤FßQ|÷ßRÌ}{ß9¨ran¨ßB¨屏幕亮度¨ßF¨#FBA613¨ßI¢47ßHÉßLÊßMÏßNÊßO¨SliderKey¨´x´É´y´¤DßQ|÷ßRÎ}{ß9ßAßB¨花盆湿度¨ßD¨fad fa-sprinkler¨ßFßußHÉßIº0ßJßKßLÉßMÍßNËßO¨humi_10¨´x´Í´y´ÉßQ|÷ßRË}{ß9ßoßB¨文本1¨ßg¨系统运行时间¨¨size¨´15´ßLÊßD¨fad fa-cogs¨ßMÍßNËßO¨tex-time¨´x´É´y´¤FßQ|÷ßRÌßFßu}{ß9¨btn¨ßD¨fal fa-power-off¨¨mode¨ÊßB¨屏幕开关¨ßg¨文本2¨ßLÊßMËßNËßO¨print¨´x´Í´y´ÍßQ|÷ßRÉßFßU}{ß9ß14ßD¨far fa-sync¨ß16ÉßB´刷新´ßgß18ßLÊßMËßNËßO¨reflash¨´x´Ï´y´ÍßQ|÷ßFßU}{ß9ßXßLÉßYßZßFßUßaßZßb¨#EA0909¨ßcßZßdßeßMÑßNÍßO´´´x´É´y´ÒßQ|÷ßh¨temp_10¨ßB¨花盆温度¨ßfßyßgßwßRÊßi¨bat_10¨ßj¨花盆电量¨}{ß9ßAßBß1EßD¨fal fa-question¨ßF¨#00A90C¨ßHÉßI¤eßJ´°C´ßLÉßMÍßNËßOß1D´x´É´y´ÉßQ|÷ßRË}{ß9ßsßB¨设定湿度¨ßFßußI¤eßH¤GßLÊßMÑßNÊßO¨Slidertem¨´x´É´y´¤HßQ|÷ßRÌ}{ß9ßAßB´电量´ßD¨far fa-charging-station¨ßFßeßHÉßIº0ßJ´%´ßLÉßMËßNËßOß1F´x´Ë´y´Í}{ß9ßsßB¨浇水时间¨ßFßeßI¤KßHÉßLÉßMÏßNÊßO¨water_time¨´x´É´y´¤EßRÎ}{ß9ß14ßDß15ß16ÊßBßzßgß18ßLÉßMËßNËßO¨water¨´x´Ï´y´¤DßRÉ}{ß9ß14ßDß15ß16ÊßB¨ota¨ßgß18ßLÉßMËßNËßOß1P´x´É´y´¤I}{ß9ß14ßDß15ß16ÊßB¨显示电量¨ßgß18ßLÉßMËßNËßO¨batdisplay¨´x´Í´y´¤I}{ß9ß14ßD¨fad fa-lightbulb-on¨ß16ÊßB¨led控制¨ßgß18ßLÉßMËßNËßO¨led¨´x´Ë´y´¤IßFßU}{ß9ß14ßDß15ß16ÊßB¨自动浇水¨ßgß18ßLÉßMËßNËßO¨auto¨´x´Ï´y´¤I}{ß9ßAßB´电量´ßD¨fas fa-blinds¨ßFßeßHÉßIº0ßJ´%´ßLÉßMËßNËßO¨bat_0¨´x´É´y´Í}÷¨actions¨|÷¨triggers¨|¦¨range¨¨source¨¨source_zh¨¨unit¨‡|¢-K¤o÷ßV´温度´´℃´|ɺ0÷ßP´湿度´´%´—÷ßW|÷}

主板上设定了一个0.96的oled,主要在浇水时显示浇水速度以及浇水时间,当浇水开始时自动打开屏幕,显示数据,浇水完成,则关闭屏幕,达到省电效果。

关于浇水程序,采用的是pwm的方式,控制功率管控制是否浇水以及浇水速度,这样可以有一个加速以及减速过程,

因为用了不少库,减少编程难度,但这样增加了代码占用空间大小,最后几乎用尽空间,做了不少删减,有能力还是自己写代码,库尽量少用。

最后发现可笑的是,我发现它是个废物,不实用,哈哈哈哈哈

相关知识

【雕爷学编程】Arduino智慧农业之土壤湿度监测
【雕爷学编程】Arduino智能家居之家庭植物智能灌溉系统
【雕爷学编程】Arduino智慧农业之植物生长环境的智能调节
【雕爷学编程】Arduino智慧农业之根据光照强度进行遮阳器的控制
视频教程
自动浇水系统设计
自动喷淋浇水系统在庭院花园中的应用
智能浇水(arduino+mixly)
基于Arduino的智能花卉灌溉系统设计
元编程艺术,第 1 部分: 元编程简介

网址: esp8266使用Arduino编程实现自动浇水、OTA升级功能 https://m.huajiangbk.com/newsview154908.html

所属分类:花卉
上一篇: Arduino Esp8266
下一篇: 桂花的功效与作用、禁忌和食用方法