0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

スマート人感検出(SPD)ライブラリでスマート卓上ファンを作ってみた!(4)制作記 ~ SPDの移植

Last updated at Posted at 2025-09-03

この一連の記事ではスマート卓上ファンを作ってみます。このファンにはSTマイクロエレクトロニクスのToF(Time-of-Flight)測距センサを使っています。一部のToF測距センサはst.comで提供されるスマート人感検出(以下SPD : Smart Presence Detection)を使うことで高度な人感センサとして動作します。このSPDの結果を使い、羽の回転や左右の首振りを制御します。
0.1.「全体構成」.png

前の記事へのリンク
前回までの記事ではToFとSPDの紹介から始まり、機構・モータ制御の考察、STM32H533のプロジェクトの作成を進めてきました。この記事ではSPDライブラリ内にあるSTM32F401のプロジェクトをSTM32H533のプロジェクトに移植していきます!がんばっていきましょう!

4. SPDをNUCLEO-H533REへ移植する

次はSPDをNUCLEO-H533REに移植していきます。STSW-IMG048がSPDのソフトウェアライブラリのパッケージとなっており、ドライバやライブラリをはじめ、サンプルコードとしてSTM32のプロジェクトもありますが、NUCLEO-F401RE用になっています。ちまたで人気のSTM32H5シリーズには対応していません。粛々と移植をしていくしかありません。移植の途中で少し後悔をしたこともありましたので、素直にNUCLEO-F401REを使用しても大丈夫です。その場合は、この章は飛ばしていただけます。では、気を取り直して進めていきます。

4.1 ファイルのコピー

STSW-IMG048の「SmartPresenceDetectionKit_F401_1.0.0」フォルダからファイルをコピーします。Core/Inc,Core/Srcにコピーするファイルは以下のリストを参照してください。「VL53LMZ_ULD_API」フォルダはフォルダごとコピーします。「SPD_lib」フォルダは.aファイル以外をコピーして、.aファイルはMPUに合ったものが必要なので、「SPD_compiled_libraries_1.0.0」フォルダにある「libSPD_m33.a」をコピーします。

4.1.「ファイルのコピー」.png

4.2.「ファイルのコピー2」.png
「VL53LMZ_ULD_API」フォルダをコピーしたときには注意が必要です。STM32CubeIDEでは新しく出現したフォルダはコンパイルから外されます。フォルダを右クリックしてプロパティを開き、「Exclude resource from build」のチェックを外すのを忘れないようにしましょう。
4.3.「フォルダを追加した場合」.png

4.2 ファイルの小修正

前のファイルのコピーで小修正となっているファイルを修正しました。修正は少ないです。

ファイルごとの小修正コード詳細
platform.h
#include <stdint.h>
#include <string.h>
- #include "stm32f4xx.h"
+ #include "stm32h5xx.h"
stm32xxx_hal.h
#ifdef STM32F401xE
#include "stm32f4xx_hal.h"
#define MCU_NAME "STM32F401xE"
#endif
#ifdef STM32L476xx
#include "stm32l4xx_hal.h"
#define MCU_NAME "STM32L476"
#endif
+ #ifdef STM32H533xx
+ #include "stm32h5xx_hal.h"
+ #define MCU_NAME "STM32H533xx"
+ #endif
platform.c
#include "platform.h"
+ #include "main.h"
sensor_command.c
static void _ParseError( const char *fmt, ...){
    va_list ap;
    va_start(ap,fmt);
    SB_vprintf(fmt, ap);
-     SB_VDebug(fmt,ap);
+     //SB_VDebug(fmt,ap);
}
uart_trace.h
/**
 * Force TRACE_UART to 0 by default (if not defined in the project)
 */
- #define TRACE_UART  0
+ #define TRACE_UART  1

4.3 main.hの修正

