USB-IOに代わるもの

以前、USB-IOという製品を紹介した。(http://d.hatena.ne.jp/yaneurao/20041109)


私は長らく電子工作でUSB-IOを愛用していたのだが、1バイトずつデータを送信すると1秒間のスループットは200バイト/秒ぐらいしか出ない。1600bpsなので、通信としてはかなり遅い部類に入るだろう。


今回、通信部分の速度がもう少し要求される案件があったので、FT232で何とかしようかと思っていたのだが、たまたま立ち寄った大阪日本橋のデジットでABL-168というUSBブートローダー付きのAVRマイコン(載っているのはATmega168)ボードを見ていたら、FT232RLが載っていた。PC側からは仮想COMポート経由でAVRにアクセス出来る。

FT232RLとATmega168が載っていて、USBケーブル、ドライバ、回路図付き、ブートローダー書き込み済、AVRマイコンへ自分の作ったプログラムを転送するためのソフトもついてて、組み立て済みなのに2,700円!*1 これは破格の安さだと思う。私はあとで300個ほど買ってくる予定だ。(ちなみに共立エレショップからインターネット通販でも買える→http://eleshop.kyohritsu.com/)


今回は、C#からこのAVRマイコンとUSB経由でデータのやりとりをする方法を書いておく。


回路図のFT232RLのところを見るとTXD,RXDがAVRのRXD,TXDに結線されていることがわかる。つまり、AVR側のUSART機能を利用すれば何も考えずに1バイトデータを送受信出来る。以下のプログラムは割り込みを使わず受信バッファから1バイト取り出して、その文字のキャラクタコードに1を足したものを送信バッファに返すプログラムである。


Windows付属のハイパーターミナルで接続して、echo backされることを確認した。



#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define FOSC 20000000 // 20MHz
#define BAUD 38400
#define MYUBRR FOSC/16/BAUD-1

/* sio設定 */
// 38400bps,データビット8,パリティなし,ストップビット1,フロー制御なし。
void sio_init(unsigned int ubrr){
UBRR0H = (unsigned char)(ubrr>>8); // ボーレート上位8bit
UBRR0L = (unsigned char)ubrr; // ボーレート下位8bit
UCSR0B = (1<<RXEN0) | (1<<TXEN0); // 送受信許可,割り込みは不許可
UCSR0C = (3<<UCSZ00); // stopbit 1bit , 8bit送信
}

void wait_for_sending()
{
loop_until_bit_is_set(UCSR0A,UDRE0); // 送信データレジスタ空きまで待機
}

int is_received()
{
return UCSR0A & (1<<RXC0);
}

int main(void){

sio_init(MYUBRR); // SIO設定

for(;;)
{
if (is_received())
{
// UDR0 = UDR0; // echo back
UDR0 = UDR0+1; // 一文字化けさせてみる
wait_for_sending();
}
}
}


C#からUSB経由でこのAVRを通信するには、仮想COMポートなのでSerialPortクラスを用いれば簡単だ。なお、通信速度は57600bpsが限界のようだ。

port = new SerialPort("COM10");
port.Parity = Parity.None;
port.BaudRate = 38400;
port.StopBits = StopBits.One;
port.Open();

char[] buffer = new char[4]{'A','B','C','D'};

port.Write(buffer, 0, 4); // 送信バッファに4バイト書き込み

// 以下は、例えば、というコード
int read_size = port.BytesToRead; // バッファに受信しているデータサイズ
if (read_size != 0)
{
port.Read(buffer, 0, 1); // 受信バッファから1文字読み込み
Console.WriteLine( buffer[0] );
}


1バイトずつSerialPort.Writeで送信した場合のスループットは800バイト/秒程度。USB-IOの4倍ぐらい速い。
4バイトずつ送信した場合のスループットはその3倍ぐらい。ある程度まとめて送信したほうがスループットは上がる。無論、BaudRate以上にはならないが。


そんなわけで、FT232RLの先にAVRマイコンが付属していると複雑な処理でもそこでさせることが出来るし、言語はCで開発できるし、AVRライターは不要だし、ATmega168ならI/Oは16本以上あるし、20MHzの(ワンチップマイコンとしては)高速動作だし、外部電源から電源をとるかUSBからとるかは基板上のジャンパーで変更できるようになっているし、組み立て済みだし、FLASHマイコンだからプログラムは一度書き込んでしまえば電源を切っても残ってるし、このkitは掘り出し物だと思う。USB経由でデータを送受信したいときにお勧め。


上で紹介したABL-168はATmega168が載っていて、ATmega168は16KB(8Kワード)のフラッシュメモリがある。組み込み用途ならこれでも十分な容量だが、これの上位製品としてABL-128というのがデジットで売られている。(共立エレショップからも買える) こちらはATmega128が載っていて、3,900円。ATmega128はユーザーI/Oが50本以上あり、128KB(64Kワード)のフラッシュメモリがある。ABL-128も回路図を確認したところ、ABL-168と同じようにFT232RLと接続されているので上で紹介した方法でPCからアクセスできる。


あと、複数のABL-168を1PCに接続するノウハウも書いてみたので興味のある人はどうぞ。


・FT232RLの周辺
http://d.hatena.ne.jp/yaneurao/20080630


■ 関連記事


いますぐPICをやめてAVRに移行すべき10の理由
http://d.hatena.ne.jp/yaneurao/20080228


JTAGICE mkIIとICD2のclone
http://d.hatena.ne.jp/yaneurao/20080229

*1:私が見たものはピンヘッダがついていたが、ついてないものもあるようだ。写真ではISPピンがついているが、これはないものもあるようだ。