HIDaspx を作る

AVR を使った電子工作では、ISP プログラマーが必須だ、以前から「ELM さんの AVR ライタ」を使わせてもらっている。
※シリアル→ISPの変換デバイスを USB シリアル変換(FTDI)と組み合わせて、ケースに入れてある。

IMG_0436s
※さすがにかなりくたびれているが、未だ現役。

数年前に、ATtiny2313 を使って、ソフトウェアーだけで、USB クライアントになる ISP プログラマーが発表され、ずっと使ってみたかったのだが、現役のプログラマーで何とかなっていたので、ずっと見送っていた。
千秋ゼミ(AVRマイコンなど)
先日ゲームコントローラーを作るので部品を買った余り(余分に買った)があり、丁度良い機会なので、作ってみる事にした。

HIDaspx は、ATtiny2313 といくつかの部品だけで動作する AVR 用 ISP プログラマーなのだが、非常に洗練されており、ソフトウェアーの機能もてんこ盛りだ(はまった)。
折角なので、単純に AVR の ISP プログラマーを作りたい人の為に、簡単な製作記を残しておこうと思う。

(1) ハードの製作
HIDaspxは、プリント基板を販売しているところがあり、それを使えば簡単なのだがー、いくつかの点で、自分のスタイルに会わない為、今回はパス。

・やはりこの手の物は、ちゃんとケースに入れて、使わないと、ショートしたり、何かとトラブルが起こるもので、前回同様、同じケースに入れる事とした。
・ISP のコネクターは、前回と互換性を持たせ、10ピン仕様とする。
・最近はミニ USB やマイクロ USB が主流で、小さくて、扱いやすいので、ミニ USB コネクター仕様とした。
・電源の切り替えは、前回同様、5V、3.3Vを切り替えできるようにした。
・HIDaspx は、Ready と Busy のランプがある。
以上を踏まえて、ケース内のレイアウトを決め、ケースの加工、基板の切り出し、加工を行った。

IMG_0434s
※この段階では、LED 電源切り替えスイッチの穴は開けてない。
※ミニ USB のコネクターは、既製品の変換アダプターを使った。(かなり昔に買ったもの)
※このケースは、底蓋の面構造が、基板を、コネクターの形状を利用して固定するのに都合良く作られている。

内部に納める基板が出来たら、回路図を見ながら、部品を乗せて行く。

IMG_0437s

IMG_0438s
※緑の LED、VF が 3.2~3.4V なので、3.3V で動作させた場合にLEDが点灯しないのでは無いかと考え、フォトカプラーを間に入れて、常に5Vで駆動するように改修してある。
※他は、ほぼオリジナルの回路準拠
※経験上、三端子レギュレーターの入力側にはコンデンサはを入れていない(無くても、まず発振したりしないし、レギュレーションが悪くなる事も無い)
※緑 LED は超高輝度を使った為(手持ちがそれしかなかった)、電流を少なくしても、直視できないほど刺すような明るさで、失敗・・・、ブルー LED に交換する予定

最後にケースにレタリング

IMG_0439s
※新旧、2台のISP

IMG_0440s
※USB コネクター部分の違い

(2) 動作検査
まず、ファームやツールなどをダウンロードする。

今回使ったのは「hidspx-2012-0326.zip」で、既存の ISP で、2313 にファームを書き込んだ。

hidspx-2012-0326/bin/firmware/main-12.hex

ヒューズの設定は、ここに詳しく書かれている。

さて、一応、配線を確認後、PC の USB ポートに接続する、しばし・・・
問題なく、デバイスドライバーがインストールされた。

※自分の環境は、Windows7 64 ビットだ。
※USB2.0 のハブに接続している。

HIDaspxDeviceMan
※デバイスドライバーは、「HID 準拠デバイス」として認識されているようだ・・

(3) ツールの用意

