ESP-WROOM-02 と Arduino を通信させる

なにするの?

今回は、ESP-WROOM-02 と、Arduino で通信をさせてみたいと思います。Arduino で測定した気温を i2c を使って ESP-WROOM-02 で受信します。受信した内容を PC からシリアルポート経由で確認します。 ESP-WROOM-02 を使う理由は、安価で、 Arduino IDE を使ってプログラムが書き込め、wifiに接続ができるからです。(もっと新しくていいデバイスがでているかも、、)

使用機材

こちらの紹介は hinohika.hatenablog.com で行なっています。

  • ESP-WROOM-02
    こちらを使用しました。Arduino IDE からのプログラムの書き込みが USB ケーブルを挿すだけでできるので楽です。

    ESPr Developer(ピンソケット実装済)

    ESPr Developer(ピンソケット実装済)

    • スイッチサイエンス(Switch Science)
    Amazon

  • Micro USB ケーブル
    ESP-WROOM-02 に接続するには Micro USB ケーブルが必要です。 百均にも売っているので準備してください。
    ※ 注意 百均で売っているケーブルには、充電のみが可能なものと、データの送受信も可能なものの2種類が存在します。購入の際にはデータの送受信もできるケーブルであることを確認してください。

回路図

ブレッドボードを使って Arduino と気温センサー、液晶ディスプレイと ESP-WROOM-02 を次のように繋ぎます。右下の小さい基盤が ESP-WROOM-02 です。USB Hub を使って、ArduinoESP-WROOM-02 を同時にPCへ接続しています。

全体図

全体回路

ESP-WROOM-02 の接続先

全体図ではわかりにくいので ESP-WROOM-02 の配線をアップにしました。基盤に 5 と書かれている端子からSCLにつながるように(下図 オレンジの線)、基盤に 4 と書かれている端子から SDA につながるように(下図 白の線)接続してください。

作業

Arduino UNO に必要な作業

コードの修正を行います。 今回使用したプログラムは下記のプログラムです。 Arduino IDE から Arduino に書き込みを行ってください。

#include <LiquidCrystal_I2C.h>   // ライブラリのインクルード

#define LCD_COLS 20
#define LM75B_ADDR 0x4A

LiquidCrystal_I2C lcd(0x27, LCD_COLS, 4); 

signed int raw_temperature;
  
double get_temperature(int addr){
  signed int message;
  double temp;
  Wire.requestFrom(addr,2);
  message  = (Wire.read() << 8);
  message |= Wire.read();
  raw_temperature = message;
  temp = ((message >> 5) & 0x3FF) * 0.125;
  return temp;
  }

void receiveEvent(){
  byte data[2];
  data[0] = raw_temperature >> 8;
  data[1] = raw_temperature;
  Wire.write(data,2);
  }
 
void setup() {
  // put your setup code here, to run once:
   lcd.init();                    // LCDの初期化
   lcd.backlight();               // LCDバックライトの点灯
   lcd.setCursor(0, 0);           // カーソルの位置を指定
   lcd.print("Room Temperature");      // 文字の表示
   Wire.begin(0x51);
   Wire.onRequest(receiveEvent);
}

void loop() {
  // put your main code here, to run repeatedly:
  double temp;
  temp = get_temperature(LM75B_ADDR);
  lcd.setCursor(0,2);
  lcd.print(temp);  
  delay(5000);
}

ESP-WROOM-02 に必要な作業

esp8266 用の拡張モジュールのインストール

Arduino IDEESP-WROOM-02 用のプログラムの作成、書き込みを行うために必要な拡張モジュールのインストールを行います。

画面上のメニューバーから ツール > ボード > ボードマネージャー をクリックします。

ボードマネージャの開き方

esp8266と検索すると今回使用する拡張モジュールが表示されます。インストールボタンを押し、インストールを行います。

ボードマネージャー

インストールが完了すると ツール > ボード に表示される項目に "ESP8266 Boards (2.7.4)" が追加されているはずです。

ツール > ボード > ESP8266 Boards > Generic ESP8266 Module を選択します。

ボード設定は以下のような設定にしています。

ボード設定

ESP-WROOM-02 へのプログラムの書き込み

ESP-WROOM-02 側は下記のプログラムを使用しました。

#include <Wire.h>
#define ARDUINO_ADDR 0x51

void setup() {
  Serial.begin(115200);  // start serial for output
  Wire.begin();        // join i2c bus (address optional for master)
}

void loop() {
  signed int message;
  double temp;

  Wire.requestFrom(ARDUINO_ADDR, 2);
  while (Wire.available()) { 
    message  = (Wire.read() << 8);
    message |= Wire.read();
    temp = ((message >> 5) & 0x3FF) * 0.125;
  }
  Serial.println(temp);
  delay(5000);
}

ツール > シリアルポートから "/dev/cu.usbserial-****" というポートを選択し書き込みます。****の内容は環境によって異なる可能性があります。それっぽいものを選択してください。

Mac で書き込みを行おうとすると

pyserial or esptool directories not found next to this upload.py tool.
スケッチの書き込み中にエラーが発生しました

というエラーが発生しました。

macOSでESPr Developerに書き込みできない時に – スイッチサイエンス マガジン を参考に修正を行なったところ、改善したので、同じ症状の方はお試しください。

実行結果

Arduino IDE からESP-WROOM-02が接続されているシリアルポートを開くと、、

結果

受け取れていそうです!
次回は、ESP-WROOM-02 を使ってwebサーバーを立て、スマホのブラウザから気温を確認できるようにしようと思います!

Arduino を液晶ディスプレイと繋ぐ

なにするの?

今回は、Arduino と 液晶ディスプレイ(LCD : Liquid crystal display)を繋いで前回取得した気温を表示できるようにしたいと思います。予算は ¥2000 弱(今回追加分のみ)です。

使用機材

これらの紹介は hinohika.hatenablog.com で行なっています。

  • 液晶ディスプレイ
    今回使用したディスプレイは、AMAZON では現在取り扱われていないようです。

www.amazon.co.jp

類似商品なら応用可能だと思いますが、保証はできません。すみません。

回路図

ブレッドボードを使って Arduino と気温センサー、液晶ディスプレイを次のように繋ぎます。 前回の配線で、同じピン名の列で空いている所に追加で線を差し込むイメージです。

f:id:etuetuetutan:20211017144414j:plain

ピン名と配線の色の対応は以下の通りです。

VCC GND SDA SCL
LCD-ブレッドボード間
Arduino-ブレッドボード間

作業

LCDはこんな感じです。欲張って4行、20文字表示のLCDを購入しました。

f:id:etuetuetutan:20211017144440j:plain

裏はコントローラーがつけられています。ピン名をかいてくれているので配線は楽ですね。

f:id:etuetuetutan:20211017144505j:plain

プログラムは、こんな感じです。

#include <LiquidCrystal_I2C.h>   

#define LCD_COLS 20
#define LM75B_ADDR 0x48

// LCDの情報 (アドレス、一行の文字数、表示列数)
LiquidCrystal_I2C lcd(0x27, LCD_COLS, 4); 

double get_temperature(int addr){
  signed int message;
  double temp;
  Wire.requestFrom(addr,2);
  message  = (Wire.read() << 8);
  message |= Wire.read();
  temp = ((message >> 5) & 0x3FF) * 0.125;
  return temp;
  }
 
void setup() {
  // put your setup code here, to run once:
   lcd.init();                    
   lcd.backlight();
  // 表示する位置の指定 (列、行)               
   lcd.setCursor(0, 0);           
   lcd.print("Room Temperature");      
   Wire.begin();
}

void loop() {
  // put your main code here, to run repeatedly:
  double temp;
  temp = get_temperature(LM75B_ADDR);
  // 表示する位置の指定 (列、行)               
  lcd.setCursor(0,2);
  lcd.print(temp);  
  delay(5000);
}

今回は、LiquidCrystal_I2C.h というライブラリを使用します。
少し Arduino IDE で作業が必要になります。

  1. Arduino IDE で画面上に表示されているメニューバーから スケッチ > ライブラリをインクルード > ライブラリを管理 をクリック。

  2. ライブラリマネージャーが表示されるので、右上の検索バーに LiquidCrystal I2C と入力。

  3. 画像と同じライブラリを選択しインストールをクリック。

    f:id:etuetuetutan:20211002163452p:plain
    使用ライブラリ

これでライブラリを使用可能になります。

今回は、既存のライブラリを使用しただけなので、あまり解説できる内容はありませが少しだけ。

double get_temperature(int addr){
....
}

は、前回の内容で、気温を取得する部分を関数として用意し、それを使用しています。

lcd.setCursor(0, 0)

で左から何文字目、上から何行目に表示するか指定できます。

