• ベストアンサー
  • すぐに回答を!

PICのA/Dを使うプログラムについて質問です

今、電子ドラムを作っているのですが、プログラムが上手く作動せず困っています。 知恵を貸していただけたら幸いです。 センサー部が叩かれると電圧が上昇するようにしてあるのですが、PICでHighと認識されるほど電圧が上がらないので、A/D変換を使い入力を判定しているのですが、2つ以上の入力のプログラムが上手く行きません。 Pinごとに順番にA/D変換し、一定値以上なら変数にpinごとに割り振った2進数を加算し、入力pinすべての判定が終わったときの変数の値別にswitch文で出力を変え、70ms出力するようなプログラムをつくりました。 入力が1pinだけの同様のプログラムは動くのですが、入力を複数にすると動きません。 このように複数のA/D変換をほぼ同時にする方法は無いでしょうか? デバイスは16F877/20-SP 言語はCでCCS-Cコンパイラーを使っています。 回答よろしくお願い致します。

共感・応援の気持ちを伝えよう!

  • 回答数4
  • 閲覧数535
  • ありがとう数5

質問者が選んだベストアンサー

  • ベストアンサー
  • 回答No.4
  • zwi
  • ベストアンサー率56% (730/1282)

コードを見ましたが、大問題があります。 (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

  • PICでの入力カウントについて

    PICを最近はじめました。 スイッチを10回押せば、出力がONするようなプログラムを作るにはどうすればよろしいでしょうか? PICは16F819で、コンパイラはCCS社のPCMを使用しています。 わかる方、よろしくお願いいたします。

  • picへのフォトインタラプタ出力の入力

    現在、フォトインタラプタの入力をpicに入力してからカウンターに出力する回路を作成しています。 フォトインタラプタでモータの回転数(3150rev/min)を数えています。 この時ccs社のコンパイラを使用して以下のようなプログラムを作成しました。 if(input_PIN(C4)==1){   delay_ms(2); if(input_PIN(C4)==0{ 出力; } } 上記のdelay_ms(2)があれば製作に計測できますが、delay_ms(2)を消去したプログラムでは、全く出力されません。 どういった理由からこのような現象になるのでしょうか? また、間の待ち時間をなくしても正確に回転数を計測できるようなプログラムがおわかりの方はいらっしゃいますでしょうか?

  • マイクロチップ社PIC用の Cコンパイラについて

    今までPICのプログラムを作るのにマイクロチップ社のアッセンブル言語を使っていましたが、今後もう少し複雑なプログラミングをしようと思っているのでC言語のコンパイラを購入しようと思っています。 ここで結構迷いまして、どのメーカーのコンパイラがいいか色々な意見を聞きたいために書き込みをしました。 コストパフォーマンスで考えていた候補が CCS-CかMikroCです。 試しにMikroCを使ってみたところ確かにあっという間にちょっとしたプログラムが作れるので快適なのですが、ソフト上のシミュレーション機能で変数の変化を見ると時々挙動が変だったりするのが気になります。 (知っておくべき知識があるのかバグなのかはわかりません)。 また、CCS-Cは若干値段が高く癖のあるC言語ということを聞きますが、人気があるように思えます。私は癖があってもそれを覚えればいいと楽観的なのですが・・。 PIC用のCコンパイラに見識がある方がおられれば意見をお聞かせいただければと思います。 こういうところはかなり問題だとか、こういう機能はすごく便利だとか、こっちの方がこうだから絶対お勧めだとか、なんでもいいので教えていただければ幸いです。 よろしくお願いします。  

その他の回答 (3)

  • 回答No.3
  • zwi
  • ベストアンサー率56% (730/1282)

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.2
  • zwi
  • ベストアンサー率56% (730/1282)

複数入力のコンバートは可能です。 ADコンバータがちゃんと動かないとしたら次の2点が考えられます。 (1)サンプルホールドキャパシタの蓄積時間が不足。チャンネル切り替えごとに20マイクロ秒が必要です。 (2)ADCON1のPCFGの設定ミス。該当ピンがアナログ入力になっていない。 これがちゃんとしていて動かないとしたら、回路に問題があるか、プログラムにAD変換以外の問題があるかだと思います。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

チャンネル設定の後に delay_us(60)いれてますし、 all_analogにしてあるので大丈夫だとは思うのですが、 私の予想としてはA/D変換での入力複数をループさせているので、AN0に入力したときにAN1の設定のdelayが入ってて駄目なのだと思うのですがどうでしょうか?

  • 回答No.1

トランジスタを使ってもっと昇圧すれば・・・

共感・感謝の気持ちを伝えよう!

質問者からのお礼

回答ありがとうございます。 今回は後先考えずセンサー部を量産してしまっているのでプログラムでどうにかするしかなくて。 現在のセンサーはB級増幅回路のつもりが、何故か無信号時に0V、有信号時に3.5Vくらいまで上がるという回路なのですが…

関連するQ&A

  • PICのプログラムカウンタについて

    プログラムカウンタでポートAに4bitの2進数を入力して、変換された2進数のデータをポートBに出力させることはできたのですが、 ポートCにも違うデータを同時に出力させたいのですが、どういった命令文を作ったらいいでしょうか? 例えば、ポートAが「HLHL」の入力の時にポートBでは「HLLH」、ポートCでは「LLHL」を出力させる方法です。 言語はアセンブラ、マイコンはPIC16F886です。 よろしくお願いします。

  • PICのPWMについてのプログラム

    先程似たような質問してしまいましたが変更します。 PICを使い外部からのアナログ音声約0.5秒をPIC内臓のAD変換機能を使用してPIC内に格納します。 元々スイッチを2つ付けて1つを押したら上記のようになり、もう1つを押したら格納されているデジタルデータがPWM波となりポートBから出力される物を作りたいです。 出力された波形はローパスフィルターを通りDA変換されてアナログ音が外部に出る。 『0.5秒しか録音できないレコーダ』みたいなものをつくりたいというのが全体図です。 AD変換やDA変換はなんとか解るのですがPICからPWM波を出力する回路(プログラム)がよく解りません。 知っている方いましたら力を貸してもらえませんでしょうか?

  • PICプログラムについて

    こんにちは 早速ですが質問です。 PIC16A84を使用しています。発振は4Mhzを使用しようと考えています。 入力Aの信号ONで出力Aの信号を(通常ON)をを25mSec間OFFし次にONを25mSecと入力Aの信号がONの間繰り返すのですが、この他に、入力Bと出力Bがあり、入力A、出力Aと同じ動きをするのですが、入力AとBが同時にONしたときのプログラム方法がわかりません。(プログラムの同時進行の場合のプログラミング方法) わかりずらいですがよろしくお願い致します。

  • C言語のPICプログラミングなんですが、

    C言語のPICプログラミングなんですが、 これのどこがおかしいか教えてください。 if(input(PIN_B1)) { while(input(PIN_B2) == 0) { output_high(PIN_B7); //前進後進パルス出力 delay_us(50); //変換待ち output_low(PIN_B7); delay_us(16000); //共通遅延16000us } break; } if(input(PIN_B1)) { while(input(PIN_B2) == 0) { output_high(PIN_B7); //前進後進パルス出力 delay_us(50); //変換待ち output_low(PIN_B7); delay_us(16000); //共通遅延16000us } break; }

  • picを使った温度計

    picと温度センサーを使ってLCDに温度を表示するようなものを作ろうと思っています。 温度センサーはS-8100Bというものを使って直接picに接続しており、picに内蔵された10bitのAD変換器を使って温度を測定しようと思っています。 AD変換の基準電圧を5Vにしてうまくフルスケールになるようにと思っているのですがどう計算したらいいのかわからなく困っています。 センサーの温度特性は-8mV/℃で30℃の時1.508V、80℃の時1.095Vを出力します。 精度としては室内の温度を測定したいので、小数点以下は四捨五入して0~80℃(実際は80℃もいりませんが)の範囲で考えています。 また、部品数を少なくしたいので電圧値がらみの計算は全てプログラム上でやろうと思っています。 フルスケールでかつプログラム上で処理しやすくするにはどのように電圧値を考えたらよいのでしょうか。

  • PIC12F683からパソコンへのシリアル通信

    PIC12F683 を使って、簡単な電圧ロガーを作ろうとしているのですが、 パソコンへの送信が正常に行われません、わかる方がおられたらどこが悪いのかご指摘願います。 PICの書き込み、PICからのデータ受信に用いているパソコン(のマザーボード)は、G45GCMX-S2です。 参考にさせていただいているサイトは、 http://www8.plala.or.jp/InHisTime/page005.html#PIC-002 なのですが、上記サイトのソースプログラム http://www8.plala.or.jp/InHisTime/PIC-001/DataLogger2.c には何の手も加えず、動作させております。 また、PIC->PCへの接続端子の接続が正常である事も、テスターで確認しております。 (回路から、PCのCOM1(DSUB-9pin)へ接続。) コンパイル(MikroC 8.88)、hexの書き込み(RCDライタ)までうまくいくのですが、 ブレッドボードに組んで、電源を入れてもGP5の電圧に変化が無い、という状況です。 (LEDを点滅させるプログラムを書き込んだ場合は問題なく動作しています。) 実際の各端子は Vdd 1pin : 5V GP5 2pin : open (※ この端子の電圧に変化が無い) GP4 3pin : open GP3 4pin : 5V CPP1 5pin : open AN1 6pin CH1 : open AN0 7pin CH0 : open Vss 8pin : GND となっています。テスターで測ると 2pinは2.3Vで一定、 レベル変換用のトランジスタのコレクタは3.4V一定です。 念のためレベル変換回路 (http://www8.plala.or.jp/InHisTime/img2022.jpg の右上、C1815の部分。) 単体の動作確認はしています。 ハイパーターミナルその他のソフトで通信しようと試みたのですが、 反応が無いため、ピンの電圧を測ってみたところ、パソコンへの送信出力ピンの電圧が 変化していないので、これは正常じゃないのでは無いか?と思い、 詳しい方のアドバイスをいただこうと投稿しました。 上記のソースであれば、1秒ごとに出力電圧に反応があるかと思いますが、無反応です。 説明がややこしくなりましたが、わかる方がおられましたらよろしくお願いします。

  • PICの誤動作についての質問です

    現在PIC18F24K20というPICを使用していて、2つの入力信号に対して、1ビットずつ判定を行いその2つの信号が間違っていればPORTBを+1してカウントしていくというプログラムを作っています。 RC0、RC2から信号を入力しています。Receive0でまずタイミングを合わせて、Receiveで間違っているかの判定を行うというプログラムです。 Receive0 BTFSS PORTC,0 ;RC0がHighなら次の命令をスキップ GOTO Receive0 NOP NOP NOP NOP NOP ;*** 入力信号の解析 Receive BTFSS PORTC,0 ;RC0がHighなら次の命令をスキップ GOTO ZERO BTFSS PORTC,2 ;RC2がHighなら次の命令をスキップ INCF PORTB,F ;PORTBを+1 NOP GOTO Receive ZERO BTFSC PORTC,2 ;RC2がLowなら次の命令をスキップ INCF PORTB,F ;PORTBを+1 NOP GOTO Receive (PORTの設定は省かせてもらっています) プログラムにおかしい点があれば指摘していただければうれしいです。 回路は入力をFPGAから直接RC0、RC2に入力して、PORTBも開放してロジアナで波形を観測しています。 ロジアナで見ると思っているような動作ではなく、PORTBが勝手にHighやLowになってしまっています。どのようなことが問題になっているのでしょうか?

  • C言語 PICプログラムについて質問です

    さっそく中身を書きます PIC16F84Aのプログラムで RB0,RB1,RB6を出力ポートと宣言し、RB7を入力ポートと宣言しています。 PORTB=0x03; とすると、RB7ポートは変な異なったりしちゃいますか。

  • PIC(16F84A)を使用しての250Hz以上…

    PIC(16F84A)を使用しての250Hz以上の周波数判定について 16F84Aを使用して外部からの信号(方形波)周波数をRA2に入力して判定し、ある周波数以上であればRA2への入力信号がHiの時にRB0からHiを出力、Lowの時には出力しないというプログラムを組み、その先にトランジスタを取り付けてLEDを点滅させるというテストを行っています。 100Hz基準くらいの周波数の判定は順調に行えるようになりましたが、約200Hzを判定基準にすると、LEDが外部信号と同期しなくなりました。 誤動作といったほうがいいのかもしれませんが、安定しない動作を行います。200Hzの信号を入力しているのに、1Hzくらいの点滅を繰り返す・点灯しっぱなし・点灯しないetc. ←同じプログラムを焼いたPICでです。  外部発振子は20MHzのものを使用しています。 私は、PICの処理速度?が追いつかなくなったのかなと考察したのですがどういった原因が考えられますか?対策方法等はありますか? PIC初心者なので、簡単な言葉で説明していただければ幸いです。 よろしくお願いします。

  • PIC の出力ピン(High) には電流は流れ込まない?

    PIC の出力ピン(High) には電流は流れ込まない? プルアップ抵抗の勉強をしています。出力ピンがLow の時は内部でグラウンド接続となっていて、流れ込み電流がありますよね。 ではHigh の時、プルアップ抵抗により電圧が上がるわけですから、出力ピン側に流れ込むと思うんです。従ってPIC の内部ではHigh の時に逆流しないようにダイオード経由になっている、と考えて差し支えないのでしょうか? そういう説明のされたサイトを見かけないので、誤ってますか?