RM-922

続・RM-922をbit bangでリセットする

Posted in RM-922

本日,RM-922とパソコンをつなぐ基板が届いたのでハンダ付けし,動作確認をしましたので報告します.

結論としては,動きました.以前に報告したハードウェアソフトウェアでです.下の写真は届いた基板に必要なICなどの部品を実装したものです.見た目は以前作成したものとほとんど変わりませんが,FT232RLの6番端子とRM-922のRESET端子とがANDゲートを介してつながっています.

WithoutRM922

 

思惑通り,BitBangを使ってRM-922をリセットすることができました.Linuxでも同じことが行えるか今後検証していきます.

FT232RLのBit BangでRM-922をリセット

Posted in RM-922

ここではJavaでBitBangを制御してRM-922をリセットするためのプログラムについて述べています.FT232RLに備わるBitBangを使えば,ちょっとした端子を制御を行えるため,RM-922をFT232RL経由でリセットすることができます.ハードウェア構成についてはこちらをご覧ください.

以前,BitBangを用いるにはFTDIが提供しているライブラリを利用してC++でアプリケーションを作っていました.しかしJavaでBitBangを利用するとしたらC++で作成したアプリケーションをJavaのプログラム中で呼び出さねばならず,ちょっと面倒でした.そこでJNA(Java Native Access)を使ってDLLにある関数を呼び出すことにしました.参考にしたサイトはこちらです.参考にしたサイトの情報はおそらくちょっと古いのか,DLLの名称が異なっていたためにそれを変えるとともに,FT_OpenEX関数を使用していたところをFT_Open関数に変更しました.加えてFT_SetBitMode関数を使うことで端子のモードを変えられるようにしました.これにより,Bit Bangを使ったのち,通常のUSB-シリアル変換の機能を使えるようにしました.ついでに今後の拡張を考えて端子や状態をEnumで定義しておきました.下にプログラムを示します.

FT232Controller.java

package jp.ac.nagano_nct.ashida_lab.ft232_bitbang_controller;

import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;

/** FT232のBit Bang機能をコントロールするクラス
 * @author ashida
 */
public class FT232Controller {

	/** オープンする
	 * @param device_number デバイス番号
	 * @param handle ハンドル
	 * @return デバイスの状態
	 */
	static native int FT_Open(int device_number, PointerByReference handle);
	/** クローズする
	 * @param handle ハンドル
	 * @return デバイスの状態
	 */
    static native int FT_Close(Pointer handle);
    /** 書き込む
     * @param handle ハンドル
     * @param write_data 書き込むデータ
     * @param write_data_length 書き込むデータの長さ
     * @param written_data_length 書き込んだデータの長さ
     * @return
     */
    static native int FT_Write(Pointer handle, Pointer write_data, int write_data_length, IntByReference written_data_length);
    /** 読み込む
     * @param handle ハンドル
     * @param read_data 読み込むデータ
     * @param read_data_length 読み込むデータの長さ
     * @param get_data_length 読み込んだデータの長さ
     * @return
     */
    static native int FT_Read(Pointer handle, Pointer read_data,int read_data_length, IntByReference get_data_length);
    /** ビットモードを設定する
     * @param handle ハンドル
     * @param pin 端子
     * @param mode モード
     * @return
     */
    static native int FT_SetBitMode(Pointer handle, int pin, int mode);

    static {
    	/* FT232を操作するDLLの名称 */
        Native.register("ftd2xx");
    }
    /** ハンドル */
    Pointer _handle = null;

    /** コンストラクタ
     * @param device_number デバイス番号
     */
    public FT232Controller(int device_number){
    	/* ハンドラの参照返し */
        PointerByReference handle = new PointerByReference();

        if (FT_Open(device_number, handle) != DeviceStatus.FT_OK.getValue()) {
            throw new RuntimeException("FT_Open failed.");
        }
        _handle = handle.getValue();
    }

    /** クローズする */
    public void close() {
        FT_Close(_handle);
    }

    /** 書き込む
     * @param data 書き込むデータ
     */
    public void write(short... data){
        Memory memory = new Memory(data.length);
        IntByReference ref = new IntByReference();

        memory.write(0, data, 0, data.length);
        FT_Write(_handle, memory, data.length << 1, ref);
    }

