Loading...
  Show Posts
Pages: [1] 2 3 ... 6
1  Using Arduino / Sensors / Re: arduino uno + ov7670 (vga cmos sensor) = awesome on: May 17, 2013, 06:59:24 pm
@hlankoande
I made some code for the arduino mega awhile ago check it out it uses the arduino ide

@isaiful
It is no were near the jpeg TTL camera. The Jpeg TTL CMOS camera is way easier to use but cost more money.
2  Using Arduino / Sensors / Re: arduino uno + ov7670 (vga cmos sensor) = awesome on: May 11, 2013, 09:43:09 am
This is the old school eprom with UV erase. There are several reason why this would not work. First of all how are you going to erase it in a reasonable time. Even if you had a UV led driven by the arduino it would still take awhile to erase and UV is bad for your eyes so you would need to cover it with something. Also you would not have enough pins are the eprom is parallel. Also how fast are the write speed will it even accept data fast enough. Another problem is that you would wear it out fast. Eproms only have a certain amount of writes (They do have unlimited reads though). Also this Eprom has only 64kb of memory you would have to break the frame up even more which would reduce performance even more. In short the Eprom would not work for this purpose save it for repairing a bios or make your own NES cartridge or do something fun with it but not in a camera. Just buy or sample the 23LC1024 it is kinda cheap at $2.59 if you only order one at digi-key and you will not regret it. It is even in dip package. The dip package one is called 23LC1024-I/P by the way
3  Using Arduino / Sensors / Re: arduino uno + ov7670 (vga cmos sensor) = awesome on: April 30, 2013, 08:39:04 pm
I think there has been a misunderstanding. My camera is without fifo...
So is mine so will need the same connections as I use and the external sram. Also the reason d0-d7 not need shifting is the arduino will never drive those pins so it is up to you to make sure that those pins are always set to input on the arduino.
4  Using Arduino / Sensors / Re: arduino uno + ov7670 (vga cmos sensor) = awesome on: April 28, 2013, 02:18:29 pm
I think the 74HC245 would work just fine also a unidirectional one would work too. Pretty much any buffer that is fast enough to handle a 16mhz signal and can accept 3.3v as a supply voltage which the 74HC245 can. You do not need to shift the d7-d0 as those are always output from the sensor and never input. Only the clock signal needs to go though the buffer as that is an input and the sd card if you are using it.  From twi just disable internal pullup resistors and have them to 3.3v instead of 5v. Also I think I may have forgot to mention that RESET needs to be tided to 3.3v and PWDN to ground or you could use more GPIO pins if you need to use the PWDN and RESET features although a reset can also be triggered by writing to a register so driving that pin with the arduino has little purpose.
5  Using Arduino / Sensors / Re: arduino uno + ov7670 (vga cmos sensor) = awesome on: April 27, 2013, 10:28:20 am
A recent discovery that I made is you can get an F_CPU/2 (8mhz in the arduino's case) clock output with pwm this removes the need to edit fuse bits. Note that this is for the arduino mega 2560 I switched to from the uno to the mega recently. This will work with the arduino uno also just change the timer number.
Code:
DDRL|=8;
 ASSR &= ~(_BV(EXCLK) | _BV(AS2));
 //generate 8mhz clock
TCCR5A =67;
TCCR5B=17;
Also change DDRL to proper port and pin or be lazy and replace with pinMode();
6  Using Arduino / Sensors / Re: arduino uno + ov7670 (vga cmos sensor) = awesome on: April 26, 2013, 04:32:11 pm
The connections will be mostly the same but it could be abit different as I do not own the one with the fifo I am not sure but I think instead of PCLK you use RCLK and and RCLK is output you strobe that to get data. Check you this for more info about the fifo version http://wiki.beyondlogic.org/index.php/OV7670_Camera_Module_with_AL422_FIFO_Theory_of_Operation Also you could try a resistor divider but I have heard that they are too slow you may need a buffer/level-shiftier. Also this would not require the ram as you have the fifo.
7  Using Arduino / Sensors / Re: arduino uno + ov7670 (vga cmos sensor) = awesome on: April 16, 2013, 05:53:08 pm
I forget that. I bought the camera ov7670 fifo.
Sorry and thank you so much.
Smart choice the one with the fifo is much better I wish I would have bought it but I bought the one without the fifo.
8  Using Arduino / Storage / Re: Serially receiving an image file from arduino mega on: April 14, 2013, 09:41:32 am
If you really care about speed you do not want to use the arduino library. Instead set this up manully. Here is code for 0.5M baud the fastest I could get out of my uno faster misses bytes.
To enable serial do
Code:
UBRR0H=0;
UBRR0L=3;//3 = 0.5M 2M baud rate = 0 7 = 250k 207 is 9600 baud rate
UCSR0A|=2;//double speed aysnc
UCSR0B = (1<<RXEN0)|(1<<TXEN0);//Enable receiver and transmitter
UCSR0C=6;//async 1 stop bit 8bit char no parity bits
To write a byte do
Code:
UDR0=dat;
while ( !( UCSR0A & (1<<UDRE0)) ) {} //wait for byte to transmit
Also do not use the SD library that comes with the arduino IDE that one is HORRIBLE. Use sdfatlib instead. http://code.google.com/p/sdfatlib/
The SD library that comes with the arduino IDE can wear out your card overtime as writes are not buffered and it is very slow sdfatlib is much faster and better coded.
9  Using Arduino / Sensors / Re: arduino uno + ov7670 (vga cmos sensor) = awesome on: April 13, 2013, 09:03:23 pm
michinyon I bought an ov7670 camera module that means some of the pins are routed to a 2.54mm pitch header I think you have bought just the sensor. I am busy right now I will take a picture soon.
Saren it is possible I will have to get back with you on this one though. I am busy right now and don't have any code written right now for using no ram. I do however have a program that is compiled with avr-gcc that sends the image to a frame grabber program that I wrote.
Here is the sender program it is in 3 files main.c ov7670.h ov7670.c
main.c:
http://pastebin.com/dF3pc23T
I will warn you that I made some changes to the code but forgot to change the comments like the captureImg function says it missed a byte but now it does not I posted it to paste bin before realising this.
ov7670.h
http://pastebin.com/CqYTwNqn
ov7670.c
http://pastebin.com/T1nN5Ni4
Here is the frame grabber source code
http://pastebin.com/dxMJhZTq
This one is only one file. If on Gnu/Linux you will need to install the development package of SDL or if gentoo just emerge sdl. If on windows get the development library from http://www.libsdl.org/download-1.2.php
Also I made an update to my program that captures an image to the sd card it nows saves raw bayer data.
http://pastebin.com/zV0ahzPv
The link is different than the previous code that I posted.
Here is a program to debayer/demosaic the data it is still in very beta needs work
It will also convert yuv422 to rgb (the old image to sd card program saved data in that format)
Code:
//to compile type gcc -Wall -Wextra -lm -lpng -o yuv main.c
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <png.h>
#include <zlib.h>
#include <sys/stat.h>
#define img_w 640
#define img_w_2 1280
#define img_h 480
#define CLIP(X) ( (X) > 255 ? 255 : (X) < 0 ? 0 : X)
#define C(Y) ( (Y) - 16  )
#define D(U) ( (U) - 128 )
#define E(V) ( (V) - 128 )
#define YUV2R(Y, U, V) CLIP(( 298 * C(Y)              + 409 * E(V) + 128) >> 8)
#define YUV2G(Y, U, V) CLIP(( 298 * C(Y) - 100 * D(U) - 208 * E(V) + 128) >> 8)
#define YUV2B(Y, U, V) CLIP(( 298 * C(Y) + 516 * D(U)              + 128) >> 8)
char buf[1024];
void showHelp()
{
puts("Yuv422 raw image data to png");
puts("-n x replace x with the image number you want to convert");
puts("-h shows this help file");
puts("-o x replace x with a real integer between 0 and 7 this sets the offset");
}
int savePNG(char * fileName,uint32_t width,uint32_t height,void * ptr)
{
//saves a 24bit png with rgb byte order
png_byte * dat=ptr;//convert to uint8_t
//png_byte **row_pointers = malloc(height*sizeof(png_byte));
//if (row_pointers==0)
// return 1;
FILE * fp=fopen(fileName,"wb");
if (fp==0)
return 1;
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)0,0,0);
if (!png_ptr)
return 1;
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
png_destroy_write_struct(&png_ptr,(png_infopp)NULL);
return 1;
}
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(fp);
return 1;
}
png_init_io(png_ptr, fp);
png_set_IHDR(png_ptr, info_ptr, width, height,8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);//must be called before other png_set_*() functions
//png_set_compression_level(png_ptr,Z_BEST_COMPRESSION);//since we are doing timelapses we may be dealing with many files it is good to keep disk space usage down
uint32_t y;
//for (y=0;y<height;y++)
// row_pointers[y]=&dat[(y*width*3)];//the rows are contiguous
png_set_user_limits(png_ptr, width, height);
png_write_info(png_ptr, info_ptr);
//puts("saving data 2");
//png_write_image(png_ptr, row_pointers);
for (y=0;y<height;y++)
png_write_row(png_ptr, &dat[(y*width*3)]);
//png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
png_write_end(png_ptr, info_ptr);
png_destroy_write_struct(&png_ptr, &info_ptr);
//free(row_pointers);
fclose(fp);//done with file
return 0;//will return 0 on success non-zero in error
}
void yuv2rgb(uint8_t * yuvDat,uint8_t * out)
{
uint64_t xy;
for (xy=0;xy<(img_w/2)*img_h;xy++)
{
*out++=YUV2R(yuvDat[0],yuvDat[1],yuvDat[3]);
*out++=YUV2G(yuvDat[0],yuvDat[1],yuvDat[3]);
*out++=YUV2B(yuvDat[0],yuvDat[1],yuvDat[3]);
*out++=YUV2R(yuvDat[2],yuvDat[1],yuvDat[3]);
*out++=YUV2G(yuvDat[2],yuvDat[1],yuvDat[3]);
*out++=YUV2B(yuvDat[2],yuvDat[1],yuvDat[3]);
yuvDat+=4;
}
}
void deBayerN(uint8_t * in,uint8_t * out)
{
uint32_t x,y;
for (y=0;y<img_h;y+=2)
{
for (x=0;x<img_w;x+=2)
{
//this will do a 2x2 pixel rectangle
/*R G
 G B*/
out[(x*3)]=in[x];//copy red
out[(x*3)+1]=in[x+1];//green
out[(x*3)+2]=in[x+1+img_w];//blue

out[(x*3)+3]=in[x];//red
out[(x*3)+4]=in[x+1];//green
out[(x*3)+5]=in[x+1+img_w];//blue

out[((x+img_w)*3)]=in[x];//red
out[((x+img_w)*3)+1]=in[x+img_w];//green
out[((x+img_w)*3)+2]=in[x+1+img_w];//blue

out[((x+img_w)*3)+3]=in[x];//red
out[((x+img_w)*3)+4]=in[x+img_w];//green
out[((x+img_w)*3)+5]=in[x+img_w+1];//blue
}
out+=img_w*6;
in+=img_w*2;
}
}
void deBayerL (uint8_t * in,uint8_t * out)
{//this is an implementation of http://www.ipol.im/pub/art/2011/g_mhcd/
uint32_t x,y;
for (y=0;y<img_h;y+=2)
{
for (x=0;x<img_w;x+=2)
{
//this will do a 2x2 pixel rectangle
/* B Gb
  Gr R
*/
/*R G THIS IS WRONG BUT STANDARD The rows are reversed on omnivision sensors keep this in mind later just get alg working for now
 G B*/
//if (x>=2 && x<=img_w-2 && y>=2 && y<=img_h-2)//see if we are able to grab pixels from neighboors
//{
//printf("X %d Y %d x-img_w %d\n",x,y,x-img_w);
out[x*3]=in[x];//red just needs to be copied
//out[(x*3)+1]=((in[x]*4)+(in[x-1]*2)+(in[x+1]*2)+(*(in+x-img_w)*2)+(in[x+img_w]*2)-(in[x-2])-(in[x+2])-(*(in+x-img_w_2))-in[x+img_w_2])/8;//green at red locations
//out[(x*3)+2]=((in[x]*6)+(*(in+x-1-img_w)*2)+(*(in+x+1-img_w)*2)+(*(in+x-1+img_w)*2)+(in[x+1+img_w]*2)-(in[x-2]/3*2)-(in[x+2]/3*2)-(*(in+x-img_w_2)/3*2)-(in[x+img_w_2]/3*2))/8;//Blue at red

//out[(x*3)+4]=
out[(x*3)+4]=in[x+1];//copy green

out[((img_w+x)*3)+1]=in[x+img_w];//copy green

out[((img_w+x)*3)+5]=in[x+img_w+1];//copy blue
/*}
else//we are on the edge defualt to edge safe algorthim
{
out[(x*3)]=in[x];//copy red
out[(x*3)+1]=in[x+1];//green
out[(x*3)+2]=in[x+1+img_w];//blue

out[(x*3)+3]=in[x];//red
out[(x*3)+4]=in[x+1];//green
out[(x*3)+5]=in[x+1+img_w];//blue

out[((x+img_w)*3)]=in[x];//red
out[((x+img_w)*3)+1]=in[x+img_w];//green
out[((x+img_w)*3)+2]=in[x+1+img_w];//blue

out[((x+img_w)*3)+3]=in[x];//red
out[((x+img_w)*3)+4]=in[x+img_w];//green
out[((x+img_w)*3)+5]=in[x+img_w+1];//blue
}*/
}
out+=img_w*6;
in+=img_w*2;
}
}
uint8_t readImg(uint32_t num,uint8_t * dat)
{
sprintf(buf,"F%d.YUV",num);
FILE * myfile = fopen(buf,"rb");
if (myfile==0)
{
printf("Cannot open file %s\n",buf);
return 1;
}
fread(dat,2,img_w*img_h,myfile);
fclose(myfile);
return 0;
}
uint8_t processImg(uint8_t * in,uint8_t * out,uint32_t num,uint8_t alg,uint16_t offset)
{
if (readImg(num,in))
return 1;
uint32_t w,h;
switch (alg)
{
case 2:
deBayerL(in+offset,out);//linear
break;
case 1:
deBayerN(in+offset,out);//nearest neighboor low quality try to avoid using
break;
case 0:
yuv2rgb(in+offset,out);
break;
default:
puts("You must pick an algorithm to save the image as");
return 1;
}
sprintf(buf,"frame %d.png",num);
if (savePNG(buf,img_w,img_h,out))
{
return 1;
puts("Error while saving PNG");
}
return 0;
}
int main(int argc,char ** argv)
{
uint8_t useNum=0;
uint32_t useImg;
uint16_t offset=0;
uint8_t debayer=1;
if (argc>1)
{
//handle arguments
int arg;
for (arg=0;arg<argc;arg++)
{
if (strcmp(argv[arg],"-n") == 0)
{
arg++;
useImg=atoi(argv[arg]);
useNum=1;
continue;
}
if (strcmp(argv[arg],"-o") == 0)
{
arg++;
offset=atoi(argv[arg]);
if (offset>img_w)
{
printf("you must specify a number between 0 and %d for argument -o\n",img_w);
showHelp();
return 1;
}
continue;
}
if (strcmp(argv[arg],"-h") == 0)
{
showHelp();
continue;
}
}
}
uint8_t * Dat;//in case some of the file was not saved we use calloc instead of malloc to garentte that the unsaved pixels are set to 0
if (debayer!=0)
Dat = calloc(img_w*img_h+img_w,1);
else
Dat = calloc(img_w*img_h+img_w,2);
uint8_t * outImg = malloc(img_w*img_h*3);//all bytes in the array will be overwritten no need for calloc
if (useNum)
{
processImg(Dat,outImg,useImg,debayer,offset);
}
else
{
uint32_t imgC;
for (;;imgC++)
{
printf("Saving image %d\n",imgC);
if (processImg(Dat,outImg,imgC,debayer,offset))
return 1;
}
}
free(Dat);
free(outImg);
return 0;
}
10  Using Arduino / Sensors / Re: arduino uno + ov7670 (vga cmos sensor) = awesome on: April 12, 2013, 04:06:02 pm
I wish you the best of luck if anything does not work right just reply and I will help you.
11  Using Arduino / Sensors / Re: arduino uno + ov7670 (vga cmos sensor) = awesome on: April 11, 2013, 07:30:22 pm
The connections are simple. Start by plugging in SIO_C to A5 and SIO_D to A4 since this is i2c/twi you must have a 4k7 resistor 10k also works. Make sure you have the resistor to pull up 3.3v not 5v. Also edit twi.c  in the arduino ide folder/libraries/Wire/utility search for these lines and comment them out or remove them
Code:
// activate internal pullups for twi.
  digitalWrite(SDA, 1);
  digitalWrite(SCL, 1);
