シリーズ:実験シリーズ(フェーズ1)
対応ロードマップ:フェーズ1 / E1-07
今回の役割:ボタンを1回押したつもりでも、実際には押した/離したが細かく揺れて複数回反応することを、UARTログとLEDの動きで見えるようにする。
1. 目的
今回は、チャタリング を観察します。
タクトスイッチは、押した瞬間に理想的に1回だけ切り替わるわけではなく、実際には接点が細かく揺れて、短時間に何回もON/OFFしたような状態になることがあります。
この現象を チャタリング と言います。
今回は、この現象が実際に起きる様子を
- ログに複数回表示される
- LEDが1回押しただけなのに複数回反応することがある
という形で確認します。
次回の E1-08 ボタン入力を安定させる(デバウンス) では、この問題を減らす方法を扱います。
2. 前提・環境
- 評価ボード:RTK7EKA8M2S00001BE
- 開発環境:e² studio + FSP
- 前提:
- E0-01〜E0-06 が完了している
- E0-05 のUARTログ出力ができる
- E1-05 のボタン入力(ポーリング)ができる
- E1-06 のプルアップ/プルダウンを体験済み
- 使用部品
- LED × 1
- 抵抗:1kΩ × 1
- タクトスイッチ × 1
- ブレッドボード
- ジャンパ線
- UARTログ確認用のPC環境(TeraTermなど)
- 使用するGPIO
- 外付けLED用GPIO:P409(J25-9)
- ボタン入力用GPIO:P704(J25-10)
- GND:J25-11
3. 回路・配線
今回は、E1-05 と同じ配線 を使います。
新しい部品は増やしません。
ポイントは、ボタン入力を“安定化せずにそのまま読む” ことで、チャタリングを観察することです。
- LED側
GPIO → 1kΩ抵抗 → LED → GND - ボタン側
ボタン入力GPIO → タクトスイッチ → GND
今回は 内部プルアップ を使います。
そのため、押していないときは High、押したときは Low を読む構成です。
3-1. 配線の考え方
- LEDは「反応した回数」を目で見やすくするために使います
- ボタンは、押した瞬間と離した瞬間の変化をそのまま読みます
- 今回は安定化(デバウンス)を入れません
- そのため、1回押しただけでも、ログ上は複数回変化したように見えることがあります
3-2. 配線図・配線写真


