Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Forum Arduino

Télécharger au format doc, pdf ou txt
Télécharger au format doc, pdf ou txt
Vous êtes sur la page 1sur 12

Forum Arduino> Utiliser Arduino> Capteurs> [RESOLU] Problème avec le module de caméra OV7670

Sujet: [RÉSOLU] Problème avec le module de caméra OV7670 (lu 16470 fois)

matanbright

[RESOLU] Problème avec le module de caméra OV7670

17 mars 2018 à 19h02 Dernière édition : 02 avril 2018 à 11h09 par matanbright

Bonjour,

j'ai Arduino MEGA 2560 et le module caméra OV7670.

Le module caméra ne fonctionne pas!

J'ai essayé les tutoriels suivants:

http://www.instructables.com/id/OV7670-Without-FIFO-Very-Simple-Framecapture-With-/

http://www.instructables.com/id/OV7670-Arduino- Module de capteur de caméra-Framecapture-T /

https://forum.arduino.cc/index.php?topic=159557.0

https://create.arduino.cc/projecthub/tech-duino/visual-capturing-with-ov7670 -on-arduino-069ebb

Ces tutoriels sont pour l'Arduino UNO et j'ai changé les valeurs DDRx, PORTx et PINx afin qu'il
corresponde aux broches de l'Arduino MEGA, mais cela ne fonctionne pas!

Je pense que le module de caméra est faux, car il ne ressemble pas aux images d'Internet:

Aidez-moi, s'il vous plaît! Je vous remercie.


falexandru

Re: Problème avec le module de caméra OV7670

#1

20 mars 2018, 20h50 Dernière édition : 20 mars 2018, 20h52 par falexandru

J'en ai un similaire à celui d'Internet.

Je ne l'ai pas dé-scellé pour le moment (prévu pour une étape ultérieure du projet). Mais je l'ai apporté
d'une source commerciale réputée et fiable dans mon pays. Donc, d'après l'apparence, celui de l'image
de droite est le même que celui que j'ai,

cela ne signifie pas que celui de gauche est un faux, à ma connaissance.

Pourrait être une version de base / simplifiée.

Qu'entendez-vous par «ne fonctionne pas»? Le code ne compile pas? La caméra n'envoie rien au
tableau?

Je n'ai aucune idée de la caméra en tant que telle, mais souvent, j'ai mal câblé ou les cavaliers ne sont
pas en contact.

matanbright

Re: Problème avec le module de caméra OV7670

#2

21 mars 2018 à 20h55

Ok, enfin ça marche, donc ce n'est pas un faux module :).


Cela ne fonctionnait pas car j'ai oublié de modifier certaines valeurs de registres de minuterie qui
fonctionnent sur l'Arduino UNO mais pas sur l'Arduino MEGA. Maintenant, la minuterie génère un signal
PWM de 8 MHz pour l'horloge principale de l'OV7670 et je suis capable de capturer des images.

Mais j'ai toujours un problème!

Je ne peux pas modifier les registres de la caméra.

La caméra est connectée aux broches Arduino SCL et SDA, et les communications avec les registres de
caméra se font via le protocole I2C.

Autant que je sache, la caméra communique via le protocole SCCB, qui peut être implémenté via le
protocole I2C.

Pour écrire une valeur dans un registre de caméra:

1) L'Arduino démarre une transmission I2C vers la caméra.

2) L'Arduino envoie un octet représentant l'ID du registre dont on souhaite modifier sa valeur.

3) L'Arduino envoie un octet représentant la valeur à écrire dans le registre.

4) L'Arduino met fin à la transmission I2C.

Voici mon code pour écrire une valeur dans un registre:

Code: [Sélectionner]

void writeCameraRegister(byte registerId, byte registerValue) {

Wire.beginTransmission(0x42);

Wire.write(registerId);

Wire.write(registerValue);

Wire.endTransmission();

Pour lire la valeur d'un registre de caméra:


1) L'Arduino démarre une transmission I2C vers la caméra.

2) L'Arduino envoie un octet représentant l'ID du registre dont on veut lire sa valeur.

3) L'Arduino met fin à la transmission I2C.

4) La caméra envoie à l'Arduino la valeur du registre.

Voici mon code pour lire la valeur d'un registre:

Code: [Sélectionner]

byte readCameraRegister(byte registerId) {

Wire.beginTransmission(0x42);

Wire.write(registerId);

Wire.endTransmission();

Wire.requestFrom(0x43, 1);

return Wire.read();

Selon la fiche technique OV7670, les adresses esclaves de la caméra sont: 0x42 pour l'écriture et 0x43
pour la lecture. Mais lorsque j'essaye de lire une valeur dans un registre, la caméra ne répond pas à la
demande.

J'envoie à la caméra l'identifiant du registre Je veux lire sa valeur, mais la caméra ne me renvoie pas la
valeur.

J'ai essayé d'exécuter un code qui essaie toutes les adresses possibles pour les périphériques I2C et
imprime si une adresse démarre une connexion avec succès, mais aucune adresse n'a démarré une
connexion, cela signifie qu'il y a un problème avec la connexion I2C de l'appareil photo avec l'Arduino .

Le code vient d'ici: https://playground.arduino.cc/Main/I2cScanner

S'il vous plaît, aidez-moi! Je vous remercie.


matanbright

Re: Problème avec le module de caméra OV7670

#3

28 mars 2018 17:13 Dernière édition : 31 mars 2018 à 11:19 par matanbright

Ok, enfin après tous mes essais ça fonctionne parfaitement! :)

Maintenant, je peux modifier les registres de la caméra et je peux prendre des photos et des vidéos de
la caméra avec mon Arduino MEGA sans aucun problème!

Au début cela n'a pas fonctionné pour moi parce que j'ai essayé un code qui était pour l'Arduino UNO,
j'ai donc oublié de changer certains des noms et valeurs des registres afin qu'ils soient compatibles avec
l'Arduino MEGA (je veux dire Registres DDRx, PORTx et PINx) et en plus, l'Arduino MEGA a des broches
différentes associées à chaque minuterie PWM donc j'ai oublié de changer la broche pour qu'elle soit
compatible avec la minuterie utilisée dans le code (je veux dire aux registres OCRxA les broches
associées).

Ensuite, j'ai eu des problèmes de communication avec les registres de la caméra. Je n'ai pas pu
communiquer avec les registres car j'ai utilisé l'adresse d'écriture (0x42) et l'adresse de lecture (0x43) de
la caméra dans les fonctions "Wire.beginTransmitting" et "Wire.requestFrom". Ces adresses contiennent
le bit de lecture / écriture pour l'I2C:

0x42 -> 100001 0

0x43 -> 100001 1

Mais les fonctions I2C ont besoin de l'adresse sans le bit de lecture / écriture car elles gèrent
automatiquement les adresses de lecture / écriture.

Donc, si nous décalons les bits des adresses de lecture / écriture vers la droite une fois (1000010 >> 1),
nous obtiendrons l'adresse sans le bit de lecture / écriture: 0x21 (1000010 >> 1 = 0100001).

Donc, lorsque j'écris l'adresse 0x21 dans les fonctions I2C, cela fonctionne!

Code: [Sélectionner]

Wire.beginTransmission(0x21);

Wire.requestFrom(0x21, 1);
Veuillez noter que la caméra a besoin d'un signal PWM à la broche de l'horloge maître (MCLK ou XCLK)
même pour la communication via l'I2C avec l'Arduino. Sans le signal d'horloge maître, la caméra ne
fonctionnera pas du tout! Pour cette raison, lorsque j'ai essayé le code qui essaie toutes les adresses
possibles pour les périphériques I2C, même lorsqu'il a essayé l'adresse 0x21, la communication n'a pas
fonctionné!

Le problème est donc résolu! :)

zoomx

Re: Problème avec le module de caméra OV7670

#4

28 mars 2018, 23h13

Pouvez-vous partager votre croquis?

matanbright

