質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

551閲覧

省エネモデルのストップウォッチを作る

actionstudio

総合スコア39

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2023/03/26 04:03

編集2023/03/31 01:10

実現したいこと

  • 処理量を減らし省エネを実現する
  • forever 関数の代替

前提

Microsoft MakeCode for micro:bitで勉強のためのストップウォッチを作っています。
勉強した時間に応じる長さの棒グラフがLEDライトによって表示されます。
各ボタンの説明

  • Aボタンを押すとストップウォッチが開始、停止します。
  • Bボタンを押すとリセットされます。
  • micro:bitについているロゴを短くタッチするとLEDライトが消灯し、これによって省エネをしています。
  • ロゴを長くタッチすると棒グラフがリセットされます。時間はリセットされないまま、棒グラフは初めからスタートします。つまり、棒グラフが最大値まで達してしまったときに、はじめから開始できるようになっているということです。なお、棒グラフは50分程度で最大になるように設定しています。

問題

ここで、棒グラフは計っている時間によって長さがきまり、そのために”forever”で長さを決める計算をしなくてはなりません。処理量を減らすために1000msで繰り返すようにしているのですが、これよりいい方法がないか探しています。

追加の質問
forever関数で処理するのにはそれほど電力はかからないのでしょうか。

試したこと

処理量を減らすために1000msで繰り返すようにしました。
10秒ごとにすればそれほど支障はないのですが、それより長くにしてしまうと、時間の経過に対応する棒グラフの変化が遅れてしまうということが起こってしまいます。

該当のソースコード

JavaScript

1input.onLogoEvent(TouchButtonEvent.LongPressed, function () { 2 LastGraphValue = elasped() 3}) 4input.onButtonPressed(Button.A, function () { 5 ShouldShowGraph = false 6 led.stopAnimation() 7 led.setBrightness(LedBrightness) 8 basic.clearScreen() 9 if (InMeasure == false) { 10 InMeasure = true 11 start = input.runningTime() 12 basic.showIcon(IconNames.Yes) 13 ShouldShowGraph = true 14 } else { 15 InMeasure = false 16 basic.showLeds(` 17 . . . . . 18 . . . . . 19 . . # . . 20 . . . . . 21 . . . . . 22 `) 23 basic.clearScreen() 24 basic.showNumber(Math.round(elasped())) 25 } 26}) 27function elasped () { 28 elapsed = input.runningTime() - start + elapsed 29 start = input.runningTime() 30 return elapsed / 1000 / 60 31} 32input.onButtonPressed(Button.B, function () { 33 control.reset() 34}) 35input.onLogoEvent(TouchButtonEvent.Pressed, function () { 36 if (led.brightness() == LedBrightness) { 37 led.setBrightness(0) 38 } else { 39 led.setBrightness(LedBrightness) 40 } 41}) 42let LedBrightness = 0 43let ShouldShowGraph = false 44let InMeasure = false 45let LastGraphValue = 0 46let start = 0 47let elapsed = 0 48elapsed = 0 49start = 0 50LastGraphValue = 0 51InMeasure = false 52ShouldShowGraph = false 53LedBrightness = 100 54loops.everyInterval(1000, function () { 55 if (ShouldShowGraph == true) { 56 led.plotBarGraph( 57 elasped() - LastGraphValue, 58 55 59 ) 60 } 61}) 62

補足情報(FW/ツールのバージョンなど)

micro:bitはバージョン2を使用しています。

見つけたこと

明るさを下げることで省エネができました

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

処理量を減らすために1000msで繰り返すようにしているのですが、これよりいい方法がないか

 
全体の文脈から、ここでの"処理量"とは「単位時間当たり(たとえば、1時間あたり)の電力消費量」と理解しました。

単位時間当たりの電力消費量を減らしたいのであれば、

  • 更新間隔を 1000ms より長くする。
  • LED を計測中ずっと表示させるのではなく、切り替わるときだけ表示させる。

等になります。(1番目は要件として除外されるとのことですが)

forever関数で処理するのにはそれほど電力はかからないのでしょうか。

forever を使った場合、質問文記載のコードと同じ動作をさせるという前提ならば、pause 関数で一定間隔ごとに一時停止させるコードを書いているはずです。

これが正しいとして、この場合(=everyInterval の代わりに、forever 関数と pause 関数を組み合わせる場合)、everyInterval 関数を使用したコードと forever 関数を使用したコードの間で、消費電力に有意な差異はありません。

なぜなら、everyInterval 関数自体も内部で pause 関数を 呼び出しているからです。


everyInterval 関数は、pause 関数を呼び出しており、
pause関数は、低レベル関数である、fiber_sleep 関数を呼び出しています。

証拠:
https://github.com/microsoft/pxt-microbit/blob/7ea4fced7784857db1d7734ff666d25930f2d1c2/libs/core/loops.ts#L13-L22

https://github.com/microsoft/pxt-microbit/blob/7ea4fced7784857db1d7734ff666d25930f2d1c2/libs/core/basic.ts#L24-L26

https://github.com/microsoft/pxt-microbit/blob/7ea4fced7784857db1d7734ff666d25930f2d1c2/libs/core/basic.cpp#L100-L102

fiber_sleep 関数の実行中(=スリープ中)、消費電力は大幅に削減されます。
もちろんボタンやタッチセンサー等は最低限待受状態になっていて、すぐに復帰できるようにはなっていますが。

fiber_sleep 関数は、 micro:bit の ファイバースケジューラー(fiber_scheduler) という機能に依拠しているようです。

参考:
https://lancaster-university.github.io/microbit-docs/advanced/#initialising-the-fiber-scheduler

From the moment the fiber scheduler is initialised, it is then possible to block the processor in a power efficient way and to operate threaded event handlers:

ファイバースケジューラが初期化された瞬間から、電力効率の良い方法でプロセッサをブロックし、スレッド化されたイベントハンドラを動作させることが可能になります:

投稿2023/03/26 05:41

編集2023/03/26 05:47
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

actionstudio

2023/03/26 11:54

丁寧な解説ありがとうございました。参考のリンクも張って頂き、勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問