ESP32C3にスマホからテキストメッセージ送信!

ESP32C3にスマホからテキストメッセージ送信!

はじめに

この記事を読めば「ESP332C3」マイコンボードでOLEDディスプレイを使っていきます。

今回使い方を紹介するSSD1306ディスプレイは0.96インチと小型ですが視認性が良く
単価が安く、誰にいでも手を出しやすいものになっています。

無線通信で受け取ったメッセージを表示させたり、気温系を作ったりなど
ディスプレイ付きのデバイスを簡単に制作することができます。

わからないことがありましたら、問い合わせページまたは公式ラインに連絡をください!
Youtubeもありますので、ぜひ見てみてください!

つかうもの

この記事で使っているものを紹介します。
*このリンクは、アフィリエイトリンクです。
こちらのリンクから購入されると、投稿主にインセンティブが発生します。
より良い記事のために、ぜひ購入する際は以下のリンクよりお願いします。。

購入はこちらをクリック!
*画像はリンク先より引用

購入はこちらをクリック!
*画像はリンク先より引用

購入はこちらをクリック
*画像はリンク先より引用

モジュール解説

ESP32C3

XIAO ESP32C3は無線通信が可能です。
今回は、BLE「Bluetooth Low Energy」を使っていこうと思います。
スマホから入力された文字をSSD1306ディスプレイに表示していきます!

今回はこちらの0.96インチの有機ディスプレイに文字を表示させていきます。

つくるもの

今回は、ESP32C3とスマホをBluetoothでつなぎスマホからテキスト情報を送信して、受け取ったものをSSD1306ディスプレイに表示させるというプログラムです。

今回の内容に理解していただければ、無線通信でもマイコンに接続したモジュールなどを操作することができるようになります!

回路解説

下の画像を参考に回路を組ん見てください。

プログラム解説

まずは、必要なライブラリをインストールします。

まずは「Adafruit_GFX→インストール→すべてをインストール」

もう一つインストールします。
「Adafruit_SSD1306で検索→インストール→すべてをインストール」

これで準備は終わりです。

プログラムコードをArduino studioで書き込んでください。

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET     -1
#define SCREEN_ADDRESS 0x3C

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

#define MAX_STRINGS 4 // 4行しか表示できない
#define MAX_LENGTH 20

char strings[MAX_STRINGS][MAX_LENGTH + 1]; // 文字列配列の定義
bool display_updated = false; // ディスプレイの更新フラグ
int value_count = 0; // 値の入力回数
bool connected = false; // BLE接続状態のフラグ

// BLEサーバーのコールバッククラス
class MyServerCallbacks : public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
        // スマートフォンとの接続が確立されたときに呼ばれる
        connected = true;
        display_updated = true;
    }

    void onDisconnect(BLEServer* pServer) {
        // スマートフォンとの接続が切断されたときに呼ばれる
        connected = false;
        // BLEアドバタイズの再開
        BLEAdvertising *pAdvertising = pServer->getAdvertising();
        pAdvertising->start();
        display_updated = true;
    }
};

// BLEキャラクタリスティックのコールバッククラス
class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
        // BLEキャラクタリスティックに新しい値が書き込まれたときに呼ばれる
        std::string value = pCharacteristic->getValue();
        if (value.length() > 0) {
            // 値の長さが0より大きい場合の処理
            if (value.length() > MAX_LENGTH) {
                value = value.substr(0, MAX_LENGTH - 2) + "..";
            }
            // 文字列配列をひとつずつ下にずらす
            for (int i = min(value_count, MAX_STRINGS - 1); i > 0; i--) {
                strncpy(strings[i], strings[i - 1], MAX_LENGTH + 1);
            }
            // 最新の値を配列の先頭に追加
            value.copy(strings[0], value.length());
            strings[0][value.length()] = '\0'; // 終端文字を追加
            value_count++;
            // 値の入力回数が最大行数を超えた場合は調整
            if (value_count > MAX_STRINGS) {
                value_count = MAX_STRINGS;
            }
            // ディスプレイを更新するフラグを立てる
            display_updated = true;
        }
    }
};

