エントリー

カテゴリー「電子工作」の検索結果は以下のとおりです。

MFT2012 戦利品&組み立て後記

MakerFaireTokyo2012の戦利品の中から、組み立てたものを紹介します。

 

FLIS-UNO/e (juju_suuさん)

 

20121222_64-2.jpg

 

2線式フルカラーLEDコントローラです。

ATtiny10を使用し、電源ラインにフルカラーLEDをコントロールする信号を重畳しているそうです。8個連なっていますが、1個ずつ切り離して使うこともできます。クリスマスの明かりにはもってこいです。半田付けの難易度は、ATtiny10が非常に小さい上に部品間の間隔がほとんどなく、後述のTTL時計よりも難しいかもしれません。

ImpressWatchでも紹介されていました。
【イベントレポート】【Maker Faire Tokyo 2012】巨大人型4脚ロボットからジョーク系まで展示されたものづくりの祭典

 

USB-HID Volume Controller (morecat_labさん)

 

20121222_64-3.jpg

 

Win/Mac対応で接続するだけでボリュームコントローラとして自動認識されます。私はスピーカーよりヘッドホンの使用頻度が高く、PCのボリュームをわりと頻繁に調整するので、こういうものがあれば便利だなと思っていました。

 

TTL時計キット (楢ノ木技研さん)

 

20121222_64-4.jpg

 

74シリーズのICで構成された時計のキットです。

実は中学生の頃に「74シリーズだけで時計を作ってやろう」と考えていましたが、結局そのまま忘却の彼方に。そんな当時を思い出しながら製作していました。

 

「表面実装の半田付け練習に最適」と書かれている通り、かなり練習になります。表面実装部品の半田付けが確実に行える中級レベル(?)以上でないと完成させることは難しいです。しかも数が多いので途中でくじけそうになります・・・

私も数の苦行に耐えつつ完成させましたが、いくつかの箇所にブリッジがあり一発動作は達成できませんでした。上の写真はまだどこかにブリッジが残っていて、7セグ上部のLEDが光っていないものだったり・・・^^;

twitter上で楢ノ木技研のfelis_silvさんに助言を頂きつつ半田不良箇所を特定、無事正常に動かすことができました。めでたしめでたし。

 

DE0-nano + ドットマトリックスLED で遊ぶ その3

さて前回の続きですが、USBホストコントローラ部分の回路については触れていませんでした。ざっくりと言ってしまえば、Sparkfun の USB Host Shield と回路は同じです。

SparkFun Electronics - USB Host Shield
http://www.sparkfun.com/commerce/product_info.php?products_id=9947

 

DE0-nanoとの接続については、前回紹介した microbridge_nios2 の README.md に書かれていますので、そちらをご参考にということで。

DE0-nanoへ繋ぐ端子のうち、唯一オープンになっていないINT端子は MAX3421E 直近から引き出します。抵抗を挟んだ向かい側(電源側)に繋ぐと意味がなくなってしまうので注意です。

 

MAX3421E に供給する12MHzのクロックですが、せっかくFPGAがありますので水晶等は使わずにFPGAのPLLで生成することにしました。

FPGAのクロック50MHzを6逓倍して25分周する設定で12MHzが得られます。これはNiosIIコンポーネントに組み込む必要がないので、MegaWizardを使ってNiosIIの外に置きます。またクロックを出してくる端子は、MAX3421Eになるべく近くなるようにアサインします。

 

20120525_58-1.jpg

 

次に、ドットマトリックスLEDを制御するモジュールを、NiosIIのコンポーネントとして組み込みます。「SOPC Builder」と「Qsys」 というツールがあり、どちらを使ってもできますが、私はQsysを使いました。(QuartusがQsysを使えと言うので)

組み込み方法は・・・長くなるので省略します。スミマセン。

 

Sim さんの blog 「Qsysを使ってみた」という記事で紹介されていますので、そちらをご覧ください。

・Sim's blog
http://blog.goo.ne.jp/sim00

 

とりあえず、試行錯誤でやっていれば、そのうちなんとなく理解できて形になります。組み込んだ後の状態はこのようになります。

 

20120525_58-2.jpg

 

