热度 12
2022-4-26 17:30
3084 次阅读|
0 个评论
用ESP32和RTC做一个“唤醒闹钟”吧! 最初于2019年12月3日发布 这篇文章来源于DevicePlus.com英语网站的翻译稿。 本文最初发布在deviceplus.jp网站上,而后被翻译成英语。 目录 前言 关于ESP32闹钟 创建日期和时间的“RTC” 在ESP32 LCD上显示日期和时间 使用MP3模块发出闹铃响声 给闹钟主机接线 给ESP32闹钟分机接线 安装库和字体文件 Arduino IDE闹钟程序 分机程序 确认运行情况 结论 相关文章 前言 您每天早上被什么闹钟吵醒?早上人们的一个常见问题是关掉闹钟并直接回去睡觉。 这一次,我们决定使用ESP32制作一个“唤醒闹钟”,应该有助于解决这个问题。 设计步骤 预计完成时间:120分钟 名称 卖方 价格 ESP32-DevKitC(2 件) 贸泽电子 约10.00美元 DS3231 模块 亚马逊 约3.00美元 LIR2032(纽扣充电电池) 亚马逊 约3.60美元 扬声器 亚马逊 约1.00~3.00美元 2.8英寸SPI连接器 320×240像素LCD屏幕 亚马逊 约15.00美元 *除上述物品外,还需要一个轻触开关、一个LED和一个约100Ω的电阻器。 关于ESP32闹钟 我们来使用ESP32完成一个目标吧:像普通闹钟一样在屏幕上显示日期和时间,并在指定的时间响起。在设计制作这款“唤醒闹钟”时,我们需要将分机按钮(用于关闭闹钟)与闹钟主机分开放置。之所以这样设计,是因为想要您必须起床并走到分机按钮处才能将闹钟关掉。 如下面的视频所示,使用两个ESP,一个用于主机,另一个用于分机。在视频中,主机和分机是挨着的,但如果通过Wi-Fi连接,它们是可以在Wi-Fi范围内分开放置的。 将主机和分机分开放置时,请使用ESP32的Wi-Fi功能。两个ESP32作为Web服务器和客户端运行,并相互通信,如图1所示。 图 1 主机和分机之间的通信 创建日期和时间的“RTC” 对于Arduino等微控制器来说,通常能够获取在启动程序后经过的时间。但是,您获得的时间通常不是很准确,因为断电时会重置经过时间。 而如果使用ESP32,则可以通过Wi-Fi连接到互联网,以定期从互联网上的NTP服务器获取日期和时间,并将其设置到ESP32上。但Arduino Uno等部分微控制器没有互联网连接功能,因此,拥有一种可以更轻松地处理日期和时间的机制会很方便。 这就是为什么经常使用一种被称作“RTC”(实时时钟)的IC。 RTC是基于周期性发出信号的元件来计时的IC。此外,通过将其连接到电池等外部电源,即使在微控制器断电时也可以继续计时。 许多产品都采用RTC,此次,我们将使用一种名为“DS3231”的RTC模块。 在电子设计所用的RTC模块当中,DS3231模块很受欢迎,且很容易获得。由于接口是I2C,因此只需要4根线。除了RTC功能,还具有温度传感器功能(不过本文不会用到温度传感器)。 此外,在照片1所示的DS3231上,安装一个名为“LIR2032”的纽扣电池,这样即使在微控制器关闭的情况下也能继续记录日期和时间。LIR2032的电池尺寸与CR2032的相同,但不同的是它可充电。 照片1 DS3231模块 在ESP32 LCD上显示日期和时间 由于闹钟用于查看当前日期和时间,因此需要以易于理解的方式显示日期和时间。以下设备用于显示日期和时间。 7段LED LED 矩阵 OLED 显示器 字符液晶显示器 图形液晶显示器 根据设备的不同,有不同的库和不同的编程方法。这还取决于它是否适合您想要制作的作品。例如,7段LED仅适合以低成本显示数字,但不适合显示详情。其中,图形液晶显示器是最通用的,可以用于许多不同的项目,所以我这次决定使用它。 市面上有各种类型的液晶显示器模块,但对于今天的项目,我们将使用一个名为“ILI9341”的控制器,并使用SPI接口(照片2)。此外,液晶显示器通常以2.2英寸/2.4英寸/2.8英寸尺寸出售,因此,请根据您正在做的作品类型进行相应调整。 照片2 控制器用ILI9341 2.8英寸液晶显示器 使用MP3模块发出闹钟铃声 既然是闹钟,在指定时间发出铃声是必需的。您可以将蜂鸣器连接到ESP32以产生单一铃声,但如果您愿意,也可以使用自己喜欢的铃声。为此,我们将使用一个名为“DFPlayer Mini”的模块,它可以播放任何MP3数据(照片3)。 DFPlayer Mini是一个可以通过串口发送命令来播放microSD卡中MP3的模块。可以将一个小型扬声器连接到扬声器输出引脚以产生铃声。 照片3 DFPlayer Mini 给闹钟主机接线 让我们进入实际构建吧。首先,给闹钟接线。 使用两个面包板,一个配有ESP32和DS3231,另一个配有液晶显示器(LCD)和DFPlayer Mini。各部件接线如图2所示。 由于ESP32很宽,您只能在普通面包板的一面放一根跳线。因此,请改用电源线只在一侧、多一排插孔的面包板(例如Sanhayato的SAD-101)。 ESP32和液晶显示器通过SPI进行连接。ESP32可以使用两个 SPI(VSPI和HSPI),但使用的是VSPI(引脚18/19/23)(表1)。 ESP32和DS3231通过I2C进行连接。在ESP32中,I2C可以分配给任何引脚,但我们使用标准引脚(SDA=21和SCL=22)(表 2)。 DFPlayer Mini 进行串行连接。ESP32可以使用3个串口,但为此请同时使用引脚16和引脚17(表3)。此外,将扬声器连接到DFPlayer Mini“SPK1”和“SPK2”两个引脚。 图2 闹钟主机接线 ESP32 引脚 液晶显示器引脚 5V VCC GND GND 5 CS 4 RESET 2 DC 23 MOSI 18 SCK 19 MISO 表 1:ESP32 与液晶显示器的连接 ESP32 引脚 DS3231 引脚 5V VCC GND GND 21 SDA 22 SCL 表 2:ESP32与DS3231的连接 ESP32 引脚 DFPlayer Mini 引脚 5V VCC GND GND 16 TX 17 RX 表 3:ESP32与DFPlayer Mini的连接 给ESP32闹钟分机接线 接下来,我们将给分机接线。分机接线应按图3所示进行。您所要做的就是将开关和 LED连接到ESP32。将开关的一侧连接到ESP32的3V3引脚,另一侧连接到引脚4。通过电阻器→LED再通过ESP32的引脚13连接到GND。 在读取开关状态的电路上插入一个上拉电阻或下拉电阻。但是,由于ESP32可以通过内部电阻进行上拉/下拉,因此省略了外部电阻。 图3 分机接线 安装库和字体文件 完成接线工作后,您可以创建程序。首先,从安装下面的各个库开始。 Adafruit GFX Adafruit ILI9341 RTCLib DFRobotDFPlayerMini 安装步骤如下: 启动Arduino IDE。 “Manage Library”菜单,以打开Library Manager。 在“Filter search”字段中输入“Adafruit GFX”。 Adafruit GFX将在库列表中显示。单击“Install”按钮(图 4)。 以相同的方式安装每个库。 有几个名称相似的RTCLib和DFPlayer库。RTCLib 安装“RTCLib by Adafruit”,而DFPlayer安装“DFRobotDFPlayerMini by DFRobot”。 图 4 Adafruit GFX库安装 此外,为通过大字符显示时间,需要安装字体文件。如果您下载并解压缩以下zip文件,将可以获得一个名为“FreeSans40pt7b.h”的文件。 “Fonts”文件夹,将字体文件复制到那里。 https://www.h-fj.com/deviceplus/font.zip Arduino IDE闹钟程序 接下来,在Arduino IDE中创建一个闹钟程序并将其写入ESP32。程序内容如清单1所示。 清单1:闹钟主机程序 程序内容(放在这里) 但是,第17行到第21行需要改写如下: ・第17/18行 根据您的Wi-Fi路由器的SSID/密码重写。 ・第19行 指定要分配给ESS32的IP地址。根据您的Wi-Fi路由器的网络配置自行决定IP地址。 在普通IP地址中,四组数字用句点分隔,但在这一行中,它是函数参数的形式,所以四组数字用逗号分隔。 ・第20行 指定网络默认网关的IP地址。通常,它是Wi-Fi路由器的IP地址。用逗号分隔IP地址中的四组数字。 ・第21行 根据分配给分机ESP32的IP地址重写。 例如,如果您想按照表4所示进行设置,请重写第17行至第21行,如清单2所示。 项目 设定值 Wi-Fi路由器SSID my_wifi Wi-Fi路由器密码 my_password 分配给主机ESP32的IP地址 192.168.1.101 默认网关IP地址 192.168.1.1 分配给分机ESP32的IP地址 192.168.1.102 表4:主机网络设置示例 清单 2:重写第17-21行的示例 分机程序 分机程序如清单3所示。 以与闹钟主机相同的方式重写第5行到第9行。 但是,在第7行,指定分配给分机的IP地址。 此外,在第9行的“Main console IP address(主控台IP地址)”中指定闹钟的IP地址。 清单 3:分机程序 程序内容 #include #include #include #include #include #include #include #include #include "time.h" #include #include #include #include #include // Initial setup const char *ssid = "Wi-Fi SSID"; const char *pass = "Wi-Fi password"; IPAddress ip(IP address assigned to main unit); IPAddress gateway(IP address of default gateway); const char* notify_url = "http://IP address of extension unit/alarm"; const char* adjust_time = "04:00:00"; #define DF_VOLUME 30 // Constants, etc. #define ALARM_SIG 25 #define TFT_DC 2 #define TFT_CS 5 #define TFT_RST 4 #define TFT_WIDTH 320 Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST); RTC_DS3231 rtc; HardwareSerial hs(1); DFRobotDFPlayerMini myDFPlayer; WebServer server(80); char old_date ; char old_time ; char old_alarm ; char alarm_time ; char wdays = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; bool alarm_checked = false; bool alarm_on = false; bool ntp_adjusted = false; int alarm_ctr; // Set date and time using NTP void setTimeByNTP() { struct tm t; configTime(9 * 3600L, 0, "ntp.nict.jp", "time.google.com", "ntp.jst.mfeed.ad.jp"); if (!getLocalTime(&t)) { Serial.println("getLocalTime Error"); return; } rtc.adjust(DateTime(t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec)); } // Display string on LCD void showMessage(char* s_new, char* s_old, int y0, int height) { int16_t x1, y1; uint16_t w, w2, h; int x, y; if (strcmp(s_new, s_old) != 0) { tft.getTextBounds(s_old, 0, 0, &x1, &y1, &w, &h); w2 = w * 11 / 10; tft.fillRect((TFT_WIDTH - w2) / 2 , y0 - (height / 2) + 1, w2, height, ILI9341_BLACK), tft.getTextBounds(s_new, 0, 0, &x1, &y1, &w, &h); tft.setCursor((TFT_WIDTH - w) / 2, y0 + (h / 2) - 1); tft.print(s_new); strcpy(s_old, s_new); } } // Main settings page void handleRoot() { int i; String html = " \n" " \n" " \n" " \n" " Alarm clock settings \n" " \n" " \n" " \n" " \n" " \n"; for (i = 0; i < 24; i++) { html += "
热度 13
2022-3-23 12:03
5729 次阅读|
0 个评论
本项目是一个基于IoT技术的智能pH测量仪,使用了一个pH传感器和ESP32 WiFi模块,pH读数通过ThingSpeak可视化服务器显示。项目物料清单如下: ESP32开发板 (ESP-WROOM-32) PH传感器 9V电池或DC适配器 跳线 面包板 项目清单中的pH传感器是一款比较先进的工业级电极,这是专门为Arduino、ESP8266、ESP32和其他MCU而设计的线性模拟工具,测量范围0-14pH。ESP32是内置12-bit ADC的32位芯片, 可进行高精度的测量。 PH传感器检测包 项目连接器板上的LED可用作电源指示器。该板子带有BNC-type连接器和PH传感器接口。使用时,将pH sensor与BNC连接器连接,再将PH接口插入MCU板的任一模拟输入端口即可。如果已经编程就绪,就很容易获得pH值,也可以通过万用表来测量输出电压。 高分辨率pH探针可按照用户定义的间隔对液体取样,并将结果发送到远端服务器,响应时间少于1分钟,应用场景有养鱼缸、水厂、实验室等。 PH传感器带有BNC连接器的工业级pH电极,电源指示器LED,和一个校准PH探针。技术规格如下: 模块电压:DC 9.00V 1A 测量范围:0-14PH 测量精度:±0.1pH 响应时间: 1min 输出:模拟电压0.5V to 3V Alkali误差: 0.2PH 内阻: 250MO 本仪器事先进行了校准,测量结果与温度成正比。如果PH传感器探针连接状态改变了,就需要重新校准:PH4 = 1.5V, PH7 = 2.0V & PH9 = 2.5V。校准时,让PH传感器探针直立并保持较长一段时间。如果该传感器在2-3天内多次使用过,测量结果就会更加精准。 在测试中将PH探针浸入溶液之前,要先用去离子水冲洗传感器的试管,然后用薄绉纸擦拭干净。要获得稳定测量结果,大约需要30-40秒时间。 一旦测量读数完成,在收储PH探针之前,要再用去离子水冲洗探针,用薄绉纸将表面溶液擦拭干净,然后盖上保护盖进行保管。 注意,PH传感器探针的试管尖非常敏感,禁止用手触碰,也不能放在地上。该灯泡型的外壳非常脆弱,不用时应按规定妥善保管。 用ESP32接口测试PH传感器 制作IoT pH检测仪之前,要先将其与ESP32 WiFi模块按照如下电路图连接并测试。 该pH传感器使用外接9V电池,或者9V DC电源供电。将pH传感器信号板的输出连接到ESP32的VP引脚,这个引脚可作为A0引脚使用。传感器的输出范围为0.5-3V,可与ESP32的模拟引脚一起使用。 基本测试代码 pH传感器是模拟传感器,需要将模拟输出转换成数字pH值。下面是一组简单ESP32 & pH传感器代码,拷贝并将这些代码黏贴到Arduino IDE。 从开发板管理器选择ESP32和COM端口后,就可以上传代码了。 const int potPin=A0; float ph; float Value=0; void setup() { // put your setup code here, to run once: Serial.begin(115200); pinMode(potPin,INPUT); delay(1000); } void loop(){ Value= analogRead(potPin); Serial.print(Value); Serial.print(" | "); float voltage=Value*(3.3/4095.0); ph=(3.3*voltage); Serial.println(ph); delay(500); } 上传代码后,打开Serial Monitor,传感器数值就出现了。 刚才我们测量的是柠檬汁,Ph值范围为2.8~3.0。我们也测量了一个常用洗衣液,其Ph值大于8。我们也测量了一杯牛奶,其Ph值会为5左右。 如果传感器探针与测量套装保持完整的话,我们就没有必要对其进行校准了。否则,如果连接状态改变了,就要微调Ph模块中的5K电位器,按照前述方法进行校准。 制作智能pH检测仪 接下来,我们重写代码构建一个基于IoT的pH检测仪,通过这个pH检测仪我们可在世界上任何地方监视目标的pH值。 项目使用Thingspeak服务器在线监视pH数据。ThingSpeak是一个面向IoT项目的工具,首先应登录https://thingspeak.com并注册一个账号,然后开设一个新通道,为pH读数数据创建一个新装置。 接着,创建API Key。后面更改程序和设定数据时需要这个Key。 下面是基于pH Sensor & ESP32的智能pH测量仪代码: String apiKey = "*************"; const char *ssid = "*************"; const char *password = "*************"; 这需要黏贴并拷贝前面的API Key来升级API密码,同时更新Wi-Fi信用、Wi-Fi名称,以及一个后期可变更的密码。 拷贝以下代码并上传到ESP32开发板: #include const int potPin=A0; float ph; float Value=0; String apiKey = "*************"; // Enter your Write API key from ThingSpeak const char *ssid = "*************"; // replace with your wifi ssid and wpa2 key const char *password = "*************"; const char* server = "api.thingspeak.com";// don't change this WiFiClient client; void setup() { // put your setup code here, to run once: Serial.begin(115200); pinMode(potPin,INPUT); delay(1000); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(2000); Serial.print("."); } // Print local IP address and start web server Serial.println(""); Serial.println("WiFi connected."); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } void loop() { // put your main code here, to run repeatedly: Value= analogRead(potPin); Serial.print(Value); Serial.print(" | "); float voltage=Value*(3.3/4095.0); ph=(3.3*voltage); Serial.println(ph); delay(500); if (client.connect(server, 80)) // "184.106.153.149" or api.thingspeak.com { String postStr = apiKey; postStr += "&field1="; postStr += String(ph); postStr += "\r\n"; client.print("POST /update HTTP/1.1\n"); client.print("Host: api.thingspeak.com\n"); client.print("Connection: close\n"); client.print("X-THINGSPEAKAPIKEY: " + apiKey + "\n"); client.print("Content-Type: application/x-www-form-urlencoded\n"); client.print("Content-Length: "); client.print(postStr.length()); client.print("\n\n"); client.print(postStr); } } 上传完成后,ESP32将尝试连接WiFi网络。每隔15秒,传感器就向Thinkspeak server上传数据。我们可在Thinkspeak控制面板看到上传的数据结果。 如果你对模拟Ph传感器的测量结果不满意,也可以采用科学仪器级别的Ph传感器,通过它们的I2C & UART接口获得更精准的测量结果。