Inhaltsverzeichnis:

Machen Sie Ihre eigene Kamera - Gunook
Machen Sie Ihre eigene Kamera - Gunook

Video: Machen Sie Ihre eigene Kamera - Gunook

Video: Machen Sie Ihre eigene Kamera - Gunook
Video: How Do Germans Stay in Shape? | Easy German 424 2024, Juli
Anonim
Image
Image
Machen Sie Ihre eigene Kamera
Machen Sie Ihre eigene Kamera

Diese Anleitung erklärt, wie man eine Monochrom-Kamera mit einem Omnivision OV7670-Bildsensor, einem Arduino-Mikrocontroller, ein paar Überbrückungsdrähten und der Processing 3-Software herstellt.

Experimentelle Software zum Erhalten eines Farbbildes wird ebenfalls vorgestellt.

Drücken Sie die Taste „c“, um ein Bild mit 640*480 Pixeln aufzunehmen … drücken Sie die Taste „s“, um das Bild in einer Datei zu speichern. Aufeinanderfolgende Bilder werden fortlaufend nummeriert, falls Sie einen kurzen Zeitrafferfilm erstellen möchten.

Die Kamera ist nicht schnell (jeder Scan dauert 6,4 Sekunden) und ist nur für den Einsatz bei fester Beleuchtung geeignet.

Die Kosten ohne Arduino und PC betragen weniger als eine Tasse Kaffee.

Bilder

Die Einzelteile ohne Überbrückungsverdrahtung sind auf dem Eröffnungsfoto zu sehen.

Das zweite Foto ist ein Screenshot, der die Arduino-Kamerasoftware und den Processing 3 Frame-Grabber zeigt. Der Einschub zeigt, wie die Kamera angeschlossen ist.

Das Video zeigt die Kamera in Aktion. Wenn die Aufnahmetaste „c“gedrückt wird, blitzt kurz auf, gefolgt von einem Aktivitätsschub, während das Bild gescannt wird. Das Bild erscheint automatisch im Anzeigefenster, sobald der Scan abgeschlossen ist. Die Bilder werden dann nach jedem Drücken der Taste „s“im Ordner Processing angezeigt. Das Video endet mit einem schnellen Durchlaufen jedes der drei gespeicherten Bilder.

Schritt 1: Schaltplan

Schaltplan
Schaltplan
Schaltplan
Schaltplan
Schaltplan
Schaltplan

Der Schaltplan für alle Versionen dieser Kamera ist in Foto 1 dargestellt.

Fotos 2, 3 zeigen, wie die Jumper-Drähte und Komponenten angeschlossen werden.

Ohne die Aluminiumhalterung liegen die Bilder auf der Seite.

Warnung

Programmieren Sie Ihren Arduino, BEVOR Sie Überbrückungsdrähte an den OV7670-Kamerachip anschließen. Dadurch wird verhindert, dass 5-Volt-Ausgangspins eines vorherigen Programms den 3v3-Volt-OV7670-Kamerachip zerstören.

Schritt 2: Teileliste

Liste der Einzelteile
Liste der Einzelteile

Die folgenden Teile wurden von https://www.aliexpress.com/ bezogen.

  • 1 nur OV7670 300KP VGA Kameramodul für Arduino DIY KIT
  • 1 einzige Kamerahalterung komplett mit Schrauben und Muttern
  • 1 nur UNO R3 für arduino MEGA328P 100% original ATMEGA16U2 mit USB-Kabel

Die folgenden Teile wurden vor Ort bezogen

  • 18 anly Arduino männlich-weiblich Überbrückungskabel
  • 3 nur Arduinin weiblich-weiblich Überbrückungskabel
  • 1 nur Mini-Brotbrett
  • 4 nur 4K7 Ohm 1/2 Watt Widerstände
  • 1 nur Altaluminiumständer.

Außerdem benötigen Sie folgende Datenblätter:

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

Schritt 3: Theorie

Theorie
Theorie

OV7670 Kamerachip

