1 Star 1 Fork 2

拉灯/esp32EpdAlarmClock

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
projectV2.ino 37.54 KB
一键复制 编辑 原始数据 按行查看 历史
拉灯 提交于 2022-11-06 10:01 . C语言
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180
#include "Adafruit_SHT31.h"
/* Includes ------------------------------------------------------------------*/
#include "DEV_Config.h"
#include "EPD.h"
#include "GUI_Paint.h"
#include "imagedata.h"
#include <stdlib.h>
// #include "stdio.h"
// #include "string.h"
// #include "iostream"
#include <Wire.h>
#include "Adafruit_SHT31.h"
#include "RTClib.h"
#include <EEPROM.h>
#include <WiFi.h>
#define debuguse 0 //是否开调试输出
RTC_DATA_ATTR int TimeWakeCount = 0; //这个参数不会应为休眠而清除
#define NTP1 "ntp1.aliyun.com"
#define NTP2 "ntp2.aliyun.com"
#define NTP3 "ntp3.aliyun.com"
#define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 60 /* Time ESP32 will go to sleep (in seconds) */
// #define BUTTON_PIN_BITMASK 0x8004 // GPIOs 2 and 15
#define BUTTON_PIN_BITMASK 0xB00001014 // GPIOs 2 and 15
//填写WIFI入网信息
const char *ssid = "WH_HOME"; // WIFI账户
const char *password = "A19901366";
RTC_DS3231 rtc;
Adafruit_SHT31 sht31 = Adafruit_SHT31();
UBYTE *BlackImage;
int SetAlarmHour = 0; //读数据,闹钟设置的小时
int SetAlarmMin = 0; //读数据,闹钟设置的分钟
int SetAlarMode = 0; //读数据,闹钟设置的模式 响一次,5天响,7天响 数据为 1/5/7
int SetAlarOnOffFlag = 0; //读数据,闹钟设置的开关 数据为0/1
int button1Flag=0;//Buton1被按下
int button2Flag=0;//Buton2被按下
int button3Flag=0;//Buton3被按下
int button4Flag=0;//Buton4被按下
int button5Flag=0;//Buton5被按下
int button6Flag=0;//Buton6被按下
int AlarmStartFlag=0;//闹钟是否开始响标志
char daysOfTheWeek[7][12] = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
/*
Method to print the reason by which ESP32
has been awaken from sleep
打印唤醒的原因
*/
uint8_t WakeFlag=0;//苏醒的原因
//得到苏醒的原因
void print_wakeup_reason(){
esp_sleep_wakeup_cause_t wakeup_reason;
wakeup_reason = esp_sleep_get_wakeup_cause();
WakeFlag=0;
switch(wakeup_reason)
{
case ESP_SLEEP_WAKEUP_EXT0 :
{
WakeFlag=1;
#if debuguse
Serial.println("Wakeup caused by external signal using RTC_IO");
#endif
}break;
case ESP_SLEEP_WAKEUP_EXT1 :
{
WakeFlag=2;
#if debuguse
Serial.println("Wakeup caused by external signal using RTC_CNTL");
#endif
} break;
case ESP_SLEEP_WAKEUP_TIMER :
{
WakeFlag=3;
#if debuguse
Serial.println("Wakeup caused by timer");
#endif
} break;
case ESP_SLEEP_WAKEUP_TOUCHPAD :
{
WakeFlag=4;
#if debuguse
Serial.println("Wakeup caused by touchpad");
#endif
}break;
case ESP_SLEEP_WAKEUP_ULP :
{
WakeFlag=5;
#if debuguse
Serial.println("Wakeup caused by ULP program");
#endif
}break;
default :
{
WakeFlag=6;
#if debuguse
Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason);
#endif
}break;
}
}
//打印和设置rtc时间
void printLocalTime()
{
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
#if debuguse
Serial.println("Failed to obtain time");
#endif
return;
}
//Serial.print(asctime(&timeInfo)); //默认打印格式:Mon Oct 25 11:13:29 2021
#if debuguse
Serial.println(&timeinfo, "%A, %Y-%m-%d %H:%M:%S");
Serial.println("Get Ntp time is:");
Serial.println(timeinfo.tm_year);
Serial.println(timeinfo.tm_mon);
Serial.println(timeinfo.tm_mday);
#endif
//设置RTC时间
rtc.adjust(DateTime(timeinfo.tm_year+1900, timeinfo.tm_mon+1, timeinfo.tm_mday, timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec));
}
//电池电量的计算
int PowerVolume(int readAD)
{
readAD+=180;
float VBat=(33.0/4095.0)*readAD;//得到当前电池电压
// Serial.println("readAD :");
// Serial.println(readAD);
// Serial.println("readAD VBat:");
// Serial.println(VBat);
if(VBat>4.2) { return 100;}
else if((VBat<=4.2)&&(VBat>4.06)) { return 100;}
else if((VBat<=4.06)&&(VBat>3.98)) {return 90;}
else if((VBat<=3.98)&&(VBat>3.92)) {return 80;}
else if((VBat<=3.92)&&(VBat>3.87)) {return 70;}
else if((VBat<=3.87)&&(VBat>3.82)) {return 60;}
else if((VBat<=3.82)&&(VBat>3.79)) {return 50;}
else if((VBat<=3.79)&&(VBat>3.77)) {return 40;}
else if((VBat<=3.77)&&(VBat>3.74)) {return 30;}
else if((VBat<=3.74)&&(VBat>3.68)) {return 20;}
else if((VBat<=3.68)&&(VBat>3.45)) {return 10;}
else if((VBat<=3.45)&&(VBat>3.00)) {return 5;}
else if((VBat<=3)&&(VBat>2.00)) {return 0;}
else {return 0;}
}
//墨水屏的输出
void epdOut()
{
DateTime now = rtc.now();
digitalWrite(23, LOW); //打开墨水屏电源
DEV_Delay_ms(100);
#if debuguse
printf("EPD_2IN9_test Demo\r\n");
#endif
DEV_Module_Init();
#if debuguse
printf("e-Paper Init and Clear...\r\n");
#endif
EPD_2IN9_Init(EPD_2IN9_FULL);
EPD_2IN9_Clear();
// DEV_Delay_ms(500);
//Create a new image cache
UBYTE *BlackImageAll;
/* you have to edit the startup_stm32fxxx.s file and set a big enough heap size */
UWORD Imagesize = ((EPD_2IN9_WIDTH % 8 == 0)? (EPD_2IN9_WIDTH / 8 ): (EPD_2IN9_WIDTH / 8 + 1)) * EPD_2IN9_HEIGHT;
if((BlackImageAll = (UBYTE *)malloc(Imagesize)) == NULL) {
#if debuguse
printf("Failed to apply for black memory...\r\n");
#endif
while(1);
}
#if debuguse
printf("Paint_NewImage\r\n");
#endif
Paint_NewImage(BlackImageAll, EPD_2IN9_WIDTH, EPD_2IN9_HEIGHT, 270, WHITE);//旋转了270度显示
Paint_SelectImage(BlackImageAll);
Paint_Clear(WHITE);
Paint_DrawLine(0, 20, 296, 20, BLACK, DOT_PIXEL_1X1, LINE_STYLE_SOLID);//上格横线
Paint_DrawRectangle(210, 20, 296, 108, BLACK, DOT_PIXEL_1X1, DRAW_FILL_EMPTY);//左边矩形框
Paint_DrawLine(0, 108, 296, 108, BLACK, DOT_PIXEL_1X1, LINE_STYLE_SOLID);//下面横线
Paint_DrawLine(1, 20, 1, 108, BLACK, DOT_PIXEL_1X1, LINE_STYLE_SOLID);//最左边竖线
Paint_DrawLine(0, 88, 210, 88, BLACK, DOT_PIXEL_1X1, LINE_STYLE_SOLID);//中间闹钟横线
//显示时间
EPD_2IN9_Init(EPD_2IN9_PART);
Paint_SelectImage(BlackImageAll);
PAINT_TIME sPaint_time2;
sPaint_time2.Hour = now.hour();
sPaint_time2.Min = now.minute();
sPaint_time2.Sec = now.second();//这个实际不显示
Paint_ClearWindows(50, 30, 20 + Font48.Width * 7, 30 + Font48.Height, WHITE);
Paint_DrawTime(50, 30, &sPaint_time2, &Font48, WHITE, BLACK);
//显示当前年月日 星期
String datatemp1=String(now.year(), DEC);//转换成字符串 显示年
const char *tempdatastr1 = datatemp1.c_str(); //转换为字符数组
// Paint_DrawString_EN(0, 0, "2022-09-26", &Font16, WHITE, BLACK);//白底黑字
Paint_DrawString_EN(0, 2, tempdatastr1 , &Font16, WHITE, BLACK);//白底黑字
Paint_DrawString_EN(43, 2, "-", &Font16, WHITE, BLACK);//白底黑字
String datatemp2=String(now.month(), DEC);////转换成字符串 显示月
const char *tempdatastr2 = datatemp2.c_str(); //转换为字符数组
Paint_DrawString_EN(53, 2, tempdatastr2, &Font16, WHITE, BLACK);//白底黑字
Paint_DrawString_EN(73, 2, "-", &Font16, WHITE, BLACK);//白底黑字
String datatemp3=String(now.day(), DEC);//转换成字符串 显示日期
const char *tempdatastr3 = datatemp3.c_str(); //转换为字符数组
Paint_DrawString_EN(83, 2, tempdatastr3, &Font16, WHITE, BLACK);//白底黑字
Paint_DrawString_CN(118, 2,daysOfTheWeek[now.dayOfTheWeek()], &Font12CN, BLACK, WHITE);//显示星期
// 显示电量
int sensorValue=PowerVolume(analogRead(A0));//gpio 36
Paint_DrawString_CN(190, 0,"电量:", &Font12CN, BLACK, WHITE);
Paint_DrawNum(232, 2, sensorValue, &Font16, BLACK, WHITE); //电量
Paint_DrawString_EN(270, 2, "%", &Font16, WHITE, BLACK);//白底黑字
// //最下格的文字
// Paint_DrawString_CN(2, 109,"晴转多云", &Font12CN, BLACK, WHITE);
// Paint_DrawString_CN(148, 109,"温度:", &Font12CN, BLACK, WHITE);
// Paint_DrawString_EN(194, 109, "30~33", &Font16, WHITE, BLACK);//白底黑字
// Paint_DrawString_CN(276, 109,"℃", &Font12CN, BLACK, WHITE);
//中间的闹钟的位置
if(SetAlarOnOffFlag==1)
{
Paint_DrawString_CN(2, 88,"闹钟开", &Font12CN, BLACK, WHITE);
}
else
{
Paint_DrawString_CN(2, 88,"闹钟关", &Font12CN, BLACK, WHITE);
}
if(SetAlarMode==1)
{
Paint_DrawString_CN(68, 88,"一次", &Font12CN, BLACK, WHITE);
}
else if(SetAlarMode==5)
{
Paint_DrawString_CN(68, 88,"五天模式", &Font12CN, BLACK, WHITE);
}
else if(SetAlarMode==7)
{
Paint_DrawString_CN(68, 88,"七天模式", &Font12CN, BLACK, WHITE);
}
//显示设定的闹钟时间
PAINT_TIME sPaint_alar_time2;
sPaint_alar_time2.Hour = SetAlarmHour;
sPaint_alar_time2.Min = SetAlarmMin;
sPaint_alar_time2.Sec = 0;//这个实际不显示
Paint_ClearWindows(140, 90, 30 + Font16.Width * 7, 88 + Font16.Height, WHITE);
Paint_DrawTime(140, 90, &sPaint_alar_time2, &Font16, WHITE, BLACK);
// Paint_DrawString_EN(148, 88, "07:10", &Font16, WHITE, BLACK);//白底黑字
//温度、湿度和大气压
float t = sht31.readTemperature();
float h = sht31.readHumidity();
//温度
if (! isnan(t)) { // check if 'is not a number'
String dataTtemp2=String(t, 1);//转换成字符串 //温度 保留一位小数
const char *Ttempstr2 = dataTtemp2.c_str(); //转换为字符数组
// Paint_DrawNum(223, 23, 338, &Font12, BLACK, WHITE); //温度
Paint_DrawString_EN(213, 27, Ttempstr2, &Font16, WHITE, BLACK);//白底黑字//温度
Paint_DrawString_CN(270, 23,"℃", &Font12CN, BLACK, WHITE);
#if debuguse
Serial.print("Temp *C = "); Serial.println(t);
#endif
}
else {
#if debuguse
Serial.println("Failed to read temperature");
#endif
}
//湿度
if (! isnan(h)) { // check if 'is not a number'
String dataHtemp2=String(h, 1);//转换成字符串 //湿度 保留一位小数
const char *Htempstr2 = dataHtemp2.c_str(); //转换为字符数组
// Paint_DrawNum(223, 40, 666, &Font12, BLACK, WHITE); //湿度
Paint_DrawString_EN(213, 43, Htempstr2, &Font16, WHITE, BLACK);//白底黑字 //湿度
Paint_DrawString_EN(260, 43, "%RH", &Font16, WHITE, BLACK);//白底黑字
#if debuguse
Serial.print("Hum. % = "); Serial.println(h);
#endif
}
else {
#if debuguse
Serial.println("Failed to read humidity");
#endif
}
// EPD_2IN9_Display(BlackImageAll);
// DEV_Delay_ms(3000);
//显示时间
EPD_2IN9_Init(EPD_2IN9_PART);
Paint_SelectImage(BlackImageAll);
PAINT_TIME sPaint_time;
sPaint_time.Hour = now.hour();
sPaint_time.Min = now.minute();
sPaint_time.Sec = now.second();//这个实际不显示
Paint_ClearWindows(50, 30, 20 + Font48.Width * 7, 30 + Font48.Height, WHITE);
Paint_DrawTime(50, 30, &sPaint_time, &Font48, WHITE, BLACK);
EPD_2IN9_Display(BlackImageAll);
// DEV_Delay_ms(500);//Analog clock 1s
#if debuguse
printf("epd Goto Sleep...\r\n");
#endif
EPD_2IN9_Sleep();
free(BlackImageAll);
BlackImageAll = NULL;
digitalWrite(23, HIGH); //关闭墨水屏
}
//联网更新时间,并写入RTC
void InitWifiTime()
{
//设置ESP32工作模式为无线终端模式
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
#if debuguse
Serial.print(".");
#endif
}
Serial.println("WiFi connected!");
configTime(8 * 3600, 0, NTP1, NTP2, NTP3);
#if debuguse
Serial.println("SET time internet Over!");
#endif
delay(1000);
printLocalTime();
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
}
//检测闹钟是否到时间,置闹铃标志
void CheckAlarm()
{
DateTime now = rtc.now();
//检测闹钟是否到时间
if(SetAlarOnOffFlag==1)//打开了闹钟
{
#if debuguse
Serial.println("CheckAlarm SetAlarOnOffFlag IS:");
Serial.println(SetAlarOnOffFlag );
#endif
if((SetAlarmHour==now.hour())&&(SetAlarmMin==now.minute()))
{
#if debuguse
Serial.println("CheckAlarm OK IS:");
#endif
if(SetAlarMode == 1)//说明是响一次
{
SetAlarOnOffFlag=0;//关闭闹钟
EEPROM.write(3, SetAlarOnOffFlag); //写入数据
EEPROM.commit(); //保存更改的数据
AlarmStartFlag=1;
#if debuguse
Serial.println("CheckAlarm OK SetAlarMode ONE");
#endif
}
else if(SetAlarMode == 5)//说明是工作日响
{
if((now.dayOfTheWeek()!=0)&&(now.dayOfTheWeek()!=6))
{
AlarmStartFlag=1;
}
}
else if(SetAlarMode == 7)//说明是所有时间都响
{
AlarmStartFlag=1;
}
}
}
}
//墨水屏设置闹钟时间 设置完不休眠epd
void epdOutAlarmSet(int SleepFlag) //睡眠标志,0不睡眠,1睡眠
{
DateTime now = rtc.now();
digitalWrite(23, LOW); //打开墨水屏电源
DEV_Delay_ms(100);
#if debuguse
printf("EPD_2IN9_test Demo\r\n");
#endif
DEV_Module_Init();
#if debuguse
printf("e-Paper Init and Clear...\r\n");
#endif
EPD_2IN9_Init(EPD_2IN9_FULL);
EPD_2IN9_Clear();
// DEV_Delay_ms(500);
//Create a new image cache
// UBYTE *BlackImage;
/* you have to edit the startup_stm32fxxx.s file and set a big enough heap size */
UWORD Imagesize = ((EPD_2IN9_WIDTH % 8 == 0)? (EPD_2IN9_WIDTH / 8 ): (EPD_2IN9_WIDTH / 8 + 1)) * EPD_2IN9_HEIGHT;
if((BlackImage = (UBYTE *)malloc(Imagesize)) == NULL) {
#if debuguse
printf("Failed to apply for black memory...\r\n");
#endif
while(1);
}
#if debuguse
printf("Paint_NewImage\r\n");
#endif
Paint_NewImage(BlackImage, EPD_2IN9_WIDTH, EPD_2IN9_HEIGHT, 270, WHITE);//旋转了270度显示
Paint_SelectImage(BlackImage);
Paint_Clear(WHITE);
Paint_DrawLine(0, 20, 296, 20, BLACK, DOT_PIXEL_1X1, LINE_STYLE_SOLID);//上格横线
Paint_DrawRectangle(210, 20, 296, 108, BLACK, DOT_PIXEL_1X1, DRAW_FILL_EMPTY);//左边矩形框
Paint_DrawLine(0, 108, 296, 108, BLACK, DOT_PIXEL_1X1, LINE_STYLE_SOLID);//下面横线
Paint_DrawLine(1, 20, 1, 108, BLACK, DOT_PIXEL_1X1, LINE_STYLE_SOLID);//最左边竖线
Paint_DrawLine(0, 88, 210, 88, BLACK, DOT_PIXEL_1X1, LINE_STYLE_SOLID);//中间闹钟横线
// Paint_DrawLine(68, 106, 88, 106, BLACK, DOT_PIXEL_1X1, LINE_STYLE_SOLID);//闹钟模式设置显示,在下方画一条线
// Paint_DrawLine(140, 106, 150, 106, BLACK, DOT_PIXEL_1X1, LINE_STYLE_SOLID);//闹钟的时设置显示,在下方画一条线
// Paint_DrawLine(155, 106, 150, 106, BLACK, DOT_PIXEL_1X1, LINE_STYLE_SOLID);//闹钟的分钟设置显示,在下方画一条线
//显示时间
EPD_2IN9_Init(EPD_2IN9_PART);
Paint_SelectImage(BlackImage);
PAINT_TIME sPaint_time2;
sPaint_time2.Hour = now.hour();
sPaint_time2.Min = now.minute();
sPaint_time2.Sec = now.second();//这个实际不显示
Paint_ClearWindows(50, 30, 20 + Font48.Width * 7, 30 + Font48.Height, WHITE);
Paint_DrawTime(50, 30, &sPaint_time2, &Font48, WHITE, BLACK);
//显示当前年月日 星期
String datatemp1=String(now.year(), DEC);//转换成字符串 显示年
const char *tempdatastr1 = datatemp1.c_str(); //转换为字符数组
// Paint_DrawString_EN(0, 0, "2022-09-26", &Font16, WHITE, BLACK);//白底黑字
Paint_DrawString_EN(0, 2, tempdatastr1 , &Font16, WHITE, BLACK);//白底黑字
Paint_DrawString_EN(43, 2, "-", &Font16, WHITE, BLACK);//白底黑字
String datatemp2=String(now.month(), DEC);////转换成字符串 显示月
const char *tempdatastr2 = datatemp2.c_str(); //转换为字符数组
Paint_DrawString_EN(53, 2, tempdatastr2, &Font16, WHITE, BLACK);//白底黑字
Paint_DrawString_EN(73, 2, "-", &Font16, WHITE, BLACK);//白底黑字
String datatemp3=String(now.day(), DEC);//转换成字符串 显示日期
const char *tempdatastr3 = datatemp3.c_str(); //转换为字符数组
Paint_DrawString_EN(83, 2, tempdatastr3, &Font16, WHITE, BLACK);//白底黑字
Paint_DrawString_CN(118, 2,daysOfTheWeek[now.dayOfTheWeek()], &Font12CN, BLACK, WHITE);//显示星期
// 显示电量
int sensorValue=PowerVolume(analogRead(A0));//gpio 36
Paint_DrawString_CN(190, 0,"电量:", &Font12CN, BLACK, WHITE);
Paint_DrawNum(232, 2, sensorValue, &Font16, BLACK, WHITE); //电量
Paint_DrawString_EN(270, 2, "%", &Font16, WHITE, BLACK);//白底黑字
// //最下格的文字
// Paint_DrawString_CN(2, 109,"晴转多云", &Font12CN, BLACK, WHITE);
// Paint_DrawString_CN(148, 109,"温度:", &Font12CN, BLACK, WHITE);
// Paint_DrawString_EN(194, 109, "30~33", &Font16, WHITE, BLACK);//白底黑字
// Paint_DrawString_CN(276, 109,"℃", &Font12CN, BLACK, WHITE);
//中间的闹钟的位置
if(SetAlarOnOffFlag==1)
{
Paint_DrawString_CN(2, 88,"闹钟开", &Font12CN, BLACK, WHITE);
}
else
{
Paint_DrawString_CN(2, 88,"闹钟关", &Font12CN, BLACK, WHITE);
}
if(SetAlarMode==1)
{
Paint_DrawString_CN(68, 88,"一次", &Font12CN, BLACK, WHITE);
}
else if(SetAlarMode==5)
{
Paint_DrawString_CN(68, 88,"五天模式", &Font12CN, BLACK, WHITE);
}
else if(SetAlarMode==7)
{
Paint_DrawString_CN(68, 88,"七天模式", &Font12CN, BLACK, WHITE);
}
//显示设定的闹钟时间
PAINT_TIME sPaint_alar_time2;
sPaint_alar_time2.Hour = SetAlarmHour;
sPaint_alar_time2.Min = SetAlarmMin;
sPaint_alar_time2.Sec = 0;//这个实际不显示
Paint_ClearWindows(140, 90, 30 + Font16.Width * 7, 88 + Font16.Height, WHITE);
Paint_DrawTime(140, 90, &sPaint_alar_time2, &Font16, WHITE, BLACK);
// Paint_DrawString_EN(148, 88, "07:10", &Font16, WHITE, BLACK);//白底黑字
//温度、湿度和大气压
float t = sht31.readTemperature();
float h = sht31.readHumidity();
//温度
if (! isnan(t)) { // check if 'is not a number'
String dataTtemp2=String(t, 1);//转换成字符串 //温度 保留一位小数
const char *Ttempstr2 = dataTtemp2.c_str(); //转换为字符数组
// Paint_DrawNum(223, 23, 338, &Font12, BLACK, WHITE); //温度
Paint_DrawString_EN(213, 27, Ttempstr2, &Font16, WHITE, BLACK);//白底黑字//温度
Paint_DrawString_CN(270, 23,"℃", &Font12CN, BLACK, WHITE);
#if debuguse
Serial.print("Temp *C = "); Serial.println(t);
#endif
}
else {
#if debuguse
Serial.println("Failed to read temperature");
#endif
}
//湿度
if (! isnan(h)) { // check if 'is not a number'
String dataHtemp2=String(h, 1);//转换成字符串 //湿度 保留一位小数
const char *Htempstr2 = dataHtemp2.c_str(); //转换为字符数组
// Paint_DrawNum(223, 40, 666, &Font12, BLACK, WHITE); //湿度
Paint_DrawString_EN(213, 43, Htempstr2, &Font16, WHITE, BLACK);//白底黑字 //湿度
Paint_DrawString_EN(260, 43, "%RH", &Font16, WHITE, BLACK);//白底黑字
#if debuguse
Serial.print("Hum. % = "); Serial.println(h);
#endif
}
else {
#if debuguse
Serial.println("Failed to read humidity");
#endif
}
// EPD_2IN9_Display(BlackImage);
// DEV_Delay_ms(3000);
//显示时间
EPD_2IN9_Init(EPD_2IN9_PART);
Paint_SelectImage(BlackImage);
PAINT_TIME sPaint_time;
sPaint_time.Hour = now.hour();
sPaint_time.Min = now.minute();
sPaint_time.Sec = now.second();//这个实际不显示
Paint_ClearWindows(50, 30, 20 + Font48.Width * 7, 30 + Font48.Height, WHITE);
Paint_DrawTime(50, 30, &sPaint_time, &Font48, WHITE, BLACK);
EPD_2IN9_Display(BlackImage);
// DEV_Delay_ms(500);//Analog clock 1s
if(SleepFlag==1)
{
#if debuguse
printf("epd Goto Sleep...\r\n");
#endif
EPD_2IN9_Sleep();
free(BlackImage);
BlackImage = NULL;
digitalWrite(23, HIGH); //关闭墨水屏
}
}
void epdOutAlarmSetChange(int Postion) //下划线选择设置 1为闹钟模式下面加下划线,2为闹钟时间的时加下划线,3为闹钟时间的分加下划线
{
// UBYTE *BlackImage;
EPD_2IN9_Init(EPD_2IN9_PART);
Paint_SelectImage(BlackImage);
Paint_ClearWindows(67, 105, 185, 106, WHITE);//清空原来的线
if(Postion==1)
{
Paint_DrawLine(68, 106, 130, 106, BLACK, DOT_PIXEL_1X1, LINE_STYLE_SOLID);//闹钟模式设置显示,在下方画一条线
}
else if(Postion==2)
{
Paint_DrawLine(142, 106, 160, 106, BLACK, DOT_PIXEL_1X1, LINE_STYLE_SOLID);//闹钟的时设置显示,在下方画一条线
}
else if(Postion==3)
{
Paint_DrawLine(167, 106, 187, 106, BLACK, DOT_PIXEL_1X1, LINE_STYLE_SOLID);//闹钟的分钟设置显示,在下方画一条线
}
EPD_2IN9_Display(BlackImage);
// DEV_Delay_ms(500);//Analog clock 1s
}
void epdOutAlarmSetModeChange() //闹钟模式选择显示,一次,5天制,7天制显示
{
EPD_2IN9_Init(EPD_2IN9_PART);
Paint_SelectImage(BlackImage);
Paint_ClearWindows(68, 88, 140, 104, WHITE);//清空原来字
if(SetAlarMode==1)
{
Paint_DrawString_CN(68, 88,"一次", &Font12CN, BLACK, WHITE);
}
else if(SetAlarMode==5)
{
Paint_DrawString_CN(68, 88,"五天模式", &Font12CN, BLACK, WHITE);
}
else if(SetAlarMode==7)
{
Paint_DrawString_CN(68, 88,"七天模式", &Font12CN, BLACK, WHITE);
}
EPD_2IN9_Display(BlackImage);
// DEV_Delay_ms(500);//Analog clock 1s
}
void epdOutAlarmSetHourMinChange() //闹钟时间设置选择显示 同时显示时分
{
// UBYTE *BlackImage;
EPD_2IN9_Init(EPD_2IN9_PART);
Paint_SelectImage(BlackImage);
Paint_ClearWindows(140, 88, 190, 104, WHITE);//清空原来字
//显示设定的闹钟时间
PAINT_TIME sPaint_alar_time2;
sPaint_alar_time2.Hour = SetAlarmHour;
sPaint_alar_time2.Min = SetAlarmMin;
sPaint_alar_time2.Sec = 0;//这个实际不显示
Paint_ClearWindows(140, 90, 30 + Font16.Width * 7, 88 + Font16.Height, WHITE); //清空原来字
Paint_DrawTime(140, 90, &sPaint_alar_time2, &Font16, WHITE, BLACK);
EPD_2IN9_Display(BlackImage);
// DEV_Delay_ms(500);//Analog clock 1s
// free(BlackImage);
// BlackImage = NULL;
}
/*
Method to print the GPIO that triggered the wakeup
*/
void print_GPIO_wake_up(){
uint64_t GPIO_reason = esp_sleep_get_ext1_wakeup_status();
Serial.print("GPIO that triggered the wake up: GPIO ");
Serial.println((log(GPIO_reason))/log(2), 0);
Serial.println("UINT IS:");
Serial.println(GPIO_reason);
}
/* Entry point ----------------------------------------------------------------*/
void setup()
{
Serial.begin(115200);
pinMode(4, INPUT);//初始化4号管脚为输入,button1 闹钟暂停和背光按钮 RTC-GPIO-10
pinMode(2, INPUT);//初始化2号管脚为输入,button2 闹钟闹钟开关按钮 RTC-GPIO-12
pinMode(12, INPUT);//初始化12号管脚为输入,button3 选择 RTC-GPIO-15
pinMode(35, INPUT);//初始化35号管脚为输入,button4 + RTC-GPIO-5
pinMode(32, INPUT);//初始化32号管脚为输入,button5 - RTC-GPIO-9
pinMode(33, INPUT);//初始化33号管脚为输入,button6 确定 RTC-GPIO-8
pinMode(23, OUTPUT);//初始化23号管脚为输出,墨水屏供电控制
pinMode(5, OUTPUT);//初始化5号管脚为输出,蜂鸣器控制
pinMode(18, OUTPUT);//初始化18号管脚为输出,背光LED控制
//初始化输出管脚
digitalWrite(23, HIGH); //关闭墨水屏
digitalWrite(5, LOW);//关闭蜂鸣器
digitalWrite(18, LOW);//关闭LED背光
// button1Flag= digitalRead(4);//button1 闹钟暂停和背光按钮
// button2Flag= digitalRead(2);//button2 闹钟闹钟开关按钮
// button3Flag= digitalRead(12);//butto3 选择
// button4Flag= digitalRead(35);//button4 +
// button5Flag= digitalRead(32);//button5 -
// button6Flag= digitalRead(33);//button6 确定
//初始化DS3232的RTC模块
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
while (1) delay(10);
}
// 初始化温湿度模块
if (! sht31.begin(0x44)) { // Set to 0x45 for alternate i2c addr
Serial.println("Couldn't find SHT31");
while (1) delay(1);
}
analogSetPinAttenuation(A0,ADC_0db); //测试范围100mv~950mv 参考电压1.1v
EEPROM.begin(10); //申请10个字节的EEPROM存储空间,存储闹钟的时间、模式和是否开关闹钟的状态
/////////////////////////////////////////////////////////////////////////////////
//读出存储的闹钟时间、模式和开关闹钟情况
SetAlarmHour = EEPROM.read(0); //读数据,闹钟设置的小时
SetAlarmMin = EEPROM.read(1); //读数据,闹钟设置的分钟
SetAlarMode = EEPROM.read(2); //读数据,闹钟设置的模式
SetAlarOnOffFlag = EEPROM.read(3); //读数据,闹钟设置的开关
if(SetAlarmHour>25)//说明小时时间不对
{
EEPROM.write(0, 12); //写入数据
EEPROM.commit(); //保存更改的数据
}
if(SetAlarmMin>60)//说明分钟时间不对
{
EEPROM.write(1, 00); //写入数据
EEPROM.commit(); //保存更改的数据
}
if((SetAlarMode==1)||(SetAlarMode==5)||(SetAlarMode==7))//说明模式设置不对,响一次,5天响,7天响
{
;
}
else
{
EEPROM.write(2, 1); //写入数据
EEPROM.commit(); //保存更改的数据
}
if((SetAlarOnOffFlag==0)||(SetAlarOnOffFlag==1))//说明开关设置不对,设置为关
{
;
}
else
{
EEPROM.write(3, 0); //写入数据
EEPROM.commit(); //保存更改的数据
}
SetAlarmHour = EEPROM.read(0); //读数据,闹钟设置的小时
SetAlarmMin = EEPROM.read(1); //读数据,闹钟设置的分钟
SetAlarMode = EEPROM.read(2); //读数据,闹钟设置的模式 响一次,5天响,7天响
SetAlarOnOffFlag = EEPROM.read(3); //读数据,闹钟设置的开关 0是关了闹钟,1是开闹钟
//以上是读出闹钟相关参数
////////////////////////////////////////////////////////////////////////////////
// digitalWrite(23, LOW); //打开墨水屏电源
// DEV_Delay_ms(100);
print_wakeup_reason();//得到苏醒的原因
}
/* The main loop -------------------------------------------------------------*/
int DelayCount=0;
int BuzzerGpioFlag=0;//管脚状态
int SetFlag=0;//选择第几项记录
int AlarmDelayCountStop=0;//在没有人关闭闹钟的情况下计数,响一分钟后自动停止
void loop()
{
if(WakeFlag==6)//说明是第一次上电启动的,初始化EPD和时钟
{
InitWifiTime();//联网对时
epdOut(); //墨水屏的显示
CheckAlarm();//检测闹钟是否到时间,置闹铃标志
AlarmDelayCountStop=0;//清一下计数器
}
else if(WakeFlag==3)//说明是定时器苏醒,要更新一下时间
{
epdOut(); //墨水屏的显示
CheckAlarm(); //检测闹钟是否到时间,置闹铃标志
AlarmDelayCountStop=0;//清一下计数器
}
else if(WakeFlag==2) //外部管脚触发唤醒
{
// if(esp_sleep_get_ext1_wakeup_status()==16)//说明是button1按钮
if(log(esp_sleep_get_ext1_wakeup_status())/log(2)==4)//说明是button1按钮 停止闹钟或者打开背光
{
if(AlarmStartFlag==1)//说明闹钟在响
{
AlarmStartFlag=0;
}
else
{
digitalWrite(18, HIGH);//打开LED背光
while(digitalRead(4));
digitalWrite(18, LOW);//关闭LED背光
}
}
if(log(esp_sleep_get_ext1_wakeup_status())/log(2)==2)//开关闹钟选项的按键
{
if(SetAlarOnOffFlag==0)//说明开关设置为关,设置为开
{
EEPROM.write(3, 1); //写入数据
EEPROM.commit(); //保存更改的数据
SetAlarOnOffFlag=1;
}
else if(SetAlarOnOffFlag==1)//说明开关设置开,设置为关
{
EEPROM.write(3, 0); //写入数据
EEPROM.commit(); //保存更改的数据
SetAlarOnOffFlag=0;
}
epdOutAlarmSet(1); //墨水屏的显示 休眠和清除显存
}
if(log(esp_sleep_get_ext1_wakeup_status())/log(2)==12)//设置选择按钮
{
SetFlag=1;//选择闹钟模式选项
//读出存储的闹钟时间、模式和开关闹钟情况
SetAlarmHour = EEPROM.read(0); //读数据,闹钟设置的小时
SetAlarmMin = EEPROM.read(1); //读数据,闹钟设置的分钟
SetAlarMode = EEPROM.read(2); //读数据,闹钟设置的模式
SetAlarOnOffFlag = EEPROM.read(3); //读数据,闹钟设置的开关
epdOutAlarmSet(0); //墨水屏的显示 不休眠和清楚显存//刷新epd不休眠
epdOutAlarmSetChange(SetFlag);//显示下划线
for(uint16_t nn=0;nn<3000;nn++)//延时30S做为设置等待,如果有按键操作就再延时30S
{
if(digitalRead(12))//选择按键
{
nn=0;//清一下计数器,再延时30S
if(SetFlag<3) SetFlag++;
else SetFlag=1;//到第一项
epdOutAlarmSetChange(SetFlag);//加下划线
}
else if(digitalRead(35))//+加号按键
{
nn=0;//清一下计数器,再延时30S
if(SetFlag==1)//说明设置闹钟模式
{
if(SetAlarMode==1)
{
SetAlarMode=5;
}
else if(SetAlarMode==5)
{
SetAlarMode=7;
}
else if(SetAlarMode==7)
{
SetAlarMode=1;
}
epdOutAlarmSetModeChange();//显示
}
else if(SetFlag==2)//说明是设置闹钟时间的时
{
if(SetAlarmHour<24)
{
SetAlarmHour++;
epdOutAlarmSetHourMinChange();
}
else if(SetAlarmHour==24)
{
SetAlarmHour=0;
epdOutAlarmSetHourMinChange();
}
}
else if(SetFlag==3)//说明是设置闹钟时间的分
{
if(SetAlarmMin<59)
{
SetAlarmMin++;
epdOutAlarmSetHourMinChange();
}
else if(SetAlarmMin==59)
{
SetAlarmMin=0;
epdOutAlarmSetHourMinChange();
}
}
}
else if(digitalRead(32))//-加号按键
{
nn=0;//清一下计数器,再延时30S
if(SetFlag==1)//说明设置闹钟模式
{
if(SetAlarOnOffFlag==1)
{
SetAlarOnOffFlag=7;
}
else if(SetAlarOnOffFlag==7)
{
SetAlarOnOffFlag=5;
}
else if(SetAlarOnOffFlag==5)
{
SetAlarOnOffFlag=1;
}
epdOutAlarmSetModeChange();//显示
}
else if(SetFlag==2)//说明是设置闹钟时间的时
{
if(SetAlarmHour>0)
{
SetAlarmHour--;
epdOutAlarmSetHourMinChange();
}
else if(SetAlarmHour==0)
{
SetAlarmHour=24;
epdOutAlarmSetHourMinChange();
}
}
else if(SetFlag==3)//说明是设置闹钟时间的分
{
if(SetAlarmMin>0)
{
SetAlarmMin--;
epdOutAlarmSetHourMinChange();
}
else if(SetAlarmMin==0)
{
SetAlarmMin=59;
epdOutAlarmSetHourMinChange();
}
}
}
else if(digitalRead(33))//确认按键 写入数据并退出
{
nn=0;//清一下计数器,再延时30S
EEPROM.write(0, SetAlarmHour); //写入数据,闹钟设置的小时
EEPROM.write(1, SetAlarmMin); //写入数据,闹钟设置的分钟
EEPROM.write(2, SetAlarMode); //写入数据,闹钟设置的模式
EEPROM.write(3, SetAlarOnOffFlag); //写入数据,闹钟设置的开关
EEPROM.commit(); //保存更改的数据
epdOutAlarmSet(1);//墨水屏彻底显示一下
// //设置外部管脚唤醒
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); //设置休眠时间
esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH);
#if debuguse
Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) +
" Seconds");
#endif
#if debuguse
Serial.println("This will never be printed");
#endif
Serial.flush();
esp_deep_sleep_start();//开始休眠
}
delay(10);//延时10ms
}
epdOut(); //墨水屏彻底显示一下
}
// print_GPIO_wake_up();//查找是哪个按钮被按下
// //设置外部管脚唤醒
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); //设置休眠时间
esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH);
#if debuguse
Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) +
" Seconds");
#endif
#if debuguse
Serial.println("This will never be printed");
#endif
Serial.flush();
esp_deep_sleep_start();//开始休眠
}
WakeFlag=0;//复位以下
// print_GPIO_wake_up();//查找是哪个按钮被按下
if(AlarmStartFlag==0)//说明闹钟没有响,可以进行休眠
{
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); //设置休眠时间
// //设置外部管脚唤醒
esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH);
#if debuguse
Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) +
" Seconds");
#endif
#if debuguse
Serial.println("This will never be printed");
#endif
Serial.flush();
esp_deep_sleep_start();//开始休眠
}
button1Flag= digitalRead(4);//button1 闹钟暂停和背光按钮
button2Flag= digitalRead(2);//button2 闹钟闹钟开关按钮
button3Flag= digitalRead(12);//butto3 选择
button4Flag= digitalRead(35);//button4 +
button5Flag= digitalRead(32);//button5 -
button6Flag= digitalRead(33);//button6 确定
#if debuguse
Serial.println("No sleep");
Serial.println("AlarmStartFlag IS:");
Serial.println(AlarmStartFlag);
#endif
if(button1Flag==1)//说明是button1被按下,暂停闹钟
{
if(AlarmStartFlag==1)//说明闹钟在响
{
AlarmStartFlag=0;
if(SetAlarMode==1) //显示闹钟关的字
{
digitalWrite(5, LOW);//关闭蜂鸣器
epdOut();
}
}
}
//响蜂鸣器
if(AlarmStartFlag==1)//说明闹钟在响
{
DelayCount++;
if(DelayCount>20)
{
#if debuguse
Serial.println("Alarm Sound");
#endif
DelayCount=0;
if(BuzzerGpioFlag==0)
{
BuzzerGpioFlag=1;
digitalWrite(5, HIGH);//打开蜂鸣器
}
else
{
BuzzerGpioFlag=0;
digitalWrite(5, LOW);//关闭蜂鸣器
}
}
}
else digitalWrite(5, LOW);//关闭蜂鸣器
//计数如果没有人停止那种到1.5分钟后就自动停止
AlarmDelayCountStop++;
if(AlarmDelayCountStop>9000)
{
AlarmDelayCountStop=0;//清计数器
AlarmStartFlag=0;//关闭闹钟
if(SetAlarMode==1) //说明只响一次,显示闹钟关的字
{
SetAlarOnOffFlag=0;//关闭闹钟
EEPROM.write(3, SetAlarOnOffFlag); //写入数据
EEPROM.commit(); //保存更改的数据
digitalWrite(5, LOW);//关闭蜂鸣器
epdOut();
}
}
delay(10);//延时10ms
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/ladneg/esp32-epd-alarm-clock.git
git@gitee.com:ladneg/esp32-epd-alarm-clock.git
ladneg
esp32-epd-alarm-clock
esp32EpdAlarmClock
master

搜索帮助