chakokuのブログ(rev4)

テック・コミック・ごくまれにチャリ

MicroPythonを使ってジャイロセンサを評価する

クオータニオンの理解*1が最後まで終っていないが、、クオータニオンがある程度わかっても、ドローンを制御するには、ジャイロセンサのXYZ軸変換とか、カルマンフィルタとかまだまだ技術の壁があることが分かった。で、、少し動かしながらセンサ類のデータ処理を理解したいと思い、ジャイロセンサとかをMicroPythonで制御したい。ここでいきなりRustだとTurnAroundTimeがハンパない。ESP32(MicroPython)と9DoFの組み合わせで勉強するか、あるいは、STVAL-DRONE01にMicroPythonを入れて、ボードに貼り付けられている6軸センサ(LSM6DSL)を制御するか。。どうしたものか。STVAL-DRONE01上のマイコンはSTM32F401CCというやつなんだが、あまりリソースが無い(SRAM:64KB/FlashMemory:256KB)のでMicroPythonが動くのかどうか不明。

MicroPythonはNUCLEO_F401REをサポートしているらしい。NUCLEO_F401REとSTVAL-DRONE01のハード構成と同じだったらそのままビルドしたら流用できそうだが、シリアルポートの定義とかよくわからない。PYB_UART_2ってなぜここでPyBoardが出てくるのだろうか。。

// UART config
#define MICROPY_HW_UART2_TX     (pin_A2)
#define MICROPY_HW_UART2_RX     (pin_A3)
#define MICROPY_HW_UART6_TX     (pin_C6)
#define MICROPY_HW_UART6_RX     (pin_C7)
// UART 2 connects to the STM32F103 (STLINK) on the Nucleo board
// and this is exposed as a USB Serial port.
#define MICROPY_HW_UART_REPL        PYB_UART_2
#define MICROPY_HW_UART_REPL_BAUD   115200

いきなりはハードル高いので、STMicroの評価ボード、NucleoL476RGにMicroPythonを入れてみた。いろんなところで紹介されているので細かいことは省略しますが、、自分の場合、boocho氏の所から、NucleoL476RG用のファームをもらってきて、USB経由でダウンロードしました。ダウンロードが終わると、MicroPythonが走って、USB経由でシリアル接続されます。だから、、シリアルポートに繋がなくても、USB経由(USBの先はUSB変換チップがあってその先はデバッガがあると理解しています)で、MicroPythonのシリアルコンソールと接続できている。が、、これは拡張基板のデバッガが賢いからUSB経由でシリアルが繋げられるのであって、STVAL-DRONE01の基板はUSB変換チップがあるものの、、それを期待していいのかどうか、、上記USB変換チップはレベル変換だけやっていそうで、STM32F401CCからはPA11(USB_DM),PA12(USB_DP)が出ていて、出口ですでにUSB用の信号になっていそうだ。だから。。。MicroPythonファームでUSBサポートしてくれていないと、USB経由ではシリアル接続できない。
NUCLEO_L476RG/mpconfigboard.hから引用していますが、この定義で、拡張ボードのデバッガ経由(USB)でMicroPythonとしてはシリアル接続できることになるのだろうか。。全く分かりません。

// UART config
#define MICROPY_HW_UART2_TX     (pin_A2)
#define MICROPY_HW_UART2_RX     (pin_A3)

#define MICROPY_HW_UART_REPL        PYB_UART_2
#define MICROPY_HW_UART_REPL_BAUD   115200

Nucleoの回路図をざっと見る限り、拡張ボードのデバッガもST-LINK相当のようで、、だったら手持ちのST-LINK互換のデバッガをSTVAL-DRONE01のデバッグポートに繋ぐとMicroPythonのシアルコンソールが繋がるのだろうか・・・そんな甘いモンではないだろう。。
MB1136C_schematic_layout/MB1136.pdf

試しに、ST-LINK互換のデバッガをSTM32の安いボード(デバッガなし)と接続したら、デバイスマネージャ上では単に以下のように出ただけであった。まぁそらそうか。

