2015年7月31日金曜日

ESP-WROOM-02についてのメモ(4)

以下、ESP-WROOM-02の取扱い店についてのメモ

・aitendo

 aitendoも技適マーク付きのESP-WROOM-02の取扱いを開始
  20150803追記:項目が存在するだけで商品自体は未入荷の様子
        技適マークなし版の在庫消化待ちか?
         →入荷を確認
        基板は在庫あり
  20150907追記:プルアップ抵抗/短絡パターン付きの新基板発売


 ESP-WROOM-02

 WiFiモジュール変換基板(A)
 WiFiモジュール変換基板(B)

変換基板A
変換基板B

 変換基板Aはピッチ変換のみのプレーンな構成
 ピンのプリントが無いので配置が判りづらいがかなりコンパクト

 変換基板Bは片側9x2列に変換するという変則的な構成
 使い道がイマイチ思いつかないがオリジナリティは感じる

 あと2.4GHzのアンテナが沢山売っており甘く誘惑してくるが
 アンテナを後付加工すると技適マークは無効になるので注意


・igitalMaker

 7/1にできたばかりのオンラインショップ

 BreakOutボード

 設定用GPIOポートがジャンパではなくチップ抵抗用パッドなのが特徴
 やっぱりプルアップ/プルダウン抵抗いるんじゃないのか…?と不安になる



Maker Faireのメモ

今年も開幕MakerFaireTokyo


2015年8月1日(土)12:00~19:00
2015年8月2日(日)10:00~18:00

東京ビッグサイト西4ホールにて
公式HP


夏休みなので意外と混む
入場時の捌きがグダグダになることが多いので前売り券を買っておこう
 ローソンチケット
 イープラス


無線を使った展示が結構あるのが気になる…
出展者/来場者がガンガンガジェットを使うので電波環境は最悪
2.4Ghz帯の通信はかなり辛い(同じブース/同じ卓上であったとしても)

当日になってデモ不可では悲しいので事前に周知しておくべきかも

2015年7月30日木曜日

ESP-WROOM-02についてのメモ(3)

・ESP-WROOM-02とは?

 上海にあるEspressif社製の無線LANモジュール
 同じくEspressif社製の無線LANSoCであるESP8266EXを使用している

 ESP8266EX + アンテナ + ファームウェア用フラッシュROM = ESP-WROOM-02

公式HPより:燦然と輝く技適マークがまぶしい

 
データシートより抜粋:9割方ESP8266EXで構成されている

・基本的な機能

 Wi-Fi規格での通信
 無線LANルータ等に接続してクライアントとして通信
 アクセスポイントとして他のWi-Fi機器を複数接続可能

 ESP-WROOM-02への命令/情報の取得などはシリアルポート経由で行う
 Arduinoなどに簡単に無線LAN機能をアドオンできる
 

・ファームウェアの書き換え可能

 SDKが公開されており、ユーザーによるファームウェアの書き換えが可能

 ESP-WROOM-02は制御可能な数本のGPIOを持つため
 『無線LAN機能付きのワンチップマイコン』のように使うことができる

 →実際に使ってみた


・注意点
 
 ・十分な電流が供給されないと正常動作しない
  平均80mAとの表記があるが、無線通信時にはもっと必要(max170+αmA程度?)
  ボタン電池やArduinoの3.3Vピンなどからの給電では無理

  USB-シリアル変換機のVCCもおそらく無理
  前のメモでスイッチサイエンスの変換機FTDI USBシリアル変換アダプター を使ったが、これが流せるのは50mAまで
  
  レギュレータ使って3.3Vを作る場合は定格電流に気をつけること
  レギュレータの定格は絶対的なものではないので過電流でも動く場合がある
  ただちに破壊はされず、ダメージが蓄積していくので性質が悪い

データシートより抜粋:イニシャライズ時に即通信しようとするので注意

 ・上記の『基本的な機能』もファームウェアで実装されている
  ユーザーが作ったミニマムなファームウェアではこれらの機能は失効する
  (例:Lチカのスケッチを書き込んだらそれ以外の動作はしない)

 ・デフォルトファームウェアへのロールバックは公式フォーラム参照
  ファームウェアの書き込みツールと書き込みイメージが公開されている

 ・類似品がたくさんある
  名前にESPが入っているものは全部ESP8266SoCを使った類似の製品
  基板サイズやインタフェースの違いによるバリエーションモデルの模様
  技適は無いので大っぴらには使えない
  ESP-13の技適を取ったものがESP-WROOM-02らしい

2015年7月29日水曜日

ESP-WROOM-02についてのメモ(2)

以下、ESP-WROOM-02にスケッチをArduinoIDEから書き込む際のメモ

・IDEの環境構築は省略
 githubのESP8266コミュニティから環境を頂戴してくる
 IDEのBoardsManagerからインストールすればボードの選択肢にESP8266が
  
・USB-シリアル変換(3.3Vレベル)が必要
例:FTDI USBシリアル変換アダプター ・シリアル変換機のTX/RXとESP-WROOM-02のRX/TXを接続
・シリアル変換機のGNDとESP-WROOM-02のGNDを接続
・シリアル変換機をArduinoIDEと同じPCにUSB接続

・GPIO0をGND(L)に
・GPIO2を3.3V(H)に
・GPIO15をGND(L)に

