Individální projekty MPOA

Mikroprocesory s architekturou ARM

Uživatelské nástroje

Nástroje pro tento web


2015:cam-al422

Kamera OV7670 s FIFO AL422

Vytvořil: Martin Kráčala, 17.1.2015

Zadání

  • Připojte modul kamery OV7670 s FIFO bufferem AL422 ke vhodnému Freedom boardu.
  • Vytvořte firmware pro sejmutí snímku z kamery, vyřešte jeho přenos do PC a následné zobrazení.
  • Využijte prostředí KDS nebo mbed.

Úvod

Tento projekt se zabývá využitím CMOS kamerového modulu OV7670 firmy OmniVision s FIFO bufferem AL422 ve spojení s mikrokontroléry s architekturou ARM. Projekt byl realizován na platformě FRDM-KL25Z od firmy Freescale s mikroprocesorem ARM Cortex-M0+ ve vývojovém prostředí mbed. Obrazová data jsou KL25Z postupně vyčítána z FIFO bufferu a posílána sériovou komunikací do PC. V rámci tohoto projektu byla dále vytvořena aplikace v prostředí MATLAB, která umožňuje připojení k sériovému portu a zpracování přijímaných obrazových dat.

Hardware

Vývojová deska FRDM-KL25Z

Projekt je založen na „ultra-low-cost“ vývojové desce FRDM-KL25Z firmy Freescale s mikroprocesorem ARM® Cortex™-M0+. Základní charakteristiky desky KL25Z jsou následující:

  • Jádro ARM® Cortex™-M0+: 48MHz, 16KB RAM, 128KB FLASH,
  • USB (Host/Device), USB sériový port,
  • rozhraní SPI, I2C, UART,
  • dotykový senzor,
  • MMA8451Q - 3-osý akcelerometr,
  • RGB led,
  • GPIO a další I/O rozhraní.

Obr. 1:  Pin mapa FRDM-KL25Z

Kamera OV7670 s FIFO AL422

Použitou periferií pro snímání obrazu je modul kamery OV7670 firmy OmniVision s integrovaným FIFO bufferem AL422, konkrétně se jedná o verzi CF76700-V3. Tato kamera je vybavena CMOS senzorem schopným zaznamenávat snímky s rozlišením VGA (640×480, 0.3 Mpx) při obnovovací frekvenci až 30 fps společně s dalšími periferiemi zajišťujícími obrazové předzpracování a externí konektivitu. Kamera díky vnitřnímu zpracování obrazu podporuje VGA i CIF rozlišení a jejich podvzorkované varianty.

Obr. 2:  Fotografie kamery OV7670 s FIFO AL422 Obr. 3:  Fotografie zadní strany kamery OV7670 s FIFO AL422 |Obr. 4:  Layout kamery CF7670C-V3

Výstupem senzoru je 8-bitová datová sběrnice přenášející následující obrazové formáty:

  • YUV/YCbCr 4:2:2
  • RGB565/555/444
  • GRB 4:2:2
  • Raw RGB

Kamera je taktována oscilátorem s frekvencí 24 MHz. Ovládá se prostřednictvím SCCB sběrnice. Jedná se o I2C rozhraní s maximální hodinovou frekvencí 400 kHz, v projektu je použito 100 kHz.

Zapojení

Zapojení jednotlivých pinů kamery je následující:

OV7670 Pin KL25Z
VCC 1 3v3
GND 2 GND
SCL (SCCB) 3 PTC8
SDA (SCCB) 4 PTC9
VSYNC 5 PTA13
HREF 6 NC
WEN 7 PTE2
XCLK 8 NC
RRST 9 PTE3
OE 10 PTE4
RCLK 11 PTE5
GND 12 GND
D0 13 PTB0
D1 14 PTB1
D2 15 PTB2
D3 16 PTB3
D4 17 PTB8
D5 18 PTB9
D6 19 PTB10
D7 20 PTB11

Na SCCB (I2C) sběrnici jsou dále připojeny nezbytné 4k7 pull-up rezistory.

 Obr. 5:  Zapojení přípravku

Firmware

