| 
 | 
 
 
上次发的大屏时钟。 
 
[Arduino] 超简单DIY~制作自动授时64*32 LED单色大屏时钟(开源)  
https://www.mydigit.cn/forum.php?mod=viewthread&tid=235844 
 
代码内置了中文字库,但是还没用上,今天折腾了一下,把天气预报的部分也搞好了,让新手也能简单上路,搞个带天气预报的时钟。 
 
本次硬件还是和上次的一样,只做了些软件的修改。 
需要自己去"心知天气"申请一个帐号,获得api-key。然后填到代码开头的相应位置。注意后面城市名,我写的是nanjing,各人自己修改好。有重名的话,去心知天气网站找到自己城市的代号填上去,更准确。 
 
我写的屏幕布局只是个例子,自己可以随意修改。就在代码的最后部分。那些都是在屏幕上打印字符串的函数,其中两个数字参数就是屏幕的x,y坐标,根据自己需要修改试验就行了。 
 
在我家的墙上挂的是这个,只是很久以前做的,不管是硬件还是软件都很烂,就不分享了。怕麻烦的同学直接做两个,并排放就可以了。 
 
- //D0 = GPIO16; 
 
 - //D1 = GPIO5; 
 
 - //D2 = GPIO4;        LED on esp8266
 
 - //D3 = GPIO0;can not download when connected to low
 
 - //D4 = GPIO2;        
 
 - //D5 = GPIO14;  
 
 - //D6 = GPIO12;
 
 - //D7 = GPIO13;
 
 - //D8 = GPIO15;  can not start when high input
 
 - //D9 = GPIO3; UART RX
 
 - //D10 = GPIO1; UART TX
 
 - //LED_BUILTIN = GPIO16 (auxiliary constant for the board LED, not a board pin);
 
  
- #include<ESP8266WiFi.h>
 
 - #include<WiFiUdp.h>
 
 - #include<ESP8266mDNS.h>
 
 - #include<ArduinoOTA.h>
 
 - #include<ESP8266WiFiMulti.h>
 
 - #include<ESP8266WiFiGeneric.h>
 
 - #include<time.h>
 
  
- #include <U8g2lib.h>
 
 - u8g2_t u8g2;
 
  
- //Include the client
 
 - //#include <WiFiClientSecure.h>
 
 - #include <WiFiClient.h>
 
  
- //Add a client
 
 - WiFiClient client;
 
  
- #define timezone 8
 
  
- unsigned long Cycle = 1000;//刷新间隔,微秒
 
 - unsigned long DisplayLight = 50;//亮度
 
  
- //一定要修改这里,使用自己的wifi信息
 
 - #include "D:\GitHub\Private\wifi_config.h"
 
 - //const char* ssid = "wang";  //Wifi名称
 
 - //const char* password = "12345678";  //Wifi密码
 
  
- //我自己用的key保存在配置文件里了,不公开了。
 
 - //要改用下面那一行URL,并把xxxxxxxxxxxxxxxxxxx改成你在“心知天气”申请到的key。
 
 - #include "D:\GitHub\Private\weather_config.h"
 
 - //String URL = "/v3/weather/daily.json?key=xxxxxxxxxxxxxxxxxxx&location=nanjing&language=zh-Hans&unit=c&start=0&days=3";
 
  
 
- char *time_str;   
 
 - char H1,H2,M1,M2,S1,S2;
 
  
- unsigned long SecondsSinceStart = 0;
 
 - unsigned long TenthSecondsSinceStart = 0;
 
 - void TenthSecondsSinceStartTask();
 
 - void OnSecond();
 
 - void OnHour();
 
 - void NonStopTask();
 
  
- unsigned long TimeOut = 30;
 
 - bool ssl_getValue(const char* string, unsigned char* Value, unsigned char* Len, unsigned char Start, unsigned char Max);
 
 - bool ssl_waitFor(const char* string);
 
 - bool ssl_getch(char* RetData);
 
 - char Weather[3][7];//"中雨"
 
 - char Date[3][6];//"02-28"
 
 - char HighTemperature[3][4];//-15
 
 - char LowTemperature[3][4];
 
  
 
- #define RowA D8                    //行信号,驱动138  
 
 - #define RowB D7
 
 - #define RowC D6
 
 - #define RowD D5
 
 - #define STB D2         //595 刷新显示  SS  
 
 - #define CLK D1         //时钟    SCK  
 
 - #define OE D0                         //  使能  
 
 - #define R1 D4          //上半屏列信号输出    
 
 - #define R2 D3          //下半屏列信号输出    
 
  
