上期我们介绍了如何利用百度地图API利用HTTP向百度地图获取信息,本来是想用STM32配合GPS模块来显示图片的,但是GPS有点问题还尚未解决,因此本期我们利用ESP32联网来模拟一下给出定位之后获取图片信息并显示。

开发平台:Arduino IDE 硬件设备:ESP32C3,ST7IDE_LCD(240*240)

接下来我们讲一下代码以及流程:

先,定义一下我们的网址还有密钥以及我们的Wifi账户和密码。


void setup() {
  Serial.begin(115200);
  
  pinMode(outputPin, OUTPUT);
  digitalWrite(outputPin, HIGH);
  
  tft.begin();
  tft.setRotation(1);
  tft.fillScreen(TFT_BLACK);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.setTextSize(2);
  
  WiFi.begin(ssid, password);
  tft.println("正在连接WiFi...");
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    tft.print(".");
  }
  
  tft.println("");
  tft.println("WiFi已连接");
  tft.print("IP地址: ");
  tft.println(WiFi.localIP().toString());
  
  delay(1000);
  tft.fillScreen(TFT_BLACK);
  tft.println("正在获取地图...");
  
  getAndDisplayMap();
}

初始化外设以及屏幕,关于屏幕可以参考以前的一期公众号文章

从零开始的ESP32天气时钟(1)——点亮TFT并连接Wifi


void getAndDisplayMap() {
  HTTPClient http;
  
  String url = String(baiduMapAPI) + 
               "?ak=" + apiKey + 
               "&width=" + String(mapWidth) + 
               "&height=" + String(mapHeight) + 
               "&zoom=" + String(zoom) + 
               "&center=" + center + 
               "&copyright=1&scale=2&quality=100"; // 增加quality参数
  
  Serial.println("请求URL: " + url);
  
  http.begin(url);
  int httpCode = http.GET();
  
  if (httpCode > 0) {
    if (httpCode == HTTP_CODE_OK) {
      WiFiClient * stream = http.getStreamPtr();
      
      pngle_t *pngle = pngle_new();
      pngle_set_draw_callback(pngle, pngle_on_draw);
      
      uint8_t buf[1024];
      int remain = 0;
      int len = http.getSize();
      
      Serial.printf("图片大小: %d 字节\n", len);
      
      while (http.connected() && (len > 0 || len == -1)) {
        size_t size = stream->available();
        if (size) {
          int c = stream->readBytes(buf + remain, ((size > sizeof(buf) - remain) ? sizeof(buf) - remain : size));
          int fed = pngle_feed(pngle, buf, remain + c);
          if (fed < 0) {
            Serial.printf("PNG解码错误: %s\n", pngle_error(pngle));
            break;
          }
          remain = remain + c - fed;
          if (remain > 0) memmove(buf, buf + fed, remain);
          if (len > 0) {
            len -= c;
          }
        }
        delay(1);
      }
      
      pngle_destroy(pngle);
      tft.println("地图加载完成");
    }
  } else {
    tft.println("Get MAP Error");
    Serial.printf("HTTP错误: %s\n", http.errorToString(httpCode).c_str());
  }
  
  http.end();
}

在获取图片的函数中,我们向百度地图发送API请求,获取图片,但需要注意的是,我们获取到的图片是一张png图片,是不能作为RGB565直接显示到我们的屏幕上的,因此我们需要对图片进行解码将PNG格式转换为RBG565之后显示。

因此我们引入一个轻量级的PNG解码库。

这个库也可以直接在Arduino IDE的库管理中直接安装。

// PNG解码回调
void pngle_on_draw(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t rgba[4])
{
    uint16_t color = tft.color565(rgba[0], rgba[1], rgba[2]);
    tft.drawPixel(x, y, color);
}

添加PNG解码的回调函数,当我们解码完数据之后会将数据在LCD显示屏中刷新。

这样子就完成了从百度地图获取图片并在ESP32中显示啦。

嘉立创PCB

还没有评论,抢个沙发!