ここも修正はありますが、そこまで多くありません。注意点としては参考にしているNUCLEO-F401RE用のプロジェクトではVL53L8CXが使われていることです。VL53L8CXを使う場合にはそのまま使えますが、VL53L7CXの場合にはコントロールするピンが1つ増えます。

main.hの修正コード詳細
main.hの型宣言
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/** Timing data
 */
+ typedef struct {
+ 	float ranging_frequency;	// [Hz]
+ 	int ranging_period; 		// [msec]
+ 	int prev_tstp;  			// [msec]
+ 	int curr_tstp;  			// [msec]
+ } APP_time_data;
/* USER CODE END ET */
main.hの型宣言
/* Private defines -----------------------------------------------------------*/
#define SWDIO_Pin GPIO_PIN_13
#define SWDIO_GPIO_Port GPIOA
#define SWCLK_Pin GPIO_PIN_14
#define SWCLK_GPIO_Port GPIOA
#define JTDI_Pin GPIO_PIN_15
#define JTDI_GPIO_Port GPIOA
#define SWO_Pin GPIO_PIN_3
#define SWO_GPIO_Port GPIOB


/* USER CODE BEGIN Private defines */
+ #define SPDKit_ULD_version "1.0.0"
+ 
+ // L7 - H533 - Main
+ #define INT_C_Pin GPIO_PIN_1       //
+ #define INT_C_GPIO_Port GPIOB      //
+ #define INT_C_EXTI_IRQn EXTI1_IRQn // INT (A2 -> B1)
+ #define PWR_EN_C_Pin GPIO_PIN_0    //
+ #define PWR_EN_C_GPIO_Port GPIOB   // PWR_EN_Sensor (A3 -> B0)
+ #define I2C_RST_C_Pin GPIO_PIN_3   // 
+ #define I2C_RST_C_GPIO_Port GPIOB  // I2C_RST only for L7 (D3 -> B3)
+ #define LPn_C_Pin GPIO_PIN_4       //
+ #define LPn_C_GPIO_Port GPIOB      // IO_LPn (D5 -> B4)
/* USER CODE END Private defines */

4.4 プロジェクト設定の修正

ここでプロジェクトの設定を先にします。プロジェクトのプロパティを開いて、Paths and Symbolsのところで、以下のようにIncludesでフォルダ、LibrariesでSPD_m33.a、Library PathsでSPD_libを追加します。
4.4.「プロジェクトの設定」.png
ここで一度プロジェクトをBuildしておきます。成功しましたか??

4.5 main.cの修正

最後に一番大きな山であるmain.cに挑みます。NUCLEO-F401RE用のプロジェクトのmain.cからの移植になります。必要な部分だけ移植しようとも考えます。コードをみる限り、綺麗に分離するのは難しそうです。しかたがないので、まるごと移植を試みます。移植の個所は大きく分けて以下の3か所に分かれています。

  1. 冒頭の宣言部分
  2. main関数(ループの前、ループの中)
    ループの前の初期化部分には元のVL53L8CX使用時のコードにはない、VL53L7CXの電源ONのコードを入れます。
  3. 独自の関数たちの定義です。

それぞれ順番に説明していきます。

4.5.1 最初の宣言の部分

元のmain.cから新しいmain.cへ冒頭の宣言部分をそれぞれ移植していきます。/* USER CODE BEGIN PM */の下にマクロをいれて、/* USER CODE BEGIN PV */にプライベートな変数を書きます。/* USER CODE BEGIN PFP */にプライベートな関数の宣言を書きます。
ちょっと込み入っているので修正コードの詳細は割愛させていただきます。この辺りが元のコードでは分かれていないのが私には気になってしまいます。

4.5.2 main関数

元のmain()関数のメインループwhile(1)の前のにコードを/* USER CODE BEGIN 2 */から/* USER CODE END 2 */の間にコピーします。VL53L7CXでは元のソースにはないパワーONのコードが入っているところに注意してください。

