锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

Arduino ESP8266学习(5)

时间:2023-09-15 20:07:02 4ws贴片电阻

ESP8266的花样点灯

WS2812B

实物预览效果

.
.
.
.

实物制作

材料清单

名称 数量
D1 mini (esp8266) 1
5050灯珠 (WS2812B) 16
DS18B20 1
光敏电阻 1
1206贴片电容(104) 16
1206贴片电阻(105) 1
1206贴片电阻(4701) 1
2mm铜柱 10
球形灯罩 1

.
DS18B20 电路原理图
注:不要接收数据引脚D8引脚!D8引脚已下拉,如果上拉会导致esp8266无法启动。
DS18B20
.
光敏电阻电路原理图

.
5050灯珠 电路原理图

.

底座(可以用纸底座)

第一层:


第二层


第三层


实物

部分功能测试
  • 光强检测
Serial.println(analogRead(A0)); 
  • 温度检测
#include  #include  #define ONE_WIRE_Pin D7  OneWire oneWire(ONE_WIRE_Pin);        DallasTemperature sensors(&oneWire);   //初始化 void setup() { 
          sensors.begin();  sensors.setWaitForConversion(false); } //打印温度 void loop() { 
          float tempC = sensors.getTempCByIndex(0);   if (tempC != DEVICE_DISCONNECTED_C)//如果温度正常  { 
             char TEMP[10];   sprintf(TEMP,"%f*C",tempC);
		Serial.print("Temp:");
		Serial.println(TEMP);
	} 
	else
	{ 
        
		Serial.println("ERROR!");
	}
	sensors.requestTemperatures(); //发起新的温度转换
	/* * 其他代码 */
	//delay(1000);
}
  • led显示
#include  //直接在库管理器搜索 FastLED 下载
#define LED_PIN D1 //控制引脚
#define NUM_LEDS 6 //灯珠数量

CRGB leds[NUM_LEDS];
//初始化
void setup()
{ 
        

	FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
	//将灯珠全部熄灭
	for(int i=0;i<NUM_LEDS;i++)leds[i] = CRGB(0, 0, 0);
	
	FastLED.show();
	
}
//测试
void loop()
{ 
        
	//全部点亮
	for(int i=0;i<NUM_LEDS;i++)
	{ 
        
		leds[i] = CRGB(5, 5, 5); //0~255
	}
	FastLED.show();	
	
	delay(3000);
	
	//逐个点亮
	for(int i=0;i<NUM_LEDS;i++)
	{ 
        
		for(int j=0;j<NUM_LEDS;j++)leds[j] = CRGB(0, 0, 0);
		
		leds[i] = CRGB(5, 0, 5);
		
		FastLED.show();
		
		delay(400);
	}

}
  • 时间获取
#include 
#include 
#include 

WiFiUDP ntpUDP;
NTPClient  timeClient(ntpUDP, "ntp1.aliyun.com",60*60*8, 30*60*1000);//时间已经校准

void setup()
{ 
        
	Serial.begin(115200);
	Serial.println();
	
	pinMode(D4,OUTPUT);	//板载led灯
	digitalWrite(D4,LOW);
	
	WiFi.begin("ssid","password");//设置名称及密码
	
	while(WiFi.status() != WL_CONNECTED )	//等待WiFi连接
	{ 
        
		delay(250);
		digitalWrite(D4,LOW);	//点亮
		delay(250);
		digitalWrite(D4,HIGH);	//熄灭
	}
	
	timeClient.begin(); 
	timeClient.update();
	
	delay(200);
	
	ntpUDP.stop();
	
	WiFi.disconnect();
	delay(100);
	WiFi.mode(WIFI_OFF);  

}

void loop()
{ 
        
	//获取时间
	timeClient.update();
	int H = timeClient.getHours();
	int M = timeClient.getMinutes();
	int S = timeClient.getSeconds();	
	
	//打印
	Serial.println("Time:");
	Serial.println( H );
	Serial.println( M );
	Serial.println( S );
	
	delay(1000);
}
代码部分

在写代码之前需要构思想要实现的功能
比如定时
开关机,APP控制,颜色设置,温度检测等。由于程序有点长,就只列出部分程序,完整程序和APP代码以及PCB文件已经放入群文件,需要的话加群下载(群链接在文章结尾)。
.
.
ESP8266保存的信息

//需要EEPROM.h文件
	struct config_type
{ 
        
