Autor Tema: Camara OV7670  (Leído 29694 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado groundman

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1870
    • www.ingeniopic.com
Camara OV7670
« en: 26 de Junio de 2016, 14:56:36 »

Hola a todos estas son las pruebas con la camara OV7670,pic18f87k22 y el ICD3.

en primer lugar.el voltage con el que trabajaremos tanto en la camara como en el pic.es de 3.3v
al terminal RESET de la camara no se le conectara ningun terminal.aunque en el datasheet de la camara dice que 1 es modo reset.es todo lo contrario.y si ponemos este pin a masa
la camara no funcionara.porque se estaria reseteando.

El pic trabajara con el oscilador interno a 64Mhz

El pin XCLX le conectaremos un oscilador externo de 10Mhz que es a la minima frecuencia que puede trabajar la camara.ya que aunque las señales de sincronismo
VSYNC y HREF funcionan.los circuitos de barrido interno no funcionan.y los datos del video no reaccionan.pude ver la señal en un osciloscopio.y tapando
y descubriendo la optica las salidas no hacian nada.cosa que si hacen a su frecuencia.

El pin RE3/REFO del pic se puede configurar para sacar una frecuencia desde f/osc hasta varias divisiones.pero la mas cercana a 10Mhz son 8Mhz y ya lo he probado.
y no funciona.el problema es que este pic se queda corto para esta camara.ya que la camara trabaja a un minimo de 10Mhz con un ciclo de reloj de 100ns
y el pic trabajando a 64Mhz la instruccion mas simple consume 64ns.y lo recomendable seria que consumiera menos de 50ns.asi que haria falta un pic mas rapido.

aunque tambien he probado con 10Mhz y la camara no responde a la luz.asi que o busco un chip mas potente o me olvido de esto.




Montando mi primera impresora 3D (Raprep Prusa i3)

Desconectado groundman

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1870
    • www.ingeniopic.com
Re:Camara OV7670
« Respuesta #1 en: 26 de Junio de 2016, 15:53:31 »
creo que con un pic de 120Mhz la camara puede funcionar.alguien me recomienda alguno que sea parecido al 18F87k22 en prestaciones y precio?
Montando mi primera impresora 3D (Raprep Prusa i3)

Desconectado luismh

  • PIC16
  • ***
  • Mensajes: 149
Re:Camara OV7670
« Respuesta #2 en: 26 de Junio de 2016, 16:35:31 »
Hola! Hace unos meses estuve jugando con esta camarita
Compré 2 versiones: una con una memoria FIFO donde guarda los datos y otra sin memoria...

La diferencia entre ambas es abismal!

Que versiones tenés?

Si tenés la versión sin FIFO, entonces definitivamente vas a necesitar algo más rápido y probablemente una memoria externa para guardar los datos. Intenté con un dsPIC33FJ128GP802 a 80MHz(lo máximo con este pic) y nunca pude: primero porque era muy lento y segundo porque la memoria del micro era insuficiente... Lo solucioné con un raspberryPi.

Lamentablemente creo que no se puede con ningún pic de gama media.. tendrás que pensar en

La versión con FIFO es muuy fácil de implementar!! La cámara ya trae todo! Solo le mandas un pulso para que saque la foto y automáticamente guarda todos los datos en la FIFO. Luego extraes la información a la velocidad que quieras.. Lo hice con un pic16f88 a 4MHZ!!.
Lo que si vas a necesitar implementar alguna forma para ver la imagen(yo guardaba en una SD y luego la veía en la PC. Para esto tendrás que implementar un sistema de archivos FAT16 o 32). Tomar una foto VGA me tomaba casi 5 minutos!!

Personalmente me llevó mucho tiempo y esfuerzo mental ponerla a andar. Espero que lo logres!

Saludos!
Luis.

Desconectado groundman

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1870
    • www.ingeniopic.com
Re:Camara OV7670
« Respuesta #3 en: 26 de Junio de 2016, 17:30:40 »
gracias por responder luismh.mi intencion hera crear algo parecido a lo que es un calibre laser.es decir proyectar la imagen de un hilo de 1.75mm de diametro y calcular su diametro.
para esto no me hace falta mucha memoria.en realidad solo haria falta una linea horizontal.que segun el datasheet de la camara ocuparia 1024bytes.2 bytes por cada pixel de 640pixel por linea.

pero no tuve en cuenta que el barrido interno de la camara me iba a dar problemas.voy a tener que inyectar a la camara 16Mhz.que con esta velocidad si me funciona la sensivilidad
de recepcion de la matriz receptora de imagen.y de alguna manera sincronizar la recepcion de los datos sin tener encuenta el PCLK que lo usaba para este sincronismo.pero que
me quita velocidad al chip.si lo logro no me haria falta mas velocidad.

ah.le hechare un vistazo a la camara con FIFO que comentas.me podria servir para otros proyectos.
Montando mi primera impresora 3D (Raprep Prusa i3)

Desconectado groundman

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1870
    • www.ingeniopic.com
Re:Camara OV7670
« Respuesta #4 en: 26 de Junio de 2016, 18:02:06 »
acabo de mirar lo de la FIFO  AL422B. y por menos de 2€ se puede adaptar a las camaras OV7670  que he comprado.si quieres la camara con el chip adaptado.sale por 9€.lo que te ahorras es hacer la PCB.
« Última modificación: 27 de Junio de 2016, 10:09:34 por groundman »
Montando mi primera impresora 3D (Raprep Prusa i3)

Desconectado luismh

  • PIC16
  • ***
  • Mensajes: 149
Re:Camara OV7670
« Respuesta #5 en: 27 de Junio de 2016, 15:43:14 »
Si está dentro de tus posibilidades, te sugiero que lo intentes con la versión con FIFO  incluida.

En teoría, solo necesitarías 1024 bytes, pero configurar la cámara para que te entregue solo esta cantidad de información puede resultar difícil y confuso. La cámara tiene una gran cantidad de registros y lamentablemente están muy mal documentados(Por ej: leyendo en foros me di con que era vital configurar algunos registros que en el manual figuraban como no implementados :shock:); y además están implementados de una manera poco intuitiva(si estás acostumbrado a los nobles registros de los pics, entonces notarás la diferencia).

No es mi intención desmotivarte, solo te cuento que a mi me costó bastante(aclaro que no soy exactamente un gran iluminado).

Una buena idea sería comenzar a probar con el bus serie de la cámara para configurar sus registros(es un protocolo muuy parecido a I2C, no deberías tener mayores inconvenientes). Puedes empezar a leer los registros y comparar con los valores por defecto que vienen de fábrica y luego puedes empezar a escribirlos y luego leerlos para confirmar la escritura exitosa. Un display LCD 2x16 puede servir para esto.

Manejar el bus I2C me parece importante antes que comenzar a lidiar con la señales de sincronismos e información.
Tiene una memoria volátil por lo que tendrás que configurar los registros siempre que inicie tu programa.

Me comentas tus avances!
Y si hay algo en lo que pueda aportar, lo haré!

Saludos!
Luis.







Desconectado groundman

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1870
    • www.ingeniopic.com
Re:Camara OV7670
« Respuesta #6 en: 30 de Junio de 2016, 10:31:40 »
te agradezco la ayuda.ya he pedido la camara con FIFO includa.supongo que antes de un mes la tendre en mi poder.claro que para practicar con el I2C me puede servir las que tengo.
el problema es que he estado loco perdido intentando leer por I2C los registros de la camara sin ningun exito. ni siquiera con un 18F2550.si he podido leer una 24L16 bien y algun DS1307
pero con errores porque creo que esta roto.

sin embargo de tras camaras que tengo.no he podido pasar de la fase de Start y Escritura de los bytes de ID y direccion.parece como si la camara no respondiera.los bytes de escritura y lectura
creo que son 0x42 y 0x43 respetivamente.pero no me funciona.no se si es porque el tipo de comunicacion es diferente a los 24LC16 o un DS1307 que usan la comunicacion standar de I2C

o es porque no le tenia una frecuencia por PCLK de la camara.aunque para sincronizar I2C solo deberia hacer fata GND,SCL y SDA.
Montando mi primera impresora 3D (Raprep Prusa i3)

Desconectado luismh

  • PIC16
  • ***
  • Mensajes: 149
Re:Camara OV7670
« Respuesta #7 en: 30 de Junio de 2016, 14:29:53 »
No te preocupes por PCLK. Puedes comunicarte con la cámara sin esta señal.

Estás tratando de hacer una red I2C? Probaría primero con la cámara y luego agregaría la memoria y el RTC.
Las direcciones son correctas: 0x42 para escritura y 0x43 para lectura.

La frecuencia máxima del bus es 100KHz(SCL). Con 70Khz anduvo bien para mi.
Para estas frecuencias(menores a 100khz), Microchip recomienda pull-up de 4.7k en ambas líneas.

Para lectura de registros usé dos fases de comunicación:
En la primera fase:
-se abre el bus(START)
-se envía comando de escritura(0x42) y se espera ACK de cámara
-se envía dirección de registro de leer y se espera ACK de cámara.
-se cierra el bus(STOP)

En la segunda fase:
-se abre el bus(START)
-se envía comando lectura(0x43) y se espera ACK de cámara
-se invierte el sentido de información en el bus(estuvimos enviando desde el pic... ahora nos preparamos para recibir la respuesta)
-se lee registro y se envía NACK(significa que se recibió la respuesta y no se desea seguir con la comunicación por ahora.)
-se cierra el bus(STOP)

Entre cada línea de las secuencias anteriores tuve que agregar un retardo de 10useg sino no funcionaba
Tengo un código en C30, quieres q lo suba?.. tal vez puedas ver la secuencia. No se si estás familiarizado con los registros de dspics

Saludos.
Luis.

Desconectado groundman

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1870
    • www.ingeniopic.com
Re:Camara OV7670
« Respuesta #8 en: 01 de Julio de 2016, 17:23:59 »
intentare hacer lo que dices.haber si puedo tener comuncacion.respecto al codigo,solo programo en ASM.se JAVA para programar en android.y es muy parecido al C.pero por el poco tiempo
que tengo.de momento prefiero seguir en el ASM respecto a los pic.aunque cada vez los pic son mas potentes,de momento a mi parecer en algunas aplicaciones se me antojan lentos.
haber si algun dia no me da lastima desperdiciar recursos de un pic.pero por el momento prefiero aprovechar hasta el ultimo bit.saludos y gracias.

PD:epero tener buenos resultados pronto.essty ansioso por ver funcionar la camara.
Montando mi primera impresora 3D (Raprep Prusa i3)

Desconectado luismh

  • PIC16
  • ***
  • Mensajes: 149
Re:Camara OV7670
« Respuesta #9 en: 04 de Julio de 2016, 09:03:21 »
Ok. Si tenés alguna duda, escribí.

A mi también me gusta escribir en assembler y exprimir cada bit de cada registro.. pero a partir de los micros de 16 bits, escribir en C es bastante tentador.
Tenés un osciloscopio? Suele ser de mucha utilidad en las comunicaciones seriales.

Saludos!
Luis.


Desconectado groundman

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1870
    • www.ingeniopic.com
Re:Camara OV7670
« Respuesta #10 en: 04 de Julio de 2016, 15:17:31 »
si tengo osciloscopio y es muy util.la verdad.respecto a usar o no un pic de gama mas alta que por ejemplo el 18F87k22 que estoy usand .solo me lo limita el precio.no tengo miedo a programar en ASM para estos pic.si es cierto que cuanto mas avanzados son los pic,menos ejemplos hay en ASM.el 18f87k22 sale por unos 5€.si un pic de la gama 33F valiera igual.pues me pasaria a este.
lo malo es que pasarse a un pic de una gama mas alta no garantiza que internamente tenga mas perifericos.
Montando mi primera impresora 3D (Raprep Prusa i3)

Desconectado groundman

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1870
    • www.ingeniopic.com
Re:Camara OV7670
« Respuesta #11 en: 05 de Julio de 2016, 11:00:43 »
hola luismh.por el momento no logro que funcione el i2c con la camara.estoy usando el modulo interno del pic para esto.y como dices que usas un retardo de 10uS para cada linea,no se a que te refieres.

es antes de la llamada a una de las rutinas del i2c.o el codigo que usas no maneja el i2c interno del pic? porque no se si se puede controlar un retardo en estas condiciones.ya que el envio
de datos por la linea SCK o SDI la gestiona internamente el pic.
Montando mi primera impresora 3D (Raprep Prusa i3)

Desconectado luismh

  • PIC16
  • ***
  • Mensajes: 149
Re:Camara OV7670
« Respuesta #12 en: 05 de Julio de 2016, 12:15:54 »
Hola!, tal vez me expresé mal... No son 10useg entre cada línea de código, sino entre cada fase de la comunicación

La secuencia para leer un registro es así:

-Aseguro que el bus está libre
-Envío Start y espero que termine
-Retardo
-Envío 0x42 al bus y espero que se complete el envío
-Espero ACK de cámara
-Retardo
-Envío dirección de registro a leer y espero que se complete el envío.
-Espero ACK de cámara
-Retardo
-Envío Stop

;Hasta aquí enviamos dos palabras a la cámara: dirección en bus y dirección de registro en cámara
;Ahora abrimos de nuevo el bus y nos preparamos para recibir su respuesta.

-Me aseguro que el bus está libre.
-Envío Start y espero que termine.
-Envío 0x43 y espero que se complete el envío.
-Espero ACK de cámara.
-Retardo
-Cambio dirección de bus para permitirle enviar información a la cámara.
-Espero que se complete el envío desde cámara.
-Retardo.
-Leo dato y lo guardo en alguna variable.
-Envío NACK y espero que se complete el envío.
-Retardo.
-Envío Stop.
-Retardo

Primero intenté sin retardos, y me leía mal, luego de agregarlos, me quedó funcionando perfecto.

Te paso mi código en C30 para un dsPIC. Es una función sencilla que le mandas una dirección de registro de la cámara y devuelve el valor guardado en él. Tal vez puedas sacarle algo:

Código: C
  1. unsigned char LeerOV7670(unsigned char direccion){
  2.        
  3.         unsigned char dato = 0;
  4.        
  5.        
  6.        
  7.         while(I2C1CONbits.SEN || I2C1CONbits.RSEN || I2C1CONbits.PEN ||
  8.                 I2C1CONbits.RCEN || I2C1CONbits.ACKEN);//Aseguro que el bus está ocioso.
  9.        
  10.         I2C1CONbits.SEN=1;                      //Inicio secuencia de start.
  11.         while(I2C1CONbits.SEN);                 //Espero aquí hasta que finalice secuencia de start.
  12.        
  13.         __delay_us(DELAY_US);
  14.        
  15.         I2C1TRN = WriteAddressOV7670;           //Cargo dato a enviar en buffer.
  16.         while(I2C1STATbits.TBF);                //Espero aquí hasta que se completa envío de byte.
  17.         while(!IFS1bits.MI2C1IF);               //Espero interrupción por sucesión de noveno bit.
  18.         IFS1bits.MI2C1IF = 0;                   //Limpio bandera de inetrrupción.
  19.         while(I2C1STATbits.ACKSTAT);            //Espero aquí hasta que recibo confirmación de recepción.
  20.        
  21.         __delay_us(DELAY_US);
  22.        
  23.         I2C1TRN = direccion;                    //Cargo dato a enviar en buffer.
  24.         while(I2C1STATbits.TBF);                //Espero aquí hasta que se completa envío de byte.
  25.         while(!IFS1bits.MI2C1IF);               //Espero interrupción por sucesión de noveno bit.
  26.         IFS1bits.MI2C1IF = 0;                   //Limpio bandera de inetrrupción.
  27.         while(I2C1STATbits.ACKSTAT);            //Espero aquí hasta que recibo confirmación de recepción.
  28.        
  29.         __delay_us(DELAY_US);
  30.        
  31.        
  32.         while(I2C1CONbits.SEN || I2C1CONbits.RSEN || I2C1CONbits.PEN ||
  33.                 I2C1CONbits.RCEN || I2C1CONbits.ACKEN);//Aseguro que el bus está ocioso.
  34.        
  35.        
  36.         I2C1CONbits.PEN =1;                     //Inicio secuencia de STOP.
  37.         while(I2C1CONbits.PEN);                 //Espero aquí hasta que finalice secuencia STOP.
  38.        
  39.         __delay_us(DELAY_US);
  40.        
  41.         while(I2C1CONbits.SEN || I2C1CONbits.RSEN || I2C1CONbits.PEN ||
  42.                 I2C1CONbits.RCEN || I2C1CONbits.ACKEN);//Aseguro que el bus está ocioso.
  43.        
  44.         I2C1CONbits.SEN=1;                      //Inicio secuencia de start.
  45.         while(I2C1CONbits.SEN);                 //Espero aquí hasta que finalice secuencia de start.
  46.        
  47.         __delay_us(DELAY_US);
  48.        
  49.         I2C1TRN = ReadAddressOV7670;            //Cargo dato a enviar en buffer.
  50.         while(I2C1STATbits.TBF);                //Espero aquí hasta que se completa envío de byte.
  51.         while(!IFS1bits.MI2C1IF);               //Espero interrupción por sucesión de noveno bit.
  52.         IFS1bits.MI2C1IF = 0;                   //Limpio bandera de inetrrupción.
  53.         while(I2C1STATbits.ACKSTAT);            //Espero aquí hasta que recibo confirmación de recepción.
  54.        
  55.         __delay_us(DELAY_US);
  56.        
  57.         while(I2C1CONbits.SEN || I2C1CONbits.RSEN || I2C1CONbits.PEN ||
  58.                 I2C1CONbits.RCEN || I2C1CONbits.ACKEN);//Aseguro que el bus está ocioso.
  59.        
  60.         I2C1CONbits.RCEN = 1;                   //Cambio dirección de bus.
  61.         while(I2C1CONbits.RCEN);                //Espero aquí hasta que se completa envío de byte (8 bits).
  62.        
  63.         __delay_us(DELAY_US);
  64.        
  65.         dato = I2C1RCV;                         //Leo dato.
  66.        
  67.        
  68.         I2C1CONbits.ACKDT=1;                    //Prepara para enviar NACK
  69.         while(I2C1CONbits.SEN || I2C1CONbits.RSEN || I2C1CONbits.PEN ||
  70.                 I2C1CONbits.RCEN || I2C1CONbits.ACKEN);//Aseguro que el bus está ocioso.
  71.        
  72.         I2C1CONbits.ACKEN=1;                    //Envío NACK
  73.         while(I2C1CONbits.ACKEN);               //Espero aquí hasta que finalice secuencia NACK.
  74.         I2C1CONbits.ACKDT=0;                    //Reestablezco ACK.
  75.        
  76.         __delay_us(DELAY_US);
  77.        
  78.         while(I2C1CONbits.SEN || I2C1CONbits.RSEN || I2C1CONbits.PEN ||
  79.                 I2C1CONbits.RCEN || I2C1CONbits.ACKEN);//Aseguro que el bus está ocioso.
  80.        
  81.         I2C1CONbits.PEN =1;                     //Inicio secuencia de STOP.
  82.         while(I2C1CONbits.PEN);                 //Espero aquí hasta que finalice secuencia STOP.
  83.        
  84.         __delay_us(DELAY_US);
  85.        
  86.         return dato;   
  87. }

Saludos.
Luis.

Desconectado groundman

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1870
    • www.ingeniopic.com
Re:Camara OV7670
« Respuesta #13 en: 09 de Julio de 2016, 11:51:22 »
porfin  :-/ :-/ :-/ :-/ gracias luismh por la ayuda.al final me di cuenta de que durante las practicas si no reseteamos la camara.esta se pude quedar bloqueada a la espera de un evento.
ya porque hayamos enviado mal un comando o porque hemos parado el simulador.por eso hay que enviar un reset cada vez que queramos comunicarnos con ella.almenos durante los ensayos.

otro de los errores hera que despues de escribir la direccion de la memoria de la camara no hacia como tu.STOP y START sino que ponia un RESTART y eso aqui no funciona.
respecto a los retardos de 10us no me han hecho falta ponerlos.y la velocidad la he puesto a 400Khz y va bien por ahora.

solo me queda esperar a recibir la camara con FIFO y empezar las practicas.aunque de momento voy a experimentar con los comandos internos de la camara.y por eso queria preguntarte
que registros hay que configurar para recibir la imagen en B/N.y el tipo de cabezera que usas para almacenar la imagen en BMP.

saludos.
Montando mi primera impresora 3D (Raprep Prusa i3)

Desconectado groundman

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1870
    • www.ingeniopic.com
Re:Camara OV7670
« Respuesta #14 en: 09 de Julio de 2016, 13:07:48 »
estos son los datos que he sacado de la camara.desde a direccion 0x00 a la 0xC9.

« Última modificación: 09 de Julio de 2016, 13:25:48 por groundman »
Montando mi primera impresora 3D (Raprep Prusa i3)