できること

第55回 SORACOM Air×3GIMによるArduinoの3G通信 その3~センサ評価キットと組み合わせてデータロガー作成

DSC_0073-2

前回、3GIMからサーバー側にデータを送信することができましたので、今回は以前利用したセンサ評価キットで実際にデータを取得して、それをサーバーに溜めていく「簡易データロガー」を作成してみます!

目次

  1. センサ評価キットとArduinoでデータを取得
  2. 取得したデータをサーバーに送信
  3. グラフ化してみる
  4. まとめ

1. センサ評価キットとArduinoでデータを取得

今回データロガーを作成するために、センサ評価キットのセンサは「第43回 複数のセンサを組み合わせた照明デバイス制作に挑戦!」で利用した気圧センサと温度センサを利用してみます。

写真1 ロームセンサ評価キット

写真1 ロームセンサ評価キット

第43回では温度センサ、気圧センサ、カラーセンサを搭載していますが、今回はカラーセンサを取り外して使います。ちなみに気圧センサと温度センサの電圧は3Vなので、センサ評価キットの電圧を決めるジャンパピンは3Vで設定します。

写真2 第43回では気圧センサとカラーセンサ、温度センサを搭載

写真2 第43回では気圧センサとカラーセンサ、温度センサを搭載

温度センサ・気圧センサの取得プログラムは下記のとおりです。

Code-Example
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <Wire.h>
#include <BD1020.h> //温度センサ用
#include <BM1383GLV.h> //気圧センサ用
 
BM1383GLV bm1383;//温度センサ用
int tempout_pin = A2; //温度センサ用ピン設定
BD1020 bd1020; //気圧センサ用
 
void setup() {
 
Serial.begin(9600);
while (!Serial);
 
//温度センサ用
bd1020.init(tempout_pin);
Serial.println("BD1020HFV Sample");
 
//気圧センサ用
byte rc;
Wire.begin();
rc = bm1383.init();
 
}
 
void loop() {
 
//************************************
//温度センサ用
//************************************
float temp;
bd1020.get_val(&temp);
Serial.print("BD1020HFV Temp=");
Serial.print(temp);
Serial.print(" [degrees Celsius], ADC=");
Serial.println(bd1020.temp_adc);
 
delay(500);
 
//************************************
//気圧センサ用
//************************************
byte rc;
float press;
 
rc = bm1383.get_val(&press);
if (rc == 0) {
Serial.write("BM1383GLV (PRESS) = ");
Serial.print(press);
Serial.println(" [hPa]");
Serial.println();
}
delay(500);
}

 

図1 気圧と温度が表示

図1 気圧と温度が表示

気圧と温度が正常に取得できていることが確認できたら、次はこのプログラムと3GIMの通信処理部分を組み合わせてみます。

 

2. 取得したデータをサーバーに送信

センサから取得したデータをサーバーに送信する部分を実装していきます。まず、回路に関してはセンサ評価キットシールドをArduinoの上に搭載したので、それを考慮しながら3GIMの配線をする必要があります。といっても、基本的にピン番号などは変える必要がないので、そのままArduinoに対応するセンサ評価キットのピン番号に配線すれば大丈夫です。

写真3 Arduinoの上にセンサ評価キットシールドを載せて、3GIMと接続

写真3 Arduinoの上にセンサ評価キットシールドを載せて、3GIMと接続

データを送信するプログラムは、前回のものをベースにして、データロガー自体の処理の流れとしては

  1. 各種センサから値を取得
  2. データを送信
  3. 一定時間待ってループ(1へ戻る)

となります。これを基本にして、センサの種類を増やしたり、データの送信部分を改良したり拡張を考えていくのがよいと思います。

 

センサデータ送信プログラム

Code-Example
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
// 3GIM(V2) sample sketch -- httpGET
#include <SoftwareSerial.h>
#include "a3gim.h"
#include <Wire.h>
#include <BD1020.h> //温度センサ用
#include <BM1383GLV.h> //気圧センサ用
 
BM1383GLV bm1383;//温度センサ用
int tempout_pin = A2; //温度センサ用ピン設定
BD1020 bd1020; //気圧センサ用
 