Die Standardausgabe des OV7670 Kamerachips umfasst ein YUV (4:2:2) Videosignal und 3 Timing-Wellenformen. Andere Ausgabeformate sind durch Programmierung der internen Register über einen I2C-kompatiblen Bus möglich.

Das YUV (4:2:2) Videosignal (Foto 1) ist eine kontinuierliche Folge von monochromen (Schwarzweiß) Pixeln, die durch U (blaue Farbdifferenz) und V (rote Farbdifferenz) Farbinformationen getrennt sind.

Dieses Ausgabeformat ist als YUV (4:2:2) bekannt, da jede Gruppe von 4 Bytes 2 monochrome Bytes und 2 Farbbytes enthält.

Einfarbig

Um ein monochromes Bild zu erhalten, müssen wir jedes zweite Datenbyte abtasten.

Ein Arduino hat nur 2K Random Access Memory, aber jeder Frame umfasst 640*2*480 = 307.200 Datenbytes. Sofern wir dem OV7670 keinen Framegrabber hinzufügen, müssen alle Daten zur Verarbeitung zeilenweise an den PC gesendet werden.

Es gibt zwei Möglichkeiten:

Für jeden von 480 aufeinanderfolgenden Frames können wir mit hoher Geschwindigkeit eine Zeile zum Arduino erfassen, bevor wir sie mit 1 Mbit / s an den PC senden. Ein solcher Ansatz würde dazu führen, dass der OV7670 mit voller Geschwindigkeit arbeitet, aber lange dauern würde (weit über eine Minute).

Der Ansatz, den ich gewählt habe, besteht darin, den PCLK auf 8uS zu verlangsamen und jedes Sample so zu senden, wie es kommt. Dieser Ansatz ist deutlich schneller (6,4 Sekunden).

Schritt 4: Designhinweise

Designhinweise
Designhinweise
Designhinweise
Designhinweise
Designhinweise
Designhinweise

Kompatibilität

Der Kamerachip OV7670 ist ein 3v3-Volt-Gerät. Das Datenblatt weist darauf hin, dass Spannungen über 3,5 Volt den Chip beschädigen.

Um zu verhindern, dass Ihr 5-Volt-Arduino den Kamerachip OV7670 zerstört:

  • Das externe Taktsignal (XCLK) vom Arduino muss mittels eines Spannungsteilers auf ein sicheres Niveau reduziert werden.
  • Die internen Arduino I2C-Pull-Up-Widerstände auf 5 Volt müssen deaktiviert und durch externe Pull-Up-Widerstände zur 3v3-Volt-Versorgung ersetzt werden.
  • Programmieren Sie Ihren Arduino, BEVOR Sie Jumper-Drähte anschließen, da einige der Pins möglicherweise noch als Ausgang eines früheren Projekts programmiert werden !!! (Ich habe das auf die harte Tour gelernt … zum Glück habe ich zwei gekauft, da sie so billig waren).

Externe Uhr

Der Kamerachip OV7670 benötigt einen externen Takt im Frequenzbereich 10Mhz bis 24MHz.

Die höchste Frequenz, die wir von einem 16-MHz-Arduino erzeugen können, ist 8 MHz, aber dies scheint zu funktionieren.

Serielle Verbindung

Es dauert mindestens 10 uS (Mikrosekunden), um 1 Datenbyte über eine serielle Verbindung mit 1 Mbit/s (Millionen Bits pro Sekunde) zu senden. Diese Zeit setzt sich wie folgt zusammen:

  • 8 Datenbits (8us)
  • 1 Startbit (1uS)
  • 1 Stoppbit (1uS)

Innere Uhr

Die interne Pixeltaktfrequenz (PCLK) innerhalb des OV7670 wird durch Bits [5:0] im Register CLKRC eingestellt (siehe Foto 1). [1]

Wenn wir Bits[5:0] = B111111 = 63 setzen und auf die obige Formel anwenden, dann:

  • F(interner Takt) = F (Eingangstakt)/(Bit[5:0}+1)
  • = 8000000/(63+1)
  • = 125.000 Hz oder
  • = 8uS