・ESP-WROOM-02の3V3に3.3V電源を接続
・ESP-WROOM-02のGNDに電源のGNDを接続

・ArduinoIDE(環境構築済)を起動
・ツール→ボードからGeneric ESP8266 Moduleを選択
 (選択肢が無い場合は環境構築に失敗している)
・ツール→ポートからシリアル変換機のポートを選択
 (ポートがわからなければデバイスドライバ等からCOM番号を確認)

・適当なスケッチを選んで書き込みボタン(→)を押す
・『マイコンボードへの書き込みが完了しました。』表示がでれば成功
・自動的にリセットがかかりスケッチが動作

・GPIO0を3.3V(H)にしてリセット
・スケッチが動作することを確認

注意点:
 GPIO0をGND(L)で起動すると書き込みモードで起動するためにスケッチは動作しない
 GPIO0をGND(L)でスケッチ動作するのは書き込み直後の自動的なリセット時のみ

※※追記:
 GPIO0,2,15をHにする場合はプルアップ抵抗があった方が安全


書き込み環境/マイクロテクニカのボードを使用

2mmジャンパによる書き込み時設定

2mmジャンパによる動作時設定

スケッチ書き込み成功時

2015年7月24日金曜日

HC-SR04の不具合について

スイッチサイエンスから告知あり

間の悪いことに他店で先週買ったばっかり
基板を見る限り問題のあるバージョンの方っぽい
交換対応があるといいな…

ゲームの自動操作装置(12):キー入力ウェイトの実装

連続するキー入力のタイミング調整などにスリープ(ウェイト)処理が必要になる
以下はそれの簡単な実装について

Thread.Sleep()を使うのが一番簡単なのだが、スレッド自体が止まるのでUIも固まってしまう
(逆にこれを許容するならばThread.Sleep()でよい)
UIとキー入力部分を別スレッドにすればよいのだがこれもなかなか面倒くさい

以下のコードはThread.Sleep()の代わりに用いるスリープ用処理の抜粋
Timerクラスを用いて指定された時間だけ待つ
この間Application.DoEvents()メソッドを呼び続けることでUIが固まることを防ぐ

スリープの精度はイマイチだと思うが今回の用途には問題ないものとした

        static System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
        static bool timerEndFlag = false;

        //フォームのロード時にイベントハンドラを仕込んでおく
        private void FormLoad(object sender, EventArgs e)
        {
            //…
            myTimer.Tick += new EventHandler(TimerEventProcessor);
            //…
        }
        private static void TimerEventProcessor(Object myObject,
                                                EventArgs myEventArgs)
        {
            myTimer.Stop();
            timerEndFlag = true;
        }

        //Thread.Sleep()の代わりに使用
        private void sleep(int msec)
        {
            if (msec <= 0)
                msec = 1;
            myTimer.Interval = msec;
            timerEndFlag = false;
            myTimer.Start();

            // Runs the timer, and raises the event.
            while (timerEndFlag == false)
            {
                Application.DoEvents();
            }
        }

2015年7月23日木曜日

ゲームの自動操作装置(11):TIPSその3

・PCの省電力設定

 長時間稼動/長時間放置する場合にはPCの設定が必要になる
 アプリケーションが動作していようがWindowsの省電力機能は動作してしまう

  ・スクリーンセーバー
  ・モニタ電源のオフ
  ・スリープモード
  ・シャットダウン

 いずれも動作した時点でゲーム画面の取得ができなくなってしまう
 すべて設定でオフにしておくこと
 逆に言えばゲーム画面の取得ができてアプリケーションが動作するかぎりは
 どのような省電力機能が働いても構わない
 
 手元の環境では上記省電力機能をすべてオフにした状態でノートPCの蓋を閉じると
 モニタ表示はオフだがキャプチャはできる、という都合のいい状態を作ることができた

 そもそもアプリケーションで直接USBキャプチャできればこんな設定はいらない
 処理ももっと軽いはず
 とりあえず動くものが出来た時点でブラッシュアップを止めてしまったのは反省点



・システムの長時間稼動について

 自動操作装置は1~12時間程度の連続使用×2年程度の稼動に耐えた
 のべ時間は2000時間程度のはず

 2年間で交換したものはUSBキーボードシールドのみである
 (故障ではなく無線→有線に方式を変更した)

 長時間放置するため、電源周りやハードウェアの周辺に可燃物を置かないこと
 電源タップ/コンセント周りの掃除はマメに行うこと

板金のネジ穴破壊について

板金で作られたフレームに対して基板がネジで固定してあるようなセットについて

評価等で基板の付け外しを頻繁に行う場合にネジ穴が壊れる場合がある
(スカスカになってどこまでも回ってしまう/固定されない)

これはネジが元々のネジ溝に入っていないのに強引に締めてしまったため
板金のネジ山は大した強度が無いため、ネジによって新たにタッピングされてしまう

元々のネジ溝に入れるにはネジをネジ穴に当てた状態で軽く『緩める方向に』回すこと
ネジ先がネジ溝に落ちる箇所があるのでそこを基点にねじ込む

ゲームの自動操作装置(10):TIPSその2

