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

article/2025/9/22 22:29:49

创作前情:

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

实现目的:

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

所用材料:

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

设计步骤:

远程控制以及数据查看,采用点灯平台,接入简单,有完善的文档以及例子可以参考,温湿度数据通过光合未来的设备,通过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;//创建结构体变量
/*******新加 20220411 多版子*************/
struct_message myData;
struct_message board1; //用于储存开发版1的值
struct_message board2;
struct_message board3;
struct_message Shuju[3] = {board1, board2, board3}; //创建一个包含所有结构数组方便电泳读写数据
/*******新加 20220411 多版子*************/
//创建一个回调函数作为接收数据后的串口显示
void OnDataRecv(uint8_t *mac_addr, uint8_t *incomingData, uint8_t len)
{/*******新加 20220411 多版子*************/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);/*******新加 20220411 多版子*************/memcpy(&myData, incomingData, sizeof(myData));// Serial.print("Bytes received: ");
//    Serial.print("数据包大小: ");
//    Serial.println(len);
//    Serial.print("来自开发版: ");
//    Serial.println(myData.id);//  Serial.print("Char: ");
//    Serial.print("IP 地址: ");
//    Serial.println(myData.ip);
//    Serial.print("电量百分比: ");
//    Serial.print(myData.b);
//    Serial.println(" %");//  Serial.print("Float: ");//  Serial.println(myData.c);//  Serial.print("String: ");//  Serial.println(myData.d);//  Serial.print("Bool: ");//  Serial.println(myData.e);
//    Serial.print("电池电压: ");
//    Serial.println(myData.rx_bat);
//    Serial.print("温度: ");
//    Serial.println(myData.rx_temp);
//    Serial.print("湿度: ");
//    Serial.println(myData.rx_humi);
//    Serial.print("********************************************************");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.begin(115200);Serial.println();Serial.print("ESP8266 Board MAC Address: ");Serial.println(WiFi.macAddress());//设置ESP8266模式WiFi.mode(WIFI_STA);//初始化 ESP-NOWif (esp_now_init() != 0){Serial.println("初始化 ESP-NOW 出错");return;}//设置ESP8266角色:esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);//先前创建的功能 测试ESP-NOW通信esp_now_register_recv_cb(OnDataRecv);
}void esp_now_loop()
{
}

这里是发射端的代码

//发送
#include <ESP8266WiFi.h>
//#include <WiFi.h>
//#include <esp_now.h>
#include <espnow.h>
char ownmacStr[18];//定义字符串数组
/******************ESP NOW *******************************/
//接收方MAC地址 根据自己的板子修改 CC:50:E3:08:E5:A9   60:01:94:52:DE:03   BC:DD:C2:4F:4E:E4  5C:CF:7F:9B:22:8F 5C:CF:7F:99:B8:57//uint8_t broadcastAddress[] = {0xBC, 0xDD, 0xC2, 0x4F, 0x4E, 0xE4};
//uint8_t broadcastAddress[] = {0x5C, 0xCF, 0x7F, 0x9B, 0x22, 0x8F};
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;
//esp_now_peer_info_t peerInfo;//创建对等接口 add 20220411
/******************ESP NOW *******************************/
//这是一个回调函数,将在发送消息时执行。
//在这种情况下,无论是否成功发送该消息,都会简单地打印出来
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {//Serial.print("\r\n最后一个数据表发送状态: \t");if (sendStatus == 0) {// Serial.println("发送成功");}else {//Serial.println("发送失败");}
}void esp_now_setup() {//初始化串行监视器以进行调试//Serial.begin(115200);//将设备设置为Wi-Fi站点WiFi.mode(WIFI_STA);Serial.print("ESP8266 Board MAC Address: ");Serial.println(WiFi.macAddress());//立即初始化ESPif (esp_now_init() != 0) {Serial.println("初始化 ESP-NOW 出错");return;}//设置ESP8266角色  ESP_NOW_ROLE_CONTROLLER, ESP_NOW_ROLE_SLAVE,//ESP_NOW_ROLE_COMBO, ESP_NOW_ROLE_MAX。esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);//先前创建的功能。esp_now_register_send_cb(OnDataSent);//成功初始化,注册发送包,获取已发送状态//与另一个ESP-NOW设备配对以发送数据esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
}void esp_now_loop() {//配置要发送的值myData.id = 0;//自定义开发版id//strcpy(myData.a, "THIS IS A CHAR");strcpy(myData.ip, WiFi.localIP().toString().c_str());//myData.b = random(1,20); //随机数myData.b = bat_num;myData.c = 1.2;//myData.d = "Hello";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));//延时两秒//delay(2000);
}

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

ota实现的部分