Da wir nur jedes zweite Datenbyte abtasten, führt ein PCLK-Intervall von 8uS zu einem 16uS-Abtastwert, was ausreichend Zeit ist, um 1 Datenbyte (10uS) zu übertragen, wobei 6uS für die Verarbeitung übrig bleiben.

Bildrate

Jeder VGA-Videoframe umfasst 784*510 Pixel (Bildelemente), von denen 640*480 Pixel angezeigt werden. Da das Ausgabeformat YUV (4:2:2) durchschnittlich 2 Datenbytes pro Pixel hat, dauert jedes Bild 784*2*510*8 uS = 6,4 Sekunden.

Diese Kamera ist NICHT schnell !!!

Horizontale Positionierung

Das Bild kann horizontal verschoben werden, wenn wir die HSTART- und HSTOP-Werte ändern, während ein Unterschied von 640 Pixeln beibehalten wird.

Wenn Sie Ihr Bild nach links bewegen, kann Ihr HSTOP-Wert kleiner als der HSTART-Wert sein!

Seien Sie nicht beunruhigt … es hat alles mit Zählerüberläufen zu tun, wie in Foto 2 erklärt.

Register

Der OV7670 verfügt über 201 Acht-Bit-Register zur Steuerung von Dingen wie Verstärkung, Weißabgleich und Belichtung.

Ein Datenbyte erlaubt nur 256 Werte im Bereich [0] bis [255]. Wenn wir mehr Kontrolle benötigen, müssen wir mehrere Register kaskadieren. Zwei Bytes geben uns 65536 Möglichkeiten … drei Bytes geben uns 16, 777, 216.

Das in Foto 3 gezeigte 16-Bit-AEC-Register (Automatic Exposure Control) ist ein solches Beispiel und wird durch Kombinieren von Teilen der folgenden drei Register erstellt.

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

Seien Sie gewarnt … die Registeradressen sind nicht zusammengefasst!

Nebenwirkungen

Eine langsame Bildrate führt zu einer Reihe unerwünschter Nebenwirkungen:

Für eine korrekte Belichtung erwartet der OV7670 eine Bildrate von 30 fps (Bilder pro Sekunde). Da jedes Bild 6,4 Sekunden dauert, ist der elektronische Verschluss 180-mal länger geöffnet als normal, was bedeutet, dass alle Bilder überbelichtet werden, es sei denn, wir ändern einige Registerwerte.

Um eine Überbelichtung zu vermeiden, habe ich alle AEC (Auto Exposure Control)-Registerbits auf Null gesetzt. Trotzdem wird bei heller Beleuchtung ein Neutralfilter vor dem Objektiv benötigt.

Auch eine lange Belichtung scheint die UV-Daten zu beeinflussen. Da ich noch keine Registerkombinationen gefunden habe, die korrekte Farben erzeugen … betrachten Sie dies als in Arbeit.

Notiz

[1]

Die im Datenblatt (Foto 1) gezeigte Formel ist korrekt, aber der Bereich zeigt nur Bits an [4:0] ?

Schritt 5: Timing-Wellenformen

Timing-Wellenformen
Timing-Wellenformen
Timing-Wellenformen
Timing-Wellenformen
Timing-Wellenformen
Timing-Wellenformen

Der Hinweis in der unteren linken Ecke des Diagramms „VGA Frame Timing“(Foto 1) lautet:

Für YUV/RGB, tp = 2 x TPCLK

Abbildungen 1, 2 und 3 überprüfen das/die Datenblatt(e) und bestätigen, dass Omnivision alle 2 Datenbytes als Äquivalent zu 1 Pixel behandelt.

Die Oszilloskop-Wellenformen überprüfen auch, dass HREF während der Austastintervalle NIEDRIG bleibt.

Abb. 4 bestätigt, dass der XCLK-Ausgang des Arduino 8 MHz beträgt. Der Grund, warum wir eine Sinuswelle anstelle einer Rechteckwelle sehen, ist, dass alle ungeraden Harmonischen für mein 20-MHz-Sampling-Oszilloskop unsichtbar sind.

