ESP32のデータをサーバーにUPLOADする場合、これまでHTTP通信(GET文)を使ってきた。しかし画像データはGET文で送ることができない。どうしたものかあれこれ調べていると、Local LAN内での写真転送方法に関するネット記事があった。そこで下記の記事を参考に、まずはその環境を構築してみた。
参考記事:
TTGO T-Camera+M5StackでWi-Fiカメラ
Wi-Fiカメラ TTGO T-Camera側のスケッチGithub
TTGO T-Camera ESP32 が人体などの動きを検出すると、写真を撮影し、 WifiネットワークでLinuxサーバーへ送信・保存するプログラムを作成する。
1、ESP32のソースコードの作成
GitHub bokunimowakaru/iot-cameraから、ZIPファイルをダウンロード。これを展開し、フォルダー名を「iot-camera]として、~/Arduinoに移動。
①「iot-camera.ino」を開き、WifiのSSID, PASSWDを記述
/***************************************
* WiFi
**************************************/
#define WIFI_SSID "xxxxxxxxxx-g" // your wifi ssid
#define WIFI_PASSWD "33xxxxxxxxx62" // your wifi password
②さらに画像送信先のLinuxサーバーのIPとポート番号を記述
#define IP5306_ADDR 0X75 ← IP5306はLiイオン制御ICなので、今回は不要
#define IP5306_REG_SYS_CTL0 0x00 ←
#define SENDTO "192.168.1.7" // 送信先LinuxサーバーのIPアドレス
#define PORT 1024 // 送信のポート番号
2、Linuxサーバー側の設定
①TTGO T-camの画像データを取得するシェルスクリプト「iot-cam_serv.sh」を公開ディレクトリに保存。Linuxでは、public_htmlをAppacheの公開ディレクトリとしているので、以下のようにファイルを配置。
~/iot-cam/iot-cam_serv.sh ・・・TTGO T-cam画像データ取得プログラム
~/iot-cam/phpto ・・・画像データ保存ディレクトリ
②iot-cam_serv.shのカメラのIPアドレスとポートを設定
#!/bin/bash
################################################################################
# Server Example 04: 防犯システム
# Copyright (c) 2016-2019 Wataru KUNINO
################################################################################
PORT=1024 # 受信UDPポート番号を1024に
REED=1 # ドアスイッチON検出=0 OFF=1
IP_CAM="192.168.1.14" # カメラのIPアドレス
FILE="cam_a_5" # カメラ名・保存時ファイル名
echo "Server Example 04 Cam (usage: $0 port)" # タイトル表示
if [ $# -ge 1 ]; then # 入力パラメータ数の確認
if [ $1 -ge 1024 ] && [ $1 -le 65535 ]; then # ポート番号の範囲確認
PORT=$1 # ポート番号を設定
fi # ifの終了
fi # ifの終了
echo "Listening UDP port "$PORT"..." # ポート番号表示
mkdir photo >& /dev/null # 写真保存用フォルダ作成
while true; do # 永遠に繰り返し
UDP=`nc -luw0 $PORT|tr -d [:cntrl:]|\
tr -d "\!\"\$\%\&\'\(\)\*\+\;\<\=\>\?\[\\\]\^\{\|\}\~"`
# UDPパケットを取得
DATE=`date "+%Y/%m/%d %R"` # 日時を取得
DEV=${UDP#,*} # デバイス名を取得(前方)
DEV=${DEV%%,*} # デバイス名を取得(後方)
echo -E $DATE, $UDP # 取得日時とデータを表示
# echo -E $DATE, $UDP >> log_$DEV.csv # 取得日時とデータを保存
CAM=0 # 変数CAMの初期化
case "$DEV" in # DEVの内容に応じて
"rd_sw_"? ) DET=`echo -E $UDP|tr -d ' '|cut -d, -f2`
if [ $DET -eq $REED ]; then # 応答値とREED値が同じとき
CAM=1
fi ;;
"pir_s_"? ) DET=`echo -E $UDP|tr -d ' '|cut -d, -f2`
if [ $DET != 0 ]; then # 応答値が0以外の時
CAM=1
fi ;;
"Pong" ) CAM=1 ;;
"${FILE}" ) IP_CAM=`echo -E $UDP|tr -d ' '|cut -d'/' -f3`
echo "IP_CAM="${IP_CAM}
;;
esac
if [ $CAM != 0 ]; then # CAMが0で無いとき
echo -n "wget "${IP_CAM}"/cam.jpg"
wget -qT10 $IP_CAM/cam.jpg # 写真撮影と写真取得
if [ $? -eq 0 ]; then
echo " OK"
else
echo " ERROR"
fi
SFX=`date "+%Y%m%d-%H%M"` # 撮影日時を取得し変数SFXへ
mv cam.jpg photo/$FILE"_"$SFX.jpg >& /dev/null
fi # 写真の保存
done # 繰り返しここまで
3、画像データの取得
TTGOと同じWifilネットワークに接続したLinuxサーバーで、上記シェルスクリプトを実行する。
次にサーバが起動した状態で、TTGO T-Camera ESP32のボタン(IO34またはRST)を押すと、カメラのIPアドレスがサーバへ送信され、以降、人感センサが反応するたびに、写真を撮影し、Linuxのphotoディレクトリに画像が保存される。
・Arduinoスケッチの場所
\Documents\Arduino\iot-camera¥iot-camera.ino
→結果OK
このサンプルプログラムでは、URLを指定してファイルをダウンロードするwgetコマンドを使用している
wget -qT10 $IP_CAM/cam.jpg # 写真撮影と写真取得
-q --quiet 経過のメッセージを出力しない
-T 秒数 --timeout=秒数 タイムアウトするまでの秒数を指定する
Localエリア内であればこの手法でよいが、クラウドサーバー(さくらインターネット)ではローカルのURLを指定することはできない。やはりHTTPのPOST文などで送信するしかないだろう。あれこれ悩みながらネット検索すると、外部サーバーへ転送する方法を掲載した記事があったので、それを参考にプログラムを作成した。以降は次のブログで記述。
コメント