ユニバーサルシリアルバスデバイス
   STM32 STLink

シリアル出力のDefineが理解できないので、MicroPythonが焼けたとしてもコンソールでは接続できなさそうである。ということで、、STVAL-DRONE01上のSTM32F401CCにMircoPythonを焼く作業は行わず、ESP32+9DoFでジャイロとか姿勢を勉強することにする。もしSTVAL-DRONEのジャイロセンサを扱う時点になったらデータ転送プログラムだけをSTM32F401CCに焼いて、データ処理はESP32かPC側でやってもいいだろう。

■追記
defineを再度見ていて、シリアルコンソールはST-Link経由で接続と書かれていて、確かにボード上もシリアルはST-Linkの拡張デバッガボードに接続されている。使っている足は、PA2(USART_TX),PA3(USART_RX)である。これがPYB_UART_2に相当するのか?? PYB_USART_2ってどこで定義されているのか。。

ちなみに、、Droneに乗っているSTM32F401CCの場合、PA9(USART1_TX),PA10(USART1_RX)がシリアル用接続ピンと繋がっている。

stm32/uart.hで定義されていた。enum型の1始まりで、PYB_UART2は定数2のようである。

typedef enum {
    PYB_UART_NONE = 0,
    PYB_UART_1 = 1,
    PYB_UART_2 = 2,
    PYB_UART_3 = 3,
    PYB_UART_4 = 4,
    PYB_UART_5 = 5,
    PYB_UART_6 = 6,
    PYB_UART_7 = 7,
    PYB_UART_8 = 8,
} pyb_uart_t;

uart.cの初期化関数で、該当UARTが存在するか確認しているので、この辺の定数がボードのレジスタと一致していたら動きそうに思える。STM32側ではUART1と言ってるのだが、UART0もあるのか、レジスタの番地等はマイコンの仕様書で確認が必要。

    switch (uart_id) {
        #if defined(MICROPY_HW_UART1_TX) && defined(MICROPY_HW_UART1_RX)
        case PYB_UART_1: return true;
        #endif

        #if defined(MICROPY_HW_UART2_TX) && defined(MICROPY_HW_UART2_RX)
        case PYB_UART_2: return true;
        #endif

製品仕様書によると、UARTは3本らしい。レジスタマップは以下

0x4001 1400 - 0x4001 17FF USART6
0x4001 1000 - 0x4001 13FF USART1
0x4000 4400 - 0x4000 47FF USART2

stm32f4xx_hal_conf.h

#ifdef HAL_UART_MODULE_ENABLED
 #include "stm32f4xx_hal_uart.h"
#endif /* HAL_UART_MODULE_ENABLED */

#ifdef HAL_USART_MODULE_ENABLED
 #include "stm32f4xx_hal_usart.h"
#endif /* HAL_USART_MODULE_ENABLED */

また戻って来たけど、UART2ならPinA2/A3,UART6ならPinC6/C7だと。
MicroPythonとして指定できるのは、2か6,一方基板で繋がっているのは1だ。
だから、定義の追加が必要だろう。

// UART config
#define MICROPY_HW_UART2_TX     (pin_A2)
#define MICROPY_HW_UART2_RX     (pin_A3)
#define MICROPY_HW_UART6_TX     (pin_C6)
#define MICROPY_HW_UART6_RX     (pin_C7)

ビルドが通るかどうか分からないが、UART1をMicroPythonのコンソールに割り当てるには以下の記述になるかと

// UART config
#define MICROPY_HW_UART1_TX     (pin_A9)
#define MICROPY_HW_UART1_RX     (pin_A10)
#define MICROPY_HW_UART_REPL        PYB_UART_1
#define MICROPY_HW_UART_REPL_BAUD   115200

また、USART6はUQFN48(48pin QuadFlatPackage?)の場合、足が出ていないので使えない。
micropython-esp32/mpconfigboard.h at esp32 · micropython/micropython-esp32 · GitHub

*1:証明を追いかける程度