M5Stack : M5CAMERA

OS/M5Stack 2019.02.19 23:01 Posted by 파란크리스마스

M5Stack Korea인 WIZnet에서 운영하는 메이커 컨텐츠 커뮤니티 사이트의 후원을 받아서 작성되었습니다.

출처

M5Stack : M5CAMERA

M5CAMERA는 와이파이 AP모드로 PC나 스마트폰에서 와이파이로 접속하게되면 M5CAMERA로 부터 아이피를 부여받게 되고, 와이파이에 접속한 PC나 스마트폰의 브라우져를 통해서 http://192.168.4.1에 접속하면 M5CAMERA로 촬영한 영상을 얻을 수 있습니다.

M5CAMERA는 M5Stack과 마찬가지로 ESP32칩으로 만들어져서 아두이노나 MicroPython언어로 개발이 가능합니다.

M5CAMERA의 펌웨어를 최신 버전으로 적용해야 MicroPython의 최신 함수도 지원하고, 기능도 개선되므로 최신버전의 펌웨어 적용을 권장합니다.

펌웨어를 적용하면 와이파이 SSID가 변경이 될 수도 있는데, 최신버전으로 업그레이드 하게되면 SSID가 M5Psram_Cam으로 변경되었습니다.

단점이 있다면 하나의 기기만 접속을 허용하고 있어서 이미 접속이 되어 있는 경우 다른 기기는 접속을 허용하지 않습니다.

M5CAMERA의 동영상 스트리밍 방식은 mjpg streamer 방식으로 jpg 이미지를 연속으로 http 웹서비스 하는 방식으로 일반적으로 현관문 CCTV에 많이 사용하는 방식중에 하나 입니다.

  

  

  

스마트폰에서 M5CAMERA의 영상 받아보기

스마트폰에서 M5CAMERA의 접속

스마트폰의 와이파이 목록에서 M5Cam-xxxx (펌웨어의 버전에 따라서 이름이 변경되고 있음)을 찾아서 와이파이 연결하고, 연결이 되면 스마트폰 브라우져에서 192.168.4.1로 접속하면 M5CAMERA의 영상이 보입니다.

    

M5CAMERA의 로그

브라우져로 영상 받아오기

M5Stack에서 M5CAMERA 영상 받아오기

예제 소스에는 M5CAMERA의 영상을 받아 와서 M5Stack LCD에 보여 주고 있지만, 지금 가지고 있는 M5Stack 모델은 메모리가 부족 해서 소스를 수정해서 일부만 LCD에 보여주고 있습니다. 다음에 기회가 된다면 M5Stack 4M-PSRAM모델에서 전체 영상을 받아서 보여주는 예제를 실행해보겠습니다.

수정한 아두이노 소스

#define SSID_NAME "M5Psram_Cam"
#define SSID_PASSWORD ""
#define URL "http://192.168.4.1/jpg"
#define BUFFER_MAX 1024 * 6   // 최대 메모리 크기 설정

#include <M5Stack.h>
#include <WiFi.h>
#include <HTTPClient.h>

void setup() {
  M5.begin();
  M5.Lcd.setBrightness(255);
  WiFi.begin(SSID_NAME, SSID_PASSWORD);
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) {
    // wait for WiFi connection
    delay(1000);
  } else {
    HTTPClient http;

    Serial.print("[HTTP] begin...\n");
    http.begin(URL);

    Serial.print("[HTTP] GET...\n");
    int httpCode = http.GET();

    Serial.printf("[HTTP] GET... code: %d\n", httpCode);
    // HTTP header has been send and Server response header has been handled
    if (httpCode <= 0) {
      Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
    } else {
      if (httpCode != HTTP_CODE_OK) {
        Serial.printf("[HTTP] Not OK!\n");
      } else {
        // get lenght of document (is -1 when Server sends no Content-Length header)
        int len = http.getSize();
        Serial.printf("[HTTP] size: %d\n", len);

        if (len <= 0) {
          Serial.printf("[HTTP] Unknow content size: %d\n", len);
        } else {
          // 버퍼크기 설정 - M5Stack의 메모리 한계로 최대 메모리 설정(BUFFER_MAX ) 만큼 버퍼 크기 설정
          int buffer_len = len > BUFFER_MAX ? BUFFER_MAX : len;
          
          // create buffer for read
          uint8_t buff[buffer_len] = { 0 };

          // get tcp stream
          WiFiClient * stream = http.getStreamPtr();

          // read all data from server
          uint8_t* p = buff;
          int l = 0;
          while (http.connected() && (l < sizeof(buff)) /*(l == 0 || len == -1)*/) {
            // get available data size
            size_t size = stream->available();

            if (size) {
              int s = ((size + l > sizeof(buff)) ? sizeof(buff) - l : size);
              int c = stream->readBytes(p, s);
              p += c;

              Serial.printf("[HTTP] read: %d\n", c);
              l += c;
            }
          }

          Serial.println();
          Serial.print("[HTTP] connection closed.\n");
          
          M5.Lcd.drawJpg(buff, sizeof(buff));

          // LCD display
          M5.Lcd.drawString("http://bluexmas.tistory.com", M5.Lcd.width() - 170, M5.Lcd.height() - 20, 2);
        }
      }
    }

    http.end();
  }
}

실행

  

원본 소스를 사용했을 경우 메모리가 부족해서 발생하는 오류 메시지

ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1100
load:0x40078000,len:10088
load:0x40080400,len:6380
entry 0x400806a4
M5Stack initializing...OK
[HTTP] begin...
[HTTP] GET...
[HTTP] GET... code: 200
[HTTP] size: 17937
Guru Meditation Error: Core  1 panic'ed (Unhandled kernel exception)

Core 0 register dump:
PC      : 0x4000bea8  PS      : 0x00060f33  A0      : 0x8008f1d1  A1      : 0x3ffbde50  
A2      : 0x00000050  A3      : 0x00000000  A4      : 0x3f405144  A5      : 0x3f404ddc  
A6      : 0x00000003  A7      : 0x00060423  A8      : 0x800e26b3  A9      : 0x3ffbe1e0  
A10     : 0x3ffb6678  A11     : 0x3f406025  A12     : 0x3f404ddc  A13     : 0x3f404d70  
A14     : 0x00000069  A15     : 0x3f406018  SAR     : 0x00000018  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x00000004  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000  
Core 0 was running in ISR context:
EPC1    : 0x4000bea8  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x00000000

Backtrace: 0x4000bea8:0x3ffbde50 0x4008f1ce:0x3ffbde70 0x4008f414:0x3ffbde90 0x40081588:0x3ffbdeb0 0x400815b8:0x3ffbded0 0x40081711:0x3ffbdf00 0x400ee26b:0x3ffbdf20 0x400ea4fd:0x3ffbe1e0 0x400e26b0:0x3ffbe230 0x40090131:0x3ffbe260 0x4008f57d:0x3ffbe290 0x400831ec:0x3ffbe2b0 0x40083421:0x3ffbe2e0 0x40081add:0x3ffbe300 0x4016a43b:0x00000000

Rebooting...