Re: Problème avec le module de caméra OV7670

#5

29 mars 2018, 22h29 Dernière édition : 31 mars 2018, 21h35 par matanbright

Voici mon croquis et les connexions.

L'esquisse sert à capturer des images en niveaux de gris (car c'est plus facile).

Pour recevoir des images, vous devrez installer le logiciel à partir de l'un des tutoriels du premier
message.
Code: [Sélectionner]

// Pins configurations:

// SDA/SIOD ---> pin A4 (for Arduino UNO) | pin 20/SDA (for Arduino MEGA)

// SCL/SIOC ---> pin A5 (for Arduino UNO) | pin 21/SCL (for Arduino MEGA)

// MCLK/XCLK --> pin 11 (for Arduino UNO) | pin 10 (for Arduino MEGA)

// PCLK -------> pin 2

// VS/VSYNC ---> pin 3

// HS/HREF ----> pin 8

// D0 ---------> pin A0

// D1 ---------> pin A1

// D2 ---------> pin A2

// D3 ---------> pin A3

// D4 ---------> pin 4

// D5 ---------> pin 5

// D6 ---------> pin 6

// D7 ---------> pin 7

#include <Wire.h>

#define CAMERA_ADDRESS 0x21

// Definitions of functions for manipulating the Arduino boards pins according to each Arduino board
registers, so the code will work for both Arduino UNO and Arduino MEGA:

// The only change is the connections of the SDA/SIOD, SCL/SIOC and MCLK/XCLK pins to each board
(see the pins configurations above).
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) // If you are using Arduino
MEGA the IDE will automatically define the "__AVR_ATmega1280__" or "__AVR_ATmega2560__"
constants.

#define TIMER2_PWM_A_PIN_MODE_OUTPUT() ({ DDRB |= 0b00010000; })

#define PIN2_DIGITAL_READ() ({ (PINE & 0b00010000) == 0 ? LOW : HIGH; })

#define PIN3_DIGITAL_READ() ({ (PINE & 0b00100000) == 0 ? LOW : HIGH; })

#define PIN4_DIGITAL_READ() ({ (PING & 0b00100000) == 0 ? LOW : HIGH; })

#define PIN5_DIGITAL_READ() ({ (PINE & 0b00001000) == 0 ? LOW : HIGH; })

#define PIN6_DIGITAL_READ() ({ (PINH & 0b00001000) == 0 ? LOW : HIGH; })

#define PIN7_DIGITAL_READ() ({ (PINH & 0b00010000) == 0 ? LOW : HIGH; })

#define PIN8_DIGITAL_READ() ({ (PINH & 0b00100000) == 0 ? LOW : HIGH; })

#define PINA0_DIGITAL_READ() ({ (PINF & 0b00000001) == 0 ? LOW : HIGH; })

#define PINA1_DIGITAL_READ() ({ (PINF & 0b00000010) == 0 ? LOW : HIGH; })

#define PINA2_DIGITAL_READ() ({ (PINF & 0b00000100) == 0 ? LOW : HIGH; })

#define PINA3_DIGITAL_READ() ({ (PINF & 0b00001000) == 0 ? LOW : HIGH; })

#elif defined(__AVR_ATmega328P__) // If you are using Arduino UNO the IDE will automatically define
the "__AVR_ATmega328P__" constant.

#define TIMER2_PWM_A_PIN_MODE_OUTPUT() ({ DDRB |= 0b00001000; })

#define PIN2_DIGITAL_READ() ({ (PIND & 0b00000100) == 0 ? LOW : HIGH; })

#define PIN3_DIGITAL_READ() ({ (PIND & 0b00001000) == 0 ? LOW : HIGH; })

#define PIN4_DIGITAL_READ() ({ (PIND & 0b00010000) == 0 ? LOW : HIGH; })

#define PIN5_DIGITAL_READ() ({ (PIND & 0b00100000) == 0 ? LOW : HIGH; })

#define PIN6_DIGITAL_READ() ({ (PIND & 0b01000000) == 0 ? LOW : HIGH; })

