micro:bitで矩形波を出力してみる(その3:PWMモジュールを使ってみる)

micro:bit矩形波を出力してみるシリーズ、第3弾。
前回まではSleep関数を使って矩形波を出力しようとしていましたが、
どうやらメインループが回るときにオーバーヘッドがあるらしく、
精度の良い矩形波が出力されない、という結論でした。
stacked-tip.hateblo.jp
stacked-tip.hateblo.jp

何かないのかと調べていましたら、
どうやらmicro:bitはPWMモジュールを持っていることがわかりました。
sanuki-tech.net

これを使えば矩形波を出せるんじゃないか?
ということで、試してみました。

まずは、周期1ms、つまり1kHzでトライしてみます。
f:id:stacked-tip:20190929095724p:plain:w400

micro:bitでは「アナログ出力」がPWM出力を意味するようです。
うーん…と思ってしまいますが、まぁここは流しましょう。

「最初だけ」のブロックで、

  • アナログで出力する 端子P0 値512
  • アナログ出力 パルス周期を設定する 端子P0 周期(マイクロ秒) 1000

と書いていますが、実はこの順番が大事です。

2番目の

  • アナログ出力 パルス周期を設定する 端子P0 周期(マイクロ秒) 1000

というブロックは、P0がアナログ出力端子として使用されていない時は無視される仕様になっているらしいので、

  • まずP0をアナログ出力端子として使用する
  • それからパルス周期を変更する

の順で処理してあげる必要があります。
f:id:stacked-tip:20190929100303p:plain:w400
ブロックにカーソルを合わせると、その旨を注意するメッセージが表示されます(英語だけどね)。

オシロスコープに繋いて、波形を見てみましょう。
f:id:stacked-tip:20190929094150j:plain:w400

さて、結果です。
f:id:stacked-tip:20190929091623j:plain:w400
1ms周期の矩形波がちゃんとでています。
PWMモジュールを使えば綺麗な矩形波が出力できることが分かりました。

できるとわかったら、「どこまでできるのか」を調べたくなるのが技術者です。
パルス周期をどんどん短くしてみましょう。

次は一気に0.01ms=10us、周期にして100kHzです。
f:id:stacked-tip:20190929100936p:plain:w400

結果はこちら。
f:id:stacked-tip:20190929092854j:plain:w400
問題なく100kHzの矩形波が出力されています。

次は5us、周期にして200kHz。
f:id:stacked-tip:20190929101106p:plain:w400

結果はこのとおり。
f:id:stacked-tip:20190929093443j:plain:w400
200kHzの矩形波が出力されて…はいますが、
よく見るとDuty比が50%になっていませんね。
ハイレベルが2usとローレベルが3usで、併せて5usになっています。
2.5usという制御ができない、最小単位が1usということなのですかね?

では、2us、周期にして500kHzにしてみますか。
f:id:stacked-tip:20190929101549p:plain:w400

結果はこちら。
f:id:stacked-tip:20190929093734j:plain:w400
今度は大丈夫です。無事、Duty比50%の500kHz矩形波が出力されました。
どうやら最小単位が1usで、小数点以下は切り捨てられてしまうようです。

じゃぁ1us、周期にして1MHzは…たぶんでないんだろうけど。
f:id:stacked-tip:20190929101834p:plain:w400

結果はこうなる。
f:id:stacked-tip:20190929094058j:plain:w400
波形は出力されません。
0.5usが切り捨てられて0usになり、ハイレベル部分がなくなってしまったのでしょう。

というわけで、
micro:bit矩形波を出力したい場合は、

  • PWMモジュールを使用する
  • 最小単位は1usであることに注意する

で、実現できることがわかりました。

実際のところ、どれくらいの周波数なら使い物になるのでしょうか。
精度を定量化して、この記事を終えましょう。
f:id:stacked-tip:20190929111505p:plain:w400

精度の指標として、Hiレベル時間の、理想と実際との比率でみてみようと思います。
実際のHiレベル時間が、理想のHiレベル時間と近いほど、高精度であると言えますから、
この比率が100%に近いほど良いということになります。

f:id:stacked-tip:20190929112316p:plain:w400

精度はあるところでストンと落ちて、そこからじりじりと上がっていき、
100%になったところでまたストンと落ちる、となっています。
500kHzを超えると、理想のHiレベル時間が1usを切るので、精度は0%になってそのまま上がってきません。

f:id:stacked-tip:20190929112542p:plain:w400
100kHzまでで拡大してみました。
35kHzまでなら、95%以上の精度になります。
11kHzまでに限定すれば、99%以上の精度になります。
実用範囲は10kHzまで、というところでしょうかね。

micro:bitで矩形波を出力してみる(その2:Pythonエディター)

micro:bit矩形波を出力しようとしています。
前回はMakeCodeエディターでプログラミングしてみましたが、
今回はPythonエディターでプログラミングしようと思います。
stacked-tip.hateblo.jp

まずは1ms、周期にして500Hzの矩形波を出力してみます。
Pythonコードは以下のとおり。
f:id:stacked-tip:20190928225110p:plain:w400

結果はこちら。
f:id:stacked-tip:20190928221335j:plain:w400

うーん。時間が長いところと短いところがありますね。

f:id:stacked-tip:20190928221523j:plain:w400
f:id:stacked-tip:20190928221607j:plain:w400

短いところは1.1ms、長いところは4.9msですか。
この4.9msというのはループの処理なのでしょうか。

f:id:stacked-tip:20190928222024j:plain:w400
でも0.24msという変な場所もあるんですよね。
割り込み処理でも入っているのかな?

次は10ms、周期にして50Hzの矩形波を出力してみましょう。
Pythonコードは以下のとおり。
f:id:stacked-tip:20190928224813p:plain:w400

結果はこちら。
f:id:stacked-tip:20190928222732j:plain:w400
f:id:stacked-tip:20190928222858j:plain:w400
ぱっと見るといい感じ?と思いましたが、
12ms前後で揺れています。
2~4msの遅延が発生していますね。

Pythonエディターで組んでも、それくらいの遅延が発生してしまいます。

続き
micro:bitはPWM出力ができるようですよ。
stacked-tip.hateblo.jp

micro:bitで矩形波を出力してみる(その1:MakeCodeエディター)

折角オシロスコープを買ったので、
micro:bit矩形波を出力してみましょう。
stacked-tip.hateblo.jp

micro:bitは組込み現場で役に立つの?
もう少し具体的に言うと、
少なくともミリ秒(ms)レベルの制御をmicro:bitは可能なのか?
という検証も兼ねています。

まずはブロックでプログラミングをしてみました。
f:id:stacked-tip:20190928212539p:plain:w400
100ms周期でP0ピンをパタパタしているので、5Hzの矩形波が出力されているはずです。

結果はこちら。
f:id:stacked-tip:20190928205740j:plain:w400
f:id:stacked-tip:20190928205811j:plain:w400

立ち上がり後は102msの間隔で、まぁそんなものなのかな、という感じですが、
立ち下がり後は126msの間隔で、既に26%のずれ…これはいけませんネ。

続いてこちらのプログラミング。
f:id:stacked-tip:20190928212648p:plain:w400
0.5ms周期のパタパタなので、プログラミング上では1kHzの矩形波…ですが。

f:id:stacked-tip:20190928210403j:plain:w400
f:id:stacked-tip:20190928210601j:plain:w400

立ち上がり後は6msって、これがmicro:bitの限界なのかな(少なくともブロックプログラミングでは)。
立ち下がり後は30ms?メインループ終了後になんか重い処理が入っているのでしょうか。
そう言えば、最初の5Hzの時も、立ち下がり後に26msの遅延がありましたね。
ここにきっと何かの制御が入っているのでしょう。