hidspx-2012-0326/bin/hidspx.exe があるので、cygwin などのシェルを起動して、このコマンドを使ってみる。

↓以下のようにコマンドを打てば、認識したデバイスを表示してくれる。
% ./hidspx -ph?
VID=16c0, PID=05df, [ YCIT], [HIDaspx], serial=[0000] (*)

では、AVR を ISP に接続して、ヒューズビットを読み込んでみよう~
% ./hidspx -ph -d4 -rf
Detected device is ATmega88.

==== ATmega88 ====

Low: 11100110
||||++++-- CKSEL[3:0] システムクロック選択
||++-- SUT[1:0] 起動時間
|+-- CKOUT (0:PB0にシステムクロックを出力)
+-- CKDIV8 クロック分周初期値 (1:1/1, 0:1/8)

High:11-11111
|||||+++-- BODLEVEL[2:0] (111:無, 110:1.8V, 101:2.7V, 100:4.3V)
||||+-- EESAVE (消去でEEPROMを 1:消去, 0:保持)
|||+-- WDTON (1:WDT通常動作, 0:WDT常時ON)
||+-- SPIEN (1:ISP禁止, 0:ISP許可) ※Parallel時のみ
|+-- DWEN (On-Chipデバッグ 1:無効, 0:有効)
+-- RSTDISBL (RESETピン 1:有効, 0:無効(PC6))

Ext: -----001
||+-- BOOTRST (1:Normal, 0:BootLoader)
++-- BOOTSZ[1:0] (11:128W, 10:256, 01:512, 00:1024)

Cal: 182

※何かの拍子に、ISP が認識しなくなる事があるようだ、USB ケーブルをさし直すと直るようだが・・・

----- 注意!注意!注意! -----

hidspx は非常に高機能で、複雑、オプションなど注意を要する、得に、他の ISP プログラマーの機能を取り込んでいる為、他の ISP と混同すると期待した動作はしない。

※ありがちな事(自分もやった)
・USBaspx と HIDaspx を混同する。
※USBaspx は、libusb-win32 経由でデバイスとやりとりする為、libusb-win32 のツールを使って、デバイスを認識させる必要がある。

・libusb-win32 のツールを使って、HIDaspx を認識させてしまうと、hidspx で認識しなくなる。
※誤って、そうしたら、デバイスドライバーを削除すれば OK。
※HIDaspx はドライバーのインストールなどが一切不要で、直ぐに利用できる、半面、デバイスドライバーのプロパティでは、「HID 準拠デバイス」としか認識されない。

「千秋ゼミ」のページは、情報が多く、初心者には判りずらいかもしれない、しかしながら HIDaspx は非常に素晴らしい ISP なので、AVR のプログラマーを探している人は是非使ったら良いと思う。

追記:
> 何かの拍子に、ISP が認識しなくなる事があるようだ、USB ケーブルをさし直すと直るようだが・・・
外部電源に、数百mA程度を消費するような機器を繋いだ場合に、瞬間的に電源電圧が変動して、ATtiny2313 の機能が止まって認識しなくなるようです。
※Windows のデバイスマネージャーからは、正常に見えている。
そこで、外部電源ラインに、直列にフェライトビーズ「BLM18PG471SN1D」(秋月電子扱い)を入れたら、安定しました。
※470オーム(100MHz)/1000mA/0.2オーム(直流抵抗)

AVRでUSBゲームコントローラーを自作する

自分フレームワークの実装過程で、前回、エミュレーターソースを流用してスペースインベーダーを作成した。

GLFW3 には、標準で、ゲームコントローラーの取得 API があるので、それを使ってみる事にした。

適当な USB ゲームパッドを買っても良いのだがー、備品の中に、ファミコン時代に購入した、「ASCII STICK II TURBO」が埃をかぶっている事を発見したー

IMG_0423s

