HHD Free Serial Port Monitor

Windows PCのシリアルポート(仮想COMポートを含む)の送受信データを傍受してモニタできるツール。コンソール表示、Hex/ASCII表示など種々の形式でモニタできる。
freeserialanalyzer.com

Free Serial Analyzerという名前になっているが、このソフトはHHD社のDevice Monitoring Studioという製品群のSerial Port MonitorのFree版という位置づけである。
www.hhdsoftware.com

Free版の制約は以下の2点。ただし、最初の14日間は無制限で利用できる。

  • 1セッションは20分まで
  • 1日に5セッションまで

1セッション20分まではともかく、1日5セッションまでというの制約はかなり辛いように思う。使ってみて良さげなら製品版の購入を検討すべきか。

Arduinoのハードウェアシリアルのボーレート誤差

AVR 5V(16MHz)系 (Uno, Mega, Leonardo, Micro, Pro Mini 5V など)

ボーレート設定 実際のボーレート 誤差[%]
9600 9615.4 0.16
19200 19230.8 0.16
38400 38461.5 0.16
57600 58823.5 2.12
115200 117647.1 2.12
230400 222222.2 3.55

基本的には倍速動作で設定されます。倍速動作では8クロックで1ビット、標準動作では16クロックで1ビットとなります。倍速動作は標準動作よりクロックとボーレートの精度要求が厳しいです。

ボーレート57600の場合のみ特別に分周比の計算が異なります。HardwareSerial::begin()のソースのコメントのよると、「Duemilanoveやそれ以前に出荷されたボードのブートローダ、およびUnoやMega 2560上の8U2のファームウェアとの互換性のため」だそうです。倍速動作でボーレート57142.9 (誤差0.79%)に設定可能であるのに、標準動作でボーレート58823.5 (誤差2.12%)に設定しています。

また、ボーレート488以下の場合は倍速動作では設定できないので標準動作で設定されますが、そんな低いボーレートを使うことはあまりないでしょう。

AVR 3.3V(8MHz)系 (Pro Mini 3.3Vなど)

ボーレート設定 実際のボーレート 誤差[%]
9600 9615.4 0.16
19200 19230.8 0.16
38400 38461.5 0.16
57600 58823.5 2.12
115200 111111.1 3.55
230400 250000.0 8.51

AVR 3.3V系はAVR 5V系よりシステムクロック周波数が低いので、通信可能なボーレートの上限も低くなります。ボーレート115200は使えないと言ってよいでしょう。(AVR 3.3V系どうしで通信するなら使えますが。)

基本的には「倍速動作」で設定されます。ボーレート244以下の場合は倍速動作では設定できないので標準動作で設定されますが、そんな低いボーレートを使うことはあまりないでしょう。

SAM(84MHz)系 (DUE)

ボーレート設定 実際のボーレート 誤差[%]
9600 9615.4 0.16
19200 19230.8 0.16
38400 38602.9 0.53
57600 57692.3 0.16
115200 116666.7 1.27
230400 238636.4 3.57

SAM系のHardwareSerial::begin()の実装にはかなり問題があります。ボーレートの分周比が四捨五入でなく切り捨てで計算されているため、誤差が不当に大きくなってしまう場合があります。Arduino SAM Boards バージョン1.6.12で確認しました。

SAMはシステムクロック周波数が高いため、115200以下の一般的なボーレートではほぼ問題になりませんが、115200を超える高いボーレートを設定したい場合には問題になる場合があります。例えば、ボーレート230400に設定したい場合、228260.9(誤差0.93%)に設定できるにもかかわらず、238636.4(誤差3.57%)に設定されてしまいます。

苦し紛れですが、下記のような関数を使って四捨五入計算相当のボーレートを設定することができます。

#include <stdint.h>

uint32_t SAM_BAUD_FIX(uint32_t baud) {
  uint32_t ret = (uint32_t)(
    (double)SystemCoreClock * (double)baud / (double)(SystemCoreClock + 8*baud)
  );
  return ret;
}

void setup() {
  Serial1.begin(SAM_BAUD_FIX(230400));
}

画像ビューア・加工ツールまとめ

IrfanView

  • 昔からある定番ソフト。メインの画像ビューアとして使ってる。
  • 色調補正やリサイズ・トリミング、フィルタといった一通りの加工機能はそろってる。
  • 複数のファイルの一括変換機能もある。(例:座標を指定して一括トリミング)
  • 透過PNGの扱いは苦手?

forest.watch.impress.co.jp

Ralpha

  • 複数のファイルの一括リサイズ・トリミングなどの加工ができる。
  • 特に透過PNGを扱うときに使ってる。
  • IrfanViewにないトーンカーブもある。

www.vector.co.jp

Jcropper

  • JPEGを劣化なくトリミングができる。

www.vector.co.jp

XnRetro

  • 写真をレトロ調に加工できるツール

www.vector.co.jp

メモ:C#でスレッド

今どきはC#ならasync/awaitが使えるのでThreadを使う機会は減ったけどやはり使う時は使うものである。たまにしか使わないと忘れるのでメモ。

(1) スレッドの起動

ThreadStartというデリゲートを使うのがポイント。というかC#の妙ちくりんなところ。短い処理であればラムダ式で書いた方が簡潔。

using System.Threading;
    Thread threadHoge;
    // スレッドの起動
    threadHoge = new Thread(new ThreadStart(funcHoge));
    threadHoge.Start();
    private void funcHoge()
    {
        // スレッドの処理
    }

(2) スレッドの終了待ち合わせ

    // スレッドの終了待ち合わせ
    threadHoge.Join();

(3) スレッドからUIを操作