電源を切っても、回路データやNiosIIのプログラムが消えないように、EPCSにこれらを保存します。EPCSからプログラムをロードするには、EPCS Flash Controller のコンポーネントを追加しておく必要があります。

ただしリセットベクタの飛び先をメモリからEPCSに変えることになるので、NiosIIのEclipseからプログラムを直接実行できなくなります。デバッグが終わってから組み込んだほうがいいかもしれません。(まあリセットベクタのアドレスをメモリに設定すればいいだけですが…)

 

NiosIIで走らせるプログラムは、@iseroidさんのサンプルプログラムに若干手を加えた程度です。Android側からは、ドットマトリックスの 32x16 の64バイトデータが直接来ることを期待しています。というわけで実はFPGAはあまり仕事をしていません。

修正したファイルです。
mb_de0nano_demo.c

 

後は回路合成後のsofファイルと、NiosIIプログラムのelfファイルをEPCSに書き込むだけ・・・と、まあこのような感じでDE0-nano側は作っています。途中の工程をかなりブッ飛ばして書いていますが、細かいところはグーグル先生にお任せすることにしましよう。

 

ここからいよいよお待ちかねの、Android側のプログラミングです。

早速ですが、Androidの画面に描いた絵をドットマトリックスLED上に表示させるデモを作ってみました。そんなに難しいことをしているわけではないので、詳細はソースコードをご覧ください。

LEDを点灯させるかどうかは、特定のポイントで判定するよりも領域の平均的な明るさから決めたほうが、輪郭が綺麗になるとは思いますが、今回は時間があまりなかったということを言い訳として簡単な処理にしました。

ソースコードはこちら。
touch2matrix.zip

 

動いているところなど。

 

最後にLED上で動画を表示させてみたかったのですが、

 

20120525_58-3.jpg

 

残念、静止画で~す。
動画表示は無理っぽいですね。というのも・・・

 

  • 画面を取り込む手段が無い
    一番やりたかったことは、Android側で画面データを逐次取り込み、 LEDに送るデータに加工して転送するということでした。

    しかし、通常のJava(というかAndroid-API)を使っての開発では無理ということが徐々に判明してきました。フレームバッファ等に直接もしくは間接的にアクセスする手段がないので、例えば、動画を再生しつつその映像に対して独自の効果をかける、ということもできません。(カメラの映像ならできるんですよね。ファイルからの映像でできないのは著作権がらみ?)

    NDKならできるかもしれませんが、詳しくないのでわかりません。

    機種によっては、ADB経由でフレームバッファのデータを取得できます。日曜エレクトロニクスの @yishii さんが試されています。Garaxy-SでもできたのでSamsungの他の端末でもおそらくできます。IS01では無理でしたのでSHARPの端末は不可能かと。
     
  • 転送速度が遅い
    フレームバッファがADB経由で読めたとしても、800x480の画面サイズのデータがRGB888で送られてくるので、Hi-Speedでないと間に合いません。

    USBの転送速度、MAX3421EとFPGA間(SPI)の速度が遅いので、頑張っても1fpsいければいいところだと思います。

 

=====

 

