ラズパイ&ブレッドボードで遊ぶ(5)~8接点ロータリースイッチ

マスコン風のパワーパックを作りたい、ということを最終目標にして、まずは Raspberry Pi Pico でどんなことができるのか、と、ブレッドボードを使っていろいろと遊んでいます。

ロータリースイッチを組み込む

そろそろ、マスコンの試作的なものを作って行きたいのですが、ハード的にやっておきたいのが、ロータリースイッチの作成です。

直線的に動くスライドスイッチがあれば面白いのですが、そこそこの大きさで多段階のスライドスイッチってなかなか手に入りにくく、妥協案として多段階のロータリースイッチで代用したいと考えています。

さすがにロータリーディップスイッチでは、一次的な試作はともかく運用上操作性に問題があるので大き目のツマミと、ロータリースイッチを用意しました。

購入したのは、「接点可変ロータリースイッチ 1回路2~12接点」というもの。

ちょっと写真だけだとわかりにくいのですが、ナットとワッシャーを外して、ストッパー金具(写真右下)の爪を数字の書かれた穴にセットすることで、2接点から12接点までのロータリースイッチとして使用できます。

今回は、8接点として使用したいので、8と書かれた数字の右側(9との間)の穴にストッパーの爪をセットしてナットを戻しました。

1回路を選択したのは、単純に、回路が理解しやすいから。タクトスイッチのようにコモンをGNDに接続して1~8の各端子を8個のGPIO(プルアップ設定)につなげれば、スイッチの指しているポートが L になります。(その他のポートは H … 実は微妙)

試作はブレッドボードを使いますが、最終的にはユニバーサル基板に組んでみたい(ケースに収納したい)、という思惑もあって、こんな感じにしてみました。

これに、QIケーブル 1列10P というものを購入して、ブレッドボードに接続しています。

扱いやすくていいですね。

ロータリースイッチ ピン番号接続先
A (コモン)Raspberry Pi Pico GND
1Raspberry Pi Pico GP13P
2Raspberry Pi Pico GP12P
3Raspberry Pi Pico GP11P
4Raspberry Pi Pico GP10P
5Raspberry Pi Pico GP9P
6Raspberry Pi Pico GP8P
7Raspberry Pi Pico GP7P
8Raspberry Pi Pico GP6P

Raspberry Pi Pico の端子は、GPIOであればどれでも構いません。若番と老番を逆にしたのも特に意味はありません。それぞれの端子で1bitずつ独立して扱いますので、並んでいようが、バラバラだろうが、関係ないですからね。

コモンはRaspberry Pi Picoの18番ピン(GND)につなぎましたが、もちろん、ブレッドボードの-(GND)でも同じです。

ソフトで扱う

追加したソースコードはこんな感じに。

(省略)
# ROTARYスイッチ用
rotarySw1_pin = machine.Pin(13, machine.Pin.IN, machine.Pin.PULL_UP)
rotarySw2_pin = machine.Pin(12, machine.Pin.IN, machine.Pin.PULL_UP)
rotarySw3_pin = machine.Pin(11, machine.Pin.IN, machine.Pin.PULL_UP)
rotarySw4_pin = machine.Pin(10, machine.Pin.IN, machine.Pin.PULL_UP)
rotarySw5_pin = machine.Pin(9, machine.Pin.IN, machine.Pin.PULL_UP)
rotarySw6_pin = machine.Pin(8, machine.Pin.IN, machine.Pin.PULL_UP)
rotarySw7_pin = machine.Pin(7, machine.Pin.IN, machine.Pin.PULL_UP)
rotarySw8_pin = machine.Pin(6, machine.Pin.IN, machine.Pin.PULL_UP)
(省略)
# ロータリースイッチ判定
def getRotarSw():
    if rotarySw1_pin.value() == 0:
        rtsw = 1
    elif rotarySw2_pin.value() == 0:
        rtsw = 2
    elif rotarySw3_pin.value() == 0:
        rtsw = 3
    elif rotarySw4_pin.value() == 0:
        rtsw = 4
    elif rotarySw5_pin.value() == 0:
        rtsw = 5
    elif rotarySw6_pin.value() == 0:
        rtsw = 6
    elif rotarySw7_pin.value() == 0:
        rtsw = 7
    elif rotarySw8_pin.value() == 0:
        rtsw = 8
    else:
        rtsw = 1

    return rtsw
