STマイクロエレクトロニクス社のNucleo F072RBボード、Arm社のMbed環境で大分お世話になったのですが、このところ「遊休」状態。IoTネットワークに接続できる装置(ラズパイ)などとバディを組ませて復活を目論見ます。今回はよりお手軽なAruduino環境でプログラミング。STM32、Uart沢山あるけど一体何番がつかえるのですか?
※「トホホな疑問」投稿順Indexはこちら
アイキャッチ画像に掲げましたのはいずれもArduino環境でビルドできるボード5品でございます。その中で中央の白いボードがNucleoボードです。Nucleoボードにもいくつか型式があるのですが、同一ボード型式であると搭載マイコン以外は皆同じに見えます(マイコンのスペックはかなり異なります。)手元には同一型式のNucleoボードがF401REとF072RBの2種あり、いずれも
-
- Arm Cortex-M系マイコンボード+ST-LINKデバッグアダプタ結合
- Arduino互換配列の拡張端子とST社仕様(Morpho)の拡張端子つき
- 出来の良いボード、お求めやすい価格
であります。そして、Arm社のMbed開発環境以外にもST社の自社開発環境、IAR社などのサードベンダの開発環境など充実、なのであります。しかし、Arm Cortex M4F搭載のR401REはまだしも、ぶっちゃけ
スペックの低いF072RBはだんだん肩身が狭くなっている
感じがいたします。32bit Arm Cortex-M0, 48MHz, 128KB Flash, 16KB SRAM。それでもArduino業界標準機?のUno、AVR 8bit ATmega328P, 16MHz, 32KB Flash, 2KB SRAMと比べたらかなり強力。Arduinoとしてならまだまだやれる?
ということで、ArduinoIDEにSTM32マイコンの環境を追加しArduinoでプログラミングを始めました。環境設定自体は、Arduino環境でESP32やSAMD51などのAVR以外のマイコンを使う場合と変わりありません。GitHubの以下のページに説明があるとおり、
ArduinoIDEのボードマネージャに以下を設定し、STM32マイコンを使えるようにするだけです。
https://github.com/stm32duino/BoardManagerFiles/raw/master/STM32/package_stm_index.json
これにより大量の種類のSTM32マイコン搭載ボードをArduino環境で開発可能になります。その中 Nucleo 64のカテゴリの中にR072RBもふくまれております。ArdinoIDEで新たなプロジェクトを始め、ボードを設定すれば、即座にNucleo R072RB用のコードをビルド可能。Nucleoは元々Arduino互換の拡張端子を備えているくらいなのでかなり互換性が高く、Arduino Unoのコードをコピペしても大抵のことはできてしまいそうです。ただし、STM32の方が仕様が大きいのでArduino Unoを上回るところを使いたい場合は変更しないとなりません。今回の疑問はまたしてもシリアルポートです(他のボードと接続するために。)
-
- Arduino UnoはUART一つ
- F072RBはU(S)ART4つ
4つもあるので
-
- USBシリアルに接続しているUARTはデバッグ用にとっておきたい。
- 残り3つのうち取り扱い易いArduino拡張端子で接続できる1チャンネルを選びたい。(Morpho端子は、数が多すぎて端子数えるのがメンドイのでなるべくパス)
という方針であります。まずは、Arduino環境でSTM32のSerial通信使うためのコアライブラリを探して中身を拝見いたしました。HardwareSerial.hというヘッダの中で
Serial1からSerial10、そして SerialLP1
などというオブジェクトが外部参照されていました。この定義はSTM32の各機種のORとった定義であろうと思われますが、11個は多いね。多分そのうちのいくつかがF072RBでも使える筈。ヘッダファイル類をさらっと調べた限り
-
- USART2という物理インタフェースがArduino UnoでSerialというお名前で使えるのRX(D0), TX(D1)に接続されているように見える
- USART2はHardwareSerial.h上はSerial2という名前で呼べる
ように見受けられました。早速、Serial2に対して、ダラダラと数字を垂れ流すテストコードを書いて動作させてみました。結論からいうと
Serial2に出力すると
USBシリアルには出力されるが、TX(D1)には出力されない。
です。Unoとちょっと挙動が違うよね、と思ってマニュアルを読んでみると、ちゃんと書いてありました。以下がその説明など記載されているボードマニュアルへのリンクです。
STM32 Nucleo-64 boards (MB1136) – UM1724
肝心な部分を引用さてていただくと以下のようです。ここでPA2がTX(D1)、PA3がRX(D0)端子に接続しているSTM32マイコンの実端子名です。
The USART2 interface available on PA2 and PA3 of the STM32 microcontroller can be connected to ST-LINK MCU, ST morpho connector, or to ARDUINO® connector. The choice can be changed by setting the related solder bridges.
確かにUSART2はUnoのTX/RXと同じ拡張端子に接続可能。しかし、半田ブリッジ(ボードの裏面に用意されています)を盛らないとつながらないようになってました。デフォルトではデバッグ用のST-LINKのコントローラを介してUSBシリアルに接続しているようです。Serial2は駄目だ、デバッグ用にとって置かないと。そこでもっとソースを深く読み込めば立派なのですが、面倒なので、端から確かめてみました(そんなことで良いのか。)無印のSerialを含めSerial1, Serial2, Serial3とトライしてみた結果が以下のようです。
-
- Serial(番号無)、Serial2と実体同じ、USBシリアルに接続。「伝統の」printf的デバッグにはこれだね。
- Serial1、ビルド時にエラー発生。
- Serial2、番号無のSerialと同じUSBシリアルに接続
- Serial3、ビルド時にエラー発生。
全部で11個あったですが、4個目で早くも諦めました。沢山ある筈なのに使えないじゃん!気を取り直しました。「既定のオブジェクト」にたよらず自分でHardwareSerialオブジェクトを初期化して使ってみればいいじゃん!大した手間じゃないし。。。
データシートで接続している筈の端子とUARTをインスタンス化、こんな感じ。
HardwareSerial serialX(PA_10, PA_9);
これは動作しました。なお、第一引数がRX, 第2がTXです。PA_10はArduino環境のD2端子、PA_9はD8端子。実際に結線したところがこちら。配線の行先はRaspberry Piの拡張端子に出ているUART、ttyS0です。
実際に動作した 「Lチカ+シリアル垂れ流し」のテストコードがこちら。インスタンス名はSerial1などとすると被るので、とりあえずserialXなどとしてありますが、何でも良いでしょう。実体ハード的にはUSART1の筈。
#include "HardwareSerial.h" HardwareSerial serialX(PA_10, PA_9); int count; void setup() { serialX.begin(115200); while(!serialX) {}; serialX.println("Start Serial"); pinMode(D13, OUTPUT); digitalWrite(D13, LOW); count = 0; } void loop() { serialX.println(count); if ((count % 2) == 0) { digitalWrite(D13, HIGH); } else { digitalWrite(D13, LOW); } count += 1; delay(5000); }
Raspbian OSのttyS0で接続していてF072RBから送られてきた文字列がこちら。ちゃんと接続されておりますで。
ま、動いたから良いけれど。御馴染みの開発環境、御馴染みのボードでも、組み合わせかえると、またいろいろあるのね。トホホ。