先日5/19に、ECCコンピュータ専門学校を会場とした「関西FPGA・DE0勉強会」がありました。拙作のボードを持って行ってデモをしたところ、キャンパスニュースに(かなり大きく)載ることになりました。ありがとうございます! (テヘ

・ECCコンピュータ専門学校
http://comp.ecc.ac.jp/

・ECCコンピュータ専門学校 キャンパスニュース (5/22)
http://comp.ecc.ac.jp/news/campus/detail.php?id=2592

 

DE0-nano + ドットマトリックスLED で遊ぶ その2

2月初めには完成していましたが、とりあえず完成ー!ということで。

 

20120226_54-1.jpg

 

ボード右上に何やら怪しげなQFPのICが載っていますが、USBホストコントローラーのMAX3421Eです。実は最終的にAndroidと接続することを企んでいたりします。「なんだ結局Androidなのか」と思っちゃうかもしれませんが、まあそう言わずに。 ^^

急いで作ったので、若干雑な仕事になってしまいました。

 

ちなみに写真のQFP変換基板ですが、Aitem-Labにて購入しました。変換基板って無駄なスペースをとってしまうものばかりで、省スペースのものって電気街のパーツ屋を探し回っても見つかりませんでした。ネットで見つけて購入しましたが、狭いスペースでも使えて良い感じです。

 

ボード上の回路についてですが、ソース側は74ACTのシフトレジスタを、シンク側はトランジスタアレイを使用し、FPGAからそれらをコントロールしているというものになっています。 ボードの回路図

シフトレジスタは、以前の記事にも書いていますが、東芝の TC74ACT164 を使う予定でした。ただ、どの部品屋にも在庫がない状態だったため、TI の CD74ACT164 で代用しています。仕様的にも問題はありません。

 

LEDの電流制限抵抗は120Ω。決め方は下記の通りです。とりあえず 74ACT164のPch側のON抵抗は無視しています。流す電流も高々16mAですし、トランジスタアレイの Vce(sat) の特性ばらつきや温度による変動の方が大きいので、そこまで細かい値は気にする意味も無いと思います。

R = ( Vcc - Vf[LED] - Vce(sat)[TrArray] ) / 16mA

5V電源については今のところDE0-nano経由で、PCのUSBポートから供給しています。Androidを接続する場合は確実に供給能力不足になるので、外部電源が必要になります。

 

さて、FPGAの方に話を移しましょう。
ドットマトリックスLED制御部分のVerilogHDLはこちら。例によって無保証です。

matrix_led_ctrl.zip

 

構成としては、32bitx16のメモリを内部に持っていて、これにデータを書き込むことでその内容を表示します。またNiosIIのコンポーネントとして組み込むことで、ソフトウェア上で表示パターンを変更することができるようになります。

ゆくゆくはAndroidで制御しますので、ベースとしては@iseroidさんが公開されているNiosII用のMicrobrigeを使います。githubから取ってこれます。

https://github.com/iseroid/microbridge_nios2
 
今回はここまで~。(次回は未定)

 

DE0-nano + ドットマトリックスLED で遊ぶ

昨年末、AlteraのFPGA「CycloneIV」を搭載しているボード DE0-nano を買いました。

 

20120109_49-1.jpg

 

digikeyで7K円程度と、FPGAのボードにしては非常にお手ごろな価格です。

さて時を同じくして、秋月電子で16x16のドットマトリックスLEDを購入していて、なんとなくFPGAでドットマトリックスLEDを動かして遊びたいな~、という気分になりました。

 

下記、テキトーに考えた構成です。
 

  • 16x16のドットマトリックスLEDを、横に2個ならべて32x16で表示。LEDはダイナミックドライブ(縦方向をスキャン)で点灯。
  • CycloneIVには NiosII を搭載して、いろいろ怪しく遊べるようにする
  • とりあえず秋月電子で手に入る部品で作る。
    ドライバとしてソース側 74HC541APx4個、シンク側 TD62083APGx4個 使用。FPGAからは縦横パラレルでデータを出力。FPGA外の配線数が異常に多くなってしまうが、秋月で買えるICがこれしかないので我慢。あとシンク側で4個使用するのは以下2つの理由から。
  • ドット1個あたり平均1mAの電流で光らせたい。それ以下だと結構暗くなりそう。そんなわけでソース側の出力電流は16mA/ch程度に設定。
  • シンク側のICは絶対最大定格500mAなので、IC1個で横方向32ドットの同時点灯は無理 (16mA x 32 = 512mA)
    仕方なく横方向は16ドットにつきIC1個使いで。

 

完成イメージ

 

20120109_49-2.jpg

 

かなり重量バランスが悪い・・・

ともかく部品も揃っているので早速製作に取りかかろう!と、仕様書を改めて見てみると、TC74HC541AP、使えない子でした・・・orz

 

TC74HC541APで8端子分のLEDを全て点灯させると、1端子あたりの電流値は問題ないのですが、電源電流 Icc の絶対最大定格 75mA を超えてしまうことに気づきました。

9mA/chに設定するといけそうですが、表示がかなり暗くなることが予想されます。

ただ、電流値を多めに設定しておいて、後でシンク側のパルス幅を調整して輝度を下げることはできますが、逆に輝度を上げることはできないので、これはやりたくないです。

 

結局、74HC はどのメーカー、どの品番もダメ。

74AC に変更すれば、Iccが200mAなので十分使えそうです。実は 74HC の場合も言えることなのですが、これらのICを5V駆動させる場合、FPGAからの3.3V出力を直接受けるのは規格的にかなり厳しいです。

そういうわけでTTLレベル入力に対応した 74ACT にすることにしました。

どうせ部品を変更するなら、配線数削減のため、シフトレジスタ付きの TC74ACT164 にしたいところです。シリアルアウトがある TC74ACT299 もありますが、余計な機能が付いてピン数が多くなっているのでイマイチ。

 

あー、またパーツ買うのが非常に面倒くさい・・・(つづく)

 

 

~ 絶対最大定格よもや話 ~

絶対最大定格は一瞬たりとも超えてはならないという規格ではあるのですが、超えたからといってすぐにICが壊れてしまうことはおそらくありません。ですが、絶対最大定格スレスレもしくはそれを超えるような回路を設計すると、仮に趣味の工作であっても、どこからかマサカリが飛んでくることが考えられます。

 

さて、その絶対最大定格の範囲内で使用するとしても、実はこれは動作が保証される限界というわけではありません。動作が保証されるのは推奨動作範囲内に限ります。そしてこの範囲で使用するのが一般的に(信頼性の観点からして)正しい使い方です。

推奨動作範囲から絶対最大定格までの空白の領域については、瞬時に故障しない保証はありますが、動作保証はありません。自己責任で使ってくださいということです。

 

ところで話が若干逸れますが、どのメーカーのどんな規模の集積回路も「バーンイン」や「高電圧印加」と呼ばれる加速試験により、わずかに劣化させてから出荷されます。初期不良を排除するためです。

例えば、「初めて電源を投入して1000時間連続で動作させて問題がない場合、99.9999%の確率でその後10万時間は故障せずに動作する」ということが、あらかじめ何らかの方法によりわかっているとします。

できた製品をそのまま出荷するのではなく、1000時間動作させてから出荷すれば、1000時間未満で故障してしまう不良品は排除でき、ほとんどが将来10万時間動作する製品だけになります。あくまで確率の話ですが。

 

しかし、出荷する全てのICを1000時間も放置しておくのは、時間的にも費用的にも、ただの無駄でしかありません。そこで、1000時間動作させた時の劣化度合と同等と考えられるストレスを短時間で与えます。高温に曝すバーンインをしたり、電源電圧として高い電圧を加えたり、もしくはその両方を実施することによって1000時間を数時間(場合によっては数秒)に短縮させます。

加速試験は絶対最大定格、もしくはそれ以上の過酷なストレスがかかる状態で実施されます。つまり、加速試験をパスして出荷されたものは、少なくとも絶対最大定格内では瞬時に壊れることはない、ということになります。

またこの試験では、ICに本来の動作をさせるのではなく、IC内のトランジスタが極力全て動くような特殊なモードにします。絶対最大定格が動作保証限界ではないのはこのためです。

ちなみに、IC本来の動作をみる検査は、通常は推奨動作範囲の最大・最小(多少マージンを加味したり)の条件で行われます。
 

結局結論は何だということですが、

上のバーンイン試験の内容からもわかるように、実は絶対最大定格内で使用すればICが劣化しない、というわけでもなく、通電している限り極めてゆっくりですが劣化は進行していきます。推奨動作範囲で動かすことは要するに想定された製品寿命を保証する基準と言ってもいいでしょう。

つまり、信頼性の確保が最重要である場合は推奨動作範囲で動かさなければなりません。

 

しかし、耐用年数や安全性等を十分に検証した上での使用、または趣味用途といった信頼性がさほど重要でなく、リスクを自ら負える状況で使用する限りは、推奨動作範囲や絶対最大定格を逸脱することがあっても構わないと私は考えます。

例えば、LEDを抵抗などの電流制限素子を使わずに点灯させることも、使用状況を理解しているならアリと思うわけです。(さすがに電子工作入門の書籍等、理解が十分でない人向けには、あまり取り扱うべきではありませんが…)

 

とはいえ、特別な理由がない限りは、趣味レベルにおいてもスペックに対して十分余裕のある動作をさせることがベストなのは言うまでもありません。

 

H8マイコンでLinux 2回目

前回で開発環境が一応整ったみたいなので、Linuxカーネルのビルドを試してみました。
Linuxといっても、改めて言う必要はないかもしれませんが、組み込み向けの「uClinux」を使うことになります。

 

早速uClinuxのサイトから最新のソースパッケージを取得。
TOPページのhttp://www.uclinux.org/はなぜか頻繁に見れなくなるようなので、ファイルの置いてあるこのページに直接行ったほうがよいかもしれません。

現状では、uClinux-dist-20110810.tar.bz2 が最新のようです。
この記事では1つ前、"20110603"の日付のものを使用していますが、これから行う内容におそらく相違はないと思います。

 

ソースパッケージには、2.0.x、2.4,x、2.6.xのカーネルソースがそれぞれ入っています。今回はとりあえず2.4.xでビルドします。H8マイコンのメモリ増設はまだしていませんし、メモリ使用量が2.6.xよりも少なくなるようですので。

パッケージを展開して、make menuconfig、make dep、make、めんどいので詳細は略。

make CROSS_COMPILE=h8300-elf- menuconfig
make CROSS_COMPILE=h8300-elf- dep 2>&1 | tee make_dep_log
make CROSS_COMPILE=h8300-elf- 2>&1 | tee make_log

実はツールチェイン構築時の"--target=h8300-elf"は不要でした。このオプションを付けてしまったせいで、make時にもわざわざ"CROSS_COMPILE=h8300-elf-"をつけなくてはなりませんでした。
(何もつけない場合は"h8300-linux-elf"になります)

とりあえず今はこのまま進めます。

 

makeするとエラーて怒られてしまいました。滞りなく完了すると思っていたのに…
結論から言えば、ソースコードがGCC3以下でコンパイルされることを前提として書かれているのに対し、GCC4でコンパイルしたことが原因でした。GCC4から構文チェックが厳密になって、一部でこれまでの警告がエラーとして出てしまうようです。

いっそのことGCC3でやり直すか、いや待てそれは敗北宣言っぽい気がするな・・・、てなわけで、仕方ないので見ていくことにしましょう。

 

エラーその1

make CFLAGS="-fno-builtin -DNO_CACHE -D__KERNEL__ -I/usr/local/src/uClinux-dist/linux-2.4.x/include  -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -fno-builtin-sprin
tf -fomit-frame-pointer -Wno-pointer-sign -pipe -DNO_MM -DNO_FPU -DNO_CACHE -mh -mint32 -D__ELF__  -DNO_FORGET -DUTS_SYSNAME=\"uClinux\" -D__linux__ -DTARGET=aki3068net -Os  " -C  drivers
h8300-elf-ld  -mh8300helf   -r -o aki3068net.o timer.o
ptrace_h8300h.c: In function 'getnextpc':
ptrace_h8300h.c:249:7: error: lvalue required as left operand of assignment
ptrace_h8300h.c:253:7: error: lvalue required as left operand of assignment

 

linux-2.4.x/arch/h8300/platform/h8300h/ptrace_h8300h.c

202 static unsigned short *getnextpc(struct task_struct *child, unsigned short *pc)
203 {
204         const struct optable *op;
205         unsigned char *fetch_p;
206         unsigned char inst;
207         unsigned long addr;
208         unsigned long *sp;
209         int op_len,regno;
210         op = optables[0].ptr;
211         op_len = optables[0].size;
212         fetch_p = (unsigned char *)pc;
213         inst = *fetch_p++;
214         do {
・・・
247                                 case relb:
248                                         if ((inst = 0x55) || isbranch(child,inst & 0x0f))
249                                                 (unsigned char *)pc += (signed char)(*fetch_p);
250                                         return pc+1; /* skip myself */
251                                 case relw:
252                                         if ((inst = 0x5c) || isbranch(child,(*fetch_p & 0xf0) >> 4))
253                                                 (unsigned char *)pc += (signed short)(*(pc+1));
254                                         return pc+2; /* skip myself */
257                                 }

 

エラーが出ている箇所は249行目です。
ググればすぐに出てきますが、左辺がキャストされていることでエラーとなります。やりたいことはわからなくはないですが、この書き方は確かにあいまいです。

 

修正方法は、2.6.xのソースから引っこ抜いてこればOKです。

247                                 case relb:
248                                         if (inst == 0x55 || isbranch(child,inst & 0x0f))
249                                                 pc = (unsigned short *)((unsigned long)pc +
250                                                                        ((signed char)(*fetch_p)));
251                                         return pc+1; /* skip myself */
252                                 case relw:
253                                         if (inst == 0x5c || isbranch(child,(*fetch_p & 0xf0) >> 4))
254                                                 pc = (unsigned short *)((unsigned long)pc +
255                                                                        ((signed short)(*(pc+1))));
256                                         return pc+2; /* skip myself */
257                                 }

 

エラーその2

h8300-elf-gcc -fno-builtin -DNO_CACHE -D__KERNEL__ -I/usr/local/src/uClinux-dist/linux-2.4.x/include  -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -fno-builtin-spri
ntf -fomit-frame-pointer -Wno-pointer-sign -pipe -DNO_MM -DNO_FPU -DNO_CACHE -mh -mint32 -D__ELF__  -DNO_FORGET -DUTS_SYSNAME="uClinux" -D__linux__ -DTARGET=aki3068net -Os    -nostdinc -iwithprefix
 include -DKBUILD_BASENAME=ints  -c -o ints.o ints.c
make[3]: ディレクトリ `/usr/local/src/uClinux-dist/linux-2.4.x/drivers/media' に入ります
make -C radio
make[5]: ディレクトリ `/usr/local/src/uClinux-dist/linux-2.4.x/drivers/ide/arm' に入ります
rm -f idedriver-arm.o
h8300-elf-ar rcs idedriver-arm.o
make[4]: ディレクトリ `/usr/local/src/uClinux-dist/linux-2.4.x/drivers/media/radio' に入ります
make all_targets
n_tty.c: In function 'write_chan':
n_tty.c:1406:5: error: assignment of read-only variable '__gu_val'
n_tty.c:1406:5: warning: passing argument 1 of 'memcpy' discards qualifiers from pointer target type
rm -f mm.o

 

__gu_val が read-only ということで怒られています。 __gu_val を探してみると下記の場所にありました。
linux-2.4.x/include/asm-h8300/uaccess.h

 85 #define get_user(x, ptr)                                        \
 86 ({                                                              \
 87     int __gu_err = 0;                                           \
 88     typeof(*(ptr)) __gu_val = 0;                             \
 89     switch (sizeof(*(ptr))) {                                   \
 90     case 1:                                                     \
 91     case 2:                                                     \
 92     case 4:                                                     \
 93         __gu_val = *(ptr);                                        \
 94         break;                                                  \
 95     case 8:                                                     \
 96         memcpy(&__gu_val, ptr, sizeof (*(ptr)));                \
 97         break;                                                  \
 98     default:                                                    \
 99         __gu_val = 0;                                           \
100         __gu_err = __get_user_bad();                            \
101         break;                                                  \
102     }                                                           \
103     (x) = __gu_val;                                             \
104     __gu_err;                                                   \
105 })

 

ふむふむなるほど。
typeof(*(ptr)) としているんだけど、上記エラー箇所の場合、ptr が const unsigned char* なので、__gu_val が const になってしまい値が代入できない、というオチのようです。

get_userの詳細はさておき、結局やっていることは *ptr → __gu_val → x と値をコピーしていっているだけです。ということはつまり、暗黙的に x と *ptr は同じ(もしくは x が *ptr を内包する)型になっていると考えてもよく、下記でも問題ないはずです。

 88     typeof(x) __gu_val = 0;                             \

もちろん x が const となることはありません。

 

というわけで、これら2つのエラーを修正することで、カーネル自体のコンパイルはうまくいったようです。

しかしこの後、uClibやユーザランドのコンパイルでエラーがたくさん出てしまうことに…
それはまた次回・・・(って、あるのかわかりませんが^^)

ページ移動

ユーティリティ

Author


oaks (twitter: @oks486)

記事の内容に関しては無保証です。何事も At your own risk ってことでよろしく。
リンクはご自由にどうぞ。

SPAM対策が面倒なため現在コメント投稿機能を停止しています。あしからず...

検索

エントリー検索フォーム
キーワード

Feed

リンク