This is to remove the internel pullup resistor by not removing these 2 lines you could cause damage to the sensor. Then plug d7 to digital pin 7 d6 to 6 d5 to 5 d4 to 4 d3 to A3 d2 to A2 d1 to A1 and d0 to A0 now plug in VSYNC to digital pin 3 and PCLK to pin 2. Now change the fuse bits to be exacly the same except enable the CLKOUT pin. This will output a clock run this through a buffer or level shifter to 3.3v if you do not get the 5v signal down to 3.3v it could damage the sensor. The sd card and spi ram is just standard spi wiring nothing special.
12  Topics / Robotics / Re: Interfacing arduino with ov7670 on: April 10, 2013, 01:23:02 pm
Sorry for the bump but this is the first thing that appears on google.
I got my arduino uno to save a 640x480 image to an sd card read how I did it plus sample code at http://arduino.cc/forum/index.php/topic,159557.0.html
13  Using Arduino / Sensors / arduino uno + ov7670 (vga cmos sensor) = awesome on: April 09, 2013, 10:50:06 pm
I have recently been working with the ov7670 unfortunately I made the mistake of cheeping out and buying the cheaper one without the fifo. At first I though it would be a challenge to get this to work but it turns out not to be that hard at all. The problems: the arudino does not have enough ram and is slow additionally it runs on 5v when both the ov7670 and the sd card need 3.3v. The solutions. Break the image into smaller peices and transfer the smaller pieces into spi ram in this case I have the 23LC1024 128kb of ram that means if I want a vga image 640*480*2 bytes per pixel. I must divide it into 5 equal parts. So I transfer part of the image and save that part into the sd card and do this for a total of 5 times each time skipping different regions and saving others. The sensor can output both rgb565 or yuv422 I found that yuv422 is better quality so I made a converter for that but the library libbmp outputs bmps that gimp does not like only ffmpeg and the imageviewer that came with LXDE (my current desktop environment of choice) appear to open them. Once I fix that I will post the code for the converter but here is code for the capture program. http://pastebin.com/1nnRc5qL I used sdfatlib to write and based my code off of his fastlogger code. Note that by defining useLed using #define useLed will assume you have an led on pin 0 and a button on pin 1 to stop the capture hold down the button and wait for the led to blink very fast make sure that the button sinks the pin to grounnd. If you do not define useLed then it uses serial to start stop image send one letter to the arduino and it will  save 1 image you can send more for more images. Also Note that I found some registers online somewhere and I could not find documentation on those registers. The only ov7670 datasheet that I could find online does not explain all the registers it gives the name but the description is blank. If someone could explain with a reply or PM what these:
Code:
    wrReg(AWBC7,0x88);
    wrReg(AWBC8,0x88);
    wrReg(AWBC9,0x44);
    wrReg(AWBC10,0x67);
    wrReg(AWBC11,0x49);
    wrReg(AWBC12,0x0e);
