タブレイン社の3GIMを使ってSDカードに保存している画像データをAWSに送信してみました。
今回使用したカメラはアドバリーシステム様のDRE-LTE-CAMを使いました。
#環境
- Genuino 101 1
- 3GIMシールドV2.0 for Arduino
- 3GIM V2.1 2
- SORACOM Air SIMカード(データ通信のみ) (マイクロ)
- DRE-LTE-CAM 鮮明化カメラユニット
- Arduino イーサネットシールド2
#処理の流れ
カメラで撮影したデータを一度SDカードに保存、SDカードに保存している画像データを
3GIMを使ってTCP送信してクラウドへアップロードしています。
#処理説明
カメラから画像を取得する処理は割愛します。
今回はSDカードに保存された後を想定して行います。
###1. 3GIM初期化とSDカード初期化
ここからArduinoのプログラムを書いていきます。
まず、3GIMとSDカードの初期化を行います。
// 3GIM初期化
if (a3gs.start() == 0 && a3gs.begin(0, baudrate) == 0) {
Serial.println("ok");
delay(15000); // 電波安定までウェイトをかませる
} else {
// 接続失敗
Serial.println("3Fin");
}
// sdカード初期化
Serial.print("SDカード初期化 ...");
if (!SD.begin(chipSelect)) {
Serial.println("SDカード初期化失敗!");
return;
}
###2. 3GIMをTCP接続する
3GIMをTCP接続して送信の準備をします。
接続がOKなら0が返ってきます。
connectTCPというメソッドで接続先IPとポート番号を指定します。
resflag = a3gs.connectTCP(server_aws, xxxxxxx);
if (resflag == 0) {
Serial.println("TCP connect OK");
// 読み取り開始
done = 1;
} else {
Serial.print("TCP 接続失敗");
}
###3. SDカードを読み取ってサーバーに送信する
SD.open処理で画像ファイルを読み取り、対象バイト数を超えるか、画像ファイルを読み取るまで処理を続けます。
a3gs.writeBegin
で書き込むデータ数を指定
a3gSerial.write
で実際に送信するデータを指定します。
// ファイル読み込み
myFile = SD.open("test.jpg");
~省略~
// 既定バイト数読み込み終わった or 全ファイル読み取り終わった
if ((ii == MAX_BYTE) || EndFlag) {
// TCPサーバーに書き込み処理開始
a3gs.writeBegin(sizeof(data));
a3gSerial.write((uint8_t*) data, sizeof(data));
}
###全体の流れ
#include <SD.h>
#include <SPI.h>
#include <SoftwareSerial.h>
#include <Ethernet2.h>
#include "a3gim2.h"
#define baudrate 115200UL // ボーレートを速い設定にしておく
boolean EndFlag=0; // 読み取り終了フラグ
const int chipSelect = 4; // SDカードチップ番号
File myFile; // SDカードファイル
byte readingbyte;
uint8_t done = 0; // 完了処理番号
#define MAX_BYTE 800 // 800バイトで安定している
const char *server_aws = "xxx.xxx.xxx.xxx"; // TCP接続先サーバーIPアドレス
int resflag;
byte data[MAX_BYTE];
void setup() {
while(!Serial);
// ボーレート設定
Serial.begin(baudrate);
delay(3000);
Serial.println("Ready.");
// 3GIM初期化
if (a3gs.start() == 0 && a3gs.begin(0, baudrate) == 0) {
Serial.println("ok");
delay(15000); // 電波安定までウェイトをかませる
} else {
// 接続失敗
Serial.println("3Fin");
}
// sdカード初期化
Serial.print("SDカード初期化 ...");
if (!SD.begin(chipSelect)) {
Serial.println("SDカード初期化失敗!");
return;
}
// 待ち1秒
delay(1000);
// スタート処理開始
startAction();
}
// スタート処理
void startAction()
{
// 念のため一旦TCP切断しておく
a3gs.disconnectTCP();
// TCPサーバー接続
do {
resflag=0;
done = 0;
// TCPサーバー接続 お好きなポート番号を指定しましょう
resflag = a3gs.connectTCP(server_aws, xxxxxxx);
if (resflag == 0) {
Serial.println("TCP connect OK");
// 読み取り開始
done = 1;
} else {
Serial.print("TCP 接続失敗");
}
} while(resflag != 0);
}
void loop()
{
if (done >= 3) {
// 30秒待ってから再度カメラ画像取得する
Serial.println("wait Time!");
delay(30000);
Serial.println("re start!");
startAction();
}
if (done == 1) {
// ファイル読み込み
myFile = SD.open("test.jpg");
if (myFile) {
EndFlag=0;
while(!EndFlag)
{
int ii=0;
while(myFile.available())
{
// 800バイトずつ読み込む
if((ii < MAX_BYTE)&&(!EndFlag)) {
readingbyte=myFile.read();
data[ii]=readingbyte;
if((data[ii-1]==0xFF)&&(data[ii]==0xD9)) EndFlag=1; // ファイルの終了チェック
ii++;
}
// 既定バイト数読み込み終わった or 全ファイル読み取り終わった
if ((ii == MAX_BYTE) || EndFlag) {
// TCPサーバーに書き込み処理開始
a3gs.writeBegin(sizeof(data));
a3gSerial.write((uint8_t*) data, sizeof(data));
delay(50);
ii = 0;
memset(data,' ',sizeof(data));
// 画像ファイル読み取り終了確認
if (EndFlag) {
Serial.println("画像読み取り終了!");
myFile.close();
do {
resflag=0;
// TCP処理終わらせる
a3gs.write("exit");
delay(5);
// TCP切断する
resflag = a3gs.disconnectTCP();
if (resflag == 0) {
Serial.println("disconnect OK");
} else {
Serial.print("disconnect Failed! ");
Serial.print(resflag);
Serial.println(res);
}
} while(resflag != 0);
done = 2;
break;
}
}
}
}
}
} else if (done == 2) {
Serial.println("ALL Fin.");
done = 3;
return;
}
}
#サーバーの処理
3GIMから送信されたデータを受け取るための処理をPHPで実装します。
今回はAWSに仮想サーバーを設置し、そこにPHPをインストールしました。
AWSのEC2にPHPで動くTCPサーバーを構築TCPサーバーはxinetd
を使用しました。
http://rys.hatenablog.com/entry/2012/12/03/php-tcp-server
<?php
$test_file="/var/www/html/test.jpg";
$stdin = fopen('php://stdin','r');
if (is_file($test_file)===TRUE) {
unlink($test_file);
}
touch($test_file);
while (true) {
$img = fgets($stdin);
$buffer = trim($img);
if ('exit' === $buffer) {
// exitが来たら終了する
break;
}
file_put_contents($test_file, $img, FILE_APPEND);
}
?>
#まとめ
とても簡単に3GIMから画像をアップロードすることが出来ました。
監視カメラ等で利用出来るシーンがあると思います。