こんにちは、しゅうです。
前回は、プログラムの書き込みができることを確認しました。
今回は各種センサやLEDなどの動作確認を行なっていきます。
LED
まずは基本のLED点灯。基本ですが、素子の取り付け向きが逆だったり、マイコンのピン配置を間違えていると動作しません。
プログラムには以下のように、STM32CubeIDEで生成したmain.cを編集して、新たにstatic_parameters.hを追加します。
こうすることで、main.cが長いものにならず、可読性が上がります。
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include static_parameters.h
/* USER CODE END Includes */
-- 中略 --
/* USER CODE BEGIN WHILE */
while(1)
{
TOGGLE_LED0; // Turns on and off the LED
HAL_Delay(500); // Waits 500ms
}
static_parameters.hで使っているHAL関数はHAL_GPIO_TogglePin関数です。
設定したGPIOピンに対して、0と1を交互に出力します。第一引数にピンのグループ(A,B,Cなど)を指定して、第二引数にピン番号を指定します。
こうすると、TOGGLE_LED0を呼び出すたびに、LEDが点灯・消灯を繰り返します。
#include "stm32f1xx_hal.h" // LEDs #define TOGGLE_LED0 HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_10);

残りのLEDも同様に確認していきます。ここまでは特に問題なく進んでいるので、次に行きます。
スイッチ
スイッチが押されたかを認識する部分は、Pi:Coの実装方法を採用しています。LEDの動作確認時に作ったファイルをそのまま使います。
ここでは、HAL関数のHAL_GPIO_ReadPin関数を使って。スイッチの状態を読み取ります。
/* USER CODE BEGIN WHILE */
while (1)
{
// チャタリング防止用に
HAL_Delay(CHATTERING_WAIT);
while(!(READ_SW0 & READ_SW1 & READ_SW2));
// いずれかのスイッチが押されるまで待つ
HAL_Delay(CHATTERING_WAIT);
while((READ_SW0 & READ_SW1 & READ_SW2));
if(READ_SW0 == SW_ON){
TOGGLE_LED0;
}else if(READ_SW1 == SW_ON){
TOGGLE_LED1;
TOGGLE_LED2;
}else if(READ_SW2 == SW_ON{
TOGGLE_LED3;
}
}
// Switch related #define CHATTERING_WAIT (50) // in ms // Switches #define READ_SW0 HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7); #define READ_SW1 HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_8); #define READ_SW2 HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_9);
TOGGLE_LED1から3は、TOGGLE_LED0と同様のものを定義しています。上記のプログラムでは、スイッチを押すたびに、該当するLEDの点灯・消灯を行います。

こちらも特に問題なく動作したので、次に進んでいきます。
赤外線センサ
Pi:Coで使っていたものと違い、可視光線はあまりでないものを採用しています。電流を流した時に、正面から見ると光っているのが見れるようにはなっています。
なので、スマホのカメラを利用して、確認する必要があります。
赤外線センサの発光はとても簡単です。LEDを点灯した時と同じで、該当のピンの出力を切り替えれば点灯します。
ここでは、点灯具合を確認するので、付けっぱなしにします。
// main関数の中でwhile文の手前に書く SENSOR_OUT_R_ON;
// Light sensor - Emmit #define SENSOR_OUT_R_ON HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 1); #define SENSOR_OUT_R_OFF HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0);
上記のプログラムの場合、右端のセンサが点灯します。下記画像では、LEDの先端が薄ら光っているのが確認できます。隣のLEDは光らせていないので、そちらと比較するとわかりやすいと思います。

もし、LEDが点いていなさそうだったら、オシロスコープを当てて波形を確認したり、素子の取り付け方向が正しいか確認してみましょう。
ちなみに僕は最初逆につけていました(笑)
赤外線受光センサ
こちらはPi:Coと同じものを採用しています。
AD変換を行なって、センサの値を取得します。タイマー関数のほうに組み込むのは、まだ先になります。
STM32CubeIDEの設定はこちらの記事を参考にしてください。
デバッグをしやすくするために、スイッチの動作確認をした時のプログラムを流用します。
printデバッグを行うので、こちらの記事で紹介した設定を忘れずに行いましょう。下記プログラムの方にも書いておきます。
AD変換などの処理はハイライト部分になります。
/* USER CODE BEGIN 0 */
int __io_putchar(int ch) {
HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 100);
return ch;
}
/* USER CODE END 0 */
-- 中略 --
/* USER CODE BEGIN 2 */
// Printf thing
setbuf(stdout, NULL);
/* USER CODE BEGIN WHILE */
double s_r_val = 0;
while (1)
{
-- 中略 --
if(READ_SW0 == SW_ON){
// LEDが完全に点灯するまで少し待ちます
SENSOR_OUT_R_ON;
for (int i=0; i<30; i++);
// AD変換を行う
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 1);
// センサの値を読み取とって、値を保管する
s_r_val = HAL_ADC_GetValue(&hadc1)
SENSOR_OUT_R_OFF;
}else if(READ_SW1 == SW_ON{
-- 中略 --
print("SENSOR_R value : %d \n\r", s_r_val);
}
これで、ボタンを押す度にセンサの値を取得できます。以下のスクショは、4つのセンサ値を取得したときの実行例です。

ここで右のセンサ値だけ、他のセンサに対して変化が少ない(6→28)ですね?実は右側の赤外線LEDだけ上向いちゃってました。センサの向きを固定する、ということの重要さがわかりますね。

ブザー… 🙁
ブザーに関しては、マイコンからの電流量が足りていないからか、思ったように鳴らすことができませんでした…
こちらの記事で、ブザー用に設定したPA4をHiに設定したら高い音、PA5をHiに設定したら低い音、が鳴らせるような回路設計をしています。ですが、こちらは唯一、ブレッドボードなどを使ったテストを行なっていません。余裕ができたら、こちらの発振回路のデバッグなどを行いたいと思います。
ひとまずは無くても動かせるので、このまま実装を進めていきます。
まとめ
今回は、LED、スイッチ、赤外線センサ、受光センサの動作確認を行なっていきました。
次回はモータとエンコーダの動作確認を行います!
