hiro99ma blog

何か技術的なこと

ncs: ボタンの取り込みはチャタリング処理をしたい

2024/08/30

DevAcademy Fundamentals Lesson 2 - Exercise 2 はボタン押下を割込みで検知して LEDをトグルさせるというものだ。

gpio_pin_interrupt_configure_dt(GPIO_INT_EDGE_TO_ACTIVE)だとアクティブになる方の割込みでコールバックされて LED をトグルしている。 それだとちょっと寂しかったので、立ち下がりも検知して押下中だけ LED 点灯するようにした。

commit

そこで思い出したのが、ボタンといえばチャタリング処理だよなあ、ということ。 人間が押すからなのか、接点を物理的に接続させるためなのかは知らないがボタンの押下を割込みで処理しているとガサガサと何度か押下時に割込が入ることがある。 LED の点灯くらいだったら気にならないのだが、それでは済まないこともある。

昔は、そういうのはハードウェアで解決していた。 たぶんコンデンサーを挟むかなにかしてノイズ除去みたいなことをやってたんじゃないかな? 私が最初に携わっていた製品もそうなっていたのだが、次の製品か何かで部品が取り除かれた。 まあ、価格が下がるしね。
ハードでやらない代わりにソフトでやるんですよ、と説明してもらった。

やり方は地道で、最初に割込みを検知したらタイマーを動かして何度かポーリングし、一定回数以上同じレベルが続いたら安定したと見なしてタイマーを止めて本処理を行う、というものだ。 タイマー的なものを使わないといかんのが面倒なところだ。 スレッドが使えるなら、いっそのことワーキングスレッドを立ち上げてそっちに処理を任せてもよいのかもしれない。 ただ、チャタリング処理中に割込が入ってもそれは無視するとか、そういう気遣いはいる。

うう、めんどくさい。

多重割込みができないのであれば、コールバック・・・割り込みハンドラが呼ばれてから割込みを無効化し、チャタリングの監視期間が終わったら戻せばよい気がする。 しかし多重割り込みできるのであれば、割込みを無効化しようとしている間に割込みが発生するかも? それでも同一レベルの割込みは発生しなかったような気もするので、それなら間に合うのか。

そもそも、割込みのコールバックは割込みのコンテキストで行われるのだろうか。

Interrupts

An ISR’s interrupt handler function executes in the kernel’s interrupt context.

割込みコンテキストだった。
なら、別スレッドにしてやるのがよいのかな。 少なくとも割込みコンテキストの中でやるのはよくないだろう。

セマフォとあわせて、スレッドは最初から起動してセマフォで止めておき、割込みが来たら解除してポーリングするようにしてみた。

commit

なんとなく日本用語かと思ったがwikipediaでもそうなっているので検索に使っても大丈夫だろう。

< Top page