ov7670 camera sensor success!
The ov7670 camera sensor, cheaply available from ebay, has been the bane of my existence during my short electronics hobby career. I bought my first ov7670 sensor maybe a year ago, and have been tearing my hair out trying to get it to respond. It seemed completely dead. It didn't respond to any form of i2c communication, and showed no signs of life in the oscilloscope.
Every now and then, I tried to get it to work using various approaches, but to no avail, and was ready to completely give up. However, now after seeing some recent success stories with the ov7670 here and here, I decided to give it one more go.
I'm pretty new to electronics, and I'm learning new stuff every day. On my most recent attempt at breathing life into the wretched thing, my attention got directed towards a feature I had not even considered before - the XCLK pin. This pin labeled "external clock", always seemed to me like it was something optional, as I've gotten used to all my other toys having internal RC oscillators, or no need for oscillators. But no, in this case it's not optional, and my oversight seems so obvious now!
I've read pretty much every document available on the internet about the ov7670 sensor, but to this day, I'm not sure it's clearly stated anywhere that feeding the XCLK is an important step to getting the ov7670 up and running. It's probably listed in every schematic out there, but my newbie mind ignored it.
So, to feed the camera some clockage, I used the CLKOUT feature of the LPCXpresso to generate a frequency of \~10Mhz, and lo and behold, it's alive! Alive!
From this point on, working with the camera was pretty straightforward. Analyzing the sync signals and reading the digital color signals with the aid of the provided pixel clock was easy as a pie. Some minor headaches with the clock running so fast, but that was possible to tune down to more workable levels.
The smallest resolution the camera supports is QQVGA (160x120), and with rgb565 color space, that fits quite neatly in the 64K of memory that LPC1769 has.
To pump out the image to my computer for viewing, I initially used the semihosting feature of LPCXpresso - just for testing. Printing out the full image with printf's took nearly an hour! But after a few attempts I managed to conjure a sensible image out of the data, crowning my success with a picture of my stupid face.
Next step was to output the data via UART at more convenient speeds. Initially I didn't seem to be able to pump the data to my computer at speeds more than \~57600. Somewhere the data got buffered, and when it buffered enough, it went nuts. So I adjusted the serial protocol a little, so the client sends commands to request lines one at a time, and the lpcxpresso responds with data. This keeps both parties happy about the rate of data flowing, and I was able to increase the baudrate to 921600.
Now I was able to view a new image from the camera every 1-2 seconds. This almost feels like watching a video instead of a slideshow :) I could do some tricks to get faster framerates, but actually I won't bother. My initial thoughts with the camera were to use it for still images taken on request, and to transfer them wirelessly via XBee, so in future I'll use the camera at a much slower pace.
In case someone reads this page one day, looking for advise with the ov7670, I'll list some notes here that might be useful:
- Needs a clock source
- i2c is dodgy, I had to add some delay to read routines
- different versions exist on ebay, some take 2.8V instead of 3.3V, and some have FIFO
I've dumped the project source to github at https://github.com/desaster/ov7670test. At the time of writing, the pygame + pyserial client isn't there, but I might add it later after I work on it a bit.