このセンサーはモノクロだった


さて、改めて言いますが、私は全くの素人からカメラ作りを始めました。

ですので、今となっては常識的な事も、全く知りませんでした。

 

絵がちゃんと出る様になった段階で、何に気がついたかと言うと

私が開発しているセンサーは、モノクロセンサーだったと言う事です

当時の私と同じ様に「モノクロってどう言う事?」って言う人もいるかと思います

 

そもそもイメージセンサーは、どうやって絵を撮影しているかと言うと

切手くらいの大きさの面に5ミクロン平方くらいの格子状の面が敷き詰められていて

その面が受け取った光の量をパソコンに送ります。

じゃあ、その光の量と言うのは、色についてはどうするのでしょうか?

実は、イメージセンサーは色を分ける事はできません。

「何言ってるんだよ、カラーセンサーってあるじゃん」と言われるでしょう

 

では、カラーセンサーってなんでしょう?

そこで私は色の勉強をする事になります

光と言うのは、波になってるのですが(光の性質については省略)幾つもの波長の重なり合いで出来ています。

例えばあるポイントで観測された光が550nmの波長が強ければ、これは緑を表します

また、450nmが強ければ青、650nmが強ければ赤となります

モノクロのセンサーは、どの色の波長も受け取るので、赤でも緑でも光が入ってきたピクセルが明るくなります

 みなさんご存知の様に、カラーTVなどは、赤(650nm)、緑(550nm)、青(450nm)を並べて、その強弱で色を表現しています。

受け取る方(カラーイメージセンサー)も、これらの波長を分て受信することで、赤、緑、青を交互に受け取ります。

具体的には、元々モノクロのピクセルの上に、ピクセルのサイズのフィルタを貼ります。信じられますか?5umx5umとかのサイズのフィルタです。

これにより、ピクセルを赤のみを取り込むピクセルとか、緑のみを取り込むピクセルにします

赤、緑、赤、緑、赤、緑・・・・・・

緑、青、緑、青、緑、青・・・・・・

と言う並びにして、取り込みます。

これらをあとで合成してカラーイメージを作ります

と、言うのがカラーカメラの原理ですが

とりあえずモノクロでカメラを完成させていきます 

 

f:id:info-akiron-com:20201218085916g:plain

monochorom

この回路を直す

さて、前回、回路のビット不正を見つけたところでした

これを上司に報告すると、「あっ間違えちゃった。じゃあ修正してね」

私は呆気に取られていました。

当時まだ素人だった私は、基板の回路が間違えていると言うことは

切腹ものの致命傷だと思っていました。

回路を書き直して、間違えた基板は捨てて、一からやり直し

費用も何十万円もかかると思っていました。

ところが、上司はあっさりハンダごてを持ってきて

ピンを加熱して針で持ち上げました。

更に、基板の配線をカッターでカットして、センサーの出力からワイヤーで引出しました。

普段ほとんど何も教えてくれない上司ですが、この時はやり方を教えてくれました

20箇所ある修正点のうち、2箇所を終えると

「っていう風に直すんだよ」って言って、残りは俺に預けました。

「え〜、俺の間違いじゃないのに俺が直すのかよ」

って当時は思ったのですが、結果としてこの作業をしておいて良かったです。

他の全ての作業にいえることですが、ハードウェアの開発には様々なシチュエーションが発生します。自分が間違える事も他人が間違える事もあります。それらに柔軟に対応する為に、可能な事は自分でやって見ておく事が必要です。

 

 因みに間違えていた回路とは、この時のイメージセンサーは1ピクセルが10ビットで

10ピクセルを同時に出力します(100ビット)

でも、FPGAでは100bitを受けるだけのピンの余裕が無いので8ビットだけを使用する事にしていました。

下位2ビットを切り捨てると、回路は8ビットカメラとして動作する事になるのですが

今回は上位2ビットを切り捨ててしまいました。

飽和の処理ができない為、色が折り返す結果となりました

 

信号をジャンパーした基板は、ワイヤーだらけになりましたが

ちゃんとした絵が出る様になりました。

めでたしめでたし 

 

f:id:info-akiron-com:20201209084435p:plain

ピンを持ち上げる

 

えー?回路間違ってんじゃん!


さて、絵が出る様になった頃、不思議な現象がおきました

確かに絵が出るのですが、絵を明るくしていくと、ある部分がぽこっと黒くなってしまうのです、暗くなった部分は色が消えるわけではなく、そこにはそこで、絵があるのですが、いったん黒くなって、また明るくなります。

ふえー?なんだこれは?

1,2,3,4と増えていくはずの値が、突然折り返すと、精神衛生上とても良くないです。

 

f:id:info-akiron-com:20201205102929g:plain

ビット不正

私の特技は、不具合が出た時にその不具合を追い詰める事です

ソフトウェアの不具合はバグ(虫)と呼びますが、このバグの発生箇所を