Schritt 6: Framegrabber

Framegrabber
Framegrabber

Der Bildsensor innerhalb eines OV7670 Kamerachips besteht aus einem Array von 656*486 Pixeln, von denen ein Raster von 640*480 Pixeln für das Foto verwendet wird.

Die Registerwerte HSTART, HSTOP, HREF und VSRT, VSTOP, VREF werden verwendet, um das Bild über dem Sensor zu positionieren. Wenn das Bild nicht richtig über dem Sensor positioniert ist, sehen Sie einen schwarzen Streifen über einer oder mehreren Kanten, wie im Abschnitt „Design Notes“beschrieben.

Der OV7670 scannt jede Bildzeile Pixel für Pixel, beginnend von der oberen linken Ecke bis zum unteren rechten Pixel. Der Arduino übergibt diese Pixel einfach über die serielle Verbindung an den PC, wie in Foto 1 gezeigt.

Die Aufgabe der Framegrabber besteht darin, jedes dieser 640*480=307200 Pixel zu erfassen und den Inhalt in einem „Bild“-Fenster anzuzeigen

Processing 3 erreicht dies mit den folgenden vier Codezeilen !!

Codezeile 1:

byte byteBuffer = neues byte[maxBytes+1]; // wo maxBytes=307200

Der zugrunde liegende Code in dieser Anweisung erstellt:

  • ein 307201-Byte-Array namens „byteBuffer[307201]“
  • Das zusätzliche Byte ist für ein Abschlusszeichen (Zeilenvorschub) vorgesehen.

Codezeile 2:

Größe (640, 480);

Der zugrunde liegende Code in dieser Anweisung erstellt:

  • eine Variable namens „width=640;“
  • eine Variable namens „height=480“;
  • ein 307200-Pixel-Array namens „Pixel[307200]“
  • ein 640*480-Pixel-"Bild"-Fenster, in dem der Inhalt des Pixel-Arrays angezeigt wird. Dieses „Bild“-Fenster wird kontinuierlich mit einer Bildrate von 60 fps aktualisiert.

Codezeile 3:

byteCount = myPort.readBytesUntil(lf, byteBuffer);

Der zugrunde liegende Code in dieser Anweisung:

  • puffert die eingehenden Daten lokal, bis ein „lf“-Zeichen (Zeilenvorschub) angezeigt wird.
  • Danach werden die ersten 307200 Bytes lokaler Daten in das byteBuffer-Array geschrieben.
  • Es speichert auch die Anzahl der empfangenen Bytes (307201) in einer Variablen namens „byteCount“.

Codezeile 4:

Pixel = Farbe(byteBuffer);

Bei Platzierung in einer for-next-Schleife ist der zugrunde liegende Code in dieser Anweisung:

  • kopiert den Inhalt des Arrays „byteBuffer“in das Array „pixels“
  • dessen Inhalt im Bildfenster erscheint.

Tastenanschläge:

Der Framegrabber erkennt folgende Tastenanschläge:

  • ‘c’ = Bild aufnehmen
  • ‘s’ = Bild in Datei speichern.

Schritt 7: Software

Laden Sie jedes der folgenden Softwarepakete herunter und installieren Sie es, falls es noch nicht installiert ist:

  • „Arduino“von
  • „Java 8“von https://java.com/de/download/ [1]
  • „Verarbeitung 3“von

Installation der Arduino-Skizze:

  • Entfernen Sie alle OV7670-Überbrückungsdrähte [2]
  • Verbinden Sie ein USB-Kabel mit Ihrem Arduino
  • Kopieren Sie den Inhalt von „OV7670_camera_mono_V2.ino“(angehängt) in eine Arduino „Skizze“und speichern Sie.
  • Laden Sie die Skizze auf Ihren Arduino hoch.
  • Trennen Sie den Arduino
  • Sie können die Jumperdrähte des OV7670 jetzt sicher wieder anschließen
  • Schließen Sie das USB-Kabel wieder an.

