前の記事の最後にちょっと触れた、0.96インチOLEDを使ったオシロの試作版というか、機能確認バージョンが出来ました。
最高サンプリング速度(周期)は8μsなので、10kHzくらいまでの波形なら観察出来るはずです。
▼0.96インチOLEDオシロ

小さな画面ですが、コントラストが高いので、思いのほか見易いです。
▼回路図

Arduinoのアナログ入力(A0)から信号を入れると、その波形をOLEDに表示します。入力電圧は0-5Vの固定。操作スイッチは今のところ、スイープ速度4段の切り替えと、トリガスロープの選択だけです。
スケッチはこちら、→
0.96インチOLEDオシロスコープのスケッチ S-JISエンコードです。(Arduino IDEの画面にコピペするのが簡単だと思います)
縦軸の自動ズーム機能、自動トリガ機能が付いています。これ以上の詳しい説明は省略します。I2Cインターフェイスの0.96インチOLED(SSD1306)を接続すればそのまま動くはずです。ファンクションジェネレータなど無くても、入力に短い線を繋ぐことで、ACラインの誘導ノイズ波形が観察出来るので動作確認が出来ます。
表示のVRAMに1kバイト、波形バッファに400バイトのメモリーが必要なので、RAMの容量が苦しいです。なお、ライブラリはAdafruit_GFX.hとAdafruit_SSD1306.hを使っています。
◆動いている様子 (?rel=0)
あれこれ入力波形を変えて観察している様子です。初めの方に、同じ波形を入力したアナログオシロの画面も出てきます。(トリガ極性切り替えの様子の動画を入れるのを忘れました)
なお、波形はドットで描いているのですが、ドット間を直線で接続した方が見易かったかも知れません。
◆まとめ
・結構それっぽい物が出来ていると思います。
・ADCは数100kHz以上の信号でも反応するようで、エイリアシングが強く出ています。勘違い防止のために、入力にローパスフィルタを入れた方が良さそうです。
・試作版を動かしていて思ったのですが、この小ささを生かしてペン型オシロを作ると面白そうです。操作スイッチやメニューなどは、ペン型にした時のことを意識して作り込みたいと思います。
- 関連記事
-
Arduinoのオシロ、私も色々悩みながらちょっとずつ作っていっているところで、ソフト周りは大体出来たんですが、入力回路周りで悩みがあったりします。
(1)ラジオペンチさんが言われているように、入力回路側でLPFを組み込んで、折りたたみノイズを拾わないようにしたほうがいいんでしょうかねぇ?それとも素のデータを拾うようにしたほうがいいでしょうかねぇ?(通常のオシロって、そもそも入ってるんでしょうかね)
(2)LPFを組み込むなら、どんな特性のフィルタがいいんでしょうかね?何次くらいのフィルタがいいんでしょうかね?
(3)レンジ切り替えには、アナログスイッチを使って、オペアンプのレンジ切り替えが出来るようにしたいんですが、アナログスイッチの内部抵抗が以外に大きくて、誤差の元になってしまうんですが、なにかいい方法ないでしょうかね?
(4)DC入力、AC入力を切り替える回路で、特にAC入力の場合オフセット電圧をかけてやらないといけないと思うんですが、どんな回路構成がいいんでしょうかね?(うちにあるオシロの1個は、AC/DC切り替え時にリレーがカチッと音をだすんですよ)
(5)パッシブプローブの位相補正回路周りの定数設定がよくわからず…
今のところ、LPFは取っ払ってしまいつつ、一方、レンジ切り替え(および入力インピーダンスを無限大近くにする)のためには、アンプを組んでADCへ引き継ぐ感じにしようと思っています。
レンジ切り替えはちょっと頭が痛く、E24系列の抵抗でビシッと嵌る値のを組み合わせると、アナログスイッチの内部抵抗の誤差が結構大きくなってしまい、あまり単純な回路構成にはならず…
あとプローブ側(パッシブプローブ)の位相補正について、本体側でどういう回路で受けたらいいのかについて、細かいところがよくわかっておらず…。参考にしてみた回路では、
http://reclearnengoolong.blog.fc2.com/blog-entry-109.htmlhttp://zakii.la.coocan.jp/transmission_line/29f_oscillo_probe.htmオシロ内部に20pFとか容量を持っている回路が描かれているんですが、これは、20pFを実際に取り付けるのか、それともADC内部のサンプル&ホールド回路やオペアンプの入力端子、基板上の浮遊容量などを足すと「だいたいこのくらい」なのか、なんてあたりがよく解らず、困っています。
もしこのあたりご存知でしたら、ご教示いただけるとうれしいのですが。
コメントありがとうございます。nekosanさんのオシロの検討ページも拝見しました。いろいろ真面目に検討されているんですね。
まずはご質問にざっとお答えします。
(1) この試作機に数100kHzくらいの信号を入れると、偽物の波形が表示されちゃったのを見て、ありゃーこれはヤバイと思いました。
(2) LPFはCRの2次くらいを考えています。
(3) レンジ切り替えですが、画面の縦軸の画素が50しかないので、そこでバレない程度に誤魔化すことを考えています。
ご存知のようにarduinoのADCは1023までの値を返すので、例えば下の0-100の範囲だけ使えば10倍のアンプを入れたのと同じになります。この手で、2倍、5倍、10倍くらいのレンジ切り替えをソフトでやっちゃおうかと。
あと、これだけでは足りないのでアッテネーターを入れることを考えています。別のロジックのポートから抵抗(Rp)を出して、アンプの入力抵抗(Rin)に並列に抵抗を入れれば良いかな、と思っています。なお、Rpを使わない時はポート入力にしてHi-Z。Rp使う時は出力にしてLOW出力です(これでほぼ0ボルトがデリことを期待してます)。
入力端子にはアッテネーターの上側の抵抗(Rs)として500kΩくらいを入れておこうかと。アッテネーションは、Rin/(Rs+Rin)の場合と、(Rin//Rp)/((Rs+(Rin//Rp))になるはず。
なお、どうせゲインに誤差が出るので、最後にソフトで補正するつもりです。
(4)AC入力機能はまじめにやると面倒なので省略するつもりです。また負電圧の測定機能も無しです。
(5) オシロの入力端子には1MΩ、15pFなどと表示があります。この15pFはその値のコンデンサが入っているのではなく、部品などの浮遊容量を等価的に表したものだと思います。
ちなみに手元にテクトロのアナログオシロの2465Bの回路図があるので確認してみました。すると、ch1と2には多段のアッテネーターが入っているので並列のコンデンサは無し。ch3と4は2段切り替えの小さなアッテネータなので、浮遊容量を補うために100Ωと2.7pfを直列にしたものが入っていました。
こんなところです。あ、ADCは内部Vrefを使う予定です。
また進展があったら記事にします。入力のスイッチの検出を割り込みでやった方がいいので、そのあたりの確認が先かなと。あと、今ドライブレコーダーを取り付けたところで、そっちの話が先になりそうです。
色々とご回答いただきありがとうございます。助かります。
レンジ切り替えの件、LCD(OLED)の画面サイズを考慮して、ソフト的に切り替えてしまうのもいい手に思いますね。なるほど。思いつきませんでした。
私の考えていたゴールは、ペン型みたいな小型化よりは、Arduinoシールド型程度にして、場合によってサンプルデータをPCにシリアル転送するなんて機能も載せたいな、などと欲張っていたので、ADCフルレンジ(もしくは 256段階程度)までは要りそうです。あと、FFTを載せており、ある程度のビット数で取り込まないと、dB表示にしたときにいまいちなレンジになってしまうのもあって、やはりある程度のレンジは要りそうです。
AC入力は、ほんと結構面倒なんですよね…。オフセット調整なんかも考えると、あちこちごちゃごちゃしてきてしまって…。オフセット調整はハード的にしたほうが色々都合はいいんでしょうけど、ソフト的に実装しちゃう手もあるかなぁ…など悩んでます。
内部の容量成分の情報、回路図を調べていただき、本当にありがとうございます。助かりました。そのあたりでモヤモヤしていた回路周りは、少し進められます。
入力端子の読み込みは、ピンチェンジ割り込みを使うか、ポーリングがいいか、色々悩んでいるところなんですけど、サンプリング速度のレンジを秒単位とかまで広げると、バッファ全体をサンプルするときに、その時間がだいぶ長くなってしまうので、やはり割り込みが現実的なのかな、などと思っています。
(現状は、ポーリングで処理しているので、あまり長いサンプル間隔が設定できないようになっている)
いずれにしても、続報を楽しみに待っています。
FFTまでお考えなら、量子化ビット数を落とす訳にはいかないですね。
AC入力の場合のオフセットの話、前のコメントにもお書きになってますが、実は何のことだか理解できないでいます。
ACカップルなら波形の平均値がゼロになるので、それをそのまま表示すればいいと思うのですが、、まあオフセットかけると見易くなったりするとは思いますが。
操作スイッチの検出方法ですが、私も同じこと悩んでいます。タイマー割り込みだと波形のキャプチャに影響が出そうなので、ピンチェンジ割り込みで行くしかないかなと思ってます。
で調べたら、昔同じようなことやってました
http://radiopench.blog96.fc2.com/blog-entry-656.htmlいずれにしても、同じようなことを目指している方からのコメントはものすごく助かります。
AC入力に対応する場合、入力のアンプ回路周りで、VccとGNDの中点を取って、正帰還に入力すれば、オフセット自体は簡単に実現できると思うのですが、なんとなく2つの点で面倒があるかな、と思っています。
ひとつは、ゼロボルト位置の微調整(オフセット調整)です。
中点を決める2個の抵抗の間に小さな可変抵抗を挟めば、上下の抵抗値を微調整できるのですが、アンプICによって入力オフセット電圧が異なり、どの程度のオフセット調整幅を確保すればいいのか? AC入力、DC入力それぞれ同じオフセット調整範囲で足りるのか? ソフト側でオフセット調整できないか? など。
あと、AC入力に限らない部分ではありますが、信号を扱う電圧幅を考えると、RailToRailのアンプを使いたいところですが、一般に速度が遅いので、電源電圧を広げて高速なアンプを使い、ADCの入力電圧からはみ出た部分は保護回路でカットする…みたいなことも必要かなと。
なので、その辺を簡単操作で行えつつ、少ないパーツで安全に行う回路はどうしたらいいのかな?などと考え始めると、あっちを立てればこっちが…みたいになってきて…。昇圧回路や保護回路なんかも足すと、シールド1枚に収まらない気がして。
まぁ、ビデオ信号みたいに、上下で信号の量が異なるような場合でもない限り、あまりACのオフセット量は気にしなくてもいいのかも知れませんが。
もう1点は大した話では無いのですが、コンデンサで直流カットする回路周りの定数です。
そのコンデンサや、アンプの入力抵抗/帰還抵抗周りや、プローブ内部の抵抗などによって、波形の特定の周波数が鈍ったりしないか、などなど。
あまりアナログ回路の計算得意ではないので、事前にちゃんと計算できるか自信ないのと、マイクロ秒レベル~数秒レベルのレンジの信号を扱うと考えて、結局どのくらいの容量のコンデンサで直流カットすればいいのかが、いまいちわかってません。まぁこれは、ちゃんと調べればすぐわかることだと思いますが。
まぁ、AC入力以外にも、電源にスイッチング電源使ってしまって、信号がノイズに埋もれないのかとか、色々判らないところがあって、悩ましかったりします。
操作スイッチや操作ダイヤル(ロータリーエンコーダ)は、なんとなくピンチェンジ割り込みが素直だろうと思うのですが、チャタリングに対してどのようにソフト側で受けたらいいのかとか、まだ考えがまとまってなくて未知数なところがあります。
速度レンジ切り替えの瞬間などは、当然まともに信号拾えているはずは無い(バッファに蓄えられたデータは中途半端な状態なので読んでも意味が無い)ので、操作を行っていない安定状態のときだけまともに表示できるってことだけ考慮しておけば事足りると思うんですけどね。
サンプルレートが長時間の場合、おかしな表示が残ったりしないように、バッファを適当なタイミングでフラッシュしたりすればいいんだろうと思います。
一方、トリガ条件は今のところソフト処理で行っているので、トリガの掛かり方とかと齟齬が起きないようにしないといけないよな、など、いくつか考えておく点は残っていそうです。
色々、頭の中でまとまりきらないことが沢山残ってて、頭がいっぱいといった状態です。とりとめなくてすみません。
私の頭の中では、欲張りすぎなところもあるので、何か1個動作する基板を作ってみれば、色々割り切れるのかな、という気もしています。
すみません、お考えになっているAC入力が私の頭にはしっくりきません。そんなことで、まずは一方的に書いてみます。
オシロは(DCだろうがACだろうが)正負の電圧を観察しないといけないので、入力した信号は両電源のオペアンプで扱います。一方でマイコンのADCはGND基準なので、そのままでは接続できないので、最後にオペアンプでレベルをシフトさせて、マイコンのアナログポートに入力します。つまりDC入力の場合でもレベルシフトと言うか、オフセットアンプは必要になります。
AC入力は、回路の入力に単にコンデンサを入れるだけです。なお、ACカップルと呼んだ方がしっくりきます。
ともかくAC入力だからと言ってアンプのオフセットに特別な注意が必要にはならないと思います。
以上、考え方にギャップを感じた部分について書いてみました。
なお、オシロでは画面上での波形の上下位置を任意に動かす機能が必要なので、実質的にはオフセット調整やっているのと同じです。
あと、レベルシフトの基準電位は電源の二分割だとちょっとフラフラして危ない感じなので、安定化した方が良いと思いました。マイコンから出ているVrefをバッファアンプで取り出して基準電位に使う例を見たことがありますが、ここまでやれば万全でしょう。
AC入力のDCカットのコンデンサは0.1μFが使われることが多いと思います。もちろんアンプの入力インピーダンスに依存します。このコンデンサは性能の良い物(低tanδ、低誘電体吸収など)が必要なので、計測メーカーの測定器ではメタルCAN入りの立派な物が使われています。なお、DSO-SHELLではセラコンが使われていましたが、出来ればフイルムコンを使って欲しかったです。
ADCの保護はマイコンのポートの保護ダイオードに頑張ってもらうとして、安全のために抵抗を入れておけば大丈夫かと。DSO-SHELLの回路図見たらここには150Ωが入ってました。
ピンチェンジ割り込みで少しプログラムを書き始めたのですが、5回に1回くらい取りこぼしが出てます。裏で走っているプロセスで割り込みを禁止されている期間があって、その時ボタンを押すと無視されている感じです。
まあボタンを押し直せば良いのですが、気持ち悪いので何とかしたいと思ってます。無理かもですが、、
AC入力の話は、元々DC入力だけの回路で回路図描き始めて、あとから、でもやっぱ欲しいよな…なんて欲を出して、ある程度描いた回路図のあっちこっちとの兼ね合いでなんか変なこと起きそうだなぁ、なんて考え始めてから、頭の中で考えが発散しちゃって面倒になって放置、ってだけなので、あまり気になさらないでください。
ちなみに0.1uFであれば、(短い時間は大丈夫だろうと思うんですが)数秒おきのサンプルでも波形がゆがんだりしないでしょうかね?そのあたりがよくわかっておらず、その辺と、アッテネータ周りの定数とで、波形がまた鈍ったりしないかなぁなんてあたりが自信が無く…。
フィルムコンデンサ使うのがよいという情報、助かりました。
基準電圧の件、ここもやっぱり色々考えて難しいなと思っていたんですが、ADCの基準となる「GND」を絶対的な基準として扱うのがよいのか、それとも1/2Vccを(アンプ通して)低インピーダンスで出力して、それを基準にしておけばよいのか、迷ってました。
たとえば5VのArduinoなら、中間の1/2VccがAGND扱い、Vccが+2.5V扱い、GNDが-2.5V扱いといった感じでサンプリングすることになると思いますが、+2.5Vも-2.5Vも、AGNDに対してふらふらするだろうと。
で、その前段のアンプ用電源がこのふらつく+2.5V、-2.5Vであっても、アンプのPSRRが60~80dBほどあれば、信号自体にはあまり影響出ずに済むかなぁ?などと思っていたんで、適当に半分に分圧すればいいかな、と。しかし、よく考えると、ADC用の参照電圧とAGNDの間でふらふらしちゃうとダメですよね…。
外部の参照電圧使いたくないなと思っていたので、そんな風に済ませてしまおうと思っていたんですが。
マイコン内蔵のAREFから参照電圧取り出せば、パーツも少なく、あまり苦労無く出来そうな気がしてきました。
AREFから電圧取り出して、1/2倍したのをボルテージフォロアでインピーダンス下げて、AGNDとすればいい感じでしょうかね?VCC(+2.5V側)がふらふらしても、GND(-2.5V)とAGNDの両者は安定しそうに思います。
アンプの選定もちょっと悩んでます。RailToRailだと選択肢が狭いし、動作電圧も狭いし、速度も遅いし。
なのである程度広い電圧使える高速アンプにして、ADC範囲を超える分は保護ダイオード、というのが一番安全で楽チンな気がしています。
割り込みの取りこぼしの件は、信号ロストよりは、割り込み要因をクリアする前に同じ割り込みが発生してしまっているからなのでしょうね。
(チャタリング防止はソフト側なのかハード側なのかが判って無いので、なんとなくの想像ですが9
一般的な割り込みは、発生した段階でその割り込みの原因となった「割り込み要因のフラグ」が1にセットされると思うんですが、その時点で「割り込み禁止」が設定されていると、「解除」されるまで割り込み要因のフラグは1に立ったまま放置され、割り込み許可になったときに改めて割り込みベクタに飛ばされることになると思います。(その時点で割り込み要因フラグがクリアされる)
もしその割り込み要因による割り込み処理が実行される前に(つまりフラグクリアの前に)、次の割り込み要因が発生してしまうと、「フラグ=1」をさらに「1」で上書きして、元の1が無かったことに。つまり、1回の「割り込み禁止期間中」に2回以上ピンチェンジが発生すると、そのような取りこぼしが起きそうに思います。
(ピンチェンジ割り込みのステータス管理を調べなおして無いので、もしかしたら間違ってるところがあるかもしれません)
なので、この長時間割り込み禁止を掛けている処理がなんなのかを突き止める必要がありそうなのですが、ユーザプログラム側なのか、Arduinoコアの内部処理なのかの切り分けが、なかなか難しそうな気もしますね。
ユーザプログラム側で怪しそうなところが見当たらなければ、シリアルモニタやmillis関数などを使っていないのであれば、そのあたりを設定するレジスタを一旦無効化しちゃう手はあるかもしれません。(UART割り込みやtimer0割り込みあたり?)
あと、割り込み処理内で更新している2バイト以上の変数は、通常処理側ではアトミックアクセスできるようになっていますかね?
とりあえず、なんとなく思いついたのはそのあたりくらいでした。
0.1μFはもっと大きな容量を使いたいのでしょうが、サイズが大きくなるのでこんなとこなんでしょうね。あと計測器だと、耐圧も400Vくらいは必要でしょうからサイズが大きくなっちゃいますし。
秒単位の波形にサグが出るのは、みんな諦めていると思います。
オペアンプの基準電圧をVrefから生成する話は、トラ技に記事を書かれている下間さんの回路図で見て、へーなるほどと感心しました。なお、おっしゃるように、Vrefの出力をボルテージフォロワで受けて、その出力を半分にしていたと思います。
割込みの解説ありがとうございます。頭の中の整理が出来ました。
ピンチェンジ割り込みがミスすることがある件ですが、いろいろ調べたのですが、裏というか表側でいろんなことやっているので、犯人は判っていません。
そもそもピンチェンジ割り込みはArduinoではサポートされていないので、うまく動かなくても仕方がない気がしてきました。
対策として、正式にサポートされている attacheInterrrupt を使ってしのいでます。
こんな感じ→ attachInterrupt(0, pin2IRQ, FALLING);
これ、信号の変化の方向を指定出来るのはいいのですが、1ピンしか読めないので、ダイオードで複数のスイッチの状態を合成して割込みピンにも接続するという、なんだかみっともない回路になっちゃってます。まあピンはいっぱい余っているからいいかと。
そういえば、以前ピンチェンジ割り込みについてちょっと調べて以降、しばらく時間空いてたので忘れてました。Arduinoは、attachInterruptで外部割込みピンしか使えなかったんですね。(ピンチェンジ割り込みは未対応)
attachInterruptの割り込みベクタは、ピンごとに独立しているので、複数のピンを並列に使えたかと思います。調べてみると、328ベースのUnoでは2と3(それぞれint0、int1)を同時に使えるみたいです。
といっても、ロータリーエンコーダで2本、押しボタンで1本使うとなると、すでに1本足りないですかねぇ。
ダイオードで合成する回路がどのような構成になっているかが判らないのですが、信号のfalling edgeを拾うのは大丈夫ですかね?ダイオードで複数信号を束ねるとなると、OR回路にはなると思うのですが、その場合1個でもHighだとfalling edgeにならないような…と思いまして。
XORで複数回路を束ねて、fall+rise両方の信号を拾ったら、ロータリーエンコーダ+押しボタン数個程度を(完全に同時押し/同時変化しない限り)信号の変化をこぼさずに拾えるんではないかという気がします。
あと、もうひとつ気になるのは、attachInterruptで1本に束ねた情報で割り込みを掛けているとなると、割り込み処理内で改めてピンの状態を読み直していると思うのですが、その信号が微小時間でチャタリングを起こしている場合、ピンが変化した直後のピンの内容から、それを読み出しするまでの微小時間で、信号が変化してしまっている可能性があるかと。
その場合に、処理がきちんと行えるロジックになっているかが気になります。
その辺を気にしなくても良くするために、ハード回路(RCフィルタ程度)でチャタリング防止をしておくのがよい気がします。(AVRの入力ピンはシュミットトリガ入力なので、RCフィルタだけで十分かと)
数kHz程度に絞っておけば、割り込み発生時と読み直し時の信号は変化していない状態で読めるはず。
ただ、ちょっと難しいのは、RCフィルタをどこに設定するか、ってあたりですかね。
理想は、全信号線1本1本を一旦RCフィルタに通してから、シュミットトリガを通した上で、「1本に合成→intピン」の流れと、「個別信号→GPIOピン」の流れにすることなんですが、これだと回路が大分複雑に。
ピンが変化した直後に、ラッチ回路でラッチしておくとか出来れば、もう少し楽が出来そうな気もするんですが、いい回路が思いつかず…
SFRを直接弄って、他のピンでピンチェンジ割り込みかけてしまえば、回路はシンプルになりそうな気がしますが、Arduinoスタンダードから外れちゃうと、メンテ性や移植性が悪くなっちゃいますしね。悩ましい。
回路構成がわからないまま想像で書いているので、意味不明なところがあるかもしれません。すみません。
0.1uFは、ある程度妥協して、というのがあるんですね。なるほど。
商用100V電源まで対応するかどうするかは先送りしていたので、耐圧まであまり考えてませんでした。フィルムで250Vとか400Vとかになると、大きいですもんね。
あと、基準電圧の件、ありがとうございます。
いろいろ解説書いていただいてありがとうございます。それ、ほとんど私がやったことの振り返りに近いです。理路整然と文書が出て来るのは流石です。
おさらいですが、最初にピンチェンジ割り込みでやったのは、PCMSK0とPCICRレジスタをセットして、割り込みをISR(PCINT0_vect)で処理するやつです。使うのは今のところ、項目選択、とUP,DOWNの3ピンです。
これ、ボタンを押してもたまに反応しないことがありました。
割り込み処理ルーチンの中で割り込み原因を探しても空振りになった?
そもそもピンチェンジ割込みは、変化があれば割込み発生なので、スイッチがOFFになった時でも割込みが入るので空振り覚悟なの?
Arduinoの割り込み(たぶんタイマー割り込み)と競合して、ピンチェンジ割込みがマスクされている?
こんなことで、あきらめちゃいました。
現在は attachInterrupu を使い、スイッチの状態をダイオードでまとめて int0(pin2)に入力してます。入力ピンはINPUT_PULLUPで吊っておいて、スイッチを負論理で読んでいるのでダイオードで束ねれば大丈夫(のはず)です。
割込みルーチンの中でどのピンが入力されたか探す処理が必要ですが、deigitalRead( )で順番に探していると、その間にピンの状態が変わる恐れがあるので、最初にPINBの内容をコピーしておいて、あとで探すようにしてます。
ポートのチャッタ対策はCRでやっていますが、ちょっとした注意点があるので、詳しくはそのうち書く記事で紹介予定です。
基準電圧をADCのVrefから取る話ですが、下間さんのブログの「居酒屋ガレージ日記」に記事があったはずなので探してみたのですが見つかりませんでした。
この記事に私がコメント入れているあたりが、かすっているのですが、
http://igarage.cocolog-nifty.com/blog/2018/02/post-ce01.htmlちょっと違います。
やはり、もうあれこれ検討されつくしている感じですね。
ダイオードで負論理で合成とうことで、大体回路がわかりました。intピンを適当な抵抗値でプルアップしてあって、同時に小さいコンデンサでGNDに落としてあって(CRフィルタ)、さらにintピンから3本のダイオードを生やして、それぞれ3つのスイッチに繋がっているのかなと。(スイッチと並列にコンデンサも入っている感じ?)
すると各ピンの情報をPINBから読み出すのは、このスイッチとダイオードの間の電圧ということになりますよね。
という回路と仮定すると、ひとつ気になるのは、PINBで読み出すタイミングと、割り込み要因が発生するタイミングは、微妙にラグがあるのでは?という点です。
CRフィルタの時定数にも因ると思うのですが、スイッチ押下でCRフィルタのCの電圧が下がっていって、閾電圧以下になるタイミングでは、まだチャタリングが収まりきっていない可能性があるかと思います。その場合、PINBからは、3本ともHIGHとして読み出されるケースがあるのでは?と。
(それが起きるのか起きないのか、頭の中で考えてみたんですが、私の頭ではよく解りませんでした。チャタリングしている最中の、ダイオードとスイッチの間の電圧って、どういう風に変化するんですかね?VccとGNDの間を行ったり来たり?それとも、CRフィルタのCの電圧とGNDを行ったり来たり?)
割り込みが発生した回数と、ピンが押された(と認識された)回数をカウントしてみて、ズレがあれば、割り込み自体は発生していて、ピン押下が検知できていない(3つともHIGH入力)の状態であると判断できるかもしれません。
ポートのチャタリング対策はあとでまた触れられるとのことなので、続報をお待ちしたいと思います。よろしくお願いいたします。
はい、回路はほぼおっしゃている通りです。
言葉で回路の話をするのは辛いので、回路図をアップロードしました。
https://blog-imgs-124.fc2.com/r/a/d/radiopench/20190210AsclloscopeSchem.png回路図には表現できませんが、ポートの2, 8, 9, 10はCPU内部でプルアップしています。
右側のトランジスタとLEDはスイッチの操作確認用です。
R51はタクトスイッチの接点保護用に入れたものです。
チャッタリングは心配したのですがこれで問題無いようです。もちろん使っているスイッチに依存する話ではあります。
スイッチがONになると少し(100ns?)遅れてD2(Pin2)がLOWになることで、FALLINGの割り込みが入って、割り込み処理ルーチンが起動。で、D8から10のピンの状態を読みに行くわけですが、この間10μSもかからないと思います。チャッタが発生したとしても、たぶんポートを読んだ後になっているのだと思います。
嫌なのは、D2のポートがチャッタで複数回割り込みが入ることですが、大丈夫みたいです。割り込みルーチンの中で変数をインクリメント(デクリメント)する処理にしているので多重割込みがあれば値が1以上進むので判ります。
操作系はソフトも含めてほぼ出来たので、これから信号の入力回路の実験にかかるところです。そんなことで、アップロードした回路図は現在の妄想版です。
この先の山場は、R3を使ってアッテネーターを1/5から1/50に切り替えが出来るかです。
回路図ありがとうございます。3つのスイッチ入力端子とint端子がプルアップモードということで、全体的な動作がよく理解できました。
ひとつ気になるところがあるので、時間を取って、手元のArduino環境で実験してみたいと思います。スイッチは、普通のタクトスイッチでしょうかね?あと、CRの時定数が0.01m秒くらいですかね?
ゲイン調整の仕組み、面白い回路ですね。あぁなるほどと思いました。多分上手く動くような気がします。(もし期待と少し違う感じになったとしても、R2の方もGPIOでオン/オフできるように配線すれば、目論見どおり上手く動きそうな気がします)
一つ書き忘れてました。
ゲイン 1/10x のR3を使わない時はポートを入力にしてHi-zにします。使わないと言ってもポートの保護ダイオードと入力容量はぶら下がってくるので影響がありますが、まあいいかと。
では、