SoftwareSerial Serial3g(4,5);
 
#define baudrate 9600UL
const int powerPin = 7; // 3gim power pin(If not using power control, 0 is set.)
const char *server = "deviceplus.jp";
const char *path = "";
int port = 80;
char res[a3gsMAX_RESULT_LENGTH+1];
int len;
 
String imei = "";
int rssi = 0;
float lat = 0;
float lng = 0;
int height = 0;
int utc = 0;
int number = 0;
int quality = 0;
String date = "";
 
// setup AGPS function
void setupAGPS()
{
char apn[20], user[20], password[20];
if (a3gs.getDefaultProfile(apn, user, password) == 0) {
char atwppp[50];
sprintf(atwppp,"at+wppp=2,4,\"%s\",\"%s\"",user,password);
Serial.println(atwppp);
a3gs.enterAT(2);
a3gSerial.println(atwppp);
delay(200);
Serial.println("Assisted GPS set OK");
}
else
Serial.println("NG: getDefaultProfile(), can't use AGPS..");
}
 
void setup()
{
Serial.begin(baudrate);
Serial3g.begin(38400);
 
delay(3000); // Wait for Start Serial Monitor
Serial.println("Ready.");
//温度センサ用
bd1020.init(tempout_pin);
Serial.println("BD1020HFV Sample");
 
//気圧センサ用
byte rc;
Wire.begin();
rc = bm1383.init();
 
}
 
void loop()
{
//************************************
//1.センサからデータを取得する
//************************************
 
//温度センサのデータを取得
float temp;
bd1020.get_val(&temp);
Serial.print("BD1020HFV Temp=");
Serial.print(temp);
Serial.print(" [degrees Celsius], ADC=");
Serial.println(bd1020.temp_adc);
 
delay(500);
 
//気圧センサのデータを取得
byte rc;
float pressure;
 
rc = bm1383.get_val(&pressure);
if (rc == 0) {
Serial.write("BM1383GLV (PRESS) = ");
Serial.print(pressure);
Serial.println(" [hPa]");
Serial.println();
}
delay(500);
 
//************************************
//2.3GIMでデータをサーバーに送信
//************************************
Serial.print("Initializing.. ");
if (a3gs.start(powerPin) == 0 && a3gs.begin(0, baudrate) == 0) {
Serial.println("Succeeded.");
 
delay(25000); // ウェイトを持たせる
Serial.println("httpGET() requesting.. ");
len = sizeof(res);
 
//***************************************************
//get rssi
//***************************************************
if (a3gs.getRSSI(rssi) == 0) {
Serial.print("RSSI = ");
Serial.println(rssi);
if(rssi > 0 || rssi <= -113 ){
//電波強度が取得できない場合は最初から
Serial.println("retry.");
return;
}
}
else{
//電波強度が取得できない場合は最初から
Serial.println("retry.");
return ;
}
 
//***************************************************
//get imei
//***************************************************
char imei[a3gsIMEI_SIZE];
if (a3gs.getIMEI(imei) == 0) {
Serial.print("IMEI: ");
Serial.println(imei);
}
//***************************************************
//get time
//***************************************************
char date[a3gsDATE_SIZE], time[a3gsTIME_SIZE];
if (a3gs.getTime(date, time) == 0) {
Serial.print("DATE:");
Serial.print(date);
Serial.print(" ");
Serial.println(time);
}
 
//***************************************************
//GPS-location
//***************************************************
setupAGPS();
char lat[15], lng[15], utc[7], height[8];
if (a3gs.getLocation2(lat, lng, height, utc, &quality, &number) == 0) {
Serial.print("OK: ");
Serial.print(lat);
Serial.print(",");
Serial.print(lng);
Serial.print(",");
Serial.print(height);
Serial.print(",");
Serial.print(utc);
Serial.print(",");
Serial.print(quality);
Serial.print(",");
Serial.println(number);
}
 
String pathStr = "/api.php?imei=";
String tempS = String(temp); //温度センサの値
String pressureS = String(pressure); //気圧センサの値
String imeiS = String(imei);
String rssiS = String(rssi);
String latS = String(lat);
String lngS = String(lng);
String utcS = String(utc);
String qualityS = String(quality);
String numberS = String(number);
String heightS = String(height);
String dateS = String(date);
String timeS = String(time);
 
pathStr = pathStr+imeiS+"&rssi="+rssiS+"&rssi="+tempS+"&="+pressureS+"&utc="+utcS+"&lat="+latS+"&lng="+lngS+"&quality="+qualityS+"&number="+numberS+"&height="+height+"&datetime="+dateS+"%20"+timeS;
 
int rst = a3gs.httpGET(server, port, pathStr.c_str(), res, len);
 
Serial.print("URL:");
Serial.println(server);
Serial.println("");
Serial.print("PATH:");
Serial.println(pathStr);
 
Serial.print("RESULT:");
Serial.println(rst);
if (rst == 0) {
Serial.println("OK!");
Serial.print("[");
Serial.print(res);
Serial.println("]");
}
else {
Serial.print("Can't get HTTP response from ");
Serial.println(server);
}
}
else{
Serial.println("Failed.");
}
Serial.println("Shutdown..");
a3gs.end();
a3gs.shutdown();
}
 
// END

 

図2 温度センサと気圧センサの値を送信

図2 温度センサと気圧センサの値を送信

 

シリアルモニタで正常に送信できていることが確認できました。ただ、今回コンパイルをした際に「スケッチで使用できるメモリが少なくなってしまっています。動作が不安定になる可能性があります」との表示がArduinoのソフトウェアに表示されました。

10851711163c8349f328d1648b8086d7

プログラムが処理が多くArduino内のメモリが少なくなると、Arduinoの実行時にメモリを多く使う処理などが走った際にArduinoが正常に動作しなくなってしまう可能性があります。このような場合は、メモリの多い別のArduinoを利用するか、無駄な処理をできるだけ削除してメモリを軽くするかどちらかの対策をとると良いです。

 

3. グラフ化してみる

せっかくなので、前回は表で表示するだけだったサーバー側も、少し手を加えてグラフで表示してみます。サーバーサイドでの表示は、プログラムや方法がいろいろあるので、自分がやりやすい方法を選択してもらえればよいのですが、手軽にグラフを表示できるサービスとして、Google Chartsを今回使ってグラフ化してみました。Google Chartsはjavascriptでシンプルな表記で様々な種類のグラフを表示することができるので、簡単にデータを表示したい場合などに適しています。

 

図3 Google Charts

図3 Google Charts

Google Chartsのページで紹介されているサンプルコードを見ていただくとわかるのですが、javascriptのプログラム部分に表示したいデータやグラフの設定を行い、表示したいタグのIDを指定することでグラフの表示が可能です。

実際に取得した気圧、温度をグラフにしたのが下記の図です。

図4 気圧・温度をグラフで表示

図4 気圧・温度をグラフで表示

グラフで表示されるとわかりやすくなりますね(今回の例ではあまり変動がありませんでしたが)。

 

まとめ

簡易的ですがデータロガーが完成しました。これでいつでも好きな場所でセンサデータを取得できるようになりましたが、まだ大きな課題が残されています。それはやはり「電源」。常時データロガーをオンにしておくと、電源が常に必要になってしまい、せっかく3G通信でどこでも通信できても電源の確保が必要になってしまいます。次回はデータロガーの電源周りの対策について考えてみます。

 

■関連記事

SORACOM Air×3GIMによるArduinoの3G通信〜センサ評価キットと組み合わせてデータロガー作成(3)
SORACOM Air×3GIMによるArduinoの3G通信〜Arduinoで3G通信をする方法(2)

SORACOM Airを使ってArduinoで通信できる?~Arduinoで3G通信をする方法(1)
ラズベリーパイとSORACOM Airでインターネット接続!(1)登録編

アバター画像

電子工作や新しいデバイスをこよなく愛するエンジニア。日常生活のちょっとしたことを電子工作で作って試して、おもしろく過ごしたいと日々考えています。

高専ロボコン2016 出場ロボット解剖計画