2019年3月22日金曜日

SwiftからMetalへFloatの値を渡す(仮)

縦横比は無視(こういう演出なので)

(仮)がついているのは、「とりあえず動いたけど正しいかわからない」というツッコミ待ちフラグを示します。堤修一さんの「Metal入門」を読んでいることが前提です。

最初に結果を書きます。そのあとはほぼ雑談です。

まず、swift側のコード。drawの中です。valueが渡したい値で最初にバッファを定義して
        // バッファを作成
        var valueBuffer: MTLBuffer!
        let value:[Float] = [0.5]
        let size = MemoryLayout.size
        valueBuffer = device.makeBuffer(bytes: value, length: size)
次に生成したエンコーダーにセットします。
        renderEncoder.setFragmentBuffer(valueBuffer, offset: 0, index: 0)
.metal側
fragment float4 fragmentShader(ColorInOut       in       [[ stage_in ]],
                               texture2d texture  [[ texture(0) ]],
                               device float     *fBuffer [[ buffer(0) ]])
{
    float f = fBuffer[0];

fに値が入ります。めでたしめでたし。

[[ ]] の中の修飾子がどういう働きをしているのか理解できていなかったんですが…これ、GPUとCPUの共有メモリにtexure[0], [1], [2]....、vertex_id、buffer[0], buffer[1], buffer[2]....のような領域があって、
device float     *fBuffer [[ buffer(0) ]]
って書いた場合、「0番目のbuffer領域のアドレスをfloatのポインタfBufferにセットする」って意味なんですね。で、Swift側ではサイズとx番目かを示してデータをセットすれば、metal側ではそれをポインタ渡しみたいな形で受け取れる。

わかってしまえば簡単なんですが…いやー、苦労したたたた。

■背景■

「Metal入門」という本を読みつつ、Metalのお勉強をしています。お勉強中ですが、同僚のM氏から「作って」と言われている課題をこなさなければいけないので必死です。

その課題は撮影した画像をRGBとグレイに分割して、それらを重ねつつ動かすというやつです。CIFilterなどを探してみたのですが、どうにも上手く行かず、Metal様におすがりしました。

で、「Metal入門」を拾い読みして(それがいかんのだ)、fragment shaderを使えば画像の任意の点の色情報を取得し、それを最終的な描画位置の色として加工して返す、という処理が記述できることがわかった…のは良いですが、アニメーションとして処理したいのでCPUからパラメータを渡す必要があり、その方法を探していた次第です。

この記事が誰かの役に立ちますよーに。

■余談■

MSLでもif文書けるんですね。やってみたらエラーでないで意図した通りに動いたので思わずユーレカーと叫びながら表を走ってしまうところでした。ベクトルプロセッサだから無理だろと思って無駄な苦労してました。もちろん、GPUを使う上ではもっと効率のいい方法なんかもあるんでしょうけども、不勉強な凡夫として助かっております。

とりあえずfragmentShaderの実装については「今度、ここの座標の色を教えろや」って上位からドットの数だけ呼ばれるので、textureとして受け取った画像からsamplerを使って元画像の色の値を取り出し、そのカラー値(r, g, b, a)を返せば元画像がそのまま描画されるし、color = float4(red, 0, 0, 1)を返せば赤プレーンだけの値が返される…ということがわかって、そこから何とか書けるようになった感じです。

いやー…奥が深い。私基本的に業務系アプリ屋なんで、Metalのお勉強してもあんまり役に立たないんですけどねw でも、何かあったらお仕事いただければ幸いですm(_ _)m

2019年3月9日土曜日

受託開発もやってます

宣伝です。ココナラハンドメイドなどでハードウェアの受託開発をやっています。下記はいずれもブログ公開を許可していただいたもの。TwitterやFacebookでご依頼いただいてAmazonギフトやPayPalで決済することが多かったのですが、今年は少しココナラハンドメイドの実績を増やしていこうという魂胆でございます。

以下2018年の主な実績です。公開の許可をいただいた関係で何故かArduino nanoが多くなりましたが、ESP32、LPC1114やRaspberry pi用拡張ボードも同数あります。

これはATMega328とSakuraのIoTモジュールを搭載した基板です。0.4mmピッチのSIMモジュールコネクタが難物でしたが、ステンシルプリンターとリフロー炉を導入したことで歩留まりが一気に上る契機になりました(導入後リフローおよび手ハンダによる不良はQFNやVSONパッケージも含めてゼロです)。現在、ESP32-WROVER-IとSakura IoTモジュールを簡単に使える基板を製作中です。

これは、スイッチ2個の状態に応じてランプを表示させる装置のメイン部分。ご覧の通り、Arduino nanoの互換機で作っています。

またUnoです。マイクからの入力をFFT処理してノイズ部分をカットした後、エネルギーレベルが一定以上を越えたらリレーをONにして電力機器を動かすデバイスです。インジケーターは赤緑LEDで3色表示、音量の閾値とON継続時間はロータリーDIP SWでデジタル指定する方式です。

ラズパイを使った、工場ライン用ファームウェア書き込みの試作機です。ESP32の基板を接続してから緑ボタンを押すと自動的にpythonスクリプトで書き込みが始まり、終わると簡単な検査を行って正常だとグリーンランプが点灯します。ラズパイはSD Card保護のためRead Only + RAM DISK化してあります。これを原型としたコピー機が中国・深圳にて実際の生産ライン(1万台規模)で使用されました。なお、マステで説明書いてますけど…超特急のご依頼だったので(遠い目

DFPlayer + Arduino unoを使った音源デバイスです。センサーで一定の条件になると録音した音声が流れます。DFPlayer、間違えて100個注文してしまったので、大量に余ってます。お仕事ください(必死)。ちなみに余ったやつを使ってカラスが猛禽類に襲われている音声を録音してときどき流すようにしたらカラスがまったく来なくなりました。カラスを撃退するためにはタイマーで同じ音声を適当に流すのではなく、複数仕込んでおきセンサーに反応させて流すと効果が高いようです。

最後に、サラリーマン業で作ったものです。Hamicベアって商品名です。私はプロトタイプ〜製品版ファームウェア担当者の一人で、ハードウェアについてもちょこっと口出ししました。

単価は1万円〜10万円です。以下ページからダイレクトメッセージをお送り下さい。相談は無料ですので、どぞお気軽に。

RX8900、時計メーカーのICすげえ

紅い基板がRX8900

RX8900は、DXCXO内蔵高精度リアルタイムクロックです。温度補正され、出荷時に周波数調整されているのでトリムなしに高精度(公称月差9秒)で働くRTC ICです。

バッテリバックアップ性能を試してみました。

RX8900は、Vbat端子が独立していて電気二重層キャパシタの場合抵抗を1本つけるだけで充電・バックアップが可能になります。リチウム一次電池などの場合には充電阻止のダイオードが必要です。

買い置きの1Fの電気二重層と抵抗を直列にして、Vbatに接続し、時刻をセットしたあとVccを切ってそのまま放置します。キャパシタの電圧を見てると直後に2.4Vまで下がってバックアップモードに入り、その後はごくゆっくり電圧が下がっていきます。

72時間後の電圧は1.656Vでした。最低電圧1.6Vとのことなので、まだ余裕です。

マイコンを接続して時刻を読み出したところ…見事に経時されていました。いやー…すごいですね。いま、製品としてデジタル時計を作っているところなので、しっかり働いてもらおうと思います。

追記:96時間での計測を忘れて104時間後に計測したところ1.44Vでした。もうダメかと思ったのですが、ちゃんと正確にときを刻んでいました。さすが、墜落した飛行機が海底から引き上げられた際にも動いていたというSEIKOの子孫ですね!



2019年3月1日金曜日

IO12に気をつけて!(ESP32への書き込みが出来ない件)

おまえーがー 生まれたーときー …きれいな基板だったんだぜ

初期の通信はネゴシエーションはできるのですが、その後以下のエラーがでます。

esptool.py v2.6-beta1
Serial port /dev/cu.usbserial-DN0483G4
Connecting.....
Chip is ESP32D0WDQ5 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, BLK3 partially reserved, Coding Scheme 3/4
MAC: 30:ae:a4:c6:88:50
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Configuring flash size...
Warning: Could not auto-detect Flash size (FlashID=0xffffff, SizeID=0xff), defaulting to 4MB
Compressed 8192 bytes to 47...
A fatal error occurred: Timed out waiting for packet content

結果を先に書くと、IO12をプルアップしていたのが原因でした。プルアップしているとSPI Flashが1.8Vモードになってしまうので、書き込みできなくなります。
Cannot Download to ESP-WROVER-KIT

てことで、配線をカットしたら無事動きました…。

ほぼ同じ設計の基板が問題なく動いているので、リフローの不良を疑ってコテを全ピンに当ててみたり、果てはESP32-WROVERを交換してみたりしたのですが…そりゃー動きませんよね。

あとで思い返してみると、上の赤字の行の2つ上にwarningが出ていますが、これはFlashへの書き込みができないからサイズ検出が働いていなかったのでしょう。

いやー…アホでした…いつもは気をつけて使わないようにしているピンですが、GPIOを使い切ってしまって、その後、布線の都合で大スワップ大会になってしまい、いつの間にか使っていました…。

ESP32チップの交換

ソフト屋なのかハード屋なのかはっきりしろ!な机
カプトンテープで軽く周囲をカバーしてからリワークステーションで加熱。プリヒートで150度ぐらいに温めてから280度の温風で溶かします。ESP32-WROVERは私が外した部品のうちで最大級なのですが、風量とか温度にノウハウないと難しいですね…今回は外した部品を再利用しないので壊れても良いんですが…。


外した後は、吸い取り線とハンダゴテでお掃除。この写真でいえば吸い取り線を縦に置いて、一番上のピンの上側にハンダゴテを当てます。溶けるとコテが下に動かせるようになるので次のピンへと順次吸い取っていきます。なお写真でみてGNDが残っていることに気づいてもうちょっと掃除しました。ハンダを吸い取った後はフラックスクリーナーで清掃します。

右上1箇所にだけハンダを盛り、手で左手でチップを抑えながら右手ではんだ付けします。ズレていないことを確認しながら、右下にもはんだ付けします。動かなくなったら、シリンジではんだペーストを塗っていきます。細い針が見つからなかったので、どうも汚いな。


あとは、一番上から下へ、ハンダゴテで1ピン2-4秒ぐらいずつ、溶かし込ませながらゆっくりコテを移動していきます。ちょっとハンダが少なかったので、その時は糸ハンダで補充します。だいたい均等になったら、最後にまた上から下にゆっくりハンダゴテをあてて均一にならします。



均一にといいつつ、GNDはムラが出てしまいますね…。


余談ですが最近ハンドラップ使ってます。フラックスクリーナーを入れてキムワイプで使っているんですが、便利っす。

昭和の補修テクニック

チップ→LED→GNDという流れで設計したのですが、点灯せず。確認したらチップの出力端子がオープンドレインでした。チップ←LED←Vccに変更しないとダメです。



ということでスズメッキ線と抵抗で補修しました。

なお、余っているスズメッキ線は、オシロなどを接続するための延長です(TPつけるのを忘れてた。テヘ)。

最初の試作ということであまり詰め込まないで設計しといてよかった…。

昔はこうやってスズメッキ線で回路作ったなぁ…としみじみする朝でございました。

そうそう、電動式のハンダ吸い取り器を導入して、その圧倒的な威力に震えているところなのですが…LED、抵抗など2端子のチップ抵抗を外すのであれば、吸い取るよりも左にハンダゴテ右手にハンダ吸い取り器を持って、単に両方から加熱して取る方が簡単である…というごく当たり前のことに最近になって気づきました。

なお、この基板、ESP32-WROVERに書き込みが出来ないという問題が生じていて、それで定数変えたりもしたんですが、USBシリアルと通信はできるけどFlashサイズを検出できない等のエラーを出す、という状態です。ESP32-WROVERが不良なのだと思うのですが、リワークで交換するのが面倒なので他に理由がないか、回避する言い訳ができないか考えているところでございます。esptool.py、一応betaは取れたみたいだけど…。

esptool.py v2.6-beta1
Serial port /dev/cu.usbserial-DN0483G4
Connecting.....
Chip is ESP32D0WDQ5 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, BLK3 partially reserved, Coding Scheme 3/4
MAC: 30:ae:a4:c6:88:50
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Configuring flash size...
Warning: Could not auto-detect Flash size (FlashID=0xffffff, SizeID=0xff), defaulting to 4MB
Compressed 8192 bytes to 47...

A fatal error occurred: Timed out waiting for packet content

2019年2月6日水曜日

iPhoneアプリのお手伝い

真面目にiOSの勉強をしていたのはiOS 8の頃までだったので、最近のSwift4なんて全然浦島太郎状態なのですが、こういう変なことを頼めるのは倉橋さんしかいない!と同僚さんに言われてお手伝いしました。

…「難しいこと」じゃなくて「変なこと」指名ですかい…ありがたいことですw

やったのは、動画にエフェクトを入れる処理。何本かCIFilterを使って、その後作ったのがこれです。


CIDetectorはかなり重い処理なのでCIDetectorAccuracyLowで使えたらと思うのですが、Highじゃないとそもそも結果が返ってこないんですよね…。描線と角度を一致させるためにfaceAngleを見ているのですが、たまにしか値が返ってこないので、左右の目の位置からatan2で角度を求め、線画の座標を変換してベジェ曲線で書き込みました。

何年かに一度Swiftを使うんですが…そのたびにバージョンが上がっていて、まずは差分の習得からやることになるので、手間取ります。

2019年1月28日月曜日

ステンシルプリンターとリフロー炉

1.注文
2.到着時破損
3.リフロー炉試用
4.ステンシルプリンタ試用
5.フレーム付きステンシル+ステンシルプリンタ+リフロー炉


■注文■

Aliexpressに注文したものが届きました。今まで細かいものは買ったことがあったんですが$100を超えるものは初めてです。


ステンシルプリンターは11月12日注文で11月14日発送、21日着。



リフロー炉は唯一無二の家庭用中華リフロー炉T962の後継機、LY-962Aを注文しました。赤外線+熱風式です。

■到着時破損■

ステンシル・プリンタは2つの意味で難物でした。まず到着時に破損してました。AliExpressにDisputeしたところ「それはFedExによる破損なので、FedExにクレーム入れろ」と。ただ、費用負担は一切交渉の余地なしでしたが、破損した部分の修理についてはかなり親身に相談に乗ってくれました。

ただ、プリンタがないと仕事にならないので、ebay.comにもうちょっと安いやつを注文しました。

で、FedExについても、破損状況を示す動画や写真、なかでも外箱とシュリンクラップと製品に同じ打痕があったことが決定打となったのか、一度も確認無しですんなり返金となりました。ものすごく重い製品で、8mmぐらいの太いボルトがぐんにゃり曲がっていましたので、多分相当高いところから落としたんじゃないでしょうか。

FedExさんに壊れたステンシル・プリンタの処分について確認したところ、捨ててくださいとのこと。譲渡や修理について確認したところOKとのことでした。

AliExpressの業者さんにはその旨を報告し、一件落着。

と思ったら(笑)、前記ebay.comの業者が発送すらしていないことが判明w

相談してみたところ、前記AliExpressの業者さんが15000円ほどで修理部品を送ってくれることになり、直して使うことに。ただ機械経験のないソフト屋風情に破損部分の解体は本当に難物で、ハンマー1本と半日を潰して、なんとか復旧できました。鋼鉄製の土台も微妙に曲がっているので広い面積の基板だと精度が落ちるんですが…私が使う程度ならまぁOK 。

なお「新しいのを買ったほうが安かったんじゃない?」という指摘を禁止します。

■リフロー炉試用■

この時点ではステンシル・プリンターが手元になかったので、手スキージングで試してみました。共晶ハンダを使って温度220度。110Vの機器を100Vで使っているせいか、昇温が遅いのですが、きれいに仕上がりました。

■ステンシルプリンタ試用■

ということで、ステンシルプリンターの試用です。

このあと1時間かかろうとは…。

組み立てと、細かいパーツの役割の理解、基板を取り付けて調整が終わるまでに90分かかりました。ステンシルフレームの取り付けまではわりと見た通り大きな部品を組みててていけば良いのですが、基板を正しい位置に固定する機構に関しては理解するのに時間がかかりました。実作業してて写真がないのですが、
  1. L字型の金具の横にあるネジをアーレンキーで緩めてピンを基板のネジ穴にあわせて交換する。3mm、2.5mm、など4種類のピンが付属しています。
  2. ピンが金具から基板の厚さより少し短い程度、飛び出すように金具の底の部分のネジをアーレンキーで回して、金具横のネジで固定する。
  3. フレームをプリンターに取り付けて高さを調節する。ネジたくさん。ここできちんと水平かつ同じ高さに合わせておかないと密着精度がでません。
  4. 金具を基盤に固定する。その際、基盤のすべての穴にネジが切られているわけではなく、ステンシルの位置と合わせる必要があるので、なかなか面倒くさいです。ステンシルの比較的大きめな穴から基板の特徴的なパターンが見えるように合わせたら金具を基盤に固定し、あとはX-Yステージ調節ノブを回してあわせるのが良いと思いますが…いやー苦労しました。
  5. 最後に基盤の下にある固定ネジでステージが動かないようにする

位置を合わせたら、あとはスキージングです。フレーム付きのステンシルを使うのは始めてですが、「あろえ師匠」が書いておられた通り、基板とステンシルに余計な力をかけなくても密着するので、ずれることや塗ったステンシルが抜けることを気にしないでスキージングできます。実際、少し粘度の高くなったペーストを使ったのですが、VSONや0.5mmピッチコネクタ周辺でも抜けはゼロでした。

箱から出して組み立てて〜また箱にしまうのに軽く2時間かかりましたw まぁ慣れれば30分ぐらいで済むでしょうけど、出しっぱなしにできる作業場がほしいです。試作についてはこれまで通りフレーム無しのステンシルをテープで貼ってスキージングし、生産のときにはステンシルプリンターを使うという運用になりますわ…。

■フレーム付きステンシル+ステンシルプリンタ+リフロー炉■

これまでシリンジでクリームハンダを塗ってVSONを使うと不良率が1割程度あり、フレーム無しステンシルでのスキージングでもパターン抜けが必ず1箇所は発生していました。

写真とってからL1忘れに気づきましたorz

でも、今回パターン抜け、ハンダブリッジ、いずれもゼロでした。いやー…ウデが悪い分は道具に金かけないといかんですね…。

という当たり前の結論ですみません。

2019年1月26日土曜日

Eagle 9.2の怖い現象

■追記 : 原因がわかりました! : 追記終わり■


上の回路図はUSBコネクタ付近です。図の通り、VCCには何も配線していません。



が、ボード図を見ると、他のデバイスのVCCと接続されています。



で、回路図にダミーの配線を付けてダミーのNAMEをつけると



意図した通り、何も配線が生成されなくなります。

つながっているところは全部チェックしますが、つないでいないところはチェックから漏れやすいものです。今回たまたまAutoRouteをかけたらAirwireとして残ったので気づけたのですが…この基板の標準電圧は+3V3なのでUSBのVccが接続されていたら無事ではすまなかったでしょうね…。

気をつけましょう…。


2019年1月23日水曜日

Eagleのライブラリにパッケージ生成機能が!


いつからあったんですか?この機能。

パッケージのタイプ(SOICとかSOT)を選択して、ピン間隔などを入力すると3Dデータとフットプリントが生成されてしまう。

今までライブラリ探しに費やした時間は何だったんや…これなら確実に探すより早いです。

ライブラリのデバイス一覧画面、3D Packageの一番下にある「Impoprt 3D Package」をクリックするとプルダウンが出て、その中の「Create with Package Generator」を選択すれば出てきます。


いやー、今まで3Dデータなんて無縁って考えていたので、ぜんぜん気づきませんでした。