2020/08/22(土)javascript の fetch と XMLHttpRequest

今回は、これにちょっと嵌ったので自分メモ。
fetch も XMLHttpRequest も Javascript 内でWebサーバと通信処理が出来る便利な機能で
ちょっと前は「Ajax」とか言ってもてはやされたものですが、今はほぼ死語でしょうかね。
それでも今はWebサイトでちょっとしたことをするには欠かせなくなってきているもの。

今回は、オンラインでの画像編集機能をサイト内にて実現するために、
最初は fetch による以下のコードを書きました(一部を公開用に変更部分あり):
async function gosub_canvasimg(serial,imgblob) {
  var responce = await (await fetch('/editor.cgi', {
                          method : 'POST',
                          cache  : 'no-cache',
                          headers : {'Content-Type' : 'application/x-www-form-urlencoded' } ,
                          body   : 'imgblob=' + imgblob ;
                         })).text() ;
  if (responce != 'valid') {
    alert(serial + "つめの画像ファイル保存に失敗しました。" );
  }
}
ところが、これだと、
Uncaught (in promise) TypeError: NetworkError when attempting to fetch resource.
というエラーが出て、fetch 自体が実行されないのです。*1
これは、拙作のシステムにて「画像があるはずだが、編集画面で表示されない」という現象を作り出す直接原因になっていました。

同期処理でないと、編集時に不具合が更に出るので、こうしています。
『同期処理なんぞ殆ど使われません』と大声で叫ぶサイトなんかも散見されますが、
それはよほど精通している方か、同期処理の必要な案件に出会ったことが無い方なのでしょう。
少なくともハードウェアの制御がシステム全体として絡んで来ると、同期処理はどうやっても必須。

結局、fetch がエラーになる原因は判らず仕舞いで、fetch のところを同じ処理になるように、
async function gosub_canvasimg(serial,imgblob) {
  var imgxhr  = new XMLHttpRequest() ;
  var msgbody = 'imgblob=' + imgblob ;

  imgxhr.open('POST', '/editor.cgi', false) ;
  imgxhr.send(msgbody) ;
  var responce = imgxhr.response ;

  if (responce != 'valid') {
    alert(serial + "つめの画像ファイル保存に失敗しました。" );
  }
}
みたいな感じにすると、エラーは出なくなった模様。
これで不具合は出なくなったと思うが様子見です。
fetch の実装バグなのか、「同期方式」という使い方が悪いのか調べても全く判らないのです。

やっぱり XMLHttpRequest() のほうが断然判りやすい。
fetch は Promise という挙動の概念を理解しなければならず、これが当方にはあまり直感的ではなく判りずらさの極みです。これを使いこなせないのがこの顛末の一因でしょう。

何せ、類似の事例が殆ど表に出てきていない案件なので、エンドユーザに動作検証してもらうという暴挙を敢行するしかないのです。

*1 : 当方は英語が苦手なので、日本語表示がある程度出来る Firefox でデバッグをしています. chrome のデバッガは、英語だらけで正直発狂しそうになります...

2020/03/17(火)中華なオシロスコープを使いこなす(2)

さすがに最近のオシロスコープは、画像保存が出来るようになっている模様。
先日の記事と同じような画になってしまったのですが。。
20200317.png


ブラウン管オシロスコープな時代は、専用の道具を使いつつ、写真撮影していたものです。
USB端子が付いており、そこにUSBメモリを挿すと、オシロスコープ側で保存した画像をコピー&ペーストで取得できます。

ただ、ここからが中華らしい曲者で、、、orz
USBメモリにコピーしたはいいが、PC側で読み込みしようとすると、
「このドライブで問題が見つかりました。今すぐドライブをスキャンして修復してください。」
みたいなメッセージが出る。しかし、スキャンすると・・・「問題は見つかりませんでした。」
なんだこれ、、、更に、右端側のメニューが消えない。邪魔だ、、、

右端側のメニューがない状態で記録出来ないものか。。
ご存知のかた誰か教えてください・・。orz

2020/03/11(水)中華なオシロスコープを使いこなす(1)

最近のオシロスコープは、色々な機能が付随しています。
20200311.JPG


これは、プロトコルアナライザ。
今も昔も広く使われている RS-232C 信号線で、どういうデータが流れているかを解析した様子。
他にSPI だの I2C だのといったものが使える模様。見慣れないものもあります。

データを取得するときのトリガの掛け方(早い話、データを取得するタイミングをどう設定するか)が今ひとつ慣れていないが、こんなことができるという確認。
間違った解析をしていないのを確認。

あと、リアルタイムで電圧や周波数(周期)なんかも表示できます。
更に、ヒストグラムとFFT機能があるのですが、この2つは使う機会が出てくるのかどうか何とも・・です。
ただ、試作中の技術的評価には使えるかな、といったところ。

2020/03/09(月)中華製なオシロスコープを入手した