・自動操作キックの回避について

 キーマクロや連射装置などを弾いてしまうゲームがある
 あるサイクル内でキー操作がパターン化されているか?という判定を行っている様子

 以下のような対策でこのチェックを回避できる

  ・キー操作の間にランダムな幅のウェイトを入れる
  ・動作に影響しないボタンの打鍵をランダムな回数行う
  ・パターンチェックの前にまとまった大きさのランダムな幅のウェイトを入れる


・パターンチェックが動作しなくなった場合

 まず疑うべきはキャプチャソフトの設定
 アプリケーション作成時から設定が変わってしまった場合は当然動かなくなる

  ・アスペクト比
  ・ウィンドウサイズ
  ・フレームの有無
  ・明るさ/コントラスト
  etc…

 ネットワークゲームではクライアントのバージョンアップによって動作しなくなる場合がある(らしい)
 運営のBOTへの対応は真剣そのものであり、画面の表示を少し変えるくらいは当然のお話
 各種オブジェクトやウィンドウの表示位置を数ドットずらされるだけでパターンチェックは使えなくなる

  この場合はパターンチェック部分の実装を修正する必要がある

ゲームの自動操作装置(9):TIPSいろいろ

・NumLockについて

 USBキーボードで一番難物はこの存在
 テンキーの2,4,8,6を方向キーとして用いるゲームが多いため
 この切り替えをミスすると意図した操作にならない

 ネットゲームで
  『88888888888888』
 みたいなシャウトを延々としているキャラクターがいたら
 それはNumLock切り替えをミスしたまま放置されている可哀想なBOT
 GMを呼ぼう

 Control.IsKeyLocked(Keys.NumLock))
 でNumLockの状態を取得できるので自動操作を開始する前にチェックすること
 不安ならばUI上にテンキ―とNumLock打鍵用のボタンを作っておくこと
 ArduinoおよびUSBキーボード変換機が起動する際にGPIOの状態が不定になるため
 NumLockがどちらの状態で起動するかは不安定であることに注意


・暴走について

 意図しない遷移によってキー入力が暴走する場合がある
  ・全キーをOFFする
  ・状態遷移を強制停止する
 というボタンを準備しておくこと

 とっさにアプリケーションを終了したとしても、Arduino側は動作を止めないことに注意
 

・Arduinoのケースについて

 長時間動作/長時間放置のプロジェクトなのでArduinoを適当なケースに入れること
 シールド剥き出しのまま外部に放置すると恐ろしいくらいに埃が積もっていく
 端子間が埃でショートすると火災の原因になる

 ケースは100均のタッパーにケーブル穴を開けたもので十分機能する
 Arduino自体は問題になるような発熱は発生しない

ゲームの自動操作装置(8):メインプログラム

自動操作アプリケーションメインプログラムは以下の処理の反復で構成される

 1.オブジェクトチェック
 2.内部状態遷移
 3.キー入力

オブジェクトをチェックすることで現在の画面情報を取得する
画面の切り替わりが検知できたら内部状態の遷移を行う
状態遷移に応じてキー入力を行う

問題点は前述のとおりオブジェクトチェック部分が低速であること
キー入力するまでに画面の状態が変わっている場合がある
このためユーザー入力を待たずにイベントが発生するゲームには向かない

また、内部状態の粒度を細かくするとオブジェクトチェックの回数が増えて重くなる
連続するキー入力は毎回オブジェクトチェックせずに決め打ちで行ってしまった方がよい

ゲームの自動操作装置(7):画像解析部のコード

ゲームの自動操作装置(6):画像解析部 からの続き


以下は画像解析部のコードの抜粋
いずれも簡単な方法で実装しており動作は低速である

・PC画面のスクリーンキャプチャ処理部分

 キャプチャの取得はSystem.Drawing.Graphicsクラスを使用している
 画面の左上にゲーム画面キャプチャソフトのウィンドウ(720x480ドット)がある前提
 サブディスプレイで動かすためにプライマリ/セカンダリスクリーンの切り替えが仕込んである
 PC画面の左上(0,0)から720x480ドット分のビットマップ(=ゲーム画面)を切り出す

  
        public static Bitmap GetDesktop()
        {
            Rectangle rect;
            if (outputDisplayNum == 0)
            {
                rect = Screen.PrimaryScreen.Bounds;
            }
            else
            {
                rect = Screen.AllScreens[1].Bounds;
            }
            //※※高速化のために全画面取得は廃止
            rect.Width = 720;
            rect.Height = 480;

            Bitmap bmp = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb);

            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.CopyFromScreen(rect.X, rect.Y, 0, 0, rect.Size, CopyPixelOperation.SourceCopy);
            }
            return bmp;
        }

・画像の解析処理部分

 ゲーム画面の任意座標にオブジェクトがあるかどうかの判定を行う
 オブジェクトチェック用にキャプチャ画面から矩形に画像を切り出しておく

 前述のゲーム画面とオブジェクトチェック用の画像のマッチングを行う
 マッチングの指標は各ピクセルの輝度の差の二乗和をピクセル数で割ったもの
  (3プレーンともチェックする場合は、更にプレーン分を足した後3で割る)

  実行時間はチェック用画像のサイズに依存する
  highSpeedフラグがある場合はRプレーン以外は無視する
 (処理は速くなるが当然精度は相応に落ちる)


