Raspberry Piを注文してみた

ずいぶん前にRaspberry Piについてニュースが流れたときにRSオンラインのメールでのお知らせに登録しておいたら、「受注できるよ」ってメールが来たのですが、その夜にはSoldOutだったのでがっかりしていまいた。

・・・・で、さっき、なにげなく Hack a Day を眺めていたら Raspberry Pi を使った記事が出ていました。そこから RS Components へのリンクが張られていて、辿ってみるとなんと受注可能っぽい表示に変わっているではありませんか。

ひょっとして、日本でも買えるのか?と思って、早速、RSオンラインの方から辿ってみると、「注文受付を開始しました」に変わっています。

今回は専用ケースも追加されたようで、ケースとセットで速攻で2台注文してみました。

Raspberry Pi TypeB 本体が27.40ユーロ、ブラックのケースが5.06ユーロ、HDMIケーブルが4.30ユーロ、送料が6.28ユーロでPayPalで支払い。為替レートは1ユーロ=99.58円でした。

しかしながら、予想配送期間は18週間….orz

気長に待つことにします。

普通のメディアでもニュースになっているみたいです。→読売の記事(1時間前)

追伸:ひょっとして、結構前から注文可能だった??

PythonでUSBのパイプを扱う方法

Pinguino(PICマイコンでArduinoのようなことをするもの)について調べていたら、

http://wiki.pinguino.cc/index.php/Interfacing_with_Python

にUSBのパイプをPythonで扱う方法が出ていた。

PinguinoではUSBでホストとのデータ送受信ができるようであり、そのための例として載っている。
(ちなみにPinguinoは秋月で売っている PIC32MX220F032BのQFP44ピンバージョンであるPIC32MX220F032Dを搭載したバージョンがOLIMEXから販売されている)

ここによれば、

On Computer Side

#!/usr/bin/env python
#
import usb
busses = usb.busses()
# Search pinguino between all the usb devices
for bus in busses:
  devices = bus.devices
  for dev in devices:
    if dev.idVendor==0x04d8 and dev.idProduct==0xfeaa:
      pingu = dev
# Get a device handler for th usb device
dh = pingu.open()
# Set configuration 3 an interface 0
dh.setConfiguration(3)
dh.claimInterface(0)
# Read 5 bytes in Bulk mode, convert them to 
# a string and print it
while 1 == 1: 
  cadena = ""
  for i in dh.bulkRead(0x82, 5, 10000):
    cadena += chr(i)
  print cadena

という簡単な記述で扱えるらしい。

 

CHDK/Luaを使うための情報

CHDK/Luaを使いこなすための情報収集をしました。

  • http://chdk.wikia.com/wiki/Lua
    CHDKのWebサイト内のLuaに関する説明ページ
    ここに重要なリンク集や、スクリプトの起動方法、サンプル、ライブラリに関する情報、スクリプトの例などがある。
  • http://www.lua.org/home.html
    Lua言語に関するページ。
    LuaはCHDKオリジナルの言語というわけではなく、ブラジルのリオデジャネイロのPontifical Catholic(カトリック?)大学で設計・実装・メンテナンスされている汎用の言語のようです。特徴は高速性、移植性、組み込み可能、パワルフかつシンプル、小さい(ソースは20Kライン)、フリー(MITライセンス?)で、なおかついろいろな商業製品にも採用されている・・・らしいです。
  • http://chdk.wikia.com/wiki/Lua/Lua_syntax
    Luaの文法の説明。C言語でもなく、BASICでもなく、PerlやPythonともまた違う感じです。
  • http://chdk.wikia.com/wiki/CHDK_Scripting_Cross_Reference_Page
    CHDKで使える関数の一覧
  • http://chdk.wikia.com/wiki/Lua/Lua_Reference
    Luaのライブラリの説明

とにかくインターバル撮影

IXY210FにせっかくいれたCHDK、インターバル撮影ができなければ意味がありません。

で、ググってみたら、こちらのページ
基本的にはコピペのようですが、とにかく追試して実際に動作することを確認できました。(感謝)

で、ここで使われているスクリプトが、Luaというスクリプトです。

この説明は

http://chdk.wikia.com/wiki/Lua

にあって、最初に参考にさせていただいたスクリプトもここに記載されているものでした。

uBASICというスクリプトに比べてかなり強力なことができそうなので、調べてみたいと思います。

パラレルリンク機構を使った3Dプリンタ

