TTGO-Camera による定点観測・WEBサーバ経由の画像公開
2020.03.04
YouTubeでポイントを説明しています。画像をクリックすると再生できます。
今回は、TTGO-Cameraを用いて定点観測した画像をWEB公開する仕組みを構築します。
TTGO-Camera の画像を直接インターネットに流すのではなく、WEBサーバ側から定期的にTTGO-Cameraを呼び出して画像を取得・保存して、
保存した画像の中から最新の画像を公開します。
■TTGO T-Camera ESP32 WROVER & PSRAM Camera Module ESP32-WROVER-B OV2640 Camera Module 0.96 OLED (魚眼レンズ)

TTGO T-Camera はイメージセンサーにOV2640(オムニビジョン)を搭載、UXGA(1600×1200)解像度での撮影が可能です。
ESP32に小型LCD、人感センサーが付き、PSRAMは8Mバイトです。
技適取得済みですので安心して使用できます。
【T-Camera specification】
| Master Chip: | esp32 dual-core |
| Protocol: | Wi-Fi 802.11 b/g/n & Bluetooth 4.2 BLE & BR/EDR |
| Flash: | 4MBytes |
| PSRAM: | 8MBytes |
| Display: | SSD1306 I2C(OLED液晶128×64) |
| PIR: | AS312(モーションセンサー) |
| Uart Chip: | CP2104 |
| Charging chip: | IP5306 I2C |
| Camera: | OV2640(カメラ2M pixel) |
■TTGO T-Camera 動作確認
予め、GitHubで公開されているサンプルプログラムが書き込まれているので、
USBから電源供給すると、アクセスポイントモード(AP-Mode)で起動します。
WiFi接続に、TTGO-CAMERA-XX:XXを選択します。
http://2.2.2.1に接続すると設定画面が表示されます。
設定画面上部の解像度(Resolution)を適当に変更して、画面を下のほうにスクロール、[Start Stream]を押します。
カメラからの映像が表示されます。TTGO-Cameraの基板にカメラが逆さに取り付けられているので、画像の上下が逆になっています。
■開発環境・WEB公開環境
【開発環境】
プログラムのビルド、TTGO-Camera への書込み、画像ファイル転送テストを行います。
| Platform : | Raspberry Pi 2 Model B (ARMv7) |
| Distribution : | Raspbian Stretch |
【WEB公開環境】
TTGO-Camera からの定期的な画像取得およびその画像を公開します。
| Platform : | Raspberry Pi 3 Model B+ |
| Distribution : | ubuntu 18.04.3 server |
■ライブラリ・ダウンロード
Interface 2020年 04 月号
今回の内容はこちらを参考にしています。一読されると理解を深められると思います。
使用するソースコードは下記よりダウンロードしてください。
Interface 2020年4月号 マイクロIoTカメラ
IF2004A.zip を解凍して、
→[IF2004A]
→[esp32_ttgo]
→[ttgo_wifi_httpd]
→[esp32_cam2]
→esp32_cam2.ino を使用します。
esp32-camera-master.zip
ソース解析用にこちらもダウンロードしておきましょう。
■esp32_cam2.inoの編集・ビルド
開発環境にはARMv7あるいはARMv8のラズベリーパイが必要です。後述しますが、TTGO-Camera を固定ローカルIPアドレスでブロードバンドルータに
WiFi接続するようにプログラムの書き換えを行います。
また、プログラムを書き込むために、Raspberry Pi と TTGO-Camera をUSB接続します。
プログラムのビルドには、Platformioを使用します。
まずは、接続デバイスを確認します
$ platformio device list
/dev/ttyUSB0
------------
Hardware ID: USB VID:PID=10C4:EA60 SER=01B86EA3 LOCATION=1-1.5
Description: CP2104 USB to UART Bridge Controller
/dev/ttyAMA0
------------
Hardware ID: 3f201000.serial
Description: ttyAMA0
利用できるボードを確認します
$ platformio boards "espressif32"
Platform: espressif32
=======================================================================
ID MCU Frequency Flash RAM Name
------------ ----- ----------- ------- ------ --------------------
esp32cam ESP32 240MHz 4MB 320KB AI Thinker ESP32-CAM
.....
開発環境の初期化を行います
$ mkdir ~/TTGO-Camera
$ cd ~/TTGO-Camera
$ platformio init -b esp32cam
esp32_cam2.ino を初期化により作成された srcディレクトリの下にコピーします。
余談ですが、はじめは開発環境に手軽なRaspberry Pi Zero Wを使おうと思ってました。
下記は、Raspberry Pi Zero W でビルドした結果です。
$ platformio run
Processing esp32cam (platform: espressif32; framework: arduino; board: esp32cam)
-----------------------------------------------------------------------
PlatformManager: Installing espressif32
Downloading [####################################] 100%
Unpacking [####################################] 100%
espressif32 @ 1.11.2 has been successfully installed!
The platform 'espressif32' has been successfully installed!
The rest of packages will be installed automatically depending on your build environment.
PackageManager: Installing tool-esptoolpy @ ~1.20600.0
tool-esptoolpy @ 1.20600.0 has been successfully installed!
PackageManager: Installing toolchain-xtensa32 @ ~2.50200.0
Error: Could not find a version that satisfies the requirement '~2.50200.0' for your system 'linux_armv6l'
platformioは以下のURLからパッケージを探します。
http://dl.platformio.org/packages/manifest.json
manifest.jsonの中身をみてみると
....
"toolchain-xtensa32": [
{
"sha1": "78fd686e27d2619a2691150a25015ab44ae5d7ca",
"system": [
"linux_armv7l",
"linux_armv8l"
],
"url": "http://dl.platformio.org/packages/toolchain-xtensa32-linux_armv7l-2.50200.80.tar.gz",
"version": "2.50200.80"
},
....
linux_armv61 は対象外なので、パッケージをダウンロードできませんでした。
開発環境をRaspberry Pi 2 (ARMv7)に換えてビルドします。
$ platformio run
Processing esp32cam (platform: espressif32; board: esp32cam; framework: arduino)
----------------------------------------------------------------
PlatformManager: Installing espressif32
Downloading [##########################] 100%
Unpacking [##########################] 100%
espressif32 @ 1.11.2 has been successfully installed!
The platform 'espressif32' has been successfully installed!
The rest of packages will be installed automatically depending on your build environment.
PackageManager: Installing framework-arduinoespressif32 @ ~3.10004.191002
Downloading [##########################] 100%
Unpacking [##########################] 100%
framework-arduinoespressif32 @ 3.10004.200129 has been successfully installed!
PackageManager: Installing toolchain-xtensa32 @ ~2.50200.0
Downloading [##########################] 100%
Unpacking [##########################] 100%
toolchain-xtensa32 @ 2.50200.80 has been successfully installed!
PackageManager: Installing tool-esptoolpy @ ~1.20600.0
tool-esptoolpy @ 1.20600.0 has been successfully installed!
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/espressif32/esp32cam.html
PLATFORM: Espressif 32 1.11.2 > AI Thinker ESP32-CAM
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
DEBUG: Current (esp-prog) External (esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES: framework-arduinoespressif32 3.10004.200129 (1.0.4), toolchain-xtensa32 2.50200.80 (5.2.0), tool-esptoolpy 1.20600.0 (2.6.0)
Converting esp32_cam2.ino
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 26 compatible libraries
Scanning dependencies...
Dependency Graph
|-- 1.0.1
|-- 1.0
Building in release mode
Compiling .pio/build/esp32cam/src/esp32_cam2.ino.cpp.o
Generating partitions .pio/build/esp32cam/partitions.bin
/home/pi/TTGO-Camera/src/esp32_cam2.ino:40:21: fatal error: SSD1306.h: No such file or directory
*****************************************************************
* Looking for SSD1306.h dependency? Check our library registry!
*
* CLI > platformio lib search "header:SSD1306.h"
* Web > https://platformio.org/lib/search?query=header:SSD1306.h
*
*****************************************************************
#include "SSD1306.h"
compilation terminated.
Compiling .pio/build/esp32cam/libe19/Wire/Wire.cpp.o
Compiling .pio/build/esp32cam/libd94/WiFi/ETH.cpp.o
*** [.pio/build/esp32cam/src/esp32_cam2.ino.cpp.o] Error 1
============== [FAILED] Took 210.86 seconds =============
SSD1306.h が見つからないと言われたので、まずはライブラリを検索します。
$ platformio lib search "header:SSD1306.h"
$ platformio lib search "header:SSD1306.h"
ESP8266_SSD1306
===============
#ID: 562
I2C display driver for SSD1306 OLED displays connected to ESP8266, ESP32, Mbed-OS
Compatible platforms: Espressif 32, Espressif 8266
Authors: Daniel Eichhorn, ThingPulse, Fabrice Weinberg
ESP8266 and ESP32 OLED driver for SSD1306 displays
==================================================
#ID: 2978
I2C display driver for SSD1306 OLED displays connected to ESP8266, ESP32, Mbed-OS
Compatible platforms: Espressif 32, Espressif 8266
Authors: ThingPulse, Fabrice Weinberg
ssd1306
=======
#ID: 1904
Display driver for VGA, SSD1306, SSD1325/SSD1327, SSD1331, SSD1351, ILI9163/ST7735, ILI9341, PCD8544.
Compatible platforms: Atmel AVR, Atmel megaAVR, Atmel SAM, Espressif 32, Espressif 8266,,,,
Authors: Alexey Dynda
....
互換プラットフォームが適合するものだけでも複数のライブラリが見つかります。
https://github.com/lewisxhe/esp32-camera-series のREADME をみてみます
・OLED requires esp8266-oled-ssd1306 library support
のリンクをクリックすると、
ThingPulse OLED SSD1306 (ESP8266/ESP32/Mbed-OS)
に飛びます。
It is also available as a platformio library. Just execute the following command:
platformio lib install 562
とあるので、検索結果の先頭で表示されたライブラリが該当します。
$ platformio lib install 562
Library Storage: /home/pi/TTGO-Camera/.pio/libdeps/esp32cam
LibraryManager: Installing id=562
Downloading [####################################] 100%
ESP8266_SSD1306 @ 4.1.0 has been successfully installed!
$ platformio run
無事にビルドが完了しました。警告は無視しましょう。
■プログラムの書換え
esp32_cam2.ino を開いて、プログラムを書き換えます。
TTGO-Camera のIPアドレスの固定化、連続モードの解除、画像サイズ変更、表示補正を行います。
また、直接ブラウザ表示しないので、余計なヘッダー情報も出力しないようにしています。
$ vi src/esp32_cam2.ino
#define WIFI_SSID "*************" ← ネットワーク環境に合わせて
#define WIFI_PASSWD "*************" ← 設定してください
// capture and send
// while (1) { ← ループをコメントアウト
......
size_t hlen = snprintf((char *)tmp_buf, 64, _STREAM_PART, _jpg_buf_len);
//if ((res = httpd_resp_send_chunk(req, (const char *)tmp_buf, hlen)) != ESP_OK) return res;
if ((res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len)) != ESP_OK) return res;
//if ((res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY))) != ESP_OK) return res;
if (fb->format != PIXFORMAT_JPEG) free(_jpg_buf);
esp_camera_fb_return(fb);
......
// } // while
// return res;
....
IPAddress fixed_ip( 192, 168, 11, 30); // for fixed IP Address
IPAddress gateway( 192, 168, 11, 1); // Gateway Address
IPAddress subnet(255, 255, 255, 0); // Subnet Mask
IPAddress DNS( 192, 168, 11, 1); // DNS server
WiFi.config(fixed_ip, gateway, subnet, DNS);
Wire.begin(I2C_SDA, I2C_SCL);
if (psramFound()) {
config.frame_size = FRAMESIZE_XGA; // 1024x768
config.jpeg_quality = 10;
config.fb_count = 2;
....
oled.init();
参考:espressif/esp32-camera パラメタ一覧
Ref.https://github.com/espressif/esp32-camera
Ref.https://github.com/espressif/esp32-camera/blob/master/driver/include/sensor.h
Ref.https://github.com/espressif/esp32-camera/blob/master/driver/include/esp_camera.h
ビルドしたコードを、TTGO-Camera にアップロードします。
$ platformio run -t upload
ラズパイから、TTGO-Cameraの応答を確認します。
$ ping 192.168.11.30
PING 192.168.11.30 (192.168.11.30) 56(84) bytes of data.
64 bytes from 192.168.11.30: icmp_seq=1 ttl=255 time=1150 ms
64 bytes from 192.168.11.30: icmp_seq=2 ttl=255 time=126 ms
.....
■公開WEBサーバの設定
WEBサーバの構築は「ラズパイで自宅WEBサーバ構築 全16回」を参考にしてください。

TTGO-Camera を開発環境のラズパイから外して、電力供給用のUSBケーブルに繋ぎます。
カメラ画像取得用スクリプト作成
取得する画像は防犯目的も考慮して、上書き保存は行わず、日付をフォルダー名として作成し、
その下に、ファイル名 '時刻.jpg' として保存します。
また、TTGO T-Camera はカメラが逆さまに取り付けられているので、逆さまに映った画像を180℃回転させています。
<WEBサーバのドキュメントルート>
+-<TTGO-Camera>
+--<20200302>
| +-000000.jpg
| +-000500.jpg
| +-....
| +-235500.jpg
+--<20200303>
| +-....
+--<20200304>
| +-....
+--....
$ vi ~/TTGO-Camara/scripts/getImage.php
<?php
$folder = '/home/pi/www-root/TTGO-Camera/'.date('Y-m-d');
if (!file_exists($folder)) mkdir($folder,0777);
$savePath = $folder.'/'.date('His').'.jpg';
$fp = fopen($savePath,'w');
$ch = curl_init("http://192.168.11.30/");
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_exec($ch);
curl_close($ch);
fclose($fp);
$source = imagecreatefromjpeg($savePath);
$rotate = imagerotate($source, 180, 0);
imagejpeg($rotate, $savePath, -1);
imagedestroy($source);
imagedestroy($rotate);
?>
crontab 設定
5分おきに画像を取得します。
$ vi ~/TTGO-Camara/scripts/getImage.sh
#!/bin/bash
#
SCRIPTDIR=/home/pi/TTGO-Camera/scripts
INCPATH=.:/usr/lib/php
/usr/bin/php -d include_path=$INCPATH $SCRIPTDIR/getImage.php > getImage.log 2>&1
$ chmod a+x getImage.sh
$ sudo vi /etc/crontab
*/5 * * * * root /home/pi/TTGO-Camera/scripts/getImage.sh >/dev/null 2>&1
$ sudo service cron restart
※画像ファイルの削除
画像ファイルは防犯用途も考慮して、上書き保存ではなく、日時による新規作成の方法を用いています。
画像ファイルの削除もスクリプトファイルを作成して、定期的に古い画像を削除するようにするとよいと思います。
WEBページへの埋め込み
PHPで書かれた動的ページに埋め込む場合は、下記のようなコードを組み込みます。
<?php
......
$web_dir = '/TTGO-Camera/'.date('Y-m-d').'/';
$dirpath = '/home/pi/www-root'.$web_dir;
$dir = opendir($dirpath);
while (false !== ($filenames[] = readdir($dir))) ;
closedir($dir);
rsort($filenames);
if( is_file( $dirpath.$filenames[0]) ) {
echo '<img src="'.$web_dir.$filenames[0].'">';
}
......
?>
↓次のようなタグが挿入されます
<img src="/TTGO-Camera/2020-03-02/231500.jpg">
|
Raspberry Pi(ラズベリー パイ)は、ARMプロセッサを搭載したシングルボードコンピュータ。イギリスのラズベリーパイ財団によって開発されている。
たいていのことは100日あれば、うまくいく。長田英知著
「時間がなくて、なかなか自分のやりたいことができない」
「一念発起して何かを始めても、いつも三日坊主で終わってしまう」
「色んなことを先延ばしにしたまま、時間だけが過ぎていく」
そこで本書では、そんな著者が独自に開発した、
まったく新しい目標達成メソッド「100日デザイン」について、
その知識と技術を、余すところなくご紹介します。
まんがで納得ナポレオン・ヒル 思考は現実化する
OLとして雑務をこなす日々に飽き足らず、科学者だった父が残した薬品を商品化すべく、起業を決意した内山麻由(27)。彼女はセミナーで知り合った謎の女性からサポートを得ながら、彼女と二人三脚でナポレオン・ヒルの成功哲学を実践し、さまざまな問題を乗り越えていく。
ヒル博士の<ゴールデンルール>に従い、仕事に、恋に全力疾走する彼女の、成功への物語。
今日は人生最悪で最高の日 1秒で世界を変えるたったひとつの方法 ひすいこたろう著
偉人の伝記を読むと、最悪な日は、不幸な日ではなく、新しい自分が始まる日であることがわかります。最悪な出来事は、自分の人生が、想像を超えて面白くなる兆しなのです。偉人伝を読むことで、このときの不幸があったおかげで、未来にこういう幸せがくるのかと、人生を俯瞰する視線が立ち上がるのです。
ご飯は私を裏切らない heisoku著
辛い現実から目を背けて食べるご飯は、いつも美味しく幸せを届けてくれる。
29歳、中卒、恋人いない歴イコール年齢。バイト以外の職歴もなく、短期バイトを転々とする日々。ぐるぐると思索に耽るけど、ご飯を食べると幸せになれる。奇才の新鋭・heisokuが贈るリアル労働グルメ物語!
【最新版Gemini 3に対応!】できるGemini (できるシリーズ)
Geminiを「最強の知的生産パートナー」として使いこなすための、実践的なノウハウを凝縮した一冊です。
基本的な操作方法から、具体的なビジネスシーンでの活用、日々の業務を自動化するGoogle Workspaceとの連携、さらには自分だけのオリジナルAIを作成する方法まで余すところなく解説します。
Rustプログラミング完全ガイド 他言語との比較で違いが分かる!
Rustの各手法や考え方を幅広く解説!
500以上のサンプルを掲載。実行結果も確認。
全24章の包括的なチュートリアル。
ポチらせる文章術
販売サイト・ネット広告・メルマガ・ブログ・ホームページ・SNS…
全WEB媒体で効果バツグン!
カリスマコピーライターが教える「見てもらう」「買ってもらう」「共感してもらう」すべてに効くネット文章術
小型で便利な Type-C アダプター USB C オス - USB3.1 オスアダプター
Type-C端子のマイコンボードをこのアダプタを介して直接Raspberry Piに挿すことができます。ケーブルなしで便利なツールです。
Divoom Ditoo Pro ワイヤレススピーカー
15W高音質重低音/青軸キーボード/Bluetooth5.3/ピクセルアート 専用アプリ/USB接続/microSDカード
電源供給USBケーブル スリム 【5本セット】
USB電源ケーブル 5V DC電源供給ケーブル スリム 【5本セット】 電源供給 バッテリー 修理 自作 DIY 電子工作 (100cm)
|