1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Embedded Swift Swiftでマイコン(ESP32)を動かす

Last updated at Posted at 2024-08-01

Embedded Swift Swiftでマイコン(ESP32)を動かす

Appleにより、Embedded SwiftでESP32を動かすサンプルが公開されました
このサンプルを試してみた際のTipsと、デジタル入出力、サーボモータ、LCDを実装してみた際の手順を紹介します

デジタル入出力、サーボモータ、LCDを実装してみたリポジトリはこちらです

デジタル入出力の動作の様子

こちらのボードで動作確認しました

swift-matter-examplesを試してみる

環境構築

swift-matter-examplesのチュートリアル通りに進めれば大丈夫でした

1点ハマったポイントとして、espressif/esp-idfespressif/esp-matter.git~/esp にcloneするステップがあります
これらのリポジトリをユーザのホームディレクトリ直下のespディレクトリ以外にcloneした場合、手元ではうまく環境構築できませんでした
一方で swift-matter-examples など実際に実装するコードはどのディレクトリにあっても問題ないようです

Docker環境は、macOSはUSBのパススルーがないですし、自分には要らないかな?と思いスキップしています
macOS上に環境を作って問題ないのであれば、スキップしても問題なさそうでした

動作確認

必要な環境変数を追加します
これはターミナルを起動して、毎度1回だけ実行する必要があります

$ export TOOLCHAINS=org.swift.59202407091a
$ . ~/esp/esp-idf/export.sh
$ . ~/esp/esp-matter/export.sh

cloneしたswift-matter-examplesのサンプルのディレクトリに移動します

$ git clone https://github.com/apple/swift-matter-examples.git
$ cd swift-matter-examples/smart-light

esp32c6をターゲットに設定します
このターゲットの設定は実際に動作させたいプログラムのディレクトリごとに実行する必要があるようです

$ idf.py set-target esp32c6

ESP32をPCに接続し、ビルドして書き込みます

$ idf.py build flash monitor

成功するとターミナルに 🏎️ Hello, Embedded Swift! と表示されています

swift-matter-examples以外の使い方を試してみる

swift-matter-examplesのLチカ以外に、デジタル入出力、サーボモータ、LCDを試してみました
espressifが公開しているesp-idfのexamplesが大変参考になりました

使いたいコンポーネントのサンプルコードをC言語からSwiftに書き換え、シンボルの参照に必要なヘッダをBridging Headerに追加します
例えば、デジタル入出力では <driver/gpio.h> を追加します

BridgingHeader.h
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <led_strip.h>
#include <sdkconfig.h>
#include <nvs_flash.h>
#include <led_driver.h>
#include <device.h>
#include <driver/gpio.h> // 追加

これで、 gpio_reset_pin などGPIOの設定に必要な関数を利用できます

let ledPin: gpio_num_t = GPIO_NUM_21
let buttonPin: gpio_num_t = GPIO_NUM_22

@_cdecl("app_main")
func app_main() {
    // LED
    gpio_reset_pin(ledPin);
    gpio_set_direction(ledPin, GPIO_MODE_OUTPUT)

    // Button
    gpio_reset_pin(buttonPin);
    gpio_set_direction(buttonPin, GPIO_MODE_INPUT)
    gpio_set_pull_mode(buttonPin, GPIO_PULLUP_ONLY)

    while true {
        if gpio_get_level(buttonPin) == 0 {
            for _ in 0..<5 {
                gpio_set_level(ledPin, 1)
                sleep(1)
                gpio_set_level(ledPin, 0)
                sleep(1)
            }
        }
        sleep(1)
    }
}

また、esp-idfに含まれていないコンポーネント(例えばLCD)を利用したい場合は、idf_component.yml に追加します
例えば、LCDを利用する場合は下記を追加します

idf_component.yml
dependencies:
  espressif/cmake_utilities:
    version: 0.*
    rules: # will add "optional_component" only when all if clauses are True
      - if: "idf_version >=5.0"
      - if: "target in [esp32c2]"
  lvgl/lvgl: "~8.3.0" # 追加
  esp_lvgl_port: "^1" # 追加

esp-idfに詳しくないのですが、おそらくC言語で開発する場合と遜色なく、esp-idfの資源を利用できそうでした
また、SwiftがC言語のAPIを十全に呼び出せるため、困った際はC言語の例を調べて、
Swiftに書き換えれば大丈夫そうでした
今回、実装してみたデジタル入出力、サーボモータ、LCDのコードはこちらのリポジトリにあります

Xcode上でプログラミングする

せっかくなので、Xcode上でのプログラミングにも実験的にチャレンジしてみました
Swift 5系では、Swift Package ManagerでBridging Headerを使えないので、xcodegenでxcodeprojを作成するようにしました

project.yml
name: swift-esp32-examples
settings:
  OTHER_LDFLAGS:
    - "-Wl,-undefined,dynamic_lookup"
targets:
  ex00-empty-template:
    type: framework
    platform: macOS
    sources:
      - path: ex00-empty-template/main/
        group: ex00-empty-template
      - path: ex00-empty-template/
        buildPhase: none
        excludes:
          - build/**
    settings:
      SWIFT_OBJC_BRIDGING_HEADER: ex00-empty-template/main/BridgingHeader.h
      HEADER_SEARCH_PATHS:
        - "$(inherited)"
        - "$(PROJECT_DIR)/headers/**"

ビルドターゲットにESP32を設定できないので、frameworkをターゲットにしました
また、Xcode上でのframeworkビルド時に、esp-idf系もビルドされると大変なので、シンボルを正しく利用しているかヘッダで検証だけして、ビルド時のリンクではスキップするようにしました
Xcode上でシンボルを検証するためのヘッダは、esp-idfなどのリポジトリをXcodeで開こうとすると固まる問題があったため、必要そうなヘッダのみをコピーして持ってきました
ESP32に書き込む際は、毎回ターミナルで idf.py build を打ち込んでおり、この辺はもう少し改良の余地がありそうです

まとめ

swift-matter-examplesを動かしてみて、それをベースにデジタル入出力、サーボモータ、LCDを試してみました
環境構築後は大きな問題もなくすんなり動きました
SwiftはC言語のAPIを十全に呼び出せるため、espの資源を活用できそうです
まだまだ、Swiftで本腰を入れてマイコン開発するのは難しそうですが、とても可能性を感じました

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?