Raspberry Pi Pico + MH-Z19C で部屋の CO2 濃度を監視したい

# 作業録

# 1. H/W 構成
- Raspberry Pi Pico
- 4-digit LED
    - 安全域と危険域で色を分けたかった
        - 他に LED を点けてもよかった
        - ブザーは寝てるときとかうるさそうだったのでボツ
    - `OSL40363-LRYG`（赤/黄緑　カソードコモン）
    - https://akizukidenshi.com/catalog/g/gI-15999/
- CO2 センサー
    - `MH-Z19C`
    - https://akizukidenshi.com/catalog/g/gM-16142/
- ブレッドボード
    - 5穴版だと `MH-Z19C` が絶妙に刺さらない
        - 足の間隔が `29.54mm` で、2.54mm ピッチだと微妙に合わない（`29.54/2.54 = 11.63...`）が、6穴版の B-L 行に押し込めば刺さる
    - `0165-40-4-39010`
    - https://akizukidenshi.com/catalog/g/gP-12366/
- 電源キット
    - 一式を電池駆動させたかったから買った
        - Raspberry Pi Pico が CR2032 一個で駆動できることは確認した
    - `AE-COINCELL-BOARD-I(S)`
    - https://akizukidenshi.com/catalog/g/gK-09586/
- その他
    - DC昇圧回路
        - `MH-Z19C` の動作電圧が 5V だが、電池駆動だと VBUS が使えなく、3.3V を昇圧する必要がある
    - `AE-XCL102D503CR-G`
    - https://akizukidenshi.com/catalog/g/gK-13065/


## 1.1 配線図 (Raspberry Pi Pico USB)
![配線図-USB.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278058/ab936da9-9efb-96fd-0e71-3f01346f2a0a.jpeg)

## 1.2 配線図（Standalone）
- 電源キットで動かそうとしたら、MH-Z19C繋いでると Pico が起動しない











# 2. プロジェクト作成
- https://github.com/uyiromo/pico-co2
- Chapter 8, Creating your own Project
    - https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf
- 要らないかなと思って SWD はそもそもピンが付いてない


# 3. 4-digit LED を制御する
- https://github.com/uyiromo/pico-co2/commit/2eec3c32df137d31616a966a5499cffb73e12f5e

## 3.1 ダイナミック点灯の制御
- `OSL40363-LRYG` はカソードコモンなので、ダイナミック点灯の制御が必要
    1. Specific Digit のカソードを Low にする
    1. 7-seg LED の制御を入れる
    1. All Digit のカソードを High にする
    1. を繰り返す 
- ピンの定義を書き下すのが面倒くさい
    - 多分これもっと便利な方法がある
    - C の `const` は入れ子にできないから面倒
- LED初期化
    - マスクで「初期化（Output Enable/Value Clear＋SIOに設定）」「向きを OUT に」

```c:led/led.c
   gpio_init_mask(MASK_LED_PIN_ALL);
   gpio_set_dir_out_masked(MASK_LED_PIN_ALL);
```

- LED制御
    - アノード、カソードのマスクを OR して `gpio_set_mask`
    - 最初は `gpio_clr_mask` ではなく `gpio_set_mask` でカソードマスクを全て High にしていた
        - `gpio_set_mask` を「ビットが立っているなら HIGH、ビットが落ちているなら LOW にする」機能と勘違いしていたため
        - 実際は「ビットが立っているなら HIGH」だけなので、カソードマスクを全て立てると以降全て反応しない

```c:led/led.c
    for (i = 3; i >= 0; --i) {
        /* Generate mask from amask (anode mask) and cmask (cathode mask) */
        amask = amasks[i];
        cmask = LED_MASK[v * 0xF];
        mask = amask | cmask;

        /* set mask, sleep 100ms, clear cathodes */
        gpio_set_mask(mask);
        sleep_ms(1);
        gpio_clr_mask(mask);
        v = (v >> 4);
    }
```

## 3.2 BCD (Binary-Coded Decimal) 表示
- CO2 センサーの値をhexで表示されても分からない
    - ぱっと見で分かる人ならいい
    - CO2濃度が4桁を超えるのは明らかに異常なので、BCDで4桁表示できれば十分
        - https://www.mhlw.go.jp/content/11130500/000771215.pdf