追い詰めるのは、なかなか自信があります

 

まずは、何が起きているかを調べます

今回の場合、明るさに起因している事は間違いないので

丸いボールの様なものを用意したりします

ここに光を当てて、絞りを調節すると、明るさが段階的に変化する絵ができます

この値が、いくつになるのかを見ていきます

 

まず、光を遮光して真っ黒にします、イメージセンサの出力は真っ黒にしても少し出ているので(完全に0になったらどこかおかしいですよ)2〜10暗いの値がチラチラしていきます。

ここでは不具合がないので、少しずつ明るくしていきます。

最終的に光量は255まで明るくなります。

え?0〜255まで値が出てんじゃん!

俺の予想は127あたりで折り返すのかと思ってたけれど、ちゃんと255まで出ている・・・っと思ったら0に戻りました、なんと明るくしていくとまた0に戻り、値が上がっていく、更に255まで上がってから0にもどる。

光が飽和するところまで完全に明るくすると全て255になるのですが、その間に3回飽和していました。

 

ここから、回路を戻っていきます。

一つの画素信号に注目していき、bit7(最上位)ビットをオシロスコープで確認しながら

光を当てていきます

これでポイントを遡っていき、どこまで正常かを見ていきます。

 

最終的に、どこまで行ってもこの不具合は繋がっていて、源泉のイメージセンサにたどり着きました。

英語の仕様書を読み直します。

すると、なんと言う事でしょう。

このセンサーは10bitの出力でした

FPGAのピン数の制限で、10ビット全てを取り込む事ができなかったため

上位8bitを取り込もうとして、下位8ビットを取り込む回路になっていました。

 

私は回路を引いた上司に報告した・・・

 

 

 

黒い点も解消

FIFOの部分もこの投稿で終わりにしたいと思います

 

風に揺らぐのれんの様な不具合を直すと、絵はすっきりと表示されました。

この時は更に感動しましたが、それでももうひとつ不可解な不具合が残っていました。

FIFOの不具合(俺の不具合ですけどね)で最後に残ったのは

黒い妙な点でした。

f:id:info-akiron-com:20201125224118g:plain

黒ドット画像

基本的には綺麗に表示されているのですが、画面中に百個くらいの点が

規則性なくバラバラと表示されるのです。

まだまだアマチュアだった私は「見なかったことにしよう」かと思いましたが

流石にそういうわけにもいかず、原因を調査しました。

まず、よく見るとこの黒い点は点ではなく短い横棒でした

つまり、センサーの中でピクセル単位で起きている現象ではなく、これもデータを転送する過程で、ロジックの不具合により発生している現象でした。

とても不可解だったのは、画像の縦横が揃っていたという事です。

それのどこが不可解なのかと言うと、不具合になる点があるにも関わらずデータの総量は正しいという事です

 

元々予定した信号は、有効信号に対してデータが同期しているもの でした

f:id:info-akiron-com:20201125085739p:plain

期待していた信号

 

黒い点のエラーが発生する場合、それに押し出されて画素がずれるのではないか?と思いました。

f:id:info-akiron-com:20201125085812p:plain

エラーを予測していたケース

しかし実際には、該当する部分の画素がすっぽり抜けてしまっていたのです

f:id:info-akiron-com:20201125085839p:plain

実際のエラー

 

この理由は、ちょっと変わったFIFOにありました

この時使っていたFIFOは、データを読み出す指示を出した最初の一クロックを無視します、更に、2クロック目のreadが発生してから1クロック遅れてデータが発生しています。

また、read=outputではなく、read=アドレスの進行なので、readによってデータ(D0)が読まれてもenableが出ていないと、このデータは有効にはなりません

つまりこれが黒ドットだったと言うわけです

f:id:info-akiron-com:20201126082716p:plain

なぜreadしたにもかかわらず、enableは別に存在するかと言うと

これは、このFIFOFPGAの外にある事に起因するのだと思います

例えばFIFOが複数存在している場合、outputのバスを共有にしたいケースがあるとします、FIFO1が出力をしている間に、FIFO2,FIFO3は読み進めて一部のデータを捨てたいとします、その時にFIFOのoutputが競合しない様にするなどの使い方が考えられます

f:id:info-akiron-com:20201128114058g:plain

FIFO read, enable

 

結果として、readとenableのタイミングが合っていない事がわかり、ここまで修正すると、おかしな点のない絵が出る様になりました。

やれやれでしたが、一切不具合なく、センサの出力をはっきり出せる様になった時も、気持ちは感慨深いものがありました。



 

少し見えてきた。流れる絵

非同期の信号が問題であることを見破った私は

そこを、あーやって、こーやって調整する事で、解決していきました。

これは、私がカメラを開発する過程で必ず毎回通る道ですが

一発で絵が出ることはなく、ちょいちょいと絵が見えていきます

この時も、ぐちゃぐちゃだった絵を解決すると、ちょっと進展はありましたが

