Arduino開発、ファイルを分割してC/C++で書く、VSCode

# 動機
最近Arduinoが自分の中でアツい。が、結局マネタイズも考えると、別のプラットフォームへのポーティング労力を最小化できるようにしたい。また、いい加減ウン十年もC/C++を使ってきて、しかも組み込みがルーツである技術者にとって、sketch(限定されたC/C++)よりは、普通にC/C++で書きたいし(というかnewやmallocも使いたくない、ほぼC言語一択)、モジュール分けしたい。既に作ったたくさんの汎用モジュールを活用したい。

色々と調べたが、
**Arduino IDE 1.8.x (Legacy IDE)** 
**Visual Studio Code**
**Arduino for Visual Studio Code(VSCode機能拡張)**
の組み合わせで行ってみることにした。


# 開発環境
**1. Arduino IDE**
[arduino.cc、Downloads](https://www.arduino.cc/en/software)
から、 **Legacy IDE** をダウンロード、インストール。
執筆時点(2023/04/14)では、1.8.19であった。
2.xも試してみたが、Arduino for Visual Studio Codeがうまく動作しなかった。

**2. Visual Studio Code**
[Download Visual Studio Code](https://code.visualstudio.com/download)
からダウンロード、インストール。

**3. Arduino for Visual Studio Code**
VSCodeのExtensionsからインストール。Microsoft製。(少なくともpeepされてなさそうという意味で)安心。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082015/310ab2e6-f86d-fe2b-c776-de94581ce377.png)


# ディレクトリ構成
結論として、以下のようにする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082015/2363eac1-3b7b-f339-4e10-c11b795d2e2d.png)
【ポイント】
* 「スケッチ名」(ここでは"AppName")ディレクトリ以下に、「src」ディレクトリを作り、それ以下にCソースを配置すると、自動的にプロジェクトのメンバとして認識し、コンパイル・リンクしてくれる。これは、なぜか「src」じゃないとうまくいかない。eclipse系の何か？のような気がするが、ひとまずこれで行く。

> [Arduino用スケッチのサブルーチンをサブディレクトリに配置する](https://nuneno.cocolog-nifty.com/blog/2018/03/arduino-65a0.html)

がカギでした。ありがとうございます。

* 出力ディレクトリをworkspace下のbuildとする。
出来上がったelfやhexがすぐ目に付くところに出来上がる。安心。
cleanする場合には、buildディレクトリを削除。
Arduino IDEには、cleanがない？


# プロジェクト作成
## ディレクトリ準備
まず、以下のディレクトリを準備する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082015/eba5389b-e48f-9446-8beb-8ba44e332eb1.png)

AppName.inoは新規スケッチの例のアレ。
注意点として、 **BOM付きのUTF8は許容されない。コンパイルエラーになる。**
Arduinoに関しては、自分はBOMなしUTF8、LFでソースコード作っていくことになると思う。

```AppName.ino
void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}
```

## パス設定(Arduino for Visual Studio Codeの設定)
F1をHit、「Open Workspace Settings」。
「もしかしたらプロジェクトごとに別のバージョンにせざるを得ない日が来るかもしれない」ことを念頭に、Workspaceでの設定とする。Userの設定としない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082015/806883bf-5dea-db3e-c984-7ff32bad6c47.png)

検索ボックスに「arduino」を入力、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082015/131819ac-877d-a786-4d7c-133cb399775f.png)

Arduino: PathにArduino IDEへのパスを入力。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082015/6a380a6e-ede6-484d-ed95-6ad0351e559d.png)

この時、以下のような警告が出るが、ここでは無視。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082015/db2ff3cb-57cc-a471-0672-f8ba5bade3f5.png)

自分はそれに加え、出力を詳細化している。
不要と言えば不要だが、どのようなbuildが走っているのか確認できるようにしておきたいため。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082015/5035b24c-e6ce-0750-8c36-6dfbb4495d91.png)

この時点でのsettings.jsonは以下。
```.vscode\settings.json
{
    "arduino.path": "C:\\Program Files (x86)\\Arduino\\1.8.19",
    "arduino.logLevel": "verbose"
}
```

## プロジェクトの初期化
F1をHit、「Arduino: Initialize」。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082015/a2b4addd-78aa-61ff-d121-7a5bcd2689b7.png)

この時点でarduino.jsonが自動生成される。
```.vscode\arduino.json
{
    "sketch": "AppName\\AppName.ino"
}
```


## ボード設定
F1をHit、「Arduino: Board Config」を起動。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082015/aa224296-c6a9-338c-4bd7-814b504750c7.png)

ボードを選択する。以下は自分の環境で、「Portenta H7」。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082015/c7381acc-f812-b529-9e4f-532a75b00b00.png)

arduino.jsonが更新される。
```.vscode\arduino.json
{
    "sketch": "AppName\\AppName.ino",
    "configuration": "target_core=cm7,split=50_50,security=none",
    "board": "arduino:mbed_portenta:envie_m7"
}
```

また、しばらくすると、c_cpp_properties.jsonが自動生成される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082015/1e378c9e-0228-7408-ab35-ac0f6a4617a7.png)

## C/C++モジュールの配置
スケッチディレクトリ下に、C/C++モジュールを配置する。
既出のとおり、「src」ディレクトリ以下に配置すること。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082015/235cb1bb-662c-230d-d429-e906b4a31a4b.png)

## 出力ディレクトリ、インクルードパスの追加
「output」で出力ディレクトリを設定、「buildPreferences」でインクルードパスを設定。
自分はいつも-Wallも指定している。

```.vscode\arduino.json
{
    "buildPreferences":[
        ["compiler.c.extra_flags","-Wall -IAppName/src/Category01/inc"],
        ["compiler.cpp.extra_flags","-Wall -IAppName/src/Category01/inc"]
    ],
    "output": "build",
    "sketch": "AppName\\AppName.ino",
    "configuration": "target_core=cm7,split=50_50,security=none",
    "board": "arduino:mbed_portenta:envie_m7"
}
```

## ビルド
AppName.inoをアクティベート、Verify
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082015/e416eeb6-676b-f8bd-6753-f9e08704effb.png)

ビルド完了し、elf、hexが生成される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082015/1be6ddcd-8523-6175-0ea2-5b3d0d215135.png)