というわけで、少なくともブロックプログラミングでmicro:bitを制御するのでは、
組込み現場では使い物にならなそうだということが分かりました。

シリアル通信(UART)をする程度なら使えるのかも知れませんね、今回は試していませんけど。


続き
今度はPythonエディターでやってみました。
stacked-tip.hateblo.jp

オシロスコープを購入しました

オシロスコープを購入しました。
f:id:stacked-tip:20190928200550j:plain:w400
f:id:stacked-tip:20190928200813j:plain:w400

OWON製の2chデジタルオシロスコープです。
いやぁ、思えば趣味で電子工作始めた時から、
いずれはオシロ欲しいなぁと思っていましたが、
ようやく一般人の手の届く範囲のものが出回るようになりましたね。

f:id:stacked-tip:20190928201031j:plain:w400
テスト波形(0V-5V, 1kHzの矩形波)もしっかり出ます。

試しに、手元にあったmicro:bit用の電池ボックスを
接続してみました。
f:id:stacked-tip:20190928202040j:plain:w400
f:id:stacked-tip:20190928201930j:plain:w400

単4電池直列2個なのでフル充電なら3.0V出力のはずですが、
2.64Vしか出ませんでした。へたってるな。

Unityで製品紹介ビデオ制作にトライする

f:id:stacked-tip:20190815183758g:plain:w400
製品を紹介するビデオを作成したい。
具体的には、3Dの製品が画面の真ん中でクルクル回るような映像を作りたい。

この記事では、

  • 回転させたいものの3DCADデータがある状態で
  • Unityを使って

それを実現する方法を紹介します。

…3DCADデータがない?Blenderで作ってくれ。
私もBlender初心者だったが、色々ググって数時間でモデリングできるようになったから。
なお、トップの文字列が回転しているものについては、
もっとお手軽に「TINKERCAD」でモデリング、objデータをエクスポートしてUnityにインポートしています。

開発環境

私の開発環境は以下のとおり。3D映像制作をするのには、余りに貧弱だが仕方ない。
PC: SONY VAIO Pro 11 (VJP111B01N)
CPU: Intel Core i7-4510U @ 2.00GHz
RAM: 8.00GB
GPU: なし
OS: Windows 8.1
Unity: 2018,4,6f1 Personal

今回は、以下のようなコインをクルクルさせようと思う。
(本当はBlenderで組んだモデルを見せたいところだが、大人の都合でそれはできないので…)
f:id:stacked-tip:20190815133659p:plain:w400

コインをクルクルさせる

3Dオブジェクトをクルクルさせるには、そのようなC#スクリプトを書いて、そのオブジェクトに紐づければOKです。

もう少し丁寧に言えば、

  • [Assets]エリアを右クリックし、[Create]→[C# Script]を選択してC#スクリプトを作成し、
  • それをダブルクリックしてコードエディタを開き、
  • そこにコードを記述、保存して閉じてから、
  • C#スクリプトをコインにドラッグ&ドロップして紐づける

とやればOKです。

C#コードはこんな感じです。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class rotate : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        transform.Rotate(new Vector3(0,0,90)*Time.deltaTime);
    }
}

結果は以下のとおり。
f:id:stacked-tip:20190815135312g:plain:w400
メインカメラの位置について、開発画面と再生画面を一致させています。

  • [Hierarchy]で[Main Camera]を選択したうえで、
  • メニューバーの[GameObject]→[Align With View]を選択

因みに、このコードは下記書籍を参考にしています。
藤森将昭『Unityではじめる おもしろプログラミング入門』リックテレコム

背景を黒にする

さて、上記の映像でOKならそれでいいのですが、私は、背景を真っ黒にしたいなと思いました。
暗闇の中で、モデルがクルクル回っているイメージです。

