ESP-WROOM-02 PlatformIDE for VSCode デバックビルド時にデバック用コードを実行

### PlatformIDE for VSCode でデバックビルドを構成する方法

　前回 ESP-WROOM-02 を使った ESP気象センサーの観測データをUDPパケットでブロードキャストする方法を紹介しました。
[ESP-WROOM-02 気象センサーの観測データをUDPパケットでブロードキャストする](https://qiita.com/pipito-yukio/items/ee47de91fbbbe787d659)

　今回はデバックビルド時にデバック用コードをコンパイルするための設定方法と、プリプロセッサの実装方法を説明します。

[A] リリースビルド時(デフォルト)のシリアル出力
```
CH<0>: [449,449,449,449,449,449,449,449,449,449], mean adc: 449
Therm.outVolt: 1.447 V 
rx: 12806.24, xa: 0.000072
Therm Temp:18.4
```

[B] デバックビルド時(デバック用設定と処理を追加)のシリアル出力

```
CH<0>: [449,449,449,449,449,449,449,449,449,449], mean adc: 449
ReadData: [[0x1,0xc1],[0x1,0xc1],[0x1,0xc1],[0x1,0xc1],[0x1,0xc1],[0x1,0xc1],[0x1,0xc1],[0x1,0xc1],[0x1,0xc1],[0x1,0xc1],]
Therm.outVolt: 1.447 V 
rx: 12806.24, xa: 0.000072
Therm Temp:18.4
```

### 参考にしたサイト

(英語)
[Creating Project in PlatformIO using Arduino Framework](https://docs.logicrom.com/en/latest/book/quick_start/arduino.html)
本家サイトのドキュメント
[docs.platformio.org: Build Configurations](https://docs.platformio.org/en/stable/projectconf/build_configurations.html#build-configurations)
[docs.platformio.org: Section[env] / Build Options / build_flags](https://docs.platformio.org/en/stable/projectconf/sections/env/options/build/build_flags.html)

#### 開発環境

+ PC: Ubuntu 22.04
+ ソースの作成とビルド: PlatformIO IDE for VSCode
+ USBシリアルポートドライバーがインストール済み


### PlatformIO プロジェクト設定ファイル

#### 1. リリース用ビルドの設定

シリアルモニター設定とバイナリーのアップロードプロトコルは手動で追加

```platformio.ini
[env:esp_wroom_02]
platform = espressif8266
board = esp_wroom_02
framework = arduino
; シリアルモニター設定
monitor_port = /dev/ttyUSB0
monitor_speed = 9600
; バイナリーのアップロードプロトコル (esptool | espota)
upload_protocol = esptool
```

#### 2. デバックビルド用の設定

※リリースビルドの設定分は上記1と同一なので割愛

+ **build_type = debug**
※この設定は必須。下のプリプロセッサオプション定義だけではデバック用の処理がコンパイルされません
+ **build_flags = -D DEBUG**
※プリプロセッサに対するマクロシンボル名を指定。複数可

```platformio.ini
[env:esp_wroom_02]
; リリースビルドの設定分は割愛
; DEBUGビルドを有効にする
build_type = debug
; マクロシンボル名 (DEBUG) を追加
build_flags = -DDEBUG
```

　ファイル保存すると ```.vscode/c_cpp_properties.json``` ファイルの"defines"にマクロシンボル名が追加されます

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583120/7f9277ab-9b4c-8922-794b-299d9a5ac6fb.png">

#### 3. コンパイルの分岐制御

##### 3-1. デバックビルド時のみ実行したい処理 (関数)

デバック出力用データ (配列) を16進数でシリアル出力する

```cpp
void debugSerialOut(ReadData (&datas)[ADC_SAMPLES]) {
  int len = sizeof(datas) / sizeof(datas[0]);
  Serial.print("ReadData: [");
  for (int i = 0; i < len; i++) {
    ReadData rd = datas[i];
    char chrbuf[5];
    Serial.print("[0x");
    sprintf(chrbuf, "%x", rd.highByte);
    Serial.print(chrbuf);
    Serial.print(",0x");
    sprintf(chrbuf, "%x", rd.lowByte);
    Serial.print(chrbuf);
    Serial.print("]");
    if (i < ADC_SAMPLES) {
      Serial.print(",");
    }
  }
  Serial.println("]");
}
```

##### 3-2. #if 条件式 〜 #endif でコンパイルを分岐する

**マクロシンボル名(DEBUG)が定義有りの場合**、下記のデバック用コードをコンパイルする
+ デバック出力用の配列を確保
+ ループ処理で上記配列にオブジェクトが保持している読取りデータ値を設定する
+ デバック出力用の配列をシリアル出力する

```cpp
float getSamplingAdcValue(uint8_t ch, SimpleMCP3002 &mcp) {
  int adcSamples[ADC_SAMPLES];
#if defined(DEBUG)
  ReadData datas[ADC_SAMPLES];
#endif
  int i;
  Serial.print("CH<");
  Serial.print(ch);
  Serial.print(">: [");
  for (i = 0; i < ADC_SAMPLES; i++) {
    adcSamples[i] = mcp.analogRead(ch);
#if defined(DEBUG)
    datas[i] = mcp.getReadData();
#endif
    Serial.print(adcSamples[i]);
    if (i < (ADC_SAMPLES - 1)) {
      Serial.print(",");
    }
    delay(30);
  }
  Serial.print("], mean adc: ");
  uint16_t adcTotal = 0;
  for (i = 0; i < ADC_SAMPLES; i++) {
    adcTotal += adcSamples[i];
  }
  uint16_t meanAdc = round(1.0 * adcTotal / ADC_SAMPLES);
  Serial.println(meanAdc);
#if defined(DEBUG)
  debugSerialOut(datas);
#endif
  return meanAdc;
}
```

#### 4. バイナリ実行

##### 4-1. リリースビルド時のシリアルモニター出力

```
�␖␖�����--START--
CH<0>: [448,449,448,449,448,448,448,449,449,449], mean adc: 449
Therm.outVolt: 1.448 V 
rx: 12783.96, xa: 0.000072
Therm Temp:19.1
CH<0>: [452,452,452,452,452,452,452,452,452,452], mean adc: 452
Therm.outVolt: 1.458 V 
rx: 12632.74, xa: 0.000068
Therm Temp:19.4
CH<0>: [447,447,447,447,447,447,447,447,447,447], mean adc: 447
Therm.outVolt: 1.442 V 
rx: 12885.91, xa: 0.000074
Therm Temp:18.9
```

##### 4-2. デバックビルドのシリアルモニター出力

```
�␖␖�����--START--
CH<0>: [446,446,446,446,446,446,445,446,446,446], mean adc: 446
ReadData: [[0x1,0xbe],[0x1,0xbe],[0x1,0xbe],[0x1,0xbe],[0x1,0xbe],[0x1,0xbe],[0x1,0xbd],[0x1,0xbe],[0x1,0xbe],[0x1,0xbe],]
Therm.outVolt: 1.437 V 
rx: 12959.64, xa: 0.000075
Therm Temp:18.1
CH<0>: [445,445,445,445,445,445,445,445,445,445], mean adc: 445
ReadData: [[0x1,0xbd],[0x1,0xbd],[0x1,0xbd],[0x1,0xbd],[0x1,0xbd],[0x1,0xbd],[0x1,0xbd],[0x1,0xbd],[0x1,0xbd],[0x1,0xbd],]
Therm.outVolt: 1.434 V 
rx: 13011.24, xa: 0.000077
Therm Temp:18.0
CH<0>: [445,445,445,445,445,445,445,445,445,445], mean adc: 445
ReadData: [[0x1,0xbd],[0x1,0xbd],[0x1,0xbd],[0x1,0xbd],[0x1,0xbd],[0x1,0xbd],[0x1,0xbd],[0x1,0xbd],[0x1,0xbd],[0x1,0xbd],]
Therm.outVolt: 1.434 V 
rx: 13011.24, xa: 0.000077
Therm Temp:18.0
```

以下はラズパイにサーミスタを接続しスクリプトを実行したときのログ出力

上記デバック用データReadDataのシリアル出力と、下記 r_data[0], r_data[1]の値との比較により取得値が妥当かどうかの検証が可能になります。

```
2024-02-16 14:23:41 INFO read_1_thermistorWithMCP3000.py(73)[<module>] Namespace(adc_name='mcp3002', interval=30.0, use_lib='pigpio')
2024-02-16 14:23:41 DEBUG mcp3000.py(53)[__init__] spi_handle: 0
2024-02-16 14:23:41 DEBUG mcp3000.py(54)[__init__] v_ref: 3.3V, resolution: 1023
2024-02-16 14:23:41 DEBUG mcp3000.py(55)[__init__] cmd_func: <function _create_cmd_3002 at 0xb6789270>
2024-02-16 14:23:41 DEBUG mcp3000.py(56)[__init__] read_func: <function _analog_read_3002 at 0xb67674f8>
2024-02-16 14:23:41 INFO read_1_thermistorWithMCP3000.py(85)[<module>] adc: <lib.mcp3000.MCP3000 object at 0xb6642f90>
2024-02-16 14:23:42 DEBUG mcp3000.py(61)[analog_read] ch: 0, din: [104, 0]
2024-02-16 14:23:42 DEBUG mcp3000.py(66)[analog_read] count: 2
2024-02-16 14:23:42 DEBUG mcp3000.py(68)[analog_read] r_data[0]: 0x01
2024-02-16 14:23:42 DEBUG mcp3000.py(68)[analog_read] r_data[1]: 0xb7
2024-02-16 14:23:42 DEBUG mcp3000.py(69)[analog_read] adc_value: [439] - 0x1b7
2024-02-16 14:23:42 INFO read_1_thermistorWithMCP3000.py(91)[<module>] volt: 1.42
2024-02-16 14:23:42 DEBUG analogtempsensors.py(52)[temperature_thermistor] rx: 13302.96, xa: 0.00008, xb: 0.00335, temp: 17.79
2024-02-16 14:23:42 INFO read_1_thermistorWithMCP3000.py(94)[<module>] Temp 17.8
```