Arduinoの高速化

約3か月前、多くの不幸な電子機器と同様に、私は、Arduinoファミリーの最も洗練されたマイクロプロセッサボード、すなわちAtmega1280プロセッサをベースにしたSeeeduino Megaを購入しました。 回転するサーボドライブと点滅するLEDに夢中になって、「なぜ購入したのですか?」という疑問が生じました。



私はゼレノグラードの大規模な工場で主要なデザイナーの一人として働いており、現在、計量計測器の開発プロジェクトを実施しています。 この問題には、個別の解決策を必要とする問題が無限にあります。 これらのタスクの1つは、ステッピングモーターのドキュメントに記載されているように、ノイズなしで1.8度ではなく、最大0.0001度のステップでステッピングモーターを制御することです。 このタスクは難しくて優柔不断であるように思えますが、制御スキームに少し手を加えた結果、すべてが現実的で可能だという結論に達しました。 特定の形状で、位相シフトと最大1 MHzの電圧変動の周波数を持つ2つの信号の生成のみが必要です。 (ステッピングモーターの詳細な研究と制御の秘密のすべての開示については、次の記事で説明します)すぐに、私の小さな赤いSeeeduinoに1,500ルーブルを費やしても無駄ではなかったという希望のかすかな光が頭に浮かび始め、熱意を得て、理解し始めました。



最初の恐怖:



マイクロプロセッサボードをオシロスコープに接続し、サイクルdigitalWrite(HIGH)を書き込み、digitalWrite(LOW)を下回ると、オシロスコープで周波数が50 Hzのやや鈍い蛇行を見つけました。 これは悪夢です。 必要な1 MHzの中でこれはクラッシュだと思いました。

次に、オシロスコープを使用して、さらにいくつかの実行速度を調べました。

AnalogRead()-実行速度110μs。

AnalogWrite()-2000μs

SerialPrintLn()-9600の速度で約250μs、最大速度で約3μs。

DigitalWrite()-1800mks

DigitalRead()-1900mks



これで、私は泣いて、ほとんどシードゥイーノを投げました。 しかし、そこにありました!



目が怖い、手がしている!



私は精神的な苦悩を語らず、3日間の勉強を説明しません。すぐに言った方が良いです。

ArduinoとAtmega1280プロセッサに関するすべての可能なドキュメント作成し、 外国人の同僚経験を研究して、読み/書きを置き換える方法に関するいくつかのヒントを提供したいと思います。



AnalogReadの改善()


#define FASTADC 1



// defines for setting and clearing register bits

#ifndef cbi

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))

#endif

#ifndef sbi

#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

#endif



void setup() {

int start ;

int i ;



#if FASTADC

// set prescale to 16

sbi(ADCSRA,ADPS2) ;

cbi(ADCSRA,ADPS1) ;

cbi(ADCSRA,ADPS0) ;

#endif



Serial.begin(9600) ;

Serial.print("ADCTEST: ") ;

start = millis() ;

for (i = 0 ; i < 30000 ; i++)

analogRead(0) ;

Serial.print(millis() - start) ;

Serial.println(" msec (30000 calls)") ;

}



void loop() {

}









結果: 18.2μsの速度対以前の110μs

ところで、Atmega ADCの最大速度はわずか16μsです。 オプションとして-ADC専用にシャープ化された別のチップを使用します。これにより、速度が0.2マイクロ秒に低下します (以下を参照)。



digitalWriteの改善()


各Arduino / Seeeduino / Feduino / Orduino / otherduinoにはポートがあります。 各ポートは8ビットであり、最初に録音用に設定する必要があります。 たとえば、私のSeeeduino PORTAで-22から30脚まで。 これですべてがシンプルになりました。 機能を使用して22〜30脚を制御

PORTA = B00001010(ビット、レッグ23および25-HIGH)

または

PORTA = 10(10進数、まだ)

結果 = 0.2μs対1800μs、通常のdigitalWrite()で達成



digitalReadの改善()


digitalWrite()での改善とほぼ同じですが、今度はレッグをINPUTに設定し、次のように使用します。

if(PINA == B00000010){...}(レッグ23にHIGHが存在し、レッグ22および24-30にLOWが存在する場合)

() の結果は、通常のdigitalRead()によって達成される1900μsに対して0.2μsです。



PWM変調器の改善、またはanalogWrite()


したがって、digitalRead()は0.2μsを実行し、PWM変調器の分解能は8ビットであり、PWMの最小スイッチング時間は51.2μs対2000μsであるという証拠があります。

次のコードを使用します。

int PWM_time=32; //, analogWrite(PIN, 32)

for (int k=0;k<PWM_time) PORTA=B00000001;

for (int k=0;k<256-PWM_time) PORTA=B00000000;







そこで 、周波数が19 kHz50 Hzの PWM を取得しました



まとめると



digitalWrite()は1800mksでしたが0.2mksになりました

digitalRead()は1900μsでしたが、 0.2μsになりました

analogWrite()は2000μsでしたが、51.2μsになりました

analogRead()は110μsでしたが、18.2μsになり、 0.2μsまで可能です。



All Articles