Unityで背景を真っ黒にするのにはいくつか設定が必要なのですが、
詳しくは以下のブログ様を参照してください。
私もこれに従って背景を真っ黒にできました。
murasame-labo.hatenablog.com

1. シーンに配置された光源を無効にする

新規でシーンを作成すると、ディレクショナルライトという光源がデフォルトで設定されています。
詳細は割愛しますが、ディレクショナルライトとは、シーン内のすべての場所に対して、一定の方向から光を当てる光源です。
これを無効にすると、以下のようになります。
f:id:stacked-tip:20190815165341g:plain:w400
確かに暗くはなりましたが、予想よりもまだまだ明るいです。

2. 環境を構成する天と太陽を消す

実は、シーンを照らす光は、光源だけではありません。
光源とは別に「環境光」なるものがUnityにはあります。
私のバージョンでは、
[Window]→[Rendering]→[Lighting Settings]
で環境光の設定画面に到達できます。

先に紹介したブログ様では、環境光の強さ(Intensity Multiple)を0にしていますが、
ここでは、そもそも環境光の存在自体を消してしまいます。
ついでに、シーンの背景にある空も消してしまいましょう。

先ほど開いた設定ウィンドウの、

  • Skybox Material
  • Sun Source

を見てください。
f:id:stacked-tip:20190815171212p:plain:w300
私のバージョンでは、デフォルトでは

  • Skybox Material: Default - Skybox
  • Sun Source: Directional Light (Light)

となっていました。

ここで、それぞれを次のように設定します。
f:id:stacked-tip:20190815171856p:plain:w300

  • Skybox Material: None (Material)
  • Sun Source: None (Light)

これにより、開発画面も目に見えて真っ暗になってしまいました。
f:id:stacked-tip:20190815172125p:plain:w400

再生画面もこのとおり。
f:id:stacked-tip:20190815172423g:plain:w400

3. カメラの背景色を黒にする

「カメラの背景色」とは?と思うでしょう。
実は、カメラの設定として、オブジェクトの背景を何にするという設定ができます。
ここで、背景色(Background)の色を変更します。
f:id:stacked-tip:20190815173013p:plain:w400
ここを、デフォルトの群青色から、黒にします。
f:id:stacked-tip:20190815173606p:plain:w400

こうして、シーンを完全な暗闇にすることができます。
f:id:stacked-tip:20190815173816p:plain:w400

光源を有効にしてみる

本当に完全な暗闇では、何も見えないので、オブジェクトを照らすくらいの光は欲しいです。
そこで、最初に無効化した光源「ディレクショナルライト」を再度有効にしてみましょう。
すると、このようになります。
f:id:stacked-tip:20190815174233g:plain:w400

背景を白にしてみる

背景を白にしたい?先ほどのカメラの背景を白にすれば、再生画面の背景も白になります。
f:id:stacked-tip:20190815174750g:plain:w400
でもこれだと、背景は白なのにコインは暗くて違和感がありますね。

カメラのClear FlagsをSolid Colorにする

実は、カメラの背景の設定として、Clear Flagsというのがあります。
デフォルトはSkyboxですが、これをSolid Colorにしてみましょう。
その上で、環境光の設定を元に戻してみてください。

  • Skybox Material: Default - Skybox
  • Sun Source: Directional Light (Light)

すると、開発画面での背景は、以前の空と地面がある背景なのに、
Camera Previewでは背景が白色になっています。
f:id:stacked-tip:20190815180004p:plain:w400

再生画面もこのとおり。
f:id:stacked-tip:20190815180704g:plain:w400

参考情報

GIFアニメーションは、「ScreenToGif」というソフトウェアで作成しました。
github.com

プロジェクトマネージャ試験に合格しませんでした

先週、IPA公式ホームページで、プロジェクトマネージャ試験の合格発表がありましたが、残念ながら合格できませんでした。
f:id:stacked-tip:20190629201545p:plain:w200
午後1が合格ラインギリギリの60点、午後2はC判定でした。
やはり、PMとしての実務経験がない(しかも職種的にも試験が想定する業務プロセスから外れている)状態での合格は難しいようです。
さて、リベンジの有無ですが、他の私事もありますので、暫くはいいかなと考えております。また必要になったら受験を検討しようと思います

プロジェクトマネージャ試験の午後1の本番でやったこと

プロジェクトマネージャ試験の午後1の本番で私がやったことを、
問題用紙を見ながら説明してみようと思います。

午後1の問題は「S→ぐ→W」で解ける

小見出しにあります「S→ぐ→W」ですが、これは私が高校生のころ受けていた現代文の授業で、
代ゼミの笹井講師が毎回のように掲げていたフレーズです。
3つの文字は

  • S:主語は?
  • ぐ:具体的に言うと?
  • W:なぜ?

であり、この順で現代文の問題に当たれば解ける、というものです。

今回、午後1の問題で、最初から「S→ぐ→W」を使おうとしていたわけではありません。
問題を解く中で、設問と本文を行き来するのが面倒で、
本文の方に設問を端的にメモしたのが始まりでした。

例えば、今回(H31)の問2の設問2 (1)の問題は、以下のようなものでした。

〔プロジェクトマネジメントの要素のリスクへの対応〕について,(1),(2)に答えよ。
(1)本文中の下線②について,H課長が考えた,G社プロジェクトが遅延するリスクがG社に与える非常に大きな影響とは,具体的に何を指すか。35字以内で述べよ。

このとき、私は、本文の下線②にある「非常に大きな影響」を丸で囲み、余白まで線を引っ張り、「ぐ」と書きました。
こうすることで、いちいち設問を見直すことなく、本文の方に集中できる効果がありました。
f:id:stacked-tip:20190425210807j:plain
以下、同じように、

  • 下線③の「人選」に「どのような?」とメモ
  • 下線④全体に「なに?」のメモ
  • 下線⑤全体に「なぜ?」のメモ
  • 下線⑥の後にある「確認すること」に「なに?」のメモ

を書いていき、各々の設問の答案を作っていました。

改めてこの時の設問の文末に注目してみると、

  • 設問1:「~のはなぜか。」
  • 設問2
    • (1):「~具体的に何を指すか。」
    • (2):「~どのような人選か。」
  • 設問3
    • (1):「~とは何か。」
    • (2):「理由は何か。」
    • (3):「~確認したことは何か。」
  • 設問4:「特性とは何か。」

となっており、結局

  • これは何?
  • 具体的には?
  • それはなぜ?

の3つしかないことに気づきました。
他の2問についても、基本的にはこの3つに集約できる設問だったので、
きっと、過去の問題についても同じなのではないかと思います。
(スイマセン、未確認です)

問題点のある表現にはマークすること

これは、今回私が使ったテキスト、ITのプロ46『うかる!プロジェクトマネージャ2019年版』でも使われている手法です。

否定的表現や違和感を覚える部分などを含め,問題点を見つけたら,ほぼ必ず設問に関係してくる。
したがって,わかるようにマークしておこう。
(p258)

問3の本文では、問題点のある表現にひたすら「マイナス記号」をメモしていきました。
f:id:stacked-tip:20190425210935j:plain

  • 「担当者が認識する品質と実際の品質との間にギャップ」をチェック
  • 「初回のレビュー実施時期は,レビューイの判断で決定」をチェック
  • 「チームメンバがクリティカルパス上の活動を認識していない」をチェック

こうすると、設問を解くタイミングで、最初にチェックポイントを確認するようになり、
効率的に答案を作れるようになりました。

やはり問題用紙にガシガシとメモを書いていった方が、答案を作りやすかったと感じています。
演習時にわざわざ紙に印刷して解くのは、あまり現実的ではないですが、
問題用紙にメモをするイメージで解いてみるといいかもしれません。