チャタリング対策
Re: チャタリング対策
試していませんが、適当な間隔でポートを読み、数回同じ値が連続した時、かつその時のみ条件分岐に使う値を更新するといいかもしれません。
↓このサイトでは1ビットですが、複数ビットでも同じと考えられるでしょう。
PICマイコン スイッチの入力 - パレットソフト
↓このサイトでは1ビットですが、複数ビットでも同じと考えられるでしょう。
PICマイコン スイッチの入力 - パレットソフト
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: チャタリング対策
言っていることはなんとなく理解できたのですがみけCAT さんが書きました:試していませんが、適当な間隔でポートを読み、数回同じ値が連続した時、かつその時のみ条件分岐に使う値を更新するといいかもしれません。
↓このサイトでは1ビットですが、複数ビットでも同じと考えられるでしょう。
PICマイコン スイッチの入力 - パレットソフト
どうコーディングすればいいのでしょうか?
サンプルコードを見ながら書いているのですが上手くいきません。
よろしくお願いします。
Re: チャタリング対策
なにをどうしたらいいかわかりません。みけCAT さんが書きました:試していませんが、適当な間隔でポートを読み、数回同じ値が連続した時、かつその時のみ条件分岐に使う値を更新するといいかもしれません。
↓このサイトでは1ビットですが、複数ビットでも同じと考えられるでしょう。
PICマイコン スイッチの入力 - パレットソフト
質問①
switchの引数を(SwEdge)にすると前回情報がないので起動時に動作をしません。
どうすればいいですか?SwDataの現在のスイッチ情報だけみればいいのでしょうか?
質問②
特にswitch文に拘ってる訳じゃないのですがこの記述だと飛んだ先の関数で
SwEdgeが更新されないので無限ループに入ってしまいます。
main関数の中でif文で書いてもみたのですがどうしてもうまくいきません。(立てたビットを戻せないとか)
どうすればいいですか?
よろしくお願いします。
while(1){
SwData = SwGet(); // スイッチの取得
#if 1
SwChatExcute(SwData); // スイッチ情報のチャタリング除去 同じ値を数回見ている
SwData = SwChatGet(); // 現在のスイッチ確定状態を取得
#endif
SwEdge = (SwBefore ^ SwData) & SwData; // 前回0で今回1のビットのみ1になる
SwBefore = SwData; // 次回判定用に今回の情報を前回の情報へ
while(1){
switch(SwEdge){
case 0b00000001: PATTERN0(); break;
case 0b00000010: PATTERN1(); break;
case 0b00000011: PATTERN2(); break;
}
}
void PATTERN0(void){
while(SwEdge == 0x01){
PORTAbits.RA0 = 1;
}
PORTAbits.RA0 = 0;
return;
}
Re: チャタリング対策
タイマー割り込みが使えるのであれば、
タイマー割り込みでスイッチの状態をポーリングしてチャタリングを除去したスイッチの状態を変数に記録し、
メインの処理ではリアルタイムのスイッチの状態のかわりにその記録した変数を見て処理を行うといいと思います。
※試していません
タイマー割り込みでスイッチの状態をポーリングしてチャタリングを除去したスイッチの状態を変数に記録し、
メインの処理ではリアルタイムのスイッチの状態のかわりにその記録した変数を見て処理を行うといいと思います。
※試していません
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: チャタリング対策
チャタリングを除去したスイッチの状態はSwDataの変数に格納しています。whileの上にTOIE=1にしてるのでポーリングもしてる(?)と思います。しかし、その変数を見て処理するとスイッチが切り替わらなくなります。それにオンエッジ検出(教えていただいたサイトに書いてある)はしなくていいということですか?みけCAT さんが書きました:タイマー割り込みが使えるのであれば、
タイマー割り込みでスイッチの状態をポーリングしてチャタリングを除去したスイッチの状態を変数に記録し、
メインの処理ではリアルタイムのスイッチの状態のかわりにその記録した変数を見て処理を行うといいと思います。
※試していません
当方まだプログラムを勉強しはじめてひと月も経っていないため言葉だけではまったく理解できないことが多いのでよろしくお願いします。
Re: チャタリング対策
SwGet()、SwChatExecute()、SwChatGet()の中身が載っていないので、本当かどうかわかりません。ぱおぱお さんが書きました:チャタリングを除去したスイッチの状態はSwDataの変数に格納しています。
肝心の割り込みハンドラが載っていないので、本当にポーリングしてるかどうかわかりません。ぱおぱお さんが書きました:whileの上にTOIE=1にしてるのでポーリングもしてる(?)と思います。
提示されたコードではswitch文のみをwhile(1)で囲んで変数を更新していないように見えます(割り込みハンドラで更新している可能性は否定できません)が、変数は更新していますか?ぱおぱお さんが書きました:しかし、その変数を見て処理するとスイッチが切り替わらなくなります。
ぱおぱおさんがやりたいことによります。ぱおぱお さんが書きました:それにオンエッジ検出(教えていただいたサイトに書いてある)はしなくていいということですか?
スイッチが切り替わったタイミングで何か特別な処理をしたいのであればオンエッジ検出をするべきですし、そうでなければしなくていいでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: チャタリング対策
SwGet()、SwChatExecute()、SwChatGet()の中身はみけCATさんに教えていただいたサイトにサンプルプログラムがありました。それをそのまま使っています。みけCAT さんが書きました:SwGet()、SwChatExecute()、SwChatGet()の中身が載っていないので、本当かどうかわかりません。ぱおぱお さんが書きました:チャタリングを除去したスイッチの状態はSwDataの変数に格納しています。
これは以前、みけCATさんに教えていただいたtmr0についてのコードをそのまま使用しています。みけCAT さんが書きました:肝心の割り込みハンドラが載っていないので、本当にポーリングしてるかどうかわかりません。ぱおぱお さんが書きました:whileの上にTOIE=1にしてるのでポーリングもしてる(?)と思います。
見ての通りswitch文に入るとPATTERN関数に飛ぶので変数は更新されていません。ということは割り込みハンドラ(?)がポーリングしていないってことですね。main関数内では動いてるように思えたのですが・・・。恐らくここら辺を理解していないのが原因のように思えます。どこで何をどうすればいいのか全然わかりません。ご教示ください。みけCAT さんが書きました:提示されたコードではswitch文のみをwhile(1)で囲んで変数を更新していないように見えます(割り込みハンドラで更新している可能性は否定できません)が、変数は更新していますか?ぱおぱお さんが書きました:しかし、その変数を見て処理するとスイッチが切り替わらなくなります。
[/quote]みけCAT さんが書きました:ぱおぱおさんがやりたいことによります。ぱおぱお さんが書きました:それにオンエッジ検出(教えていただいたサイトに書いてある)はしなくていいということですか?
スイッチが切り替わったタイミングで何か特別な処理をしたいのであればオンエッジ検出をするべきですし、そうでなければしなくていいでしょう。
やりたいことはLチカです。2つのLEDを点灯・消灯をいろんなパターンでLチカしたいです。
どうぞよろしくお願いします。
Re: チャタリング対策
わかりました。ぱおぱお さんが書きました:SwGet()、SwChatExecute()、SwChatGet()の中身はみけCATさんに教えていただいたサイトにサンプルプログラムがありました。それをそのまま使っています。
更新されたコードはわかりませんが、提示されているコードはチャタリング防止どころか入力の処理がありません。ぱおぱお さんが書きました:これは以前、みけCATさんに教えていただいたtmr0についてのコードをそのまま使用しています。
すなわち、ポーリングなんか全くしていませんね。
予想ですが、割り込みハンドラでSwChatExecute(PORTB);を呼び出し、メインの処理(各パターンの処理をする関数を含む)でSwEdgeの代わりにSwChatGet()を使うと良さそうだと思います。ぱおぱお さんが書きました:見ての通りswitch文に入るとPATTERN関数に飛ぶので変数は更新されていません。ということは割り込みハンドラ(?)がポーリングしていないってことですね。main関数内では動いてるように思えたのですが・・・。恐らくここら辺を理解していないのが原因のように思えます。どこで何をどうすればいいのか全然わかりません。ご教示ください。
やりたいことを実現するプログラムを書けばいいでしょう。ぱおぱお さんが書きました:やりたいことはLチカです。2つのLEDを点灯・消灯をいろんなパターンでLチカしたいです。
オンエッジ検出の意味はわかっていますか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: チャタリング対策
みけCATさんのアドバイスを基に割り込みハンドラに下記の部分を丸ごと入れてswitchの変数をSwDataにしたら変数が更新されるようになりました。みけCAT さんが書きました:予想ですが、割り込みハンドラでSwChatExecute(PORTB);を呼び出し、メインの処理(各パターンの処理をする関数を含む)でSwEdgeの代わりにSwChatGet()を使うと良さそうだと思います。
void interrupt InterTimer(void){
if(T0IF == 1){
cnt++;
T0IF = 0;
if(cnt >= 5){
cnt = 0;
SwData = SwGet();
SwChatExcute(SwData);
SwData = SwChatGet();
}
}
}
プリスケール:8
クロック:4MHz
ソフトウェアでの分周:5
申し訳ありません。理解していません。ただ単に前回と今回の違いを見ている変数だと思いSwEdgeの変数を使っていました。オンエッジとはどんな意味ですか?どんな時に使うのが正しいのでしょうか?よろしくお願いします。みけCAT さんが書きました:オンエッジ検出の意味はわかっていますか?
Re: チャタリング対策
「20msecほどずれる」というのは何がですか?ぱおぱお さんが書きました:しかし、スイッチの切り替え時にものすごく時間がかかるようになった気がします。そこでTMR0の周期を変えたのですが20msecほどずれるのです。以前教わった(tmr0について)ようにTMR0に入れる値を計算したら1,000,000÷(256×8)=781.25になり、256-781.25=-525.25でマイナスになってしまいます。このような場合はどうすればいいのでしょうか?
動作がいい感じになるようにプログラムを修正して書き込めばいいと思いますが、どうなってほしいのですか?
参考として、4MHz ÷ (4(何クロックで1回インクリメントか) × 8(プリスケーラ) × 256(オーバーフローまでのカウント数) × 5(ソフトウェアでの分周)) ≒ 97.7Hz となり、
この速さで5回同じ値が出るのを確認するのにかかる時間は約51.2msとなります。
オンエッジとは前回のポーリングではオフだったのに今回のポーリングでオンになったやつ、すなわちオフからオンに切り替わった瞬間のことです。ぱおぱお さんが書きました:オンエッジとはどんな意味ですか?どんな時に使うのが正しいのでしょうか?
オフからオンに切り替わったことに反応して何か処理をしたい時に使うのが正しいでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: チャタリング対策
言葉足らずで申し訳ありません。RA0のbitを1秒ごとにON/OFFしたときにオシロで計測すると1.020msで20msほどずれてしまうのです。この20msをもう少しなんとかしたいのですが、分周をいじればいいのかプリスケーラなのかTMR0に入れる値を変えるのか、タイマーをいまだ理解できておらずどうすればいいのかわかりません。もう少しお知恵をお貸しください。この20msのずれをなくすにはどうしたらいいですか?みけCAT さんが書きました: 「20msecほどずれる」というのは何がですか?
動作がいい感じになるようにプログラムを修正して書き込めばいいと思いますが、どうなってほしいのですか?
なるほど。とてもよくわかりました。みけCAT さんが書きました:オンエッジとは前回のポーリングではオフだったのに今回のポーリングでオンになったやつ、すなわちオフからオンに切り替わった瞬間のことです。
オフからオンに切り替わったことに反応して何か処理をしたい時に使うのが正しいでしょう。
Re: チャタリング対策
どのようなプログラムでやっていますか?ぱおぱお さんが書きました:RA0のbitを1秒ごとにON/OFFしたときにオシロで計測すると1.020msで20msほどずれてしまうのです。この20msをもう少しなんとかしたいのですが、分周をいじればいいのかプリスケーラなのかTMR0に入れる値を変えるのか、タイマーをいまだ理解できておらずどうすればいいのかわかりません。もう少しお知恵をお貸しください。この20msのずれをなくすにはどうしたらいいですか?
それによって変わると思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: チャタリング対策
下記のように書いてます。みけCAT さんが書きました:どのようなプログラムでやっていますか?ぱおぱお さんが書きました:RA0のbitを1秒ごとにON/OFFしたときにオシロで計測すると1.020msで20msほどずれてしまうのです。この20msをもう少しなんとかしたいのですが、分周をいじればいいのかプリスケーラなのかTMR0に入れる値を変えるのか、タイマーをいまだ理解できておらずどうすればいいのかわかりません。もう少しお知恵をお貸しください。この20msのずれをなくすにはどうしたらいいですか?
それによって変わると思います。