web-dev-qa-db-ja.com

Arduino + OV7670-なしFIFO-スナップショットの読み取り

私はインターネットにOV7670についてたくさんあることを知っています( http://forum.arduino.cc/index.php?topic=159557. など)そして私はそれについてたくさん読んでいますが、何かのようです不足している。

まず最初に、カメラからピクセルごとに読み取って長方形の600 X 480画像を作成する方法を調べました。これは、ここのドキュメントに記載されているHREF、VSYNCH、およびPCLOCKを考慮すると非常に簡単に理解できました。 http://www.voti.nl/docs/OV7670.pdf 。 XCLOCKを一種のサイクルコントローラーとしてOV7670に与える必要のある入力として理解しており、RESETはそれをリセットするためのものです。

したがって、この時点で、このようなカメラの機能は、次のピンを配線することでカバーされると思いました。

  • D0..D7-arduinoボードの入力としてarduinoデジタルピン0〜7に接続されたデータ(ピクセル)の場合
  • [〜#〜] xclk [〜#〜]-arduinoボードからの出力としてarduinoデジタルピン8に接続されたカメラクロック用
  • [〜#〜] pclk [〜#〜]-arduinoボードの入力としてarduinoデジタルピン9に接続されたピクセルクロック用
  • [〜#〜] href [〜#〜]-arduinoデジタルピン10に接続されたラインの開始/終了をarduinoボードのINPUTとして定義します
  • [〜#〜] vsych [〜#〜]-arduinoボードのINPUTとしてarduinoデジタルピン11に接続されたフレームの開始/終了を定義します
  • [〜#〜] grd [〜#〜]-arduinoGRDに接続されたgroud
  • 3V3-3,3INPUTはarduino3,3vに接続されています
  • [〜#〜] reset [〜#〜]-arduinoRESETに接続
  • [〜#〜] pwdn [〜#〜]-arduinoGRDに接続

私の観点からのそのようなアプローチの実装は次のようになります。コード:

_for each loop function do
   write high to XCLK

   if VSYNCH is HIGH 
      return;

   if HREF is LOW 
      return;

   if lastPCLOCK was HIGH and currentPCLOCK is LOW 
      readPixelFromDataPins();

end for
_

私のreadPixelFromDataPins()は基本的に最初のバイトだけを読み取り(カメラから何かを読み取ることができるかどうかをテストしているだけなので)、次のように記述されています。

コード:

_byte readPixelFromDataPins() {
  byte result = 0;
  for (int i = 0; i < 8; i++) {
    result = result << 1 | digitalRead(data_p[i]);
  }
  return result;
}
_

カメラから何かが読み取られているかどうかを確認するために、シリアル9600に出力します。バイトはデータピンから数値として読み取られます。しかし、現在、私はゼロの値しか受け取っていません。画像の取得に使用しているコードは次の場所に保存されています: https://Gist.github.com/franciscospaeth/8503747

OV7670をArduinoで動作させる誰かが、私が何を間違っているのかをすでに理解していましたか? XCLOCKを間違って使用していると思いますか?それを機能させるにはどうすればよいですか?

よく検索しましたが、arduinoを使ったこのカメラのSSCCE( http://sscce.org/ )は見つかりませんでした。誰かが持っている場合はお知らせください。


この質問はarduinoフォーラム( http://forum.arduino.cc/index.php?topic=211741. )にもあります。

7

あなたの考えは悪くありませんが... xclockは時計である必要があります(あなたのプログラムでは0から1への移行であり、そこでフリーズしています)カメラを構成するためにSIOCとSIODでI2Cを使用する必要もあります(またはあなたデフォルト設定を使用できますが、30F/s、VGA、YUVフォーマットなどの正しい出力フォーマットかどうかはわかりません。)

データの読み取りと同じループでシリアル出力を使用すると、コードの実行が遅くなります。xclockピンを切り替えて、if()でピクセル印刷を移動することをお勧めします。また、HREFの0から1への遷移後、PCLKの0から1への新しい遷移を待つ必要があるよりも、1バイトのみを読み取りたい場合は、非常に正確な時間でのみデータを読み取ることができます( PCLKの784x2遷移後、HREFの0-1遷移を1つだけ見ることができます(640アクティブピクセル+各ラインの144デッドタイム)x 2(YUVまたはRGBの場合、各ピクセルで2バイトを受信))

5
user3408340

こんにちは、arduinoフォーラムのMr_Arduinoです。あなたの問題は、あなたがピクセルを読むのが遅すぎるということです。そのようなことをするためにデジタル読み取りを使用しないでください。また、バイトを読み取るためだけに別の関数を使用することを主張する場合は、関数がインライン化されていることを確認してください。これを行うには、関数を静的インラインとして宣言します。また、上記のように、どのように時計を生成していますか。 arduinoでPWMを使用してXCLKを生成できます。

ここで実用的な例を作成しました:

https://github.com/ComputerNerd/arduino-camera-tft/blob/master/captureimage.c

編集:サードパーティが上記のリンクからここの回答にコードの一部をコピーしましたが、すべてではありません。ただし、以下に投稿されたコードが実際に機能するには、そのソースからの追加ファイルが必要なため、リンクはそのままにしておく必要があります。編集2:無関係なコードを削除しました。データの処理方法を変更する必要があります。

void capImg(void){
    cli();
    uint8_t w,ww;
    uint8_t h;
    w=160;
    h=240;
    tft_setXY(0,0);
    CS_LOW;
    RS_HIGH;
    RD_HIGH;
    DDRA=0xFF;
    //DDRC=0;
    #ifdef MT9D111
        while (PINE&32){}//wait for low
        while (!(PINE&32)){}//wait for high
    #else
        while (!(PINE&32)){}//wait for high
        while (PINE&32){}//wait for low
    #endif
    while (h--){
        ww=w;
        while (ww--){
            WR_LOW;
            while (PINE&16){}//wait for low
            PORTA=PINC;
            WR_HIGH;
            while (!(PINE&16)){}//wait for high
            WR_LOW;
            while (PINE&16){}//wait for low
            PORTA=PINC;
            WR_HIGH;
            while (!(PINE&16)){}//wait for high
            WR_LOW;
            while (PINE&16){}//wait for low
            PORTA=PINC;
            WR_HIGH;
            while (!(PINE&16)){}//wait for high
            WR_LOW;
            while (PINE&16){}//wait for low
            PORTA=PINC;
            WR_HIGH;
            while (!(PINE&16)){}//wait for high
        }

    }
    CS_HIGH;
    sei();
}

github でも見つけることができます。

2
user3462295