Vytvořil: Martin Kráčala, 17.1.2015
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.
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í:
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.
Výstupem senzoru je 8-bitová datová sběrnice přenášející následující obrazové formáty:
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í 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.
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.
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]].
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)); }
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.
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í.
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.
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í: