さてさて、そろそろ何か始めないとな

さいたま市のソフトウェアエンジニアのブログ

ESP32-DevKitC デュアルコアボード初心者ガイド

ESP32-DevKitC デュアルコアボード初心者ガイド

こんにちは!今回は、IoTプロジェクトに最適な「ESP32-DevKitC デュアルコアボード ESP32 TYPE-C USB CH340C 開発ボード ESP32-WROOM-32D WiFi」について初心者の方向けにご紹介します。この記事を読めば、ESP32の基本からプログラミングまで、スムーズに始められるようになりますよ。

ESP32-DevKitCとは?

ESP32-DevKitCは、Espressif Systems社が開発した強力なマイクロコントローラボードです。Arduino互換でありながら、より高性能な機能を備えています。

主な特徴: - デュアルコアプロセッサ(240MHz) - WiFi & Bluetooth内蔵 - TYPE-C USB接続 - CH340Cシリアル変換チップ搭載 - ESP32-WROOM-32Dモジュール搭載 - 豊富なGPIOピン

開発環境のセットアップ

必要なもの

  • ESP32-DevKitCボード
  • USB Type-Cケーブル
  • パソコン

Arduino IDEのセットアップ

  1. Arduino IDEをダウンロードしてインストール
  2. Arduino IDEを起動し、「ファイル」→「環境設定」を開く
  3. 「追加のボードマネージャのURL」に以下を入力: https://dl.espressif.com/dl/package_esp32_index.json
  4. 「ツール」→「ボード」→「ボードマネージャ」を開く
  5. 検索欄に「ESP32」と入力し、Espressif Systems製のパッケージをインストール

ドライバのインストール

CH340Cシリアル変換チップ用のドライバが必要です: - Windows: CH340ドライバ - Mac: CH340ドライバ

最初のプログラム:LEDを点滅させる

ESP32ボードの動作確認として、定番のLチカ(LEDチカチカ)プログラムを試してみましょう。ESP32-DevKitCにはピン2に接続されたLEDがあります。

void setup() {
  // LED用のピンを出力モードに設定
  pinMode(2, OUTPUT);
}

void loop() {
  digitalWrite(2, HIGH);  // LEDをオン
  delay(1000);           // 1秒待機
  digitalWrite(2, LOW);   // LEDをオフ
  delay(1000);           // 1秒待機
}

コード解説:LEDチカチカ

このコードは非常にシンプルですが、Arduino/ESP32プログラミングの基本構造を示しています。

  1. setup()関数

    • プログラムの最初に一度だけ実行される関数です
    • pinMode(2, OUTPUT)でGPIO2ピンを出力モードに設定しています
    • ESP32-DevKitCボードでは、GPIO2にLEDが内蔵されているため、このピンを制御することでボード上のLEDを操作できます
  2. loop()関数

    • setup()実行後、繰り返し実行される関数です
    • digitalWrite(2, HIGH)でGPIO2ピンにHIGH(3.3V)を出力し、LEDをオンにします
    • delay(1000)で1000ミリ秒(1秒)待機します
    • digitalWrite(2, LOW)でGPIO2ピンにLOW(0V)を出力し、LEDをオフにします
    • 再度1秒待機し、ループの先頭に戻ります

このシンプルなパターンによって、LEDが1秒ごとにオン/オフを繰り返す(チカチカする)動作が実現されます。

プログラムのアップロード方法

  1. Arduino IDEで「ツール」→「ボード」→「ESP32 Arduino」→「ESP32 Dev Module」を選択
  2. 「ツール」→「シリアルポート」からESP32のポートを選択
  3. コンパイルボタン(チェックマーク)をクリックしてコードを検証
  4. アップロードボタン(→)をクリックしてコードをボードに転送

注意点: アップロード時に「Connecting...」の表示で止まる場合は、ボード上の「BOOT」ボタンを押しながらアップロードを開始すると成功しやすくなります。

WiFi機能を使ってみよう

ESP32の最大の特徴の一つがWiFi機能です。簡単なWiFi接続プログラムを見てみましょう:

#include <WiFi.h>

const char* ssid = "あなたのWiFi名";
const char* password = "WiFiのパスワード";

