• ベストアンサー

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コンパイラーを使っています。 回答よろしくお願い致します。

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

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

aerialis
質問者

お礼

ありがとうございます。

その他の回答 (3)

  • zwi
  • ベストアンサー率56% (730/1282)
回答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変換部のプログラムコードのだけでも見たいです。

aerialis
質問者

お礼

回答ありがとうございます。 プログラムを抜粋しますと、こんな感じになってます。 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; } 別の変数に値を保存しておいて、あとで判定したほうがいいですかね?

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

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

aerialis
質問者

お礼

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

回答No.1

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

aerialis
質問者

お礼

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

関連するQ&A

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

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

  • PIC16F88のA/D変換の時間設定について質問です。最近PICを始

    PIC16F88のA/D変換の時間設定について質問です。最近PICを始めたばかりの素人です、色々な書籍を読みあさりC言語でプログラミングしていますが、PIC16F88のA/D変換を利用しステッピングモータの回転数を制御するプログラムを作りました。そこでアナログからデジタルに変換する待ち時間が必要とわかりとりあえず仕様書に19.72μSの待ち時間らしき時間がありましたので使用しましたがこれが正しいのかわかりません。どうぞアドバイスお願いします。 以下プログラムの抜粋です。コンパイラはCCS社のPCMを使用しています。 #include<16f88.h> #fuses HS,NOWDT,PUT,NOPROTECT,NOLVP,NOBROWNOUT, #device ADC=10 #usedelay(clock=10000000) 途中省略 void DEGVR() { ///////////////////////VR→デジタル計算/////////////////////// set_adc_channel(2);//A/D変換チャンネル設定 delay_us(20);//変換にかかる時間19.72μs vr = read_adc();//A/D変換レジスタリードしvrへ 途中省略 main() { ////////////////////////vr設定/////////////////// setup_adc_ports(sAN2); //アナログポート設定 setup_adc(ADC_CLOCK_DIV_32);//アナログ変換クロック設定 途中省略

  • PICのA/D変換の入力が何故か0Vになってしまいます・・・

    現在、PIC12f675を用いて下記のようなことをしたいと検討しているのですが、 中々思った通りに動いてくれません。 どなたか分かる方がいらっっしゃいましたらアドバイスお願い出来ないでしょうか? 「開発環境」 ・CCSのCコンパイラを使用 ・PICは12f675 「内容」 アナログ入力端子に任意の電圧を加えて、RS232CでPC上にその電圧を表示する。 現在、アナログ入力端子(AN0)に電源電圧から分圧して0.5Vや1Vなどの電圧を加えているのですが、 何故か入力端子の電圧をテスターで測定すると0Vとなり、PC上でもやはり0Vと表示されてしまいます。 何故、任意の電圧を加えても全て0Vとなってしまうのかが分かりません。 おそらくプログラム上でのミスがあると思うのですが・・・ 検討中のプログラムを下記に書きます。 ***************************************************** ///// 初期設定 ///// #include <12f675.h> #device ADC=10 #fuses INTRC_IO, NOWDT, PUT, NOPROTECT, BROWNOUT /////RS232C使用宣言///// #use delay(CLOCK = 4000000) #use rs232(BAUD = 9600, XMIT = PIN_A2, RCV = PIN_A1) //GP1=受信 GP2=送信 //// メイン関数 void main() { // A/D初期設定 float data; setup_adc_ports(AN0_ANALOG); //AN0をアナログ設定 setup_adc(ADC_CLOCK_INTERNAL); //ADCのクロック設定(内部発振) set_tris_a(0); output_A(0); while(1) { set_adc_channel(0); delay_us(50); data = read_adc(); data = (data * 3.0) / 1024; printf("電圧 = %1.3fV\r\n",data); } } ***************************************************** 申し訳ありませんが、アドバイスお願いします。

  • PIC18F2550でのA/D変換

     初めて質問させていただきます。  現在、PIC18F2550でA/D変換プログラムと、USB(CDC使用)でのパソコンへの文字列送信プログラムを作成しているのですが、うまくいかないので教えてください。  開発言語はCで、コンパイラはC18で、MPLAB-IDEを使用しています。  A/D変換を行う際、sleep機能を用いているのですが、A/D変換割り込みでsleepを解除すると、パソコンへの文字列送信ができなくなってしまいます。  sleep機能を使用しなければ文字列は送信できるので、sleepしたせいで文字列が送信できなくなっているみたいです。    sleep解除後もパソコンからの受信は可能で、プログラム自体は動いているみたいです。送信だけができません。    文字列の送信プログラムは下記の命令を使用しています。  if(mUSBUSARTIsTrfReady()) putrsUSBUSART("xxxx xxxx");  おそらく、 mUSBUSARTIsTxTrfReady が0を返しているのだと思いますが、原因が全くわかりません。  このままでは開発が進まず、困っています。分かる方がいらっしゃいましたらどうかよろしくお願いします。  

  • PICの型番で最後にAがついている改良版について

    PICの型番で最後にAがついている改良版とついてない物は具体的にどのように違うのでしょうか? タイマーの精度だけなら、PICのCコンパイラでデバイス指定する時Aのついている物とついていない物、区別する必要ないじゃないですか?僕の持っているCCSのCコンパイラは古くてAのついていない物が沢山あります。メーカーに問い合わせたら古すぎて、アップデートは出来ないとのことです。 デバイス指定する時Aのついている物とそうでない物が存在する理由を教えてください。どうかよろしくお願いいたします。

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

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

  • PICプログラムについて

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

  • PICプログラム C言語とアセンブラ言語

    PIC18シリーズを使用して、プログラミングをしています。コンパイラはCCS-Cです。今まではすべてC言語で書いてきたのですが、アセンブラでしか設定ができない部分があり、今までのC言語のソースに加えてアセンブラを組み合わせようと思っているのですが、C言語とアセンブラを組み合わせることは可能なのでしょうか?

  • PICのCコンパイラーについて

    PICのCコンパイラーでどれを使うかで迷っています。 高価なものでCCS社やmicrochipのものがいいかなと思うんですが、 やはり安く済まそうと思うとmikroCやBoostCがやすいかなって思います。安いにこしたことはないんですが、購入後に不便に感じて、あっちのコンパイラーをにしとけば良かったなどと後悔したくもありません。 実際、ある程度の経験がないとそれぞれの(コンパイラーの)長所と短所が見えてこない気がしましたので、お伺いします。 説明がわかりづらいかもしれませんが、よろしくお願いします。

  • 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秒ごとに出力電圧に反応があるかと思いますが、無反応です。 説明がややこしくなりましたが、わかる方がおられましたらよろしくお願いします。

専門家に質問してみよう