ゲームの自動操作装置(8):メインプログラム へ続く

        private Bitmap gameBitmap;
        private int imgMuchValue;

        public bool checkMenuBase(Bitmap checkBitmap, int x, int y, bool highSpeed)
        {
            bool ret = false;
            int testVal;

            gameBitmap = Win32APICall.GetDesktop();

            testVal = cmpBitmapSSD(gameBitmap, checkBitmap, x, y, highSpeed);
            if (testVal < imgMuchValue)
            {
                ret = true;
            }
            else
            {
                ret = false;
            }
            return ret;
        }

        private int cmpBitmapSSD(Bitmap lb1, Bitmap lb2, int x, int y, bool highSpeed)
        {
            int xBuf, yBuf;
            int muchCountR = 0;
            int muchCountG = 0;
            int muchCountB = 0;

            int buf;
            int retbuf;

            if (highSpeed)
            {
                for (yBuf = y; yBuf < (y + lb2.Height); yBuf++)
                {
                    for (xBuf = x; xBuf < (x + lb2.Width); xBuf++)
                    {
                        buf = lb1.GetPixel(xBuf, yBuf).R - lb2.GetPixel(xBuf - x, yBuf - y).R;
                        muchCountR += buf * buf;
                    }
                }
                retbuf = muchCountR / lb2.Height / lb2.Width;
            }
            else
            {
                for (yBuf = y; yBuf < (y + lb2.Height); yBuf++)
                {
                    for (xBuf = x; xBuf < (x + lb2.Width); xBuf++)
                    {
                        buf = lb1.GetPixel(xBuf, yBuf).R - lb2.GetPixel(xBuf - x, yBuf - y).R;
                        muchCountR += buf * buf;

                        buf = lb1.GetPixel(xBuf, yBuf).G - lb2.GetPixel(xBuf - x, yBuf - y).G;
                        muchCountG += buf * buf;

                        buf = lb1.GetPixel(xBuf, yBuf).B - lb2.GetPixel(xBuf - x, yBuf - y).B;
                        muchCountB += buf * buf;
                    }
                }
                muchCountR = muchCountR / lb2.Height / lb2.Width;
                muchCountG = muchCountG / lb2.Height / lb2.Width;
                muchCountB = muchCountB / lb2.Height / lb2.Width;

                retbuf = (muchCountR + muchCountG + muchCountB) / 3;
            }
            lastCheckResult = retbuf;
            return retbuf;
        }

2015年7月22日水曜日

ESP-WROOM-02についてのメモ(1)

各販売店でESP-WROOM-02の取り扱いが始まった様子
800円程度で技適済の無線LANモジュールが手に入るのは驚き
しばらくはこれで遊べそう

問題はモジュールのサイズが小さく、ピンのピッチが1.5mmであるところ
2.54mmピッチへの変換基板が付いたものを選ぶとよい

スイッチサイエンスの販売ページより:モジュール単体



スイッチサイエンスのピッチ変換済みモジュール
 2.54mmピッチへ引き出しただけのシンプルな構成
 幅広すぎてブレッドボード上では若干使いにくそう
 価格はモジュール+200円程度と申し分ない

 2015/07/22時点ではモジュール含めて次ロット待ち

スイッチサイエンスのピッチ変換モジュール


マイクロテクニカの実装済ブレークアウトボード  設定用のピンを別途2mmピッチで引き出してあるのが特徴
 作例のようにここにジャンパピンを立てるととても使いやすい

 マイクロテクニカのページにはESP-WROOM-02の情報がまとまっているので必見
 日本語簡単マニュアルではセットアップと接続までを日本語解説している
 (マニュアルpdfのパスワードは商品を買うとついてくる)
 
 2.54mmピッチへ引き出す際にピン配列を変えてしまっているのは評価が分かれるところ


マイクロテクニカのブレークアウトボード


CEREVOのブレークアウトボード
 こちらは未実装品
 設定ピンの引き出しがある(一部はショート前提の割りパターン)
 2.54ピッチへの引き出しはピン配置の変更無し

 一番安いが1.5mmピッチのはんだ付け作業が待っている…
 実装作業やセットアップ方法はメーカーブログ参照

CEREVOのブレークアウトボード

2015年7月21日火曜日

ゲームの自動操作装置(6):画像解析部

ゲームの自動操作装置(5):キャプチャ環境 からの続き


画像の解析処理は以下のような流れになる

・スクリーンキャプチャ
 Windowsの標準APIを用いてPC上の画面をキャプチャする
 これで画面のビットマップイメージが取得できる
 キャプチャソフトの配置座標、ウィンドウサイズをあらかじめ決めておけば
 このビットマップイメージを切り取ることでゲーム画面の情報を取得できる


・画像の解析/状態の取得
 取得したゲーム画面を解析して現在の状態の取得を行う
 各状態(画面)特有のオブジェクトに対してその有無をチェックする方法をとった
 
 例:
  ・フィールド移動中にミニマップが表示される
  ・戦闘中には必ずHP表示ウィンドウが出る
  ・カジノで定型メッセージによって次の操作が促される
   Etc

 チェックしたいオブジェクトをあらかじめ準備しておく
 ゲーム画面のプリントスクリーンから矩形に切り取ってビットマップファイル化しておけばOK
 このとき、切り取ったオブジェクトの座標、矩形の縦横ドット数をメモしておく
 
 キャプチャ画面のビットマップに対して、上記オブジェクトのビットマップとの比較を行う
 比較の方法は何でもよい
 一番簡単なのは各ピクセルのRGB成分の値を取得し、その差の二乗の平均値をとる方法である
 まったく同じ画像ならばこの値は0となり、画像の差が大きいほど値は大きくなる
 マッチングのしきい値未満ならばオブジェクトを検知とする