永年欲しくても買えずにいたオシロスコープを、やっとの思いで購入。
絶対額が安くはないんですが、業務を全うするのに必要なのです。(この機種でもどちらかといえば安いほう)
これ無いと、電子回路の設計・開発に大きな支障あるんですが、今までこれ無しでやってきたのです。
オシロスコープ使わずに電子回路の設計・開発が出来たのは奇跡以外の何物でもないのです。(本当に、、、)
当然のことながら、受注業務の技術的限界を感じていました。

でもこれ、中華メーカなんだよね。。ただ、評判はそれほど悪くはないようなので・・・
20200309_1.jpg

20200309_2.jpg


設置場所確保するだけで徹夜になってしまいました。orz
Amazon で購入したんですが、中華なところから成田空港経由の空輸で製造元にて二重梱包されていました。
梱包材破損のクレームが過去にあったからですかね。。

これからセットアップです。

2020/03/08(日)XML ファイルを解析する perl モジュール

現在の作業が落ち着いたところで、
2年近くずーっと延期していたWeb気象通報サイトの抜本的改築を行おうと考えています。

元データはXML形式のファイルで、技術的にこれを逐次解析処理する必要があります。
そこで作業準備にあたり、どのXMLライブラリを主力にするかの検討からなのです。

現状、Perl5 では下記のXMLライブラリがあり、依存する汎用ライブラリが異なります:

XML::Simple libexpat が必要
XML::Parser libexpat が必要
XML::DOM   libexpat が必要
XML::LibXML libxml2 が必要
XML::Feed  libxml2 と libexpat の両方必要
#他にもあるが、最終更新日時が古い・事例が殆ど無いなどの理由で最初から却下。

libexpat も libxml2 も XMLを処理するC言語ベースのライブラリで、
Perlで実現するXML処理は、単にこれらのライブラリとの仲介をしているだけに過ぎないです。

ですが、その処理手法が異なっており、libexpat を使うモジュールは、libexpat そのものの構造からして

・巨大なXMLをパース(解析)できない
・複雑なデータ構造のXMLをパースできない

という問題があるようで、これは今回のプロダクションには採用できない(しないほうが無難)模様。
また、XML::Feed は、複雑なデータ構造のXMLパースは機能しないという報告もあり、
昔から標準的で実績豊富とされている XML::LibXML というところに落ち着く形ですね。

ただ、ちょっと使いにくそうです。

2020/03/01(日)XBee のプログラマブルモジュールとノーマルタイプの違い《お勧めは「ノーマルタイプ」!!》

依頼元などは公表出来ませんが、
昨年からこの無線通信モジュールを使用するシステム開発に関わっています。
実際に関わってみると、何と言っても「これほど判りずらいモジュールはない!!」という印象が強いです。
日本語による情報が殆ど無い、説明書通りの挙動をしない、情報が古い、という現状も判りずらさを助長しています。
更に、名前の紛らわしさが判りずらさを更に助長しています。
XBee (「じぐびいぃ」と発音する模様)は、この無線モジュールの商標だが、ZigBee はXBee が採用している通信規格。発音が日本人に言わせると全く同じ。

更に XBee と書いて別の読み方をする日本メーカの小型乗用車なんかもあって、調べる際に結構な割合で検索結果に混同してきます。

そもそも、ノーマル版とPro版が先ず最初にあり、これは無線通信の電波の強さの違いのようです。
Pro 版の方が高出力で通信距離を稼げます。
要するに、「Pro版」はプログラマブルモジュールのことではなく、「高出力版」ということのようです。

次に、ノーマル版とプログラマブルモジュール版があります。
プログラマブルモジュールは、機能的にはMicrochip社のPIC16FシリーズとPIC18Fシリーズの中間的な機能を有するマイコンが内蔵され、こういうのに欲張りな当方は「値段が殆ど同じなら、プログラマブルモジュールを使う」という選択肢が自然と行くのですが、これは駄目です。全くお勧めできません。とても苦労する羽目になります。

先駆者諸氏のブログ等を拝見すると、当方と同じような思考で結果的に使用を断念してしまったり、間違って購入して苦労しているのを散見します。
両者はよくよく見ないと区別できないのもこの状況を助長しています。

ここで、「ノーマルタイプ」と「プログラマブルモジュール」を並べた様子です。
20200301_1.jpg


全く『違い』が判りませんね。実は、裏面を見ると辛うじて判ります:
20200301_2.jpg


型番の最後が
「003」になっているのが「プログラマブルモジュールなXBee」、
「004」になっているのが「ノーマルタイプの XBee」なのです。(赤枠で囲った部分)

こういうのは、表に大きな文字で型番を印刷するとか、色を変えるとかして区別できるようにするべきだと個人的には思います。

蛇足ですが、プログラマブルモジュールに内蔵しているマイコンは、Freescale社の MC9508QE32CFT という型番のマイコンのようです。
実は、XBee プログラマブルモジュール用のSDK(プログラム開発ツール)が無償提供されてはいるのですが、
全く使えないのです。どうもCコンパイラが吐き出す命令コードがおかしい。
サブルーチンの前後で引数が突然変わるんです。
何か回避できるトリックがあるのでしょうが、そういうのも見当たらず、一般人には使い物にならない。
これは想定外の大きな誤算でした。

