|
setup diary |
AVRを使うときに、以前はtiny2313をよく使っていたが、最近は秋月の価格が高くなって、megaとあまり変わらなくなったので、mega88をよく使うようになってきた。megaの方がtinyよりも安いのは、変な気がする。
AVRの書き込みにはFTDIのFT232RLを使っているが、PCとUSBで通信する時にも同じ石を使っている。arduino-ft232rの書き込みpinとTX,RXの通信pinをつないでおくと、通信と書き込みの両方ができるようになる。この配線をするのが面倒だと思っていたのだが、UncomPatino基板を使うと、この配線をする手間が省けるので、この基板を利用することが多くなってきた。それなら、Arduinoを使えば良いじゃないかとも思えるが、クロック用に2pinを奪われるので、IOに使えるpinが減ってしまう。
PCとは、USBからFT232RLでUARTに変換して、mega88と通信する。そのとき、できるだけマイコンの負荷を減らすには、割り込みをうまく使うと良い。これまで、マイコンが受信するときは、割り込みでバッファに取り込んでいたが、バッファの内容を送信するときには、一文字送信されるのを待って次の文字を送信していた。以下のようにすると、送信のときの処理時間が減らせる。
#define BUFSIZE 100 static volatile unsigned char buf[BUFSIZE]; static volatile unsigned char i_buf=0; static volatile unsigned char run_CMD=FALSE; ISR(USART_RX_vect){ /* received */ volatile unsigned char c; c=UDR0; buf[i_buf++]=c; if(i_buf>=BUFSIZE){i_buf=0;} if(c==10){ run_CMD=TRUE; i_buf=0; } } ISR(USART_UDRE_vect){ if(buf[i_buf]!=10){UDR0=buf[++i_buf];} //next else{i_buf=0;clearbit(UCSR0B,UDRIE0);} //end } void buf_rs232c(){ // buffer transmit while(checkbit(UCSR0B,UDRIE0)){} //previous buffer transmit is running UDR0=buf[i_buf=0]; setbit(UCSR0B,UDRIE0); }ちなみに、setbit,clearbitやcheckbitなども定義している。
測定装置に組み込んでいるモーターの挙動が変だということなので、原因を調べてみた。このモーターは、USBシリアルで変換した信号を、AVRのtiny2313で読み取って、ソリッドステートリレーを制御することによって、回転させている。しかし、時々逆回転をしたりしている。
まず疑ったのが、rubyのversion問題である。回転方向を指定するときに、binaryを送っているので、以前遭遇したunicodeへの自動変換が行われているのでは無いかと疑った。しかし、これは問題無いようだった。次に疑ったのが、ハードウェアの故障である。しかし、ランプなどを見ていると問題無い。仕方がないので、オシロでシリアルの信号を見てみる。すると、時々文字が化けていることが分かった。
以前、USBのハブが悪さをしていたのだが、モーターのためのシリアルには、大した情報は送っていないので、ハブを介してUSBシリアルを接続していた。これをPCというかRaspberry Pi2に直挿しすると、文字化けは無くなった。しかしこのままではUSBのポートが足りないので、手持ちのUSBハブをいろいろ持って行って、交換してみたら、ひとつ目でうまく行くようになった。
システムを入れ替えたのが7月なので、約半年も気づかずに使っていたようだ。しかし、これで別の装置との通信も安心して行えるようになる気がする。