IchigoJam+BME280で気温、気圧、湿度をロギング

IchigoJamで部屋の気温のログを取得して
暖房効率を見える化したいなー

と思い、昨年末に[BME280](https://www.amazon.co.jp/gp/product/B01M98R905)というセンサーを購入。

買ってから気づいてしまったが、このセンサー
ネット上にIchigoJamでの使用例が存在しない orz

わりと苦労したけど、できたので、やりかたを共有します。
あまり詳しくないので、まちがいあればご指摘ください。

## 方針

IchigoJamだけでやらない。
（できなかったので、あきらめた）

IchigoJamでBME280からレジスタ値を読み出し、
レジスタ値をサーバプログラム(Python)に送って、
サーバプログラムで気温、気圧、湿度を計算する。

## 前提

サーバとHTTP通信するので、MixJuice等のWifiモジュールが必要。
私は~~互換の~~MJ POSTが使える[Web Term](https://blog.goo.ne.jp/roboz80/e/3edd6daf7bc0ae16eb38770667d71f89)を使用しました。

## 参考にした資料

* http://www.ne.jp/asahi/o-family/extdisk/BME280/BME280_DJP.pdf
* https://github.com/SWITCHSCIENCE/samplecodes/blob/master/BME280

## IchigoJamとの接続

BME280側　⇔　IchigoJam側
VCC ⇔　VCC
GND ⇔　GND
SCL ⇔　SCL
SDA ⇔　SDA
CSB ⇔　接続しない
SDO ⇔　GND

## IchigoJam側のプログラム

954 Byte
https://gist.github.com/kinumi/a33bc034b63056fec1196e4ac27d264a

自由に使ってください。
動作保証はないです。


### 解説

```
10 X=1
20 Y=10
30 Z="example.com"
```

パラメータ設定

Xは、IchigoJamの番号
複数台のIchigoJamで複数の部屋の気温をはかりたいときに、サーバ側で区別するために使う。

Yは、測定インターバル(秒)

Zは、サーバーのアドレス

```
110 GSB@SETUP
120 ?"MJ POST START ";STR$(Z)
130 ?X
140 GSB@CARIB
150 FORI=0TO31:?PEEK(#800+I):NEXT
160 GSB@DATA
170 FORI=0TO7:?PEEK(#800+I):NEXT
180 ?"MJ POST END"
190 WAIT Y*60
999 GOTO120
```

110行目`GSB@SETUP`で、BME280の設定レジスタに設定値を書き込みます。

120行目〜180行目 HTTP POST。
POSTするデータは以下。

1.IchigoJamの番号(パラメータX) 10進数
2.BME280の調整データ 32バイト分 16進数 (`GSB@CARIB`で読み出し)
3.BME280の測定データ 8バイト分 16進数 (`GSB@DATA`で読み出し)

190〜200行目 測定インターバルのWAIT、ぐるぐる回す

```
1010 @I2CR
1020 [101]=I2CR(#76,#8C6,1,#8C8,1)
1999 RETURN

2010 @I2CW
2020 [101]=I2CW(#76,#8C6,1,#8C8,1)
2999 RETURN
```

こいつらは、`I2CR`、`I2CW`をかんたんに呼び出すためだけに定義。

```
3010 @SETUP
3020 A=#8C6:B=#8C8:C=0
3030 POKEA,#F2:POKEB,`00000101:GSB@I2CW
3040 POKEA,#F4:POKEB,`10110111:GSB@I2CW
3050 POKEA,#F5:POKEB,`10100000:GSB@I2CW
3999 RETURN
```

設定レジスタ書き込み。
何も考えずにオーバーサンプリングx16
(資料読んでもよくわからんかった)

```
4010 @CARIB
長いので略
```

BME280の調整レジスタを順番に読み出して
IchigoJamのメモリアドレス#800から順々に書き込んでます

```
5010 @DATA
5020 A=#8C6:B=#8C8:C=0
5030 POKEA,#F3:GSB@I2CR
5040 IF PEEK(B)&`00001000!=0 GOTO5030
5050 FOR I=0 TO 7
5060 POKEA,#F7+I:GSB@I2CR
5070 POKE#800+I,PEEK(B)
5080 NEXT
5999 RETURN
```

5030行目〜5040行目で、測定完了を待ってます
あとはBME280の測定結果のレジスタを順番に読み出して
IchigoJamのメモリアドレス#800から順々に書き込んでます

## サーバ側のプログラム (Python)

https://gist.github.com/kinumi/15a6fbdb7ac1ab634f4e81e50e61426c

`bme280.py`のロジックは、スイッチサイエンスのサンプルをほぼほぼ流用してます。
よって再利用はスイッチサイエンスのライセンス(MIT)に従います。
https://github.com/SWITCHSCIENCE/samplecodes/blob/master/LICENSE


```python:app.pyより抜粋
@app.route('/', methods=["POST"])
def post():
    post_data = request.get_data().splitlines()
    post_data = list(map(lambda x: int(x), post_data))
    ijid = post_data[0]
    calib = post_data[1:1+32]
    data = post_data[1+32:1+32+8]
    bme280 = BME280()
    bme280.setCalib(calib)
    bme280.setData(data)
    return 'done.'
```

`post_data`がIchigoJamから送られてきたデータです
改行区切りのテキストデータなので、改行で分割して数値変換してます

0番目がIchigoJamの番号(`ijid`)
1番目〜32番目が調整データ(`calib`)
33番目〜40番目が測定データ(`data`)

これらのデータをBME280クラスにぶちこんで計算してます

## 動作例

こんなかんじで、気温、気圧、湿度が測定できます。
あとはDBにいれたりグラフを描いたり、自由自在！

```
$ python app.py 
 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
temp : 10.32  ℃
pressure : 1013.46 hPa
hum :  62.86 ％
127.0.0.1 - - [19/Jan/2020 14:37:34] "POST / HTTP/1.0" 200 -
temp : 10.32  ℃
pressure : 1013.47 hPa
hum :  62.83 ％
127.0.0.1 - - [19/Jan/2020 14:37:45] "POST / HTTP/1.0" 200 -
temp : 10.32  ℃
pressure : 1013.44 hPa
hum :  62.77 ％
127.0.0.1 - - [19/Jan/2020 14:37:54] "POST / HTTP/1.0" 200 -
temp : 10.32  ℃
pressure : 1013.46 hPa
hum :  62.84 ％
127.0.0.1 - - [19/Jan/2020 14:38:05] "POST / HTTP/1.0" 200 -
temp : 10.32  ℃
pressure : 1013.46 hPa
hum :  62.92 ％
```