Forum: Mikrocontroller und Digitale Elektronik Camera Modul (OV9655,OV7670) am STM32F4 Discovery mit OPEN407V-D


von Marcel F. (kellertuer)


Angehängte Dateien:

Lesenswert?

Hallo,

habe bereits diversen Code mit meiner Hardware ausprobiert, unter 
anderem den Code von Uwe (Beitrag "Camera Modul (OV9655) am STM32F4 Discovery Board") 
und den zum Open407V-D mitgelieferten Code.

Leider bekomme ich kein gescheites Kamerabild auf dem Display, was mich 
wundert, da der Code von Uwe funktionieren sollte. Habe natürlich die 
Hardwarepins im Code umgebogen.

Die Displayinitialisierung funktioniert, ich kann GUIText darauf 
schreiben. Mit einigen wilden Einstellungen in den Registern HSTART 
HSTOP der OV9655 kann man ein Kamerabild auf dem Display erahnen.

Mich wundert, dass ich dieses Problem (Streifenbild) bei verschiedenen 
Kameras mit Code habe, der eigentlich funkltionieren sollte bzw bei 
anderen funktioniert hat. Das STMDiscovery habe ich auch schon 
getauscht, gleiches Problem. Die Portpins kommen Hardwaremäßig alle dort 
an, wie sie in der Software eingetragen sind. Ein Hardwareproblem 
schließe ich also aus.

Hat jemand gleiche Probleme gehabt oder eine Idee, was der Fehler sein 
könnte?

von Ziegenpeter (Gast)


Lesenswert?

Das erste Bild sieht für mich ganz stark danach aus, als würde die 
horizontale Auflösung bzw. Breite vom Bild nicht mit der Auflösung des 
Displays übereinstimmen. D.h. Bild ist z.B. 260 Pixel breit, das Display 
320 Pixel und du schreibst alles linear in den Display-Speicher ohne auf 
die Breite zu achten.

von Marcel F. (kellertuer)


Lesenswert?

Das würde auch damit zusammenpassen, dass bei einigen Einstellungen in 
H(orizontal)Start und HStop das Bild einigermaßen zu erkennen ist.

Mich wundert jedoch, dass ich Code probiert habe, der für die gleiche 
Cam und das gleiche Display geschrieben wurde und als funktionierend im 
Netz herumwandert. Meine HardwareIDs lauten LCDID = 0x8989 CamPID = 0x96

Ich suche weiter nach der Ursache.

von Uwe B. (derexponent)


Lesenswert?

Hi Marcel,

der Code von meiner Seite funktioniert...
natürlich nur mit absolut gleicher Hardware :-)

>Habe natürlich die Hardwarepins im Code umgebogen.

also hast du nicht die gleiche Hardware
(was für ein Display benutzt du bzw. welcher Display-Chip)

vermutlich stimmt der Anzeigemode von deinem Display nicht
es muss im Landscape-Mode initialisiert werden

die Start Adresse X=0, Y=0 ist eine Ecke vom Display
und durch das autoincrement beim zeichnen
muss zuerst die Längere Seite (die mit 320 Pixel) gezeichnet werden
das 321 Pixel ist dann in der nächsten Zeile


Prüf das mal ob dein Display so initialisiert ist :

stell das Display auf "Landscape-Mode"
setz den Cursor am Display auf X=0, Y=0
und lass 320 Pixel zeichnen (per autoincrement)
das muss eine einzelne Linie an der längeren Seite ergeben

640 Pixel ergeben dann zwei Zeilen usw

Gruss Uwe

von Marcel F. (kellertuer)


Lesenswert?

Ich habe auch das ov9655 und das ssd8989 (id siehe oben), habe den 
ini-vektor von dir (display und cam) ausprobiert. Leider ohne Erfolg. 
Dann hab ich die Register unter die Lupe genommen und im Datenblatt 
gelesen, leider sind die Informationen zu den Registern sehr spärlich.

von Marcel F. (kellertuer)


Lesenswert?

Ein paar Fragen hab ich:

Was sollte passieren, wenn ich im DCMI einstelle: 
DCMI_CaptureMode_SnapShot? Bei mir zeichnet er eine kurze Linie Pixel, 
so ca 5 - 10 Pixel lang.

Wie sage ich dem Programm, dass es genau eine Linie (320 Px) zeichnen 
und dann aufhören soll?

Welche Auswirkung hat Änderung der DMA Buffer Size? Bei mir keine, außer 
wenn ich den Buffer auf Null setze.

Mir ist noch nicht ganz klar, wie der Mechanismus "Daten vom DCMI holen 
- Daten auf FSMC schreiben" funktioniert und wie ich da reinschauen und 
überprüfen kann, ob das richtige passiert. Wie der DMA selbst 
funktioniert, weiß ich.

Edit: ich stelle gerade fest, dass sich das angezeigte Bild ändert, wenn 
ich im DCMI address setup time, address hold time und data setup time 
ändere. Wie berechne ich die für mich richtigen Daten?

von Uwe B. (derexponent)


Lesenswert?

wie schon gesagt, vergiss erst mal die Camera
und löse erst mal das Problem mit dem Display