※注意点
 ・キャプチャソフトの設定について必ずメモしておくこと
 ・できればバッチファイル等で設定/特定の座標へのウィンドウ表示を再現可能にしておくこと
  アスペクト比や明るさ・コントラストの設定が変わってしまうと機能しなくなる

 ・マッチングのしきい値を適正な値にすること
   高くしすぎれば誤検知が増える
   低くしすぎれば未検知が増える


ゲームの自動操作装置(7):画像解析部のコード へ続く

2015年7月19日日曜日

ゲームの自動操作装置(5):キャプチャ環境

ゲームの自動操作装置(4):アプリ/シリアル通信部分 からの続き


キャプチャ環境の構築はすべて市販のものを使えばよい

必要な機能:
 ・ゲーム機の画像出力をPC上にリアルタイム表示できること
 ・上記の表示がプリントスクリーン可能であること

 ゲーム機の画面をPC上に表示できさえすればどのような方法でもかまわない
 ただし、表示できてもこれをアプリケーションで取り込めない場合がある

 これは著作権保護機能やグラフィックカードの動画再生補助が原因
 取り込めるかどうかはPCの画面をプリントスクリーンすれば判断できる
 取り込めない場合はこの画像のゲーム画面部分が真っ黒になる

 自動操作アプリが判断に用いるだけなので画質は不要
 安価なコンポジットのUSBキャプチャユニットで構わない
 過去のプロジェクトで用いたキャプチャユニットは以下のもの
  GV-USB2 (アイオーデータ)

GV-USB2/メジャーなUSBキャプチャ

 キャプチャソフトは付属のものやフリーのものでOK
 過去のプロジェクトではGV-USB2の付属アプリが不評だったため以下のフリーソフトを使用

2015年7月18日土曜日

ゲームの自動操作装置(4):アプリ/シリアル通信部分

ゲームの自動操作装置(3):USBキーボードスケッチ からの続き


以下は自動操作アプリケーションのシリアル通信部の抜粋
開発言語はVC#

.NET FrameworkではSerialPortクラスが準備されており、簡単にシリアル通信が実現できる
今回のプロジェクトでは送信側しか用いないので特に簡単になる

ミニマムな構成は以下になる

・接続部
 任意パラメータでシリアルポート接続を行う

・通信部(送信部)
 シリアル通信で任意データを送信する

・切断部
 接続済のシリアルポート接続を切断する


ここではすべてにボタンが割り振られており、以下はそれぞれをクリックした際のハンドラである
送信するコマンド入力用にnumericUpDownを設けている
抜粋なので定義していない変数も使っているがそこはがんばって類推すること