- void setup() 
 
 - {       
 
 -         delay(50);                      
 
 -         Serial.begin(115200);
 
  
-         pinMode(RowA, OUTPUT);
 
 -         pinMode(RowB, OUTPUT);
 
 -         pinMode(RowC, OUTPUT);
 
 -         pinMode(RowD, OUTPUT); //138片选
 
 -         pinMode(OE, OUTPUT); //138 使能
 
 -         pinMode(R1, OUTPUT);//595 数据
 
 -         pinMode(R2, OUTPUT);//595 数据
 
 -         pinMode(CLK, OUTPUT); //595 时钟
 
 -         pinMode(STB, OUTPUT); //595 使能
 
  
-         WiFi.disconnect();
 
 -         WiFi.mode(WIFI_STA);//设置模式为STA
 
 -         byte mac[6];
 
 -         WiFi.softAPmacAddress(mac);
 
 -         printf("macAddress 0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:0x%02X\r\n",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
 
  
-         Serial.print("Is connection routing, please wait");  
 
 -         WiFi.begin(ssid, password); //Wifi接入到网络
 
 -         Serial.println("\nConnecting to WiFi");
 
 -         //如果Wifi状态不是WL_CONNECTED,则表示连接失败
 
 -         unsigned char WiFiTimeOut = 0;
 
 -         while (WiFi.status() != WL_CONNECTED) {  
 
 -                 Serial.print("."); 
 
 -                 delay(1000);    //延时等待接入网络
 
 -                 WiFiTimeOut++;
 
 -                 if (WiFiTimeOut>10)
 
 -                 {
 
 -                         break;
 
 -                         Serial.println("\nConnecting to WiFi Failed");
 
 -                 }
 
 -         }
 
  
-         //设置时间格式以及时间服务器的网址
 
 -         configTime(timezone * 3600, 0, "pool.ntp.org", "time.nist.gov");
 
 -         Serial.println("\nWaiting for time");
 
 -         while (!time(nullptr)) {
 
 -                 Serial.print(".");
 
 -                 delay(1000);    
 
 -         }
 
 -         Serial.println("");
 
  
 
-         //开启OTA功能。除了第一次需要用USB下载,以后就可以使用WiFi下载程序了。
 
 -         ArduinoOTA.onStart([]() {
 
 -                 String type;
 
 -                 if (ArduinoOTA.getCommand() == U_FLASH) {
 
 -                         type = "sketch";
 
 -                 } else { // U_SPIFFS
 
 -                         type = "filesystem";
 
 -                 }
 
 -                 // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
 
 -                 Serial.println("Start updating " + type);
 
 -         });
 
 -         ArduinoOTA.onEnd([]() {
 
 -                 Serial.println("\nEnd");
 
 -         });
 
 -         ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
 
 -                 Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
 
 -         });
 
 -         ArduinoOTA.onError([](ota_error_t error) {
 
 -                 Serial.printf("Error[%u]: ", error);
 
 -                 if (error == OTA_AUTH_ERROR) {
 
 -                         Serial.println("Auth Failed");
 
 -                 } else if (error == OTA_BEGIN_ERROR) {
 
 -                         Serial.println("Begin Failed");
 
 -                 } else if (error == OTA_CONNECT_ERROR) {
 
 -                         Serial.println("Connect Failed");
 
 -                 } else if (error == OTA_RECEIVE_ERROR) {
 
 -                         Serial.println("Receive Failed");
 
 -                 } else if (error == OTA_END_ERROR) {
 
 -                         Serial.println("End Failed");
 
 -                 }
 
 -         });
 
 -         ArduinoOTA.begin();
 
 -         Serial.println("Ready");
 
 -         Serial.print("IP address: ");
 
 -         Serial.println(WiFi.localIP());
 
  
-         u8g2_Setup_ssd1306_64x32_noname_f(&u8g2, U8G2_R0, NULL, NULL);  // init u8g2 structure
 
  
- }
 
  
- void hc138sacn(byte r)   //输出行线状态ABCD (A低,D高)
 
 - {
 
 -         digitalWrite(RowA,(r & 0x01));
 
 -         digitalWrite(RowB,(r & 0x02));
 
 -         digitalWrite(RowC,(r & 0x04));
 
 -         digitalWrite(RowD,(r & 0x08));
 
 - }
 
  