  char Ssid[64];
  char Pswd[64];
  char SleepState;			//'1'为睡眠时间大于60分钟 '0'则睡眠时间小于60分钟
  unsigned int SleepTime;	//睡眠时间(分钟)
  short int R;	//led颜色
  short int G;
  short int B;
  short int OFFH;	//关机时间(小时)
  short int OFFM;	//关机时间(分钟)
  short int ONH;	//开机时间
  short int ONM;
  char clour;	//0为手动设置颜色 1为随机颜色
};
config_type Config;
//保存
void saveConfig()
{ 
        
	EEPROM.begin(2048);
	uint8_t *p = (uint8_t*)(&Config);
	for (int i = 0; i < sizeof(Config); i++)
	{ 
        
		EEPROM.write(i, *(p + i));
	}
	EEPROM.end();
}
//读取
void loadConfig()
{ 
        
	EEPROM.begin(2048);
	uint8_t *p = (uint8_t*)(&Config);
	for (int i = 0; i < sizeof(Config); i++)
	{ 
        
		*(p + i) = EEPROM.read(i);
	}
	EEPROM.end();
}

.
.
开机功能

//由于ESP8266最长睡眠时间为71分钟
//为了达到长时间的睡眠效果,通过设置开机检测来判断是否达到开机时间 
//未达到则继续进入睡眠状态

//单次最大睡眠时间为4,294,967,295us 约合4294s 即71分钟
void SleepSet(int t)	//睡眠时间设置 输入单位 分钟
{ 
        	
	//MAX_SLEEPTIME为设置的最大睡眠时长 小于70
	if(t>MAX_SLEEPTIME)	
	{ 
        
		Config.SleepTime = t;	//剩余睡眠时间
		Config.SleepState = '1';//睡眠时间大于 MAX_SLEEPTIME
		saveConfig();	//保存设置 
		delay(100);
		ESP.deepSleep(MAX_SLEEPTIME*60*1000000,WAKE_NO_RFCAL);//睡眠 MAX_SLEEPTIME 分钟
	}
	else 
	{ 
        
		Config.SleepTime = 0;	//剩余睡眠时间
		Config.SleepState = '0';
		saveConfig();
		delay(100);
		ESP.deepSleep(t*60*1000000,WAKE_NO_RFCAL);//睡眠t分钟
	}
}
//开机检测 放在setup()中
void CHECK_SLEEP()
{ 
        
	//如果是睡眠了MAX_SLEEPTIME分钟 则判断是否继续睡眠
	if(Config.SleepState == '1')
	{ 
        
		if(Config.SleepTime-MAX_SLEEPTIME>=MAX_SLEEPTIME)
		{ 
        
			//如果开机时间未达到 则重新计算剩余的睡眠时间
			Config.SleepTime = Config.SleepTime-MAX_SLEEPTIME;	
			Config.SleepState = '1';
			saveConfig();
			delay(100);
			ESP.deepSleep(MAX_SLEEPTIME*60*1000000,WAKE_NO_RFCAL);	
		}
		else if(Config.SleepTime-MAX_SLEEPTIME>=1)
		{ 
        
		//如果剩余的睡眠时间小于MAX_SLEEPTIME分钟 
		//则睡眠时间清零 并睡眠时间设置为剩下的睡眠时间
			Config.SleepTime = 0;	//剩余睡眠时间清零
			Config.SleepState = '0';	//更改睡眠状态
			saveConfig();
			delay(100);
			ESP.deepSleep((Config.SleepTime-MAX_SLEEPTIME)*60*1000000,WAKE_NO_RFCAL);
		}
	}
}

.
.
关机功能

//检测关机时间 放在loop()中
void CLOCK()
{ 
        
	static short int onH = Config.ONH;
	static short int onM = Config.ONM;
	static short int offH = Config.OFFH;
	static short int offM = Config.OFFM;	
	//当数据被修改 保存修改后的设置 
	//并判断是否关闭定时功能
	if(Config.ONH!=onH||Config.ONM!=onM||Config.OFFH!=offH||Config.OFFM!=offM)
	{ 
        
		onH = Config.ONH;
		onM = Config.ONM;
		offH = Config.OFFH;
		offM = Config.OFFM;
		//开启和关闭时间相同则关闭定时功能
		if(Config.ONH==Config.OFFH&&Config.ONM==Config.OFFM)
		{ 
        
	      	Config.SleepState = '0';
			client.print("@Lightsetcloseok#");//向APP反馈
			saveConfig();
		}
		else 
		{ 
        
			saveConfig();
		}
	}
	
	//当开机时间和关机时间相同则关闭开关机功能
	//判断是否开启关机功能 检测关机时间
	if( Config.OFFH!=Config.ONH||Config.OFFM!=Config.ONM )
	{ 
        
		if(Hours == Config.OFFH)
		{ 
        
			if(Minutes == Config.OFFM)
			{ 
        
			//当达到关机时间则计算需要睡眠的时间
				if(Config.OFFH<=Config.ONH)
				{ 
        
					int sleepH = Config.ONH - Config.OFFH;
					int sleepM = Config.ONM - Config.OFFM;
					SleepSet(sleepH*60+sleepM);
				}
				else
				{ 
        
					int sleepH = 23-Config.OFFH + Config.ONH;
					int sleepM = Config.ONM - Config.OFFM;
					SleepSet(sleepH*60+sleepM);
				}
			}
		}
	}
}