    /** 読み込む
     * @return 読み込んだデータ
     */
    public byte read() {
        Memory memory = new Memory(1);
        IntByReference ref = new IntByReference();
        FT_Read(_handle, memory, 1, ref);
        return memory.getByte(0);
    }

    /** ビットモードを設定する
     * @param bit_mode ビットモード
     * @param pins 操作する端子
     */
    public void setBitMode(BitMode bit_mode,Ft232Pin...pins){

    	int pins_value=0;
    	for(Ft232Pin pin: pins){
    		pins_value += pin.getValue();
    	}
    	FT_SetBitMode(_handle, pins_value, bit_mode.getValue());
    }

    public static void main(String []args){
    	/* オープンする */
    	FT232Controller controller = new FT232Controller(0);
    	/* D7を非同期Bit Bangモードにする */
    	controller.setBitMode(BitMode.FT_BITMODE_ASYNC_BITBANG, Ft232Pin.D7);
    	/* D7をLow(=リセット)にする */
    	controller.write((short)0x00);
    	try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
    	/* D7をHigh(=リセットでない)にする */
    	controller.write((short)0x80);
    	/* D7を通常の端子状態にする */
    	controller.setBitMode(BitMode.FT_BITMODE_RESET, Ft232Pin.D7);
    	/* クローズする */
    	controller.close();
    }
}

 

BitMode.java

package jp.ac.nagano_nct.ashida_lab.ft232_bitbang_controller;

/** ビットモード
 * @author ashida
 */
public enum BitMode {
	/** Bit Bangモードをやめる */
	FT_BITMODE_RESET(0x00),
	/** 非同期式のBit Bangモード */
	FT_BITMODE_ASYNC_BITBANG(0x01),
	/** MPSSEモード */
	FT_BITMODE_MPSSE(0x02),
	/** 同期式のBit Bangモード */
	FT_BITMODE_SYNC_BITBANG(0x04),
	/** MCU ホストバスのエミュレーションモード */
	FT_BITMODE_MCU_HOST(0x08),
	/** 高速シリアル通信モード */
	FT_BITMODE_FAST_SERIAL(0x10),
	/** CBUS Bit Bangモード */
	FT_BITMODE_CBUS_BITBANG(0x20),
	/** 同期式FIFO Bit Bangモード */
	FT_BITMODE_SYNC_FIFO(0x40);

	/** 値 */
	private int _value;

	/** コンストラクタ
	 * @param value 値
	 */
	private BitMode(int value){
		_value = value;
	}

	/** 値を得る
	 * @return 値
	 */
	public int getValue(){
		return _value;
	}
}

 

DeviceStatus.java

package jp.ac.nagano_nct.ashida_lab.ft232_bitbang_controller;

/** デバイスの状態
 * @author ashida
 */
public enum DeviceStatus {
	/** OK */
	FT_OK(0),
	/** 不当なハンドル */
	FT_INVALID_HANDLE(1),
	/** デバイスが見つからない */
	FT_DEVICE_NOT_FOUND(2),
	/** デバイスが開かれていない */
	FT_DEVICE_NOT_OPENED(3),
	/** IOエラー */
	FT_IO_ERROR(4),
	/** 操作をするためのリソースが不足している */
	FT_INSUFFICIENT_RESOURCES(5),
	/** ある操作のときに提供されたパラメータが不当であった */
	FT_INVALID_PARAMETER(6),
	/** 不当なボーレート */
	FT_INVALID_BAUD_RATE(7),

