Sommario:

Crea la tua fotocamera: 8 passaggi
Crea la tua fotocamera: 8 passaggi

Video: Crea la tua fotocamera: 8 passaggi

Video: Crea la tua fotocamera: 8 passaggi
Video: TRUCCO INCREDIBILE CHE DEVI SAPERE! 2024, Luglio
Anonim
Image
Image
Crea la tua fotocamera
Crea la tua fotocamera

Questa istruzione spiega come realizzare una fotocamera monocromatica utilizzando un sensore di immagine Omnivision OV7670, un microcontrollore Arduino, alcuni cavi jumper e il software Processing 3.

Viene presentato anche un software sperimentale per ottenere un'immagine a colori.

Premere il tasto "c" per acquisire un'immagine da 640*480 pixel… premere il tasto "s" per salvare l'immagine su file. Le immagini successive sono numerate in sequenza se si desidera creare un breve filmato time-lapse.

La fotocamera non è veloce (ogni scansione richiede 6,4 secondi) ed è adatta solo per l'uso con illuminazione fissa.

Il costo, escludendo Arduino e PC, è inferiore a una tazza di caffè.

immagini

Le parti componenti, prive di ponticello, sono mostrate nella foto di apertura.

La seconda foto è uno screenshot che mostra il software della fotocamera Arduino e il frame-grabber Processing 3. L'inserto mostra come è collegata la fotocamera.

Il video mostra la telecamera in azione. Quando si preme il tasto di acquisizione "c", si verifica un breve lampo seguito da un'esplosione di attività durante la scansione dell'immagine. L'immagine viene visualizzata automaticamente nella finestra del display una volta completata la scansione. Le immagini vengono quindi visualizzate nella cartella Elaborazione dopo ogni pressione del tasto "s". Il video si conclude scorrendo rapidamente ciascuna delle tre immagini salvate.

Passaggio 1: Schema del circuito

Schema elettrico
Schema elettrico
Schema elettrico
Schema elettrico
Schema elettrico
Schema elettrico

Lo schema elettrico, per tutte le versioni di questa fotocamera, è mostrato nella foto 1.

Le foto 2, 3 mostrano come sono collegati i ponticelli e i componenti.

Senza la staffa in alluminio le immagini giacciono su un fianco.

Avvertimento

Programma il tuo Arduino PRIMA di collegare i cavi dei ponticelli al chip della fotocamera OV7670. Ciò impedirà ai pin di uscita da 5 volt di un programma precedente di distruggere il chip della fotocamera OV7670 da 3v3 volt.

Passaggio 2: elenco delle parti

Elenco delle parti
Elenco delle parti

Le seguenti parti sono state ottenute da

  • 1 solo modulo telecamera VGA OV7670 300KP per arduino KIT FAI DA TE
  • 1 solo staffa per telecamera completa di dadi e bulloni
  • 1 solo UNO R3 per arduino MEGA328P 100% originale ATMEGA16U2 con cavo USB

Le seguenti parti sono state ottenute localmente

  • 18 cavi jumper Arduino maschio-femmina per Arduino
  • 3 soli cavi jumper femmina-femmina Arduino
  • 1 solo mini tagliere
  • 4 solo resistenze 4K7 ohm 1/2 watt
  • 1 solo supporto in alluminio di scarto.

Avrai anche bisogno delle seguenti schede tecniche:

  • https://web.mit.edu/6.111/www/f2016/tools/OV7670_20…
  • https://www.haoyuelectronics.com/Attachment/OV7670%…

Passaggio 3: teoria

Teoria
Teoria

Chip fotocamera OV7670

L'uscita predefinita dal chip della fotocamera OV7670 comprende un segnale video YUV (4:2:2) e 3 forme d'onda di temporizzazione. Altri formati di output sono possibili programmando i registri interni tramite un bus compatibile I2C.

Il segnale video YUV (4:2:2) (foto 1) è una sequenza continua di pixel monocromatici (bianco e nero) separati da informazioni di colore U (differenza di colore blu) e V (differenza di colore rosso).

Questo formato di output è noto come YUV (4:2:2) poiché ogni gruppo di 4 byte contiene 2 byte monocromatici e 2 byte a colori.

Monocromo

Per ottenere un'immagine monocromatica dobbiamo campionare ogni secondo byte di dati.

Un Arduino ha solo 2K di memoria ad accesso casuale, ma ogni frame comprende 640*2*480 = 307, 200 byte di dati. A meno che non si aggiunga un frame-grabber all'OV7670, tutti i dati devono essere inviati al PC riga per riga per l'elaborazione.

Ci sono due possibilità:

