※なにか気になる点がありましたらコメント欄にご記入ください。
目次
1.はじめに
以前の記事の続編です。以前書いた記事では、Pico-SDK C/C++ 環境での開発の進め方について述べました。今回は、Raspberr Pi Pico(以下Pico と記述) によるUART接続をするコードを、実際にPico-SDK C/C++ 環境にて開発してみました。
以前書いた記事:pico-sdk C/C++ での開発の進め方 - Tanuki_Bayashin’s diary
開発環境:Windows10 Raspberry Pi Pico(C/C++により記述) ubuntu Visual Studio 2022 cmake など
PicoにてUART接続するコードは、ubuntu 内のpico-examples の中にあるhello_uart(フォルダuart 内)の中のhello_uart.c というファイルにて既に出来上がっています。しかしこのコードでは、数値は送信できません。
そこでここでは、数値もUARTにて送信できるようにしたuart2.c というコードを作ってみました。(開発の進め方は以前書いた記事に示してあります)
※ここでは自分なりに考えた処理を紹介していますが、後日、以下のやり方を他の方のブログにて見つけました。こちらの方がPC側に送信した後でもデータの扱いがしやすいことから、コードに書くには適していると思われます。(2022/08/11追記)
snprintf(s, sizeof(s), "%f", angle); uart_puts(UART_ID, s);
解説:1行目により、angleというfloatの変数をsという文字列に変換したのち、uart_puts()にてデータを送信しています。
2.コードの内容
2.1 1桁の数値を送信するには
1桁の数値(整数型とします)を送信するときの関数を、自分なりに考えてみました。何のことはない、if 文で各数値ごとに、それに見合う文字を送信しているだけです。
※uart_putc( ) は文字(変数の場合、const を付ける必要がある)を1つ送信する関数です。
(Pico‐SDK内で定義されている模様)
リスト1 1桁の数値を送信する関数 uart_integer_to_string()
void uart_integer_to_string(int16_t a) { if (a == 0) { uart_putc(UART_ID, '0'); } else if (a == 1) { uart_putc(UART_ID, '1'); } else if (a == 2) { uart_putc(UART_ID, '2'); } else if (a == 3) { uart_putc(UART_ID, '3'); } else if (a == 4) { uart_putc(UART_ID, '4'); } else if (a == 5) { uart_putc(UART_ID, '5'); } else if (a == 6) { uart_putc(UART_ID, '6'); } else if (a == 7) { uart_putc(UART_ID, '7'); } else if (a == 8) { uart_putc(UART_ID, '8'); } else if (a == 9) { uart_putc(UART_ID, '9'); } else { uart_putc(UART_ID, 'X'); } }
特に説明はいらないかと思います。else では'X' を送信するようにしました。ある種のデバッグ用の処理です。
2.2 複数の桁を送信する場合
複数の桁の数値を送信したいときは、数値を1桁ずつに区切ってやればいいと考えました。10進の場合だと、常用対数で何桁かを求め、最上位の数値を切り取ります。それを1の位まで繰り返したのが、リスト2に示す関数です。(数値は符号付き整数としました。この後用いる予定のセンサーが扱うデータが、16ビットの符号付整数だからです)
少し詳しく説明します。数値として’12345’ を用います。
ⅰ)常用対数を求めます
ⅱ)この値の小数点以下を切り捨てます(floor関数を用います)
ⅲ)今度はこの値4を用いて10の4乗(pow関数を使用)で数値’12345’ を割ると、
ⅳ)さらに小数点以下を切り捨てると、最上位の値、’1’を求めることができます。
この値をUARTにて送信します。
ⅴ)これを10の位まで行い、for 文の外で1の位の値をUARTにて送信しています。
(1つ下の桁での計算をする前に、
のように、最上位の値を引き算しています)
※uart_puts( ) は文字列を1つ送信する関数です。
(Pico‐SDK内で定義されている模様)
リスト2 複数の桁を送信する関数 sendDataByUART() (負の数の場合にも対応しています)
void sendDataByUART(int16_t x) { int16_t digit, a; if (x < 0) { x = -1 * x; uart_putc(UART_ID, '-'); } digit = floor(log10((double)x)); for (int j = digit; j > 0; j--) { a = floor(x / pow(10.0, j)); x = x - a * pow(10.0, j); uart_integer_to_string(a); } uart_integer_to_string(x); uart_puts(UART_ID, "\n\r"); sleep_ms(100); }
この関数により、データ1つ分を送信可能です。
※この方式だと、データの型の問題がクリアされていれば、小数や2進数(小数含む)の場合にも、1桁ずつ送信できるのではと、思っています。(時間のある時に検証したいです)
2.3 main() 内での処理
リスト3にmain() 内での処理を示します。送信したいデータを配列に収めました。
リスト3 無限ループの部分を中心に示します
int16_t data[6] = { 1, 0, -200, 32767, -900, -32767 }; int16_t x; while (1) { for (int i = 0; i < 6; i++) { x = data[i]; sendDataByUART(x); } sleep_ms(250); }
3.PicoからPCにデータを送信する(動画)
実際にデータを送信する様子を動画にて示します。
動画の前半部分は、実際にコードをビルドする様子を示しました。データを送信する様子では、負の値も’-’ の符号付きで表示されています。センサーの値を送信するには十分なようです。(符号付16ビット整数)