メインスレッド(UIスレッド)以外のスレッドからUIを操作するにはInvokeまたはBeginInvokeを使う。Actionというデリゲートを使うのがポイント。というかC#の妙ちくりんなところ。たいていは数行ですむのでラムダ式で書くと簡潔だが、ラムダ式そのものを引数にはできない。
Invokeなら同期、BeginInvokeなら非同期で処理される。

    // 同期処理
    this.Invoke((Action)(() => {
        textboxHoge.Text = "Hoge";
    }));
    // 非同期処理
    this.BeginInvoke((Action)(() => {
        textboxHoge.Text = "Hoge";
    }));

(4) 排他処理

ロック用のオブジェクトを定義してロックする。デッドロックに注意。(イベントハンドラはスレッドでないことに注意。)

    // ロック用オブジェクト
    object lockobj = new object();
    lock(lockobj )
    {
        // 排他処理
    }

FTDIのUSBシリアル変換ICのCBUSの機能割り当て

FTDIのUSBシリアル変換ICのCBUSxピンには種々の機能を割り当てることができます。
FT232RLの場合、デフォルトでは下表の機能が割り当てられています。

ピン 機能 説明
CBUS0 TXLED# 送信データLED駆動 (Lowアクティブ)
CBUS1 RXLED# 受信データLED駆動 (Lowアクティブ)
CBUS2 TXDEN RS-485用の送信データイネーブル(DE)
CBUS3 PWREN# 電源イネーブル (Lowアクティブ)
起動後Lowになり、USBサスペンド中はHighになる。
Pch MOSFETで外部回路の電源を制御するのに使える。
CBUS4 SLEEP# スリープ (Lowアクティブ)
USBサスペンド中はLowになる。

機能割り当てはIC内部のEEPROMに記憶されています。
これを変更するにはFTDIが提供するユーティリティー「FT_PROG - EEPROM Programming Utility」を使用します。

FT_PROGによる機能割り当ての変更

  • 下記サイトよりFT_PROGをダウンロードしてインストールします。
  • FT_PROGを起動します。
  • 「EEPROM」タブの「DEVICES」メニューから「Scan and Parse」を実行します。
  • USBに接続されているFTDIデバイスが「Device Tree」に列挙されます。
  • 所望のデバイスの「FT EEPROM」>「Hardware Specific」>「IO Controls」を開く。
  • C0~C4(FT232RLの場合)の機能割り当てが表示されるので、適宜変更します。
  • 「DEVICES」メニューから「Program」を実行します。
  • 「Program Devices」ダイアログが開くので「Program」ボタンを押します。

f:id:licheng:20190312210226p:plain

メモ:モータのトルク定数と逆起電力定数

  • モータのトルク定数と逆起電力定数は理論上は一致する
  • トルク定数の単位は Nm/A (単位電流あたりのトルク)
  • 逆起電力定数の単位は V/rpm (単位回転数あたりの逆起電力)
  • 換算式 1 Nm/A = (2π/60) V/rpm
  • DC電圧[Vdc] か 実効値電圧[Vrms] かも要注意

f:id:licheng:20201214230340j:plain:w500
【2020/12/14】訂正
f:id:licheng:20201214230513j:plain:w500

ブラウザでMQTTクライアント (Paho)

Pahoとは

PahoとはオープンソースのMQTTクライアントのライブラリです。Pahoはさまざまな言語で実装されています。(Java, Python, JavaScript, C, C++, C#, Goなど) 今回はブラウザベースで使えるJavaScript版の使い方を説明します。JavaScript版Pahoは、MQTT over WebSocketプロトコルを使っており、MQTTブローカーとの通信はWebSocket上でおこなわれます。当然ながらMQTTブローカー側がMQTT over WebSocketに対応している必要があります。
www.eclipse.org

ダウンロード

JavaScript版の説明は下記のページにあります。

ダウンロードは下記のページの「JavaScript client x.x.x」のリンクからできます。

paho.javascript-x.x.x.zipを解凍すると、フル版のpaho-mqtt.jsと圧縮版のpaho-mqtt-min.jsが得られます。これがJavaScript版Pahoライブラリです。これを自分のWebアプリに配置して使います。上記の説明ページにはソースからのビルド方法についても書かれていますが、なんのことかよく分からないので今回は無視します。

CDNでの利用

または、CDNで配信されているものを利用する方法もあります。ただし、少しバージョンが古いようです。

<!-- フル版 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js" type="text/javascript"></script>
<!-- 圧縮版 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js" type="text/javascript"></script>

使い方

  // MQTTクライアント生成
  var client = new Paho.MQTT.Client(
    "MQTTブローカーのドメイン",
    WebSocketポート番号,
    "web_" + parseInt(Math.random() * 100, 10));

  // コールバックの定義
  client.onConnectionLost = onConnectionLost; // 接続が切れたとき
  client.onMessageArrived = onMessageArrived; // メッセージ受信したとき

  // 接続
  var options = {
    useSSL: true,
    userName: "ユーザー名",
    password: "パスワード",
    onSuccess:onConnect, // 接続したときのコールバック
    onFailure:doFail // 失敗したときのコールバック
  }
  client.connect(options);

  // 接続したとき
  function onConnect() {
    console.log("onConnect");
    
    // トピックを購読する
    client.subscribe("トピック名");
    
    // トピックにメッセージを発行してみる
    message = new Paho.MQTT.Message("Hello, World!");
    message.destinationName = "トピック名";
    client.send(message);
  }
  
  // 失敗したとき
  function doFail(e){
    console.log(e);
  }

  // 接続が切れたとき
  function onConnectionLost(responseObject) {
    if (responseObject.errorCode !== 0) {
      console.log("onConnectionLost:"+responseObject.errorMessage);
    }
  }

  // メッセージを受信したとき
  function onMessageArrived(message) {
    console.log("onMessageArrived:"+message.payloadString);
  }

リファレンスドキュメント