Translate

ページ

2016年1月11日月曜日

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

nRF52832での基本設計

それでは、これと同様のことをnRF52832で実現するにはどうしたら良いでしょうか?Objective Production SpecificationSPIMのセクションを読んでみます。
 
 まず、先例でやっているような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=330nsecT1H=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で点灯させることが出来ることを確認するだけのプログラムであり、データの自由度など何もない、汚くて恥ずかしいプログラムです。
 もう少し使いやすく改良する予定です。

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



2016年1月10日日曜日

nRF52832 + WS2812B その2 : nRF52832のeasyDMA

easyDMAについて

 当初、SoCの中に汎用のDMAユニットが存在していることをイメージしていました。実はそれは間違いの様でBlockdiagramにあるように、いくつかのハードウェアユニットがeasyDMAを内蔵しているということのようです。
 つまり、easyDMAを使ってWS2812Bを使うという場合、easyDMAを持ったユニットのどれかを流用しなければならないということです。

もう1つ悩ましいのは、タイミングチャートを見ると、SPI伝送後のMOSIの値が不定となっていることです。


これは、実験で確認したところ、次のことが分かりました。
  • SPI伝送終了直後、500ns程度最終ビットの状態が維持される。
  • その後、次のSPI伝送開始までのMOSIの状態はCPOLの値(SDKではSPIのモードとしてNRF_DRV_SPI_MODE_#を設定)に依存する。
    • CPOLが0の場合は、SPI伝送間のMOSIはHとなる。
    • CPOLが1の場合は、SPI伝送間のMOSIはLとなる。←WS2812B制御時はこれが必要
これらを考慮して、SPI伝送のモードとSPI伝送最終データのビット列を調整せねばなりません。つまり、モードとしてはNRF_DRV_SPI_MODE_1あるいはNRF_DRV_SPI_MODE_3を使用し、伝送最終ビットが0となるようにする必要があります。

 この辺の仕様外の挙動はSoCのリビジョンによって変わる可能性があるので注意が必要かもしれません。


SPI使用WS2812Bドライブの例

 WS2812B, DMA等で検索をかけると、SPIインタフェース用にDMAを持ったSoCでドライブする例がいくつか見つかりました。

要は、SPIの複数ビットのHi(1)とLow(0)を複数組み合わせて 0code, 1codeを実現しようというものです。
 
SPIMのeasyDMAを使えば、nRF52832でもWS2812Bの制御が出来そうです。

nRF52832 + WS2812B その1 : nRF52に関する情報

NORDIC Semiconductor Global Tech Tour 2015

もう1ヶ月ほど前の話になりますが、NORDIC Semiconductor社のGlobal Tech Tour 2015に参加してきました。

お目当ては、同社が2015年6月に発表したnRF52832に関する情報収集と参加者に配布された開発者向けボード(おそらく、これ→nRF52 DK)。

当日の内容は以下参照

nRF52 DK

nRF52 DKはいわゆる技適の取得は行われておらず、国内での販売も行われていません(Digi-Keyなどからの輸入は可能のようです)。
 ちなみにGlobal Tech Tourで配布されたDK搭載チップはEngineering B (QFAA-BA0)でした。ここで確認できるとおり、まだまだエラーが残っています。Errataのv1.1, v1.2が該当します。そういったことが気になる方は、量産版が出回るまで待った方が良いかもしれません。(ICのmarkingの情報はこちら参照。)



上記Global Tech Tourの直後に発表されたSDK Ver.11以降、nRF51とnRF52向けのSDKが統合され、nRF5 SDKとなりました。


easyDMA と WS2812B

先行のnRF51シリーズからの機能強化点の1つに、easyDMAを使ったI/Oや定型処理能力の強化(CPU負荷の低減)があります。

 その話を聞いているときに、ふと思い出したのが、家で眠っているWS2812Bを使ったLEDテープでした。フルカラーのLEDとして広く普及しており、バリエーションもいろいろあります
ドライブのタイミングが難しいため、CPUの負荷が高くなると聞いています。

 これのドライブにもしeasyDMAが使えれば、軽はずみなことを考えてしまいました。そこでいろいろ調べてみることにしました。

2015年8月20日木曜日

こて先温度計シールド+PSoC4 BLE PIONEER KIT

こて先温度計シールドI2C接続の小型LCD搭載ボード(3.3V版)
今度は(PSoCまつり2015以来積んであった)PSoC4 BLE PIONEER KITとを組み合わせて使って
こて先温度計を作ってみました。
(PSoCの勉強も兼ねた習作です。)



こて先温度計シールドの3.3V化


    プログラム

    • 作成したプログラムはこちらに置きました(PSoC Creator 3.2SP1にて作成)。
    • CapSense CSD スライダでコントラスト調整可能とした版←ボタン電池で使用する場合はこちらをご利用ください。
    • ノウハウ
      • PSoC Creatorで、sprintfにおける浮動小数点(%f)の取扱いがうまく表示されない問題に悩みました。PSoCにお詳しい中村様に助けて頂きました。
        • 原因1: デフォルトでリンクされる小さなlibcにおいて、浮動小数点対応を不足している。
          対策:浮動小数点対応のprintfライブラリを追加する。(参考)([Project]-[Build Settings]を開き、下図のようにARM GCCのLinkerセクションの”Use newlib-nano Float Form”を"Yes"に設定)
        • 原因2:デフォルトのヒープサイズが小さいため動作しない。
          対策:ヒープサイズを増やす。(参考)((ピン割り当てなどを設定する)*.cydwrファイルを開き、[System]タブを選択。下図のようにHeap Sizeを0x80から0x200に増やす。

      • これは、バッドノウハウのような気がしますが、SSピンはSPIMモジュール外、プログラムで直接制御しています。
        SPIMモジュールが一度に読み出せるのは16ビットまでの様子。こて先温度計シールドで使用しているMAX31855では32ビットを一度に読み出す必要があるので、32ビット分読み出すまでSSピンをLに保つために、このようなことをしています。

    感想など

    • PSoC初挑戦。mbed慣れしていたので、PSoC Creatorの世界観に慣れるまで苦労しました。
        • 当初、作成したコンポーネント名に対応したルーチン(API)が自動生成されることが理解できず、ドキュメント記載のAPIが使えないと悩みました。

    • 非力なマシンを使っていると、非常に効率が悪い(ローカルにコンパイラが動くため、さくさくコンパイラが出来る環境無いと辛い。mbedのクラウド環境は、ローカルマシンのCPUパワーが低くても結構実用になる)。

    • 初心者こそオシロスコープ、ロジックアナライザ必要
      • I2C液晶がうまく動かない時に、LABTOOLを使ってコツコツデバッグしました。これが無かったら、ギブアップしていたかもしれません。

    • SPIも初挑戦。前述のSSピンの制御以外は、こちらは前述のSSピンの制御以外は割とすんなり行きました。

    参考リンク



      2015年7月20日月曜日

      コテ先温度計シールド + Universal Embedded Board for LPC11U68)

      こて先温度計シールドUniversal Embedded Board for LPC11U68を購入
      これをI2C接続の小型LCD搭載ボード(3.3V版)と組み合わせてこて先温度計を作ってみました



      参考リンク


      • スイッチサイエンス コテ先温度計シールド
      • HAKKOのこて先温度計ページ(こて先温度計を使ったことが無い人は、メンテナンス情報を一通り目を通しておいた方が良い。測り方も丁寧に説明されている。)
      • 交換用センサー191-212
        • HAKKO e-shop
        • 店舗販売の例:斎藤機工秋葉原営業所 コテ先温度計を取り扱っている店なら置いているかと
        • その他通販(取り寄せになるところが多い)

      Arduino Uno3で使用


      余談:”ジグザグハック”or"Sneaky Footpinrts"

      • ピンヘッダ用のパターンが真っ直ぐではありません。これは”ジグザグハック”or"Sneaky Footpinrts"と呼ばれているテクニックで、手はんだ字のピンヘッダが傾きにくく、抜けにくくなるようです。参考リンクswitch sciencesparckfun 

      回路図を読む


      • 回路自体は3.3Vで動作(3.3VのArduino互換機で使用する場合は、SJ1とSJ2をショート
      • MAX31855はSPI動作
      • 使用しているピンは、3.3V(JP1-5)、GND(JP1-2,3)、MISO(JP3-5)、SS(JP3-3)、SCKC(JP3-6)、SDA(JP3-9)、SCL(JP3-10)

      Universal Embedded Board for LPC11U68で使えるか?

      • Universal Embedded Board for LPC11U68 に上記信号は出ているか?→出ている
      • IOピンの電圧は3.3Vなので、コテ先温度計シールドのSJ1とSJ2をショートして3.3V動作にする必要がある
      • USB UARTは使えない
      • シールドを被せるとRESET, ISPボタンに指が届かない。P2から信号を引き出して外部にボタンを設けた。(1:GND, 2:ISPボタン, 3:RESETボタン)
      • ピンの引き出した様子は写真参照
      • MAX31855のライブラリが既に存在したので、コードはほとんど書いていません。
      • mbedコード : https://developer.mbed.org/users/takafuminaka/code/Soldering_Tips_Thermometer/
      • コンパイル方法: LPCXpresso 11U68を選択してコンパイル
      • 書き込み方法
        1. USBケーブルでPCに接続
        2. RESETボタンとISPボタンを同時に押し、RESETボタンを先に離してから、ISPボタンを離す
        3. ドライブとしてマウントされるので、firmware.binを消去後、mbedで作成したbinファイルを書き込む
        4. RESETボタンを押す

      • こうして作成したのが最初の写真となります。

      2015年5月31日日曜日

      I²C延長実験(HRM1017+BME280+HDC1000)



      結露モニタ プロトタイプ1(BME280とHDC1000使用)にて、LANケーブルを利用したI²Cの延長を試しましたが、何が起こっているのかをLabToolを使って調べてみました。
      (真面目にバッファICを使って延長する方法は、NXPのアプリケーションノート(AN10658)。とっつきにくい場合はI²Cサンプルブックから。)

      プログラムの動作を見る限りでは、何の違いもなく45mまで延長出来たように見えましたが、アナログ的には随分と状況が悪化していることが分かりました。

      主たる原因はバスの容量の増加に伴う信号の立ち上がりの鈍化。
      規格上のI²Cバスの容量の400pFですが、
      Cat6ケーブルの容量は5~6nF/100m (1kHz)程度らしいので、500~600pF/10m。
      現在の何の工夫もない状態では、高々10m位までで使うのが良いようです。

      最初の公開時に言及していたリンギングは、測定方法に問題がありました。測定点のそばでGNDを確保したところ無くなりました。

      このような状態で一見うまく動いているのは、たまたま、今回の組みあわせ(HRM1017+BME280)が良かったのかもしれません。
      電圧降下は激しいので、少なくとも低電圧動作が可能なマイコン/センサの方がうまく動きそうな気がします。

      mbed祭 2015@初夏の東銀座用資料

      mbed祭 2015@初夏の東銀座で展示した、
      「mbed HRM1017+BME280使用 結露モニタと LANケーブル利用I2C延長」
      の資料です。

      用意したプレゼンテーション資料です。うまく映せずすいませんでした。 

      別途用意していた配布資料+回路図です。

      HRM1017用のコードは以下で公開しております。


      LabToolについて

      LabToolはNXP社の光速ADコンバータ搭載マイコンLPC4370を使った簡易測定キットです。
      詳しくは、以下のリンク先をご覧ください。

      実験装置概要
      回路とプログラムは結露モニタ プロトタイプ1(BME280とHDC1000使用)です。液晶表示装置を追加しています。
      I²Cバス上のデバイスは、HRM1017を除いて4つ
      LANケーブルの手前には、HRM1017そばにHDC1000と液晶表示装置、そのうちHDC1000に10kオームのプルアップ抵抗
      LANケーブルの先にはBME280と液晶表示装置、それぞれに10kΩのプルアップ抵抗となります。

      測定結果

      以下に、バスの接続ケーブルを伸ばしていくにつれ、SCLシグナルがどうなっていくのかを記しています。(HRM1017側のSCLと、ケーブルの先のI²CバスのSCLを取得しています。)

      ジャンパケーブル接続(数10cm)



      2mのCat6 LANケーブル
      少し信号がなまっている位で、あまり違いは見えません。



        7mのCat6 LANケーブル使用
        電圧降下、波形のなまり



        15m Cat6 LANケーブル使用
        さらに信号は悪化
        回路自体は動作している



        30m(15mLANケーブル2本連結)
        波形の悪化に伴い、動作周波数が勝手に50kHzに落ちている。クロックストレッチという現象が発生している?
        プログラム自体は正常に動作しているように見える。値も正常。



        45m(15mLANケーブル3本連結)
        30mの時と同様
        プログラム自体は正常に動作しているように見える。値も正常。




        2015年5月1日金曜日

        結露モニタ プロトタイプ(BME280とHDC1000使用)

        mbed祭 2015@初夏の東銀座用資料

        mbed祭 2015@初夏の東銀座で展示した、
        「mbed HRM1017+BME280使用 結露モニタと LANケーブル利用I2C延長」
        の資料です。

        用意したプレゼンテーション資料です。うまく映せずすいませんでした。 

        別途用意していた配布資料+回路図です。

        HRM1017用のコードは以下で公開しております。


        以下、投稿当時の内容


        スイッチサイエンス社から、BME280という温湿度気圧センサーが発売されました。


        また、秋月で購入したHDC100という温湿度センサーを持っています。


        これらを利用して、結露に関する情報を得られるモニタのプロトタイプを作ってみました。

        概要

        • mbedマイコン (最終的にBLEで情報を飛ばしたいと思っているので、mbed HRM1017を使っていますが、現段階では使っていないので他のmbedでも動くと思います。)
        • 屋内用センサ: 秋月で購入したHDC1000 (温湿度センサ)
        • 屋外用センサ: スイッチサイエンス社で購入したBME280(温湿度+大気圧センサ)
          • プルアップ抵抗 10kΩ
        • LANコネクタDIP化キット:秋月で購入したK-05404
        • LANケーブル:LD-GPT/WH70 (7m Cat6対応ケーブル)
          • カテゴリー6ケーブル(Wikipedia)参照
          • T568B結線の半分(4本)を使っています。
            ピン番号
            ケーブル色
            信号名称
            1
            /
            VDD (+3.3V)
            2
            SDA
            3
            /
            VSS (GND)
            6
            SCL


        • LEDは通常のLED(OSNG3133A, OSNR3133A)。電流制限抵抗3.9kΩ (3.3kΩ可)


        配線図など

        • パーツリスト
          • 屋内(想定)モジュール
            #
            モジュール
            製品名称
            購入先
            備考
            1
            mbed
            mbed HRM1017
            スイッチサイエンス

            2
            I2C温湿度センサ
            HDC1000使用
            温湿度センサーモジュール
            秋月電気通商
            I2Cのプルアップ抵抗搭載
            3
            LED1
            OSNG3133A
            秋月電気通商

            4
            LED2
            OSDR3133A
            秋月電気通商

            5
            抵抗
            3.3kΩ
            秋月電気通商
            HRM1017GPIO電流制限0.5mA用に調整
            LEDは定格よりはかなり低い電流値で使用
            6
            抵抗
            3.3kΩ
            秋月電気通商
            同上
            7
            RJ45
            LANコネクタ
            DIP化キット
            秋月電気通商

          • 屋外(想定)モジュール
            #
            モジュール
            製品名称
            購入先
            備考
            1
            I2C温湿度・気圧センサ
            BME280搭載 温湿度・
            気圧センサモジュール
            スイッチサイエンス
            I2Cのプルアップ抵抗未搭載
            2
            抵抗
            10kΩ
            秋月電気通商
            I2Cのプルアップ用
            3
            抵抗
            10kΩ
            秋月電気通商
            同上
            4
            RJ45
            LANコネクタ
            DIP化キット
            秋月電気通商

        • 実体配線図など


        プログラム

        今回使ったプログラムはmbed上に公開しました。
        https://developer.mbed.org/users/takafuminaka/code/Condensation_Monitor/


        • 起動後10秒間、LED1(緑)とLED2(赤)を点灯させ、消灯します。
        • 10秒周期で2つのセンサーの値を読み取ります。
        • 結露を検知すると、LED2(赤)が点灯します。コンソール出力が有効な場合はそちらにメッセージを出します。(後述)
        • 結露が近いと判断する(結露までの温度差がwarn_wid(℃)を下回る)と、LED1(緑)が点灯します。コンソール出力が有効な場合はそちらにメッセージを出します。(後述)
          • warn_widは20℃と大きく設定しています。実運用では2~3℃に設定すると良いです。
        • コンソール出力はmain.cppの”#define NEED_CONSOLE_OUTPUT 1”をコメントアウトすると抑制出来ます。
          • コンソールをPC側で表示させない場合は抑制しないとmbed側の動作が停止すると思います。
        • コンソール出力について
        • 出力例
          In: 24.90 degC, 60.85 % Out: 26.10 degC, 55.20 %, 1011.04 hPa
          Humidity Ratio [g/kg] : In 11.79 Out 11.49
          Due Point Temperature [degC] : In 16.40 Out 16.81
          9.70 degC to Condensation at Outside
          8.08 degC to Condensation at Inside
          9.29 degC to Condensation at Window Inside
          8.49 degC to Condensation at Window Outside
          • 1行目に室内センサーの温度と湿度、室外センサーの温度、湿度、気圧が表示されます。
          • 2行目に屋内外の絶対湿度が[g/kg]単位で表示されます。
            • 結露対策のために換気をしても良いかどうかの目安となります。
              例えば、屋内の湿度が高い場合に、屋外の絶対湿度が屋内よりも低ければ、換気をするだけで湿度が低下します。
              逆に屋外の絶対湿度が屋内よりも高い場合は、湿分を取り込むことになるので換気をすると屋内の湿度が上がります。
          • 3行目に屋内外の露点が表示されます。
          • 4行目以降は警告あるいは注意表示です。
            • 上記の例は、後何度下がると何が起こるかが表示されています。
              • 最初の行は屋外の温度と露点を比較し、あと何度で結露するかを表示
              • 次の行は屋内の温度と露点を比較し、あと何度で結露するかを表示
              • 次の行は屋外の温度と屋内の露点を比較し、あと何度屋外が冷えると窓が結露するかを表示
              • 次の行は屋内の温度と屋外の露点を比較し、あと何度屋内が冷えると窓が結露するかを表示
            • もし、露点を下回った場合は結露が発生したとみなし、” Condensation at  XXX”あるいは” Condensation at Window XXX”の様にメッセージを出します。


        理屈


        温湿度が分かれば、露点が計算できます。
        さらに気圧が分かれば、絶対湿度が計算できます。


        室内外の計測情報を活用すると、結露しているのかどうか、あるいは、あと何度で結露するのかが分かります。

        今回のプログラムでは、ここここの式を利用して計算しています。


        LANケーブルによるI2C延長について

         シリアル拡張ICサンプルブックI2C仕様書等を参考に考察と実験を行い、上記ケーブルを使いました。ツイストペアケーブルを使ったバス延長はI2C仕様書p.60に説明があります。

         そこで、Cat6の15mケーブルを借りてきて試したところ、3.4Mhz(設定値ベース)で通信可能でした。

         プロの方いわく、「シングルエンドの信号なんで,インピーダンスの低い線とペアで扱うことにより良好な結果が得られる」のだそうです。

         

        写真は載せませんがその後もう少し実験をした結果です。

        • Cat5e 15mのケーブルでも成功(100kHz設定)
        • Cat6 15mのケーブル3本を延長コネクタで接続(つまり45m!!)しても成功(100kHz設定)

         結局限界は今回は分からずじまいでした。私の用途では、十分すぎる性能です。
        本当は、数mでうまく動かなくなり、サンプルブック付属のバッファICで延長するという計画だったのですが、無くても動くという、思わぬうれしい誤算でした。

        (2015-05-19追記)
        Labtoolで取得したI2Cバスの様子です。
        アナログ波形はずいぶん歪んでいるようです。
        また、I2Cの周波数指定はうまく効いていなかったようで、100kHz動作です。