
給大家分享一個用ESP8266做一個高顏值的RGB時鐘的項目!
這個時鐘還具有自動亮度控制功能并配備了溫度傳感器!


Neo Pixel是可尋址的LED,我們可以通過編程,讓它顯示任何一種顏色或者數字。
Neo Pixel有不同的smd封裝,這個項目使用的是Ws2812b-5050 mini RGB。
這種迷你LED的額定電壓為3.0V到5.5V,電流為16mA(每個LED)。
NodeMCU有3.3V的穩壓器,可以正常驅動所有的LED。



在這里,我們需要把所有的電源并聯起來,把所有的數據連接串聯起來,使用7段顯示方法,如上圖連接所有的LED。
每段有2個LED,整個面板總共有14個LED。
我們需要4個面板來顯示時間(2個顯示小時,2個顯示分鐘)。
當然還可以再連接兩個面板來顯示秒/任何其他數值,或者溫度。
不管怎么連接,記住總是要把第一個面板的DOUT連接到第二個面板的DIN。


為了連接小時和分鐘面板,在兩面板之間有一個小的PCB板,名為Dash,包含了2個LED作為二進制數字,這2個LED燈每隔一秒就會發光一次。

ESP8266集成了一個32位Tensilica處理器,標準的數字外圍接口。
我們的ESP8266具有板載Wi-Fi支持,通過它我們可以連上互聯網調整時間,而不需要任何RTC(實時時鐘)模塊。
這樣子的話可以減少連接,使整個項目變得更簡單一些。

如果使用本文提供的代碼,那么我們可以在這個7段時鐘中增加2個額外的功能:
在13號針腳上添加一個DHT11傳感器,在12號針腳上添加一個觸覺按鈕,可以在屏幕上獲得攝氏或華氏的溫度值。
用一個10k電阻將按鈕的第12針腳連接到5V,另一端連接到GND。也就是說,當按鈕針腳被拉到GND時,顯示器將顯示溫度讀數。如果沒有這個溫度傳感器,代碼也可以工作,所以如果你想讓項目簡單一點,也可以不需要這些連接。

通過在A0引腳上做一個電阻分壓器網絡,添加一個帶有10k電阻的LDR傳感器,可以相應地改變亮度。
白天的亮度高,晚上的亮度低。如果你不想要可調節亮度,這部分代碼也可以在沒有這些傳感器的情況下工作,它將會鎖定在默認設置。