Celý firmware byl tvořen SDK mbed.org. Projekt se do značné míry inspiruje pracemi OV7670 Camera (by Martin Smith) a OV7670 Camera + mbed LPC1768 over USB od (by Edoardo De Marchi) včetně v obou případech použité knihovny ov7670. Kromě ní bylo využito ještě knihovny BufferedSerial, rozšiřující možnosti běžného Serial interface definovaného v knihovně mbed o softwarový TX a RX buffer.

Odkaz k programu na mbed.org

Firmware pro KL25Z je k dispozici na stránkách mbed.org [https://developer.mbed.org/users/wrecky/code/OV7670-application-over-USB-with-KL25Z/|OV7670 application over USB with KL25Z]].

Hlavní části main.cpp

Na začátku výkonu programu je inicializováno sériové rozhraní spolu s modulem kamery OV7670.

BufferedSerial pc(USBTX, USBRX);        // PTA2,PTA1
 
OV7670 camera (
    PTC9,PTC8,                  // SDA,SCL(I2C)
    PTA13,NC,PTE2,              // VSYNC,HREF,WEN(FIFO)
    PortB,0x00000F0F,           // PortIn data PTB<0-3>,PTB<8-11>
    PTE3,PTE4,PTE5              // RRST,OE,RCLK
);

Program využívá nejvyšší podporovanou přenosovou rychlost, baudrate 921600. Program záhy zapadne do nekonečné smyčky, ve které čeká na povely z PC skrze Serial-USB.

int main()
{
    // set high baud rate
    pc.baud(BAUDRATE);                     
 
    // send hello message via Serial-USB
    pc.printf("Starting FRDM-KL25Z...\r\n");
 
    // reset camera on power up
    camera.Reset() ;
 
    while (true)
    {
        // Look whether things are in the RX-buffer...
        if(pc.readable())
        {
            int i = 0;
            // if so, load them into buffer_in
            while(pc.readable())
            {
                buffer_in[i++] = pc.getc();
            }
            // compare buffer_in with defined commands, execute
            cmd();
        }
        ledG = LED_OFF;
        wait_ms(DELAY_MS);
        ledG = LED_ON;
    }
}

Následující funkce slouží k rozeznání přijatého příkazu a jeho provedení. Obsahuje funkce na výpis všech registrů kamery (reg_status) používanou především při vývoji programu, dále funkce pro nastavení kamery (setup_…) a sejmutí a odeslání snímku (snapshot).

Základním nástrojem pro všechny tyto funkce je knihovna OV7670.

// Parse command from buffer_in and execute function
void cmd()
{
    // Read all camera registers - commandline use only (for verification) 
    if(strcmp("reg_status\r\n", buffer_in) == 0) {
        int i = 0;
        pc.printf("AD: +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F");
        for (i=0; i<OV7670_REGMAX; i++) {
            int data;
            data = camera.ReadReg(i);
            if ((i & 0x0F) == 0) {
                pc.printf("\r\n%02X: ",i);
            }
            pc.printf("%02X ",data);
        }
        pc.printf("\r\n");
    }
    // Take a picture
    else if(strcmp("snapshot\r\n", buffer_in) == 0) {
        ledR = LED_ON;
        // Kick things off by capturing an image
        camera.CaptureNext();
        while(camera.CaptureDone() == false);
        // Start reading in the image data from the camera hardware buffer
        camera.ReadStart();
        ledG = LED_OFF;
 
        for(int x = 0; x<resolution; x++) {
            // Read in the first half of the image
            if(colorscheme == RAW && resolution != VGA) {
                camera.ReadOnebyte(RMASK1,ROFFSET1,RMASK2,ROFFSET2);
            } else if(colorscheme == YUV || colorscheme == RGB) {
                pc.putc(camera.ReadOnebyte(RMASK1,ROFFSET1,RMASK2,ROFFSET2));
            }
            // Read in the Second half of the image
            pc.putc(camera.ReadOnebyte(RMASK1,ROFFSET1,RMASK2,ROFFSET2));      // Y only
        }
 
        camera.ReadStop();
        ledG = LED_ON;
 
        camera.CaptureNext();
        while(camera.CaptureDone() == false);
 
        pc.printf("Snap_done\r\n");
        ledR = LED_OFF;
    }
    // Set up commands...
    else if(strcmp("setup_RAW_VGA\r\n", buffer_in) == 0) {
        // VGA (640*480) RAW
        colorscheme = RAW;
        resolution = VGA;
        setup(colorscheme,resolution);
    }
    else if(strcmp("setup_YUV_QVGA\r\n", buffer_in) == 0)
    {
        // QVGA (320*240) YUV 4:2:2   
        colorscheme = YUV;
        resolution = QVGA;
        setup(RAW,resolution);
    }
    else
    {
        ...    // more commands
    }
    memset(buffer_in, 0, sizeof(buffer_in));
}

Zpracování v PC

Pro řízení a přenos dat z kamery je využito sériové komunikace skrze USB port. Možností komunikace na straně PC je několik, např. využití běžných terminálových aplikací nebo návrh programu pro sériovou komunikaci a zpracování snímků. V rámci této úlohy bylo využito prostředí MATLAB, které obsahuje integrované nástroje pro sériovou komunikaci, zpracování dat a v neposlední řadě i vývoj aplikací (GUI).

Aplikace je dostupná ke stažení na MATLAB Central. Umožňuje připojení k sériovému portu počítače s pokročilými možnostmi nastavení komunikačního módu. Po připojení aplikace funguje podobně, jako jiné terminály pro sériovou komunikaci. Navíc však obsahuje sadu ovládacích prvků pro řízení kamery - nastavení formátu a zachycení jednotlivých snímků, které jsou následně zobrazeny. Aplikace umožňuje také získané snímky uložit do PC. V další části dokumentace jsou uvedeny příklady sejmutých snímků i video ukazující ovládání programu.

Obr. 6:  OV7670 Serial Communication Interface

Ukázky pořízených snímků

Na následujících snímcích je předvedena kvalita snímků při různých světelných podmínkách a různých formátech snímání. Pro praktické využití je největší překážkou obtížně nastavitelné zaostření, které je vysoce citlivé a lze jej hledat pouze metodou pokud-omyl. V případě snímání na stálou vzdálenost ale prokazuje kamera poměrně vysokou kvalitu snímků, dostatečnou pro širokou nabídku praktických uplatnění.

Indoor

 Snímek 1:  "Selfie" formát RAW Bayer to RGB (640x480)  Snímek 2:  "Flora" formát RAW Bayer to RGB (640x480)  Snímek 3:  "Flora" formát RGB 565 (320x240)  Snímek 4:  "Flora" formát YUV 4:2:2 (320x240)

Outdoor

 Snímek 5:  "Proti západu slunce" formát RAW Bayer to RGB (640x480)  Snímek 6:  "Zahrady" formát RAW Bayer to RGB (640x480)  Snímek 7:  "Zahrady" formát RGB 565 (320x240)  Snímek 8:  "Zahrady" formát YUV 4:2:2 (320x240)

Video ukázka

Následující video dokazuje funkčnost projektu. Je spuštěna aplikace v MATLABu, provedeno připojení k sériovému portu, zachycení a přenesení několika snímků s různým nastavením.

Závěr

Zadání projektu bylo splněno v celém rozsahu. Ve vývojovém prostředí mbed byl vytvořen firmware pro desku FRDM-KL25Z umožňující komunikace s kamerou OV7670 s FIFO bufferem AL422 skrze sériovou komunikaci přes USB port. V PC byla vytvořena aplikace pro ovládání kamery a příjem snímků.

Dalšími možnostmi rozvoje projektu by byla implementace zbylých formátů, podporovaných kamerou OV7670 a zdokonalení programu v MATLAB. Přes na dnešní dobu nízké maximální rozlišení kamery mají snímky při správném nastavení vysokou kvalitu a kamera by tak byla použitelná například v automatizovaných robotech.


Odkazy ke stažení:

2015/cam-al422.txt · Poslední úprava: 2016/02/04 22:47 autor: Martin Kráčala