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();
}
大功告成,放在辦公室當時鐘也挺不錯的~
這是第一步,接下來就要燒腦了,如何去把股票的即時資料抓下來,來杯咖啡好好爬文一下!
文章標籤
全站熱搜
留言列表