Hack a Day をみていたら パラレルリンク機構を使った3Dプリンタの動画がアップされていました。

XYZ座標を使う機構に比べて、シンプルで大きなものを作れそうです。しかも、デモ動画のリンク機構は非常に高速かつ安定感があります。(パラレルリンクロボットの特徴ですが)

3Dプリンタにパラレルリンクを使うアイデアは面白いなと思いました。

Web散策中に見つけたもの:

 

IXY210FにCHDKを入れてみた

CHDKを入れてTimeLapse撮影をするために購入したIXY210Fですが、なかなかCHDKの導入の方法が分からずそのままにしていました。・・・・が、今回CHDKの導入方法がわかりましたので、試してみました。

インストール(というか導入)

参考:CHDK Installation Guide.pdf

  1. ファームウェアのバージョン確認
    CHDKを入れる際は元々入っているファームウェアのバージョンがわかっていないといけません。
    通常の機種だとSDにルートディレクトリに「ver.req」や「vers.req」という空のファイルを置いたSD Cardを挿入して電源投入し、特定のキー操作をするとバージョンが表示されるはずです。
    ・・・・・されるはずなのですが、ちっともうまくいきません。これがしばらく放置していた原因です。
    今回は諦めて(最悪、復活不可になってもいい、と覚悟して)、4種類あるファームウェアを総当たりで試してみることにしました。
  2.  CHDKファイルのダウンロード
    http://chdk.wikia.com/wiki/CHDK
    に各機種用のファイルがあるように見えますが、IXY210F用のものは見当たりません。
    まだ開発中なので、「for Developpers」のリンクを辿った
    http://chdk.wikia.com/wiki/For_Developers
    に海外での機種名「ELPH100 HS (IXUS 115 HS & IXUS 117 HS)」で開発ページをみることができます。
    そこから上の方の地味な「Downloads」のリンクを辿って、さらに「The Latest Builds – Unstatble trunk 1.1」を辿った先に、開発中の対象機種を含めたzipファイルのダウンロードリンクがありますので、とりあえずFirmware1.01用のa,b,cバージョンのそれぞれのファイルをダウンロードしました。
    なお、「http://chdk.wikia.com」の下のページは(多分マルウェアだと思うのですが)ダウンロードやポップアップの広告リンクが『これでもか!』というくらい多数出てきますので、うっかり踏まないよう気をつけないといけません。ダウンロードしたファイルは展開しておきます。
  3. SD Cardのフォーマット&書き込み
    SD Cardの作成、と言った方が良いかもしれません。自分は
    http://chdk.wikia.com/wiki/Prepare_your_SD_card
    のページを参考にしました。
    SD Cardをフォーマットして、ブート可能にセット、ファイルを書き込むようなのですがそれをやってくれるツールのLinux版がLICKS(Linux Installer for CHDK and SDM)です。
    ここで、 コピーするファイルのコピー元(「Copy all files from」)に上でダウンロードしたCHDKファイルを展開したディレクトリを指定して、下の方の「Prepare Card」を押すとSD Cardのフォーマットと書き込みをやってくれます。書き込みが終わったら「Eject Card」でSD Cardを取り出します。
    なお、4GB以上のカードでパーティションを切って使うフォーマットにも対応しているようですが、いまのところカメラ側でパーティションを切り替える方法がわかりません・・・。
  4. CHDKを起動させる
    書き込まれた SD Card をライトプロテクト状態にしてIXY210Fにセットして電源ONします。
    自分の場合には3種類のファイルをトライして、1.01B用のファームウェアで起動しました。起動は電源ボタンで起動する場合と再生ボタンでしか起動しない場合がありましたが、法則はまだよくわかりません。
    ファームウェアのバージョンが違っていると、うんともすんとも言わなくなりました。自分の場合は SD Cardを取り出して電源ボタンを押しても何とも言わなくなったので、少し焦りましたが、電池を外して10秒くらい待つとカード無しで起動できる(普通のSDならカードありでも起動するでしょうが)ことが確認できました。
    他の機種でも電池を外せば復活するのかはわかりませんので、ご注意を。
  5. 起動後の操作
    CHDKの拡張機能の設定画面を出したり、スクリプトを起動したりするには「FUNC.SET」を押しながら「ズーム拡大(つまり右)」の操作をします。そうすると画面下に<ALT>表示がでますので、この状態で「MENU」を押すと拡張機能のメニューがでます。<ALT>のままシャッターを押すとスクリプトが動作するようですので、通常の撮影画面に戻るには、再度「FUNC.SET」を押しながら「ズーム拡大(つまり右)」の操作が必要です。

