2010年11月23日火曜日

LinkSprite JPEG Color Camera LS-Y201が動作しなくなったアレコレの顛末

先日LinkSprite JPEG Color Camera LS-Y201スイッチサイエンスさんから購入しました。
これはSparkFunでも扱われているカメラで、VGA/QVGA/160x120と画像サイズが選択できるうえにシリアルで制御できるというC328の代替としても嬉しいカメラです。


早速ライブラリの実装にとりかかり入手可能なデータシートを基に全てのインターフェースを実装したところで、全関数テストを実行しました。これがアレコレの始まりでした。

このカメラはリセット時(電源投入時含む)に「自分は何であるのか」をシリアル経路で送信してきます。


なのですが、先ほどの全関数テストを実行した直後からこのメッセージが一切送られて来ません。
最初はオシロを見ていなかったので「ボーレートの設定間違ったかな?」程度に考えていました。

しかし、オシロをあてて愕然。「カメラモジュールから何も送られて来ない・・・。」

これは怪しいと思いサイトを駆け回るとLinkSpriteが何やらArduino用のサンプルを提供しています。
http://www.linksprite.com/download/showdownload.php?lang=en&id=70

ここでは
  • SendResetCmd()
  • SendTakePhotoCmd()
  • SendReadDataCmd()
  • StopTakePhotoCmd()
のみです。


それではということでSparkFunのサイトにあるArduino用サンプルを見てみると
  • int reset(char * response);
  • int getSize(char * response, int * size);
  • int takePicture(char * response);
  • int stopPictures(char * response);
  • int readData(char * response, int address);
のみがJPEGCameraクラスで定義されています。


私はこのカメラモジュールの全機能を掌握すべく、上記の二つの内容に加えて
  • Compression ratio
  • Image size
  • Power saving
  • Change baud rate
も実装し、このカメラモジュールに対して実行しました。
そして、よくよくカメラを見ると「24LC16B」が見えます。


ちょっとガーンとなります。

ここで立ち止まって仮説を立てました。

  • 既存公開ライブラリが特定コマンドのみを使用しているのには理由があるのではないか?
  • 既存公開ライブラリが使用していないコマンドの組み合わせ動作に不具合があるのではないか?
上記のように考えると、

  • 全関数テストの過程でモジュールが持つ潜在的な不具合で24LC16Bの内容が不適切な状態になった。
  • 24LC16Bの内容が不適切な状態になった結果、モジュールが動作しない状況に陥った。
というシナリオが出てきます。

これは困ったとTwitterで呟いたところスイッチサイエンスさんから「人柱にしてしまうのは申し訳ない。交換します。」と本当にありがたいお言葉を頂きました。

そこで、今回の調査になったわけです。

まず、「どうやったらこの状態から現象を回避できるか?」を考えてみました。

24LC16Bの内容に依存してモジュールが初期化に失敗した結果、メッセージを送ってこないのであれば、コントローラ内部の初期値に期待する作戦が取れそうです。
そこで、以下のようにSDAをグランドに落とすためのリードをハンダ付けして試してみることにしました。


結果から言うとこの作戦は起動させるという意味で成功。
確かに初期化のメッセージを送ってきます。
では、ということでピクチャを取るコマンドを投げるとこれは失敗。
様々なコマンドの動作で24LC16Bの内容を参照しているようです。

こうなったら気持ち悪いので正しく動くカメラモジュールのROMに戻したくなります。
そこでスイッチサイエンスさんから頂いた代替カメラモジュールのROMを吸い出すことにしました。

まずはメインのプロセッサの足にハンダ屑が飛ばないようにマスキングし、24LC16Bの足にハンダを盛ります。取り外し用の特殊ハンダを使いたいところですが、意外に高価です。8ピン程度であれば普通のハンダでやっても大丈夫。


基板とパッケージの小さな隙間に優しくドライバを入れながらはんだごてをピンにあてていきます。
この時、間違ってもドライバをグイグイしてはいけません。ランドが基板からはがれます。