内部
IMG_0424s
※ボタンの「受け」などは鉄板で補強してあり、筐体はプラスチックだが、必要な剛性を確保してある。
※設計は、当時ナムコの筐体デザインなどをしていた遠山さんと言う噂なのだがー、この創りの良さとこだわりは、実際そうなのだろうと思う。

当時5000円くらいはした覚えがあるが、機能的には、ファミコン用なので、ボタンが少ないのだがー、連射や、4方向、8方向切り替えなど、色々と芸が細かい、
デザインも優れているし、剛性も高く、方向レバーはマイクロスイッチで、価格以上の素晴らしい創りとなっている、今回はこれを改造する事とした。

USB のゲームコントローラーでは当然ながら、制御用マイコンが必要だが、ネットを探すと色々ある、今回利用させてもらったのは「ココ」のサイト。
AVR を使った USB ゲームデバイスで、最近ではあまり馴染みの無い ATMega8 を使っている。
手持ちの ATMega88 とかで出来れば良いのだがー、このコントローラーの制御ソースはアセンブラなので、ATMega8 を別途購入した(秋月で180円)。
そもそも、USB の通信機能が無い AVR でUSB(Low スピード)の通信を行うのはかなりハードルが高い、マシンサイクルを正確に計算して、ソフトウェアーのタイミングループだけで、USB の制御信号を
生成しているのは、クールとしか言いようが無い。

ASCII STICK には、何に使うか最後まで不明な「OPTION」コネクターがある。
丁度良いので、USB コネクターはここに出そうと考えて、工作してみた。

IMG_0429s
※回路は、特に変更はしていないが、USB の差動ラインに入っている68オーム、手持ちが無かったので75オームとした。
※アナログの電源ライン「GND」も回路図ではオープンとなっているが、一応 GND に落としておいた。

----- Fuse ビット書き込み時の注意 -----

ATMega8 は、ピンアサインなどは、ATMega88P などに近いものの、古いデバイスで、注意する点があります。
現在も流通はしているものの、ATMega88Pや上位デバイスに置き換えるのでしょう。
※自分もそれでハマリました・・・
まず、ヒューズビットを書き込む場合ですが、最初に low バイトを書き込んでしまうと、発振機が動作しなくなります。
これは、「fuse.txt」の値が適切とは言えない点と、ATMega8 の仕様によるところにあります。
12MHz のクリスタルを使う場合なので、high バイトの「CKOPT」を変更して、「0」にしておく必要があるようです。

僕は、色々やった結果、high バイトに「0xC9」、low バイトに「0xEF」を書き込んでいます。
※WatchDog は有効にした方が良いかもしれません・・
※fuse.txtでは、low バイトの CKSEL が、「External Low-frequency Crystal」となっていて、これは絶対間違っていると思います。

AVR の痛いところは、fuse の書き込みを失敗すると、再起不能になる場合がありますので、注意が必要です。
クロックの選択を誤った場合は復帰するチャンスはありますが、「RESET」端子とかを無効にしたりすると、ISP でのプログラムは不可能となります。

IMG_0431s

IMG_0433s
※いつものフォーレックスを適当に削って、USB コネクターのカバーにした、基板とLOCTITE で接着してある。

Game_Controler_Dialogjpg
※ゲームコントローラーとして認識したダイアログ(ボタンが多いのは愛嬌)

フレームワークを USB コントローラーに対応した。
ソース
バイナリー

GLFW3と自分FWを使って昔懐かしい「Space Invaders」を作る

以前から、チクチクとゲーム開発の補助になる自分用フレームワークを作ってきましたがー
GLFW3 がリリースされたタイミングで、glut から GLFW3 に変更していましたが、とりあえずのベータが出来たので、アーカイブを公開します。

自分用フレームワークの完成度を上げるには、一通りの機能を使って、アプリケーションを作る必要があるものです。
また、C++ の熟練度が少しづつ向上して、ソースコードの品質も少しづつではあるけど洗練されてきつつあります。
そこで、何か良い題材は無い物かと考えてましたが、とりあえず、キーボード入力と、サウンド(効果音)が出る、そして簡潔に出来る。
などの理由で、昔懐かしい「Space Invaders」を作る事にしましたww