プログラムを Arduino に書き込むと、、、表示されました!!

f:id:etuetuetutan:20211017144313j:plain

今回は表示するだけでしたが、単に表示するだけでなく、文字を動かしてみるのも面白いですね!

次回は、新たに ESP32 というマイコンを使っていきます。無線wi-fi モジュールがついており、 IoT に近づきます!!

Arduino と気温センサーで温度計

なにするの?

始めての今回は、Arduino と気温センサーを使って室温の測定を行います。
温度計買えばいいやんなんて言わないで‼️

使用機材

回路図

ブレッドボードで作りました。見辛くてごめんなさい。 色とピン名の対応は以下の通りです。

  • 黒 : GND
  • 赤 : VCC
  • 白 : SDA
  • 茶 : SCL

GND,SDA,SCL は Arduino と気温センサーの両方にピンがあるので同じ名前同士で繋いでください。気温センサーの VCC は Arduino の 3.3V か 5V のどちらかと繋いでください。本記事では 5V に繋いでおきます。

f:id:etuetuetutan:20210927015132j:plain

作業

気温センサーです。ケースに入って届きました。とても、空間をもて余してますが。

f:id:etuetuetutan:20210926183814j:plain

はんだ付けしました。

f:id:etuetuetutan:20210926183858j:plain

これを、回路図通りに接続します。

次に、Arduino とセンサーを通信させるプログラムを作成します。Arduino とセンサーの通信は I2C という通信方式で行います。Wire.h というライブラリを使えば簡単にできるみたいです。

プログラム作ってて気がついたんですが、この気温センサー、AMAZON の商品名では LM75A と書いてあったので、そちらのデータシートを参考にしていたのですが、本体をよく見たら LM75B と書いてありました、、、紛らわしい。
https://www.switch-science.com/catalog/1813/ ここに、データシートや、サンプルプログラムまでありました。ありがたい。

サンプルを参考に、気温取得を行います。 プログラムはこんな感じです。 5秒ごとに気温を取得します。

#include <Wire.h>

#define LM75B_ADDR 0x48
  
void setup() {
  Wire.begin();
  Serial.begin(115200);
  Serial.println("start");
}

void loop() {
  signed int message;
  double temp;
  Wire.requestFrom(LM75B_ADDR,2);
  message  = (Wire.read() << 8);
  message |= Wire.read();
  temp = ((message >> 5) & 0x3FF) * 0.125;
  Serial.print("temperature : ");
  Serial.println(temp);
  delay(5000);
}

少し、プログラムの解説をしておくと、

#define LM75B_ADDR 0x48

の部分でセンサーのアドレスを指定しています。
I2C では、通信時にデバイスのアドレスが必要になります。このアドレスによって特定のデバイスとだけ通信を行うことができます。データシートによると、アドレスは 0x48~0x4F のどれかみたいです。このセンサーは、アドレスを変えることで最大8個同時に接続できるので、家の部屋毎にセンサーをおいて気温を測ることもできそうですね。
ただ、私の手元のセンサーは0x48 として認識されたり、 0x4C として認識されたりします。部品をよく見ると A2 と書かれた部分に小さな穴が空いています。アドレス的に A2 が影響していそうなのでこいつが悪さしている?

f:id:etuetuetutan:20210927020510j:plain

message  = (Wire.read() << 8);
message |= Wire.read();

の部分でセンサーから送られてくるデータを message という名前で保存します。気温のデータが分解されて送られてくるので受け取って組み立てているイメージです。

temp = ((message >> 5) & 0x3FF) * 0.125;

の部分で実際に気温データを表している数値の部分を抜き出しています。実は、送られてくるデータには気温ではない部分もあるのでそこを除去しています。本当は、氷点下の場合だと別の処理が必要なのですが、今回はそこは考慮しません。

これを Arduino IDE を使って Arduino に書き込んでいきます。そして、ツール > シリアルモニタ を選んで、、

f:id:etuetuetutan:20210926184809p:plain

それっぽい値が取れました!!温度計完成です。
27℃ は少し高いような、、、? まぁ、いいでしょう!
さて、次は何を作ろうか。。。

余談

専門的な内容になってしまうのですが、I2C 通信開始時のアドレスの後に続く Write Read の指定に必要なビットの処理は、 Wire.h のライブラリの requestFrom や beginTransmission 関数で適切に処理されているのでしょうね。ここの部分でかなり悩んでしまいました。