とりあえずとれるところまではやっていたが、ちゃんと負荷をかけていなかったのでかけたメモ

[Qualcomm認証済み]Aukey モバイルバッテリー 大容量 10400mAh スマホ充電器 [Quick Charge 2.0対応] 急速充電可能 (シルバー)PB-T1 -

5.0 / 5.0

例によってこのバッテリーで、結論からいうとスペック通り(12V 1.35A) の出力はとれ、ノイズ(リプル)も定格内だと全く問題なさそう。

  • 実際は 1.5A超ぐらいまでは出力され、1.6Aぐらいでシャットダウンされる。電源ボタンを押すとすぐリセットされるのでポリスイッチ以外での制御もしている? ショートされた場合はしばらくリセットもできないのでポリスイッチも入ってそうだけど
  • QucikCharge モードに入っている場合でも、低電流状態が続くと自動シャットダウンされる。1分ぐらい。閾値は面倒なので調べていない 。スペックに表記はない。

ちなみにこれ、安い割に外装がちゃんとアルミで、しっかりしている。ただしパワーが入っている間は常にコイル鳴きが聞こえる。負荷があがるとコイルもさらによく鳴く。

  1. トップ
  2. tech
  3. Quick Charge 2.0 バッテリーから12Vをとる(追試)

前行におく

promise.
  then(function () { }).
  catch(function () { });

後行におく

promise
  .then(function () { } )
  .catch(function () { });

どっちもいいんだけど、僕は前行においております

  • JS には自動セミコロン挿入があるので閉じ括弧で行が終わっていると不安になる
  • 上から順に読んでいく場合は行継続のマークが行の最後にあったほうが読みやすい気がする
  • then 〜 . で、ピリオドを文の終わりのように見せられる

行頭を重点的に見ながらコード読む人にとっては前の行との繋がりがわかりやすいのは、後行にドットなので (前行に置いた場合に行頭だけ読んでいくとただの関数コールに見える)、難しいところですね。

JS の場合セミコロン自動挿入があるのが嫌で、これが一番の理由で前行につけているフシがある。(文法違反になってはじめてセミコロン挿入がくるので、この場合どちらもセミコロン自動挿入は起きませんが……)

then 〜 . で1行にするとセミコロンと対応する感じになるので良いような気がする。

条件演算子で

var piyo = foo ? bar:
           fuu ? baz:
                 buz;

みたいに書くとき : と ; が対応していい感じなので、そういうイメージでいます

  1. トップ
  2. tech
  3. JS のメソッドチェインでドットを前行に置くか後行に置くか

前のエントリでいい感じで書けそうみたいなことを書いたが、例外処理について言及していなかった。

CompletableFuture は Promise 同様エラー処理用にcompleteExceptionally(Throwable ex) というメソッドを持っている。これを呼ぶと後続の exceptionally() にエラー処理が移る (そしてリカバリできる) 。

では普通の、時間のかかり、なおかつ検査例外を出す同期メソッドを CompletableFuture として実行する場合例外はどうすればいいだろうか?

runAsync などの中では CompletableFuture インスタンスは見えないので、catch して明示的に completeExceptionally() することができない。

いくつか方法がありそうだけど、よくわかってない

CompletableFuture を明示的に扱うラッパメソッドを作る

package com.company;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
public class Main {
public static void main(String[] args) {
new Main().doMain(args);
}
private static <T> CompletableFuture<T> async(Consumer<CompletableFuture<T>> function) {
final CompletableFuture<T> future = new CompletableFuture<>();
function.accept(future);
return future;
}
public void doMain(String[] args) {
final CompletableFuture<Void> future1 = async(f -> {
try {
f.complete("Foobar");
} catch (Exception e) {
f.completeExceptionally(e);
}
}).thenAccept(x -> {
System.out.println(x);
});
final CompletableFuture<Void> future2 = async(f -> {
try {
throw new RuntimeException("exception");
} catch (Exception e) {
f.completeExceptionally(e);
}
}).exceptionally(ex -> {
System.out.println("exception!!");
return ex;
}).thenAccept(x -> {
System.out.println(x);
});
CompletableFuture.allOf(future1, future2).thenRun(() -> {
System.out.println("All done");
});
}
}
view raw Main.java hosted with ❤ by GitHub

こういう感じで、JS でいうところの new Promise( (resolve, reject) => {}) に相当するメソッドを作って、明示的に同期コードでの終了時/例外時の処理を行う。

JS の流れだとわかりやすいけど、ラッパメソッドとかいちいち書きたくはないし、せっかくマルチスレッドによって同期的に書ける処理を非同期っぽくなおすのはダサい。

全部 RuntimeException にしてしまう

runAsync 内で全例外をキャッチして非検査例外にしてしまう。

この場合投げられた例外は java.util.concurrent.CompletionException (これも非検査例外) にさらにラップされて exceptionally に渡される。

全例外 catch して completeExceptionally するのも実質非検査への変換なのでこれでもよさそう。実質はラッパメソッドでキャッチして completeExceptionally するのと変わりない。

その他

検査例外をうまく生かしつつ処理するというのが難しそう。各ステージで検査例外は全て処理するというのが想定されているのだろうか? とりあえず全部 catch して uncheck にするというのをやっていると、当然検査例外をまともに処理しようという気にはならなくなる。

検索例外を投げるメソッドは、直接メソッド参照のスタイルで runAsync(this::FooBar) 等と渡せない。

  1. トップ
  2. tech
  3. CompletableFuture と例外
  1. トップ
  2. java
  3. CompletableFuture と例外

(実質的な) 非接続状態のことをハイインピーダンス (Hi-Z) 状態 (Tri-state) と言う。久しぶりに触ると、どうすれば Hi-Z になるんだっけ??となるのでメモしておく

Arduino 風にいうと、

  • DDxn は pinMode(XX, INPUT | OUTPUT);
  • PORTxn は digitalWrite(XX, LOW | HIGH);
  • PUD (in MCUCR) はプルアップの有効化を決めるフラグだけど普通は有効にしとくので気にしない (Pull-up Disable フラグ、1でdisableされる)

プルアップ有効のケースだと、pinMode が INPUT かつ digitalWrite で LOW したピンはハイインピーダンス

  1. トップ
  2. tech
  3. Arduino / AVR でコード上からピンを非接続状態とする

続きをかきました [tech] Quick Charge 2.0 電源から 9V をとる (任意の電圧をとる) | Mon, Dec 14. 2015 - 氾濫原

仕様はちょっと前に調べて、先日対応バッテリーがきたので試してみました。

[Qualcomm認証済み]Aukey モバイルバッテリー 大容量 10400mAh スマホ充電器 [Quick Charge 2.0対応] 急速充電可能 (シルバー)PB-T1 -

3.0 / 5.0

回路図

12V を出す場合必要なのは D+ 0.6V / D- 0.6V なので、非常に簡単な構成。

VBUS には QC時に 5V〜12V の電圧がかかる。直接 Arduino の VIN に繋いでいるが、Arduino 側で 5V レギュレータが入っているので問題ない (ref. https://www.arduino.cc/en/uploads/Main/ArduinoNano30Schematic.pdf )。当然 5V ピンに直接繋いではならない (燃える)

コード

#include <Arduino.h>
#include <avr/sleep.h>

const int D_PLUS  = 11;
const int D_MINUS = 12;

/**
 * Arduino nano has 5V regulated power, so required voltages are generated with:
 * 3.3V: 4.7kΩ / 9.1kΩ
 * 0.6V: 1.1kΩ / 150Ω
 *
 */

void setup() {
	// wait until stable connection
	delay(1000);

	// reset line
	pinMode(D_PLUS, OUTPUT);
	pinMode(D_MINUS, OUTPUT);
	digitalWrite(D_PLUS, LOW);
	digitalWrite(D_MINUS, LOW);
	delay(100);

	// D+ and D- to 0.6V for 1.25s
	digitalWrite(D_PLUS, HIGH);
	digitalWrite(D_MINUS, HIGH);
	delay(1500);

	// D- to 0V for 1ms
	digitalWrite(D_MINUS, LOW);
	delay(2);

	// Set voltage
	digitalWrite(D_MINUS, HIGH);

	set_sleep_mode(SLEEP_MODE_PWR_DOWN);
	sleep_mode();
}

void loop() {
}

結果

12V とれたよ〜 (赤が VBUS、黄は D-)

備考

9V に対応する場合 D+ を途中から 0.6V -> 3.3V とする必要があるので、もう少し回路とコードが必要。

  1. トップ
  2. tech
  3. Quick Charge 2.0 電源から 12V とる