使い方は他のページにゆずりますが、いまのところInterval撮影に必要なスクリプトがうまく動作しません・・・・。
ベータ版だからでしょうか・・・・?

commi(GUIシリアルターミナル)をインストールしてみた

最近、仕事でリバースエンジニアリングっぽいことをやっています。相手がUARTなのでFT232Rベースのシリアルコンバータを接続してごにょごにょやっているのですが、Linuxでマイコン開発をしていると結構困るのがシリアルターミナルプログラムです。Windows環境だとTeraTermという鉄板ターミナルプログラムがあるのですが、Linuxではこれまでいいターミナルプログラムが見つけられず、screen コマンドの引数で /dev/ttyUSB0 などを指定して使っていました。しかしながら、なにぶん通信条件の設定等が面倒です。・・・で、調べていたら見つかったのが commi というQtベースのGUIのシリアルターミナルプログラムです。

オリジナルのプロジェクトページは http://commi.berlios.de/ のようです。で、ページを覗いてみると、CuteComというプロジェクトから fork したようなのですが、画面イメージを見ると、 commi の方が自分の好みに合いそうです。

早速ソースを http://sourceforge.jp/projects/freshmeat_commi/ から取ってきて、LinuxMint11(64bit)環境で展開、

$ ./configure
$ make 
$ sudo make install

であっさりインストールできました。起動は /dev/ttyUSB0 のアクセス権の関係から、

$ sudo commi

で自分は起動してます。

設定のしかたがTeratermに比較的近いので気に入っています。

PIC32MXで7segLEDを駆動してみた

続いて、PIC32MXで7segLEDを点灯してみました。

使用したのは4桁のカソードコモンの7セグメントLEDです。

回路は各桁のSEGMENTのA~G、DPをポートBのbit4~10、bit11に100Ωの抵抗を介して接続、各桁をデジタルトランジスタDTC123ESAを介してポートBのbit2,bit3、ポートAのbit2,bit3で駆動しています。

ダイナミック点灯の処理は割込みを1ms周期でかけて、1msごとに点灯する桁を変更しています。

表示している内容は0.1秒単位のストップウォッチ風の何かです。(単にカウントアップしているだけ)

さすがに28pinのDIPマイコンだとこれだけでポートを12本も使ってしまいます。PIC32MX120F032B(PIC32MX120F016BやPIC32MX220F032Bも同じ)は電源・GND関係だけで6本、さらにデバッガで3本の端子を使ってしまいますので、ちょっと苦しいかもしれません。

なお、デフォルトではJTAGやセカンダリオシレータがイネーブルになっているようで、使えない端子があります。それを解決するために、15行目に

#pragma config JTAGEN = OFF, FSOSCEN = OFF

という記述を入れて、JTAGやセカンダリオシレータを禁止しています。

なお、例によって役に立たないソースを置いておきます。→7seg駆動のソース

あ~、コメントは直し忘れていますので、無視してください。^^;

PIC32でLチカ(別の方法)

待ちループ、割り込みで点滅するLチカを紹介しましたが、MIPS CPUの場合には別の方法の時間待ちも可能です。
MIPS CPUの場合にはCPUの中のCP0(CoProcessor 0)というのがあって、その中にCOUNTレジスタというレジスタがあります。このレジスタはCPUコアの周波数の1/2の周波数でカウントアップしていきますので、CPUコアの周波数がわかっていれば、時間待ちに使うことが可能です。

#define SYS_FREQ (40000000L)
void foo(int index)
{
 register int i,j;
 i=_CP0_GET_COUNT();
 j=index;
 while(_CP0_GET_COUNT()-i<j);
}
int main(void)
{
<途中略>
while(1){
 foo(SYS_FREQ/20);
 mPORTAToggleBits(BIT_0);
 }
return 0;
}

本来、CP0のレジスタ読み出しには専用命令(mfc)が必要なのですが、コンパイラにはじめからマクロ定義が用意されているのでこんな感じで使えます。この例は100ms待ってLEDを反転させます。このレジスタには書き込みもできますが、基本的に読み出し専用で使います。読み出し専用で使えば複数のタスクでも共有できるからです。ただし、40MHz動作の場合には200秒程度でカウンタが1周しますし、上記の使い方だとその半分で正常に動作しなくなりますので要注意です。

