2014-01-19 452 views
7

我知道有很多在互联网上(例如http://forum.arduino.cc/index.php?topic=159557.0)关于OV7670,我读了很多关于它,但似乎缺少一些东西。Arduino + OV7670 - 无FIFO - 读取快照

首先,我看看如何从相机读取像素来构建矩形600 X 480图像,考虑到文档中描述的HREF,VSYNCH和PCLOCK,这很容易理解:http://www.voti.nl/docs/OV7670.pdf。我将XCLOCK理解为一个输入,我需要将它作为一种循环控制器提供给OV7670,而RESET则可以重置它。

所以在这一点我认为这种相机的功能将通过配线以下引脚被覆盖:

  • D0..D7 - 数据(像素)连接到Arduino的数字引脚0至7作为Arduino板
  • XCLK INPUT - 用于相机时钟连接到Arduino的数字销8从Arduino板OUTPUT
  • PCLK - 用于像素时钟连接到Arduino的DIGITA升上Arduino板
  • HREF销9作为输入 - 定义当一个行开始/结束连接到Arduino的数字销10作为输入上Arduino板
  • VSYCH - 定义当一个帧开始/结束连接到Arduino的数字销11作为输入上Arduino板
  • GRD - GROUD连接的Arduino GRD
  • 3V3 - 连接到Arduino的3,3 INPUT 3,3V
  • RESET - 连接到Arduino的RESET
  • PWDN - 连接到Arduino的GRD

从我的角度来看这种方法的实施将是这样的: 代码:

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吧?我该怎么做才能使它工作?

我搜索了很多,我没有找到任何SSCCE(http://sscce.org/)这款相机使用arduino,如果有人请让我知道。


这个问题出现在arduino论坛(http://forum.arduino.cc/index.php?topic=211741.0)上。

回答

5

你的想法是不坏,但... 的XCLOCK需要一个时钟(在你的程序仅仅是一个从0到1的转变,并冻结在那里) 你也需要使用I2C与SIOC和SIOD为配置相机(或者您可以使用默认设置,但我不确定输出格式是否适合您,30F/s,VGA,YUV格式....)

您的代码执行速度较慢在读取数据的同一回路串行输出 我会建议您切换的xclock针,并在IF()移动像素打印。你也可以只在一个非常精确的时间读取数据,如果你想读的只有一个字节,比从0到HREF的1你需要等待一个新的转变,从0到PCLK 1的过渡后,(你将能够看到只有一个0-1 HREF的转变之后784x2 PCLK的转变,(640个有效像素+ 144的死区时间为每行)×2(用于YUV或者RGB的每个像素接收到的2个字节))

2

你好,我是来自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上找到它。

+0

@XaverKapeller - 请在编辑更加小心。您只将其中一个文件的内容替换为工作存储库的链接。 –

+0

@ChrisStratton我没有删除链接,我刚搬到它跌到了谷底。而且他只链接了一个文件,所以我在这里复制了它的内容。 –

+0

我承认我只是从我的存储库发布一个链接而感到有点懒惰。所有你需要的代码都在capImg()中。您将需要为您的应用程序修改它。重要的是,我使用cli()禁用中断,而不是使用digitalRead来获取数据,而是使用端口映射。 – user3462295

-1

你可以用我的指示:how to retrieve image from ov7670它包含了所有你所需要的步骤。还有instuction设置采集卡:how to run framegrabber

+0

我一直在研究这个问题,并且在几个地方看到了你的博客的链接。你真的应该把它翻译成英文。我唯一能理解的就是代码,但即使如此,我也有很多关于...... –

+0

的问题有关于指导的翻译版本。 – Kanaris007