.
.
接入网络

//网络初始化 连接WiFi 时间获取 连接端口
void INIT_NETWORK()
{ 
        
	pinMode(D4, OUTPUT);
	digitalWrite(D4, HIGH);
	
	WiFi.mode(WIFI_STA);
	WiFi.begin(Config.Ssid, Config.Pswd);
	uint32_t las = millis();
	while(WiFi.status() != WL_CONNECTED )//等待8s连接 未连接则配网
	{ 
        
		delay(350);
		digitalWrite(D4, LOW);
		delay(650);
		digitalWrite(D4, HIGH);
		if(millis()-las>=8000)
		{ 
        
			webConfig();
			break;
		}
		ESP.wdtFeed();
	}
	GetTime();//先获取网络时间
	
	//连接IP
	las = millis();
	while(!client.connect(CLIENT_IP, CLIENT_PORT))
	{ 
        
		if(millis()-las>=5000)ESP.restart();
		ESP.wdtFeed();      
		client.connect(CLIENT_IP, CLIENT_PORT);
		delay(200);
	}
	digitalWrite(D4, HIGH);
	//显示之前保存的颜色 
	for(int i=0;i<NUM_LEDS;i++)
	{ 
        
		leds[i] = CRGB(Config.R, Config.G, Config.B);
		FastLED.show();
	}
}

.
.

时间获取

/*如果不使用定时器更新时间而直接读取 Hours = timeClient.getHours(); Minutes = timeClient.getMinutes(); Seconds = timeClient.getSeconds(); 开机30分钟后会发生卡顿(卡顿时长3~5s) 如果嫌麻烦可以直接调用函数读取时间 不影响关机功能 */
Ticker updateTicker;
int Hours = 0;   
int Minutes = 0;   
int Seconds = 0;   
//定时器回调函数 更新时间 每秒钟将上面三个变量更新一次
void updateTime() 
{ 
        
	Seconds++;
	if(Seconds >= 60)
	{ 
        
		Seconds = 0;
		Minutes++;
		if(Minutes >= 60)
		{ 
        
			Minutes = 0;
			Hours++;
			if(Hours >=24 )
			{ 
        
				Hours = 0;
			}        
		}
	}
}

//时间获取 设置秒定时器 放在setup()中
void GetTime()
{ 
        
	WiFiUDP ntpUDP;
	NTPClient  timeClient(ntpUDP, "ntp1.aliyun.com",60*60*8, 30*60*1000);
	
	timeClient.begin(); 
	
	timeClient.update();
	
	Hours   = timeClient.getHours();
	Minutes = timeClient.getMinutes();
	Seconds = timeClient.getSeconds();
	
	updateTicker.attach_ms(1000, updateTime); //设置定时器 1s执行一次
	ntpUDP.stop();    
}

.
.
温度检测

static bool tempsend = false;//温度自动更新变量
char tempbuff[22];//向APP发送的温度
//放在loop()函数中
void TEMP_SEND()
{ 
        
	static uint32_t ti = millis();
	if(millis()-ti>=2000)	//2s更新一次温度
	{ 
        
		ti = millis();
		
		float tempc = sensors.getTempCByIndex(0);
		if (tempc != DEVICE_DISCONNECTED_C)	//读取正确
		{ 
        
			for(int i=0;i<22;i++)tempbuff[i]=0;
			sprintf(tempbuff,"@Lighttemp=%.2f*C#",tempc);
		}
		else 
		{ 
        
			sprintf(tempbuff,"@Lighttemp=读取错误#");
		}
		//判断是否开启温度自动功能
		if(tempsend == true)
		{ 
        	
			client.print(tempbuff);
		}
		sensors.requestTemperatures();
	}
}

.
.
接收APP的数据

void GET_CMD()
{ 
        
	if(client.available())
	{ 
        
		char clientbuff[50]元器件数据手册、IC替代型号,打造电子元器件IC百科大全!
          

相关文章