void setup() {
  Serial.begin(115200);
  delay(1000);
  
  Serial.println("WiFiに接続しています...");
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  
  Serial.println("");
  Serial.println("WiFi接続完了!");
  Serial.print("IPアドレス: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  // ここに追加のコードを書く
}

コード解説:WiFi接続

このコードはESP32をWiFiネットワークに接続する基本的な方法を示しています。

  1. ライブラリのインクルード

    • #include <WiFi.h> でESP32用のWiFiライブラリを読み込みます
    • このライブラリによってWiFi関連の機能が使えるようになります
  2. WiFi認証情報の設定

    • const char* ssidconst char* passwordで接続先のWiFiネットワーク名とパスワードを定義します
    • 実際に使用する際は、ご自身のWiFi情報に書き換えてください
  3. setup()関数内のWiFi接続処理

    • Serial.begin(115200)でシリアル通信を開始(115200bpsのボーレート)
    • WiFi.begin(ssid, password)で指定したWiFiネットワークへの接続を開始
    • while (WiFi.status() != WL_CONNECTED)ループでは、接続が完了するまで待機します
      • このループ内では0.5秒ごとに「.」を出力することで接続待ちであることを視覚的に表示
    • 接続が完了すると、シリアルモニタにIPアドレスを表示します

このコードを実行すると、シリアルモニタに接続過程と接続後に割り当てられたIPアドレスが表示されます。IPアドレスはESP32をネットワーク上で識別するために重要で、後でWebサーバーを作る際などに必要になります。

デュアルコアを活用する

ESP32の強みはデュアルコアプロセッサです。両方のコアを同時に活用するプログラムの例:

// コア0とコア1で別々のタスクを実行するサンプル
TaskHandle_t Task1;
TaskHandle_t Task2;

void setup() {
  Serial.begin(115200);
  
  // コア0でTask1を実行
  xTaskCreatePinnedToCore(
    Task1code,   // タスク関数
    "Task1",     // タスク名
    10000,       // スタックサイズ
    NULL,        // パラメータ
    1,           // 優先度
    &Task1,      // タスクハンドル
    0);          // コア0で実行
    
  delay(500);
  
  // コア1でTask2を実行
  xTaskCreatePinnedToCore(
    Task2code,   // タスク関数
    "Task2",     // タスク名
    10000,       // スタックサイズ
    NULL,        // パラメータ
    1,           // 優先度
    &Task2,      // タスクハンドル
    1);          // コア1で実行
}

void Task1code(void * parameter) {
  for(;;) {
    Serial.print("Core 0 running, millis: ");
    Serial.println(millis());
    delay(1000);
  }
}

void Task2code(void * parameter) {
  for(;;) {
    Serial.print("Core 1 running, millis: ");
    Serial.println(millis());
    delay(700);
  }
}

void loop() {
  // ループは空でOK - タスクが実行している
}

コード解説:デュアルコア活用

このコードはESP32のデュアルコア機能を活用して、2つの異なるタスクを別々のコアで並行実行する例です。

  1. タスクハンドルの宣言

    • TaskHandle_t Task1TaskHandle_t Task2は、作成するタスクへの参照を保持する変数です
    • これらのハンドルを使って、後からタスクの制御(一時停止、再開、削除など)ができます
  2. xTaskCreatePinnedToCore関数

    • この関数はFreeRTOS(ESP32で使用されるリアルタイムOS)のタスク作成関数です
    • 指定したコア上でタスクを実行させることができます
    • 引数の意味:
      • 第1引数:実行するタスク関数(Task1codeなど)
      • 第2引数:タスクの名前(デバッグ用)
      • 第3引数:タスクのスタックサイズ(バイト単位)
      • 第4引数:タスクに渡すパラメータ(ここではNULL)
      • 第5引数:タスクの優先度(値が大きいほど優先度が高い)
      • 第6引数:タスクハンドルを格納する変数
      • 第7引数:実行するコア番号(0または1)
  3. タスク関数(Task1code、Task2code)

    • void Task1code(void * parameter)形式で定義されたタスク関数
    • for(;;)は無限ループを意味し、タスクは継続的に実行されます
    • Task1codeは1秒ごとに、Task2codeは0.7秒ごとに現在の時間(millis)を出力します
    • 異なるタイミングで出力することで、両方のタスクが独立して並行実行されていることが確認できます
  4. 空のloop関数

    • 通常のArduinoスケッチと違い、タスクベースのプログラムではloop()関数は不要になります
    • すべての処理はタスク内で行われるため、loop()は空のままでOKです

このコードを実行すると、シリアルモニタに両方のコアからの出力が交互に表示されます。異なるタイミングでメッセージが出ることから、2つのタスクが本当に並行して実行されていることが確認できます。

この並行処理機能は、例えばセンサーからのデータ読み取りとWiFi通信を同時に行いたい場合など、複雑なIoTプロジェクトで非常に役立ちます。

センサーを接続してみよう

ESP32は多くのセンサーと簡単に連携できます。ここでは、DHT11温湿度センサーの接続例を紹介します:

必要なもの

  • DHT11センサー
  • 10kΩ抵抗(プルアップ用)
  • ジャンパーワイヤー

配線

  • DHT11のVCCピン → ESP32の3.3V
  • DHT11のDATAピン → ESP32のGPIO4(10kΩ抵抗でプルアップ)
  • DHT11のGNDピン → ESP32のGND

プログラム

まず、ライブラリをインストールします:「スケッチ」→「ライブラリをインクルード」→「ライブラリを管理」→「DHT sensor library」を検索してインストール。

#include "DHT.h"

#define DHTPIN 4     // DHT11のデータピンをGPIO4に接続
#define DHTTYPE DHT11   // DHT11センサーを使用

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(115200);
  Serial.println("DHT11テスト開始!");
  dht.begin();
}

