13
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

M5StickCにM5Cameraからの動画を表示する

Last updated at Posted at 2020-12-17
#はじめに 「__LovyanGFXグラフィックライブラリ__は描画がめちゃ早い」 といううわさを聞いたので、M5StickC PLUSで使ってみました。 M5Cameraの画像を動画で表示しています。 #コード 上の動画では画面のサイズが合ってませんが、以下のコードではM5StickC PLUSを横にした画面にちょうど良くなるよう変更してあります。
#include <WiFi.h>
#include <HTTPClient.h>

#define  LGFX_AUTODETECT // (1)
#include <LovyanGFX.hpp>
#include <M5StickCPlus.h>

// 接続先のSSIDとパスワード
const char ssid[] = "YOURM5CAMERASSID";
const char passwd[] = "YOURCAMERAPASSWORD";

HTTPClient http;
int httpCode;
String response;
uint8_t buff[64 * 1024] = { 0 };// カメラの画像を受け取る用のバッファ。十分な大きさが必要

static LGFX lcd;


void setup() {
    Serial.begin(115200);

    lcd.init();
    lcd.setRotation(1);
    lcd.setBrightness(128);
    lcd.fillScreen(TFT_BLACK);

    // WiFi つなぐ
    connectWiFi();

    // カメラのフレームサイズを設定する
    cameraInit();  // (2)

    // カメラの準備ができるのを待つ。数字は適当です
    delay(1000); 
}

// メインループ
void loop() {

    if ( WiFi.status() != WL_CONNECTED ) {
        // WiFi切れたらつなぎなおす
         connectWiFi();
         cameraInit();
         delay(1000);
    } else {
        // 画像を受け取って表示する
         draw_captureimage();
    }
    // このdelay(1)は必要
    delay(1);
}

// WiFiに繋ぐ処理
void connectWiFi()
{
    WiFi.begin(ssid, passwd);
    Serial.print("WiFi connecting..");
    while(WiFi.status() != WL_CONNECTED) {
      Serial.print(".");
      delay(100);
    }
    Serial.print(" connected. ");
    Serial.println(WiFi.localIP());
}

// M5Cameraからの画像を受け取って表示する処理
void draw_captureimage(){
    http.begin("http://192.168.4.1/capture"); // GET
    httpCode = http.GET();
    if (httpCode > 0) {
        int len = http.getSize();
        Serial.printf("[HTTP] size: %d\n", len);
        if (len <= 0) {
          Serial.printf("[HTTP] Unknow content size: %d\n", len);
        } else {
          // create buffer for read
          //uint8_t buff[len] = { 0 };
          // get tcp stream
          WiFiClient * stream = http.getStreamPtr();
          Serial.printf("[HTTP] strm ptr: %x\n", stream);
          // read all data from server
          uint8_t* p = buff;
          int l = len;
          while (http.connected() && (l > 0 || len == -1)) {
            // get available data size
            size_t size = stream->available();
            if (size) {
              int s = ((size > sizeof(buff)) ? sizeof(buff) : size);
              int c = stream->readBytes(p, s);
              p += c;
              Serial.printf("[HTTP] read: %d\n", c);
              if (l > 0) {
                l -= c;
              }
            }
          }
        }
        lcd.drawJpg(buff,sizeof(buff)); // 画像の描画 (3)
    } else {
        Serial.println("Error on HTTP request");
        Serial.println(httpCode);
    }
    http.end();
    Serial.println();
    Serial.print("[HTTP] connection closed.\n");
}

// カメラのフレームサイズを設定 (2)
void cameraInit(){
    // 画像サイズをQVGAに設定
    // これがM5StickC PLUSの画面にちょうどいいサイズ感
    http.begin("http://192.168.4.1/control?var=framesize&val=3");
    httpCode = http.GET();
    if (httpCode > 0) {
        Serial.println("status");
        response = http.getString();
        Serial.println(httpCode);
        Serial.println(response);
    } else {
        Serial.println("Error on HTTP request");
        Serial.println(httpCode);
    }
    http.end();
}

#ちょっとだけ説明
(1)#define LGFX_AUTODETECT
LovyanGFXがLCDのサイズを自動的に判別するという定義。
現在は次の定義でもいけるそうです。(LovyanGFX 0.3.4情報)
#define LGFX_M5STICK_C

(2)カメラのフレームサイズをQVGAに設定
もっと大きなサイズでも取得はできますが、LCDに収まらないので一部しか見れません。
大きな画像を受け取りたいときはバッファサイズも変更したほうがいいと思います。

(3)lcd.drawJpg(buff,sizeof(buff));
これを使うためにLovyanGFXを導入したのだ

#実行結果

#おわりに 上にも書きましたが、LovyanGFXを使うと決めたのは__drawJpg()__が使えるようになるからです。 M5StickCのライブラリにはdrawJpg()がないんです! M5Stackにはあるのに! >(追記) GitHubのソースを追ってみたのですが、どうもM5StickC PLUSはソースにはdrawJpg()あるけど使うことはできないという状況みたいです。謎。

M5Cameraの画像はjpeg形式で送られてくるわけで、それが描画できないというのはけっこう問題でした。

それと、先人のブログなどを拝見していると皆さん__画像表示の遅さ__には苦労しておられるようで...
それがLovyanGFXの登場で圧倒的に早くなったわけですから、これは是非やってみたいと思った次第でした。

先人の皆様と、ライブラリ作者の@lovyan03さんに深く感謝です。

###参考文献
github - LovyanGFX
Androidのカメラ映像をMotionJPEGで配信する
ESP32でビットマップ画像ファイルを生成し、ブラウザに連続送信してMotion JPEGならぬMotion BMP動画ストリーミングする実験

#おまけ
IMU × LovyanGFX

13
8
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?