#author("2022-09-18T15:21:25+09:00","siio","siio") #author("2022-09-18T15:21:38+09:00","siio","siio") [[How2Computing]] -これをLinuxで動かす方法は[[FT245RL_Linux:http://is.ocha.ac.jp/~siio/index.php?FT245RL_Linux]]を参照のこと -これをRaspberry Piで動かす方法は[[FT245RL_RaspberryPi:http://is.ocha.ac.jp/~siio/index.php?FT245RL_RaspberryPi]]を参照のこと --pythonに関する記述が新しいので、Raspberry Piのガイドもチェックしてください *FTDI社USB-8ビットパラレル変換器 FT245RL を Mac OS X で使う [#a6c677ef] 秋月電子で購入.一個980円. FTDI社のFT245RLにUSBコネクタ付けて,パスコンなど取り付けて, 使い易くした製品. FTDI社の製品は,USB-シリアル変換器チップで有名なシリーズであるが, これは,USB-シリアル変換に,バッファとパラレル入出力を付けたものらしい. FTDI社が配布している仮想シリアルドライバを使うと,シリアルデバイスとして バッファを読み書きできるが, 外部端子にタイミング信号を与えないとバッファからパラレル端子に入出力しない. 一方,FTDI社が配布しているライブラリーをインストールして呼び出すと, Bit-Bangモードという方式でお手軽にパラレル入出力できる. Big-Bangモードは,外部からバッファー・パラレル端子間の変換タイミング信号を 与えなくても,内部で定期的に更新してくれるモード. FTDI社のページ http://www.ftdichip.com/Drivers/D2XX.htm から,各種プラットフォーム用のドライバ/サンプルプログラムが入手可能. ここからダウンロードしたうちの,Bit Modeのサンプルが, お手軽にパラレル入出力するためのBit-Bangモードのサンプルプログラムだった. **インストールとテストの方法 [#q9142ba0] +http://www.ftdichip.com/Drivers/D2XX/MacOSX/D2XX1.2.2.dmg をダウンロードして内容をどこかにコピーする. --追記:現在の最新版は,http://www.ftdichip.com/Drivers/D2XX.htm から確認可能. +libftd2xx.0.1.0.dylibを/usr/local/libにコピー --cp D2XX/bin/libftd2xx.0.1.0.dylib /usr/local/lib +バージョン名を外した名前のシンボリックリンクを作っておく --cd /usr/local/lib --ln -sf libftd2xx.0.1.0.dylib libftd2xx.dylib Samplesのディレクトリの中に,サンプルプログラムが多数ある. Samplesの中でmakeすると全部コンパイルされる.それぞれのディレクトリで個別にmakeしても良い. たとえば,bitmodeのプログラムは,1バイトの値を出力して,読み込むサンプル. **ハードウェアを作ってテストする [#h2cbee4b] ブレッドボードの上に,LEDとスイッチを作って,接続した. #ref(DSC_0028s.jpg); このスイッチを押すとLEDが光るプログラムを,bitmodeのサンプルを元に作ってみた. LEDはData 0 (LSBのビット) に,スイッチはData 4に接続している. (逆スラッシュ¥が疑問符?に化けているので注意) /* To build use the following gcc statement (assuming you have the d2xx library in the /usr/local/lib directory). gcc -o bitmode main.c -L. -lftd2xx -Wl,-rpath /usr/local/lib */ #include <stdio.h> #include <stdlib.h> #include <signal.h> #include "../ftd2xx.h" #include <unistd.h> //for usleep() // Globals FT_HANDLE ftHandle = NULL; void ft245close() { if(ftHandle != NULL) { FT_Close(ftHandle); ftHandle = NULL; printf("Closed device?n"); } } void ft245quit()//コントロールCで止められた時の修了処理 { ft245close(); exit(1); } void ft245open() { FT_STATUS ftStatus; ftStatus = FT_Open(0, &ftHandle);//接続されている0番目のデバイスを設定. if(ftStatus != FT_OK) { printf("FT_Open(0) failed = %d?n", ftStatus); exit(1); } FT_SetBaudRate(ftHandle, 9600);//読み書きする周期を指定 //上位4ビットを入力に,下位4ビットを出力に,Bit-Bangモードに設定 ftStatus = FT_SetBitMode(ftHandle, 0x0F/*1=out 0=in*/, 1/*bit-bang mode on*/); if(ftStatus != FT_OK) { printf("Failed to set bit mode?n"); exit(1); } } void ft245write( unsigned char data)//1バイト出力 { DWORD dwBytesInQueue = 0; FT_Write(ftHandle, &data, 1, &dwBytesInQueue); } unsigned char ft245get()//1バイト入力 { FT_STATUS ftStatus; unsigned char ucdata; ftStatus = FT_GetBitMode(ftHandle, &ucdata); if(ftStatus != FT_OK) { printf("Failed to get bit mode?n"); exit(1); } else return(ucdata); } int main(void) { unsigned char data; signal(SIGINT, ft245quit); // trap ctrl-c call quit fn ft245open(); for(;;) { data=ft245get(); printf("data=0x%X?n", data); if ( (data & 0x10) ==0 ) ft245write(0x01); else ft245write(0x00); usleep(100000L); } ft245close(); return 0; } **openに失敗することへの対策 [#n3938e1d] openするときにエラーコード3で、エラーが返ってくることがありました。 USB接続をしないときはエラーコード2です。 USB接続を外すと、2が返ってきて、USBに挿すと3が返ってくる場合です。 同じコンピュータでArduinoを使ったことがある場合にも発生します。 これは、Arduinoをインストールしたときに、 FTD社のシリアル用ドライバがすでにインストールされていて、 これと衝突しているためです。 ArduinoのシリアルUSB変換器も、FTD社を使っているため、USBのVID, PIDが同一になってしまいます。 FTD社のチップを使うには、 このページで紹介しているD2XX (direct driver interface)の他に、 VCP (virtual COM port)というドライバの2種類があり、これらの2つは共存できません。 Arduinoを使ったか、もしくは、ほかのきかっけで、VCPドライバがインストールされてしまっていると、 そちらが先にこのチップの使用権を占有してしまっていて、openにエラーコード3で失敗するようです。 対策は、以下の2つです。 +VCPのドライバを削除する&br; これを行うには、参考リンクのマニュアルPDFにしたがって、 sudo rm -r /System/Library/Extensions/FTDIUSBSerialDriver.kext sudo rm -r /Library/Receipts/FTDIUSBSerialDriver.kext などとします。 --普通は、ArduinoとFT245RLを1つのコンピュータで同時に使うことは無いので、 ドライバを外しても良いと思います。 --Arduinoも使わないといけない場合、 FTD社のVCPドライバを使わないArduinoを使うという手もあります。 最近のArduino (Arduino Uno, Arduino MEGA 2560)は、 AtmelのATmega8U2チップにファームウェアを搭載しUSBシリアル変換を実現しています。 これは、標準のCDCクラスとして動作するので、 MacおよびLinuxではドライバーは必要なくなっています。 これらを使うことで、VCPドライバとの衝突はなくなります。 --VCPドライバを削除してもエラーコード3が出る場合 カーネル拡張モジュールを確認し、全てアンロードしてみる。 [参考]http://www.oversea-pub.com/free/environment/2083.html kextstat|grep FTDI 140 0 0xffffff7f81660000 0x8000 0x8000 com.FTDI.driver.FTDIUSBSerialDriver (2.2.18) <127 36 5 4 3 1> 141 0 0xffffff7f80f1f000 0x7000 0x7000 com.apple.driver.AppleUSBFTDI sudo kextunload -bundle com.FTDI.driver.FTDIUSBSerialDriver sudo kextunload -bundle com.apple.driver.AppleUSBFTDI +チップのVID,PIDを変更する&br; マニュアルのどこかに書いてあります。(試していません) **追記:なぜかFT_Get Bit Modeがエラーを返す [#s6d1a938] 久々にこのプログラムを最新版ライブラリで試してみました. するとどういうわけかFT_Get Bit ModeがFT error code 4で失敗します. その場合は,FT_Readを使ったらなんとかなりました. ft245get()の部分を以下のようにすると,同様に動くようです. unsigned char ft245get()//1バイト入力 { FT_STATUS ftStatus; unsigned char ucdata; int readsize=0; FT_Purge( ftHandle, FT_PURGE_RX | FT_PURGE_TX); //clear receiver buffer while(readsize==0) { ftStatus = FT_Read(ftHandle, &ucdata, 1, &readsize); if(ftStatus != FT_OK) { printf("Failed to get bit mode. err %d\n", ftStatus); exit(1); } } return(ucdata); } **参考リンク [#bd5552b9] -http://akizukidenshi.com/catalog/g/gK-01799/ //-http://akizukidenshi.com/catalog/items2.php?p=1&q=FT245RL -http://www.ftdichip.com/Drivers/D2XX.htm -http://www.ftdichip.com/Support/Knowledgebase/index.html -http://www.ftdichip.com/Support/Documents/InstallGuides/Mac_OS_X_Installation_Guide.pdf -http://ore-kb.net/hard/BitBang/ **番外編:Pythonから動かしてみる [#va3c15e9] +上記のドライバをダウンロードする。 +https://github.com/snmishra/ftd2xx からPython用のラッパーをダウンロードする。 +ダウンロードすると ftd2xx-git1/setup.py があるのでインストールする。 --python setup.py build --python setup.py install +プログラムの中で import ftd2xx とすれば使える! --サンプルは無さそうなので、 ftd2xx-git1/ftd2xx/ftd2xx.py などを見ながら自力で頑張る。 ***上で用意したハードウェアのLEDを光らせるプログラム [#e08a45e0] #!/usr/bin/python # -*- coding:utf-8 -*- #DB0に取り付けたLEDを1秒ごとに点滅させるプログラム import ftd2xx import time def ft245open(): ftHandle = ftd2xx.open(0) ftd2xx.FTD2XX.setBaudRate(ftHandle, 9600) ftd2xx.FTD2XX.setBitMode(ftHandle, 0x0F, 1) return ftHandle def ft245write(ftHandle, data): #dataは1バイトで受け取る、例:b'\xFF' ftd2xx.FTD2XX.write(ftHandle, data) def ft245close(ftHandle): if ftHandle: ft245write(ftHandle, b'\x00') ftd2xx.FTD2XX.close(ftHandle) ftHandle = None print 'Closed device' #ここから実行される ftHandle = ft245open() #control-cを押したら終了 try: while 1: ft245write(ftHandle, b'\x01') print("on") time.sleep(1) ft245write(ftHandle, b'\x00') print("off") time.sleep(1) except KeyboardInterrupt: ft245close(ftHandle) *** readする [#d8c0968d] ftd2xx.FTD2XX.purge(self.ft_handle) data = ftd2xx.FTD2XX.read(self.ft_handle, 1) とすると、dataの中にreadした値が入ります。 repr(data)とやるとうまくいくかもしれないです。