少しずつはんだごてをあてるとパッケージが徐々に基板から離れます。
これを片側4ピンずつ繰り返していくことで8ピンSOPを基板から取り外します。


取り外したらこんな感じ。
失敗してパッケージが壊れても大丈夫。
Digikeyで購入できます。http://jp.digikey.com/1/1/46508-ic-eeprom-16kbit-400khz-8soic-24lc16b-sn.html


取り外したらROMの内容を吸い出します。


で、吸い出したROMの内容がこれ。
0x0000: AA 55 01 00 04 E1 00 01
0x0008: 2A F2 02 98 00 0E 00 0D
0x0010: 02 02 00 00 00 01 1E 08
0x0018: 01 11 35 02 00 02 21 13
0x0020: 83 33 B8 0A 10 31 05 08
0x0028: 00 00 00 64 00 03 E8 07
0x0030: 00 00 80 00 35 00 5F 00
0x0038: 00 00 9F 02 E3 02 FA 00
0x0040: 00 03 B6 03 D2 04 78 04
0x0048: 84 00 00 00 00 04 A9 04
0x0050: B1 04 BF 00 00 04 A4 00
0x0058: 00 00 00 00 00 00 00 00
0x0060: BA 01 02 01 01 00 44 80
0x0068: 04 05 20 00 00 01 01 08
0x0070: 01 90 01 01 00 00 00 00
0x0078: 82 43 01 00 20 00 00 00
0x0080: 00 00 00 50 20 00 00 00
0x0088: 00 00 00 00 00 00 20 00
0x0090: 00 00 00 00 00 10 00 00
0x0098: 00 00 00 00 00 00 00 02
0x00A0: 41 0F 70 11 00 04 00 60
0x00A8: 01 0A 20 1C 10 0A 0A 08
0x00B0: 06 06 04 04 40 80 00 C0
0x00B8: 00 00 60 00 60 78 00 00
0x00C0: 00 97 00 00 00 97 02 02
0x00C8: 0A 05 00 00 00 97 00 7E
0x00D0: 3A FC 3B 10 00 00 03 64
0x00D8: 01 B4 0C 37 00 64 01 00
0x00E0: 06 00 06 00 06 00 00 00
0x00E8: 1C 00 00 00 1C 00 00 00
0x00F0: 1C 00 00 00 82 00 00 00
0x00F8: 82 00 00 00 82 0C 77 0C
0x0100: 00 00 00 20 00 00 00 20
0x0108: 00 00 00 20 00 00 00 20
0x0110: 00 00 00 20 00 00 00 20
0x0118: 00 00 00 20 00 00 00 20
0x0120: 00 00 00 20 00 00 00 24
0x0128: 00 00 00 28 00 00 00 2C
0x0130: 00 00 00 30 00 00 00 34
0x0138: 00 00 00 38 00 00 00 3C
0x0140: 00 00 00 A0 00 00 00 A2
0x0148: 00 00 00 A4 00 00 00 A6
0x0150: 00 00 00 A8 00 00 00 AA
0x0158: 00 00 00 AC 00 00 00 AE
0x0160: 00 00 00 B0 00 00 00 B2
0x0168: 00 00 00 B4 00 00 00 B6
0x0170: 00 00 00 B8 00 00 00 BA
0x0178: 00 00 00 BC 00 00 00 BE
0x0180: 00 00 00 C0 00 00 00 C2
0x0188: 00 00 00 C4 00 00 00 C6
0x0190: 00 00 00 C8 00 00 00 CA
0x0198: 00 00 00 CC 00 00 00 CE
0x01A0: 00 00 00 D0 00 00 00 D2
0x01A8: 00 00 00 D4 00 00 00 D6
0x01B0: 00 00 00 D8 00 00 00 DA
0x01B8: 00 00 00 DC 00 00 00 DE
0x01C0: 00 00 00 E0 00 00 00 E2
0x01C8: 00 00 00 E4 00 00 00 E6
0x01D0: 00 00 00 E8 00 00 00 EA
0x01D8: 00 00 00 EC 00 00 00 EE
0x01E0: 00 00 00 F0 00 00 00 F2
0x01E8: 00 00 00 F4 00 00 00 F6
0x01F0: 00 00 00 F8 00 00 00 FA
0x01F8: 00 00 00 FC 00 00 00 FE
0x0200: 00 00 01 C0 00 00 01 C1
0x0208: 00 00 01 C2 00 00 01 C3
0x0210: 00 00 01 C4 00 00 01 C5
0x0218: 00 00 01 C6 00 00 01 C7
0x0220: 00 00 01 C8 00 00 01 C9
0x0228: 00 00 01 CA 00 00 01 CB
0x0230: 00 00 01 CC 00 00 01 CD
0x0238: 00 00 01 CE 00 00 01 CF
0x0240: 00 00 01 D0 00 00 01 D1
0x0248: 00 00 01 D2 00 00 01 D3
0x0250: 00 00 01 D4 00 00 01 D5
0x0258: 00 00 01 D6 00 00 01 D7
0x0260: 00 00 01 D8 00 00 01 D9
0x0268: 00 00 01 DA 00 00 01 DB
0x0270: 00 00 01 DC 00 00 01 DD
0x0278: 00 00 01 DE 00 00 01 DF
0x0280: 00 00 01 E0 00 00 01 E1
0x0288: 00 00 01 E2 00 00 01 E3
0x0290: 00 00 01 E4 00 00 01 E5
0x0298: 00 00 01 E6 00 00 01 E7
0x02A0: 00 00 01 E8 00 00 01 E9
0x02A8: 00 00 01 EA 00 00 01 EB
0x02B0: 00 00 01 EC 00 00 01 ED
0x02B8: 00 00 01 EE 00 00 01 EF
0x02C0: 00 00 01 F0 00 00 01 F1
0x02C8: 00 00 01 F2 00 00 01 F3
0x02D0: 00 00 01 F4 00 00 01 F5
0x02D8: 00 00 01 F6 00 00 01 F7
0x02E0: 00 35 01 00 15 01 01 00
0x02E8: 00 00 0F 01 04 02 0C E0
0x02F0: 05 0D 03 7C 30 C0 09 31
0x02F8: 0C 01 00 BC 01 01 00 06
0x0300: 00 B4 14 0A 04 14 0A 05
0x0308: 08 03 0A 08 04 05 08 42
0x0310: E0 08 43 01 01 01 31 00
0x0318: 00 01 01 06 00 82 01 01
0x0320: 35 00 30 18 40 1B 18 42
0x0328: DE 18 43 00 18 44 1D 18
0x0330: 46 DD 18 47 00 18 48 1B
0x0338: 18 4A E2 18 4B 00 18 4C
0x0340: 1D 18 4E 1B 18 50 1C 18
0x0348: 5A 14 18 5C 13 18 5E 14
0x0350: 19 0F 0C 19 94 50 19 95
0x0358: 05 19 97 13 19 99 FF 19
0x0360: 9A 03 19 9B 05 19 9C 0A
0x0368: 19 9D 0E 19 80 08 19 82
0x0370: 12 19 84 38 19 85 40 19
0x0378: 8D FF 19 8E 23 19 89 FF
0x0380: 19 8A 24 19 8F 2E 1A 15
0x0388: 48 1B 19 20 1B 1A 80 1B
0x0390: 1B 20 1B 1C 80 1B 22 06
0x0398: 1B 23 0A 1B 28 31 1B 29
0x03A0: 13 1B 2A 42 1B 2B 24 1B
0x03A8: 2C 42 1B 2D 24 1B 2E 31
0x03B0: 1B 2F 13 08 01 41 00 F5
0x03B8: 00 02 00 00 04 03 02 08
0x03C0: 07 05 06 09 00 00 00 00
0x03C8: 00 00 20 18 10 10 00 40
0x03D0: 00 30 00 A4 03 40 00 03
0x03D8: 30 00 03 24 FF FF FF FF
0x03E0: 02 02 01 00 00 00 A0 00
0x03E8: 40 01 E0 01 7F 02 00 00
0x03F0: 78 00 F0 00 68 01 DF 01
0x03F8: 00 04 00 04 00 04 00 04
0x0400: 00 04 00 04 00 04 00 04
0x0408: 00 04 00 04 00 04 00 04
0x0410: 00 04 00 04 00 04 00 04
0x0418: 00 1E 00 1E 00 1E 00 1E
0x0420: 00 1E 00 1E 00 1E 00 1E
0x0428: 00 1E 00 1E 00 1E 00 1E
0x0430: 00 1E 00 1E 00 1E 00 1E
0x0438: 00 06 00 06 00 06 00 06
0x0440: 00 06 00 06 00 06 00 06
0x0448: 00 06 00 06 00 06 00 06
0x0450: 00 06 00 06 00 06 00 06
0x0458: 00 2D 00 2D 00 2D 00 2D
0x0460: 00 2D 00 2D 00 2D 00 2D
0x0468: 00 2D 00 2D 00 2D 00 2D
0x0470: 00 2D 00 2D 00 2D 00 2D
0x0478: 50 F8 F8 F8 50 F8 F8 F8
0x0480: 50 00 00 00 10 20 30 40
0x0488: 50 60 70 80 90 A0 B0 C0
0x0490: D0 E0 F0 00 28 46 60 71
0x0498: 81 90 9D AA B6 C2 CD D8
0x04A0: E3 ED F6 FF 00 80 80 00
0x04A8: 40 11 08 08 06 17 08 08
0x04B0: 08 10 10 10 10 10 10 10
0x04B8: 10 10 10 10 10 10 10 81
0x04C0: 00 81 81 00 08 10 18 05
0x04C8: 0F 7F 7F 08 00 20 33 33
0x04D0: 33 33 03 1E 7B 09 01 58
0x04D8: 60 00 00 03 FF 10 10 18
0x04E0: 18 0F FF FF FF FF FF FF
0x04E8: FF FF FF FF FF FF FF FF
0x04F0: FF FF FF FF FF FF FF FF
0x04F8: FF FF FF FF FF FF FF FF
0x0500: FF FF FF FF FF FF FF FF
0x0508: FF FF FF FF FF FF FF FF
0x0510: FF FF FF FF FF FF FF FF
0x0518: FF FF FF FF FF FF FF FF
0x0520: FF FF FF FF FF FF FF FF
0x0528: FF FF FF FF FF FF FF FF
0x0530: FF FF FF FF FF FF FF FF
0x0538: FF FF FF FF FF FF FF FF
0x0540: FF FF FF FF FF FF FF FF
0x0548: FF FF FF FF FF FF FF FF
0x0550: FF FF FF FF FF FF FF FF
0x0558: FF FF FF FF FF FF FF FF
0x0560: FF FF FF FF FF FF FF FF
0x0568: FF FF FF FF FF FF FF FF
0x0570: FF FF FF FF FF FF FF FF
0x0578: FF FF FF FF FF FF FF FF
0x0580: FF FF FF FF FF FF FF FF
0x0588: FF FF FF FF FF FF FF FF
0x0590: FF FF FF FF FF FF FF FF
0x0598: FF FF FF FF FF FF FF FF
0x05A0: FF FF FF FF FF FF FF FF
0x05A8: FF FF FF FF FF FF FF FF
0x05B0: FF FF FF FF FF FF FF FF
0x05B8: FF FF FF FF FF FF FF FF
0x05C0: FF FF FF FF FF FF FF FF
0x05C8: FF FF FF FF FF FF FF FF
0x05D0: FF FF FF FF FF FF FF FF
0x05D8: FF FF FF FF FF FF FF FF
0x05E0: FF FF FF FF FF FF FF FF
0x05E8: FF FF FF FF FF FF FF FF
0x05F0: FF FF FF FF FF FF FF FF
0x05F8: FF FF FF FF FF FF FF FF
0x0600: FF FF FF FF FF FF FF FF
0x0608: FF FF FF FF FF FF FF FF
0x0610: FF FF FF FF FF FF FF FF
0x0618: FF FF FF FF FF FF FF FF
0x0620: FF FF FF FF FF FF FF FF
0x0628: FF FF FF FF FF FF FF FF
0x0630: FF FF FF FF FF FF FF FF
0x0638: FF FF FF FF FF FF FF FF
0x0640: FF FF FF FF FF FF FF FF
0x0648: FF FF FF FF FF FF FF FF
0x0650: FF FF FF FF FF FF FF FF
0x0658: FF FF FF FF FF FF FF FF
0x0660: FF FF FF FF FF FF FF FF
0x0668: FF FF FF FF FF FF FF FF
0x0670: FF FF FF FF FF FF FF FF
0x0678: FF FF FF FF FF FF FF FF
0x0680: FF FF FF FF FF FF FF FF
0x0688: FF FF FF FF FF FF FF FF
0x0690: FF FF FF FF FF FF FF FF
0x0698: FF FF FF FF FF FF FF FF
0x06A0: FF FF FF FF FF FF FF FF
0x06A8: FF FF FF FF FF FF FF FF
0x06B0: FF FF FF FF FF FF FF FF
0x06B8: FF FF FF FF FF FF FF FF
0x06C0: FF FF FF FF FF FF FF FF
0x06C8: FF FF FF FF FF FF FF FF
0x06D0: FF FF FF FF FF FF FF FF
0x06D8: FF FF FF FF FF FF FF FF
0x06E0: FF FF FF FF FF FF FF FF
0x06E8: FF FF FF FF FF FF FF FF
0x06F0: FF FF FF FF FF FF FF FF
0x06F8: FF FF FF FF FF FF FF FF
0x0700: FF FF FF FF FF FF FF FF
0x0708: FF FF FF FF FF FF FF FF
0x0710: FF FF FF FF FF FF FF FF
0x0718: FF FF FF FF FF FF FF FF
0x0720: FF FF FF FF FF FF FF FF
0x0728: FF FF FF FF FF FF FF FF
0x0730: FF FF FF FF FF FF FF FF
0x0738: FF FF FF FF FF FF FF FF
0x0740: FF FF FF FF FF FF FF FF
0x0748: FF FF FF FF FF FF FF FF
0x0750: FF FF FF FF FF FF FF FF
0x0758: FF FF FF FF FF FF FF FF
0x0760: FF FF FF FF FF FF FF FF
0x0768: FF FF FF FF FF FF FF FF
0x0770: FF FF FF FF FF FF FF FF
0x0778: FF FF FF FF FF FF FF FF
0x0780: FF FF FF FF FF FF FF FF
0x0788: FF FF FF FF FF FF FF FF
0x0790: FF FF FF FF FF FF FF FF
0x0798: FF FF FF FF FF FF FF FF
0x07A0: FF FF FF FF FF FF FF FF
0x07A8: FF FF FF FF FF FF FF FF
0x07B0: FF FF FF FF FF FF FF FF
0x07B8: FF FF FF FF FF FF FF FF
0x07C0: FF FF FF FF FF FF FF FF
0x07C8: FF FF FF FF FF FF FF FF
0x07D0: FF FF FF FF FF FF FF FF
0x07D8: FF FF FF FF FF FF FF FF
0x07E0: FF FF FF FF FF FF FF FF
0x07E8: FF FF FF FF FF FF FF FF
0x07F0: FF FF FF FF FF FF FF FF
0x07F8: FF FF FF FF FF FF FF FF
よくよく見てみると途中にルックアップテーブルのようなものも見えます。
動作しなくなったモジュールのROMの内容も見てみました。(以下先頭を抜粋。)
0x0000: FF FE FE FE FA FE FE FE
0x0008: 2A F2 02 98 00 0E 00 0D
0x0010: 02 02 00 00 00 01 1E 08
0x0018: 01 0B 35 02 00 02 21 13
0x0020: 83 33 B8 0A 10 31 05 08
0x0028: 00 00 00 64 00 03 E8 07
0x0030: 00 00 80 00 35 00 5F 00
0x0038: 00 00 9F 02 E3 02 FA 00
0x0040: 00 03 B6 03 D2 04 78 04
0x0048: 84 00 00 00 00 04 A9 04
0x0050: B1 04 BF 00 00 04 A4 00
0x0058: 00 00 00 00 00 00 00 00
0x0060: BA 01 02 01 01 00 44 80
0x0068: 04 05 20 00 00 01 01 08
0x0070: 01 90 01 01 00 00 00 00
0x0078: 82 43 01 00 20 00 00 00
0x0080: 00 00 00 50 20 00 00 00
なんと、先頭のデータが明らかに異なります。
「そりゃ設定を更新したからでしょ?」という突っ込みもあろうとおもいますが、先頭の2バイト「0xAAと0x55」は意味がありそうですよね?(0b10101010と0b01010101) -> ちょいこじつけ。