wrReg(REG_GFIX,0x00);
//wrReg(GGAIN,0x40);
    wrReg(AWBCTR3,0x0a);
    wrReg(AWBCTR2,0x55);
    wrReg(AWBCTR1,0x11);
    wrReg(AWBCTR0,0x9f);
wrReg(0xb0,0x84);//not sure what this does
registers do that would be awesome.
To solve the 5v issue I use a buffer. To solve the fact that the arduino is slow I set the divider to 9 also I am getting the clock with the CLKOUT pin you will have to change your fuse settings for that. Also for twi communication the ov7670 is picky about what pullup resistor values you use I found 4.7k and 10k to work. I tried 1k and 2.2k and those do NOT work. You will need twi to write to the registers the image out is parallel. Here are some images taken with the ov7670.


I am busy right now I will take more later. Here is the arduino uno itself. Image is very large click here to view http://img407.imageshack.us/img407/4593/img3475m.jpg
14  Using Arduino / Programming Questions / error: attempt to use poisoned "SIG_USART0_RECV" on: March 21, 2013, 06:55:19 pm
I recently started using Gentoo GNU/Linux as my choice of distro and I installed the arduino ide when trying to compile a program I can compile it for the arduino uno but not the arduino mega. Does anybody know a fix for this?
15  Using Arduino / Programming Questions / Re: When possible why isn't digitalWrite and read also pinMode replaced? on: January 15, 2013, 03:51:08 pm
Keep in mind that the port assignments are different for 328 Vs the other avr chips the IDE supports so there is some portability given up when you use direct port addressing in your sketch.

Lefty

That is why you select if you are using the arudino mega or arduino uno or other board. Then the pre-processor will determine with bit in which port to set or clear.
Pages: [1] 2 3 ... 6