- BCD変換
    - お手軽に、ポインタを渡してそこに書いてもらう
    - Pico は HW Divider を持っているのでそれにやらせる
    - 10,000 以上の値が来ても無視する

```c:led/led.c
void get_bcd(uint value, uint *buf)
{
    int i;
    uint v;

    v = value;
    for (i = 3; i >= 0; --i) {
        buf[i] = (v % 10);
        v /= 10;
    }

    return;
}
```

## 3.3 LED を常時点灯させる
- CO2 センサーの制御をしたいので、LED制御は Core 1 に任せる
- Pico SDK の multicore 機能を使う

```cmake:led/CMakeLists.txt
target_link_libraries(led pico_stdlib pico_multicore)
```


```c:led/led_test.c
#include "pico/multicore.h"

uint led_value;

void control_led()
{
    uint v;
    while (1) {
        v = led_value;
        set_led(v, GREEN);
    }

    return;
}

int main()
{

    /* Initialize LED Pins */
    init_led();

    led_value = 0;
    multicore_launch_core1(control_led);
    while (1) {
        ++led_value;
        sleep_ms(1000);
    }

    return 0;
}
```

## 3.4 LED 関連をサブディレクトリに移動して、テスト用mainの作成
### トップディレクトリ
```cmake:CMakeLists.txt
# led
add_subdirectory(led)
```

### サブディレクトリ led
- led 操作関数群は利用できるようにライブラリを作成する

```cmake:led/CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
include(../pico_sdk_import.cmake)

project(lib_led C CXX ASM)

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

pico_sdk_init()

# Configurations for led.a
add_library(led STATIC led.c)
target_link_libraries(led pico_stdlib)

# Configurations for led_test
add_executable(led_test led_test.c)
pico_enable_stdio_usb(led_test 1)
pico_enable_stdio_uart(led_test 0)
pico_add_extra_outputs(led_test)
target_link_libraries(led_test led pico_stdlib pico_multicore)
```

```c:led/led_tets.c
#include "hardware/gpio.h"
#include "pico/binary_info.h"
#include "pico/multicore.h"
#include "pico/stdlib.h"
#include <stdio.h>

#include "led.h"

uint led_value;

void control_led()
{
    uint v;
    while (1) {
        v = led_value;
        LED_COLOR c = (v % 2 == 0) ? GREEN : RED;
        set_led(v, c);
    }

    return;
}

int main()
{
    stdio_init_all();

    /* Initialize LED Pins */
    init_led();

    led_value = 0;
    multicore_launch_core1(control_led);
    while (1) {
        ++led_value;
        sleep_ms(1000);
    }

    return 0;
}
```

## 3.5 テスト
- 一秒ごとに RED/GREEN を切り替えながら BCD 表示でカウントアップすれば OK

```zsh
% mkdir build
% cd build
% export PICO_SDK_PATH=$HOME/pico-sdk
% cmake ..
Using PICO_SDK_PATH from environment ('/home/pi/pico-sdk')
PICO_SDK_PATH is /home/pi/pico-sdk
Defaulting PICO_PLATFORM to rp2040 since not specified.
Defaulting PICO platform compiler to pico_arm_gcc since not specified.
-- Defaulting build type to 'Release' since not specified.
PICO compiler is pico_arm_gcc
-- The C compiler identification is GNU 8.3.1
-- The CXX compiler identification is GNU 8.3.1
-- The ASM compiler identification is GNU
-- Found assembler: /usr/bin/arm-none-eabi-gcc
Defaulting PICO target board to pico since not specified.
Using board configuration from /home/pi/pico-sdk/src/boards/include/boards/pico.h
-- Found Python3: /usr/bin/python3.9 (found version "3.9.2") found components: Interpreter 
TinyUSB available at /home/pi/pico-sdk/lib/tinyusb/src/portable/raspberrypi/rp2040; enabling build support for USB.
-- Configuring done
-- Generating done
-- Build files have been written to: /home/pi/pico-co2/build

% make led_test
Scanning dependencies of target bs2_default
[  1%] Building ASM object pico-sdk/src/rp2_common/boot_stage2/CMakeFiles/bs2_default.dir/compile_time_choice.S.obj
[  1%] Linking ASM executable bs2_default.elf
[  1%] Built target bs2_default
Scanning dependencies of target bs2_default_padded_checksummed_asm
[  3%] Generating bs2_default.bin
[  3%] Generating bs2_default_padded_checksummed.S
[  3%] Built target bs2_default_padded_checksummed_asm
Scanning dependencies of target led
[  3%] Building C object led/CMakeFiles/led.dir/led.c.obj
[  4%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_stdlib/stdlib.c.obj
[  4%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/hardware_gpio/gpio.c.obj
[  6%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/hardware_claim/claim.c.obj
[  6%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_platform/platform.c.obj
[  7%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/hardware_sync/sync.c.obj
[  7%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/hardware_uart/uart.c.obj
[  9%] Building ASM object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/hardware_divider/divider.S.obj
[  9%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/common/pico_time/time.c.obj
[ 10%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/common/pico_time/timeout_helper.c.obj
[ 10%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/hardware_timer/timer.c.obj
[ 12%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/common/pico_sync/sem.c.obj
[ 12%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/common/pico_sync/lock_core.c.obj
[ 14%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/common/pico_sync/mutex.c.obj
[ 14%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/common/pico_sync/critical_section.c.obj
[ 15%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/common/pico_util/datetime.c.obj
[ 15%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/common/pico_util/pheap.c.obj
[ 17%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/common/pico_util/queue.c.obj
[ 17%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_runtime/runtime.c.obj
[ 18%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/hardware_clocks/clocks.c.obj
[ 18%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/hardware_irq/irq.c.obj
[ 20%] Building ASM object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/hardware_irq/irq_handler_chain.S.obj
[ 20%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/hardware_pll/pll.c.obj
[ 21%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/hardware_vreg/vreg.c.obj
[ 21%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/hardware_watchdog/watchdog.c.obj
[ 23%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/hardware_xosc/xosc.c.obj
[ 23%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_printf/printf.c.obj
[ 25%] Building ASM object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_bit_ops/bit_ops_aeabi.S.obj
[ 25%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_bootrom/bootrom.c.obj
[ 26%] Building ASM object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_divider/divider.S.obj
[ 26%] Building ASM object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_double/double_aeabi.S.obj
[ 28%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_double/double_init_rom.c.obj
[ 28%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_double/double_math.c.obj
[ 29%] Building ASM object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_double/double_v1_rom_shim.S.obj
[ 29%] Building ASM object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_int64_ops/pico_int64_ops_aeabi.S.obj
[ 31%] Building ASM object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_float/float_aeabi.S.obj
[ 31%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_float/float_init_rom.c.obj
[ 32%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_float/float_math.c.obj
[ 32%] Building ASM object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_float/float_v1_rom_shim.S.obj
[ 34%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_malloc/pico_malloc.c.obj
[ 34%] Building ASM object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_mem_ops/mem_ops_aeabi.S.obj
[ 35%] Building ASM object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_standard_link/crt0.S.obj
[ 35%] Building CXX object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_standard_link/new_delete.cpp.obj
[ 37%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_standard_link/binary_info.c.obj
[ 37%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_stdio/stdio.c.obj
[ 39%] Building C object led/CMakeFiles/led.dir/home/pi/pico-sdk/src/rp2_common/pico_stdio_uart/stdio_uart.c.obj
[ 39%] Linking CXX static library libled.a
[ 39%] Built target led
Scanning dependencies of target ELF2UF2Build
[ 40%] Creating directories for 'ELF2UF2Build'
[ 40%] No download step for 'ELF2UF2Build'
[ 42%] No update step for 'ELF2UF2Build'
[ 42%] No patch step for 'ELF2UF2Build'
[ 43%] Performing configure step for 'ELF2UF2Build'
-- The C compiler identification is GNU 10.2.1
-- The CXX compiler identification is GNU 10.2.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/pi/pico-co2/build/elf2uf2
[ 43%] Performing build step for 'ELF2UF2Build'
Scanning dependencies of target elf2uf2
[ 50%] Building CXX object CMakeFiles/elf2uf2.dir/main.cpp.o
[100%] Linking CXX executable elf2uf2
[100%] Built target elf2uf2
[ 43%] No install step for 'ELF2UF2Build'
[ 43%] Completed 'ELF2UF2Build'
[ 43%] Built target ELF2UF2Build
Scanning dependencies of target led_test
[ 45%] Building C object led/CMakeFiles/led_test.dir/led_test.c.obj
[ 45%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_stdlib/stdlib.c.obj
[ 46%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_gpio/gpio.c.obj
[ 46%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_claim/claim.c.obj
[ 48%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_platform/platform.c.obj
[ 48%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_sync/sync.c.obj
[ 50%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_uart/uart.c.obj
[ 50%] Building ASM object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_divider/divider.S.obj
[ 51%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/common/pico_time/time.c.obj
[ 51%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/common/pico_time/timeout_helper.c.obj
[ 53%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_timer/timer.c.obj
[ 53%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/common/pico_sync/sem.c.obj
[ 54%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/common/pico_sync/lock_core.c.obj
[ 54%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/common/pico_sync/mutex.c.obj
[ 56%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/common/pico_sync/critical_section.c.obj
[ 56%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/common/pico_util/datetime.c.obj
[ 57%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/common/pico_util/pheap.c.obj
[ 57%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/common/pico_util/queue.c.obj
[ 59%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_runtime/runtime.c.obj
[ 59%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_clocks/clocks.c.obj
[ 60%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_irq/irq.c.obj
[ 60%] Building ASM object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_irq/irq_handler_chain.S.obj
[ 62%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_pll/pll.c.obj
[ 62%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_vreg/vreg.c.obj
[ 64%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_watchdog/watchdog.c.obj
[ 64%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_xosc/xosc.c.obj
[ 65%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_printf/printf.c.obj
[ 65%] Building ASM object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_bit_ops/bit_ops_aeabi.S.obj
[ 67%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_bootrom/bootrom.c.obj
[ 67%] Building ASM object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_divider/divider.S.obj
[ 68%] Building ASM object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_double/double_aeabi.S.obj
[ 68%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_double/double_init_rom.c.obj
[ 70%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_double/double_math.c.obj
[ 70%] Building ASM object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_double/double_v1_rom_shim.S.obj
[ 71%] Building ASM object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_int64_ops/pico_int64_ops_aeabi.S.obj
[ 71%] Building ASM object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_float/float_aeabi.S.obj
[ 73%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_float/float_init_rom.c.obj
[ 73%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_float/float_math.c.obj
[ 75%] Building ASM object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_float/float_v1_rom_shim.S.obj
[ 75%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_malloc/pico_malloc.c.obj
[ 76%] Building ASM object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_mem_ops/mem_ops_aeabi.S.obj
[ 76%] Building ASM object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_standard_link/crt0.S.obj
[ 78%] Building CXX object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_standard_link/new_delete.cpp.obj
[ 78%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_standard_link/binary_info.c.obj
[ 79%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_stdio/stdio.c.obj
[ 79%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_stdio_usb/reset_interface.c.obj
[ 81%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_stdio_usb/stdio_usb.c.obj
[ 81%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_stdio_usb/stdio_usb_descriptors.c.obj
[ 82%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/lib/tinyusb/src/portable/raspberrypi/rp2040/dcd_rp2040.c.obj
[ 82%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/lib/tinyusb/src/portable/raspberrypi/rp2040/rp2040_usb.c.obj
[ 84%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/lib/tinyusb/src/device/usbd.c.obj
[ 84%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/lib/tinyusb/src/device/usbd_control.c.obj
[ 85%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/audio/audio_device.c.obj
[ 85%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/cdc/cdc_device.c.obj
[ 87%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/dfu/dfu_device.c.obj
[ 87%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/dfu/dfu_rt_device.c.obj
[ 89%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/hid/hid_device.c.obj
[ 89%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/midi/midi_device.c.obj
[ 90%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/msc/msc_device.c.obj
[ 90%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/net/ecm_rndis_device.c.obj
[ 92%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/net/ncm_device.c.obj
[ 92%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/usbtmc/usbtmc_device.c.obj
[ 93%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/vendor/vendor_device.c.obj
[ 93%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/video/video_device.c.obj
[ 95%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/lib/tinyusb/src/tusb.c.obj
[ 95%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/lib/tinyusb/src/common/tusb_fifo.c.obj
[ 96%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c.obj
[ 96%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_unique_id/unique_id.c.obj
[ 98%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_flash/flash.c.obj
[ 98%] Building C object led/CMakeFiles/led_test.dir/home/pi/pico-sdk/src/rp2_common/pico_multicore/multicore.c.obj
[100%] Linking CXX executable led_test.elf
[100%] Built target led_test

pi@raspberrypi % sudo cp led/led_test.uf2 /media/pi/RPI-RP2
```