Installieren und Ausführen der Verarbeitungsskizze

  • Kopieren Sie den Inhalt von „OV7670_camera_mono_V2.pde“(angehängt) in eine Verarbeitungs-„Skizze“und speichern Sie.
  • Klicken Sie oben links auf die Schaltfläche „Ausführen“… ein schwarzes Bildfenster wird angezeigt
  • Klicken Sie auf das „schwarze“Bildfenster
  • Drücken Sie die Taste „c“, um ein Bild aufzunehmen. (ca. 6,4 Sekunden).
  • Drücken Sie die Taste „s“, um das Bild in Ihrem Bearbeitungsordner zu speichern
  • Wiederholen Sie die Schritte 4 & 5
  • Klicken Sie auf die Schaltfläche „Stopp“, um das Programm zu beenden.

Anmerkungen

[1]

Verarbeitung 3 erfordert Java 8

[2]

Dies ist ein einmaliger Sicherheitsschritt, um eine Beschädigung Ihres OV7670-Kamerachips zu vermeiden.

Bis die Skizze „OV7670_camera_mono.ini“auf Ihr Arduino hochgeladen wurde, sind die internen Pullup-Widerstände mit 5 Volt verbunden, außerdem besteht die Möglichkeit, dass einige der Arduino-Datenleitungen 5-Volt-Ausgänge haben können … der 3v3 Volt OV7670 Kamerachip.

Sobald das Arduino programmiert wurde, muss dieser Schritt nicht wiederholt werden und die Registerwerte können sicher geändert werden.

Schritt 8: Erhalten eines Farbbildes

Erhalten eines Farbbildes
Erhalten eines Farbbildes
Erhalten eines Farbbildes
Erhalten eines Farbbildes
Erhalten eines Farbbildes
Erhalten eines Farbbildes

Die folgende Software ist rein experimentell und wird in der Hoffnung veröffentlicht, dass sich einige der Techniken als nützlich erweisen. Die Farben scheinen invertiert zu sein … Ich muss noch die richtigen Registereinstellungen finden. Wenn Sie eine Lösung finden, posten Sie bitte Ihre Ergebnisse

Um ein Farbbild zu erhalten, müssen alle Datenbytes erfasst und die folgenden Formeln angewendet werden.

Der OV7670 verwendet die folgenden Formeln, um RGB-Farbinformationen (Rot, Grün, Blau) in YUV (4:2:2) umzuwandeln: [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)

Die folgenden Formeln können verwendet werden, um YUV (4:2:2) wieder in RGB-Farbe umzuwandeln: [2]

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

Die beiliegende Software ist lediglich eine Erweiterung der monochromen Software:

  • Eine „c“Capture-Anfrage wird an das Arduino gesendet
  • Der Arduino sendet die geraden (monochromen) Bytes an den PC
  • Der PC speichert diese Bytes in einem Array
  • Der Arduino sendet als nächstes die ungeradzahligen (Chroma-) Bytes an den PC.
  • Diese Bytes werden in einem zweiten Array gespeichert … wir haben jetzt das gesamte Bild.
  • Die obigen Formeln werden nun auf jede Gruppe von vier UYVY-Datenbytes angewendet.
  • Die resultierenden Farbpixel werden dann im Array „pixels“platziert
  • Der PC scannt das Array „pixels“und ein Bild erscheint im Fenster „Bild“.

Die Processing 3-Software zeigt kurz jeden Scan und die Endergebnisse an:

  • Foto 1 zeigt die U- und V-Chroma-Daten aus Scan 1
  • Foto 2 zeigt die Y1- und Y2-Luminanzdaten von Scan 2
  • Foto 3 zeigt das Farbbild … nur eines stimmt nicht … die Tasche sollte grün sein !!

Ich werde neuen Code posten, sobald ich dieses Programm gelöst habe …

Verweise:

[1]

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

[2]

en.wikipedia.org/wiki/YCbCr (JPEG-Konvertierung)

Klicken Sie hier, um meine anderen instructables anzuzeigen.

Empfohlen: