有时间就接着更新
文章目录
1.SPI四线驱动OLED
我使用的是U8g2库。
1.1其中一种方法:
#include <Arduino.h>
#include <SPI.h>
#include <U8g2lib.h>
//cs脚只要接地就好,不需要定义
U8G2_SSD1306_128X64_NONAME_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 36, /* data=*/ 35, /* cs=*/ -1, /* dc=*/ 33, /* reset=*/ 34);
void setup(void) {
u8g2.begin(); //选择U8G2模式,或者U8X8模式
}
void loop(void) {
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.drawStr(0,15,"Hello World!");
} while ( u8g2.nextPage() );
delay(1000);
}
1.2也可以用另外的方式
#include <Arduino.h>
#include <SPI.h>
#include <U8g2lib.h>
//cs脚只要接地就好,不需要定义
U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 36, /* data=*/ 35, /* cs=*/ -1, /* dc=*/ 33, /* reset=*/ 34);
void setup(void) {
u8g2.begin(); //选择U8G2模式,或者U8X8模式
//下面这个放在loop里面也是可以的
u8g2.clearBuffer(); // clear the internal memory
u8g2.setFont(u8g2_font_wqy12_t_gb2312); // choose a suitable font
u8g2.drawStr(0,8,"Hello World!"); // write something to the internal memory
u8g2.sendBuffer(); // transfer internal memory to the display
}
void loop(void) {
delay(1000);
}
1.3显示多个中文
#include <Arduino.h>
#include <SPI.h>
#include <U8g2lib.h>
//cs脚只要接地就好,不需要定义
U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 36, /* data=*/ 35, /* cs=*/ -1, /* dc=*/ 33, /* reset=*/ 34);
//下面是显示多个中文的写法
void setup()
{
u8g2.begin();
u8g2.enableUTF8Print(); // enable UTF8 support for the Arduino print() function
Serial.begin(115200);
delay(1500);
}
void loop()
{
u8g2.setFont(u8g2_font_wqy12_t_gb2312); // 像素为8
u8g2.setFontDirection(0); // 设置字体方向
u8g2.clearBuffer(); // 清除buffer,清除上一次显示的画面
Serial.println("oled begin");
u8g2.setCursor(16, 16);
u8g2.print("时间:");
Serial.println("oled end");
u8g2.sendBuffer(); // 发送buffer,显示在屏幕上
}
1.4查找字体的官方网站连接:
里面可以直接看到字体的样子,要是看不了的话,就得墙后才可以。
https://github.com/olikraus/u8g2/wiki/fntlistall
https://github.com/olikraus/u8g2/wiki/fntlistall
1.5比较全面的U2g8教程链接:
https://blog.csdn.net/dpjcn1990/article/details/92831760
https://blog.csdn.net/dpjcn1990/article/details/92831760
1.6关于Fontstruct
其实就是可以下载和设计字体
https://vidabytes.com/zh-CN/fontstruct-%E5%88%9B%E5%BB%BA%E4%B8%8B%E8%BD%BD%E5%92%8C%E5%85%B1%E4%BA%AB/
2.ESP32连接网络
#include <Arduino.h>
#include "WiFi.h"
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin("AA", "12345678");//WiFi名称和密码
while (!WiFi.isConnected())
{
delay(500);
Serial.print(".");
}
Serial.println("WIFI连接成功!");
}
void loop()
{
}
3.ESP32获取气象信息
3.1通过心知天气获取天气数据
3.1.1通过手动输入城市获取天气数据
https://blog.csdn.net/weixin_42487906/article/details/119990731?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164420210316780366550793%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=164420210316780366550793&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-119990731.first_rank_v2_pc_rank_v29&utm_term=arduino+ESP32%E8%8E%B7%E5%8F%96%E5%A4%A9%E6%B0%94&spm=1018.2226.3001.4187
https://www.seniverse.com/products?iid=1c147258-2934-4f2a-b424-13ee70f6bfa1
其中的API可以有不同的连接方式:
https://docs.seniverse.com/api/fct/search.html
修改后的代码(代码来源):
代码中需要修改的地方:
- 网络名称和密码
- 心知天气的密钥
- 城市名称
#include <Arduino.h>
#include <ArduinoJson.h>
#include <WiFi.h>
//使用的时候需要将这里的 网络名称 和 密码 进行更改
const char *ssid = "AA";
const char *password = "12345678";
const char *host = "api.seniverse.com";
const char *privateKey = "****"; // 这里需要你自己去获取密钥,方法上面说过了
const char *city = "guangzhou"; //这里改为你想要查询的城市名称
const char *language = "en";
struct WetherData
{
char city[32];
char weather[64];
char high[32];
char low[32];
char humi[32];
};
void setup()
{
Serial.begin(115200);
Serial.print("Connecting to ");
Serial.println(ssid);
//开始连接网络
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.println("");
Serial.println("WiFi Conected!");
//开始连接API
WiFiClient client;
if (!client.connect(host, 80))
{
Serial.println("Connect host failed!");
return;
}
Serial.println("host Conected!");
String getUrl = "/v3/weather/daily.json?key=";
getUrl += privateKey;
getUrl += "&location=";
getUrl += city;
getUrl += "&language=";
getUrl += language;
client.print(String("GET ") + getUrl + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n");
Serial.println("Get send");
char endOfHeaders[] = "\r\n\r\n";
bool ok = client.find(endOfHeaders);
if (!ok)
{
Serial.println("No response or invalid response!");
}
Serial.println("Skip headers");
String line="";
line += client.readStringUntil('\n');
Serial.println(line);
//下面开始解析得到的json格式的数据
DynamicJsonDocument doc(1400);
DeserializationError error = deserializeJson(doc, line);
if (error)
{
Serial.println("deserialize json failed");
return;
}
Serial.println("deserialize json success");
struct WetherData weatherdata = {0};
strcpy(weatherdata.city, doc["results"][0]["location"]["name"].as<const char*>());
strcpy(weatherdata.weather, doc["results"][0]["daily"][0]["text_day"].as<const char*>());
strcpy(weatherdata.high, doc["results"][0]["daily"][0]["high"].as<const char*>());
strcpy(weatherdata.low, doc["results"][0]["daily"][0]["low"].as<const char*>());
strcpy(weatherdata.humi, doc["results"][0]["daily"][0]["humidity"].as<const char*>());
Serial.println("City");
Serial.println(weatherdata.city);
Serial.println("textDay");
Serial.println(weatherdata.weather);
Serial.println("temp high");
Serial.println(weatherdata.high);
Serial.println("temp low");
Serial.println(weatherdata.low);
Serial.println("humi");
Serial.println(weatherdata.humi);
Serial.println("read json success");
Serial.println();
Serial.println("closing connection");
client.stop();
}
void loop()
{
// put your main code here, to run repeatedly:
}
3.1.2通过所连接网络信息直接获取天气数据
方法:先获取当前所连接网络的IP地址,再去获取天气数据。
代码如下:
代码中需要修改的地方:
- 网络名称和密码
- 心知天气的密钥
#include <Arduino.h>
#include "WiFi.h"
#include "HTTPClient.h"
#include "ArduinoJson.h"
String ip_req;
String ip_rsp;
String now_weather_req;
String now_weather_rsp;
const char *ip; //所连接的网络的IP地址
const char *city; //所在的城市
const char *weather; //现在的天气
const char *temperature; //现在的温度
const char *ssid = "whatk"; //wifi名
const char *password = "0123456789"; //wifi密码
const char *host = "https://api.seniverse.com"; //心知天气APIhost
const char *apiKey = "*****************"; //API key 私钥
WiFiClient wifi_Client;
HTTPClient http_weather_client;
HTTPClient http_ip_client;
DynamicJsonDocument ip_doc(512);
DynamicJsonDocument now_weather_doc(512);
//Wifi初始化
void Wifi_connect()
{
delay(10);
Serial.println("Connecting WIFI");
//设置ESP32工作模式为无线终端模式
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected!");
}
void Http_get_ip()
{
short int http_code;
ip_req = "https://api.live.bilibili.com/client/v1/Ip/getInfoNew";
Serial.println(ip_req);
while (1)
{
if (http_ip_client.begin(ip_req))
{
Serial.println("Http_get_ip setUp done!");
}
http_code = http_ip_client.GET();
Serial.println(http_code);
if (http_code > 0)
{
Serial.printf("HTTP get code: %d\n", http_code);
if (http_code == HTTP_CODE_OK)
{
ip_rsp = http_ip_client.getString();
Serial.println(ip_rsp);
break;
}
else
{
Serial.printf("fail to get ip,code:%d\n", http_code);
}
}
}
}
void Ip_json()
{
//解析JSON字符串
Serial.println("从jsonStr解码成的DynamicJsonDocument对象doc:");
deserializeJson(ip_doc, ip_rsp);
serializeJson(ip_doc, Serial);
Serial.println();
JsonObject data1 = ip_doc["data"];
Serial.print("data:");
serializeJson(data1, Serial);
Serial.println();
ip = data1["addr"];
Serial.print("ip:");
Serial.println(ip);
city = data1["city"];
Serial.print("city:");
Serial.println(city);
}
void Http_get_now_weather()
{
short int http_code;
//实例:https://api.seniverse.com/v3/weather/now.json?key=SDsx89dbgoOO4RVat&location=beijing&language=zh-Hans&unit=c
now_weather_req = (String)host + "/v3/weather/now.json?key=";
now_weather_req += apiKey;
now_weather_req += "&location=";
now_weather_req += ip;
now_weather_req += "&language=zh-Hans&unit=c";
Serial.println(now_weather_req);
while(1)
{
if (http_weather_client.begin(now_weather_req))
{
Serial.println("Http_get_now_weather setUp done!");
}
http_code = http_weather_client.GET();
Serial.println(http_code);
if (http_code > 0)
{
Serial.printf("HTTP get code: %d\n", http_code);
if (http_code == HTTP_CODE_OK)
{
now_weather_rsp = http_weather_client.getString();
Serial.println(now_weather_rsp);
break;
}
else
{
Serial.printf("fail to get cityWeather,code:%d\n", http_code);
}
}
}
}
void Weather_now_json()
{
//解析JSON字符串
Serial.println("从now_weather_rsp解码成的DynamicJsonDocument对象doc:");
deserializeJson(now_weather_doc, now_weather_rsp);
serializeJson(now_weather_doc, Serial);
Serial.println();
Serial.println("root里有一个子JsonArray对象 results:");
JsonArray results = now_weather_doc["results"];
serializeJson(results, Serial);
Serial.println();
//JsonArray类型的数组results里面只有一个元素: JsonObject对象results[0],
//该元素有三个子对象 location, now, last_update
//now
Serial.println("JsonObject对象 results[0]中的子JsonObject对象now(为了避免和timer中的now重名,把它叫做now1):");
JsonObject now1 = results[0]["now"];
serializeJson(now1, Serial);
Serial.println("从JsonObject对象now1中取出weather");
weather = now1["text"];
Serial.println(weather);
Serial.println("从JsonObject对象now1中取出temperature");
temperature = now1["temperature"];
Serial.println(temperature);
Serial.println();
}
void setup()
{
Serial.begin(115200);
delay(1000);
Wifi_connect();
Http_get_ip();
Ip_json();
Http_get_now_weather();
Weather_now_json();
}
void loop()
{
delay(1000);
}
3.2通过getString方法获取网络时间和气象数据
https://blog.csdn.net/weixin_42880082/article/details/120944183?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164420550316780274197155%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164420550316780274197155&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-1-120944183.first_rank_v2_pc_rank_v29&utm_term=%2F**+%E9%80%9A%E8%BF%87getString%E6%96%B9%E6%B3%95%E8%8E%B7%E5%8F%96%E7%BD%91%E7%BB%9C%E6%97%B6%E9%97%B4%E5%92%8C%E6%B0%94%E8%B1%A1%E6%95%B0%E6%8D%AE++*%2F&spm=1018.2226.3001.4187
4.ESP32获取实时时间
4.1最简单直接获取网络时间方法
https://blog.csdn.net/weixin_42880082/article/details/120947163?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164420413416780264094419%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164420413416780264094419&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-2-120947163.first_rank_v2_pc_rank_v29&utm_term=arduino+esp32+%E8%8E%B7%E5%8F%96%E5%BD%93%E5%89%8D%E6%97%B6%E9%97%B4&spm=1018.2226.3001.4187
修改后的代码:
代码中需要修改的地方:
- 网络名称和密码
#include <WiFi.h>
#define NTP1 "ntp1.aliyun.com"
#define NTP2 "ntp2.aliyun.com"
#define NTP3 "ntp3.aliyun.com"
//填写WIFI入网信息
const char* ssid = "AA"; // WIFI账户
const char* password = "AA471819"; // WIFI密码
void setClock()
{
struct tm timeinfo;
if (!getLocalTime(&timeinfo))
{
//如果获取失败,就开启联网模式,获取时间
Serial.println("Failed to obtain time");
WiFi.disconnect(false);
WiFi.mode(WIFI_STA); //开启网络
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
configTime(8 * 3600, 0, NTP1, NTP2,NTP3);
return;
}
Serial.println(&timeinfo, "%F %T %A"); // 格式化输出:2021-10-24 23:00:44 Sunday
Serial.print(asctime(&timeinfo));//默认打印格式:Mon Oct 25 11:13:29 2021
WiFi.disconnect(true);
}
void setup()
{
Serial.begin(115200);
Serial.println();
//设置ESP32工作模式为无线终端模式
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected!");
configTime(8 * 3600, 0, NTP1, NTP2,NTP3);
setClock();
// 从网络时间服务器上获取并设置时间
// 获取成功后芯片会使用RTC时钟保持时间的更新
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);//关闭网络
Serial.println("WiFi disconnected!");
}
void loop()
{
Serial.println("Waiting 10s before the next round...");
delay(10000);
setClock();
}
4.2忘了哪里找来的
#include <Arduino.h>
#include <WiFi.h>
#include <SPI.h>
#include <U8g2lib.h>
//cs脚只要接地就好,不需要定义
U8G2_SSD1306_128X64_NONAME_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 36, /* data=*/ 35, /* cs=*/ -1, /* dc=*/ 33, /* reset=*/ 34);
#define NTP1 "ntp1.aliyun.com"
#define NTP2 "ntp2.aliyun.com"
#define NTP3 "ntp3.aliyun.com"
//填写WIFI入网信息
const char *ssid = "AA"; // WIFI账户
const char *password = "12345678"; // WIFI密码
const String WDAY_NAMES[] = {"星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"}; //星期
const String MONTH_NAMES[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; //月份
//time_t now; //实例化时间
void setClock()
{
struct tm timeInfo; //声明一个结构体
if (!getLocalTime(&timeInfo))
{ //一定要加这个条件判断,否则内存溢出
Serial.println("Failed to obtain time");
return;
}
//Serial.print(asctime(&timeInfo)); //默认打印格式:Mon Oct 25 11:13:29 2021
String date = WDAY_NAMES[timeInfo.tm_wday];
Serial.println(date.c_str());
// sprintf_P(buff1, PSTR("%04d-%02d-%02d %s"), timeInfo.tm_year + 1900, timeInfo.tm_mon + 1, timeInfo.tm_mday, WDAY_NAMES[timeInfo.tm_wday].c_str());
String shuju = String(timeInfo.tm_year + 1900); //年
shuju += "-";
shuju += timeInfo.tm_mon + 1; //月
shuju += "-";
shuju += timeInfo.tm_mday; //日
shuju += " ";
shuju += timeInfo.tm_hour; //时
shuju += ":";
shuju += timeInfo.tm_min;
shuju += ":";
shuju += timeInfo.tm_sec;
shuju += " ";
shuju += WDAY_NAMES[timeInfo.tm_wday].c_str(); //星期
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.drawStr(0,15,timeInfo.tm_mon);
} while ( u8g2.nextPage() );
Serial.println(shuju.c_str());
}
void setup()
{
u8g2.begin(); //选择U8G2模式,或者U8X8模式
Serial.begin(115200);
Serial.println();
//设置ESP32工作模式为无线终端模式
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected!");
configTime(8 * 3600, 0, NTP1, NTP2, NTP3);
}
void loop()
{
Serial.println("Waiting 10s before the next round...");
delay(10000);
setClock();
// printLocalTime();
}
5.将日期转化为星期几
可以使用蔡勒公式
6.API总结
6.1获取时间
苏宁的:
http://quan.suning.com/getSysTime.do
http://api.k780.com:88/?app=life.time&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json
https://api.m.jd.com/client.actionfunctionId=queryMaterialProducts&client=wh5
https://api.m.jd.com/client.action?functionId=queryMaterialProducts&client=wh5
5.2获取IP地址
https://api.live.bilibili.com/client/v1/Ip/getInfoNew
6.Json
https://blog.csdn.net/dpjcn1990/article/details/92831648?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164464920516781683942710%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164464920516781683942710&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-1-92831648.pc_search_result_cache&utm_term=ArduinoJson&spm=1018.2226.3001.4187