2017-02-22 2 views
1

私はブレッドボードにArduino Unoと抵抗ラダーを備えた基本波形発生器を作った。私は必要に応じてloop機能とmicros()を使って電圧レベルを変えて、各電圧変化の間を遅らせます。完璧ではありませんが、ピエゾでうまく動作します。analogReadに時間がかかりすぎる

私の問題は私のコードで信号の周波数を設定して、私はポットなどを使ってそれを変更できるようにしたいと思います。しかし、すぐに私のコードのどこかにanalogReadを置くと(すべてのコードはloop()の関数にあります)、出力信号が変化します。私は、実際の信号周期が正しくないのでanalogRead機能を実行するために100μsの間に取ることができ、そしてそれは、各電圧変化の間の遅延よりも大きいということが分かった:

unsigned long now, next; 
int freq; 

void loop(){ 

    //if I put analogRead() here it takes to much time 

    now = micros(); 

    if(now >= next){ 
     //Here I change the output analog value using a R-2R ladder 
     //then I change the value of next 
    } 
} 

私が代わりにスイッチを使用するなど、いくつかの解決策を試してみました鍋のdigitalReadと組み合わせたif文はより効率的ではないようです。私はまた、割り込みでスイッチを試しましたが、結果はdigitalReadと同じです。

誰か他の解決策を知っていますか?

ありがとうございました!

+0

(私はそれを使用していますなぜあなたは不思議場合)1<<(BIT)に置き換えられます*あなた*割り込みベースの試みの説明を提供してくださいだろうか? * loop()*から*の出力処理ルーチンを*割り込みサービスルーチン*にプッシュする方法があります。これはシグナルを変更せずに 'analogRead()'を使用できるようにするはずです。 *割り込み*で処理されているので優先します。間違っていますか? –

答えて

2

analogRead変換が完了するまで待機するので、別の処理をしたい場合は、別の方法で処理する必要があります。

ADC割り込みとフリーランニングモードを使用できます。または、タイマ比較のようないくつかのソースによってADC変換サイクルをトリガすることができます。

"イベント"ベースのアプローチ - ADC変換が行われたことを確認し、そのフラグに論理1を書き込んでリセットすることで、これを行うことができます。ところで

// in setup: 
ADCSRA |= _BV(ADATE); // enable auto trigger mode 
ADCSRB = 0; // free running mode for the auto trigger 

// and in the loop: 
if (ADCSRA & _BV(ADIF)) { 
    value = ADC; // get ADC value 
    ADCSRA |= _BV(ADIF); // reset flag by writing logic one into it 
    // whatever you want with the current value 
    // or ADCSRA |= _BV(ADSC); // start another conversion if you don't want free running mode 
} 

:マクロ_BV(BIT)

+0

ありがとうございました!私はそれをテストしますが、ArduinoのanalogReadよりも時間がかかりません – 695nb

関連する問題