Raspberry Pi Pico で UART を二本使う

# 本記事を書くきっかけ
以前、Raspberry Pi Pico（以降 パイピコ）で、Sigfox 通信を実現する記事を記載しました。
https://qiita.com/kataoka_se/items/293c7d7a2e466f1f5f65

上記の記事では、uart0 と Sigfox モジュールを接続し、シリアル通信で機能実現を行ったのですが、より入り組んだコードを組む上でとりあえずログぐらいは取れるようにしようと printf() の内容を USB 経由で PC に転送させたところ、そのUSBからのログと uart0 の通信が混雑してしまい、まともに動かない状態になりました。

より詳しく説明すると、uart0 に ```"AT$I=10\r"```　という ATコマンドを送ると、Sigfoxモジュールから デバイスID が返ってくるのですが、それを USB経由でログを出力しようとすると、そのログが再度 uart0 にも流れてしまい Sigfox モジュールから "Parse Error" というレスポンスが返ってきてしまうので、使い物にならないのです。

その解決策を模索したところ、パイピコには UART が2系統あるで、一つを Sigfoxモジュールの通信用とし、もう一方をログ出力用としようと考えました。
 
## パイピコの uart 
パイピコには、uart が2系統搭載されています。
https://www.switch-science.com/catalog/6900/

今回の実験では、uart0 に Sigfox モジュールを接続し、uart1 の USB - TTLシリアルアダプター を接続しPCからログを確認します。

# 使用した機材
* Raspberry Pi Pico
* Sigfox Break Out Board（Sigfoxモジュール）
    * https://www.switch-science.com/catalog/5373/
* DSD TECH SH-U09C USB - TTLシリアルアダプター + FTDI FT232RLチップ
    * https://www.amazon.co.jp/DSD-Tech-TTL%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%AB%E3%82%A2%E3%83%80%E3%83%97%E3%82%BFwith-ft232rl%E3%83%81%E3%83%83%E3%83%97%E3%81%A8%E4%BA%92%E6%8F%9B%E6%80%A7Windows-10%E3%80%818%E3%80%817%E3%81%A8Mac/dp/B07BBPX8B8
    

# 構成と接続

Sigfoxモジュールとパイピコ、TTLシリアルアダプターとパイピコはそれぞれ下記のポートを接続します。


|  パイピコ UART|  パイピコ 物理的ピン番号  | GPIOピン番号	| 接続先 |
| ---- | ---- | ---- |---- |
|  UART0_TX  | 1 | 0 | Sigfox モジュール RX | 
|  UART0_RX  | 2 | 1 | Sigfox モジュール TX |
|  UART1_TX  | 6 | 4 | TTLシリアルアダプター RX | 
|  UART1_RX  | 7 | 5 | TTLシリアルアダプター TX |

* Sigfox モジュール は、パイピコから 3.3V と GND を取ります
* TTLシリアルアダプターは、GND だけでOKです

![connection.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/716263/ae28dc4b-3d5c-8d18-3f5f-715689fa380c.jpeg)



# ソースコード

``` c
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/uart.h"


#define UART_ID_SIGFOX  uart0
#define UART_ID_TTL     uart1

#define BAUD_UART_0_RATE 9600
#define BAUD_UART_1_RATE 115200

#define UART_SIGFOX_TX_PIN 0
#define UART_SIGFOX_RX_PIN 1

#define UART_TTL_TX_PIN 4
#define UART_TTL_RX_PIN 5


int main() {
    stdio_init_all();

    uart_init(UART_ID_SIGFOX, BAUD_UART_0_RATE);
    uart_init(UART_ID_TTL, BAUD_UART_1_RATE);
        
    gpio_set_function(UART_SIGFOX_TX_PIN, GPIO_FUNC_UART);
    gpio_set_function(UART_SIGFOX_RX_PIN, GPIO_FUNC_UART);
    gpio_set_function(UART_TTL_TX_PIN, GPIO_FUNC_UART);
    gpio_set_function(UART_TTL_RX_PIN, GPIO_FUNC_UART);    
    
    uart_puts(UART_ID_TTL, "Sigfox - Dual UART\n");

    sleep_ms(1000 * 10);
    
    while (true) {
        uart_puts(UART_ID_SIGFOX, "AT$I=10\r");   
        
        sleep_ms(10);

        uart_puts(UART_ID_TTL, "Device ID : ");
        while (uart_is_readable(UART_ID_SIGFOX)) {
            char ret = uart_getc(UART_ID_SIGFOX);
            uart_putc(UART_ID_TTL, ret);
        }

        sleep_ms(1000);
        
    }
    return 0;
}

```

# Tera Term で接続
Tera Term を使用して、シリアルポートに接続。
![teraterm2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/716263/c8e85982-e8b9-de99-bc03-65cf1e8b171c.png)

今回、パイピコ側のボーレートを 115200 に設定しているので、Tera Term 側で速度を合わせて接続。

![teraterm2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/716263/ad40dbbb-64e5-855e-ed27-81b1415a5640.png)


無事に、UART0 経由で取得した、Sigfox モジュールの Device ID を UART1 にシリアル転送して PC上（Tera Term）確認することができました。

# 気が付いてしまった事
ここまでやってようやく気が付いたのですが、uart0 と usb が混線するなら、Sigfox を uart1 に接続して、ログ出力を usb からとればいいのでは？と今更気が付きました。

実際やってみると、下記のコードで Sigfox モジュール と UART 通信しながら、USB からログを取得できました。

```
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/uart.h"


#define UART_ID_SIGFOX  uart1

#define BAUD_UART_1_RATE 9600

#define UART_SIGFOX_TX_PIN 4
#define UART_SIGFOX_RX_PIN 5


int main() {
    stdio_init_all();
    char response[1024];
    int ptr = 0;

    uart_init(UART_ID_SIGFOX, BAUD_UART_1_RATE);

    gpio_set_function(UART_SIGFOX_TX_PIN, GPIO_FUNC_UART);
    gpio_set_function(UART_SIGFOX_RX_PIN, GPIO_FUNC_UART);

    printf("Sigfox - UART with USB\n");

    sleep_ms(1000 * 10);
    
    while (true) {
        uart_puts(UART_ID_SIGFOX, "AT$I=10\r");   
        ptr = 0;
        sleep_ms(10);

        while (uart_is_readable(UART_ID_SIGFOX)) {
            char ret = uart_getc(UART_ID_SIGFOX);
            response[ptr++] = ret;
        }

        response[ptr] = '\0';
        
        printf("Device ID : %s", response);

        sleep_ms(1000);
        
    }
    return 0;
}
```
uart1 から受信したデータの扱いが雑ですが、動作確認目的なのでご容赦ください。