「作る」と言っても、「Space Invaders」は、mame32 由来のエミュレーターソースをそのまま使います。
※その為、このソースコードもそれらライセンスに従います。

スペースインベーダーは、8ビットのZ80(2MHz)を使い、256×240のモノクロビットマップグラフィクスを使ったゲームで、
当時は、もの凄く洗練されていました。(今でも洗練されていると思う)
エミュレーターは、8080のエミュレーションと、インベーダーのハードをエミュレーションします。
結果は、モノクロビットマップの出力として出てくるので、OpenGL のテクスチャーに貼って、描画します。
インベーダーはアナログシンセサイザーを持っていて、現在では、はサンプリングされたデータを入手出来るので、それを使いSEとして
発音します。

spain

プログラムの動作には、ROMイメージが必要なので、どこかで見つけて下さい。
※このプログラムでは、sounds.zip、invaders.zip の二つのアーカイブを必要とします。
ここが参考になると思います

ソースコード

コンパイルに必要なライブラリー郡、/usr/local 以下に展開

boost_1_53_0 が必要です。

コンパイル済みバイナリー

※操作方法
「1」1プレイヤーボタン
「2」2プレイヤーボタン
「3」コイン
「←」ビーム砲左
「SPACE」ビーム発射
「→」ビーム砲右

GLFW-3.0.1 の機能追加

GLFW ですが、既に 3.0.1 がリリースされてましたーー

Bugfix: The wrong name was used for the CMake variable for the Xxf86vm library
[Cocoa] Bugfix: glfwGetFramebufferSize return the size in screen coordinates
[Cocoa] Bugfix: Messages not supported on Mac OS X 10.6 were used without tests for precence
[Cocoa] Bugfix: Process transformation was not performed if menu bar creation was disabled
[Win32] Bugfix: Context creation was attempted even if no valid pixel formats had been found
[X11] Bugfix: Duplicate window position and window and framebuffer size events were reported

まぁ、基本的にBugFixのようですが・・・

さて、OpenGL のアプリケーションですが、作っていて不便な事があります、アプリケーション・ウィンドウに
ファイルをドラッグ・アンド・ドロップして、ファイル名を受け取る事が出来ない事です。

アプリケーションを作る上で不便なので、GLFW を改造して、この機能を付けましたー

glfw-3.0.1 のパッチ

glfw-3.0.1 のソースを展開して、ルートディレクトリーに異動後、以下のコマンドを入れればパッチが当たると思います。

patch -p0 < glfw_3_0_1-dropfiles.diff で、make すれば OK。 exsamples に dropfiles.c のサンプルがあるので、これを観ればどのようにファイル名を受け取るのか判ると思います。 もっと実用的なサンプルとして、ビューアー・プレイヤーを作りました。
※ソースコードが欲しい方は、連絡下さい、必要なフレームワークの準備に少し時間が必要です。

このアプリケーションは、起動すると、空のウィンドウが開きます、ここに画像ファイル(BMP、PNG、JPEG、JPEG2000)や音楽ファイル(WAV、MP3)を落とせば、それを開きます。
※音楽ファイルは再生します、MP3に画像が含まれている場合は、それを表示します。

※メイン部分だけアップしておきます~

GLFW3.0 を使う

自分のフレームワークとして、「gl_fw」と言うプロジェクトを実装していましたがー

最近(そうでもないかww)、GLFW と言うフレームワークがある事を知りました、現在のところ、OS-X、X11、Windows で使える、マルチプラットホームのフレームワークです。
C、Objective-C(OS-X)で実装されており、シンプルで、良く出来ています。
※「glut」があるのですが、これは、メンテナンスされていないし、色々と痛いところが多いのです。

