Archive for the 'ハードウェア開発' Category

AVR割り込みメモ

Posted by ゆのじ on 11月 4th, 2009

またはまっていた。AVRのPCINT割り込みを使う場合のはまりどころ。特に頭が疲れているとやらかしかねない。

割り込みレジスタ関連:

PCMSKnにビットを立てただけでは駄目。PCICRにPCIEnを指定しよう。

割り込み内エッジ処理関連:

PCINT割り込みはINT割り込みと違ってエッジの指定が出来ないので自分でやる必要がある。ここでぼーっとしてると

ISR(PCINT3_vect)
{
	if(bit_is_set(PORTD, PD4)) {
		// rise
	} else {
		// fall
	}
}

と書いてしまいがち。正しくはこう。

ISR(PCINT3_vect)
{
	if(bit_is_set(PIND, PIND4)) {
		// rise
	} else {
		// fall
	}
}

PORTnだと生の値が拾えないので忘れずに。

 

なんというか、昔もこうだったっけ、ということだらけ。十分なリハビリが必要そうで泣ける。

XBeeを最高速で使いたい

Posted by ゆのじ on 11月 2nd, 2009

Digi社のXBee、かなり便利に使える道具だと思うのだが、割とはまっているのが速度。ああいった物に速度を求めるなという話もあるが、実際どれくらい出るのだろうと思って試してみることにした。なお、XBeeといっても802.15.4だけしか使えないOEM RF Moduleで、ZigbeeやDigimeshを使えるモデルではない。また、転送レートを調べることが目的なので、Transparent modeで使っての試験とした。

試験は自宅というごくありふれた環境で、送信元と送信先のXBee距離は40cm程度、WiFiの電波もそれ以外の妨害電波もばしばし飛んでいる状況である。その中でXBeeのボーレートを250kbpsにして、適当なソースをつないでフロー制御なしで走らせてみることにした。設定は8bit/Odd/1Stopとしたので、1バイトあたり9bit分のデータを飛ばすことになる。

その結果だが、数回繰り返したところ、おおよそ12~13kbytes/sec程度の転送レートが出ることがわかった。流れたビット数で108~117kbps、つまり出ても定格の半分程度ということになるだろうか。このテストでは、最大速度を知ることが目的だったのでフロー制御をしていない。そのため、パリティをつけている分欠損データは拾わない(カウントしていない)ものの、データの欠落は山ほど出る。実際に使うには送信側できちんとフロー制御しなければいけないだろう。また、XBeeは無線の制御にCSMA-CA方式をつかっているため、リアルタイム性も保証されない。ビットレートを落とせばある程度の安定したタイムラグを得ることは出来るだろうが、正確なリアルタイム制御をしたければNTP的にラウンドトリップタイムを得たりしなければならいような感じである。

ちなみに、マニュアルによれば、フロー制御をしたくない場合、DI Buffer size(202bytes)より1メッセージを小さくしたりボーレートを下げることを要点としてあげている。

簡単なテストではあったが、割と勘所はつかめた気がしてきた。ひとまず、CTSを握って制御してやることがまず第一のようだ。

引き続き開発。

追記:その後、CTSをきちんと処理するようにした結果、目視する限りビット落ち無しで、8k~9kbytes/sec程度のスループットが出ることもわかった。鉄筋コンクリートの壁を数枚隔てたくらいではほぼスループットは落ちない感じ。ビット落ちがきわめて少ないのは大変有り難い。

AVRが予想せずリセットされる時

Posted by ゆのじ on 11月 2nd, 2009

WinAVRの環境(avr-gccなら同じだと思うが)で複雑な割り込みがかかるようなプログラムを書いているとき、原因不明のリセットがかかる場合、可能性として考えられるのは1)ウォッチドッグ、2)電圧低下のBORリセット、3)割り込みベクタが変、が考えられる。このうち1と2は割とデバグしやすいのだが3がどう対応すればいいのかと思って調べてみたところ、こう書けばいいということがわかった。

ISR(BADISR_vect)
{
    cli();    // これ以上割り込ませない
    // このあたりでデバグメッセージ
    for(;;);  // ここで止めておく
} 

とりあえずこの中でデバッグメッセージを書いて止めてしまえば、何か起きていることまではわかる。その先はさらにデバグデバグ。

 

なんでこういうことになったかというと、送信可能状態になったときに飛んでくる割り込み(USART1_UDRE_vect)を書かないといけないところに、ぼんやりしていて送信完了時に飛んでくる割り込み(USART1_TX_vect)を書いてしまっていたからだった。そりゃBADISRにもなる。

同じはまり方をしないためにメモ。

追記:何も考えずにTXCIEnを有効にする場合、USARTn_UDRE_vectだけだとBADISRになる。USARTn_TX_vectも書いておくこと。

追追記:嘘書いた。TXCIEnはUSARTn_TX_vect、UDRIEnがUSARTn_UDRE_vectに対応ということのよう。もう少し調べてまとめたい。