# 4. MH-Z19C からデータを取得する
- https://github.com/uyiromo/pico-co2/commit/917588c07bd428259ae62473271f0171335598bd

## 4.1 UART でデータ取得
- 配線
    - Pico: UART1 (GP4/GP5) を使う
        - https://akizukidenshi.com/download/ds/raspberry/pico-datasheet.pdf
    - MH-Z19C: UART を使う
        - https://akizukidenshi.com/download/ds/winsen/MH-Z19C_20210518.pdf
    - Vin-GND-RX-TX (MH-Z19C) <--> VBUS-GND-TX-RX (Pico)
        - TX-TX, RX-RX をつなぐものと勘違いしてかなりの時間を無駄にしてしまった……

- UART 初期化
    - Baud Rate: 9600, Data: 8-bit, Stop: 1-bit, Parity: None

```c:sensor/sensor.c
    #include "hardware/uart.h"

    #define UART_ID   (uart1)
    #define MHZ19C_HD (1)
    #define MHZ19C_TX (4)  // UART1 TX
    #define MHZ19C_RX (5)  // UART1 RX

    uart_init(UART_ID, 9600);
    gpio_set_function(MHZ19C_TX, GPIO_FUNC_UART);
    gpio_set_function(MHZ19C_RX, GPIO_FUNC_UART);
    uart_set_format(UART_ID, 8, 1, UART_PARITY_NONE);
```