どうりで XBee プログラマブルモジュールの応用事例が殆ど皆無なわけです。
メーカの方でもそういうのは判っていると思うのですが・・・ 現状は何も対策無しです。
なので、プログラマブルモジュールの XBee は、現状ではお勧めできないわけです。

2020/01/23(木)Raspberry Pi 3 Model B+ FreeBSD12.1 その他の情報

雑多な情報を、書き残しておきます。

・FreeBSD RaspBerry Pi 3 は FreeBSD/ARM 対応プロジェクトの一環で開発作業が続けられており、
 位置づけは、Tire 2 となっています。
 従って、Tire 1 サポート(i386、amd64 が該当)のみとなっている FreeBSD UPDATE は使えません。

・FreeBSD/ARM 対応プロジェクトは、Tire 1 に乗せる準備が進められている模様。
 FreeBSD が組み込み機器用途で使用できる最初のプラットフォームになれるかも。

・FreeBSD における GPIO 制御は、gpioctl コマンドが使用できます。
 Perl には、これと同じことを Perl スクリプトで行うための Device::BCM2835 なるモジュールや、
 RPi::Pin、WiringPi::API などありますが、FreeBSD12.1 ではどれも使えません。

 以下のような感じでピン情報を取得します(例):
  $result = qx(gpioctl -l) ;
  chomp ($result) ;
  my @iostat = split("\n",$result) ;

  foreach my $getpin (@iostat) {
    $getpin =~ /\Apin\s(\d+):\s+(\d)/ ;
    next if ($pinnum ne $1) ;
    $lvlstat = $2 ;
    last ;
  }
# $pinnum に文字列でピン番号を与え、$lvlstat に 0か1 が入ります。
# 0 がL、1 がHです。

2020/01/23(木)Raspberry Pi 3 Model B+ に FreeBSD12.1 をインストール (3)

次は、任意でユーザ環境の設定です。
.cshrc や .profile でお好みな環境をセットアップしますが、ここは個人の好みの部分なので、
説明省略。

筆者の環境では、基本的に Perl5 を使いたいので、
このあと、ports にてパッケージインストールを行います。
以下のような感じで root ユーザにて導入します:
# cd /usr
# mkdir ports
# portsnap fetch extract
# cd /usr/ports/editors/vim-console
# make install
# make clean

# cd /usr/ports/misc/lv
# make install
# make clean

# cd /usr/ports/ports-mgmt/portupgrade
# make install
# make clean
portupgrade のインストールにて、依存するパッケージとして、ruby や Perl がインストールされます。

途中、青地画面で、インストールオプションの選択画面が何度か出るが、適当にデフォルト値に任せずに、必ず内容を確認して作業しましょう。

2020/01/23(木)Raspberry Pi 3 Model B+ に FreeBSD12.1 をインストール (2)

起動ができるようになったら、次の段階として、設定を行います。
/etc/rc.conf に最初に記述されている、イーサネット関連のデフォルト設定値は、
ifconfig_DEFAULT="DHCP"
となっています。
この状態で起動すると、DHCPネゴシエーションで通知された参照用DNS設定ファイル /etc/resolv.conf が自動生成されています。
当然のことながら、LAN上にDHCPサーバが無い場合、このファイルは自動生成されません。

筆者の場合は以下のようになりました:
search deverop.basekernel.ne.jp
nameserver xxx.xxx.xxx.xxx
nameserver yyy.yyy.yyy.yyy
#セキュリティ対策上、IPアドレスは伏せてあります。

見てのとおり、IPv4 で機能しています。
適宜変更が必要かもしれません。

先ずは、ユーザ名 freebsd の削除・変更と、root パスワードの変更。
初期値は、ユーザ名 freebsd パスワード freebsd でログインでき、root のパスワードは、root なので、変更すべきです。(メンテナンスを簡単に始められるようにこうなっている)

先ず、ユーザ名 freebsd を削除して、新たに任意のユーザ名を追加、root のパスワードは変更しましょう。
更に、/etc/group の wheel 行に、root ユーザになれるように 新たに追加した任意のユーザ名を追加し、ユーザ名 freebsd は削除することを忘れないように。

次に /etc/rc.conf の変更。以下のようにします:
hostname="bypass_ctl"
defaultrouter="172.16.15.1"
ifconfig_ue0="inet 172.16.15.188 netmask 0xffffff00"

ntpd_enable="YES"
ntpd_sync_on_start="YES"

inetd_enable="YES"
sendmail_enable="NONE"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"
growfs_enable="YES"

keymap="jp.kbd"
ホスト名、IPアドレスやネットマスク、デフォルトルータあたりの設定は、使用中のネットワークポリシーに合わせます。
/etc/ntp.conf はデフォルト値でも大丈夫ですが、ネットワーク内に公開NTPサーバがある場合や、指定されている場合は、そのサーバを設定します。

基本インストールの最後に、タイムゾーンの設定です。
日本時間の指定は、以下のコマンドを root ユーザにて実行します:
# tzsetup /usr/share/zoneinfo/Asia/Tokyo
一度設定すれば、次回の起動以後もこのタイムゾーンで動作します。
設定の最後に
# shutdown -r now
で、再起動します。