Quimat QY-15 を LINUXで動かす
何の話?
USB経由で4つのスイッチをON/OFFできる Quimat QY-15 リレーモジュールを使ってLINUX(CentOS7)上で動作させるところまでの話です。
IoTっぽい事をやりたいと思い、CentOSが起動する小型デバイスを用意したので、バスパワーで動かせるスイッチモジュールが欲しいと思った次第です。
LINUX系(Ubuntu Mac等)においてはやる事は基本同じだと思いますので、各々の解釈で見ていただければ幸いです。
Amazonにて
USBでスイッチのON/OFF制御が4チャンネルでできるやつです。便利そうでしょ?
Amazonで「リレー usb」と検索すると一番最初に現れるし、「Amazon's Choice」だから安心だろと思い、ポチりました。(スポンサープロダクトは見逃してました・・)
買った後
まあ分かっていたんですが、案の定「本体」と「ケーブル」のみ。マニュアルもドライバもサンプルプログラムも入っておらず、ショップのページで見たダウンロードURLはリンク切れ(後でわかったのですが、今見たら復活していました・・不安定なのかな?)なので、いろいろ調べました。
幸い、レビューのコメントや別機器のプログラムを参考にして分かったことをまとめます。
色々調べる
どうやら、「FTDIチップ」という、「USBからゴニョっと制御できちゃうよ~」という何とも便利そうなチップを使っているようです。となると、そのドライバで制御できちゃうのでは?と思い、サイトに突入。
https://www.ftdichip.com/Drivers/D2XX.htm
ドライバを無事入手できました。(CPUの種類やOSを選んでダウンロード)
インストールはReadMeの通り実行(※libftd2xx-xxxxx.tgzはフォルダでまとめられていない為、展開したら中身をぶちまけることになるので注意)
(xxxxxはバージョン番号です。各々のバージョンに合わせてください)
mkdir libftd2xx
cd libftd2xx
wget [libftd2xxダウンロードのURL]
tar xfvz libftd2xx-x86_64-xxxxx.tgz
cd release/build
sudo cp libftd2xx.* /usr/local/lib
sudo chmod 0755 /usr/local/lib/libftd2xx.so.xxxxx
sudo ln -sf /usr/local/lib/libftd2xx.so.xxxxx /usr/local/lib/libftd2xx.so
この後、デバイスを接続し、認識していることを確認するのですが、
「ftdi_sio」 というドライバが競合するそうなので、以下も実行します。
※こちらは他で使っている場合があるかもしれませんので、心当たりのある方は別の手段をご検討ください。
sudo rmmod ftdi_sio
sudo rmmod usbserial
ドライバはそろった。でも制御は?
LINUX環境の制御ソフトは有り物がないので、作るしかないという感じでした。LINUX開発環境と言えば?
sudo yum install gcc
gcc(c/c++)先輩の登場です。(CentOSのパッケージマネージャはyumですが、他の環境では各々の解釈でお願いします。あと開発環境はディスク容量取るので、コンパイルする環境は制御デバイスと分けた方がいいです。ディスクサイズが許容範囲であればYで進んでください。)
gitにてソース用意しました(なければインストールしてください)
git clone https://github.com/RAWSEQ/ftd2_qy15_relay
cd ftd2_qy15_relay/sample
make
コンパイルしてファイル ftd2_qy15_relay_sample
ができるので、それを実行。
(デバイスの制御はルート権限が必要なので注意。)
sudo ./ftd2_qy15_relay_sample
カチっと音が鳴れば成功。
どうなっているかはソースを確認してみましょう。
上記、sampleフォルダには単純化したソースを用意しています。
# include <stdio.h>
# include <assert.h>
# include <string.h>
# include "./ftd2xx.h"
int main()
{
// Settings
int port = 0;
char buff = 0b00001010; // channel 1 2 3 4 => 0 1 0 1
int retCode = -1; // Assume failure
FT_STATUS ftStatus = FT_OK;
FT_HANDLE ftHandle = NULL;
DWORD bytesWritten = 0;
// Open
ftStatus = FT_Open(port, &ftHandle);
if (ftStatus != FT_OK)
{
printf("FT_Open(%d) failed, with error %d.\n", port, (int)ftStatus);
printf("- Use lsmod to check if ftdi_sio (and usbserial) are present.\n");
printf(" If so, unload them using rmmod, as they conflict with ftd2xx.\n");
printf("- Check the port number of the device you want to use.\n");
printf("- Try run by Super User Mode.\n");
goto exit;
}
// Setup (BIT BANG MODE)
assert(ftHandle != NULL);
FT_ResetDevice(ftHandle);
FT_SetBaudRate(ftHandle, 9600);
FT_SetDataCharacteristics(ftHandle, FT_BITS_8, FT_STOP_BITS_1, FT_PARITY_NONE);
FT_SetDtr(ftHandle);
FT_SetFlowControl(ftHandle, FT_FLOW_RTS_CTS, 0, 0);
FT_SetRts(ftHandle);
FT_SetTimeouts(ftHandle, 3000, 3000); // 3 seconds
FT_SetBitMode(ftHandle, 0xff, 1);
// Write
FT_Write(ftHandle, &buff, 1, &bytesWritten);
printf("Sended.\n");
retCode = 0;
exit:
if (ftHandle != NULL)
FT_Close(ftHandle);
return retCode;
}
FT_Open
でデバイスに接続し、ゴニョゴニョ設定(BIT BANGモードとやらに)して FT_Write
で書き込みという流れです。
ここで注目すべきは buff
という変数。二進数で「00001010」とセットされています。
(デバイスが複数ある時は port
を変えてみてください。)
一番右(1桁目)から数えて 1,2,3,4 番のスイッチを制御できます。
つまり、上記の場合は「1=OFF, 2=ON, 3=OFF, 4=ON」となります。
ということは、今はコンパイルしないと値を変えられないですが、buff
を何とかしてやれば、自由にスイッチ制御できるということです!
逆の方法で FT_Read
を使って状態を確認することもできます。
引数で制御できるやつも作ったのでご利用ください。
https://github.com/RAWSEQ/ftd2_qy15_relay