それではということで、吸い出したROMの内容を動作しなくなったモジュールに搭載されていたROMに書き戻して、再度動作させてみました。


結果は
  • Reset:OK
  • Take picture:OK
  • ReadJpegFileSize:OK
とOKずくし。

「絵を見せてくれ!」と言われそうですが、そこのデバッグをしようとしたところでモジュールのバグにハマったので、その辺の実装と動作確認はこれからです。

現状わかっている範囲を日本語にするならば
  • 既存公開ライブラリが実装していないコマンドの単独ないし組み合わせ動作に不具合のある可能性がある。
でしょうか?

現象を再現して更に追い込む事も必要なのですが、SOPを剥がしたり付けたりで大変そうです。
ひとまずはこの辺りで止めておいて、機能の実装と検証を行いたいところです。

本稿では
  • 新品のモジュールのROM内容を掲載し、1台のみの所有でも復活できるような道を作りました。

今後の課題として
  • 仮説に対する検証
が挙げられます。

最後になりましたが、心温まる対応をして頂いたスイッチサイエンスさんに感謝いたします。
ありがとうございました。




追記1: @arms22さんから「Image Sizeのコマンドはこっちで動作確認とれたよ。コマンド送った後、電源断しないとだめだけどね。VGAで撮れた。」と御報告を頂きました。ありがとうございます。こういった御報告を頂けると非常に助かります。感謝感謝。