void loop() {
  delay(2000); // センサーの読み取りには少し時間がかかります
  
  float h = dht.readHumidity();    // 湿度を読み取り
  float t = dht.readTemperature(); // 温度を読み取り(摂氏)
  
  // 読み取りに失敗した場合のエラーチェック
  if (isnan(h) || isnan(t)) {
    Serial.println("DHT11からの読み取りに失敗しました!");
    return;
  }
  
  Serial.print("湿度: ");
  Serial.print(h);
  Serial.print("%  温度: ");
  Serial.print(t);
  Serial.println("°C");
}

コード解説:DHT11温湿度センサー

このコードはDHT11センサーから温度と湿度を読み取り、シリアルモニタに表示する例です。

  1. ライブラリのインクルードと定義

    • #include "DHT.h"でDHTセンサーライブラリを読み込みます
    • #define DHTPIN 4でDHT11のデータピンが接続されているGPIOピン番号を定義します
    • #define DHTTYPE DHT11で使用するセンサーのタイプを指定します(DHT11またはDHT22)
  2. DHTオブジェクトの作成

    • DHT dht(DHTPIN, DHTTYPE)で、指定したピンとタイプでDHTセンサーオブジェクトを初期化します
    • このオブジェクトを通してセンサーとの通信を行います
  3. setup()関数

    • シリアル通信を開始します
    • dht.begin()でDHTセンサーの初期化を行います
  4. loop()関数

    • delay(2000)で2秒待機します。DHT11センサーは頻繁に読み取りを行うと不安定になるため、適切な間隔を空けています
    • dht.readHumidity()で湿度を、dht.readTemperature()で温度(摂氏)を読み取ります
    • isnan()関数でセンサーからの読み取りに失敗していないかチェックします
      • 読み取りに失敗した場合は、エラーメッセージを表示して処理をスキップします
    • 読み取りに成功した場合は、温度と湿度の値をシリアルモニタに表示します

DHT11センサーは±2℃、±5%RHの精度を持つ比較的安価なセンサーです。より高精度な測定が必要な場合はDHT22/AM2302センサーを使用することもできます(その場合は#define DHTTYPE DHT22に変更します)。

センサーの読み取り間隔は2秒以上を推奨します。間隔が短すぎると、センサーが不安定になったり、寿命が短くなったりする可能性があります。

次のステップ

ESP32の基本を理解したら、次のステップとして以下のプロジェクトに挑戦してみましょう:

  1. Webサーバーの構築: ESP32をアクセスポイントとして設定し、センサーデータをブラウザで表示
  2. MQTT通信: クラウドサービスとの連携
  3. ディープスリープモード: バッテリー駆動の省電力設計
  4. Bluetooth接続: スマートフォンアプリとの連携

トラブルシューティング

問題: ボードが認識されない 解決策: - USBケーブルが正しく接続されているか確認 - CH340ドライバが正しくインストールされているか確認 - 別のUSBポートを試す

問題: アップロードに失敗する 解決策: - BOOTボタンを押しながらアップロード - ENボタンを一度押してリセット - 適切なボード設定とポートが選択されているか確認

問題: WiFi接続に失敗する 解決策: - SSIDとパスワードを確認 - WiFiルーターがESP32の近くにあるか確認 - WiFiルーターが2.4GHz帯を使用しているか確認(ESP32は5GHzに対応していません)

まとめ

ESP32-DevKitCは、豊富な機能と手頃な価格で初心者からプロまで幅広く使えるマイクロコントローラーです。WiFi、Bluetooth、デュアルコアプロセッサを一つのチップに統合した強力なデバイスで、様々なIoTプロジェクトの可能性を広げてくれます。

この記事で基本的な使い方を理解できたら、ぜひ自分のアイデアを形にしてみてください。ESP32の世界は奥が深く、探求する価値があります!


この記事が参考になりましたら、コメントやSNSでのシェアをお願いします。次回の記事もお楽しみに!