Translate

ページ

2016年3月11日金曜日

LabTool を Raspberry Pi2B の Raspbian Jessie上でコンパイルする

 簡易オシロLabToolを時々使っていますが、せっかくRasPi2に綺麗なモニタもつながったので、PC無しで使えると便利(?)と考えました。

ところが、ネットで調べるとゲーマニウムさん曰く、最新版のRaspbian Jessie 4.1をはじめ、Raspbian Wheezy 3.18以降動かないとのこと。

しかし、よく読むとバイナリで配布しているものを試したということ。LabToolはソースも配布していますので、手順を読んでコンパイルしたところ動くものが出来たようです。



 以下に手順をまとめます。と言っても、ほとんどオリジナルの手順をなぞっただけですが...



    バイナリ配布版の確認

    • バイナリ配布版(2014-04-28版)を使用したところ、LabToolアプリ自体は起動するのですが、LabToolをUSBポートに差し込んでもアプリ側で認識されません。確かに動作しません。
      • その後、バイナリ配布版の動かない原因はファームウェア操作用のツールの実行権限が落ちていることであるこちが分かりました。(こちら参照)というわけで、以下は本当に趣味&勉強用となってしまいました…
    • なお、標準ではRasPiのUSBバスパワー供給能力は不足しますので、電源アダプター付のUSBハブ経由でLabToolをつないでいます。


    準備するもの

    • Raspbian Jessie 4.1 のインストールされたRaspberry Pi
    Raspbery Pi 2Bを使いました。(初代のモデルA以外は512MB以上積んでいるので使用可能だと思います。)
    あらかじめsudo apt-get update : sudo apt-get upgrade して最新版にしています。
    8GB以上のmicroSD/SDHCが必要です。
    sudo raspi-configコマンドの Expand Filesystem を行って、カード全体をRaspberry Piで使える状態にする必要があります。 
     インターネットへアクセスできる環境が必要です。
    言語環境はデフォルトのen_GB.UTF-8としました。(特に必須ではありませんが、参考にした手順が英語なので、合わせて作業しました。)
    • 1024x768以上の表示環境(モニタ又はX-Window server)
     コンパイル時に統合開発環境Qt Creatorを使います。XGA以上の解像度が無いと画面に収まりません。(設定でどうにかなるのかもしれませんが、Qtで開発環境を整備することが目的では無いので、深追いはしません。)
     Qt CreatorはGUI環境となりますので、対応したキーボードと対応したポインティングデバイス(マウス、タッチパッド)が必要です。
    • 電源アダプター付のUSBハブ
    標準ではRasPiのUSBバスパワー供給能力は不足しますので、電源アダプター付のUSBハブ経由でLabToolを接続しています。(config.txtにバスパワー電流増強のおまじないを書けば不要に出来る場合もあるようです。)


    参考にした手順


    LabToolアプリビルド完了までの記録

    • コンパイルに必要な開発環境関係パッケージをインストール
      (所要時間20分ほど)
    $ sudo apt-get update
    $ sudo apt-get install git libudev-dev libtool automake qt-sdk
    • libusbx 1.0.17をコンパイル、インストール
      (所要時間数分)
    $ mkdir ~/projects
    $ cd ~/projects
    $ wget http://sourceforge.net/projects/libusbx/files/releases/1.0.17/source/libusbx-1.0.17.tar.bz2/download
    $ mv download libusbx-1.0.17.tar.bz2
    $ tar -xf libusbx-1.0.17.tar.bz2
    $ cd libusbx-1.0.17
    $ ./configure
    $ make
    $ sudo make install
    • github上のlabtoolソースレポジトリをローカルに複製(ソースダウンロード)
    $ cd ~/projects/
    $ git clone https://github.com/embeddedartists/labtool.git

    •  先ほどコンパイルしたlibusbxをlabtoolソースツリー上にコピー
    $ cp ~/projects/libusbx-1.0.17/libusb/.libs/libusb-1.0.a ~/projects/labtool/app/libusbx/Linux/ 
    • Qt Creatorのコンパイル環境整備

      • GUIで「Menu」-「Programming」-「Qt Creator」 又はコマンドラインから「qtcreator」を起動
      • 「Help」-「About Plugins」を開く
      • 「Device Support」の下の「Remote Linux」オプションのチェックを外し、右下の[Close]をクリックする
      • 一旦QtCreatorを終了する

        • Qt Creatorを再度起動する
        • 「Tools」-「Options」を開き、「Build&Run」を開く
        • 「Compilers」タブを開き、「Add」ボタンを押し「GCC」を選択する。コンパイラパスに「/usr/bin/arm-linux-gnueabihf-gcc」を指定し、[Apply]をクリックする

        • 「Kits」タブを開き、デスクトップを選択する。Compilerパラメータ欄を数回クリックすると表示が空白からGCCに変わる。Qt versionのパラメータ欄も数回クリックして、自動設定される値とする。設定のCompilerにGCC、Debuggerに/usr/bin/gdbが設定されていることを確認し[Apply]を押す


        • [OK]を押しOptions画面を閉じる 

      • LabToolをコンパイルする

        • Qt Creatorを起動する
        • 「FIle」-「Open File or Project」を開き、/home/pi/projects/labtool/app/LabTool.proを選択し[Open]をクリックする
        • 「デスクトップ」にチェックが入っていることを確認し[Configure Project]をクリックする


        • ビルドモードがDebugになっていることを確認後、ビルドをクリックする(Releaseでもコンパイル可能です。)
          (所要時間15分ほど)



        • ビルド後の実行ファイルLabToolは、/home/pi/projects/labtool/build-LabTool-unknown-Debug/の下に格納されています。(Releaseでコンパイルした場合は/home/pi/projects/labtool/build-LabTool-unknown-Releaseの下です。)

      ファームウェアのコンパイル

      • LabToolアプリは、アプリ本体とは別に、LPC Link2に送り込むfirmware.binを必要とします
      • バイナリ配布パッケージ中のfirmware.binがそのまま使えるようですが、せっかくなのでこちらのコンパイルもやってみました
      • ここまでの作業が完了していれば、ファームウェアのソースが/home/pi/projects/labtool/fwの下に、コンパイル手順書が/home/pi/projects/labtool/fw/COMPILE.mdに格納されています

      • まず、gcc-arm-none-eabi環境をインストールします
        (所要時間5分ほど)
      $ sudo apt-get install gcc-arm-none-eabi

        • 続いて、コンパイルを実施します
          (所要時間2分ほど)
        $ cd ~/projects/labtool/fw
        $ make

        • ファームウェアは/home/pi/projects/labtool/fw/firmware.binとして保存されます


          /etc/udev/rules.d/10-ea-labtool.rules

          • もしまだ存在しない場合は以下の内容を書き込みます
          # Allow group plugdev to access the LabTool Hardware (1fc9:0018)
          ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="0018", MODE="664", GROUP="plugdev"

          # Allow group plugdev to access the LPC DFU device (1fc9:000c)
          ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="000c", MODE="664", GROUP="plugdev"


          動作確認

          • コンパイル完了した実行ファイルLabToolとファームウェアfirmware.binを同じディレクトリにコピーします
          $ mkdir ~/Desktop/LabTool2
          $ cp ~/projects/labtool/build-LabTool-unknown-Debug/LabTool ~/Desktop/LabTool2/
          $ cp ~/projects/labtool/fw/firmware.bin ~/Desktop/LabTool2/
          $ cp -pr ~/projects/labtool/tools ~/Desktop/LabTool2/
          $ chmod u+x ~/Desktop/LabTool2/tools/dfu-util-0.7-binaries/linux-armel/dfu-util

          • 起動
          $ cd ~/Desktop/LabTool2
          $ ./LabTool



          •  Users Manual記載のQuick Start Guideに沿って動作テストを行いました。prjファイルはWindows版のパッケージに含まれていたdemo.prjをコピーして使いました。(格納パスはC:\Program Files\Embedded Artists\LabTool\)

          うまく動いたようです。良かった! 

                2016年3月8日火曜日

                LabTool on Raspberry Pi2B with Raspbian Jessie

                再コンパイルとかいろいろやっている間に気づいたのですが、単に
                http://www.embeddedartists.com/products/app/labtool.php
                からダウンロードできるlabtool_raspi_2014-04-28.tgz を手順に沿ってインストールした後、
                chmod u+x /home/Pi/Desktop/LabTool/tools/dfu-util-0.7-binaries/linux-armel/dfu-util
                とするだけで動きそうな気がする....?

                2016年2月28日日曜日

                Raspberry Pi2 B : 7inch toucscreen や IGZOパネルやら...

                メモメモ
                新旧情報が入り乱れているので、2016-02-28現在の最新情報だけまとめる。
                細かい話は抜き

                使用Raspberry Pi

                DOWNLOAD&標準的なインストール手順

                  • ZIPファイルをダウンロードし展開
                  • SDカードをSD Formatter 4で初期化
                  • ダウンロードしたZIPファイルの全中身をSDカードにコピー
                  • SDカートを差し込んでRasPiを起動
                  • 画面に従ってインストール

                  • ZIPファイルをダウンロードし展開
                  • Win32DiskImagerを使ってイメージを書き込み

                公式7inchタッチスクリーンの場合

                • 仕様
                  • これ
                  • フレキシブルケーブル接続
                  • 解像度は800x480


                • 使用ケース
                  • スイッチサイエンス(adafruit製) (このケースは上下がひっくり返る構造となっているので、後述の通りconfig.txtを編集して反転させる必要がある)

                • NOOBS
                  • インストーラ起動する
                  • ただし、上のスタンドは表示が上限反転となる
                  • インストール中の画面は下が切れる
                  • インストール後、/boot/config.txtにlcd_rotate=2 を追加して上下を合わせる

                • RASBIAN
                  • 普通に起動する
                  • 上下はやっぱりひっくり返るので、NOOBS同様に/boot/config.txtを直す

                IGZO液晶パネル

                • 仕様
                  • HDMI接続
                  • 解像度は1920x1200(フルHD)



                • NOOBS
                  • NOOBS経由のインストールは現在お勧めしません...
                  • インストーラの画面が全く表示されない
                  • 他のモニタ(上述のタッチスクリーンや通常のPC用モニタなど)を使ってインストールする
                  • RASPBIANを選択した場合は、次の通り/boot/config.txtを編集する
                  • 注: 2016/02/28現在、rpi-updateするとGraphical インストール画面が表示されなくなってしまいます。

                • RASPBIAN JESSIE
                  • /boot/config.txtをこちらの内容と置き換えるか、”# 以下はオリジナル”という行までを追加する
                    • 液晶の向きにより4つの設定が書かれており、1つ(フレキシブルケーブルが下となった縦長)だけ有効となっている
                    • フレキシブルケーブルを左とする設定を生かしたかったので、そのように変更した
                    • 当該部分(framebuffer_width=1920, framebuffer_height=1200は変更可能。1280x800位が使いやすそう)

                両方切り替えて使いたい場合

                • SDメモリかモニタケーブルを差し替えて両方使いたい場合は。/boot/cofig.txtを各モニタ向けに数パターン用意しておき切り替えて使うと良い
                  • /boot/config.txtは、SDメモリが読み書きできる環境があれば、PCからも編集や置き換えが可能です
                • 両方同時に使う方法があるのかどうかは知りません。

                うまく行かない場合


                • 既存のRaspberry Piに使う等で環境が古い場合、igzoパネルはうまく表示できない場合があるようです。
                  • apt-get update, apt-get upgrade, rpi-updateを実行するとうまく行くという情報がありますが、うちでは逆に起動後のXの起動に失敗するようになってしまいました。(emerge+さんブログ参照)

                GL Driver


                • raspi-configのAdvanced OptionでGL Driverをonにすると以下が起こります。
                  • 公式7inchタッチスクリーンは電源投入直後のレインボーの正方形のまま画面が変化しなくなります。
                  • IGZOパネルの場合は、framebuffer_width, famebuffer_heightの指定が効かなくなります。
                • SDカードのconfig.txtにdtoverlay=vc4-kms-v3dという行が追加されていますので、これをコメントアウトするか、消去すると設定を無効化することができます。
                  • 操作可能なら、sudo vi /boot/config.txt
                  • 操作できない場合は、SDカードをPCにつないで編集できます

                2016年2月23日火曜日

                mbed TY51822r3 を mbed HRM1017と差し替えて使う


                (大した話ではありません。自分向けの備忘録みたいなものです。すいません。)

                TY51822r3発売!!

                スイッチサイエンス社からBLE用の新しいmbed TY51822r3が発売です。
                本製品は、mbed HRM1017の後継製品と位置づけられており、比べると、以下の特徴があります。
                • 搭載しているnRF51822チップのリビジョンがr2から最新版のr3に変更
                • RAMが16kBから32kBに増量(今までメモリ不足で動かなかったnRF5 SDK for IoTが動くようになるそうです)
                • 搭載クリスタルなどは違いはありますが、動作は同じ16Mhz
                • パッケージ外観はほぼ同じ。長さ、高さが少し小さくなっている。
                • さらにSoCからのピンの引き出しがmbed HRM1017と互換なので、ハードウェア的な置き換えが容易
                • 価格はmbed HRM1017より少し安い(5400→4730)
                たまたま、スイッチサイエンスのオープンハウスで先行購入することが出来ましたので、少し試してみました。

                mbed HRM1017と差し替えて使う

                mbed TY51822r3はmbed HRM1017とハード的なピンの割り当てが同じであり、ハードウェア上のスペックダウンも無いため、ファームウェアさえ適切に作り直せば、mbed HRM1017と差し替えて使うことができます。

                ここで、注意すべきことがあります。それは、ピンのハード的な割り当ては同じですが、mbedオンラインコンパイラ上の機能の割り当てが両社で異なっているからです。

                mbed.org上の両社のPinOut図を見比べて見ましょう。

                まず、mbed TY51822r3はこちらとなります。

                mbed HRM1017はこちらとなります。

                Serial,SPI1,Analogin等は機能の割り当てが同じですが、SPI0, I2C,LED#, BTN#等が異なっていることが分かります。

                今までmbed HRM1017を使ってきたユーザにとっては、まずmbed HRM1017向けのプログラムをmbed TY51822r3で動かしてみたいところだと思います。

                ピン割り当てが同じであるため、機能名称ベースのenum定義をピン番号に変更すると、同じプログラムが両方で動くようになります。(バイナリはターゲット毎にコンパイルして作る必要があります。)

                例えば、
                TMP102      healthThemometer(I2C_SDA0, I2C_SCL0, 0x90); 
                という行があったとすると、
                TMP102      healthThemometer(p22, p20, 0x90); としたり、

                DigitalOut  oneSecondLed(LED1); 
                DigitalOut  advertisingStateLed(LED2);
                を
                DigitalOut  oneSecondLed(p18); 
                DigitalOut  advertisingStateLed(p19);
                となります。

                mbed HRM1017のピン配置図を見ながらこれを行っても良いのですが、実は一度mbed HRM1017をターゲットに選択してコンパイルすると、該当変数部分をクリックすると、pXXというピン名称enumがソースの枠内右上に表示されるようになります。これを使って、ピン名称に変換すると効率よく変更作業が出来ます。

                この辺を覚えておくと、mbed TY51822r3をmbed HRM1017と置き換えて簡単に使えるようになります。

                ちなみに、mbed TY51822r3のピン番号と機能の割り当ては、NordicのnRF51-DKと合わせたそうです。世界的には、nRF51-DKのユーザが多いわけで、mbedやSDK上のnRF51822向けのプログラムはかなりのものがnRF51-DK向けに作られています。それらが、そのまま使えるわけです。


                2016年2月20日土曜日

                nRF52832 + WS2812B その5: I2S で制御

                (動画、BGMあるので注意。うるさくてすいません。)

                I2SでWS2812Bをドライブ

                これまでやってきたSPIを使う方法を振り返ってみます。
                nRF52のSPIベースのeasyDMAでは1度のDMA伝送で送れるバッファのサイズが256バイトだったので、約20個ずつ連続して信号を送り出す必要がありました。しかも本来の仕様では1.25μ秒で送るべき1ビット分のデータを1μ秒で送っているためか、電源電圧が下がった時などにうまく制御しきれずに後半のLEDの幾つかが明るい色で光りだすという現象が発生していました。
                まぁ、なんとか制御してみたものの、少し行き詰りを感じていました。

                そこへ、I2SでWS2812Bをドライブしているよ!って話を聞きました。



                nRF52832にも、easyDMAを使ったI2Sが備わっています。
                調べてみると、次のことが分かりました。
                • 伝送レートの設定が幅広く備わっており、3.2MHzのビットレートが作れる。これは、4ビットが1.25μ秒となり、WS2812Bの仕様に合致したシグナルが生成可能(Ref. CONFIG.MCKFREQ)
                • easyDMAのサイズ指定バッファが最大16384あり、LED 1365個分のデータを一気に送ることができる(SPIの時のように分割する細かく分割する必要がない。Ref. RXTXD.MAXCNT)
                実際にやってみたら、SPIをだましだまし使った時よりも処理も安定し、制御が乱れることがなくなりました。プログラムもシンプルです。

                WS2812Bドライブ方法

                WS2812Bのドライブ信号は、次の通りです。

                3.2MHzの信号の1ビットは312.5n秒ですので、 
                0codeは312.5*1のHと312*3のLを組み合わせて、
                1codeは312.5*3のHと312*1のLを組み合わせて、
                作成することができます。

                レベル変換IC(TXB0104)

                nRF52832のGPIOは3.3V, WS2812Bのシグナルレベルは5Vですので、レベル変換が必要です。

                SPIでドライブしていた時に調子の良かったレベル変換IC TXB0104を引き続き使いました。製品はこちら。双方向である必要性は無いので、もっと良いソリューションがあると思います。


                ハードウェア概要

                LEDテープを味付け海苔の空き容器に巻きつけています(前回からまき直し、一周17個です。4mのLEDテープは先に行くほど電圧が落ちて輝度が落ちるので、縦方向に電源のバイパス配線を追加しています)。
                • ボードはnRF52 DK
                • P0..25 をレベル変換IC(ブレッドボード上のTXB0104) ICを使ってLEDテープDinへ
                • 電源はLED用に別途準備必要です。
                  • 試験段階は20Aのスイッチング電源、調整完了後モバイルバッテリー(5V2A)利用



                その後、バッファはシールド形式のブレッドボードに搭載しnRF52-DKに被せました。
                撮影時の状態は以下の通り。



                ソフト概要


                今回作ったプログラムはgithubに載せました。
                https://github.com/takafuminaka/nRF52832/tree/master/i2s_ws2812b_demostration_planB
                (https://github.com/takafuminaka/nRF52832.git)

                nRF5 SDK 11.0.0-2.alpha_bc3f6a で動作させています。

                W2812Bの制御に必要なルーチンはws2812b_drive, i2s_ws2812b_driveディレクトリに集約しています。

                main.cで、led_array_work配列にRGBの各輝度を設定して、更新処理を繰り返し呼び出しています。

                処理の流れ

                • 処理全体はデモパターン3種の繰り返し
                • 各デモは次を設定時間ループで実行
                  • led_array[*].green, led_array[*].red, led_array[*].blueに各要素の輝度(0~255)を設定
                  • ws2812b_drive_current_cap(led_array_work, NUM_LEDS, CURRENT_LIMIT); // 電流制限のための輝度調整
                  • ws2812b_drive_dim(led_array, NUM_LEDS, dim); // フェードイン、アウトの輝度調整
                  • i2s_ws2812b_drive_xfer(led_array, NUM_LEDS, I2S_STDO_PIN); // LED更新
                  • nrf_delay_ms(DELAY_MS); // 次の更新までの待ち
                • LED更新処理は、ハードウェアの初期化、転送バッファメモリの確保、実際の伝送、伝送完了後のハードウェアの終了処理をすべて1つの関数にまとめました。通常の利用では、この方が使いやすいと思います。
                • ただし、毎回メモリの確保・開放を行うなど無駄が多いので、効率や処理速度を重視する場合は、当該関数の処理を展開してください。
                • 電流制限はWS2812B の消費電流調査のデータを参考に作成しました。上記動画中、USB電流計が電圧と電流を交互に表示しています。1.5A制限のプログラムで1.3A位に収まっていますので、うまく機能しているようです。

                調整パラメータ

                ファイルproject.h

                #define NUM_LEDS (240) // Number of LEDs (LED総数)
                #define MAX_INTENSE (64) // Max intense of random LEDs for "flashing_random" (flashing_random用のランダム色LEDの最大輝度)
                #define MAX_INTENSE2 (255) // Max intense of "shooting start" running bright LEDs for all demos.
                #define MAX_INTENSE3 (64) // Max intense of "rainbow LEDs" for "running_rainbow" and "running_rainbowv" demos.
                #define MIN_INTENSE (1) // Minimum intense of randaom LEDs for "flashing_random" (flashing_random用のランダム色LEDの最小輝度)
                #define ROW_SIZE (17) // Count of LEDs for each line (1巻き分のLEDの数)
                #define CURRENT_LIMIT (1500) // Current limit of LEDs (mA) (総電流制限値)
                #define FADE_IN_MS (6000) // Fade in/out period (フェードイン・アウトの秒数)


                ファイルmain.c

                新しいデモを追加する場合は、demo_list_t demo_listに定義を追加してください。
                各デモは初期化処理、更新処理、終了処理を準備し、1回更新後の待ち時間(ms)、デモの継続時間(ms)、デモの更新処理の所要時間(継続時間調整用、ms)をパラメータ設定しています。


                2016年1月17日日曜日

                nRF52832 + WS2812B その4 : というわけで、ライブラリ化しイルミネーションっぽいの作ってみました

                安心してください!(電波)吹いてませんよ(^^♪

                先日の作品は実現性の確認のための酷い出来でしたので、ライブラリ化して作品作ってみました。
                演出は即興です。



                これまでの経緯もご覧ください

                注意!!電源について

                万が一真似してひ弱な電源を壊す人がいると恐いので、最初にこれを書いておきます。

                WS2812Bは最高輝度でドライブすると、1つ当たり約50mA消費します。
                今回使用した240個のLEDテープですと、12A近く消費する計算となります(購入元のスイッチサイエンス社調べで12.72A)。

                今回、私は試験段階で5V20Aの電源を用意して使用しました(秋月の5V 20A電源をケースに入れた自作品)。LED専門サイトの電源を使った方が簡単かもしれません。

                今回作成したライブラリには、LED設定値と消費電流の最大値(mA)を設定して呼び出すと、その電流値を超えた場合に、全体を暗くして最大値を超えない値に設定しなおすサブルーチンを準備しています。(http://aid.her.jp/uratan/led/index.html#currentを参考にしました。uratanさん、すばらしい!)

                void ws2812b_driver_current_cap(rgb_led_t * led_array, uint16_t num_leds, uint32_t limit);
                led_array : LEDの輝度データ配列
                num_leds : LEDの数
                limit : 電流制限値(mA)

                ただし、このルーチンの効果に頼りすぎないで下さい。
                制御信号が乱れると、設定以上の輝度でLEDが光ることが結構あります。このような現象が発生した場合は、すぐにLED用の電源を切ってハードとソフトを確認して下さい(配線を伸ばそうとしたらいきなり高輝度でちらつき、消費電流がいきなり通常の5倍位になって慌てたことがあります)。

                今回の作品は、十分動作確認を行ったのち、モバイルバッテリー(5V 2A供給タイプ)やPCのUSB端子から電源供給して動かしています(実測で0.5A以下)。

                また、激しくドライブしたときに、LEDテープの後ろの方が追随しなかったり、異常点灯することがあります。
                どうも、カスケードしている電源の電圧が揺らいでいるのではないかと思っています。
                電源を供給するポイントを増やしてあげれば、安定動作するのではないかと思います。

                ハードウェア概要

                LEDテープを味付け海苔の空き容器に巻きつけています(一周約19個です)。
                プログラムはこちらに公開しています。

                • ボードはnRF52 DK
                • P0..25 (SPI0のMOSIピン)をレベル変換IC(ブレッドボード上のTXB0104) ICを使ってLEDテープDinへ(ブレッドボードには、比較試験に利用したFET, 74LS00も乗っています)
                • 電源はLED用に別途準備必要です。
                  • 試験段階は20Aのスイッチング電源、調整完了後モバイルバッテリー(5V2A)利用




                ソフト概要


                今回作ったプログラムはgithubに載せました。
                https://github.com/takafuminaka/nrf52832-spi_ws2812b_flashing_random

                nRF5 SDK 11.0.0-2.alpha_bc3f6a で動作させています。

                W2812Bの制御に必要なルーチンはws2812b_driverディレクトリに集約しています。

                main.cで、led_array_work配列にRGBの各輝度を設定して、更新処理を繰り返し呼び出しています。

                処理の流れ

                • spi_buffer_t spi0_buffer; // ws2812b制御用のSPIバッファの定義
                • alloc_spi_buffer(&spi0_buffer, NUM_LEDS); // SPIバッファの初期化
                • rgb_led_t led_array_work[NUM_LEDS]; // 輝度設定用LED配列の準備
                • 以下をループで実行
                  • led_array[*].green, led_array[*].red, led_array[*].blueに各要素の輝度(0~255)を設定
                  •  ws2812b_driver_current_cap(led_array_work, NUM_LEDS, CURRENT_LIMIT); // 電流制限のための輝度調整
                  • ws2812b_driver_xfer(led_array_work, spi0_buffer, spi0); // LED更新
                  • nrf_delay_ms(DELAY_MS); // 次の更新までの待ち


                調整パラメータ
                ・DELAY_MS                 (5) LEDの更新待ち時間(m秒)(小さいほど激しく更新)
                ・NUM_LEDS (240) LEDの数
                ・MAX_INTENSE (16) 暗いLEDの最大輝度
                ・MAX_INTENSE2 (255) 明るい流れる効果のLEDの最大輝度
                ・MIN_INTENSE (1) 各LEDの最低輝度
                ・DECAY_STEP (30) 明るい流れるLEDの更新毎の減衰ステップ
                ・PRAB_FLASH (5000) 明るい流れるLEDの発生頻度(確率の逆数に比例。小さくすると出現頻度が上がる)
                ・ROW_SIZE (19) 一行当たりのLEDの数
                ・STEP_SRIDE1 (-(ROW_SIZE+1)) 明るい流れるLEDの更新毎の移動ステップ1
                ・STEP_SRIDE2 (-(ROW_SIZE-1)) 明るい流れるLEDの更新毎の移動ステップ2
                ・CURRENT_LIMIT (1000) 最大電流制限値 

                * 当初の公開版から、拡張しました。デモンストレーションを複数用意し、時間差で切り替えるようにしました。また、SPIを8Mhzで動かすように変更しました。

                今後の予定

                制御ルーチンについて以下を改良していきたいと考えています。
                • ルーチン名、構造体の名称の調整(ws2812b_drv_*に統一するなど)
                • 割り込み処理を工夫し、伝送終了まで待たずにメインルーチンに戻るようにする
                • 3系統のSPIをすべてWS2812B点灯に使えるようにする
                • (日本国内で電波を吹けるnRF52モジュールがにゅうしゅできたら)BLE通信と連携しながらドライブできるようにする



                2016年1月11日月曜日

                nRF52832 + WS2812B その3: nRF52832での設計

                nRF52832での基本設計

                それでは、これと同様のことをnRF52832で実現するにはどうしたら良いでしょうか?Objective Production SpecificationのSPIMのセクションを読んでみます。
                 
                 まず、先例でやっているような10bitモードのSPIは使えないようです。8bit固定です。
                また、 nRF52832ではSPIのクロックも先例のような3MHzという設定はなく、その前後で使えるのは1MHz, 2MHz, 4MHz, 8MHzです。

                 先ほどのタイミングチャートから、
                0codeの場合、Hiを250~550ns, Lowを700~1000ns,
                1codeの場合、Hiを700~1000ns, Lowを300ns~600ns
                を作る必要があります。さらに、基本周期は1250ns (800kHz)となっています。
                実は、これに従った信号を作ろうとすると、結構プログラムが複雑になってしまいます。

                 例えば、4MHz(250ns単位制御)でやろうとした場合、
                0codeにHiが1~2ビット、Lowが3~4ビット、
                1codeをHiが3~4ビット、Lowが2ビット、
                となり、1ビットの送信に最低5ビットが必要になります。

                 8MHz(125ns単位制御)でやろうとした場合、
                0codeにHiが2~4ビット、Lowが6~8ビット、
                1codeをHiが6~8ビット、Lowが3~4ビット、
                となり、1ビットの送信に最低9ビットが必要になります。

                1バイトは8ビットなので、これではデータの生成が非常に面倒になります。

                 ただ、http://aid.her.jp/uratan/led/の記載では
                • 432nsec までのパルスは '0' として判別される。 (132nsec のパルスでも '0')
                • 536nsec 以上のパルスは '1' として判別される。
                • DOUT 出力は判別された論理に従って新規のパルスが出力される。
                • その DOUT 出力においては、T0H=330nsec、T1H=660nsec である。
                • インターバル 6.7μsec 程度を境に Treset として判別され、 中継処理が中断される。    (しかしながら これは誤点灯になります)
                とのこと。

                 これに従うのであれば、
                4MHz(250ns単位制御)でやろうとした場合、
                0codeにHiに1ビット、Lowに3ビット、
                1codeをHiに3ビット、Lowに1ビット、
                とし、1ビットの送信にきりの良い4ビットを割り当てることが出来ます。

                 もう1つ、22個以上制御するときに限りますが、easyDMAによるSPIMで1度に送信できるのは256バイト(2048ビット)までということに注意が必要です。
                WS2812Bの1ビットに4ビットを使うと、1つのLED向けのデータ24ビットはSPIの96ビットとなり、一度に送れるのは21LED分のデータが最大となります。
                 これ以上のLEDを制御したい場合は、素早く次の伝送を行う必要があります。が、上記の通り6.7μsec以内に伝送が開始されなければなりません。
                実は、このタイミングが難しく、SPI伝送とSPI伝送の間に、現在丁度6.2μsecかかっています。最終データの再開ビットがゼロの場合、Lowが3ビット分、つまり750nsec(0.75μsec)がかかってしまい、結果6.95μsecのLowが発生し、中継処理が中断してしまいます。
                 これを解決するために、最後のデータをLSB側に寄せる必要があります。ただし、SPI伝送直後のMOSIがダラーんと残るので、最後のビットは0にする必要があります。
                 まとめると、0codeであれば通常0B1000を送るところを0B0010に、1codeであれば0B1110をそのまま送ります。

                 Labtoolで取得した波形は次のようになります。(今回からプローブ使用。10xで測定。)
                7μsec超えているので、苦しいですね。固体によっては、動かないかもしれませんね。だめだな時は、踏み込んで対応することにしましょう。













                ドライブ回路

                 nRF52 DKのVccは3.3V、WS2812BのVccは5Vですので、MOSI信号のレベル変換が必要です。
                今回、次の3つを試してみました。
                 ちなみに、元の波形は次の通り。


                MOS FET

                 2N7000を使って、こちらの回路を試してみました。
                動きましたが、波形はこんな感じです。動くには動きますが、遅延が大きくかなり悲惨ですね.....


                TTL (74LS00)

                丁度手元にあった74LS00をバッファとして使ってみました。2V以上をHiとみなすので、これでも3.3V系のシグナルを5V系に変換することが出来ます。
                 バッファは、NANDゲートをNOTとして2つ組み合わせています。新たに準備するのであれば、こちらを参考に最新のロジックICを用意するのが良いでしょう。
                 
                 波形は綺麗です。



                レベル変換IC(TXB0104)

                レベル変換IC TXB0104を使った波形です。製品はこちら。nRF52側の電圧が低くても安定して動作するので、準備できるのであれば、ここまで試した中では一番よさそうです。ただ、双方向である必要性は無いので、もっと良いソリューションがあると思います。


                サンプルプログラム

                 とりあえず、ここまでの試行錯誤をまとめ、240個のLEDテープを点滅させることに成功したプログラムをGITHUBに公開しました。といっても、easyDMAで点灯させることが出来ることを確認するだけのプログラムであり、データの自由度など何もない、汚くて恥ずかしいプログラムです。
                 もう少し使いやすく改良する予定です。

                (安心してください(^^♪電波吹いてません)