2014/11/24

Arduino - ロータリスイッチの状態をA/D変換で取得する

前置きが長いので,すぐに回路図とスケッチを確認したい場合は,最初の2項目を読み飛ばしてください.

しろくま氏のPWMパワーパックの改良

しろくま氏ジオタウンドットコムで公開している,PWMパワーパックを製作してみることにしました. プログラムをPICに移植して製作しようと思っていたのですが,Arduinoの使用経験がなかったこともあり,私の技術不足で一筋縄では行きそうにありません. そこで,Arduinoの開発環境を用意して,ひとまずArduinoで製作してみることにしました.

しろくま氏が記事を投稿してから3年以上経過しているため,既に多くの方が,しろくま氏のPWMパワーパックを製作したようです. ジオタウンドットコムのコメント欄を見ると,誤動作するという方も散見されます. どうやら,マスコンとして使用している,ロータリスイッチ周辺回路やプログラムに問題が1つあるようです. 今回は,このロータリスイッチ周辺回路とプログラムの改良について考えてみました.

誤動作の原因は回路にあると推測

誤動作の原因や対応策についてコメント欄でさまざまな議論がされていますが,私は回路に原因があると考えました. 記事の添付写真から推測すると,しろくま氏が使用しているロータリスイッチは,秋月電子通商で発売されているノンショーティングタイプの1回路12接点のものです. ノンショーティングタイプのロータリスイッチは,スイッチを回転させて選択接点を切り換える際,一時的に共通接点がどの選択接点にも接触していない状態になります.

ここで,しろくま氏の回路図を確認します. ロータリスイッチ RSW_12の共通接点aは,アナログ入力ピンに接続されています. つまり,ロータリスイッチを回転させた際に,一時的にアナログ入力ピンがどこにも接続されていない状態(ハイインピーダンス)になります. このとき,Arduinoがロータリスイッチの状態を取得できなくなりますので,誤動作が発生します. ただし,これは回路図から読み取った推測です. 実際には,見当違いであったり,複合的な原因である可能性もありますのでご注意ください. ご指摘があれば,コメントをいただければ幸いです.

次項から,改良した回路について紹介します.

回路
回路図

PDFファイルにて公開します. 回路図中の「ユーザ回路」部分を製作し,Arduinoのアナログ入力ピンに接続してください.

ロータリスイッチ SW1の共通接点Aは,グランドに接続されています. 一方,Arduinoのアナログ入力ピンは,常にSW1の選択接点1に接続されています. スイッチを回転させると,合成抵抗の分圧比が変化し,アナログ入力ピンに印加される電圧が変化します. この変化を読み取ることで,SW1の状態を取得できます.

仮に共通接点Aがいずれの選択端子にも接続されていない状態になっても,アナログ入力ピンは抵抗 R1でプルアップされている状態となり,ハイインピーダンスにはなりません.

回路部品

下表は,回路図中の「ユーザ回路」部分の使用部品表です. 参考単価をクリックすると,秋月電子通商のページに飛びます. 「互換品」と記載されているリンクについては,互換性があると考えられる部品のページに飛びます. ただし,私が互換性および動作を確認したわけではありませんので,ご注意ください.

使用部品表
番号 部品名 型番 数量 参考単価
SW1 ロータリスイッチ 1回路12接点
ノンショーティングタイプ
1 150円
(互換品)
R1, R10 炭素皮膜抵抗 各社 1/4W 4.7kΩ 2 1円
(互換品)
R2 炭素皮膜抵抗 各社 1/4W 470Ω 1 1円
(互換品)
R3 炭素皮膜抵抗 各社 1/4W 680Ω 1 1円
(互換品)
R4 炭素皮膜抵抗 各社 1/4W 820Ω 1 1円
(互換品)
R5 炭素皮膜抵抗 各社 1/4W 1kΩ 1 1円
(互換品)
R6 炭素皮膜抵抗 各社 1/4W 1.2kΩ 1 1円
(互換品)
R7 炭素皮膜抵抗 各社 1/4W 1.5kΩ 1 1円
(互換品)
R8 炭素皮膜抵抗 各社 1/4W 2.2kΩ 1 1円
(互換品)
R9 炭素皮膜抵抗 各社 1/4W 3kΩ 1 1円
(互換品)
R11 炭素皮膜抵抗 各社 1/4W 8.2kΩ 1 1円
(互換品)
R12 炭素皮膜抵抗 各社 1/4W 15kΩ 1 1円
(互換品)
その他 リード線など 適量
回路製作例

私が製作した回路の写真です. 炭素皮膜抵抗R2R12は1/4Wの小型品を使用し,ロータリスイッチの接点間に直接ハンダ付けしました.


回路製作例
スケッチ
A/D変換値からロータリスイッチの状態を取得する方法

まず,ロータリスイッチの各状態における,アナログ入力ピンへの印加電圧を計算してみましょう. 計算結果を下表に示します. 下表から,例えば選択接点2の場合は,アナログ入力ピンへの印加電圧が0.455Vになることがわかります. ArduinoのA/D変換の分解能は10bit(0~1023)ですから,A/D変換値は93になると考えられます. ただし,電源電圧や抵抗値の公差により,各値は多少変動します.

これらの計算結果を基に,A/D変換値と閾値を比較することで,ロータリスイッチの状態を割り出します. 例えば,選択接点が3以下か4以上かを調べるためには,各状態におけるA/D変換値(201と302)の中間値(252)を閾値にします. このような比較処理を繰り返すことで.選択接点が特定できます.

ロータリスイッチの選択接点とアナログ入力ピンへの印加電圧の関係
選択接点 印加電圧 [V] A/D変換値(10bit)
1 0.000 0
2 0.455 93
3 0.983 201
4 1.477 302
5 1.936 396
6 2.351 481
7 2.734 560
8 3.130 641
9 3.491 715
10 3.841 787
11 4.175 855
12 4.459 910
スケッチ例

下記は,スケッチ例 rotary_sw.inoです. A/D変換値からロータリスイッチの状態を取得する,getRotarySwStatus()関数を作成しました. 復帰値1~12でロータリスイッチの状態を,復帰値0で取得エラーを示します.

getRotarySwStatus()関数内の条件分岐処理がif文の入れ子構造になっているのは,ロータリスイッチの状態によって関数内の処理時間が変動しないようにしたかったためです. この関数では,ロータリスイッチがいずれの状態であっても条件分岐処理が3回以内になっています. よりスマートなやり方があるのだとは思いますが….

製品紹介

2 件のコメント:

  1. しろくま氏の製作記に触発され作ってみた口です
    https://github.com/MasudaNaika/powerpack6
    で試行錯誤してます。よろしければご覧ください。

    返信削除
    返信
    1. Masuda Naikaさん,情報共有ありがとうございます.
      回路構成も変更されているようですね.参考にさせていただきます.

      私も,この記事で紹介した他に,FET周辺回路などにも変更を加えています.
      ブレッドボード上では動作確認済ですが,まだ基板作成に着手できていません.
      今後も関連記事を投稿しようと思いますので,アドバイスなどをいただければ幸いです.
      よろしくお願いいたします.

      削除