#include <Arduino.h>
#include <WiFiManager.h>
#include <ArduinoOTA.h>
#include <ESP8266WiFi.h>
#include <Ticker.h>
//#define OTA_KEY_PIN  4// 闪烁时间间隔(秒)
const int blinkInterval = 2;
//bool led_on_flag = false;
Ticker ticker;
// 在Tinker对象控制下,此函数将会定时执行。
void tickerCount() {led_on_flag = true;//digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
// 设置wifi接入信息(请根据您的WiFi信息进行修改)
//const char* ssid = "taichimaker";
//const char* password = "12345678";
#if defined(ARDUINO_AVR_UNO) || defined (ARDUINO_AVR_NANO_EVERY)
void key_press()
{// include all buttons here to be checked// button.tick(); // just call tick() to check the state.
}
#elif defined(ESP8266)
ICACHE_RAM_ATTR void key_press()
{otaflag = !otaflag;if (otaflag)b1 = 1;elseb1 = 0;ota_change_flag = true;// Serial.println("key press");// include all buttons here to be checked//button.tick(); // just call tick() to check the state.
}
#endif
void otasetup() {//Serial.begin(115200);// Serial.println("");pinMode(LED_BUILTIN, OUTPUT);ticker.attach(blinkInterval, tickerCount);  // 设置Ticker对象//connectWifi();// OTA设置并启动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 );
//  Serial.println("ota int done ");
//  Serial.print("ota set pin = ");
//  Serial.println(OTA_KEY_PIN);
}
void otaconnectWifi() {//开始连接wifi//WiFi.begin(ssid, password);// Serial.begin(115200);while (WiFi.status() != WL_CONNECTED){delay(500);//xianshi_wifi();Serial.print(".");if (!(WiFi.status() != WL_CONNECTED)) {break;} else {WiFiManager wifiManager;wifiManager.autoConnect("ESP8266");}}//Serial.println("");// Serial.print("ESP8266 Connected to ");//Serial.println(WiFi.SSID());              // WiFi名称// Serial.print("IP address:\t");// Serial.println(WiFi.localIP());           // IP
}
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);}}

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

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

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

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


http://chatgpt.dhexx.cn/article/QyW0HiA3.shtml

相关文章

ESP8266-Arduino编程实例-MPL3115A2压力传感器驱动

MPL3115A2压力传感器驱动 1、MPL3115A2介绍 MPL3115A2 是一款紧凑型压阻式绝对压力传感器,具有 I2C 数字接口。 MPL3115A2 具有 20 kPa 至 110 kPa 的宽工作范围,该范围涵盖了地球上的所有表面高度。 MEMS 使用片上温度传感器进行温度补偿。 压力和温度数据被馈送到高分辨率…

ESP8266-Arduino编程实例-AHT20温湿度传感器驱动

AHT20温湿度传感器驱动 1、AHT20介绍 AHT20作为新一代温湿度传感器,在尺寸和智能方面树立了新标准。 它嵌入在适合回流焊接的双排扁平无铅封装中,底部为 3 x 3 mm,高度为 1.0 mm。 该传感器以标准IAHT20输出校准后的数字信号,作为新一代温湿度传感器,在尺寸和智能方面树…

ESP8266-Arduino编程实例-中断

中断 本文将演示如何使用 ESP8266 NodeMCU 的中断和定时器。 中断检测 GPIO 状态的变化且无需不断检查其当前值。通过使用中断,当检测到更改时,会触发事件(调用函数)。 在实例中,使用 PIR 运动传感器检测运动:当检测到运动时,ESP8266 会启动一个定时器并打开 LED 预定…

ESP8266-Arduino编程实例-MLX90393磁场传感器驱动

MLX90393磁场传感器驱动 1、MLX90393介绍 MLX90393 磁场传感器可以在运行时重新编程为不同的模式和不同的设置。 该传感器使用 Melexis 专有的 Triaxis 技术提供与沿 XYZ 轴感应的磁通密度成比例的 16 位输出,还提供温度输出信号。 这些数字值可通过 I2C 和 SPI 获得,其中 …

arduino新手入门详细教程系列之【Ⅱ:arduino编程环境配置】

目录 一&#xff09;下载Arduino IDE 二&#xff09;安装驱动 三&#xff09;认识Arduino IDE 四&#xff09;下载一个Blink程序 五&#xff09;blink程序 更多优质文章请关注博主&#xff1a; 沄边小卖部的博客_CSDN博客-笔记,计算机类相关,《初级会计实务》考试学习分享…

ESP8266-Arduino编程实例-PWM

PWM 本文将演示如何使用ESP8266 NodeMCU生成PWM信号,通过随时间改变占空比来调节 LED 亮度。 ESP8266 GPIO 可以设置为输出 0V 或 3.3V,但在0~3.3V之间不能输出任何电压。 尽管如此,可以使用脉宽调制 (PWM) 输出“假”中电平电压,从而产生不同级别的 LED 亮度的方式。 如…

Arduino编程基础与常用函数(详细)解析

Arduino编程基础 关键字&#xff1a; if、if…else、for、switch、case、while、do…while、break、continue、return、goto。 语法符号&#xff1a;每条语句以“&#xff1b;”结尾&#xff0c;每段程序以“{}”括起来。 数据类型&#xff1a; boolean、 char、 int、 unsign…

Arduino入门-Arduino编程语言入门教程

