Захват изображений с OV7670 (без FIFO) с использованием Arduino Uno?

Я хочу захватить изображения с моего OV7670 (без FIFO) и отправить их на свой компьютер через Wi-Fi (ESP8266) (которым я умею пользоваться) с помощью Arduino Uno. Я прочитал так много блогов и тем в Интернете, но не смог найти простого и точного решения проблемы. Я новичок в этом, и все, что мне нужно, это простая схема подключения, код, который можно использовать с Arduino IDE, и направление действий.

Я нашел этот случайный код. Пожалуйста, посмотрите, смогу ли я его использовать.

    #include <Wire.h>
    #include <Ethernet.h>
    #include <SPI.h>
    uint8_t sensor_addr = 0x42;

    //************ REGISTRADORES **********************//

    #define REG_COM1    0x04    /* Control 1 */

    #define REG_COM7    0x12    /* Control 7 */

    #define   COM7_RESET      0x80    /* Register reset */

    #define   COM7_FMT_MASK   0x38

    #define   COM7_FMT_VGA    0x00

    #define   COM7_FMT_CIF    0x20    /* CIF format */

    #define   COM7_FMT_QVGA   0x10    /* QVGA format */

    #define   COM7_FMT_QCIF   0x08    /* QCIF format */

    #define   COM7_RGB    0x04    /* bits 0 and 2 - RGB format */

    #define   COM7_YUV    0x00    /* YUV */

    #define   COM7_BAYER      0x01    /* Bayer format */

    #define   COM7_PBAYER     0x05    /* "Processed bayer" */

    #define REG_RGB444  0x8c    /* RGB 444 control */

    #define   R444_ENABLE     0x02    /* Turn on RGB444, overrides 5x5 */

    #define   R444_RGBX   0x01    /* Empty nibble at end */

    #define REG_COM9    0x14    /* Control 9  - gain ceiling */

    #define REG_COM10   0x15    /* Control 10 */

    #define REG_COM13   0x3d    /* Control 13 */

    #define   COM13_GAMMA     0x80    /* Gamma enable */

    #define   COM13_UVSAT     0x40    /* UV saturation auto adjustment */

    #define   COM13_UVSWAP    0x01    /* V before U - w/TSLB */

    #define REG_COM15   0x40    /* Control 15 */

    #define   COM15_R10F0     0x00    /* Data range 10 to F0 */

    #define   COM15_R01FE     0x80    /*            01 to FE */

    #define   COM15_R00FF     0xc0    /*            00 to FF */

    #define   COM15_RGB565    0x10    /* RGB565 output */

    #define   COM15_RGB555    0x30    /* RGB555 output */

    #define REG_COM11   0x3b    /* Control 11 */

    #define   COM11_NIGHT     0x80    /* NIght mode enable */

    #define   COM11_NMFR      0x60    /* Two bit NM frame rate */

    #define   COM11_HZAUTO    0x10    /* Auto detect 50/60 Hz */

    #define   COM11_50HZ      0x08    /* Manual 50Hz select */

    #define   COM11_EXP   0x02

    #define REG_COM16   0x41    /* Control 16 */

    #define   COM16_AWBGAIN   0x08    /* AWB gain enable */

    #define REG_COM17       0x42    /* Control 17 */

    #define COM17_AECWIN    0xc0    /* AEC window - must match COM4 */

    #define COM17_CBAR      0x08    /* DSP Color bar */

    #define REG_TSLB    0x3a    /* lots of stuff */

    #define   TSLB_YLAST      0x04    /* UYVY or VYUY - see com13 */

    #define MTX1            0x4f    /* Matrix Coefficient 1 */

    #define MTX2            0x50    /* Matrix Coefficient 2 */

    #define MTX3            0x51    /* Matrix Coefficient 3 */

    #define MTX4            0x52    /* Matrix Coefficient 4 */

    #define MTX5            0x53    /* Matrix Coefficient 5 */

    #define MTX6            0x54    /* Matrix Coefficient 6 */

    #define REG_CONTRAS     0x56    /* Contrast control */

    #define MTXS            0x58    /* Matrix Coefficient Sign */

    #define AWBC7           0x59    /* AWB Control 7 */

    #define AWBC8           0x5a    /* AWB Control 8 */

    #define AWBC9           0x5b    /* AWB Control 9 */

    #define AWBC10          0x5c    /* AWB Control 10 */

    #define AWBC11          0x5d    /* AWB Control 11 */

    #define AWBC12          0x5e    /* AWB Control 12 */

    #define REG_GFIX        0x69    /* Fix gain control */

    #define GGAIN           0x6a    /* G Channel AWB Gain */

    #define DBLV            0x6b    

    #define AWBCTR3         0x6c    /* AWB (Automatic White Balance) Control 3 */

    #define AWBCTR2         0x6d    /* AWB Control 2 */

    #define AWBCTR1         0x6e    /* AWB Control 1 */

    #define AWBCTR0         0x6f    /* AWB Control 0 */

    #define REG_COM8    0x13    /* Control 8 */

    #define   COM8_FASTAEC    0x80    /* Enable fast AGC/AEC (Automatic Gain Control - Automatic Exposure Control)*/

    #define   COM8_AECSTEP    0x40    /* Unlimited AEC step size */

    #define   COM8_BFILT      0x20    /* Band filter enable */

    #define   COM8_AGC    0x04    /* Auto gain enable */

    #define   COM8_AWB    0x02    /* White balance enable */

    #define   COM8_AEC    0x01    /* Auto exposure enable */

    #define REG_COM3        0x0c    /* Control 3 */

    #define COM3_SWAP       0x40    /* Byte swap */

    #define COM3_SCALEEN    0x08    /* Enable scaling */

    #define COM3_DCWEN      0x04    /* Enable downsamp/crop/window */

    #define REG_BRIGHT      0x55    /* Brightness */

    #define REG_COM14      0x3E    

    //*************************************************************************//

    byte mac[] = {
      0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // MAC do arduino
    IPAddress ip(192,168,0,120); // IP do arduino
    byte server[] = {
      192,168,0,105}; //Endereço do servidor



    void setup (){

      DDRC&=~15;//low d0-d3 camera  PORTC (pino A0 ao pino A5) (11110000) A0 a A3 como entrada e A4 (SDA) e A5 (SCL) como saídas - essa linha tem a mesma função de pinMode que declara quem 
      //é pino de saída e de entrada. Se for 0 é entrada e se for 1 é saída. O valor é não 15 (acima).                 
      DDRD&=~255;//d7-d4 and interupt pins PORTD (pino 0 ao pino 7) (0000 d7 ao d4           0=d3=vsync 0=d2=pclock               0=d1=href   1=d0=button)

      DDRB&=~1;

      Serial.begin(57600);
      Wire.begin();

      UCSR0B = (1<<RXEN0)|(1<<TXEN0);//Enable receiver and transmitter (habilita bit 4 e bit 3)

      UCSR0C=6;// B (00000110) async (b7 e b6 = 00); (b3 = 0) 1 stop bit; (b2 e b1 = 1)  8bit char; no parity bits (b5 e b4 = 00); (b0 = 0)clock polaridade

      //set up twi for 100khz
      TWSR&=~3;//disable prescaler for TWI
      TWBR=72;//set to 100khz

      //SET UP CAMERA
      wrReg(0x15,32);//pclk does not toggle on HBLANK COM10 vsync falling
      //wrReg(0x15,0);//pclk does not toggle on HBLANK COM10 vsync falling
      wrReg(REG_RGB444, 0x00);             // Disable RGB444
      wrReg(REG_COM11,226);//enable nigh mode 1/8 frame rate COM11*/
      wrReg(REG_TSLB,0x04);                // 0D = UYVY  04 = YUYV     
      wrReg(REG_COM13,0x88);               // connect to REG_TSLB
      //definição para o RGB 565
      wrReg(REG_COM7, 0x04);           // RGB + color bar disable 
      wrReg(REG_COM15, 0xD0);          // Set rgb565 with Full range    0xD0

        wrReg(REG_COM3,0);    // REG_COM3

      wrReg(0x32,0xb6);        // HREF   
      wrReg(0x17,0x13);        // HSTART
      wrReg(0x18,0x01);        // HSTOP
      wrReg(0x19,0x02);        // VSTART
      wrReg(0x1a,0x7a);        // VSTOP
      wrReg(0x03,0x0a);        // VREF

      wrReg(REG_COM1, 0x00);



      //COLOR SETTING
      wrReg(REG_COM8,0x8F);        // AGC AWB AEC Unlimited step size
      wrReg(0xAA,0x14);            // Average-based AEC algorithm
      wrReg(REG_BRIGHT,0x00);      // 0x00(Brightness 0) - 0x18(Brightness +1) - 0x98(Brightness -1)
      wrReg(REG_CONTRAS,0x40);     // 0x40(Contrast 0) - 0x50(Contrast +1) - 0x38(Contrast -1)
      // wrReg(0xB1,0xB1);            // Automatic Black level Calibration
      wrReg(0xB1,4);//really enable auto black level calibration
      wrReg(MTX1,0x80);        
      wrReg(MTX2,0x80);      
      wrReg(MTX3,0x00);        
      wrReg(MTX4,0x22);        
      wrReg(MTX5,0x5e);        
      wrReg(MTX6,0x80);        
      wrReg(MTXS,0x9e);        
      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
      wrReg(REG_COM16,COM16_AWBGAIN);//disable auto denoise and edge enhancment
      //wrReg(REG_COM16,0);
      wrReg(0x4C,0);//disable denoise
      wrReg(0x76,0);//disable denoise
      wrReg(0x77,0);//disable denoise
      wrReg(0x7B,4);//brighten up shadows a bit end point 4
      wrReg(0x7C,8);//brighten up shadows a bit end point 8
      //wrReg(0x88,238);//darken highligts end point 176
      //wrReg(0x89,211);//try to get more highlight detail
      //wrReg(0x7A,60);//slope
      //wrReg(0x26,0xB4);//lower maxium stable operating range for AEC
      //hueSatMatrix(0,100);
      //ov7670_store_cmatrix();
      //wrReg(0x20,12);//set ADC range to 1.5x
      wrReg(REG_COM9,0x6A);//max gain to 128x
      wrReg(0x11,9);//using scaler for divider
      delay(100);//i2c uses interupts to write data wait for all bytes to be written



      //            #ifdef qqvga || ifdef qvga

      wrReg(REG_COM3,4);    // REG_COM3 

      //    #ifdef qqvga

      wrReg(REG_COM14, 0x1a);          // divide by 4

      wrReg(0x72, 0x22);               // downsample by 4

      wrReg(0x73, 0xf2);               // divide by 4

      wrReg(0x17,0x16);

      wrReg(0x1A,0x04);

      wrReg(0x32,0xa4);           

      wrReg(0x19,0x02);

      wrReg(0x18,0x7a);

      wrReg(0x03,0x0a);




      wrReg(REG_COM1, 0x00);

      // COLOR SETTING



      wrReg(REG_COM8,0x8F);        // AGC AWB AEC Unlimited step size

      wrReg(0xAA,0x14);            // Average-based AEC algorithm

      wrReg(REG_BRIGHT,0x00);      // 0x00(Brightness 0) - 0x18(Brightness +1) - 0x98(Brightness -1)

      wrReg(REG_CONTRAS,0x40);     // 0x40(Contrast 0) - 0x50(Contrast +1) - 0x38(Contrast -1)

      // wrReg(0xB1,0xB1);            // Automatic Black level Calibration

      wrReg(0xB1,4);//really enable auto black level calibration

      wrReg(MTX1,0x80);        

      wrReg(MTX2,0x80);      

      wrReg(MTX3,0x00);        

      wrReg(MTX4,0x22);        

      wrReg(MTX5,0x5e);        

      wrReg(MTX6,0x80);        

      wrReg(MTXS,0x9e);        

      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

      wrReg(REG_COM16,COM16_AWBGAIN);//disable auto denoise and edge enhancment

      //wrReg(REG_COM16,0);

      wrReg(0x4C,0);//disable denoise

      wrReg(0x76,0);//disable denoise

      wrReg(0x77,0);//disable denoise

      wrReg(0x7B,4);//brighten up shadows a bit end point 4

        wrReg(0x7C,8);//brighten up shadows a bit end point 8

        //wrReg(0x88,238);//darken highligts end point 176

      //wrReg(0x89,211);//try to get more highlight detail

      //wrReg(0x7A,60);//slope

      //wrReg(0x26,0xB4);//lower maxium stable operating range for AEC

      //hueSatMatrix(0,100);

      //ov7670_store_cmatrix();

      //wrReg(0x20,12);//set ADC range to 1.5x

      wrReg(REG_COM9,0x6A);//max gain to 128x

      //    #ifdef qvga

      wrReg(0x11,4);//using scaler for divider

      pinMode(4,OUTPUT);
      digitalWrite(4,HIGH);
      Serial.println("Iniciando conexao");
      Ethernet.begin(mac, ip);
      Serial.println("Por favor, espere.");
      delay(1000);

    }


    EthernetClient client;
    void loop (){

    connectWeb(7000,server);
    foto(480,640);

    }


    byte wrReg(int regID, int regDat )

    { 

      Wire.beginTransmission(sensor_addr >> 1);
      Wire.write(regID & 0x00FF);   
      Wire.write(regDat & 0x00FF);  
      if(Wire.endTransmission())
      {
        return 0; 
        PORTB|=32;
        while (1) {
        }
      }
      delay(1);
      return(1);
    }

    uint16_t d;


    void foto(uint16_t linha, uint16_t coluna)
    { 
      while (!(PIND&8)) {
      }//wait for high
      while ((PIND&8)) {
      }//wait for low
      //uint16_t a =millis(); //teste de tempo
      if (linha != 0)
      {
        //while (!(PINB&1)) {}//wait for high
        //while ((PINB&1)) {}//wait for low
        //while (!(PINB&1)) {}//wait for high

        while (linha--)
        {

          while (!(PIND&4)) {
          }//wait for high
          while ((PIND&4)) {
          }//wait for low
          //      int a = millis(); //teste de tempo

          uint16_t byte1, byte2;
          uint8_t buf[512];

          uint16_t  coluna_temp=coluna;
          while (coluna--){

            for(int i=0; i<2;i++){
              while (!(PIND&4)) {
              }//wait for high
              if(i==0){             
                byte1= (uint8_t)(PINC&15)|(PIND&240); //B 00001111 (A0 a A3) ou 11110000 (d7 ao d4)
              }
              else{
                byte2= (uint8_t)(PINC&15)|(PIND&240);

                //((byte1<<8)|byte2);
               /* for(int x=0;x<512;x++){
                  buf[x]= (((byte1<<8)|byte2),BIN);
                  d+=buf[x];        
                }*/
            sendMsg(client, ((byte1<<8)|byte2));    
                //Serial.println(d);

                // Serial.println(((byte1<<8)|byte2),BIN); //B 00001111 (A0 a A3) ou 11110000 (d7 ao d4)
                //teste++;
              }
              while ((PIND&4)) {
              }//wait for low
            }

          }
          //                                        int b = millis(); //teste de tempo
          //  Serial.println((b-a)); //teste de tempo
          coluna=coluna_temp;
        }

        //while ((PIND&1)) {}//wait for low



      }
      //uint16_t b =millis(); //teste de tempo
      //Serial.println((b-a)); //teste de tempo
     // return teste;

    }



    void connectWeb(int port, byte ipServer[]){

      if (client.connect(ipServer,port)){
        Serial.println("Conectado");
        //essa e a parte que da erro. Perceba que estou enviando a mensagem
        //aqui, mas a intençao e enviar na funcao de tirar a foto.Aqui e teste
       // sendMsg(client, 800);

      }else{
        Serial.println("Conexao falhou");
      }

       if (!client.connected()) {
        Serial.println();
        Serial.println("disconnecting.");
        client.stop();

        // do nothing forevermore:
        while(true);
      }

    }

    //void sendMsg(EthernetClient client, uint8_t msg){
    //      client.println("valor "+String(msg));
    //}

    void sendMsg(EthernetClient client, uint32_t msg){
          client.println(msg,DEC);
    }

, 👍5

Обсуждение

Arduino, вероятно, неправильный выбор для этой работы — даже если вы вообще сможете заставить его работать, он будет ограничен небольшой долей возможностей этой камеры., @Chris Stratton

@ChrisStratton Если Arduino действует как мост между ESP и камерой, то потери функциональности не будет, за исключением увеличения скорости передачи. Но Arpit лучше удалить Arduino, вместо этого использовать ESP для чтения данных с камеры и отправки их по Wi-Fi., @Avamander


2 ответа


2

Вы должны начать с подключения Arduino UNO к ПК. Для этого используйте следующую статью: Arduino Uno и камера ov7670 — пример использования. Длинный текст на русском языке сверху можете не обращать внимания, в нем обсуждается, почему стоит выбрать именно эту камеру.

Как указано в этом источнике, основные проблемы, с которыми вы столкнетесь:

  1. Входной ток камеры не на 100 % совместим с током Arduino. Вам нужно будет использовать резисторы. Связанный блог содержит схему того, как соединить оба.

  2. Вам потребуется написать код для подключения обоих. В интернете есть примеры. Вы также можете увидеть код, используемый в ссылке. Основная проблема здесь в том, что камера работает в режиме YUV. Каждый пиксель в этом формате кодируется двумя байтами. Первый байт кодирует градиент серого, второй несет информацию о цветности. Для простого теста достаточно получить изображение в градациях серого, поэтому отбрасываем второй байт.

Осциллограммы на связанном сайте показывают ожидаемый сигнал, за которым следует код, необходимый для считывания информации об изображении.

  1. Настоящая программа для получения изображения может быть очень простой. Автор связанной статьи написал один. Он читает из COM9, использует коммуникационный API Java и сохраняет в формате bmp. Вы можете скачать его здесь.

Это простое тестовое соединение имеет следующие недостатки:

  • Без буферизации изображение размазывается
  • На изображении есть артефакты синхронизации.
  • Вы не можете изменить фокус, объект должен находиться на расстоянии фокусировки камеры.

Следующим шагом будет передача данных по Wi-Fi. Но это будет сложно, так как Uno и модуль Wi-Fi подключены по интерфейсу UART, а максимальная скорость ограничена 230,4 Кбит/с.

Вот пример передачи изображения по Bluetooth, Передача картинки с OV7670 через Arduino Uno на телефоне Android. Это может быть полезно для вас.

Предполагается, что вы подключили Arduino и камеру, как описано выше, в шаге 1.

На шаге 2 необходимо решить проблему несоответствия скорости. Интерфейс HC-06 UART и Arduino Uno имеют следующие скорости:

HC-06: 1200/2400/4800/9600/19200/38400/57600/115200/230400/460800/921600/1382400

Arduino Uno: 2400/4800/9600/14400/19200/28800/38400/57600/76800/115200/230400/250000/500000/1000000/2000000

Максимальная скорость, общая для обоих, составляет 230 400, поэтому вы должны использовать ее. Затем вам нужно уменьшить внутреннюю скорость обработки с помощью wrReg(0x11, 31);. Отправить на 230400 все равно нельзя, потому что картинка отправляется в два приема, сначала четные строки, потом нечетные. Вы должны написать приложение Arduino для захвата изображения.

Наконец, вы можете написать программное обеспечение для телефона. Он должен только прочитать картинку и показать ее на странице, не более того. На Bluetooth 2.1 автор блога измерил более 1 минуты на кадр, и результат был сильно искажен. В Bluetooth 4.0 качество изображения было приемлемым, а отправка кадра занимала менее 15 секунд.

,

К сожалению, ссылки, которые вы предоставляете, относятся к блогам, написанным на русском языке, а это англоязычный сайт вопросов и ответов. Не могли бы вы отредактировать свой ответ, добавив ссылки на страницы, написанные на английском языке?, @Greenonline

По сути, это ответ, содержащий только ссылки, который станет бесполезным, если целевой сайт выйдет из строя. Плюс сайт по ссылке на русском, а это англоязычный сайт. Было бы полезно разместить или обобщить информацию на английском языке в вашем ответе., @Nick Gammon

к сожалению, он не прочитал ваш пост и сказал «подключитесь к uno», когда вы четко заявили, что используете esp8266., @Scott


1

перевод со страницы: http://privateblog.info/arduino-uno-i- kamera-ov7670-primer-ispolzovaniya/ (см. ссылки в исходной ссылке, так как я не мог их опубликовать, потому что мне нужно как минимум 10 репутации, бла-бла-бла)

Arduino Uno и камера ov7670 — пример использования (15 декабря 2015 г.)

В настоящее время ov7670 является самым доступным модулем получения изображений для поклонников Arduino. Когда-то он стоил около 12 долларов, сейчас его цена упала до менее 5 долларов.

ov7670 ( datasheet ) имеет хорошие возможности за свою цену:

  1. разное разрешение VGA (640 x 480); - QVGA (320 х 240); - СИФ (352 х 240); - QCIF (176 × 144);

  2. скорость передачи до 30 кадров в секунду,

  3. несколько способов кодирования изображения RAW RGB, RGB 565/555, YUV/YCbCr 4:2:2

  4. Интерфейс взаимодействия I2C.

Было бы идеально, если бы не одна проблема - подключение и получение хотя бы тестового образа, как на любом мало-мальски сложном железе. В интернете много обсуждений, статей, рекомендаций, но четких шагов найти не получается: кому-то лень их писать, кто-то выкладывает только схему или код, кто-то вообще ничего не выкладывает, а сообщает только об успешных связь. Особо хочется отметить ComputerNerd, выложивший прекрасный пример с небольшим описанием, но для новичка этого мало.

Эта статья призвана показать, как подключить, настроить и получить тестовый образ с помощью небольшой программы на java, которая станет отличной отправной точкой для дальнейших экспериментов.

Свои эксперименты я проводил на Arduino Uno, как это лучше всего описано — схемы подключения и статьи. Была попытка настроить на Arduino Mega, но она закончилась плачевно. Оказалось, что на леске А4 и А5 эта плата уже имеет опорное напряжение 5v, из-за чего сгорела камера.

В моем примере будет использоваться камера

  • Плагин AtmelStudio + Arduino

  • ov7670 без буфера, режим работы qvga (320×240), кодировка YUV

  • Ардуино Уно

  • 2 резистора на 10 кОм

  • 2 резистора по 4,7 кОм

  • компьютер.

  1. Схема подключения ov7670 к Arduino Uno

Программирование камеры необходимо начинать с правильного подключения. Напряжение на входах камеры местами отличается от напряжения Arduino, поэтому необходимы резисторы.

Схема подключения ov7670 к Arduino Uno

  1. Программа для ov7670 и Arduino Uno

Для компиляции программы мы использовали пример от ComputerNerd, который пришлось немного обрезать, а потом заменить местами. Код можно скачать по ссылке.

Основные шаги в коде следующие:

  1. Настройка ШИМ Arduino Uno так, чтобы он выдавал 8 МГц на 11-й ноге.

ДДРБ | = (1<<3); // контакт 11

АССР & = ~ (_BV (EXCLK) | _BV (AS2));

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

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

OCR2A = 0; // (F_CPU) / (2 * (X + 1))

DDRC & = ~ 15; // низкая камера d0-d3

DDRD & = ~ 252; // d7-d4 и контакты прерывания

  1. Настройка интерфейса I2C

TWSR & = ~ 3; // отключаем предварительный делитель для TWI

TWBR = 72; // установить на 100 кГц

  1. Настройка RS232.

UBRR0H = 0;

UBRR0L = 1; // 0 = скорость передачи 2M. 1 = 1 Мбод. 3 = 0,5М. 7 = 250k 207 соответствует скорости 9600 бод.

UCSR0A | = 2; // двойная скорость aysnc

UCSR0B = (1 << RXEN0) | (1<<TXEN0); // Включить приемник и передатчик

UCSR0C = 6; // асинхронный 1 стоповый бит 8-битный символ без битов четности

  1. Настройка камеры

....

wrReg (0x12, 0x80);

задержка_мс (100);

wrSensorRegs8_8 (ov7670_default_regs);

wrReg (REG_COM10, 32); // PCLK не переключается на HBLANK.

...

  1. Получение изображения

Рабочий режим камеры передачи изображения был установлен на YUV. В этом случае каждый пиксель кодируется двумя байтами. Первый байт кодирует градацию серого, второй - цветоразностную составляющую.

Наша задача — получить хотя бы черно-белое изображение, чтобы второй байт можно было отбросить.

Далее нам нужно привести осциллограмму, из которой становится понятно, какие сигналы мы ожидаем при высоких и низких значениях.

осциллограмма ov7670

StringPgm (PSTR ( "* RDY *" ));  

// ВСИНХ
while  (! (PIND &  8 )); // ждем максимума
while  ((PIND &  8 )); // ждем минимума

y = hg;  
while  (y -) {  
   x = wg;  
   while  (x -) {  
      // ПКЛК
      while  ((PIND &  4 )); // ждем минимума
      UDR0 = (PINC &  15 ) | (PIND &  240 );  
      while  (! (UCSR0A & ( 1  << UDRE0))); // ждем передачи байта
      while  (! (PIND &  4 )); // ждем максимума
      while  ((PIND &  4 )); // ждем минимума
      while  (! (PIND &  4 )); // ждем максимума
   }  
}  
_delay_ms ( 100 );  
  1. Программа на java для получения образа с ov7670 через Arduino Uno

Программа для получения изображений чрезвычайно проста. Он получает данные из порта COM9 с помощью Java Communication API и сохраняет их в формате bmp. Все переменные задаются прямо в коде, так что придется менять на свои.

граббер

  1. Результаты

На основании изображений можно сразу сделать вывод о недостатках:

  1. Отсутствие внутреннего буфера приводит к смазыванию картинки, она тут же передается на компьютер, а на это нужно время.

  2. Есть артефакты в виде горизонтальных полос - сбой синхронизации при получении картинки. Вместо градации серого прислали цветностную составляющую.

  3. Для получения четкого изображения объект должен находиться в фокусе камеры

Эту статью можно закончить. Жду комментариев и предложений.

,