現在,我們有4個面板和一個Dash(儀表盤)。
根據上面GIF圖來連接面板和儀表盤;將2個面板串聯在一起。
然后使用上面給出的原理圖連接NodeMCU。
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#define?PIXEL_PER_SEGMENT?2?//?Number?of?LEDs?in?each?Segment
#define?PIXEL_DIGITS?4?//?Number?of?connected?Digits
#define?PIXEL_PIN?2?//?GPIO?Pin
#define?PIXEL_DASH?1?//?Binary?segment
#define?LDR_PIN?A0?//?LDR?pin
#define?DHT_PIN?13?//?DHT?Sensor?pin
#define?BUTTON_PIN?12?//?Button?pin
3. 對于時間格式,使用Wi-Fi把ESP8266連接到互聯網:
WiFi.begin(ssid,?password);
Serial.print("Connecting.");
while?(?WiFi.status()?!=?WL_CONNECTED?)
void?disp_Time()?{
clearDisplay();
writeDigit(0,?Hour?/?10);
writeDigit(1,?Hour?%?10);
writeDigit(2,?Minute?/?10);
writeDigit(3,?Minute?%?10);
writeDigit(4,?Second?/?10);
writeDigit(5,?Second?%?10);
disp_Dash();
5. 面板上的顏色設置:
if?(index?==?0?||?index?==?1?)?color?=?strip.Color(0,?Brightness,?0);
if?(index?==?2?||?index?==?3?)?color?=?strip.Color(0,?Brightness,?0);
if?(index?==?4?||?index?==?5?)?color?=?strip.Color(Brightness,?0,?0);
這只是一個簡單的介紹,同時代碼還有溫度和自動時間選項。
溫度模式可以通過數字針腳12的開關來選擇。
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#define?PIXEL_PER_SEGMENT??2?????//?Number?of?LEDs?in?each?Segment
#define?PIXEL_DIGITS???????4?????//?Number?of?connected?Digits?
#define?PIXEL_PIN??????????2?????//?GPIO?Pin
#define?PIXEL_DASH?????????1????//?Binary?segment
#define?LDR_PIN???????A0????//?LDR?pin
#define?DHT_PIN???????13????//?DHT?Sensor?pin
#define?BUTTON_PIN????12????//?Button?pin
//?Uncomment?the?type?of?sensor?in?use
#define?DHT_TYPE????DHT11?????//?DHT?11
//#define?DHT_TYPE????DHT22?????//?DHT?22?(AM2302)
//#define?DHT_TYPE????DHT21?????//?DHT?21?(AM2301)
#define?TIME_FORMAT????????12????//?12?=?12?hours?format?||?24?=?24?hours?format?
Adafruit_NeoPixel?strip?=?Adafruit_NeoPixel((PIXEL_PER_SEGMENT?*?7?*?PIXEL_DIGITS)?+?(PIXEL_DASH?*?2),?PIXEL_PIN,?NEO_GRB?+?NEO_KHZ800);
DHT?dht(DHT_PIN,?DHT_TYPE);
//?set?Wi-Fi?SSID?and?password
const?char?*ssid?????=?"Hackster";
const?char?*password?=?"Sainisagar7294";
WiFiUDP?ntpUDP;
//?'time.nist.gov'?is?used?(default?server)?with?+1?hour?offset?(3600?seconds)?60?seconds?(60000?milliseconds)?update?interval
NTPClient?timeClient(ntpUDP,?"time.nist.gov",?19800,?60000);?//GMT+5:30?:?5*3600+30*60=19800
int?period?=?2000;???//Update?frequency
unsigned?long?time_now?=?0;
int?Second,?Minute,?Hour;
//?set?default?brightness
int?Brightness?=?40;
//?current?temperature,?updated?in?loop()
int?Temperature;
bool?Show_Temp?=?false;
//Digits?array
byte?digits[12]?=?{
??//abcdefg
??0b1111110,?????//?0
??0b0110000,?????//?1
??0b1101101,?????//?2
??0b1111001,?????//?3
??0b0110011,?????//?4
??0b1011011,?????//?5
??0b1011111,?????//?6
??0b1110000,?????//?7
??0b1111111,?????//?8
??0b1110011,??????//?9
??0b1001110,?????//?C
??0b1000111,?????//?F
};
//Clear?all?the?Pixels
void?clearDisplay()?{
??for?(int?i?=?0;?i?????strip.setPixelColor(i,?strip.Color(0,?0,?0));
??}
??strip.show();
}
void?setup()?{
??Serial.begin(115200);
??strip.begin();
??strip.show();
??dht.begin();
??pinMode(BUTTON_PIN,?INPUT);
??WiFi.begin(ssid,?password);
??Serial.print("Connecting.");
??while?(?WiFi.status()?!=?WL_CONNECTED?)?{
????delay(500);
????Serial.print(".");
??}
??Serial.println("connected");
??timeClient.begin();
??delay(10);
}
void?loop()?{
??if?(WiFi.status()?==?WL_CONNECTED)?{?//?check?WiFi?connection?status
????int?sensor_val?=?analogRead(LDR_PIN);
????Brightness?=40;
????timeClient.update();
????int?Hours;
????unsigned?long?unix_epoch?=?timeClient.getEpochTime();???//?get?UNIX?Epoch?time
????Second?=?second(unix_epoch);????????????????????????????//?get?seconds
????Minute?=?minute(unix_epoch);????????????????????????????//?get?minutes
????Hours??=?hour(unix_epoch);??????????????????????????????//?get?hours
????if?(TIME_FORMAT?==?12)?{
??????if?(Hours?>?12)?{
????????Hour?=?Hours?-?12;
??????}
??????else
????????Hour?=?Hours;
????}
????else
??????Hour?=?Hours;
??}
??if?(digitalRead(BUTTON_PIN)?==?LOW)?{
????Show_Temp?=?true;
??}
??else
????Show_Temp?=?false;
??if?(Show_Temp)?{
????Temperature?=?dht.readTemperature();
????Serial.println(Temperature);
????clearDisplay();
????writeDigit(0,?Temperature?/?10);
????writeDigit(1,?Temperature?%?10);
????writeDigit(2,?10);
????strip.setPixelColor(28,?strip.Color(Brightness,?Brightness,??Brightness));
????strip.show();
????delay(3000);
????clearDisplay();
????Show_Temp?=?false;
??}
??while?(millis()?>?time_now?+?period)?{
????time_now?=?millis();
????disp_Time();?????//?Show?Time
??}
}
void?disp_Time()?{
??clearDisplay();
??writeDigit(0,?Hour?/?10);
??writeDigit(1,?Hour?%?10);
??writeDigit(2,?Minute?/?10);
??writeDigit(3,?Minute?%?10);
??writeDigit(4,?Second?/?10);
??writeDigit(5,?Second?%?10);
??disp_Dash();
??strip.show();
}
void?disp_Dash()?{
??int?dot,?dash;
??for?(int?i?=?0;?i?2;?i++)?{
????dot?=?2?*?(PIXEL_PER_SEGMENT?*?7)?+?i;
????for?(int?j?=?0;?j???????dash?=?dot?+?j?*?(2?*?(PIXEL_PER_SEGMENT?*?7)?+?2);
??????Second?%?2?==?0???strip.setPixelColor(dash,?strip.Color(0,Brightness?,0))?:?strip.setPixelColor(dash,?strip.Color(0,?Brightness,0));
????}
??}
}
void?writeDigit(int?index,?int?val)?{
??byte?digit?=?digits[val];
??int?margin;
??if?(index?==?0?||?index?==?1?)?margin?=?0;
??if?(index?==?2?||?index?==?3?)?margin?=?1;
??if?(index?==?4?||?index?==?5?)?margin?=?2;
??for?(int?i?=?6;?i?>=?0;?i--)?{
????int?offset?=?index?*?(PIXEL_PER_SEGMENT?*?7)?+?i?*?PIXEL_PER_SEGMENT?+?margin?*?2;
????uint32_t?color;
????if?(digit?&?0x01?!=?0)?{
??????if?(index?==?0?||?index?==?1?)?color?=?strip.Color(Brightness,?0,??Brightness);
??????if?(index?==?2?||?index?==?3?)?color?=?strip.Color(Brightness,?0,Brightness);
??????if?(index?==?4?||?index?==?5?)?color?=?strip.Color(Brightness,?0,??0);
????}
????else
??????color?=?strip.Color(0,?0,?0);
????for?(int?j?=?offset;?j???????strip.setPixelColor(j,?color);
????}
????digit?=?digit?>>?1;
??}
}



主要的PCB設計,用于顯示數字和其他字母。
點擊閱讀原文可以下載源文件。


DIN總是與DOUT串聯在一起,如果接反了或從任何地方斷開了,整個裝置就會停止工作;
按上面的圖連接Dash;
確保所有的連接都焊接好,干焊會導致數據值和顏色的改變;
在焊接時,不要把印刷電路板加熱太多,溫度保持在300度。


喜歡大家喜歡這個項目!
-END-
往期推薦:點擊圖片即可跳轉閱讀

什么是外包公司?要不要去外包公司?

STM32和Arduino對比,誰更厲害?

總結 | 從華為的轉正到離職

在華為五個月,我的所見所得!