3-3. 注意点
- タクトスイッチの向きが違うと、意図した通りにつながりません
- GNDが共通になっていないと、正しく入力を読めません
- 今回は「わざと不安定さを見る回」ですが、配線ミスとチャタリングは別です
- まずは E1-05 と同じ配線が正しいことを確認してから進めます
4. 接続手順
4-1. 先に電源を切る
最初に評価ボードの電源を切ります。
通電したまま配線を触ると、ショートや誤配線の原因になります。
4-2. E1-05 の配線をそのまま使う
次の2本ができているか確認します。
- LED用GPIO → 1kΩ抵抗 → LED → GND
- ボタン入力用GPIO → タクトスイッチ → GND
4-3. UARTログの接続を確認する
今回はログを見るので、E0-05 で使ったUARTログ出力環境も確認します。
- COM番号が合っているか
- TeraTermなどが開けるか
- ログが見える状態になっているか
4-4. 配線を再確認する
今回は「チャタリング」を観察したいので、配線ミスでおかしくなっている状態ではなく、
正しい配線で、現実のスイッチのクセを見る ことが大切です。
5. FSP設定
今回は、基本的に E1-05 の設定をそのまま使います。
ボタン入力は内部プルアップ有効、LEDは出力です。
UART設定も、E0-05 の設定をそのまま使います。
5-1. Pins設定
- FSP Configurator(configuration.xml)→ Pins を開きます
- LED用GPIO:P409 を次のように設定します
- Mode:Output mode (Initial Low)
- ボタン入力用GPIO:P704 を次のように設定します
- Mode:Input mode
- Pull-up/down:Input pull-up
- 設定を確認したら「Generate Project Content」を実行します
5-2. UART設定
- E0-05 で作成した UARTログ出力設定をそのまま使います
- 今回は新しいUART設定は追加しません
6. コード
今回は、入力状態が変わった瞬間をそのまま記録 します。
まだデバウンスは入れません。
そのため、ボタンの接点が揺れると、短時間に何回も状態が変わった と判定されることがあります。
6-1. 先に考え方
今回は次の流れで確認します。
- ボタン入力を読む
- 前回の状態と違ったら「変化した」とみなす
- 変化するたびに
- LEDを反転する
- UARTログを出す
- 1回押しただけでも、ログが複数回出ることを観察する
ポイントは、今回は“正しく1回だけ反応させる”のが目的ではない ことです。
むしろ、1回だけのつもりでも複数回反応してしまう ことを確認するのが目的です。
6-2. 最小コード
#include "hal_data.h"
#include <stdbool.h>
static void uart_send_string(const uint8_t * p_msg, uint32_t len)
{
fsp_err_t err;
err = R_SCI_B_UART_Write(&g_uart0_ctrl, p_msg, len);
if (FSP_SUCCESS != err)
{
while (1) {;}
}
/* 簡易待ち */
for (volatile uint32_t i = 0; i < 100000U; i++)
{
__asm volatile ("nop");
}
}
void hal_entry(void)
{
fsp_err_t err;
bsp_io_level_t sw_level;
bsp_io_level_t prev_sw_level = BSP_IO_LEVEL_HIGH;
bsp_io_level_t led_level = BSP_IO_LEVEL_LOW;
static const uint8_t start_msg[] = "Chattering observe start\r\n";
static const uint8_t pressed_msg[] = "PRESSED\r\n";
static const uint8_t released_msg[] = "RELEASED\r\n";
/* UART Open */
err = R_SCI_B_UART_Open(&g_uart0_ctrl, &g_uart0_cfg);
if (FSP_SUCCESS != err)
{
while (1) {;}
}
R_BSP_PinAccessEnable();
/* 初期状態:LED消灯 */
R_BSP_PinWrite(BSP_IO_PORT_04_PIN_09, BSP_IO_LEVEL_LOW);
uart_send_string(start_msg, (uint32_t)(sizeof(start_msg) - 1));
while (1)
{
sw_level = R_BSP_PinRead(BSP_IO_PORT_07_PIN_04);
/* 状態が変わったら、その都度そのまま反応する */
if (sw_level != prev_sw_level)
{
/* LEDを反転 */
if (led_level == BSP_IO_LEVEL_LOW)
{
led_level = BSP_IO_LEVEL_HIGH;
}
else
{
led_level = BSP_IO_LEVEL_LOW;
}
R_BSP_PinWrite(BSP_IO_PORT_04_PIN_09, led_level);
/* UARTログ出力 */
if (sw_level == BSP_IO_LEVEL_LOW)
{
uart_send_string(pressed_msg, (uint32_t)(sizeof(pressed_msg) - 1));
}
else
{
uart_send_string(released_msg, (uint32_t)(sizeof(released_msg) - 1));
}
}
prev_sw_level = sw_level;
}
}6-3. このコードで何が起きるか
たとえば理想的には、
- 押したときに 1回
- 離したときに 1回
だけ反応してほしいです。
しかし実際には、ボタンの接点が細かく揺れるため、
- PRESSED
- RELEASED
- PRESSED
- RELEASED
のように、短時間に何回も変化したようなログが出ることがあります。
これが、今回見たい チャタリング です。
7. 実行結果
7-1. 期待する観察結果
- ボタンを1回押したつもりでも、ログが複数行 出ることがある
- ボタンを離したときにも、複数回変化したようなログ が出ることがある
- LEDが一瞬だけ複数回反応したように見えることがある
- 毎回まったく同じ回数になるとは限らない
7-2. ログ例
[I] Chattering observe start
[I] edge=1 state=PRESSED press=1 release=0
[I] edge=2 state=RELEASED press=1 release=1
[I] edge=3 state=PRESSED press=2 release=1
[I] edge=4 state=RELEASED press=2 release=2
このように、1回押しただけのつもりでも複数回反応 することがあります。
これが「押した瞬間に理想通り1回だけ切り替わっていない」ことの証拠です。
8. ハマりポイントと直し方
8-1. ログがまったく出ない
原因
- UART設定ができていない
- TeraTermなどの設定が合っていない
uart_printf()などのログ関数が正しく動いていない
直し方
- E0-05 のUARTログ記事に戻って設定を確認する
- COM番号、ボーレート、改行設定を見直す
- 最初に固定文字列が出るか確認する
8-2. 1回押しても1回しか反応しない
原因
- たまたまチャタリングが目立たなかった
- ループの中に大きな待ち時間が入っていて、細かい変化を取り逃している
- スイッチや配線の状態によって揺れが小さい
直し方
- 何回か押して試す
- ゆっくり押す/ゆっくり離すも試す
- ループの中に不要な delay が入っていないか確認する
補足
- 1回しか出ないことがあっても失敗ではありません
- 毎回必ず同じように見えるわけではないのが、現実の入力らしいところです
8-3. ログが多すぎて読みにくい
原因
- 接点が大きく揺れている
- 配線の接触も不安定になっている
- 変化のたびに全部出しているため、短時間に行数が増える
直し方
- まずは正しい配線か確認する
- ジャンパ線やスイッチがしっかり刺さっているか確認する
- 今回は「多く出ること」自体が観察対象なので、まずはそのまま見てよい
8-4. 配線ミスなのかチャタリングなのか分からない
原因
- 入力が浮いている
- プルアップ設定ができていない
- GNDが共通になっていない
- 実際のチャタリングと、単純な誤配線が混ざっている
直し方
- E1-05 の「押したら点灯、離したら消灯」に一度戻る
- E1-06 のプルアップ/プルダウン構成を見直す
- 押していないときの状態が安定しているかを確認する
補足
- 今回見たいのは「正しい配線の上で起きる、現実のスイッチの揺れ」です
- 配線ミスで不安定になっている場合は、先にそこを直します
9. 次回やること
次は、E1-08 ボタン入力を安定させる(デバウンス) に進みます。
今回見えた「1回押したのに複数回反応する」を、自分の手で減らしていきます。
10. 関連リンク
- E1-05 ボタン入力でLEDを点ける(ポーリング)(リンク)
- E1-06 プルアップ/プルダウンを体験(リンク)
- E1-08 ボタン入力を安定させる(デバウンス)(リンク)
- E0-05 UARTログ入門(リンク)
- プルアップ/プルダウン入門(リンク)
- ボタンが不安定なとき(デバウンス入門)(リンク)
- 組み込み開発とは(リンク)