TTGO TFT屏幕Arduino使用的小结
本帖最后由 topdog 于 2022-5-27 14:37 编辑TTGO TFT屏幕是一款ESP32和1.44寸LCD屏幕组合的产品,屏幕由ST7789驱动。ESP32自带520 kB SRAM和QSPI外接4MB flash。最近用Arduino的方法解析世界著名的气象服务网站Dark Sky,做一个彩色的时钟和气象的桌面显示,中间还有一条动感的火焰。效果如下图:
知识点阐述:
1,LCD驱动ST7789的库,使用TFT_eSPI库:
我结合这款产品把库改了一下,放在文章尾部的网盘链接里面给小伙伴们分享。
1.44寸换算成像素就是135x240,实体性化屏幕:TFT_eSPI tft = TFT_eSPI(135, 240);
初始化屏幕: tft.init();
屏幕旋转角度:tft.setRotation(0);
使用官方黑色清屏:tft.fillScreen(TFT_BLACK);标定位置和文字大小:tft.setCursor(0, 0);tft.setTextFont(2); 也可以简略写:tft.setCursor(0, 0,2);
设置文字色彩: tft.setTextColor(TFT_YELLOW);
屏幕上输出数据:tft.println(TimeZoneCity);
2,享受Dark Sky的服务需要注册一下,在https://darksky.net/dev/account查看一下Your Secret Key,然后我们用https://api.darksky.net/forecast//, 来看看上海的天气情况吧。细心的小伙伴发现这里使用的https协议。HTTPS(全称:Hypertext Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。
3,数据的解析,使用ArduinoJson库:
我们把上述的网站链接粘贴到浏览器地址栏,得到气象数据反馈。全选复制到ArduinoJosn官方网站提供的助手。第一步按下图选择。
4,ESP32官方在Flash上建立了一个叫做nvs的分区,而Preferences功能就是建立在该分区上的。ESP32中默认分区( Partition Scheme: “Default 4MB with spiffs (1.2MB APP /1.5MB SPIFFS)” )情况下nvs分区的大小为 20480 字节,实际可存放的数据大小要小于这个值( 单个数据来说最大为496K或者97%的nvs分区大小 )。Preferences中数据以键值对(key - value)的方式存储。在键值对之上还有一层命名空间 ,不同命名空间中可以有相同的键名存在。在Preferences中命名空间和键名均为字符串,并且长度不大于15个字节。
首先创建一个实体: Preferences DarkSky;
其次给出DarkSkySpace命名空间:DarkSky.begin("DarkSkySpace");
本示例中往实体空间里面存放数据只涉及String和Float两种数据类型:DarkSky.putString("precipType",currently_precipType); DarkSky.putFloat("temperature", currently_temperature);
相对应提取数据操作,查询没有结果返回值是自由设定的,此处String类型返回null,Float返回0:String precipType = DarkSky.getString("precipType","null");float temperature = DarkSky.getFloat("temperature", 0);
5,多任务ESP32使用Ticker库可以简单的完成,ESP32联网以后先Changer.once(1, GetData); 去解析一次气象数据,数据存入nvs分区,然后SetDisplayStore.attach(SetDisplayPeriod, SetDisplay);每秒读取时间日期和nvs分区里已经存储的气象数据。GetDataStore.attach(GetDataPeriod, GetData);注册一小时解析的任务,避免频繁访问。
6, 通过控制pin4即屏幕的TFT_BL背光强度,0-255可调整。参见esp32的ESP32\examples\AnalogOut\SigmaDelta。
7,开启16bit的RGB565显示,使画面更加细腻。tft.setSwapBytes(true);
8,烧录程序时开发板的选择:
程序如下:
#include <Arduino.h>
#include <ArduinoJson.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h>
#include <TFT_eSPI.h>
#include <Ticker.h>
#include <Preferences.h>
#include "flame.h"
#define TFT_GREY 0x5AEB
#define lightblue 0x01E9
#define darkred 0xA041
#define blue 0x5D9B
TFT_eSPI tft = TFT_eSPI(135, 240);
WiFiMulti WiFiMulti;
Preferences DarkSky;
TickerSetDisplayStore;
TickerGetDataStore;
TickerChanger;
const float SetDisplayPeriod = 1;
const float GetDataPeriod = 3600;
const int pwmFreq = 312500;
const int pwmLedChannelTFT = 0;
const int backlight = 199;
String api_key = "你的API密钥";
String latitude ="31.145";
String longitude = "121.521";
const char* ntpServer = "time2.cloud.tencent.com";
const longgmtOffset_sec = 28800;
const int daylightOffset_sec = 0;
int frame = 0;
String payload = " ";
const char* ssid = "你的WiFi名称";
const char* password = "你的WiFi密码";
const char* rootCACertificate = \
"-----BEGIN CERTIFICATE-----\n" \
"MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF\n" \
"ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n" \
"b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL\n" \
"MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv\n" \
"b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj\n" \
"ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM\n" \
"9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw\n" \
"IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6\n" \
"VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L\n" \
"93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm\n" \
"jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n" \
"AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA\n" \
"A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI\n" \
"U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs\n" \
"N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv\n" \
"o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU\n" \
"5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy\n" \
"rqXRfboQnoZsG4q5WTP468SQvvG5\n" \
"-----END CERTIFICATE-----\n";
void SetDisplay() {
struct tm timeinfo;
getLocalTime(&timeinfo);
String TimeZoneCity = DarkSky.getString("TimeZoneCity", "null");
String summary = DarkSky.getString("summary", "null");
float temperature = DarkSky.getFloat("temperature", 0);
float humidity = DarkSky.getFloat("humidity", 0);
float pressure = DarkSky.getFloat("pressure", 0);
float windSpeed = DarkSky.getFloat("windSpeed", 0);
float centigrade = (temperature - 32) / 1.8;
tft.fillScreen(TFT_BLACK);
tft.setCursor(0, 0);
tft.setTextFont(2);
tft.setTextColor(TFT_YELLOW);
tft.println(&timeinfo, "%A, %B %d %Y");
tft.setCursor(0, 30, 2);
tft.setTextColor(TFT_PINK);
tft.println(&timeinfo, "%H:%M:%S");
tft.fillRect(0, 120, 135, 20, TFT_GREENYELLOW);
tft.setCursor(3, 123, 2);
tft.setTextColor(TFT_WHITE, lightblue);
tft.print("TEMP: ");
tft.print(centigrade);
tft.drawCircle(90, 124, 2, TFT_BLACK);
tft.drawString("C", 95, 123, 2);
tft.fillRect(1, 150, 64, 20, blue);
tft.setCursor(1, 150, 2);
tft.println(TimeZoneCity);
tft.fillRect(70, 150, 64, 20, TFT_RED);
tft.setCursor(70, 150, 2);
tft.print("HUMI:");
tft.println(humidity);
tft.fillRect(1, 180, 64, 20, TFT_GOLD);
tft.setCursor(1, 180, 2);
tft.println(pressure);
tft.fillRect(70, 180, 64, 20, TFT_SKYBLUE);
tft.setCursor(70, 180, 2);
tft.print("WIND:");
tft.println(windSpeed);
tft.fillRect(1, 210, 135, 20, TFT_DARKGREEN);
tft.setCursor(3, 213, 2);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.println(summary);
tft.pushImage(0, 55, 135, 65, ani);
frame++;
if (frame >= 10)
frame = 0;
//delay(200);
}
void setup() {
Serial.begin(115200);
sigmaDeltaSetup(pwmLedChannelTFT, pwmFreq);
sigmaDeltaAttachPin(TFT_BL, pwmLedChannelTFT);
sigmaDeltaWrite(pwmLedChannelTFT, backlight);
WiFi.mode(WIFI_STA);
WiFiMulti.addAP(ssid , password);
tft.init();
tft.setRotation(0);
tft.fillScreen(TFT_BLACK);
tft.setSwapBytes(true);
tft.setCursor(0, 0);
tft.setTextFont(1);
tft.setTextColor(TFT_WHITE, lightblue);
tft.printf("Connecting to %s ", ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
tft.print(".");
}
tft.println("");
tft.println("WiFi connected.");
tft.println("IP address: ");
tft.println(WiFi.localIP());
DarkSky.begin("DarkSkySpace");
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
Changer.once(1, GetData);
SetDisplayStore.attach(SetDisplayPeriod, SetDisplay);
GetDataStore.attach(GetDataPeriod, GetData);
}
void loop() {}
void GetData() {
WiFiClientSecure *client = new WiFiClientSecure;
if (client) {
client -> setCACert(rootCACertificate);
{
HTTPClient https;
if (https.begin(*client, "https://api.darksky.net/forecast/" + api_key + "/" + latitude + "," + longitude)) {
int httpCode = https.GET();
if (httpCode > 0) {
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String payload = https.getString();
DynamicJsonDocument doc(24576);
DeserializationError error = deserializeJson(doc, payload);
const char* timezone = doc["timezone"]; // "Asia/Shanghai"
String TimeZone = timezone;
int CityList = TimeZone.lastIndexOf('/');
String City = TimeZone.substring(CityList + 1);
JsonObject currently = doc["currently"];
const char* currently_summary = currently["summary"]; // "rain"
float currently_temperature = currently["temperature"]; // 76.24
float currently_humidity = currently["humidity"]; // 0.92
float currently_pressure = currently["pressure"]; // 1015.7
float currently_windSpeed = currently["windSpeed"]; // 7.57
DarkSky.putString("TimeZoneCity", City);
DarkSky.putString("summary", currently_summary);
DarkSky.putFloat("temperature", currently_temperature);
DarkSky.putFloat("humidity", currently_humidity);
DarkSky.putFloat("pressure", currently_pressure);
DarkSky.putFloat("windSpeed", currently_windSpeed);
}
https.end();
//DarkSky.end();
}
}
delete client;
}
}
}
百度网盘分享:链接:https://pan.baidu.com/s/1i79IGoPfJOnHvgDzUqpRpA
提取码:meek
nvs分区以及ticker库的使用,值得收藏,感谢分享 感谢楼主 ordding 发表于 2022-9-27 02:10
感谢楼主
一起学习,一起进步。
页:
[1]