close
前一陣子看到一個ESP8266的開發版,蠻特別的非ESP模組 + 0.91" SSD1306 OLED顯示器,WiFi Kit 8,大概就2cm x 5cm 的大小,內建CP2104模組,插USB即可直接燒錄程式碼。
當下有一個想法,有什麼資料可以從網路下載直接顯示出來........股票好像是一個不錯的選擇
好吧!就動手做看看吧~
首先,要顯示當下的日期時間,可以參考這篇,有很詳盡的說明
利用 NTP 伺服器來同步 Arduino 系統時鐘 (二)
文章裡面是使用LCD,修改一下用OLED,使用 Adafruit_SSD1306.h 的函式庫,然後自製WiFi 訊號強度圖示,原本扇形的有點醜,把他改成手機訊號的型式。
程式碼如下:
#include <ESP8266WiFi.h> #include <WiFiUdp.h> #include <Time.h> #include <TimeAlarms.h> #include <DNSServer.h> #include <ESP8266WebServer.h> #include <WiFiManager.h> //oled #include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 32 // OLED display height, in pixels // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) #define OLED_RESET 16 // Reset pin # (or -1 if sharing Arduino reset pin) Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); unsigned int localPort=2390; //local port to listen for UDP packets IPAddress timeServerIP; //time.nist.gov NTP server address const char* ntpServerName="time.nist.gov"; //NTP Server host name const int NTP_PACKET_SIZE=48; //NTP timestamp resides in the first 48 bytes of packets byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets WiFiUDP udp; //UDP instance to let us send and receive packets over UDP int count=0; static const unsigned char PROGMEM signal5[] = { 0xfe, 0x00, 0x00, 0x92, 0x00, 0x03, 0x54, 0x00, 0x33, 0x38, 0x03, 0x33, 0x10, 0x33, 0x33, 0x10, 0x33, 0x33, 0x13, 0x33, 0x33, 0x00, 0x00, 0x00 }; static const unsigned char PROGMEM signal4[] = { 0xfe, 0x00, 0x00, 0x92, 0x00, 0x00, 0x54, 0x00, 0x30, 0x38, 0x03, 0x30, 0x10, 0x33, 0x30, 0x10, 0x33, 0x30, 0x13, 0x33, 0x30, 0x00, 0x00, 0x00 }; static const unsigned char PROGMEM signal3[] = { 0xfe, 0x00, 0x00, 0x92, 0x00, 0x00, 0x54, 0x00, 0x00, 0x38, 0x03, 0x00, 0x10, 0x33, 0x00, 0x10, 0x33, 0x00, 0x13, 0x33, 0x00, 0x00, 0x00, 0x00 }; static const unsigned char PROGMEM signal2[] = { 0xfe, 0x00, 0x00, 0x92, 0x00, 0x00, 0x54, 0x00, 0x00, 0x38, 0x00, 0x00, 0x10, 0x30, 0x00, 0x10, 0x30, 0x00, 0x13, 0x30, 0x00, 0x00, 0x00, 0x00 }; static const unsigned char PROGMEM signal1[] = { 0xfe, 0x00, 0x00, 0x92, 0x00, 0x00, 0x54, 0x00, 0x00, 0x38, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const unsigned char PROGMEM signal0[] = { 0xfe, 0x00, 0x00, 0x92, 0x00, 0x20, 0x54, 0x00, 0x20, 0x39, 0x26, 0x20, 0x11, 0xa9, 0x20, 0x11, 0x69, 0x00, 0x11, 0x26, 0x20, 0x00, 0x00, 0x00 }; void setup() { Serial.begin(115200); if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32 Serial.println(F("SSD1306 allocation failed")); for(;;); // Don't proceed, loop forever } // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally display.display(); WiFiManager wifiManager; wifiManager.autoConnect("AutoConnectAP"); //Start UDP Serial.println("Starting UDP"); udp.begin(localPort); Serial.print("Local port: "); Serial.println(udp.localPort()); sync_clock(); //以 NTP 時間初始設定內部時鐘 // Clear the buffer display.clearDisplay(); } void loop() { //int rssi = WiFi.RSSI(); String d=getDate(); String t=getTime(); String w=getWeek(); int Hm=hour()*100 + minute(); //時:分整數, 0~2359 Serial.print(d + " " + t + " " + w + " "); Serial.println(Hm); display.clearDisplay(); display.setTextSize(1); // Normal 1:1 pixel scale display.setTextColor(SSD1306_WHITE); // Draw white text display.setCursor(0,0); // Start at top-left corner display.print(d);display.print(" ");display.println(w);//display.print(" ");display.println(rssi); display.println(" "); display.setTextSize(2); display.println(t); //display.drawBitmap(96, 0, signal1_icon24x8, 24, 8, SSD1306_WHITE); winfi_signal(); display.display(); ++count; if (count >= 300) { //每 40 次迴圈與 NTP 同步一次 sync_clock(); count=0; } delay(1000); } void sync_clock() { unsigned long GMT=getUnixTime(); if (GMT != 0) { //有得到 NTP 回應才更新 ESP8266 內建 RTC setTime(GMT + 28800L); //以台灣時間更新內部時鐘 } } void winfi_signal(){ int rssi = WiFi.RSSI(); if(rssi<-30 && rssi>=-40) display.drawBitmap(104, 0, signal5, 24, 8, 1); else if(rssi<-40 && rssi>=-50) display.drawBitmap(104, 0, signal4, 24, 8, 1); else if(rssi<-50 && rssi>=-60) display.drawBitmap(104, 0, signal3, 24, 8, 1); else if(rssi<-60 && rssi>=-70) display.drawBitmap(104, 0, signal2, 24, 8, 1); else if(rssi<-70 && rssi>=-80) display.drawBitmap(104, 0, signal1, 24, 8, 1); else display.drawBitmap(104, 0, signal0, 24, 8, 1); } String getDate() { String d=(String)year() + "-"; byte M=month(); if (M < 10) {d.concat('0');} d.concat(M); d.concat('-'); byte D=day(); if (D < 10) {d.concat('0');} d.concat(D); return d; } String getTime() { String t=""; byte h=hour(); if (h < 10) {t.concat('0');} t.concat(h); t.concat(':'); byte m=minute(); if (m < 10) {t.concat('0');} t.concat(m); t.concat(':'); byte s=second(); if (s < 10) {t.concat('0');} t.concat(s); return t; } String getWeek() { String w[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; return w[weekday()-1]; } String getDateTime() { //傳回日期時間 String dt=(String)year() + "-"; byte M=month(); if (M < 10) {dt.concat('0');} dt.concat(M); dt.concat('-'); byte d=day(); if (d < 10) {dt.concat('0');} dt.concat(d); dt.concat(' '); byte h=hour(); if (h < 10) {dt.concat('0');} dt.concat(h); dt.concat(':'); byte m=minute(); if (m < 10) {dt.concat('0');} dt.concat(m); dt.concat(':'); byte s=second(); if (s < 10) {dt.concat('0');} dt.concat(s); return dt; //傳回格式如 2016-07-16 16:09:23 的日期時間字串 } unsigned long getUnixTime() { WiFi.hostByName(ntpServerName, timeServerIP); //get a random server from the pool sendNTPpacket(timeServerIP); //send an NTP packet to a time server delay(1000); // wait to see if a reply is available int cb=udp.parsePacket(); //return bytes received unsigned long unix_time=0; //預設傳回 0, 表示未收到 NTP 回應 if (!cb) {Serial.println("no packet yet");} else { //received a packet, read the data from the buffer Serial.print("packet received, length="); Serial.println(cb); //=48 udp.read(packetBuffer, NTP_PACKET_SIZE); //read the packet into the buffer //the timestamp starts at byte 40 of the received packet and is four bytes, //or two words, long. First, esxtract the two words: unsigned long highWord=word(packetBuffer[40], packetBuffer[41]); unsigned long lowWord=word(packetBuffer[42], packetBuffer[43]); //combine the four bytes (two words) into a long integer //this is NTP time (seconds since Jan 1 1900): unsigned long secsSince1900=highWord << 16 | lowWord; Serial.print("Seconds since Jan 1 1900=" ); Serial.println(secsSince1900); Serial.print("Unix time="); //Unix time starts on Jan 1 1970. In seconds, that's 2208988800: unix_time=secsSince1900 - 2208988800UL; //更新 unix_time Serial.print(F("Unix time stamp (seconds since 1970-01-01)=")); Serial.println(unix_time); //print Unix time } return unix_time; //return seconds since 1970-01-01 } unsigned long sendNTPpacket(IPAddress& address) { Serial.println("sending NTP packet..."); // set all bytes in the buffer to 0 memset(packetBuffer, 0, NTP_PACKET_SIZE); //Initialize values needed to form NTP request //(see URL above for details on the packets) packetBuffer[0]=0b11100011; // LI, Version, Mode packetBuffer[1]=0; // Stratum, or type of clock packetBuffer[2]=6; // Polling Interval packetBuffer[3]=0xEC; // Peer Clock Precision //8 bytes of zero for Root Delay & Root Dispersion packetBuffer[12]=49; packetBuffer[13]=0x4E; packetBuffer[14]=49; packetBuffer[15]=52; // all NTP fields have been given values, now // you can send a packet requesting a timestamp: udp.beginPacket(address, 123); //NTP requests are to port 123 udp.write(packetBuffer, NTP_PACKET_SIZE); udp.endPacket(); }
![]()
大功告成,放在辦公室當時鐘也挺不錯的~
這是第一步,接下來就要燒腦了,如何去把股票的即時資料抓下來,來杯咖啡好好爬文一下!
文章標籤
全站熱搜