こんにちは、しゅうです。
前回は、プログラムの書き込みができることを確認しました。
今回は各種センサや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、スイッチ、赤外線センサ、受光センサの動作確認を行なっていきました。
次回はモータとエンコーダの動作確認を行います!