9 件のコメント:

  1. shintaさん、はじめまして機械屋と申します

    ラジコン飛行機からのリアルタイム画像を受信したく
    シリアルカメラの無線化中です
    初期化コマンドが送られて来ない同様の症状が出ましたが
    (ROM内容も全く同じでした、、、)
    おかげさまで無事カメラ復旧できました
    この場をお借りしてお礼申し上げます、ありがとうございました

    返信削除
  2. 機械屋さん

    お役に立てて光栄です。
    空撮なんて素敵ですね!
    この手のモジュールは安かろう悪かろうで罠にハマりがち。
    罠にハマって復活したお友達がいると心強いです。
    今後ともよろしくお願いしますです。

    返信削除
  3. こんにちは、
    この説明が、一つ質問していただきありがとうございます:
    私はあなたがEEPROMを接続する方法を理解しませんでした。それが接続されているEEPROMの各端子。あなたは私のより詳細な説明を与えることができます。
    ありがとう

    返信削除
  4. こんにちは、
    この説明が、一つ質問していただきありがとうございます:
    私はあなたがEEPROMを接続する方法を理解しませんでした。それが接続されているEEPROMの各端子。あなたは私のより詳細な説明を与えることができます。
    ありがとう

    返信削除
  5. Hi. sonda-san.

    It's a general I2C EEPROM.
    You can find the connection with google. :)

    Shin.

    返信削除
  6. Hi. shinta
    thank you for your reply.

    返信削除
  7. i need code in 'C' language. please provide me.

    返信削除
  8. Please see mbed web site.
    http://mbed.org/cookbook/Camera_LS_Y201
    http://mbed.org/users/shintamainjp/code/Camera_LS_Y201/

    返信削除
  9. The recovering program is http://mbed.org/users/shintamainjp/code/Recover_Camera_LS_Y201/

    返信削除