void setup() {
    // OLEDディスプレイの初期化
    if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
        // ディスプレイの初期化に失敗した場合は無限ループに入る
        for(;;);
    }
    display.clearDisplay();
    display.setTextSize(2); // 文字サイズを2に設定
    display.setTextColor(SSD1306_WHITE);

    // BLEデバイスの初期化
    BLEDevice::init("MyESP32");
    BLEServer *pServer = BLEDevice::createServer();
    pServer->setCallbacks(new MyServerCallbacks());

    // BLEサービスの作成
    BLEService *pService = pServer->createService(SERVICE_UUID);

    // BLEキャラクタリスティックの作成
    BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );

    // BLEキャラクタリスティックにコールバックを設定
    pCharacteristic->setCallbacks(new MyCallbacks());

    // 初期値の設定
    pCharacteristic->setValue("Hello World");

    // BLEサービスの開始
    pService->start();

    // BLEアドバタイズの開始
    BLEAdvertising *pAdvertising = pServer->getAdvertising();
    pAdvertising->start();
}

void loop() {
    // ディスプレイの更新が必要な場合の処理
    if (display_updated) {
        display.clearDisplay();

        // BLE接続状態の表示
        if (connected) {
            // 接続されている場合
            display.setCursor(0, 0);
            display.println("connected");
        } else {
            // 接続されていない場合
            display.setCursor(0, 0);
            display.println("no-connect");
        }

        // 値の表示
        for (int i = 0; i < value_count; i++) {
            String strToDisplay = strings[i];
            if (strToDisplay.length() > 8) {
                // 文字列が長すぎる場合は省略して表示
                strToDisplay = strToDisplay.substring(0, 8) + "..";
            }
            // ディスプレイに文字列を表示
            display.setCursor(0, (i + 1) * 16); // 1行あたりの高さは16ピクセル
            display.println(strToDisplay);
        }

        // ディスプレイの更新
        display.display();
        display_updated = false;
    }
    delay(200); // 更新間隔の調整
}

以下のプログラムをArduino studioにコピペして、書き込んでください。

実行

書き込みが終了したら、スマホアプリの「BLE Scaner」を開き、以下の画像の手順で文字を送ります。

スマホアプリを起動して、一番下のバーの「Scaner→MyESP32」を選択します。

「Services→Write&Read」を選択します

その後「Write→Text」そして表示させたい文字列を入力します。
*日本語は非対応です。

入力したらキーボードのEnterではなく、Writeを押します。
初めに「kouduki」と入力してみます。

そうすると、、、

その後、「denkou」「ssssssssss」という順で入力すると、、、

古い値は1行下がって表示されました!
次は「111q11q」と適当に入力してみます。

一番最初に入力した「kouduki」が消えて一番上に入力した値が表示されました!

これで今回の内容は無事終了です。

プログラムの解説

長いので折りたたんでます。
↓をクリック!

コードの解説はここをクリック
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

このセクションでは、BLEライブラリおよびOLEDディスプレイのためのライブラリをインクルードしています。BLEデバイスと通信するために必要なBLEDevice、BLEUtils、BLEServerライブラリが含まれています。また、OLEDディスプレイを制御するためのWire、Adafruit_GFX、Adafruit_SSD1306ライブラリも含まれています。

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET     -1
#define SCREEN_ADDRESS 0x3C

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

#define MAX_STRINGS 4
#define MAX_LENGTH 20

このセクションでは、ディスプレイの幅と高さ、リセットピン、アドレスなどのOLEDディスプレイに関する定数、およびBLEサービスとキャラクタリスティックのUUID、文字列の最大数と最大長さなどの関連する定数を定義しています。

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
char strings[MAX_STRINGS][MAX_LENGTH + 1];
bool display_updated = false;
int value_count = 0;
bool connected = false;

このセクションでは、OLEDディスプレイのインスタンスであるdisplay、受信した文字列を保持するための文字列配列strings、ディスプレイの更新フラグdisplay_updated、受信した値の数value_count、BLE接続状態のフラグconnectedをグローバル変数として定義しています。

class MyServerCallbacks : public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
        connected = true;
        display_updated = true;
    }

    void onDisconnect(BLEServer* pServer) {
        connected = false;
        BLEAdvertising *pAdvertising = pServer->getAdvertising();
        pAdvertising->start();
        display_updated = true;
    }
};

このセクションでは、BLEサーバーの接続と切断時のコールバック関数を定義しています。onConnect関数は、クライアントが接続したときに呼び出され、connectedフラグをtrueに設定し、display_updatedフラグを立ててディスプレイを更新します。onDisconnected関数は、クライアントが切断したときに呼び出され、connectedフラグをfalseに設定し、BLEアドバタイズを再開してディスプレイを更新します。

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
        std::string value = pCharacteristic->getValue();
        if (value.length() > 0) {
            if (value.length() > MAX_LENGTH) {
                value = value.substr(0, MAX_LENGTH - 2) + "..";
            }
            for (int i = min(value_count, MAX_STRINGS - 1); i > 0; i--) {
                strncpy(strings[i], strings[i - 1], MAX_LENGTH + 1);
            }
            value.copy(strings[0], value.length());
            strings[0][value.length()] = '\0'; // 終端文字を追加
            value_count++;
            if (value_count > MAX_STRINGS) {
                value_count = MAX_STRINGS;
            }
            display_updated = true;
        }
    }
};

このセクションでは、BLEキャラクタリスティックの書き込み時のコールバック関数を定義しています。onWrite関数は、キャラクタリスティックに新しい値が書き込まれたときに呼び出されます。受信した値をstring配列に保存し、display_updatedフラグを立ててディスプレイを更新します。

void setup() {
    if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
        for(;;);
    }
    display.clearDisplay();
    display.setTextSize(2);
    display.setTextColor(SSD1306_WHITE);

    BLEDevice::init("MyESP32");
    BLEServer *pServer = BLEDevice::createServer();
    pServer->setCallbacks(new MyServerCallbacks());

    BLEService *pService = pServer->createService(SERVICE_UUID);

    BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );

    pCharacteristic->setCallbacks(new MyCallbacks());

    pCharacteristic->setValue("Hello World");
    pService->start();

    BLEAdvertising *pAdvertising = pServer->getAdvertising();
    pAdvertising->start();
}

このセクションでは、セットアップ関数が定義されています。ディスプレイの初期化と設定、BLEサーバーの初期化とサービスの作成、キャラクタリスティックの作成とコールバックの設定、サービスの開始、BLEアドバタイズの開始が行われています。

void loop() {
    if (display_updated) {
        display.clearDisplay();

        if (connected) {
            display.setCursor(0, 0);
            display.println("connected");
        } else {
            display.setCursor(0, 0);
            display.println("no-connect");
        }

        for (int i = 0; i < value_count; i++) {
            String strToDisplay = strings[i];
            if (strToDisplay.length() > 8) {
                // 文字列が長すぎる場合は省略して表示
                strToDisplay = strToDisplay.substring(0, 8) + "..";
            }
            // ディスプレイに文字列を表示
            display.setCursor(0, (i + 1) * 16); // 1行あたりの高さは16ピクセル
            display.println(strToDisplay);
        }

        // ディスプレイの更新
        display.display();
        display_updated = false;
    }
    delay(200); // 更新間隔の調整
}

このセクションでは、メインループ関数が定義されています。ディスプレイが更新された場合、BLE接続状態と受信した値をディスプレイに表示し、ディスプレイを更新します。また、更新間隔を調整するための一定時間の遅延が行われています。

動かないときは、、

回路

まずは、回路が正しいか確認してください。
ブレッドボード上で正しくつながっていますか?

また、ジャンパー線が断線している。
ブレッドボードの接続不良ということもあります。
違うものを使ってみましょう。

プログラム

プログラムを正しく書き込めているか確認しましょう。
エラーが出ていないか確認してください。

プログラムを書き込む前にライブラリをインストールしたかを確認してください。

公式ラインに連絡!

解決しない場合は、以下の公式ラインに連絡ください!
可能な限り対応させていただきます!
*やってほしい企画、ご要望ありましたら遠慮なく連絡ください!

友だち追加

XIAO_ESP32C3カテゴリの最新記事