更多内容,请访问我的网站:https://jiangge12.github.io/
----------------------------------------------------------------------------------------------------------------------
Arduino + ESP32-C3 + TFT(1.8‘ ST7735S)基础平台
Arduino + ESP32-C3 + TFT(1.8‘ ST7735S)基础平台(实验一)
Arduino + ESP32-C3 + TFT(1.8‘ ST7735S)基础平台(实验二)玩具示波器
Arduino + ESP32-C3 + TFT(1.8‘ ST7735S)基础平台(实验三)折腾 TFT_eSPI 库
Arduino + ESP32-C3 + TFT(1.8‘ ST7735S)基础平台(实验四)直接显示网络图片
Arduino + ESP32-C3 + TFT(1.8‘ ST7735S)基础平台(实验五)温湿度
----------------------------------------------------------------------------------------------------------------------
前篇搞定了 TFT_eSPI , 那么肯定是用来显示点什么。存 数组或 FATFS 里面什么的都有些麻烦,直接显示一个网页图片还不错,搜一下还真有: Pngle GitHub - kikuchan/pngle: Pngle - PNG Loader for Embeddinghttps://github.com/kikuchan/pngle例程如下,如按前篇写的配置好 TFT_eSPI ,能够正确显示,那么本实验只需要配置 wifi 。
注意:
首先,确保 http://www.joindesign.cn/1.png 可以在浏览器看到如下图片( 目前放了10张,编号1.png - 10.png ),如失效了可以另外找,或者内网跑一个web服务器,甚至 ESP32 ESP8266 都能跑简单的web服务器。
其次,本实验是特指这块合宙的 1.8‘TFT ,分辨率 160x128 ,所以呢图片也是这个规格的 png, 本程序暂时不支持其他图片格式。实测图片大些也能显示,只是没有自动缩放填充这些windows里常用的功能,参数里好像也有缩放设定,没测试。
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
#include <HTTPClient.h>
#include <WiFi.h>
WiFiClient client;
#include "pngle.h"
#define WIFI_SSID "xxx"
#define WIFI_PASS "xxx"
// ===================================================
// pngle example for TFT_eSPI
// ===================================================
double g_scale = 1.0;
// pngle callback, called during decode process for each pixel
void pngle_on_draw(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t rgba[4])
{
// Convert to RGB 565 format
uint16_t color = tft.color565(rgba[0], rgba[1], rgba[2]);
// If alpha > 0 then draw
if (rgba[3]) {
if (g_scale <= 1.0) tft.drawPixel(x, y, color);
else {
x = ceil(x * g_scale);
y = ceil(y * g_scale);
w = ceil(w * g_scale);
h = ceil(h * g_scale);
tft.fillRect(x, y, w, h, color);
}
}
}
void load_png(const char *url, double scale = 1.0)
{
HTTPClient http;
http.begin(client,url);
int httpCode = http.GET();
if (httpCode != HTTP_CODE_OK) {
tft.printf("HTTP ERROR: %u\n", httpCode);
http.end();
return ;
}
int total = http.getSize();
WiFiClient *stream = http.getStreamPtr();
pngle_t *pngle = pngle_new();
pngle_set_draw_callback(pngle, pngle_on_draw);
g_scale = scale;
uint8_t buf[2048];
int remain = 0;
uint32_t timeout = millis();
while (http.connected() && (total > 0 || remain > 0)) {
// Break out of loop after 10s
if ((millis() - timeout) > 10000UL)
{
tft.printf("HTTP request timeout\n");
break;
}
size_t size = stream->available();
if (!size) { delay(1); continue; }
if (size > sizeof(buf) - remain) {
size = sizeof(buf) - remain;
}
int len = stream->readBytes(buf + remain, size);
if (len > 0) {
int fed = pngle_feed(pngle, buf, remain + len);
if (fed < 0) {
tft.printf("ERROR: %s\n", pngle_error(pngle));
break;
}
total -= len;
remain = remain + len - fed;
if (remain > 0) memmove(buf, buf + fed, remain);
} else {
delay(1);
}
}
pngle_destroy(pngle);
http.end();
}
// ===================================================
void setup()
{
Serial.begin(115200);
tft.begin();
tft.setRotation(3);
tft.fillScreen(TFT_GREEN);
tft.setTextColor(TFT_BLUE);
tft.setTextFont(2);
tft.printf("Welcome.\n");
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) { delay(500);}
tft.printf("WiFi connected.\n");
delay(1000);
}
void loop()
{
long t;
t = micros();
load_png("http://www.joindesign.cn/1.png");
delay(2000);
load_png("http://www.joindesign.cn/2.png");
delay(2000);
load_png("http://www.joindesign.cn/3.png");
delay(2000);
load_png("http://www.joindesign.cn/4.png");
delay(2000);
load_png("http://www.joindesign.cn/5.png");
delay(2000);
load_png("http://www.joindesign.cn/6.png");
delay(2000);
load_png("http://www.joindesign.cn/7.png");
delay(2000);
load_png("http://www.joindesign.cn/8.png");
delay(2000);
load_png("http://www.joindesign.cn/9.png");
delay(2000);
load_png("http://www.joindesign.cn/10.png");
delay(2000);
t = ( micros() -t - 20000000) / 1000; // (扣除显示延时)单位微秒,除1000后单位毫秒
tft.fillScreen(TFT_GREEN);
tft.setTextColor(TFT_BLUE);
tft.setCursor(30,10);
tft.setTextFont(4);
tft.print(t); // 显示10张图的总加载时间, 大概10秒左右
delay(5000);
}
------------------------------------------------------------------------------------------
Pngle 顾名思义是适用png图片, 再搜一下, 找到 适用 jpg 图片的库 TJpg_decoder
也是基于 TFT_eSPI 的, 库自带有几个例程,我实验的 SPIFFS_Web_Jpg 几乎不用怎么改动就成功显示出 jpg图片。 如果例程的图片失效, 下面几个网络图片供测试:
-----------------------------------------------------------------------------------------------------------------
小结一下:
显示网络图片是比较有意思的功能,这是建立在ESP32-C3有 wifi功能的基础上。比如上图是实际的一个测试:先显示飞机图片,然后在服务器端把图片替换为月历,那么ESP32-C3这边只需要复位一次就能变身月历显示屏。这样,几乎就不用折腾汉字硬字库、图标、取模、排版、阴历阳历转换这些对单片机占用内存多且麻烦枯燥的工作,在电脑端用python等工具准备好素材,转换为图片,上传服务器即可。运用适当的web或者蓝牙这些可以交互的方式,甚至可以连复位都不用,实时更新图片。
如果我有一家超市,每个电子价签对应一个唯一序列号,并在服务器建立一个对应图片文件。需要更换价签就在服务器跑一下脚本就完成了,整套成本应该不比墨水屏的高。
还有人用它玩 stream (电脑桌面缩略图实时推送到单片机,帧率10+) https://www.jianshu.com/p/2195acbe2404
也还有人用来 显示 ESP32-CAM 的照片https://www.bilibili.com/read/cv14845053