最近、メジャーバージョンが「3.0」となり、「2.x」から、より洗練された実装になりましたー、まだ機能で欲しい部分は色々あるのですがー、これから追加されていくと思います。

自分のフレームワークも glut から GLFW に変更すべく色々修正中です。
GLFW 3.x で良い部分をいくつか上げると・・・
・マウスホイールのイベントを取得できる。
・クリップボードのやり取りが追加された。
・メインループから綺麗に抜けてくれる。(glutでは、スマートでは無い方法で実装しなければなりません・・)
・ゲームパッドの値を標準的に取得できる。
・キーボードの扱いがゲーム向き。(単純に押したか、押さないを取得できる)
・必要最小限の機能だけ用意してあり、わかり易い。
・ライブラリーをコンパイルするのが簡単。(cygwin の windows クロスコンパイラ i686-w64-mingw32 でコンパイルできるようになった)

現在の「3.0」には、ドロップファイルのイベントを受け取る機能が無いので、これは自分で足そうと思います。
※「2.x」で実装したので、「3.0」風に書き直す感じww

cygwin で glfw-3.0 をコンパイルする手順を書いておきます。

(0) cygwin に i686-w64-mingw32-gcc、cmake などをインストールしておく。
(1) glfw-3.0 のソースアーカイブを取得して展開する。
(2) glfw-3.0 に移動
(3) 「cmake -DCMAKE_TOOLCHAIN_FILE=CMake/i686-w64-mingw32.cmake」
(4) 「make」
※何も指定しないとスタティックリンクライブラリーが作られるようです。(DLL にする意味は無いと思う)

これでおしまい!(ああ、何て簡単なんだろ・・)

(5) 「make install」で、/usr/local/以下にインストールされます。

では動かしてみましょう!


#include <stdlib.h>
#include <GLFW/glfw3.h>

