Arduino + ESP32-C3 + TFT(1.8‘ ST7735S)基础平台(实验四)直接显示网络图片

更多内容,请访问我的网站: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 Embeddingicon-default.png?t=N7T8https://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+) ​icon-default.png?t=N7T8https://www.jianshu.com/p/2195acbe2404  

也还有人用来 显示 ESP32-CAM 的照片icon-default.png?t=N7T8https://www.bilibili.com/read/cv14845053

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值