ATmega328PとBME280でポータブル温湿度気圧計を作ってみた

![implemented](https://qiita-image-store.s3.amazonaws.com/0/30370/f3e27863-bb11-d62c-d8b3-3864f6990eb0.jpeg)

先日、秋月電子からお手軽な [**3.3V昇圧DCDCコンバータ**](https://akizukidenshi.com/catalog/g/g113066) の発売を知り、せっかくの三連休だったのでこれを利用して、単4電池1本と Arduino のスケッチで動く **ポータブル温湿度気圧計** を作ってみました。

# 機能と特徴

- 温度 (℃)、湿度 (%)、気圧 (hPa) が LCD に表示、約3秒間隔で更新
- 単4電池 または 単3電池 1本のみで駆動
- 手に載せられる大きさのブレッドボード1枚分のコンパクト仕様
- 抵抗、コンデンサ、クリスタルを別途接続する必要はなく、各モジュールを結線するだけで組み立て可

# 必要な部品

すべて秋月電子などで購入できます。

| 部品名 | リンク | 備考 |
|---|---|---|
| ブレッドボード | [URL](https://akizukidenshi.com/catalog/g/g100315) | 400穴タイプがベスト |
| 電池ボックス | [URL](https://akizukidenshi.com/catalog/g/g102670) | 単4x1 ピンタイプ。単3でも可 |
| 電池| | 単4形乾電池。二次電池 (定格1.2V) でも動作可 |
| ATmega328P-PU | [URL](https://akizukidenshi.com/catalog/g/g103142) | 内蔵 8MHz を使用 |
| 3.3V出力昇圧DCDCコンバータ | [URL](https://akizukidenshi.com/catalog/g/g113066) | 3端子として使用 |
| 温湿度気圧センサ BME280 | [URL](https://akizukidenshi.com/catalog/g/g109421) | I<sup>2</sup>C として使用 |
| 小型キャラクタLCDモジュール | [URL](https://akizukidenshi.com/catalog/g/g108896) | |

下記3つのモジュールは、組み立てに はんだ付けが必要です。また、

- 温湿度気圧センサ AE-BME280 は I<sup>2</sup>C で接続するため、**J3, J1, J2 を全て** はんだブリッジでショートさせてください。
  - はんだブリッジの意味は [**こちら**](https://qiita.com/nanase/items/f34e03c29410add9c4d0#ae-bme280%E3%81%AE%E3%81%AF%E3%82%93%E3%81%A0%E3%82%B8%E3%83%A3%E3%83%B3%E3%83%91%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6) をご覧ください
- LCD のプルアップ抵抗 (10kΩ) のための はんだブリッジは不要です。
  - 代わりに AE-BME280 側の抵抗 (4.7kΩ)でプルアップさせます
- ATmega328P で動作させるためには書き込み装置が必要です（後述）。

|![bme280](https://qiita-image-store.s3.amazonaws.com/0/30370/cf2af534-49ba-b496-d8a3-8fbd1d11375b.jpeg)|![xcl102d333cr-g](https://qiita-image-store.s3.amazonaws.com/0/30370/af1157f7-aa56-a5d3-16a4-dc46d34bbeef.jpeg)|![aqm1602xa-rn-gbw](https://qiita-image-store.s3.amazonaws.com/0/30370/943cb135-0acc-8396-f4df-825f83e6f9f0.jpeg)|
|:---:|:---:|:---:|
|**温湿度気圧センサ**<br />AE-BME280|**3.3V昇圧DCDCコンバータ**<br />AE-XCL102D333CR-G|**I<sup>2</sup>C接続小型キャラクタLCD**<br />AQM1602XA-RN-GBW|

# 回路と配線

|![schematic](https://qiita-image-store.s3.amazonaws.com/0/30370/14e4ea7f-4b5c-f233-ae23-ccb9ffbd8a64.png)|![wiring](https://qiita-image-store.s3.amazonaws.com/0/30370/f91c1555-2cfb-c798-19b8-8349eaeb3996.jpeg)|
|:---:|:---:|
|回路図|ブレッドボードに配線と ATmega328P のみを配置した図|

電池と ATmega328P と各モジュールを接続するだけです。追加の抵抗もコンデンサも必要ありません。ATmega328P のクロックには内蔵 8MHz を使用するため、クリスタルも必要ありません。

前述の通り、I<sup>2</sup>C のプルアップ抵抗は AE-BME280 に搭載されている 4.7kΩ を使用します。
また、DCDCコンバータのデータシートによると 1.5V → 3.3V の変換で、最大 130mA しか電流が取り出せませんが、下記の通り十分に供給可能です。

| 部品 | 消費電流 | 条件 |
|---|---:|---|
| ATmega328P | 約 3.2 mA | 活動時かつ内蔵 8 MHz 使用時
| AE-BME280 | 0.0036 mA | 測定時 |
| プルアップ抵抗 | 1.4 mA | 4.7kΩ x2 |
| AQM1602XA-RN-GBW | 1.0 mA | |
| **計** | **約 5.6 mA** |

ブレッドボード片側の電源用レーンは今回使わないため、取り外してもう片方に装着させます。配線は必要ありませんが、LCD の保持のため装着しています。
電池ボックスのピンはマイナス側を j-23、プラス側は j-6 (単4電池使用時) または j-3 (単3電池使用時) に挿入します。

# スケッチ

BME280 用のライブラリを [GitHubのリポジトリ](https://github.com/sparkfun/SparkFun_BME280_Arduino_Library) から入手してインストールしておきます。

このライブラリではデフォルトで I<sup>2</sup>C 使用、各センサ測定が有効になっていますが、I<sup>2</sup>C アドレスのみ `0x77` になっているため、`0x76` を設定しておきます。
LCD の実装はデータシートに記載されているものを使っています。ただし、LCD の電圧は 3.3V を指定しています。

```c++:PortableObservator.ino
#include "SparkFunBME280.h"
#include <Wire.h>

#define LCD_ADDRESS 0x3E
#define BME280_ADDRESS 0x76
#define decimal_1(num) ((int)((num - (int)num) * 10))

BME280 Sensor;

void setup() {
  Wire.begin();
  init_LCD();

  // I2C Address 0x77 (default) -> 0x76
  Sensor.settings.I2CAddress = BME280_ADDRESS;
  Sensor.begin();
}

void loop() {
  char buffer[17];
  float temp, humi, press;
  static int8_t dot = -1;

  if (dot < 2) {
    dot++;
  } else {
    dot = 0;
    temp = Sensor.readTempC();
    humi = Sensor.readFloatHumidity();
    press = Sensor.readFloatPressure() / 100.0;

    setCursor(0, 0);
    sprintf(buffer, "%3d.%d%cC %3d.%d %% ", (int)temp, decimal_1(temp), '\xf2',
                                            (int)humi, decimal_1(humi));
    setLineChars(buffer);

    setCursor(1, 0);
    sprintf(buffer, " %4d.%d hPa     ", (int)press, decimal_1(press));
    setLineChars(buffer);
  }

  for (uint8_t i = 0; i <= dot; i++) {
    setCursor(1, 12 + dot);
    writeData('.');
  }

  delay(1000);
}

void setLineChars(char* buffer) {
  for (uint8_t i = 0; i < 16; i++)
    writeData(buffer[i]);
}

void setCursor(uint8_t line, uint8_t pos) {
  writeCommand(0x40 * line + pos + 0x80);
}

void writeData(byte t_data) {
  Wire.beginTransmission(LCD_ADDRESS);
  Wire.write(0x40);
  Wire.write(t_data);
  Wire.endTransmission();
  delay(1);
}

void writeCommand(byte t_command) {
  Wire.beginTransmission(LCD_ADDRESS);
  Wire.write(0x00);
  Wire.write(t_command);
  Wire.endTransmission();
  delay(10);
}

void init_LCD() {
  delay(100);
  writeCommand(0x38);
  delay(20);
  writeCommand(0x39);
  delay(20);
  writeCommand(0x14);
  delay(20);
  writeCommand(0x73);
  delay(20);
  writeCommand(0x56);  // <- for 5V = 0x52, 3.3V = 0x56
  delay(20);
  writeCommand(0x6C);
  delay(20);
  writeCommand(0x38);
  delay(20);
  writeCommand(0x01);
  delay(20);
  writeCommand(0x0C);
  delay(20);
}
```

# ATmega328Pへの書き込み

![writer](https://qiita-image-store.s3.amazonaws.com/0/30370/5f2f9841-2a45-c1f2-b88c-176a5a34cf1a.jpeg)

デバッグには Arduino Nano を使用していましたが、ATmega328P の使用には別途 書き込み装置が必要です。
書き込み装置の詳細は参考文献にて解説されているので省略しますが、今回は内蔵 8MHz をクロックとして使うため、以下の手順で書き込みを行いました。

1. [公式サイト](https://www.arduino.cc/en/Tutorial/ArduinoToBreadboard) から breadboard-1-6-x.zip をダウンロードして ArduinoIDE が認識するディレクトリに展開する。
2. Arduino Nano と ATmega328P を結線し、ATmega328P に 16MHz のクリスタルとコンデンサを接続する。
3. Arduino Nano に ArduinoISP のスケッチを書き込む。
4. ArduinoIDE 上にて、書き込み装置を **Arduino as ISP**、ボードを **ATmega328 on a breadboard (8 MHz internal clock)** としてブートローダを書き込む。
5. 「書き込み装置を使って書き込む」で PortableObservator.ino を ATmega328P に書き込む。

4\. のブートローダを書き込んだ時点で内蔵 8MHz が使われます。上記写真ではクリスタルの配線を抜いていますが、抜かなくても 5. は実行できるかもしれません（未検証）。

今回自作の書き込み装置に使った部品は下表の通りです。Arduino は他種でも可能です。LED と 抵抗は活線確認用のため省略します。

| 部品名 | リンク | 備考 |
|---|---|---|
| ブレッドボード | [URL](https://akizukidenshi.com/catalog/g/g100285) | 板・端子付き、ジャンパが付属 |
| Arduino Nano | [URL](https://akizukidenshi.com/catalog/g/g109059) | |
| miniUSB ケーブル | | Arduino Nano 接続用 |
| クリスタル | [URL](https://akizukidenshi.com/catalog/g/g108671) | 16MHz。[セラロック](https://akizukidenshi.com/catalog/g/g100525/) も可 |
| 積層セラミックコンデンサ | [URL](https://akizukidenshi.com/catalog/g/g108094/) | 22pF。セラロック使用時は不要

# 最後に

![implemented](https://qiita-image-store.s3.amazonaws.com/0/30370/8847bf53-a549-2f3b-7e4c-0b438229528a.jpeg)

乾電池1本で動作する利点は大きく、たとえば屋外に持ち出したり、ブレッドボード裏の両面テープを使って自宅の壁に設置したりと活用の幅が広がりそうです。

ただし、はんだ付け、ATmega328P への書き込みのために初期投資が必要です。温湿度気圧計 本体の価格は 2,400円 前後ですが、書き込み装置や はんだ用品をゼロから揃えると +5,000円 ほどかかってしまいます[^writer] [^writer2]。

また、今回は Arduino のスケッチを使用したいがためにポピュラーかつ標準的な ATmega328P を使いました。リソース的にはかなり余裕があるため、さらに廉価で小型のマイコンICを使用できるかもしれません。

## 参考文献

- [ATmega328/328P データシート (PDF)](https://avr.jp/user/DS/PDF/mega328P.pdf)
- [Ｉ２Ｃ接続小型キャラクタＬＣＤモジュール データシート (PDF)](https://akizukidenshi.com/download/ds/xiamen/AQM1602_rev2.pdf)
- [3.3V 出力昇圧 DCDC コンバータ データシート (PDF)](https://akizukidenshi.com/download/ds/akizuki/AE-XCL102D333CR-G_20180517.pdf)
- [[I<sup>2</sup>C] 温湿度大気圧センサー (BME280)](https://ht-deko.com/arduino/i2c_bme280.html)
- [【ArduinoIDE1.8.x】ATmega328PでArduinoを作る(内蔵8MHz使用)](https://teppodone.hatenadiary.jp/entry/ArduinoIDE1.8.5_8MHz_internalClock_ATmega328P)
- [arduinoを最小構成で自作する(atmega328/8MHz/3.3V/内部クロック)](https://portaltan.hatenablog.com/entry/2018/01/04/132617)

[^writer]: ATmega328P を取外し可能な Arduino Uno であれば、Arduino Uno 単体を書き込み装置として使用でき、はんだ用品を除いて +3,200円 程度の費用で済むと思われます。ただし IC の付け替え作業の煩雑さや、Arduino Uno 一台を丸々書き込み装置として潰してしまう側面もあります。
[^writer2]: [FT232RL](https://akizukidenshi.com/catalog/g/g106693) を使って書き込みを行う方法もあり、この場合は はんだ用品を除いて +1,500円 程度で済みます。