Per ciascuno dei 480 frame successivi, possiamo catturare una linea su Arduino ad alta velocità prima di inviarla al PC a 1Mbps. Un tale approccio vedrebbe l'OV7670 funzionare a piena velocità ma richiederebbe molto tempo (ben più di un minuto).

L'approccio che ho adottato è quello di rallentare il PCLK fino a 8uS e inviare ogni campione come viene. Questo approccio è significativamente più veloce (6,4 secondi).

Passaggio 4: note di progettazione

Note di progettazione
Note di progettazione
Note di progettazione
Note di progettazione
Note di progettazione
Note di progettazione

Compatibilità

Il chip della fotocamera OV7670 è un dispositivo da 3v3 volt. La scheda tecnica indica che le tensioni superiori a 3,5 volt danneggeranno il chip.

Per evitare che il tuo Arduino da 5 volt distrugga il chip della fotocamera OV7670:

  • Il segnale del clock esterno (XCLK) proveniente da Arduino deve essere ridotto a un livello di sicurezza tramite un partitore di tensione.
  • Le resistenze pull-up Arduino I2C interne a 5 volt devono essere disabilitate e sostituite con resistenze pull-up esterne all'alimentazione 3v3 volt.
  • Programma il tuo Arduino PRIMA di collegare eventuali ponticelli poiché alcuni dei pin potrebbero essere ancora programmati come output da un progetto precedente !!! (L'ho imparato a mie spese… fortunatamente ne ho comprati due perché erano così economici).

Orologio esterno

Il chip della fotocamera OV7670 richiede un clock esterno nella gamma di frequenza da 10 Mhz a 24 MHz.

La frequenza più alta che possiamo generare da un Arduino a 16 MHz è 8 MHz, ma sembra funzionare.

Collegamento seriale

Sono necessari almeno 10 uS (microsecondi) per inviare 1 byte di dati su un collegamento seriale da 1 Mbps (milioni di bit al secondo). Questa volta è così composta:

  • 8 bit di dati (8us)
  • 1 bit di avvio (1uS)
  • 1 bit di stop (1uS)

Orologio interno

La frequenza del pixel clock interno (PCLK) all'interno dell'OV7670 è impostata dai bit [5:0] all'interno del registro CLKRC (vedi foto 1). [1]

Se impostiamo bit[5:0] = B111111 = 63 e lo applichiamo alla formula sopra, allora:

  • F(clock interno) = F (clock di ingresso)/(Bit[5:0}+1)
  • = 8000000/(63+1)
  • = 125000 Hz o
  • = 8uS

Poiché stiamo campionando solo ogni secondo byte di dati, un intervallo PCLK di 8 uS risulta in un campione di 16 uS che è un tempo sufficiente per trasmettere 1 byte di dati (10 uS) lasciando 6 uS per l'elaborazione.

Frequenza dei fotogrammi

Ciascun frame video VGA comprende 784*510 pixel (elementi di immagine) di cui vengono visualizzati 640*480 pixel. Poiché il formato di output YUV (4:2:2) ha una media di 2 byte di dati per pixel, ogni fotogramma impiegherà 784*2*510*8 uS = 6,4 secondi.

Questa fotocamera NON è veloce!!!

Posizionamento orizzontale

L'immagine può essere spostata orizzontalmente se cambiamo i valori HSTART e HSTOP mantenendo una differenza di 640 pixel.

Quando sposti l'immagine a sinistra, è possibile che il tuo valore HSTOP sia inferiore al valore HSTART!

Non allarmatevi… è tutto a che fare con gli overflow del contatore come spiegato nella foto 2.

Registri

L'OV7670 ha 201 registri a otto bit per controllare cose come guadagno, bilanciamento del bianco ed esposizione.

Un byte di dati consente solo 256 valori nell'intervallo da [0] a [255]. Se abbiamo bisogno di un maggiore controllo, dobbiamo mettere in cascata diversi registri. Due byte ci danno 65536 possibilità… tre byte ci danno 16, 777, 216.

Il registro AEC (Controllo automatico dell'esposizione) a 16 bit mostrato nella foto 3 è un esempio e viene creato combinando parti dei tre registri seguenti.

  • AECH[5:0] = AEC[15:10]
  • AEC[7:2] = AEC[9:2]
  • COM1[1:0] = AEC[1:0]

Attenzione… gli indirizzi dei registri non sono raggruppati!

Effetti collaterali

Un frame rate lento introduce una serie di effetti collaterali indesiderati:

Per una corretta esposizione, l'OV7670 prevede di funzionare a una frequenza fotogrammi di 30 fps (fotogrammi al secondo). Poiché ogni fotogramma impiega 6,4 secondi, l'otturatore elettronico è aperto 180 volte più a lungo del normale, il che significa che tutte le immagini saranno sovraesposte a meno che non alteriamo alcuni valori di registro.

Per evitare la sovraesposizione ho impostato tutti i bit del registro AEC (controllo dell'esposizione automatica) a zero. Anche così è necessario un filtro a densità neutra davanti all'obiettivo quando l'illuminazione è intensa.

Anche una lunga esposizione sembra influenzare i dati UV. Dato che devo ancora trovare combinazioni di registro che producano colori corretti … considera questo come un lavoro in corso.

Nota

[1]

La formula mostrata nella scheda tecnica (foto 1) è corretta ma l'intervallo mostra solo bit[4:0] ?

Passaggio 5: forme d'onda di temporizzazione

Forme d'onda di temporizzazione
Forme d'onda di temporizzazione
Forme d'onda di temporizzazione
Forme d'onda di temporizzazione
Forme d'onda di temporizzazione
Forme d'onda di temporizzazione

La nota nell'angolo in basso a sinistra del diagramma "VGA Frame Timing" (foto 1) recita:

Per YUV/RGB, tp = 2 x TPCLK

Le figure 1, 2 e 3 verificano i fogli dati e confermano che Omnivision considera ogni 2 byte di dati come l'equivalente di 1 pixel.

Le forme d'onda dell'oscilloscopio verificano anche che HREF rimanga BASSO durante gli intervalli di soppressione.

La Fig.4 conferma che l'uscita XCLK da Arduino è 8MHz. Il motivo per cui vediamo un'onda sinusoidale, piuttosto che un'onda quadra, è che tutte le armoniche dispari sono invisibili al mio oscilloscopio di campionamento da 20 MHz.

Passaggio 6: Frame Grabber

Telaio Grabber
Telaio Grabber

Il sensore di immagine all'interno di un chip della fotocamera OV7670 comprende una matrice di 656*486 pixel di cui una griglia di 640*480 pixel viene utilizzata per la foto.

I valori dei registri HSTART, HSTOP, HREF e VSTRT, VSTOP, VREF vengono utilizzati per posizionare l'immagine sul sensore. Se l'immagine non è posizionata correttamente sul sensore vedrai una banda nera su uno o più bordi come spiegato nella sezione "Note di progettazione".

L'OV7670 esegue la scansione di ogni riga dell'immagine un pixel alla volta partendo dall'angolo in alto a sinistra fino a raggiungere il pixel in basso a destra. L'Arduino passa semplicemente questi pixel al PC tramite il collegamento seriale come mostrato nella foto 1.

Il compito dei frame-grabber è catturare ciascuno di questi 640*480=307200 pixel e visualizzare il contenuto in una finestra "immagine"

L'elaborazione 3 ottiene ciò utilizzando le seguenti quattro righe di codice !!

Riga di codice 1:

byte byteBuffer = nuovo byte[maxBytes+1]; // dove maxBytes=307200

Il codice sottostante in questa istruzione crea:

  • un array di 307201 byte chiamato “byteBuffer[307201]”
  • Il byte aggiuntivo è per un carattere di terminazione (linefeed).

Riga di codice 2:

dimensione (640, 480);

Il codice sottostante in questa istruzione crea:

  • una variabile chiamata “larghezza=640;”
  • una variabile denominata “altezza=480”;
  • un array di 307200 pixel chiamato "pixel[307200]"
  • una finestra “immagine” da 640*480 pixel in cui vengono visualizzati i contenuti dell'array pixels. Questa finestra "immagine" viene continuamente aggiornata a un frame rate di 60 fps.

Riga di codice 3:

byteCount = myPort.readBytesUntil(lf, byteBuffer);

Il codice sottostante in questa dichiarazione:

  • memorizza i dati in entrata localmente finché non vede un carattere "lf" (linefeed).
  • dopodiché scarica i primi 307200 byte di dati locali nell'array byteBuffer.
  • Salva anche il numero di byte ricevuti (307201) in una variabile chiamata “byteCount”.

Riga di codice 4:

pixel = color(byteBuffer);

Quando inserito in un ciclo for-next, il codice sottostante in questa istruzione:

  • copia il contenuto dell'array “byteBuffer” nell'array “pixels”
  • il cui contenuto appare nella finestra dell'immagine.

Tratti chiave:

Il frame-grabber riconosce le seguenti sequenze di tasti:

  • 'c' = cattura l'immagine
  • 's' = salva l'immagine su file.

Passaggio 7: software

Scarica e installa ciascuno dei seguenti pacchetti software, se non è già installato:

  • “Arduino” da
  • “Java 8” da https://java.com/en/download/ [1]
  • "Processing 3" da

Installazione dello schizzo Arduino:

  • Rimuovere tutti i cavi dei ponticelli OV7670 [2]
  • Collega un cavo USB al tuo Arduino
  • Copia il contenuto di "OV7670_camera_mono_V2.ino" (allegato) in uno "schizzo" di Arduino e salva.
  • Carica lo schizzo sul tuo Arduino.
  • Scollega l'Arduino
  • Ora puoi ricollegare in sicurezza i cavi del ponticello OV7670
  • Ricollegare il cavo USB.

Installazione ed esecuzione dello sketch di Processing

  • Copia il contenuto di "OV7670_camera_mono_V2.pde" (allegato) in uno "schizzo" di elaborazione e salva.
  • Fare clic sul pulsante "Esegui" in alto a sinistra… apparirà una finestra di immagine nera
  • Fare clic sulla finestra dell'immagine "nera"
  • Premere il tasto "c" per acquisire un'immagine. (circa 6,4 secondi).
  • Premi il tasto "s" per salvare l'immagine nella cartella di elaborazione
  • Ripeti i passaggi 4 e 5
  • Fare clic sul pulsante "stop" per uscire dal programma.

Appunti

[1]

L'elaborazione 3 richiede Java 8

[2]

Questo è un passaggio di sicurezza "una volta sola" per evitare di danneggiare il chip della fotocamera OV7670.

Fino a quando lo sketch "OV7670_camera_mono.ini" non è stato caricato sul tuo Arduino, i resistori di pull-up interni sono collegati a 5 volt, inoltre c'è la possibilità che alcune delle linee dati di Arduino possano essere uscite a 5 volt … il chip della fotocamera 3v3 volt OV7670.

Una volta che Arduino è stato programmato, non è necessario ripetere questo passaggio e i valori del registro possono essere modificati in sicurezza.

Passaggio 8: ottenere un'immagine a colori

Ottenere un'immagine a colori
Ottenere un'immagine a colori
Ottenere un'immagine a colori
Ottenere un'immagine a colori
Ottenere un'immagine a colori
Ottenere un'immagine a colori

Il seguente software è puramente sperimentale e viene pubblicato nella speranza che alcune delle tecniche si rivelino utili. I colori sembrano essere invertiti… devo ancora trovare le corrette impostazioni di registro. Se trovi una soluzione, pubblica i risultati

Se vogliamo ottenere un'immagine a colori, tutti i byte di dati devono essere catturati e devono essere applicate le seguenti formule.

L'OV7670 utilizza le seguenti formule per convertire le informazioni sui colori RGB (rosso, verde, blu) in YUV (4:2:2): [1]

  • Y = 0,31*R + 0,59*G + 0,11*B
  • U = B – Y
  • V = R – Y
  • Cb = 0,563*(B-Y)
  • Cr = 0,713*(R-Y)

Le seguenti formule possono essere utilizzate per riconvertire YUV (4:2:2) in colore RGB: [2]

  • R = Y + 1,402* (Cr – 128)
  • G = Y – 0,344136*(Cb -128) – 0,714136*(Cr -128)
  • B = Y + 1,772*(Cb -128)

Il software allegato è semplicemente un'estensione del software monocromatico:

  • Una richiesta di acquisizione "c" viene inviata ad Arduino
  • L'Arduino invia i byte pari (monocromatici) al PC
  • Il PC salva questi byte in un array
  • L'Arduino poi invia i byte dispari (chroma) al PC.
  • Questi byte vengono salvati in un secondo array… ora abbiamo l'intera immagine.
  • Le formule di cui sopra vengono ora applicate a ciascun gruppo di quattro byte di dati UYVY.
  • I pixel di colore risultanti vengono quindi posizionati nell'array "pixel"
  • Il PC esegue la scansione dell'array “pixels” e nella finestra “image” appare un'immagine.

Il software Processing 3 visualizza brevemente ogni scansione e i risultati finali:

  • La foto 1 mostra i dati di crominanza U e V dalla scansione 1
  • La foto 2 mostra i dati di luminanza Y1 e Y2 dalla scansione 2
  • La foto 3 mostra l'immagine a colori… solo una cosa non va… la borsa dovrebbe essere verde!!

Pubblicherò un nuovo codice una volta risolto questo programma…

Riferimenti:

[1]

www.haoyuelectronics.com/Attachment/OV7670%… (pagina 33)

[2]

en.wikipedia.org/wiki/YCbCr (conversione JPEG)

Fai clic qui per visualizzare gli altri miei istruttori.

Consigliato: