#というわけで
私の考えたさいきょうのレーザーポインターの作り方をできる限り丁寧に説明します。
※さいきょうの定義は各個人によりますので予めご了承ください。
今回、さいきょうの定義は以下の三要素とします。
その1. 高機能
欲しい機能はこんな具合。
- スライドを送る/戻す
- スライドショー発表中に黒背景にする
- プレゼンタイマー
その2. 拡張性がある
機能を後から追加、変更できる。
その3. 安い
上の機能が入ったレーザーポインタを市販品より安く作れる。
今回比較対象としたのは、ロジクール R800 (2020/9/1時点で8,500円) です。
##対象読者
- Arduinoでの初歩的なスケッチの文法が分かる。例)
setup()
とloop()
の使い分けができる。 - Arduino IDEを用いてマイコンに書き込みができる。
- ビルドでエラーが起きても諦めない心を持っている。
#用意する部品
M5StickC以外は秋月電子通商でほぼ揃います。M5StickCはマルツで購入できます。
どちらの店舗もオンライン通販に対応しているので、コロナ禍でも大丈夫です。
試作用の部品を除くと、__総額2,718円__で調達できます。
品名 | 価格 | 備考 |
---|---|---|
40ピン基板用ピンヘッダー 40ピン×1列 | 88円 | 8ピン以上だったら大丈夫です。 |
タクトスイッチ | 10円 | |
レーザーモジュール | 500円 | |
単4形アルカリ乾電池 | 80円 | |
電池ボックス 単4×3本 | 60円 | |
M5StickC | 1,980円 |
以下は試作用の部品なので、必須ではありません。
品名 | 価格 | 備考 |
---|---|---|
ジャンパワイヤー(オス-オス) | 180円 | 抵抗の足で代用可能。 |
ブレッドボード | 200円 |
#電子回路
レーザーモジュールとM5StickCに乾電池を繋ぎます。
##注意事項
秋月電子通商のよくある質問を見ると、レーザーモジュールは3V以上の電圧や電源逆接続すると壊れます。
と書いてありますが、1
上の回路では乾電池3本の直列電圧(1.5V×3本=4.5V) を印加しています。
私の環境ではレーザーモジュールは壊れませんでしたが、気になる方は分圧なりしてください。
M5StickCの3.3Vから出すのもありですが、仕様上、電源OFF状態では3.3Vは出力されないようです。2
#M5StickCのプログラム
Githubはこちら→only-my-laser
とりあえず使ってみたい方はGithubから落として、Arduino IDE等で焼いてみて下さい。
何も変更しなくてもそのまま使えます。(多分)
では、__要点のみ__解説していきます。
##ざっくりした考え方
スライド操作
M5StickCはBLE(Bluetooth Low Energy)が喋れるので、キーボードとして認識させて、PowerPointのショートカットキーに対応させます。
プレゼンタイマー
M5StickCに内蔵されているタイマーで時間を計測をします。
##スライド操作
BLEキーボードとして利用するために、BleKeyboard.h
を利用します。
有り難いことにライブラリを作ってくださっている方がいるので、活用しましょう。ライブラリへの追加方法やSampleは下のGithubに書かれています。
BLEキーボードのライブラリはこちら→T-vK/ESP32-BLE-Keyboard
ライブラリのダウンロード/インクルード
- GithubからライブラリのZIPをダウンロードします。
- Arduino IDEのメニューから
スケッチ > ライブラリをインクルード
を選択し、先程落としたZIPファイルを指定します。
ライブラリの宣言
スケッチ先頭の宣言部に書いてください。
#include <BleKeyboard.h>
BleKeyboard bleKeyboard("only-my-laser");
2行目でBLEキーボードの名前を指定しています。PC等からペアリングするときはこの名前で探します。
PowerPointのショートカット送信
loop()
に書いてください。
/* -- スライド操作関連 -- */
// Bluetooth接続後の動作
if( bleKeyboard.isConnected() ){
FlagBleConnected = true;
// ボタンAが押されたとき、[n]を送信
if( M5.BtnA.wasReleased() ){
Serial.println("Send n key");
bleKeyboard.print("n");
}
// ボタンBが押されたとき、[p]を送信
if( M5.BtnB.wasReleased() ){
Serial.println("Send p key");
bleKeyboard.print("p");
}
// ボタンBが指定秒数以上押されたとき、[b]を送信
if( M5.BtnB.wasReleasefor(TIME_BTNB_LONG_PRESS) ){
Serial.println("Send b key");
bleKeyboard.print("b");
}
bleKeyboard.releaseAll();
} else {
FlagBleConnected = false;
}
M5.BtnA
は正面の「M5」と書かれたボタン、M5.BtnB
は右側のボタンです。
wasReleased()
はボタンが押されて、__離されたとき__にTrue
が返ってきます。
wasReleasefor()
は__何ms以上押して離したか__でTrue
が返ってきます。
##プレゼンタイマー
タイマーの宣言
スケッチ先頭の宣言部に書いてください。
hw_timer_t * presenTimer = NULL;
タイマーの作成と初期化
setup()
に書いてください。
presenTimer = timerBegin(0, 80, true);
// presenTimer 初期停止と初期化
timerStop(presenTimer);
timerWrite(presenTimer, 0);
timerBegin(0, 80, true)
は
第1引数でタイマーのIDを指定し (0〜3
の4つのタイマーが内蔵されています)、
第2引数で何クロックでカウントアップするのか指定し(通常は80
MHz)、
第3引数でカウントアップを意味しています (false
だとカウントダウンします)。
第2引数に関する解説はこちらに詳しく載っています。
ESP32の高精度タイマー割り込みを調べる
タイマー操作
loop()
に書いてください。
/* -- タイマー関連 -- */
// 電源ボタンの押下状態を取得する。
// HACK: GetBtnPress()は0以外の値は一度しか値を取得できないから、ここで取得する。
// 格納しないで下のif文で呼ぶと、ボタンを長押ししても[1]ではなく、先に短い場合の[2]を返してしまうため、長押しの分岐に入らない。
int axpBtn = M5.Axp.GetBtnPress();
// 電源ボタンが短時間押されたときは、タイマーのStart/Stop
if( axpBtn == 2 ){
if ( timerStarted(presenTimer) ){
timerStop(presenTimer);
} else {
timerStart(presenTimer);
}
}
// 電源ボタンが長時間(1.5s)押されたら、タイマーリセット
if ( axpBtn == 1 ){
timerStop(presenTimer);
timerWrite(presenTimer, 0);
}
今回、本体の電源ボタンをタイマー操作ボタンと兼用しています。
BtnA
などの汎用ボタンと違い、押された秒数によってM5.Axp.GetBtnPress()
の返り値が変化します。
電源電圧や接続状態のモニターをしていますが、そちらはGithubのソースコードを読んでみてください。
##それで、結局「さいきょう」になったの?
高機能
スライドを送る/戻す、黒背景にする、プレゼンタイマーは実装できました。
拡張性
M5StickCは後でいくらでも書き換えできるので、機能変更にも対応できます。
今回はBluetoothぐらいしか使っていませんが、他にもいろんなセンサやモジュールが乗っているので夢は無限大ですね!
低価格
今回、外装は3Dプリンターで製作しました。
プリンターのフィラメント代を含めても安く作れたと思います。
強いて弱点を言うなら、「でかい」ぐらいでしょうか。
そこは外装設計を見直してバージョンアップしていきたいと思います。
「さいきょう」のレーザーポインターを作ることが出来ました。めでたしめでたし。
#(余談)本当に格安で作るなら
今回はプレゼン操作やタイマーのためにM5StickCを導入しましたが、
「レーザーポインターさえあればいい!余計な機能は不要だ!!」という方は、とっても低価格で作ることが出来ます。
作り方は簡単。
レーザーモジュールと乾電池×2本を繋ぐ。
以上。
外装は蓋付きの単4形乾電池ケース(120円)にレーザ光の穴を開けるだけ。
単4形乾電池の直径(10.5mm)とレーザーモジュールの直径(最大で10mm程度)がほぼ同じなので、すっぽり収まるはずです。
そうすればなんと、外装も含めて700円で作ることが出来ます。