ソースリストはこんな感じです→CountレジスタでLチカ

このレジスタは特定の区間のCPUの処理時間などの計測にも使えるので結構便利です。デバッガでCPUを停止させるとこのレジスタも停止するので、ブレークポイントを2箇所設定してそれぞれでこのレジスタを見れば処理時間がわかります。

PIC32MXの動作周波数を確認してみる

Lチカは動いたものの、結局何MHzで動作しているのかよくわからなかったPIC32MXですが、実際の動作周波数を調べてみます。

方法はいろいろありますが、知りたいのはプログラムの実行速度なのでデバッガの表示と実際の速度から推定する手段をとってみます。

まず、ループで時間待ちするプログラムのコードに着目します。

void foo(int index)
{
 register int i;
 for(i=0;i<index;i++);
}
int main(void)
{
 <途中略>
while(1){
 foo(100000);
 mPORTAToggleBits(BIT_0);
 }
return 0;
}

ソースからは1回の点灯期間/消灯期間の間にfoo()という関数が10万回ループすることがわかります。ループ以外の時間はほとんど無視できると思われるのでループに着目します。

デバッガでプログラムをいったんスタートしてブレークし、Disassembly Listingを表示しながらアニメーション実行をさせると、

の赤い四角で囲った部分が「for(i=0;i<index;i++);」のループ内であることがわかります。実際には、最後のbne命令はDelayed Branch命令なので、その次のnopも実行しているはずです。また、ループ内にはlw命令が入っていて、メモリからのリードサイクルが発生することになりますが、頻度は低いのでここではそれが速度の制約にはおそらくならないでしょう。
となると、1ループで5命令を5clkかけて実行することになります。つまり、foo()関数では時間待ちとして約50万clkサイクルを要することになるわけです。

一方で、runモードで実際の実行時間を計ってみると、

H区間/L区間ともに約75msであることがわかりました。ここから計算すると、50万clkサイクルが75msなので、75000000ns/500000=150ns=6.67MHzということになってしまいました。

どうやらconfigビットの設定がおかしいようですので、調べていくと、#pragma config の設定はMPLAB IDEの「Help」→「Topics」→「Language Tools」→「PIC32MX Config Setting」の中にあることがわかりました。

そこで、これを参照してConfigの設定を

#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_2, FWDTEN = OFF
#pragma config POSCMOD = OFF, FNOSC = FRCPLL, FPBDIV = DIV_2

と修正したところ、H区間/L区間ともに約15msになりました。計算すると、1サイクルが30ns=33.3MHzということになりました。
ちなみにFPLLODIV = DIV_1 のままでは暴走してしまいました。まあ、66.6MHzとなるとしかたないでしょう。

こんどはConfigの設定を

#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_2, FWDTEN = OFF
#pragma config POSCMOD = OFF, FNOSC = FRC, FPBDIV = DIV_2

と修正すると、内部オシレータ(8MHz)が直接SYSCLKとして使用されるはずですが、H区間/L区間はともに約75ms=6.67MHzに戻りました。

ここまでの結果から考察すると、1ループが5clkで回っているのではなく6clkになっていると考えると辻褄が合うようです。
(75000000ns/600000=125ns=8MHz、15000000ns/600000= 25ns=40MHz)

そこで、「Project」→「Build Option」→「main.c」でCategoriesをOptimizationを選択して、最適化を「0」から「s」に変更してみます。

すると、青の部分をみるとわかるように関数foo()の呼び出し自体が削除されてしまいました。orz・・・
この状態でリアルタイム実行させてみると、370~380nsでトグルしています。これは125nsの3クロック分、ということなのでしょう。 Configの設定を「FNOSC = FRCPLL」に変更すると70~80nsのトグルになりましたので、こちらも25nsの3クロック分、赤で囲んだ部分のループ(Delayed Branchで実行されるnopを含めて3clk)ということであっていそうです。

修正したLチカプログラムをアップロードしておきます。

  • ループでLチカ
    100万回ループで150msの待ち時間を作って、0.3秒周期でLEDが点滅します。
    ただし、最適化をかけてしまうと待ち時間そのものがなくなってしまいます。
    <追伸>SYS_FREQの定数定義が間違っていました(直し忘れ)。修正していませんのでご注意を。
  • 割り込みでLチカ
    タイマー割り込みで100ms周期(1秒間に10回) でLEDが点滅します

いずれもCPUは40MHz動作(SYSCLKは40MHz、PBCLKは20MHz)です。