	/** 開かれていないデバイスを消そうとしてできなかった */
	FT_DEVICE_NOT_OPENED_FOR_ERASE(8),
	/** 開かれていないデバイスに書き込もうとしたができなかった */
	FT_DEVICE_NOT_OPENED_FOR_WRITE(9),
	/** デバイスへの書き込みに失敗した */
	FT_FAILED_TO_WRITE_DEVICE(10),
	/** EEPROMの読み込みに失敗した */
	FT_EEPROM_READ_FAILED(11),
	/** EEPROMの書き込みに失敗した */
	FT_EEPROM_WRITE_FAILED(12),
	/** EEPROMの消去に失敗した */
	FT_EEPROM_ERASE_FAILED(13),
	/** EEPROMがこのデバイスでは提供されていない */
	FT_EEPROM_NOT_PRESENT(14),
	/** EEPROMをプログラムされていない */
	FT_EEPROM_NOT_PROGRAMMED(15),
	/** 不当な引数であった */
	FT_INVALID_ARGS(16),
	/** サポートされていない */
	FT_NOT_SUPPORTED(17),
	/** その他のエラー */
	FT_OTHER_ERROR(18),
	/** デバイスリストが用意されていない */
	FT_DEVICE_LIST_NOT_READY(19);

	/** 値 */
	private int _value;

	/** コンストラクタ
	 * @param value 値
	 */
	private DeviceStatus(int value){
		_value = value;
	}

	/** 値を得る
	 * @return 値
	 */
	public int getValue(){
		return _value;
	}
}

 

FT232Pin.java

package jp.ac.nagano_nct.ashida_lab.ft232_bitbang_controller;

/** FT232の端子
 * @author ashida
 */
public enum FT232Pin {
	/* すべての端子 */
	ALL(0xFF),
	/** D7 */
	D7(0x80),
	/** D6 */
	D6(0x40),
	/** D5 */
	D5(0x20),
	/** D4 */
	D4(0x10),
	/** D3 */
	D3(0x08),
	/** D2 */
	D2(0x04),
	/** D1 */
	D1(0x02),
	/** D0 */
	D0(0x01);

	/** 値 */
	private int _value;

	/** コンストラクタ
	 * @param value 値
	 */
	private Ft232Pin(int value){
		_value = value;
	}

	/** 値を得る
	 * @return 値
	 */
	public int getValue(){
		return _value;
	}
}

 

RM-922をbit bangでリセットする

Posted in RM-922

RM-922は通信を開始するとリセットするまで設定可能状態になりません.raspberry piであれば汎用端子でリセットができますが,パソコンをUSBシリアルで接続した場合にはこれまで手動でリセットスイッチを押すしかありませんでした.開発者であればこの動作は造作もないことですが,エンドユーザにとっては煩わしく感じるでしょうし,何より指示してもリセットを押してくれないかもしれません.色々考えたのですが,USBシリアル変換ICであるFT232RLにはbit bangという機能があり,これを使えば8個の汎用入出力を制御できるようです.そこでこれまで開発したRM-922をパソコンのUSBシリアルに接続する回路を改造し,FT232RLの汎用端子(D7)とリセット端子を接続しました.ただし,それではユーザがタクトスイッチでリセットできないので,リセットスイッチとD7のANDの入力とし,ANDの出力をRM-922のリセット端子に接続しました.

RM922 USB A FT232Reset

基板の発注はいつものSeeedですが,現在中国では旧正月のため2月4日まで全く対応してもらえないようです.従って,基板が到着するのはおそらく2月末でしょう.顛末を今度アップします.

煙る基板

Posted in RM-922

完全にやってしまいました.原因は逆挿しです.

今回作成した回路にはUSBmicroBがついているのですが,このコネクタを新しくeagleでライブラリとして作成しました.このとき,ピンのアサインを完全に逆にしてしまったようです.その結果,VCCとGNDの”逆挿し”が完成したわけです.下の基板にUSBケーブルを接続すると,FT232RLから白い煙がふわっと出てきます.もちろん,即ケーブルを外しました.このまま続けたら燃えるのでしょうかねぇ.

 煙った基板

ということで,すぐさま作り直してFusion PCBに発注しました.今なら$6.93で5×5[cm]の基板が10枚作れるのですね.ちょうど安い時期に基板を作ることができて良かったです.負け惜しみですが.

RM-922を用いたPC間通信の方法

Posted in RM-922

RFリンク社製無線通信モジュールRM-922を使って通信するため,まずはモジュールに入っているプログラムを使いこなすことにしました.この文書ではRM-922に入っているプログラムの使い方について述べます.