- void DisplayOneLine()
 
 - {
 
 -         //显示缓存扫描
 
 -         static unsigned char row=0;
 
 -         for (int i=0; i<64; i++)
 
 -         {
 
 -                 digitalWrite(CLK,0);
 
 -                 digitalWrite(R1, ((u8g2.tile_buf_ptr[i%64+(row/8)*64]>>(row%8))&1));//发送上半屏
 
 -                 digitalWrite(R2, ((u8g2.tile_buf_ptr[i%64+(row/8)*64+128]>>(row%8))&1));//发送下半屏
 
 -                 digitalWrite(CLK,1);
 
 -         }
 
  
-         hc138sacn(row);            //选行
 
 -         digitalWrite(STB, 1);      //数据确认
 
 -         digitalWrite(STB, 0);
 
 -         if (DisplayLight>0)
 
 -         {
 
 -                 digitalWrite(OE, 0);  //开启显示
 
 -         }
 
 -         delayMicroseconds(DisplayLight) ;  //亮度调节
 
 -         digitalWrite(OE, 1);  //关闭显示
 
 -         row++;
 
 -         if (row>15)
 
 -         {
 
 -                 row = 0;
 
 -                 NonStopTask();
 
 -         }
 
 - }
 
  
- unsigned long CurrentDisplayTime;
 
 - unsigned long LastDisplayTime;
 
 - void DisplayTimerTask()
 
 - {
 
 -         CurrentDisplayTime = micros();
 
 -         if (abs(CurrentDisplayTime - LastDisplayTime) > Cycle)
 
 -         {
 
 -                 LastDisplayTime = CurrentDisplayTime;
 
 -                 DisplayOneLine();
 
 -         }
 
 - }
 
  
- void loop() 
 
 - {
 
 -         DisplayTimerTask();
 
 - }
 
  
- void NonStopTask() 
 
 - {
 
 -         TenthSecondsSinceStartTask();
 
 -         ArduinoOTA.handle();
 
 - }
 
  
- void OnTenthSecond()
 
 - {
 
 -         if (TenthSecondsSinceStart % 10 == 0)
 
 -         {
 
 -                 OnSecond();
 
 -                 SecondsSinceStart++;
 
  
-                 if (SecondsSinceStart % 3600 == 5)//每小时运行,并且保证启动5秒后也运行一次
 
 -                 {
 
 -                         OnHour();
 
 -                 }
 
  
-         }
 
  
- }
 
  
- unsigned long LastMillis = 0;
 
 - void TenthSecondsSinceStartTask()
 
 - {
 
 -         unsigned long CurrentMillis = millis();
 
 -         if (abs(CurrentMillis - LastMillis) > 100)
 
 -         {
 
 -                 LastMillis = CurrentMillis;
 
 -                 TenthSecondsSinceStart++;
 
 -                 OnTenthSecond();
 
 -         }
 
 - }
 
  
 
- char* WeekStr[7] = { "Sunday"
 
 -                                                         ,"Monday"
 
 -                                                         ,"Tuesday"
 
 -                                                         ,"Wednesday"
 
 -                                                         ,"Thursday"
 
 -                                                         ,"Friday"
 
 -                                                         ,"Saturday" };
 
  
 
 
 
- bool ssl_waitFor(const char* string) {
 
 -         char so_far = 0;
 
 -         char received;
 
 -         int counter = 0;
 
 -         do {
 
 -                 if (!ssl_getch(&received))
 
 -                 {
 
 -                         return false;
 
 -                 }
 
 -                 counter++;
 
 -                 if (received == string[so_far]) {
 
 -                         so_far++;
 
 -                 }
 
 -                 else {
 
 -                         so_far = 0;
 
 -                 }
 
 -         } while (string[so_far] != 0);
 
 -         return true;
 
 - }
 
  