main.cのループ前に必要な修正コード詳細
main関数のループの前
  /* USER CODE BEGIN 2 */
  int status = 0;
  int off = 0;
  
  UartComm_Start(); // restart RX

  /* Clean the Serial Terminal */
	HAL_Delay(1000);
	uart_printf("\x1b[2J");
	uart_printf("\x1b[1;1H");
    uart_printf("SPD ULD SW Kit version %s\n", SPDKit_ULD_version);

  /* Enable Power */
    HAL_GPIO_WritePin(PWR_EN_C_GPIO_Port, PWR_EN_C_Pin, GPIO_PIN_RESET);
    HAL_Delay(100);
    HAL_GPIO_WritePin(PWR_EN_C_GPIO_Port, PWR_EN_C_Pin, GPIO_PIN_SET);
    HAL_Delay(100);

  /* Initialize VL53LMZ I2C address */
  LMZDev.platform.address = 0x52;

  /* Initialize sensor */
  status = init_vl53lmz_sensor();
  if (status != VL53LMZ_STATUS_OK){
		uart_printf("init_vl53lmz_sensor failed : %d\n",status);
  }

  /* Sensor identification */
  Params.spdRangingPeriod = LMZDev.module_type == 1 ? SPD_RANGING_PERIOD_L7 : SPD_RANGING_PERIOD_L8;
  Params.spdIntegrationTime = LMZDev.module_type == 1 ? SPD_INTEGRATION_TIME_L7 : SPD_INTEGRATION_TIME_L8;
  Params.spdAutonomousIntegrationTime = LMZDev.module_type == 1 ? SPD_AUTONOMOUS_INTEGRATION_TIME_L7 : SPD_AUTONOMOUS_INTEGRATION_TIME_L8;

  /* Initialize SPD algo */
  SPD_Init(1);

  // Reset sensor settings in Tracking mode (after SPD init)
  SEN_SetParamsForTracking();
  
  /* Initialize SPD algo */
  SPD_Init(1);

  // Reset sensor settings in Tracking mode (after SPD init)
  SEN_SetParamsForTracking();
  
  /* USER CODE END 2 */

ループの中には/* USER CODE BEGIN 3 */の下に、コードをコピーしていきます。コメントのブロックでいうと、/*UART RX Receiver management*//*START command*//*RANGING Mode*//*STOP command*//*OFF command*//*SET command*/までになります。
#ifdef VL53LMZ_XTALK_CALIBRATION以下は使用していないので、コピーしません。

main.cのメインループ内に必要な修正コード詳細
main.cのメインループ内
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		/*******************************/
		/* UART RX Receiver management */
		/*******************************/
        if (UartComm_CmdReady) {
			SC_HandleCmd(UartComm_RXBuffer);
			UartComm_CmdReady = 0;
			UartComm_Start(); // restart RX
		}
        
        // 以下省略

4.5.3 独自の関数たちの定義

独自関数たちはMX_GPIO_Initの宣言の後の/* USER CODE BEGIN 4 */以下にコピーしていきます。
init_vl53lmz_sensor()vl53lmz_sci_calculate_required_memory()vl53lmz_Configure()vl53lmz_spd_set_output_pipe()get_ranging_data()SPD_Init()SEN_update_info()SEN_CopyMeasurementData()SEN_SetParamsForTracking()SEN_SetParamsForAutonomous()SPD_ChangeSensorMode()HAL_GPIO_EXTI_Falling_Callback()の関数になります。最後のGPIOの割り込みCallbackも忘れずにコピーします。これのCallbackがないとデータが来たことを検知できず、動きません。
ここまでできたらコンパイルしてみます。エラーが出たらひとつひとつ、つぶしていきましょう!

今回はSTM32F401プロジェクトのコードをSTM32H533に移植していきました。細かいコードが続いて気がめいります。他のSTM32へのSPDの移植でも参考になる情報となっていることを願っています。次回はSPDライブラリの結果でモータを制御していきます。次の記事につづきます!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?