(省略)
while True:
    # ロータリースイッチ状態取得  
    rotarySw = getRotarSw()
(省略)

machine.Pin の設定時に、machine.Pin.PULL_UP の設定をしてますから、スイッチが指している箇所がGNDと導通して、value()の値が 0 になります。

マスコンとしての仕様は、まだ正確には決めていませんが、SW1の場所が「OFF」というのは決めてますので、万一接点が見つからない場合の異常事態発生時は trsw = 1 を返すようにしています。

メインループに、print文を仕込んで、スイッチ状態を表示させるようにして確認してみました。

程よいクリック感です。

右に7回で回転は止まり、左にも7回でそれ以上進めません。8段階、ということですね。

実は、最初、上記のソースコードの取得関数は下のようなものでした。

# ロータリースイッチ判定
def getRotarSw():
    if rotarySw8_pin.value() == 0:
        rtsw = 8
    elif rotarySw7_pin.value() == 0:
        rtsw = 7
    elif rotarySw6_pin.value() == 0:
        rtsw = 6
    elif rotarySw5_pin.value() == 0:
        rtsw = 5
    elif rotarySw4_pin.value() == 0:
        rtsw = 4
    elif rotarySw3_pin.value() == 0:
        rtsw = 3
    elif rotarySw2_pin.value() == 0:
        rtsw = 2
    else:
        rtsw = 1

    return rtsw

ロジック的には、見たところ何の違いも無いのですが、動作上、大きな違いがあったんです。

動画もログも残っていないのですが、右回り(数字が大きくなる方)に回していると、"5″ で確定する前に、一瞬 “6" が割り込むことがありました。

    elif rotarySw6_pin.value() == 0:
        rtsw = 6

この処理が効いている、ということです。"6″の位置にまで回したつもりはないんですけどね。

これは、ロータリースイッチの切替えタイミングの仕様に起因しているようです。

ロータリースイッチには、切替えタイミングとして「ショーティング」と「ノンショーティング」の二つのタイプがあります。それぞれの違いは、ざっくりとこのような感じになるでしょうか。

ショーティングは、常にどこかの端子に接触していますので、断線するタイミングがありません。一方、ノンショーティングは、タイミングによってはどこにも接しないことがありますが、同時に2つの接点が導通することはありません。

どちらを選ぶかは回路設計次第ですね。

今回は単純に数値を取得するためだけのスイッチなのでタイプを気にせずに購入したんですが、回転させるときの弾み(勢い)で、次の端子に触れてしまうようです。

    elif rotarySw6_pin.value() == 0:
        rtsw = 6
    elif rotarySw5_pin.value() == 0:
        rtsw = 5

elif を使用していますので、6番と判定されると if rotarySw5_pin.value() == 0: は実行されません。

なので、"5″ を期待しているのに “6" が一瞬割り込んでしまう、というわけです。

もちろん、逆にしたら全てOKなのかというと、逆回転時に同じことが起こりますから、システム設計次第ではありますけどね。確認用の暫定仕様で、スイッチの右回りでLED点灯を見ていたので、"5″のときに “6"となって、急遽、判定順序を逆にした、という次第です。

意図して"6″まで回しているのか、ノイズ的に一瞬"6″となったのか、チャタリング除去をしてやる必要がありそうですね。

一方で、ノンショーティングタイプなら、値が取れない(すべて"1″となる)ケースが発生します。

その時は elseで rtsw = 1 を返すのではなく、0 等を返して、関数コール側で「前回取得値を使用する」という処理にしてあげる必要があります。そういう意味では、ノンショーティングの方がソフトウェアとしては処理しやすいんですかね。

というわけで、LED、タクトスイッチ、ロータリーディップスイッチ、モータードライバー、磁気センサーと見てきて、このロータリースイッチで、一通りのハードが揃いました。

次はいよいよ、マスコン風の制御を Raspberry Pi Pico でやってみたいと思います。