今、電子ドラムを作っているのですが、プログラムが上手く作動せず困っています。
知恵を貸していただけたら幸いです。
センサー部が叩かれると電圧が上昇するようにしてあるのですが、PICでHighと認識されるほど電圧が上がらないので、A/D変換を使い入力を判定しているのですが、2つ以上の入力のプログラムが上手く行きません。
Pinごとに順番にA/D変換し、一定値以上なら変数にpinごとに割り振った2進数を加算し、入力pinすべての判定が終わったときの変数の値別にswitch文で出力を変え、70ms出力するようなプログラムをつくりました。
入力が1pinだけの同様のプログラムは動くのですが、入力を複数にすると動きません。
このように複数のA/D変換をほぼ同時にする方法は無いでしょうか?
デバイスは16F877/20-SP
言語はCでCCS-Cコンパイラーを使っています。
回答よろしくお願い致します。
No.2
- 回答日時:
複数入力のコンバートは可能です。
ADコンバータがちゃんと動かないとしたら次の2点が考えられます。
(1)サンプルホールドキャパシタの蓄積時間が不足。チャンネル切り替えごとに20マイクロ秒が必要です。
(2)ADCON1のPCFGの設定ミス。該当ピンがアナログ入力になっていない。
これがちゃんとしていて動かないとしたら、回路に問題があるか、プログラムにAD変換以外の問題があるかだと思います。
チャンネル設定の後に
delay_us(60)いれてますし、
all_analogにしてあるので大丈夫だとは思うのですが、
私の予想としてはA/D変換での入力複数をループさせているので、AN0に入力したときにAN1の設定のdelayが入ってて駄目なのだと思うのですがどうでしょうか?
No.3
- 回答日時:
AD変換のプログラムは、
set_adc_channel(0);
delay_us(60);
an0 = read_adc();
set_adc_channel(1);
delay_us(60);
an1 = read_adc();
といった感じで大丈夫なはずです。
これとは違う書き方のプログラムでしょうか?
>AN0に入力したときにAN1の設定のdelayが入ってて駄目なのだと思うのですがどうでしょうか?
サンプルホールドキャパシタの蓄積時間ことを言っているならdelay_us(60);もやっていてダメな理由は分かりません。
何らかのディレイが必要と感じるなら試しに入れてみてはどうでしょうか?
残念ながら回路図とかプログラムコードを見ないと、これ以上は推測不能ですね。せめて肝心のAD変換部のプログラムコードのだけでも見たいです。
回答ありがとうございます。
プログラムを抜粋しますと、こんな感じになってます。
int judge(int channel),
int main()
{
long out;
set_tris_a(63);
set_tris_e(7);
set_tris_c(0);
set_tris_d(0);
setup_adc_ports(all_analog);
setup_adc(ADC_CLOCK_DIV_32);
while(0)
{
port_c = 0;
port_d = 0;
out = 0;
set_adc_channel(0);
channel = 0;
out += judge(channel);
set_adc_channel(1);
channel = 1;
out += judge(channel);
set_adc_channel(2);
channel = 2;
out += judge(channel);
set_adc_channel(3);
channel = 3;
out += judge(channel);
set_adc_channel(4);
channel = 4;
out += judge(channel);
set_adc_channel(5);
channel = 5;
out += judge(channel);
set_adc_channel(6);
channel = 6;
out += judge(channel);
set_adc_channel(7);
channel = 7;
out += judge(channel);
if(out > 0)
{
switch()
{略}
delay_ms(70),
}
}
return 0,
}
int judge(int channel)
{
int output;
delay_us(60);
value = read_adc();
if(value >=380)
{
switch(channel)
{
case 0: output = 1 ;
break;
case 1: output = 2 ;
break;
case 2: output = 4 ;
break;
case 3: output = 8 ;
break;
case 4: output = 16 ;
break;
case 5: output = 3 2;
break ;
case 6: output = 64 ;
break;
case 7: output = 128;
break;
}
}
return output;
}
別の変数に値を保存しておいて、あとで判定したほうがいいですかね?
No.4ベストアンサー
- 回答日時:
コードを見ましたが、大問題があります。
(1)whileの条件
mainのwhile(0)←これだとループしません。これで反応がなかったのかも知れません。正しく書くならwhile(1)です。
それとint channel;の定義がないですが、エラーになりませんでした?
(2)judgeのoutput
outputが初期化されていませんので、ボタンが押されなかったときに不定値になります。if(value >=380)のelseで必ず0を入れてください。
あとコードが長いのでシンプルにする方法も教えます。
int ch;←先頭で定義をお願いします。
{略}
//アナログチャンネルの処理。
out = 0;
for( ch=0 ; ch<8 ; ch++ ) {←ループで処理します。
set_adc_channel(ch);
out |= judge(ch);←加算ではなく、OR演算が望ましいです。
}
{略}
int judge(int channel)
{
int output;
delay_us(60);
value = read_adc();
if(value >=380)
{
output = 1 << channel;←この場合、シフト演算でswitch文でやりたかったことと同じことができます。
} else {
output = 0;←ボタンが押されなかったら0。
}
return output;
}
//
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
変数の値が勝手に変化する原因
-
360度を超える角度
-
プログラミングなんですが。。
-
65536は2の何乗なのでしょうか?
-
Excelで4096点以上のFFTの方法
-
モジュロ
-
バッチファイルでウインドウを...
-
あるプログラムのコマンドライ...
-
クリックするとページ内で説明...
-
バッチ、vbs等でのソフトウェア...
-
常駐プログラム
-
powered byの表記について
-
バッチファイルでUSB挿入時に実行
-
AutoCADを用いて板金展開図を自...
-
VB6のWScript.Shellについて
-
Bluestacks内でダウンロードし...
-
VBAを使って、pdfを関連付けら...
-
EXCELなどで「返す」という表現
-
VBAで仕様書は書きますか?
-
VBでReplace
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
変数の値が勝手に変化する原因
-
JCLの基本について教えてください
-
Sublime Text 3でのFortranプロ...
-
【JAVA】数字をひし形に出力す...
-
360度を超える角度
-
ProC 固定SQLでNULLってどう表...
-
COBOLのピリオド
-
Fortran90についての質問です。
-
3つの整数のうち奇数のみを表示...
-
main関数終了時のreturnの意味は?
-
fortran if文
-
fortranについて
-
4桁の数値を逆に表示されるプ...
-
3次関数を作るプログラム
-
PICのプログラムでsrandを使う...
-
整数格子点を列挙するプログラム
-
ロトカ=ヴォルテラ方程式 をC...
-
Fortran90のプログラムについて
-
Segmentation fault
-
Fortran "実引数の型が仮引数の...
おすすめ情報