danach löst sich das Camera-Problem von selbst

>Wie sage ich dem Programm, dass es genau eine Linie (320 Px) zeichnen
>und dann aufhören soll?

wie steuerst du den das Display an ?

du brauchst eine Funktion um den Cursor auf eine X/Y-Koordinate zu 
setzen
und eine Funktion um an der Stelle vom Cursor das Pixel einzufärben

also z.B
1
setCursor(10,20);   // setzt den Cursor auf X=10, Y=20
2
drawPixel(0x1234);  // zeichnet ein Pixel mit der Farbe 0x1234

und für eine Linie würde ich eine For-Schleife empfehlen
1
setCursor(0,0);
2
for(n=0;n<320;n++) {
3
  drawPixel(0x1234);
4
}

schreib wieder wenn das funktioniert

von Marcel F. (kellertuer)


Lesenswert?

Die Displayansteuerung funktioniert. Dein Test-Code (rote Linie 
zeichnen) und andere Codes (GUI Text schreiben) laufen korrekt mit 
meinem Display.

von Marcel F. (kellertuer)


Lesenswert?

Sorry, oben schrieb ich was über dcmi setup time, gemeint waren aber die 
fsmc-Zeiten. Das kuriose dabei ist: wenn ich diese Zeiten ändere, dann 
hat das zwar Auswirkungen auf das angezeigte Kamerabild, aber nicht auf 
andere Displayinhalte wie Text schreiben oder Linien zeichnen.

von Uwe B. (derexponent)


Lesenswert?

>Mir ist noch nicht ganz klar, wie der Mechanismus "Daten vom DCMI holen
>- Daten auf FSMC schreiben" funktioniert und wie ich da reinschauen und
>überprüfen kann, ob das richtige passiert. Wie der DMA selbst
>funktioniert, weiß ich.

die Kamera sendet (einmal angestupst) ständig das aktuelle Bild
und zwar Pixel für Pixel Bild für Bild

mann muss am Anfang am Display den Cursor auf x=0, y=0 setzen
und weil die Auflösung vom Display und die von der Camera
genau gleich ist, füllt ein Camera-Bild genau ein Display-Bild aus

das "synronisiert" sich sozusagen selbst

der DMA holt ein Pixelwert von der Camera und sendet
ihn direkt ins RAM vom Display
die Camera erhöht dann intern auf die nächste Pixel-Adresse
und das Display macht das gleiche
dann kommt das nächste Pixel usw.

wenn du eine andere Auflösung willst (das geht auch)
kannst du die Camera z.B. QQVGA auf 160x120 Pixel einstellen,
dann muss am Display aber auch das Aktiv-Window genau auf diese
Größe eingestellt werden


>Sorry, oben schrieb ich was über dcmi setup time, gemeint waren aber die
>fsmc-Zeiten. Das kuriose dabei ist: wenn ich diese Zeiten ändere, dann
>hat das zwar Auswirkungen auf das angezeigte Kamerabild, aber nicht auf
>andere Displayinhalte wie Text schreiben oder Linien zeichnen.

das verstehe ich auch nicht ganz,
was sein kann ist, das du den FSMC so langsam einstellst,
das die Daten von der Camera schneller kommen als sie
auf das Display geschrieben werden

ich würde den FSMC so schnell wie möglich einstellen
(gerade so das das Display noch funktioniert)

kannst du leicht testen, wenn du die Zahlen verkleinerst
wird irgendwann nichts mehr neues angezeigt


>Was sollte passieren, wenn ich im DCMI einstelle:
>DCMI_CaptureMode_SnapShot?

Snapshot holt nur ein einzelnes Bild von der Camera
und zeichnet es auf das Display (wie ein Foto)

Nachtrag : mach mal ein Foto von dem Strich mit 320 Pixel
und stell es hier rein

>Die Displayansteuerung funktioniert. Dein Test-Code (rote Linie
>zeichnen) und andere Codes (GUI Text schreiben) laufen korrekt mit
>meinem Display.

VORSICHT : diese Funktionen benutzen meist intern
eine Funktion zum setzen vom Cursor,
damit kannst du nicht erkennen ob der Landscape Mode aktiviert ist oder 
nicht

im zweiten Bild das du gepostet hast, sieht man das er eben nicht im 
Landscape-Mode ist....und so wird das nie was


Gruss Uwe

von Marcel F. (kellertuer)


Lesenswert?

"von DEM strich mit 320 pixel" - welchen Strich meinst du? Ich habe hier 
keinen Strich mit 320 Pixel. Meinst du den Strich, der bei mir 
erscheint, wenn ich DCMI_CaptureMode_SnapShot einstelle? Da gibts nich 
viel zu sehen, das sind nur 20 Pixel.

Woher weiß ich eigentlich den Adressoffset für das RAM des Display? In 
deinem Code steht was von Seite 1316 des refman, aber bei meinem hört 
der FSMC-Teil auf S.1277 auf.

Mich verwirrt noch immer, dass sich das "Kamerabild" ändert, wenn ich an 
den Timings rumspiele. Muss ich FSMC und DCIM irgendwie aufeinander 
abstimmen?