int main(int argc, char** argv);
int main(int argc, char** argv)
{
    GLFWwindow* window;

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {
        /* Render here */

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();

    return 0;
}

※ cygwin のコンパイルで重要なのは、リンクライブラリーとして、glfw3、opengl32、glu32、gdi32 を加える事です。

さて、ゲームなどで必要なのは、サウンド、スレッド、画像の読み込み等ですが、GLFW のポリシーでは、「これをフレームワークに含め無い方が良い」との考えのようです。

自分もそう思います、自分は、以下のように解決しています。
・サウンド ---> OpenAL を使うのが良いでしょう~
・スレッド ---> POSIX のスレッド pthread を使う。(OS-X、Linux、mingw では標準です、VisualStudio を使う場合は、pthread-win32 ライブラリーを使います)
・画像 ---> libpng、などを使えば良いし、読み込みをサポートするライブラリーやソースは沢山あるので、自分に合った物を選べば良い。

「gl_fw」(紛らわしいけど、GLFW を知る前からなので・・・)の改修が終わったら、またブログを書きます。
※gl_fw は、C++ を使ったフレームワークで、サウンド(単音、ストリーム)を扱うクラス、画像ファイルを単一的に扱うクラス、フォント(漢字)、GUI、などそこそこ高機能な物です。
ソースコードは、テストが済み次第取得できるようにしますが、興味のある人は連絡下さい~
githubから取得出来ます。
※glfw3には、ドロップファイルを受け取る改修をしています(windows版のみ)、Libraries にlibファイルとヘッダーを用意しています。

9XR 送信機と FrSky テレメトリー

自分は、以前に JR の7チャネル送受信機を買ったのだがー、マルチコプターと、ヘリコプターを購入して、受信機を買い足す必要が出てきたー
それに、マルチコプターの本格的運用では7チャネルでは少し足りない感じもする・・・
残念な事に JR の受信機だけ買い足すのも、割高な強気値段で、どうしたもんかなーと考えていたらー、9チャネル送信機が5000円!、えっ?!

そうなんですー、モジュール式の送信機だけなら海外では格安で売られているのですー、品質はそれなりなのかなーと思ったら、そんな事もなさそうだしー
JR は DMSS に対応した物を購入したのですがー、実際、センサーなどのモジュールが割高で、テレメトリーとして運用するには、かなり厳しい・・
テレメトリーのモジュールを自分で作りたいけど、プロトコルは非公開だし、リバースエンジニアリングするのも億劫だし。

TURNIGY 9XR は JR 用モジュールが使えるようになっている。
TURNIGY 9XR

それから、格安の FrSky のテレメトリーモジュールも購入した。
※それでも、JR の受信機買うのとあんまし代わらないお値段。
FrSky DJT

FrSky D8R-II PLUS

FrSky のテレメトリーモジュールは、プロトコルが公開されており、自分で簡単に作る事も出来る。
そこで、とりあえず、送信機側表示モジュールを作って、実験してみようと思う。

基本的構成はいつもの AVR 、今回は ATMega328P を使った(250円)、それと、DJT とシリアル通信を行う為の RS232C のラインドライバー(ADM3202)、表示は、秋月の128×64ピクセルの液晶

9XR はオープンソースもあり、ファームを書き換えする事も出来るので、DJT からのテレメトリープロトコルを突っ込んで、9XR の液晶に表示させれば、シンプルでクールなのだがー、本体を多少改造しないと駄目なので、今回はパスする事にした。
まず、表示用液晶として、秋月電子で売られている128 x 64 のドットマトリックス液晶、この液晶、そこそこ小さく、手頃な価格で良いのだがー、痛いとこもある、接続が、2mm ピッチで自作向きでは無い、そこで、まず、付属のコネクターをユニバーサル基板に接着し、強度を増す為、スタビライザーみたいな物を追加した。
※2本なら、2mmピッチを無理やり2.54mmピッチに差し込める。

128x64 接続A
128x64 接続B

完成した基板
TelemetryBoadTop
TelemetryBoadBottom

とりあえず、ソフトウェアーは、アナログポートの数値を読み込むだけの物を仮に作ってみた。
DJT から送られてくるプロトコルは、以下の通り(ヘッダー、ターミネーター 0x7E、アナログポートのID:0xFE)

0x7E、0xFE、PORT1、PORT2、Link_quality(2)、0x00、0x00、0x00、0x00、0x7E
※FrSky のマニュアルでは、Link_quality は1バイトで zero が5バイト続くとなっているが、Link_quality は2バイトで、zero は4バイトのようだ。

port1 のアナログ電圧は4倍して表示してある。
リチウムポリマー電池の電圧を1/4にして入力すれば良い。
グラフィックス液晶の利点を使って、レベルバーも表示してある。
LCD の下に破線が表示されていて、プロトコルを受信している場合に、アニメーションする。
一応、プロトコルの生データを16進で表示している。
この LCD は、アイコンの表示があり、最下位の4ピクセルの On/Off で表示するのだけど、役に立たないので、63ラインは使わない事にする。IMG_0410s

自分で作ると、専用のカスタマイズを作成する事が出来るのが良い。

※ソースコード

※回路は、mainloop.cpp にポートと、LCD の接続をコメントしてあるので、それを参考に。
※液晶は低速で、コマンドを書き込んでから、それが有効になり次のコマンドを発行するまで待たないといけない、一般的には、ステータスを読み取るのだけど、
液晶を外した状態にすると、プログラムが進まなくなるし、ポートの制御が面倒なので、プログラムループで遅延している、その為 R/W は書き込みしか行わないので、GND に落とす。
※シリアルは、RXD、TXD を RS-232C のコンバーターを通して接続する、DJT:RXD と AVR:TXD、DJT:TXD、AVR:RXD となる事に注意されたい。
※そのうち、KiCAD のプロジェクトをアーカイブに含めるつもり。