随着社会的发展&#xff0c;越来越多的中小学生、老师、创客们、设计师、艺术家等都在玩Arduino,那Arduino编程语言入门难吗&#xff1f;我们都知道Arduino使用C/C编写程序&#xff0c;虽然C兼容C语言&#xff0c;但这是两种语言&#xff0c;C语言是一种面向过程的编程语言&…

arduino c语言pdf,arduino编程从零开始

arduino编程从零开始是一款Arduino新手编程入门手册,由Simon Monk编著,刘椮楠翻译,全书揭示了arduino的软件特性,介绍了如何在arduino上用c语言编写能稳定运行的sketch。本书的重点是对Arduino编程,作者将介绍怎样简单并有趣地对Arduino编程,避免使用生涩难瞳的代码而让制…

小白入门Arduino,一步一图搭建开发环境

目录 1、Arduino 2、环境搭建 2.1 下载软件&#xff1a; 2.2 ide安装 2.3 软件试用 2.5 代码解读 3、总结 最近有机会接触到物联网的开发&#xff0c;所以自己学习一下&#xff0c;记录一下。 在查阅了各种资料&#xff0c;对比了下各种难度&#xff0c;资料的丰富程度…

arduino入门1

文章目录 编程并不是一间很难的事&#xff0c;你可这样理解&#xff1a; 在编程中&#xff0c;你就像是一个老板arduino就像是你的员工&#xff0c;你可指挥arduino去做你想让它做的事。当然&#xff0c;要做的事得在员工的工作范围之内。 arduino这位员工就是一块电路板&…

Arduino面向对象编程基础

面向对象编程基础 1.基础概论 面向对象三大特征&#xff1a;继承、封装、多态 2.简单的类和对象 案例&#xff1a;创建Led类 案例01&#xff1a;感受构造函数与析构函数的功能 class Led {public :Led(); //构造函数声明&#xff0c;初始化对象&#xff0c;在创建对象的…

Arduino入门教程

Arduino是一款简单易学的开源电子原型平台&#xff0c;包含硬件&#xff08;各种型号的Arduino板&#xff09;和软件&#xff08;Arduino IDE&#xff09;。它通过各种各样的传感器来感知环境&#xff0c;再通过控制灯光、电机和其他的装置来完成很多自动控制任务&#xff0c;在…

Arduino学习篇,基础入门

什么是arduino? 简单来讲arduino就是通过源代码控制开发板的信号输入输出从而实现对一些电子元件的控制&#xff0c;例如LED灯&#xff0c;蜂鸣器&#xff0c;按键 arduino程序 首先来讲arduino程序是基于C语言&#xff0c;而实现类似对于LED灯和蜂鸣器的简单控制只需简单C语…

TCP 四次挥手,可以变成三次挥手吗?

作者&#xff1a;小林coding 计算机八股文网站&#xff1a;https://xiaolincoding.com 大家好&#xff0c;我是小林。 虽然我们在学习 TCP 挥手时&#xff0c;学到的是需要四次来完成 TCP 挥手&#xff0c;但是在一些情况下&#xff0c; TCP 四次挥手是可以变成 TCP 三次挥手的…

TCP的三次握手、四次挥手--非常详细讲解

本篇文章转自 TCP的三次握手(建立连接&#xff09;和四次挥手(关闭连接&#xff09;不过进行了一些编辑。 TCP(Transmission Control Protocol) 传输控制协议 1&#xff64;TCP三次握手和四次挥手的过程图 tcp的6种标志位的分别代表&#xff1a; SYN(synchronous建立联机) ACK…

两张动图-彻底明白TCP的三次握手与四次挥手

背景描述 通过上一篇中网络模型中的IP层的介绍&#xff0c;我们知道网络层&#xff0c;可以实现两个主机之间的通信。但是这并不具体&#xff0c;因为&#xff0c;真正进行通信的实体是在主机中的进程&#xff0c;是一个主机中的一个进程与另外一个主机中的一个进程在交换数据。…

http——三次握手四次挥手

http htttp:TCP三次握手四次挥手&#xff08;TCP连接的释放&#xff09; htttp: 超文本传输协议&#xff08;Hyper Text Transfer Protocol&#xff0c;HTTP&#xff09;是一个简单的请求-响应协议&#xff0c;它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消…

HTTP的三次握手和四次挥手

目录 1. HTTP的三次握手2. HTTP的四次挥手3. HTTPS的三次握手 1. HTTP的三次握手 三次握手&#xff08;Three-way Handshake&#xff09;其实就是指建立一个TCP连接时&#xff0c;需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力…

我终于搞懂了TCP的三次握手和四次挥手(图片案例超详解)

【辰兮要努力】&#xff1a;hello你好我是辰兮&#xff0c;很高兴你能来阅读&#xff0c;昵称是希望自己能不断精进&#xff0c;向着优秀程序员前行&#xff01; 博客来源于项目以及编程中遇到的问题总结&#xff0c;偶尔会有读书分享&#xff0c;我会陆续更新Java前端、后台、…