- UART 取得
    - DataSheet に従ってコマンド送信＆受信
    - 一応受信データの CHECKSUM も計算して不正なら不正な値を返す

| | Byte0 | Byte1 | Byte2 | Byte3 | Byte4 | Byte5 | Byte6 | Byte7 | Byte8 |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| TX | 0xFF  | 0x01  | 0x86  | 0x00  | 0x00  | 0x00  | 0x00  | 0x00  | 0x79  |
| RX | 0xFF  | 0x86  | HIGH  | LOW  | -  | -  | -  | -  | CHECKSUM  |

```c:sensor/sensor.c
    const int8_t tx[9] = {  0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79 };
    uint8_t rx[9];
    uint8_t checksum;
    int concentration;

    // Send/Recv Read CO2 command
    uart_write_blocking(UART_ID, tx, sizeof(tx));
    uart_read_blocking(UART_ID, rx, sizeof(rx));
      
    // sanity check 
    concentration = rx[2] * 256 + rx[3];
    checksum = get_checksum(rx);
    
    return (checksum == rx[8]) ? concentration : -1;
```

# 4.2 サブディレクトリとテストハーネスを作成 
### トップディレクトリ

```cmake:CMakeLists.txt
# sensor
add_subdirectory(sensor)
```


### サブディレクトリ sensor
- sensor 操作関数群は利用できるようにライブラリを作成する

```cmake:led/CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
include(../pico_sdk_import.cmake)

project(lib_sensor C CXX ASM)

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

pico_sdk_init()

# Configurations for sensor.a
add_library(sensor STATIC sensor.c)
target_link_libraries(sensor pico_stdlib)

# Configurations for sensor_test
add_executable(sensor_test sensor_test.c)
pico_enable_stdio_usb(sensor_test 1)
pico_enable_stdio_uart(sensor_test 0)
pico_add_extra_outputs(sensor_test)
target_link_libraries(sensor_test sensor pico_stdlib pico_multicore)
```

```c:led/led_test.c
#include "hardware/gpio.h"
#include "pico/binary_info.h"
#include "pico/multicore.h"
#include "pico/stdlib.h"
#include <stdio.h>

#include "sensor.h"

int main()
{
    stdio_init_all();

    /* Initialize sensor Pins */
    init_sensor();

    while (true) {
        /* read concentration */
        int concentration = read_concentration();
        printf("current concentration: %d\n", concentration);

        sleep_ms(100);
    }

    return 0;
}
```

## 4.3 テスト
- CO2 濃度が UART-USB に出力され続ければ OK

```zsh
% mkdir build
% cd build
% export PICO_SDK_PATH=$HOME/pico-sdk
% cmake ..
Using PICO_SDK_PATH from environment ('/home/pi/pico-sdk')
PICO_SDK_PATH is /home/pi/pico-sdk
Defaulting PICO_PLATFORM to rp2040 since not specified.
Defaulting PICO platform compiler to pico_arm_gcc since not specified.
-- Defaulting build type to 'Release' since not specified.
PICO compiler is pico_arm_gcc
-- The C compiler identification is GNU 8.3.1
-- The CXX compiler identification is GNU 8.3.1
-- The ASM compiler identification is GNU
-- Found assembler: /usr/bin/arm-none-eabi-gcc
Defaulting PICO target board to pico since not specified.
Using board configuration from /home/pi/pico-sdk/src/boards/include/boards/pico.h
-- Found Python3: /usr/bin/python3.9 (found version "3.9.2") found components: Interpreter 
TinyUSB available at /home/pi/pico-sdk/lib/tinyusb/src/portable/raspberrypi/rp2040; enabling build support for USB.
-- Configuring done
-- Generating done
-- Build files have been written to: /home/pi/pico-co2/build

% make led_test
Scanning dependencies of target bs2_default
[  0%] Building ASM object pico-sdk/src/rp2_common/boot_stage2/CMakeFiles/bs2_default.dir/compile_time_choice.S.obj
[  2%] Linking ASM executable bs2_default.elf
[  2%] Built target bs2_default
Scanning dependencies of target bs2_default_padded_checksummed_asm
[  4%] Generating bs2_default.bin
[  4%] Generating bs2_default_padded_checksummed.S
[  4%] Built target bs2_default_padded_checksummed_asm
Scanning dependencies of target sensor
[  4%] Building C object sensor/CMakeFiles/sensor.dir/sensor.c.obj
[  4%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_stdlib/stdlib.c.obj
[  7%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/hardware_gpio/gpio.c.obj
[  7%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/hardware_claim/claim.c.obj
[  7%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_platform/platform.c.obj
[  7%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/hardware_sync/sync.c.obj
[  9%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/hardware_uart/uart.c.obj
[  9%] Building ASM object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/hardware_divider/divider.S.obj
[  9%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/common/pico_time/time.c.obj
[ 12%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/common/pico_time/timeout_helper.c.obj
[ 12%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/hardware_timer/timer.c.obj
[ 12%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/common/pico_sync/sem.c.obj
[ 14%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/common/pico_sync/lock_core.c.obj
[ 14%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/common/pico_sync/mutex.c.obj
[ 14%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/common/pico_sync/critical_section.c.obj
[ 17%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/common/pico_util/datetime.c.obj
[ 17%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/common/pico_util/pheap.c.obj
[ 17%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/common/pico_util/queue.c.obj
[ 19%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_runtime/runtime.c.obj
[ 19%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/hardware_clocks/clocks.c.obj
[ 19%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/hardware_irq/irq.c.obj
[ 19%] Building ASM object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/hardware_irq/irq_handler_chain.S.obj
[ 21%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/hardware_pll/pll.c.obj
[ 21%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/hardware_vreg/vreg.c.obj
[ 21%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/hardware_watchdog/watchdog.c.obj
[ 24%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/hardware_xosc/xosc.c.obj
[ 24%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_printf/printf.c.obj
[ 24%] Building ASM object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_bit_ops/bit_ops_aeabi.S.obj
[ 26%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_bootrom/bootrom.c.obj
[ 26%] Building ASM object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_divider/divider.S.obj
[ 26%] Building ASM object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_double/double_aeabi.S.obj
[ 29%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_double/double_init_rom.c.obj
[ 29%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_double/double_math.c.obj
[ 29%] Building ASM object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_double/double_v1_rom_shim.S.obj
[ 31%] Building ASM object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_int64_ops/pico_int64_ops_aeabi.S.obj
[ 31%] Building ASM object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_float/float_aeabi.S.obj
[ 31%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_float/float_init_rom.c.obj
[ 31%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_float/float_math.c.obj
[ 34%] Building ASM object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_float/float_v1_rom_shim.S.obj
[ 34%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_malloc/pico_malloc.c.obj
[ 34%] Building ASM object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_mem_ops/mem_ops_aeabi.S.obj
[ 36%] Building ASM object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_standard_link/crt0.S.obj
[ 36%] Building CXX object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_standard_link/new_delete.cpp.obj
[ 36%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_standard_link/binary_info.c.obj
[ 39%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_stdio/stdio.c.obj
[ 39%] Building C object sensor/CMakeFiles/sensor.dir/home/pi/pico-sdk/src/rp2_common/pico_stdio_uart/stdio_uart.c.obj
[ 39%] Linking CXX static library libsensor.a
[ 39%] Built target sensor
Scanning dependencies of target ELF2UF2Build
[ 39%] Creating directories for 'ELF2UF2Build'
[ 41%] No download step for 'ELF2UF2Build'
[ 41%] No update step for 'ELF2UF2Build'
[ 41%] No patch step for 'ELF2UF2Build'
[ 43%] Performing configure step for 'ELF2UF2Build'
-- The C compiler identification is GNU 10.2.1
-- The CXX compiler identification is GNU 10.2.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/pi/pico-co2/build/elf2uf2
[ 43%] Performing build step for 'ELF2UF2Build'
Scanning dependencies of target elf2uf2
[ 50%] Building CXX object CMakeFiles/elf2uf2.dir/main.cpp.o
[100%] Linking CXX executable elf2uf2
[100%] Built target elf2uf2
[ 43%] No install step for 'ELF2UF2Build'
[ 43%] Completed 'ELF2UF2Build'
[ 43%] Built target ELF2UF2Build
Scanning dependencies of target sensor_test
[ 46%] Building C object sensor/CMakeFiles/sensor_test.dir/sensor_test.c.obj
[ 46%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_stdlib/stdlib.c.obj
[ 46%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_gpio/gpio.c.obj
[ 48%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_claim/claim.c.obj
[ 48%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_platform/platform.c.obj
[ 48%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_sync/sync.c.obj
[ 48%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_uart/uart.c.obj
[ 51%] Building ASM object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_divider/divider.S.obj
[ 51%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/common/pico_time/time.c.obj
[ 51%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/common/pico_time/timeout_helper.c.obj
[ 53%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_timer/timer.c.obj
[ 53%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/common/pico_sync/sem.c.obj
[ 53%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/common/pico_sync/lock_core.c.obj
[ 56%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/common/pico_sync/mutex.c.obj
[ 56%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/common/pico_sync/critical_section.c.obj
[ 56%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/common/pico_util/datetime.c.obj
[ 58%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/common/pico_util/pheap.c.obj
[ 58%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/common/pico_util/queue.c.obj
[ 58%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_runtime/runtime.c.obj
[ 60%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_clocks/clocks.c.obj
[ 60%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_irq/irq.c.obj
[ 60%] Building ASM object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_irq/irq_handler_chain.S.obj
[ 63%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_pll/pll.c.obj
[ 63%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_vreg/vreg.c.obj
[ 63%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_watchdog/watchdog.c.obj
[ 63%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_xosc/xosc.c.obj
[ 65%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_printf/printf.c.obj
[ 65%] Building ASM object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_bit_ops/bit_ops_aeabi.S.obj
[ 65%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_bootrom/bootrom.c.obj
[ 68%] Building ASM object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_divider/divider.S.obj
[ 68%] Building ASM object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_double/double_aeabi.S.obj
[ 68%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_double/double_init_rom.c.obj
[ 70%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_double/double_math.c.obj
[ 70%] Building ASM object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_double/double_v1_rom_shim.S.obj
[ 70%] Building ASM object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_int64_ops/pico_int64_ops_aeabi.S.obj
[ 73%] Building ASM object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_float/float_aeabi.S.obj
[ 73%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_float/float_init_rom.c.obj
[ 73%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_float/float_math.c.obj
[ 75%] Building ASM object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_float/float_v1_rom_shim.S.obj
[ 75%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_malloc/pico_malloc.c.obj
[ 75%] Building ASM object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_mem_ops/mem_ops_aeabi.S.obj
[ 75%] Building ASM object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_standard_link/crt0.S.obj
[ 78%] Building CXX object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_standard_link/new_delete.cpp.obj
[ 78%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_standard_link/binary_info.c.obj
[ 78%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_stdio/stdio.c.obj
[ 80%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_stdio_usb/reset_interface.c.obj
[ 80%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_stdio_usb/stdio_usb.c.obj
[ 80%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_stdio_usb/stdio_usb_descriptors.c.obj
[ 82%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/lib/tinyusb/src/portable/raspberrypi/rp2040/dcd_rp2040.c.obj
[ 82%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/lib/tinyusb/src/portable/raspberrypi/rp2040/rp2040_usb.c.obj
[ 82%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/lib/tinyusb/src/device/usbd.c.obj
[ 85%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/lib/tinyusb/src/device/usbd_control.c.obj
[ 85%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/audio/audio_device.c.obj
[ 85%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/cdc/cdc_device.c.obj
[ 87%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/dfu/dfu_device.c.obj
[ 87%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/dfu/dfu_rt_device.c.obj
[ 87%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/hid/hid_device.c.obj
[ 87%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/midi/midi_device.c.obj
[ 90%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/msc/msc_device.c.obj
[ 90%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/net/ecm_rndis_device.c.obj
[ 90%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/net/ncm_device.c.obj
[ 92%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/usbtmc/usbtmc_device.c.obj
[ 92%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/vendor/vendor_device.c.obj
[ 92%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/lib/tinyusb/src/class/video/video_device.c.obj
[ 95%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/lib/tinyusb/src/tusb.c.obj
[ 95%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/lib/tinyusb/src/common/tusb_fifo.c.obj
[ 95%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c.obj
[ 97%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_unique_id/unique_id.c.obj
[ 97%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/hardware_flash/flash.c.obj
[ 97%] Building C object sensor/CMakeFiles/sensor_test.dir/home/pi/pico-sdk/src/rp2_common/pico_multicore/multicore.c.obj
[100%] Linking CXX executable sensor_test.elf
[100%] Built target sensor_test

pi@raspberrypi % sudo cp led/led_test.uf2 /media/pi/RPI-RP2
```

### 

# 5. 完成させる
- https://github.com/uyiromo/pico-co2/commit/73559dbb3cc3dc09e35574e803e5a8fc376e2110
- マルチコアで処理させる
    - Core-0：CO2 センサの読み取り
        - 60秒ごと
    - Core-1：CO2 濃度を使って LED の常時点灯処理
        - 800ppm を超えたら赤、正常なら緑
    - コア間変数はグローバル変数で授受
        - Core-1 は、一応変数をコピーしてから処理する

- ディレクトリ構造
```zsh
% tree
.
├── CMakeLists.txt
├── led
│   ├── CMakeLists.txt
│   ├── led.c
│   ├── led.h
│   └── led_test.c
├── main.c
├── pico_sdk_import.cmake
├── sensor
│   ├── CMakeLists.txt
│   ├── sensor.c
│   ├── sensor.h
│   └── sensor_test.c
└── test.c
```


```cmake:CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
include(pico_sdk_import.cmake)

project(test_project C CXX ASM)

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

pico_sdk_init()

# test configs
add_executable(test test.c)
pico_enable_stdio_usb(test 1)
pico_enable_stdio_uart(test 0)
pico_add_extra_outputs(test)
target_link_libraries(test pico_stdlib)

# main configs
add_executable(main main.c)
pico_enable_stdio_usb(main 1)
pico_enable_stdio_uart(main 0)
pico_add_extra_outputs(main)
target_link_libraries(main led sensor pico_stdlib pico_multicore)
target_include_directories(main
    PRIVATE led
    PRIVATE sensor
)



# led
add_subdirectory(led)

# sensor
add_subdirectory(sensor)
```

```c:main.c
#include "hardware/gpio.h"
#include "pico/binary_info.h"
#include "pico/multicore.h"
#include "pico/stdlib.h"
#include <stdio.h>

#include "led.h"
#include "sensor.h"

uint led_value;

void control_led()
{
    uint v;
    while (1) {
        v = led_value;
        LED_COLOR c = (v > 800) ? RED : GREEN;
        set_led(v, c);
    }

    return;
}

int main()
{
    stdio_init_all();

    /* Initialize */
    init_led();
    init_sensor();

    led_value = 0;
    multicore_launch_core1(control_led);
    while (true) {
        // Read MH-Z19C every 60 seconds
        uint c = read_concentration();
        led_value = (c > 0) ? c : led_value;

        sleep_ms(60 * 1000);
    }

    return 0;
}
```