必要なもの

  • 通信モジュールRM-922 × 2
  • RM-922とパソコンを接続するRM900_EV × 2
  • USBケーブル × 2
  • RM-900_EV付属のCD
  • 通信ターミナル TeraTerm

TeraTermのインストール方法

  1. https://osdn.jp/profects/ttssh2/にアクセスする.
  2. 「ダウンロード」から最新版のtera term-.〇〇.exeをクリックしてダウンロードする.
  3. ダウンロードした.exeファイルを開く.
  4. インストール中に使用する言語を「日本語」に設定して「OK」をクリックする.
  5. Tera termセットアップウィザードの開始」画面が表示されるので「次へ」をクリックする.
  6. 利用規約が表示されるので,「利用規約に同意する」を選択して「次へ」をクリックする.
  7. 「インストール先の指定」画面が表示されるので,インストール先を指定して「次へ」をクリックする.
  8. 「コンポーネントの選択」画面が表示されるので,必要なタスクにチェックを入れ「次へ」をクリックする.
  9. 「言語の選択」画面が表示されるので,「日本語」を選択して「次へ」をクリックする.
  10. 「プログラムグループの指定」画面が表示されるので,プログラムグループを作成する場合はそのまま,作成しない場合は「プログラムグループを作成しない」にチェックを入れ「次へ」をクリックする.
  11. 「追加タスクの選択」画面が表示されるので,必要なタスクにチェックを入れ「次へ」をクリックする.
  12. 「インストールの準備完了」画面が表示されるので,内容を確認して「インストール」をクリックする.
  13. インストールが終了したら「完了」をクリックしてインストールを終了する. 

RM-922のドライバをインストール

  1. 付属のCDを読み込む.
  2. CDの中の「Driver」フォルダを開き,その中の「ftdi」フォルダを開く.
  3. 使用しているPCのOSがWindows8.1以降の場合は8-1がついたほうを,それ以外のWindowsの場合はついていないほうを開く.
  4. 中にある.zipファイルを解凍する.
  5. 解凍したファイル内にある.zipファイルを同じフォルダ内に解凍する.
  6. 同じフォルダ内にある.exeファイルを開く
  7. 「Extract」をクリックすると「Welcome to the Devise Driver Installation Wizard!」画面が表示されるので,「次へ」をクリックし,インストールを開始する.
  8. インストールが終了したら「完了」をクリックし,インストールを終了する.

通信方法

以下では2個のノード(AとB)間での通信方法について説明しています.Aのアドレスを0,Bのアドレスを1として通信します.

  1. ノードAとPCをケーブルでつなぐ.
  2. コントロールパネルの「ハードウェアとサウンド」から「デバイスマネージャ」を開く.
  3. ポート(COMとLPT)からCOM番号を調べる.
  4. tera termを起動する.
  5. 設定画面が表示されるので,下側の「シリアル」を選択し,手順3で調べたCOM番号に設定して「OK」をクリックする.
  6. 「設定」→「シリアルポート」からボー・レートを115200に設定する.
  7. RM900_EVにあるRESETボタンを押すとコマンド一覧が表示される.
  8. これまで設定した情報がEEPROMにあり,それをロードする場合には"y"を押す.
  9. "c"を入力すると自分のアドレスを入力するよう表示が出るので,"0"と入力してEnterキーを押す.
  10. 次に"d"を入力すると通信相手のアドレスを入力するよう表示が出るので,"1"と入力してEnterキーを押す.
  11. ノードBに対しても手順1から手順10までを行う.ただし,手順9ではアドレスとして1を,手順10ではアドレスとして0を入力する.
  12. 設定をEEPROMに保存するときには,"x"を押す.
  13. 片方のtera termで"s"を入力すると通信を開始する.
  14. 片方のtera termで入力した文字がもう片方のtera termに表示されれば通信は成功している.
  15. 長い文字列を送信したいときは送信したい文字列を入力したテキストファイルを作成し,tera termの「ファイル」→「ファイル送信」からそのテキストファイルを選択することで100バイトまでの文字列を送信することができる.
  16. 通信を終了するときは端末のRESETボタンを押すか,tera termを閉じて終了する.