Und warum ist es egal, welchen Memorytype ich beim initialisieren wähle, 
es ändert sich dabei nichts an der Funktionalität.

von Uwe B. (derexponent)


Lesenswert?

sorry, ich gebs auf

von Marcel F. (kellertuer)


Lesenswert?

Kein Problem, hab jetzt nochmal von vorn angefangen den Code 
umzuschreiben (hatte vorher einen Mischmasch aus deinem und nem anderen) 
und nun hab ich Bild. Zwar mit Falschfarben, aber das löse ich auch 
noch. Ich werd auch die Codes vergleichen, woran es nun lag.

Dennoch: Woher hast du das Adressoffset für das RAM?

von Uwe B. (derexponent)


Lesenswert?

> Dennoch: Woher hast du das Adressoffset für das RAM?

ich habe die Rev.3 vom Referenz Manual RM0090 vom Nov.2012
das PDF hat 1416 Seiten und auf der Seite 1316
wird der externe Adressraum vom FSMC beschrieben

Kapitel 32.4 "External device address mapping"


die eigentliche Adresse ist relativ egal
(das Display hat sowieso keine Adressleitungen)
sie muss nur irgendwo in BANK1/PSRAM1 liegen
damit der richtige (weil einzige) ChipSelect-Pin
aktiviert wird (NE1 an PD7)

und fuer NE1 sind Adressen zwischen
0x60000000 und 0x63FFFFFF zuständig

ich hab halt 0x60000000 benutzt
du könntest aber genausogut 0x61234567 benutzen
das macht keinen Unterschied

das einzigste was noch eine Rolle spielt ist,
wo der RS-Pin vom Display angeschlossen ist
(bei mir an A19=PE3) und das du einmal
eine Adresse hast mit RS-Pin = Lo
und einmal eine mit RS-Pin = Hi
die das obige Kriterium erfüllt

aber das alles ist bei dir richtig eingestellt
sonst würde gar nichts auf dem Display angezeigt werden

>Zwar mit Falschfarben

das klingt mir nach Display im Mode BGR statt RGB
(oder andersrum)

Gruss Uwe

von Marcel F. (kellertuer)


Angehängte Dateien:

Lesenswert?

So, hab die Tage noch etwas mit den Registern rumgespielt und nun 
endlich ein passendes Set gefunden. Dafür habe ich die serielle 
Schnittstelle eingebunden um online die Register ändern zu können und 
die direkte Wirkung auf dem Display zu sehen.
Habe nun ein lauffähiges Projekt basierend auf dem Code von Uwe, welches 
das Kamerabild der OV9655 (Standardmodul von Waveshare) auf dem Display 
(HY32C) anzeigt. Motherboard ist das Open407V-D. Es wurden keine 
Hardwareveränderungen vorgenommen. Einfach alle Module anstecken, 
flashen und los. Einzig ein paar Pfade müssen in den Projekten angepasst 
werden.

von Jeno Kocsis (Gast)


Lesenswert?


von Marcel F. (kellertuer)


Lesenswert?

Please check all wirings and clocks first (where is your cams xclk? 
please compare with the code I posted). After that you can compare the 
registersettings and the order of the registersettings! the order is 
important! Very important are things like resolution, h and v polarity.

von Jeno Kocsis (Gast)


Lesenswert?

The XCLK is connected to the PA8 pin (RCC_MCO1Config(RCC_MCO1Source_HSI, 
RCC_MCO1Div_1); - 8 MHz) It seems to be working, because it can 
communicate over I2C. Did you managed to get working ov7670? I only saw 
ov9650 in your code. I'll try to compare the different registers.

von Jeno Kocsis (Gast)


Angehängte Dateien:

Lesenswert?

I managed to get picture, but it's black on the left side, and the 
resolution seems to be wrong. Did you saw this type of problem before?
Thanks!

von Marcel F. (kellertuer)


Lesenswert?

It seems to be a problem with the resolution or/and the hstart/hstop 
vstart/vstop bits?

von Jeno Kocsis (Gast)


Lesenswert?

I found out, that if I didn't change the resolution from the default 
640*480 there is no black line, and the resolution is also ok. When I 
change the resolution to cif I receive 2 picture in 640 pixel width 
side-by-syde with black line. Maybe the camera did not crop the image, 
and sends windowed picture? I'll try to crop it with DCMI.

von Marcel F. (kellertuer)


Lesenswert?

if you change the resolution of the camimage, then you will receive less 
data per picture. but the display doesnt know this! you have to change 
the active window on the display also :)

von Jeno Kocsis (Gast)


Lesenswert?

I did not used a display, only a virtual one on the pc. The problem was 
with hstart hstop registers. I corrected them, and the image is fine 
now. Thank you for your help!

von Bharath K. (bharath_k)


Lesenswert?

hello,
can you please send me the complete code of your project

von Bharath K. (bharath_k)


Lesenswert?

Jeno Kocsis schrieb:
> I managed to get picture, but it's black on the left side, and the
> resolution seems to be wrong. Did you saw this type of problem before?
> Thanks!




Could you please send me the code sir i want to develop this.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.