- bool ssl_getValue(const char* string, unsigned char* Value, unsigned char* Len, unsigned char Start, unsigned char Max)
 
 - {
 
 -         char received;
 
 -         *Len = 0;
 
 -         unsigned char CurrentChar = 0;
 
  
-         if (!ssl_waitFor(string)) return false;
 
  
-         unsigned long RecvStartTime = SecondsSinceStart;
 
 -         while (1)
 
 -         {
 
 -                 if (!ssl_getch(&received))
 
 -                 {
 
 -                         return false;
 
 -                 }
 
  
-                 if ((received == '"') || ((*Len) >= Max))
 
 -                 {
 
 -                         return true;
 
 -                 }
 
 -                 else
 
 -                 {
 
 -                         if (CurrentChar >= Start)
 
 -                         {
 
 -                                 *(Value + (*Len)) = received;
 
 -                                 (*Len) = (*Len) + 1;
 
 -                         }
 
 -                         else
 
 -                         {
 
 -                                 CurrentChar++;
 
 -                         }
 
 -                 }
 
  
-                 if (SecondsSinceStart - RecvStartTime > TimeOut)
 
 -                 {
 
 -                         return false;
 
 -                 }
 
 -         }
 
 - }
 
  
- bool ssl_getch(char* RetData)
 
 - {
 
 -         //static bool WaitFinsih = false;
 
 -         //static unsigned char CompareIndex = 0;
 
 -         //static bool NewLine = false;
 
  
-         unsigned long RecvStartTime = SecondsSinceStart;
 
 -         while (1)
 
 -         {
 
 -                 if (client.available() > 0)
 
 -                 {
 
 -                         *RetData = client.read();
 
 -                         return true;
 
 -                 }
 
 -                 else
 
 -                 {
 
 -                         //NonStopTask();
 
 -                         DisplayTimerTask();
 
 -                 }
 
  
-                 if (SecondsSinceStart - RecvStartTime > TimeOut)
 
 -                 {
 
 -                         return false;
 
 -                 }
 
 -         }
 
 - }
 
  
- //收到的天气数据,举例:
 
 - //{"results":[{"location":{"id":"WTSQQYHVQ973","name":"南京","country":"CN","path":"南京,南京,江苏,中国","timezone":"Asia/Shanghai",
 
 - //"timezone_offset":"+08:00"},"daily":[
 
 - //{"date":"2021-02-26","text_day":"小雨","code_day":"13","text_night":"小雨","code_night":"13","high":"7","low":"5","rainfall":"6.1","precip":"","wind_direction":"东北","wind_direction_degree":"45","wind_speed":"23.4","wind_scale":"4","humidity":"91"},
 
 - //{"date":"2021-02-27","text_day":"阴","code_day":"9","text_night":"阴","code_night":"9","high":"14","low":"6","rainfall":"0.0","precip":"","wind_direction":"东","wind_direction_degree":"90","wind_speed":"32.8","wind_scale":"5","humidity":"71"},
 
 - //{"date":"2021-02-28","text_day":"阴","code_day":"9","text_night":"小雨","code_night":"13","high":"17","low":"11","rainfall":"0.0","precip":"","wind_direction":"东南","wind_direction_degree":"135","wind_speed":"32.8","wind_scale":"5","humidity":"77"}],
 
 - //"last_update":"2021-02-26T11:00:00+08:00"}]}
 
 - void OnHour()
 
 - {
 
  
 
 
-         long now;
 
 -         char host[] = "api.seniverse.com";
 
  
-         printf("Conneting weather server\r\n");
 
 -         if (client.connect(host, 80)) {
 
 -                 Serial.println("connected");
 
  
-                 client.println("GET " + URL + " HTTP/1.1");
 
 -                 client.print("Host: "); client.println(host);
 
 -                 client.println("User-Agent: arduino/1.0");
 
 -                 client.println("");
 
  
-                 TimeOut = 10;
 
 -                 if(!ssl_waitFor("200 OK")) return;
 
 -                 TimeOut = 2;
 
  
-                 
 
 -                 printf("Got weather info OK\r\n");
 
  
-                 //print everything recived
 
 -                 //now = millis();
 
 -                 //while (millis() - now < 1500)
 
 -                 //{
 
 -                 //        while (client.available())
 
 -                 //        {
 
 -                 //                char c = client.read();
 
 -                 //                printf("%c", c);
 
 -                 //        }
 
 -                 //}
 
  
 
-                 unsigned char valueLen;
 
  
-                 for (int i = 0; i < 3; i++)//循环取3天的天气信息
 
 -                 {
 
 -                         //先找到 date":", 往后跳5个字符,然后最多取5个字符,得到日期。
 
 -                         ssl_getValue("date":"", (unsigned char*)Date[i], &valueLen, 5, 5);
 
 -                         Date[i][valueLen] = 0;
 
 -                         printf("date:%s\r\n", Date[i]);
 
  
-                         //先找到 t_day":", 往后跳0个字符,然后最多取6个字符,得到白天天气。
 
 -                         ssl_getValue("t_day":"", (unsigned char*)Weather[i], &valueLen, 0, 6);
 
 -                         Weather[i][valueLen] = 0;
 
 -                         printf("Weather:%s\r\n", Weather[i]);
 
  
-                         //先找到 high":", 往后跳0个字符,然后最多取3个字符,得到温度。
 
 -                         ssl_getValue("high":"", (unsigned char*)HighTemperature[i], &valueLen, 0, 3);
 
 -                         HighTemperature[i][valueLen] = 0;
 
 -                         printf("High:%s\r\n", HighTemperature[i]);
 
  
-                         //先找到 low":", 往后跳0个字符,然后最多取3个字符,得到温度。
 
 -                         ssl_getValue("low":"", (unsigned char*)LowTemperature[i], &valueLen, 0, 3);
 
 -                         LowTemperature[i][valueLen] = 0;
 
 -                         printf("Low:%s\r\n", LowTemperature[i]);
 
 -                 }
 
  
-         }
 
 -         else
 
 -         {
 
 -                 Serial.println("connecte failed");
 
 -         }
 
 - }
 
  