#define PIN7_DIGITAL_READ() ({ (PIND & 0b10000000) == 0 ? LOW : HIGH; })

#define PIN8_DIGITAL_READ() ({ (PINB & 0b00000001) == 0 ? LOW : HIGH; })

#define PINA0_DIGITAL_READ() ({ (PINC & 0b00000001) == 0 ? LOW : HIGH; })

#define PINA1_DIGITAL_READ() ({ (PINC & 0b00000010) == 0 ? LOW : HIGH; })


#define PINA2_DIGITAL_READ() ({ (PINC & 0b00000100) == 0 ? LOW : HIGH; })

#define PINA3_DIGITAL_READ() ({ (PINC & 0b00001000) == 0 ? LOW : HIGH; })

#endif

void initializePWMTimer() {

cli();

TIMER2_PWM_A_PIN_MODE_OUTPUT(); // Set the A PWM pin of TIMER2 to output

ASSR &= ~(_BV(EXCLK) | _BV(AS2));

TCCR2A = (1 << COM2A0) | (1 << WGM21) | (1 << WGM20);

TCCR2B = (1 << WGM22) | (1 << CS20);

OCR2A = 0;

sei();

byte readCameraRegister(byte registerId) {

Wire.beginTransmission(CAMERA_ADDRESS);

Wire.write(registerId);

Wire.endTransmission();

Wire.requestFrom(CAMERA_ADDRESS, 1);

while (Wire.available() <= 0);

byte registerValue = Wire.read();

delay(1);

return registerValue;

}
void writeCameraRegister(byte registerId, byte registerValue) {

Wire.beginTransmission(CAMERA_ADDRESS);

Wire.write(registerId);

Wire.write(registerValue);

Wire.endTransmission();

delay(1);

void captureFrame(unsigned int frameWidth, unsigned int frameHeight) {

Serial.print("*RDY*"); // send to the frame capture software a "start of frame" message for beginning
capturing

delay(1000);

cli(); // disable all interrupts during frame capture (because it needs to be as fast as possible)

while (PIN3_DIGITAL_READ() == LOW); // wait until VS/VSYNC pin is high

while (PIN3_DIGITAL_READ() == HIGH); // wait until VS/VSYNC pin is low

unsigned int tempWidth = 0;

while (frameHeight--) {

tempWidth = frameWidth;

while (tempWidth--) {

while (PIN2_DIGITAL_READ() == LOW); // wait until PCLK pin is high

while (PIN2_DIGITAL_READ() == HIGH); // wait until PCLK pin is low

byte byteToWrite = 0b00000000;

byteToWrite |= ((PIN7_DIGITAL_READ() == HIGH) << 7);


byteToWrite |= ((PIN6_DIGITAL_READ() == HIGH) << 6);

byteToWrite |= ((PIN5_DIGITAL_READ() == HIGH) << 5);

byteToWrite |= ((PIN4_DIGITAL_READ() == HIGH) << 4);

byteToWrite |= ((PINA3_DIGITAL_READ() == HIGH) << 3);

byteToWrite |= ((PINA2_DIGITAL_READ() == HIGH) << 2);

byteToWrite |= ((PINA1_DIGITAL_READ() == HIGH) << 1);

byteToWrite |= ((PINA0_DIGITAL_READ() == HIGH));

UDR0 = byteToWrite; // send data via serial connection with UART register (we need to use the serial
register directly for fast transfer)

while (PIN2_DIGITAL_READ() == LOW); // wait until PCLK pin is high

while (PIN2_DIGITAL_READ() == HIGH); // wait until PCLK pin is low

// ignore each second byte (for a grayscale image we only need each first byte, which represents
luminescence)

sei(); // enable all interrupts

delay(1000);

void setup() {

initializePWMTimer();

Wire.begin();

Serial.begin(1000000); // the frame capture software communicates with the Arduino at a baud rate of
1MHz

}
void loop() {

captureFrame(320, 240); // capture a frame at QVGA resolution (320 x 240)

Vous aimerez peut-être aussi