ゲームの自動操作装置(5):キャプチャ環境 に続く


  
        private void buttonConnect_Click(object sender, EventArgs e)
        {
            try
            {
                if (serialPort1.IsOpen)
                {
                    MessageBox.Show(this.textBoxSerialPort + " はすでに開かれています。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    // ポート番号文字列=this.textBox1.Text, 115200bps/N81/ハードウェアフロー/UTF8/改行=CR
                    this.serialPort1.PortName = this.textBoxSerialPort.Text;
                    this.serialPort1.BaudRate = 9600;
                    this.serialPort1.Parity = System.IO.Ports.Parity.None;
                    this.serialPort1.DataBits = 8;
                    this.serialPort1.StopBits = System.IO.Ports.StopBits.One;
                    this.serialPort1.Handshake = System.IO.Ports.Handshake.RequestToSend;
                    this.serialPort1.Encoding = Encoding.UTF8;
                    this.serialPort1.NewLine = "\r";
                    serialPort1.Open();

                    connectFlag = true;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private void buttonSend_Click(object sender, EventArgs e)
        {
            try
            {
                sendBuffer[0] = (byte)this.numericUpDownCommand.Value;
                this.serialPort1.Write(sendBuffer, 0, 1);

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }
        private void buttonDisConnect_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                serialPort1.Close();
                connectFlag = false;
            }
        }

ゲームの自動操作装置(3):USBキーボードスケッチ

ゲームの自動操作装置(2):USBキーボードシールド からの続き

以下は前述のUSBキーボードシールドのためのスケッチ

シリアルポートを監視してPCから打鍵情報(1byte)が来るのを待つ
打鍵情報が来たら対応するGPIOへの出力を行う

ピンの最大数は17、打鍵は3種類(ON/OFF/HIT(一瞬ONしたのちOFF))なので1byteで足りる
(スケッチ内では簡単化のために17ではなくキリのよい20で計算している)

また、暴走対策のためにすべてのキーをOFFにするALL_OFF命令を設けている
どのピンに何のキーが対応しているかはこのスケッチでは扱わない

シリアル出力へデバッグ出力を行っているがアプリケーション側はこれを無視してもかまわない


ゲームの自動操作装置(4):アプリ/シリアル通信部分 へ続く

  
#define  PIN_MAX  17
#define  KEY_BASE  20

#define  KEYTYPE_HIT  0
#define  KEYTYPE_ON  1
#define  KEYTYPE_OFF  2
#define  KEYTYPE_MAX  2

#define  ALL_OFF  0
#define  KEY_DELAY  100

char command = 0;
int pin;
int commandType;
int commandNum;

void setup()
{
  Serial.begin(9600);
  for(pin = 2; pin <= 17; pin++)
  {
    pinMode(pin, OUTPUT);
    digitalWrite(pin, HIGH);
  }
}

void loop()
{
  if (Serial.available() > 0) 
  {
    command = Serial.read();
    if(command == ALL_OFF)
    {
      Serial.print("command:");
      Serial.print(command, DEC);

      Serial.print("ALL OFF");
      for(pin = 2; pin <= 17; pin++)
      {
        digitalWrite(pin, HIGH);  
      }      
      delay(KEY_DELAY);
    }
    else
    {
      commandType = (int)(command / KEY_BASE);
      if(commandType <= KEYTYPE_MAX)
      {
        pin = (int)(command - (KEY_BASE * commandType));
        if(pin <= PIN_MAX)
        {
          Serial.print("command:");
          Serial.print(command, DEC);
          Serial.print(" commandType:");
          Serial.print(commandType);
          Serial.print(" pin:");
          Serial.println(pin);
           
          switch(commandType)
          {
            case KEYTYPE_HIT:
              Serial.print("HitKey");          
              digitalWrite(pin, LOW);
              delay(KEY_DELAY);
              digitalWrite(pin, HIGH);
              break;
            case KEYTYPE_ON:
              Serial.print("OnKey");          
              digitalWrite(pin, LOW);
              delay(KEY_DELAY);            
              break;
            case KEYTYPE_OFF:
              Serial.print("OffKey");          
              digitalWrite(pin, HIGH);
              delay(KEY_DELAY);
              break;
            default:
              Serial.println("UnknownType");
              break;         
          }
        } 
      }
    }
  }
}

ゲームの自動操作装置(2):USBキーボードシールド

ゲームの自動操作装置(1):全体の構成 からの続き

必要な機能:

 ・ホストに対してUSB接続が可能であること
 ・ホストに対してUSBキーボードとして振舞うこと
 ・PCとシリアルポートで接続可能であること
 ・PCからシリアル通信で打鍵情報(何を押すか?)を受け取れること
 ・受け取った打鍵情報をUSBキーボードの打鍵に変換してホストに出力できること
 ・打鍵する可能性のあるキーは10種類程度とする

作例1:市販のキーボードを用いた例
 
 USBキーボードを分解してキー部分の配線を引き出す
 配線はマトリクス上になっており、2線の接続の組み合わせで任意キーの打鍵となる
 必要なキーの配線を引き出し、フォトリレーの両端に接続する
 フォトリレーのアノードにArduinoの出力ピン、カソードにGNDを接続する
 このときどちらかに適切な抵抗をはさむこと
 (フォトリレーの内部LEDが破損するため/電流値はフォトリレーのデータシート参照)

 これでArduinoのピン出力を打鍵に変換することができる
 スケッチについては次回のメモを参照
 
作例1:無線キーボード+電池BOX+フォトリレーシールド(自作)+Arduino Uno


フォトリレーシールドの裏面/無計画に作るとこうなる

  作成時に必要なキーが絞り切れていなかったため、15種のキーに対応している
  電池BOXは無線キーボードへの給電用
  ゲーム機には専用無線ドングル経由でUSB接続を行う

  ※作例では無線キーボードを使ってしまっているがこれは電波法に抵触するのでダメ
    有線キーボードを使うこと


作例2:市販のキーボード/GPIO変換機を用いた例

 ビットトレードワン/REVIVE USBを用いた例
 ポートとキーの設定は専用の設定ツールを用いて行う

作例2:REVIVE USB+プロトシールド+Arduino Uno
 
 必要なキーの絞り込みをおこなったため、8種のキーに対応している
 作例2と同じ機能の装置が簡単かつ簡潔に作成できている
 (配線が散らかっているのは作例1と互換をとったため)

 市販製品があるものは積極的に使ったほうがよい
 プロトシールドのブレッドボード上に構築しているので再利用も簡単


ゲームの自動操作装置(1):全体の構成

過去にコンシューマTVゲームにのめり込んでいた時期があり
「他の作業中でもレベルアップできないか?」
とArduinoとWindowsアプリケーションで自動操作装置を作った
(止めた今となってはなぜそこまで傾倒していたのかがわからない・・・)

以下はその記録
なお、ネットワークゲームサービスなどで自動操作を用いると確実に処分対象になるため
使用はおススメしない


・全体構成
  
  ゲーム機からの画像情報をUSBキャプチャ/キャプチャソフトを用いてPCに表示させる
  これらはすべて市販のものでかまわない

  PC上の自動操作アプリケーションはPCに表示される画像を認識できる
  この情報を用いて状態を判断し、次にすべき操作をArduinoに出力する
  アプリケーションは自作

  Arduinoを使ったUSBキーボードプロジェクトをゲーム機にUSB接続する
  これはゲーム機側からはUSBキーボードとして認識される
  このプロジェクトも自作

  ArduinoはシリアルポートでPCとも接続する
  アプリから送られる操作情報をUSBキーボードの打鍵としてゲーム機に伝達する

  
  このプロジェクトではゲーム機への入力にUSBキーボード入力を用いたが
  ゲーム機のコントローラーとフォトリレー等を組み合わせればコントローラー入力も可能

 
システムの構成

2015年7月17日金曜日

入り組んだ配線のパターンカットについてのメモ

入り組んだ配線をパターンカットするとき、カッターなどでガリガリ削ると周囲の配線まで巻き込みがちになる

最小の面積で確実にパターンカットする場合には小径ドリルで浅く穿孔してやるとよい

両面基板の場合は背面のパターンを破壊しないように注意すること(穴を貫通させないこと)

配線に合わせた径のドリルビットを選択し、位置がずれないように穿孔前に下穴やくぼみをつけること

2015年7月16日木曜日

ArduinoプロジェクトとWindowsアプリケーションの連動:接続方法

ArduinoプロジェクトとPCのWindowsアプリケーションの連動を考える


まずArduino―PC間の接続方法について


ケース1.Arduino内蔵USB-シリアル変換を使用する
 USB-シリアル変換を持つArduinoならば一番簡単な方法
 USBケーブルが給電と通信ケーブルを兼ねるためスマートに接続できる
 
 
ケース2.外付けUSB-シリアル変換を使用する
 USB-シリアル変換を持たないArduinoやAVR単体動作時はこちら
 FTDIのICを使っていて5V/3.3V切り替えスイッチのあるもの、DTRピンがあるものがおススメ
 例:FTDI USBシリアル変換アダプター  
 (AVRへのシリアル書き込みが可能であるため)

 ArduinoのTX/RXと信号レベルを合わせること
 USB-RS232C変換機と絶対に間違えないこと
 (RS-232Cの信号はMAX15V程度なので簡単に破損する)



ケース3.Bluetoothブリッジを使用する
 市販のブリッジICを用いる
 Bluetoothのコネクション確立後はシリアルポートとして扱うことができる


ケース4.SDカードを使用する
 データの交換のみならば直接接続する必要は無い
 ArduinoからのSDカードへのデータ書き込みは容易(ピンを4つ使うのみ)
 市販のSDカードシールドを用いるとさらに楽


ケース5.無線サーバ機能付きSDカードを使用する
 FlashAir など、デジカメ用の無線サーバ機能付きSDカードを使う
 Arduinoからは通常のSDカードに見える
 PC側からは無線サーバに見えるのでArduinoが書き込んだファイルへのアクセスが可能

東芝FlashAir/バージョンが複数あるので注意

直接通信する場合は全部シリアル通信でOKということがわかる

2015年7月15日水曜日

2.54mmピッチの世界

電子工作で最も使われるユニバーサル基板はスルーホールの間隔が2.54mmである
 2.54ピッチ基板/秋月
電子部品の類もこの間隔で作られているものが多い
以下多用する関連部品について


・ブレッドボード
 ブレッドボードはほぼすべてが2.54mmピッチで作られている
 当然すぎて基本的にピッチの表記が無いくらい


・ピンヘッダ(片側ロングタイプ)
 基板に対して垂直にピンを立てるときに用いる
 長さ6ミリ程度のピンはコネクタ/ジャンパー線(メス)などと連結できる
 ピンは連結されており、必要な数だけニッパーで切り離して使う

ピンヘッダ/ピンソケットと合わせて多用する


・ピンヘッダ(両側ロングタイプ)
 こちらは両側が長いタイプのピンヘッダ
 ブレッドボード上にピンを立てるときによく使う
 メス―メスコネクタ間の接続にも便利

ロングピンヘッダ/メス→オス変換としても使える


ピンヘッダ(L型)
 基板に対して横向きにピンを立てる場合に用いる


ピンソケット(分割タイプ)
 ピンヘッダとの接続を行うソケット
 ジャンパー線(オス)なども挿さる
 ピン数が固定のものが多いがリンク先の商品は任意に分割可能である
 ただしピッチが狭いので慎重に切らないと端のソケットが砕ける

ピンソケット/ピンに対して種類が少ないため多用する


ジャンパーピン
 隣接するピンヘッダを短絡(接続)させるときに用いる


・ピンソケット(脚ロングタイプ)
 ソケットの足が長く、ロングピンとして使えるタイプ
 基板の亀の子構造を作ることができる
 Arduinoのシールド用として用いられる

長脚ピンソケット/実質Arduino用


ジャンパー線(メス―メス)
 ピン同士を結線するのに用いられる
 メスは両側ロングのピンヘッダを用いれば簡単にオスに変換できる
 逆の変換は凄く面倒くさいのでメス―メスのジャンパー線は何本か持っていると便利



2015年7月14日火曜日

フレキシブルフラットケーブルの(FFC)のTIPS

・フレキシブルフラットケーブル(FFC)とは
 帯状の銅箔をならべて絶縁フィルムでサンドイッチした形状のケーブル
 多数の配線を一括してソケット接続できる
 ソケット接続部に補強板としてPET素材などのプレートが付くタイプが多い

FFCの裏面/端子が並んでいるのがわかる


 基本的に組み立て時に一回挿したら挿しっぱなしなのだが
 開発ではこれを挿抜する機会が多い
 (そしてトラブル要因になる)


・FFCのトラブル:断線
 ソケットが基板に対して垂直に実装されているとFFCを補強板付近で折り曲げることが多い
 この状態で頻繁な挿抜を行うと折り目に負荷がかかって断線する
 目視では確認し辛いため原因がわかり辛い
 心当たりがある場合はテスターで全ピンの導通テストを

 普通のケーブルとは異なり補修は困難/原則交換すること


・FFCのトラブル:接続部のダメージ
 ソケットへの挿抜をくりかえすことで接続部の銅箔のへこみ/剥離によって導通しなくなる
 これも目視では気付けない

 これも原則交換すべき
 応急処置として接続部の端を1mmほど切断してやると接点が復活する(場合がある)
 (ソケットと銅箔の接触位置がズレるため)


・FFCのトラブル:補強板の剥離
 挿抜によって補強板の接着が剥がれる
 ソケットは補強板こみの厚さで設計されているため、挿入が困難になる

 薄い両面テープや接着剤で補修すればOK
 (絶縁性のものを使うこと)


・FFCのトラブル:ソケットの破損
 そもそも抜くことを考慮していないのでソケットは破損しやすい
 ストッパーが付いているタイプは特にやってしまいがち

 表面実装パーツであり破損した場合の修復は困難


・FFCから信号線の引き出し
 ソケット基板側から信号線が引き出せない場合の裏ワザ
 FFCの真ん中あたりから引き出したいピン上の絶縁フィルムを5mmほど削る
 フィルムを縦方向に折り曲げてカッターの刃を立てて削ると楽
 内部の銅箔が目視できれば十分
 あとは予備はんだをした線材を乗せてハンダごてでプレスしてやればOK
 線材はペンチなどで平たく潰しておくとよい
 上からグルーガンや接着剤などで絶縁体をコーティングすればなおよい




2015年7月13日月曜日

チップ抵抗のハンダ付けについてのメモ

(以下、基板上に既にチップ抵抗用パッドがある前提)

1.パッドの片側にハンダを盛る
 予備ハンダをするくらいの気持ちで軽くハンダ付けする
 パッドは相応に小さいのでこれで十分に盛れる
 片側のみであることに注意

2.パッドにチップ抵抗を乗せ、片側をハンダ付けする
 チップ抵抗をパッドを跨ぐように配置して上からピンセットやツメなどで軽く押さえる
 1.でハンダを盛った側に対して、チップ抵抗の上からコテ先を押さえつける
 盛ったハンダが溶けたのを確認したらコテ先を離す

3.もう片側をハンダ付けする
 2.の逆側をハンダ付けして終了


パッドの両側にハンダを盛ってしまうと仕上がりがボコボコになる
(2.の工程で片側ずつ押さえつけることになるため、チップ抵抗が基板に対して密着しない)
 
ダメな例:両側に予備ハンダしてしまったため仕上がりが汚い

aitendoのArduino関連商品(2)

前回の続き

あちゃんでいいの [AKIT-ADINO]  ○
 AVR単体動作用の最小構成ボード
 安価だがUSBシリアル変換と電源以外の機能はすべて備えている
 ただただ安い
 難点は抵抗とコンデンサがチップタイプなのでハンダ付けの難易度が高いところ
 電源は2.54ピッチ2ピンへ5V/GNDを直接接続する

 2015/09/24追記:チップ抵抗/コンデンサが実装済の新型が発売された

拙作の裏面


極小AVRマイコンキット [CORE8]  ○
 AVR単体動作用の補助ボード
 単体動作に最小限必要なコンデンサとRESETピン用抵抗のみを備えている
 クリスタルやリセットボタンは外付けする前提で別売
 コンデンサを外付けするよりレイアウトがかなりスッキリしていい感じ
 難点は抵抗とコンデンサがこれまたチップタイプなところ

拙作の裏面

CORE8のほぼ等価回路/これがピンソケットの基板裏にスッキリ収まる


ぶれぼでいいの [BBDeiino]  ○
 ブレッドボード上で最小構成Arduinoを構築するためのキット
 前述の『あちゃんでいいの』を分割してピンソケットとピンヘッダを除いたもの
 別途ブレッドボードが必要となる
 使用時に基板がAVRの上を跨ぐという大胆な構造
 こちらは抵抗/コンデンサはチップタイプでは無い
 
USB電源キット [K-UBF6209] ○
  降圧機能付きUSB電源キット
 5Vの他に1.8~4.4Vに降圧した出力があるのがユニーク
 降圧する電圧は固定でありキットによって異なる
 出力用のピンヘッダは別売(2.54mmピッチのピンを立てるとよい)
 ピンを立てたらメスーメスのピンヘッダ接続ケーブルがあると便利
 (リンク先のケーブルは20Pだが、必要な数だけ割いて分割できる)

『あちゃんでいいの』との組み合わせ(5Vポートより給電)


USB-シリアル変換 ×
 USBシリアル変換の無い構成のArduinoでスケッチを書き込むのに必要
 USB-RS232C変換ではないことに注意
 aitendoの安価な製品の多くは変換ICにCH340を使っているのでできればパスしたいところ
 FTDIのICを使っていて5V/3.3V切り替えスイッチのあるもの、DTRピンがあるものがおススメ
 (DTRピンが無いとArduinoの書き込み用途に使えない)

 aitendoで該当するのはこれ
 秋月ならばこれ
 スイッチサイエンスならこれ