用20块的摄像头(不带fifo的OV7670)做WiFi实时传图小车 | 您所在的位置:网站首页 › 微信控制摄像头 › 用20块的摄像头(不带fifo的OV7670)做WiFi实时传图小车 |
博客地址 用20块的摄像头(不带fifo的OV7670)做WiFi实时传图小车 – Infinite’s Blog 零、导读在这篇文章中,你将看到如下内容: OV7670 QVGA配置的注意事项;将FPGA做成一个FIFO驱动不带FIFO的OV7670;libjpeg阉割库的使用;ESP8266传图给上位机的简单实现。ESP8266传图给OneNET,微信小程序的方案在开头的博客里有整个工程的GitHub链接(仅供参考) 一、项目背景与吐槽该项目是大三下的嵌入式短学期,因为一些的原因做的不太一样,正常做的是一个STM32F103的WiFi上位机的项目,但为了玩地快乐我做了一个FPGA控制的小车,并且还兼备了WIFI传图,上位机/微信小程序显示与控制地功能。 我在老师发布项目之后的三天内,使用STM32F1战舰开发板进行了测试(毕竟一下子玩的太大,怕失手),确定了初步方案,当时感觉是捡了一个大便宜,做了一个简单的任务,但当我看到FPGA的RTL图的时候,我自闭了。 编辑 还有许多小模块没全部展现出来,特别是在sdram ip中,害,自闭 要往上面这个FPGA中动手脚是比较困难的。特别是在我对整个sdram存储的运用还不太熟练的情况下。 吐槽:本来没打算做微信小程序的,结果在最后的实验验收要求上看到了安卓手机控制。阿这,这是我没想到的,只得硬着头皮做完。。。 二、项目设计方案回归正题,这次的任务的要求如下: 基于FPGA小车、STM32最小系统、摄像头、无线模块等常用电子模块,实现一个远程可视的遥控小车。 对此我的设计方案如下: 编辑 系统框图 系统设计方案 由系统框图所示,整个系统设计方案分成三个部分,分别是FPGA部分,STM32部分以及上位机/云端部分。 1、FPGA部分使用黑金的AX301来进行设计,FPGA在系统中的作用是获取图像、存储图像、传输图像以及控制小车。 获取图像 使用OV7670摄像头来进行图像获取,其中对摄像头的配置,采用QVGA、RGB565的格式输出,输出窗口设置为256*128的大小图像存储 使用SRAM来进行图像的存储,同时采用乒乓操作,一边获取图像一边传输图像;图像的传输 为了加快图像的传输速率,采用流水线,将RGB565的图像转换成灰度图,然后通过SPI作为从机进行图像的传输;小车控制 根据获得的控制指令,输出1KHZ的PWM波驱动电桥控制电机从而控制小车,其中PWM的占空比可调,在进行转弯时为了增加驱动能力,适当提高PWM的占空比。 2、STM32部分使用自制的STM32F407最小系统板,STM32在系统中的作用是与FPGA进行交互,对图像数据进行处理,与上位机/云端进行交互,是连接云端与底层的通道。 与FPGA进行交互 STM32使用硬件SPI作为主机,使用21M的速率与FPGA进行双向传输,即获取FPGA中存储的图像数据的同时,传达小车的方向控制指令。对图像数据进行处理 根据计算,256*128的图像即使是作为灰度图仍然后32KB的大小,相对于ESP8266的115200的波特率来说图像还是太大,因此需要对图像进行jpeg压缩,在jpeg的压缩方面,借助了libjpeg的库。实测灰度图压缩为jpeg后图像大小压缩至1KB左右。大大加快了传输的速率。与上位机/云端进行交互 STM32驱动ESP8266一方面可以与PC的上位机进行交互,传输图片到上位机上并获取来自上位机的小车控制指令,另一方面可以与OneNET进行交互,通过http协议post图像数据到OneNET上,并能通过get获取OneNET上的小车控制指令。 3、上位机/云端部分 这一部分是最后的显示与控制终端,其中上位机部分采用C#进行编写,云端部分借助OneNET这个物联网开发平台存储数据,并通过微信小程序获得图像数据以及传达控制指令。 三、项目具体实现与难点攻克 1、有关FPGA的方案设计借助黑金的OV7670_sdram的例程,进行修改。 1、OV7670 QVGA的配置 根据OV7670的datasheet,就会发现OV7670有上百个寄存器(阿这),一一地去配置显然过于复杂,不过我使用的程序是黑金官方的一个例程,黑金官方已经给了OV7670的寄存器的配置,而我们要做的是修改他的寄存器配置,因为一般来说FPGA驱动OV7670都是为了VGA的传输,所以基本都是配置了VGA的模式,但VGA模式对于这个项目来说是在是太大了,我们需要将他修改到QVGA模式,并且设置输出的窗口,这里借鉴了STM32驱动OV7670时的配置(详细可以参考这个ov7670摄像头分辨率设置方法详解 - STM32/8),以下的代码给出了QVGA的输出以及设置输出窗口的相应寄存器的配置。 这里我给出了三个输出窗口的配置,分别是128*64、320*240和256*128 但需要注意的时,将OV7670配置成QVGA时,根据datasheet给出的波形图。 我们可以看到他的输出速率是VGA模式的一半,表现在应用中,我发线他的PCLK输出变为原来的一半,即原来我是25M的PCLK,但我设置位QVGA时,他的输出变成了12.5M。 这里必须安利一波singalTap,我本来没有注意这一点,然后他的输出数据一支不对,然后我就将OV7670的全部引脚全部放到singalTap上,然后就发现了他的PCLK变为原来的一半,这时候我才想到datasheet这个时序图的含义......他的这个时钟是会影响到后续的fifo等一系列操作。 2、修改保存的图像的大小 要改变图像大小,只需修改sdram_vga_top.v的最大地址大小 NOTE:这里的地址大小最好是与wr_length和rd_length的整数倍,否则在显示图像的时候会出现图像会进行移动。 注意:我在上面记录了OV7670的配置时给了320*240的图像大小,但我最后并没有使用,一方面是因为图像大了传输过慢,另一方面是因为建议图像的大小是他的wr_length以及rd_length的整数倍,否则显示图像的时候可能会出现图像的移动。 3、FPGA与STM32的SPI通信 为了实现高速率的传输,我设置了SPI通信为21M,需要注意的是一下几点: 为了保证SPI和STM32的通信,一定要让STM32与FPGA共地!!!SPI模块的时钟 在FPGA这里经过测试发现SPI模块的时钟建议倍频到200M,一开始我设置了100M的时钟,发现SPI通信会发生错位,有时候还会紊乱,提高时钟的频率可以解决这个问题。SPI模块的CS 一般SPI模块都会设计一个CS,然后又由于STM32的硬件SPI只有3个输出脚,我自己定义了一个CS,但实际的使用效果不佳,我查看SingalTap的时候发现,好几次SPI传输的时候这个CS脚会突然来一个高电平,导致我的数据出现问题,预计原因是STM32与FPGA之间的地还是不稳,因此我最后没有用32控制CS,而是引出来进行手动复位......4、将FPGA做成一个FIFO 因为原来的程序中,摄像头的数据是存储在sdram中,使用了乒乓操作,一边读取一边存储,并且设计是考虑到VGA的时序,基本读取与存储是可以很好的同步的进行,但在我这个项目中,我对图像数据的处理明显时远远慢于OV7670图像数据的输出,因此我需要将FPGA做成一个保存数据的FIFO(吐槽一下:此处点题,20块的摄像头不带fifo就是这么真实,但凡他有一个fifo我可以简便不少.....) 为了达到fifo的效果,我从sdban_switch入手修改了他的交换bank的条件 case(state_write) 3'd0:begin if(frame_write_done && frame_read_done) //to be sure data with the same image has been wrote state_write |
CopyRight 2018-2019 实验室设备网 版权所有 |