- void OnSecond()
 
 - {
 
 -         static char sprint_buf[20];
 
  
-         time_t now = time(nullptr); //获取当前时间
 
  
 
-         //转换成年月日的数字,可以更加自由的显示。
 
 -         struct   tm* timenow;
 
 -         timenow = localtime(&now);
 
 -         unsigned char tempHour = timenow->tm_hour;
 
 -         unsigned char tempMinute = timenow->tm_min;
 
 -         unsigned char tempSecond = timenow->tm_sec;
 
 -         unsigned char tempDay = timenow->tm_mday;
 
 -         unsigned char tempMonth = timenow->tm_mon + 1;
 
 -         unsigned int tempYear = timenow->tm_year + 1900;
 
 -         unsigned char tempWeek = timenow->tm_wday;
 
  
 
-         u8g2_ClearBuffer(&u8g2);//清空显存
 
 -         //u8g2_SetFont(&u8g2, u8g2_font_crox3t_tn);
 
 -         ////第一行大字,显示时间
 
 -         //sprintf(sprint_buf, "%02d:%02d:%02d"
 
 -         //        , tempHour
 
 -         //        , tempMinute
 
 -         //        , tempSecond
 
 -         //);
 
 -         //u8g2_DrawStr(&u8g2, 3, 12, sprint_buf);
 
  
-         ////第二行小字,显示日期
 
 -         //u8g2_SetFont(&u8g2, u8g2_font_IPAandRUSLCD_tf);//字体5*7
 
 -         //sprintf(sprint_buf, "%04d-%02d-%02d"
 
 -         //        , tempYear
 
 -         //        , tempMonth
 
 -         //        , tempDay
 
 -         //);
 
 -         //u8g2_DrawStr(&u8g2, 0, 22, sprint_buf);
 
  
-         ////第三行小字,显示星期
 
 -         //sprintf(sprint_buf, "%s"
 
 -         //        , WeekStr[tempWeek]
 
 -         //);
 
 -         //u8g2_DrawStr(&u8g2, 0, 31, sprint_buf);
 
  
-         u8g2_SetFont(&u8g2, u8g2_font_IPAandRUSLCD_tf);//字体5*7
 
  
-         u8g2_DrawStr(&u8g2, 0, 8, Date[0]);
 
 -         u8g2_DrawStr(&u8g2, 0, 16, LowTemperature[0]);
 
 -         u8g2_DrawStr(&u8g2, 18, 16, HighTemperature[0]);
 
  
-         u8g2_DrawStr(&u8g2, 32, 8, Date[1]);
 
 -         u8g2_DrawStr(&u8g2, 32, 16, LowTemperature[1]);
 
 -         u8g2_DrawStr(&u8g2, 18+32, 16, HighTemperature[1]);
 
  
-         //显示中文
 
 -         u8g2_SetFont(&u8g2, u8g2_font_wqy16_t_gb2312);
 
 -         u8g2_DrawUTF8(&u8g2, 0, 30, Weather[0]);
 
 -         u8g2_DrawUTF8(&u8g2, 32, 30, Weather[1]);
 
 - }
 
  复制代码 
 
 
 |   
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册 
 
 
 
 
x
 
 
打赏
- 
查看全部打赏
 
 
 
 
 
 |