すぐに安定することはなく、次は、絵が流れるようになりました

 

どう言うことかと言うと、一ラインの最初と最後までの絵が連続する部分は繋がっているので、それとなく絵は見えてるのですが、下の行に行くほど、絵が右にずれてきます

更に、行毎にずれ方が違うので、連続して表示すると、ひらひらと舞うのれんのようでした。なんか黒いぽっちもちょっと残っています

こちらはこちらで、考える必要がありました

この黒点の理由は、読み出しの信号と、その信号をイネーブルにする信号があり

そのタイミングのラグのせいでした。

なぜこんな事(イネーブル)が必要かと言うと、FIFOの中身をカラ読みするケースに対応する為でしたが、私はカラ読みの必要はなかったし、その時は理由もわからなかったので

ただただ苦労した事を恨んだものです

 

さて、この流れる絵がでた時の私の気持ちはと言うと

超ハッピーでした。

この絵は、当然製品としてはあり得ない訳ですが

今日まで一度も自分でハードウェアを作った事が無かった人間が

ここまで出す事が出来た事は感無量でした

 

f:id:info-akiron-com:20201117214404g:plain

エラー画像でも絵が出た

f:id:info-akiron-com:20201117214435g:plain

映像流れる

 

FIFO進展

さて、最初の絵をなんとかしないといけなくて

信号を見ながら確認していると、分かった事は

インプットのクロックとアウトプットのクロックが非同期であると言う事です

同じ66MHzでも、クロックのソースが同じでない場合、それぞれのクロックドメインの信号は同期しないのです。

今となっては、そんな事も知らないのかい、と思うような事も知らなかったです

もしも言ってる事がわからない人は、2つのデバイスで30Hzの同期信号を作り

オシロスコープで二つの信号を計測して見てください(オシロが使える人はこんな事知ってるけどね)

すると片方の信号に対して同じような波形がもう一個できるのですが、その信号がスーっと動いて行きます。

これは、どんなに精度が良いクロックソースであっても、誤差を持つためです

例えばクロックを作る水晶には

50MHz±100ppmなどと書かれています

これは20nsで一周するクロックを提供するけど、100ppmの誤差は勘弁してよ

って意味です

ppmと言うのはPerts Per Millionの頭文字で100万個と言う意味で

100ppmは100万個の中の100個つまり1万分の1の誤差はあると言う意味です

20.002の場合は不具合じゃないよ、19.998の場合は不具合じゃないよ

って事です

 

さて、非同期だからどうだと言うのかと言うと、あるタイミングで256クロック分のインプット信号が来ると分かっている場合、信号が開始するタイミングでFIFOを256クロック読みに行くと、まだ書き込まれていない場合があります

これを読みに行くと、黒い絵だったり、前のクロックと同じ絵だったりします

不具合の画像が横方向の線をランダムに配置したようになっているのは、64bit単位でのデータは揃っていたらからです

 

f:id:info-akiron-com:20201107221337g:plain

oscillo

 

 

FIFOでの不具合

FIFOで不具合が出た場合、どのような事が起きるか見てみましょう

カメラを作るにあたって次の様な絵を表示したいと思いました

f:id:info-akiron-com:20201030084926j:plain

最初の目標 グレースケールパターン

この絵は、カメラを作る過程で何度も使ってきた絵で、今でも良く使います

ピクセルが順番に並んでいる事を確認する最初の画像になります

メモリが極めて少ない環境でもささっと用意できるので重宝します

 

さて、そんな画像を目標にFPGAを構築して、最初に目にしたのは

次の様な画像でした

実際にどんな絵だったかは残っていませんが、パソコンでシミュレーションしました

f:id:info-akiron-com:20201030085909j:plain

最初に見た絵

理想と現実のギャップに心が折れます

「やっぱ俺にはカメラの開発なんて無理なんだ」っていじける心を押さえて

順番に問題点を解決していきました

ここで最初のグレースケールバーが活躍します

あのグレースケールバーは、1ピクセル8ビットのデータが0,1,2,3.....254,255,0と順番に並んでいるので、その連続性が途切れた所、例えば123,0,125等の様になっていたら

そこが不具合の原因である事が分かります

 

悩んだ末、まずはカメラのデータの信号をオシロスコープで見てみます

オシロスコープで見る限り、データの信号は正しくでているようでした

どういう事かと言うと、一定の周期で信号がパルスを出しているので

上の絵のようなランダム性はない様でした

 

カメラの信号が正しく出ていて、終着点ではずれていると言う事は、

その途中で絵が崩れていると言う事です、ここではFIFOPCIバスがその中継点になるのですが、PCIバスは、データが崩れた場合、PCが直ぐにハングアップしてしまいます。それにPCIバスのデータのやりとりは、ここにくるまでに何度もやりました。

と、言う事で、今回は初めて触るFIFOをじっくり見ていく事になりました