arduino 时间灯控
总体介绍一下这个灯控是具体干啥的。最开始是老师看了我那个阿里云灯控之后,然后来活了。做一个可以控制220V灯通过时间控制的通过按键设置时间的灯控,然后就有了这个创作。
开始搭建前,就要有一个大致的思路,于是我画了一个思维导图。
大概讲解一下我的思路.
1.我是基于arduino Nano制作的(arduino uno也可以引脚接法一模一样),之所以选择它,是因为其体积小,之后打算画一块板子,将它们直接插上去,省得杜邦线绕来绕去
2.按键就用了两个,通过按键来进行具体设置,我的想法是先长按按键2大约1秒的样子,开始设置小时时间的十位数,通过按键2来加减。然后再通过按键2设置小时时间个位,分钟设置同理。然后就是设置开启时间和关闭时间。显示屏上哪个亮哪个就是所设置的量
3.220V的电压是通过继电器来控制的,注意电流,如果继电器的工作范围在0~10A之间,我推荐电流不要超过5A,因为我那个工作没几天就坏了,可能是瞬间开启时电流过大对其的损耗比较大。(个人经验所得)
4.本来打算在arduino上跑操作系统的,任务之间来回调度。苦于刚学打算还是跑裸机慢慢学。
5.其实项目整体难度并不大,难就难在程序怎么写,它偏算法和逻辑方面的程序比较多。
软件部分
OLED屏
说一说雷区,很多人都会用这一套代码的确,这是基础代码,但是我发现它一定要在while( u8g.nextPage() ); 这一串代码中跑,而这一串代码返回的是0,0,0,1循环发送,而且它库给的IIC通讯速度特别慢,达不到我的速度要求(后来选择的是SPI协议),我很快就把这条思路扔掉了,而且我的循环要逐步的往深处走,后续整体代码解析会讲到的。
所以我用了以下代码:
//显示中英文字符程序
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#define LOGO16_GLCD_HEIGHT 16 //定义显示高度
#define LOGO16_GLCD_WIDTH 16 //定义显示宽度
//中文:中 (存储点阵变量,用函数display.drawBitmap()调用即可)
static const unsigned char PROGMEM str_1[] =
{0x00,0xFE,0x02,0x12,0x92,0x92,0x92,0xF2,0x92,0x92,0x92,0x12,0x02,0xFE,0x00,0x00,
0x00,0xFF,0x40,0x48,0x48,0x48,0x48,0x4F,0x48,0x4A,0x4C,0x48,0x40,0xFF,0x00,0x00};/*"国",0*/
//中文:国
static const unsigned char PROGMEM str_2[] =
{
0x00,0x7F,0x40,0x48,0x49,0x49,0x49,0x4F,0x49,0x49,0x49,0x48,0x40,0x7F,0x00,0x00,
0x00,0xFF,0x02,0x12,0x12,0x12,0x12,0xF2,0x12,0x52,0x32,0x12,0x02,0xFF,0x00,0x00,
};/*"国",0*/
/* (16 X 16 , 宋体 )*/
#if (SSD1306_LCDHEIGHT != 64)
//#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
void setup() {
Serial.begin(9600);
// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3D (for the 128x64)
// init done
display.clearDisplay(); //清屏
//英文字符显示,直接用display.println或print显示字符串就行
//println换行,print不换行
display.setTextSize(1); //设置字体大小
display.setTextColor(WHITE); //设置字体颜色白色
display.setCursor(0,0); //设置字体的起始位置
display.println("Hello, world!"); //输出字符并换行
display.setTextColor(BLACK, WHITE); //设置字体黑色,字体背景白色
display.println(3.141592); //输出数字并换行
display.setTextSize(2); //设置字体大小
display.setTextColor(WHITE); //设置字体白色
display.print("0x"); //输出字符
display.println(0xDEADBEEF, HEX); //输出为ASCII编码的十六进制
//display.clearDisplay(); //清屏
delay(2000);
display.display(); //显示以上
display.clearDisplay(); //清屏
delay(2000);
//display.drawRect(38, 38, 51, 6, WHITE);//以(38,38)为起点绘制一个长度51宽度为6的矩形
//中文字符显示
//delay(3000);
//display.clearDisplay(); //清屏
// display.drawBitmap(26, 32, str_1, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH, 1); //在坐标X:26 Y:16的位置显示中文字符凌
//display.drawBitmap(42, 32, str_2, 16, 16, 1); //在坐标X:42 Y:16的位置显示中文字符顺
//display.display(); //把缓存的都显示
}
void loop() {
display.setTextSize(1); //设置字体大小
display.setTextColor(WHITE); //设置字体颜色白色
display.setCursor(0,0); //设置字体的起始位置
display.println("Hello, world!"); //输出字符并换行
display.setTextColor(BLACK, WHITE); //设置字体黑色,字体背景白色
display.println(3.88); //输出数字并换行
display.display(); //显示以上
}
借鉴资料:
https://blog.csdn.net/jiayan0428/article/details/105254403
他的关键就在于
display.setTextSize(1); //设置字体大小
display.setTextColor(WHITE); //设置字体颜色白色
display.setCursor(0,0); //设置字体的起始位置
display.println(“Hello, world!”); //输出字符并换行
这几行代码的限制条件几乎没有,你可以在任何函数中调用,方便了我们的函数构造。
DS1302
说一说雷区,我最开始用的是DS1302库的示例代码,但是将它和OLED代码拼装的时候,set up中的这几段代码执行之后就停止了,想实现的循环结构被打破了。后来想了想是不是wire库之间冲突了,所以我借鉴了这个大佬的程序
https://blog.csdn.net/TonyIOT/article/details/105778466
#include <DS1302.h>
DS1302 rtc(2, 3, 4); //对应DS1302的RST,DAT,CLK
void initRTCTime(void)//初始化RTC时钟
{
rtc.writeProtect(false); //关闭写保护
rtc.halt(false); //清除时钟停止标志
Time t(2020, 4, 25, 21, 50, 50, 7); //新建时间对象 最后参数位星期数据,周日为1,周一为2以此类推
rtc.time(t);//向DS1302设置时间数据
}
void printTime()//打印时间数据
{
Time tim = rtc.time(); //从DS1302获取时间数据
char buf[50];
snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d",
tim.yr, tim.mon, tim.date,
tim.hr, tim.min, tim.sec);
Serial.println(buf);
}
void setup() {
Serial.begin(9600);
//新模块上电需要设置一次当前时间,
//下载完成后需屏蔽此函数再次下载,否则每次上电都会初始化时间数据
initRTCTime();
}
void loop() {
printTime();
delay(1000);
}
推荐认真看一下,他的库我放到后续百度网盘链接中。
继电器
#define LIGHT_PIN 9 //设置继电器的控制数字引脚
void setup() {
// put your setup code here, to run once:
pinMode(LIGHT_PIN,OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
Serial.print("turn off the light");
digitalWrite(LIGHT_PIN,LOW);
Serial.print("turn on the light");
digitalWrite(LIGHT_PIN,HIGH);
}
以上就是继电器的代码,通过高低电平控制其开关即可。
按键
按键我用的是上拉电阻
我借鉴的是太极创客的资料代码,非常推荐这个网站,本人arduino7成的知识都来自于这个网站。
#define button1 6 //按键1,加减
#define button2 7 //按键2,开启设置,确定
void setup() {
// put your setup code here, to run once:
pinMode(button1,INPUT);
pinMode(button2,INPUT);
}
void loop() {
// put your main code here, to run repeatedly:
}
EEPROM
之所以用它,相必也猜到了,掉电我也要保证数据不会丢失。
#include <EEPROM.h>
char TimeOn[6]={'0','8',':','0','0'};
char TimeOff[6]={'2','1',':','0','0'};
char All[12];
void setup() {
// put your setup code here, to run once:
// 初始化串口
Serial.begin(9600);
//等待串口准备好
//在地址0~3依次写入2~5
for(int i = 0;i<6;i++){
EEPROM.write(i,TimeOn[i]);
//延时100ms 等待写入
delay(10);
}
for(int i = 0;i<6;i++){
EEPROM.write(i+6,TimeOff[i]);
//延时100ms 等待写入
delay(10);
}
for(int i = 0;i<12;i++){
All[i]=EEPROM.read(i);
Serial.print(All[i]);
}
// for(int i = 0;i<6;i++){
// EEPROM.write(i, 0);
// }
// Serial.println("clear");
// TimeOn[0]={'0'};TimeOn[1]={'8'};
//
// Serial.println(EEPROM.length());
// for (int i = 0 ; i < 6 ; i++) {
// TimeOn[i]=EEPROM.read(i);
// //Serial.println(i);
// delay(3);
// }
// for(int i=0;i<6;i++)
// Serial.print(TimeOn[i]);
// Serial.println("read data end");
// TimeOn[0]={'0'};TimeOn[1]={'8'};
// for(int i=0;i<6;i++)
// Serial.print(TimeOn[i]);
}
void loop() {
// put your main code here, to run repeatedly:
}
以上是EEPROM调试代码,注意它是有寿命的可擦除次数在20000次左右。
整体代码
写代码,首先就要有思路,大致的讲一讲:
1.时间变量有5位(09:00)我用了一个char型6位数组放置数据,因为我发现5位的话,OLED屏上会有乱码。然后再构建了一个timeOn[6],timeOff[6]用于贮存开关灯时间,再用EEPROM的12位储存以上数据。
2.当按键2按下后,让其再子循环中无限循环,设置小时或者分钟时,让其在它的子循环中无限循环所以我的while(1)用的比较多,这时候我不能用break了太麻烦,我选择了goto。
3.设置时按键1,按键2高电平为设置,OLED屏
display.setTextColor(BLACK, WHITE); //设置字体黑色,字体背景白色,用于显示。
4.设置步骤先按下按键2一秒左右,OLED屏小时出现设置框图,通过按键1加数,加至24后归0;再按下按键2,开始设置分钟,按键2设置分钟时间,加到60之后返回至0;再次按下按键2,选择设置的时间是开灯时间或者是关灯时间;再按下按键2,OLED屏会显示OK,表示设置完成。
6.初始化开启时间为08:00,关闭时间为21:00
#include <DS1302.h>
#include <EEPROM.h>
//#include <Arduino_FreeRTOS.h>
//void serilafun1(void *param);
//void serilafun2(void *param);
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//注意时钟模块需要断电和程序重装才能有时间改变
DS1302 rtc(2, 3, 4); //对应DS1302的RST,DAT,CLK
int sec_temp;
char datestring[20];char days[11];char times[6];int val=0;int var=0;char light[2]="ON";
char TimeOn[6]={'0','8',':','0','0'};
char TimeOff[6]={'2','1',':','0','0'};
#define button1 6 //按键1,加减
#define button2 7 //按键2,开启设置,确定
#define button3 8
#define LIGHT_PIN 9 //设置继电器的控制数字引脚
#define OLED_RESET 4
#define SSD1306_LCDHEIGHT 64
Adafruit_SSD1306 display(OLED_RESET);
#define LOGO16_GLCD_HEIGHT 16 //定义显示高度
#define LOGO16_GLCD_WIDTH 16 //定义显示宽度
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
void initRTCTime(void)//初始化RTC时钟
{
rtc.writeProtect(false); //关闭写保护
rtc.halt(false); //清除时钟停止标志
Time t(2020, 4, 25, 21, 50, 50, 7); //新建时间对象 最后参数位星期数据,周日为1,周一为2以此类推
rtc.time(t);//向DS1302设置时间数据
}
void updatTime()//打印时间数据
{
Time tim = rtc.time(); //从DS1302获取时间数据
char date[20];
char timer[20];
snprintf(date, sizeof(date), "%04d-%02d-%02d",
tim.yr, tim.mon, tim.date);
snprintf(timer, sizeof(timer), "%02d:%02d:%02d",
tim.hr, tim.min, tim.sec);
for(int i=0;i<10;i++)
days[i]=date[i];
for(int i=0;i<5;i++) //5 第三位是:
times[i]=timer[i];
if (tim.sec != sec_temp) { //一秒刷新一次
display.clearDisplay();//清屏
display.setCursor(0, 2);//设置显示位置
display.println(days);
display.setCursor(0, 24);//设置显示位置
display.println(times);
display.setCursor(30, 50);//设置显示位置
display.print("ON");
display.setCursor(55,50);//设置显示位置
display.print("/");
display.setCursor(65,50);//设置显示位置
display.println("OFF");
display.display(); // 开显示
}
sec_temp = tim.sec;
}
void setup(){
Serial.begin(9600);
pinMode(button1,INPUT);
pinMode(button2,INPUT);
pinMode(LIGHT_PIN,OUTPUT);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3D (for the 128x64)
display.setTextColor(WHITE);//开像素点发光
display.clearDisplay(); //清屏
display.setTextSize(2); //设置字体大小
// while (!Serial);//等待串口连接后执行
// xTaskCreate(serilafun1, "serilaName1" ,100, NULL, 4, NULL);//任务函数,任务名称,任务堆栈,任务输入参数(可以为NULL),任务优先级(0是最低优先级),任务传递句柄
// xTaskCreate(serilafun2, "serilaName2" ,100, NULL, 3, NULL);
// // xTaskCreate(serilafun3, "serilaName3" ,100, NULL, 5, NULL);
// vTaskStartScheduler();
}
//void serilafun1(void *param)
//{
// while (1)
// {
// RtcDateTime now = Rtc.GetDateTime(); //调用printDateTime函数
// printDateTime(now);
// }
//}
//void serilafun2(void *param)
//{
// while (1)
// {
// u8g2.firstPage();
// do
// {
// page1();
// vTaskDelay(1000);
// }while(u8g2.nextPage());
// }
//}
//void serilafun3(void *param)
//{
// while (1)
// {
// readbutton();
// }
//}
void loop(){
updatTime();
readbutton();
LightCotrol();
delay(1000);
}
void readbutton(){
//Serial.println(digitalRead(button2));
//Serial.println(digitalRead(button1));
if(digitalRead(button2)==1)
{
delay(50);
Serial.println("开始设置");
display.setTextSize(2);
display.setTextColor(BLACK, WHITE); //设置字体黑色,字体背景白色
display.setCursor(0,25); //128*64的点阵屏对应x,y轴,x,y的起始点
display.print(times[0]); //这里输入显示内容,可以是变量
display.print(times[1]); //这里输入显示内容,可以是变量
display.display();
while(1){
if(digitalRead(button1)==1&&val==0){
while(1){
Serial.println();
int hours[2];
for(int i=0;i<2;i++)
hours[i]=(int)times[i]-48; //把char改成int型,中间变量方便人工改变时间
int a=hours[0];int b=hours[1];unsigned int sum=a*10+b;
display.setTextSize(2);
display.setTextColor(BLACK, WHITE); //设置字体黑色,字体背景白色
display.setCursor(0,25); //128*64的点阵屏对应x,y轴,x,y的起始点
display.print(sum); //这里输入显示内容,可以是变量
display.display();
Serial.print(a);Serial.print(" ");Serial.println(b);
while(1){
if(digitalRead(button1)==1){ //按键加减
delay(50);
if(digitalRead(button1)==1){
sum=sum+1;
Serial.print("小时 ");
delay(500);
Serial.println(sum);
if(sum>=24 ||sum<=0){
sum=0;
}
}
}
a=sum/10;b=sum%10; //变回char,用于显示
char ac=char(a+48);
char bc=char(b+48);
times[0]=ac;
times[1]=bc;
Serial.print("小时时间设置为 ");
Serial.print(times[0]);
Serial.println(times[1]);
//Serial.println(sum);
delay(100);
display.setTextSize(2);
display.setTextColor(BLACK, WHITE); //设置字体黑色,字体背景白色
display.setCursor(0,24); //128*64的点阵屏对应x,y轴,x,y的起始点
display.print(times[0]); //这里输入显示内容,可以是变量
display.print(times[1]); //这里输入显示内容,可以是变量
display.display();
if(digitalRead(button2)==1){
val=1;
goto start;}
}
}
start:{
Serial.println("小时时间设置完成");
display.setTextSize(2);
display.setCursor(0,24); //128*64的点阵屏对应x,y轴,x,y的起始点
display.print(times[0]); //这里输入显示内容,可以是变量
display.print(times[1]); //这里输入显示内容,可以是变量
//display.display();
display.setTextColor(BLACK, WHITE); //设置字体黑色,字体背景白色
display.setCursor(35,24); //128*64的点阵屏对应x,y轴,x,y的起始点
display.print(times[3]); //这里输入显示内容,可以是变量
display.print(times[4]); //这里输入显示内容,可以是变量
display.display();
}
}
if(digitalRead(button1)==1&&val==1){
display.setTextSize(2);
display.setTextColor(BLACK, WHITE); //设置字体黑色,字体背景白色
display.setCursor(35,24); //128*64的点阵屏对应x,y轴,x,y的起始点
display.print(times[3]); //这里输入显示内容,可以是变量
display.print(times[4]); //这里输入显示内容,可以是变量
display.display();
while(1){
int minutes[2];
for(int i=0;i<2;i++)
minutes[i]=int(times[i+3])-48; //把char改成int型,中间变量方便人工改变时间
int a1=minutes[0];int b1=minutes[1];int sum1=a1*10+b1;
display.setTextSize(2);
display.setTextColor(BLACK, WHITE); //设置字体黑色,字体背景白色
display.setCursor(35,24); //分钟对应的位置
display.print(sum1); //这里输入显示内容,可以是变量
display.display();
Serial.print(a1);Serial.print(" ");Serial.println(b1);
if(digitalRead(button1)==1){ //按键加减
delay(20);
if(digitalRead(button1)==1){
sum1=sum1+1;
Serial.print("分钟 ");
delay(10);
Serial.println(sum1);
if(sum1>=60||sum1<0){
sum1=0;
}
}
}
a1=sum1/10;b1=sum1%10; //变回char,用于显示
times[3]=char(a1+48);
times[4]=char(b1+48);
Serial.print("分钟时间设置为 ");
Serial.print(times[3]);
Serial.println(times[4]);
display.setTextSize(2);
display.setTextColor(BLACK, WHITE); //设置字体黑色,字体背景白色
display.setCursor(35,24); //128*64的点阵屏对应x,y轴,x,y的起始点
display.print(times[3]); //这里输入显示内容,可以是变量
display.print(times[4]); //这里输入显示内容,可以是变量
display.display();
if(digitalRead(button2)==1){
val=2;
goto start1;
}
}
start1:
Serial.println("分钟时间设置完成");
display.setTextSize(2);
display.setTextColor(BLACK, WHITE); //设置字体黑色,字体背景白色
display.setCursor(30,50); //128*64的点阵屏对应x,y轴,x,y的起始点
display.print("ON"); //这里输入显示内容,可以是变量
Serial.print("ON"); //这里输入显示内容,可以是变量
display.setCursor(65,50); //128*64的点阵屏对应x,y轴,x,y的起始点
display.print("OFF"); //这里输入显示内容,可以是变量
display.display();
}
if(digitalRead(button1)==1&&val==2){
delay(20);
if(digitalRead(button1)==1&&val==2){ //按键加减
int lights=1;
Serial.println("设置开关灯");
while(1){
if(digitalRead(button1)==1&&lights==1){
light[2]="ON";
lights=0;
display.setTextSize(2);
display.setTextColor(BLACK, WHITE); //设置字体黑色,字体背景白色
display.setCursor(30,50); //128*64的点阵屏对应x,y轴,x,y的起始点
display.print("ON"); //这里输入显示内容,可以是变量
Serial.print("ON"); //这里输入显示内容,可以是变量
Serial.println(lights);
display.setTextColor(WHITE,BLACK);
display.setCursor(65,50); //128*64的点阵屏对应x,y轴,x,y的起始点
display.print("OFF"); //这里输入显示内容,可以是变量
display.display();
}
if(digitalRead(button1)==1&&lights==0){
if(digitalRead(button1)==1&&lights==0){ //按键加减
delay(30);
light[2]="OF";
lights=1;
display.setTextColor(BLACK, WHITE); //设置字体黑色,字体背景白色
display.setTextSize(2);
display.setCursor(65,50); //128*64的点阵屏对应x,y轴,x,y的起始点
display.print("OFF"); //这里输入显示内容,可以是变量
Serial.print("OFF"); //这里输入显示内容,可以是变量
Serial.println(lights);
display.setTextColor(WHITE,BLACK);
display.setCursor(30,50); //128*64的点阵屏对应x,y轴,x,y的起始点
display.print("ON"); //这里输入显示内容,可以是变量
display.display();}
}
if(digitalRead(button2)==1&&lights==0){ //on 设置开启时间
delay(20);
if(digitalRead(button2)==1&&lights==0){
Serial.println("完成设置");
val=0;
display.setTextColor(WHITE,BLACK);
display.setCursor(80,24); //128*64的点阵屏对应x,y轴,x,y的起始点
display.print("OK"); //这里输入显示内容,可以是变量
display.display();
delay(3000);
display.setCursor(60,24); //128*64的点阵屏对应x,y轴,x,y的起始点
display.print(" ");
display.display(); //显示以上
for(int i=0;i<6;i++)
TimeOn[i]=times[i];
for(int i = 0;i<6;i++){
EEPROM.write(i,TimeOn[i]);
//延时100ms 等待写入
delay(10);
}
goto start3;
}
}
else if(digitalRead(button2)==1&&lights==1){ //off 设置关闭时间
delay(20);
if(digitalRead(button2)==1&&lights==1){
Serial.println("完成设置");
val=0;
display.setTextColor(WHITE);
display.setCursor(80,24); //128*64的点阵屏对应x,y轴,x,y的起始点
display.print("OK"); //这里输入显示内容,可以是变量
display.display();
delay(3000);
display.setCursor(60,24); //128*64的点阵屏对应x,y轴,x,y的起始点
display.print(" ");
display.display(); //显示以上
for(int i=0;i<6;i++)
TimeOff[i]=times[i];
for(int i = 6;i<12;i++){
EEPROM.write(i,TimeOff[i-6]);
//延时100ms 等待写入
delay(10);
}
goto start3;
}
}
}
}
}
}
}
start3:
Serial.println("end");
}
void LightCotrol(){
for (int i = 0 ; i < 6 ; i++) {
TimeOn[i]=EEPROM.read(i);
//delay(10);
}
for (int i = 6 ; i < 12 ; i++) {
TimeOff[i-6]=EEPROM.read(i);
//delay(10);
}
// char All[12];
// for(int i = 0;i<12;i++){
// All[i]=EEPROM.read(i);
// Serial.print(All[i]);
// }
int hour_ten_OFF,hour_ge_OFF,minute_ten_OFF,minute_ge_OFF;
int hour_ten_ON,hour_ge_ON,minute_ten_ON,minute_ge_ON;
Serial.println("关闭时间为:");
Serial.println(TimeOff); //通过它输出日历
int hour_ten=(int)TimeOff[0]-48; //小时十位 ASCLL码对应2
int hour_ge=(int)TimeOff[1]-48; //小时个位 ASCLL码对应2
int minute_ten =(int)TimeOff[3]-48;
int minute_ge=(int)TimeOff[4]-48;
Serial.println("开启时间为:");
Serial.println(TimeOn); //通过它输出日历
int hour_ten1=(int)TimeOff[0]-48; //小时十位 ASCLL码对应2
int hour_ge1=(int)TimeOff[1]-48; //小时个位 ASCLL码对应2
int minute_ten1 =(int)TimeOff[3]-48;
int minute_ge1=(int)TimeOff[4]-48;
//Serial.print(hour_ten);
//Serial.print(hour_ge);
//Serial.print(minute_ten);
//Serial.println(minute_ge);
if(hour_ten_OFF==hour_ten&&hour_ge_OFF==hour_ge&&minute_ten_OFF==minute_ten&&minute_ge_OFF==minute_ge){
Serial.print("turn off the light");
digitalWrite(LIGHT_PIN,LOW);
}
if(hour_ten_ON==hour_ten1&&hour_ge_ON==hour_ge1&&minute_ten_ON==minute_ten1&&minute_ge_ON==minute_ge1){
Serial.print("turn on the light");
digitalWrite(LIGHT_PIN,HIGH);
}
}
更具以上思路我写下了以上代码,然后我发现了一个问题,即便是构造了一个全局变量,贮存初始化的时间,但是我优先考虑的应该是EEPROM里边有没有时间,当时没想到什么好的逻辑算法进行两者之间的判断。所以打算把初始化的时间直接放到EEPROM里边。所以外加了一段初始化时间的代码,一定要在整体代码之前烧录,这是发现问题之后才写的代码,所以我补充在了后边。
初始化时间代码
#include <EEPROM.h>
char TimeOn[6]={'0','8',':','0','0'};
char TimeOff[6]={'2','1',':','0','0'};
char All[12];
void setup() {
// put your setup code here, to run once:
// 初始化串口
Serial.begin(9600);
//等待串口准备好
//在地址0~3依次写入2~5
for(int i = 0;i<6;i++){
EEPROM.write(i,TimeOn[i]);
//延时100ms 等待写入
delay(10);
}
for(int i = 0;i<6;i++){
EEPROM.write(i+6,TimeOff[i]);
//延时100ms 等待写入
delay(10);
}
for(int i = 0;i<12;i++){
All[i]=EEPROM.read(i);
Serial.print(All[i]);
}
// for(int i = 0;i<6;i++){
// EEPROM.write(i, 0);
// }
// Serial.println("clear");
// TimeOn[0]={'0'};TimeOn[1]={'8'};
//
// Serial.println(EEPROM.length());
// for (int i = 0 ; i < 6 ; i++) {
// TimeOn[i]=EEPROM.read(i);
// //Serial.println(i);
// delay(3);
// }
// for(int i=0;i<6;i++)
// Serial.print(TimeOn[i]);
// Serial.println("read data end");
// TimeOn[0]={'0'};TimeOn[1]={'8'};
// for(int i=0;i<6;i++)
// Serial.print(TimeOn[i]);
}
void loop() {
// put your main code here, to run repeatedly:
}
以下是其的接线图
设置时间图片
串口调试初始化EEPROM时间
成功设置时间后
它会将初始化数据覆盖,掉电重启后数据依旧在。
以上就是整体设计,我将代码和库,等资料放在了百度网盘中,有需要的话,请带走
百度网盘链接:https://pan.baidu.com/s/1r93L29XekVZWya7f2A175w
提取码:khgi