Forum: Mikrocontroller und Digitale Elektronik Brauche Unterstützung beim OV7670 (bzw. SCCB)


von David D. (saturi)


Angehängte Dateien:

Lesenswert?

Liebe Community,
ich bin auf eure Hilfe angewiesen.
Ich versuche schon seit mehreren Monaten den OV7670 (VGA-Modul) mit dem 
mit einem Atmega 328P anzusteuern.

Dabei scheitere ich allerdings schon bei der ansteuerung bzw. der 
Kommunikation mit dem SCCB-Interface zur Steuerung des Moduls.

Nach studium diverser Datenblätter und Websiten dachte ich, die 
Funktionsweise verstanden zu haben und das Problem läge in einer 
fehlerhaften ungewollten Programmierung. Nachdem ich nun aber auch 
endlich stolzer Besitzer eines Oszilloskops geworden bin, muss ich 
feststellen, dass alle Pins so schalten, wie ich es mir vorstelle und 
dass ich offensichtlich nicht verstehe, was zu tun ist. Daher wende ich 
mich an euch und hoffe auf einen Hilfsbereiten der sich erbarmt meine 
Wissenslücke zu füllen.

Um die Funktionsweise des SCCB sicherzustellen sieht mein Plan vor, 
ersteinmal nur das Register 0x01 auszulesen und den Default-Wert 0x80 
als Antwort zu bekommen. Um das zu erzielen sieht mein Plan folgendes 
vor:
2-Phasen Write Zyklus gefolgt von einem 2-Phasen Read Zyklus.
Dazu sende ich folgende Befehle:
0x42 + 0 + 0x01 + 0 + 0x43 + 0 + Eingang + 1

(die Nullen bzw. 1 stellen hier die mitgeschickten Don't care Bits dar)
Nach meinem bisherigen verständnis sollte doch während der letzten Phase 
(hier mit Eingang bezeichne) die Daten vom Slave, also dem Kamaramodul 
aus geschrieben werden. Ich erhalte allerdings nur ein durchgehendes 
HIGH oder LOW jenachdem, ob ich die SIOD Leitung mit dem Pull-Up an 3,3V 
hänge.
Abweichend zu dem Anschlussplan, betreibe ich die xCLK über einen 
Arduino Nano mit einer Frequenz von 16kHz.

Gerne führe ich mein Problem weiter aus, hoffe aber schoneinmal, dass 
sich jemand dazu berufen fühlt mir zu helfen.

vielen Dank!

lg.
David

von pegel (Gast)


Lesenswert?

Moin,

ich kenne das Modul nicht, aber wenn ich mir das ansehe:
https://github.com/maslovk/STM32_OV7670/blob/master/Src/OV7670.c

wird die Reset Leitung auf L gelegt, dann 100ms gewartet, dann auf H.
Danach wird an I2C 8bit Adresse 0x42 ein 0x0A gesendet und es kommt ein 
0x76 zurück.

von pegel (Gast)


Lesenswert?

Übrigens sind die Signale schon am Maximum der Absolute Maximum Werte.

von David D. (saturi)


Lesenswert?

Bitte entschuldigt die verzögerte Antwort. Leider war ich die Woche 
beruflich sehr eingespannt, weshalb ich nicht dazu gekommen bin, weiter 
zu basteln und zu versuchen.

Zur Aussage von Pegel, das ist richtig. Da dieser Baustein in Verbindung 
mit diversen Arduino sets angeboten wird, bin ich davon ausgegangen, 
dass ich ihn direkt an dem Uno betreiben kann.
Sollte ich etwa jeden Pin noch über einen Spannungsteiler reduzieren?

von pegel (Gast)


Lesenswert?

Nimm einen Atmega mit weniger F_CPU und probier alles zusammen bei 3,3V 
aus.
Damit sollte sich das Problem einkreisen lassen.

von Olli Z. (z80freak)


Lesenswert?

Es kommt etwas drauf an welches Modul Du gekauft hast. Der Chip selbst 
(OV0706) hat eine Betriebsspannung um 3,3V. Das häufig erhältliche 
OV7670 Modul mit Linse wird oft mit 5V TTL Interface, direkt für Arduino 
angeboten. Das ist dann ein Pegelwandler enthalten.

von Olli Z. (z80freak)


Lesenswert?

Hab grad nochmal im Datenblatt nachgeschaut. Also die Vio ist dort mit 
1.7 - 3.0V angegeben. Berichten zufolgen sollen 3.3V jedoch 
"unbedenklich" sein.

Du brauchst also höchstwahrscheinlich einen Pegelwandler für jedes 
Signal zwischen Arduino und Kamera.

von Olli Z. (z80freak)


Lesenswert?

David D. schrieb:

> Ich versuche schon seit mehreren Monaten den OV7670 (VGA-Modul) mit dem
> mit einem Atmega 328P anzusteuern.
Offensichtlich verfolgst Du einen eher akademischen Ansatz, sprich Du 
bist nicht auf eine schnelle Lösung ohne Hintergrundinformation aus. Das 
ist schön, denn dann kann man sich alle Links auf die div. Umsetzungen 
sparen. Damit lernt man nämich nix, wenn man das fertige Gedankengut 
eines anderen einfach verwendet.

> Dabei scheitere ich allerdings schon bei der ansteuerung bzw. der
> Kommunikation mit dem SCCB-Interface zur Steuerung des Moduls.
Deine Vorgehensweise ist auf jeden Fall richtig. Erstmal nur das 
Kommandointerface zum laufen zu bringen und den Rest aussen vor zu 
lassen. Solange man keinen PCLK anlegt, gibt der Chip ohnehin keine 
Videosignale aus.

Die Kommunikation mit dem SCCB-Teil läuft über den 2-Wire Bus ab. Ob und 
in wie weit der zu 100% der SPI-Spezifikation entspricht konnte ich 
leider nicht ermitteln. Von daher wäre es, für den Anfang ein guter Plan 
nicht die fertigen I2C-Libs zu nutzen, sondern die Signale via 
"Bitbangig" selbst zu generieren.

Zum Glück arbeitet der 2-Draht-Bus statisch, man kann sich also ruhig 
Zeit lassen. Es gibt keine minimale Taktfrequenz, nur max. 400 kHz.

Dein Setup mittels Arduino ist vollkommen ok, nur einen Pegelwander für 
die beiden Signale solltest Du zwingend vorsehen. Ein Spannungsteiler 
wäre für die SIO_C (CLK) noch ok, aber für die SIO_D sollte es schon ein 
richtiger Pegelwandler sein. Im einfachsten Fall mit Transistoren (gibts 
hier auf der Website auch als Schaltbeispiel) oder halt ein 
entsprechendes IC. Später, bei den Videosignalen, braucht man das auch. 
Für die SCCB-Kommunikation würde anfangs sowas hier reichen: 
https://www.roboter-bausatz.de/434/i2c-pegelwandler/level-konverter-3.3v-5v-bidirektional-2-kanal

Steht die Hardware, können wir uns der Kommunikation widmen. Dafür sind 
vor allem die START- und STOP-Konditionen wichtig.

: Bearbeitet durch User
von Olli Z. (z80freak)


Lesenswert?

Ohja, was noch wichtig sein dürfte. Betriebsspannung anlegen, 3.3V ;-), 
PWDN auf GND (ist Active High), RESET auf 3.3V (active low).
Und dann ist da noch der Systemtakt, XCLK. Laut Datenblatt sind hier 
wenigstens 10 MHz anzulegen. Vermutlich damit die interne Logik 
überhaupt arbeitet und damit auch das I2C Interface.
Diesen Takt kann man z.b. vom Arduino mittels PWM erzeugen lassen.
Selbstredent muss hier auf der richtige Pegel verwendet werden, also 
besser gleich einen 4fach Pegelwandler nehmen.

von Stephan C. (stephan_c)


Lesenswert?

Bei mir ist es schon wieder eine Weile her, als ich mal einen 
Omnivision-Sensor über den SCCB angesteuert hab.
Aber ist das bei SCCB nicht so, das du zum Lesen eines Registers erstmal 
einen Schreibbefehl senden mußt, um dann bei der nächsten 
Datenübertragung den Registerwert zurückzubekommen?

von Olli Z. (z80freak)


Lesenswert?

Genau so ist es. Es ist übrigens schon möglich die Arduino I2C-Lib 
("Wire.h") für die Kommunikation zu nutzen. Es kommt jetzt etwas drauf 
an wie tief der Thread-Ersteller hier einsteigen möchte. Habs grad mal 
auf die Schnelle mit einem Testaufbau nachgestellt. Klappt.

Für das grundsätzliche Verständnis wäre die eigene Implementation schon 
gut. Will man sich aber "nur" mit der Kamera beschäftigen ist es nicht 
zwingend notwendig.

: Bearbeitet durch User
von Olli Z. (z80freak)


Angehängte Dateien:

Lesenswert?

David hat sich bislang nicht mehr gerührt, aber ich fang einfach mal so 
an :-)
Eigentlich bietet fast jeder noch so kleine uC bereits ein I2C-Interface 
On-Board. Auch hat mein kleiner Test gezeigt, das der Arduino darüber 
problemlos mit dem OV7670-Modul kommunizieren kann. Daher sehe ich nicht 
viel Sinn darin die I2C-Kommunikation per Bit-Banging zu emulieren. 
Einzig David "besteht" darauf...

Wichtig dafür das es auch funktioniert ist eine vernünftige Verbindung 
beider über einen Pegelwandler. Ohne halte ich das Unterfangen für mehr 
als fraglich. Das von David gepostete Pinout kann m.E. nicht 
funktionieren, da einfach alle Signale (3.0V IO-Pegel vom OV7670 und 
5.0V Pegel vom Arduino) verbunden sind. Habe mal auf die Schnelle einen 
Eagle Schaltplan gezeichnet, wie ich es aktuell aufgebaut habe. Als 
Pegelwandler kommt fast alles in Frage, hauptsache Bidirektional 
(wichtig für I2C!).

Den Systemtakt XCLK erzeuge ich über Manipulation der Timer-Register:
1
pinMode(9, OUTPUT);
2
TCCR1A = ((1 << COM1A0));
3
TCCR1B = ((1 << WGM12) | (1 << CS10));
4
TIMSK1 = 0;
5
OCR1A = 0;
Hiermit erhalte ich an Pin 9 einen Takt von 8 MHz. mit 50% Duty-Cycle. 
Laut Datenblatt müssten es mind. 10 sein. Leider kann der Uno nicht mehr 
liefern mit seinen 16 MHz Systemtakt. Aber es scheint auch so zu 
funktionieren.

Damit wäre das Setup bereit für die Programmierung des Chips ansich.

von David D. (saturi)


Lesenswert?

Hallo zusammen,

das Thema interessiert mich immer noch brennend und ich bin dankbar für 
eure ausführlichen Beschreibungen.
Das mit dem Pegelwandler scheint für mich ein sehr unterschätzter Punkt 
zu sein, den ich als erstes betrachten und korrigieren werde.

den xCLK betreibe ich über einen zweiten Controller (Arduino Nano) an 
dem ich einfach die CKOUT-Fuse gesetzt und bekomme damit erstmal meine 
16 Mhz über den PB0 Pin geliefert. (allerdings wieder ohne 
Pegelwandlung... ja ich gestehe mir ein, ich muss den vorgegeben 
Spannungen definitiv mehr Aufmerksamkeit schenken)

ab Mittwoch wird es bei mir hoffentlich etwas ruhiger (stehe grade 
mitten in meiner Masterthesis Erstellung und der Bewerbungsphase für den 
Berufseinstieg) sodass ich mich spätestenz zum Wochenende endlich 
nochmal dem uController zuwenden kann.

den I2C benutze ich zur Zeit nicht, weil ich irgendwo gelesen hatte, 
dass das SCCB nicht ganz dem Protokoll entspricht. Lasse mich da aber 
sehr gerne belehren wenn das damit einfacher geht :)
Stelle auch gerne meinen Code zur Einsicht/Fehleridentifikation zur 
Verfügung, wobei ich grade eher die Hoffnung habe, dass der Fehler in 
der Spannungsversorgung ist.
Werde zum Wochenende hin auch hoffentlich einmal meinen ganzen 
Anschlussplan erstellen und mit euch teilen.

@Olli "Offensichtlich verfolgst Du einen eher akademischen Ansatz.."
Ob ich da jetzt wirklich wissenschaftlich an die Sache ran gehe wage ich 
noch etwas zu bezweifeln :D aber ja ich will es verstehen und nicht nur 
irgendwelchen Code Copy'n'Pasten.

von grundschüler (Gast)


Lesenswert?

Das mit dem Pegelwandler würde ich mir ersparen. Wenn du den AVR mit 8 
Mhz betreibst, reichen für diesen auch 3Volt. Für eine gescheite 
Auflösung ist der avr eh zu langsam. Ein stm32f407-board mit 
dcmi-camera-Schnittstelle kostet um die 10€. Auch damit ist der Betrieb 
des camera-Moduls noch anspruchsvoll genug.

von David D. (saturi)


Lesenswert?

Was die Auflösung und Frame Rate angeht hab ich mir auch schon gedacht, 
dass er dafür zu langsam ist. Mir reicht es aber in erster Linie auch 
erstmal einfach nur ein Bild von einem statischen Motiv zu machen.
Ich würde auch gerne bei einem AVR bleiben, weil ich nur damit 
Erfahrungen habe.

von Olli Z. (z80freak)


Lesenswert?

Mit ein paar kleinen Enschränkungen sollte das auch mit dem Uno 
funktionieren. Es gibt zwei Versionen der 0.3 MP Kamera OV7670, eine 
ohne und eine mit zusätzlichem FIFO-Bildspeicher.

Bei der Version ohne FIFO muss man die Bilddaten in der nativen 
Geschwindigkeit des Sensors erfassen können. Ist die MCU zu langsam, 
verliert man Daten und das ganze Bild ist unbrauchbar. Bei der Version 
MIT FIFO Speicher werden die Bilddaten eines Frames in diesen abgelegt 
und man hat "alle Zeit der Welt" sich die Daten abzuholen. Natürlich 
verliert man dabei Frames, aber jedes ist konsistent.

Ich habe beide Versionen der Kamera hier. Man muss auch sagen das der 
OV7670 die unterste Einsteigsklasse der Kameras ist. Wenn wir mit dem 
Modell ohne FIFO arbeiten und die Daten nicht in Echtzeit in den Arduino 
laden können, dann müssen wir einfach die Auflösung und Bildrate 
reduzieren bis es klappt. Es geht hier ja erstmal auch nur um einen 
"Proof-of-Concept", nicht wahr :-)

Neben der Hardware sollten wir auch die Software diskutieren, denn die 
ist ja nicht weniger wichtig. Um dem ganzen eine gewisse Nachhaltigkeit 
zu geben, habe ich hier in meinem Wiki mal einen Bereich dafür angelegt: 
http://e-wiki.denkdose.de/video/ccd-sensor/ov7670/start
Dort würde ich alle Eregebnisse zusammentragen.

Zur Takterzeugung:

Laut Datenblatt des OV7670 sollten es mind. 10 MHz sein. Wie gesagt hat 
es bei mir mit 8 MHz, welche sich ohne Tricks einfach per 
umprogrammierung eines PWM-Timers erzeugen lassen geklappt.

Durch ändern der FUSE-Bits kann man den, beim Arduino Uno/Nano durch 
einen externen 16 MHz Quarz erzeugten Takt auf dem PORTB Bit 0 (PB0) 1:1 
durchreichen. PB0 liegt beim Uno/Nano auf dem Port "D8". Um das zu tun 
sind jedoch einige tiefergreifende Modifikationen der IDE (boards.txt) 
notwendig, da die FUSEs sich nicht innerhalb der Software anpassen 
lassen, sondern zum Zeitpunkt der Chip-Programmierung eingestellt 
werden.

Ich schlage daher vor, den o.g. Code zu nutzen und erstmal darauf zu 
vertrauen das 8 MHz ausreichend sind. Im Prinzip könnte man auch den 
Quarz umlöten auf 20 MHz. Das hält der 328p locker aus. Aber auch das 
würde ich erst in Erwägung ziehen, wenn es zwingend sein muss.


Zur Pegelanpassung:

Das Taktsignal "XCLK" für den Kamerachip, sowie die SIO_C und SIO_D 
Leitung sollten zwingend über einen Pegelwandler betrieben werden. Das 
ist für mich alternativlos, auch wenn es Beschaltungen und Berichte gibt 
die ohne auskommen. Diese nutzen den Umstand das die IO-Pins mit 
Schutzdioden versehen sind, manche sind wenigstens so gändig und 
schalten Widerstände in Reihe. Im von Dir gezeigten Schaltbild wird man 
per Software wohl die Ausgänge ohne internen Pullup beschalten, also 
quasi Open-Collector. Den High-Pegel erzeugen dann Pullups auf 3.3V. Das 
könnte durchaus klappen, funktioniert aber bei der Clockerzeugung so 
nicht. Dafür hat man da wohl den Serienwiderstand eingebaut, quasi 
Pegelwandler für Arme ;-)
Kann man alles mal ausprobieren... was ich noch nicht untersucht habe 
ist, ob sich durch den Pegelwandler die Flankensteiheilt irgendwie 
problematisch verändert. Bislang gehe ich davon aus das der von mir 
verwendete, auf Transistoren basierende, da keinerlei Probleme 
verursacht.

Was die Datensignale angeht, könnte man durchaus auf einen Wandler 
verzichten, da man diese ja nur liest. Der TTL-Pegel ist hier 
abwärtskompatibel mit dem 3.0V Pegel des Kamerachips.

Auch wenn geht, würde ich hier ebenfalls auf Modifikationen des Uno, wie 
andere Betriebsspannung, etc. verzichten. Wenn man an einer ernsthaften 
Anwendung interessiert ist, sollte man einfach auch die passenden Chips 
dafür wählen und da ist der STM32 (Bluepill) einfach besser geeignet 
(stärker, billiger, richtiger Pegel, eigenes Interface, etc.).

Neben den Bilddaten-Pins D0-D7 benötigen wir auch den PCLK, VSYNC und 
HREF um die Daten synchron einlesen zu können. VSYNC gibt uns den Start 
eines Frames, HREF den einer jeden Zeile. PCLK zeigt uns wann welche 
Pegel (auch die der Datenbits) stabil anliegen.


Zur Software:

Wenn Dein Hardwareaufbau steht, würde ich als erstes die grundlegende 
Kommunikation (Protokoll) zwischen Arduino und OV7670 besprechen. Dies 
soll es uns am Ende ermöglichen die Register des Chips zu lesen und zu 
schreiben, sowie die für uns relevanten herauszufinden, sodass wir dem 
Chip die passenden Einstellungen geben können.

Wenn das klappt, machen wir uns Gedanken wie wir einen Frame lesen und 
daraus eine Bilddatei für den PC produzieren. Etappenziel wäre es, ein 
Einzelbild in S/W zu übertragen und darzustellen. Danach können wir uns 
allen weiteren Themen wie der Farbtransformationsmatrix (YUV<->RGB) etc. 
widmen.

Was mich persönlich noch interessiert wären die OSD-Funktionen des 
Chips. Laut Datenblatt soll man Zeichen und eine Overlaygrafik 
darstellen können. Das wäre schon interessant. Auch kann man Bereiche 
definieren in denen die Kamera auf Änderungen "reagiert" (Überwachung).

Ganz pfiffige haben Software zur Kanten- und Objekterkennung 
(Verfolgungsmodus) geschrieben. So weit werden wir es sicher nicht 
bringen...

Was aber noch denkbar ist, ist der Anschluß eines LCD-Panels um das Bild 
gleich 1:1 anzuzeigen. Mit dem Uno/Nano wird das aber langsam knapp, 
sowohl an MCU-Ressourcen als auch an Pins.

von Olli Z. (z80freak)


Lesenswert?

Die grundlegende Kommunikation auf dem SCCB entspricht der von I2C. Der 
Busaufbau ebenfalls. Die Kamera agiert dabei als Slave und der Arduino 
muss folglich den Master machen. Das heisst sowohl beim schreiben, als 
auch beim lesen von Daten geht das immer vom Master aus.

Ein Slave reagiert nur auf eine bestimmte Adresse, welche im Fall des 
Ov7676 scheinbar die 0x21 ist, auch wenn ich das im Datenblatt nirgens 
finde.

Eine Bit-Übertragung beginnt immer mit einer Start-Kondition bei der die 
SDA Leitung nach Low geht während SDC noch High ist. Der Empfänger 
stellt sich aufs lesen von Daten ein. Es folgt eine Übertragung von 8 
Bit langen Datenwörten, wiederum gefolgt von einer Stop-Kondition. Dabei 
geht der Pegel von SDA auf High während SDC bereits High-Pegel hat. Nur 
zur Info, normalerweise muss während der High-Phase von SDC der Zustand 
von SDA stabil sein.

Konzentrieren wir uns nun auf die Nutzdaten des Protokolls. Hier sendet 
der Master zuerst die Adresse des anzusprechenden Slave. Ab hier gibt es 
nun ein paar Varianten, abhängig davon was man tun will.

Im „3-Phase-Write Cycle“ wird nach der Empfänger-ID die Subadresse, im 
Fall des OV7676 ist es das zu beschreibende Register (COM...), 
übertragen. Ihr folgt der Wert welcher in das Register zu schreiben ist.

Im „2-Phase-Write Cycle“ werden nur Empfänger und Subadresse 
geschrieben. Diese Variante ist zur Vorbereitung der dritten 
Übertragungsart, dem Lesezyklus gedacht. Sie selektiert das zu lesende 
Register im Slave.

Beim „2-Phase-Read Cycle“ muss ein 3- oder 2-Phase-Write vorausgegangen 
sein. Nach dem senden der Slaveadresse wird der Master passiv und 
erwartet das der Slave nun seine Daten sendet.

Um also Daten aus dem Chip zu lesen, müssen vorher welche geschrieben 
werden. Dies resultiert aus dem Umstand das ein Slave nicht 
selbstständig auf den Bus senden darf.

Das Arduino Framework verwendet hierfür die „Wire“ Library.

Soviel erstmal zum Protokoll. Natürlich habe ich jetzt Komplexität 
wissentlich unterschlagen, wie NA und ACK Bits, Multi-Master Busse, etc.

von David D. (saturi)


Angehängte Dateien:

Lesenswert?

Guten Abend,
ja genauso hatte ich das Protokoll des SCCB auch verstanden.
Wenn du dir nochmal den Anhang in meinem Eröffnungspost anschaust, 
sollten auch die vier Zyklen erkennbar sein. Wenn man dort die einzelnen 
Bits anschaut (nach meinem Verständnis) wurden dort auch die richtigen 
Adressen gesendet. Nur das was eben vom Slave nachher zurückkommt - in 
dem letzten Zyklus - ist eben nur ein high Pegel mit falschem 
Informationsgehalt.

Nach euren Ratschlägen habe ich mir eine weiteren OV7670 diesmal mit 
AL422B Fifo und ein paar LVL-Shifter gekauft. Die sind heute angekommen.

Ich habe mich dann heute auch mal an Eagle gesetzt. Nunja um es kurz zu 
machen bin ich da noch nicht so ganz routiniert ;-) sondern eher 
komplett Neueinsteiger (ich arbeite noch an der Darstellung und der zum 
Teil unvorteilhaften Beschriftung).
Der neue OV7670 weist schon mal mehr PINs auf, was vermutlich auf das 
FIFO zurückzuführen ist. Hier tun sich für mich jetzt in erster 
Betrachtung zwei Fragen auf:
1. Wenn das Bild im FIFO abgelegt wird, wozu werden dann noch VSync und 
HREF nach außen geführt? Eventuell zum Zählen um festzustellen ob das 
Bild fertig vorliegt?
2. xCLK ist nicht mehr vorhanden. Womit gebe ich dann den Takt vor? 
eventuell befindet sich auch der Quarz schon auf der Kamera Platine?

Ich konnte mich leider noch nicht detaillierter mit der Sache 
auseinander setzten und in den Datenblättern oder dem Internet großartig 
stöbern, wollte euch aber an meinen Gedankengängen teilnehmen lassen.
lg.
David

PS: Übrigens arbeite ich nicht mit der Arduino Umgebung, sondern direkt 
mit dem Atmelstudio auf der Atmelbasis. Sind die genannten Bibliotheken 
sehr komplex? oder kann man sich das ganze auch selber 
zusammenschreiben, bzw. ummünzen?

: Bearbeitet durch User
von Olli Z. (z80freak)


Lesenswert?

Hallo David. Ich würde nicht mitten drin die Verhältnisse ändern. Du 
schaffst gerade neue Probleme. Lass uns doch erstmal mit der "alten" 
Kamera ohne FIFO weiterarbeiten. Das Bild interessiert uns doch aktuell 
noch nicht. Dabei ist es völlig egal ob das Teil nene Fifo hat oder 
nicht und wie und ob die Sync-Signale genutzt werden.

Hier ein Test-Code
1
#include "Wire.h"
2
3
void setup() {
4
  // put your setup code here, to run once:
5
6
  pinMode(9, OUTPUT);
7
  TCCR1A = ((1 << COM1A0)); //0x23;
8
  TCCR1B = ((1 << WGM12) | (1 << CS10)); //0x09;
9
  TIMSK1 = 0;
10
  OCR1A = 0;
11
  
12
  Serial.begin(38400);
13
14
  Wire.begin();
15
  Wire.beginTransmission(0x21);
16
  Wire.write(0x12);
17
  Wire.write(0x80);
18
  Wire.endTransmission();
19
  delay(500);
20
21
  Wire.beginTransmission(0x21);
22
  Wire.write(0x0A);
23
  Wire.endTransmission();
24
  Wire.requestFrom(0x21, 1);
25
  while(Wire.available() == 0);
26
  while(Wire.available())
27
    Serial.println(Wire.read(), HEX);
28
29
  Wire.beginTransmission(0x21);
30
  Wire.write(0x0B);
31
  Wire.endTransmission();
32
  Wire.requestFrom(0x21, 1);
33
  while(Wire.available() == 0);
34
  while(Wire.available())
35
    Serial.println(Wire.read(), HEX);
36
37
}
38
39
void loop() {
40
  // put your main code here, to run repeatedly:
41
42
}

von Michael U. (amiga)


Lesenswert?

Hallo,

es kann vielleicht trotzdem helfen bei Arduino vorbeizuschauen.
https://github.com/ComputerNerd/ov7670-no-ram-arduino-uno

Ich habe mit der OV7670 ohne FiFo nur kurz rumgespielt, allerdings an 
einem ESP32. Eigentlich ist die OV7660 eine komplette Enttäuschung für 
mich.
Dann habe meine uralten DC3840 und MCA-25 rausgekramt...
Die DC3840 lief ja vor Jahren schließlich mal stabil bei mir an einem 
AVR-NetIO mit einem Mega32.
http://www.ulrichradig.de/home/index.php/projekte/uC-kamera

Allerdings sind diese Cams wohl inzwischen kaum noch aufzutreiben.

Gruß aus Berlin
Michael

von Olli Z. (z80freak)


Lesenswert?

Danke für den Link zu der OV-Software, das wird später hilfreich sein! 
David und ich wollen aber erstmal bei dem ursprünglich genannten Modell 
bleiben um uns nicht zu verzetteln. Das wäre erstmal ans Laufen zu 
bringen und dann können wir das Gebiet erweitern :-)

Eine Frage zu den I2C-Leitungen vom Arduino. Laut I2C Spezifikation 
müssen die Pins für SDA und SCL open drain mit einem 2,2 k Pullup 
bestückt sein.

Auf dem Schaltplan vom Uno kann ich keinerlei externe Pullups finden.
Im Quellcode der Wire-Library (twi.c) ist für Wire.Begin():

  // activate internal pullups for twi.
  digitalWrite(SDA, 1);
  digitalWrite(SCL, 1);

und Wire.end() dieses enthalten:

  // deactivate internal pullups for twi.
  digitalWrite(SDA, 0);
  digitalWrite(SCL, 0);

Vorausgesetzt beide Ports sind als Eingänge definiert (DDR-Register), 
aktiviert bzw. deaktiviert dies in der Tat die internen Pullups und hat 
die gleiche Wirkung wie z.B.:
  pinMode(SDA, INPUT_PULLUP);
  pinMode(SCL, INPUT_PULLUP);

Sowohl SCL (wenn der Arduino als Slave arbeiten würde) als auch SDA 
können zeitweise auch als Ausgänge konfiguriert sein.

Im Datenblatt vom Atmega328p finde ich hierzu:

SCL/ADC5/PCINT13 – Port C, Bit 5
  – SCL: 2-wire Serial Interface Clock. When the TWEN bit in TWCR is set 
(one) to enable the 2-wire Serial Interface, pin PC5 is disconnected 
from the port and becomes the Serial Clock I/O pin for the 2-wire Serial 
Interface. In this mode, there is a spike filter on the pin to suppress
spikes shorter than 50 ns on the input signal, and the pin is driven by 
an open drain driver with slew-rate limitation.
SDA/ADC4/PCINT12 – Port C, Bit 4
– SDA: 2-wire Serial Interface Data. ... <der gleiche Text wie SCL>

Wenn ich das alles richtig im Quellcode vom Arduino verstehe, dann wird 
bei Wire.begin() das TWEN-Bit in TWCR gesetzt und beim Wire.end() wieder 
gelöscht. Im I2C-Modus sind beide Pins wirklich auch open-drain und 
benötigen einen Pullup. Sobald man den I2C-Modus aber wieder verlässt, 
liegen die IO-Pins wieder an.

Ich muss das manl nachmessen...

von Michael U. (amiga)


Lesenswert?

Hallo,

aua, da müßte ich jetzt auch stark das Datenblatt des Mega328 
befragen...
Meiner Erinnerung nach bleibt die PullUp-Funktion auch dann aktiv wenn 
TWEN gesetzt wird. Es wird nur die OUT-Stufe umgeschaltet, die PullUp 
müßten zur IN-Hardware gehören und damit weiterhin ein-/ausschaltbar 
sein. IN bleibt ja mit dem Pin verbunden.

Gruß aus Berlin
Michael

von Olli Z. (z80freak)


Lesenswert?

In dem Fall wäre aber das häufig zu findende, im erster Post abgebildete 
Pinout mit den beiden externen Pullups zu 3,3V falsch. Das würde ja, 
alternativ zu einem Pegelwanlder, nur funktionieren wenn die Ausgänge 
wirklich ausschließlich opendrain wären.
Zum Einschaltzeitung (Resetphase) sollen die Pins laut Datenblatt 
Tristate sein. Soblad ich Zeit hab prüfe ich das mit einem Uno/Nano und 
dem DSO mal nach...

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,

nach Rest sind sie triState und der interne PullUp ist aus.
Setze ich den Pin über DDR auf Ausgang ist die Push-Pull-Stufe aktiv.
Schalte ich TWEN aktiv ist die Ausgangsstufe openDrain, meiner 
Erinnerung nach völlig unabhängig vom Zustand des DDR-Bits (da müßte ich 
jetzt aber ins Datenblatt schauen).
Die exiernen PullUp sind für I2C nötig wegen der OpenDrain Ausgänge.
Wenn jetzt mit dem Portbit der interne Pullup eingeschaltet wird liegen 
eben diese ca. 50k  parallel zum externen PullUp, stört doch keinen.
Wenn keine externen pullUp da sind und der interne eingeschaltet wird, 
hat der I2C eben diese 50k als PullUp. Das funktioniert in der Praxis 
auch dzurchaus bei nur einem Slave am Bus und kurzen Leitungen und z.B. 
100kHz I2C-Clock. Ist aber natürlich nicht normgerecht.

Praktisch kommt bei den China-BreakOut-Board noch dazu, daß jeder macht 
was er will. Mal sind auf den Modulen PullUps an SDA/SCL, mal 
Pegelwandler, mal garnichts...

Gruß aus berlin
Michael

von Olli Z. (z80freak)


Lesenswert?

Mir ging es nicht um die Pullups selbst, sondern vielmehr um die 
Spannungspegel. Wenn ich auf einem Uno Board zu irgendeinem Zeitpunkt 
die internen Pullups aktiviere, oder wenn die Ausgangsstufe im Push 
Modus einen High Pegel erzeugtm dann habe ich doch 5V am jeweiligen 
Signal. Da nutzt dann der externe Pullup gegen 3,3V doch auch nichts 
mehr...?,

von David D. (saturi)


Lesenswert?

Hallo zusammen, ich melde mich nach einigen versuchs Stunden.

@Olli
Ich gebe dir recht, dass wir die Startbedingungen nicht ändern sollten 
und bin deswegen wieder auf die Kamera ohne Fifo umgestiegen.
Da ich bislang, wie schon erwähnt, nicht mit der Arduino IDE gearbeitet 
habe, sondern mit dem Atmel Studio, stellen sich für mich die ganzen 
Sachen etwas komplexer dar. Um aber die Fehler eingrenzen zu können, hab 
ich mich jetzt einmal dazu durchgerungen zumindest testweise auf die 
Arduino IDE umzusteigen. Ich habe es allerdings nicht geschafft, die 
bisher genutzten Controller über diese anzusteuern. Vermutlich habe ich 
den Bootloader beim ISP Programmieren überschrieben.

Glücklicherweise habe ich noch einen unbenutzten Nano gefunden, mit dem 
ich das ganze zum laufen gebracht habe. Ich denke, ob ich jetzt zur 
Ansteuerung am Anfang den Nano oder den Uno verwende, sollte keinen 
Unterschied machen. (Bitte belehrt mich wenn ich falsch liege)

zu deinem geposteten Test-Code:
Über das I2C Interface wird das ganze definitiv viel Übersichtlicher als 
in meinem bisherigen Programmcode, in dem Ich die Übertragung zu Fuß 
abbilden wollte. Ich denke ich kann auch nachvollziehen, was du mit dem 
Code bezwecken willst, was ich hier kurz zusammenfassen möchte, um 
Missverständnisse auszuschließen:
1.Block: Register Reset
 ->Alle Register auf Default Value
2. Block
 -> Default Value von Register 0x0A auslesen
3. Block
 -> Default Value von Register 0x0B auslesen

das ganze hab ich jetzt einfach mal auf den Nano geladen.
ich bekomme allerdings "falsche" Default Werte zurück. Sie Variieren 
schon mal zwischen den beiden Registern, was schon mal sehr gut ist, 
weil ich bisher immer nur 0xFF zurück bekommen habe, allerdings bekomme 
ich für das

0x0A Register: 0xEC
0x0B Register: 0xFC

nach meinem Datenblatt sollten es aber 0x76 und 0x70 sein.
Übersehe ich was?
Was sind die Rückgabe Werte die du bekommst?
-----------------------------
Zum Thema Pull-Up Widerstände, kann ich eurer Diskussion zumindest 
folgen. Ich bin eben im Datenblatt des Atmega328P auch auf diese Stelle 
gestoßen.
Hier heißt es, dass die externen Pull-Up Widerstände nötig sind. (Wird 
aber ein paar Seiten weiter wieder relativiert und es heißt, dass für 
manche Anwendungen auch die internen Pull-Up Widerstände genutzt werden 
können).

Da hätte ich eine Verständnis Frage: ich war bislang immer der Meinung, 
dass Pull-Up Widerstände nur wichtig sind, wenn der Pin als Eingang 
konfiguriert ist. Ist das ein Fehlglaube?

Danke euch

von Michael U. (amiga)


Lesenswert?

Hallo,
David D. schrieb:
> Glücklicherweise habe ich noch einen unbenutzten Nano gefunden, mit dem
> ich das ganze zum laufen gebracht habe. Ich denke, ob ich jetzt zur
> Ansteuerung am Anfang den Nano oder den Uno verwende, sollte keinen
> Unterschied machen. (Bitte belehrt mich wenn ich falsch liege)

egal ob Uno oder Nano, ist eben ein Mega328. Die Pinbelegungen der 
Boards kannst Du ja vergleichen und die Schaltpläne für beie liegen im 
Netz.

Allgemein noch zu ArduinoIDE: Du kannst aus der IDE auch ohne Bootloader 
flashen wenn Du einen der gängigen ISP-Programmer hast.
Bei Werkzeuge-> Programmer Deinen Programmer auswählen und dann im Menü 
Sketch->Hochladen mit Programmer

Dann brauchst Du auch keinerlei Bootloader auf dem Ziel-AVR.

PullUp sind für die Eingänge soweit richtig. Eingang ist bei I2C das 
Ende, was gerade Empfangen will, bei SDA also mal der Master, mal der 
Slave.
Deshalb ja OpenDrain damit eine kurzschlüsse gibt wenn einer High setzt 
und der andere Low. Bei SCK ist es auch so: ein I2C darf zu jeder Zeit 
SCK auf Low halten und so dem Master mitteilen, daß er noch Zeit braucht 
(ClockStretching). Deshalb ist I2C auf einem AVR in reiner Software 
(also ohne das interne Hardware-TWI ziemlich tricky. Man darf dabei dann 
einen Ausgang nie auf PushPull setzen, er ist entweder Eingang (High 
dann vom PullUp irgendwo) oder Ausgang/Low.

Gruß aus Berlin
michael

von David D. (saturi)


Lesenswert?

Michael U. schrieb:

> Allgemein noch zu ArduinoIDE: Du kannst aus der IDE auch ohne Bootloader
> flashen wenn Du einen der gängigen ISP-Programmer hast.
> Bei Werkzeuge-> Programmer Deinen Programmer auswählen und dann im Menü
> Sketch->Hochladen mit Programmer
Ich habe den AVR Dragon, der ja glaube ich leider nicht dort aufgeführt 
ist. Ich habe zwar einen Beitrag gefunden, wo mehrere Dateien der IDE 
geändert wurden, um das zu ermöglichen, allerdings nutze ich auf win10 
die App von Arduino und da finde ich die Dateien nicht und bin auch 
nicht sicher, ob es genauso funktionieren würde.

> Deshalb ja OpenDrain damit eine kurzschlüsse gibt wenn einer High setzt
> und der andere Low. Bei SCK ist es auch so: ein I2C darf zu jeder Zeit
> SCK auf Low halten und so dem Master mitteilen, daß er noch Zeit braucht
> (ClockStretching). Deshalb ist I2C auf einem AVR in reiner Software
> (also ohne das interne Hardware-TWI ziemlich tricky. Man darf dabei dann
> einen Ausgang nie auf PushPull setzen, er ist entweder Eingang (High
> dann vom PullUp irgendwo) oder Ausgang/Low.

Wie genau bekomme ich einen Pin auf OpenDrain? mir sind nur die Modi In 
oder Out bekannt. Habe jetzt schon ein paar Beiträge dazu gelesen, aber 
werde nicht ganz schlau daraus. Im Datenblatt des OV7670 hab ich etwas 
von einem Widerstand in der SDA Leitung gelesen, um die Kurzschlüsse zu 
vermeiden. Das erscheint mir aber nicht allzu elegant.

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Ich habe den AVR Dragon, der ja glaube ich leider nicht dort aufgeführt
> ist. Ich habe zwar einen Beitrag gefunden, wo mehrere Dateien der IDE
> geändert wurden, um das zu ermöglichen, allerdings nutze ich auf win10
> die App von Arduino und da finde ich die Dateien nicht und bin auch
> nicht sicher, ob es genauso funktionieren würde.
Ich habe gerade mal geschaut, ob mein "Drache" noch lebt. ;)
Ich hatte den mal in die IDE eingetragen, war etwas trickreich, habe ich 
in der aktuellen inzwischen auch nicht mehr gemacht.
Du kannst auch einfach mit Sketch->Kompilierte Binärdatei exportieren 
die von der IDE erzeugten .hex-Files exportieren. Die liegen dann bei 
Deinem Projekt im Sketch-Ordner. Einmal mit und einmal ohne Bootloader. 
Kannst Du dann ja aus dem Studio ö.ä. mit dem Dragon per ISP 
raufschreiben.
Nicht schön, funktioniert aber.
Wenn Du da mehr experimetierst würde ich die ArduinoIDE unbedingt 
portabel installieren.
IDE als ZIP runterladen, an einen Ort Deiner Wahl entpacken, IDE NICHT 
starten! Im dann vorhandenen Ordner Arduino-1.8.5 einen Ordner
portable
anlegen und dann die IDE starten.
Dann landen alle Dateien, Bibliotheken, Sketchbook usw. in diesem 
Arduino-1.8.5 Ordner. Den kann man dann auch koplett umkopieren oder die 
IDE von einem USB-Stick direkt an irgendeinem Windows-Rechner starten 
und benutzen.

> Wie genau bekomme ich einen Pin auf OpenDrain? mir sind nur die Modi In
> oder Out bekannt. Habe jetzt schon ein paar Beiträge dazu gelesen, aber
> werde nicht ganz schlau daraus. Im Datenblatt des OV7670 hab ich etwas
> von einem Widerstand in der SDA Leitung gelesen, um die Kurzschlüsse zu
> vermeiden. Das erscheint mir aber nicht allzu elegant.

Was hast Du vor? Wenn Du die TWI-Hardware des AVR nutzt muß Dich nichts 
davon interessieren, daß erledigt die Hardware komplett alleine.
Nur wenn Du TWi/I2C komplett von Hand programmieren willst mußt Du 
diverses beachten. habe ich auch schon gemacht, in ASM als die AVR noch 
keine TWI in Hardware hatten. Ist aber viele Jahre her...

Ob Du mit der OV7670 jetzt aus der Arduino-IDE redest oder on Du Dir 
eine I2C-Bibliothek in C suchst und im Atmel-Studio o.ä. programmierst, 
ist relativ egal. Von I2C mßt Du erstmal nur grundsätzliches wissen: 
Adresse, Start/RepaetStart/Stop-Condition. Die Wire.h der ArduinoIDE 
kapselst aber auch dieses schon. Wire.begin() initialisiert die 
I2C-hardware des Mega328 (setzt also taktteiler, TWIEN usw. 
beginTransmission schickt Start und Adresse, write schickt Datenbytes. 
Das ACK/NACK-Handling erledigen die Funktionen auch mit.

Ich habe auch etwas den Überblick verloren was Du zur Zeit gerade mit 
der Kamera anfangen willst...

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Vielen Dank für die Informationen. Ja ich werde dann wohl mit dem 
fertigen I2C arbeiten, um die Tücken vorerst zu umgehen.

Ja genau deswegen würde ich Vorschlagen erstmal Back-To-Topic.
Das Ziel ist es, die Funktionsweise der Kamera zu verstehen und sie dann 
auch zu betreiben. (Dabei möchte ich auf föllig fertige Librarys 
verzichten.
Der aktuell 1. Schritt ist, dass SCCB-Interface zum laufen zu bringen.

von Olli Z. (z80freak)


Lesenswert?

Sehr gut David, wir sind wieder auf einem Nenner! :-)
Um Software zum laufen zu bekommen muss man natürlich die Hardware 
beherrschen, ganz klar. Daher ist der kleine Exkurs zum Thema Arduino IO 
Ports schon wichtig.Ich wollte uns ja, durch den Einsatz eines 
Pegelwandlers von der ganzen Problematik fern halten. Genauso wie die 
ganzen vielen kleinen fiesen Details zum I2C Interface.

Kurz gesagt habe ich gestern mal einen Versuchsaufbau unternommen und 
festgestellt das man schon mit externen Pullups arbeiten kann. Im Grunde 
macht man das dann so: Solange der Port unprogrammiert ist, ist er 
Tristate. Dann programmiert man den Pin als Eingang, schreibt aber 
vorher auf den Port eine 0. Dies „entfernt“ den internen Pullup 
Widerstand. In Folge ist der Ausgang Opendrain, also offen und der 
externe Pullup zieht die Leitung auf den gewünschten Spannungspegel. Nun 
kann man durch ändern der Datenrichtung im DDR Register von Eingang aus 
Augang dafür sorgen das die Ausgangsstufe auf GND schaltet. Das Ergebnis 
ist klar, oder? ;-)

So könnte man auf einen Pegelwandler verzichten. Dieses Prinzip könnte 
man auf jeden Port anwenden, also auch auf CLK und Daten. Macht man in 
der Programmierung aber irgendwo einen Fehler, oder nutzt eine Library 
wo man nicht genau weiss was sie intern tut, ist es gleich vorbei...

Apropos Library. Jetzt verwendest Du ja keine Arduino IDE und somit auch 
keine entsprechenden Libs. Hier müssen wir noch zusammenkommen. Ich habe 
mich auf Arduino eingelassen weil der sehr verbreitet ist. Du kannst 
Deinem Nano den Bootloader nachflashen, via ISP Port.

Wir können aber auch gern die AVR Umgebung nutzen, dann müssten wir uns 
halt um das TWI Interface des Atmega selbst kümmern... geht alles, 
bringt uns aber erstmal wieder weiter weg vom Ziel.

von David D. (saturi)


Lesenswert?

Olli Z. schrieb:

> Wir können aber auch gern die AVR Umgebung nutzen, dann müssten wir uns
> halt um das TWI Interface des Atmega selbst kümmern... geht alles,
> bringt uns aber erstmal wieder weiter weg vom Ziel.

Mein langfristiges Ziel ist es, das ganze in der AVR Umgebung, bzw. über 
das Atmelstudio zu programmieren. Weil ich dann wirklich nachvollziehen 
kann, was welcher Pin wirklich wann macht. Da wir aber wie wir ja schon 
festgestellt haben auf verschiedenen Systemen arbeiten, habe ich mir zu 
Beginn des Wochenendes die Arduino IDE runtergeladen und eben auch noch 
einen auf dieser Umgebung funktionierenden Nano ausgegraben.
Für den Anfang sollte das auch in Ordnung sein. Den Transfer auf AVR 
ebene kann man dann ja im Nachgang noch vollziehen.

Damit habe ich mich dann an deinen Test-Code (s.o.) gemacht.
Hiernochmal der wichtige Part:

>zu deinem geposteten Test-Code:
>Über das I2C Interface wird das ganze definitiv viel Übersichtlicher als
>in meinem bisherigen Programmcode, in dem Ich die Übertragung zu Fuß
>abbilden wollte. Ich denke ich kann auch nachvollziehen, was du mit dem
>Code bezwecken willst, was ich hier kurz zusammenfassen möchte, um
>Missverständnisse auszuschließen:
>1.Block: Register Reset
> ->Alle Register auf Default Value
>2. Block
> -> Default Value von Register 0x0A auslesen
>3. Block
> -> Default Value von Register 0x0B auslesen
>
>das ganze hab ich jetzt einfach mal auf den Nano geladen.
>ich bekomme allerdings "falsche" Default Werte zurück. Sie Variieren
>schon mal zwischen den beiden Registern, was schon mal sehr gut ist,
>weil ich bisher immer nur 0xFF zurück bekommen habe, allerdings bekomme
>ich für das
>
>0x0A Register: 0xEC
>0x0B Register: 0xFC

>nach meinem Datenblatt sollten es aber 0x76 und 0x70 sein.
>Übersehe ich was?
>Was sind die Rückgabe Werte die du bekommst?

Ich habe mittlerweile schon zwei Datenblätter gefunden, in denen 
unterschiedliche default Values stehen. Daher würde es mich doch 
brennend interessieren, was du für Rückgabewerte hast und falls es 
andere sind, die Ursache finden, was bei mir wohl noch falsch ist.

Danke und einen schönen Sonntag :)

: Bearbeitet durch User
von Olli Z. (z80freak)


Lesenswert?

Ich lese folgende Werte:
Register 0x0A = 0x76
Register 0x0B = 0x73
Darin soll ja die Produkt-ID stecken. In 0A das MSB (PID) und in 0B das 
LSB (VER). Da wirken meine Werte jetzt plausibel, denn die Product-ID 
(PID) ist laut Datenblatt 0x76 und die Versions-ID (VER) unterscheidet 
sich nur leicht (0x73 anstelle im Datenblatt 0x70).

Was ich noch nicht finde ist die tatsächliche Slave-ID. Im Datenblatt 
steht: auf Seite 10 "The device slave addresses are 42 for write and 43 
for read.". Leider weder ob das Dezimal oder Hexadezimaladressen sind, 
es ist auch anders als in den Arduino Beispielcodes zu finden, da wird 
für Read und Write diesselbe Adresse verwendet, nämlich 0x21.

Habe mal zum vergleichen den Sketch angepasst um einfach mal alle 
Register damit auslesen und anzeigen zu können. Laut Datenblatt gibt es 
nur die Register von 0x00 bis 0xC9.
1
#include "Wire.h"
2
3
void setup() {
4
  Serial.begin(38400);
5
6
  // Generate 8 MHz clock output on Pin "9"
7
  pinMode(9, OUTPUT);
8
  TCCR1A = ((1 << COM1A0)); //0x23;
9
  TCCR1B = ((1 << WGM12) | (1 << CS10)); //0x09;
10
  TIMSK1 = 0;
11
  OCR1A = 0;
12
  
13
  // Reset chip to defaults
14
  // (write 0b10000000 into register 0x12)
15
  Wire.begin();
16
  Wire.beginTransmission(0x21);
17
  Wire.write(0x12);
18
  Wire.write(0x80);
19
  Wire.endTransmission();
20
  delay(500);
21
22
  // Read out values of all registers
23
  for (int adr=0; adr<256; adr++)
24
  {
25
    Serial.print("Value of 0x");
26
    if (adr < 0x10)
27
      Serial.print("0");
28
    Serial.print(adr, HEX);
29
    Serial.print(" = ");
30
    Wire.beginTransmission(0x21);
31
    Wire.write(adr);
32
    Wire.endTransmission();
33
    Wire.requestFrom(0x21, 1);
34
    while(Wire.available() == 0);
35
    while(Wire.available()) {
36
      int b = Wire.read();
37
      Serial.print("0x");
38
      if (b < 0x10)
39
        Serial.print("0");
40
      Serial.print(b, HEX);
41
    }
42
    Serial.println("");
43
  }
44
}
45
46
void loop() {
47
48
}

Und hier mein Ergebnis dazu. Auch ich stelle teils massive Abweichungen 
zu den Defaultwerten laut Datenlbatt fest:
1
Value of 0x00 = 0x1A
2
Value of 0x01 = 0x80
3
Value of 0x02 = 0x88
4
Value of 0x03 = 0x00
5
Value of 0x04 = 0x01
6
Value of 0x05 = 0x7D
7
Value of 0x06 = 0x6E
8
Value of 0x07 = 0x40
9
Value of 0x08 = 0x7D
10
Value of 0x09 = 0x01
11
Value of 0x0A = 0x76
12
Value of 0x0B = 0x73
13
Value of 0x0C = 0x00
14
Value of 0x0D = 0x00
15
Value of 0x0E = 0x01
16
Value of 0x0F = 0x43
17
Value of 0x10 = 0x7F
18
Value of 0x11 = 0x80
19
Value of 0x12 = 0x00
20
Value of 0x13 = 0x8F
21
Value of 0x14 = 0x4A
22
Value of 0x15 = 0x00
23
Value of 0x16 = 0x00
24
Value of 0x17 = 0x11
25
Value of 0x18 = 0x61
26
Value of 0x19 = 0x03
27
Value of 0x1A = 0x7B
28
Value of 0x1B = 0x00
29
Value of 0x1C = 0x7F
30
Value of 0x1D = 0xA2
31
Value of 0x1E = 0x01
32
Value of 0x1F = 0x00
33
Value of 0x20 = 0x04
34
Value of 0x21 = 0x02
35
Value of 0x22 = 0x01
36
Value of 0x23 = 0x00
37
Value of 0x24 = 0x75
38
Value of 0x25 = 0x63
39
Value of 0x26 = 0xD4
40
Value of 0x27 = 0x80
41
Value of 0x28 = 0x80
42
Value of 0x29 = 0x07
43
Value of 0x2A = 0x00
44
Value of 0x2B = 0x00
45
Value of 0x2C = 0x80
46
Value of 0x2D = 0x00
47
Value of 0x2E = 0x00
48
Value of 0x2F = 0x72
49
Value of 0x30 = 0x08
50
Value of 0x31 = 0x30
51
Value of 0x32 = 0x80
52
Value of 0x33 = 0x08
53
Value of 0x34 = 0x11
54
Value of 0x35 = 0x1A
55
Value of 0x36 = 0x00
56
Value of 0x37 = 0x3F
57
Value of 0x38 = 0x01
58
Value of 0x39 = 0x00
59
Value of 0x3A = 0x0D
60
Value of 0x3B = 0x00
61
Value of 0x3C = 0x68
62
Value of 0x3D = 0x88
63
Value of 0x3E = 0x00
64
Value of 0x3F = 0x00
65
Value of 0x40 = 0xC0
66
Value of 0x41 = 0x08
67
Value of 0x42 = 0x00
68
Value of 0x43 = 0x14
69
Value of 0x44 = 0xF0
70
Value of 0x45 = 0x45
71
Value of 0x46 = 0x61
72
Value of 0x47 = 0x51
73
Value of 0x48 = 0x79
74
Value of 0x49 = 0x00
75
Value of 0x4A = 0x00
76
Value of 0x4B = 0x00
77
Value of 0x4C = 0x00
78
Value of 0x4D = 0x04
79
Value of 0x4E = 0x00
80
Value of 0x4F = 0x40
81
Value of 0x50 = 0x34
82
Value of 0x51 = 0x0C
83
Value of 0x52 = 0x17
84
Value of 0x53 = 0x29
85
Value of 0x54 = 0x40
86
Value of 0x55 = 0x00
87
Value of 0x56 = 0x40
88
Value of 0x57 = 0x80
89
Value of 0x58 = 0x1E
90
Value of 0x59 = 0x91
91
Value of 0x5A = 0x94
92
Value of 0x5B = 0xAA
93
Value of 0x5C = 0x71
94
Value of 0x5D = 0x8D
95
Value of 0x5E = 0x0F
96
Value of 0x5F = 0xF0
97
Value of 0x60 = 0xF0
98
Value of 0x61 = 0xF0
99
Value of 0x62 = 0x00
100
Value of 0x63 = 0x00
101
Value of 0x64 = 0x50
102
Value of 0x65 = 0x30
103
Value of 0x66 = 0x00
104
Value of 0x67 = 0x80
105
Value of 0x68 = 0x80
106
Value of 0x69 = 0x00
107
Value of 0x6A = 0x88
108
Value of 0x6B = 0x0A
109
Value of 0x6C = 0x02
110
Value of 0x6D = 0x55
111
Value of 0x6E = 0xC0
112
Value of 0x6F = 0x9A
113
Value of 0x70 = 0x3A
114
Value of 0x71 = 0x35
115
Value of 0x72 = 0x11
116
Value of 0x73 = 0x00
117
Value of 0x74 = 0x00
118
Value of 0x75 = 0x0F
119
Value of 0x76 = 0x01
120
Value of 0x77 = 0x10
121
Value of 0x78 = 0x00
122
Value of 0x79 = 0x00
123
Value of 0x7A = 0x24
124
Value of 0x7B = 0x04
125
Value of 0x7C = 0x07
126
Value of 0x7D = 0x10
127
Value of 0x7E = 0x28
128
Value of 0x7F = 0x36
129
Value of 0x80 = 0x44
130
Value of 0x81 = 0x52
131
Value of 0x82 = 0x60
132
Value of 0x83 = 0x6C
133
Value of 0x84 = 0x78
134
Value of 0x85 = 0x8C
135
Value of 0x86 = 0x9E
136
Value of 0x87 = 0xBB
137
Value of 0x88 = 0xD2
138
Value of 0x89 = 0xE5
139
Value of 0x8A = 0x00
140
Value of 0x8B = 0x00
141
Value of 0x8C = 0x00
142
Value of 0x8D = 0x0F
143
Value of 0x8E = 0x00
144
Value of 0x8F = 0x00
145
Value of 0x90 = 0x00
146
Value of 0x91 = 0x00
147
Value of 0x92 = 0x00
148
Value of 0x93 = 0x00
149
Value of 0x94 = 0x50
150
Value of 0x95 = 0x50
151
Value of 0x96 = 0x01
152
Value of 0x97 = 0x01
153
Value of 0x98 = 0x10
154
Value of 0x99 = 0x40
155
Value of 0x9A = 0x40
156
Value of 0x9B = 0x20
157
Value of 0x9C = 0x00
158
Value of 0x9D = 0x99
159
Value of 0x9E = 0x7F
160
Value of 0x9F = 0xC0
161
Value of 0xA0 = 0x90
162
Value of 0xA1 = 0x03
163
Value of 0xA2 = 0x02
164
Value of 0xA3 = 0x02
165
Value of 0xA4 = 0x00
166
Value of 0xA5 = 0x0F
167
Value of 0xA6 = 0xF0
168
Value of 0xA7 = 0xC1
169
Value of 0xA8 = 0xF0
170
Value of 0xA9 = 0xC1
171
Value of 0xAA = 0x14
172
Value of 0xAB = 0x0F
173
Value of 0xAC = 0x00
174
Value of 0xAD = 0x80
175
Value of 0xAE = 0x80
176
Value of 0xAF = 0x80
177
Value of 0xB0 = 0x00
178
Value of 0xB1 = 0x00
179
Value of 0xB2 = 0x00
180
Value of 0xB3 = 0x80
181
Value of 0xB4 = 0x00
182
Value of 0xB5 = 0x04
183
Value of 0xB6 = 0x00
184
Value of 0xB7 = 0x66
185
Value of 0xB8 = 0x00
186
Value of 0xB9 = 0x06
187
Value of 0xBA = 0x00
188
Value of 0xBB = 0x00
189
Value of 0xBC = 0x00
190
Value of 0xBD = 0x00
191
Value of 0xBE = 0x00
192
Value of 0xBF = 0x00
193
Value of 0xC0 = 0x00
194
Value of 0xC1 = 0x00
195
Value of 0xC2 = 0x00
196
Value of 0xC3 = 0x00
197
Value of 0xC4 = 0x00
198
Value of 0xC5 = 0x00
199
Value of 0xC6 = 0x00
200
Value of 0xC7 = 0x00
201
Value of 0xC8 = 0x06
202
Value of 0xC9 = 0xC0
203
Value of 0xCA = 0xC0
204
Value of 0xCB = 0xC0
205
Value of 0xCC = 0xC0
206
Value of 0xCD = 0xC0
207
Value of 0xCE = 0xC0
208
Value of 0xCF = 0xC0
209
Value of 0xD0 = 0xC0
210
Value of 0xD1 = 0xC0
211
Value of 0xD2 = 0x88
212
Value of 0xD3 = 0x88
213
Value of 0xD4 = 0x88
214
Value of 0xD5 = 0x88
215
Value of 0xD6 = 0x88
216
Value of 0xD7 = 0x88
217
Value of 0xD8 = 0x88
218
Value of 0xD9 = 0x88
219
Value of 0xDA = 0x88
220
Value of 0xDB = 0x88
221
Value of 0xDC = 0x1A
222
Value of 0xDD = 0x1A
223
Value of 0xDE = 0x1A
224
Value of 0xDF = 0x1A
225
Value of 0xE0 = 0x1A
226
Value of 0xE1 = 0x1A
227
Value of 0xE2 = 0x1A
228
Value of 0xE3 = 0x1A
229
Value of 0xE4 = 0x1A
230
Value of 0xE5 = 0x88
231
Value of 0xE6 = 0x88
232
Value of 0xE7 = 0x88
233
Value of 0xE8 = 0x88
234
Value of 0xE9 = 0x88
235
Value of 0xEA = 0x88
236
Value of 0xEB = 0x88
237
Value of 0xEC = 0x88
238
Value of 0xED = 0x88
239
Value of 0xEE = 0x1A
240
Value of 0xEF = 0x1A
241
Value of 0xF0 = 0x1A
242
Value of 0xF1 = 0x1A
243
Value of 0xF2 = 0x1A
244
Value of 0xF3 = 0x1A
245
Value of 0xF4 = 0x1A
246
Value of 0xF5 = 0x1A
247
Value of 0xF6 = 0x1A
248
Value of 0xF7 = 0x1A
249
Value of 0xF8 = 0x88
250
Value of 0xF9 = 0x88
251
Value of 0xFA = 0x88
252
Value of 0xFB = 0x88
253
Value of 0xFC = 0x88
254
Value of 0xFD = 0x88
255
Value of 0xFE = 0x88
256
Value of 0xFF = 0x88

: Bearbeitet durch User
von David D. (saturi)


Lesenswert?

Okay, dann hab ich bei mir offensichtlich noch ein Problem. Ich werde 
nochmal den Aufbau überprüfen und mich dann nochmal melden, entweder mit 
dem gefundenen Fehler oder ein paar Fotografien zur Fehleranalyse mit 
euch :D

Edit: Habe den Fehler gefunden... aber es ist mir zu peinlich zuzugeben, 
dass ich bei meinem Terminal Programm vergessen habe die Baudrate 
anzupassen xD....
Damit bin ich mit dir auf einem Nenner, manche Register zeigen zu deinen 
zwar Abweichungen, aber ich habe auch die 76 und die 73 in 0A und 0B

> Was ich noch nicht finde ist die tatsächliche Slave-ID. Im Datenblatt
> steht: auf Seite 10 "The device slave addresses are 42 for write and 43
> for read.". Leider weder ob das Dezimal oder Hexadezimaladressen sind,
> es ist auch anders als in den Arduino Beispielcodes zu finden, da wird
> für Read und Write diesselbe Adresse verwendet, nämlich 0x21.

Da kann ich Licht ins Dunkle bringen. Das ist nämlich bei beiden das 
gleiche ;-)
nur das im Datenblatt offensichtlich das Lese bzw. Schreib Bit 
dazugezählt wird, also das R/W-Bit
Sprich der Aufbau ist ja:

Die ersten 7 Bit sind die Adresse und das 8. Bit ist schreiben/lesen.
Wenn jetzt die Adresse 0x21 ist, man die aber einmal nach Links shiftet 
um das 8. Bit noch anhängen zu können erhält man: 0x42 (Multiplikation 
mit 2)
jetzt ist das R/W bit beim schreiben 0 sprich wir bleiben bei 0x42 und 
beim lesen 1 womit wir bei der 0x43 wären.
Ich hoffe das ist soweit verständlich ausgedrückt.

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Da kann ich Licht ins Dunkle bringen. Das ist nämlich bei beiden das
> gleiche ;-)
> nur das im Datenblatt offensichtlich das Lese bzw. Schreib Bit
> dazugezählt wird, also das R/W-Bit
> Sprich der Aufbau ist ja:
>
> Die ersten 7 Bit sind die Adresse und das 8. Bit ist schreiben/lesen.
> Wenn jetzt die Adresse 0x21 ist, man die aber einmal nach Links shiftet
> um das 8. Bit noch anhängen zu können erhält man: 0x42 (Multiplikation
> mit 2)
> jetzt ist das R/W bit beim schreiben 0 sprich wir bleiben bei 0x42 und
> beim lesen 1 womit wir bei der 0x43 wären.

das ist das "übliche" I2C-Problem. I2C benutzt 7Bit-Adressen in 
Bit7...Bit1.
Bit0 ist eben R/W.
Ich kenne genug Datenblätter die es mit R/W als 2x 8Bit-Adresse angeben, 
ungefähr genausoviele, die die 7Bit-Adresse angeben und die Bitmaske des 
Bytes dazu. Bei der Software ist es sehr ähnlich.
Wird man mit leben müssen.

Gruß aus Berlin
Michael

von Olli Z. (z80freak)


Lesenswert?

Oh ja, Danke für die Nachhilfe! :-)
0x43 = 0b0100 0011
0x42 = 0b0100 0010
0x21 = 0b0010 0001

Ja und genau das sind natürlich die "Freuden" wenn man Libs verwendet. 
Die wollen einem die Arbeit abnehmen und verursachen dadurch manchmal 
erst die Probleme ;-) Aber auch die Datenblätter sind mitunter ganz 
schön schrottig, wie in diesem Beispiel.

Zu den Defaultwerten: Keine Ahnung ob die immer so sein müssen wie im 
Datenblatt. Aber anscheinend klappt die grundsätzliche Kommunikation und 
wir könnten einen Schritt weiter gehen?! (Nur weil Du es nicht explizit 
erwänht hast: Hast Du nun den Pegelwandler zwischen den Signalen?).

Als nächstes wäre die Frage was wir als nächstes tun. Normalerweise 
würde man jetzt die Betriebsparameter für den Kamerabetrieb übermitteln, 
dann den PCLK (Pixelclock) anlegen und Bilddaten am Parallelport 
abrufen. Ein netter Test hier wäre erstmal nur die HSYNC- und 
VSYNC-Signale zu erfassen und zu zählen. Nach jedem erkannten VSYNC 
müssten ja immer eine der Auflösung entsprechende Anzahl HSYNC-Signale 
folgen. Die einfach zählen und ausgeben.

von Michael U. (amiga)


Lesenswert?

Hallo,

@Olli Z. (z80freak):
das kommt nun davon...
Arduino Nano und Pegelwandler und die OV7670 zusammengesteckt,
nur 3,3V/GND/SCL/SDA und XCLK angeschlossen.
Deinen Sketch rauf und gestartet.

Ich könnte jetzt die nächste Liste abweichender Registerwerte anbieten, 
mit dem Datenblatt habe ich noch nicht vergleichen.

Value of 0x00 = 0xF9
Value of 0x01 = 0x80
Value of 0x02 = 0x88
Value of 0x03 = 0x00
Value of 0x04 = 0x01
Value of 0x05 = 0x7A
Value of 0x06 = 0xAD
Value of 0x07 = 0x40
Value of 0x08 = 0x7A
Value of 0x09 = 0x01
Value of 0x0A = 0x76
Value of 0x0B = 0x73
Value of 0x0C = 0x00
Value of 0x0D = 0x00
Value of 0x0E = 0x01
Value of 0x0F = 0x43
Value of 0x10 = 0x7F
Value of 0x11 = 0x80
Value of 0x12 = 0x00
Value of 0x13 = 0x8F
Value of 0x14 = 0x4A
Value of 0x15 = 0x00
Value of 0x16 = 0x00
Value of 0x17 = 0x11
Value of 0x18 = 0x61
...

Gruß aus Berlin
Michael

von David D. (saturi)


Angehängte Dateien:

Lesenswert?

Guten Abend,
mein letzter Post für Heute, versprochen ;-)

also ja ich habe drei Pegelwandler zwischen der SCL,SDA und XCLK. 
Nachdem ich mir eben dachte, dass so viele Bauteile ja nicht drauf sind 
und man die auch bestimmt selber bauen kann, hab ich mir die 
Funktionsweise angeschaut und festgestellt, dass es eine High und eine 
Low Seite gibt. (Wie auch bei dir im Eagle zu sehen) Wie der Zufall es 
so will, hab ich die das Ganze Wochenende so betrieben, was bei kurzem 
Nachmessen eben die Erkenntnis brachte, dass ich die Kamera das ganze 
Wochenende an 5V Signalen betrieben habe. Jetzt passt aber alles!

Nachdem ich mir die Signalverläufe von deiner Sketch mit deinen von 
meinem AVR-Selbstgebasteltem-Kommunikationsprotokoll verglichen habe, 
ist mir aufgefallen, dass ich die Stopp und Start Sequenz zwischen den 
beiden 2-Phasen Übertragungen vergessen habe. Kaum sind die drin 
funktioniert auch mein Skript im Atmel-Studio und liefert die richtigen 
Werte! Das Wochenende war also - dank eurer Hilfe - ein voller Erfolg :)

@Michael
Value of 0x0A = 0x76
Value of 0x0B = 0x73

scheinen wenigstens bei uns dreien alle gleich zu sein. :D der Rest 
weicht offensichtlich immer vom Datenblatt ab.

@Olli
Hört sich doch schon mal nach einem Plan an.
Habe mal kurz das Oszi dran gehangen und das sieht schonmal nach nem 
vernünftigen Signal aus :)

viele Grüße aus dem Schwabenland
David

von Olli Z. (z80freak)


Lesenswert?

Prima, David! Da sind wir doch schonmal einem Problem auf die Spur 
gekommen. Die Sache mit den Start Stop Sequenzen ist ja elementar für 
I2C, logisch.

Was die „Default“-Werte angeht glaub ich fast das die sich aufgrund 
bestimmter Funktionen des Chips sofort wieder ändern. Wenn z.Bl Autogain 
für irgendwas eingestellt ist, dann könnte ich mir vorstellen das in dem 
dafür vorgesehenen Register zum einstellen der Gain im Automatikmodus 
dort der aktuelle, selbst gemessene Wert vom Chip auszulesen ist. Ich 
würde die stark abweichenden Defaults erstmal vergessen...

Also, unser Programm soll erstmal die Schnittstelle initialisieren, also 
TWI Interface aktivieren, XCLK erzeugen und abfragen ob an Slave ID 0x21 
der Wert für Register 0x0A den Wert 0x76 aufweist. In dem Fall haben wir 
wohl eine OV7670 dran ;-)

Ist das getan, sollten wir der Kamera einen Reset per Software 
verpassen, indem wir in Register 0x12 eine 0x80 (0b1000 0000) schreiben. 
Hierbeiminteressiert uns der Rest des Registers nicht, weil es sowieso 
resettet wird ;-)

Dann kämen die Kameraparameter... hier gerne Vorschläge!

von Olli Z. (z80freak)


Lesenswert?

Zuerst noch ein Wort zur Arbeitsweise der Wire-Lib von Arduino 
(https://www.arduino.cc/en/Reference/Wire). Achja, mein Beispielsketch 
oben ist wirklich nur ein Beispiel, quick'n'dirty, also bitte nicht als 
Referenzdesign nehmen ;-)

Einbinden der Lib wie üblich mit:
1
#include "Wire.h"

Initialisiert wird das I2C-Interface vom Atmega als Master (sonst käme 
eine Slave-ID in den Funktionsparameter) so:
1
Wire.begin()

Hierbei werden die Signalleitungen A4 und A5 auf Open-Drain eingestellt 
und mit SDA und SCL des I2C-controllers im Atmega verbunden. Die 
Übertragungsgeschwindigkeit wird (Prozessortaktabhängig durch Teiler) 
auf 100 kHz eingestellt und dann mittels TWEN-Bit aktiviert.

Im Prinzip gibt es auch ein "Wire.end()" was das alles wieder 
zurückdreht. Das werden wir aber wohl nie aufrufen...

Eine Übertragung sieht so aus, das man eine neue Transmission beginnt, 
die zu übertragenden Werte festlegt und startet. Etwas umständlich, aber 
naja. Das sieht dann grundsätzlich immer so aus:
1
Wire.beginTransmission(0x21);
2
...
3
Wire.endTransmission();

Wie wir gelernt haben wird die Slave-ID (hier die 0x21) als 7-Bit Wert 
angegeben. Das Write-Bit setzt die Lib selbstständig. eine 
"Transmission" ist immer eine schreibende Operation.

Nun gibt es bei SCCB den 3-Phase-Write. Dieser besagt das 3 Bytes 
hintereinander zum OV-Chip übertragen werden. Um z.B. den Wert eines 
Registers zu ändern genügt dies:
1
Wire.beginTransmission(0x21);
2
Wire.write(address);
3
Wire.write(value);
4
Wire.endTransmission();

Um den Wert eines Registers auszulesen sendet man nur die 
Register-Adresse und lauscht anschließend am Bus bis Daten kommen:
1
Wire.beginTransmission(0x21);
2
Wire.write(address);
3
Wire.endTransmission();
4
Wire.requestFrom(0x21, 1);
5
while(Wire.available() == 0);
6
while(Wire.available()) {
7
  char c = Wire.read();
8
  ...
9
}

Der erste Teil löst einen 2-Phase-Write aus und schreibt nur Slave-ID 
und Register-Adresse die man lesen möchte. Das nachfolgende 
"requestFrom()" löst einen 2-Phase-Read aus. Dieser übermittelt die 
Slave-ID (erster Parameter) und die Anzahl der zu lesenden Bytes 
(zweiter Parameter im Funktionsaufruf).

Jetzt müssen wir warten bis die Daten vom Slave im Eingangspuffer des 
I2C-Controllers stehen. Hierfür ist die erste Dummy-While-Schleife mit 
"Wire.available() == 0". Ja, das ist unsauber, weil es die 
Programmausführung blockiert und sich der Atmega hier aufhängen würde, 
käme nie eine Antwort vom Slave. In der Realität würde man hier eher 
Events bevorzugen und mittels "Wire.onReceive(handler)" einbauen.

Im Prinzip könnte man sich die nachfolgende While-Schleife um 
"Wire.read()" sparen und durch ein einzelnes read ersetzen, weil wir ja 
genau ein Byte angefragt haben. Das ist hier nur zur Sicherheit, falls 
der Client doch mal mehr oder weniger Bytes sendet als erwartet.

Um anstelle von Bytewerten mit Register- und Wertenamen arbeiten zu 
können, sollten wir das benötigte per "#define" Deklaration bekannt 
geben. Z.B.:
1
#define OV7670_I2C_ID  0x21
2
#define OV7670_PID     0x76
3
#define OV7670_COM7    0x12
4
#define OV7670_RESET   0x80

So, das müsste im groben und ganzen alles sein was wir zur Kommunikation 
mit dem OV-Chip benötigen. Hab ich was vergessen?

von Michael U. (amiga)


Lesenswert?

Hallo,

Olli Z. schrieb:
> Um anstelle von Bytewerten mit Register- und Wertenamen arbeiten zu
> können, sollten wir das benötigte per "#define" Deklaration bekannt
> geben. Z.B.:

und wenn Du jetzt "faul" bist, schau mal in meinen Post oben vom 
23.03.2018 08:58 rein...
https://github.com/ComputerNerd/ov7670-no-ram-arduino-uno
und dann schau dort in die ov7670.h

Selbstverständlich kann man es auch komplett selbst anlegen. Hängt von 
Erfahrung, Zeit und der eigenen Art zu Lernen ab.

Früher (tm) habe ich es öfter bei meinen Bastelein machen müssen, weil 
nichts dafür zu finden war. C64 ASM und Videotextdecoder (SAA5246).
Zum AVR bin ich wegen des MAS3507 (MP3-Decoder) gekommen, das war 
1999...

Zu Deiner Analyse der Wire.h: ich habe sie nur benutzt und auf die 
Funktion vertraut. Einen grund reinzuschauen hatte da konkret nicht.
Das viel Arduino-Libs blokierend sind liegt am Konzept. Natürlich kann 
man ein Event-Handling mit Interruptsteuerug auch mit den 
Arduino-Klassen machen.

PS: vielleicht als I2C-Ergänzung: die Lib muß natürlich auch das 
ACK/NACK erledigen. Bei Wire.requestFrom(0x21, 1); muß ja z.B. nach 
Senden von Adresse usw. ein RepeatStart statt Stop bei I2C geschickt 
werden wenn danach gelesen werden soll.

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Habe jetzt erstmal die Pixel pro Zeile gezählt.
Da bekomme ich immer zwischen 479 und 480 Pixel raus.
vielleicht ist mein senden an den UART zu langsam, sodass ich den ersten 
Pixel verpasse.
1
/*
2
 * main.cpp
3
 *
4
 * Created: 23.07.2017 17:35:15
5
 *  Author: David
6
 */ 
7
8
 #ifndef F_CPU
9
 #define F_CPU 16000000
10
#endif
11
 
12
 #include <avr/io.h>
13
 #include <avr/interrupt.h>
14
15
#include "OV7670.h"
16
#include "OV7670.c"
17
18
#include "UART.h"
19
20
 int main(void)
21
22
 {
23
  sei();
24
  UART0_init();
25
   OV7670_init();
26
27
  int RowCount = 0;
28
  bool VSync_Flag=false;
29
  bool HREF_Flag=false;
30
   while (1)
31
   {
32
    if(((OV_VSYNC_PIN>>OV_VSYNC_PINNR)&(0x01))&&(VSync_Flag==false))
33
    {
34
      VSync_Flag=true;      
35
      UART0_senden_zahl(RowCount);
36
      UART0_senden_Byte(13);
37
      UART0_senden_Byte(10);
38
      RowCount=0;      
39
    }
40
    if(!((OV_VSYNC_PIN>>OV_VSYNC_PINNR)&(0x01))&&(VSync_Flag==true))
41
    {
42
      VSync_Flag=false;
43
      RowCount=0;
44
    }
45
    
46
    if(((OV_HREF_PIN>>OV_HREF_PINNR)&(0x01))&&(HREF_Flag==false))
47
    {
48
      HREF_Flag=true;
49
      RowCount++;
50
    }
51
52
    if(!((OV_HREF_PIN>>OV_HREF_PINNR)&(0x01))&&(HREF_Flag==true))
53
    {
54
      HREF_Flag=false;
55
    }
56
   }
57
   return 0;
58
 }

Zur Vorgehensweise würde ich als erstes Versuchen die Frequenz runter zu 
nehmen, also PCLK zu verringern und zu schauen, ob es Wirkung zeigt.
Verstehe ich es richtig, dass dann auch die V-Sync und HREF Frequenzen 
runter gehen?
Die nötigen Register hierfür wären 0x11 und 0x6B, wobei ich letzteres 
nicht ganz verstehe.

von Olli Z. (z80freak)


Lesenswert?

Die HREF und VSYNC ändern sich bei der fallenden Flanke von PCLK, sind 
also synchron zum Takt.

von Olli Z. (z80freak)


Lesenswert?

Wir sollten kurz das Pinout klären, damit wir auch auf einem Nenner 
bleiben :-) Das Problem beim Nano ist, das nur relativ wenig IO-Pins zur 
Verfügung stehen. Leider haben wir nichtmal einen kompletten 8-Bit Port 
für die Videodaten zur Verfügung. Port D ist mit 2 Bit am UART und fällt 
damit flach, sonst haben wir keine Debug-Schnittstelle. Einzige 
Alternative wäre hier SoftSerial und zwei andere Pins nehmen. Dann 
müsste man den Nano aber wohl besser über ISP flashen.

Habe das jetzt erstmal so vorgesehen:
1
 *  OV7670 Dir  Arduino   Meaning
2
 *  3v3    <-   3V3       Vcc (+3,3V)
3
 *  GND    <-   GND       GND
4
 *  SIOC   <-   A5        SCL (I2C clock) !USE LEVEL-SHIFTER!
5
 *  SIOD   <-   A4        SDA (I2C data)  !USE LEVEL-SHIFTER!
6
 *  XCLK   <-   D2        System-Clock    !USE LEVEL-SHIFTER!
7
 *  RESET  <-   3V3       Reset fixed for testing
8
 *  PWDN   <-   GND       Power-Down fixed for testing
9
 *  HREF   ->   A6        Start of new line in Videoframe
10
 *  VSYNC  ->   A7        Start of new Videoframe
11
 *  PCLK   <-   D3        Pixel clock     !USE LEVEL-SHIFTER!
12
 *  D0     ->   A0        Videodata LSB
13
 *  D1     ->   A1        Videodata
14
 *  D2     ->   A2        Videodata
15
 *  D3     ->   A3        Videodata
16
 *  D4     ->   D4        Videodata
17
 *  D5     ->   D5        Videodata
18
 *  D6     ->   D6        Videodata
19
 *  D7     ->   D7        Videodata MSB

Ich hab das Datenwort in ein low- und high-nibble geteilt und damit es 
einfach einzulesen ist, das lower auf Bit 0-3 von Port C (A0-A3) und das 
higher auf Bit 4-7 von Port D (D4-D7). So müssen wir nur beide Ports 
lesen, maskieren und oder-verknüpfen.

: Bearbeitet durch User
von David D. (saturi)


Lesenswert?

Guten Morgen,
ich verstehe deinen Einwand nicht.
Am Nano sind doch noch mehr Pins nach außen geführt als beim UNO oder?

Ich würde es sehr begrüßen, wenn wir die Pins nehmen, die auch beim UNO 
verfügbar sind, damit man das selbe Programm auf beiden Boards nutzen 
kann:

Habe an deinem Plan mal ein paar Anpassungen vorgenommen:

 *  OV7670 Dir  Arduino   Meaning
 *  3v3    <-   3V3       Vcc (+3,3V)
 *  GND    <-   GND       GND
 *  SIOC   <-   A5        SCL (I2C clock) !USE LEVEL-SHIFTER!
 *  SIOD   <-   A4        SDA (I2C data)  !USE LEVEL-SHIFTER!
 *  XCLK   <-   D2        System-Clock    !USE LEVEL-SHIFTER!
 *  RESET  <-   3V3       Reset fixed for testing
 *  PWDN   <-   GND       Power-Down fixed for testing
 *  HREF   ->   A0        Start of new line in Videoframe
 *  VSYNC  ->   A1        Start of new Videoframe
 *  PCLK   <-   D3        Pixel clock     !USE LEVEL-SHIFTER!
 *  D0     ->   D8        Videodata LSB
 *  D1     ->   D9        Videodata
 *  D2     ->   D10       Videodata
 *  D3     ->   D11       Videodata
 *  D4     ->   D4        Videodata
 *  D5     ->   D5        Videodata
 *  D6     ->   D6        Videodata
 *  D7     ->   D7        Videodata MSB

D8-D11 wäre dann der PORTB 0-3
und D4-D7 wäre PORTD 4-7

Damit verlieren wir nur den MOSI pin. Aber brauchen wir den?
Weiterhin habe ich HREF und VSYNC auf A0 und A1 geholt, weil es A6 und 
A7 auf dem UNO nicht nach außen geführt gibt.
Bist du damit einverstanden oder übersehe ich was?

lg. David

von Michael U. (amiga)


Lesenswert?

Hallo,

A6 und A7 sind beim Mega328 nur ADC-Eingänge, sie haben keine digitalen 
I/O-Funktionen. Insofern ist ohnehin Deine Version sinnvoll.

Könntest Du Deinen Source komplett als Archiv hier anhängen?
Ich würde mit den Stand gern ein wenig "mitspielen", nur aus Neugier und 
weil die Hardware nun sowieso hier rumliegt.

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

kann ich machen, wenn ich zuhause bin. Noch eine Frage: Warum muss PCLK 
über einen Level-Shifter gehen? der Takt wird doch von der Kamera 
vorgegeben oder? den Lese ich doch nur aus?

von Michael U. (amiga)


Lesenswert?

Hallo,

Danke, hat keine Eile, ich spiele noch mit meiner alten DC3840 am ESP32 
weiter, die macht auch noch nicht, was soll.

Bei PCLK stimme ich Dir nach kurem Blick ins Datenblatt der OV7670 zu, 
ist Ausgang, braucht also keinen Levelshifter.

Gruß aus Berlin
Michael

von Olli Z. (z80freak)


Lesenswert?

David D. schrieb:
> Am Nano sind doch noch mehr Pins nach außen geführt als beim UNO oder?
Du hast recht!

Das mit dem PCLK hatte ich falsch verstanden und habs unten im Pinout 
korrigiert. Ist aber auch logisch, auf die "Frequenz" der Daten haben 
wir ja keinen Einfluss. Evtl. über die Auflösung. Leider kann man die 
beim OV7670 nicht frei definieren, sondern nur zwischen VGA, QVGA und 
noch was exotischem wählen. Ich glaub das kleinste ist QVGA mit 320x200.

Mit Deinem Pinout habe ich folgendes Problem: Zur Erzeugung des XCLK 
habe ich PWM verwendet. Das geht bis max. 8MHz was aber funktioniert. Du 
wolltest das per FUSE machen, was man in der Arduino-IDE aber nicht so 
ohne weiteres einstellen kann. Wenn wir bei PWM bleiben wollen, dann 
müssen wir nur D2 und D3 vertauschen und schon gehts :-) Man könnte auch 
den PCLK auf A2 legen, dann wär das mit den anderen Signalen in einem 
Register, was vielleicht auch nicht blöd ist.

Hier mein Korrekturvorschlag:
1
  *  OV7670 Dir  Arduino   Meaning
2
  *  3v3    <-   3V3       Vcc (+3,3V)
3
  *  GND    <-   GND       GND
4
  *  SIOC   <-   A5        SCL (I2C clock) !USE LEVEL-SHIFTER!
5
  *  SIOD   <-   A4        SDA (I2C data)  !USE LEVEL-SHIFTER!
6
  *  XCLK   <-   D3        System-Clock    !USE LEVEL-SHIFTER!
7
  *  RESET  <-   3V3       Reset fixed for testing
8
  *  PWDN   <-   GND       Power-Down fixed for testing
9
  *  HREF   ->   A0        Start of new line in Videoframe
10
  *  VSYNC  ->   A1        Start of new Videoframe
11
  *  PCLK   ->   A2        Pixel clock
12
  *  D0     ->   D8        Videodata LSB
13
  *  D1     ->   D9        Videodata
14
  *  D2     ->   D10       Videodata
15
  *  D3     ->   D11       Videodata
16
  *  D4     ->   D4        Videodata
17
  *  D5     ->   D5        Videodata
18
  *  D6     ->   D6        Videodata
19
  *  D7     ->   D7        Videodata MSB


> D8-D11 wäre dann der PORTB 0-3
> und D4-D7 wäre PORTD 4-7
Um ein Datenbyte zu lesen wär dann nur sowas nötig:
1
c = (PORTD & 0b11110000) | (PORTB & 0b00001111);

> Weiterhin habe ich HREF und VSYNC auf A0 und A1 geholt, weil es A6 und
> A7 auf dem UNO nicht nach außen geführt gibt.
Stimmt! Hab ich komplett übersehen, bzw. nicht quer geprüft. A6+A7 sind 
Analog-Only und fallen eh flach.

> Bist du damit einverstanden oder übersehe ich was?
Ich glaub wir habens fast ;-)

von Michael U. (amiga)


Lesenswert?

Hallo,

warum eigentlich PWM und nicht CTC-Mode? Auch da gehen zwar nur 8MHz bei 
16MHz Clock aber der wurde ja dafür eingebaut.
Habe jetzt aber nicht nach den Ausgabepins der Timer geschaut.

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Olli Z. schrieb:

> Mit Deinem Pinout habe ich folgendes Problem: Zur Erzeugung des XCLK
> habe ich PWM verwendet. Das geht bis max. 8MHz was aber funktioniert. Du
> wolltest das per FUSE machen, was man in der Arduino-IDE aber nicht so
> ohne weiteres einstellen kann. Wenn wir bei PWM bleiben wollen, dann
> müssen wir nur D2 und D3 vertauschen und schon gehts :-)
Jap sollte kein Problem machen, dann machen wir das so. Das mit der Fuse 
geht nur auf D8 also (PB0). Aber das hatte ich eh nur testweise über 
einen zweiten Controller gemacht. Also können wir da deinen Vorschlag 
übernehmen.

>Man könnte auch
> den PCLK auf A2 legen, dann wär das mit den anderen Signalen in einem
> Register, was vielleicht auch nicht blöd ist.

Der Vorteil an D3 ist, dass der Pin Interrupt fähig ist. Wenn wir es 
also in Zukunft schaffen eventuell die Bilder noch irgendwie zu 
verarbeiten, wäre der Interrupt gut, um zwischen drin nichts zu 
verpassen.
Das alle Signale auf einem Register liegen ist ja nicht unbedingt 
notwendig.
Da erscheinen mir die Vorzüge des Interrupts lukrativer und wir belegen 
nicht unnötiger Weise einen analogen Eingang.

Hier ein weiterer Korrekturvorschlag: ;-)
1
   *  OV7670 Dir  Arduino   Meaning
2
   *  3v3    <-   3V3       Vcc (+3,3V)
3
   *  GND    <-   GND       GND
4
   *  SIOC   <-   A5        SCL (I2C clock) !USE LEVEL-SHIFTER!
5
   *  SIOD   <-   A4        SDA (I2C data)  !USE LEVEL-SHIFTER!
6
   *  XCLK   <-   D3        System-Clock    !USE LEVEL-SHIFTER!
7
   *  RESET  <-   3V3       Reset fixed for testing
8
   *  PWDN   <-   GND       Power-Down fixed for testing
9
   *  HREF   ->   A0        Start of new line in Videoframe
10
   *  VSYNC  ->   A1        Start of new Videoframe
11
   *  PCLK   ->   D3        Pixel clock
12
   *  D0     ->   D8        Videodata LSB
13
   *  D1     ->   D9        Videodata
14
   *  D2     ->   D10       Videodata
15
   *  D3     ->   D11       Videodata
16
   *  D4     ->   D4        Videodata
17
   *  D5     ->   D5        Videodata
18
   *  D6     ->   D6        Videodata
19
   *  D7     ->   D7        Videodata MSB


>> D8-D11 wäre dann der PORTB 0-3
>> und D4-D7 wäre PORTD 4-7
> Um ein Datenbyte zu lesen wär dann nur sowas nötig:
1
> c = (PORTD & 0b11110000) | (PORTB & 0b00001111);
2
>
richtig, das sollte mit dem Maskieren eigentlich recht einfach gehen.

>> Weiterhin habe ich HREF und VSYNC auf A0 und A1 geholt, weil es A6 und
>> A7 auf dem UNO nicht nach außen geführt gibt.
> Stimmt! Hab ich komplett übersehen, bzw. nicht quer geprüft. A6+A7 sind
> Analog-Only und fallen eh flach.

Jetzt sind wir hoffentlich schon fast d'accord :-)

@Michael
Ich glaube, dass du da recht hast, aber es war bisher ja nur ein erster 
Gedanke und Entwurf von Olli. Aber ich habe es mal in der Liste der zu 
behandelnden Punkte geschrieben.

von David D. (saturi)


Lesenswert?

Ich habe jetzt mal einen Test zum Schreiben von einem Register gemacht.
Ich habe in das CLKRC-Register (Adresse:0x11) das Bit 7 auf 0 gesetzt 
und die Bits 0-4 auf 1 um einen Prescaler von 16 zu erhalten.

Damit ist es mir dann tatsächlich gelungen die PCLK von 16Mhz auf 500KHz 
zu drosseln. Erfreulich war, dass auch die Frequenz von HREF linear 
gesunken ist.

bei 16 MHz PCLK lag die Frequenz von HREF bei 10,2KHz.
bei 500 KHz PCLK lag sie nur noch bei 322 Hz.

Damit könnten wir es sogar schaffen, die Bild Daten testweise mal über 
den Serial Port an den PC zu übertragen. Oder verkalkulier ich mich da 
grade?

von Andreas S. (igel1)


Lesenswert?

Hi Leute,

ich habe vor ein paar Monaten die OV7670 an meinem STM32 ARM ans Laufen 
gebracht: Beitrag "Camera OV7670: Register Settings für Farbbilder gesucht"

Dasselbe auf dem ATmega stelle ich mir sehr herausfordernd vor,...

Zuerst wollte ich mir ebenfalls alles selber erschließen, aber die Doku 
zu dem Teil ist so schlecht, dass man wirklich beliebig viel Zeit 
vergeuden kann, bis alles richtig läuft. Diese Zeit war mir dann 
irgendwann zu schade und ich habe bei anderen "abgespickt".

Ich würde Euch nun natürlich gerne mit ein paar Tipps versorgen, habe 
dummerweise aktuell aber Null Zeit.

Daher hier nur auf die Schnelle meine Quellen, die mir seinerzeit sehr 
geholfen hatten:

Zum Allgemeinen Verständnis:
http://embeddedprogrammer.blogspot.de/2012/07/hacking-ov7670-camera-module-sccb-cheat.html
http://embeddedprogrammer.blogspot.de/2013/01/demo-stm32f4-ov7670-qserialterm.html

SCCB:
https://e2e.ti.com/support/embedded/linux/f/354/p/171390/862562#862562
https://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/99/t/120548
http://embeddedprogrammer.blogspot.de/2012/07/hacking-ov7670-camera-module-sccb-cheat.html
https://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/99/p/6092/22820#22820
http://forum.arduino.cc/index.php?topic=195642.msg1446591#msg1446591
https://electronics.stackexchange.com/questions/259119/ov7670-omnivision-sccb-read-sequence-issue

Die functional specification:
http://www4.cs.umanitoba.ca/~jacky/Teaching/Courses/74.795-LocalVision/ReadingList/ov-sccb.pdf

Der Implementation Guide:
http://www.haoyuelectronics.com/Attachment/OV7670%20+%20AL422B%28FIFO%29%20Camera%20Module%28V2.0%29/OV7670%20Implementation%20Guide%20%28V1.0%29.pdf

Wie ich lese, kämpft Ihr aktuell noch mit dem SCCB-Protokoll - da ist 
die Doku sogar noch halbwegs verständlich und vollständig. Spätestens 
wenn Ihr Euch mit den dutzenden Registern und ihren teils 
undokumentierten Werten und Bedeutungen herumschlagt, werdet Ihr evtl. 
auch zu meiner Erkenntnis kommen: die Doku ist Schrott und selber 
ausprobieren macht kaum Sinn, wenn's andere vor einem schon durch 
wochenlanges Herumprobieren herausbekommen haben. Selbst dann ist der 
Weg noch hinreichend steinig ...
Good luck Euch!

Viele Grüße

Igel1

von Olli Z. (z80freak)


Lesenswert?

David D. schrieb:
> Der Vorteil an D3 ist, dass der Pin Interrupt fähig ist. Wenn wir es
Gutes Argument. Das wäre bei der Verarbeitung der PCLK sicher hilfreich. 
Sehe grad das ich D3 in meinem Pinout zweimal geschrieben hab.

Aber wo wir grad bei Interrupts sind, viellecht setzen wir erstmal 
nochmal da an, bevor wir das Pinout festzurren.

Wir müssen ja PCLK (24 MHz laut Datenblatt), HSYNC (ca. 32 kHz) und 
VSYNC (50-60 Hz) verarbeiten. Ich würde vorschlagen wir tasten VSYNC ab 
bis wir einen Bildstart erkennen und setzen ein Flag. Bei jedem HSYNC 
müssen wir eine Bildzeile einlesen. Dafür brauchen wir soviel Power vom 
kleinen Atmega das wir vermutlich zu nichts anderem kommen werden?! Das 
wäre doch was für den Interrupt. Den PCLK können wir für den Interrupt 
eh nutzen, da er viel zu schnell ist.

Bitte Vorschläge hierzu :-)


P.S. An alle die ab jetzt erst mitlesen die Info: Wir wollen keine 
fertigen Lösungen sondern unsere eigene erarbeiten. Warum? Um genau auf 
all die vielen kleinen Details zu kommen die es bei einem solchen Design 
zu beachten gilt :-)

: Bearbeitet durch User
von Olli Z. (z80freak)


Lesenswert?

Michael U. schrieb:
> warum eigentlich PWM und nicht CTC-Mode? Auch da gehen zwar nur 8MHz bei
> 16MHz Clock aber der wurde ja dafür eingebaut.
> Habe jetzt aber nicht nach den Ausgabepins der Timer geschaut.

Ich muss gestehen das ich da nicht somtief drin bin wie Du. Könntest Du 
mir das Konzept kurz erläutern?

von Olli Z. (z80freak)


Lesenswert?

David D. schrieb:
> Ich habe jetzt mal einen Test zum Schreiben von einem Register gemacht.
> Ich habe in das CLKRC-Register (Adresse:0x11) das Bit 7 auf 0 gesetzt
> und die Bits 0-4 auf 1 um einen Prescaler von 16 zu erhalten.

Dein Forscherdrang in allen Ehren, aber ich glaube wir müssen uns 
darüber verständigen welche Ziele wir in welcher Reihenfolge verfolgen 
und konsequent durchhalten. Sonst glaube ich, verzetteln wir uns ganz 
schnell und jeder will grad was anderes ;-) Nicht böse gemeint, ich will 
das hier nur zusammenhalten... aber es ist Dein Thread!

Eigentlich haben wir Schritt 1 doch gut geschafft, das Kommandointerface 
zur Kamera. Nun waren wir am Dateninterface. Hier sollten wir doch 
zunächst überlegen wie und wo wir die erhaltenen Bilddaten 
zwischenspeichern und zur Ansicht an den PC übertragen. Selbst in 
kleinster Auflösung mit 320x200 Bildpunkten und im YUV-Farbmodell 
benötigten wir bei 25 Bildern/s einen Datendurchsatz von ca. 4,6 MB/s. 
Standardmäßig haben wir nur die UART-Übertragung zum PC, also 
Echtzeitvideo dürfte da schonmal ausscheiden.

Das Problem ist, das wir im Arduino nicht genügend Speicher für ein 
ganzes Bild haben. Selbst mit 8-Bit s/w würden wir schon 512kb 
benötigen. Wir müssen also beim einlesen in Echtzeit zum PC streamen. Da 
hab ich noch keine Ahnung wie wir das hinbekommen...

von Michael U. (amiga)


Lesenswert?

Hallo,

@Andreas S. (igel1): das waren am Anfang des threads auch meine 
Gedanken, ich habe mal kurz mit der OV7670 am ESP32 rumgespielt.

Olli Z. schrieb:
> P.S. An alle die ab jetzt erst mitlesen die Info: Wir wollen keine
> fertigen Lösungen sondern unsere eigene erarbeiten. Warum? Um genau auf
> all die vielen kleinen Details zu kommen die es bei einem solchen Design
> zu beachten gilt :-)

Ich finde das sehr gut, findet man kaum noch, so habe ich mit µC mal 
angefangen. Keine Ahnung davon, 1979 einen MC6800 (8Bit), 512Byte Ram, 
einen MC6820 (2x 8Bit I/O) bekommen. Befehlssatz und Beschaltung aus 
einem Motorola-Handbuch im Lesesaal das Staatsbibliothek der DDR 
abgemalt...
Das ging auch für Normalsterbliche ohne Probleme, für Kopien hätte man 
aber Student einer passenden Fachrichtung sein und für Ausleihen einen 
Schrieb der Uni haben müssen. Der Rest war DDR-TTL, 7-Segmantanzeigen 
usw. gab es durchaus.

Ich habe noch ein wenig im Datenblatt der OV7670 gekramt. Der Ansatz 
wäre auch meiner. Mit PCLK auf sinvolle langsame Werte runter. Ich muß 
mir die Timingdiagramme noch genauer anschauen mal rechnen wieviel Daten 
bei sinnvoll kleiner Auflösung und Format eine Zeile sind. letztlich 
entscheide das und der Ram des Mega328 wie man es anpackt. Mit FTDI-USB 
habe ich 500kBaud beim Übertragen genutzt, da spielte es aber keine 
Rolle, wie langen der AVR zum Bereitsrtellen der Daten brauchte, habe 
ich von einem externen Ram per Portzugriffen eingesammelt. War in ASM, 
muß ich mal schauen, da habe ich die Zykluszeiten in die Kommentare 
geschrieben.

Zum Test müßte man wenigstens eine Zeile ins Ram bekommen und dann zum 
PC. Ansonsten kann man vermutlich auf einen Trick von U.Radig mit der 
DV3840 von damals zurückgreifen: eine Zeile lesen und rüberschicken, 
dann die das Auskesen der Kamera neu starten, die Zeilen mitzählen bis 
zur nächsten und die holen usw. Könnte bei der OV7670 auch gehen.
Interrupt würde bei mir höchstens den Anfang  festlegen (VSYNC), 
Einlesen mit hardwarenaher Schleife, alles andere kosten unnütz Zeit 
(INT-Aufruf, Register retten usw.). Der AVR kann in dieser Zeit sowieso 
nicht sinvolles anderes machen, also sollte er es auch nicht.

Olli Z. schrieb:
> Ich muss gestehen das ich da nicht somtief drin bin wie Du. Könntest Du
> mir das Konzept kurz erläutern?

Welcher Timer ist denn dafür genutzt? Bei Timer 1 wäre es MODE2, 
PreScaler auf max. internem Takt, OCR0A auf 1 und der zugehörige 
Zugehörige Ausgang liefert ein 50:50 Rechteck ab.
Letztlich dürfte es egal sein, ist nur ein Hinweis auf die vorhandene 
Funktion im AVR.

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Andreas S. schrieb:


> Daher hier nur auf die Schnelle meine Quellen, die mir seinerzeit sehr
> geholfen hatten:

Vielen Dank für die Links, die können wir sicher noch gut brauchen.
Wir versuchen einfach mal unser bestes :)

Olli Z. schrieb:
>Eigentlich haben wir Schritt 1 doch gut geschafft, das Kommandointerface
>zur Kamera. Nun waren wir am Dateninterface. Hier sollten wir doch
>zunächst überlegen wie und wo wir die erhaltenen Bilddaten
>zwischenspeichern und zur Ansicht an den PC übertragen. Selbst in
>kleinster Auflösung mit 320x200 Bildpunkten und im YUV-Farbmodell
>benötigten wir bei 25 Bildern/s einen Datendurchsatz von ca. 4,6 MB/s.
>Standardmäßig haben wir nur die UART-Übertragung zum PC, also
>Echtzeitvideo dürfte da schonmal ausscheiden.
>
>Das Problem ist, das wir im Arduino nicht genügend Speicher für ein
>ganzes Bild haben. Selbst mit 8-Bit s/w würden wir schon 512kb
>benötigen. Wir müssen also beim einlesen in Echtzeit zum PC streamen. Da
>hab ich noch keine Ahnung wie wir das hinbekommen...

Das sehe ich auch so. Das SCCB läuft ja schon mal hervorragend.
Ich finde es gut, dass du mich bremst um uns alle in eine Richtung zu 
lenken. Ich bin mir nicht sicher, ob du in meinem Beitrag gelesen hast, 
dass ich die PCLK-Frequenz senken konnte. mit allen Prescalern komme ich 
dann auf 256KHz von PCLK was uns deutlich mehr Zeit verschafft.

Was jetzt meine Gedanken-Gang wäre:
zunächst einmal mit VSync ein neues Bild detektieren
Dann die Anzahl der Zeilen zählen, bis zum nächsten VSync.
(Das bekomme ich hin mit dem zuverlässigen Wert von 480)

Jetzt wäre der nächste Punkt in einer Zeile die Pixel zu zählen. Den 
Counter würde ich mit jeder fallenden Flanke von HREF wieder 
zurücksetzten. Hier müsste ich ja (im RGB Mode) für jedes Pixel zwei 
Bytes bekommen, sprich zwei PCLK takte. (Ich beziehe mich grade auf 
Figure 11 im Datenblatt) Sprich ich müsste 640 * 2 PCLK = 1280 
PCLK-Counter pro Zeile bekommen. Hier hänge ich gerade, weil mein 
Counter warum auch immer extrem Schwankt zwischen 30 und 60 (Hier 
scheine ich vielleicht noch nicht alles verstanden zu haben.

Mein Weitere Plan würde dann wie folgt aussehen, einfach ein Pixel 
relativ in der Mitte auszulesen und die Farbdaten in einer Variable 
festzuhalten. Dann zu schauen, ob die Farbe passt, oder erstmal ob 
Veränderungen auftreten, wenn ich bspw. eine weiße Fläche oder eine 
schwarze vor der Linse habe.

Erst wenn das Funktioniert hätte ich mir Gedanken darüber gemacht, wie 
ich ganze Bilder zusammensetzte oder Speicher oder übertrage.

Ich lasse mich aber auch gerne eines Besseren belehren :)

@Michael 1979 war mein Vater 17 und ich noch längst nicht in Planung :D
Die Idee mit dem Zeilenweisen Aufbau finde ich gar nicht mal so übel, 
wenn wir von einer statischen Aufnahme reden.

lg. David

von Olli Z. (z80freak)


Lesenswert?

Michael U. schrieb:
> Ich habe noch ein wenig im Datenblatt der OV7670 gekramt. Der Ansatz
> wäre auch meiner. Mit PCLK auf sinvolle langsame Werte runter.

100%ige Zustimmung. Evtl. kommen wir da dann an den Punkt wo es 
sinnvoller ist den OV7670+FIFO zu nutzen... Da gäbs vielleicht nur noch 
die Option eine SD-Card als Zwischenspeicher zu verwenden. Dafür 
bräuchten wir aber die SPI-Pins. Mit einem Puffer könnte man ganz 
gemütlich nach dem "Schnappschuß" übermitteln.
Dieses Problem müssten aber auch die STM32 haben, denn ein, zwei 
Megabyte RAM haben die auch nicht ;-)

> entscheide das und der Ram des Mega328 wie man es anpackt. Mit FTDI-USB
> habe ich 500kBaud beim Übertragen genutzt, da spielte es aber keine

Ich verwende nen Nano-Clone und der hat leider keinen Original FTDI 
drin. Daher könnte es sein das ich auf die 115kbaud beschränkt bin. 
Damit wäre ich bau lausigen 14 kbyte/s. Das ist noch ziehmlich weit weg 
von dem was wir bräuchten fürchte ich.

> Zum Test müßte man wenigstens eine Zeile ins Ram bekommen und dann zum
Damit fangen wir doch in jedem Fall an, oder? Auf VSYNC warten und die 
ersten 320 (oder 640) Pixel lesen und übertragen.

> PC. Ansonsten kann man vermutlich auf einen Trick von U.Radig mit der
> DV3840 von damals zurückgreifen: eine Zeile lesen und rüberschicken,
> dann die das Auskesen der Kamera neu starten, die Zeilen mitzählen bis
> zur nächsten und die holen usw. Könnte bei der OV7670 auch gehen.
Eine coole Idee :-) An sowas ähnliches hab ich auch schon gedacht, nur 
mit Halbbildern, also nur jede 2. Zeile übermitteln oder so. Wenn man 
immer ganze Zeilen überträgt spielt auch das Subsampling keine Rolle.

In dieser Richtung könnte man auch horizontal "sparen", also auf Pixel 
innerhalb einer Zeile verzichten. Zumindest im YUV-Farbraum sollte man 
dann immer zwei aufeinanderfolgende Pixel erhalten, also 2 übertragen, 2 
auslassen. Am Anfang wäre RGB zwar einfacher im Bytehandling, aber ich 
würde stand jetzt eigentlich beim YUV 4:2:2 bleiben wollen.

> Interrupt würde bei mir höchstens den Anfang  festlegen (VSYNC),
Der kommt ja so selten, da sollte man doch drauf warten können, nicht? 
Wir können ja immer nur dann ein Bild einlesen wenn wir dazu bereit 
sind. In dieser Phase würde ich einfach aufs nächste VSYNC warten und 
los gehts...

> Einlesen mit hardwarenaher Schleife, alles andere kosten unnütz Zeit
> (INT-Aufruf, Register retten usw.). Der AVR kann in dieser Zeit sowieso
> nicht sinvolles anderes machen, also sollte er es auch nicht.
Heißt das, wir sind einer Meinung?

> Olli Z. schrieb:
>> Ich muss gestehen das ich da nicht somtief drin bin wie Du. Könntest Du
>> mir das Konzept kurz erläutern?
> Welcher Timer ist denn dafür genutzt? Bei Timer 1 wäre es MODE2,
> PreScaler auf max. internem Takt, OCR0A auf 1 und der zugehörige
> Zugehörige Ausgang liefert ein 50:50 Rechteck ab.

Verstehe nur Berlin Hauptbahnhof ;-) Daher meine war meine Bitte: Wie 
hängt das alles zusammen? Timer, Modes, Pins, ... ich blicks noch nicht.

Gruß,

Olli

P.S.: Ich finde unsere aktuelle Konstellation (David und Du) wirklich 
klasse! Vor allem weil wir uns, etwas untypisch für dieses Forum, weder 
anmaulen noch sonst irgendwie im Ton vergreifen. Zudem können wir uns 
immer wieder auf einen Nenner bringen. Ich bin echt begeistert und es 
macht richtig Spaß!!! :-)

von David D. (saturi)


Angehängte Dateien:

Lesenswert?

Zum CTC Mode:
Atmega328P Datenblatt Seite 100. (Der Anfangsausschnitt im Anhang)

Im Prinzip wird damit das gleiche erreicht wie mit dem PWM Signal von 
dir.
Nur muss man einfach weniger Einstellungen treffen.
Im Prinzip gibst du einfach nur den Timer Wert vor bis zu dem gezählt 
werden soll. Wird der erreicht, wird ein Pin (OC0A beim Atmega328P ist 
das PD6)getoggelt und der Timer zurückgesetzt.
Somit kannst du relativ einfach ein Rechtecksignal erzeugen.

Was sagst du zu meiner Vorgehensweise?

lg.
David

PS: wie kann ich ein falsches Bildformat wieder löschen?

: Bearbeitet durch User
von Olli Z. (z80freak)


Lesenswert?

David D. schrieb:
> Andreas S. schrieb:
Ich lese und beantworte immer einen Post nach dem anderen. Manches 
überschneidet sich... auch ein Grund warum ich versuche möglichst immer 
nur an einem Punkt gleichzeit zu "arbeiten".

>> Daher hier nur auf die Schnelle meine Quellen, die mir seinerzeit sehr
>> geholfen hatten:
> Vielen Dank für die Links, die können wir sicher noch gut brauchen.
> Wir versuchen einfach mal unser bestes :)
Ja, sicher sehr hilfreich. Ich denke auch das wir einiges von unseren 
eigenen Erkenntnissen im Dokuwiki hinterlegen sollten/werden, auch für 
uns selbst. Hier nochmal mein Vorschlag an Dich und Michael mir mal ne 
PN mit eurer Mail zukommen zu lassen, dann lege ich für Euch einen 
Account an und ihr könnt dort mit editieren.

> Ich finde es gut, dass du mich bremst um uns alle in eine Richtung zu
> lenken. Ich bin mir nicht sicher, ob du in meinem Beitrag gelesen hast,
Danke für die "Blumen", ich verweise nur auf den letzten Absatz meines 
vorherigen Posts :-)

> dass ich die PCLK-Frequenz senken konnte. mit allen Prescalern komme ich
> dann auf 256KHz von PCLK was uns deutlich mehr Zeit verschafft.
Im Prinzip arbeiten wir ja auch an dieser Stelle. Momentan haben wir 
einen Strauß von Möglichkeiten. PCLK wäre einer. Ich bin mir mit der 
aktuellen Erfahrung nur nicht sicher ob das verringern der PCLK so ganz 
ohne Nebenwirkungen ist. Ich hätte gedacht wenn wir versuchen die 
Auflösung, Bildfrequenz, Skalierung (und was weiß ich was die Kamera 
noch alles kann) zu verringern, das sich die PCLK automatisch 
verkleinert. Wollen wir in diese Richtung mal schauen?

> Was jetzt meine Gedanken-Gang wäre:
> zunächst einmal mit VSync ein neues Bild detektieren
> Dann die Anzahl der Zeilen zählen, bis zum nächsten VSync.
> (Das bekomme ich hin mit dem zuverlässigen Wert von 480)

Ich hätte da einen Vorschlag wie wir mitbekommen können ob der Arduino 
schon überlastet ist: Wir arbeiten zeilenbasierend, sprich ein HSYNC 
löst via INT die Verarbeitung einer Bildzeile aus. Darin enthalten ist 
das auslesen der Pixelwerte, synchron zu PCLK, ggf. der Verarbeitung 
dieser (Farbraumumwandlung, Skipping, oder was weiss ich...) bis hin zu 
Übermittlung an den PC. Wenn diese Schleife komplett durchläuft ohne das 
vorher schon wieder ein HSYNC-INT ausgelöst wird, dann ist alles gut und 
wir könnten die Werte "hochdrehen" oder hätten einfach noch Luft für 
Bildbearbeitungsfunktionen. Sollten wir jedoch ein Problem erkennen, 
könnte man das Programm anhalten und eine LED blinken oder leuchten 
lassen.

> zurücksetzten. Hier müsste ich ja (im RGB Mode) für jedes Pixel zwei
> Bytes bekommen, sprich zwei PCLK takte. (Ich beziehe mich grade auf
Bei RGB sollten es 3 Byte sein, ein 8-Bit Wert für Rot, einer für Grün 
und einer Blau. 2 Byte sind es im YUV-Verfahren.

> Figure 11 im Datenblatt) Sprich ich müsste 640 * 2 PCLK = 1280
> PCLK-Counter pro Zeile bekommen. Hier hänge ich gerade, weil mein
> Counter warum auch immer extrem Schwankt zwischen 30 und 60 (Hier
> scheine ich vielleicht noch nicht alles verstanden zu haben.
Wie gesagt, ich würde noch etwas anders rangehen als sich auf das reine 
Pixelzählen zu beschränken. Es geht ja darum ein Bild zu übertragen. 
Also erstmal überlegen was man alles machen kann um die Datenflut vom 
OV-Chip zum Arduino so weit wie möglich einzudämmen.

Wir sollten vielleicht damit anfangen das Bild nur S/W zu übertragen. 
Das ist bei Daten im YUV Farbraum recht simpel, man benötigt einfach nur 
das Y-Byte (Luminanz). Das verringert die zu übertragenden Daten 
erheblich.

> Ich lasse mich aber auch gerne eines Besseren belehren :)
Deine Ideen sind nicht verkehrt, halt alles nur eine Frage worauf wir 
uns einigen. Wie siehst Du das Michael? Ich schlage folgendes vor:

1. Möglichkeiten zur Verringerung der Auflösung/Farbe/PCLK finden 
(Datenblatt und Links wühlen)
2. Auf VSYNC warten, Interrupts aktivieren und beim nächsten HSYNC-INT 
versuchen sämtliche Daten vom Chip einzulesen.
3. Kollisionserkennung implementieren (kommt während eines INT ein 
weiterer)
4. Datenübertragung zum PC (hier brauchst irgend ein "Frontend" auf dem 
PC welches die Daten über Serial entgegen nimmt und in eine (Bild)daten 
schreiben kann. Entweder was fertiges, oder ein PHP oder Python Skript?

> @Michael 1979 war mein Vater 17 und ich noch längst nicht in Planung :D
Ups, dann bin ich ja quasi der "Opa" hier unter Euch Jungfüchsen ;-))

Olli

von David D. (saturi)


Lesenswert?

Olli Z. schrieb:

> Bei RGB sollten es 3 Byte sein, ein 8-Bit Wert für Rot, einer für Grün
> und einer Blau. 2 Byte sind es im YUV-Verfahren.
Ich meinte auch RGB555

> Wir sollten vielleicht damit anfangen das Bild nur S/W zu übertragen.
> Das ist bei Daten im YUV Farbraum recht simpel, man benötigt einfach nur
> das Y-Byte (Luminanz). Das verringert die zu übertragenden Daten
> erheblich.
Das klingt gut. Mit dem Format kenne ich mich leider überhaupt nicht aus 
und habe es deshalb erstmal gekonnt ignoriert. Ich werde diese 
Wissenslücke dann jetzt erstmal füllen.

> 1. Möglichkeiten zur Verringerung der Auflösung/Farbe/PCLK finden
> (Datenblatt und Links wühlen)
Ich weiß nicht ob es uns was bringt die Auflösung runter zu schrauben. 
Das hilft uns vielleicht bei der Übertragung zum PC aber ich denke 
nicht, dass sich das auf die PCLK Frequenz auswirkt sondern einfach die 
Frames/sec hochgehen werden.

> 2. Auf VSYNC warten, Interrupts aktivieren und beim nächsten HSYNC-INT
> versuchen sämtliche Daten vom Chip einzulesen.
Jap können wir versuchen
> 3. Kollisionserkennung implementieren (kommt während eines INT ein
> weiterer)

> 4. Datenübertragung zum PC (hier brauchst irgend ein "Frontend" auf dem
> PC welches die Daten über Serial entgegen nimmt und in eine (Bild)daten
> schreiben kann. Entweder was fertiges, oder ein PHP oder Python Skript?
Ich habe am Samstag eine sehr lange Autofahrt vor mir, da werde ich mal 
im Visual Studio was mit c# rumbasteln und uns ein kleines Programmchen 
entwerfen, dass das vielleicht kann. (eventuell schaff ich es ja :) )

>> @Michael 1979 war mein Vater 17 und ich noch längst nicht in Planung :D
> Ups, dann bin ich ja quasi der "Opa" hier unter Euch Jungfüchsen ;-))
Ist doch Toll, dass wir so ein bunter Haufen sind und uns ergänzen 
können.

von Andreas S. (igel1)


Lesenswert?

Olli Z. schrieb:
> P.S.: Ich finde unsere aktuelle Konstellation (David und Du) wirklich
> klasse! Vor allem weil wir uns, etwas untypisch für dieses Forum, weder
> anmaulen noch sonst irgendwie im Ton vergreifen. Zudem können wir uns
> immer wieder auf einen Nenner bringen. Ich bin echt begeistert und es
> macht richtig Spaß!!! :-)

Das kann ich nur unterstreichen. Als Gelegenheits-Mitleser möchte ich 
Euch allein dafür ein Kompliment machen: es ist sehr angenehm, diesen 
Thread zu lesen. Hier gibt's ein Ringen um die Sache und einen 
respektvollen Umgang miteinander - so macht Elektronik (und überhaupt 
das Leben im Ganzen) Spaß. Weiter so!

Ich würde ja soooo gerne mitmachen, aber ich habe vermutlich erst in 
einigen Wochen wieder Zeit fürs Hobby. Ich kann Euch also nur ein paar 
Tipps aus meinem wochenlangen Kampf mit dem OV7670 geben - so lange 
hat's gebraucht, bis es halbwegs an meinem STM32 lief (dummerweise habe 
ich auch schon vieles wieder vergessen).

Tipp Nr.1: alle Gedanken, die Ihr Euch gerade macht (vom Interrupt, bis 
zu den anzusprechenden SCCB-Adressen), hatten auch andere, die sich mit 
dem OV7670 beschäftigt haben. Und diese anderen haben ebenfalls Wochen 
und Monate investiert.

Ich habe irgendwann für mich beschlossen, dass ich meinen Stolz, alles 
selber herauszufinden, über Bord werfe und von den Erfahrungen dieser 
anderen profitieren will - zumindest um die Doku-Defizite damit 
aufzufüllen. Daher mein Tipp: lest viele Threads und Foren-Beiträge von 
Leuten, die die Tortour schon hinter sich haben und spart Euch Eure 
Energie für's Wesentliche auf. Fehlende Hersteller-Doku per 
Try-and-Error aufzufüllen wird Euch sonst zermahlen (so meine Weissagung 
- basierend auf meinen Erfahrungen)

> 100%ige Zustimmung. Evtl. kommen wir da dann an den Punkt wo es
> sinnvoller ist den OV7670+FIFO zu nutzen...

Ja - viele andere haben sich das ebenfalls überlegt.
Meiner Meinung nach macht nur die OV7670+FIFO-Variante für einen Aufbau 
mit AVR Sinn. Alles andere überfordert den AVR oder es ist schlicht und 
einfach heillose Quälerei.

> Da gäbs vielleicht nur noch
> die Option eine SD-Card als Zwischenspeicher zu verwenden. Dafür
> bräuchten wir aber die SPI-Pins. Mit einem Puffer könnte man ganz
> gemütlich nach dem "Schnappschuß" übermitteln.
> Dieses Problem müssten aber auch die STM32 haben, denn ein, zwei
> Megabyte RAM haben die auch nicht ;-)

Richtig, daher bin ich in meinem aktuellen Projektstand bislang auch 
nicht über QVGA (320x240 Punkte) hinausgekommen.

Allerdings kann so ein STM32 trotz ca. 512k RAM auch größere Bilder 
speichern. Das hatte ich mir so überlegt:

- ich lassen den STM32 die Zeilen per DMA (bzw. DCMI) in einen 
Ringbuffer einlesen

- während also vorne eingelesen wird (DMA bzw. DCMI belasten ja die CPU 
nicht), kann ich hinten im Ringbuffer auslesen und jeweils N-Zeilen 
jpeg-kodieren. Sobald diese N-Zeilen jpeg-kodiert sind (der STM32F4 hat 
dafür auch einen DSP an Bord), ist der entsprechende Teil im Ringbuffer 
wieder frei und kann überschrieben werden.

Damit passen dann auch (komprimierte) Bilder mit der vollen 
OV7670-Auflösung in den STM32-Speicher. Irgendeiner im Internet hatte 
das wohl auch schon einmal hinbekommen.

Aber allein schon bis zum aktuellen Projektstand musste ich erst einmal 
PWM, DMA, DCMI, YUV, YCbCr & Co verstehen und beherrschen. Hat ein 
bißchen gedauert.

Der nächste Schritt wird dann JPEG und DSP sein - man braucht dafür 
einen wirklich langen Atem (insbesondere wenn's nur Hobby ist) - ich 
drücke Euch daher insbesondere die Daumen, dass Euch zwischendurch nicht 
die Puste ausgeht.

Weiterhin noch viel Spaß und Erfolg!!

Viele Grüße

Igel1


PS:

- Um überhaupt die eingelesenen Bilder testen/sehen zu können, habe
  ich ein ILI9346-Display verwendet: kostet ca. 5 € und kann per
  SPI (und auch I2C ??) vom MC angesteuert werden.
  Ist super-einfach und unkompliziert im Umgang.
  Gängige Module haben sogar auch eine SD-Card-Slot auf der Platine.
  Vielleicht wäre das auch etwas für Euch.

- Per UART an den PC senden, geht natürlich auch, ist aber auf die
  Dauer zu nervig (weil zu langsam). Insbesondere, wenn's ans
  Register-Austesten geht. Da will man nicht jedesmal 1 Minuten warten,
  bevor man das Ergebnis einer Register-Veränderung auf dem Schirm 
sieht.

- Letzter Tipp: lest Euch unbedingt meine ersten 2 Links aus meinem
  letzten Posting durch - diese Seitn sind die "Bibel" für alle OV7670-
  Einsteiger.

von David D. (saturi)


Lesenswert?

Noch eine Sache, da unser Projekt offensichtlich etwas umfangreicher und 
komplexer wird.

Habt ihr beiden schon Erfahrungen mit GitHub gemacht? Ich nur am rande. 
Habe mir grade einmal die vielseitigen Möglichkeiten und Tools 
angeschaut, die einem da an die Hand gegeben werden.

Ich denke, da könnten wir unser Projekt besser mit strukturieren, 
Aufgaben/Ideen festhalten und diskutieren als hier, wo quasi jeder Post 
untereinander kommt.

zusätzlich (bzw. ursprünglich) kann man dort seinen Programm-Code 
austauschen, zusammen dran arbeiten und vorschläge unterbreiten.

Auf den ersten Blick wirkt das ganze sehr erschlagend und wenn man der 
englischen Sprache nicht ganz so mächtig ist auch erstmal etwas 
unverständlich. Aber ich denke, dass wir das ganze damit viel 
strukturierter angehen können. Da gäbe es auch eine Wiki-Funktion, wobei 
wir da auch bei deinem bleiben können. Du nutzt deins ja noch darüber 
Hinaus für andere Projekte.

Schaut es euch mal an uns sagt mir eure Meinung.
Falls ihr begeistert seid, würde ich mal versuchen ein Projekt 
aufzusetzen und euch einzuladen.

lg.

David

von David D. (saturi)


Lesenswert?

Andreas S. schrieb:
> Ich würde ja soooo gerne mitmachen, aber ich habe vermutlich erst in
> einigen Wochen wieder Zeit fürs Hobby. Ich kann Euch also nur ein paar
> Tipps aus meinem wochenlangen Kampf mit dem OV7670 geben - so lange
> hat's gebraucht, bis es halbwegs an meinem STM32 lief (dummerweise habe
> ich auch schon vieles wieder vergessen).

Ich denke den langen Atem werden wir brauchen :D aber ich bin 
zuversichtlich. Und werden auch noch einige Wochen brauchen :D
Also du bist dann gerne Willkommen, sobald du die Zeit hast ;-)

  Ich habe irgendwann für mich beschlossen, dass ich meinen Stolz, alles
> selber herauszufinden, über Bord werfe und von den Erfahrungen dieser
> anderen profitieren will - zumindest um die Doku-Defizite damit
> aufzufüllen. Daher mein Tipp: lest viele Threads und Foren-Beiträge von
> Leuten, die die Tortour schon hinter sich haben und spart Euch Eure
> Energie für's Wesentliche auf. Fehlende Hersteller-Doku per
> Try-and-Error aufzufüllen wird Euch sonst zermahlen (so meine Weissagung
> - basierend auf meinen Erfahrungen)

Das glaube ich dir und ich bin mir auch sicher, dass wir das von anderen 
gesammelte Wissen nutzen werden. Das wir alles selber machen wollen 
bezieht sich darauf, dass wir alles verstehen wollen und keine fertigen 
Code-Schnipsel verwenden möchten. Das heißt nicht, dass wir die 
Scheuklappen aufsetzten und die Erfahrungen Anderer völlig ignorieren :)

Danke für deine Tipps :)

lg. David

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
>>> @Michael 1979 war mein Vater 17 und ich noch längst nicht in Planung :D
>> Ups, dann bin ich ja quasi der "Opa" hier unter Euch Jungfüchsen ;-))
> Ist doch Toll, dass wir so ein bunter Haufen sind und uns ergänzen
> können.

hmmm.. das bezog sich von Daniel auf meinen Kommentar zu meinen 
µC-Anfängen 1979...
Ich will nicht zuviel abschweifen:
Als Rentner habe ich jetzt die Zeit hier einfach mal "mitzuspielen".
Meine ersten Videoexperimente war ein "Videograbber" am C64-Userport.
3 Komparatoren für 4 Graustufen und TTL drumrum. Auflösung 160x200, die 
war dem C64 Multicolormode geschuldet. Kamera eine TFK500, ohnhin nur 
s/w.
Das ging natürlich nur mit einem Standbild, also wie ganz ganz früher: 
Start drücken und ca. 3 Minuten nichts bewegen...
Leider habe ich kein so erzeugtes Bild von damals mehr. Meine Kollegen 
meinten erkannten den Kopf auf dem Bild zumindest sofort. ;-)

Zum Thema: üblicherweise können diese Cam-ICs einen Snapshotmode, wo sie 
das Bild im internen Ram lassen und man es sooft wieder abholen kann wie 
man will. Man könnte sonst nie ein sauberes Bild mit anderer als der 
Sensorrate auslesen. Die Rate hängt aber direkt vom Sensor-IC, 
Lichtempfindlichkeit, interne Umladezeiten usw. usw. ab.
Man hat ja schließlich weder Blende noch Verschluß dran.
Muß ich mal ins Datenblatt der OB7660 schauen.

Ich hör erstmal auf, meine alte DC3840 am ESP32 redet inzwischen mit mir 
und schickt mir einen kaputten JFIF-Header???
Die Dc3840 hat vermutlich den Chip der OV7660 drauf, es hängt eben nur 
ein OV528 hinten dran als Serial-Bridge.
Bewegte Bilder wid es mit einem Mega328 nicht geben, Snapshots in 
640x480 in Farbe alle paar Sekunden sind mit Sicherheit machbar.

3Byte x 320 Pixel wären 960Byte Ram, bei 160 wären es 460 Byte.
Also mit 160x120 zeilenweise einlesen und zum PC schicken.
Sind dann 120 Durchläufe für ein Bild.

Zum Arduino-Nano: der CH340 kann auch 921kBit. Ob er 500 oder 460kBit 
kann hängt vom Treiber ab. Gerade mal mein Win7 gefraht: der CP2102 und 
der CH340 bieten maximal 128kBit an, der FTDI 921kBit. Das ist aber nur 
der Windows-Treiber. Der CH340 (am ESP8266) kann auch 921kBaud.
Nutzt aber alles nur bedingt, der Mega328 mit 16MHz Takt kann zwar 
250/500/1000kBaud mit 0% Fehler erzeugen, verkürzt letztlich 
Übertragungszeit zum PC, nur beleiben es mangels Ram im Mega328 trotzdem 
lauter kleine Häppchen mit Pausen dazwischen zum Lesen der Kamera.

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Guten Abend,
ich probiere wieder etwas rum, um unserem Ziel einen Schritt näher zu 
kommen.

ich möchte euch auf meinen bisherigen Stand bringen:
Ich versuche das zu realisieren, was wir uns als erstes Teilziel 
festgelegt haben:

Das aufnehmen einer Zeile.

dazu habe ich zunächst mehrere Einstellungen in den Registern getroffen, 
die zwar Wirkung zeigen, ich die gänzlichen Auswirkungen noch nicht 
absehen kann:

CLKRC-Register: 0x0F
COM7-Register: 0x08
COM3: 0x08
COM14: 0x1C
COM10: 0x20
SCALING_PCLK: 0x04

Dabei sei gesagt, dass ich die Register erst auslese und nur die 
beabsichtigten Bytes verändere, damit bspw. Reserved Bits nicht 
überschrieben werden. Daher kann der tatsächliche Registerwert von 
meinen abweichen.

Mit den Einstellungen ergibt sich vollgendes Bild:
- PCLK ist stark gedrosselt, auf ca. 50kHz
- PCLK alterniert nur während HREF-High Pegel aktiv (ansonsten wird PCLK 
auf High gehalten)
- Es sollte das QCIF Format eingestellt sein mit 160x120 px (durch 
ebenfalls aktiviertes Scaling)
- Das YUV Format sollte aktiv sein.

Was ich vorhabe:
1. die positive Flanke von PCLK erkennen (mittels Interrupt)
2. Dabei die Daten von D0-D8 in ein Byte schreiben
3. Das Byte (zu Testzwecken) in einem Array ablegen
4. so viele wie mögliche Bytes erfassen

Wenn ich mit dem Oszilloskop messe, bekomme ich das Verhalten Von PCLK 
und HREF wie vorgestellt hin.
Der Interrupt löst aber nur unregelmäßig aus (obwohl die Flanke von PCLK 
auf dem Oszi sichtbar ist). Meistens immer zu V-Sync Signalen, sprich 
wenn HREF und somit PCLK länger statisch sind.

Meine Interrupt Routine ist nicht überladen:
1
 ISR(INT0_vect){
2
  PORTB |= 0x20;
3
  interruptFlag=true;
4
  i++;
5
  _delay_ms(1); //eingeführt um ein "übersehen" vom Oszi auszuschließen
6
  PORTB&= ~(0x20);
7
}

PortB 0x20 ist Pin 13 und da greife ich mir das Signal ab, wenn der 
Interrupt ausgeführt wird

Da ich nun wirklich schon mehrere Stunden an diesem Problem sitze, 
drängt sich mir die Frage auf, wie schnell denn der externe Interrupt 
eigentlich arbeiten kann, und ob es dort ebenfalls max. Frequenzen gibt. 
Leider konnte ich nichts finden. Habt ihr da schon Erfahrungen?

lg. David

von Andreas S. (igel1)


Lesenswert?

@David:

bzgl. Interrupt-Routinen, gibt es viele Seiten, die sich mit der 
Latenz-Zeit beschäftigen. Evtl. ist die ja schon hinreichend:

Beitrag "Interrupt latency"

Meine AVR-Zeiten liegen leider schon ein paar Jährchen zurück, aber ich 
habe vielleicht doch einen sehr praktischen Tipp:

Natürlich kann man die Dauer der ISR-Routine (inkl. dem Overhead zum 
Aufruf der ISR-Routine) sauber auf dem Papier ausrechnen. Das bedeutet 
aber immer viel Lesen und Nachschlagen.

Ich habe damals oftmals einfach den Debugger genutzt:

Wenn Du das Programm im Debugger laufen läßt, so kannst Du exakt 
nachverfolgen, wieviele Zyklen das Einspringen in die ISR und die 
Abarbeitung Deiner ISR benötigt.

Und ja, es gibt eine bestimmte Zeit, die ein Pegel anliegen muß, damit 
die ISR ausgelöst wird - steht irgendwo im Datenblatt.

Viele Grüße

Igel1

von Olli Z. (z80freak)


Lesenswert?

Hi David, offensichtlich müssen wir uns noch zwei grundlegende Techniken 
im Zusammenhang mit dem Arduino (Atmega) aneignen: Timer (zur 
Clock-Erzeugung) und Interrupts. Darauf basieren die wesentlichen 
Komponenten unserer Umsetzung.

Deine Ermittlung mit PCLK finde ich bemerkenswert, denn laut Datenblatt 
läge der PCLK immer an, sobald XCLK bereitgestellt wird. Aber vielleicht 
sind das eben genau die Dinge von denen Andreas gesprochen hat...

Gelesen hab ich über Timer und Interrupts schon so einiges, angewendet 
hab ich die auch schonmal, aber so ein richtig tiefgehendes Verständnis 
habe ich auch nicht dafür. Gute Voraussetzungen um hier mal "ganz unten" 
zu starten :-)

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:

> Wenn ich mit dem Oszilloskop messe, bekomme ich das Verhalten Von PCLK
> und HREF wie vorgestellt hin.
> Der Interrupt löst aber nur unregelmäßig aus (obwohl die Flanke von PCLK
> auf dem Oszi sichtbar ist). Meistens immer zu V-Sync Signalen, sprich
> wenn HREF und somit PCLK länger statisch sind.
>
> Meine Interrupt Routine ist nicht überladen:
>
1
 ISR(INT0_vect){
2
>   PORTB |= 0x20;
3
>   interruptFlag=true;
4
>   i++;
5
>   _delay_ms(1); //eingeführt um ein "übersehen" vom Oszi auszuschließen
6
>   PORTB&= ~(0x20);
7
> }
8
>
>
> PortB 0x20 ist Pin 13 und da greife ich mir das Signal ab, wenn der
> Interrupt ausgeführt wird
>
> Da ich nun wirklich schon mehrere Stunden an diesem Problem sitze,
> drängt sich mir die Frage auf, wie schnell denn der externe Interrupt
> eigentlich arbeiten kann, und ob es dort ebenfalls max. Frequenzen gibt.
> Leider konnte ich nichts finden. Habt ihr da schon Erfahrungen?

Erfahrung ja, aber leider liegt meine Atmega-Zeit schon etwas zurück, 
daher bitte meine Hinweise mit Vorsicht genießen:

1.) Ein Sprung in die ISR benötigt minimal 4 Takte:
    s. Kap. 11.7.1 im Datenblatt:
    http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdf

    ABER: das kannst Du nur erreichen, wenn Du in Assembler 
programmierst
    und exakt weißt, was Du tust.
    Dein C-Compiler wird noch jede Menge Zusatz-Befehle einfügen (vor
    allem Register-Push Operationen).
    Auch benötigt der Rücksprung aus der ISR nochmals 4 Takte sowie
    vermutlich jede Menge Register-Pop-Operationen.

2.) Bei 50kHz PCLK-Frequenz ist eine Periode 20us lang, was immerhin
    320 Takten bei 16MHz Prozessortakt entspricht. Müßte eigentlich
    ausreichen, um eine ISR sauber auszuführen.

3.) Hier meine Vermutung, was bei Dir passiert:

    - Du hüpfst mit der ersten PCLK-Flanke in die ISR und schaltest
      dort Deinen Pin13 an.

    - Per "interruptFlag=true;" enables Du dann vermutlich Dein
      globales Interrupt-Flag, so dass weitere Interrupts akzeptiert
      werden - auch während Du noch in der ISR weilst.
      Du brauchst das "interruptFlag=true;" vermutlich deshalb,
      weil Deine _delay_ms(1) sonst nicht funktioniert.

    - Dann rufst Du die Delay-Routine auf.  Diese Delay-Routine wird
      vermutlich Ihrerseits ebenfalls über Interrupts abgewickelt
      werden. Je nach Implementierung wird sie jedoch niemals zu
      Ende kommen, weil ja bereits nach 20us die nächste PCLK-Flanke
      kommt, die wiederum einen Einsprung in Deine ISR bewirkt.

    - Bevor die Video-Zeile zu Ende ist (bei Deinem QCIF also nach
      160 x 20us = 3200us) plus 1ms Delay wird Dein Pin 13 also nicht
      abgeschaltet werden. Außerdem wurde die ISR zu diesem Zeitpunkt
      160x rekursiv aufgerufen - der Rücksprung wird entsprechend
      lange dauern ...

Daher mein Tipp:

    - Schmeiss unbedingt die Delay-Funktion aus Deiner ISR raus.
      Dein Oszi wird ja wohl Signale an Pin13, die > 0,1us lang
      sind, locker darstellen können.
    - Dann triggerst Du auf dem ersten Oszi-Kanal auf PCLK und
      schaust Dir auf dem 2. Oszi-Kanal Pin13 an. So solltest Du
      den Delay beim Aufruf der ISR schön sehen können.

Viele Grüße

Igel1

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

PCLK auf 50kHz, da kommt alle 20µs ein Clock-Impuls.
Bei 17MHz ist die Zykluszeit des AVR 62,5ns, also maximal 320 Takte für 
ISR-Aufruf, Abarbeitung und wueder raus. Dann ist aber keinerlei Zeit 
mehr, außerhalb was zu machen. Der AVR führt nach verlassen einer ISR 
genau einen ASM-Befehl aus wenn schon wieder irgendein Interrupt 
ansteht.

 ISR(INT0_vect){
>   PORTB |= 0x20;
>   interruptFlag=true;
>   i++;
>   _delay_ms(1); //eingeführt um ein "übersehen" vom Oszi auszuschließen
>   PORTB&= ~(0x20);
> }
>
1ms Delay geht ja mal garnicht, da sind 50 PCLK vergangen...

Man könnte sich jetzt das ASM-Listing anschauen, das der Compiler 
erzeugt.
Wenn die Portzugriffe richtig optimiert (kann der GCC eigentlich), sind 
das jeweils 3 oder 4 Takte. Die Umsetzung von interruptFlag=true; und 
i++; wird wesentlich ungünster sein, weil der GCC intern C-typisch mit 
16Bit-Werten rechnet und das kostet einige Registerschiereien. Dazu 
kommt die recht umfangreiche Register-Retterei beim ISR-Aufruf und die 
Wiederherstellung beim Verlassen in C.
Ich hoffe, ich habe jetzt auf die Schnelle nicht falsch gerechnet...
Ich hatte oben schon irgendwo angedeutet, das ich den Weg nicht für 
machbar halte. Bei VSync in die ISR und dann per Busy-Loop auf H-Sync 
warten. Dann PCLK direkt abfragen und bei jeder Flanke die Daten 
einlesen und wegspeichern. Das in der ISR der AVR nur mit dem Kram 
beschäftigt ist, ist hier nur von Vorteil, außerdem ist es nur für genau 
ein Bild (oder beim Test erstmal eine Zeile). Wie man dann mit den Daten 
umgeht ist sowieso noch zu klären...

PS: meine alte DC3840 redet inzwischen am ESP32 mit mir, prinzipiell 
auch am ESP8266. Diese Camera hat vermutlich sogar den gleichen 
Bildsensor, man kommt wegen ser seriellen Bridge und deren Firmware 
allerdings nicht an dessen Register ran. Leider hat sie im Gegensatz zur 
OV7670 eine miserable Optik.
Diese Kamera lief irgendwann um 2008 schonmal mit einem Webserver von 
U.Radig auf einem Mega32 mit 14,xxx MHz Takt.
Ich habe sie mal schnell mit einer USB-Verlängerung auf den Balkon 
geklemmt, so als Anreiz. ;-)

Gruß aus Berlin
Michaeö

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb im Beitrag #53744
> Hallo,
>
> PCLK auf 50kHz, da kommt alle 20µs ein Clock-Impuls.
> Bei 17MHz ist die Zykluszeit des AVR 62,5ns, also maximal 320 Takte für
> ISR-Aufruf, Abarbeitung und wueder raus. Dann ist aber keinerlei Zeit
> mehr, außerhalb was zu machen.

Im großen und ganzen stimme ich Michael ja zu, nicht aber beim oben 
Zitierten. (Statt 17MHz meinte Michael sicherlich 16MHz - aber das war 
bestimmt nur ein kleiner Typo und ist nicht Gegenstand meiner Kritik.)

Der Punkt, um den es geht, ist folgender: ich bin der Meinung, dass der 
Prozessor bei 320 Takten zwischen zwei PCLK-Flanken nach der Abarbeitung 
einer kurzen ISR noch >200 Takte Zeit für andere Dinge haben sollte.

David wird das hoffentlich in Kürze bestätigen, wenn er mit angepaßtem 
ISR-Code hier neue Ergebnisse posten wird.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Der Punkt, um den es geht, ist folgender: ich bin der Meinung, dass der
> Prozessor bei 320 Takten zwischen zwei PCLK-Flanken nach der Abarbeitung
> einer kurzen ISR noch >200 Takte Zeit für andere Dinge haben sollte.

ist gut möglich, habe ich nicht weiter ins Detail gerechnet.
Ich wollte auch mehr darauf hinaus, daß es für das konrete Projekt nicht 
wirklich etwas zwischen dem Einlesen von 2 Pixeln zu tun gibt.
Wenn man also eine Zeile komplett in einer HSync-ISR einliest und 
zwischenspeichert, erspart man sich mögliche Timingprobleme mit einer 
PCLK-ISR erstmal ganz.

Man muß zum Üben und Testen nicht alle Probleme gleichzeitig lösen 
wollen. ;)

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

... ich hoffe, der Thread schläft nicht ein, bin doch zu neugierig,
wie's weitergeht.

Habe mir die HW-Aussstattung so eines Atmega328p vorhin nochmals
genauer angeschaut ... puhhh, ganz schön knapp ...

Das war für mich seinerzeit der Grund, auf ARM umzusteigen und
das wäre auch mein Rat an Euch:

OV7670 und ATmega - das paßt einfach nicht gut zusammen.
Früher oder später wird Euch die HW-Beschränkung frustrieren,
weil Ihr maximal die Pixel bei arg reduzierter Auflösung einlesen und
mehr oder weniger 1:1 irgendwohin weiterschieben könnt.

Wenn ich die Zeit betrachte, die ich benötigt habe, um vernünftige
Bilder aus der OV7670 herauszubekommen, so kann man sich in dieser
Zeit auch schon etwas vom ARM-Prozessor beibringen.

Und daraus ergibt sich meine Anregung an Euch: überlegt Euch, ob es
Sinn machen könnte, ein paar Wochen Einarbeitung in ARM-Technologie
zu stecken, um dann mit ca. 10-fach gestärkter Muskelkraft nochmals
an die OV7670 heranzutreten.

Um Euch die Sache schmackhaft zu machen:

Ein STM32F429I-Discovery-Board bekommt man für ca. 20-25 EUR in der 
Bucht.
Dort ist neben einem potenten stm32f429-Prozessor auch schon ein 
ILI9346-Display drauf - optimal zum Experimentieren mit dem OV7670

Und der Prozessor kann (aus dem Kopf geschrieben):

- Läuft auf 3,3V und kann direkt mit OV7670 gekoppelt werden
- Hat 180 MHz Taktfrequenz
- Hat ca. 256 kByte RAM, ca. 1 MB Flash
- Kann DMA  (= Daten von A nach B schieben ohne die CPU zu behelligen)
  (A oder B können sein: RAM, GPIO, UART, DCMI, SPI, ...)
- kann DCMI (= Kamera-Daten per DMA in RAM-Bereiche schieben)
- hat DSP an Board
- hat unendlich viele IO-Ports
- hat mehr als zwei Hände voller Timer
- hat mehrere unabhängige UART's, I2C's und SPI's an Board
- hat Ethernet, CAN, USB - Controller an Board
- hat sogar irgendwelche LCD-TFT-Controller an Board
- hat mehrere 12-Bit A/D- und D/A-Wandler

... ach ja: und auf dem Board stecken zufällig noch 64MB SDRAM,
Test-LED, Test-Button und ein Beschleunigungs-Sensor.

Oder schaut einfach selbst:

Board: http://www.st.com/en/evaluation-tools/32f429idiscovery.html

Prozessor - Datasheet:
http://www.st.com/resource/en/datasheet/dm00071990.pdf

Prozessor - Reference Manual:
http://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf

Und das Beste: so ein ARM-Prozessor kommt mit einem "Hardware-
Debugger" daher - man kann seine Programme also Schritt für
Schritt debuggen - nicht im (buggy Atmel-)Simulator, sondern
nativ auf der Hardware (inkl. Register-Auslesen und Pi-Pa-Po)

Kurzum: ihr bekommt alles, was man sich schon immer gewünscht hat.
Im Gegenzug - das sei nicht verschwiegen - kostet so ein ARM-
Prozessor aber ein paar Wochen Einarbeitungszeit und insbesondere
der Anfang ist etwas hart.

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Hallo,
ich habe nicht vor diese Thread einschlafen zu lassen. Ich verfolge die 
Beiträge auch sehr interessiert. Leider bin ich diese Woche sehr 
eingespannt und werde erst ab dem Wochenende wieder dazu kommen, meinen 
ausführlichen Beitrag zu leisten.

lg.
David

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> OV7670 und ATmega - das paßt einfach nicht gut zusammen.
> Früher oder später wird Euch die HW-Beschränkung frustrieren,
> weil Ihr maximal die Pixel bei arg reduzierter Auflösung einlesen und
> mehr oder weniger 1:1 irgendwohin weiterschieben könnt.
Man kann die Pixel in maximaler Auflösung (sind ja nur 640x480) einlesen 
und kann die irgendwohin schieben (als Webseite wenn man noch einen 
ENC28J60 oder was moderneres dranhängt) oder auf eine SD-Karte 
speichern.
Was einschränkt: man kann keine Bewegtbilder bekommen, geht mit dieser 
Kamera aber sowieso nicht wirklich) und muß etwas Geduld mitbringen 
(10-15s um ein Bild in den Webbrowser zu bekommen) und man muß ein paar 
egenwillige Wege gehen.
Ich hatte am 02.04.2018 13:42 ein Bild von meiner DC3840 angehängt, 
allerdings mit einem ESP32 eingelesen und rübergeschickt.
Genau diese Kamera hing vor vielen Jahre an einem ATMega32 mit dem 
ENC28J60 als LAN-IC.
921000Baud von der Kamera und auch kein Ram. Eingelesen in 128 Byte 
Häppchen und dem TCP-Buffer in die Hand gedrückt. Wenn das Paket voll 
war rausgeschickt usw.
Ziel war nur "es müßte machbar sein".
Natürlich konnte man auch damals schon eine USB-Webcam bemühen, an einen 
kleinen PC hängen usw. Das konnte ja sozusagen jeder. ;-)
Sind 10 Jahre seitdem vergangen:
http://www.ulrichradig.de/home/index.php/projekte/uC-kamera

> Wenn ich die Zeit betrachte, die ich benötigt habe, um vernünftige
> Bilder aus der OV7670 herauszubekommen, so kann man sich in dieser
> Zeit auch schon etwas vom ARM-Prozessor beibringen.

Ich nehme an, die OV7660 ist überhaupt nur wieder aufgetaucht, weil es 
sonst wohl nichts mehr auf dem Markt gibt, mit dem man überhaupt an 
einem AVR o.ä. Chancen hätte.

Wollte ich sowas machen wäre es doch heute ein RasPi Zero W, die 
zugehöirge Cam dran und der Viedostream in HD wäre greifbar.
Man wird heute solch ein Kameramodul kaum noch irgendwo wirklich 
einsetzen wollen. Weder mit einem ARM noch überhaupt. Zu langsam, 
Auflösung zu gering, Lichtempfindlichkeit zu schlecht usw. usw.

Der Sensor der OV7670 ist der, der auch in obiger DC3840 vor 10 Jahren 
drin war... Die Optik der OV7660 ist etwas besser und lichtstärker.

Wozu also das Ganze? Man lernt Datenblätter zu lesen, man lernt I2C 
kennen, man lernt es, das Zeitverhalten eines System in Hardwarenähe zu 
beachten.
Das hilft aber auch auf anderen Systemen bei anderen Aufgaben.

Nimm es als Spaß an der Sache, Zeit bei einer Hobbyaufgabe war noch nie 
ein Kriterium.

Ich verfolge das hier interessiert weil ich es schon kenne (und auch 
schon kann) und als Rentner etwas Zeit habe.

Wäre doch lusitg (und sinnlos...): OV7670, Mega328, SX1276 
(LoRa-Funkmodul) und nach 6-7 Stunden hätte man ein komplettes Bild am 
anderen Ende. ;)

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Hier ein Beitrag, den ich vergessen hatte, abzuschicken - er 
referenziert auf den letzten Beitrag von David.

David D. schrieb:

> Da ich nun wirklich schon mehrere Stunden an diesem Problem sitze,
> drängt sich mir die Frage auf, wie schnell denn der externe Interrupt
> eigentlich arbeiten kann, und ob es dort ebenfalls max. Frequenzen gibt.
> Leider konnte ich nichts finden. Habt ihr da schon Erfahrungen?
>
> lg. David

Zu dem "Overhead", der bei der Interrupt-Verarbeitung anfällt, hatten 
Ulrich und ich ja bereits etwas geschrieben.

Nun habe ich nochmals nachgeschaut, wie lange so ein Puls denn anliegen 
muss, damit eine Flanke denn auch wirklich einen Interrupt auslöst.

Die Antwort findet sich im Datenblatt des Atmega328p auf S. 53 und S. 
54:
http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf

Aus Figure 12-1 läßt sich schon erahnen: der Pegelwechsel muss 
mindestens 1 CPU-Takt lang anliegen und auf S. 54 wird das nochmals 
bestätigt:
". If edge or toggle interrupt is selected, pulses that last longer than 
one clock period will generate an interrupt".

Wenn Dein ATmega328p-Schweinchen also mit 16MHz rennt, so können Pulse 
mit einer Dauer von 1/16MHz = 0,0625us detektiert werden. Von dort droht 
also keine Gefahr.

Das Problem bei einer Bearbeitung über Interrupts wird eher der Overhead 
für das Einspringen (min. 4 Takte), das Rückspringen (min. 4 Takte) und 
das Sichern bzw. Widerherstellen von N Registern und für ein bißchen 
ISR-Code sein.

Man liest von 50-80 Taktzyklen, die dann mal ganz fix futsch sind. Bei 
80 Taktzyklen könntest Du also frühestens nach 80 x 0,0625us = 5us die 
nächste Taktflanke per Interrupt bearbeiten. Ganz streng betrachtet 
kannst Du beim YCbCr422 Format sogar eine Flanke "schludern", weil Du ja 
nur die Y-Flanke mitbekommen mußt - aber da wind's dann schon langsam 
haarig mit den ganzen Timings.

Das beschränkt Deinen PCLK-Takt auf 1/5us = 200kHz, was wiederum am 
unteren Ende der Spaßgrenze liegt, denn:

Gemäß Tabelle 3.3 im Implementation Guide:
http://www.haoyuelectronics.com/Attachment/OV7670%20+%20AL422B%28FIFO%29%20Camera%20Module%28V2.0%29/OV7670%20Implementation%20Guide%20%28V1.0%29.pdf

... kannst Du bei 24MHz PCLK die max. 30 Frames/s erreichen.
Mit 200kHz liegst Du um den Faktor 120 darunter, was Deine Framerate auf 
30f/s / 120 = 0,25/s reduziert. Wie gesagt: am unteren Ende der 
Spaßgrenze.

Kurzum: Ein Polling-Mechanismus wäre vermutlich besser geeignet, um die 
Pixel aus der Kamera in das RAM einzulesen.

Soweit meine 10 Cent ...

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Guten Tag zusammen,
ich hoffe ihr könnt den Tag ebenso sonnig genießen wie ich es tue.
So sitze ich also gemütlich mit meinem Laptop auf dem Balkon und nehme 
mir wie versprochen die Zeit, einen ausführlichen Beitrag zu schreiben.

Zunächsteinmal vielen Dank für die vielen Hilfestellungen.

Zu meinem letzten Post:
Ich glaube ich sollte aufhören Nachts noch schnell einen Beitrag zu 
schreiben, sondern lieber in Ruhe vollständige Informationen liefern ;-)

Folgendes war mein (vollständiger) Gedankengang:
Ich schaue zunächst, ob neben der ISR-Routine, die den PCLK Peak 
detektieren soll, noch Zeit bleibt um in dem Hauptprogramm etwas zu 
rechnen/bearbeiten/senden/speichern etc.
Wie ich das vorhabe:
Ich lasse in der ISR-Routine einen Zähler hochlaufen und setzte eine 
FLag-Variable die anzeigt, dass ein Interrupt da war. Im Hauptprogramm 
frage ich die Flag ab und erhöhe, falls diese Vorhanden ist, einen 
zweiten Zähler und setzte die Flag dann wieder zurück.

Wenn ich jetzt im Debugging-Modus bin und Pause drücke, sollten beide 
Zähler den gleichen Wert haben, oder der ISR-Zähler maximal eins mehr 
haben.
Um einen Überlauf der int-Variablen zu verhindern habe ich noch eine 
Grenze festgelegt. Ebenso wollte ich mit dem Zählen erst bei der 
nächsten HREF-Periode beginnen, um gleichzeitig zu schauen, ob ich auch 
die eingestellt Auflösung (bzw. die erwartete Anzahl an Bytes) erhalte.

Mir ist bewusst, dass eine delay Funktion absolut nichts in einem 
Interrupt zu suchen hat (daher habe ich sie jetzt auch wieder raus 
genommen). Diese ist nur als letzter Hoffnungsschimmer eingefügt worden, 
weil ich verzweifelt gedacht habe, mein Oszi könnte die eventuell 
verpassen. (Der Kommentar im Programmcode war anscheinend nicht 
ausführlich genug)

Der Verdacht des rekursiven Aufruf gefällt mir ganz gut. Hatte aber auch 
zu Beginn und zum Ende der Routine cli() bzw. sei() gesetzt, um diesen 
Fall auszuschließen. Brachte aber leider keine Veränderung.

Hier mein Vollständiger Code (allerdings im AVR-Style)(Versuche das die 
Tage mal auf Arduino umzumünzen, damit wir wieder auf der gleichen 
Plattform sind) Ich hoffe, ihr könnt trotzdem etwas damit anfangen:
1
/*
2
 * main.cpp
3
 *
4
 * Created: 23.07.2017 17:35:15
5
 *  Author: David
6
 */ 
7
8
 #ifndef F_CPU
9
 #define F_CPU 16000000
10
#endif
11
 
12
 #include <avr/io.h>
13
 #include <avr/interrupt.h>
14
15
#include "OV7670.h"
16
#include "OV7670.c"
17
18
#include "UART.h"
19
20
21
volatile unsigned int i=0;
22
//unsigned char myBytes[100];
23
bool interruptFlag =false;
24
 int main(void)
25
 {
26
  sei();
27
28
  UART0_init();
29
   OV7670_init();
30
  OV7670_checkConnection();
31
32
33
//Reduce frequency of PCLK
34
  char ReadData =0;
35
  char MASK = ~0x80; 
36
  char WriteData; 
37
   //Read the RCLK Register to get the internal Clock
38
   OV7670_read(OV_SCCB_CLKRC,&ReadData);
39
   UART0_senden_Byte(ReadData);
40
   UART0_newLine();
41
   
42
   //Reduce PCLK by Prescaler
43
   OV7670_write(OV_SCCB_CLKRC,0x0F);
44
   
45
   //Check if change succed
46
   OV7670_read(OV_SCCB_CLKRC,&ReadData);
47
   UART0_senden_Byte(ReadData);
48
   UART0_newLine();
49
50
   //Change Format to QCIF and YUV
51
   OV7670_read(OV_SCCB_COM7,&ReadData);
52
   MASK = ReadData & 0b01000000;
53
   MASK |= 0x08;
54
   ReadData |= MASK;
55
   OV7670_write(OV_SCCB_COM7,ReadData);
56
   
57
   //activate Skaling
58
   OV7670_read(OV_SCCB_COM3,&ReadData);
59
   ReadData|=0x08;
60
   OV7670_write(OV_SCCB_COM3,ReadData);
61
62
   //Activate DCW and scaling PCLK enable (neccessary for Divide PCLK) and Divide PCLK by 16
63
   OV7670_read(OV_SCCB_COM14,&ReadData);
64
   ReadData|=0x1C;
65
   OV7670_write(OV_SCCB_COM14,ReadData);
66
67
   //deactivate PCLK during HREF Blank
68
   OV7670_read(OV_SCCB_COM10,&ReadData);
69
   ReadData|=0x20;
70
   OV7670_write(OV_SCCB_COM10,ReadData);
71
72
   //Scaling PCLK
73
   OV7670_read(OV_SCCB_SCALING_PCLK,&ReadData);
74
   ReadData &=~(0x0F);
75
   ReadData |=0x04;
76
   OV7670_write(OV_SCCB_SCALING_PCLK,ReadData);
77
78
//set Variables and Flags
79
   i=0;
80
  interruptFlag=false;
81
  bool HREF_Flag=false;
82
83
  volatile int j=0;
84
  //Setup interrupt pin
85
  EICRA |= (0b00000011);  //Interrupt at Int0-Pin at positiv change
86
  EIMSK &= ~(0b00000001);  //Disable Int0-Pin
87
88
   while (1)
89
   {
90
    //start conditions for external interrupt (Wait until HREF is LOW to make sure to get a complete Line)
91
    if((!((OV_HREF_PIN>>OV_HREF_PINNR)&(0x01)))&&(HREF_Flag==false))
92
    {
93
      i=0;
94
      j=0;
95
      EIMSK |= 0b00000001;  //Enable Int0-Pin    
96
    }
97
    
98
    //Count PCLK in Line
99
    if(((OV_HREF_PIN>>OV_HREF_PINNR)&(0x01))&&(interruptFlag==true))
100
    {
101
      j++;  //Count the Interrupts in the Main-Loop (Test if j and i have the same value)
102
      interruptFlag=false;
103
      HREF_Flag=true;  //indicate a period of HREF
104
    }
105
    
106
    //Disable Interrupt after One Line  
107
    if((!((OV_HREF_PIN>>OV_HREF_PINNR)&(0x01)))&&(HREF_Flag==true))
108
    {
109
      EIMSK &= ~0b00000001;  //Disable Int0-Pin
110
    }
111
          
112
   }
113
   return 0;
114
 }
115
116
 
117
ISR(INT0_vect){
118
  cli();
119
  PORTB |= 0x20;  //Just for measuring at oscilloscope
120
  interruptFlag=true;
121
  i++;
122
  PORTB&= ~(0x20);
123
  sei();
124
}

Derzeit stellt es sich wie folgt da:
Führe ich den Code wie oben dargestellt aus (und setzte einen Breakpoint 
in der letzten If-Schleife, so zählt der Zähler nur bis eins, was für 
mich absolut unverständlich ist.
Die interrupts kann ich nach wie vor durch Pin 13 nicht detektieren, was 
mir ebenso nicht einleuchten will.

Kommentiere ich die letzte if-Schleife aus und pausiere willkürlich über 
den Debug-Mode, haben beide Zähler den gleichen Wert. (Ich habe aber das 
gefühl, dass sie zu langsam hochzählen)
Trotzdem sehe ich die ISR-Routine nicht auf dem Oszi.

von Michael kam folgender Beitrag:

>Ich wollte auch mehr darauf hinaus, daß es für das konrete Projekt nicht
>wirklich etwas zwischen dem Einlesen von 2 Pixeln zu tun gibt.
>Wenn man also eine Zeile komplett in einer HSync-ISR einliest und
>zwischenspeichert, erspart man sich mögliche Timingprobleme mit einer
>PCLK-ISR erstmal ganz.

Da stimme ich grob erstmal mit dir überein. Für mich stellt sich dann 
aber die Frage, wie ich die PCLK-Flanken dann detektiere,
um dann jeweils das anliegende Byte zu übernehmen. Wie kann ich soetwas 
denn abbilden? Die ISR wird doch nur einmal durchlaufen. Lasse mich da 
gerne belehren :)


Auf den Beitrag von Igel1 bezogen:
>...
>Und das Beste: so ein ARM-Prozessor kommt mit einem "Hardware-
>Debugger" daher - man kann seine Programme also Schritt für
>Schritt debuggen - nicht im (buggy Atmel-)Simulator, sondern
>nativ auf der Hardware (inkl. Register-Auslesen und Pi-Pa-Po)

über das Debug-Wire und dem Dragon kann ich doch auch die Hardware 
direkt debuggen und auch die Register lesen inkl. Eingänge.
Oder liege ich da falsch?
Im Prinzip hast du vermutlich recht, dass dein Vorgeschlagener 
Controller für diese Anwendung besser geeignet ist.
Ich habe mich aber damals für die Arduino (Atmel) Reihe entschieden und 
auch bisher nur damit Erfahrungen gemacht.
Jetzt auf einen anderen Umzusteigen würde mich (zumindest für den 
Anfang) wieder auf null zurückwerfen. Dafür fehlt mir leider noch etwas 
die Zeit und die Motivation.
Mir ist bewusst, dass ich mit dem Atmega328 keine videos darstellen 
werden kann.
Für mich geht es aber, wie Michael auch schon erkannt hat:
>Wozu also das Ganze? Man lernt Datenblätter zu lesen, man lernt I2C
>kennen, man lernt es, das Zeitverhalten eines System in Hardwarenähe zu
>beachten.
>Das hilft aber auch auf anderen Systemen bei anderen Aufgaben.

Mir reicht es tatsächlich zunächst ersteinmal ein Foto zusammengesetzt 
zu bekommen.
Das ich danach in Ruhe weiterverarbeiten kann. Ich habe in ferner 
Zukunft damit dann vor, eine Art von Sortierer zu bauen. Wie gesagt, 
ferne Zukunft :D
ab dem Sommer habe ich auch privat etwas mehr Zeit und dann kann man 
sich den Schwenk auf einen ARM-Prozessor ja nochmal überlegen. :)

Dann noch der interessante letzte Beitrag von Igel1:

>Kurzum: Ein Polling-Mechanismus wäre vermutlich besser geeignet, um die
>Pixel aus der Kamera in das RAM einzulesen.
Polling sagte mir bis zur Erstellung von diesem Beitrag noch nichts. 
Sollte ich das eher mit einer While-Schleife oder If-Schleifen lösen? 
(Mein verständnis von Polling ist "aktives" Warten, bin ich da richtig?)

Ich hoffe ihr könnt mir sagen, wo ich in obrigem Code einen Denkfehler 
habe? Es ist ja nun wirklich noch keine hochkomplizierte Angelegenheit 
und ich weiß einfach nicht wo das Problem liegt.
vielen Dank für eure Hilfe!

sonnige Grüße

David

von Olli Z. (z80freak)


Lesenswert?

Hi David. Erstmal Respekt für Deine Mühen und danke das Du deine 
Gedanken mit uns teilst. Ich persönlicch finde es immer schwer mich in 
den Code anderer Leute einzudenken, daher ist eine ausführliche 
Dokumentation wichtig.

Von daher wäre mein Vorschlag bevor wir hier über Code diskutieren, den 
Programmablauf zu beschreiben. Also was genau wie und warum erfolgen 
soll. Darauf basierend kann dann jeder seinen Code schreiben, um zu 
lernen und am Ende entwickeln wir einen gemeinsamen, z.B. in Github.

Ein guter Einstieg hierzu wäre, Deine Ideen zur Initialisierung in 
Subroutinen zu gießen. Dazu müssten wir nur beschreiben was das System 
vor Beginn und am Ende der Routine für einen Zustand hat und mit welchen 
Kommandos wir dahin kommen.

Was hälst Du (sorry, ihr) von der Idee? Wollen wir so vorgehen?

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Da stimme ich grob erstmal mit dir überein. Für mich stellt sich dann
> aber die Frage, wie ich die PCLK-Flanken dann detektiere,
> um dann jeweils das anliegende Byte zu übernehmen. Wie kann ich soetwas
> denn abbilden? Die ISR wird doch nur einmal durchlaufen. Lasse mich da
> gerne belehren :)

soviel zu belehren ist da nicht. ;-)
Du nimmst die Länge einer Zeile in Bildpunkten und damit die Anzahl PCLK 
die dazugehören. Dann rechnest Du Dir aus, wieviel zeit das in µs/ms 
ist.
Dann ignorierst Du alle Überlegungen zur Länge einer ISR und machst 
alles ab HSYNC innerhalb der ISR.
PCLK fragst Du simple per Loop ab, eben Pin einlesen und schauen, ob der 
Pegelwechsel da war. Sonst eben in der Schleife weiter abfragen.
Wenn ja Daten holen, Pixelzähler weiterzeählen und wenn noch Pixeldaten 
der Zeile fehle wieder ab in die Warteschleife auf PCLK.
Dann bist Du eben Zeit x in der ISR. Während der Zeit sind sowieso auf 
dem AVR die Interrupts gesperrt und es kann Dich keiner stören.
So bekommst Du eine Zeile. Du bekommst ja vermutlich nichtmal eine Zeile 
im Ram des AVR unter...
Ich schaue mir morgen mal das Datenblatt des OV7670 genauer an wie es 
weiter gehen könnte.

Olli Z. schrieb:
> Ein guter Einstieg hierzu wäre, Deine Ideen zur Initialisierung in
> Subroutinen zu gießen. Dazu müssten wir nur beschreiben was das System
> vor Beginn und am Ende der Routine für einen Zustand hat und mit welchen
> Kommandos wir dahin kommen.

Selbstverständlich sollte sowas in Subroutinen/Funktionen ausgelagert 
werden. InitCam() muß den kamerachip z.B. dann aus jeder Lebenslage in 
einen von uns gewünschten Zustand setzen. Erstmal das notwendigste rein, 
Register, die unbedingt auf gewünschte Werte gesetzt werden 
sollen/müssen dann nachtragen wenn nötig ist.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

@David:

Ich programmiere, wie schon gesagt, ein paar Jährchen keinen AVR mehr,
daher muss ich nicht richtig liegen, aber Deine Art der PIN-Abfrage
scheint mir etwas seltsam:
1
if((!((OV_HREF_PIN>>OV_HREF_PINNR)&(0x01)))&&(HREF_Flag==false))

Ich hätte so etwas erwartet:
1
if( !(OV_HREF_PIN & (1 << OV_HREF_PINNR)) && (HREF_Flag==false))

Außerdem wäre es gut, wenn Du den gesamten Code hier 
einstellst/anhängst.
So fehlt z.B. die Definition von OV_HREF_PIN in Deinem Code-Fragment.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Außerdem wäre es gut, wenn Du den gesamten Code hier
> einstellst/anhängst.

hatte ich auch schonmal drum gebeten, ich würde es dann eben auf einen 
passenden AVR packen und mitschauen.
Ist bei mir reines Interesse. Wenn, dann hänge ich die OV7670 ohnehin an 
einen ESP32. Die in Gang zubekommen dürfte mir kaum Probleme bereiten, 
auch an einem Mega328 nicht. Die reale Möglichkeit habe ich ja schon vor 
etlichen Jahren mit der DC3840 genutzt. Die hängt ja im Moment am ESp32, 
siehe Posting vom 02.04.2018 13:42.

PS und OffTopic: heute 3 Stunden mit 2 Obi/Norma WLAN-Steckdosen 
verbracht.
ESP8266 drin, 10 Leute haben das im Netz mit Tasmota u.ä. in Gang 
gebracht, keiner hat ein wirklich sinnvolles wirklich Stück Doku 
hinterlassen warum es einen IO für Relais on und einen IO für relais off 
gibt. Steht zwar so auf der Platine, ist aber eigentlich etwas anders 
gemeint.
Nun schalten sie wie sie sollen, hätte ich mir die ziemlich aufwändige 
Beschaltung zwischen den ESP-Pins und dem Relais mal gleich selber 
angeschaut... 3 Halbleiter (2 Transistoren, der dritte SOT-23 nicht 
identifizierbar, könnte vom Drumrum soager ein thyristor o.ä. sein), ca. 
10 Widerstande und Kondensatoren.
Ganz verstanden habe ich noch nicht, waum die Chinesen da soviel Aufwand 
getrieben haben.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Der Verdacht des rekursiven Aufruf gefällt mir ganz gut.

Mir auch :-)

> Hatte aber auch
> zu Beginn und zum Ende der Routine cli() bzw. sei() gesetzt, um diesen
> Fall auszuschließen. Brachte aber leider keine Veränderung.

Hmmm - auch dafür müßten wir Deinen kompletten Code sehen.

> Hier mein Vollständiger Code (allerdings im AVR-Style)(Versuche das die
> Tage mal auf Arduino umzumünzen, damit wir wieder auf der gleichen
> Plattform sind)

Oh schreck - dann hängt Ihr mich vermutlich ab ...

> Ich hoffe, ihr könnt trotzdem etwas damit anfangen:

Ja, bloß bitte den vollständigen Code hier noch nachschieben.

> Trotzdem sehe ich die ISR-Routine nicht auf dem Oszi.
1
ISR(INT0_vect){
2
  cli();
3
  PORTB |= 0x20;  //Just for measuring at oscilloscope
4
  interruptFlag=true;
5
  i++;
6
  PORTB&= ~(0x20);
7
  sei();
8
}

Vorab: "cli()" sollte meiner Meinung nach überflüssig sein,
weil beim Aufruf einer ISR das Globale Interrupt-Flag (I in SREG)
sowieso ausgeschaltet wird.

Gleiches gilt für "sei()" am Ende: Beim Rücksprung aus einer
ISR wird das globale Interrupt-Flag wieder aktiviert - das
gehört quasi zum Hotel-Service Deines MC.

Eine erneute steigende Flanke, die während einer "normalen" ISR
einläuft, wird also erst nach dem Rücksprung aus der ISR zum
neuen Interrupt führen.

Dieses (vermutlich von Dir gewünschte) Verhalten konterkarrierst
Du, indem Du sei() noch innerhalb Deiner ISR ausführst.
Das dürfte wiederum zu rekursiven ISR-Aufrufen führen.

Nun zurück zu Deiner ursprünglichen Frage/Aussage:

> Trotzdem sehe ich die ISR-Routine nicht auf dem Oszi.

Ich kontere mal und sage: trotzdem sehe ich nirgendwo, dass
Du PORTB überhaupt als Ausgang geschaltet hast ...

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
>>Kurzum: Ein Polling-Mechanismus wäre vermutlich besser geeignet, um die
>>Pixel aus der Kamera in das RAM einzulesen.
> Polling sagte mir bis zur Erstellung von diesem Beitrag noch nichts.
> Sollte ich das eher mit einer While-Schleife oder If-Schleifen lösen?
> (Mein verständnis von Polling ist "aktives" Warten, bin ich da richtig?)

"Polling" heißt einfach: Frage aktiv Deinen PINx aus Deinem Programm 
heraus immer wieder ab. Es ist das Konzeptionelle Gegenstück zu 
Interrupts, die den Programmablauf "von sich aus" unterbrechen.

Nachteil von Polling: belastet den Prozessor, der dauernd fragen muss - 
auch wenn gar kein Flankenwechsel passiert ist. Vorteil: Du sparst Dir 
den Interrupt-Overhead.

> über das Debug-Wire und dem Dragon kann ich doch auch die Hardware
> direkt debuggen und auch die Register lesen inkl. Eingänge.
> Oder liege ich da falsch?

Nein, Du liegst da goldrichtig, nur ich kannte Debug-Wire nicht, weil's 
scheinbar erst nach meiner AVR-Zeit aufkam. Schönes Feature!

> Im Prinzip hast du vermutlich recht, dass dein Vorgeschlagener
> Controller für diese Anwendung besser geeignet ist.

Und Du hast ebenfalls recht, wenn Du Dich jetzt aktuell in kein
ARM-Abenteuer stürzen willst, wenn Du nicht viel Zeit hast.
Kann ich absolut nachvollziehen.

Viele Grüße

Igel1

von Viktor (Gast)


Lesenswert?

Andreas S. schrieb:
> Ich hätte so etwas erwartet:
> if( !(OV_HREF_PIN & (1 << OV_HREF_PINNR)) && (HREF_Flag==false))
Ich hätte eher sowas erwartet:
1
if( bit_is_clear( OV_HREF_PIN, OV_HREF_PINNR) && (HREF_Flag==false))

Aus welchem Grund auch immer diese Makros nicht empfohlen werden:
https://www.mikrocontroller.net/articles/Bitmanipulation#Hilfsfunktionen_als_C-Makro_.28nicht_empfohlen.29

Ich finde: Lesebarer Code hat oberste Priorität.

von Michael U. (amiga)


Lesenswert?

Hallo,

ich habe zu makros auch eine geteilte Meinung.
Wenn man sie selbst geschrieben hat ok, wenn man sie übernimmt manchmal 
riskant.
Prinzipiell ist es ja nur eine Textersetzung durch #define. Das kann in 
Verbindung mit zusätzlichem kontext wie auch hier
if( bit_is_clear( OV_HREF_PIN, OV_HREF_PINNR) && (HREF_Flag==false))
Nebeneffekte erzeugen, weil nach ersetzen des Makro-Part die komplette 
Auswertung ganz was anders machen kann als erwartet.
Wenn, dann würde ich da immer Funktionen vorziehen, die haben keine 
solchen Nebenwirkungen.
Ich würde selbst hier
OV_HREF_PIN & (1 << OV_HREF_PINNR)
wohl (OV_HREF_PIN & (1 << OV_HREF_PINNR) == (1 << OV_HREF_PINNR)) 
schreiben, das liefert definitiv false oder true zurück.
Ob das Ergebnis ohne den Vergleich wirklich als true und false 
interpretiert wird, kann schon vom Compiler abgängen. Die Diskussionen 
dazu im Netz sind endlos...

Gruß aus Berlin
Michael

von Olli Z. (z80freak)


Lesenswert?

Das geht ja schon alles sehr tief in die Materie, alles hochspannend und 
sehr informativ!

Ich sehe das wir schon noch auf unterschiedlichen Ebenen unterwegs sind 
(Arduino, Atmega direkt, ESP, ARM). Persönlich würde ich auch die ohne 
Overhead vorziehen, sprich AVR direkt, selbst wenn ein Arduino-Board 
genutzt wird. Da muss man dann aber wirklich alles selbst machen, inkl. 
SPI.

Wäre das denn ein „kleinster gemeinsamer Nenner?“ für unser 
Gemeinschaftsprojekt?!

Ich glaube wir sind uns alle einige das wir mit dem Atmega328 sehr bald 
an seine Leistungsgrenze stoßen werden. Dann darf man schonmal über 
einen Nachfolger nachdenken. Da wird es in der AVR Liga schnell dünn. 
Wenn wir also die Core-Logik übertragen wollen, sollten wir drauf achten 
alle Prozessorspezifischen Aufrufe in Subroutinen auszulagern. Wenn wir 
das gleich von Anfang an machen, könnten wir vielleicht alle hier 
vertretenen Plattformen integrieren, als auch einen späteren Umstieg 
erleichtern.

P.S.: Ein Github Repository würde ich hier, unterstützend zum Thread und 
Wiki bereitstellen: https://github.com/igittigitt/ov7670
Schickt mir mal Eure Github-Accounts und ich trage die als Collaborators 
ein, damit ihr das nach belieben nutzen könnt. Gleiches gilt fürs Wiki. 
Ich hoffe das ist ok und ich nehm das hier keinem „weg“. Wenn doch, 
bitte gleich schreien, nichts ist in Stein gemeißelt! :-)

: Bearbeitet durch User
von Olli Z. (z80freak)


Lesenswert?

Andreas, Deine Überlegungen zum ISR würde ich 100% teilen. Das Problem 
sind die cli()/sei() Aufrufe innerhalb der Routine. Diese Befehle sind 
für Programmcpde außerhalb von ISRs gedacht, die nicht durch einen 
solchen unterbrochen werden sollen.

von Olli Z. (z80freak)


Lesenswert?

Viktor, ich stimme mit Dir überein, lesbarer Code ist die Basis für eine 
sinnvolle Zusammenarbeit und erfolgreiches Debugging. Und lieber 
Unterfunktionen anstelle Makros.

von Olli Z. (z80freak)


Lesenswert?

Sollen wir mal versuchen einen Programmablauf zu skizzieren und 
Unterfunktionen zu nennen, die man dann mit Code füllen kann? Ich denke 
mit diesem Gedankengerüst kommt man schneller zum Ziel, weil es uns 
etwas „zusammenhält“.

von Olli Z. (z80freak)


Lesenswert?

David, könntest Du mir mal kurz erklären wie ich das mit dem Debug-Wire 
aufsetze? Welche AVR IDE benutzt Du?

von Andreas S. (igel1)


Lesenswert?

@Victor:

Yep, Dein Makro sieht tatsächlich etwas schöner aus.
Gründe, die gegen so ein Makro sprechen, fallen mir ebenfalls nicht ein,
was nicht heißt, dass es eventuell doch welche gibt.

Ich selbst bevorzuge daher immer "mainstream coding style".
Ist halt etwas Geschmackssache.


@OV7670-Kämpfer:

Olli schlug vor:
> Sollen wir mal versuchen einen Programmablauf zu skizzieren und
> Unterfunktionen zu nennen, die man dann mit Code füllen kann? Ich denke
> mit diesem Gedankengerüst kommt man schneller zum Ziel, weil es uns
> etwas „zusammenhält“.

Mit Blick auf die arg beschränkten AVR-Ressourcen, würde ich ein
Polling zum Einlesen einer beliebigen Zeile vorschlagen.

Und da das RAM des ATmega bereits nach dem Einlesen von nur
einer Zeile randvoll sein dürfte, würde ich nach dem Einlesen
der Zeile (evtl. sogar schon während des Einlesens), die
gelesenen Werte an den PC (oder an mein TFT-Display) versenden.

Erst wenn das erledigt ist, kann ich die nächste Zeile einlesen.
Dabei sollte mir bewußt sein, dass ich mich zu diesem Zeitpunkt
vermutlich schon X-Zeilen weiter im Frame befinde und daher die
nächste Zeile im folgenden Frame abpassen muß.

Der Ablauf wäre also:
1
N=0
2
while (N < Zeilenzahl_eines_Frames) {
3
  Framebeginn abpassen
4
  Alle Pixel der N.-ten Zeile einlesen
5
  Alle Pixel der N.-ten Zeile ausgeben
6
  N = N+1
7
}

Das Einlesen aller Pixel der N.-ten Zeile würde ich wie folgt angehen:

Zunächst einen scharfen Blick auf die Abbildungen "Horizontal 
Synchronization" und "VGA timing" aus meiner Lieblings-OV7670-Page 
werfen:
http://embeddedprogrammer.blogspot.de/2012/07/hacking-ov7670-camera-module-sccb-cheat.html

Oder Direktlinks:
http://2.bp.blogspot.com/-K-OIuy-inUU/UA2gp3SYgYI/AAAAAAAAAPg/Gure3RWI8G4/s1600/href.png
http://3.bp.blogspot.com/-cjOYTMj4C4M/UA2kV-db8GI/AAAAAAAAAPs/rtCGSIGjOHo/s1600/vga.png

Daraus läßt sich entnehmen:

- Die erste Zeile eines Frames beginnt,
      wenn VSYNC von Hi auf Low geht

- Die Zeile N beginnt,
      wenn HREF genau zum N.ten mal von Low auf Hi geht

- Die jeweiligen Pixel einer Zeile stehen bereit,
      wenn PCLK von Low auf Hi geht

- Die Zeile ist beendet,
      wenn HREF auf Low geht


Daraus ergibt sich folgender Pseudo-Code:
1
// Zunächst warten wir auf den Beginn eines neuen Frames
2
// (sprich: VSYNC soll von Hi auf Low springen ...)
3
4
while (VSYNC == LOW) {}   // alten Frame auslaufen lassen ...
5
while (VSYNC == HI)  {}   // Hi-Schulter abwarten ...
6
7
// Wenn Du hier ankommst, ist VSYNC von Hi auf Low 
8
// gesprungen => Framestart
9
10
// Nun pickst Du Dir die N-te Zeile raus (hier: nline) ...
11
// (Notiz: wir zählen ab 0, d.h. die erste Zeile ist nline=0)
12
13
linecnt = 0
14
15
while (nline > linecnt) {
16
   while (HREF == LOW)  {}
17
   linecnt ++
18
   while (HREF == HI)   {}
19
}
20
21
// Wenn Du hier ankommst, ist gerade die (N-1)-te Zeile vorbei
22
// und HREF ist von Hi auf Low gesprungen
23
24
// Jetzt geht's ans Einlesen der N-ten Zeile ...
25
// Pixel-Zählung beginnt bei 0
26
27
pixelcnt = 0
28
29
wunschcode1                      // Minimal Zeit, um Wunschcode auszuführen
30
while (HREF == LOW) {}           // Erst die Low-Schulter zum Zeilen-
31
                                 // beginn abwarten
32
33
while (HREF == HIGH) {
34
   wunschcode2                   // Während der PCLK-Low-Schulter ist
35
                                 // minimal Zeit, um Wunschcode auszuführen
36
   while (PCLK == LOW) {}        // Warten auf Pixeldaten
37
   pixel[pixelcnt] = OV7670_data // Daten einlesen
38
                                 // Nicht vergessen: Bei YCrCb422 besteht
39
                                 // ein Pixel aus 2 Bytes. Das pixel-Array
40
                                 // wird als 2-mal so lang wie die Anzahl
41
                                 // der Pixel in einer Zeile (oder man
42
                                 // wirft die Farbinfos weg und nimmt nur
43
                                 // den Y-Wert.
44
   pixelcnt++
45
   wunschcode3                   // Minimal Zeit, um Wunschcode auszuführen
46
   while (PCLK == HIGH) {}
47
   wait(tphl)                    // Etwas warten, da HREF nach dem letzten
48
                                 // Pixel erst um tphl verzögert auf Low
49
                                 // geht
50
}
51
52
pixelarray_ausgeben(pixel)

Zu beachten:
1
  T(wunschcode1)   <   144 * tp  // tp: siehe Timing-Diagramme
2
  T(wunschcode2)   <   (1/2 * tp - tphl)
3
  T(wunschcode3)   <   (1/2 * tp)

Soweit mein Vorschlag.

Wie immer gilt: bitte nicht ohne genaues Nachprüfen übernehmen, denn
alles ist ungetestet und der Code ist ausschließlich aus den
TimingDiagrammen abgeleitet. Da ist bestimmt noch das eine oder
andere Schnitzerchen drin ...

Viele Grüße

Igel1

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> PS und OffTopic: heute 3 Stunden mit 2 Obi/Norma WLAN-Steckdosen
> verbracht.

Auch wenn das wirklich voll Off-Topic war und wir hier nicht weiter 
abschweifen sollten, so habe ich durch Deinen Hinweis erstmals erfahren,
dass es inzwischen alternative Firmware für Sonoff's gibt - das war
sehr interessant für mich. Danke für den Hinweis!

Viele Grüße

Igel1

von Olli Z. (z80freak)


Lesenswert?

Andreas S. schrieb:
> Mit Blick auf die arg beschränkten AVR-Ressourcen, würde ich ein
> Polling zum Einlesen einer beliebigen Zeile vorschlagen.
Das halte ich auch für eine gute Idee. Da wir im Moment nichts anderes 
tun wollen als Daten von der Kamera zu lesen, gibt es eigentlich keinen 
Grund sich der Komplexität einer ISR auszuliefern. Parallel zu dieser 
würde unser Main-Code nämlich nur in einer Sinnlos-Schleife rotieren. 
Ich glaub wir sollten erstmal versuchen das mit reinem Polling hin zu 
bekommen.

Also die Main startet nach der Initialisierung mit einem Poll auf VSYNC 
und dann gehts los.

Wir arbeiten doch mit QQVGA, also 160x120 Bildpunkten. Der XCLK wird mit 
8 MHz gefahren und der PCLK schwingt sich somit auf 50 kHz ein. Das 
macht eine Periodenzeit von 20µs, unser Bezugslevel.

Nehmen wir weiter an das wir die Bilddaten im RGB565 oder RGB555 
Ausgabemodus übertragen. Ist etwas ineffektiver als YUV, aber erstmal 
leichter zu verarbeiten. Jede Bildzeile hat also dann eine Länge von 320 
Byte. Das gesamte Bild eine Größe von 38.400 Byte. Der SRAM des 
Atmega328p ist 2.048 Byte groß, wovon ein guter Teil auch für das 
Programm benötigt wird. Ich denke aber ein Zwischenpuffern von 2-3 
Zeilen sollte schon drin sein.

Das Setup des OV7670 wäre dann doch so:
1
1.) PCLK einstellen
2
    Prescaler-Register OV_SCCB_CLKRC (0x11) auf "Disable Double clock (Bit7=0)", "Prescale external clock (Bit6=0)", "durch 16 teilen (Bit0-5=01111)" (=0b0000 1111, =0x0F) stellen
3
2.) Bildformat QCIF und RGB.
4
    Register COM7 (0x12) mit Wert 0b0001 0100 laden.
5
3.) Skalierung einstellen
6
    Register COM3 (0x0C) mit Wert 0b0000 1000 laden.

>
1
> N=0
2
> while (N < Zeilenzahl_eines_Frames) {
3
>   Framebeginn abpassen
4
>   Alle Pixel der N.-ten Zeile einlesen
5
>   Alle Pixel der N.-ten Zeile ausgeben
6
>   N = N+1
7
> }
8
>
Du würdest also dadurch "Zeit schinden" indem Du einfach nur eine Zeile 
pro Frame liest und überträgst? Ok, für den Anfang eine durchaus 
brauchbare Methode. Da hat man vermutlich genug Zeit die Daten an den PC 
zu bekommen.

> - Die erste Zeile eines Frames beginnt,
>       wenn VSYNC von Hi auf Low geht
Verstanden und bestätigt.

> - Die Zeile N beginnt,
>       wenn HREF genau zum N.ten mal von Low auf Hi geht
Verstanden und bestätigt.
Laut Timingtabelle ist das nach 17*PCLK, also 340us der Fall. Wir haben 
also von der Erkennung der fallenden VSYNC-Flanke bis zur ersten Prüfung 
auf eine steigende Flanke diese Zeit zur freien Verfügung. Ob das für 
einen Kurzlurlaub reicht? ;-)

> - Die jeweiligen Pixel einer Zeile stehen bereit,
>       wenn PCLK von Low auf Hi geht
Verstanden und bestätigt, mit einer kleinen Anmerkung: Ich würde hier 
nur nicht von Pixeln, sondern von Bytes sprechen. Denn wieviele Byte pro 
Pixel benötigt werden, hängt vom Bildausgabeformat ab. In der Regel sind 
es aber immer 2 Byte pro Pixel, da die Kamera keinen nativen 
Graufstufenmodus kennt. Theoretisch könnte man den erreichen indem man 
die Kamera auf YUV-Ausgabe stellt und immer nur das erste Byte 
(Y=Luminanz) hernimmt und das zweite einfach ignoriert.

> - Die Zeile ist beendet,
>       wenn HREF auf Low geht
Verstanden und bestätigt. Das ist dann nach PCLK * H-Pixel der Fall. 
Also 20us * 160 = 0,0032us = 3,2 ms. Anschließend folgt noch die 
Austastlücke von 144 PCLK, also nochmal 0,00288us oder 2,88 ms. Dies 
wäre für mich die Zeit die wir hätten um störungsfrei zum PC zu 
übertragen.

>
1
>
> Soweit mein Vorschlag.
PERFEKT würde ich sagen, und von der Form her exakt das was wir 
diskutieren sollten bevor auch nur eine einzige Zeile Code geschrieben 
wird :-)

Ich bin begeistert! Gern würd ich das alles mal irgendwie im Wiki 
ablegen, vielleicht auch mal mit Visio ein einfaches PAP dazu zeichnen. 
Es sind ja die vielen kleinen Nebeninformationen zum Timing, etc. die 
man später braucht, wenn man "mehr will".

Oli

von Andreas S. (igel1)


Lesenswert?

Olli Z. schrieb:
> Andreas S. schrieb:
>> Mit Blick auf die arg beschränkten AVR-Ressourcen, würde ich ein
>> Polling zum Einlesen einer beliebigen Zeile vorschlagen.
> Das halte ich auch für eine gute Idee. Da wir im Moment nichts anderes
> tun wollen als Daten von der Kamera zu lesen, gibt es eigentlich keinen
> Grund sich der Komplexität einer ISR auszuliefern.

Ehrlich gesagt wäre der ISR-Ansatz der einfachere.
Aber damit kommt Ihr nicht weit, weil Aufruf und Rücksprung der ISR
halt viel Resourcen verbrauchen.

> Parallel zu dieser
> würde unser Main-Code nämlich nur in einer Sinnlos-Schleife rotieren.
> Ich glaub wir sollten erstmal versuchen das mit reinem Polling hin zu
> bekommen.

Okay.

> Also die Main startet nach der Initialisierung mit einem Poll auf VSYNC
> und dann gehts los.

Yep.

> Wir arbeiten doch mit QQVGA, also 160x120 Bildpunkten. Der XCLK wird mit
> 8 MHz gefahren und der PCLK schwingt sich somit auf 50 kHz ein. Das
> macht eine Periodenzeit von 20µs, unser Bezugslevel.

Legt Euch nicht von vorne herein auf QQVGA fest, sondern macht
den Code flexibel / konfigurierbar.

> Nehmen wir weiter an das wir die Bilddaten im RGB565 oder RGB555
> Ausgabemodus übertragen. Ist etwas ineffektiver als YUV, aber erstmal
> leichter zu verarbeiten.

Davon würde ich klar abraten.
Fangt erst einmal mit YUV an und verarbeitet zunächst nur das Y-Signal.
Das ergibt zwar nur SW-Bilder, aber das ist ideal, um überhaupt erst
einmal die Kamera einstellen zu können. Z.B. war ich lange Zeit der
Meinung, dass mein Programm nicht funktioniert und dabei war einfach
nur die Linse massiv unscharf eingestellt.

> Jede Bildzeile hat also dann eine Länge von 320
> Byte. Das gesamte Bild eine Größe von 38.400 Byte. Der SRAM des
> Atmega328p ist 2.048 Byte groß, wovon ein guter Teil auch für das
> Programm benötigt wird. Ich denke aber ein Zwischenpuffern von 2-3
> Zeilen sollte schon drin sein.

Claro, kann man gerne später dazuprogrammieren.

>
> Das Setup des OV7670 wäre dann doch so:
>
>
1
> 1.) PCLK einstellen
2
>     Prescaler-Register OV_SCCB_CLKRC (0x11) auf "Disable Double clock 
3
> (Bit7=0)", "Prescale external clock (Bit6=0)", "durch 16 teilen 
4
> (Bit0-5=01111)" (=0b0000 1111, =0x0F) stellen
5
> 2.) Bildformat QCIF und RGB.
6
>     Register COM7 (0x12) mit Wert 0b0001 0100 laden.
7
> 3.) Skalierung einstellen
8
>     Register COM3 (0x0C) mit Wert 0b0000 1000 laden.
9
>

Auch wenn's super wichtig ist - ich bin jetzt einfach mal zu faul,
das zu überprüfen ... Ich hoffe, ein anderer erbarmt sich.

Da man hier eine ganze Menge falsch machen kann, würde ich mit
einer Konfiguration beginnen, die nachweislich bei anderen Leuten
im Internet funktioniert hat.

>
>>
1
>> N=0
2
>> while (N < Zeilenzahl_eines_Frames) {
3
>>   Framebeginn abpassen
4
>>   Alle Pixel der N.-ten Zeile einlesen
5
>>   Alle Pixel der N.-ten Zeile ausgeben
6
>>   N = N+1
7
>> }
8
>>
> Du würdest also dadurch "Zeit schinden" indem Du einfach nur eine Zeile
> pro Frame liest und überträgst? Ok, für den Anfang eine durchaus
> brauchbare Methode. Da hat man vermutlich genug Zeit die Daten an den PC
> zu bekommen.

Richtig - das war der Grundgedanke.
Im nächsten Schritt läßt sich das natürlich deutlich verfeinern und
ist in Teilen im Pseudocode schon "vorgedacht":

Ihr könnt die max. Geschwindigkeit mit einer Art FiFo-Puffer erreichen:
vorne schreibt Ihr in den Puffer rein (so lange bis der Puffer voll ist)
und hinten nutzt holt Ihr die Bytes raus und übertragt sie an den PC
oder ein TFT-Display. Jedes übertragene Byte leert den FiFo-Puffer
dann wieder.

Sobald genug Platz für eine weitere Zeile ist, kann diese wieder 
eingelesen und gespeichert werden, während hinten weiterhin die Bytes 
entnommen und rausgeschrieben werden.  Das Entnehmen und rausschreiben 
kann in den oben markierten "Wunschcode"-Zeilen passieren.

>
>> - Die erste Zeile eines Frames beginnt,
>>       wenn VSYNC von Hi auf Low geht
> Verstanden und bestätigt.
>
>> - Die Zeile N beginnt,
>>       wenn HREF genau zum N.ten mal von Low auf Hi geht
> Verstanden und bestätigt.
> Laut Timingtabelle ist das nach 17*PCLK, also 340us der Fall. Wir haben
> also von der Erkennung der fallenden VSYNC-Flanke bis zur ersten Prüfung
> auf eine steigende Flanke diese Zeit zur freien Verfügung. Ob das für
> einen Kurzlurlaub reicht? ;-)

Mindestens ;-)
Alternativ kann man in ca. 80us bei 115,2 kbit/s ein Byte übertragen.

>
>> - Die jeweiligen Pixel einer Zeile stehen bereit,
>>       wenn PCLK von Low auf Hi geht
> Verstanden und bestätigt, mit einer kleinen Anmerkung: Ich würde hier
> nur nicht von Pixeln, sondern von Bytes sprechen. Denn wieviele Byte pro
> Pixel benötigt werden, hängt vom Bildausgabeformat ab. In der Regel sind
> es aber immer 2 Byte pro Pixel, da die Kamera keinen nativen
> Graufstufenmodus kennt. Theoretisch könnte man den erreichen indem man
> die Kamera auf YUV-Ausgabe stellt und immer nur das erste Byte
> (Y=Luminanz) hernimmt und das zweite einfach ignoriert.

Genau damit würde ich an Eurer Stelle anfangen.

>
>> - Die Zeile ist beendet,
>>       wenn HREF auf Low geht
> Verstanden und bestätigt. Das ist dann nach PCLK * H-Pixel der Fall.
> Also 20us * 160 = 0,0032us = 3,2 ms.

Nicht ganz: wie Du oben selber schreibt, benötigt man immer 2 Bytes
pro Pixel, also in Deinem Beispiel 6,2 ms für eine Zeile im YCrCb422-
Format.

> Anschließend folgt noch die
> Austastlücke von 144 PCLK, also nochmal 0,00288us oder 2,88 ms. Dies
> wäre für mich die Zeit die wir hätten um störungsfrei zum PC zu
> übertragen.

... Könnte man meinen, aber leider bekommst Du bei 115,2kbit/s gerade
mal max. 36 Bytes in dieser Zeit per USART über die Leitung geschoben.

Die horizontale Austastlücke reicht also nicht zur Übertragung
der Zeileninformation.

Das wiederum bedeutet im obigen Pseudocode:
es wird auf den nächsten Frame gewartet und dort die nächste Zeile
entnommen. Will sagen: pro Zeile benötigt Ihr bei diesem Ansatz einen
Frame.

Mit der weiter oben von mir berechneten "Spaßgrenze" liegt Ihr bei
einer PCLK von 50kHz bei einer Framerate von 1 Frame / 16 Sekunden ...
(wenn die Kamera überhaupt so niedrige PCLK's erlaubt)
Um also 120 Zeilen zu übertragen braucht's hier 120 * 16s = 32 Minuten.

Das wird nicht spaßig werden.

Hmmm - ich glaube, vor dem Coding ist hier doch noch etwas
Konzept-Tuning nötig ...  (wozu ich aber vermutlich heute und die
nächsten Tage nicht mehr kommen werde => Ihr seid dran ...)

>
>>
1
>>
>> Soweit mein Vorschlag.
> PERFEKT würde ich sagen, und von der Form her exakt das was wir
> diskutieren sollten bevor auch nur eine einzige Zeile Code geschrieben
> wird :-)
>
> Ich bin begeistert! Gern würd ich das alles mal irgendwie im Wiki
> ablegen, vielleicht auch mal mit Visio ein einfaches PAP dazu zeichnen.
> Es sind ja die vielen kleinen Nebeninformationen zum Timing, etc. die
> man später braucht, wenn man "mehr will".
>
> Oli

Nur zu ...

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Hallo:

Olli schrieb:

>Von daher wäre mein Vorschlag bevor wir hier über Code diskutieren, den
>Programmablauf zu beschreiben. Also was genau wie und warum erfolgen
>soll. Darauf basierend kann dann jeder seinen Code schreiben, um zu
>lernen und am Ende entwickeln wir einen gemeinsamen, z.B. in Github.

Ja. sehe ich genauso. (siehe meinen Post vom 28.03. 13:17)
Den hat aber jeder hier gekonnt ignoriert :D
Ich habe schon ein Github Projekt aufgesetzt und da drin zwischen 
Arduino und AVR unterschieden, um den transfert auch besser 
hinzubekommen.
Aber wir können auch gerne dein Repository nehmen. Wenn du dich damit 
auskennst, ist es vielleicht sogar besser, wenn du die Adminstration 
übernimmst, weil ich neu auf dieser Platform unterwegs bin.
Da denke ich auch, dass wir das Projektdashboard gut nutzen können, um 
aufkommende Ideen festzuhalten.

>Ein guter Einstieg hierzu wäre, Deine Ideen zur Initialisierung in
>Subroutinen zu gießen.

Ja sehe ich ebenfalls so. Ich nutze die Main-Funktion nur imme rzum 
ausprobieren. Alles was sich dann als "richtig" erweist packe ich dann 
in Routinen.

von Igel1:
>aber Deine Art der PIN-Abfrage
>scheint mir etwas seltsam:

Jap... keine Ahnung was mich da geritten hat. Deine darstellung ist die 
wohl gängigste, an die wir uns auch halten sollten.
Werde ich sofort ändern. (Nichtsdestotrotz sollte meine auch 
funktionieren. Daher scheint das für mich nicht die Ursache des Problems 
zu sein)

>Außerdem wäre es gut, wenn Du den gesamten Code hier
>einstellst/anhängst.

Jap. die werden in der OV7670_init initialisiert. Ich wollte hier nicht 
den Thread damit sprengen.
Ich denke wir werden das dann jetzt über GitHub realisieren, was das 
ganze übersichlticher machen sollte.

@Michael

>hatte ich auch schonmal drum gebeten
Ebenfalls richtig. Tut mir leid hatte ich vergessen. Aber da auf meinen 
Post mit dem Github keiner geantwortet hat war mir auch nicht klar, ob 
das noch gewünscht ist.


@Igel1

>Dieses (vermutlich von Dir gewünschte) Verhalten konterkarrierst
>Du, indem Du sei() noch innerhalb Deiner ISR ausführst.
>Das dürfte wiederum zu rekursiven ISR-Aufrufen führen.

>Nun zurück zu Deiner ursprünglichen Frage/Aussage:
>> Trotzdem sehe ich die ISR-Routine nicht auf dem Oszi.
>Ich kontere mal und sage: trotzdem sehe ich nirgendwo, dass
>Du PORTB überhaupt als Ausgang geschaltet hast ...

Rekursiv heißt doch, dass die Funktion aus der Funktion selber 
nocheinmal aufgerufen wird.
Also in dem Beispiel wäre es ja quasi nur indirekt, wenn aus der ISR 
nochmal in die ISR gesprungen wird.
Das scheint aber ja dann nicht zu gehen, wenn die Interrupts erst beim 
Rausspringen aus der ISR freigegeben werden.
Was ist dann nach deinem Verständnis ein Rekursiver aufruf?

Die initialisiserung des PORTB wird wie schon erwähnt ebenfalls in der 
OV7670_init ausgeführt.
Richitg, dass könnt ihr nicht sehen aber ich habe es schon mehrfach 
überprüft.

Wird dann sicherlich auch in GitHub als ganzes nachvollziehbar sein.

@Michael:

>Ich würde selbst hier
>OV_HREF_PIN & (1 << OV_HREF_PINNR)
>wohl (OV_HREF_PIN & (1 << OV_HREF_PINNR) == (1 << OV_HREF_PINNR))
>schreiben, das liefert definitiv false oder true zurück.
Das finde ich bisher noch am besten.

Wow ist ja eine Menge zusammengekommen diese Woche.
die letzen Posts mit dem Polling muss ich nochmal überdenken und sacken 
lassen. Für die ersten "Shots" sicherlich machbar.

Zu dem Verfahren mit dem Debug-Wire mache ich morgen ein kleines 
Tutorial (Habe ich zurzeit aber nur am UNO zum laufen gebracht, weil es 
erheblich drauf ankommt, wie die Schaltungstechnische Anbindung der 
Reset Leitung ist.
mehr Dazu morgen (bzw. heute).

lg. und danke für die rege Unterstützung.

David

von David D. (saturi)


Lesenswert?

Hier der versprochene Post zum Debug-Wire:

Benötigt:
Hardware:
Arduino UNO, AVR-Dragon
Software IDE:
Atmel-Studio

Der Atmega328P unterstützt das besagte Debug-Wire. Dazu wird mittels des 
AVR-Dragon (oder einem anderen Programmer) der/die/das Fuse DWEN mittels 
ISP Programmierung gesetzt. Vorsicht! Hier besteht jetzt die Gefahr sich 
auszusperren (wie mir erst kürzlich passiert). Das Debug-Wire 
funktioniert nämlich nur, wenn die Reset-Leitung vollkommen frei ist. 
Sprich wenn ich die Fuse gesetzt habe und Debug-Wire nicht funktioniert 
komme ich nicht mehr zurück in den ISP-Modus und muss mit HighVoltage 
Programmierung die Fuse wieder entfernen.

Beim Arduino UNO ist oben auf der Platine eine Kontaktbrücke vorgesehen. 
(Bei mir auf dem SaintSmart Board steht dort Reset ON. Diese brücke kann 
man einfach mit einem kleinen Schraubenzieher wegkratzen. Dann 
funktioniert mit dem UNO das DebugWire problemlos. Bei dem Nano geht das 
nicht ohne weiteres.

hier habe ich eine wie ich finde ausführlich und gut beschriebene 
Anleitung gefunden:

http://www.hilltop-cottage.info/blogs/adam/debugging-arduino-using-debugwire-atmel-studio-and-an-avr-dragon/

Falls danach noch weitere Fragen auftreten sollten einfach melden :)

von Michael U. (amiga)


Lesenswert?

Hallo,

ich bin ja wegen des Thread-Titels hier reingeraten weil ich mir mal 
eine OV7670 mitbestellt hatte und damit rumspielen wollte.
Inzwischen ist mir aber völlig unklar, wohin dieser Thread eigentlich 
ziehlt.
Die Absicht, mit der Kamera an einem Mega328 irgendwie irgendein Bild zu 
bekommen und irgendwie anzuzeigen/zum PC zu übertragen/zu speichern, 
scheint ja völlig unwichtig zu sein.
Die Diskussionen über Programmierstile, StyleGuides, Programmstrukture 
usw. scheinen ja Vorrang zu haben.
Ich habe damit kein Problem, es ist aber nicht der Grund meines 
Interesses.
Ich werde weiter mitlesen, sehe aber im Moment den Sinn der ganzen Übung 
nicht.

Ich bin eigentlich der Typ, der gern das macht, was nicht geht. ;)
Dazu muß das aber (für mich) irgendeinen Sinn und Zweck haben. Ein 
brauchbares "Foto" einer kleinen Kamera mit dem Mega328 zu erstellen, 
irgendwie zu übertragen und dann eben anzeigen wäre ein Zweck.
Das ist aber mit der OV7670 so nicht machbar. Referenz wäre für mich 
immernoch mein Posting zur alten DC3840. Also 640x480 in Farbe als 
Snapshot mit Übertragungszeit um 10-15s. Das hat der Mega32 vor Jahren 
als Webserver hinbekommen. Die OV7670 bietet dazu aber von ihren 
technischen Voraussetzungen keine Möglichkeit. Dazu wäre externer Ram 
nötig, am Mega328 eben SPI-Ram mit mehr als 256kB oder die OV7670 mit 
FIFO drauf.

Ich habe vorhin beim Googeln diesen link gefunden:
http://www.instructables.com/id/OV7670-Arduino-Camera-Sensor-Module-Framecapture-T/
Ich habe spaßhalber mal auf einen Arduino Nano gepackt und sein 
Javaprogramm installiert, extra noch ein 32Bit Jave installiert.
Es läuft soweit, er liest ein 320x240 in s/w aus und schikct es mit 
500kBaud direkt zum PC. Auf dem PC wartet seine Java-Software af einen 
Bildanfang, klebt den passenden BMP-Header dazu und speichert es in 
einen Ordner. Es kommt ca. alle 2-3s ein Bild an. Qualität war 
unbrauchbar, erkennbar, aber Streifen usw. Da gibt es aber einen langen 
Thread bei arduino.cc zu:
https://forum.arduino.cc/index.php?topic=159557.0

Ich habe hier jetzt nur gepostet, weil es ja ursprünglich mal um die 
Kamera am Mega328 ging...

Ich wünsche den Beteiligten natürlich weiterhin viel Erfolg.

Gruß aus berlin
Michael

von Michael U. (amiga)


Lesenswert?

Hallo,

zu DebugWire:

David D. schrieb:
> Beim Arduino UNO ist oben auf der Platine eine Kontaktbrücke vorgesehen.
> (Bei mir auf dem SaintSmart Board steht dort Reset ON. Diese brücke kann
> man einfach mit einem kleinen Schraubenzieher wegkratzen. Dann
> funktioniert mit dem UNO das DebugWire problemlos. Bei dem Nano geht das
> nicht ohne weiteres.

warum sollte ich DebugWire in dieser Kombination benutzen wollen? Weil 
es DebugWire gibt?
Wenn man den UNO wieder automatisch aus der IDE programmieren will muß 
der 100nF aber wieder ran. Beim Nano muß man ihne halt selber suchen 
(bei meinem unter neben dem Elko am Spannungsregler). Bei meiner 
Nano-Version ist auch der PullUp am Reset mit 1k bestückt statt mit 10k 
wie im Schaltplan. Kann sein, daß man den auch noch tauschen müßte.

In der ArduinoIDE kann man auch die Serielle gut genug zum Debug nutzen, 
früher kam bei mir auf die kleinen AVR eben ein SoftUART rauf, der 
konnte nur Ausgaben über einen PIN als TX.
Ein Controller würfelt nicht, der macht genau was man ihm gesagt hat, 
auch wenn es nicht unbedingt das ist, was man sagen wollte und erwartet. 
;)

Egal ob DebugWire oder Debugausgaben über einen UART: in jedem Fall 
verändert man an der Stelle das Timing bis zum Stillstand und kann 
Abhängigkeiten mit externer Hardware kaum sinnvoll erfassen weil die 
davon nichts weiß...

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Hallo Michael,

der Exkurs zum Debugwire kam nur auf Anfrage von Olli und soll in diesem 
Thread hier auch nicht weiter thematisiert werden. Mir hat er bis jetzt 
geholfen, den ein oder anderen Fehler im Code zu identifizieren. Das das 
über eine mögliche Seirielle-Debug Funktionen von der Arduino-IDE aus 
möglich ist mag richtig sein. Damit habe ich noch keine Erfahrungen 
gemacht.

Zum thematischen ausufern gebe ich dir recht. Hier werden soviele 
Informationen zuzsammen getragen, dass es schwer wird, das ganze 
beisammen zuhalten. Daher hoffe ich auf Olli  und sein Github repository 
damit wir da einen gemeinsamen Code-Überblick generieren können und uns 
in diesem Thread wieder auf die tatsächlichen Fortschritte konzentrieren 
können und die kleineren Code-Diskussionen ins GitHub verlagern.

Ich hoffe nicht, dass du das Interesse verlierst, auch wenn es an der 
ein oder anderen Stelle einmal ausufert :)

um das klar zu stellen:

Ziel ist es mit dem OV7670 und dem Atmega328 und im ersten Schritt einem 
PC ein Bild zu erzeugen. Selbst wenn wir auf eine Framerate von 1/min 
kommen :D Hauptsache ein Bild.
Danach setzen wir uns ein neues Ziel

liebe Grüße

David

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Ziel ist es mit dem OV7670 und dem Atmega328 und im ersten Schritt einem
> PC ein Bild zu erzeugen. Selbst wenn wir auf eine Framerate von 1/min
> kommen :D Hauptsache ein Bild.
> Danach setzen wir uns ein neues Ziel

gut. Mein Problem zur zeit ist: die OV7670 scheint keinen Snapshot-Mode 
zu können. Also ein Bild "belichten" und dann genau dieses Bild aus dem 
Kameraspeicher identisch so oft auszulesen wie man möchte.
Sie scheint generell mit den eingestellten Werten zu grabben und dann 
eben das Bild abzuliefern. Damit wäre beim nächsten auuslesen der 
kameradaten das Bild nicht identisch mit dem vorhergehenden weil sich 
entweder im Bild was bewegt hat oder weil die Toleranzen des Sensors 
immer geringfügig abweichende Pixeldaten erzeugen. Damit wäre 
stückweises übertragen eines Bildes an den PC nicht ohne 
Bildfehler/Streifen/Doppelkonturen möglich.
Die Daten eines Bildes im Stück mit dem kleinen AVR zu übertragen ist 
möglich (siehe mein Link dazu) mit 500kBaud, vermutlich auch mit 1MBaud.
Da hat aber der AVR nur die Aufgabe die Daten der Kamera zu lesen und 
dem UART in die Hand zu dreüken. Es erfordert also auf dem PC eine 
spezielle Software, die die ankommenden Rohdaten in ein nutzbares Format 
packt.
Das macht oben im Link sein Java-Tool. Das ist aber für mich keine 
Option die einen wirklichen Nutzen hat. Ich sehe in der Kombi OV7670 und 
Mega328 im Moment keinen wenigstens theoretich realisierbaren Weg.

Damit lande ich zumindest dabei, daß ich mit dieser Kamera am ESP32 
weiterspiele. Da reicht sowohl der Ram um ein komplettes Bild einzulesen 
und die Rechenleistung um es dann per Webserver o.ä. zu übertragen.
Auch da kommen nur wenige Bilder/s raus, hier ist es aber die 
Kombination aus Kosten für OV7670 und ESP32. Damit kann ich "rumspielen" 
und für mich optimieren.
Reicht dann sicher z.B. als WLAN-Wettercam auf dem Balkon. Hat dann 10€ 
gekostet und ich habe vollen Zugriff auf die Software.
Für eine "richtige" Anwendung könnte ich einen raspi Zero W + seiner Cam 
nehmen. Sind dann eben 30€ und ein paar Skriptgeschichten. Brauche ich 
aber nicht...

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Hallo,

> Es erfordert also auf dem PC eine
>spezielle Software, die die ankommenden Rohdaten in ein nutzbares Format
>packt.
>Das macht oben im Link sein Java-Tool. Das ist aber für mich keine
>Option die einen wirklichen Nutzen hat. Ich sehe in der Kombi OV7670 und
>Mega328 im Moment keinen wenigstens theoretisch realisierbaren Weg.

wie von mir vor den Osterfeiertagen versprochen hatte ich mich da auch 
schon an ein Tool für den PC gemacht, dass die Empfangenen Daten in ein 
Bild umwandeln  soll. Da bin ich auch schon gut vorwärts gekommen. Da 
warte ich jetzt nur noch darauf, dass wir uns für ein 
"Übertragungsprotokoll" einigen, damit ich das dann auch Verwende. Löst 
die angesprochene Speicherkapazität nicht. Aber für einen ersten Shot 
würde ich mich auch mit Bildfehlern oder Doppelkonturen zufrieden geben.

liebe Grüße

David

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> wie von mir vor den Osterfeiertagen versprochen hatte ich mich da auch
> schon an ein Tool für den PC gemacht, dass die Empfangenen Daten in ein
> Bild umwandeln  soll. Da bin ich auch schon gut vorwärts gekommen. Da
> warte ich jetzt nur noch darauf, dass wir uns für ein
> "Übertragungsprotokoll" einigen, damit ich das dann auch Verwende. Löst
> die angesprochene Speicherkapazität nicht. Aber für einen ersten Shot
> würde ich mich auch mit Bildfehlern oder Doppelkonturen zufrieden geben.

und warum nicht "erstmal testen"? Ein festes Startzeichen asu wenigen 
Buchstaben und dann die Daten der Kamera hinterher. ComputerNerd hat RDY 
genommen. ;)
Die Anzahl Bytes pro zeile und die Anzahl Zeilen pro Bild stehen ja 
ohnehin mit dem Setzen der Cam auf eine Auflösung und ein Format fest, 
man kann also die ankommenden Bytes einfach mitzählen.
Da ich bei meinem LogicAnalyer vor Jahren die Daten des externen 32k Ram 
am AVR auch so übertragen habe weiß ich, daß es prinzipiell kein Problem 
mit 500000 Baud und den gängigen USB-Wandlern gibt. Auch FTDI, CP2102 
und CH340 können die auf den Arduinos.
Das Startzeichen sollte nur so sein, daß es in den Daten nicht oder nur 
sehr selten vorkommt, sonst bekommt der Empfänger Prpbleme den nächsten 
Bildanfang sicher zu erkennen. Klappt praktisch aber mit seinem RDY 
problemlos.
Die Beschaäftigung, die Kameraregister so zu setzen, daß möglichst ein 
erkennbares Bild dabei rauskommt, bleibt ohnehin. Normalerweise findet 
man dazu Application-Hinweise des Herstellers oder eben Beispiel von 
Leuten, die es schonmal geschafft haben.
Das kann etwas an Zeit kosten.

Die Senderoutime auf dem AVR ähnelt meiner damaligen weil sie eben nur 
aus Warten auf VSYNC, warten auf HSYNC und dann bei jedem PCLK Byte8s) 
holen und in den UART packen.
Das ist Beschäftigung für einen Nachmittag bis es prinzipiell läuft und 
Zeit für das Debug auf PC-Seite. Das hat mich damals einige Zeit 
gekosten (noch in VB6), weil die COM durchaus nicht meiner Meinung war 
was Empfangsbuffergröße usw. anging...

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Trotzdem sehe ich die ISR-Routine nicht auf dem Oszi.

Kleine Bitte:

Könntest Du, David, den o.g. Code hier einmal vollständig als Anhang 
einstellen? Zumindest so lang, bis Olli GitHub am Laufen hat?

Ich verstehe nämlich nach wie vor nicht, warum Dein Oszi nichts anzeigt.
Hast Du die von mir vorgeschlagenen Codeänderungen einmal ausprobiert?

Viele Grüße

Andreas

von David D. (saturi)


Angehängte Dateien:

Lesenswert?

Hallo Andreas,
wie gewünscht der Code. Ich habe gerade deine Code-Änderungen noch 
eingefügt und getestet (Also die mit der Bit-Abfrage, nicht das Polling) 
leider keine Änderungen.

Im Anhang ist das ganze Projekt.
interessieren muss dich aber nur die main, OV7670 und evtl. die Uart, 
wobei die da eigentlich nicht mitmischen sollte.

lg.

David

von Michael U. (amiga)


Lesenswert?

Hallo,

ich habe mir gerade mal den Spaß gemacht das Archiv zu entpacken und die 
nötigen Dateien in die ArduinoIDE zu werfen.
Compiler läuft durch, der Nano meldet sich.
unschön: ich habe auf die Schnelle keinen Hinweis oder Kommentar 
gefunden, der mir die aktuell eingestellte Bausrate ohne Suchen verraten 
hätte.
Der Kommentar in der UART.cpp bei UBRR0L ist recht witzlos weil ich da 
erst einen umrechnen muß und die Bits dazu raussuchen...
ok, sind 38400, der Nano meldet sich.
Fehler beim Versuch mit der Kamera zu reden?
Oh, TWI sind nur Dummys...
In OV7670.c geschaut.
void OV_SCCB_Init (void)
Nanu? Da werden I2C-Clock und I2C-Data hart auf Ausgang und H gesetzt???
I2C/TWI darf NIE einen festen H-Pegel auf den Leitungen haben, der Slave 
darf diese JEDERZEIT auf aktiv L ziehen und das ist dann unlustig für 
die Treiber der Beteiligten! I2C muß IMMER ein openDrain-Ausgang sein.
Ich habe hier erstmal abgebrochen, AVR und vermutlich auch die Kamera 
sind im Allgemeinen zwar "hart im Nehmen", aber quälen muß ich die Clock 
und Data-Leitungen nun auch nicht unbedingt...

Ich vermisse auch eine Komentarübersicht, welche Pins der Kamera auf 
welchen Portpins sind. Ein Vergleichen der Anschlüsse ist so mehr als 
mühsam. Als Liste brauchte ich nur rüberzugehen um zu sehen, daß ich 
vielleicht HSYNC auf einem anderen Pin habe und dann entweder 
umzustecken oder genau diese eine Zuordnung in der OV7670.h zu ändern.

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Hallo Michael,

>Nanu? Da werden I2C-Clock und I2C-Data hart auf Ausgang und H gesetzt???
>I2C/TWI darf NIE einen festen H-Pegel auf den Leitungen haben, der Slave
>darf diese JEDERZEIT auf aktiv L ziehen und das ist dann unlustig für
>die Treiber der Beteiligten! I2C muß IMMER ein openDrain-Ausgang sein.

Das scheine ich dann immernoch nicht verstanden zu haben... das mit dem 
openDrain. Da muss ich wohl nochmal in die Lektüre.

Kommentare sind es definitiv zu wenig, da gebe ich dir ohne weiteres 
recht. der Code war auch (noch) nicht für die Öffentlichkeit bestimmt.

lg.
David

PS: die Anschlüsse müssten aber so wie viel weiter oben mit Olli 
festgelegt, sein. (nur Pin 13 und evtl. die PCLK liegen an einem 
anderen)

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Kommentare sind es definitiv zu wenig, da gebe ich dir ohne weiteres
> recht. der Code war auch (noch) nicht für die Öffentlichkeit bestimmt.

das ist eine Fehleinschätzung. Kommentare müssen erstmal helfen, den 
eigenen Kram jederzeit zu verstehen. "Jederzeit" heißt auch, wenn man es 
aus 5 Jahren mal wieder anfasst.
Ich habe es mir zur Gewohnheit gemacht, in Stichpunkten sofort zu 
kommentieren wenn eine Funktion o.ä. erstmal irgendwie läuft.
Solche Sachen fäßt man nur selten nochmal an und dann bleiben sie 
unkommentiert.

>
> PS: die Anschlüsse müssten aber so wie viel weiter oben mit Olli
> festgelegt, sein. (nur Pin 13 und evtl. die PCLK liegen an einem
> anderen)
Wenn es sich jetzt ergibt, daß jemand, so wie ich jetzt, mal mittesten 
will oder in den Code schauen will, muß er mit dem Archiv klarkommen, 
wie es ist.
Ich nehme also den Mega328, die Kamera und will es mal schnell zusammen 
bauen. Ich lade mir oft Sourcearchive aus dem Internet wenn jemand eine 
Komponente nutzt, mit der ich gerade rumbastel. Wenn das aus irgendeinen 
Forum stammt, sieht es (leider) öfter ähnlich Deinem aus.

PS: das sollen alles nur Hinweise und Vorschläge sein und vielleicht 
auch ein wenig (20 jahre?) Hobby-Erfahrung dazu und die Erkenntnis, daß 
ich alte AVR-ASM-Sourcen von vor einigen Jahren auch nur mit Mühe wieder 
verstehe weil zuwenig oder die falschen Sachen kommentiert...

Als trost für Dich: meine ASM-Source von 2000 macht I2C auf einem 
90S8515 (Vorgänger des Mega8515) macht auch genau das falsch und spielte 
trotzdem.
Zumindest zusammen mit dem benutzten I2C-Slave (MAS3507D)...

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Hallo Michael,
>
>>Nanu? Da werden I2C-Clock und I2C-Data hart auf Ausgang und H gesetzt???
>>I2C/TWI darf NIE einen festen H-Pegel auf den Leitungen haben, der Slave
>>darf diese JEDERZEIT auf aktiv L ziehen und das ist dann unlustig für
>>die Treiber der Beteiligten! I2C muß IMMER ein openDrain-Ausgang sein.
>
> Das scheine ich dann immernoch nicht verstanden zu haben... das mit dem
> openDrain. Da muss ich wohl nochmal in die Lektüre.

Hier schön kurz und einfach erklärt (mit Schalter-Analogie):
Beitrag "Re: Open-Drain/Open-Source-Verständnis"

Oder hier ganz ausführlich:
https://www.elektronik-kompendium.de/sites/slt/1206121.htm

Oder natürlich Wikipedia:
https://de.wikipedia.org/wiki/Open-Collector-Ausgang

>
> Kommentare sind es definitiv zu wenig, da gebe ich dir ohne weiteres
> recht. der Code war auch (noch) nicht für die Öffentlichkeit bestimmt.

Es wäre jetzt etwas gemein, wenn ich zunächst laut nach dem Code
schreie, Du ihn widerwillig rausgibst (weil Du weißt, dass er noch
nicht allgemeinverständlich dokumentiert ist) und ich mich
anschließend über die schlechte Dokulage beklage ...

Ich sitze daher mit zusammengepressten Lippen auf meinem Stühlchen :-)

Allgemein stimme ich Michael zu: was man nicht sofort dokumentiert,
wird meist nie dokumentiert. Und was nicht dokumentiert ist, das
durchschaust Du bereits nach wenigen Wochen (bei mir: nach wenigen
Tagen) nicht mehr.

Im gleichen Atemzug muss ich allerdings auch zugeben, dass mein 
persönlicher, innerer Doku-Schweinehund mir auch so manchen Streich 
spielt und ich daher Null Legitimation habe, den mahnenden Zeigefinger 
zu heben ...

> PS: die Anschlüsse müssten aber so wie viel weiter oben mit Olli
> festgelegt, sein. (nur Pin 13 und evtl. die PCLK liegen an einem
> anderen)

Es wäre sehr nett, wenn Du die exakte PIN-Belegung/Verschaltung bitte 
noch nachreichen könntest. Für Dich ist das sicherlich ein Klacks, für 
einen
hilflosen Code-Reviewer ist Re-Engineering von PIN-Belegungen immer eine 
Strafarbeit ...

Ach ja: und schreibe bitte nochmals, welches Board (Arduino Nano?) und 
welche IDE (Atmel Studio, in welcher Version?) Du benutzt.

Viele Grüße

Igel1

: Bearbeitet durch User
von David D. (saturi)


Angehängte Dateien:

Lesenswert?

Huhu,

Ja... ihr habt ja recht :D ich gelobe Besserung.
Das mit der nachträglichen einfügen der Kommentare habe ich auch bei mir 
schon festgestellt, dass ich es nicht immer beibehalte...


Atmelstudio 7 (Version 7.0.1417)
zur xCLK Erzeugung nutze ich einen Arduino Nano an dem ich die CLK Out 
fuse gesetzt habe und daher an D8 ca. 16Mhz anliegen. (controller2 im 
Schaltplan)

ansonsten nutze ich für den Controller1 das Arduino UNO Board 
(abweichend vom Schaltplan), dass aber ja die gleichen Pins (zumindest 
die von mir genutzten) nach außen geführt hat wie der Nano. (der Grund 
ist einfach die Debugging Möglichkeit, mit der ich nur Erfahrungen auf 
dem UNO habe)
Allerdings sollte das Board einfach austauschbar sein.

lg.

David

Ps. Danke für die Links, die werde ich mir heute Abend direkt anschauen 
:)

von Olli Z. (z80freak)


Lesenswert?

Michael, in einigen Posts zuvor hast Du noch gemeint das wir uns zuviel 
um Konventionen scheren, als zu coden... und jetzt wird klar als 
unfertig, unoffziell, gehackter Code diskutiert. Hmmm... so ganz komm 
ich da jetzt nicht mehr mit.

Lasst uns doch kurz die Konventionen zuende bringen und gut. Dazu gehört 
neben einem Schaltplan, den bisherigen Erkenntnissen, natürlich auch ein 
Definitions-file und selbstverständlich auch sinnvolle Kommentarierung.

Zum Schaltplan:
Ich hatte auch schonmal einen in Eagle begonnen. Musste mir dafür ein 
OV7670 Item anlegen, weil ich keins fand. Grundsätzlich gehört der Plan 
im Quellformat, als PDF und Bild ins Reprository.

Zur Takterzeugung:
Einen zweiten Arduino würde ich nicht nehmen für den Takt, außer es 
besteht hier jemand auf 16 MHZ und nicht den 8 MHZ, die man auch ganz 
ohne Fuse-Tricks erzeugen kann. Hier würde ich den Hinweis mit dem CTC 
anstelle PWM nochmal aufgreifen. Für 16 MHz sind wir später beim lesen 
mit dem Mega328 eh viiel zu langsam, also wozu der Stress ;-)

Zur Plattform:
Ich glaube die Puristen sind hier in der Mehrzahl, also würde ich mich 
dem anpassen und „reinen“ AVR-Code programmieren, ganz unabhängig von 
Arduino Libs.

Zum I2C:
Die Arduino Lib „Wire“ berücksichtigt alles genannte (Open Drain, etc.). 
Da wir aber ohne auskommen wollen, könnte man sich eine entsprechende 
Lib für reinen AVR code suchen, oder die Lib portieren. Das wäre was 
fürs Repo :-)

Apropos Repo:
Das Projekt ist öffentlich und jeder darf ziehen: 
https://github.com/igittigitt/ov7670
NOCH steht nix drin. Ich werde aber das was hier als Konvention 
rauskommt dort hinterlegen (z.b. in der Readme oder als Wikiseite).
Ich fang, wenns recht ist, einfach mal damit an eine Struktur zu 
erstellen und die wichtigen Links zu sortieren.

So und jetzt bitte schnell einigen und ran an den Speck! Ich will auch 
mal bald ein Bild sehen ;-)))

Oli...


Diese sollte den Code

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Ich sitze daher mit zusammengepressten Lippen auf meinem Stühlchen :-)

:-)))
naja, ich bin auch alles andere als Vollkommen in der Beziehung, habe 
mir eben genau deshalb recht früh einen eigenen Rahmen gesteckt und 
halte mich daran. Meist... Oft...

Andreas S. schrieb:
> Ach ja: und schreibe bitte nochmals, welches Board (Arduino Nano?) und
> welche IDE (Atmel Studio, in welcher Version?) Du benutzt.

Ich habe seinen Ordner OV7670_Kamera in meinen Sketchordner der 
ArduinoIDE gekippt, nur die main.c in OV7670_Kamera.ino umbenannt. Den 
Nano eingestellt und compiliert und aus der IDE geflasht. Lief 
problemlos durch und meldete sich. Eigentlich aber nur, weil er mit 
#include "OV7670.c die Datei in main.c includioert hat. Ist eigentlich 
falsch, nur die .h wird includiert, die .c werden ja normalerweise 
einzeln vom Compiler bearbeitet und dann nur die Objekt-Files Files vom 
Linker zusammengeknotet.

Ich wollte erst ein AVR-Studio 4 Projekt draus machen, das liegt hier 
noch startbereit, allerdings irritierten mich die .cpp Files.
Wie kommt eigentlich die Namengebeung zustande? Ich habe auf den ersten 
Blick in den .cpp Files nichts C++ typisches gesehen, ist doch reines C?

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Ursprünglich wollte ich da mit Objektorientierung ran... aber das gab 
dann Probleme beim kompilieren, bzw. einfach schon nur bei der 
Verwendung von .cpp files. Warum die main jetzt noch ein .cpp file ist 
und warum es trotzdem Funktioniert kann ich grade nicht mehr beurteilen.

... Ich bereue es immer mehr das Projekt hochgeladen zu haben :D :D :D 
... nein.. immerhin lerne ich dadurch, dass mir andere meine Fehler 
aufzeigen.

das mit dem include des c-Files nicht richtig ist, wieso das noch dadrin 
steht weiß ich grade auch nicht mehr.... hust hätte ich das mal besser 
kommentiert hust

war vermutlich nur ein Test weil er die Header Datei nicht erkannt hat 
oder sonst was... Das hat mir - auch wenn es falsch ist - über 
Fehlermeldungen hinweggeholfen, an denen man aber sicher nochmal 
ansetzten müsste

@ olli
sehr gerne, ich brenne auch schon förmlich. Es freut mich das du mit auf 
die Amtel Ebene kommst :)

liebe Grüße

David

von Olli Z. (z80freak)


Lesenswert?

Michael, wie wärs wenn Du uns mal ein sauberes GERÜST zusammenstellst. 
Verzeichnisstruktur und leere Files. Gern auch schon das .h File mit den 
defines oder zumindest der Idee davon um die ganzen Parameter zu setzen.

Ich plag mich in der Zwischenzeit mit der Installation von AVR Studio 7 
rum...

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,
da sind sie wieder, meine 3 Probleme... ;)

Ich kann es mal nach meiner Ansicht versuchen. "meine Ansicht" deshalb, 
weil:
ich kann weder C noch C++ wirklich. Grundlagen habe ich mir 
projektabhängig über die letzten Jahre zusammengesucht, C++ 
bekanntschaft erst durch die Arduino-Geschichte.
Es war und ist nur Hobby, vom Z80 über 6510 zu den ersten AVR usw. Alles 
in Assembler. C kam als Notwendigkeit weil mein Anfang einen TCP-Stack 
in ASM zu schreiben zwar durchaus gangbar war (IP ging, TCP ging, ARP 
ging ICMP-Ping ging grundsätzlich. Alles nur, weil der ENC28J60 Ethernet 
Chip bezahlbar beschaffbar war und LAN am AVR.. Super!

Dann kam U.Radig mit seinem Webserver daher und ich stand vor der 
Entscheidung, meins weitermachen oder mich in C einzulesen und seine 
Software an meine Wünsche anzupassen. Ich habe mich für seine Software 
entschieden...
Entscheidend dafür war, daß ich auf Grund meiner eigenen Basteile TCP/IP 
usw. ausreichend verstand, um recht zielsicher die C-Funktionen in 
seiner Software zuordnen zu können und auch (nach und nach) zu 
verstehen.

Das schreibe ich an David D, ich finde es gut, den Dingen weit auf den 
Grund zu gehen. Von mir kenne ich aber auch, daß es oft besser ist, 
Teile zu nutzen, die andere Funktionsfähih schon gemacht haben und sich 
auf bestimmte Sachen zu konzentrieren, die eben noch nicht wunschgemäß 
verfügbar sind.
Ds Risiko, das ein Projekt auf der Strecke bleibt, weil fehlende 
Erfolgserlebnisse und steigender Zeitaufwand eben keinen Spaß mehr 
machen, ist recht hoch.

PS: Es ist zwar etwas riskant, solchen Source in ein Forum zu packen, 
weil der generelle Verriß da dicht daneben steht. Bisher hat man uns ja 
in diesem Thread in der Beziehung in Ruhe gelassen. Ich hoffe mal, das 
bleibt auch so.

Ich habe mit dem Stand des Codes kein Problem, es ist eben schwer, im 
Internet die Vorkenntnisse usw. des Gegenüber einzuschätzen.

Also: David D... Augen zu und durch und nicht die Lust verlieren, das 
wird schon.

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> Nanu? Da werden I2C-Clock und I2C-Data hart auf Ausgang und H gesetzt??

Respekt, Respekt: scharfes Auge, Michael !!

> I2C/TWI darf NIE einen festen H-Pegel auf den Leitungen haben, der Slave
> darf diese JEDERZEIT auf aktiv L ziehen und das ist dann unlustig für
> die Treiber der Beteiligten!

Hmmm - schon erstaunlich, dass bislang weder Kamera noch Arduino Nano 
gehimmelt wurden.

Eventuell hat Dich der Levelshifter irgendwie gerettet.
Welchen Typ/Bauteil verwendest Du genau?

Verwendest Du einen I2C Level-Shifter oder einen Feld-Wald-Wiesentyp?

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Einen Feld-Wald-Wiesentyp...

Ich bin leider heute doch nicht mehr dazu gekommen, mir die Links 
anzuschauen. Das werde ich morgen nachholen.

Ich habe eben durch absoluten Zufall noch eine schöne 
Erklärung/Anleitung zur Programmierung des AVR mit C gefunden, wo einige 
Sachen drin standen, die ich auch noch nicht kannte.

http://www.ulrichradig.de/home/uploads/images/Daten_Infos_Anleitungen/AtmelCprogramming.pdf

(insbesondere die "AVR/common" lib. Die macht den Umstieg von Arduino 
auf AtmelStudio vermutlich nicht ganz so hart.

Olli hat auf der genannten GitHub Seite schon angefangen die 
Informationen zusammenzutragen. Da gibt es echt tolle Möglichkeiten, das 
ganze strukturierter und themenbezogener zu diskutieren, weshalb ich da 
hier nochmal für Werbung machen wollte :)

Mich hat es auch am Anfang erschlagen, aber mit ein bisschen 
ausprobieren kriegt man das schon schnell raus :) Also nur Mut.

https://github.com/igittigitt/ov7670

lg.

David

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
>> Nanu? Da werden I2C-Clock und I2C-Data hart auf Ausgang und H gesetzt??
>
> Respekt, Respekt: scharfes Auge, Michael !!

ich hatte ja oben extra in Stichpunkten geschrieben, was ich gemacht 
habe.
Ich krame gern und oft in fremden Source, man lernt immer wieder 
irgendwas oder erkennt eigene Fehler.

>> I2C/TWI darf NIE einen festen H-Pegel auf den Leitungen haben, der Slave
>> darf diese JEDERZEIT auf aktiv L ziehen und das ist dann unlustig für
>> die Treiber der Beteiligten!
>
> Hmmm - schon erstaunlich, dass bislang weder Kamera noch Arduino Nano
> gehimmelt wurden.

Die ICs sind meist härter im nehmen als man meint. Es ist ja erstmal ein 
thermisches Problem für die Ausgangstreiber. Es ist ja auch oft kein 
statischer Zustand sondern nur zeitweise Impulse und je nach I2C-Slave 
und dessen internem Verhalten muß es nichtmal passieren, daß das 
Gegenstück in der Zeit auf Low zieht.

Beim AVR macht man es bei I2C zu Fuß so, daß man über DDR die Pegel 
setzt.
SDA und SCL als Init Port auf Low, dann auf Eingang. Der externe PullUp 
setzt jetzt den H-Pegel. Für L an SDA/SCl setzt man das Pin im DDR auf 
1, damit ist der AVR Pin Ausgang Low. Für H am Ausgang eben DDR-Bit 
wieder auf 0 -> Eingang. Ist nach außen dann wie ein OpenDrain.
Allerdings würde ich, wenn vorhanden, immer die TWI-Hardware nehmen. Die 
Abfragerei der Zustände, ACK und NACK, Start- Stopcondition sind zwar 
simple Abläufe, nur warum soll ich das machen, wenn das schon in die 
Hardware gegossen ist.

David D. schrieb:
> Ich habe eben durch absoluten Zufall noch eine schöne
> Erklärung/Anleitung zur Programmierung des AVR mit C gefunden, wo einige
> Sachen drin standen, die ich auch noch nicht kannte.
>
> 
http://www.ulrichradig.de/home/uploads/images/Daten_Infos_Anleitungen/AtmelCprogramming.pdf

Ulrich Radig... hatte ich oben schon im Zusammenhang mit meiner alten 
Kamera und dem Webserver erwähnt. Müßte so um 2010 gewesen sein.
Auch U.Radig hat mich in der Webserver-Source mal geschafft. Alles recht 
brauchbar kommentiert. Dann habe ich eine Pin-Zuordnung o.ä. geändert 
und nichts ging mehr. Irgendwo ganz weit unten in einer Funktion hatte 
er nicht seine Definition benutzt sondern das Register mit PORTB = 0x23 
oder so gesetzt. Sowas war für mich immer Hinweis, in eigenen Sachen 
immer auf solche Kelinigkeiten zu achten, Änderungen sofort in allen 
Teilen sauber anzupassen solange man eben noch direkt den Kram im Kopf 
hat.
Von ihm stammt ja auch die Idee und Realisierung, die DC3840 auf einem 
AVR bei 921kBaud auslesen zu können.

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Mahlzeit,

>Ulrich Radig... hatte ich oben schon im Zusammenhang mit meiner alten
>Kamera und dem Webserver erwähnt.

uups... entschuldige bitte.

Ich habe jetzt einmal angefangen das TWI über das AVR-Interface zu 
programmieren. Diesmal habe ich mir alle Mühe gemacht, es sauber zu 
kommentieren :D Allerdings habe ich noch keine Erfahrung mit der 
Zusammenarbeit beim Coden mit Anderen Teilnehmern gemacht, weshalb ich 
euch fragen würde, ob es von der Kommentier Weise, -Umfang ausreichend 
ist.

lg. David

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> uups... entschuldige bitte.

wofür entschuldigst Du Dich? Ich war nur zu faul im Thread hier die 
Stelle zu suchen...

Ich schaue nachher mal rein, wenn ich dazu komme. Habe es mal von gitHub 
runtergeladen.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
>
> Ich habe jetzt einmal angefangen das TWI über das AVR-Interface zu
> programmieren. Diesmal habe ich mir alle Mühe gemacht, es sauber zu
> kommentieren :D Allerdings habe ich noch keine Erfahrung mit der
> Zusammenarbeit beim Coden mit Anderen Teilnehmern gemacht, weshalb ich
> euch fragen würde, ob es von der Kommentier Weise, -Umfang ausreichend
> ist.
>

Sieht sehr hübsch aus und ich finde die Kommentierung sehr gut.

Zu Deiner Frage im Code:
1
//check if Acknowledge Bit is send by slave
2
if((TWSR & 0xF8) != TW_MT_SLA_ACK) //QUESTION: why do we MASK this with 0xF8 and not with TW_MT_SLA_ACK?

Laut util/twi.h gilt:
1
#define   TW_MT_SLA_ACK   0x18

Guckst Du Datenblatt "26.9.2.  TWI Status Register", so steht da:
"Note that the value read from TWSR contains both the 5-bit status value
and the 2-bit prescaler value. The application designer should mask the 
prescaler bits to zero when checking the Status bits. This makes status 
checking independent of prescaler setting."

Will sagen: mit 0xF8 blendest Du die Bits aus, die nicht zur 
Status-Anzeige (TWS[7:3]) gehören und mit "!= TW_MT_SLA_ACK" prüfst Du 
halt, ob TWS[7:3] genau Deinen gewünschten Wert enthalten - alles andere 
ist ein Fehler.

So wäre z.B. auch die Bitfolge "IIII I000" ein Fehler und würde mit o.g. 
Code als solcher erkannt. Würdest Du statt mit 0xF8 mit TW_MT_SLA_ACK 
maskieren, so würdest Du aus der o.g. Bitfolge "000I I000" machen, was 
keine Fehler wäre. Das wiederum wäre ein Fehler :-)

In Summe halte ich die ganze ACK-Prüfung allerdings für falsch, weil 
sich genau in diesem Punkt das SCCB-Protokoll vom I2C-Protokoll 
unterscheidet.
Daran sind schon sehr viele gescheitert ...

Hier lesen:
https://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/99/t/120548

Und die SCCB-Spec lesen - siehe meine Links weiter oben.

Und hier direkt die nächste Stolperfalle, die zu beachten ist und die 
mich seinerzeit viel Zeit gekostet hat:
https://e2e.ti.com/support/embedded/linux/f/354/p/171390/862562#862562


Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

ich bin gestern nicht dazu gekommen reinzuschauen.

Ich muß auch erstmal genauer in SCCB usw. reinschauen.
Andreas S. schrieb:
> In Summe halte ich die ganze ACK-Prüfung allerdings für falsch, weil
> sich genau in diesem Punkt das SCCB-Protokoll vom I2C-Protokoll
> unterscheidet.
> Daran sind schon sehr viele gescheitert ...

Das sehe ich insofern als Problem an, weil man (auch ich) ja 
Datenblätter in bestimmten Details erst liest, wenn was klemmt.
Die Entscheidung, ob man ein ACK oder NACK erwartet, wenn man ein Byte 
liest oder ob man AC/NACH schickt wenn man Daten empfängt usw, wann man 
Start oder Stop setzt usw. passiert ja eigentlich ohnehin abhängig von 
den Wünschen eines Slaves. Ein Problem, die TWI-Hardware des AVR zu 
nutzen sehe ich im Moment nicht so richtig. Das Statusregister muß man 
ja ohnehin sinnvoll auswerten und wenn ACH/NACh mich nicht interessieren 
oder ungültig sein können, dann ignoriere ich das Flag eben 
entsprechend.

In der einzigen Source, die ich mit der OV7670 am ESP32 real kurz in 
Betrieb hatte und die auch lief, benutzt der Programmierer auch die 
existierende TWI-Lib. Allerdings auf unterster Ebene, um den Rest 
kümmert er sich selbst.
Muß ich mir aber eben alles nochmal zu Gemüte führen.

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Hallo Igel,
hallo Michael,

vielen Dank!
Das mit dem Maskieren mit 0xF8 habe ich im Nachgang auch gelesen und 
verstanden.

von Michael:
>Ein Problem, die TWI-Hardware des AVR zu
>nutzen sehe ich im Moment nicht so richtig.

Ich glaube Igel1 hat sich mit dem ACK-Flag nur auf meinen Code bezogen.
Die Überprüfung habe ich nämlich eben zunächst erst einmal von der 
genannten Quelle übernommen. Im Nachgang werde ich jetzt noch prüfen 
müssen, ob diese Flags mit dem SCCB überhaupt decken. Vermutlich wie 
Igel ansprach eben nicht.

Aber da bin ich gerade dran. Ich möchte das TWI-File so aufbauen, dass 
ich es nach Möglichkeit immer nutzen kann, auch für kommende Projekte, 
die eventuell nicht auf SCCB-Weise funktionieren. Meine Vorstellung wäre 
da zum Beispiel über die initialisieren Funktion Parameter mitzugeben, 
bspw. ob Ack gesendet wird oder nicht.
Haltet ihr das für machbar (im ertragbaren Rahmen).
Und würdet ihr das TWI direkt über Interrupts machen oder erst den 
"normalen" weg?

lg. David

PS: OpenDrain habe ich jetzt auch endlich mal gerafft. Ist ja eigentlich 
relative einfach :D ... Sobald man verstanden hat, dass man über einen 
Eingangs-Pin indirekt den Leitungspegel beeinflussen kann.

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Aber da bin ich gerade dran. Ich möchte das TWI-File so aufbauen, dass
> ich es nach Möglichkeit immer nutzen kann, auch für kommende Projekte,
> die eventuell nicht auf SCCB-Weise funktionieren. Meine Vorstellung wäre
> da zum Beispiel über die initialisieren Funktion Parameter mitzugeben,
> bspw. ob Ack gesendet wird oder nicht.
> Haltet ihr das für machbar (im ertragbaren Rahmen).

Ich selber komme zunehmend weg vom "one code fits all"-Ansatz.
Ich würde mir separate Bibliotheken für SCCB und I2C machen.

Nächstes Thema:

In Punkto ACK/NACK musst Du evtl. ein bißchen aufpassen, ob Du
Deine Hardware mit ACK konfigurierst. Dann könnte es passieren,
dass die Hardware eine gewisse Zeit auf das ACK-Bit wartet und
in dieser Zeit quasi "hängt" (bis zum timeout).

Besser ist es vermutlich, Dein I2C/TWI-Hardwaremodul direkt so
zu konfigurieren, dass es kein ACK erwartet.
Aber hier würde ich den Ansatz "Studieren geht über Probieren" fahren.

> Und würdet ihr das TWI direkt über Interrupts machen oder erst den
> "normalen" weg?

Über den "normalen" Weg - gerade bei der Kamera ist das völlig okay,
denn die wird ja sowieso zuerst konfiguriert und dann erst richtig
genutzt.

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> PS: OpenDrain habe ich jetzt auch endlich mal gerafft. Ist ja eigentlich
> relative einfach :D ... Sobald man verstanden hat, dass man über einen
> Eingangs-Pin indirekt den Leitungspegel beeinflussen kann.

... das wiederum habe ich nicht verstanden??

Im OpenDrain-Konzept kannst Du nichts über einen Eingangspin 
beeinflussen.
Oder meintest Du den etwas schrägen Workaround, mit dem man im Atmega so 
ein OpenDrain "simuliert"? (by the way: im ARM kann man die I/O Pins in 
einen OpenDrain-Mode setzen und muss dann keine Klimmzüge machen).

Unter'm Strich hast Du halt nur einen Widerstand, der an Vcc 
angeschlossen wird und an dessen unterem Ende Du die 
Collector-Emitter-Strecke (oder die Drain-Source Strecke) beliebig 
vieler Devices gegen Masse anschließt.

Jedes der Devices kann dann das Potential an diesem unteren Ende des 
Widerstandes gegen Masse ziehen.

By the way: SCCB ist laut Datenblatt auch elektrisch kein I2C-Bus,
siehe SCCB-Spec hier: 
http://www4.cs.umanitoba.ca/~jacky/Teaching/Courses/74.795-LocalVision/ReadingList/ov-sccb.pdf
Dort: Figure 22, Figure 23 und Figure 24.
Dort wird der Bus aktiv getrieben (mit push-pull Schaltungen am Ausgang 
von Master UND Slave).

Um das Schlimmste zu vermeiden, gibt es einen "conflict-protection 
resistor", der evtl. auch des Rätsels Lösung dafür sein könnte, dass Du 
in Deiner ursprünglichen Beschaltung weder OV7670 noch AVR gegrillt 
hast. Ich vermute, dieser conflict-protection resistor steckt irgendwo 
auf dem OV7670 board.

Nevertheless - man kann SCCB mit I2C-Treibern bedienen, das haben schon 
viele Leute in der Praxis bewiesen. Aber 100% Spec-konform ist es meiner 
Meinung nach nicht.

Viele Grüße

Igel1

: Bearbeitet durch User
von David D. (saturi)


Lesenswert?

Andreas S. schrieb:
> Im OpenDrain-Konzept kannst Du nichts über einen Eingangspin
> beeinflussen.
> Oder meintest Du den etwas schrägen Workaround, mit dem man im Atmega so
> ein OpenDrain "simuliert"? (by the way: im ARM kann man die I/O Pins in
> einen OpenDrain-Mode setzen und muss dann keine Klimmzüge machen).

Okay? vielleicht habe ich es dann doch nicht verstanden?
Der Punkt ist doch, dass der High-Pegel durch den Pull-Up und nicht 
durch den Ausgang des Controllers entsteht.
Um das zu erreichen bleibt mir doch nur, den Pin des Controllers auf 
Eingang zu schalten (hohe Impedanz am Pin).

Habe meine Erkenntnisse heute morgen hier mal zusammengefasst:
https://github.com/igittigitt/ov7670/wiki/unsorted

wenn das falsch ist, bitte unbedingt bescheid geben. Dann muss ich das 
wieder löschen oder korrigieren.

lg.
David

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Um das Schlimmste zu vermeiden, gibt es einen "conflict-protection
> resistor", der evtl. auch des Rätsels Lösung dafür sein könnte, dass Du
> in Deiner ursprünglichen Beschaltung weder OV7670 noch AVR gegrillt
> hast. Ich vermute, dieser conflict-protection resistor steckt irgendwo
> auf dem OV7670 board.

Ich müßte mein Modul mal genauer mit der Lupe begutachten.

> Nevertheless - man kann SCCB mit I2C-Treibern bedienen, das haben schon
> viele Leute in der Praxis bewiesen. Aber 100% Spec-konform ist es meiner
> Meinung nach nicht.

Auf den Ausgangsüunkt des Threads bezogen hat das jetzt eine Art 
"logistisches" Problem: man sollte für den SCCB tatsächlich spezielle 
Routinen schreiben, das wäre sauber. Man kann die Kamera auch insofern 
nicht als I2C-Device betrachten, weil man sie nicht mit anderen 
i2C-Slaves an diesem Bus zusammen betreiben kann.

Problem ist, daß man sich darüber klar sein sollte, daß man das dann 
speziell für diese Kamera und  ähnliche Kamera-ICs macht. Je nach 
späteren Absichten kommt man damit vielleicht nie wieder in Berührung.
Ich habe sowas früher öfter für irgendwelche UKW/rundfunk-ICs gemacht, 
die PLLs dort hatten immer irgendwelche eigenen seltsamen Protokolle.
Sowas habe ich allerdings dann immer sehr direkt und hart gecodet mit 
Pingewackel usw. Das hat bei mir auch nie einen universellen Überbau 
bekommen weil es nicht sinnvoll allgemein nutzbar war.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Okay? vielleicht habe ich es dann doch nicht verstanden?
> Der Punkt ist doch, dass der High-Pegel durch den Pull-Up und nicht
> durch den Ausgang des Controllers entsteht.
> Um das zu erreichen bleibt mir doch nur, den Pin des Controllers auf
> Eingang zu schalten (hohe Impedanz am Pin).
>
> Habe meine Erkenntnisse heute morgen hier mal zusammengefasst:
> https://github.com/igittigitt/ov7670/wiki/unsorted
>
> wenn das falsch ist, bitte unbedingt bescheid geben. Dann muss ich das
> wieder löschen oder korrigieren.

Nein, Entwarnung: Du hast alles richtig verstanden und Dein 
github-Dokument beschreibt es ebenfalls richtig.

Evtl. möchtest Du noch erwähnen, das ein solcher I2C-Bus niemals aktiv 
auf hight geschaltet werden sollte, weil sonst die hier 
(http://www4.cs.umanitoba.ca/~jacky/Teaching/Courses/74.795-LocalVision/ReadingList/ov-sccb.pdf) 
in Figur 24 erwähnte Konstellation auftritt - allerdings ohne den dort 
eingezeichneten Widerstand ...

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

Gibt's schon Neues aus Forschung und Technik?

von David D. (saturi)


Lesenswert?

Hallo zusammen,

entschuldigt bitte die rare Informationspolitik meinerseits.
Dadurch, dass wir es ja jetzt über das TWI-Interface des AVR gehen 
wollen, stehe ich quasi wieder am Anfang und versuche mit dem SCCB zu 
kommunizieren ;-) senden funktioniert soweit auch schon, jetzt bin ich 
grade an der Read-Funktion.
War aber das ganze Wochenende, sowie die kommende Woche komplett zu 
geplant, sodass es von meiner Seite aus erst frühestens am Sonntag Abend 
neue Erkenntnisse gibt.

aktuellen Stand habe ich grade auf das TWI-branch gepushed. kann man 
sich also in Github anschauen.

Ich nehme auch gerne Vorschläge entegen :) grade habe ich einfachmal die 
Kontrolle des ACK-Bits übersprungen.

lg.
David

von Michael U. (amiga)


Lesenswert?

Hallo,

ich habe mir das mal von github geholt.
Ich werde einfach mal Deine TWI-Sachen kopieren und eine "echte" 
SCCB-Version in der ArduinoIDE machen  und für mich speziell auf dem 
ESP32 testen.
Dann kann ich das erstmal ohne Änderungen für den Arduino Nano (Mega328) 
oder eben den ESP32 compilieren.
Außerdem kann ich dann am Mega328 auch Deine version und meine zusammen 
mit Kamera und logicAnalyzer vergleichen, falls die Kamera nicht 
erwartungsgemäß antwortet.

Die pinMode()/digitalWrite()/digitalRead() der ArduinoIDE dann duch die 
Port/Pin-Zugriffe des AVR zu replacen ist ja keine wirkliche Arbeit.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Hi David, (und Michael),

@David: Danke für das Lebenszeichen - dann wissen wir, dass es hier in 
ca. 2 Wochen weitergeht (es sei denn Olli bekommt Lust, den Stier bei 
den Hörnern zu packen ...).

Ansonsten: kein Problem - in diesem Thread sind wir ja alle nur 
Hobbyisten und haben Zeit.

Ich selber bin eh nur "Zaungast" bei Euch, denn mein OV7670 läuft an 
einem STM32F429 - ARM-Prozessor, der das Einlesen quasi "nebenbei" mit 
seiner Peripherie macht. Da will man nicht mehr zurück zum AVR - sorry.

Daumen hoch aber für Michael, der sich hier so engagiert einbringt.
Ich habe hier ebenfalls einen ESP32 rumliegen und bislang noch nichts 
damit gemacht (keine Zeit). Kannst Du mir ein netterweise paar Tipps zur 
Einarbeitung geben? (okay, ist etwas off-topic, aber ein paar 
Stichpunkte wären einfach gut: IDE? Gute Einstiegs-URL's, was muss man 
unbedingt lesen, ...)

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Ich habe hier ebenfalls einen ESP32 rumliegen und bislang noch nichts
> damit gemacht (keine Zeit). Kannst Du mir ein netterweise paar Tipps zur
> Einarbeitung geben? (okay, ist etwas off-topic, aber ein paar
> Stichpunkte wären einfach gut: IDE? Gute Einstiegs-URL's, was muss man
> unbedingt lesen, ...)

ein wunder Punkt... Ich hatte bei Erscheinen mir ziemlich schnell damals 
ESP6266 gekauft. Die vorgefertige ID in einer VM (so von Espressif 
damals bereitgestellt) auf den Rechner geworfen und grrr... nichts ging, 
nichts klappte, Doku zu den ESP in gutem Chinesich oder lustigem aber 
unbrauchbarem Englisch.

Sie haben dann sehr schnell gelernt und parallel dazu kam die Einbindung 
des SDK in die ArduinoIDE. Das war eigentlich mein Grund für die 
Bekanntschaft mit dieser IDE. Mindestnes 2 der Programmierer, die damals 
die Arduino-Anbindung gebaut haben, arbeiten inzwischen fest für 
Espressif, deshalb ging es beim ESP32 auch viel schneller mit dem 
Anpassen usw.

Damit hast Du jetzt eigentlich 2 Wege: auf 
https://www.espressif.com/en/products/hardware/esp32/overview findest Du 
alles, was es dazu vom Hersteller gibt, die SDKs usw.
Ich bin da aber nicht direkt auf dem laufenden.
Ich nutze den ESP32 zusammen mit der ArduinoIDE.
https://github.com/espressif/arduino-esp32
Die Einbindung und Anpassung ist aber da noch nicht 100% und man kann 
einige Möglichkeiten auch (noch?) nicht nutzen. Dafür spielt das in 20 
Minuten und man hat ein Erfolgserlebnis und für meine kleinen Projekte 
reicht es mit Sicherheit.

Alles nützliche gibt es jetzt ohnehin bei github. 
https://github.com/espressif

Der ESP32 ist eigentlich recht genial gerade für kleine Projekte weil er 
fast alles an Hardwareanbindungen drin hat was man gebrauchen kann.

Gruß aus Berlin
Michael

: Bearbeitet durch User
von David D. (saturi)


Lesenswert?

Sorry, ich glaube das aktuellste ist jetzt erst oben. Hab wohl vergessen 
nen Knopf zu drücken...

Vielen Dank, dass du das machst.
Ganz kurze Frage: kann ich mir durch die Lvl-Shifter eigentlich die 
Pull-Up Widerstände auf den Bus-Leitungen sparen? bzw. brauche ich sonst 
auf jeder Seite einen?

lg.

David

von Olli Z. (z80freak)


Lesenswert?

Beim Levelshifter benötigst Du keine zusätzlichen Pullups.
Ich werde mir Deinen TWI Code auch mal vornehmen und die Timings mit dem 
Datenblatt vom SCCB vergleichen. Die müssen ja nicht SPI entsprechen. 
Zum Glück ist das SCCB ja eh nur ein Subset von SPI, einfaches 
Master/Slave. Das macht den zu verwendenden Code schlanker.

Ich bin auch eher ein Freund davon die Dinge optimal an die Verwendung 
anzupassen, also keine Rundum-Sorglos-Für-Alles Libs. Die haben nur 
massig Implikationen due man kennen muss und die Fehlersuche ist ein 
Graus.

Warum auch nicht eine hochspezialisierte SCCB Lib machen?
Echter AVR Code dürfte auch um einiges schlanker sein als mit Arduino 
Framework drumherum. Ich habe es inzwischen (tataaa) auch geschafft das 
AVR Studio zu installieren. Nachdem ich wirklich erstmal ALLE Windows 
Visual C* Bibliotheken von meinem PC gelöscht habe. Da hatteb sich 
inzwischen gute 20 Stück angesammelt und irgendwie dafür gesorgt das die 
IDE nicht mehr die benötigte findet.

Bin also jetzt auch mit am Start :-) Lass uns erst dieses doofe SCCB 
Dong rocken, damit es ordentlich weitergehen kann.

Ich denke, sobald wir mal ein Bild irgendwie rüber haben sollteb wir auf 
die FIFO Version wechseln, sonst ist mit AVR schnell schluß.

von Michael U. (amiga)


Lesenswert?

Hallo,

Olli Z. schrieb:
> Die müssen ja nicht SPI entsprechen.
> Zum Glück ist das SCCB ja eh nur ein Subset von SPI, einfaches
> Master/Slave.

nun verwirre ihn nicht völlig, I2C, nicht SPI...

Olli Z. schrieb:
> Warum auch nicht eine hochspezialisierte SCCB Lib machen?
Prinzipiell ist es kein Problem SCCB mit BitBanging auf dem AVR zu 
machen, ein Problem sehe ich eher darin, daß es eingentlich keiner 
wirklich braucht. SCCB ist eben als Kamera-Protokoll gebaut worden, 
zumindest habe ich nichts anderes gesehen. Man wird aber gerade die 
nicht wirklich zusammen an einem AVR nutzen können, der OV7670 wird wohl 
eine Ausnahme bleiben, weil ein netter China-Hersteller die Dinger noch 
rumliegen hatte und ein breakout-Board drum gebastelt hat...

> Echter AVR Code dürfte auch um einiges schlanker sein als mit Arduino
> Framework drumherum.

Mit dem Arduino Framework ist es so eine Sache, wenn ich seine Dateien 
in einen Ordner OV7670_Kamera im Sketchbook anlege und die main.c in 
OV7670_Kamera.ino umbenenne, kümmert sich das Arduino Framework ganz 
brauchbar um das, was es da findet. Sinnigerweise mault er dann über 
bool weil in älteren AVR-Studio (4.xx) und GCC-Versionen die noch mit 
#include  <stdbool.h> selber eingebunden werden mußte. Habe ich eben 
hinzugefügt, dann läuft der Compiler komplett durch, 134 Bytes Code.
In das alte Atmel-Studio 4.18 geworfen sind es 196 Bytes. Da könnte ich 
mir jetzt die erzeugten ASM-Files von beiden mal anschauen, ich denke 
aber, da ist der uraltete GCC von 2010 im uralten Atmel-Studio schuld, 
die neueren optimieren merklich besser.
Ein neueres AVR-Studio hatte ich nur mal kurz drauf, ich brauche es für 
meine Projekte ("Spielereien") im Moment nicht wirklich.

Das sieht alles völlig anders aus, wenn man beruflich nutzen will oder 
die Projekte richtig groß werden oder eben µC aus aktuelleren 
Entwicklungen nutzen will oder muß.

Ansonsten sind es aber eben alles Grundlagen, eine Timer bleibt ein 
Timer, egal wieviele Sonderfunktionen und Modi er hat, ein IO ist ein 
IO, ob ich da wie beim AVR den Mode direkt setzen kann oder noch einer 
komplexe IO-Matrix erklären muß, welche interne Hardware jetzt an 
welchem Pin landen soll (XMega, ESP32 usw.). I2C, SPI, I2S, CAN, ... 
sind Sachen, die sind Funktionen, wo ich wissen muß (sollte) wie das 
Protokoll funktioniert, was an Spezialitäten jeweils dazugehören und wie 
ich die benutzen kann.
An welchen Registern ich drehen muß, wenn es Hardwareunterstützung im µC 
dazu gibt oder wie weit die geht (ich sage nur USI beim AVR, kann vieles 
nund nichts vollständig), das muß ich ohnehin aus dem Datenblatt, 
Applicationsbeispielen des Herstellers des konkreten µC zusammensuchen.

Der Kram ist ohnehin hier ein netter Versuchsaufbau für mich, ich werde 
nachher mal meinen (auch alten und selbstgebauten) LA ranklemmen, das 
kann dann so erstmal hier liegenbleiben zum mitmachen.
http://www.avr.roehres-home.de/logikanalyzer/index.html
Und auch die Webseite ist uralt und ungepflegt. ;)

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:

> ein wunder Punkt... Ich hatte bei Erscheinen mir ziemlich schnell damals
> ESP6266 gekauft.

Ich ebenfalls - allerdings den ESP8266 ;-)
Zum Glück bin ich etwas später eingestiegen, aber nicht nur die 
Software, auch die Hardware hat dort üble Bugs: so mußte ich viele 
Stunden verbraten um herauszufinden, dass das WLAN-Modul die 
Meßergebnisse des AD-Wandlers beeinflußt - super Möhre ...  Erst wenn 
man Wake-Up beim WLAN deaktivierte stimmten die Ergebnisse wieder - ohne 
Worte ...

> Sie haben dann sehr schnell gelernt und parallel dazu kam die Einbindung
> des SDK in die ArduinoIDE.

Ja, habe den ESP8266 sowohl in LUA als auch in Arduino programmiert. 
Lämpchen ein-/aus geht ganz gut, aber auf anspruchsvollere Dinge möchte 
ich mich mit so einem halbgaren Teil nicht einlassen - da fressen einen 
die Bugs auf.

> Damit hast Du jetzt eigentlich 2 Wege: auf
> https://www.espressif.com/en/products/hardware/esp32/overview findest Du
> alles, was es dazu vom Hersteller gibt, die SDKs usw.
> Ich bin da aber nicht direkt auf dem laufenden.

Danke!

> Ich nutze den ESP32 zusammen mit der ArduinoIDE.
> https://github.com/espressif/arduino-esp32

Danke!

> Die Einbindung und Anpassung ist aber da noch nicht 100% und man kann
> einige Möglichkeiten auch (noch?) nicht nutzen. Dafür spielt das in 20
> Minuten und man hat ein Erfolgserlebnis und für meine kleinen Projekte
> reicht es mit Sicherheit.

Geht mir manchmal ähnlich.

> Alles nützliche gibt es jetzt ohnehin bei github.
> https://github.com/espressif

Danke!

> Der ESP32 ist eigentlich recht genial gerade für kleine Projekte weil er
> fast alles an Hardwareanbindungen drin hat was man gebrauchen kann.

Bin jetzt eine Woche auf (Dienst)reise - ideal zu abendlichen Proggen - 
und ich wollte eigentlich das kleine Tütchen mit dem ESP32 eingepackt 
haben. Nun sitze ich im Zug und was zu Hause liegt ist der ESP32 - 
grrrr....

Danke aber nochmals für Deine Tipps!

Viele Grüße

Andreas

von Olli Z. (z80freak)


Lesenswert?

Michael U. schrieb:
> nun verwirre ihn nicht völlig, I2C, nicht SPI...
Ups, Du hast natürlich recht, mein Fehler.

> Olli Z. schrieb:
>> Warum auch nicht eine hochspezialisierte SCCB Lib machen?
> Prinzipiell ist es kein Problem SCCB mit BitBanging auf dem AVR zu
> machen, ein Problem sehe ich eher darin, daß es eingentlich keiner
Ich meinte das schon unter Zuhilfenahme des I2C-Interfaces vom AVR, nur 
eben das wir nicht die fertige Wire-Lib nehmen, sondern das für unsere 
Zwecke abspecken.

> zumindest habe ich nichts anderes gesehen. Man wird aber gerade die
> nicht wirklich zusammen an einem AVR nutzen können, der OV7670 wird wohl
Jab, die Erkenntnis ist ja bereits gefestigt. Da werden wir nur mit FIFO 
halbwegs was rausbekommen. Einzige Option wäre ggf. noch ein lokal am 
AVR angeschlossenes LCD-Display, welches die empfangenen Daten der 
Kamera direkt darstellt. Aber auch das wird nur in einer sehr 
reduzierten Auflösung/Framerate möglich sein.

> hinzugefügt, dann läuft der Compiler komplett durch, 134 Bytes Code.
> In das alte Atmel-Studio 4.18 geworfen sind es 196 Bytes. Da könnte ich
Wow, das ist wirklich wenig, hätte ich nicht mit gerechnet. Da könnte 
man ja sogar noch das ASM "verstehen" ;-)

> Ein neueres AVR-Studio hatte ich nur mal kurz drauf, ich brauche es für
> meine Projekte ("Spielereien") im Moment nicht wirklich.
Ich hoffe das wir mit verschiedenen Versionen keine Probleme bekommen. 
Ich würde halt immer das aktuelle nehmen, also jetzt 7.

> Der Kram ist ohnehin hier ein netter Versuchsaufbau für mich, ich werde
Ich bin aber echt froh einen Vollblut-Programmierer hier im Thread zu 
haben. Meine Kenntnisse sind an vielen Stellen nur rudimentär. Ach, es 
gibt ja so wahnsinnig viel interessantes Zeug und so wenig Zeit ;-)

Als LA habe ich mir mal für nen 20er einen Saleae-Logic mit 8-Kanal 
zugelegt. Die Software finde ich ganz gut, hat auch Protokoll-Analyzer 
mit drin und billiger gehts kaum. Für Hobby, Spiel und Spaß genau 
richtig. Einzig das der nur für TTL-Level ausgelegt ist, also einen 
Vref-Eingang hat. 3,3V geht damit aber auch noch.

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> Der Kram ist ohnehin hier ein netter Versuchsaufbau für mich, ich werde
> nachher mal meinen (auch alten und selbstgebauten) LA ranklemmen, das
> kann dann so erstmal hier liegenbleiben zum mitmachen.
> http://www.avr.roehres-home.de/logikanalyzer/index.html
> Und auch die Webseite ist uralt und ungepflegt. ;)

Wow - bin sehr beeindruckt: ein selbstgebauter LA mit 
selbstprogrammierter Software! Nicht schlecht!

Ich selber habe einen 500MHz Intronix Logicport - ganz schnöde hier im 
Forum erstanden. Im Gegensatz zu Deinem Selbstbau also Coolnessfaktor = 
0,ist aber trotzdem eine der besten Investitionen in meinem Bastelpark.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Ja, habe den ESP8266 sowohl in LUA als auch in Arduino programmiert.
> Lämpchen ein-/aus geht ganz gut, aber auf anspruchsvollere Dinge möchte
> ich mich mit so einem halbgaren Teil nicht einlassen - da fressen einen
> die Bugs auf.

was ist anspruchsvoll? Hier läuft ein gutes Dutzend ESP8266 dauerhaft 
und stabil. Als NTP-Client für ein paar Uhren weil DCF77 hier 
mittlerweile zuviel Ärger macht. Am PIR-Sensor zum Melden einer 
Bewegung. Als IR-Send-Bridge um den alten Sony-Receiver per IR und MQTT 
steuern zu können. Als Warner wil ich im Bad mal wieder das Licht 
angelassen habe. In WLAN-Steckdosen von Sonff und Norma/Obi. Als 
433MHz-bridge nach MQTT für meine alten Eigenbausensoren. Als Steuerung 
für einen WS2812 LED-Stripe. Bin gerade einfach mal so durchgegangen, in 
solchen Dingen sehe ich den Zweck der ESP8266 gerade durch den Preis.
Einen MP3-Streamplayer mit einem VS1053 gibt es auch noch, prizipiell 
stabil, durch den etws knappen Ram aber hier im WLAN manchmal zu 
Aussetzern neigend, war auch eher ein proof-of-concept weil das Zeug 
rumlag.
Da wird ein ESP32 einziehen, dank mehr Ram und stabil laufendem 
Software-MP3-Decoder und I2S-Ausgabe besser geeignet.

Für (unangenehme) Überraschungen ist der ESP32 aber auch noch eine Weile 
gut...

Olli Z. schrieb:
> Ich bin aber echt froh einen Vollblut-Programmierer hier im Thread zu
> haben. Meine Kenntnisse sind an vielen Stellen nur rudimentär. Ach, es
> gibt ja so wahnsinnig viel interessantes Zeug und so wenig Zeit ;-)

Hmmm... Vollblut-Programmierer... Ich sage es mal so: ein Projekt zu 
haben, das in seine sinnvollen Abschnitte zu zerlegen, Lösungsansätze 
für die Teilprobleme zu finden, Datenblätter lesen und verstehen zu 
können, kein Problem. Assembler kein Problem. C geht, oft schreibe ich 
da aber eher ASM-Abläufe, nutze also die C-Vorteile nicht immer aus 
(Struktur, Union, Bitfelder usw. usw.). C++ nur duch Arduino, keine 
wirkliche Erfahrung mit Klassen usw.

Das SCCB nagele ich wahrscheinlich hier mit dem Datenblatt der OV76770 
in 2 Stunden stabil in AVR-ASM zusammen, in C vermutlich auch, da kommen 
dann aber sicher 10 Leute, die sagen, daß man das doch in C viel 
eleganter mit nutzung aller Möglichkeiten von C machen kann...

Olli Z. schrieb:
> Wow, das ist wirklich wenig, hätte ich nicht mit gerechnet. Da könnte
> man ja sogar noch das ASM "verstehen" ;-)

vermutlich lese und verstehe ich das ASM schneller als den Inhalt einer 
C++-Klasse. ;)

Olli Z. schrieb:
> Ich hoffe das wir mit verschiedenen Versionen keine Probleme bekommen.
> Ich würde halt immer das aktuelle nehmen, also jetzt 7.

Für mich sehe ich da in diesem Zusammenhang keine wirklichen Probleme. 
Ich kopiere nur die .c und .h Dateien in mein angelegtes Projekt, egal 
ob Arduino oder Atmel-Studio und lasse den Compiler meckern. Ist 
normalerweis in diesem Umfang in 10 Minuten angepasst, Änderungen an den 
eigentlich Sourcen sollten nicht nötig sein und Sachen wie das mit dem 
#include  <stdbool.h> sind über verscheiden versionen ohnehin üblich. 
Sollte auch das aktuelle Studio nicht stören, wenn das drinsthen würde. 
Vielleicht gäbe es eine Warnung über eine doppelte Deklaration...

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Olli Z. schrieb:
> Beim Levelshifter benötigst Du keine zusätzlichen Pullups.

Sicher?

@David: könntest Du den genauen Schaltplan Deines Levelshifters hier 
einmal posten?

Sieht der vielleicht so aus:
https://learn.sparkfun.com/tutorials/bi-directional-logic-level-converter-hookup-guide
?

Viele Grüße

Igel1

: Bearbeitet durch User
von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

Hi,

gemäß Implementation Guide v1.0 (Chapter 8) soll man ja zunächst einen 
Reset-Command an Adresse 0x12 (auch "COM7" genannt) absetzen, indem man 
dort das Bit 7 auf 1 setzt (in Summe also eine 0x80 sendet).

Die SCCB-Abfolge dazu ist:

0.)  I2C-Startabfolge senden (SDA geht von High auf Low während
     SDC High ist)

1.)  I2C-Adresse des OV7670 (nämlich 0x21) anpiepsen
     und Schreiboperation signalisieren.
     Die ersten 7 Bit [7:1] codieren die 0x21 und das achte Bit [0] wird
     auf "0" gesetzt, um eine Schreiboperation zu signalisieren.
     In 8-Bit Schreibweise ergibt sich somit eine 0x42, die da
     gesendet wird.

2.)  I2C-Register senden (nämlich 0x12)

3.)  Registerwert senden (nämlich 0x80)

4.)  I2C-Stopabfolge senden (SDA geht von Low auf High während
     SDC High ist)

Diesen Vorgang habe ich einmal mit meinem LogicAnalyzer mitgeschnitten 
und hier als Bild angehängt (interessant: mein OV7670 scheint irgendwie 
doch ein ACK zu senden).

Viele Grüße

Igel1

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

Ach ja: und noch ein Stilbild von meinem traurigen Dasein in einem Hotel 
- dokumentiert mit einer OV7670.

Das Bild ist in Wirklichkeit etwas schärfer als hier hochgeladen, aber 
mit einem Handy ein Bild von einem TFT-Display zu machen, ist halt nicht 
so der Hit. Außerdem habe ich die automatische Verkleinerung beim 
Hochladen in das Forum nicht deaktiviert - das Verschlimmert die 
Qualität nochmals.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Diesen Vorgang habe ich einmal mit meinem LogicAnalyzer mitgeschnitten
> und hier als Bild angehängt (interessant: mein OV7670 scheint irgendwie
> doch ein ACK zu senden).

irgendwo wohl in der SCCB-Doku stand eine Anmerkung wovon dieses Bit 
beeinflußt wird, es kann als 0 oder 1 kommen, ist aber kein ACK. Ich 
glaube, da stand auch in einem Diagramm was von Don't Care. Wer darf es 
nicht ändern? ich? Der SCCB-Slave? Muß ich sowieso nochmal reinschauen, 
auf Anhieb finde ich es jetzt nicht...

Andreas S. schrieb:
> Ach ja: und noch ein Stilbild von meinem traurigen Dasein in einem Hotel
> - dokumentiert mit einer OV7670.

Den Finger nicht im Bild und noch was auf den glasboden gelegt, dann ist 
der Stil sicher "Stillleben".

Gruß aus Berlin
Michael

von Olli Z. (z80freak)


Angehängte Dateien:

Lesenswert?

Andreas S. schrieb:
> Olli Z. schrieb:
>> Beim Levelshifter benötigst Du keine zusätzlichen Pullups.
> Sicher?

Ja, so einen hab ich auch. Das ist von der Schaltung her wohl sowas wie 
„der Klassiker“. Ist auch hier in der Forums Knowledgebase so drin: 
https://www.mikrocontroller.net/articles/Pegelwandler
Die Pullups sind da ja deutlich zu erkennen :-)

Und dann gibt es noch zahlreiche ICs für sowas. Z.B. 
https://www.adafruit.com/product/395 ein 8fach Bi-Direktional. Ebenso 
liefert die 74er Serie auch etliche Shifter, teils Uni (74540), teils 
auch Bi-Direktional wie der 74AVCH2T45. Die Auswahl ist riesig...

von Michael U. (amiga)


Lesenswert?

Hallo,

Olli Z. schrieb:
> Die Pullups sind da ja deutlich zu erkennen :-)

ob 10k im Zweifel niedrig genug sind muß man schauen. Hängt letztlich 
eben von der Anzahl Slaves ab und von den Leitungslängen. Bei den 
üblichen "basteleien geht es eigentlich immer so. Di Schaltung war schon 
ein Vorschlag in einem alten Philips I2C-Dokument.

Ich bin beim Experimentieren da immer recht großzügig, man muß nur im 
Hinterkopf haben, welche Bedeutung die PullUps bei I2C haben.
Sonst sucht man schnell mal die selbst eingebauten Fehler. Da kann man 
mal schnell 2,2k zusätzlich ranhängen, wenn es nichts ändert sollte man 
die richtige Ursache suchen. ;)

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Andreas S. schrieb:
> Ein STM32F429I-Discovery-Board bekommt man für ca. 20-25 EUR in der
> Bucht.
> Dort ist neben einem potenten stm32f429-Prozessor auch schon ein
> ILI9346-Display drauf - optimal zum Experimentieren mit dem OV7670

... kleine Korrektur zu meinem alten Post:
Es handelt sich natürlich nicht um eine ILI9346 sondern um ein 
ILI9341-Display.

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Hallo :)
ich möchte ein kurzes Lebenszeichen absenden :)

Ende dieser Woche bin ich hoffentlich wieder in der Lage mit zu basteln, 
proggen etc.

Der selbstgebaute Logic-Analyzer wäre mal einen Nachbau wert um auch 
einen zu besitzen.

mein Level-Shifter ist dieser hier:
https://www.roboter-bausatz.de/434/i2c-pegelwandler/level-konverter-3.3v-5v-bidirektional-2-kanal

gibt es schon fortschritte in Sachen Kommunikation mit dem SCCB mittels 
des TWI(I2C)-Interface am AVR?

lg. David

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Hallo :)
> ich möchte ein kurzes Lebenszeichen absenden :)

Nett von Dir!

> Ende dieser Woche bin ich hoffentlich wieder in der Lage mit zu basteln,
> proggen etc.
>
> Der selbstgebaute Logic-Analyzer wäre mal einen Nachbau wert um auch
> einen zu besitzen.

Wenn's um den reinen Bastelerfolg geht: do it!
Wenn's Dir nur um die Messmöglichkeiten als solches geht: don't do it!

Hintergrund: für 100 - 200 EUR bekommst Du auf dem Markt LA's, für
deren Funktionalität Du mindestens 2-3 Jahre designen und proggen
müsstest.

Meinen 500MHz LogicPort von Intronix bekommst Du derzeit gebraucht
z.B. für um die 100-130 EUR  (neu für ca. 170 EUR).

Sealae soll auch sehr gut sein - ob man den Clone nimmt, muss jeder
mit seinem Gewissen klar- oder eben nicht klarmachen.

> mein Level-Shifter ist dieser hier:
> 
https://www.roboter-bausatz.de/434/i2c-pegelwandler/level-konverter-3.3v-5v-bidirektional-2-kanal

Hmmm ... kann leider keinen Schaltplan finden.

Aber 2 MOS-Transistoren deuten auf dasselbe Prinzip wie beim oben 
verlinkten Pegelwandler von Sparcfun hin.

Was allerdings der VLDO auf der Platine soll, ist mir etwas unklar.
Schaltplan wäre schon schön.

> gibt es schon fortschritte in Sachen Kommunikation mit dem SCCB mittels
> des TWI(I2C)-Interface am AVR?

Ich fühle mich einfach mal nicht angesprochen, weil ich ja nur Zaungast 
bin und weiterhin beim ARM-Prozessor bleiben werde (... ich muss einfach 
nur abwarten, bis Ihr die Nase von den AVR-Einschränkungen voll habt und 
dann ebenfalls auf den ARM schwenkt :-)

Anyway - habe Euch oben einmal einen Mitschritt meines STM32F429 bei 
seiner Kommunikation mit dem OV7670 angehängt - macht die Zs.hänge etwas 
"greifbarer".

Viele Grüße

Igel1


PS:  habe mir soeben das gebrauchte Dragon-Board hier aus dem MC-Markt 
für 25€ geschnappt (nur für den Fall, dass ich doch noch mitspielen will 
...)

von Olli Z. (z80freak)


Lesenswert?

Kann für den Hausgebrauch einen Saleae nur empfehlen. Günstig und die 
Software ist leicht zu bedienen und kann was. Bin mit meinem 20€ Clone 8 
Kanal 20 Mhz hochzufrieden.

von David D. (saturi)


Lesenswert?

Hallo, kurzes Lebenszeichen.

Ich komme leider nicht mehr meinen To-Dos für meine Abschlussarbeit und 
den Job-Bewerbungen hinter her.
Ich hoffe, dass sich das in den nächsten Wochen legt und ihr trotz des 
vermutlich aufkommenden Sommers nicht die Lust verliert.

Ich werde an dem Thema dran bleiben und weiterarbeiten sobald ich auch 
nur ein bisschen Zeit übrig habe!
Aber grade muss ich eben erst einmal meinen Abschluss sichern ;-) ich 
hoffe ihr versteht das!

liebe Grüße

David

@Olli, wie siehts bei dir aus? nachdem das AtmelStudio ja jetzt bei dir 
läuft. hast du schon Neuigkeiten zur Kommunikation mit dem SCCB übers 
TWI-Interface?

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Aber grade muss ich eben erst einmal meinen Abschluss sichern ;-) ich
> hoffe ihr versteht das!

wäre mir auch wichtiger gewesen, damals... ;)

Ich habe im Moment auch nichts weiter mit der Kamera gemacht, andere 
"sinnlose" Projekte hatten/haben erstmal Vorrang. Liegt aber noch alles 
griffbereit. Wie ich mich kenne, wird es nur eine Frage der Zeit sein, 
bis ich mich da wieder dran festbeiße.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

> Aber grade muss ich eben erst einmal meinen Abschluss
> sichern ;-) ich hoffe ihr versteht das!

Kommt drauf an:  Wenn der Abschluß "Professur" oder "Doktor" heißt,
dann fände ich es doch wichtiger, das Projekt hier erst einmal sauber
abzuschliessen ...

Wenn's allerdings um den Schul- oder Lehr-Abschluss geht, dann ist
der natürlich wichtiger.

Good luck!

Igel1

von Dieter F. (Gast)


Lesenswert?

Andreas S. schrieb:
> Kommt drauf an:  Wenn der Abschluß "Professur" oder "Doktor" heißt,
> dann fände ich es doch wichtiger, das Projekt hier erst einmal sauber
> abzuschliessen ...

Da Du offensichtlich weder das Eine noch das Andere vorhast wärst Du 
doch prädestiniert :-) - ich würde auch eher einen Doktortitel erwerben 
(einen Professorentitel erwirbt man i.d.R. nicht) wie hier eine 
Ansteuerung für eine Kamera zu entwerfen :-) - wenn ich das denn könnte 
:-)

von David D. (saturi)


Lesenswert?

Huhu,

also ich lebe noch und meine Abschlussarbeit läuft auf Hochturen.
Um hier mal ein Datum zu nennen, aller aller spätestens ab dem 11.7. bin 
ich wieder zu 100% dabei, weil am 10.7. meine Verteidigung sein wird.

Nein, ich strebe aktuell "noch" ;-) nicht den Doktortitel an sondern 
begnüge mich erst einmal mit einem Masterabschluss.

Ich hoffe aber, dass ich noch vor Juli die Zeit finde hier weiter zu 
machen :)

stay tuned!

lg. David

von David D. (saturi)


Lesenswert?

So meine lieben Freunde,

ich befinde mich im Endspurt und in zwei Wochen ist alles vorbei.
Ich hoffe Ihr habt eure Boards nicht verstauben lassen und steigt mit 
mir wieder so begeistert ein, wie wir aufgehört haben.

bis dahin!

Sonnige Grüße

David

von Andreas S. (igel1)


Lesenswert?

Hallo David,

eins muss man Dir lassen: Du hast wirklich Ausdauer und Biss - find' ich 
gut.
Wenn's hier weitergeht, werde ich wieder sporadisch mitmachen - je nach 
Zeitkontingent.

Allerdings ist es dieses Jahr auch ein wunderschöner Sommer - da möchte 
ich nicht zu viel vor dem Rechner hocken. Will sagen: schau'n wir mal.

Für Deine Prüfung in 2 Wochen wünsche ich Dir jedenfalls viel Glück 
(obwohl Du das nicht benötigen wirst, denn nach Deinem Schreibstil und 
nach Deiner Programmierung zu urteilen, gehörst Du sowieso zu den 
helleren Köpfen.)

Viele Grüße

Igel1

von Olli Z. (z80freak)


Lesenswert?

Bin ebenfalls mit von der Partie :-)

von Michael U. (amiga)


Lesenswert?

Hallo,

liegt hier auch noch alles griffbereit, anderer Projekte habe ich 
ausreichend. ;)
Ansonsten auch von mir: Viel Erfolg!

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Soooo nachdem nun alles vollbracht ist wollte ich mich heute endlich 
wieder meinem Hobby zuwenden :)

Also habe ich mir gemütlich eine Tasse Kaffe gemacht und die Box mit 
meinem Elektronik-Kram herausgeholt. Der erste Griff ging natürlich zu 
der Kamera, die mir dann promt aus der Hand gerutscht ist und exakt in 
der vollen Kaffetasse untergegangen ist....

Ein Traumstart quasi....

jetzt liegt sie im Salz zum trocknen und ich hoffe, dass - wenn ich sie 
dann morgen einmal anschmeiße - noch alles funktioniert. Sonst muss ich 
mir wohl oder übel eine neue bestellen.

Der erste Projekt-Wiederaufnahme-Post muss also doch noch etwas 
warten...
schade...

In diesem Sinne :D

bis die Tage

lg.
David

von Michael U. (amiga)


Lesenswert?

Hallo,

ich schmunzel jetzt etwas, auch wenn es für Dich ärgerlich ist.
Ich bestelle bei recht preiswerten Bastelobjekten meist generell 2 
Stück.
Nicht, um für solche Unfälle Reserve zu haben,
sondern nur, weil solche und ähnliche Unfälle nie passieren, wenn man 
Reserve liegen hat...

PS: von dieser Kamera habe ich nur eine, ich werde also wohl auf Kaffe 
verzichten, wenn ich den Kram raussuche.
Oder fallen Kameras womöglich auch in Cola-Becher?!?

PS: ich hätte die Optik von der Leiterplatte abgeschraubt, den Kram mit 
destilliertem Wasser abgespült (notfalls auch einfach unter dem 
Wasserhahn) und ausgiebig trocken geföhnt. In die Optik selbst dürfte 
nichts eingedrungen sein, wenn Du sie nicht stundenlang in Kaffe gebadet 
hast.

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Olli Z. (z80freak)


Lesenswert?

Ich finde ohnehin das wir unser Vorhaben deutlich beschleunigen wenn wir 
auf das Modell mit Fifo Speicher wechseln.
Damit können wir auf der einfachen Arduino Plattform bleiben und uns den 
Dingen widmen die wichtig sind, als mit irgendwelchen Tricksereien zu 
versuchen das ohne ans laufen zu bekommen.

von Michael U. (amiga)


Lesenswert?

Hallo,

Olli Z. schrieb:
> Damit können wir auf der einfachen Arduino Plattform bleiben und uns den
> Dingen widmen die wichtig sind, als mit irgendwelchen Tricksereien zu
> versuchen das ohne ans laufen zu bekommen.

Auf der Arduino Plattform bin ich hier ohnehin, der ist es egal, ob ich 
da Arduino spezielles oder plain C oder eine bunte Mischung von beiden 
reinpacke, die compiliert das schon richtig.

direkt gefragt: was ist das Ziel der Geschichte?
Also was will letztlich jeder hier mit der Kamera machen?

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Olli Z. (z80freak)


Lesenswert?

Ich dachte das hatten wir doch ein paar hundert Antworten weiter oben 
schon geklärt?! :-)
Wir wollten damit natürlich auch ein Biöd übertragen, aber eigentlich 
ging es ums Protokoll und die Ansteuerlokig sowie Videoformate.

: Bearbeitet durch User
von David D. (saturi)


Lesenswert?

Olli Z. schrieb:
> Ich finde ohnehin das wir unser Vorhaben deutlich beschleunigen wenn wir
> auf das Modell mit Fifo Speicher wechseln.
> Damit können wir auf der einfachen Arduino Plattform bleiben und uns den
> Dingen widmen die wichtig sind, als mit irgendwelchen Tricksereien zu
> versuchen das ohne ans laufen zu bekommen.

Das denke ich auch, dann können wir in Ruhe das Bild verarbeiten, an den 
PC schicken und dort anzeigen.
Wenn wir den ganzen ablauf dann einmal hinbekommen haben sollten, kann 
man sich die option ja offen halten, den Sprung auf die andere Kamera 
ohne Fifo zu versuchen.

Damit haben wir dann erstmal nicht das Frequenzproblem richtig?
Eine mit Fifo hab ich mir ja damals auch zu gelegt.

Darf ich euch fragen, wie ihr die Kamera anschließt?

Ich hatte mir bei der Kamera ohne Fifo ein Flachbandkabel mit 
Pfostenstecker gemacht.
müsste für die mit Fifo dann heute Abend nochmal ein neues machen oder 
habt ihr da bessere Lösungen?

von Olli Z. (z80freak)


Lesenswert?

Ich habe auch noch eine mit Fifo, dann bleiben wir erstmal dabei! :-)

Für Versuchsaufbauten finde ich ja Dupont-Stifte praktisch. Daher würde 
ich, falls nicht bereits vorhanden, an die Platine der Kamera eine 
Stiftleiste löten (am besten nach hinten gerichtet damit die Kabel 
später nicht vor der Linse rumlammern) und dann mit Buchse/Stecker 
Dupont-Wires aufs Steckbrett verbinden.

von Michael U. (amiga)


Lesenswert?

Hallo,

Olli Z. schrieb:
> Ich dachte das hatten wir doch ein paar hundert Antworten weiter oben
> schon geklärt?! :-)
> Wir wollten damit natürlich auch ein Biöd übertragen, aber eigentlich
> ging es ums Protokoll und die Ansteuerlokig sowie Videoformate.

meine Frage deshalb: die Kamera kann 640x480 als Auflösung.
Mit einem AVR sind, egal, ob mit oder ohne FiFo alle paar Sekunden ein 
Bild möglich. Das sind bei 16Bit unkomprimiert also 600kB pro Bild wenn 
ich mich nicht verrechet habe.
Wir reden also von einem Bild alle 2-3s (mit FIFO) oder alle 15s ohne 
FIFO.
Als JPEG dürfte ein Bild um die 30-50kB sind (ist betwas das, was meine 
alte DC3840 packt).
Wenn Arduino auch z.B. der ESP32 ist, sind ca. 6-10 Bilder/s direkt auf 
einem angeschlossenen Display machbar,
Als "Sucher" für einen "Fotoapparat" gerade noch nutzbar, ein solches 
Projekt liegt irgendwo in Netz.

Für mich wäre also eine denkbare Anwendung z.B. alle paar Minuten eine 
Wetteraufnahme per WLAN in mein FHEM zu schicken. Da würde ich ohnehin 
dann einen ESP32 nehmen. Das ginge prinzipiell auch mit einem AVR und 
LAN-IC dran, hier liegt sicher noch ein ENC28J60 rum...

Meine Frage ging also eher in Richtung: was könnte für Euch eine 
mögliche Anwendung in dem Umfeld sein?

Gruß aus Berlin
Michael

von Olli Z. (z80freak)


Lesenswert?

Also ich, für meinen Teil, habe und brauche keine konkrete Anwendung und 
sehe die Sache rein akademisch :-)

von Michael U. (amiga)


Lesenswert?

Hallo,

Olli Z. schrieb:
> Also ich, für meinen Teil, habe und brauche keine konkrete Anwendung und
> sehe die Sache rein akademisch :-)

ok, dann sehen wir es genauso. Ich frage nachher mal meinen Bekannten, 
ob er die mit FIFO hat, dann lege ich die erstmal neben meine ohne. ;-)
Seine liegt nähmlich auch nur sehr akademisch rum...

Aber: haben ist besser als brauchen!

Gruß aus Berlin
Michael

von David D. (saturi)


Angehängte Dateien:

Lesenswert?

Das freut mich und ich hoffe, dass dein Bekannter die Kamera entbehren 
kann :)

Ich denke wir sind uns alle einig, dass dieses Projekt nur dem 
Selbststudium (in meinem Fall) oder dem Auffrischen von vorhandenem 
Wissen (evtl. in eurem Fall) dienen soll.

Ich bin für meinen Teil schon Glücklich wenn ich ein Foto mit der Kamera 
schießen und darstellen kann ;-)

Ich kenne mich mit FIFOs nicht wirklich aus. Das Grundprinzip ist zwar 
klar, aber ich werde mich erstmal einlesen müssen.
Zunächst sollten wir aber kurz abklären, dass wir alle mit den selben 
Werkzeugen arbeiten :-)

Auf meiner Kamera ist ein AL422B Frame-Buffer Fifo verbaut. Ist das der 
gängige, der ebenfalls bei euch bestückt ist?

Angehängt habe ich euch mal das Pinlayout, dass bei mir per Stiftleiste 
zum kontaktieren bereit steht.

PCLK und XCLK scheinen weggefallen zu sein, dafür kommen weitere sechs 
Pins dazu (vermutlich zur Steuerung/Auslesen des Fifos)

Ich hoffe bei euch sieht es ähnlich aus.

liebe Grüße David

EDIT:
Bei genauerer Betrachtung habe ich gerade festgestellt, dass neben dem 
FIFO ebenfalls noch ein Quarz verbaut ist, was auch erklären würde, 
warum wir keine XCLK mehr einspeisen müssen.

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

@David D.:

Musste herzlich über Deinen Kaffeetassen-Absturzbericht lachen - das 
hast Du wirklich köstlich beschrieben.

Was die FiFo-Geschichte angeht, so habe ich neben 2x OV7670 hier auch 
irgendwo eine OV7670 mit FiFo rumfliegen. Wenn die Zeit bei mir also 
ausreicht, so könnte ich auch ein bißchen mitspielen (vermutlich aber 
nicht vor Ende August).

Muss allerdings gestehen, dass mich die FiFo-Geschichte wenig reizt, da 
sie kaum anspruchsvoll sein dürfte und noch viel weniger zu meinem 
eigenen Zielszenario passt (es lautet: mit einem STM32 passable Bilder 
aus der FiFo-losen OV7670 herausfischen, dann jpeg-komprimieren und an 
einen ESP8266 zum Versand als Email-Attachment übergeben - denn meine 
Mäusefalle soll irgendwann an Ihren Besitzer Bilder von dem/den Insassen 
schicken).

Wenn's allerdings nur darauf ankommt, ein paar Bilder mit einem atmega 
aus einer OV7670 zu ziehen, so dürfte die FiFo-Version wegen nicht 
vorhandener Timing-Probleme ca. 100x einfacher auszulesen sein als die 
Non-FiFo-Version.

Nevertheless: die FiFo-Version bietet sicherlich eine gute Gelegenheit, 
sich in endlicher Zeit ein schönes Erfolgserlebnis durch erste 
ausgelesene Bilder zu verschaffen. Und danach kannst Du ja immer noch 
auf den STM32 mit Non-FiFo umsteigen :-)

Viele Grüße und Kaffee ahoi

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Wenn's allerdings nur darauf ankommt, ein paar Bilder mit einem atmega
> aus einer OV7670 zu ziehen, so dürfte die FiFo-Version wegen nicht
> vorhandener Timing-Probleme ca. 100x einfacher auszulesen sein als die
> Non-FiFo-Version.
reivoll wäre, das auf einem ESP32 komplett zu realisieren.
Ob jemand schon einen (einfachen?) JPEG-Encoder auf dem ESP32 compiliert 
hat, weiß ich nicht. SPI-PS-RAM kann man beim ESP32 direkt einbinden, es 
gibt auch Module, wo schon welcher drauf ist.

Machbar müßte es sein, auch ohne FIFO.

Gruß aus Berlin
Michael

von Tom (Gast)


Lesenswert?

Zur JPGE-Dekodierung hat elm-chan was:
http://elm-chan.org/fsw/tjpgd/00index.html

Außerdem gibt es picojpeg:
https://github.com/richgel999/picojpeg

Sollte beides vom Flashverbrauch her nicht zu dick auftragen...

von Michael U. (amiga)


Lesenswert?

Hallo,

jpeg Decoder auf dem ESP32 ist verfügbar und macht seinen Job.
Gibt ein paar Einschränkungen bei der Ausgabeskalierung, nur 
ganzzahligen Teiler usw., für eine Displayanzeige aber kein wirkliches 
Problem.
Encoder habe ich noch nichts gesehen.
Ich denke, man wird sich da sicher etwas beschränken müssen bei 
Formaten/Profilen oder so. Habe mich mit JPG-Encoding noch nie selbst 
befasst.

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Guten Abend,

ja es ist ruhig geworden, aber ich denke, dass können wir alle auf die 
klimatischen Bedingungen zurückführen, die seit einigen Wochen in ganz 
Deutschland herrschen.
Ich genieße derzeit die Sonne und freue mich schon auf die verregneten 
kühleren Tagen, an denen man erträglich die Projektarbeit wieder 
aufnehmen kann :)

lg.

David

von Andreas S. (igel1)


Lesenswert?

Dito.

Viele Grüße aus bella Italia

Igel1

von David D. (saturi)


Angehängte Dateien:

Lesenswert?

Liebe Urlauber,

ich wende mich an euch mit einer Verzweiflungstat ;-)

Ich habe in den vergangenen Tagen intensiv versucht, den OV7670 mit Fifo 
über das TWI anzusteuern.
Das Ergebnis kann ich nicht ganz einordnen. Zunächst hat es nach dem 
Equipment Aufbau und erstem Test auf Anhieb funktioniert. ich konnte die 
Device ID mit 0x76 0x73 auf den Adressen 0x0A und 0x0B auslesen. Auf 
Anhieb! Damit war die Motivation gegeben Großes zu leisten.

Einziges Manko: eigentlich werden diese 2 Read Befehle in der 
Endlosschleife ausgeführt. Bei mir stoppt diese aber nach einfachem 
Durchlauf. Die Überprüfung mit dem Oszi zeigte mir, dass die SDA Leitung 
auf Low verbleibt und nicht wie vorgesehen zum Ende einer Kommunikation 
wieder auf High gezogen wird.

Nach etlichen Code Veränderungen und Stecküberprüfungen bis mitten in 
die Nacht hatte ich immer noch keinen brauchbaren Ansatz. Verschenkte 
aber weitere 3 Stunden in der Fehlersuche, in dem ich zunächst unbemerkt 
bei den genannten Stecküberprüfungen ein Kabel falsch zurücksteckte... 
no Comment! (Schieben wir es auf die Müdigkeit)

das Studium etlicher Webseiten und allen möglichen Variationen konnte 
mir keinen Erfolg bescheren. Der aktuellste Stand ist, dass manchmal die 
Kommunikation zu funktionieren scheint und manchmal nicht. Klingt für 
mich zunächst nach etwas Undefiniertem - ich kann es aber nicht finden.

Zum Schluss hat mich ein Satz im Datenblatt des SCCB besonders 
irritiert: Sinngemäß lautete dieser, dass während des Don't care bits 
(Was beim TWI dem ACK/NACK Bit entspricht) der Master sicherstellen 
muss, dass der Bus auf LOW gezogen wird.
Diese Einstellung kann ich aber beim TWI Interface gar nicht 
beeinflussen, weil dieser ja den Pin auf Eingang Schaltet, um das ACK zu 
identifizieren?

Meine aktuelle Theorie lautet also, dass entstehende High Signale beim 
ACK den Bus ins straucheln bringen. Sehr Schwammige Aussage und ich 
erwarte von euch eine bessere Erklärung. Der Code ist angehängt.

Ich habe mich dann eben wieder entschieden mein selbstgeschustertes 
BitBangig auszugraben und siehe da, alles funktioniert wie gewünscht. 
Dennoch erinnere ich mich an die Kritik von euch, unter anderem was die 
OpenDrain Beschaltung angeht.

Daher hoffe ich, dass ihr meinen Fehler im TWI Bereich findet und wir 
das Ding ans laufen kriegen. Offensichtlich gibt es genug, die das mit 
der Arduino Lib WIre.Beginn ganz simple hinbekommen....

: Bearbeitet durch User
von Tim (Gast)


Lesenswert?

David D. schrieb:
> Diese Einstellung kann ich aber beim TWI Interface gar nicht
> beeinflussen, weil dieser ja den Pin auf Eingang Schaltet, um das ACK zu
> identifizieren?
Vielleicht kannst Du dafür noch einen Pin opfern und im richtigen Moment 
die Leitung mit 100 Ohm (o.ä.) auf low ziehen.

> Ich habe mich dann eben wieder entschieden mein selbstgeschustertes
> BitBangig auszugraben und siehe da, alles funktioniert wie gewünscht.
Dann würde ich das so lassen. Wenn kein regelkonformes I2C verwendet 
wird, kann man eben die Hardwareunterstützung des Controllers nicht 
verwenden...

von David D. (saturi)


Lesenswert?

Hallo Tim, vielen Dank für Deinen Beitrag.
Den Pin im richtigen Moment auf Low zu schalten halte ich für sehr 
kompliziert. Da müsste ich ja mit einem Timer den Zeitpunkt abzielen, 
der ja von der Frequenz der Übertragung abhängt.


lg. David

von Michael U. (amiga)


Lesenswert?

Hallo,

da es ja hier recht ruhig geworden ist und die Zeit ohnehin weitergeht:
ich habe mir mal das M5Stack Cam Modul bestellt:
https://www.amazon.de/MakerHawk-M5Stack-Antenna-Arduino-Raspberry/dp/B07F2DNX6M

Die Demosource von github:
https://github.com/igrr/esp32-cam-demo
habe ich mit großer Mithilfe meines Bekannten inzwischen nicht schön 
aber lauffähig in die ArduinoIDE geworfen.

Ich fand das als Spielerei interessant, die Kamera ist durchaus 
brauchbar, max. 1600x1200 Pixel und kann auch JPEG ausgeben.

Bild gibt es morgen...

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

@Michael U.:

Das klingt wirklich sehr interessant.
Bin auf Deine Bilder gespannt.

Dient der USB-C-Anschluß zur Stromversorgung?
Wie hast Du die Kamera mit Deinem Board verbunden?
Und musstet Ihr viele Klimmzüge machen, bis das Teil lief?

Gibt es Vorteile, die Dein Modul gegenüber den 8$-Varianten
von Aliexpress hat? (vgl. 
https://www.aliexpress.com/item/OV2640-camera-module-Module-2-million-pixel-electronic-integrated-with-jpeg-compression-new-big-promotion/32886018967.html)

Viele Grüße

Igel1

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

Andreas S. schrieb:
> @Michael U.:
> Dient der USB-C-Anschluß zur Stromversorgung?
ist natürlich auch COM für den ESP32.
> Wie hast Du die Kamera mit Deinem Board verbunden?
Das ist Kamera + ESP32-Board + Akkumöglichkeit + lade-IC usw.
> Und musstet Ihr viele Klimmzüge machen, bis das Teil lief?
An USB stecken, mit dem AP des ESP32 verbinden, Webseite aufrufen, 
Bilder anschauen...

> Gibt es Vorteile, die Dein Modul gegenüber den 8$-Varianten
> von Aliexpress hat?

Erklärt sich mit obigen von selbst, Kamera-Modul + ESP32-Modul + 
USB-Adapter + Akku-Lade-IC.

Soweit die Theorie.
Ich habe das Modul als Spielerei bestellt, kein Drahtverhau, einfach mit 
der Software experimentieren.

Nun die Praxis: in der Lieferung war ein Mini-Kühlkörper ohne jegelichen 
Hinweis, taucht auch in keiner Beschreibung auf.
Der ESP32 kann ja durchaus merklich warm werden, wenn wie hier 
durchgehend WLAN-Traffic gemacht wird. Stört den auch nicht. Hier gab es 
nach relativ kurzer Zeit fehlerhafte Bilder, hängende Übertragung usw.
Mit dem Kühlkörper ging es seltsamerweise, leider auch nur etwas länger 
bis zu den Fehlern.
Im M5Stack-Forum habe ich dann einen Hinweis gefunden: die Jungs haben 
als PullUp am SCCB-Bus nur die internen des ESP32 genommen. Die sind 
aber eigentlich sowieso viel zu hochohmig für I2C/SCCB, auch bei nur 
einem Slave und kurzen Leitungen. Wenn der ESP warm wird, werden sie 
vermutlich noch hochohmiger und es hagelt IO/Fehler.
Der Poster dort im Forum hat PullUps mit 4,7k nachgerüstet und die 
Probleme waren weg.
Kann ich mit leben, nur ist die einzige zugängliche Stelle die Lötseite 
des Kamera-Steckverbinders und die hat Rastermaß irgendwo um 0,x mm...
Das freut mich auf meine "alten Tage", werde nachher mal schauen, dünne 
Litzenadern an Pin 3,5 und 11 des Verbinders zu löten und daran 2 
SMD-Widerstände.

Das Bild ist ein nur beim Experimetieren mal gespeichert, 
Original-Firmware, 800x600 (kann man dort erstmal nicht verändern), 
JPEG-Kompression unbekannt.

Mal schauen, was mein Bekannter heute meldet, der hat seine gestern 
abgeholt.

Gruß aus Berlin
Michael

von Igel1 (Gast)


Lesenswert?

@Michael:

Danke für den kleine Bericht.
Gutes Bild - macht wirklich neugierig ...

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Guten Abend!

da sind mir eure Antworten entgangen. Da scheine ich die E-Mail 
Notifikation verpasst zu haben.

Ich wollte die Tage schon einen Post verfassen, bin aber dann doch nicht 
dazu gekommen. Ich habe die letzten Wochen nicht geruht und habe einiges 
hinbekommen (aber noch kein Bild ;-) )

morgen dann mehr...

machen wir es wie die Politiker in der Abgasaffaire :D

lg. David

von Michael U. (amiga)


Lesenswert?

Hallo,

zur M5Stack Cam: ich hatte am 22.09. nich 2 Stück bei ebay in China 
bestellt
https://www.ebay.de/itm/M5Stack-ESP32-Camera-Module-Development-Board-3D-Wifi-Antenna-Mini-Camera-Board-/173386455615
keine Ahnung, ob es der gleiche Händler ist.
Zumindest kamen die Kameras bereits am 02.10. bei mir an.

Das Problem zum SCCB-Bus tritt auch bei diesen Modulen auf. Mein 
BEkannter hat inzwischen PullUps nachgerüstet, ich muß mir da bei 0,6mm 
Pitch am Steckverbinder noch was einfallen lassen. Oder einfach meinen 
Bekannten damit beschäftigen...

Mit der Änderung läuft das Modul absolut stabil, auch stundenlang zum 
Beobachten seines 3D-Druckers beim Drucken.

Wenn man bedenkt, daß das OV2640 Modul nur mit Adapterplatine sowieso 
schon für knapp 10€ angeboten wird, diskutiere ich lieber mit der 
Software der M5Stack Cam rum.
Die Kamera bekommt man zwar einzeln für rund 3.50€ aus China oder bei 
Amazon, nur was soll ich dann mit einer 24-pol. SMD-Buchse mit 0,6mm 
Kontaktabstand anfangen?!?

So, jetzt erstmal was sinnvolles machen...

Gruß aus Berlin
Michael

von David D. (saturi)


Angehängte Dateien:

Lesenswert?

Guten Morgen,
... doch wieder zwei Tage verspätet aber dafür mit einem ausführlichen 
Bericht.
Was bisher geschah:
Wie meinem letzten, thematischen Post zu entnehmen, habe ich von der 
I2C-Variante zurück auf die eigene Bit-Banging Variante gewechselt und 
hatte damit Erfolg, eine Kommunikation aufbauen zu können.
Als nächstes musste ich mir Gedanken machen, wie der FIFO ausgelesen 
werden kann.
Bild aufnehmen:
Dafür setze ich den write pointer zurück, warte auf ein VSync Signal, 
setzte den Write Enable Pin und warte auf die nächste Flanke bei VSync. 
Dann deaktiviere ich Write Enable wieder.
An dieser Stelle sollte das Bild jetzt vollständig im FIFO liegen.
Auslesen:
Ich habe eine Funktion erstellt mit drei Input Parametern: Auflösung y 
Richtung, Auflösung x Richtung und Bytes Per Pixel. In dieser 
Reihenfolge sind die drei Parameter in For-Schleifen verschachtelt. In 
der innersten lese ich das anstehende 8Bit Signal aus und Clock den 
Read-Pointer.
das ausgelesene parallele 8 Bit Signal setzte ich zu einem Byte zusammen 
und übertrage es per Uart an den PC.
Wie aber gehe ich mit den Daten am PC um? Die ersten Versuche waren 
logischerweise mit einem fertigen Terminal Programm. Nachdem ich es aber 
geschafft habe, nicht nur FF oder 00 für jedes Byte zurückzubekommen, 
konnte ich mit der Vielzahl an Bytes nicht mehr umgehen. Also habe ich 
mich daran gemacht mit dem visual Studio ein eigenes „Terminal“ für den 
OV7670 zu schreiben. Da ich auch hier wieder viel lernen muss, zieht 
sich diese Arbeit etwas hin, besonders was die Verarbeitung von 
eingehenden Datenströmen angeht.
Aber, ich habe es geschafft, die Daten, die am fertigen Terminal 
ankommen, zu kopieren und als eine CSV Datei zu speichern. Diese Datei 
kann ich mit meinem Programm als ein Bild einlesen. Aktuell bekomme ich 
da aber nur ein „Fehler Bild“ was meiner Meinung nach, nach einem nicht 
vollgeschriebenen Fifo oder anderen Fehlern aussieht. (Siehe Anhang).
Aktuell versuche ich den eingehenden Daten stream direkt mit meinem 
Programm verarbeiten zu können.
Das ist also mein Stand. Bei Interesse gehe ich auch gerne tiefer ins 
Detail.
Ich vermisse den Olli noch in unserer kleinen Runde ?

Das Board sieht schick aus. Vlt. Werde ich auch darauf mal zurückkommen, 
sobald mein OV läuft ?
aber wie schon des Öfteren diskutiert werde ich zunächst bei Arduino 
bleiben und ggf. später einmal den ESP ausprobieren.

lg. und ein schönes Wochenende

David

von Michael U. (amiga)


Lesenswert?

Hallo,

vielleicht hätte ich mir doch von meinem Bekannten die OV760 mit FiFo 
mitnehmen sollen? Naja, kann ich am nächsten Freitag ja noch machen...
Einerseits finde ich Deine Ausdauer gut, ich bin im Moment aber etwas 
hin- und hergerissen...

Was für ein Bildformat liest Du von der kamera in den Fifo ein?
Der kann von der Größe nicht alle Formate und Größen und die Effekte, 
die sich dann ergeben, sind lustig, wie mein Bekannter feststellen 
mußte.

Den Bildern hätte ich einen passenden BMP-Header verpsst, der ist 
überschaubar auch auf dem AVR gemacht, und eben vor den Daten 
rausgeschickt.
Eingelesen hätte ich "old school" mit altem TeraTerm in den Log-Buffer 
aund dann als .bmp gespeichert und angezeigt.
Wahlweise das File in einen Hex-Editor geworfen und geschaut, was ich 
mir da für Müll geschickt habe.

Ich habe soviel Extra-drumrum auch schon programmiert, bei meinem 
LogicAnalyzer z.B. in VB6. Aber erst, nachdem die empfangenen Rohdaten 
ok waren und es um die Anwendung ging.

Ich bin durchaus noch interessiert hier mitzuspielen. Macht dann aber 
für mich nur Sinn, wenn ich einen Source durch den Compiler schicken 
kann und flashen und dann mir die Ergebnisse anschauen kann. Das mache 
ich gern auch mit Rohdaten ohne header usw, dann muß aber eindeutig 
sein, was ankommen soll, Format, Auflösung usw.

Sonst ist es zuviel stochern im Nebel für mich, wenn ich mir erst aus 
den Cam-Inits und den Loops im Source zusammenreimen soll, was 
rauskommen müßte. Ist ja auch eine Zeitfrage.

David D. schrieb:
> Das Board sieht schick aus. Vlt. Werde ich auch darauf mal zurückkommen,
> sobald mein OV läuft ?
> aber wie schon des Öfteren diskutiert werde ich zunächst bei Arduino
> bleiben und ggf. später einmal den ESP ausprobieren.

Ich sage es jetzt mal so: ist auch Spaß an der Freude. Ich darf meine 
teilweise recht bescheidenen C/C++ Kenntnisse stark aufbessern, um mich 
mit den Espressiv Demo-Source auseinanderzusetzen. Ich darf mit mit den 
Modi und dem Datenblatt der OV2640 auseinandersetzen, mit der 
Problematik, das die Jungs nicht nur den Hardware-Design-Fehler drin 
haben (mein Bekannter darf jetzt löten...) sondern dem Modul nicht auch 
noch einen PSRAM spendiert haben. Der ESP32 kann nur 128k im Stück 
reservieren, damit ist bei 800x600 JPG Ende. Ich würde aber gern die 
volle Auflösung 1600x1200 als Einzelbild übertragen bekommen.

Wehalb ich das mache? Ich könnte die Cam z.B. auf das rumliegende 20€ 
"Roboter"-Fahrgestell kleben, 640x480 mit 20-30 Frames/s sind dafür 
ausreichend und auf Knopfruck ein Standbild in voller Auflösung wäre 
gut.

Hat auch alles keinen wirklichen Nährwert...
Die Kombination OV7670 mit Mega328 hat da null Chance.
OV7660 mit ESP8266, besser ESP32 würde da noch machbar sein.

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,

auch wenn es etwas am Thema vorbeigeht:
ich hatte mir noch ein OV2640 Modul bestellt
https://eckstein-shop.de/OV2640-Camera-Board
mit kurzen Dopont-kabeln an ein ESP32 DevKit gesteckt und...
Kameratyp nicht erkannt -> reset ist auf dem Modul nicht mit dem Pin 
verbunden sondern mit 0-ohm Brücke an einer R/C-Resetschaltung.
Dem Cam-modul gefiel es offenbar nicht, daß der ESP32 XCLK erst recht 
spät nach PowerOn erzeugte. Die Camera braucht aber XCLK auch z.B. für 
SCCB.
Also umgelötet und der Kameratyp wurde richtig erkannt.
Kamera war jetzt auch im Netz, das ankommende JPED aber laut Browser 
nicht dekodierbar. Nach einigem kramen in den Sourcen beschlossen, XCLK 
von 20MHz auf 10MHz runtergesetzt und jetzt gab es auch Bild.
Das Modul ist also recht sensibel am Bus mit den 10cm Leitungen...
Letztlich ist es mit 8MHz XCLK absolut stabil.

Mit der Erkenntnis ein originales M5Stack CAM Modul so geflasht und...
stabil, keine Aussetzer oder Bildehler mehr auch ohne nachgerüstete I2C 
PullUp Widerstände. Hier scheinen sich wirklich alle Toleranzen nach 
Murphy zu treffen, mit den Widerständen gehen auch die 20MHz XCLK, aber 
auch gerade noch so, wie mein Bekannter bei einer Kamera bemerkt hat.

Das als Tipp, falls ich jemand das M5Stack CAM kaufen sollte. Das in die 
ArduinoIDE verpackte cam-demo von github schicke ich dann gern per Mail 
zu, ich will es hier nicht reinstellen, weil es sich nicht mit allen 
IDF-Versionen lauffähig compilieren läßt. Mit der ESP32 
Boardmanager-Version 1.0.0 geht es auf jeden Fall erstmal.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> reset ist auf dem Modul nicht mit dem Pin
> verbunden sondern mit 0-ohm Brücke an einer R/C-Resetschaltung.
> Dem Cam-modul gefiel es offenbar nicht, daß der ESP32 XCLK erst recht
> spät nach PowerOn erzeugte. Die Camera braucht aber XCLK auch z.B. für
> SCCB.
> Also umgelötet und der Kameratyp wurde richtig erkannt.

Könntest Du das bitte etwas näher erklären?
Hast Du die R/C-Resetschaltung vom Reset-Pin der Kamera getrennt
und separat herausgeführt und dann separat von Deinem ESP32
den Reset angestoßen nachdem XCKL stabil war ?

> Kamera war jetzt auch im Netz, das ankommende JPED aber laut Browser
> nicht dekodierbar. Nach einigem kramen in den Sourcen beschlossen, XCLK
> von 20MHz auf 10MHz runtergesetzt und jetzt gab es auch Bild.

Wie hast Du das Bild ausgewertet?
Hast Du es zunächst in Deinen Computer übertragen? (wenn ja: wie?)

> Das Modul ist also recht sensibel am Bus mit den 10cm Leitungen...
> Letztlich ist es mit 8MHz XCLK absolut stabil.

Welche Frameraten erreicht man damit?

> Mit der Erkenntnis ein originales M5Stack CAM Modul so geflasht und...
> stabil, keine Aussetzer oder Bildehler mehr auch ohne nachgerüstete I2C
> PullUp Widerstände. Hier scheinen sich wirklich alle Toleranzen nach
> Murphy zu treffen, mit den Widerständen gehen auch die 20MHz XCLK, aber
> auch gerade noch so, wie mein Bekannter bei einer Kamera bemerkt hat.

Interessant. Danke für die Hinweise.

> Das als Tipp, falls ich jemand das M5Stack CAM kaufen sollte. Das in die
> ArduinoIDE verpackte cam-demo von github schicke ich dann gern per Mail
> zu, ich will es hier nicht reinstellen, weil es sich nicht mit allen
> IDF-Versionen lauffähig compilieren läßt.

Bitte erkläre einem Arduino-Gelegenheitsuser noch etwas die Zs.hänge:
Du installierst den Board Manager für ESP32 - das habe ich verstanden.
Dann wählst Du Dein ESP32-Board aus (by the way: welches hast Du?).

Und wie integrierst Du dann die cam-demo von github?
(bitte poste einmal den Link zu dem cam-demo github-Projekt)
Muss man dann zunächst die cam-demo in der ESP-IDF compilieren,
um sie anschließend in Arduino als Library irgendwie importieren/
integrieren zu können?

> Mit der ESP32
> Boardmanager-Version 1.0.0 geht es auf jeden Fall erstmal.

Viele Grüße

Andreas

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Hast Du die R/C-Resetschaltung vom Reset-Pin der Kamera getrennt
> und separat herausgeführt und dann separat von Deinem ESP32
> den Reset angestoßen nachdem XCKL stabil war ?
Es geht um dieses Modul:
https://eckstein-shop.de/OV2640-Camera-Board

Auf der Rückseite sind an der Unterkannte einige 0-Ohm Brücken, die 
festlegen, ob PowerOn und Reset auf die Stiftleite gehen oder intern 
passend belegt werden.
Im Lieferzustand sind die beiden Signale nicht mit den Pins verbunden...
Hinweise dazu gibt es (natürlich) keine, man findet aber den Schaltplan 
im Netz und kann es dann selber überprüfen.
Ich mache da gern mal ein Bild der Rückseite mit Beschriftung der 
zuständigen Lötpunkte wenn jemand auch genau diese Kamera Modul-Version 
hat.

Zum Rest: ja, die Software erzeugt einen Restimpuls nachdem sie XCLK 
eingerichtet hat. Der nutze nur nicht viel, weil eben der Reset-Pin beim 
Modul nicht angeschlossen war.

>> Kamera war jetzt auch im Netz, das ankommende JPED aber laut Browser
>> nicht dekodierbar. Nach einigem kramen in den Sourcen beschlossen, XCLK
>> von 20MHz auf 10MHz runtergesetzt und jetzt gab es auch Bild.
>
> Wie hast Du das Bild ausgewertet?
> Hast Du es zunächst in Deinen Computer übertragen? (wenn ja: wie?)

Ich habe das fertige Demo von Espressif:
https://github.com/m5stack/esp32-cam-demo

Die Anpassungen, damit es sich aus der ArduionIDE compilieren läßt, hat 
mein Bekannter gemacht. Ich will die Sketch-Version hier nicht anhängen, 
weil sie eben nur eine Spielwiese ist, ich sende sie aber gern per Mail.

> Welche Frameraten erreicht man damit?
Real bei 800x600  ca. 3 Frames/s, ich habe muß mich erstmal mit der 
Software auseinandersetzen...

> Bitte erkläre einem Arduino-Gelegenheitsuser noch etwas die Zs.hänge:
> Du installierst den Board Manager für ESP32 - das habe ich verstanden.
> Dann wählst Du Dein ESP32-Board aus (by the way: welches hast Du?).

Richtig. Im Moment hängt sie an so einem ESP32 Modul im NodeMCu-Format, 
prinzipiell ist es aber eigentlich egal, als Beispiel:
https://www.amazon.de/ELEGIANT-ESP32-ESP32-DEVKITC-genuine-ESP-WROOM-32/dp/B06XWVS2SJ

> Und wie integrierst Du dann die cam-demo von github?
> (bitte poste einmal den Link zu dem cam-demo github-Projekt)
> Muss man dann zunächst die cam-demo in der ESP-IDF compilieren,
> um sie anschließend in Arduino als Library irgendwie importieren/
> integrieren zu können?
Nein, Sketchordner ESP32-Cam anlegen, alle Dateien des Demos in den 
Sketchordner, den Webserver noch dazu (liegt auch bei github). Dann die 
main.c in ESP32-Cam.ino umbenennen damit die ArduinoIDE zufrieden ist.
Es hagelt diverse Fehlermeldungen weil normalerweise im ESP-IDF einige 
Infos beim Compile abgefraht werden.
Den Kram hat mein Bekannter und ich passend nachgetragen, die "fertige" 
Version kann ich Dir, wie gesagt, per Mail zusenden.

Das Projekt geht ohne Änderungen auch auf der M5Stack Cam:
https://www.amazon.de/MakerHawk-M5Stack-Antenna-Arduino-Raspberry/dp/B07F2DNX6M/ref=sr_1_1?s=computers&ie=UTF8&qid=1539026864&sr=1-1&keywords=m5stack+cam

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

@Michael:

Danke für Deine Infos!
Toll, dass Ihr dies alles ans Fliegen bekommen habt.
Mir juckt es dabei arg in den Fingern - aber es hilft alles nichts:
Als 120% Berufstätiger habe ich aktuell schlicht nicht genügend Zeit
fürs Basteln und muss mich daher mit Kopfkino begnügen ...
Allerdings: für Letzteres hast Du einen guten Film gedreht :-)

Danke nochmals für Deine Erklär-Mühen.

Viele Grüße

Igel1

von David D. (saturi)


Angehängte Dateien:

Lesenswert?

Guten Abend/Nacht,

Die Kommunikation ist vorhanden! Wie erwähnt bastel ich grade an meinem 
kleinen Terminal PRogramm, dass in naher Zukunft auch die Bilder 
darstellen können sollte.
Heute ist mir der Durchbruch gelungen, nachdem ich Tage damit verbracht 
habe meinen Kenntnisstand um Themen wie Events, Delegaten und Threading 
in C# zu erweitern.

Herausbekommen ist folgendes:
Ich kann die einzelnen Register vom PC aus lesen.
Aufgabe für morgen ist es, die Register vom PC aus schreiben zu können. 
Um sich das dauernde Flashen des uController zu sparen, wenn man nur 
kleine Änderungen ausprobieren möchte.

Anbei ein Screenshot zum aktuellen "Roh-Modell"


lg. David

von Andreas S. (igel1)


Lesenswert?

Hallo David,

das sieht klasse aus!

Da viele Register schlecht oder gar nicht dokumentiert sind, hätte man 
mit Deinem Tool eine gute Möglichkeit, die Auswirkungen von Änderungen 
der Parameter in den OV7670-Registern ohne lange Turn-Around-Zeiten, zu 
testen.

Wirst Du den Code frei verfügbar machen? (z.B. auf GitHub?)

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Deine Ausdauer ist lobenswert, die Kenntnisse in C# zu erweitern auch.
Beruflich ist sowas mit Sicherheit ein Vorteil, für als inzwischen 
Rentner eher weniger. Mir reicht es, meine C/C++-Kenntnisse irgendwie 
auszubauen, fürher gab es auf µP und µC für mich nur ASM..

Daher mehr ein paar allgemeine Gedanken auch an Andreas S.:

Datenblätter sind selten Romane, das waren sie auch früher schon nicht 
und die Zusammenhänge zusammenzusuchen ist mühsam und kostet Zeit.
Er innert mich an meine erste größere Übung, am C64 den SAA52xx 
Videotextdecoder in Gang zu bringen. Datenblatt war verfügbar, 
Appliaktionshinweise war ziemlich nichts. Mußte ich also auch den Aufbau 
von Videotext erstmal verstehen lernen usw. Einzige Kontroll war ein 
kommerzielles Programm für den C64, das ich dann teilweise 
disassemblieren konnte. Teilweise, weil es nur 
"Maschinensprache-Monitore" gab, die eben ab einer Adresse den 
Speicherinhalt als ASM-Mnemotics versuchten auszugeben.

Sinn der Vorrede: die OV7670 hat 201 Register. Das Datenbaltt ist 
üblich, alles drin. Natürlich muß man dazu Vorkenntnisse haben. Wozu 
gibt es VSYNC und HSYNC bei einer zeilenweisen Bilddarstellung, was 
bedeuten die Bildformate und wie sind die Daten aufgebaut, ws ist 
Farbsättigung, Gamma, digitale Verstärkungsregelung usw. usw.
Das erklärt ein Datenblatt nicht.
Es gibt ein Applikation-Dokument im Netz zur OV7670 bei www.play-zone.ch
Google hat ihn gefunden, ich selbst auf der Seite nicht, deshalb hänge 
ich das pdf hier mal frech ran.

Mit einem Tool einfach so an den Registern rumzuspielen wäre für mich 
wie
Lottospielen, nur mit schlechteren Gewinnchancen...
Wenn ich die Kamera mit den beispielwerten des Herstellers auf einen 
Mode setze, muß hinten das erwarete Bild rauskommen.
Bis ich die Abhängigkeiten nur an Hand des Datenblattes verstanden 
hätte, wäre wohl 2020. Ich muß die Grundlagen verstehen, mich auf den 
Hersteller verlassen und kann dann natürlich auch mal variieren. Dann, 
wenn ein reproduzierbates Ergebnis ankommt, nicht vorher.
Vor allem: all das nutzt nur genau für diesen einen Kamera-Chip.
Ich muß aber verstanden habe, was nötig ist. Ich muß im datenbaltt 
suchen können, wie ist der Speicheraufbau, wie werden die Bilddaten 
abgelegt, wo lege ich fest, wo im Speicher Start- und Endpunkt einer 
Bildzeile ist, wo lege ich fest, wieviele Zeilen mein Bild haben soll 
usw.
Wenn ich ein bestimmtes Ausgabeformat haben will, will ich im Datenblatt 
schauen und geziehlt suchen können, ob der Chip das kann, wie ich es 
einstellen mus, damit er es ausgibt und wie gibt es es aus, 8Bit, 16Bit, 
24Bit, 32Bit, BigEndian, LittleEndian usw.
Ist bei der OV2640 mit der ich im Moment etwas rumspiele auch ein Drama: 
ein Hersteller beispiel mit den Inits für die Auflösungen wurde 
übernommen. Da wurde dann gekürzt und drumrumgeschrieben, weil z.B. mehr 
als 800x600 JPG auch auf einem ESP32 wegen der Ramverwaltung (max. 128kB 
im Stück verfügbar) nicht gehen. Mit PSRAM dran kann ich mir aber auch 
einen 4MB-Buffer holen. Das hat aber soweit ich bisher gefunden 
habe,noch keiner wirklich realisiert. Ich will aber wahlweise ein 
Standbild in 1600x1200 haben... Die Stream-Demos gegen einen 
HTML-JPG-Stream aus, besser wäre aber sehr wahrscheinlich ein 
MJPG-Videostream, hat aber wohl auch noch keiner probiert mit dem ESP32 
+ PSRAM.

Ist bei OV7670 mit FIFO doch auch ein Problem: der FIFO ist 384kB groß, 
ein 640x480 in 16Bit paßt also nur in 2 Halbbildern rein. Als komplettes 
Bild gehen nur 480x320.

PS: toller Roman wieder geworden......

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> Es gibt ein Applikation-Dokument im Netz zur OV7670 bei www.play-zone.ch
> Google hat ihn gefunden, ich selbst auf der Seite nicht, deshalb hänge
> ich das pdf hier mal frech ran.

Ganz so frech warst Du dann doch nicht - es hing nämlich nichts dran :-)

Hier die mir bekannten Links (hatte damals auch teils lange 
recherchiert) - vermutlich wäre der 4. Link Dein Tipp gewesen:

Datasheet V1.01  (08.07.2005):
https://www.voti.nl/docs/OV7670.pdf

SCCB functional Specification:
http://www4.cs.umanitoba.ca/~jacky/Teaching/Courses/74.795-LocalVision/ReadingList/ov-sccb.pdf

Implementation Guide V1.0 (Sept. 2005):
http://www.haoyuelectronics.com/Attachment/OV7670%20+%20AL422B%28FIFO%29%20Camera%20Module%28V2.0%29/OV7670%20Implementation%20Guide%20%28V1.0%29.pdf

Software Application Note:
https://www.play-zone.ch/en/fileuploader/download/download/?d=1&file=custom%2Fupload%2FFile-1402681702.pdf

Links zum OV7670 + AL422B(FIFO) Camera Module(V2.0):
http://www.hotmcu.com/ov7670-al422bfifo-camera-modulev20-p-19.html

Und meine absoluten Lieblingslinks:

http://embeddedprogrammer.blogspot.com/2012/07/hacking-ov7670-camera-module-sccb-cheat.html
http://embeddedprogrammer.blogspot.com/2013/01/demo-stm32f4-ov7670-qserialterm.html

Was das Register-Herumprobieren angeht, so hast Du natürlich recht: 
blind herumstochern macht keinen Sinn. Aber manchmal sind die 
Beschreibungen so missverständlich, dass man einfach prüfen muss, was 
passiert, wenn man Register X verändert und ob dies dem erwarteten 
Verhalten entspricht.

Ich für meinen Teil war mir damals jedenfalls oftmals unsicher, ob ich 
die Beschreibung korrekt verstanden hatte (und/oder ob diese nicht doch 
Buggy war).

Außerdem haben die Arduino-Anhänger ja diese 
Wahnsinns-Compile&Flash-Zeiten (die ich beim STM32 mit J-Link ja nicht 
habe). Da macht so ein Register-Tweating-Tool schon irgendwo Sinn.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Ganz so frech warst Du dann doch nicht - es hing nämlich nichts dran :-)

Stimmt...
Hast recht mit dem play-zone Link, hat sich dann ja jetzt erledigt.

Andreas S. schrieb:
> Außerdem haben die Arduino-Anhänger ja diese
> Wahnsinns-Compile&Flash-Zeiten (die ich beim STM32 mit J-Link ja nicht
> habe). Da macht so ein Register-Tweating-Tool schon irgendwo Sinn.

Das stimmt natürlich schon. Angefangen habe ich ja mit EProms, noch dazu 
in der DDR. Da hat man es sich aus gant anderen Gründen gut überlegt, ob 
eine Änderung wiklich richtig und sinnvoll war. Löschen und 
Programmieren dauerte da merklich länger und außerdem konnte es je nach 
Qualität und Herkunft der Eproms schon passieren, daß nach dem 5. 
Löschen etliche zellen eben auf 0 bleiben. Vermutlich ist das bei mir 
eben auch teilweise Gewohnheit. Heute dann eher, um während compilieren 
und flashen schon zu der Erkenntnis zu kommen, daß man da gerade Mist 
gebaut hat. Naja, einen Flash bei AVR oder ESP habe ich noch nicht 
kaputt bekommen.
Mein Bekannter hat früher auch gern mal einen Linux-Kernel gebaut, da 
waren Stunden nicht unüblich zum compilieren.

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Andreas S. schrieb:
>
> Wirst Du den Code frei verfügbar machen? (z.B. auf GitHub?)
>

Hallo Zusammen, mein Job nimmt meine Zeit doch mehr in Anspruch als es 
noch als Student der Fall war. Zumindest was die flexibilität angeht.

Daher zieht sich mein Vortschritt leider etwas.
Um auf die Frage von Igel zurückzokmmen, ich würde euch den Code oder 
das Programm zur Verfügung stellen, sobald es eingermaßen "Bug-Frei" 
läuft. Derzeit gibt es noch viele interferenzen die ich noch nicht ganz 
überblicke. Ich hoffe an diesem langen Wochenende mich nocheinmal 
intensiv mit dem Thema auseinander zu setzten zu können und endlich mal 
einen Bildstream auslesen zu können.

viele Grüße

David

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:

> Hallo Zusammen, mein Job nimmt meine Zeit doch mehr in Anspruch als es
> noch als Student der Fall war.

Ja, definitiv: Arbeit kann einem das ganze Leben versauen ;-)

> Daher zieht sich mein Fortschritt leider etwas.   [Zitat mit typofix]

Willkommen im Club.

> Um auf die Frage von Igel zurückzokmmen, ich würde euch den Code oder
> das Programm zur Verfügung stellen, sobald es eingermaßen "Bug-Frei"
> läuft. Derzeit gibt es noch viele interferenzen die ich noch nicht ganz
> überblicke. Ich hoffe an diesem langen Wochenende mich nocheinmal
> intensiv mit dem Thema auseinander zu setzten zu können und endlich mal
> einen Bildstream auslesen zu können.

Okay - aber lege die Latte Deines Qualitätsanspruchs an Dich selber 
lieber nicht zu hoch. Habe schon viele erlebt, die deshalb Ihre Projekte 
nie veröffentlicht haben - ich fand das immer schade.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

damit es hier nicht so ausgestorben aussieht... ;)

Stand meiner M5Stack Cam und Odroid Go Viewer:
Läuft prinzipiell stabil.
Prinzipiell: Cam macht QVGA (320x240) als JPG. Odroid Go holt das Bild 
im HTML-Rahmen, decodiert das JPG und zeigt es auf dem Display 
8ebenfalls 320x240) an. Sind ca. 1,5 Bilder/s, wenn ein Bild auf dem 
Display ist, fordert er die Webseite einfach weider an.
Die Idee, jetzt einen "hardware-Zoom" einzubauen: Markierung als Rahmen 
auf dem Display, mit dem Kreuzbutton verschiebbar. Dann ein Bild der 
Camera in SVGA (800x600) anfordern und den entsprechenden Ausschnitt auf 
dem Display anzeigen.
Das geht vorest nur prinzipiell.
Probleme im Viewer: Tastenabfrage lahm, weil der JPG-Decoder relativ 
lange pro Block braucht.
Ansonsten klappt die Idee so zumindest erstmal.
Bei der Camera habe ich zumindest soweit in das Cam-Demo reigefasst, daß 
ich eine Funktion zum Wechsel der Auflösung "on-the-fly" stabil in Gang 
habe. Probleme mit dem Speicher (framebuffer malloc/free führt schnell 
zur Fragmentierung und Speichermangel, also Buffer für SVGA einmal 
geholt und den behalten) sind soweit geklärt.
Jetzt bekomme ich aber nach dem Wechsel der Auflösung nur noch 
"Nachtaufnahmen", offenbar muß ich noch einige andere Einstellungen des 
Camera-Chips jeweils passen setzen, das muß ich noch klären...

PS: wenn ich es morgen nicht wieder vergesse bringe ich zumindest mal 
die OV7670 mit FIFO von meinem BEkannten mit.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

@Michael U. :

Meinst Du mit "Odroid" den hier:
https://www.heise.de/make/meldung/Odroid-Go-Bastel-Game-Boy-mit-ESP32-zum-Odroid-Geburtstag-4088637.html 
?

Und hast Du die JPG-Decompression selbst programmiert?
Wenn ja: mit welcher Library?

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> @Michael U. :
>
> Meinst Du mit "Odroid" den hier:
> 
https://www.heise.de/make/meldung/Odroid-Go-Bastel-Game-Boy-mit-ESP32-zum-Odroid-Geburtstag-4088637.html
> ?

Ja, gekauft hier:
https://www.pollin.de/p/odroid-go-mobile-spielekonsole-kit-810887

> Und hast Du die JPG-Decompression selbst programmiert?
> Wenn ja: mit welcher Library?

Nein, wäre wie auch MP3 in der Klasse, wo ich durchaus verstehe, was da 
passiert, mich der Arbeitsaufwand bei meinen C/C++ Kenntnissen aber doch 
etwas abschrecken würde.
https://github.com/Bodmer/JPEGDecoder

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Hallo zusammen,

ich verabschiede mich für zwei Wochen in den Urlaub. Da aber die erste 
Woche regen angesagt ist... Juhu.... werde ich wohl offline etwas 
weitermachen.
Ich denke, dass ich euch im anschluss einmal einen release von dem 
Programm zur Verfügung stellen werde, sodass ich vielleicht noch den ein 
oder anderen Verbesserungsvorschlag von euch erhalten kann :)

bis dahin!

lg.
David

von Michael U. (amiga)


Lesenswert?

Hallo,

schönen Urlaub wünsche ich Dir.

Ich habe inzwischen zumindest die FIFO-Version der OV7670 von meinem 
Bekannten auch hier liegen, kann also durchaus dann mal was testen.

Ansonsten habe ich inzwischen zumindest die Versandbestätigung von 
SeeedStudio für das ESP-Cam Modul bekommen, also auch da abwarten und 
überraschen lassen.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

@Michael U.:
Danke für Deine Ausführungen zum Odroiden und zur JPEG-Lib.

@David D.:
Schönen Urlaub!

@Michael U.:

> Ansonsten habe ich inzwischen zumindest die Versandbestätigung von
> SeeedStudio für das ESP-Cam Modul bekommen, also auch da abwarten und
> überraschen lassen.

Da bist Du schon weiter als ich.
Ich habe ebenfalls 2 Stück bestellt, aber noch keine Versandbestätigung 
erhalten.

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Guten Morgen meine lieben Mitstreiter.
Nach einer besinnlichen Weihnachtszeit habe ich mich nun die letzten 
Tage wieder unserem gemeinsamen Kamera Projekt gewitmet.

Ich denke, ich wäre jetzt soweit, das PC-Programm mit euch zu teilen. 
Ich habe es heute tatsächich einmal geschafft, ein Bild (allerdings nur 
schwarz) von dem uC zum PC zu senden und dort darzustellen. Dass der 
Bildstream aber funktioniert habe ich ausprobiert und einfach mal vom uC 
weiß gesendet. Jetzt liegt das Problem also wieder auf uC seite und dem 
auslesen bzw. schreiben des Fifos, was offensichtlich noch nicht 
wirklich funktioniert.

Weiterhin hoffe ich auf euren Rat bei folgendem Problem:
Derzeit übertrage ich das Bild Zeile für Zeile. Nach jeder Zeile sende 
ich noch ein CR+LF mit. Diese beiden Zeichen überprüfe ich dann. Sind 
diese an entsprechender Stelle vorhanden, wird die nächste Zeile vom uC 
abgefragt. stehen dort andere Zeichen, wird nocheinmal die Gleiche Zeile 
abgerufen.
Die Auswertung der Zeile findet erst statt, wenn >= (BytesProPixel * 
xResolution)+2 Zeichen im Buffer auf PC Seite vorhanden sind.
Wird jetzt aber ein Byte "verschluckt", wartet das Programm und sendet 
eben nichts mehr an den uC zurück. Das passiert leider relativ häufig. 
Hier bräuchte ich so eine Art watchdog oder eine andere Art der 
Herangehensweise.

Seid ihr noch im Boot und hättet Lust mit zu spielen? dann würde ich 
euch das Programm schicken und eine kleine Einweisung/Workarounds :D 
zusammenschreiben.

lg.

David

von Michael U. (amiga)


Lesenswert?

Hallo,

schön von Dir zu hören. Bei mir liegt zumindest jetzt auch die OV7670 
mit FiFo von meinem Bekannten rum.

David D. schrieb:
> ich noch ein CR+LF mit. Diese beiden Zeichen überprüfe ich dann. Sind
> diese an entsprechender Stelle vorhanden, wird die nächste Zeile vom uC
> abgefragt. stehen dort andere Zeichen, wird nocheinmal die Gleiche Zeile
> abgerufen.

Hast Du Grund zu der Annahme, das da unterwegs was aus der Leitung 
fällt?
Bei meinem LogicAnalyzer übertrage ich 32kB per Loop aus einem externen 
Ram über einen FTDI mit Einstellung 500kBaud an mein (uraltes) 
VB-Programm. Da ist nie auch nur ein Bit abhanden gekommen. Ich hatte 
zwar ein paar Diskussuinen im alten VB6 mit den seriellen Puffergrößen, 
die habe ich aber gewonnen. ;)

Anhsonsten: mitspielen durchaus, der Kram leigt ja ohnehin rum. 
Ernsthaft werde ich die OV7670 sowiso nicht einsetzen. Meine ESP-Cams 
liegen allerdings z.Z. auch nur rum. Inzwischen ist beim ESP32-Arduino 
zumindest ein Demosurce dabei. Das ist zwar ähnlich dem gemacht, was ich 
hier schon hatte, also Arduino-Rahmen und das IDF-Demo darunter, ist für 
mich aber vermutlich etwas lesbarer. Dann muß ich da nicht immer meinen 
Bekannten nerven.

OT: da ich bei Pollin mal wieder was entdeckt hatte:
https://www.pollin.de/p/portabler-designlautsprecher-schwarz-641081
hat nicht 3 Lautsprecher sondern 2+ passiv-Membran und ist auch 
USB-Soundkarte, das hat Pollin garnicht erwähnt. Da kommt in einen jetzt 
erstmal ein ESP32 Wrover + I2S-Decoder rein, als"Klo-Radio" oder so.
Muß nur noch klären, ob die diskrete Einschaltlogik mit der Taste den 
zusätzlichen Strom des ESP32 verkraftet oder ob ich da noch was 
dazulöten muß.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

@David:

ich wäre auch wieder dabei - allerdings nur als interessierter Mitleser 
und "Gelegenheits-Dreinschwätzer" ... aber das kennt Ihr ja schon.

Bitte liste (oder verlinke) nochmals Deine aktuelle 
Hardware-Konstellation, mit der Du experimentierst (nur für den Fall, 
dass der eine oder andere - im äußersten Fall sogar ich selbst - Deinen 
Aufbau einmal nachbaut). Wenn Du ganz viel Motivation hast, vielleicht 
gar mit einem kleinen Schaltplan. Mit einem Programm wie "Fritzing" 
sollte so etwas in wenigen Minuten getan sein.

Was den Code angeht, so würde ich anregen, ihn bei Github oder einem 
ähnlichen Code-Repository einzustellen. Alternativ betreibt 
mikrocontroller.net auch einen eigenen SVN-Server, in dem man ebenfalls 
Code einstellen könnte: 
https://www.mikrocontroller.net/articles/Hilfe:SVN
Allerdings ist Github im OpenSource-Bereich meiner Meinung nach etwas 
weiter verbreitet.

Vorteil: alle können an Deinem Projekt mitproggen.
Nachteil: Du bist nicht mehr Herr "Deines" eigenen Codes - weil es dann 
nämlich nicht mehr so richtig "Dein" Code ist.

Viele Grüße

Igel1

von Dieter F. (Gast)


Lesenswert?

Andreas S. schrieb:
> Vorteil: alle können an Deinem Projekt mitproggen.

Gibt es da jemanden? Nur mal so gefragt ...

Ich überlege, mit dem ATXMega mitzuspielen, passt halt nicht so ganz zum 
aktuellen Ansatz.

von Michael U. (amiga)


Lesenswert?

Hallo,

Dieter F. schrieb:
> Andreas S. schrieb:
>> Vorteil: alle können an Deinem Projekt mitproggen.
>
> Gibt es da jemanden? Nur mal so gefragt ...
Um realistisch zu bleiben: sehr wahrscheinlich nicht wirklich.
Ich würde auch nur seinen Code hier auf den AVR packen und etwas 
Fehlersuche mit betreiben, seine PC-Software würde ich ohnehin nur 
nutzen. zumindest, wenn ich dafür nicht erst meinen PC "umbauen" muß...

Die OV7660 ist nicht unbedingt mehr so sinnvoll, um die wirklich zu 
nutzen. Für Spezialanwendungen (Objekterkennung? Bewegungserkennung? 
Barcode/QR-Code Leser?) vielleicht noch. Selbst die OV7670 ist nicht 
soviel moderner, allerdings macht die etwas höhere Auflösungen und 
JPEG-Ausgabe.

> Ich überlege, mit dem ATXMega mitzuspielen, passt halt nicht so ganz zum
> aktuellen Ansatz.

Ein ATXMEga (Xplain...) liegt hier irgendwo noch rum, nie wirklich 
benutzt.
Inzwischen sind ESP8266/ESP32 meine Freunde, die ESP8266 im realen 
Einsatz hier für diverse Home-Spielereien, die ESP32 mehr im 
Experimetierstaduin, weil die Module für den Preis einfach noch 
ungeahnte Möglichkeiten bieten.
Die OV7670 habe ich am ESP32, da denke ich noch über eine "reale" 
Verwendung nach, Wetter-Cam auf dem Balkon vielleihct, da könnte sie 
alle paar Minuten ein Standdild in voller Auflösung schicken.
BT beim ESP32 bisher nur angetestet, als BT-Speaker.
Rechenleistung reicht bequem für Webstream, Software-MP3-Decoder und I2S 
Ausgabe. läuft hier u.a. auf einem Odroid Go:
https://www.pollin.de/p/odroid-go-mobile-spielekonsole-kit-810887?&gclid=EAIaIQobChMIm76Gy4vz3wIVk-J3Ch2_kAhVEAQYASABEgJuBPD_BwE

Da habe ich bei den Emalatoren letztens entdeckt, daß jemad Frode für 
den ESP32 angepasst hat, irgendwie genial, Frodo stammt ursprünglich vom 
Amiga, Christian Bauer hat ihn dann für alle möglichen OS 
bereitgestellt.
Fehlt nur noch, das jemand das mit Shapeshifter
https://de.wikipedia.org/wiki/ShapeShifter
macht, aber ein 68020 mit 14MHz (als Minimum) auf dem ESP32???

OK genug Geplauder... ;-)

Insofern wird OV7670 und AVR für mich eben nur als Beweis dienen können, 
daß man es irgendwie machen kann.

Gruß aus Berlin
Michael

von David D. (saturi)


Angehängte Dateien:

Lesenswert?

Guten Abend zusammen :)
Das freut mich ja, dass ich direkt Rückmeldung bekommen.

Anbei nochmal der gewünschte Schaltplan.

>Hast Du Grund zu der Annahme, das da unterwegs was aus der Leitung
>fällt?
Leider hatte oder habe ich das tatsächlich. Ich glaube zwar das es nicht 
Aufgrund von EMS ist, sondern lediglich durch schlechte Programmierung. 
Das mit dem abbrechen mitten im Bild-Stream habe ich jetzt tatsächlich 
hinbekommen. (Das Problem lag daran, dass ich nicht gesehen habe, dass 
ich die Write- und Read-Reset Leitungen des Fifos invertieren muss... 
kaum ist das passiert, bekomme ich auch (zuverlässig?!) meine 480 Zeilen 
geliefert. zuverlässig in Klammern, weil es bisher erst in den letzten 
beiden Bildern so war. Derzeit fahre ich aber noch im RGB888 Format bei 
voller Auflösung, einer Baudrate von 19200 und REICHLICH puffer Zeiten 
im ms Bereich, sodass ich aktuell für ein Bild rund 15 min brauche :D. 
Immerhin ist durch das nun offensichtlich funktionierende zurücksetzen 
der Write und Read Pointer im Fifo ein plausibles schwarzes Bild mit 
leichtem Rauschen hinterlegt und nicht wie vorher das komplette 
Farbspektrum willkürlich :D...
Kaum schreibe ich diese Satz stoppt die Übertragung bei 418 Zeilen....

>Gibt es da jemanden? Nur mal so gefragt ...
Nein leider nicht :D
Es gibt auch ein Github-Projekt zu diesem Anliegen hier, dass ein User 
in Leben gerufen hatte, aber nachdem ich der einzige war, der darin 
weiter gearbeitet hat, habe ich das Uploaden eingestellt.Ich stelle euch 
aber gerne den Source Code für den Atmega zur Verfügung. Ich hoffe, dass 
ich es heute Abend schaffen -werde. Dazu packe ich dann noch einen 
Release für mein "OV7670-Terminal" Programm.

@Dieter.F du bist herzlich eingeladen auch mit einem anderen Controller 
mit einzusteigen.

Viele Grüße
David

EDIT: Hier noch der Github Link:
https://github.com/igittigitt/ov7670

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Ich stelle euch
> aber gerne den Source Code für den Atmega zur Verfügung. Ich hoffe, dass
> ich es heute Abend schaffen -werde. Dazu packe ich dann noch einen
> Release für mein "OV7670-Terminal" Programm.

mach das mal, ich werde es auf jeden Fall mal anwerfen und reinschauen.
Im Moment wohl speziell in die Übertragungsgeschichte, RGB888 ist ja 
erstmal gut handhabbar. Vielleicht schicke ich einfach einen passenden 
BMP-Header vorneweg und lese es wie früher per TeraTerm in den Buffer 
und speichere den.
Dann kann es mir ja Irfanview anzeigen.
Ein lauffähiges altes VB6 habe ich hier nicht mehr, sonst hätte ich mir 
da meine Empfangsroutine vom LogicAnalyzer ausgeliehen...

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

@David:

solltest Du noch keinen LogicAnalyzer haben, so wird hier in diesem 
Forum im Marktbereich gerade genau derjenige LA gebraucht angeboten, den 
ich ebenfalls habe.

Ist ein phantastisches Gerät, das ich jedem nur empfehlen kann:
Beitrag "Intronix Logicport 34 Kanal Logic und Bus Analyser"

Einziger Nachteil: er hat nur 2k Puffer, die allerdings dank 
intelligenter Sampling-Methodik optimal ausgenutzt werden. Notfalls muss 
man halt den (sehr flexiblen) Trigger etwas klug wählen - dann kommt man 
in 99% der Fälle auch mit den 2k aus.

Dafür kann das Teil auch 250MHz-Signale noch analysieren (mit internem 
Timer sogar bis 500MHz) - absolut sensationell für diesen Preis.
Und die Logic-Level sind auch in weiten Volt-Bereichen einstellbar.
Die Software ist ebenfalls sehr, sehr gut und mächtig.

Hier die Specs:
http://www.pctestinstruments.com/logicport/specifications.htm

Bei Interesse: schnell zuschlagen - das Teil wird bald weg sein.

Viele Grüße

Igel1

PS: nich ich bin weder mit dem Verkäufer verwandt noch kenne ich ihn.

von Dieter F. (Gast)


Lesenswert?

Andreas S. schrieb:
> Die Software ist ebenfalls sehr, sehr gut und mächtig.

Zu gut und mächtig für mich (wahrscheinlich) - ich kam damit nicht klar 
und habe ein solches Teil vor einiger Zeit verkauft. Aber das ist - wie 
alles - relativ :-)

von David D. (saturi)


Lesenswert?

Guten Abend,
wie versprochen die Uploads:

Das Terminal Programm (ich vermute, dass das ein .net-Framework o.ä. 
installiert sein muss, falls ihr es nicht ausführen könnt, einfach 
nochmal melden, dann finden wir bestimmt eine Lösung):

https://github.com/igittigitt/ov7670/tree/TWI-Interfac/OV7670-Terminal-Releases

Und der Code fürs AVR Programm:

https://github.com/igittigitt/ov7670/tree/TWI-Interfac/OV7670-AVR

Und hier noch eine Kurzanleitung:
Wie schon erwähnt funktioniert noch nicht sehr viel, aber auf Wunsch 
stelle ich es trotzdem schon einmal zur Verfügung.

1. Alles anstöpseln und dann beim Aufrufen des Terminals unter der 
Register-Karte "Settings" und in der GroupBox Com-Port die 
voreingestellten Werte benutzen (evtl. muss der Com-Port eingestellt 
werden) und auf verbinden klicken. (Falls hier Änderungen vorgenommen 
werden wollen, müssen diese Ebenfalls im AVR Code geändert werden 
(UART.c))


2. nun sollte "connected" in grüner Schrift in gleicher Box stehen. 
Jetzt muss ein paar mal auf den Button get camera status geklickt 
werden, bis bei Version zwei plausible Hex Adressen erscheinen (Bei mir 
0x76 0x73)

Hierbei handelt es sich noch um ein Kommunikations Problem, das ich noch 
nicht identifizieren konnte. Mehrmaliges klicken behebt dieses aber :D

3. nun können unter den Groupboxen Read Register und Write Register 
beliebig die Register geschrieben und gelesen werden. Eine jeweilige 
Bestätigung erscheint unten in der Status leiste. Es ist auch möglich, 
mit "Read Device Settings" alle register auszulesen und ggf. 
abzuspeichern. sollte der Fortschrittsbalken unerwartet stehen bleiben 
ebenfalls nochmal den Button drücken und hoffen, dass er diesmal 
durchläuft. ;-) sollte jemand den Fehler finden, bin ich sehr Dankbar.

4. Das Laden von abgespeicherten Settings funktioniert auch. Allerdings 
nicht, diese auch alle wieder auf den Chip zu schreiben.

5. "take" (wo eigentlich "take picture" stehen sollte, funktioniert 
derzeit nur im VGA und RGB Modus. d.h bevor ein Bild aufgenommen wird 
muss erst das Register 0x12 mit 0x04 beschrieben werden. Das ganze am 
besten mit "get camera status" verifizieren.

6. Ab dann beginnt der Bildaufbau. dauert etwas und in der Statusleiste 
sieht man, wieviele Bildzeilen bereits empfangen sind. (ca 2-3 Sekunden 
pro Zeile

7. unter der Registerkarte _picture kann kann man unter den beiden 
Bildboxen den Haken setzen und bekommt das Bild, dass gerade empfangen 
wird etwas größer dargestellt. Bild speichern funktioniert ebenfalls. 
die anderen Knöpfe noch nicht.


Zum schluss möchte ich noch eins Anmerken, die Zeilen, die Seriell 
ausgelesen werden, geben das Bild wieder, dass bei "take picture" den 
Sensor belichtet hat, also bringt ein belichten der Kamera während der 
Übertragung rein garnichts.

Natürlich habe ich aktuell noch überhaupt kein Bild und bei euch wird 
mit meinem Code ebenfalls nur Rauschen zu erkennen sein. Daher lade ich 
euch hiermit recht herzlich ein, dass ganze zu testen. Gerne gehe ich 
auch noch auf den Code ein, wenn es jemanden interessiert.

viele Grüße

David

PS: Danke für den Link des Logik Analysers... Leider ist mein Budget 
aktuell etwas eng, sodass ich mit 2 Kanal Oszi leben muss. Ich habe auch 
irgendwo noch einen Logikanalyser den ich zusammen mit einem Billig USB 
Oszi gekauft habe rumliegen. Der ist aber ebenso unzuverlässig wie das 
Oszi an sich, was vermutlich noch nichtmal an der Hardware sondern 
vielmehr an der unfertigen zugehörigen Software liegt.

von Andreas S. (igel1)


Lesenswert?

@David:

Dein Programm lief auf meinem Computer (Win7 64bit) direkt out of the 
box.
Allerdings habe ich keine Levelshifter, um Deine Schaltung nachzubauen.
Ich konnte also nur das Programm anwerfen und ein paar Knöbbschen 
drücken.

Wenn Du mir sagst, in welchem Format Du die Bilder aus dem AVR 
rausschreibst, kann ich das ja vielleicht mal in meinem ARM nachstricken 
(ohne Gewähr, dass ich jemals dazu komme ...).

Wirst zu den Code vom OV7670-Terminal.exe auch noch veröffentlichen?
Irgendwo hatte ich schon einmal so ein Programm gesehen ... wo war das 
nur ...

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

Andreas S. schrieb:

> Irgendwo hatte ich schon einmal so ein Programm gesehen ... wo war das
> nur ...

Ha - gefunden: qSerialTerm heißt das Dingen - ich habe es aber niemals 
probiert:

http://embeddedprogrammer.blogspot.com/2012/07/hacking-ov7670-camera-module-sccb-cheat.html 
>  nach qSerialTerm suchen

von Michael U. (amiga)


Lesenswert?

Hallo,

Terminalprogramm startet hier auch erstmal ohne Probleme.

Die AVR-Sourcen habe ich erstmal in die ArduinoIDE geworfen und die dort 
nötigen
1
#ifdef __cplusplus
2
extern "C" {
3
#endif
4
...
5
#ifdef __cplusplus
6
}  // extern C
7
#endif
auf die .h Dateien verteilt. Gab noch ein paar unkritische Warnings und 
irgendwo fehlte ein #include "UART.h", dann lief er erstmal durch.
Ein aktuelles AVR-Studio habe ich nicht drauf und werde es auch nicht 
installieren. ;)

Mal schauen, heute Nachmittag mal OV2840-FIFO-Modul und Peegelwandler an 
einen Arduino UNO oder so stecken und mal schauen, was überhaupt 
passiert.
Dann werde ich mir das mal genauer anschauen.

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Lesenswert?

David D. schrieb:
> @Dieter.F du bist herzlich eingeladen auch mit einem anderen Controller
> mit einzusteigen.

Na ja - ich nehme erstmal den Nano ohne Arduino und spiele damit etwas 
herum.

Mit dem 16MHz-Takt an PB0 schluppt die Kamera schon schön :-). Über ein 
Oszilloskop man man da schon mal prima die Signale (HSync etc.) 
beobachten. Ein Datenbit funkt dann auch schön wild, wenn man die Kappe 
von der Kamera abmacht.

Ich verwende keine Level-Shifter - entweder das Teil (ich habe 4 im 
Sonderangebot gekauft :-) ) hält das aus oder nicht.

Was mir aufgefallen ist - bei einigen IF's hast Du "=" statt "==" 
geschrieben - das ist "nicht optimal".

Ich werde mir jetzt mal die "Kommando-Verbindung" etwas genauer 
anschauen. Bis gerade fragte ich mich, wie Du bei solchen Taktraten ein 
Bild mit dem "lahmen" :-) 328P abholen willst - bis ich Register 0x11 
entdeckte ...

VG

von Michael U. (amiga)


Lesenswert?

Hallo,

Dieter F. schrieb:
> Ich verwende keine Level-Shifter - entweder das Teil (ich habe 4 im
> Sonderangebot gekauft :-) ) hält das aus oder nicht.

naja... ich sage es jetzt mal so: aus dem Alter bin ich raus...

Meie Sorge ganz allgemein ist da aber weniger, ob sie das aushält, mehr 
der Umstand, daß ich mich da auf das Verhalten der Kamera da nicht 
verlassen wollte. Die Pegel an den Eingängen sind dann doch merklich 
oberhalb der Specs.

Gruß aus Berlin
Michael

von David D. (saturi)


Angehängte Dateien:

Lesenswert?

Hallo Dieter,

ja das Register 0x11 ist erstmal wichtig um die CLK etwas runter zu 
bekommen, damit man das VSync signal auch abtasten kann.


>Was mir aufgefallen ist - bei einigen IF's hast Du "=" statt "=="
>geschrieben - das ist "nicht optimal".


Das wäre natürlich suboptimal, ich werde den Code direkt durchgehen und 
danach suchen. Im falle der if(errorCode=functionXXX()) ist es 
allerdings gewollt, da ich so abfragen kann, ob die funktion 
durchgelaufen ist oder nicht.

Mir ist aber selber noch ein Fehler aufgefallen. In der Funktion
1
void OV7670_captureNewImage (void)
muss es heißen:
1
...
2
OV_WR_PORT &= ~(1<<OV_WR_PinNo);
3
while(!getValueOfPin(OV_VSync_PIN,OV_VSync_PinNo));
4
OV_WR_PORT |= (1<<OV_WR_PinNo);
hier hatte ich vorher OV_WR_PIN stehen. Das muss definitiv korrigiert 
werden.
Dann habe ich gerade noch etwas mit den Low Active Signalen gespielt und 
das Timing etwas geändert. Das werde ich jetzt direkt noch ins Github 
Project Pushen.
Anbei noch drei Bilder.
Das eine aufgenommen im "normalen" Modus, das zweite, bunte mit dem test 
pattern 8bar color bar (Register 0x70 [7] und 0x71 [7] auf 10 gestellt) 
Immerhin wird es Bunt. Und das dritte mit dem Testpattern 11 
"FadeToGrayColorBar" Aber etwas scheint entweder mit der Bildaufnahme, 
der Farb zusammenstellung oder der Auflösung nicht zu passen. Aber man 
sieht unterschiede.

vielen Dank fürs Miteifern.
Die nächste Woche bin ich leider auf Dienstreise. Vielleicht kann ich 
die Zeit nutzen, um die Kommunikation zwischen uC und PC zu beschreiben, 
oder zumindest meine Vorstellung davon.

lg.
David

von Dieter F. (Gast)


Lesenswert?

Michael U. schrieb:
> naja... ich sage es jetzt mal so: aus dem Alter bin ich raus...

Ich auch - aber ich suche auch keine Dauerlösung, nur einen 
"proof-of-concept" :-)

Michael U. schrieb:
> Meie Sorge ganz allgemein ist da aber weniger, ob sie das aushält, mehr
> der Umstand, daß ich mich da auf das Verhalten der Kamera da nicht
> verlassen wollte. Die Pegel an den Eingängen sind dann doch merklich
> oberhalb der Specs.

Das gilt nur in Richtung der Kamera über die SCCB-Schnittstelle. Hier 
kann man zur Sicherheit die geschriebenen Register-Werte verifizieren.

Von der Kamera kommen "Kamera-verträgliche" Pegel, welche vom 328P 
sicher erkannt werden (bei 3,3V VCC des 328P müssen die > ca. 1,8 V 
sein).

Falls das nicht funktioniert steuere ich halt nach.

David D. schrieb:
> Das werde ich jetzt direkt noch ins Github
> Project Pushen

Damit habe ich keine Erfahrung - würde ggf. dann direkt austauschen.

von Michael U. (amiga)


Lesenswert?

Hallo,

Dieter F. schrieb:
> Von der Kamera kommen "Kamera-verträgliche" Pegel, welche vom 328P
> sicher erkannt werden (bei 3,3V VCC des 328P müssen die > ca. 1,8 V
> sein).

wenn Du einen 3,3V Nano hast, passen die Pegel doch sowieso und 
Levelshifter sind unnötig. Ich hatte da auf einen 5V vermutet...

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Lesenswert?

Michael U. schrieb:
> wenn Du einen 3,3V Nano hast

Schrieb ich doch :-) - das ist zwar nicht ganz im Sinn der reinen Lehre, 
wird aber wohl funktionieren.

von Dieter F. (Gast)


Lesenswert?

David D. schrieb:
> 5. "take" (wo eigentlich "take picture" stehen sollte, funktioniert
> derzeit nur im VGA und RGB Modus.

Wo genau im Code liest Du eigentlich die Daten vom Bus ein?

Sag nicht da:
1
char OV7670_getByte (void)

dazu gibt es keinen Aufruf ...

von Michael U. (amiga)


Lesenswert?

Hallo,

Dieter F. schrieb:
> Wo genau im Code liest Du eigentlich die Daten vom Bus ein?
>
> Sag nicht da:
> char OV7670_getByte (void)
>
> dazu gibt es keinen Aufruf ...

Nein, er benutzt char readByte (void) 2 Zeilen darüber...
Ordnung ist eben nur das halbe Leben. ;)

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Lesenswert?

Michael U. schrieb:
> Nein, er benutzt char readByte (void) 2 Zeilen darüber...

Danke - muss wohl die Tomaten wegblinzeln ...

Jetzt verstehe ich auch, wieso ich keine PWM für den Takt finde.

von Saturi (Gast)


Lesenswert?

Hallo und Grüße aus dem Ausland.
Am Wochenende bin ich wieder zuhause und in der Lage detailierter auf 
die Fragen und die Erklärungen einzugehen.

Grob aus dem Kopf heraus den groben Ablauf:
der Atmega ist nach der Initialisierung der verschiedenen Komponenten in 
einer Art Idle-Mode(Programmstatus = -1). Ansonsten gibt es, wie in 
einem Automaten verschieden Programmstati. In welchen der uC versettz 
wird, hängt von dem per UART vom Terminal empfangenen Kommando ab. Die 
Befehlsverarbeitung findet in der UART.c statt. Hier gibt es (relativ 
weit unten [was für eine Angabe xD]) eine funktion, die die Empfangenen 
Bytes auswertet. Dabei gilt Folgendes Protokoll:
1. Byte = Befehl
je nach Befehl nun wvtl. 1 oder mehrere Datenbytes
2. Byte = Datenbyte
...
n. Byte = n-tes Datenbyte
n+1 Byte = 13   [ASCII CODE = Carrige return]
n+2 Byte = 10   [ASCII CODE = Line Feed]

diese Funktionen ändern den Programmstatus des uC. Die einzelnen zum 
Programmstatus auszuführenden Funktionen werden in der main.c durch eine 
Switch Anweisung angesteuert. Alle OV7670 Funktionen liegen auch im 
entsprechenden OV7670_withFifo.c (oder so ähnlich). Eine Bildübertragung 
funktioniert wie schon erwähnt immer Zeilenweise.


Ich habe letztes Wochenende noch eine zweite Version des Terminals 
"released". Hier ist ein Fehler in der Farbberechnung korrigiert worden 
und die Auflösung wird jetzt entsprechend des eingestellten Registers 
berücksichtigt (sowohl beim uC als auch beim Terminal) dadurch reduziert 
sich die Aufnahme von einem Bild dramatisch. Ich empfehle hier das QCIF 
Format.
Weiterhin sollte jetzt das Farbformat YUV - sofern per Register 
eingestellt - den Y Teil, also den Helligkeitswert abbilden. (UV)vom YUV 
werden aktuell gekonnt ignoriert.

Trotzdem bekomme ich noch kein Bild zusammengebaut.Ich bin für jede Art 
von Ratschläge offen :)

viele Grüße

David

von Dieter F. (Gast)


Lesenswert?

Saturi schrieb:
> Trotzdem bekomme ich noch kein Bild zusammengebaut.Ich bin für jede Art
> von Ratschläge offen :)

Hallo David,

kannst Du die Source für die PC-SW offen legen?

Deine Abfrage der Datenbytes mit eigener Taktung funktioniert mit 
Sicherheit nicht (zuverlässig). Die Kamera braucht eine externe Frequenz 
von 10 bis 24 MHz. 8 MHz gehen auch, das habe ich ausprobiert und damit 
will ich (auf dem 328P) arbeiten.

Du musst Dich bei der Auswertung schon an den Pixeltakt (der ausgegeben 
wird und den Du über das Register 11 beeinflussen kannst) halten.

Ich spiele aktuell ein wenig damit herum. Mein Ansatz wird der Versuch 
einer "Interleaved-Verarbeitung" sein. Am Wochenende werde ich 
hoffentlich etwas mehr Zeit dazu finden.

Alternativ zur PC-SW überlege ich ein kleines Display "rudimentär" (ohne 
Farb und Helligkeitsinformationen - stumpf Schwarz/Weiß per Schwellwert) 
per SPI oder I2C mit dem Ergebnis zu versorgen. Mal schauen.

Wenn es nicht so funktioniert, wie ich mir es vorstelle wechsle ich doch 
auf den ATXMega und nutze DMA :-)

VG
Dieter

von Saturi (Gast)


Lesenswert?

Guten Abend Dieter,

>Die Kamera braucht eine externe Frequenz
>von 10 bis 24 MHz. 8 MHz gehen auch, das habe ich ausprobiert und damit
>will ich (auf dem 328P) arbeiten.

Auch die Version mit FIFO?

Ich nehme an, dass du dich nicht durch die gesamte Unterhaltung gelesen 
hast :D (was ja auch niemand erwarten kann). Also es gibt von dem OV7670 
zwei Varianten. Eine ohne und einen mit Fifo. Ursprünglich sind wir mit 
der "ohne Fifo" Variante gestartet. Hier hatten wir aber die von dir 
angesprochenen "Timing"-Probleme, die jeweiligen Pixel Werte 
"aufzufangen". Wir haben auch die Clock-Rate reduziert, sind aber zu dem 
Ergebnis gekommen, dass -Aufgrund des für Kamera Leihen eh komplexen 
Themas- zumindest fürs erste die Variante mit FIFO der bessere Einstieg 
ist.

Mein Verständnis bis dato ist, dass ich den Fifo einen ganzen Frame lang 
beschreiben lasse und danach das Schreiben verhinder. Dadurch liegt das 
Bild im FIFO und kann in aller Ruhe ausgelesen werden. Eine 
externe-Clock entfällt glaube ich ebenfalls, weil die intern über einen 
Oszillator auf dem Board getaktet wird. Müsste ich aber Zuhause nochmal 
checken.

Kannst du mir da zustimmen oder habe ich etwas völlig falsch verstanden?

Danke

lg. David

von Saturi (Gast)


Lesenswert?

>kannst Du die Source für die PC-SW offen legen?

die würde ich Ungerne auf einer Plattform wie Github veröffentlichen. 
Ich stelle aber gerne jedem, der hier mittüfteln möchte den 
SourceCode/Projektdateien zur freien Verfügung.

Da würde ich vorschlagen einfach die E-Mail Adresse per PN an mich?

von Dieter F. (Gast)


Lesenswert?

Saturi schrieb:
> Auch die Version mit FIFO?

Nein - das hätte mir eigentlich auffallen müssen ... :-/

Ich habe nur Kameras ohne FiFo (billig :-) ) und werde versuchen, damit 
klar zu kommen. Blöd - ist aber halt so, andere werde ich mir "just for 
fun" nicht kaufen.

Wenn man den Pixel-Takt weit genug heruntersetzt dürfte das auch ohne 
große Probleme funktionieren. Man muss halt ein wenig optimieren (z. B. 
Deine Bit-Schieberei zur Datenübernahme durch die Übernahme von 2 
Halbbytes ersetzen etc.).

Mal schauen, was so herauskommt ...

von Michael U. (amiga)


Lesenswert?

Hallo,

Dieter F. schrieb:
> Ich habe nur Kameras ohne FiFo (billig :-) ) und werde versuchen, damit
> klar zu kommen. Blöd - ist aber halt so, andere werde ich mir "just for
> fun" nicht kaufen.

hatte ich eigentlich auch, mein Bekannter hatte aber mal eine mit FiFo 
gekauft und auch nie wirklich genutzt. Die ist nun erstmal bei mir. :)

Es könnte prinzipiell ohne FiFo gehen, aber: soweit ich bisher gefunden 
habe, kann die Kamera keine Snapshot-Modus oder ich habe es bisher 
übersehen.
Wenn es so ist, kann man den Kamera-Speicher nicht in Teilstücken 
auslesen.

Sonst würde der Trick wie bei der (eigentlich genauso) alten DC3840 
gehen: Buffer abholen und Bytes mitzählen, 128 Byte übernehmen, 
rausschicken und dann den Buffer wiedér ab Anfang auslesen und mitzählen 
bis zu den nächsten 128 Byte. Die DC3840 gibt aber JPEG seriell mit 
921kBaud aus, das hat dann letztlich selbst ein Mega32 ohne Verluste 
einlesen und mitzählen können.

Ich schau da aber nochmal genauer ins Datenblatt der OV7670.

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Lesenswert?

Michael U. schrieb:
> soweit ich bisher gefunden
> habe, kann die Kamera keine Snapshot-Modus oder ich habe es bisher
> übersehen.
> Wenn es so ist, kann man den Kamera-Speicher nicht in Teilstücken
> auslesen.

Muss ja auch nicht. Wenn man den Pixel-Takt mit Prescaler 32 (eigentlich 
31 + 1 Vorgabe) versieht, dann hat man (bei 16 MHz Systemtakt und 8 MHz 
Kamera-Takt) 64 Zyklen Zeit, ein Byte zu "verwursten". Das sollte 
eigentlich ausreichen. Das sind dann halt keine 30 FPS mehr sondern eher 
rund 0,5 FPS :-). Von da an kann man sich "hochtasten" und optimieren - 
mal schauen, wie weit das möglich ist.

von Michael U. (amiga)


Lesenswert?

Hallo,

64 Zyklen reichen aber nicht, um das Byte zu "verwursten". Du mußt das 
ja irgendwohin befördern, also z.B. seriell senden. Ram ist ja nicht 
genug da.
Wenn Du es direkt in den UART schickst, bist Du bei mehr als 1MBaud.
Ich laß mich da aber gern überraschen.

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Lesenswert?

Michael U. schrieb:
> Wenn Du es direkt in den UART schickst, bist Du bei mehr als 1MBaud.

1MBaud habe ich schon mal übertragen, 2MBaud kann der ATMega328 max. - 
schaun mer mal :-)

Ich will eigentlich auch gar nicht an den PC übertragen - das ist für 
mich ziemlich sinnfrei, da es billige USB-Kameras gibt. Aber als poc 
irgendein LCD ansteuern hat für mich "Charme" :-). Da werde ich mir ein 
mit SPI ansteuerbares Teil suchen (aus meinem Fundus) und das Bild als 
s/w-Krüppel oder auch in Farbe ausgeben.

Um das zu erreichen muss man die Register der Kamera verstehen und 
korrekt einstellen können. Ich lese mich noch ein und spiele herum :-). 
Dauert etwas, da ich auch noch "andere Regierungsaufgaben" habe.

von Michael U. (amiga)


Lesenswert?

Hallo,

Dieter F. schrieb:
> Ich will eigentlich auch gar nicht an den PC übertragen - das ist für
> mich ziemlich sinnfrei, da es billige USB-Kameras gibt. Aber als poc
> irgendein LCD ansteuern hat für mich "Charme" :-). Da werde ich mir ein
> mit SPI ansteuerbares Teil suchen (aus meinem Fundus) und das Bild als
> s/w-Krüppel oder auch in Farbe ausgeben.

ok, als Vorhaben akzeptiert, ich wünsche Dir Erfolg und laß mich etwas 
teilhaben. Display vielleicht das 1,8" 128x160 mit dem ST7735 
Controller, wenn es in Deinen Vorräten ist.

Dieter F. schrieb:
> Um das zu erreichen muss man die Register der Kamera verstehen und
> korrekt einstellen können. Ich lese mich noch ein und spiele herum :-).

Naja, da diskutiere ich auch noch mit der OV2640 am ESP32 rum, 
allerdings basierend auf dem Espresif-Demo. Mir ist da die Umschaltung 
der Auflösung noch nicht sauber gelungen, irgendwelche anderen 
Registereinstellungen müssen da wohl auch noch angepasst werden.

Vielleicht probiere ich auch Deine Idee einfach mal aus...

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Hallo,
ich bin zurück und wieder voller Tatendrang. Habe den Morgen auch damit 
verbracht, einen Fehler im Timing des Fifos zu suchen und.... siehe 
da... Da habe ich wohl im Eifer meines Code umwerfens vergessen die 
funktion zum "read pointer reset" aufzurufen..... kein Wunder, dass nur 
unreproduzierbarer Müll rauskommt....

Jetzt "reagiert das Bild wenigstens auf Abdunkeln und Belichten der 
Kamera.
Aber irgendetwas scheint trotzdem nicht zu funktionieren...

ich habe jetzt probeweise das Beschreiben des FIFOs deaktiviert. jetzt 
sollte ja nach meinem Verständnis immer das gleiche Bild beim Auslesen 
erscheinen (auch wenn man weniger von Bild als von Muster reden sollte). 
Tut es aber leider nicht. Daher die Frage:
Hat jemand von euch schon Erfahrungen mit dem AL422B gemacht? oder kann 
mir sagen worauf ich achten muss?

> Dauert etwas, da ich auch noch "andere Regierungsaufgaben" habe.
:D schön formuliert... das geht mir leider auch schon so...

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

Hi David, Michael U. und Dieter F.,

ich habe inzwischen eigentlich alles Zeugs zusammen, um David's 
Schaltung nachzubauen (siehe Foto), aber ich bringe es einfach nicht 
über's Herz, meine sauer erkämpften, wenigen freien Bastelstunden in 
AVR-Technik zu investieren - bitte seht's mir nach.

Wer einmal ARM gemacht hat, will nie wieder zurück ...

Also werde ich versuchen, den AL422B am ganz oben abgebildeten STM32F4 
Discovery Board (mit einem STM32F420ZI ARM-Prozessor) ans Laufen zu 
bringen. Ich habe dieses Board mit Absicht gewählt,

a) weil ich es herumliegen hatte,
b) weil ein ARM-Prozessor draufsteckt,
c) weil es auf 3,3V läuft und ich keine Level-Shifter benötige,
d) weil dort schon ein  ILI9346-Display draufklebt.

Mit dem Display kann ich die Ergebnisse etwas einfacher und direkter 
testen und spare weiteres Kabel-Wirrwarr.

Bitte seid trotzdem nicht traurig, denn ich werde ja dieselben 
AL422B/OV7670-Protokollhürden zu nehmen haben, wie Ihr.
Wir können also trotzdem alle voneinander lernen (wenn ich denn 
überhaupt etwas zustande bringe ...).

Mal sehen, wie weit ich komme - tempus fugit.

Viele Grüße

Igel1

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> ich habe inzwischen eigentlich alles Zeugs zusammen, um David's
> Schaltung nachzubauen (siehe Foto), aber ich bringe es einfach nicht
> über's Herz, meine sauer erkämpften, wenigen freien Bastelstunden in
> AVR-Technik zu investieren - bitte seht's mir nach.

ich kann mir da zwar mehr Zeit für die Geschichte nehmen (obwohl, 
Rentner haben niemals Zeit...), trotzdem wird sich meine Beteiligung ja 
auch auf Nachvollziehen seiner Versuche und Hilfestellung bei 
Fehlersuche u.ä. beschränken. Ich finde für die OV7670 am AVR für mich 
einfach keinerlei praktischen Nutzen, die Teile liegen aber rum, seine 
Software zu flashen und mal reinzuschauen, sehe ich da nicht als Aufwand 
an.
Wie schon mehrfach erwähnt, habe ich ja die OV2640 am ESP32 als 
aureichende Beschäftigung, obwohl die z.Z. wegen anderer "Projekte" auch 
mehr rumliegen.

Ein Display direkt an der Kamera wäre da auch bei mir nur zum 
Experimentieren sinnvoll, mit den kleinen OV2640/ESP32 Modulen kann ich 
die Bilder per WLAN verschicken und den Odroid Go als Monitor. Das läuft 
ja prinzipiell auch schon, nur nicht so, wie ich es mir vorstelle. ;)
Die Links zu dem Kram hatte ich nja im Thread scon mal gepostet.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

> Mal sehen, wie weit ich komme - tempus fugit.

So, der Tag ist mehr als vorbei ...

Zwischenergebnis:

- Mein STM32F429I Discovery-Board ist präpariert (ich musste erst einmal
  den ST-Link in einen J-Link umflashen (ARM-Insider werden verstehen,
  was ich damit meine)

- Sodann habe ich erstmals eine für mich neue IDE - nämlich Embedded
  Studio von SEGGER ausprobiert (wow - unglaublich das Teil!).
  Zum Glück war der Umstieg von meiner alten IDE (emIDE) nicht
  wahnsinnig schwierig, da sich beide ziemlich ähneln.

- Sodann ging's ans Code-Migrieren:
  LCD-Display kann ich ansteuern, d.h. Pixel kann ich einzeln setzen
  Später will ich den FiFo auslesen und auf das Display schreiben -
  erstmal Pixel für Pixel.

- Die Verkabelung hat ewig gedauert:
  OV7670+AL422B-FiFo sind teilweise mit dem Board verbunden.
  VCC, GND, SIOC, SIOD, VSYNC, HREF - mehr noch nicht.

- SCCB scheint zu funktionieren.
  Auslesen von Registerwerten ergibt plausible Ergebnisse.
  Zum Schreiben von Registern hatte ich noch keine Zeit.

Bevor David jetzt ganz blass wird: nein - ich war nur deshalb so 
schnell,
weil ich ja vor >1 Jahre schon einmal die OV7670 Camera an einem
identischen Board so halb am Laufen hatte.

Habe also hauptsächlich Coderecycling betrieben und mich mit dem
Aufsetzen von Dingen beschäftigt, die in meiner alten IDE schon
liefen, in der neuen aber noch nicht.

Das Tolle an ARM und der verwendeten IDE:

- Ich kann nun hardwarmäßig debuggen (und dabei Register und Variablen
  auslesen)
- Ich kann print-Statements verwenden - Ausgabe landet im Debugger
- Flashen geht sehr schnell (<2s)

Jetzt kann ich als nächstes das Auslesen des FIFOs angehen.
Wenn jemand Lust hat, mir die Vorgehensweise dafür zu schildern,
so würde das vermutlich viel Zeit und Recherche ersparen.

Aber jetzt fängt erst einmal die Woche wieder an und das Büro
freut sich auf mich.  Das heißt: Adieu OV7670 ...

Viele Grüße

Igel1


PS: @Michael U. : ja, Du bist offensichtlich in Sachen Kameras ein
ganzes Stückchen weiter als wir - nett, dass Du hier Tipps gibst!

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> - Mein STM32F429I Discovery-Board ist präpariert (ich musste erst einmal
>   den ST-Link in einen J-Link umflashen (ARM-Insider werden verstehen,
>   was ich damit meine)
Das hättest Du nicht schreiben sollen... ;)
Ich habe da als ARM-Outsider bestimmt noch mal eine Frage an Dich.
Ich mußte wiedermal sinnlos Geld ausgeben:
Beitrag "Arduino Custom Firmware für Fitness Armband mit NRF52"

Andreas S. schrieb:
> PS: @Michael U. : ja, Du bist offensichtlich in Sachen Kameras ein
> ganzes Stückchen weiter als wir - nett, dass Du hier Tipps gibst!

Es ist nur Spaß am Experimentieren. Meine erste echte Kamera-Begenung 
war eine TFK500
https://www.google.com/search?q=Kamera+TFK500&tbm=isch&source=univ&client=firefox-b&sa=X&ved=2ahUKEwjovKOz_I_gAhVNYlAKHVgADb0QsAR6BAgGEAE&biw=1484&bih=840
Dazu ein diskreter 4 Bit AD-Wandler mit 2 Komparatoren und Zählerlogik 
am Userport vom C64. Nach rund 3 Minuten hatte ich dann ein Bild 160x200 
mit 4 Graustufen. Gibt es leider nichts mehr davon, muß um 1988 gewesen 
sein.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Hi David, hi Leute,

nach Studium des Datenblattes vom AL422B:
(https://www.enrgtech.co.uk/buy/product/ET16818568/AL422B-PBF)
(Achtung: achtet darauf, irgendwo die aktuellste Version aufzutreiben)

... bin ich jetzt doch einigermaßen irritiert.
Dort steht zu lesen:
1
8.3.1 Irregular Read/Write
2
It is recommended that the WCK and RCK are kept running at least 1MHz at all times. The faster one of WCK and RCK is used as the DRAM refresh timing clock and has to be kept free running. When irregular FIFO I/O control is needed, keep the clock free running and use /WE or /RE to control the
3
I/O as follows:    [... dann folgt ein Bild ...]

Außerdem lese ich in Kapitel "7.4 AC Characteristics":
1
Trc (RCK Cycle Time)   min. 20   max. 1000 ns

Da Trc laut den nachfolgenden Bildern die Periodenlänge von RCK, also 
der Read Clock ist, bedeutet das eindeutig:

Der minimale Takt zum Auslesen der AL422B beträgt 1MHz.

Das würde den gesamten Vorteil, den der FiFo bringen soll: nämlich 
schnelles einlesen der Daten von der Kamera und (beliebig) langsames 
Auslesen der Daten aus dem FiFo durch den Mikrocontroller ad absurdum 
führen.

Wäre wenigstens der "Read Enable" Pin [/RE] auf dem Modul nach draussen 
geführt, so könnte man den Auslesevorgang zumindest ab und an anhalten, 
um kurz Luft zu schnappen (dabei liegt der Lesetakt weiterhin am AL422B 
an, aber dessen Adresszähler wird angehalten). Das ist allerdings nicht 
der Fall - schöne Fehlkonstruktion.

Da Dein ATmega 328p zudem kaum Speicher hat, müsstest Du Daten somit 
mehr oder weniger mit dieser Rate auch über den UART schicken.
Ist das so von Dir geplant?

Hmmm ... bin ratlos bis irritiert, wie Du mit dem AL422B das 
Geschwindigkeits-Bottleneck des Prozessors umschiffen kannst. Das könnte 
schwierig werden - zumindest, wenn Du die Spezifikation einhalten 
möchtest.

Allerdings will ich nicht ausschließen, dass ich mich irgendwo 
dramatisch vertan habe - mir kommt diese  1MHz-Beschränkung im Read 
Clock absolut spanisch vor, denn der Refresh-Zyklus für das DRAM im 
AL422B wird angeblich vom jeweils höheren Takt (also WCK oder RCK) 
abgeleitet.

Da sollte es dem DRAM doch egal sein, wenn der RCK-Takt z.B. nur mit 
1KHz getaktet wird - solange WCK > 1MHz ist. Dumm dabei ist nur, dass 
das Datenblatt etwas anderes sagt, nämlich "It is recommended that the 
WCK and RCK are kept running at least 1MHz at all times." Dort steht 
expliztit NICHT "WCK or RCK are kept > 1MHz" sondern "WCK and RCK are 
kept > 1MHz".

Soweit die schlechten Nachrichten.

Und nun die guten Nachricthen: wenn Du auf die Spec pfeifst, so fand ich 
hier einen Bericht von jemandem, der den AL422B angeblich super langsam 
ausgelesen hat (so jedenfalls seine Worte):
https://www.eevblog.com/forum/microcontrollers/how-to-reduce-the-data-rate(ov7670-al422b(fifo)-camera-module)/msg314703/#msg314703

Und hier sein Projekt:
http://www.rpg.fi/desaster/blog/2012/10/20/ov7670-fifo-msp430-launchpad/

Da ich gerade bin bisschen zu bequem bin, Deinen Code zu lesen, frage 
ich einfach mal: mit welcher Taktrate liest Du den AL422B aus?

Sollte die Rate < 1MHz liegen, so frage ich direkt: hast Du dabei 
Bedenken, oder kennst Du andere Berichte, die ebenfalls mit niedrigerer 
Taktrate erfolgreich ausgelesen haben?

Und noch etwas: ich habe einen 12MHz Quarz auf meinem OV7670+FiFo AL422B 
- Modul entdeckt. Habt Ihr auch einen 12MHz Quarz oder habt Ihr 
tatsächlich einen 24MHz Quarz?  Es scheinen da einige unterschiedliche 
Modul-Versionen im Umlauf zu sein ... mit jeweils unterschiedlichen 
Schaltbildern.

So scheint bei mir z.B. kein Widerstand zwischen SDA (bzw. SIO_D) und 
VCC zu stecken - hab's nachgemessen. Ich vermute daher eher, dass ich 
dieses Modul hier habe:
http://www.haoyuelectronics.com/Attachment/OV7670-Module-A/CMOS_FIFO%20schematic.pdf

Welches Modul habt Ihr?

Fragen über Fragen - wäre supernett, wenn Ihr ein paar meiner Fragen 
beantworten könntet, dann können wir uns etwas besser 
"aufsynchronisieren".

Viele Grüße

Igel1

: Bearbeitet durch User
von Dieter F. (Gast)


Lesenswert?

Andreas S. schrieb:
> Und nun die guten Nachricthen: wenn Du auf die Spec pfeifst, so fand ich
> hier einen Bericht von jemandem, der den AL422B angeblich super langsam
> ausgelesen hat (so jedenfalls seine Worte

Ich lese das etwas anders - er hat das Bild super-langsam an den PC bzw. 
das dortige Python-Programm gegeben. Gelesen hat er mit seinem schnellen 
MSP ...

"120mhz with 64KB memory), which was necessary to be able to process the 
signals in time."

von Andreas S. (igel1)


Lesenswert?

@Dieter F.:

Bitte den gesamten Absatz lesen, dort steht:
1
In my previous experiment I used a quite powerful LPC1769 microcontroller (running at
2
3
120mhz with 64KB memory), which was necessary to be able to process the signals in time.
4
5
This time however, thanks to the FIFO memory, the heavy hardware requirements are gone. For this reason I thought it might be fun to use the least powerful MCU I have around, which happens to be the MSP430.

=> Er hat das Auslesen mit einem MSP430 realisiert - das ist nun 
wahrlich keine Rennmaschine. Und im weiteren Verlauf ist zu lesen, dass 
er die Daten (die er ja kaum im MSP430 wird zwischenspeichern können) 
via UART bei gemütlichen 115200 baud überträgt.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

na toll, ich soll also Datenblatt lesen... ;)
AL422B Revision 1.5 biete ich erstmal als Datenblatt an?
Mindesttakt ist erstmal schon klar, ist ja DRAM drin.
Erfahrungsgemäß halten die die Daten auch, wenn man relativ lange nicht 
refresht. Müßte man mal Testen, einfach mehrfach auslesen und 
vergleichen mit anhalten von RCK/WCK für verschiedene Zeiten.
Beleibt beim C64: Bild laden und anzeigen. C64 aus und wieder ein und 
den VIC-Zeiger wieder auf die Grafik und schauen, wieviel schon kaputt 
ist.
1s klappte eigentlich immer ohne gekippte Bits...

Ich muß mir das aber alles erstmal anschauen.
Als Gedankenansatz: RCK läuft durch. Mit /RRST Lesezeiger auf Anfang, 
128 Byte einlesen und verarbeiten. Dann wieder Lesezeiger auf Anfang, 
RCK mitzählen und die nächsten 128 Byte holen usw.
Das war im Prinzip die Version damals mit der DC3840 um die 921kBaud von 
der Kamera durch den AVR in den Websever zu schaffen und den 
Ethenet-Buffer des ENC rauszuschicken wenn der voll war.
Dauerte eben so seine Zeit, klappte aber zuverlässig.

PS: gestern erstmalig mit ST-Link "gekämpt", war ja bisher bei mir ARM 
dran oder eher ARM ab?

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Lesenswert?

Andreas S. schrieb:
> => Er hat das Auslesen mit einem MSP430 realisiert - das ist nun
> wahrlich keine Rennmaschine. Und im weiteren Verlauf ist zu lesen, dass
> er die Daten (die er ja kaum im MSP430 wird zwischenspeichern können)
> via UART bei gemütlichen 115200 baud überträgt.

Ja - zu schnell überflogen, sorry - bin "im Dienst" :-)

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> na toll, ich soll also Datenblatt lesen... ;)

Ja, ja - das Leben ist hart und ungerecht ... :-)

> AL422B Revision 1.5 biete ich erstmal als Datenblatt an?

Hui - scheint ziemlich neu - bitte mal hier verlinken.
Ist die Revision neuer als die hier:
https://www.enrgtech.co.uk/buy/product/ET16818568/AL422B-PBF   ?

> 1s klappte eigentlich immer ohne gekippte Bits...

Na ja - ich bin eigentlich ein Freund davon, innerhalb der Specs zu 
bleiben, denn sonst wird's unberechenbar.

> Ich muß mir das aber alles erstmal anschauen.
> Als Gedankenansatz: RCK läuft durch. Mit /RRST Lesezeiger auf Anfang,
> 128 Byte einlesen und verarbeiten. Dann wieder Lesezeiger auf Anfang,
> RCK mitzählen und die nächsten 128 Byte holen usw.

In der Tat: das war auch mein erster Ansatz, wenn man RCK durchlaufen 
lassen muss und keinen Zugriff auf /RE hat.

Unterm Strich vergeudet der Ansatz allerdings wahnsinnig viel Zeit, weil 
man z.B. 479 Zeilen lang warten müsste, um Zeile 480 von einem VGA-Bild 
ausgeben zu können.

Inzwischen kam mir folgender alternativer Ansatz in den Sinn:
Den Adresszähler des FiFo's ständig durch den FiFo "durchlaufen" lassen 
und ab und an (in regelmäßigen Abständen) immer wieder kleine 
Datenpakete herausnehmen und diese per UART übertragen.
Das wäre quasi ein Interleave-Verfahren:

Beispiel dafür:
Man geht wie mit einem Kamm durch einen Bilder-Frame im FiFo und kämmt 
z.B. Zeile 1, 11, 21, 31, ... 461, 471 heraus und überträgt jedesmal die 
besagte Zeile.

Für die Übertragung einer Zeile hat man in diesem Beispiel jeweils 
weitere 9 Zeilen Zeit, was sogar einigermaßen  passen würde, wenn die 
UART Baudrate 115200 beträgt und RCK mit 1MHz läuft.

Beim nächsten Durchlauf würde man dann die Zeilen 2,12,22,32, ...462, 
472 übertragen, u.s.w.

Selbstverständlich muss man nicht unbedingt ganze Zeilen in einem Rutsch 
übertragen, sondern wird die Anzahl der herausgepickten Daten an den 
verfügbaren Puffer des MC anpassen wollen.

Vorteil gegenüber dem ersten Ansatz: man kann die UART quasi dauerhaft 
"unter Feuer" halten und muss nicht 479 Zeilen lang auf Zeile 480 
warten.

> PS: gestern erstmalig mit ST-Link "gekämpt", war ja bisher bei mir ARM
> dran oder eher ARM ab?

Ich muss schon sagen: Du schreckst vor nichts zurück!
Willst Du Dich tatsächlich in ARM einarbeiten?
Wenn ja, so hätte ich vielleicht ein paar Tipps für Dich (wenngleich ich 
auch kein ARM-Profi bin): Einer der Tricks wäre, Dich nicht mit ST-Link 
abzugeben, sondern direkt den ST-Link auf Deinem Board (welches hast 
Du?) in einen J-Link umzuflashen. Übertrage einfach vor dem Flashen ein 
größeres Image in den ARM-Prozessor und nach dem Flashen nochmals, dann 
verstehst Du sofort einen der Gründe, warum J-Link so viel besser ist.

Auf den Seiten von Segger findest Du die passende Anleitung dafür:
https://www.segger.com/products/debug-probes/j-link/models/other-j-links/st-link-on-board/

Schreibe mal, was Du mit ARM schon gemacht hast und was Du noch vorhast.

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

Dieter F. schrieb:

> Ja - zu schnell überflogen, sorry - bin "im Dienst" :-)

Kein Problem: Du hast die ersten 3 Zeilen aus dem Artikel gelesen und 
ich die nächsten - das war klassische Arbeitsteilung :-)

von Michael U. (amiga)


Lesenswert?

Hallo,

Link zum Datenblatt:
https://datasheetspdf.com/datasheet/AL422B.html
Hmmm scheinen identisch zu sein, nur meins heißt AL422B?

Deine FiFo Überlegungen gefallen mir auch, wenn ich das real teste dann 
schon aus Prinzip auf einem ATMega238. Ich muß mir das aber erst in Ruhe 
anschauen und mal Takte zählen.

Andreas S. schrieb:
>> PS: gestern erstmalig mit ST-Link "gekämpt", war ja bisher bei mir ARM
>> dran oder eher ARM ab?
>
> Ich muss schon sagen: Du schreckst vor nichts zurück!
> Willst Du Dich tatsächlich in ARM einarbeiten?

Siehe meinen Link weiter oben von 28.01.2019 09:05.

Ich will nicht direkt, aber alels, was sich aus der ArduinoIDE 
programmieren läßt, hat für mich erstmal eine sehr geringe 
Einstiegshürde.

Andreas S. schrieb:
> Schreibe mal, was Du mit ARM schon gemacht hast und was Du noch vorhast.

Nichts. Gestern viel mir dann noch ein, daß ich irgendwo mal ein 
Nucleo-Board gakauft hatte, das nach etwas suchen auch wieder 
auftauchte. Hat den Vorteil, daß ich also auch einen Original ST-Link 
verfügbar habe. Das China-Teil hat sich zwar ordentlich gemeldet, ließ 
sich aber nicht updaten. Nach der Fehlermeldung beim Update ist es auch 
nicht mehr erreichbar bis zum Abstecken/Anstecken.
Ist mir im Moment aber erstmal egal, die Uhr ist angekommen und lädt 
gerade Akku, dann kann ich sie in Ruhe kaputt machen. ;)
Das Nucloe-Board speilt zumndest mit der ArduinoIDE, wenn auch erstmal 
nur ein Blink-Sketch für die LED geflasht.
Ob ich da mehr mit den STM oder den nRF mache? Keine Ahnung.Ob ich mir 
da eine sinnvolle IDE für installiere hängt einfach von einem Projekt 
ab, das mir vielleicht noch in den Sinn kommt. Eigentlich bin ich aber 
mit dem ESP32 gut ausgelastet.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

@Michael U.:  Ja, mit dem Datenblatt hast Du den Vogel abgeschossen - 
scheint tatsächlich die neueste Version zu sein.

Was Deine NRF52832-basierende Uhr angeht, so scheint das ebenfalls ein 
interessantes Projekt zu sein - ach hätte der Tag doch nur 32 Stunden 
...

Aber nun back to business:

Habt Ihr schon einen Vorschlag für eine Reihenfolge, in der wir die 
Leitungen des OV7670+FiFo - Moduls ansteuern sollten, um:

1.) einen Frame aus dem OV7670 in den AL422B zu laden?
2.) den Frame aus dem AL422B wieder herauszulesen?
    (erst einmal ganz grundsätzlich N Bytes ab Adresse 0 herauslesen)

Ich würde diese Vorgehensweise gerne zunächst in Pseudocode 
aufschreiben, bevor ich loslege.

Alternativ könnte ich vielleicht auch einmal in David's Code spicken ...
(Wo ist eigentlich David abgeblieben?)

Viele Grüße

Igel1

: Bearbeitet durch User
von David D. (saturi)


Lesenswert?

> (Wo ist eigentlich David abgeblieben?)

Der baut gerade schon wieder Überstunden auf... und die Pendellei killt 
den Rest vom Tag... Wenn man dann noch im Sportverein tätig ist schafft 
man es an den heimischen PC erst um 23:30 :D...

Aber auf euch ist ja Verlass und ich bin begeistert über eure Einwände 
und Vorschläge.

Was mir nicht bewusst war, war die sache mit dem DRAM und dass der FIFO 
offenbar den Inhalt verliert.... darüber habe ich mir nie Gedanken 
gemacht und war der Meinung der Reset meines Read Pointers funktioniert 
nicht... -->Anfänger... Hier fehlen mir wohl noch die Grundlagen, die 
ich mir dann wohl die nächsten Tage versuche anzulesen.

Was das Datenblatt angeht hatte ich Version 1.01... somit werde ich dann 
jetzt auch mal auf das neue umsteigen.

Was die Frequenz des Betreiben angeht, habe ich mich an folgenden Satz 
geklammert:
"...The faster one of WCK and RCK is used as the DRAM refresh timing 
clock and has to be kept free running."

Das dann folgende Bild, schildert ja genau, wie man das Schreiben im 
irregular Mode dann händeln soll. Ich habe es dann naiv einfach 
angenommen, dass der auf dem Board verbaute Quarz (bei mir sind es auch 
12MHz) die WCK steuert und die dann automatisch die schnellere ist. Das 
mit dem Write and Read (und nicht Or) ist mir auch schon aufgefallen, 
habe aber gehofft, dass dem einfach keine Beachtung geschenkt wurde.

>Sollte die Rate < 1MHz liegen, so frage ich direkt: hast Du dabei
>Bedenken, oder kennst Du andere Berichte, die ebenfalls mit niedrigerer
>Taktrate erfolgreich ausgelesen haben?
Bedenken habe ich keine :D Dafür fehlen mir einfach sämtliche 
Erfahrungswerte. Die Read rate liegt mit sicherheit unter 1Mhz, weil ich 
jede Zeile zunächst per Uart an den PC übertrage, wenn diese vollständig 
übertragen wurde, vom PC die nächste anfordere und dann erst sende.

Aber da war mir die Sache mit dem flüchtigen Speicher noch nicht ganz 
klar. Dass werde ich mir (hoffentlich morgen) einmal anlesen. Werde auch 
gerne kurz erläutern wie es in meinem Code abläuft, damit ihr in dem 
Wirrwarr nicht lange suchen müsst ;-) aber jetzt bin ich erstmal reif 
fürs Bett.

von David D. (saturi)


Lesenswert?

Guten Tag,
eine weitere Sache, die mir grade bei dem Studium des Datenblattes 
auffällt:

Kapitel 8.3.2 Read Enable during Reset Cycles

hier steht, dass der Read Enable während des RRST niemals low sein darf.

Bei mir auf dem board ist der Pin garnicht nach außen geführt und wird 
somit von mir auch nicht gesteuert.

Weiß da jemand was?

Gruß David

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> eine weitere Sache, die mir grade bei dem Studium des Datenblattes
> auffällt:
>
> Kapitel 8.3.2 Read Enable during Reset Cycles


Das ist Dir vermutlich deshalb nicht eher aufgefallen, weil genau dieses 
Kapitel in  älteren Versionen des Datenblatts fehlte ... (daher hatte 
ich so geflissentlich auf die neueren Versionen verwiesen).

> hier steht, dass der Read Enable während des RRST niemals low sein darf.
>
> Bei mir auf dem board ist der Pin garnicht nach außen geführt und wird
> somit von mir auch nicht gesteuert.
>
> Weiß da jemand was?

Ich kann Deine Beobachtung leider nur bestätigen (scharfes Auge, 
Kollege!):

In der Tat ist der /RE Pin auch auf meinem Modul dauerhaft auf GND 
gezogen (hab's gerade mit dem Multimeter nochmals geprüft). Somit dürfte 
man lt. Datenblatt den /RRST niemals benutzen.

Das bedeutet im Klartext: unser Board hat einen Designfehler.
Da wir diesen ohne riesigen Lötaufwand wohl kaum beheben können,
bleibt uns keine Wahl, als damit zu leben.  Immerhin sind wir
jetzt gewarnt und wissen, dass wir bei der Benutzung von /RRST
evtl. nicht das von uns erwartete Ergebnis erhalten werden.

Viele Grüße

Igel1

: Bearbeitet durch User
von David D. (saturi)


Lesenswert?

Das kann ich leider nur Bestätigen. Bei betrieb habe ich noch eine 
Spannung von 0.2 V an dem Pin anliegen. Und auch in der Schematic die 
ich gefunden habe:

https://www.beyondlogic.org/pdf/OV7670_FIFO_SCH_V1.pdf

wird ~RE auf GND gezogen...
Wie gehen wir jetzt weiter vor? :D

Edit: Altes Datenblatt Seite 18 könnte uns retten. Allerdings finde ich 
diese Beschreibung im neuen nicht mehr.... Das ist doch zum Mäuse melken 
:D

"8.3.4 One Field Delay Line (The Old Data Read)
As the design shown in diagram by applying the reset every 1-field cycle 
(with the common signal for
/WRST and /RRST) and a constant read/write operation (with all /WE, /RE 
and /OE are tied to
ground), “1 field delay line” timing is shown in timing chart below"

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,

ihr seid also fleißig beim Datenblatt lesen.
Ich habe im Moment nur mal recht kurz durch die (Arduino-)Welt geschaut.
a) die OV7660 mit FiFo ist so aufgebaut, weil irgendjemand das mal so 
beschlossen hat.
Ich habe bisher nur diese Modulversion gefunden, wo /RE fest auf GND 
ist.
b) Der FiFo hat offenbar sein Datenblatt nicht gelesen.
Demo-Souzrce, wo ich auf die Schnelle mal reingeschaut habe, ignorieren 
das und setzen den Pointer trotzdem mit
1
   digitalWrite(RRST, LOW);
2
   PulsePin(RCLK, 1); 
3
   PulsePin(RCLK, 1);
4
   PulsePin(RCLK, 1);
5
6
void PulsePin(int PinNumber, int DurationMicroSecs)
7
{
8
  digitalWrite(PinNumber, HIGH);           // Sets the pin on
9
  delayMicroseconds(DurationMicroSecs);    // Pauses for DurationMicroSecs microseconds      
10
  
11
  digitalWrite(PinNumber, LOW);            // Sets the pin off
12
  delayMicroseconds(DurationMicroSecs);    // Pauses for DurationMicroSecs microseconds  
13
}

auf Anfang.
Auch die Clockverhältnisse von RCLK werden ziemlich ignoriert...
Ich hoffe, auch nicht-Arduino-User können den Ausschnitt so verstehen.
Ich habe mir da mal ein Beispiel rausgepickt und werde mir das wohl 
morgen mal praktisch anschauen, mal schauen, ob mein LA mit 80MHz da 
noch schnell genug ist.

Ich denke, wir sollten da erstmal mit den Gegebenheiten leben, es 
scheint kein wirkliches Problem zu sein.

@Andreas S. (igel1): bisher ist noch ARM dran. Die Uhr lebt noch und der 
Testketch aus dem anderen Thread ist drauf und läuft. Jetzt habe ich das 
Problem: was will ich eigentlich damit??? Mein Handy findet auch beim 
Scan das BT-Device, da muß mich mich auch erst schlau machen, was ich 
damit jetzt anfangen kann...

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Hi David, Michael (und eventuell auch ein bisschen Dieter, wenn Du noch 
dabei bist),

habe inzwischen alles vorbereitet, um den Stier bei den Hörnern zu 
packen:

- Das OV7670+FIFO - Modul ist mit meinem STM32F429 Discovery Board 
verkabelt. Das war bislang der zeitaufwändigste Akt von allem, denn fast 
alle Pins des MC's sind bereits mit irgendwelcher Peripherie auf dem 
Testboard verbunden. Das muss man sich erst einmal 17 Pins, die ich für 
Ansteuerung und Auslesen des OV7670+FiFo benötige, aus den Rippen 
schneiden. Hoffe, ich habe keine Fehler gemacht, sonst ist mein schönes 
Board dahin.

- Inzwischen läuft auch Timer1 (von insgesamt 17 verfügbaren Timern!) 
auf dem STM32F429 im PWM-Mode und wirft mir einen schönen 1MHz-Takt 
raus, den ich in FIFO_RCK einspeise.

- SysTick-Timer ist ebenfalls aufgesetzt - damit habe ich auch eine 
schicke Delay(ms)-Funktion.

- Funktionen zum Pixelweisen Beschreiben des LCD's habe ich ebenfalls 
(okay, nicht selbst geschrieben, sondern ausgeliehen - vgl. eines meiner 
letzten Postings).

- Sodann habe ich die folgenden Funktionen implementiert:
1
void InitControlPins();
2
uint8_t Read_VSYNC();
3
uint8_t Read_HREF();
4
uint8_t Read_FIFO_Data()
5
void Write_FIFO_WR(BitAction BitVal);   // BitVal: Bit_SET  or  BIT_RESET                               
6
void Write_FIFO_OE(BitAction BitVal);   // BitVal: Bit_SET  or  BIT_RESET                             
7
void Write_FIFO_WRST(BitAction BitVal); // BitVal: Bit_SET  or  BIT_RESET                             
8
void Write_FIFO_RRST(BitAction BitVal); // BitVal: Bit_SET  or  BIT_RESET

Ich hoffe, ich habe nichts vergessen ...

Das Brot- und Buttergeschäft ist also erledigt, jetzt kann der schönere 
Teil beginnen: nämlich die eigentliche Logikimplementierung.

Nur leider ruft jetzt, wo's gerade spannend wird, schon wieder die 
Pflicht  ...
Aber so ist das mit dem Hobby - es kommt irgendwie immer zu kurz - 
jedenfalls gefühlt :-)

Bis denne

Igel1



PS: @Michael: Du hast eine Fitnessuhr erworben und fragst "Jetzt habe 
ich das Problem: was will ich eigentlich damit???" Hmmm, ich würde 
vorschlagen, Du machst ein bisschen Fitness damit ... 
(Programmier-Fitness oder körperliche Fitness - das überlassen wir jetzt 
mal Dir :-)

: Bearbeitet durch User
von Dieter F. (Gast)


Lesenswert?

Andreas S. schrieb:
> (und eventuell auch ein bisschen Dieter, wenn Du noch
> dabei bist)

Bin ich - nur langsamer und ohne Fifo :-)

Ich lese auch Datenblätter und überlege, wie ich am Besten vorgehe. Für 
mich ist der Fifo nur ein Hilfsmittel, um langsamer auslesen zu können. 
Alles andere - speziell die Ansteuerung der Kamera - sollte sich nicht 
sehr unterscheiden.

von Andreas S. (igel1)


Lesenswert?

Hallo Dieter,

schön, dass Du noch mit dabei bist!

Kameraansteuerung mit SCCB funktioniert schon bei mir.

Aber an den richtigen OV7670-Registerwerten wäre ich wahnsinnig 
interessiert!!

Mit "richtig" meine ich solche Registerwerte, die gute Bilder geben, 
denn da kann man bei der OV7670-Kamera ja problemlos an 200 mehr oder 
weniger undokumentierten Schrauben drehen.

Habt Ihr solche Werte schon irgendwo im Netz abgreifen können?
Selberforschen ist mit diesen OV7670-Datenblättern wie 
Blinde-Kuh-Spielen.

Und der neugierdehalber:

Wie/womit programmierst Du?
Mit Arduino-IDE auf Arduino-Nano (so wie David, unser Eiskalt-Duscher)?
Oder mit Atmel-Studio in Assembler auf dem größten ATmega, den es gibt? 
(das wäre eher die Lauwarm-Duscher Variante).

Ich selber bin mit meinem 180MHz ARM-Prozessor natürlich ein 
Voll-Warmduscher :-)

Viele Grüße

Igel1

: Bearbeitet durch User
von Dieter F. (Gast)


Lesenswert?

Andreas S. schrieb:
> Wie/womit programmierst Du?

Um kompatibel zu sein mit C und Atmel Studio auf ATMega328P (Arduino 
Nano Hardware) - das ist zwar eine Krücke, aber auch eine 
Herausforderung :-). Normalerweise würde ich mit ausreichend Ports und 
DMA arbeiten (ATXMega) oder idealerweise einen STM mit entsprechender 
Anschlussmöglichkeit (es gibt welche mit "Kamera-Schnittstelle") nutzen 
- aber STM ist mir nicht geläufig und nur zum Spaß will ich mich da auch 
nicht einarbeiten.

Es haben sich schon viele mit der Ansteuerung beschäftigt und fast alle 
nutzen Vorarbeiten von anderen (Register-Definitionen und -Werte) - da 
ist ein weites Feld.

Noch bin ich nur am "rumspielen" und lesen - aber eine "normale" 
TWI-Anbindung funktioniert gut und mit 8MHz externem Takt läuft die 
Kamera auch ohne Probleme.

Wie geschrieben suche ich nach Möglichkeiten, ohne Fifo mit dem 328P 
"vernünftige" Bilder zu bekommen und vielleicht wenigsten 1 FPS zu 
erreichen (ggf. interleaved, wie geschrieben).

Beitrag #5717113 wurde von einem Moderator gelöscht.
von Michael U. (amiga)


Lesenswert?

Hallo,

ich famge mal hier an:
Dieter F. schrieb:
> Wie geschrieben suche ich nach Möglichkeiten, ohne Fifo mit dem 328P
> "vernünftige" Bilder zu bekommen und vielleicht wenigsten 1 FPS zu
> erreichen (ggf. interleaved, wie geschrieben).

Ich hatte gestern meine alten Links mal durchgeschaut, die ich da mal 
gesammelt hatte. Dabei fielen mir zwei wieder auf auf:

https://www.instructables.com/id/OV7670-Arduino-Camera-Sensor-Module-Framecapture-T/

http://privateblog.info/arduino-uno-i-kamera-ov7670-primer-ispolzovaniya/

Beide haben für uns meiner Meinung nach ein paar Vorteile als Anregung: 
es ist alles im Stück, es ist relativ überschaubar gegliedert, sie 
benutzen einen Mega328, sie benutzen OV7660 ohne FiFo. Ich werde wohl 
heute mal testen, was da real geht.

Andreas S. schrieb:
> Und der neugierdehalber:
>
> Wie/womit programmierst Du?
> Mit Arduino-IDE auf Arduino-Nano (so wie David, unser Eiskalt-Duscher)?
> Oder mit Atmel-Studio in Assembler auf dem größten ATmega, den es gibt?
> (das wäre eher die Lauwarm-Duscher Variante).
>
> Ich selber bin mit meinem 180MHz ARM-Prozessor natürlich ein
> Voll-Warmduscher :-)

Ich trenne hier mal etwas anders: Eiskalt-Duscher als Prinzip für 
"siehste, es geht doch!" bei mir. Beim ATMega kpönnte ich auch auf den 
Mega1284 ausweichen, der größte, der hier rumliegt, da lassen sich fast 
alle auch stabil bis 25MHz übertakten (Mega328 meist auch).
Xmega gibt es hier irgendwo einen der ersten (XPlain Demoboard, gekauft, 
kurz angetestet, nie was mit gemacht...).
Nächste mögliche Runde wäre ein ST-Nucleo (habe ich ja 
wiedergefunden...) oder eben meine "geliebten" ESP32.
ArduinoIDE ist eine Entscheidung zur Bequemlichkeit incl. der 
Einschränkungen. Bei AVR spielt es eigentlich keine Rolle, 
Studio-Sourcen lassen sich mit wenig Aufwand in die ArduinoIDE werfen 
und compilieren, Sketchordner "projektname" anlegen, alles wahllos da 
reinkopieren, die main.c in "projektname.ino" umbenennen, bei den .h 
Dateien noch einen Vorrat C++ - extern c Klammerei rumwerfen und dann 
geht es zu 99% schon.
Ist nicht schön, aber selten...
Für den ESP32 und die IDF-Projekte gilt prinzipeill das Gleiche, der 
Anpassungsaufwand ist aber etwas größer.
Mit STM32 habe ich das wegen der kurzen Erfahrung mit Nucloe bzw. der 
nRF5-Uhr noch nicht probiert.
Großer Vorteil für mich: nur eine "IDE" für alles, mit externem 
NotePad++ als Editor auch durchaus praktikabel. Man kann portable 
einfach mehrere auf dem Rechner haben und macht sich den Kram nicht 
gleich kaputt, weil man mal was ausprobiert.
So, genug der Arduino-Werbung...

Der Übergang zu Lauwarm-Duscher und Voll-Warmduscher wäre also eher 
fließend. Beim STM32 wäre es interessant, Du kannst mir ja mal Deinen 
STM-Code schicken und die Pinbelegung, wäre interessant, was  da unter 
Arduino passiertt.

Andreas S. schrieb:
> Aber an den richtigen OV7670-Registerwerten wäre ich wahnsinnig
> interessiert!!

"Richtige" Registerwerte findest Du doch zu Hauf im Netz, schwieruger 
ist es, halbwegs brauchbar kommentierte Init-Sequenzen zu finden, das 
halte ich aber für ein grundsätzliches Problem. Mir sind schon genug 
Applikation-Beispiele für relativ komplexe ICs von den Hersteller 
begegnet, wo 50 Register initialisiert wurden und bei 45 davon keinerkei 
Kommentar stand, so nach der Devise "das muß man eben bei unserem Chip 
so machen".

Ich habe mir bei meinen privaten Basteleien abgewöhnt, alles bis ins 
kleinste Detail zu hinterfragen.

So, Roman zu Ende...

Gruß aus Berlin
Michael

von Michael U. (amiga)


Lesenswert?

Hallo,

so, Roman 2.Teil, diesmal zum Thema:
das Programm von
http://privateblog.info/arduino-uno-i-kamera-ov7670-primer-ispolzovaniya/
compiliert bei mir nicht sinnvoll, einige Meckereien, zu groß für den 
Mega328. Ein Versuch, für den Mega2560 zu compilieren endete auch 
tragisch, ich hätte auch keinen hier gehabt.

Also den anderen Link, ist ohnehin ausführlicher für mich.
Sketch compiliert ohne Probleme, auf einen Arduino Nano geflasht.
Nichts... Ein paar Debug-Ausgaben hinzugefügt: arduinounoinut() läuft 
durch, XClock, TWI und UART sind richtig initialisiert, mein eingefügtes 
"Ready" kommt im Ternimal sauber an.
Hänger war bei camInit() und da beim ersten wrReg().
Logisch, wenn ich SDA und SCK vertauscht habe...
Umsortiert und es kommen erstmal Massen an Daten im Ternimal an.
Ich habe in SDA/SCK/XCLK Pegelwandler drin, weil die sowieso noch auf 
dem Steckbrett waren vom letzten Versuch vor Ewigkeiten.

TeraTerm kann zwar prinzipiell 1MBaud und die Daten mitloggen, die 
Anzahl Daten zwischen zwei RDY passten aber nicht zu den erwarteten. 
Entweder ich bringe sein Java-Zeug mal in Gang (hane nichtmal ein 
SunJAVA drauf zur Zeit...) oder ich nehme mein letztens wieder 
installiertes uraltes VN6 und meine LogicAnalyzer-Software von vor x 
Jahren, da kann ich sicher 500kBaud und eigentlich auch 1MBaud einlesen 
und dann eben erstmal in eine Datei schreiben. Wenn die Byteanzahl passt 
kann ich es ja auch mal als RAW in Irfanview laden.

Jetzt muß ich aber erstmal was sinnvolles machen...
Auch als Rentner hat man niemals Zeit. ;)

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe das (las sich recht "ausgereift") ausprobiert, um zu sehen, ob 
die Kamera überhaupt Bilder liefert.

http://acoptex.com/project/254/basics-project-052a-ov7670-camera-sensor-module-without-fifo-ram-at-acoptexcom/#sthash.IDGNJNcx.P8aXeyqc.dpbs

Das gelbe vom Ei ist es nicht - ich musste das Timing auf 20 (O.K., ich 
habe grobe Schritte gemacht) einstellen, damit 2 von 3 Bildern mit 0,25 
FPS in SW gut erkennbar waren (Beispiel anbei).

Das Timing ist nicht gerade optimal, ein wenig Glückssache :-). Bestärkt 
mich in meinem "Interleaved-Ansatz" ...

Michael U. schrieb:
> http://privateblog.info/arduino-uno-i-kamera-ov7670-primer-ispolzovaniya/
> compiliert bei mir nicht sinnvoll, einige Meckereien, zu groß für den
> Mega328.

Übrigens sollte das Projekt auf der von mir verlinkten Seite mit Deinem 
Link (außer der Sprache :-) ) weitgehend übereinstimmen (zumindest wird 
entsprechend referenziert).

Michael U. schrieb:
> Entweder ich bringe sein Java-Zeug mal in Gang

Muss nicht, in meinem Link ist auch ein Windows-EXE (leider schwächer im 
Vergleich zum Java-Empfänger) zur "Bildgebung" verlinkt.

Die Kamera scheint sich übrigens sehr träge an die Helligkeit anzupassen 
- da ist wohl "Register-Arbeit" angesagt :-/

Fällt mir gerade so ein - ich habe ja in der Arduino-Umgebung gewildert. 
Könnte sein, dass der "Standard-Millis-Interrupt" dazwischen funkt.

von Michael U. (amiga)


Lesenswert?

Hallo,

Dieter F. schrieb:
> Übrigens sollte das Projekt auf der von mir verlinkten Seite mit Deinem
> Link (außer der Sprache :-) ) weitgehend übereinstimmen (zumindest wird
> entsprechend referenziert).

ja, sind prinzipiell identisch, ich habe mal WinMerge drübergeschickt.

Dieter F. schrieb:
> Muss nicht, in meinem Link ist auch ein Windows-EXE (leider schwächer im
> Vergleich zum Java-Empfänger) zur "Bildgebung" verlinkt.

Wie meinst Du "schwächer"? Macht hier erstmal, was es soll, danke für 
den Hinweis auf die Win-Software.

Ich habe im Moment erstmal das Problem mit senkrechten Kinien im Bild, 
da muß ich wohl nochmal meinen Drahtverhau genauer prüfen...

Dieter F. schrieb:
> Das Timing ist nicht gerade optimal, ein wenig Glückssache :-). Bestärkt
> mich in meinem "Interleaved-Ansatz" ...

Sehe ich eigentlich kein wirkliches Problem, 1MBaud geht, hat man 10 
Bitzeiten bis der UART das rausgeschoben hat und nochmal 1 Byte weil UV 
ignoriert wird. Vielleicht schau ich mir mal das ASM-List an, das der 
Compiler baut, der dürfte aber captureImg() schon sehr brauchbar 
optimieren.
Ich finde den Code selbst eigentlich gut strukturiert und 
nachvollziehbar.

Ich werde das wohl mal mit David's Code "paaren", also z.B. seine 
SCCB-Routinen reinwerfen. Kann man ja schön sehen, was geht oder klemmt.
Auch die FiFo-Version in den Code einzubauen sollte recht problemlos 
gehen.

Naja, kommt Zeit kommt Source. ;-)

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Lesenswert?

Michael U. schrieb:
> Ich habe im Moment erstmal das Problem mit senkrechten Kinien im Bild,
> da muß ich wohl nochmal meinen Drahtverhau genauer prüfen...

Nö, den Teiler (Register 0x11) z.B. auf 20 (wie ich) hochsetzen (die 
hatte ich auch). Das ist alles ein Timing-Problem ...

Michael U. schrieb:
> Wie meinst Du "schwächer"? Macht hier erstmal, was es soll, danke für
> den Hinweis auf die Win-Software

Die Bilder mit der .EXE sind deutlich schlechter, wie die Bilder mit der 
Java-Komponente.

Michael U. schrieb:
> also z.B. seine
> SCCB-Routinen reinwerfen

Nicht erforderlich - TWI/I2C funktioniert prima.

von Dieter F. (Gast)


Lesenswert?

Michael U. schrieb:
> Sehe ich eigentlich kein wirkliches Problem, 1MBaud geht, hat man 10
> Bitzeiten bis der UART das rausgeschoben hat und nochmal 1 Byte weil UV
> ignoriert wird.

Ja, da sind nur die kleine Unsicherheit der Reaktion des 
Schnittstellen-Partners und die harte Abfrage auf high-/low-Pegel beim 
Pixel-Takt. Mein "jedes 3. Bild ist Müll" hat schon eine Ursache - 
möglicherweise einfach nur "millis()".

von Michael U. (amiga)


Lesenswert?

Hallo,

Dieter F. schrieb:
> Nö, den Teiler (Register 0x11) z.B. auf 20 (wie ich) hochsetzen (die
> hatte ich auch). Das ist alles ein Timing-Problem ...

ok, 20 passt erstmal, da muß ich das Datenblatt mal genauer befragen, es 
geht eigentlich NUR 20 bei mir.
Jedes 3. Bild Schrott bestätige ich auch erstmal.

Bilddarstellung in der .exe ist mir noch ewas unklar. Ich habe nochmal 
mit TeraTerm ein Bild geholt und als RAW in Irfanview angezeigt.
Das Bild aus der .exe ist etwas heller. Mein Fokus stand wohl völlig 
daneben, habe ich gerade mal etwas nachgestellt, muß ich morgen bei 
Vernünftiger Beleuchtung mal machen.

Reicht für heute...

Gruß aus Berlin
Michael

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

Dieter F. schrieb:
> Michael U. schrieb:
>> Sehe ich eigentlich kein wirkliches Problem, 1MBaud geht, hat man 10
>> Bitzeiten bis der UART das rausgeschoben hat und nochmal 1 Byte weil UV
>> ignoriert wird.
>
> Ja, da sind nur die kleine Unsicherheit der Reaktion des
> Schnittstellen-Partners und die harte Abfrage auf high-/low-Pegel beim
> Pixel-Takt. Mein "jedes 3. Bild ist Müll" hat schon eine Ursache -
> möglicherweise einfach nur "millis()".

doch noch ein Nachtrag: am PC unter Win7 war zumindest die Auswahl an 
Terminalprogrammen nicht groß, die 1MBaud können und die Daten als 
binär-Daten in eine Datei schreiben.
TeraTerm v6.9 macht es zumindest zuverlässig, wenn auch umständlich.
Mit einer eigenen Empfangsroutine auf der COM sehe ich aber da kein 
Problem.
Möglich, daß das Zusammenspiel beim USB-Seriell-Wandler da noch probleme 
machen könnte, sieht hier aber mit dem CH340 nicht danach aus, FTDI 
macht nach meiner Erfahrung da auch keine Probleme.

milis() wird doch garnicht genutzt, Interrupts sind ohnehin komplett 
gesperrt.
_delay_ms() beim AVR-GCC ist meiner Erinnerung nach eine busy-loop 
basierend auf F_CFU.

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> Also den anderen Link, ist ohnehin ausführlicher für mich.
> Sketch compiliert ohne Probleme, auf einen Arduino Nano geflasht.

Könntest Du netterweise "den anderen Link" ebenfalls hier einstellen?

Und schön: Dieter hat lauffähigen Code im Internet aufgetrieben - der 
grundsätzliche Beweis, dass ein Atmega eine OV7670 Kamera auslesen kann, 
scheint damit schon einmal erbracht. Jetzt müssen wir es nur selber 
ebenfalls noch hinbekommen.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Könntest Du netterweise "den anderen Link" ebenfalls hier einstellen?
Hatte Dieter oben gepostet:
http://acoptex.com/project/254/basics-project-052a-ov7670-camera-sensor-module-without-fifo-ram-at-acoptexcom/#sthash.IDGNJNcx.P8aXeyqc.dpbs

Mein Link:
https://www.instructables.com/id/OV7670-Arduino-Camera-Sensor-Module-Framecapture-T/
ist vom code für den UNO prinzipiell identisch und läuft genauso, bei 
Dieter war nur netterweise die Windows-exe für den Anzeiger dabei, mußte 
ich den JAVA-Kram nicht erst hier in Gnag bringen.

> Und schön: Dieter hat lauffähigen Code im Internet aufgetrieben - der
> grundsätzliche Beweis, dass ein Atmega eine OV7670 Kamera auslesen kann,
> scheint damit schon einmal erbracht. Jetzt müssen wir es nur selber
> ebenfalls noch hinbekommen.

Prinzipiell sollte sich das auch auf dem STM32 so in Gnag bringen 
lassen, wenn man die Hardwareabhängigkeiten bei XCLK Erzeugung, Seriell 
und TWI anpasst.

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Lesenswert?

Andreas S. schrieb:
> Und schön: Dieter hat lauffähigen Code im Internet aufgetrieben - der
> grundsätzliche Beweis, dass ein Atmega eine OV7670 Kamera auslesen kann,
> scheint damit schon einmal erbracht. Jetzt müssen wir es nur selber
> ebenfalls noch hinbekommen.

Ja - wobei ich schrieb, das das nicht optimal ist.

Ich wollte lediglich wissen, ob die (meine) Kamera grundsätzlich 
"arbeitswillig" ist. Ist sie.

Nach dem "keep it simple an stupid"-Prinzip werde ich mit QQVGA 
anfangen. 160 x 120 Pixel scheinen beherrschbar zu sein. Blöd ist, dass 
ich kein passendes PC-Programm dazu habe. Wen stört das - es gibt ja 
SPI-fähige-Displays :-)

von David D. (saturi)


Lesenswert?

Hallo, wow ...
jetzt habt ihr mich erstmal abgehängt...
Ich überlege, ob ich mir auch mal so ein Zeugs aus dem Internet drauf 
schmeißen soll, um meine Kamera zu testen, obwohl ich mir vorgenommen 
hatte, alles selbst in Gang zu bringen, um wirklich jedes Detail zu 
verstehen und zu lernen.

Andreas S. schrieb:
>Wie/womit programmierst Du?
>Mit Arduino-IDE auf Arduino-Nano (so wie David, unser Eiskalt-Duscher)?
>Oder mit Atmel-Studio in Assembler auf dem größten ATmega, den es gibt?
>(das wäre eher die Lauwarm-Duscher Variante).

Also das stimmt nicht ganz, ich mache es wie Dieter:
>Um kompatibel zu sein mit C und Atmel Studio auf ATMega328P (Arduino
>Nano Hardware) - das ist zwar eine Krücke, aber auch eine
>Herausforderung :-).

nur auf Arduino Uno Hardware (was aber im Prinzip das gleiche ist, nur 
mit weniger Pins nach außen geführt) aber ist beides der Atmega328


Dieter F. schrieb:
Noch bin ich nur am "rumspielen" und lesen - aber eine "normale"
TWI-Anbindung funktioniert gut und mit 8MHz externem Takt läuft die
Kamera auch ohne Probleme.

kannst du da villeicht deinen Source code zur verfügung stellen? das 
hatten wir hier "früher" auch schon versucht zum laufen zu bekommen 
(vergeblich...) meines erachtens wegen dem ACK, dass bei TWI und SCCB 
unterschiedlich ist. Vielleicht habe ich aber in meinem Code was 
übersehen gehabt.

EDIT:
Da flattert mir doch was ganz spannendes in die Hände (bzw. auf den 
Bildschirm)

https://github.com/dalmirdasilva/ArduinoCamera/blob/master/CameraAL422B/datasheet/OV7670%20Implementation%20Guide%20(V1.0).pdf

Das sieht mir auf den ersten Blick doch nach einer ausführlichen 
Registerbeschreibung aus und erklärt ebenfalls, dass man Auflösungen und 
Farbformate nicht beliebig mischen darf... (daher hatte ich erst recht 
keine Chance :D )

: Bearbeitet durch User
von Dieter F. (Gast)


Lesenswert?

David D. schrieb:
> Das sieht mir auf den ersten Blick doch nach einer ausführlichen
> Registerbeschreibung aus und erklärt ebenfalls, dass man Auflösungen und
> Farbformate nicht beliebig mischen darf... (daher hatte ich erst recht
> keine Chance :D )

Jein - das ist auch noch nicht die "Wahrheit". Es gibt noch einen 
Software Implementation Guide - und ein hoch-geheimes etwas, was die 
Soll-Register-Einstellungen beinhaltet.

Ich gehe auch erstmal nach den beiden ersten Beschreibungen vor und 
schaue, was dabei herauskommt.

Bei den OV7670-Programmen haben anscheinend alle von irgendwem 
abgeschrieben - die gleichen sich bei der Register-Beschickung fast 
überall.

David D. schrieb:
> Dieter F. schrieb:
> Noch bin ich nur am "rumspielen" und lesen - aber eine "normale"
> TWI-Anbindung funktioniert gut und mit 8MHz externem Takt läuft die
> Kamera auch ohne Probleme.
>
> kannst du da villeicht deinen Source code zur verfügung stellen?

Da kannst Du Dir irgendeinen beliebigen Sourcecode nehmen - die haben 
sowieso (fast) alle nur kopiert.

Ich werde "meinen" Weg gehen und schauen, ob dabei ein Bild (oder viele) 
herauskommen. Wenn ich erfolgreich bin teile ich - wenn nicht suche ich 
mir ein anderes Projekt :-)

von David D. (saturi)


Lesenswert?

Dann werde ich dem ganzen wohl noch eine Chance geben.
Da ich mir nun durch irgendeine Änderung wieder als zerschossen habe, 
habe ich beschlossen jetzt die Dokumentations- und Aufräumarbeiten in 
meinem Code dieses Wochenende zu fokussieren. und werde ihn dann nochmal 
zur Verfügung stellen. Mein Ziel ist es weiterhin ein Bild an den PC zu 
senden und mit meinem eigenen Programm zu erfassen.

Zusätzlich habe ich in meinem Sammelsorium noch ein 1.8 SPI TFT 128*160 
gefunden. (incl SD Kartenaufnahme auf der Rückseite).
Ich überlege grade parallel eure fortschritte damit zu verfolgen. Macht 
das Sinn? (Bislang habe ich das aber noch nicht in Betrieb genommen)

Weiterhin habe ich leider etwas die Übersicht verloren, wer jetzt hier 
was versucht. Ich versuche einmal zusammen zu fassen. Bitte korrigiert 
mich wenn ich falsch liege.

Dieter:
Atmega328P (Arduino Nano) (Atmel Studio) - OV7670 (ohne Fifo)
versucht das Bild direkt auf einem Display darzustellen.

Michael:
Arduino Nano (Arduino IDE) - OV7670 (mit Fifo)
versucht das Bild an den PC zu senden?! und es mit einem COM Terminal 
aufzufangen und abzuspeichern?

Igel:
Durch und durch ARM :D - OV7670 (mit Fifo)
Habe aber bei dir noch nen Nano auf dem Board stecken gesehen was 
treibst du genau mit dem?

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Ich überlege, ob ich mir auch mal so ein Zeugs aus dem Internet drauf
> schmeißen soll, um meine Kamera zu testen, obwohl ich mir vorgenommen
> hatte, alles selbst in Gang zu bringen, um wirklich jedes Detail zu
> verstehen und zu lernen.

Das habe ich ganz ganz fürher noch gemacht, als zu den ICs noch die 
Innenschaltungen veröffentlicht wurde. Ja komplexer die ICs wurde, um so 
mehr habe ich mich auf meine konkrete Anwendung konzentriert. 
Datenblätter lesen hab ich aber damals ganz gut gelernt, auch, daß 
Fußnoten und Anmerkungen oft wichtiger sind als die Registerbeschreibung 
selbst...

David D. schrieb:
> nur auf Arduino Uno Hardware (was aber im Prinzip das gleiche ist, nur
> mit weniger Pins nach außen geführt) aber ist beides der Atmega328

Ob UNO oder Nanao war bei mir ketzt nur eine Größenfrage, die sind 
funktionell in diesem Zusammenhang identisch.
Atmel Studio ist mir für meine Spielereien in zu großer Klotz, ein AVR 
Studio 4 wäre durchaus hier noch griffbereit. Die Sachen auch von Dir 
sind aber in 10 Minuten in der ArduinoIDE und compilieren dort, also 
bleibe ich dabei.
Gerade mal den Spaß gemacht den .ino Inhalt in ein AVR Studio 4 Projekt 
zu packen, hat keine 5 Minuten gedaurt, compiliert. Keine Lust, jetzt 
einen ISP-Programmer zu holen und es zu flashen...

Zu TWI: schau in die verlinkten Arduino-Sketche, ist ohnehin reines C.
Danke noch für den Link zum Applicatio-pdf, hatte ich noch nicht (und 
auch nicht gesucht...).

Ich werde mir morgen mal einen Lochrasterträger mit Buchsenleisten und 
Verdrahtung fertig machen, für den Nano und beide OV7670 Versionen und 
vorverdrahten. Dann fällt nichts gleich auseinander. Werde wohl dann 
auch mal meinen LA ranhängen und mir mal anschauen, wo ein Grund für die 
zyklische auftretenden fehlerhaften Bilder zu erkennne ist.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> EDIT:
> Da flattert mir doch was ganz spannendes in die Hände (bzw. auf den
> Bildschirm)
>
> 
https://github.com/dalmirdasilva/ArduinoCamera/blob/master/CameraAL422B/datasheet/OV7670%20Implementation%20Guide%20(V1.0).pdf

Und Michael U. schrieb daraufhin:
> Zu TWI: schau in die verlinkten Arduino-Sketche, ist ohnehin reines C.
> Danke noch für den Link zum Applicatio-pdf, hatte ich noch nicht (und
> auch nicht gesucht...).

Hättet Ihr mal schön brav die Postings vom lieben Igel1 gelesen, hättet 
Ihr den Guide schon vor Wochen kennengelernt:

Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)"

Anyway ...

Ihr seid ja ganz schön am Stricken - Respekt, Respekt.

> Ich überlege, ob ich mir auch mal so ein Zeugs aus dem Internet drauf
> schmeißen soll, um meine Kamera zu testen, obwohl ich mir vorgenommen
> hatte, alles selbst in Gang zu bringen, um wirklich jedes Detail zu
> verstehen und zu lernen.

Mach das auf keinen Fall! Abkupfern ist extrem motivationskillend
und dazu bewundere ich Deine Ausdauer und Deine steile Lernkurve.
Wenn Du Fertig-Code kopierst, hast Du einen Fan weniger ...

Außerdem kannst Du unendlich stolz auf Dich sein, wenn Du das 
tatsächlich
alles allein hinkriegst! Und willst Du Dir diesen Stolz selber stehlen?

Viele Grüße

Igel1

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Au weia - noch so'n Schnitzer (ich hoffe, diesmal nur im Datenblatt):

Schaut Euch mal das Bild "AL422-06 Write Cycle Timing (Write Enable)" 
auf S.11 der AL422B-Spec an:
Lt. diesem Bild wird das Byte n+2 auf dem Bild erst in der 2. steigenden 
Taktflanke von WCK nach einer fallenden /WE-Flanke abgespeichert.

Unser Problem: das "Horizontal Timing" der OV7670 Kamera besagt, dass 
nach einem Ansteigen von HREF bereits die erste Taktflanke von PCLK das 
erste Pixel-Byte überträgt.

Das würde bedeuten: da HREF direkt per NAND-Gatter mit dem /WE vom 
AL422B gekoppelt ist, würde das erste Pixel-Byte einer jeden Zeile nicht 
in das FiFo geschrieben werden - tolle Wurst!

Aber tröstet Euch: als Ausgleich wird am Zeilenende noch ein völlig 
falsches Byte in den Speicher geschrieben, wenn HREF längst schon wieder 
LOW ist.

Seht Ihr das ähnlich, oder liege ich falsch?

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

>>Mach das auf keinen Fall! Abkupfern ist extrem motivationskillend

okay.... überredet ;-)

was das Datenblatt angeht kann ich dir nicht ganz folgen. Also 
zunächsteinmal ist es bei mir Seite 12 (wir sprechen aber schon von 
v1.5?)

Wo nimmst du das NAND Gitter her?

Aber abgesehen davon verstehe ich das Timing diagram auch nicht 
wirklich... laut dem wird nämlich auch das n+1 Byte in DI geladen obwohl 
/WE auf high ist....

merkwürdig


>>Hättet Ihr mal schön brav die Postings vom lieben Igel1 gelesen, hättet
>>Ihr den Guide schon vor Wochen kennengelernt:


Okay... sorry das ist mir wirklich durchgegangen... zu meiner 
Verteidigung lief da noch nicht mal das SCCB-Protokoll xD ... und es ist 
fast ein Jahr her... Aber danke nochmal für den Hinweis. Jetzt hab ich 
sie mir abgespeichert :D

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

David D. schrieb:
>>>Mach das auf keinen Fall! Abkupfern ist extrem motivationskillend
>
> okay.... überredet ;-)

Tapfer!

> was das Datenblatt angeht kann ich dir nicht ganz folgen. Also
> zunächsteinmal ist es bei mir Seite 12 (wir sprechen aber schon von
> v1.5?)

Ja, hast recht - hatte versehentlich in meiner älteren Version 
nachgeschaut - das Timing ist aber in Version 1.5 unverändert 
problematisch.

> Wo nimmst du das NAND Gitter her?

Wie weiter oben geschrieben:
> Ich vermute daher eher, dass ich dieses Modul hier habe:
> 
http://www.haoyuelectronics.com/Attachment/OV7670-Module-A/CMOS_FIFO%20schematic.pdf

Dort findest Du einen Baustein SN74LVC1G00:
http://www.ti.com/lit/ds/symlink/sn74lvc1g00.pdf
... und das ist ein NAND-Gatter.

Das Gatter invertiert das HREF-Signal (wenn FIFO_WR = HIGH) und so 
werden nur dann Pixel in das AL422B hineingeschrieben, wenn HREF = HIGH, 
weil dann nämlich \WE=LOW ist.

Damit wird sichergestellt, dass nur die Zeilen-Pixel in den FiFo 
geschrieben werden (... wenn da nicht der in meinem letzten Post 
beschriebene Fehler wäre ...).

> Aber abgesehen davon verstehe ich das Timingdiagram auch nicht
> wirklich... laut dem wird nämlich auch das n+1 Byte in DI geladen obwohl
> /WE auf high ist....

Das könnte sich so erklären: evtl. ist das "Write Register" (siehe 
interner Aufbau des AL422B) ein flankengetriggertes Flip-Flop, welches 
die Daten bei steigender Flanke übernimmt. Danach werden sie im nächsten 
Schritt ins DRAM geschrieben.

Einmal im Flip-Flop geht die Sache ihren sozialistischen Gang.

Trotzdem passt das alles nicht so recht ins Bild.

> merkwürdig

Richtig. Einzige Erklärung,die uns retten könnte: Das Diagramm "AL422-06 
Write Cycle Timing (Write Enable)" ist falsch und es ist darin in der 
untersten Zeile DI7~0 nicht das Datenbyte, was außen am FiFo anliegt 
abgebildet, sondern dasjenige, welches intern ins DRAM geschrieben wird.

Aber vielleicht haben Michael oder Dieter noch eine bessere Idee ...

Im Anhang nochmals zum besseren Vergleich die zwei Timing im Vergleich.
Der Frowny zeigt auf, wo eigentlich das erste Datenbyte nach einem Write 
Enable vom AL422B geschnappt werden müsste.

Viele Grüße
Igel1

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Unser Problem: das "Horizontal Timing" der OV7670 Kamera besagt, dass
> nach einem Ansteigen von HREF bereits die erste Taktflanke von PCLK das
> erste Pixel-Byte überträgt.

ich habe jetzt nicht in das Datenblatt des AL422B geschaut und auch die 
Schaltung nicht genauer angeschaut.
Wie wird die OV7670 für den FiFo-Betrieb initialisiert?
Wenn z.B. Bit 5 in COM10 gesetzt ist wird kein PCLK während des HSYNC 
ausgegeben.
Ich komme erst heute nachmittag dazu, da mal reinzuschauen.

PS: doch kurz reingechaut: AL422 übernimmt mit der steigenden Flanke von 
WCK die Daten wenn /WE aktiv ist. Die Kamera hat das Byte mit der 
steigenden Flanke von PCLK gültig, die kommt nach Ende HREF. Sieht für 
mich im Moment glaubwürdig aus?

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:

> Wie wird die OV7670 für den FiFo-Betrieb initialisiert?
> Wenn z.B. Bit 5 in COM10 gesetzt ist wird kein PCLK während des HSYNC
> ausgegeben.

Das ist meiner Meinung nach unbedingt zu vermeiden:
Die Clocks sollten auf beiden Seiten durchlaufen, vgl. Datenblatt Absatz 
8.3.1. "It is recommended that the WCK and RCK are kept running at least 
1MHz at all times."

Und wenn wir schon den RCK-Takt brutal unter 1MHz runterdrücken, um das 
Bild in Ruhe auslesen zu können, dann sollte der WCK-Takt zumindest auf 
>1MHz durchlaufen, denn angeblich wird ja (lt. Datenblatt) der 
schnellere der beiden Takte zum DRAM-refresh verwendet (... glauben wir 
das mal ...), siehe Kapitel 8.3.1.: "The faster one of WCK and RCK is 
used as the DRAM refresh timing clock and has to be kept free running."

> Ich komme erst heute nachmittag dazu, da mal reinzuschauen.

Du bist entschuldigt :-)

> PS: doch kurz reingechaut: AL422 übernimmt mit der steigenden Flanke von
> WCK die Daten wenn /WE aktiv ist.

Ja schon, aber laut dem Bild in meinem letzten Posting übernimmt der 
AL422B   nach einem /WE=LOW (also nach einem Aktivieren der 
Schreibfähigkeit) erst mit der 2. steigenden Flanke wieder Daten vom 
Bus! Das ist genau der Knackpunkt. Schaut Euch mein Bild aus dem letzten 
Posting bitte einmal genau an.

> Die Kamera hat das Byte mit der
> steigenden Flanke von PCLK gültig, die kommt nach Ende HREF.

Richtig - die Kamera wirft somit das 1. Byte raus, bevor der AL422B es 
aufschnappen kann, denn der liest seinerseits die Daten erst ab er 2. 
steigenden Flanke ein.

> Sieht für
> mich im Moment glaubwürdig aus?

... für mich nicht - aber ich lasse mich gerne von Euch vom Gegenteil 
überzeugen ...

Ich kann nur hoffen, das das Datenblatt in diesem Punkt falsch ist, denn 
für diese Einlese-Verzögerung um einen WCK-Takt findet sich meiner 
Ansicht nach keine echte Begründung, die sich aus internen Aufbau des 
Chips ableiten ließe (vgl. "AL422-03 Block Diagram" auf S. 14 des 
Datenblatts).

Viele Grüße

Igel1

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Hi Leute,

so, hier der erste Versuch ein komplettes Bild in den AL422B zu 
schieben.
Wenn Ihr Lust habt, so wäre es super nett, wenn Ihr einmal meinen 
Pseudo-Code sichten und ggf. kommentieren könntet:
1
Reading an image frame from OV7670 into AL422B fifo:
2
-----------------------------------------------------
3
4
FIFO_WCK = >=1MHz clock // make sure AL422B FiFo is clocked by camera's PCLK with at least 1MHz
5
6
delay(1ms)              // see AL422 datasheet: do wait 0.1ms after power up before applying reset
7
8
FIFO_WR = HIGH          // enable chips WE (and keep it enabled all time till end of frame-grabbing
9
FIFO_WRST = HIGH        // disable write reset
10
                        // at this point, pixels already get shifted into AL422B, but we don't care for it
11
                        // because we will reset the FiFo's write address pointer later on.
12
13
while(!VSYNC) {}        // VSYNC=LOW: wait for end of current frame
14
while(VSYNC) {}         // VSYNC=HIGH: vsync=high marks end of old frame
15
16
// new frame starts here
17
FIFO_WRST = LOW         // reset AL422B write addr pointer by driving /WRST to LOW for >= 2 cycles (1 cycle = 1 PCLK-cycle)
18
delay(1ms)              // and < 17x Tline  =>  driving /WRST to LOW for 1ms should be okay
19
FIFO_WRST = HIGH        // reset write address pointer of AL422B
20
21
while(!VSYNC){}         // read data while VSYNC=LOW
22
23
// new frame ends here
24
FIFO_WR = LOW           // disable chips WE when end of frame is reached (VSYNC goes HIGH) 
25
                        // and keep it disabled since we are done with reading one frame.

Das Schöne am Ganzen: es ist wirklich keine echt zeitkritische Aktion 
enthalten - das ATmega sollte das also genauso locker bewerkstelligen 
können.

Viele Grüße

Igel1

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

... und weil's so schön war, hier direkt der Pseudo-Code für das 
Auslesen des AL422B FiFo:
1
Reading an image frame out of AL422B fifo:
2
-------------------------------------------
3
4
FIFO_RCK = 10kHz clock  // feed FiFo with clock signal (using TIM1 on STM32F4)
5
                        // frequency can be adjusted according to UART-baudrate (e.g. 115200 baud) 
6
                        // and UART-mode (e.g. 8N1 => 1 Start-Bit + 8 Data-Bits + 1 Stop-Bit = 10 Bits)
7
                        // If you use 115200 baud, you can transfer 115200baud/10bit/Byte = 11520 Bytes/s
8
                        // So FIFO_RCK can be at most 11.520 KHz in this example
9
                        // See: http://www.netzmafia.de/skripten/hardware/PC-Schnittstellen/seriell.html
10
11
delay(1ms)              // see AL422 datasheet: do wait 0.1ms after power up before applying reset
12
13
FIFO_RRST = LOW         // reset AL422B read addr pointer by driving /RRST to LOW
14
delay(1ms)
15
16
// pull /RRST high right after a falling RCK shoulder
17
while(!FIFO_RCK){}      // wait for a possible high shoulder to end
18
while(FIFO_RCK){}       // wait for FIFO_RCK to become low
19
FIFO_RRST = HIGH        // read addr pointer starts upcounting here (at very rising FIFO_RCK-edge)
20
21
// read out image from AL422B FiFo
22
for(noOfPixels x bytes per pixel){    // repeat for "number of bytes in an image frame" times
23
  while(!FIFO_RCK)      // wait during low FIFO_RCK-shoulder
24
  get FIFO_DATA         // grab data right after rising edge of  FIFO_RCK
25
  UARTsend(FIFO_DATA)   // send data
26
  while(FIFO_RCK)       // wait till end of high shoulder of FIFO_RCK
27
}

Auch hier würde ich mich sehr freuen, wenn Ihr einen intensiven Blick 
darauf werfen könntet und mir Feedback gebt.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Auch hier würde ich mich sehr freuen, wenn Ihr einen intensiven Blick
> darauf werfen könntet und mir Feedback gebt.

werde ich sicher machen, aber erst irgendwann nachher. Ich löte erstmal 
meinen Lochrasterträger mit Buchsenleisten zusammen, dann kann ich 
stabil zwischen mit und ohne FiFo wechseln und im Zweifel auch einfach 
mal was messen ohne daß der Drahtverhau auseinanderfällt.
Dann kann ich Deinen Ansatz auch einfach mal in den obigen Source 
reintippen, OV7670 Init ist dann dort übersichtlich genug und der TWI- 
und UART-Kram ist ja auch lauffähig vrohanden.

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Lesenswert?

Hi,

ich bin der Leserei jetzt überdrüssig und habe mich entschieden:

Ich werde erstmal mit QQVGA beginnen. Da kann ich mit 2 MBaud (getestet 
und für gut befunden) im Idealfall (errechnet) 3 - 4 FPS erzielen und 
brauche nicht mal Interleave.

Arbeite gerade an einem kleinen Python-Script. Mal schauen, wie schnell 
PIL's Routinen zum Pixel setzen sind :-)

Übrigens werde ich mit 16 MHz Takt für die Kamera arbeiten. Spielt 
sowieso keine Rolle - warum sollte ich dann außerhalb der Spezifikation 
bleiben ... . So aktiviere ich PINB0 per Fuse und fertig.

VG
Dieter

von Andreas S. (igel1)


Lesenswert?

Hi Leute,

habe den Pseudocode inzwischen in "echten" Code verwandelt.

Gerade zum ersten Mal das Programm laufen lassen.

War leider ein Schuss in den Ofen: zeigt nur weisse Mäuse vor weissem 
Hintergrund an.

Jetzt wird's interessant, denn debuggen mit einem Logicanalyzer ohne 
Zugriff auf die Pins der Kamera (es sind ja nur HREF und VSYNC nach 
draussen geführt) wird vermutlich schwierig werden.

Das wird sicherlich langwierig werden (es sei denn, Ihr findet direkt 
vorab einen dicken Bock im Pseudocode).

Viele Grüße

Andreas

von David D. (saturi)


Lesenswert?

Guten Morgen/Mahlzeit zusammen.
@Igel ich werde mir deine beiden Pseudocodes nachher, wenn ich zuhause 
bin einmal anschauen und mit meinem bisherigen vorgehen vergleichen. Bis 
nachher :)

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> War leider ein Schuss in den Ofen: zeigt nur weisse Mäuse vor weissem
> Hintergrund an.
naja, besser als garkein Bild... ;)

Ich bin mit meinem Träger löten gestern auch nicht allzuweit gekommen, 
hoffentlich wird es nachher nochwas.
Puh... Hatte ich noch garnicht nachgeschaut, aber die Eingäge des AL422B 
sind ja zum Glück 5V-tolerant...

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Sooo... meine bessere hälfte hatte doch noch was zu tun, wodurch ich 
wenigstens die Möglichkeit hatte die Write Sequenz schon einmal 
durchzuschauen:

>FIFO_WCK = >=1MHz clock // make sure AL422B FiFo is clocked by camera's >PCLK 
with at least 1MHz
So far so good... Wenn ich bei mir messe, liegen ungefähr die 12 Mhz vom 
verbauen Oszillator an.

>delay(1ms)              // see AL422 datasheet: do wait 0.1ms after power >up 
before applying reset
jep... aber jetzt steht dort: "Apply /WRST and /RRST 0.1ms after power 
on" Für mich hieß apply bei einem low-active signal auf Low ziehen.
Bin ich hier falsch? also ich habe an dieser Stelle dann
1
//Initialization From Datasheet: "Apply/WRST and //RRST 0.1ms after power on
2
  OV_WRST_PORT &= ~(1<<OV_WRST_PinNo);
3
  OV_RRST_PORT &= ~(1<<OV_RRST_PinNo);
womit ich beide Pins auf Low Signal ziehe.

bei mir pulse ich danach nohc zweimal den RCK Pin um den Read Pointer 
wirklich auf 0 zurückzuholen. Keine Ahnung ob das notwendig ist... Na 
gut, weiter im Text:



>FIFO_WR = HIGH          // enable chips WE (and keep it enabled all time >till 
end of frame-grabbing
>FIFO_WRST = HIGH        // disable write reset
>                       // at this point, pixels already get shifted into >AL422B, 
but we don't care for it
>                        // because we will reset the FiFo's write address 
>pointer later on.
Ist WE nicht ebenfalls Low-active? also eigentlich /WE demnach würdest 
du es deaktivieren und dann wird garnichts geschrieben.


>while(!VSYNC) {}        // VSYNC=LOW: wait for end of current frame
>while(VSYNC) {}         // VSYNC=HIGH: vsync=high marks end of old frame
while(VSYNC) {}... sehr gut... das hatte ich bis jetzt noch nicht, macht 
aber durchaus Sinn

>// new frame starts here
>FIFO_WRST = LOW         // reset AL422B write addr pointer by >driving /WRST to 
LOW for >= 2 cycles (1 cycle = 1 PCLK-cycle)
>delay(1ms)              // and < 17x Tline  =>  driving /WRST to LOW for >1ms 
should be okay
was meinst du genau mit diesem Kommentar?: < 17x Tline  =>
Ich habe da nur ein delay von 6 us drin... frage mich grade wie ich 
dadrauf gekommen bin

>FIFO_WRST = HIGH        // reset write address pointer of AL422B
>
>while(!VSYNC){}         // read data while VSYNC=LOW
>
>// new frame ends here
>FIFO_WR = LOW           // disable chips WE when end of frame is reached (VSYNC 
goes HIGH)
>                       // and keep it disabled since we are done with >reading 
one frame.
FIFO_WR = LOW  --> siehe oben, ich meine Low-active

Die Read Sequenz dann später :)


@Michael, wie willst du es schaffen, dass beide Kameras mit dem Board 
kompatibel sind? ich habe auch beide Versionen hier, aber die Pins 
weichen eben schon voneinander ab in den beiden Modellen? Oder willst du 
das aufwändig über jumper lösen?

Bis später,
David

EDIT: irgendwie hats die Zitate verhauen und ich bekomme es auch nicht 
korriegiert... Ich hoffe ihr könnt es dennnoch inhaltlich trennen ;-)

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> @Michael, wie willst du es schaffen, dass beide Kameras mit dem Board
> kompatibel sind? ich habe auch beide Versionen hier, aber die Pins
> weichen eben schon voneinander ab in den beiden Modellen? Oder willst du
> das aufwändig über jumper lösen?

Ich habe 2 passende Buchsenleisten parallel verlötet, es wird natürlich 
nur jeweils eine Kamara gesteckt werden.
Die "identischen" Pins verbinde ich direkt, SDA/SCl/XCLK über 
Levelshifter, D0...D7 kommen auch zusammen, ist ja egal, ob die Daten 
vom OV7670 oder dem AL422B kommen. PCLK und XCLK kommen parallel auf 2 
Pins des AL422B, dann bleiben von dem noch 4 Signale, die ich auf freie 
Pins verteilen muß.
Prinzipiell sind ja D9...D13 (PB1...PB5) noch verfügbar, außer der 
Kamera kommt an des "Spielbrett" nicht ran, bei OB7670 ohne FiFo und 
OV2640 wäre dann selbst SPI ja noch verfügbar.
Der Rest ist ja dann Sache der Definitionen in der jeweiligen Software.
Prinzipiell würde auch mein OV2640 Modul noch auch dem Platz der OV7670 
passen, die PinOuts sind identisch. Dann kann ich zumindest die Hardware 
mal in die Ecke legen, wenn ich keine Zeit dafür habe, ohne das was 
auseinanderfällt...

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Sooo... meine bessere hälfte hatte doch noch was zu tun, wodurch ich
> wenigstens die Möglichkeit hatte die Write Sequenz schon einmal
> durchzuschauen:

Dankeschön - sehr nett von Dir.

>FIFO_WCK = >=1MHz clock // make sure AL422B FiFo is clocked by camera's >PCLK
> with at least 1MHz
> So far so good... Wenn ich bei mir messe, liegen ungefähr die 12 Mhz vom
> verbauen Oszillator an.

Dann passt ja alles.

>
>>delay(1ms)              // see AL422 datasheet: do wait 0.1ms after power >up
> before applying reset
> jep... aber jetzt steht dort: "Apply /WRST and /RRST 0.1ms after power
> on" Für mich hieß apply bei einem low-active signal auf Low ziehen.
> Bin ich hier falsch?

JA. Ich glaube, Du hast da einen Denkfehler gemacht:
Schau Dir das Nand Gatter im Schaltplan genau an:
Damit wird \WE nur dann auf LOW gezogen, wenn
FiFo_WR = HIGH AND HREF = HIGH ist.


> also ich habe an dieser Stelle dann
>
1
//Initialization From Datasheet: "Apply/WRST and //RRST 0.1ms after 
2
> power on
3
>   OV_WRST_PORT &= ~(1<<OV_WRST_PinNo);
4
>   OV_RRST_PORT &= ~(1<<OV_RRST_PinNo);
> womit ich beide Pins auf Low Signal ziehe.

Okay - da könnte etwas dran sein.
Muss ich mir nochmals überlegen, ob ich das genauso machen werde.

>
> bei mir pulse ich danach nohc zweimal den RCK Pin um den Read Pointer
> wirklich auf 0 zurückzuholen. Keine Ahnung ob das notwendig ist... Na
> gut, weiter im Text:
>
>
>
>>FIFO_WR = HIGH          // enable chips WE (and keep it enabled all time >till
> end of frame-grabbing
>>FIFO_WRST = HIGH        // disable write reset
>>                       // at this point, pixels already get shifted into 
>AL422B,
> but we don't care for it
>>                        // because we will reset the FiFo's write address
>>pointer later on.
> Ist WE nicht ebenfalls Low-active? also eigentlich /WE demnach würdest
> du es deaktivieren und dann wird garnichts geschrieben.

Siehe Anmerkungen von mir weiter oben.

>
>
>>while(!VSYNC) {}        // VSYNC=LOW: wait for end of current frame
>>while(VSYNC) {}         // VSYNC=HIGH: vsync=high marks end of old frame
> while(VSYNC) {}... sehr gut... das hatte ich bis jetzt noch nicht, macht
> aber durchaus Sinn
>

>>// new frame starts here
>>FIFO_WRST = LOW         // reset AL422B write addr pointer by >driving /WRST to
> LOW for >= 2 cycles (1 cycle = 1 PCLK-cycle)
>>delay(1ms)              // and < 17x Tline  =>  driving /WRST to LOW for >1ms
> should be okay
> was meinst du genau mit diesem Kommentar?: < 17x Tline  =>

Der Write Reset muss unbedingt disabled werden, bevor HREF auf HIGH 
geht, also bevor die Zeilenübertragung beginnt.

> Ich habe da nur ein delay von 6 us drin... frage mich grade wie ich
> dadrauf gekommen bin
>
>>FIFO_WRST = HIGH        // reset write address pointer of AL422B
>>
>>while(!VSYNC){}         // read data while VSYNC=LOW
>>
>>// new frame ends here
>>FIFO_WR = LOW           // disable chips WE when end of frame is reached (VSYNC
> goes HIGH)
>>                       // and keep it disabled since we are done with >reading
> one frame.
> FIFO_WR = LOW  --> siehe oben, ich meine Low-active
>
> Die Read Sequenz dann später :)
>

Danke!

>
> @Michael, wie willst du es schaffen, dass beide Kameras mit dem Board
> kompatibel sind? ich habe auch beide Versionen hier, aber die Pins
> weichen eben schon voneinander ab in den beiden Modellen? Oder willst du
> das aufwändig über jumper lösen?
>
> Bis später,
> David
>
> EDIT: irgendwie hats die Zitate verhauen und ich bekomme es auch nicht
> korriegiert... Ich hoffe ihr könnt es dennnoch inhaltlich trennen ;-)

Macht nix.

Viele Grüße

Igel1

: Bearbeitet durch User
von David D. (saturi)


Lesenswert?

Lieber Igel....
ich bitte vielmals um Verzeiung :D ... Ich sollte mir wohl definitiv 
mehr Zeit für eure Beiträge nehmen. Das fällt mir nur immer sehr schwer, 
weil ich voller Tatendrang stecke und meine Zeit sooo begrenzt ist... 
Aber damit kämpfen wir ja alle...
Da du so hartnäckig an deinem NAND Gatter festgehalten hast und ich es 
zugegebener maßen bis grade immer noch nicht verstanden hatte, habe ich 
jetzt zwei Stunden investiert, um zum ersten meine Verkabelung zu 
überprüfen (seit der nächtlichen Umbauaktion geht leider garnix mehr :D) 
und mich mit meinem Modul auseinander zu setzen.
Ich habe beide Schematics die ich zum Modul hatte überprüft und bin zu 
dem Entschluss gekommen, dass die beide nicht zu meinem Modul gehören. 
Dann habe ich brav in diesem Chatverlauf nach deiner verlinkten 
schematics gesucht und zack... ja passt auch für mich, wie die Faust 
aufs Auge. Aber wo ist die LED?! ... jap einfach nicht aufgelötet. aber 
Die Pads sind da. nach der Schematics scheint es wohl einfach eine 
unregelbare beleuchtungs LED und keine Status LED zu sein.

Durch das NAND-Gatter wird mir jetzt auch klar, warum auf dem Board WR 
und nicht WE steht.
Wir halten also Fest: /WE bleibt weiterhin Low-Active wie im Datenblatt 
angegeben. Dazu ergibt sich folgende Logische Beziehung:

WE = ~(WR^HREF)  --> ~WE = /WE = (WR^HREF)

Damit muss ich mir schonmal keine Gedanken machen, dass während des HREF 
plötzlich was unerwartes in den Fifo geschrieben wird.


Das war aufjedenfall eine sehr Wertvolle Lehrstunde für mich und ich 
werde meinen Code nochmal dementsprechend überarbeiten.


Gruß David.


PS: Read Sequenz schaue ich mir dann jetzt gleich mal an

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Aber wo ist die LED?! ... jap einfach nicht aufgelötet. aber
> Die Pads sind da. nach der Schematics scheint es wohl einfach eine
> unregelbare beleuchtungs LED und keine Status LED zu sein.

LED ist bei mir auch nicht bestückt, mit 1k Vorwiderstand laut 
Schaltplan wohl offenbar nur als Spannungsanzeige gedacht gewesen.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Damit muss ich mir schonmal keine Gedanken machen, dass während des HREF
> plötzlich was unerwartes in den Fifo geschrieben wird

Das hast Du messerscharf erkannt!

Ich finde überhaupt, dass Du Dich sehr konsequent und zielgerichtet 
einliest und alles recht fix kapierst.

Du brauchst Dein Licht nur nicht so unter den Scheffel zu stellen.
Bescheidenheit ist eine Zier, doch es besser lebt man ohne ihr.

Habe ich das weiter oben richtig verstanden, dass so ein heller Kopf wie 
Du sich keinen LogicAnalyzer für 100 Mäuse leisten kann? Wenn das 
stimmt, so denke nochmals über Deinen aktuellen Arbeitgeber nach.

Anders ist die Situation natürlich, wenn Du und Dein Liebste gerade 
Drillinge bekommen oder ein Haus gebaut habt ...

Viele Grüße

Igel1

von Dieter F. (Gast)


Angehängte Dateien:

Lesenswert?

Hi,

damit ihr mal ein wenig Lachen könnt :-)

Immerhin bekomme ich meine Daten nach Python übertragen. Es soll eine 
Color-Bar sein (Register 0x12 Wert 0x06) :-). Mit viel Phantasie erkennt 
man das sogar ...

Python kommt offensichtlich nicht mit und "ruckelt Verschieber" rein.

Die Daten kommen sauber an (mit HTERM geprüft) - nur die 
Python-Eingangsverarbeitung hakelt scheinbar etwas.

Meine Register-Einstellungen:
1
  //Reset Register
2
  write_register_i2c(0x12, 0x80);
3
   _delay_ms(100);
4
  
5
  //Pixel-Clock = Input-Clock/2  (!! + Register 0x3e und 0x73)
6
  write_register_i2c(0x11, 0x02);
7
  
8
  //Home - Steuerung Belichtung
9
  write_register_i2c(0x13, 0xe5); //AWB off
10
  write_register_i2c(0x01, 0x96);
11
  write_register_i2c(0x02, 0x40);
12
  
13
  //Saturation 0
14
  write_register_i2c(0x4f, 0x80);
15
  write_register_i2c(0x50, 0x80);
16
  write_register_i2c(0x51, 0x00);
17
  write_register_i2c(0x52, 0x22);
18
  write_register_i2c(0x53, 0x5e);
19
  write_register_i2c(0x54, 0x80);
20
  write_register_i2c(0x58, 0x9e);
21
  
22
  //Brightness 0
23
  write_register_i2c(0x55, 0x00);
24
  
25
  //QQVGA
26
//  write_register_i2c(0x12, 0x04);    //"normale" Funktion RGB
27
  write_register_i2c(0x12, 0x06);    //"normale" Funktion RGB - + Color Bar
28
  write_register_i2c(0x0C, 0x04);    //DCW enable
29
  write_register_i2c(0x3E, 0x1A);    //DCW and scaling PCLK / 4
30
  write_register_i2c(0x70, 0x3A);    //Horizontaler Skalierungs-Faktor
31
  write_register_i2c(0x71, 0x35);    //Vertikaler Skalierungs-Faktor
32
  write_register_i2c(0x72, 0x22);    //DCW control parameter
33
  write_register_i2c(0x73, 0xF2);    //Clock divider für DSP / 4
34
  write_register_i2c(0xA2, 0x02);    //Histogramm ...
35
  write_register_i2c(0x56, 0x40);    //Kontrast 0

Das Timing auf Kamera-Seite sieht (aus meiner Sicht) hingegen gut aus:

Gelb    -> VSYNC
Violett -> HREF
Blau    -> TX

(Ich sende den String "Start" bei jedem neuen Bild - daher der "blaue 
Ausreisser")

QQVGA hat den Vorteil, dass nur jeder 4. HREF-Slot (im Vergleich zu VGA) 
Daten enthält/übermittelt. Die "Totzeit" nutze ich für die serielle 
Übertragung.

VG
Dieter

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

ok, Löten habe ich noch geschafft, läuft auf dem Arduino UNO, aber nicht 
sinnvoll... Ein halbwegs fehlerfreies Bild bekomme ich nur manchmal.
Morgen hänge ich mal den LA ran und schaue mir das erstmal an, ob 
erkennbar ist, wo es klemmt.
Zumindest kann ich jetzt wahlweise auch mal mit der FiFo-Version 
rumspielen.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Hi Leute,

na das sieht bei Dieter doch schon ganz "interessant" aus.
Und Michael hat sich ein Bienchen für sauberes Löten verdient!

Ich selber debugge mich so durch die Gegend.

Bislang gefunden:

- Hatte vergessen die Ports-Initialisierungsfunktion aufzurufen.
  Ergo waren alle Steuerein- und Ausgänge hochohmig und es passierte
  gar nichts.

- Sodann hatte ich vergessen FIFO_OE auf LOW zu setzen: folglich
  waren die Datenausgänge des AL422B ebenfalls hochohmig und nichts
  kam heraus.

Ansteuerung und Timings sehen mir inzwischen ganz passabel aus.
Inzwischen habe ich graue Mäuse auf grauem Hintergrund - supi ...

Viele Grüße

Igel1

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

Andreas S. schrieb:
> Und Michael hat sich ein Bienchen für sauberes Löten verdient!

naja, mal schauen, ob Du bei Deinem Bienchen bleibst... ;-)

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> naja, mal schauen, ob Du bei Deinem Bienchen bleibst... ;-)

Okay - ersetze "Bienchen" bitte durch "dicken Brummer".
Mama mia ...

Viele Grüße

Igel1

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

Verflixte Hacke, wo liegt der Fehler?

Bitte schaut Euch mal die Ansteuerung des Moduls für den Einlesezyklus 
an:
Mit dieser Ansteuerung will ich ein Bild von der Kamera in den FiFo 
schieben.

Seht Ihr irgendwelche Fehler?

Viele Grüße

Igel1

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Aha - habe soeben einmal die Register mit einer Zahlen-Kombination aus 
dem Internet gefüllt.  Es erscheinen erste, schemenhafte Bilder.

Alles sehr bleich.
Ist scheinbar noch ein längerer Weg bis zum ersten echten, scharfen 
Bild.

Gute Nacht

Igel1

von David D. (saturi)


Lesenswert?

Hey!  Na das hört sich doch schonmal gut an! Hast du an deinen read 
weite Funktionen was ändern müssen? Bei mir bleibt es leider dabei, dass 
ich nicht mal zweimal das gleiche auslesen kann -,-

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Hey!  Na das hört sich doch schonmal gut an! Hast du an deinen read
> weite Funktionen was ändern müssen? Bei mir bleibt es leider dabei, dass
> ich nicht mal zweimal das gleiche auslesen kann -,-

Bitte in meinem Falle nicht den Tag vor dem Abend loben ...
Es ist noch weit, weit entfernt davon, ein Bild zu ergeben.
Aktuell kann ich nur sagen: es kommt irgendwas vorne rein,
was scheinbar irgendetwas mit dem zu tun hat, was hinten rauskommt.
Nicht mehr und nicht weniger.

Was Dein Problem angeht, so sehe ich zwei mögliche/wahrscheinliche
Ursachen:

1.)  Du hältst das Schreiben des OV7670 in den FiFo nicht an.
     Will sagen: prüfe einmal, ob Du nach dem Schreiben (also
     nach dem Auslesen des Bildes) das Signal FIFO_WE auf LOW
     legst (und dort für die gesamte Zeit des späteren
     FIFO-Auslesens auch auf LOW belässt). Ein LogicAnalyzer
     ist in diesem Zs.hang Gold wert.

2.)  Du machst evtl. keinen Address Pointer Reset, bevor Du
     den FiFo ausliest:
     Prüfe, ob Du wirklich vor jedem Auslesen FIFO_RRST auf
     LOW legst und sofort, nachdem Du FIFO_RRST auf HIGH
     ziehst mit der ersten steigenden RCK-Flanke Deine Daten
     ausliest.

Mehr fällt mir aktuell auch nicht dazu ein.

Viele Grüße

Igel1

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

... man muss nur das richtige "Model" nehmen, schon erkennt man erste, 
zarte Erfolgspflänzchen ...

1. Photo:  Original
2. Photo:  ... na ratet mal ...

Fazit: es muss noch weiter am Code gestrickt werden.

Irgendetwas mit der Horizontal- und der Vertikalauflösung stimmt da noch 
nicht. Auch scheint mir das Bild noch furchtbar blass ...

Schau'n wir mal ...

Viele Grüße

Igel1

von Dieter F. (Gast)


Lesenswert?

Andreas S. schrieb:
> Fazit: es muss noch weiter am Code gestrickt werden.

Hi,

nein - das ist  meiner Meinung nach eine reine Parameter-Einstellung der 
Kamera.

Ich bekomme auch herrlich bunte Bilder, welche mit viel Phantasie das 
abbilden, was ich sehe. Da kommen dann bekannte und "magic"-Parameter 
ins Spiel. An dieser Stelle klinke ich mich aus. Es bringt mir überhaupt 
nichts, wenn ich irgendwelche Register-Einstellungen (ohne den 
Hintergrund zu kennen) nachstelle. Ich kenne den "Implementation Guide" 
und den "Software Guide" zur Kamera - aber beides ist unzureichend.

Da arbeite ich lieber mit Liniensensoren, bei denen ich ich die 
Umsetzung (Helligkeit etc.) selbst steuern muss.

Ich habe mal mit dem Gedanken gespielt, die OV7670 als Sensor für eine 
Spektralanalyse einzusetzen - das habe ich hiermit verworfen (also ein 
erfolgreicher POC :-) ).

Der ATMega328x ist schlicht nicht ausreichend, um mit diesem 
Kamera-Modul (egal ob mit oder ohne Fifo) umzugehen. Nur für ein 
Standbild ist der Fifo sinnvoll, da das Kamerabild dann für die weitere 
Verarbeitung  (VGA etc.) zwischengespeichert wird. Aber wozu?

Der ATMega328x ist schlicht unzureichend, um weitere Verarbeitung(en) 
durchzuführen. Auch ein ATXMega (trotz DMA) wird da überfordert sein.

Es war nett, das mal auszuprobieren - aber es macht aus meiner Sicht 
keinen Sinn, weiter zu machen. Irgendwelche Einstellungen nachzumachen 
(oder zu kopieren) macht für mich keinen Sinn. Die Kamera / die 
Einstellungen sind so schlecht dokumentiert, dass ich da nicht 
weitermachen möchte.

Viel Spass noch allen und viele Grüße
Dieter

von Michael U. (amiga)


Lesenswert?

Hallo,

Dieter F. schrieb:
> Der ATMega328x ist schlicht nicht ausreichend, um mit diesem
> Kamera-Modul (egal ob mit oder ohne Fifo) umzugehen. Nur für ein
> Standbild ist der Fifo sinnvoll, da das Kamerabild dann für die weitere
> Verarbeitung  (VGA etc.) zwischengespeichert wird. Aber wozu?

ein "wozu" gibt es bei der Geschichte für mich ohnehin nicht.
Der Kamera-Sensor ist einer der ersten, die es für Handy-Kameras 
überhaupt gab. von dieser Seite sind also ohnehin keine Wunder zu 
erwarten.
Ich hatte am Anfang schon mal erwaähnt, daß ich die DC3840 auch hier 
habe, die dürfte den gleichen Sensor drin haben. Die gehörte zu 
irgendeinem Siemens-Handy als Aufsteckkamera und wurde um 2007 für 1,-€ 
verramscht.
https://www.ulrichradig.de/home/index.php/projekte/uC-kamera
Unterschied ist, daß der benutzte IC OV528 einen JPEG-Encoder enthält 
und die Daten im Original mit 921kBaud seriell rausschickt.
Sowas als Standbild kann man mit einem Mega328 mit der OV7670 bermitlich 
auch schaffen. Nicht mehr und nicht weniger...
Ich hatte die DC3840 inzwischen mal erfolgreich an einen ESP8266 
gehängt, der mir auf zum Webbrowser auch ein "Foto" in 640x480 schickt.
Dauert, wie auch damals am Mega32 mit ENC28J60 als LAN-Interface, 
etliche Sekunden bis das Bild komplett da ist.
Die OV7670 kommt am Mega328 da schlechter weg, weil sie ohne FiFo keinen 
Snapshot kann und mit FiFo die Pins nicht mehr reichen, um z.B. SPI noch 
nutzen zu können.

Dieter F. schrieb:
> Ich kenne den "Implementation Guide"
> und den "Software Guide" zur Kamera - aber beides ist unzureichend.
Kann ich bis jetzt noch nicht sagen, ich habe mir noch nicht die Zeit 
genommen, da genauer durchzuschauen. Letztlich sind aber wohl die Leute 
damals damit ja auch zurechtgekommen.

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Lesenswert?

Michael U. schrieb:
> Letztlich sind aber wohl die Leute
> damals damit ja auch zurechtgekommen.

Dann schau mal weiter nach - ich bin gespannt.

von Andreas S. (igel1)


Lesenswert?

@Dieter:

Ja, ich bin inzwischen auch mächtig abgenervt von der 
Register-Setting-Lotterie.

Es muss doch irgendwen geben der das optimale Setting herausgefunden hat 
...

Viele Grüße

Igel1

von Dieter F. (Gast)


Lesenswert?

Andreas S. schrieb:
> Es muss doch irgendwen geben der das optimale Setting herausgefunden hat

Moin,

ja - dazu habe ich auch etwas gefunden.

Der Hersteller gibt "Geschäftskunden" - nach "non disclosure agreement" 
- weiterführende Unterlagen ...

Also bleibt nur, bestehende (funktionierende) Einstellungen 
"abzukupfern" oder langwierig zu experimentieren. Beides sind für mich 
keine Alternativen.

VG
Dieter

von Michael U. (amiga)


Lesenswert?

Hallo,

Dieter F. schrieb:
> Der Hersteller gibt "Geschäftskunden" - nach "non disclosure agreement"
> - weiterführende Unterlagen ...
>
> Also bleibt nur, bestehende (funktionierende) Einstellungen
> "abzukupfern" oder langwierig zu experimentieren. Beides sind für mich
> keine Alternativen.

werden diese Module heute wirklich noch irgendwo eingesetzt außer als 
NOS-Restposten für ein paar Hobbybastler? Ich kann es mir eigentlich 
nicht vorstellen. Die Daten passeg zu gut zu den damaligen ersten 
Webcams und da war man froh, wenn der Rechner 320x240 mit 10-15 Fps 
zustande gebracht hat.
Wir haben damals private Videosession mit einem Bekannten in Kanada 
gemacht, mehre als 5-10 Fps kamen da ohnehin nie stabil zustande. 
Lichtempfindlichkeit war sowieso miserabel (für heutige Verhältnisse).

Du hast doch, genau wie ich, schon ein Bild zu sehen bekommen. Die 
Grundsettings für YUV in 320x240 passten also grundsätzlich erstmal.
Sie Einstellungen von Deinem Link und von meinen sind identisch, die 
kompletten Sourcen soweit auch.

Ich kenne mit den OV7670 kaum was fertiges, auch für die OV2760 ist die 
Luft da dünn. Eine QR-Code-Auswertung und einen Roboter, der die Bilder 
mit wenigen Fps schickt, das war es eigentlich auch schon.

Kamera am "Arduino" und die Preise sind meiner Meinung nach die Auslöser 
für den Hype auf die Dinger. Es werden wohl die meisten gekauften 
irgendwo in der Ecke liegen, weil am letztlich keine irgendwie sinnvolle 
Anwendung dafür gefunden hat.
Ein RasPi Zero W mit der RasPi-Cam läßt die Dinger doch sowieso nur alt 
aussehen...

Gruß aus Berlin
Michael

von Michael U. (amiga)


Lesenswert?

Hallo,

ich hoffe ja, daß zumindest David noch im Boot ist...
Ich habe mich jetzt mal mit meinem tollen Träger etwas über die 
FiFo-Version hergemacht. Erste Erkenntnis: Der Arduino UNO mit Mega16U2 
bekommen im Gegensatz zum CH340 1MBit nicht auf die Reihe, mehr als 
230400 geht nicht stabil. Macht es etwas umständlich, mir "mal schnell" 
ein Bild anzeigen zu lassen.
Kamera-Init habe ich erstmal grob nach dem Application-pdf auf die 12MHz 
meiner FiFo-version gesetzt. Grob, weil statt der 15 Fps nur 7,5 Fps von 
der Kamera ausgegeben werden, da stimmt also noch was nicht.
FiFo lesen scheint zu passen und einlesen von der Kamera wohl auch, ich 
bekomme zumindest identsche Bilder geliefert, auf denen ein zufällig im 
Bildfeld befindlicher USB-Stecker mit einem Schild mit Barcodes drauf 
zumindest gut zu identifizieren ist...

Jetzt ist aber erstmal andere Beschäftigung dran.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> Kamera-Init habe ich erstmal grob nach dem Application-pdf auf die 12MHz
> meiner FiFo-version gesetzt.

Verstehe nicht ganz, was Du damit meinst.

> Grob, weil statt der 15 Fps nur 7,5 Fps von
> der Kamera ausgegeben werden, da stimmt also noch was nicht.

Du hast beachtet, dass die Schreiber des Implementation Guide von einem 
Szenario mit 24MHz-Quarz ausgehen, wir aber nur einen 12MHz-Quarz auf 
dem Board sitzen haben?

> FiFo lesen scheint zu passen und einlesen von der Kamera wohl auch, ich
> bekomme zumindest identsche Bilder geliefert, auf denen ein zufällig im
> Bildfeld befindlicher USB-Stecker mit einem Schild mit Barcodes drauf
> zumindest gut zu identifizieren ist...

Welchen Code verwendest Du?
Ich bin allerwärmstens daran interessiert.

Ich selber habe irgendetwas in meinem Code verschlimmbessert und nun 
bekomme ich noch nicht einmal mehr die schwachen Bilder aus dem Teil 
herausgefischt.

Und dabei habe ich sogar noch einen kapitalen Fehler in meiner Software 
gefunden, der erklärt, warum das Bild so unglaublich blass war.
Aber aktuell ist leider "rien ne vas plus" angesagt.

Viele Grüße

Igel1

von Dieter F. (Gast)


Lesenswert?

Andreas S. schrieb:
> Du hast beachtet, dass die Schreiber des Implementation Guide von einem
> Szenario mit 24MHz-Quarz ausgehen, wir aber nur einen 12MHz-Quarz auf
> dem Board sitzen haben?

Ja - spannend. Da geht dann wieder die "Raterei" los - auf die ich (wen 
wundert es) keine Lust habe.

Im tollen "Software Implementation Guide" kommt auch nicht viel mehr.

Das ist eine "Totgeburt", welche mich "Gott-sei-Dank"  nur ca. 10 € (für 
4 Module - wer will noch welche?) gekostet hat.

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Du hast beachtet, dass die Schreiber des Implementation Guide von einem
> Szenario mit 24MHz-Quarz ausgehen, wir aber nur einen 12MHz-Quarz auf
> dem Board sitzen haben?

ich benutze immernoch die Arduino-Software, läßt sich auch problemlos 
auch im alten AVR-Studio 4.18 compilieren.
Ich habe nur das PinOut an die FiFo-Version angepasst und die 
Initialisierung entsprechend geändert. Dann habe ich captureImg() vom 
Auslesen der OV7670 ohne FiFo und rausschicken auf die FiFo-Geschichte 
umgebaut.
Dabei fiel mir dann auf, das wohl der Uno nicht mit 1MBuad klarkommt.
usw. usw.
Die ursprüngliche Sourve betrieb ja die OV7670 ohne FiFo mit 8MHz XCLK 
vom AVR erzeugt und hatte auch die Teiler noch "seltsam" gesetzt.

Die 12MHz Registerwerte stammen aus der OV7670 Applikation.pdf Punkt 3.1 
zweiter Block: 15fps PCLK = 12Mhz
Da bekam ich aber nur 7,5 fps raus.
Jetzt kommt dann Dieters berechtigte Maulerei zum Zuge... ;)
Register CLKRC (0x11) hat einen default von 0x80. Bit 7 ist aber als 
Reserved angegeben. Mit 0x00 teilt der Kram aber definitv durch 2...
Mit 0x80 (default) teilt es durch 1 (teiler aktiv, Teilerwert 0 000 + 1.
bit 7 ist also wohl nicht so "reserved" wie angegeben, eigentlich müßte 
auch 0x40 (kein Vorteiler) richtig sein, muß ich morgen mal testen.
Problem ist im Moment, daß in der Source für die OV7670 ohne FiFo 
ziemlich an den Werten rumgebogen wurde, um bei einer Baudrate von 
1MBaud, also rund 100kB/pro Sekundedie Kamera auch einen PCLK von 100kHz 
zu bekommen und (manchmal) ein Bild zustande zu bringen. Das muß ich 
erstmal auf sinnvolle Werte bringen.
Ich habe zwar noch eine Source mit FiFo gefunden, was der da aber treibt 
ist mir noch völlig unklar...

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Hallo zusammen,
huch hier ist jetzt aber schlechte Stimmung aufgekommen :D

Freut euch doch erstmal, dass es bei euch soweit schon geht...

>Aber aktuell ist leider "rien ne vas plus" angesagt.
:D der ist gut... :D

Zum Thema Oszi, nein ich würde mich aktuell nicht über meinen 
Arbeitgeber beschweren, aber nach einem halben Jahr Arbeiten habe ich 
leider das Zinslose Schuldenkonto bei meinen Eltern noch nicht tilgen 
können, sodass ein Invest von über 100€ fürs "Bastel-Hobby" leider noch 
nicht drin sind...


ABER da viel mir meine Fehlinvestition von 100€ während des Studiums ein 
:D ein USB Oszi DDS140 von Sainsmart incl. Signalgenerator und 
Logicanalyzer...Spart euch die Kommentare... Die Software war/ist 
einfach so verbuggt, dass ein vernünftiger Umgang da leider nicht 
möglich ist. Dann habe ich gestern aber im Netz ein Java-Programm 
gefunden, dass mit dem kompatibel ist und siehe da, ich kann den Logic 
analyzer in Betriebnehmen! (mit einigen abstrichen, aber auf den ersten 
Blick siehts ganz gut aus.)


Ich nutze zwar eine leicht andere Sequenz als du für das schreiben, aber 
in der Theorie sollte es passen.
 Morgen komme ich hoffentlich nochmal dazu etwas auszuprobieren und 
werde euch dann meine Sequenz mal offen legen.

Da ich ja leider auch von Fehlern in meinem Terminal Programm ausgehen 
muss, wäre es super, wenn mir mal jemand erklären könnte, wie ich aus 
dem Bytestream im Terminal (zb. H-Term) ein Bild zauber kann, um zu 
überprüfen, ob mein Terminal auch wirklich das Empfangene anzeigt.

Danke und bis Morgen

David

von Andreas S. (Gast)


Angehängte Dateien:

Lesenswert?

... wird laaangsam ...

VG
Igel1

von Dieter F. (Gast)


Lesenswert?

David D. schrieb:
> huch hier ist jetzt aber schlechte Stimmung aufgekommen :D

Nö - keine schlechte Stimmung - nur etwas Frust, das es nur mit Raterei 
oder Abkupfern weiter geht :-\

Zur Bilderzeugung kann ich gerne mein Python-Scriptchen (primitiv - aber 
funktionierend und leicht anpassbar) zur Verfügung stellen (heute 
Abend).

VG
Dieter

von David D. (saturi)


Lesenswert?

> Zur Bilderzeugung kann ich gerne mein Python-Scriptchen (primitiv - aber
> funktionierend und leicht anpassbar) zur Verfügung stellen (heute
> Abend).
das wäre subba :)

von David D. (saturi)


Angehängte Dateien:

Lesenswert?

Sooo....

1. Möglichkeit:
Ich habe es einfach IMMERNOCHNICHT verstanden...
2. Möglichkeit:
Mein Terminal Programm funktioniert nicht.

Anbei meine Signalverläufe, mit einem mehr oder weniger zuverlässigem 
LogicAnalyzer... Dennoch denke ich, dass die Signalverläufe so sind wie 
dort aufgenommen, weil das auch meiner Programmierlogik entspricht.

Gibt es da irgendetwas falsches dran?
Ich danke euch für jeden Hinweis...

Gruß
David

Edit: OE überigens auf GND

: Bearbeitet durch User
von David D. (saturi)


Angehängte Dateien:

Lesenswert?

Am Terminal scheint es auch nicht zu liegen... wenn ich mit der gleichen 
Funktion ein hochzählendes Byte rausschicke zeigt mir das Terminal im 
yuv format was plausibles an....

Auch wenn der Bildstream dann irgendwann abbricht weil irgendwas nicht 
passt...

wo liegt denn bloß mein Fehler :(

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

@David D.: beim flüchtigen Hinsehen sieht es stimmig aus. Ich habe im 
Moment aber auch irgendwo Probleme mit der Übernahme Kamera -> FiFo, 
habe aber auch etwas rumgespielt und komme wohl erst morgen dazu, 
nachzuschauen.

@ Dieter F.. am Python-Script hätte ich auch Interesse, einlesen mit 
TeraTerm v6.9 und speichern geht zwar zuverlässig, ist aber umständlich, 
Anzeige dann als RAW in Irfanview.

@Andreas S.: würdest Du Deine Registerwerte zu obigem Bild hier 
reinstellen/anhängen?

Ich habe zwischendurch mal nach und nach die Registereinstellungen aus 
dem Applikation-pdf mal etwas für mich kommentiert. Oha, oha, 
genaugenommen macht das Teil mehr als gut ist. ;) AGC, AWB, AEC, 
DeNoise, Colormatrix, Linsenkorrektur usw. usw. Sagt mir grundsätzlich 
zwar fast alles was, aber da kann und muß man sich an vielen Stellen auf 
die Herstellerwerte verlassen.
Ich denke auch, daß damals, als die Dinger aktuell ware, Firmen, die 
Stückzahlen für z.B. eine Webcam beteltt haben, einfach sagen konnen, 
das sie passende Initwerte für die Sensor-Charge und Optik xy dazu haben 
wollen und die auch bekamen.

Ich hänge das mal hier an, ist das default-array für die verlinkten 
Arduino-Sourcen.

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Angehängte Dateien:

Lesenswert?

David D. schrieb:
> das wäre subba :)

Auf eigene Gefahr ... :-)

Das Script schreibt halt jede Menge Bilder in den aufrufenden Pfad ...

von Michael U. (amiga)


Lesenswert?

Hallo,

Dieter F. schrieb:
> Auf eigene Gefahr ... :-)

Danke, ich liebe die Gefahr. ;-)

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Hui - hier hat sich wieder viel getan.

Fangen wir mit David an:

Schön, dass Dein LA nun funktioniert!  Und sehr löblich,
den Kredit an Deine Eltern zurückzuzahlen und dafür auf
Hobby-Equipment zu verzichten - scheinst ein feiner Kerl zu sein.

Was Deine Signale angeht, so sehen die gut aus (wenn man es
riskieren möchte, entgegen dem AL422B-Datenblatt den RCK-Takt
nicht durchlaufen zu lassen).


Und nun zu Michael:

> würdest Du Deine Registerwerte zu obigem Bild hier reinstellen/anhängen?

Aber gerne:
1
static unsigned char OV7670_QVGA[][2]=
2
{
3
  0x12, 0x80,
4
5
  0x11, 0x01,         // see Implementation Guide "30 fps QVGA YUV mode"
6
  0x12, 0x10,         // original: YUV422 = 0x00;
7
  0x40, 0xD0,         // original: not set
8
  0x0C, 0x04,
9
  0x3E, 0x19,
10
  0x70, 0x3A,
11
  0x71, 0x35,
12
  0x72, 0x11,
13
  0x73, 0xF1,
14
  0xA2, 0x02,
15
16
  0x13, 0x8B,
17
  REG_COM9 , 0x6A,    // 128x gain ceiling; 0x8 is reserved bit
18
19
    0x4f , 0x80 ,  // "matrix coefficient 1"
20
    0x50 , 0x80 ,  // "matrix coefficient 2"
21
    0x51 , 0  ,    // vb
22
    0x52 , 0x22 ,  // "matrix coefficient 4"
23
    0x53 , 0x5e ,  // "matrix coefficient 5"
24
    0x54 , 0x80   // "matrix coefficient 6"
25
};


Achtung, grosse Erkenntnis:

Eigentlich würde man bei diesen Werten ein 320x240 QVGA-Bild
im RGB-Modus erwarten. Aber: April, April.

Heraus kommt ein 315x240 Bild !!

Wäre ich nicht vor 1,5 Jahren schon darauf gestoßen, hätte es
mich sicherlich Tage gekostet, das zu bemerken.

Mein Tipp des Tages lautet daher:

Prüft mit dem Oszi oder mit dem LA genau die Länge der HREF-
Pulse und rechnet zurück, ob die von Euch erwartete Zeilenbreite
bei der von Euch gesetzten Taktrate auch tatsächlich zu der
Länge des HREF-Pulses passt.

In meinem Fall konnte ich so exakt auf die 315 Pixelbreite
einer Zeile schließen. Schon bei geringen Abweichungen in der
Darstellung - ich habe zunächst mit 320 Pixel/Zeile dargestellt -
kann man kein Bild mehr erkennen/erahnen.

Und zum Schluss zu Dieter:

Saubere Leistung: Blitzeblanker Code - kein Kommentar trübt
die Ästhetik - daran erkennt man den Hardcore-Programmierer :-)
Aber einem geschenkten Gaul guckt man ja bekanntlich nicht ins
Maul, also: Danke für den Code! Sobald ich mit meinem LCD-Display
nicht mehr zufrieden bin, kommt Dein Code zum Einsatz.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

erstmal Danke für Deine Registerwerte, ich hoffe mal, ich komme morgen 
dazu, was damit zu machen.

Andreas S. schrieb:
> Und zum Schluss zu Dieter:
>
> Saubere Leistung: Blitzeblanker Code - kein Kommentar trübt
> die Ästhetik - daran erkennt man den Hardcore-Programmierer :-)
> Aber einem geschenkten Gaul guckt man ja bekanntlich nicht ins
> Maul, also: Danke für den Code! Sobald ich mit meinem LCD-Display
> nicht mehr zufrieden bin, kommt Dein Code zum Einsatz.

naja, ich habe von Python keine Ahnung, aber den Ablauf kann ich auch 
ohne Kommentare verstehen. Die Python-spezifischen Sachen müßte ich 
ohnehin googeln... :-)

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> naja, ich habe von Python keine Ahnung, aber den Ablauf kann ich auch
> ohne Kommentare verstehen. Die Python-spezifischen Sachen müßte ich
> ohnehin googeln... :-)

Nu fall Du mir nicht auch noch in den Rücken, wenn ich hier gerade
versuche, Dieter auf den Pfad der Tugend zu bringen!

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

mein Problem ist, dass ich die Baudrate nicht hochsetzten kann... dann 
kommt nur noch mist am PC an... und ich weiß nicht warum... ich bin mit 
leppigen 19200 im rennen -.-

okay habe es jetzt mal geschafft meinen RCK auf 500Hz anzuheben... vlt. 
geht noch mehr... aber wie macht ihr das denn, wenn ihr RCK 
"durchlaufen" lasst? mit welcher taktrate lest ihr aus?

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> mein Problem ist, dass ich die Baudrate nicht hochsetzten kann... dann
> kommt nur noch mist am PC an... und ich weiß nicht warum... ich bin mit
> leppigen 19200 im rennen -.-
>
> okay habe es jetzt mal geschafft meinen RCK auf 500Hz anzuheben... vlt.
> geht noch mehr... aber wie macht ihr das denn, wenn ihr RCK
> "durchlaufen" lasst? mit welcher taktrate lest ihr aus?

Ich lasse RCK mit 10kHz durchlaufen und schreibe die Pixel dann Pixel 
für Pixel auf das LCD-Display auf meinem Board. Ich nutze also gar kein 
UART.

Viele Grüße

Igel1

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

Hi,

anbei das Foto des Tages
(links Original, rechts OV7670-Aufnahme dargestellt auf 2.4 Zoll ILI9341 
TFT LCD Billig-Display )

Register-Settings:
1
static unsigned char OV7670_QVGA[][2]=
2
{
3
  0x12, 0x80,
4
5
  0x11, 0x00,
6
  0x12, 0x14,         // original: YUV422 = 0x00;      
7
  0x40, 0xD0,         // original: not set
8
  0x0C, 0x04,
9
  0x3E, 0x19,
10
  0x70, 0x3A,
11
  0x71, 0x35,
12
  0x72, 0x11,
13
  0x73, 0xF1,
14
  0xA2, 0x02,
15
16
  0x13, 0x8B,
17
  REG_COM9 , 0x6A,    // 128x gain ceiling; 0x8 is reserved bit
18
19
    0x4f , 0x80 ,  // "matrix coefficient 1"
20
    0x50 , 0x80 ,  // "matrix coefficient 2"
21
    0x51 , 0  ,    // vb
22
    0x52 , 0x22 ,  // "matrix coefficient 4"
23
    0x53 , 0x5e ,  // "matrix coefficient 5"
24
    0x54 , 0x80   // "matrix coefficient 6"
25
};

So weit, so gut, aber jetzt kommen die Überraschungen:

Zeilenlänge:  313 Pixel a 2 Bytes pro Pixel

Farbfolge:    [Byte1][Byte2] : [GGGGGRRR][RRRBBBBB]

... wer hätte das gedacht ...

Viele Grüße

Igel1


PS: das OV7670-Bild ist in Wirklichkeit noch etwas besser als hier im 
Anhang abgebildet - beim Abfotografieren und Hochladen geht etwas 
Qualität futsch.

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,

sicher? Entweder 555 oder 565, 6 Bit ist aber immer Grün weil der Mensch 
bei grün das bessere Detailauflösungsvermögen hat. Rot und Blau sieht 
man schlechter, da reichen dann weniger Bits.
Die Kamera ist noch stark an TV angelehnt, auch das interleave YU/YV 
über 2 Zeilen ist dafür typisch, kann man gut TV-Signale draus basteln 
R-Y und B-Y werden da übertragen, G-Y wird daraus dann per Matrix 
gewonnen. Rührt auch von TV hier, mal konnte bei PAL/SECAM/NTSC sinnvoll 
nur ein Farbsignal zusätzlich in die Zeile packen (Kompatibilität zu s/w 
war damals noch sehr wichtig). Für Display braucht man sowas nicht mehr.

Grrr, ungewöhnlich für mich, mitten in der Nacht, ich werde wach und bin 
putzmunter...

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Lesenswert?

Andreas S. schrieb:
> Nu fall Du mir nicht auch noch in den Rücken, wenn ich hier gerade
> versuche, Dieter auf den Pfad der Tugend zu bringen!

Moin,

das habe ich einfach nur mal auf die Schnelle gemacht - soll auch nicht 
bleibend sein. Einfach nur ein Script-Arbeitsstand.

Meine Programme sehen besser aus :-) und für den Pfad der Tugend bin ich 
zu alt.

Ansonsten: Schönes Bild, gratuliere ...

VG
Dieter

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

@Andreas S.: ich nehme erstmal alles zurück und behaupte das Gegentum.
Ich habe mal den Farbbalken angemacht, das sieht aber mehr als komisch 
aus...
Ich muß aber bei meinen Registerwerten erstmal wieder Ordnung machen.

RGB565 scheint aber hier schon zu passen. Bei mir sind unten die letzten 
Zeilen nicht mehr sinnvoll gefüllt.

Aber erstmal wieder anderen Dingen widmen...

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Dieter F. schrieb:

> Meine Programme sehen besser aus :-) und für den Pfad der Tugend bin ich
> zu alt.

Oh, dann ist also Hopfen und Malz bei Dir schon verloren.
Na dann müssen wir Dich (und Deine Programme) halt so nehmen,
wie Du bist ;-)   ;-)  :-)

> Ansonsten: Schönes Bild, gratuliere ...

Oh dankeschön! So ein bisschen Anerkennung tut ja jedem Hobby-Bastler 
gut ...

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:

> @Andreas S.: ich nehme erstmal alles zurück und behaupte das Gegentum.

Probate Vorgehensweise - mache ich auch immer so :-)

> Ich habe mal den Farbbalken angemacht, das sieht aber mehr als komisch
> aus...

Mit welchen Register-Settings hast Du welchen Farbbalken aufgenommen?
Evtl. möchtest Du beides noch nachlegen.

> Ich muß aber bei meinen Registerwerten erstmal wieder Ordnung machen.

Ordnung wird total überschätzt - versuche ich seit Jahren meiner 
Besseren Hälfte klar zu machen ...

> RGB565 scheint aber hier schon zu passen.

Das ist das größte Mysterium, mit dem ich aktuell kämpfe - bei mir passt 
es so gar nicht. Wie kann das nur sein?

> Bei mir sind unten die letzten
> Zeilen nicht mehr sinnvoll gefüllt.

Hmmm - scheint aus dem Takt zu kommen ...

> Aber erstmal wieder anderen Dingen widmen...

Ja, ja - die Rentner ;-)

> Gruß aus Berlin
> Michael

Grüße aus Aachen

Igel1

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

Andreas S. schrieb:
> Mit welchen Register-Settings hast Du welchen Farbbalken aufgenommen?
> Evtl. möchtest Du beides noch nachlegen.
1
das sind die von der Kamera erzeugten Color Bars.
2
  { 0x12, 0x16 },  // COM7  - Selects QVGA [4] und RGB [2][0]  [1] color bar on
3
  { 0x42, 0x08 },  // COM17 - AEC Window [7:6] Bit 1 und 0 wie COM4 [5:4], DSP Color Bar on/off[3]

Andreas S. schrieb:
>> Bei mir sind unten die letzten
>> Zeilen nicht mehr sinnvoll gefüllt.
>
> Hmmm - scheint aus dem Takt zu kommen ...

bisher keine Ahnung, wo, vermutlich schon falsch von der Kamera in den 
FiFo, das Muster bleibt immer identisch.

Andreas S. schrieb:
> Ja, ja - die Rentner ;-)

bekanntermaßen haben die niemals Zeit... :-))

ok, gerade mal am Timing beim FiFo lesen etwas rumgespielt, sieht jetzt 
schon mehr nach Farbbalken aus.
Vielleicht hätte ich einfach mal oben schauen sollen, wie Du das machst?

Gruß aus Berlin
Michael

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

so, mühsam ernährt sich das Eichhörnchen...

Ich habe das ino mal angehängt, am Ende den Arduino-Block 
auskommentieren und den AVR-Studio Block aktivieren, dann geht es auch 
als Studio Projekt zu compilieren.

Änderungen: Gamma-Werte auf die defaults aus dem Datenblatt gesetzt, 
passt erstmal ganz gut.
ov7670_default_regs sind die Settings aus Applikation, nur Gamma 
verändert.
Rest in regval_list yuv422_ov7670 und rgb565_ov7670 ist zusammengesucht, 
aber nur noch mit den rgb565 Settings getestet.

Chaos damit Andres S. auch seine Freude hat. :-)

PS: Baudrate steht auf 230400, mehr macht mein UNO mit dem Mega16U2 als 
USB-Wandler nicht stabil...

PPS: Format ist definitiv RGB565, BigEndian.

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

@Michael: danke für die Tipps - die Colorbalken wollte ich mir auch 
schon immer einmal anschauen, war bislang nur zu faul, die Register 
zusammenzusuchen.

Meine Ausgabe findest Du im Anhang.
Jetzt können wir rätseln, welche Ausgabe nun richtig ist ...
Ich finde meine auch ganz hübsch :-)
Aber korrekt wird vermutlich nur eine von beiden sein (wobei mein 4€ 
China-TFT-LCD Display sicherlich auch einiges an Fehlern in die Sache 
reinbringt.

Ich bin aktuell noch zu faul, mir Code für die Ausgabe in Richtung PC zu 
stricken. Mit so einem ARM-Prozessor braucht's da doch immer etwas mehr 
Überwindung als mit einem Arduino, wo alles schon parat liegt.

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Vielen Dank für eure Dateien, die werde ich mir dann am Wochenende 
anschauen.


Bei mir ging oberhalb von 38400 dann garnix mehr... jetzt habe ich es 
spaßeshalber auf 2 000 000 Baudrate gestellt... ja! 2MBaud... und es 
scheint zu laufen! mit dem Atmega238P :D... ich bin total fasziniert... 
mal schauen ob ich morgen mal vom RAW auf das RGB format umschalten 
kann... ist aber einiges an implementierungsaufwand im Terminal... aber 
vielleicht lohnt es sich ja. So scheine ich nicht auf einen grünen Zweig 
zu kommen.

@Igel aus Aachen? das ist ja lustig! ich komme ursprünglich aus Stolberg

: Bearbeitet durch User
von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

Ich kapier die Welt nicht mehr:

Wenn ich die Werte noch RGB565-Manier einlese, und an das LCD-Display 
sende, so bekomme ich exakt Michaels Testbild.

Wenn ich dann das Testbild abschalte und meinen Balli fotographiere,
so hat er auf dem Bild eine knallgrüne Nase (statt einer roten Nase).

Ich gucke langsam schon fast so wie mein Ball ...

Grüße

Igel1

von Dieter F. (Gast)


Lesenswert?

David D. schrieb:
> 2MBaud... und es
> scheint zu laufen! mit dem Atmega238P

Auf Sender-Seite ja - Python schafft den Empfang aber nicht richtig 
(max. 1 MBaud) - daher hatte ich auch "Verzerrungen" im Bild.

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

Andreas S. schrieb:
> Ich kapier die Welt nicht mehr:

Wie sprach das grüne Tentacle in Maniac Mansion? Ich bin ja soooo 
deprimiert... ;-)

Im Anhang mal ein Original Farbbalkenbild (Ausleihe aus der 
Burosch-Test-Beschreibung).
Von weiß nach schwarz:
Blau:  Ein-Aus-Ein-Aus-Ein-Aus-Ein-Aus.
Rot:   Ein-Ein-Aus-Aus-Ein-Ein-Aus-Aus
Grün:  Ein-Ein-Ein-Ein-Aus-Aus-Aus-Aus
Konnte man auch ganz früher schon gut mit einfacher Frequenzteilung 
eines Rechtecksignals erzeugen.

Andreas S. schrieb:
> Ich bin aktuell noch zu faul, mir Code für die Ausgabe in Richtung PC zu
> stricken. Mit so einem ARM-Prozessor braucht's da doch immer etwas mehr
> Überwindung als mit einem Arduino, wo alles schon parat liegt.

hmmm... Arduino ist an meinem Kram ein Name für das AVR328 Modul und die 
IDE.
Das ist plain C für einen AVR, die die Bytes nimmt und in den 
Hardware-UART tütet. Kann auf einem STM außer der anderen UART-Init ja 
kaum anders sein.
Auf PC-Seite lesen ich ja immernoch mit TeraTerm als binär-Log ein 
(dehalb ja die 30s Pause, weil ich da immer im Menü rumklicken muß) und 
lasse IrfanView als RAW anzeigen (dehalb nur die reinen Bilddaten, sonst 
müßte ich überflüssige Daten erst om Hex-Editor wieder abschneiden.

Die Display habe ich auch hier, allerdings müßte ich da ziemlich mit der 
Pinbelegung der IOs tricksen, ein AVR328 hat soviele nicht...

Da ich mit dem UART nur sende, könnte ich mal schnell einen Webserver 
auf einen ESP8266 werfen, die Daten vom AVR zum ESP schicken und mir das 
Bild im Browser anschauen. Wäre zwar von hinten durch die Brust ins 
Auge, macht aber eigentlich keinen Aufwand...

Eine Erklärung für Deine grüne Nase habe ich nicht, die Einstellungen 
für den Analogteil (AGC/AEC/Colormatrix usw.) sind bei mir orignal die 
Init aus der Applikation, die geben mit auch noch ein paar Rätsel auf. 
Die Nase kann ja nur da zwischen Bildensor und ADC-Ausgabe versaut 
werden, beim Farbbalken greifen die ja nicht, den erzeugt der DSP ja 
erst dahinter.

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

so, mal versucht, einen Blick Richtung Hof zu bekommen.
Leider reicht der FiFo ja nicht für 640x480, gedacht ist der ja nur für 
Interlace-Halbbilder bis 720x480, also 2x 720x240. Würde praktisch aber 
auch keinen Sinn machen, weil bei unserer Auslesegeschwindigkeit die 
geraden/ungeraden Zeilen aus zeitlich weit auseinanderliegenden Bildern 
kämen. Bei Bewegung im Bild also nur Schrott...
Bleibt also in der Geschichte bei 320x240.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

Hi Leute,

Michael hatte ja 7 Beiträge weiter oben Code mit Register-Settings 
eingestellt und dann geschrieben:
> so, mühsam ernährt sich das Eichhörnchen...

[...]

> Chaos damit Andres S. auch seine Freude hat. :-)

... und Andreas hatte seine Freude ...

Zum Glück ist ihm aufgefallen, dass er zuerst ov7670_default_regs und 
dann erst rgb565_ov7670 einladen musste, weil sich die Werte 
überschreiben.
Im Nachhinein eigentlich logisch, aber beim ersten Kopieren nicht sofort
klar.

Sodann nochmals ein paar Minuten wildes Probieren wg. Zeilenlänge 
(irgendwann war ich's dann leid und habe es wieder aus der Länge des 
HREF-Signals berechnet: 311 Pixel !!) und voila: im Anhang findet Ihr 
das Ergebnis: definitiv das bislang farblich beste Bilder.

Interessanterweise passt mit Michaels Register Settings nun auch das 
RGB565-Format sauber, so wie ich es erwartet hätte.

Einzig die Vertikalstreifen links stören noch etwas (siehe Bild)
Ihr scheint dieses Problem nicht zu haben?

Viele Grüße

Igel1

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

na wird doch langsam. :-)

Andreas S. schrieb:
> Einzig die Vertikalstreifen links stören noch etwas (siehe Bild)
> Ihr scheint dieses Problem nicht zu haben?

doch, sieht man auch auf meinen Bildern. Im Moment ist die 
Windowsposition auf "automatisch" was das auch immer heißt. Ich werden 
das mal auf manuell setzen. Register 0x3A (TSLB) Bit [0] muß ich mir 
auch noch anschauen.
Ansonsten eben Register 0x17...0x1a [HSTART/HSTOP/VSTRT/VSTOP].
Dummy-Zeilen und Pixel kann man auch noch einfügen, wo und wozu? Noch 
keine Ahnung.
Der Sensor selbst hat ja 656x488 Pixel, da darf man wohl das Window erst 
auf den aktiven Bereich anpassen...

Den kompletten Code habe ich für mich sowieso jetzt erstmal 
zusammengestrichen, ist nach wie vor Bastelstelle. YUV werde ich noch 
testen, als s/w Bild spart es übertragene Bytes. Die Aufrufe werde ich 
morgan mal in #defins und #ifdef verpacken für RGB, YUV und auch für 
Color Bar on/off. Spielt sich besser mit rum.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> na wird doch langsam. :-)

Na ja - aber leider bei den Falschen ...

Eigentlich wollten wir doch David helfen und nun müssen wir es erst 
einmal selber auf Kette bekommen.

Ich hoffe, David wird nicht davon frustiert, dass es bei uns inzwischen 
halbwegs läuft und bei ihm noch nicht so ganz.

Aber immerhin haben wir ihm nun etwas Grundlagenforschung abgenommen.
Wenn man wenigstens eine funktionierende Register-Kombination kennt, 
tappt man nicht ganz so im Dunkeln - man weiß dann wenigstens, dass 
etwas Vernünftiges aus der Kamera herauskommt und kann sich auf die 
Fehlersuche im eigenen Code konzentrieren.

@David: bitte lade doch einmal Deinen aktuellen Code hier hoch - dann 
können wir etwas stöbern.  Deine Steuersignale sahen ja schon mal gut 
aus - kann eigentlich nur noch an der AL422B Ausleseroutine liegen.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Eigentlich wollten wir doch David helfen und nun müssen wir es erst
> einmal selber auf Kette bekommen.
habe ich auch immer wieder mal drüber nachgedacht, deshalb auch mein 
kurzer TEst im alten AVR-Studio, dans sollte auch im aktuellen gehen. 
Deshalb auch der Kampf mir dem Mega328. ;)

> Ich hoffe, David wird nicht davon frustiert, dass es bei uns inzwischen
> halbwegs läuft und bei ihm noch nicht so ganz.
er wollte ja im Ursprung jedes Fahrad selbst erfinden, an sich sehr 
löblich und sinnvoll. Allerdings bin ich immernoch der Meinung, daß so 
eine Kamera zusammen mit einem Mega328 kein sinnvoller Ansatz ist. 
OV2640/ESP32 liegt ja hier mehrfach rum und läuft auch prinzipiell, aber 
nicht nach meinen Vorstellungen, da werde ich weitermachen.
Sein Ansatz mit seinem PC-Programm ist meiner Meinung nach auch ziemlich 
komplex. Ich bin jetzt mehr denn je der Meinung, daß man mit einzelnem 
Register ändern dabei nur den Heldentod stirbt...
Ich hatte ja kurz überlegt, auch ein VB6-Programm für den schreiben, 
damit Übertragung und Bilddarstellung schell zu prüfen sind. Ich bin bei 
bewährtem TeraTerm und Irfanwiev) geblieben, weil ich wußte, daß beide 
das gewünschte zuverlässig leisten, nur die Bedienung ist eben 
fragwürdig, ich scahffe es aber inzwischen in unter 10s bis ich das Bild 
sehe. ;)
Irfanwiev kann als RAW so ziemlich alles laden, was man in Bytes packen 
kann. Das selber zu machen wäre zwar machbar, nur hätte ich dann ein 
tolles Programm, das ich ohne größere Umbauten wohl nie wieder 
brauche...

Bei meinen Gedanken, die Routinen von David in meinen Source zu packen 
und zu testen, habe ich dagegen fast keine Arbeit. Übertagen und 
Kam-Init habe ich da dann im Zweifel immer sicher, um den Bereich 
einzugrenzen, wo es bei ihm klemmt. Baudrate usw. ist dabei ja auch 
egal, ist ein Byte im UART-Init und eine Auswahl in TeraTerm. Den UNO 
flashen dauert keine 15s.

Ich hoffe also schon, daß David nicht verschreckt abspringt.

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Lesenswert?

Michael U. schrieb:
> YUV werde ich noch
> testen, als s/w Bild spart es übertragene Bytes.

YUV, RGBxxx sind alles errechnete Formate. Die originäre Auflösung (640 
x 480) bekommt ihr im RAW Bayer Format. Da werden die einzelnen 
Pixel-Helligkeiten als Byte übergeben. Das bekommt man auch in den Fifo. 
Das ist auch alles, was die Sensoren können. Leider liegt eine 
Linsen-Maske über dem Sensor-Array, was (durch Lichtbrechung? - das kann 
ich nicht deuten) die Helligkeiten wie ein Farbfilter beschränkt.

Die Umrechnunng macht der DSP in der Kamera oder man selbst, wenn man 
denn will.

VG
Dieter

von Michael U. (amiga)


Lesenswert?

Hallo,

@ Dieter F.: alles zutreffend. Für mich ist die Kamera und der Sensor 
ein Produkt für damals preiswerte Überwachungs-Cams und Webcam gewesen, 
kein Meßgerät. Ziel, auch der Möglichkeiten des Kamera-DSP, sehe ich 
darin, ein subjektiv stimmiges Bild zu erzeugen, kein identisches Abbild 
der Wirklichkeit in diesem Bereich.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Dieter F. schrieb:
> Die originäre Auflösung (640
> x 480) bekommt ihr im RAW Bayer Format.

Heisst das: wenn cih RAW Bayer Format einstelle, wird der DSP komplett 
umgangen?

Viele Grüße

Igel1

von Dieter F. (Gast)


Lesenswert?

Andreas S. schrieb:
> Heisst das: wenn cih RAW Bayer Format einstelle, wird der DSP komplett
> umgangen?

Jein - es findet halt keine Umrechnung in ein "Farbformat" statt. Ob 
White-Balancing etc. noch ausgeführt werden weiß ich nicht.

VG
Dieter

von David D. (saturi)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

>Eigentlich wollten wir doch David helfen und nun müssen wir es erst
>einmal selber auf Kette bekommen.
>
>Ich hoffe, David wird nicht davon frustiert, dass es bei uns inzwischen
>halbwegs läuft und bei ihm noch nicht so ganz.


doch solangsam wird er es :D ... aber nach einem Tief kommt auch immer 
wieder ein Hoch... Habe jetzt wieder 2 Std. damit verbracht einen 
urplötzlich auftretenden Fehler zu suchen mit dem plötzich garnichts 
mehr ging... sogar den Code von gestern Nacht habe ich wieder zurück 
genommen. Nichts.... Lösung: den billigen Logic Analyzer nicht 
unbestromt an den Pins hängen lassen, weil er sonst die einzelnen 
Potentiale so runter zieht, dass Sie zwar auf dem Oszi noch genauso zu 
erkennen sind wie vorher (wenn man nicht auf die Spannung schaut) aber 
vom Atmega nicht mehr erkannt wird. Sprich meine while schleife vom 
VSync bleibt einfach hängen...
 Als hätte ich keine anderen Probleme...


Die Ursprüngliche Idee des Terminals war ja dafür gedacht um bequem 
register ändern zu können, ohne jedes mal neu flashen zu müssen. Um den 
"Re-Use" des Programms möglichst groß zu halten habe ich mir 
vorgenommen, das uC-Programm so einfach wie möglich zu halten um es 
später ggf. auch für andere Controller möglichst anwendbar zu machen.

Ich danke euch für all die Informationen und Register Werte die ihr in 
der Woche zusammen getragen habt... Diesmal nehme ich mir vor sie jetzt 
erstmal alle zu sammeln und für mich zu Bewerten damit ich nicht wieder 
die Lösung vor den Augen habe und sie übergehe...

Zum Imager:
jeder Pixel liefert nur einen Helligkeitswert (Ich denke so war es 
damals im Schwarzweiß Fernsehen-war aber vor meiner Zeit).
Um Farbe in das ganze zu bringen gibt es das Bayer-Pattern, Hier werden 
über die verschiedenen Pixel farbfilter gelegt in meistens folgendem 
Muster: RGGB
RGRGRGRGRG
GBGBGBGBGB
RGRGRGRGRG
GBGBGBGBGB

Jeder Buchstabe steht für einen Pixel und den jeweiligen Farbfilter: R= 
Rot G= Grün B= Blau. Grün kommt in einem Quadrat aus vier Pixeln immer 
zwei mal vor. Das ist vom menschlichen Auge abgeschaut, dass auf Grün 
wesentlich empfindlicher reagiert.

Im RAW format schiebt der DSP also einfach die Helligkeitswerte auf den 
Ausgang ohne die Farbfilter zu beachten, sprich es kommt ein Schwarzweiß 
bild raus (wobei die Helligkeit der einzelnen Pixel schon von den 
Farbfiltern abhängt)
 Beim processed BAYER RAW wird über nen Algo für jeden Pixel durch die 
umliegenden Pixel eine Farbinformation RGB berechnet, sodass ich für 
jeden Pixel 3 Byte bekomme (RGB) mit letzterm Format habe ich es bisher 
versucht, weil es für mich am einfachsten zu händeln war (aber 
vergeblich) ich werde heute einmal schauen auf euer RGB565 zu kommen.
So zumindest ist mein Verständnis, sollte ich hier was falsch verstanden 
haben?

kurz zu den Auflösungen:
VGA: 640*480
QCIF: 176*144
QVGA: 320*240
CIF: 352*288
Das sind die mit denen ich hier ins Rennen gehe.

Wo kommen bei euch die Uminösen 311 Pixel bei HREF her?
Anbei ein aktuelles Bild von mir -.-

Schaue mir dann jetzt mal eure Register werte an...
Aber ein Bild sollte ich doch, wenn auch in schlechter Qualität ohne 
einstellungen bekommen? (also 0x12 und 0x42 Colorbar jeweils an)


Sowohl den Code vom AtmelStudio als auch den Sourcecode vom aktuellen 
terminal stelle ich euch nachher noch rein.

von Andreas S. (igel1)


Lesenswert?

Hallo David,

mein Tipp: fange erst einmal mit einer OV7670-Register-Kombination an, 
die 100% funktioniert und die Dir ein Colorbar-Testbild rauswirft.

Dies ist solch eine Kombination:
1
static unsigned char OV7670_QVGA[][2]=
2
{
3
   0x12, 0x80,  
4
5
   0x11, 0x00  ,  // CLKRC - Teiler XCLK In -> intern 1:1 -> also 12MHz bei meinem Modul
6
   0x12, 0x16 ,  // COM7  - Selects QVGA [4] und RGB [2][0]  [1] color bar, on 0x16 off 0x14
7
   0x40, 0x14 ,  // COM15 - Selects RGB 565 [5:4] und Full Range [7:6]
8
   0x3a, 0x05 ,  // TSLB  - Window auto, YUYV [00] Ausgabe - TSLB [3], COM13[0]
9
   0x42, 0x08 ,  // COM17 - AEC Window [7:6] Bit 1 und 0 wie COM4 [5:4], DSP Color Bar on/off[3], on 0x08 off 0x00
10
11
   0x15, 0x00 ,  // COM10 - PCLK auch bei HREF
12
};

Das Ergebnis ist ein Testbild mit 313 Pixel/Zeile und 240 Zeilen. Jedes 
Pixel besteht aus 2 Bytes, die nach RGB565 kodiert sind, also:
[RRRRRGGG][GGGBBBBB].
Dabei wird das hier links dargestellte Byte als erstes Übertragen.

Wenn das funktioniert, so ändere die Werte von Register 0x12 auf 0x14 
und Register 0x42 auf 0x00 und Du bekommst Dein erstes "echtes" Bild - 
ziemlich schwache Farben, aber immerhin - ein Bild.

Danach kannst Du weiterforschen.
Das wäre meine Rat an Dich bzgl. Vorgehensweise.

Viele Grüße

Igel1

: Bearbeitet durch User
von David D. (saturi)


Angehängte Dateien:

Lesenswert?

Hallo Igel,

vielen Dank. Damit habe ich schonmal einen Fehler "enttarnt" was COM 15 
angeht. 16 ist eben nicht 0x16...
trotzdem schreibt ihr mit
0x14 doch in einem reserved Register rum oder nicht? Müsste es also 
nicht heißen
0x14: 0xD0 ?


Leider bringt mich das umstellen der xResolution auf 313 auch nicht 
weiter. Ich scheine immernoch ein Problem mit dem FIFO zu haben.


anbei ein Bild das aktuell rauskommt (QVGA (313px/Zeile)) RGB565


Immerhin habe ich diese "Zeilenstruktur" jetzt bei jedem Bild, allerding 
ändert sich die "Verzerrung" von der vermeitlichen ColorBar mal nach 
rechts und mal nach links...

von Andreas S. (igel1)


Lesenswert?

Bitte stell mal Deinen Code hier ein.

von David D. (saturi)


Lesenswert?

@Dieter kannst du mir vielleicht sagen, wie du in den Pausen sendest?

Dieter F. schrieb:
>
> QQVGA hat den Vorteil, dass nur jeder 4. HREF-Slot (im Vergleich zu VGA)
> Daten enthält/übermittelt. Die "Totzeit" nutze ich für die serielle
> Übertragung.
>
> VG
> Dieter


Ich denke eines meiner "Probleme ist wahrscheinlich, dass ich zwischen 
den einzelnen Zeilen pausiere um Rückmeldung vom Terminal zu geben, dass 
die Zeile angekommen ist. damit unterbreche ich RCK für 10,3ms... 
vielleicht rührt es daher und ich sollte mein Konzept nochmal überdenken 
und vlt. doch den ganzen Frame übertragen...

von David D. (saturi)


Lesenswert?

Unter folgendem Link sind zu finden:

https://github.com/igittigitt/ov7670/tree/TWI-Interfac

- Das Terminal Programm als release (zum Direkt ausführen: 
OV7670-Terminal_V0.3.zip)

- Das Terminal als Solution zur Sourcecode einsicht in VS

-Das Atmel Studio projekt mit allen C-Datein für den Arduino.



Bitte HELFT mir :D ....

@Igel kannst du vielleicht nochmal deine aktuelle Write und Read sequenz 
einstellen? Ich würde die gerne abgleichen.

: Bearbeitet durch User
von Dieter F. (Gast)


Lesenswert?

David D. schrieb:
> @Dieter kannst du mir vielleicht sagen, wie du in den Pausen sendest?

Hallo David,

da ich keinen Fifo nutze bringt Dir das wahrscheinlich nichts. Ich 
antworte aber gerne.

Das Auslesen basiert auf den VGA-HREF-Frames. Schau Dir dazu bitte das 
Datenblatt (Version 1.01) Seite 8 an. Also grundsätzlich 640 HREF-Frames 
pro Zeile (HREF-Intervall).

Ich nutze aktuell das QQVGA-Format (160 x 120). In Figure 8 siehst Du, 
dass in in 4 VGA-HREF-Frames nur 1 QQVGA-HREF-Frame prozessiert wird - 
QVGA entsprechend 2, CIF und QCIF - orientiert an VGA und QVGA - 
entsprechend weniger.

Der HREF-Takt orientiert sich also immer an VGA mit 640 Pixel pro Zeile 
- was nicht (vom Pixel-Takt) gebraucht wird, wird ausgeblendet.

Bei dem von mir genutzten QQVGA habe ich 3 HREF-Takte Zeit, die im 
ersten HREF-Takt gelesenen Daten seriell an den PC (oder per SPI an ein 
Display) zu übertragen.

Das ist nicht viel. Ich kann (das hast Du auch probiert) mit 2 MBaud vom 
ATMega328P (Arduino Nano-Basis) senden - (relativ) sicher empfangen kann 
ich mit Python aber nur ca. 1 MBaud. Bei 8 Daten-, 1 Start- und ein 
Stop-Bit sind das bei RGB (2 Bytes) ca. 20 µS pro Pixel (+ die 
UART-Verarbeitung für 320 Byte pro Zeile). Damit komme ich aktuell bei 1 
MBaud auf ca. 0,6 Sekunden pro Bild (QQVGA).

Erreichen kann ich das nur, wenn ich die Pixel-Clock (bei 16 MHz Takt am 
Eingang) entsprechend verlangsame (Register 0x11 etc.).

Genau da fangen die Probleme an. Viele der Einstellungen für andere 
Register sind direkt oder indirekt von der Pixel-Clock abhängig - welche 
das sind ist nicht auf den ersten Blick ersichtlich. Genau da hört der 
Spaß für mich auf.

Mit dem Fifo kannst Du mit der "vollen" Pixel-Clock die Pixel in den 
Fifo übertragen (hast also eine Art Referenz) und von dort "gemütlich" 
auslesen, da diese ja bis zum vollständigen Auslesen gehalten werden.

Wenn ich keine Umrechnungen (RAW Bayer ...) machen wollte und eine 
Kamera mit Fifo hätte würde ich auch QVGA (im Kamera-DSP umgerechnet) 
nutzen, um das Bild auf einem Display oder am PC darzustellen. Die 
passenden Register-Einstellungen sind schon x-Mal veröffentlicht worden 
- wenn Du ein Bild haben willst - einfach kopieren. Der 
"Implementation-" oder "Programming-" Guide sind nur rudimentär und (aus 
meiner Sicht) nicht vollständig.

Genug "gelabert" - schönes Wochenende
Dieter

von Dieter F. (Gast)


Lesenswert?

David D. schrieb:
> Ich denke eines meiner "Probleme ist wahrscheinlich, dass ich zwischen
> den einzelnen Zeilen pausiere um Rückmeldung vom Terminal zu geben, dass
> die Zeile angekommen ist. damit unterbreche ich RCK für 10,3ms...
> vielleicht rührt es daher und ich sollte mein Konzept nochmal überdenken
> und vlt. doch den ganzen Frame übertragen...

Du hast "alle Zeit der Welt" den Fifo auszulesen (nach meinem 
Verständnis).

Nur musst Du die Kamera so konfigurieren, dass diese den Fifo 
zuverlässig füllt (und das VSYNC-Signal auswerten, damit Du nicht 
voreilig ausliest).

von David D. (saturi)


Angehängte Dateien:

Lesenswert?

So hatte ich mir das auch vorgestellt... Aber laut Datenblatt des Fifos 
muss man RCK ebenfalls mit 1MHZ betreiben. Und da ich keinen Zugriff auf 
das ReadEnable habe, macht das die ganze Sache kompliziert.

Habe jetzt mal ein neues Feautre zum Terminal hinzugefügt, dass den 
ganzen Frame auf einmal empfängt und siehe da: zumindest die "toten" 
Bereiche sind verschwunden.


Das Bild hat 313x240 Pixel.

Ist es ein Problem mit der AUflösung oder mit dem Speicher auslesen?


EDIT: RCK habe ich jetzt auf 48kHZ und somit immernoch weit unter der 
Spec... Aber ich weiß nicht wo ich das noch rauskitzeln soll

: Bearbeitet durch User
von Dieter F. (Gast)


Lesenswert?

David D. schrieb:
> Das Bild hat 313x240 Pixel.
>
> Ist es ein Problem mit der AUflösung oder mit dem Speicher auslesen?

Zeig doch bitte Dein aktuelles Programm. Die PC-Seite "ist geheim" - 
aber dann können wir (Michael und Andreas - ich nur theoretisch) 
zumindest an der AVR-Seite mal schauen ...

von David D. (saturi)


Lesenswert?

Siehe den Post von kurz nach 17 Uhr, im Link findest  du sowohl das 
"geheime" ;-) Programm (auch den Sourcecode und ebenfalls den Sourcecode 
vom uC. Hast du Probleme mom Link? Dann Versuch ich's nochmal

von Andreas S. (igel1)


Lesenswert?

Hi Leutis,

habe dummerweise aktuell nicht viel Zeit, daher hier nur ganz kurz:

- Habe meinen Pseudocode von weiter oben mehr oder weniger 1:1 auch
  in Code umgesetzt (der Dich aktuell aber mehr verwirren als beflügeln
  würde - ich muss ihn erst aufräumen, bevor ich ihn hier einstellen
  kann).

- Den AL422B lese ich mit 10kHz aus (also weit unter der Spec).
  Der PCLK-Takt aus der Kamera läuft die ganze Zeit durch - ich hoffe
  mal, der reicht für das DRAM-Refresh.

- Ich sammle jeweils 2 Bytes aus dem FiFo und sende die als
  RGB565-Doppelbyte zu meinem LCD-Display (die entsprechende
  Funktion des LCD's spricht nämlich ebenfalls RGB565.)
  Ich warte also explizit nicht auf das Zeilenende, bevor ich die
  Daten in Richtung LCD versende.

Mehr "Magic" ist nicht dabei.

Viele Grüße

Andreas

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> EDIT: RCK habe ich jetzt auf 48kHZ und somit immernoch weit unter der
> Spec... Aber ich weiß nicht wo ich das noch rauskitzeln soll

ich habe mal testweise 50ms delay nach jeder Zeile bei mir eingefügt, 
stört in keiner Weise, Bild wird sauber aus dem FiFo gelesen.

Ich habe mal versucht, durch Dein Programm durchzuschauen, aber bis 
jetzt nur kurz.
Verwirrung: warum finde ich Registerdefinitonen wie
1
  #define OV_SCCB_COM14    0x3E
in der SCCB_old.h, bei mir würden die zur OV7670_with_Fifo.h gehören.
SCCB wäre bei mir init(), readByte(adr,wert) und writeByte(adr,Wert).
Wenn ich z.B. die OV7670_with_Fifo.h durch eine OV2740.h ersetzen 
wollte, will ich nicht in zig Dateien nach zu Ändernden Registernamen 
suchen müssen.
SCCB bliebe ja SCCB.
Mir ist auch etwas unklar, warum man die Datenpins der Kamera auf 2x 
4Bit von 2 Ports durchuas sinnvoll aufteilet und das dann mit 
Funktionen, die Funktionen aufrufen, einzeln zusammenbastelt.

Das ginge in einer Zeile mit
1
      UDR0 = (PIN_LOW & MASK_LOW) | (PIN_HIGH & MASK_HIGH);          // Byte (Y) einlesen und rausschicken
Dazu denn eben
1
#define PIN_HREF  PB0     // (D8)  IN   H-aktiv OV7670 Zeilenstart mit H-Impuls
2
#define PIN_VSYNC PD3     // (D3)  IN   H-aktiv OV7670 Bildstart mit H-Impuls
3
#define PIN_WRST  PD2     // (D2)  OUT  L-aktiv AL422B Write-Counterreset mit L-Impuls
4
5
#define PIN_STR   PB1     // (D9)  IN   H-aktiv OV7670 Blitzlichtsteuerung
6
#define PIN_RCK   PB2     // (D10) OUT  H-aktiv AL422B default L
7
#define PIN_RRST  PB3     // (D11) OUT  L-aktiv AL422B Read-Counterreset mit L-Impuls
8
#define PIN_WR    PB4     // (D12) OUT  H-aktiv AL422B verknüpft mit HREF OV7670 zu /WR AL422B
9
#define PIN_OE    PB5     // (D13) OUT  L-aktiv AL422B Output tristate/aktiv, kann hier wohl auf L bleiben
10
11
#define PIN_LOW   PINC
12
#define MASK_LOW  0x0F    // (A0...A3) PC0...PC3 IN
13
14
#define PIN_HIGH  PIND
15
#define MASK_HIGH 0xF0    // (D4...D7) PD4...PD7 IN

Das komplette Init der Kamera-IO dann
1
  DDRB &= ~((1 << PIN_HREF) | (1 << PIN_STR));                                               // IN
2
3
  PORTB &= ~((1 << PIN_WR) | (1 << PIN_OE) | (1 << PIN_RCK));                                // Low  
4
  PORTB |= (1 << PIN_RRST);                                                                  // HIGH
5
  DDRB |= (1 << PIN_RCK) | (1 << PIN_RRST) | (1 << PIN_WR) | (1 << PIN_OE);                  // OUT 
6
  
7
  DDRD &= ~(1 << PIN_VSYNC);                                                                  // IN
8
  PORTD |= (1 << PIN_WRST);                                                                   // HIGH
9
  DDRD |= (1 << PIN_WRST);                                                                    // OUT
10
  
11
  DDRC &= ~MASK_LOW;                                                                          // D0-D3 camera  IN
12
  DDRD &= ~MASK_HIGH;                                                                         // D7-D4 camera  IN

Ich weiß, daß das Herangehen da ewige Diskussionen auslösen kann, es 
stellt also nur meine Vorstellung und Meinung dar.

Wenn die Pin-Zuordnungen (für mich) schnell auffindbar gewesen wären, 
hätte ich den Kram vermutlich noch schnell an mein PinOut des AVR 
angepasst und mal geflasht. So werde ich mich erstmal durchkramen müssen 
um mehr zu verstehen.

So, genug gemault... ;-)

@Andres S. schrieb:
>  Ich warte also explizit nicht auf das Zeilenende, bevor ich die
>  Daten in Richtung LCD versende.
Ich warte auch auf nichts, die Geschwindigkeit wird nur von der 
UART-Rate bestimmt, sind hier RCLK im Moment 22,4kHz, eben 230400 Baud, 
passt ja auch ganz gut. Mit 115200 ist es aber genauso stabil, dann eben 
bei gut 11kHz RCLK.

Gruß aus Berlin
Michael

: Bearbeitet durch User
von David D. (saturi)


Lesenswert?

Danke, dass du dir das antust. Da ist Maulen dann auch erlaubt :D
Den case 0 brauchst du dir erst gar nicht anschauen. Der wird eh nie 
aufgerufen :D.... ansonsten sind in der main() die möglichen Befehle in 
dem Switch case Statement. Die Befehle selbst sind in der ov7670 With 
Fifo. Die sccb_old verwirrt zwar wegen dem Namen, aber ist die richtige 
und funktioniert auch recht zuverlässig. Bin grade leider nur mobil 
drin, kannst könnte ich dir schon mehr Infos geben

von Dieter F. (Gast)


Lesenswert?

David D. schrieb:
> Siehe den Post von kurz nach 17 Uhr, im Link findest  du

Ja - bin ein Blindfisch :-(

Was mir auffällt:
1
volatile int height = 480;
2
volatile int width  = 640;
3
volatile int BytesPerPixel = 3;

Passt das zu dem, was Du einlesen willst? Würde bedeuten, dass Du RAW 
Bayer (height / width) einlesen möchtest. Da kommt aber nur 1 Byte pro 
Pixel und nicht 3 (ob die Register-Werte dazu passen habe ich nicht 
geprüft).

3 Byte pro Pixel kann die Kamera gar nicht - die passen auch nicht in 
den Fifo bei der gewählten Auflösung, so weit mir bekannt. Damit wird 
nichts vernünftiges herauskommen.

Das
1
   //Reset the Write Pointer, (not sure, if that will work)
2
   OV7670_ResetFifoWritePointer();

gehört nicht ans Ende von "OV7670_captureNewImage" - keine Ahnung, ob es 
stört.

VG
Dieter

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Danke, dass du dir das antust. Da ist Maulen dann auch erlaubt :D

ok, wenn Du es so siehst machen wir mal weiter. :-)
Den Kram zuzuodnen ist nicht so das Problem, ich hatte erst gestern Aben 
nur schnell das PinOut der Cam prüfen wollen und an meins anpassen. Die 
steckt ja jetzt so schon auf dem Adapterboard, von dem Andreas so 
"begeistert" war. ;)

SCCB passt, da bist Du ja auch an den I2C-Pins.
D7...D4 passen,
D3...D0 hast Du an PortB, ich an PortA, muß ich anpassen.
VSYNC Du auf C4, ich auf D3,
HREF Du auf C0, ich auf B0,
RST Du auf B5, habe ich fest auf H, muß ich auf einen unbenutzten Pin 
mappen.
PDWN haben wir beide nicht beschaltet, ok.
STR Du nicht beschaltet, ich dummerweise ja, hatte erst später geschaur, 
wofür der ist, muß ich also in Deinem Source noch auf L schalten, kein 
Problem.
RCK Du auf D2, ich auf B2,
WR Du auf B4, ich auf B4,
OE Du nicht beschaltet, ich auf B5, also auch noch auf L setzen
WRST Du auf C3, ich auf D2,
RRST Du auf C2, ich auf B3.

Werde ich nachher in Deinem Source mal anpassen, der LA hängt sowieso 
noch dran, sehe ich ja zur Not, wenn ich wo falsch bin.

Compiler lief ja schon durch, ein paar Warnungen, denen ich aber nur 
nachgehe, wenn es da klemmt bzw. der Rest passt:
SCCB_Old.c:330:40: warning: passing argument 2 of 'OV7670_read' discards 
'volatile' qualifier from pointer target type [-Wdiscarded-qualifiers]
 if(ErrorCode=OV7670_read(OV_SCCB_COM14,&temp))

SCCB_Old.c:161:7: note: expected 'char *' but argument is of type 
'volatile char *'
  char OV7670_read (char regID, char* regData)

SCCB_Old.c:339:39: warning: passing argument 2 of 'OV7670_read' discards 
'volatile' qualifier from pointer target type [-Wdiscarded-qualifiers]
 if(ErrorCode=OV7670_read(OV_SCCB_COM7,&temp))

Ich werde nachher mal anpassen und mich überraschen lassen. ;-)

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Dieter F. schrieb:
>
1
> volatile int height = 480;
2
> volatile int width  = 640;
3
> volatile int BytesPerPixel = 3;
4
>
Die werden vom Terminal mit einem Klick auf  get Camera Status auf die 
aktuellen Einstellungen angepasst.
> Passt das zu dem, was Du einlesen willst? Würde bedeuten, dass Du RAW
> Bayer (height / width) einlesen möchtest. Da kommt aber nur 1 Byte pro
> Pixel und nicht 3 (ob die Register-Werte dazu passen habe ich nicht
> geprüft).
Im Processed BayerRaw kommt nur eins an? Da hätte ich drei gedacht.

> 3 Byte pro Pixel kann die Kamera gar nicht - die passen auch nicht in
> den Fifo bei der gewählten Auflösung, so weit mir bekannt. Damit wird
> nichts vernünftiges herauskommen.
Im QCiF auch nicht?

> Das
>
>
1
>    //Reset the Write Pointer, (not sure, if that will work)
2
>    OV7670_ResetFifoWritePointer();
3
>
>
> gehört nicht ans Ende von "OV7670_captureNewImage" - keine Ahnung, ob es
> stört.
Richtig, ich hatte nur irgendwo gelesen, dass der write pointer immer x 
Positionen vor dem read Pointer sein muss und dass ein reset das umgehen 
würde... Kann mich aber auch irren. Werde ich nochmal prüfen

von Dieter F. (Gast)


Lesenswert?

David D. schrieb:
> Im QCiF auch nicht?

Nein:

Application Note Punkt 2 - Tabelle (achte auf die "or")

Dann 2.1 erster Absatz:

RAW Bayer nur bei VGA, Processed Bayer für VGA und QVGA. Alle anderen 
Ausgabe-Formate gelten für VGA und alle Auflösungen kleiner CIF. Kein 
Ausgabe-Format hat 3 Byte für die Farb-Information.

Hier ist es schön dargestellt:

http://joe-c.de/pages/optik/kamerasensor.php

Beitrag #5730463 wurde vom Autor gelöscht.
von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

Hallo David,

David D. schrieb am 09.02.2019 17:19:
> @Igel kannst du vielleicht nochmal deine aktuelle Write und
> Read sequenz einstellen? Ich würde die gerne abgleichen.

Ich habe den wichtigen Part aus meinen Code, nämlich das Auslesen des
OV7670->FiFo und das Auslesen FiFo->LCD-Display, hier angehängt.

Das ganze habe ich mit vielen Kommentaren gespickt.
Der für Dich relevante Teil startet ab:
"// The interesting part starts here"

Als Register-Settings benutze ich die Colorbar-Einstellungen aus meinem
letzten Posting hier:
Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)"

Eine Zeile hat - wie oben geschrieben - 313 Pixel.

Viele Grüße

Igel1

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

so, ich habe mal alles für David passend gemacht, meinen 
High-End-Adapter etwas umgebaut:
RST zum AVR verdrahtet, ein Pegelwandler war ja noch frei
OE direkt auf GND
STB offen, ist ja sowieso nur ein OUT der Cam, der jetzt nicht gebraucht 
wird.

Compiliert, geflasht, soweit ok. Terminalprogramm geht auch, Baudrate 
bin ich auf meine 230400 gegangen.
Init geht, Status holen geht, Register lesen geht.
Register schreiben ändert den Registerwert nicht, da muß ich noch 
nachschauen, Blid holen bleibt so natürlich auch hängen.
Ich habe mal die Startsequenzen imLA verglichen, bei mir startet ja 
Einlesen automatisch, ist das kurze L bei WRST nach der Mitte.
Ab da wird auch gelesen, der H-Impuls bei WR,
und übertragen, die H-Impulse bei RCK.

Ich habe die Auflösung extra so gelassen, weil ich den kompletten Ablauf 
nach Reset sehen wollte.

PS: bediene ich Dein Terminal falsch oder stellt Du wirklich im Read 
Settings die Werte als HEX und im Write Settings als DEZ dar?
Falls ja: geht's noch? Soll ich mir zum Vergleichen da einen 
Taschenrechner daneben legen?
Falls mein Fehler bitte ein Hinweis.

ok, Register schreiben scheint jetzt zu gehen.

Hast Du die volatile im Lotto gewonnen?
//Initial Variables
volatile int Programstatus = -1;
volatile int height = 480;
volatile int width = 640;
volatile int BytesPerPixel = 3;
volatile char Byte=0;

warning: invalid conversion from 'volatile int*' to 'int*' 
[-fpermissive]
      UART0_rx_work(&Programstatus);

ich habe die volatile da erstmal alle rausgeworfen, ich habe auf Anhieb 
keinen Sinn dafür gefunden?

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

@David:

Oh ha - jetzt gibt's kein Entrinnen mehr: Michael hat Deinen Code in der 
Mangel ...


@Michael:

Nachdem Dieter bei David das Missverständnis "Ein Pixel hat 3 Byte" 
aufgeklärt hat, sollte David jetzt eigentlich das Ziel aus eigener
Kraft erreichen können.

Auch wenn es Dir in den Fingern juckt - ich würde David die Chance
geben, sein Programm selbst ans Laufen zu bringen.

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Hallo zusammen,

@Dieter
>Kein Ausgabe-Format hat 3 Byte für die Farb-Information.
Siehe Tabelle 2-1 im application guide: Processed Bayer RGB sehe ich da 
schon als 3Byte pro Pixel nämlich jeweils eins für R eins für G und eins 
für B. Vielleicht vertue ich mich aber auch und es ist stattdessen nur 1 
pro pixel und ich bekomme trotzdem wieder nur die jeweilige 
Farbinformation wie beim normalen RAW Bayer. Die Auflösung zum 
"Processed Bayer RGB" hat dein Link ja leider nicht entschlüsseln 
können.

@Igel
>Ich habe den wichtigen Part aus meinen Code, nämlich das Auslesen des
>OV7670->FiFo und das Auslesen FiFo->LCD-Display, hier angehängt.
Danke! werde ich mir nachher direkt anschauen

@Michael
>PS: bediene ich Dein Terminal falsch oder stellt Du wirklich im Read
>Settings die Werte als HEX und im Write Settings als DEZ dar?
nein alles HEX, nur das 0x fehlt noch beim Read.(das mit dem Write habe 
ich gestern erst implementiert und das mit eingebaut).
mehrere Register können übrigens geschrieben werden indem eine Textdatei 
geladen wird. Format in der Textdatei: Pro Zeile ein Register:
Adresse;Value;ggf Kommentar
Beispiel:
1
0x12;0x0D
2
0x13;0xC1;Hier könnte jetzt ein Kommentar stehen
3
...
dann steht es in der rechten Box. dann auf write Device Settings gehen 
und hoffen, dass alle Register ohne Fehler geschrieben wird. (mit Read 
All Register kann gesehen werden, was die einzelnen Register im 
uController enthalten.(Auch hier hoffen, dass alles durchläuft. Den 
Fehler warum es manchmal-scheinbar zufällig- abbricht habe ich leider 
noch nicht gefunden.)

mit get Camera status dann die Auflösung (die ganzen volatile values) 
anpassen. Volatile deshalb, weil ich mir gedacht habe, dass der compiler 
sie evtl. wegoptimiert, weil sie ja evtl. aus seiner Sicht nicht 
gebraucht werden.

@Igel
>Nachdem Dieter bei David das Missverständnis "Ein Pixel hat 3 Byte"
>aufgeklärt hat, sollte David jetzt eigentlich das Ziel aus eigener
>Kraft erreichen können.
Leider nein... Weil sich dieses "Missverständnis" auf das RAW Format 
bezieht wir aber ja im QVGA und RGB565 unterwegs sind. Und ich da die 
gleichen "Probleme" habe.

>Auch wenn es Dir in den Fingern juckt - ich würde David die Chance
>geben, sein Programm selbst ans Laufen zu bringen.
Ich möchte kein fertiges Programm vor die Füße gesetzt bekommen, sondern 
wissen was ich falsch mache. Daher möchte ich Michael nur ermutigen 
weiterhin meinen Code unter die Mangel zu nehmen und berechtigte Kritik 
zu äußern oder das Vorgehen zu hinterfragen. Nur so weiß ich, was ich 
ggf. auch falsch mache in meinem "Programmierstil" :D...

Aktuell komme ich ohne fremde Hilfe leider nicht weiter, weil ich nicht 
weiß wo ich ansetzen soll. Also Michael: Zerfetz meinen Code :D. Zum 
Terminal kann ich gerne auch noch weitere Fragen beantworten oder 
Vorschläge in die Bedienung mit einfließen lassen.
Ich gebe zu es ist nicht ganz Intuitiv... sondern ebenfalls Historisch 
gewachsen.

ABER ein beliebiges Farbbild zu übertragen (auch im RGB565) 
funktioniert. Es liegt also mehr auf uController Seite und nicht am 
Terminal.

Ich danke euch für euren hoffentlich weiterhin konstruktiven (oder von 
Michael destruktiven :D) input.

Danke

Gruß David

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Auch wenn es Dir in den Fingern juckt - ich würde David die Chance
> geben, sein Programm selbst ans Laufen zu bringen.

das Jucken beschränkt sich so ziemlich nur darauf, seinen Code hier zum 
Laufen zu bekommen.
Zur Kamera selbst habe ich eigentlich garnichts vor, schon deshalb 
nicht, weil ich sie nicht nutzen will. Sie war halt nur da und der 
Mega328 auch und den, das behaupte ich einfach mal, ganz gut kenne.

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Lesenswert?

David D. schrieb:
> Processed Bayer RGB sehe ich da
> schon als 3Byte pro Pixel nämlich jeweils eins für R eins für G und eins
> für B. Vielleicht vertue ich mich aber auch und es ist stattdessen nur 1
> pro pixel

Ja, Du vertust Dich - hast Du Dir mal den Link angeschaut? Processed 
Bayer wird sich lediglich auf die Optionen (Schärfe, etc.) auswirken. 
Muss man halt prüfen. Aber auch da gibt es nur ein Byte 
Farbinformationen pro Pixel (Verteilung höchstwahrscheinlich analog RAW 
Bayer, nur "nachgeschärft etc.) - aus meiner Sicht SICHER.

Die Kamera gibt NIEMALS 3 Byte pro Pixel aus. Nochmal - beachte die 
"or"-Angabe.

von David D. (saturi)


Lesenswert?

Dieter F. schrieb:

> Ja, Du vertust Dich - hast Du Dir mal den Link angeschaut? Processed
> Bayer wird sich lediglich auf die Optionen (Schärfe, etc.) auswirken.
Habe ich, aber da finde ich jetzt nichts, was auf das Schärfen eingeht.

> Die Kamera gibt NIEMALS 3 Byte pro Pixel aus. Nochmal - beachte die
> "or"-Angabe.
Ja ok, überzeugt ;-) hatte das "or" falsch interpretiert. Aber stimme 
jetzt mit dir überein. ein "or" steht dann also für das nächste Pixel 
steht dann auch im Einklang mit den übrigen Farbformaten. Thumb Up


@Michael
>das Jucken beschränkt sich so ziemlich nur darauf, seinen Code hier zum
>Laufen zu bekommen.

Das wäre klasse... Es ist meiner erstes "wirkliches" Projekt mit dem 
Ding...

von Dieter F. (Gast)


Lesenswert?

David D. schrieb:
> Habe ich, aber da finde ich jetzt nichts, was auf das Schärfen eingeht.

AEC, AGC, ABLC, white balance control, gamma control, SHARPNESS CONTROL 
(5.4) - keine Ahnung, was auch immer da berücksichtigt wird.

Deswegen weigere ich mich ja, irgendwelche Einstellungen blind 
abzutippen.

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> @Michael
>>PS: bediene ich Dein Terminal falsch oder stellt Du wirklich im Read
>>Settings die Werte als HEX und im Write Settings als DEZ dar?
> nein alles HEX, nur das 0x fehlt noch beim Read.(das mit dem Write habe
> ich gestern erst implementiert und das mit eingebaut).

ich habe hier Deine v0.3 von github am Laufen und da sieht die 
geschriebene u.ä. Datei so aus:
112;58
113;53
und das ist kein HEX. Falls das überholt ist, leg mal die aktuelle hin.

David D. schrieb:
> Ich danke euch für euren hoffentlich weiterhin konstruktiven (oder von
> Michael destruktiven :D) input.

ich habe mir jetzt mal meinen freien Pin als Debug-Output gesetzt.
Dein _delay_ms(5); in der while81) auskommentiert, am Anfang von while 
das Pin auf H und am Ende auf L geetzt.
Weiß jetzt auch nicht, warum er da warten sollte.
Die zykluszeit der while81) ist 2,55µs, ok, Dein switch() wird also 
sauber durchlaufen.
Dein Fifo-Konstrukt muß ich mir erst ansehen, mir gefallen 
Funktionsaufrufe in einer ISR ohnehin nicht sonderlich.
Speziell weil Du da UART0_rx_in(UDR0); für das Fifo-Handling aufrufst, 
Deinen Rückgabewert von int UART0_rx_in (char input) aber völlig 
ignorierst.
Wer behandelt dann wie return 0; bei Fifo voll?

Ich vermute mal, da bleibt er auch irgendwo hängen.

PS: ich stochere ja öfter in fremden Code rum, schon um Anleihen zu 
tätigen. ;-)
Alles, was Du da Richtung IO hast, ist ja AVR-spezifisch, für mich gibt 
es da keinen Grund, Portzugriffe usw. um 3 Ecken zu machen.
Wenn es einen HAL gäbe wie z.B. auch in der AdrduinoIDE, wo eben ein 
pinMode(6,OUTPUT); den von den Erstellern als Pin 6 bezeichneten Pin auf 
OUT setzt, egal, ob AVR, SAM, STM, ESP usw., dann macht das wieder Sinn, 
dann kann ich komplett ignorieren, wie das erreicht wird, ob da ein 
DDR-Register beim AVR, ein halbes Dutzend bei anderen µC oder noch eine 
IO-Matrix bedient werden muß.
Hat eben den Preis, daß ein pinMode(6,OUTPUT); wesentlich länger braucht 
als ein DDRB |= (1 << PB6);

Gruß aus Berlin
Michael

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Michael U. schrieb:
> ich habe hier Deine v0.3 von github am Laufen und da sieht die
> geschriebene u.ä. Datei so aus:
> 112;58
> 113;53
> und das ist kein HEX. Falls das überholt ist, leg mal die aktuelle hin.
richtig... in die Datei wurden Dezimal zahlen geschrieben... war ein 
Fehler, anbei die 0.4 Version in der der Fehler behoben wurde (und auch 
noch andere Sachen verbessert und Altlasten entfernt:
https://github.com/igittigitt/ov7670/tree/TWI-Interfac/OV7670-Terminal-Releases


> Speziell weil Du da UART0_rx_in(UDR0); für das Fifo-Handling aufrufst,
> Deinen Rückgabewert von int UART0_rx_in (char input) aber völlig
> ignorierst.
> Wer behandelt dann wie return 0; bei Fifo voll?
niemand... dann läuft es einfach ins Leere... ich weiß aber leider nicht 
wie ich es besser machen soll :/

Ich gebe zu, dass es, wenn die Datenpins auf einem Address Byte liegen 
es sicher einfach wäre die auszulesen, aber so habe ich mir die 
Flexibilität beibehalten, die Kamera auf einen beliebig anderen AVR 
anzuschließen, indem ich vlt. nicht noch zusammenhängende Ports frei 
habe. Auch wenn ich das im aktuellen Fall nicht brauche.

Gute Nacht und bis Morgen

Gruß
David

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> richtig... in die Datei wurden Dezimal zahlen geschrieben... war ein
> Fehler, anbei die 0.4 Version in der der Fehler behoben wurde (und auch
> noch andere Sachen verbessert und Altlasten entfernt:

Danke, gefällt mir so viel besser. :-)
Wenn Du jetzt noch unterschiedliche Registerwerte ind den beiden Fenster 
farblich makieren würdest... ;-)
Und wenn Du die Datei im Format einer Struktur, also z.B.
  { 0x7a, 0x24 },
  { 0x7b, 0x04 },
  { 0x7c, 0x07 },
dann könnte ich das soger direkt aus der Datei in meinen AVR_Source 
kopieren...
Duck und schnell ganz weit weg.... ;-)

David D. schrieb:
> Ich gebe zu, dass es, wenn die Datenpins auf einem Address Byte liegen
> es sicher einfach wäre die auszulesen, aber so habe ich mir die
> Flexibilität beibehalten, die Kamera auf einen beliebig anderen AVR
> anzuschließen, indem ich vlt. nicht noch zusammenhängende Ports frei
> habe. Auch wenn ich das im aktuellen Fall nicht brauche.

Deine Intension ist mir schon klar. Meine Meinung hatte ich ja schon am 
Anfang geschreiben: eine OV7670 an einem AVR (egal welchen) ist eine 
Spielerei und für mich nur der Spaß daran, ob es geht.
Ich könnte an mein Konstrukt durchaus noch einen ENC28J60 ranstricken 
und den alten Webserver da reinknoten. Ein BMP-Header voran und das Bild 
im Browser anzeigen.
Macht für mich aber keinen Sinn.
Auf einem ESP32 kann ich die Daten per I2S-DMA parallel "nebenbei" holen 
und die IOs auf fast alle IOs mappen ohne irgendwelche Nachteile. Auch 
ohne Fifo.
Da diskutiere ich aber lieber mit der OV2640 rum, etwas bessere 
Auflösung und wahlweise gleich JPEG.

David D. schrieb:
>> Wer behandelt dann wie return 0; bei Fifo voll?
> niemand... dann läuft es einfach ins Leere... ich weiß aber leider nicht
> wie ich es besser machen soll :/

Wenn der FiFo voll ist, findet Dein UART0_rx_complete nie die gesuchten 
zeichen am Ende und niemand räumt den Fifio je wieder auf.
Ein fifo_full-Flag aus der ISR oder UART0_rx_in durchreichen und in der 
while(1) in main rigiros den Buffer aufräumen um wieder einen 
definierten Status zu bekommen?

Schönen Tag noch.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Hi Leute,

Uli S. hatte offenbar unseren Thread übersehen (oder für nicht passend 
erachtet) und eine Frage zum SCCB-Protokoll auf einem STM32F429 hier im 
Forum eingestellt:
Beitrag "OV7670 blockiert Bus nach senden des Registers"

Michael U. hat ihn auf mich verwiesen und ich habe Uli gerade meinen 
SCCB-Code spendiert:
Beitrag "Re: OV7670 blockiert Bus nach senden des Registers"

Dies nur für den Fall, dass unser Stolberger Hardcore-AVR-Kämpfer 
irgendwann auf den Weg der Tugend findet und sich doch zum ARM Prozessor 
bekehren lässt ...

Viele Grüße

Igel1

: Bearbeitet durch User
von David D. (saturi)


Lesenswert?

Hey Mitstreiter,

diese Woche ist leider ganz besonders schlimm bei mir.

@Michael:
>Und wenn Du die Datei im Format einer Struktur, also z.B.
>  { 0x7a, 0x24 },
>  { 0x7b, 0x04 },
>  { 0x7c, 0x07 },


mach ich dir, wenn das der Preis dafür ist, dass du dich weiter mit 
meinem Code auseinander setzt :) bekommst du spätestens morgen Abend.


Hat jemand schonmal mein Programm auf seiner Hardware ausprobiert? 
nicht, dass einfach meine HW kaputt ist …
 (nein ich habe es noch nicht geschafft eure auf meiner 
auszuprobieren... schäm)


Gruß
David

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> diese Woche ist leider ganz besonders schlimm bei mir.
kein Problem. Ich grabe das ja ohnehin nur bei Bedarf aus, ist dank 
meiner Adapterplatine jetzt auch kein Problem, das schnell 
zusammenzustecken.
Ein "Spezialkabel  für meinen LA werde ich mir noch löten, ist aber auch 
kein Aufwand.

David D. schrieb:
> mach ich dir, wenn das der Preis dafür ist, dass du dich weiter mit
> meinem Code auseinander setzt :) bekommst du spätestens morgen Abend.
Danke, keine Eile, dann kann ich Init-Sequenzen einfach mal im "meine" 
Software kopieren und testen.

David D. schrieb:
> Hat jemand schonmal mein Programm auf seiner Hardware ausprobiert?
> nicht, dass einfach meine HW kaputt ist …
Naja, zumindest hat Dein Terminalprogramm mit Deiner Software auf meinem 
AVR geredet, Registerkram ging inzwischen offenbar auch.
Mit Deiner v0.4 habe ich aber noch nicht wirklich weitergetestet, mal 
schauen, ob ich Bilddaten bekomme ohne hängen zu bleiben.
Kann aber sein, daß ich da auch erst am Wochenende wirklich zu komme.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Hi Leute,

habe gestern Nacht mein UART endlich auf meinem STM32F429 in die Gänge 
gebracht (ein echter Kraftakt ...). Nun könnte ich Davids 
PC-Bilddarstellungsprogramm einmal ausprobieren.

Allerdings habe ich dazu noch zwei Fragen. Und da ich nicht unseren 
gesamten Thread hier nochmals durchflöhen wollte, stelle ich sie hier 
einfach:

- In welchem (Protokoll)format sendet David die Bilddaten an sein
  PC-Programm?   RGB565, Big-Endian?  Oder läßt er gar unterschiedliche
  Formate zu?

- In welchem (Protokoll)format sendet David Befehle von seinem
  PC-Programm an seinen MC? Und insbesondere: welche Bytefolge sendet
  David, um ein Register im OV7670 zu setzen?

Bitte seht's mir nach, wenn ich mir die Fragen bei aufmerksamer Lektüre 
des Threads hätte selbst beantworten können.

Viele Grüße

Igel1

: Bearbeitet durch User
von David D. (saturi)


Angehängte Dateien:

Lesenswert?

Guten Abend,

>kein Problem. Ich grabe das ja ohnehin nur bei Bedarf aus, ist dank
>meiner Adapterplatine jetzt auch kein Problem, das schnell
>zusammenzustecken.
Davon habe ich mich inspirieren lassen, weil ich eben auch nur sehr 
eingeschränkten Platz habe und schon immer rumgenörgelt wird, dass mein 
"Scheiß" den ganzen Schreibtisch blockiert :D...
Das einzige was mir noch fehlt ist der 2x11 Pin header für die Kamera, 
dann fange ich auch das Löten an.

@Igel:
>- In welchem (Protokoll)format sendet David die Bilddaten an sein
>  PC-Programm?   RGB565, Big-Endian?  Oder läßt er gar unterschiedliche
>  Formate zu?

Ja tut es, und zwar (sollte) es das automatisch tuen. Bisher 
implementiert sind das RGB565 format 1.Byte RRRRRGGG 2. Byte GGGBBBBB, 
und das YUV (wobei hier nur das Y interpretiert wird (hier sind dann 
auch noch abhängigkeit von der eingestellten Byte Order noch nicht 
implementiert, also würde ich raten auf RGB565 zu bleiben)


Sowohl das Farbformat als auch die Auflösung werden über Register 0x12 
erkannt und mit dem klick auf "get Camera Status" zuerst vom controller 
gelesen, ausgewertet und dann die Informationen xRes, yRes und 
BytesPerPixel an den Controller gesendet. Hier werden sie für die 
Ausleseroutine des FiFos benutzt.

Bei einem klick auf take picture complete, wird der ganze Frame direkt 
gesendet (ohne abschluss zeichen) bei take picture RbyR, Zeilenweise mit 
jeweils einem CR+LF am ende.


> In welchem (Protokoll)format sendet David Befehle von seinem
>  PC-Programm an seinen MC? Und insbesondere: welche Bytefolge sendet
>  David, um ein Register im OV7670 zu setzen?


folgende Kommandos kann der uC empfangen:
CommandAuswirkung  Byte1  Byte2  expected Return Value
0x01  Read Register  Register Address  -  1 Byte register Value
0x02  Write Register  Register Address  newRegisterValue  1 Byte 
Errorcode
0x03  Take Picture      1 Row  with CR+LF
0x04  set xResolution  Resolution x MSB  Resolution x LSB  1 Byte 
xresolution Value
0x05  set yResolution  Resolution y MSB  Resolution y LSB  1 Byte 
yresolution Value
0x06  set BytesPerPixel  BytesPerPixel    1 Byte bytesperpixel Value
0x08  initialisiere Kamera      Error Code
0x0A  request new Line      1 Row with CR+LF
0x0B  request Line repeat      1 Row with CR + LF
0x0C  take complete Picture      complete frame in px

Ich hoffe, dass ist lesbar
Edit: hmm wohl kaum. Ich schaue mal, dass ich vlt. noch ne Tabelle 
herbekommen, anbei aber schonmal ein Screenshot von der Excel Tabelle:

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Hallo David,

Danke für die Mühen.
Leider lese ich aus Deinen Ausführungen, dass Du Dein PC-Programm und
Dein MC-Programm ziemlich eng miteinander verknüpft hast.

Wollte ich also Dein PC-Programm nutzen, so müsste ich auch die
entsprechenden Register-Leseroutinen uns sonstigen Routinen auf
meinem ARM einbauen. Machbar wäre das, aber wiederum Aufwand.

Gibt es in Deinem Programm auch eine Möglichkeit, statt die Parameter
vom MC auszulesen und dann das Format automatisch zu setzen, das
ganze manuell im PC-Programm einzustellen?

Das wäre ideal für mich (... tssss - Wünsche haben die Leute ...)

Viele Grüße

Igel1

von Andreas S. (igel1)



Lesenswert?

Hi,

anbei mein erstes per USART übertragenes Bild.
Angezeigt bei http://rawpixels.net/

Auf diese Website kann man Bilddateien unterschiedlichsten Formats 
hochladen und bekommt die Inhalte dann angezeigt.

Echt praktisch in meinem Fall (natürlich hätte ich lieber David's 
Programm dafür genutzt, aber ... siehe voriger Beitrag ...)

Viele Grüße

Igel1

von Andreas S. (igel1)



Lesenswert?

... und weil's gerade so gut läuft, hier noch ein "richtiges Bild" - 
ebenfalls per USART übertragen.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> ... und weil's gerade so gut läuft, hier noch ein "richtiges Bild" -
> ebenfalls per USART übertragen.

na geht doch. :-)
Falls Du unter Windows unterwegs bist, nimm Irfanview, brauchst Du kdas 
Internet nicht. Soll angeblich auch unter Linux mit Wine laufen.
Dann einfach laden RAW.

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Hi David,

Du hast geschrieben:
> Sowohl das Farbformat als auch die Auflösung werden über Register 0x12
> erkannt und mit dem klick auf "get Camera Status" zuerst vom controller
> gelesen, ausgewertet und dann die Informationen xRes, yRes und
> BytesPerPixel an den Controller gesendet. Hier werden sie für die
> Ausleseroutine des FiFos benutzt.

Habe eine Nacht darüber geschlafen, verstehe die Zs.hänge aber leider 
nicht richtig:

Frage 1:

Warum liest Du Register 0x12 aus, um daraus die Dimensionen des Bildes 
abzuleiten und diese dann wiederum zurück an den MC zu senden?

Frage 2:

Wie wir festgestellt haben, haben die Bilder, trotz ausgewähltem QVGA, 
teilweise nur Zeilenlängen von 311 oder 313 Pixeln. Wie berechnest Du 
dann aus Register 0x12 die richtige Zeilenlänge?

Frage 3:

Und dann verstehe ich das CR+LF am Ende der Übertragung einer Zeile 
nicht. Was ist Sinn und Zweck der beiden Zeichen?

Frage 4:

Was genau macht der Befehl 0x03 ?

Frage 5:

Was ist der Unterschied zwischen Befehl 0x03 und 0x0B ?

Ich gebe zu: ich könnte sicherlich auch alles mit Fleiß und Ausdauer aus 
Deinem Code ableiten, aber dazu bin ich ein bisschen zu bequem ...

Viele Grüße

Igel1

: Bearbeitet durch User
von Andreas S. (igel1)



Lesenswert?

Hi David,

habe soeben Dein "OV7670-Terminal_V0.4.zip" heruntergeladen und 
ausprobiert.

Ich muss gestehen, dass ich einiges darin nicht verstehe.
Bitte sei trotzdem nicht frustriert: ich hatte auch kein 100%ig 
selbsterklärendes Programm erwartet - ist ja noch alles im Fluss ...

Zwei Dinge stachen mir sofort ins Auge:

Issue 1:

Der Rechte Rand Deines Fensters wird abgeschnitten. Intuitiv versucht 
man dann, das Fenster in Richtung X-Achse größer zu ziehen, aber das 
geht leider nicht - scheint fix zu sein.

Issue 2:

Ich habe versucht, in Deinem Reiter "Load Image" mein RGB565-file in 
Dein Programm einzuladen, um es dort anzeigen zu lassen. Leider wurde 
nur ein schwarzes Bild angezeigt. Dabei bin ich mir sicher, dass die 
Daten in dem Bild korrekt sind und formatmässig passen. Immerhin konnte 
ich ja dieselbe Datei auf http://rawpixels.net/ sauber als Bild anzeigen 
lassen.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Der Rechte Rand Deines Fensters wird abgeschnitten. Intuitiv versucht
> man dann, das Fenster in Richtung X-Achse größer zu ziehen, aber das
> geht leider nicht - scheint fix zu sein.

kann ich hier mit der v0.4 nicht nachvollziehen unter Win7-64. 
Fenstergröße passt beim Start und beide Richtungen lassen sich 
größer/kleiner ziehen.

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

>Frage 1:
>Warum liest Du Register 0x12 aus, um daraus die Dimensionen des Bildes
>abzuleiten und diese dann wiederum zurück an den MC zu senden?

Weil über 0x12 ja die vordefinierten Auflösung oder das Farbformat 
definiert werden. Dann macht das Terminal eine fall unterscheidung.
Wenn QVGA dann Auflösung xxx yyy 2Bytes pro pixel. Die Werte für x y und 
Bytes per Pixel sind hardgecoded und werden je nach Fall Unterscheidung 
dann an den Controller gesendet


>Frage 2:
>Wie wir festgestellt haben, haben die Bilder, trotz ausgewähltem QVGA,
>teilweise nur Zeilenlängen von 311 oder 313 Pixeln. Wie berechnest Du
>dann aus Register 0x12 die richtige Zeilenlänge?
>eben genau durch diese "Hardgecodete
Eben genau über das Hardgecodete... nicht schön aber für den Anfang 
akzeptabel

>Frage 3:
>Und dann verstehe ich das CR+LF am Ende der Übertragung einer Zeile
>nicht. Was ist Sinn und Zweck der beiden Zeichen?
hiermit überprüfe ich, ob die Zeile vollständig angekommen ist, stimmen 
die beiden Zeichen nicht mit den beiden erwarteten überin wird ein Line 
Repeat gesendet und die gleiche Zeile wird nocheinmal übertragen. Komme 
zu wenig zeichen an, bricht der Bildaufbau einfach ab.

>Frage 4:
>Was genau macht der Befehl 0x03 ?
Bildaufnehmen und die erste Zeile senden.
>Frage 5:
>Was ist der Unterschied zwischen Befehl 0x03 und 0x0B ?
0x0B sendet nur die zuletzt gesendete Zeile nocheinmal. (Wenn vorher 
Zeilenweise ausgelesen wurde)
0x0C hingegen nimmt ein Bild auf und sendet den kompleeten Frame, vom 
ersten bis zum letzten Pixel im Bild ohne irgendwelche Steuerzeichen (CR 
LF etc.) also einfach pixel für pixel.

>Ich gebe zu: ich könnte sicherlich auch alles mit Fleiß und Ausdauer aus
>Deinem Code ableiten, aber dazu bin ich ein bisschen zu bequem ...
ein Problem

Andreas S. schrieb:

> Ich muss gestehen, dass ich einiges darin nicht verstehe.
> Bitte sei trotzdem nicht frustriert: ich hatte auch kein 100%ig
> selbsterklärendes Programm erwartet - ist ja noch alles im Fluss ...
Kein Problem... Ich auch nicht :D

> Issue 1:
>
> Der Rechte Rand Deines Fensters wird abgeschnitten. Intuitiv versucht
> man dann, das Fenster in Richtung X-Achse größer zu ziehen, aber das
> geht leider nicht - scheint fix zu sein.

Kann ich leider genau wie Michael nicht nachvollziehen bzw. 
reproduzieren. Welche auflösung benutzt du regulär auf deinem 
Bildschirm? das schaue ich mir heute Abend mal an.

> Issue 2:
>
> Ich habe versucht, in Deinem Reiter "Load Image" mein RGB565-file in
> Dein Programm einzuladen, um es dort anzeigen zu lassen. Leider wurde
> nur ein schwarzes Bild angezeigt. Dabei bin ich mir sicher, dass die
> Daten in dem Bild korrekt sind und formatmässig passen. Immerhin konnte
> ich ja dieselbe Datei auf http://rawpixels.net/ sauber als Bild anzeigen
> lassen.
Da hast du dir auch genau das rasugesucht, was noch nicht 
funktioniert... Auch das werde ich versuchen heute Abend zu 
implementieren ;-)

von Andreas S. (igel1)


Lesenswert?

Hi David,

Danke für die Erläuterungen - jetzt blicke ich etwas besser durch die 
Funktionsweise Deines Programms durch.

Könntest Du netterweise zu meinem vor-vorigen Posting auch noch etwas 
schreiben? 
(Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)").

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Kann ich leider genau wie Michael nicht nachvollziehen bzw.
> reproduzieren. Welche auflösung benutzt du regulär auf deinem
> Bildschirm? das schaue ich mir heute Abend mal an.

Hab's gerade nochmals auf einem anderen Rechner ausprobiert (Win7 x64) - 
lief dort ohne Probleme und auch ohne das Fenster-Clipping Problem. 
Fenstervergrößerung funktionierte ebenfalls.

Kann Dir erst morgen die Eckdaten zu dem ersten Rechner zusenden.

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Hallo zusammen,

anbei der neue Release mit:
- der Möglichkeit ein Struct zu speichern / zu öffnen
- ein Bild im RGB565 Format ohne jegliche Kommandos zu empfangen: 
Erwartet werden die RGB565 Bytes direct nacheinander ohne jegliches HREF 
oder VSYNC signal. (Falls man das auch so bei der Bildübertragung nennt)

https://github.com/igittigitt/ov7670/tree/TWI-Interfac/OV7670-Terminal-Releases

@Igel
Bild öffnen geht leider noch nicht. Dafür müsste ich von dir noch 
wissen, in welchem Format du die Bilder ablegst. auch einfach eine datei 
mit Byte nach Byte? oder siehts dadrin was anders aus?


Auch wenn ich noch nicht weiß, wie jetzt diese Änderungen des Terminals 
konkret bei der Lösungsfindung meines Codes hilft... :D

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Auch wenn ich noch nicht weiß, wie jetzt diese Änderungen des Terminals
> konkret bei der Lösungsfindung meines Codes hilft... :D

fühle ich mich jetzt mal angesprochen. ;-)
Ich will Deinen Code hier möglichst Original testen.
Mit der struct-Geschichte kann ich jetzt die Registersettings einfach im 
meinen spielenden Code werfen und schauen, ob das passt bzw. 
vergleichen, was nicht passt. Oder meine settmgs in Dein Terminal und 
testen.

Zum Bild bei mir: ich schicke den FiFo mit 320x240 Pixel, die 
fehlerhaften usw. sind mir erstmal eagl, gibt es am Rand eben einen 
fehlerhaften Streifen.

Es kommt entweder RGB565 in 2 Byte so wie sie aus dem FiFo kommen, ob 
das big- oder little Endian ist, spielt keine Rolle. Variante 2 ist YUV 
nur das Y-Byte. Die akommenden Daten schreibe ich bei mir auf dem PC mit 
TeraTerm direkt in eine Datei test.raw. Name und Endung sind eigentlich 
egal, zur Anzeige nutze ich Irfanview, dem kann ich alles wichtige zum 
RAW-Format einstellen. Es gibt keinerlei Kennung oder Header, nur die 
RAW-Daten aus dem FiFo.
Bei Deinem Terminal ist es gut, das ich mit den Registerwerten direkt 
rumspielen kann. Ob jetzt gespeichert werden kann oder es eine direkte 
Anzeige gibt, isr mir da eigentlich hier völlig egal.
Außer 320x240 in RGB565 oder YUV als 8Bit Graustufen (Y-Byte) macht für 
mich eigtlich im Moment nichts Sinn. Höhere Auflösung passt nicht in den 
FiFo und weniger finde ich quatsch.
Andere Formate als diese beiden würden ja nur Sinn machen, wenn man die 
Bilddaten im Zielprogramm selber weiter verarbeiten wollte oder.

Alle Einstellungen zum Analogteil wie Weißabgleich, Belichtung usw. usw. 
bzw. zum DSP kann ich auch so durchspielen.
Eine echte Verwendungsabsicht habe ich ohnehin nicht in der Kombi 
Mega328/OV7670.
Also bleibt es letztlich nur als Test für Deine Programmierung auf dem 
AVR.

230400 läuft hier mit dem Ardiono UNO und em 32U4 als USB-Wandler 
stabil, wenn es da Übertragungsfehler geben würde, müßten die eine 
Ursache haben, der ich nachgehen würde. Warum der Nano mit dem CH340 
auch 1MBit usw. stabil macht und der 32U4 nicht, habe ich keine Lust zu 
ergründen...

Gruß aus Berlin
Michael

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

Völlig OT: mit diesem 64x32 RGB-Display habe ich mir im Moment die Zeit 
vertrieben... Hatte mein BEkannter gekauft und nach eiern Woche das 
Handtuch geworfen (das will was heißen!) und es mir in die Hand 
gedrückt.
Nach einer knappen Woche war ich am gleichen Punkt: nichts geht, 
wentweder ein paar sinnlos leuchtende Striche oder Flächen oder 
schwarzes Display.
Der Zufall hat mich vorgestern einen Thread dazu finden laasen. Das 
Display spielt bei keinem wirklich, Stromquellen-Schieberegister für die 
Zeilen und Decoer/MosFET-IC für die Spalten. Beides China, chinesiche 
Datenblätter in denen alles wichtige nicht drinsteht...
Da es in dem Forenthread zumindest Erkenntnisse und Ansätze gabe (einer 
oder beide IC-tyoen sind nicht asymcron-statisch wie es die Datenblätter 
suggereiren, sondern das Schiebereigster möchte irgendwie syncron 
zwischen SPI/Latch-Enable und /OE bedient werden.
jetzt muß ich mir erstmal in Ruhe anschauen, was ich da genau treibe, es 
ist jetzt stabil, der Ablauf aber reines ändern-flashen-wundern gewesen.
Die Ali-Händler bieten diese Displays mit diesem Chipset seit rund 3 
Wochen auch nicht mehr an wegen dieser Probleme.

So, wollte ich einfach mal loswerden. :-)

PS: das Display hat 64x32 Pixel mit 3mm LED-Abstabd. Sehr schönes Teil 
für den Preis.

Gruß aus Berlin
Michael

: Bearbeitet durch User
von David D. (saturi)


Lesenswert?

Aber schick aussehen tut es! :D

wo bekommt ihr eigentlich eure Elektrobauteile her? Bin auf der suche 
nach 2x11 Buchsenleisten, aber >5€ bei Reichelt nur für den Versand ist 
mir zu blöd...

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

David D. schrieb:
> Hallo zusammen,
>
> anbei der neue Release mit:
> - der Möglichkeit ein Struct zu speichern / zu öffnen
> - ein Bild im RGB565 Format ohne jegliche Kommandos zu empfangen:

Juhuuuu - Weihnachten ...

> Erwartet werden die RGB565 Bytes direct nacheinander ohne jegliches HREF
> oder VSYNC signal. (Falls man das auch so bei der Bildübertragung nennt)

Supi ...


> https://github.com/igittigitt/ov7670/tree/TWI-Interfac/OV7670-Terminal-Releases

... schon gezogen ...

> @Igel
> Bild öffnen geht leider noch nicht. Dafür müsste ich von dir noch
> wissen, in welchem Format du die Bilder ablegst. auch einfach eine datei
> mit Byte nach Byte?

Genau.

> oder siehts dadrin was anders aus?

Nö.

> Auch wenn ich noch nicht weiß, wie jetzt diese Änderungen des Terminals
> konkret bei der Lösungsfindung meines Codes hilft... :D

Hmmm - ich würde das eher eine selbstlose Spende nennen, für die ich 
mich recht herzlich bedanken möchte!

Leider stürzt Dein Programm im "Manuellem Modus" beim Versuch "Bild 
empfangen" sang und klanglos bereits nach ein paar Zeilen Übertragung 
(115200 baud, 8N1) ab - siehe Bild im Anhang.

Fehlercodes waren:
1
Problemsignatur:
2
  Problemereignisname:  CLR20r3
3
  Problemsignatur 01:  OV7670-Terminal.exe
4
  Problemsignatur 02:  1.0.0.0
5
  Problemsignatur 03:  5c67f336
6
  Problemsignatur 04:  OV7670-Terminal
7
  Problemsignatur 05:  1.0.0.0
8
  Problemsignatur 06:  5c67f336
9
  Problemsignatur 07:  6c
10
  Problemsignatur 08:  1c
11
  Problemsignatur 09:  System.NullReferenceException
12
  Betriebsystemversion:  6.1.7601.2.1.0.256.4
13
  Gebietsschema-ID:  1031
14
  Zusatzinformation 1:  0a9e
15
  Zusatzinformation 2:  0a9e372d3b4ad19135b953a78882e789
16
  Zusatzinformation 3:  0a9e
17
  Zusatzinformation 4:  0a9e372d3b4ad19135b953a78882e789
18
19
Lesen Sie unsere Datenschutzbestimmungen online:
20
  http://go.microsoft.com/fwlink/?linkid=104288&clcid=0x0407
21
22
Wenn die Onlinedatenschutzbestimmungen nicht verfügbar sind, lesen Sie unsere Datenschutzbestimmungen offline:
23
  C:\Windows\system32\de-DE\erofflps.txt

Das Clipping-Problem existiert leider ebenfalls noch:
Der rechte Rand des Programm-Windows wird abgeschnitten und das gesamte 
Window läßt sich nicht über die existierende Breite hinaus aufziehen - 
wohl aber verkleinern.

Meine Auflösung: 1920 x 1200 TrueColor (32bit), Windows 7 x64. Wenn ich 
das Programm starte, so nimmt es von Anfang an die gesamte 
Bildschirmbreite ein und wird am rechten Rand abgeschnitten - wie weiter 
oben in einem meiner vorigen Postings gezeigt.

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

@Michael:  Schickes Display - versuche doch mal mit der OV7670-Kamera 
die Uhrzeit abzulesen - das wäre vermutlich genau die richtige 
Herausforderung für einen Hobbyisten Deines Kalibers   :-)

Viele Grüße

Igel1


PS:  Juhu, gewonnen: erster Beitrag in der dritten MC-Threadseite.

: Bearbeitet durch User
von David D. (saturi)


Lesenswert?

Glückwunsch:D

> Leider stürzt Dein Programm im "Manuellem Modus" beim Versuch "Bild
> empfangen" sang und klanglos bereits nach ein paar Zeilen Übertragung
> (115200 baud, 8N1) ab - siehe Bild im Anhang.


Das sollte nicht so sein :D ... Hmm hab eine Vermutung ab2r kannst du 
mir genau sagen was du machst? Du hast aber schon die x y und Bytes per 
Pixel Felder mit integren gefüllt?

Ich geh der Sache nachher auf den Grund, wenn ich wieder zuhause bin

von David D. (saturi)


Lesenswert?

Problem gefunden!

Da sieht man, dass ich kein gelernter Programmierer bin ... ich sollte 
doch öfter mit exceptions arbeiten...

Naja, hier fürs erste die neuste Version, mit der du jetzt aber ein Bild 
empfangen können solltest.

https://github.com/igittigitt/ov7670/tree/TWI-Interfac/OV7670-Terminal-Releases

Bei Problemen einfach wieder den report und das Vorgehen schreiben :D 
dann finde ich die Fehler schon.. hoffentlich

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

David D. schrieb:
> Problem gefunden!

Na wenn das mal keine Weltklasse-Supportzeiten sind, dann weiß ich auch 
nicht mehr :-)

Also: der Durchbruch ist fast geschafft (wie Du im Anhang sehen kannst).
Aber: Der Bildaufbau geht nur die ersten Zeilen flott und kommt dann 
seltsam ins Stocken. Erst wenn mein Bild zu ende übertragen ist, 
flutscht Dein Bildaufbau wieder weiter, bricht dann aber bei Zeile 90 
ab.

Offensichtlich wurden aber alle Pixel eingeladen - denn wenn ich ein 
(oder manchmal gar mehrere) weiteres, neues Bild übertrage, so wird das 
alte, abgebrochene Bild zuende aufgebaut - erst bis Zeile 183, dann beim 
nächsten Bildsenden bis Zeile 239 - fertig.

Ich sende mit 115200 baud, 8N1.

Das Verhalten ist nicht ganz deterministisch - manchmals werden mehr 
Zeilen übertragen und dann bricht's ab, manchmal weniger.

Viele Grüße

Igel1


PS:  ... bin jetzt mal ein Weilchen weg ...

von Michael U. (amiga)


Lesenswert?

Hallo,

ich habe jetzt noch nicht wirklich was mit dem terminal weitergemacht, 
aber das Window-Problem ist hier noch nie aufgetrreten.
Einen Absturz hat es zumindest auch noch nie gegeben, allerdings bekomme 
ich sehr häufig eine keine Reaktion mehr nach dem Absenden eines 
Kommandos.
Beispiel: connect -> ok, Ausgabe im Logfenster kommt
Kamera initialisieren -> ok, Ausgabe im Logfenster kommt
get camera status -> ok, Ausgabe im Logfenster kommt, Registerinhalte 
werden angezeigt.
Jetzt kann ich eigentlich anklicken, was ich will:
take Picture complete,
take Picture RbyR,
Read Device Settings usw.
Es wird unten links angezeigt, es wird ins Log-Fenster geschreiben und 
es passiert nichts. Ich kann dann auch ein anderes Kommando anwählen, 
wie gehabt.
Safe File, Open File usw. funktionieren aber weiterhin richtig.

Darüber muß ich erstmal nachdenken...

Andreas S.: was ich im Moment garnicht verstehe: ich lese in meinem 
Programm von der Kamera in den FiFo:
- auf VSYNC LOW warten um sicher zu sein, daß ich nicht in einen aktiven 
VSYNC gerate
- auf VSYNC HIGH warten
- WRST auf LOW
- auf VSYNC LOW warten (Endes des SYNC-Impulses)
- WRST auf HIGH
- WR auf HIGH
- auf VSYNC HIGH warten (beginn des SYNC-Impulses)
- WR auf LOW

Dann lese ich im loop 240 Zeilen zu je 320 Pixel aus und schicke die 
raus.
Es müssen also in einer Zeile jeweils 32ß Pixel im FiFo sein, sonst 
bekäme ich nie ein Bild weil es von zeile zu zeile eine Veschiebung 
gäbe.
Das am Rand fehlerhafte Pixel sind, heißt für mich, daß da von der 
Kamera Schrottdaten in den FiFo kamen, aber eben in der richtigen 
Anzahl.

Gruß aus Berlin
Michael

von Tom (Gast)


Lesenswert?

Michael U. schrieb:
> Das
> Display spielt bei keinem wirklich, Stromquellen-Schieberegister für die
> Zeilen und Decoer/MosFET-IC für die Spalten. Beides China, chinesiche
> Datenblätter in denen alles wichtige nicht drinsteht...
Bisher habe ich in solchen Fällen die Chips gefunden, welche die 
Chinesen als Vorlage für die ihren genommen haben.
Mit den entsprechend besser lesbaren Datenblättern...

von Michael U. (amiga)


Lesenswert?

Hallo,

@Tom (Gast): ist mir bisher nicht gelungen... FM6126A

zurück zur OV7670: ich komme erst morgen dazu, das jetzt hier 
aufzuräumen und weiter zu testen.

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Lesenswert?

Tom schrieb:
> Bisher habe ich in solchen Fällen die Chips gefunden, welche die
> Chinesen als Vorlage für die ihren genommen haben.
> Mit den entsprechend besser lesbaren Datenblättern...

Zeig mal

von David D. (saturi)


Lesenswert?

Michael U. schrieb:
> take Picture complete,
> take Picture RbyR,
> Read Device Settings usw.
> Es wird unten links angezeigt, es wird ins Log-Fenster geschreiben und
> es passiert nichts. Ich kann dann auch ein anderes Kommando anwählen,
> wie gehabt.
> Safe File, Open File usw. funktionieren aber weiterhin richtig.

> take Picture complete,
> take Picture RbyR,
Setzten beide meine Software voraus, ich gehe davon aus, dass du diese 
benutzt, da sonst das Register Schreiben/Lesen ebenfalls nicht 
funktionieren würde.

Ich gebe zu, dass das Programm DERZEIT nicht wirklich intuitiv bzw. 
sogar sinnvoll zu bedienen ist. Ich bin aber gerade dabei, hier einiges 
anzupassen, das das Bild, das Andreas mit meinem Programm aufnehmen 
konnte, mir einen deutlichen Motivationsschub verpasst hat! :)

Nochmal eine ganz kurze Schritt für Schritt Anleitung wie es klappen 
sollte:
1) Com Port verbinden und Baudrate gleichhaben (brauche ich dir nicht zu 
sagen ;-)

2) Kamera initialisieren drücken. Jetzt sollten zwei einträge im Log 
erscheinen. 1. initialisiere Kamera, 2. initialisierung erfolgreich. 
Sollte hier die initialisierung fehlschlagen, einfach ein paar mal read 
register klicken und dann nocheinmal Kamera initialisieren versuchen. 
manchmal scheinen sich irgendwoher Bytes im PC-Seitigen COM Buffer 
einzufinden, die dann fälchlicherweise als ErrorCode identifiziert 
werden.

3) Klick auf get camera status. Jetzt sollte unbedingt, bei Version 0x76 
0x73 stehen. Damit ist sicher gestellt, dass die richtigen Register von 
der Kamera gelesen werden.

4. Register einstellen (entweder bei Write Register oder mit geladenen 
Settings.

Ich verwende aktuell:
0x11 0x00
0x12 0x16
0x40 0x14
0x42 0x08
0x15 0x00
(Ich hoffe ihr könnt die bestätigen)

5. get camera status klicken. Jetzt müssen Resolution auf QVGA und Color 
Format auf RGB565 stehen. Andere Formate werden noch nicht unterstützt 
und in einer internen Fallunterscheide fürs erste einfach übergangen. 
Dann tut sich bei deinem Bildaufbau garnichts.

6. Steht soweit erstmal alles richtig dar, kann jetzt mit take Picture 
complete oder take Picture RbyR ein Bild aufgenommen werden. (Ist auch 
etwas größer zu sehen unter dem tab _picture bei einem der Beiden 
Bildboxen das Häckchen zur Sychronisierung setzten.


Ich hoffe so hast du erfolg. Bitte um Rückmeldung :)

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Ich gebe zu, dass das Programm DERZEIT nicht wirklich intuitiv bzw.
> sogar sinnvoll zu bedienen ist. Ich bin aber gerade dabei, hier einiges
> anzupassen, das das Bild, das Andreas mit meinem Programm aufnehmen
> konnte, mir einen deutlichen Motivationsschub verpasst hat! :)

Das freut mich sehr für Dich - ich bin ganz sicher, dass wir Dein 
MC-Programm auch noch in die Gänge bekommen.

Wenn Du Zeit und Lust hast, den o.g. Fehler bzgl. Abbruch beim 
Bildaufbau noch zu fixen (vgl. mein letztes Posting: 
Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)") so 
wäre das super.

Bitte nenne mir einmal Deine Funktion, in der Du das Bild als ganzes 
überträgst (also ohne CR+LF), dann würde ich mir diese Funktion einmal 
gesondert angucken und brauche mich nicht durch den ganzen Code zu 
wühlen.

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Andreas S. schrieb:
> Wenn Du Zeit und Lust hast, den o.g. Fehler bzgl. Abbruch beim
> Bildaufbau noch zu fixen (vgl. mein letztes Posting:
> Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)") so
> wäre das super.


Tja... Da liegt der Hund begraben :D...

Ich denke, dass ist das gleiche Problem, dass ich auch bei den Read All 
Register auslesen habe. Es ist leider, wie du schon geschrieben hast, 
passiert es scheinbar zufällig... Ich kann mir da aktuell noch keinen 
Reim drauf bilden. Da kann ich leider nicht mit einem Hotfix dienen :D 
diese Problem verfolgt mich schon des längeren. Aber auch das werde ich 
hoffentlich irgendwann einmal finden

> Bitte nenne mir einmal Deine Funktion, in der Du das Bild als ganzes
> überträgst (also ohne CR+LF), dann würde ich mir diese Funktion einmal
> gesondert angucken und brauche mich nicht durch den ganzen Code zu
> wühlen.

Die ist relativ "einfach" gehalten:
es geht los in der main.c  case 0x0C:
1
OV7670_captureNewImage();
2
OV7670_ResetFifoReadPointer();
3
sendFrameBufferToUART (width, height, BytesPerPixel);

alle drei Funktionen aus der Datei: OV7670_withFifo.c
Die Namen sind denke ich selbsterklärend.

von David D. (saturi)


Angehängte Dateien:

Lesenswert?

Sonntag, 17.02.2019 .... irgendwann mitten in der Nacht,
David D. gelingt nach 1,5 JAHREN Entwicklungszeit der vermeintliche 
Durchbruch. Das bisherige Problem? BANAL!

Lediglich der pure Zufall brachte ihm die Erkenntnis. Er hatte sich 
entschlossen nur noch eine letzte Messung in dieser Nacht vorzunehmen, 
bevor er am nächsten Morgen mit der Betonwalze über diese Kamera fahren 
würde. Die Zielführende Messung war die Pulsdauer des WCK. Schon 
hundertmal durchgeführt, ohne Erfolg. Doch diesmal sollte es anders 
kommen, denn diesmal drehte er das Kamera Modul nicht einfach herum, um 
die Pins des Fifos zu erreichen. Dem Zufall geschuldet war, dass gerade 
seine 3. Hand Lupe in Reichweite stand, in die er die Kameraplatine 
einspannte und so die Verkabelung - eigentlich nicht hinnehmbar - unter 
Spannung setzte. Ein kurzer Klick auf take picture und den Blick zum 
Oszilloskop gewannt brachte die ernüchternde Erkenntnis nichts neues 
entdeckt zu haben. Ein Blick zurück zum Bildschirm, um erneut ein Bild 
aufzunehmen und.... WAS? eine Colorbar im Terminal Programm? Wo kommt 
die denn jetzt her? Nichts am uC verändert, nichts am Terminal Programm?
Kurze Augenblicke der Ratlosigkeit und dann der Gedanke daran, dass es 
wohl an der EMV liegen könnte, schließlich standen bei ihm einige 
elektrische Geräte in kurzer Distanz rund um den Versuchsaufbau. Kurz 
ausgespannt, wieder eingespannt.... und nichts...
Dann schoss ihm der Gedanke in den Kopf, evtl. mit der Oszilloskop Probe 
zwei Kontakte gleichzeitig berührt zu haben und so den FIFO in einen 
funktionierenden Zustand versetzt zu haben, doch nein, das erschien ihm 
dann doch zu unwahrscheinlich. Was konnte es also gewesen sein?
Es traf ihn wie einen Blitz: die Kabel der einzelnen 
Breadboardverbindern sind durch das einspannen in die andere Richtung 
gebogen gewesen als sonst, kurz nachgestellt und ZACK! die Colorbar ist 
da. Offenbar
handelt es sich um eine Kontaktschwierigkeit an den Steckern, die 
eigentlich allesamt bombenfest an der Kamera sitzen. Leichte 
Kontaktierungsprobleme die eine so fatale Wirkung haben, dass von dem 
eigentlichen Bild nichts mehr zu erkennen ist.

Ich danke an dieser Stelle dem Schicksal :D
Morgen wird also gelötet und dann bin ich wieder mit im Rennen!

Anbei zwei Bilder, 1x Colorbar (klar hier stimmt noch einiges nicht, 
aber es sind schonmal Balken zu sehen! und 2x meine Handy Taschenlampe 
in völliger Dunkelheit :D

Bis Morgen

Gruß

David

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Ich danke an dieser Stelle dem Schicksal :D
> Morgen wird also gelötet und dann bin ich wieder mit im Rennen!

erstmal Glückwunsch zum Erfolgserlebnis!
Und nun rate mal, warum ich mir die Adapterplatine gelötet habe...

Deine AVR-Source bei github ist die Deine aktuelle?
Ich habe es jetzt mal in ein AVR-Studio Projekt geworfen, muß nachher 
mal meinen Dragon raussuchen zum flashen.
Die 22 warnings ignoriere ich jetzt mal, sind zwar nicht ganz 
unberechtigt, stören aber die Funktion im Moment nicht.
Mal überlegen, ob ich den uralten GCC noch durch einen aktuellen 
ersetze, vermutlich nicht, es gibt da noch 3-4 fast 10 Jahre alte 
Projekte, an die ich vielleicht noch mal rangehe und wer weiß, ob die 
dann noch sauber laufen. ;-=

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Glückwunsch, David!
Welch ein Krimi, den Du da sehr nett und lustig beschrieben hast.
Besonders bei der Passage mit der Betonwalze musste ich lachen.

Sollte ich heute Zeit finden, so gucke ich mir Deinen Code einmal an.
Allerdings beweist das Colorbarbild, dass Du eigentlich schon alles 
richtig machst - bis auf die Farbdecodierung, also das Entnehmen der 
Farbinfio aus den 2 Bytes des RGB565.

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Die ist relativ "einfach" gehalten:
> es geht los in der main.c  case 0x0C:
> OV7670_captureNewImage();
> OV7670_ResetFifoReadPointer();
> sendFrameBufferToUART (width, height, BytesPerPixel);
>
> alle drei Funktionen aus der Datei: OV7670_withFifo.c
> Die Namen sind denke ich selbsterklärend.

Liegt hier die letzte Version Deines Codes:
https://github.com/igittigitt/ov7670/tree/TWI-Interfac/OV7670-AVR/OV7670-AVR
?

Scheint mir etwas alt zu sein - ausserdem gibt es dort keine Datei 
"OV7670_withFifo.c" sondern nur eine Datei "OV7670_with_Fifo.c", die 
immerhin schon 6 Tage alt ist. Die von Dir erwähnten Funktionen sind 
allerdings alle darin enthalten.

Bevor ich aber nun die falsche Datei analysiere, wollte ich erst einmal 
nachfragen ...

Viele Grüße

Igel1

PS: ... bin jetzt vermutlich erst einmal ein paar Stunden Wandern, dann 
Besuch, dann Familie ...

: Bearbeitet durch User
von David D. (saturi)


Lesenswert?

Michael U. schrieb:
> Und nun rate mal, warum ich mir die Adapterplatine gelötet habe...
Ich hatte es auch schon länger vor, aber nunja... daran hätte ich nicht 
gedacht.

> Deine AVR-Source bei github ist die Deine aktuelle?

jetzt ja, warum er es gestern nicht sync. hat, weiß ich nicht. (also im 
TWI branch)

>Allerdings beweist das Colorbarbild, dass Du eigentlich schon alles
>richtig machst - bis auf die Farbdecodierung, also das Entnehmen der
>Farbinfio aus den 2 Bytes des RGB565.


Nein, leider nicht. denn wenn ich mehrmals auslese bekomme ich 
verschiedene Colorbars, zum Teil auch im Bild gewechselt, also schein 
ich troztdem ein Problem mit dem Rücksetzen des Read oder Write Pointers 
zu haben...

>Scheint mir etwas alt zu sein - ausserdem gibt es dort keine Datei
>"OV7670_withFifo.c" sondern nur eine Datei "OV7670_with_Fifo.c", die
>immerhin schon 6 Tage alt ist. Die von Dir erwähnten Funktionen sind
>allerdings alle darin enthalten.

ja, jetzt die neuste online. Ich dachte mir, die Transferaugabe, sich 
einen "_" zu denken kriegt ihr hin ;-) ich meine natürlich diese.

https://github.com/igittigitt/ov7670/tree/TWI-Interfac/OV7670-AVR/OV7670-AVR

viel Spaß beim Wandern

von Michael U. (amiga)


Lesenswert?

Hallo,

github ist für mich normalerweise nur Quelle irgendwelcher 
Arduino/ESP-Geschichten... Ich durchsuche die commits da normalerweise 
nur, wenn ich nach einem bestimmten Problem suche, das evtl. schon 
behoben ist, aber noch nicht im relaese gelandet ist. Ich werde mit 
Sicherheit auch hier nur das aktuelle Archiv runterladen und daruf 
vertrauen daß es das ist: aktuell.

Bei mir zumindest einer der Gründe, weshalb ich z.B. lieber ein 
aktuelles zip mit einem Projekt nehme und nur vergleiche, welche Dateien 
neuer sind.

So, ich habe jetzt meinen Dragon mal angeworfen und das, was ich hier 
hatte, im alten AVR-Sturdo compiliert und geflasht. Soweit erstmal ok.
Cam-Init klappt, Register klappt, Einstellungen passen irgendwie nicht, 
er setzt bei get camera status VGA und will 480 Zeilen einlesen.
Reproduzierbar kommt er dabei bis Zeile 29 und dann steht der Laden.
Terminal zu, AVR Reset, alles von vorn und wieder Zeile 29. Alles bei 
230400 getestet.
ok, bei 19200 liest er nur eine Zeile ein.
Jetzt doch mal alle Dateien durch die im Link von Andres S. ersetzt, 
identisches Ergebnis.
Ich habe nur mein Pinout in OV7670_with_Fifo.h angepasst und die 
Baudrate in UART.c, dort X2 gesetzt wegen des kleineren Fehlers bei 
hohen Baudraten und UBRR0L entsprechend gesetzt.

Jetzt sind auch hier erstmal andere Sachen auf dem Plan.

Gruß aus Berlin
Michael

von Michael U. (amiga)


Lesenswert?

Hallo,

ok, Du bist schnell, David...
Sourcen aus Deinem letzten Link reingeworfen, compiliert.

Immernoch als default VGA und YUV? Warum nicht QVGA und RGB565?
Er macht beim Bild lesen alle 21-22 Zeilen eine Kaffepause, liest dann 
aber weiter. Muß ich später mal reinschauen, mit 230400 dauert ein Bild 
aus dem Fifo lesen doch sonst nur wenige Sekunden?

PS: er hat inzwischen 479 Zeilen abgeholt, für die letzte hat er keine 
Lust mehr...

PPS: nach Neustrta von Terminal und AVR läuft jetzt wieder kein Kamera 
Init, ich hör jetzt erstmal auf.

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> PS: er hat inzwischen 479 Zeilen abgeholt, für die letzte hat er keine
> Lust mehr

... weil er vermutlich bei Zeile 0 beginnt ...

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> ... weil er vermutlich bei Zeile 0 beginnt ...

da steht doch aber "hole Zeile 479 von 480"... ;-)

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> da steht doch aber "hole Zeile 479 von 480"... ;-)

Da steht vermutlich auch "hole Zeile 0 von 480" ?
Wenn ja, so passt ja alles (... bis auf die Optik ...)

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

Hi David,

weil sich Deine Camera->FiFo - Einleseroutine in einigen Punkten doch 
deutlich von meiner Routine unterscheidet, habe ich Deine Routine 
"OV7670_captureNewImage (void)" in ARM-Sprache übersetzt und 
anschließend testweise meine durch Deine Routine ersetzt:
1
void OV7670_captureNewImage_David (void)
2
 {
3
   //OV_WR_PORT &= ~(1<<OV_WR_PinNo); //Write Disabled (defined start value)
4
         Write_FIFO_WR(Bit_RESET);
5
6
   // while(!getValueOfPin(OV_VSync_PIN,OV_VSync_PinNo));  //Wait for VSync to indicate a new Frame
7
         while (!Read_VSYNC()) {}
8
9
   //OV7670_ResetFifoWritePointer();//Enable Write Pointer
10
         Write_FIFO_WRST(Bit_RESET);
11
         Delay(1);
12
         Write_FIFO_WRST(Bit_SET);
13
14
          
15
   //while(getValueOfPin(OV_VSync_PIN,OV_VSync_PinNo));
16
         while (Read_VSYNC()) {}
17
18
   //OV_WR_PORT |= (1<<OV_WR_PinNo);  //Write Enable so that the camera can write on the FrameBuffer
19
         Write_FIFO_WR(Bit_SET);
20
21
   //while(!getValueOfPin(OV_VSync_PIN,OV_VSync_PinNo)); //Wait for the next VSync Pulse, so the frame is complete
22
         while (!Read_VSYNC()) {}
23
24
   //OV_WR_PORT &= ~(1<<OV_WR_PinNo); //Write Disabled that the picture is safe in the Framebuffer
25
         Write_FIFO_WR(Bit_RESET);
26
27
  // _delay_ms(20);
28
29
   //Reset the Write Pointer, (not sure, if that will work)
30
   //OV7670_ResetFifoWritePointer();
31
}

Ergebnis: funktioniert auf meinem STM32F429 tadellos.

Viele Grüße

Igel1

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Hi David,

habe gerade einmal gesucht, ob Du "Output Enable" auf LOW ziehst, aber 
auf die Schnelle nichts dergleichen in Deinem Code gefunden.

Bitte schau selbst einmal nach, ob Du den Pin FiFo_OE des Moduls 
irgendwo in Deinem Programm auf LOW ziehst.

Viele Grüße

Igel1

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

Andreas S. schrieb:
> habe gerade einmal gesucht, ob Du "Output Enable" auf LOW ziehst, aber
> auf die Schnelle nichts dergleichen in Deinem Code gefunden.

er und auch ich haben ihn fest auf GND verdrahtet, wir sind ja alleine 
am Bus und lesen dort nur Daten.

PS: vorhin ganz vergessen...
Woltest Du nur ein Bild von der Uhrzeit auf dem Display oder soll noch 
eine Texterkennung mit formatierter serieller Ausgabe der Zeit rein? ;-)
PPS: ein Glück, meine Software geht noch undd as Geheimnis des 
UART-Wandlers auf dem UNO habe ich auch halbwegs ergründet bzw. 
umgangen, jetzt also wieder mit 1MBaud.
Mit dem Licht kommt sie bei den Einstellungen aber nicht richtig 
zurecht...

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> er und auch ich haben ihn fest auf GND verdrahtet, wir sind ja alleine
> am Bus und lesen dort nur Daten.

Das widerspricht aber dem Schaltplan von David:
Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)"

Dort liegt FiFo_OE an Pin D13.
Oder wurden danach noch andere Absprachen getroffen, die ich überlesen 
habe?

> PS: vorhin ganz vergessen...
> Woltest Du nur ein Bild von der Uhrzeit auf dem Display oder soll noch
> eine Texterkennung mit formatierter serieller Ausgabe der Zeit rein? ;-)

B)

> PPS: ein Glück, meine Software geht noch undd as Geheimnis des
> UART-Wandlers auf dem UNO habe ich auch halbwegs ergründet bzw.
> umgangen, jetzt also wieder mit 1MBaud.

> Mit dem Licht kommt sie bei den Einstellungen aber nicht richtig
> zurecht...

??
Willst Du sagen, dass das Bild aus Deinem letzten Posting von der 
OV7670-Camera stammt?

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

Was mich noch sehr interessieren würde, ist folgendes:

Wenn man die Frame-Ausgabe von Davids MC-Programm per Realterm (also 
nicht mit Davids PC-Programm) mit gemütlichen 115200 baud empfängt und 
die Daten von Realterm direkt in eine Datei umleiten lässt, kommt dann 
ein korrektes Bild dabei heraus?

Will sagen: hat David schon sein PC-Programm als mögliche Fehlerursache 
ausgeschlossen?

Viele Grüße

Andreas

von Andreas S. (igel1)


Lesenswert?

Andreas S. schrieb:
>> er und auch ich haben ihn fest auf GND verdrahtet, wir sind ja alleine
>> am Bus und lesen dort nur Daten.
>
> Das widerspricht aber dem Schaltplan von David:
> Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)"
>
> Dort liegt FiFo_OE an Pin D13.
> Oder wurden danach noch andere Absprachen getroffen, die ich überlesen
> habe?

Hat sich inzwischen geklärt: ich habe in einem der vorigen Posting 
folgende Aussage von David gefunden:

"Edit: OE überigens auf GND"

Damit ist das schon einmal geklärt und als Fehlerursache ausgeschlossen.

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Hallo, hatte heute leider Vereins-Dienst und bin daher nich viel weiter 
gekommen, als 4 von 22 Pins fertig zu löten... Immerhin, damit läuft die 
Kamera schon und Register schreiben und lesen geht auch.
Leider bin ich ab morgen erstmal für zwei Tage weg und kann mich danach 
erst um deine Routine kümmern @ Igel. Aber ich wollte zuerst das 
gelötete fertig haben um sicher zu sein, dass ich keinen Wackler mehr im 
Kabel habe.

>Bitte schau selbst einmal nach, ob Du den Pin FiFo_OE des Moduls
>irgendwo in Deinem Programm auf LOW ziehst.
Michael hats richtig gesagt: Wir beide haben ihn HW technisch auf GND. 
Auch wenn es offensichtlich mal anders war :D das kann ich aber jetzt 
nicht mehr nachvollziehen. Bringe da auch gerne eine geupdatete 
schematic

Andreas S. schrieb:
> Wenn man die Frame-Ausgabe von Davids MC-Programm per Realterm (also
> nicht mit Davids PC-Programm) mit gemütlichen 115200 baud empfängt und
> die Daten von Realterm direkt in eine Datei umleiten lässt, kommt dann
> ein korrektes Bild dabei heraus?
>
> Will sagen: hat David schon sein PC-Programm als mögliche Fehlerursache
> ausgeschlossen?
>
> Viele Grüße
>
> Andreas
Nein habe ich nicht, ich dachte, das hättest du mit dem Beweisbild.
Bis Mittwoch (oder vlt. zwischendurch mobil)

Gruß
David

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Andreas S. schrieb:
>> Wenn man die Frame-Ausgabe von Davids MC-Programm per Realterm (also
>> nicht mit Davids PC-Programm) mit gemütlichen 115200 baud empfängt und
>> die Daten von Realterm direkt in eine Datei umleiten lässt, kommt dann
>> ein korrektes Bild dabei heraus?
>>
>> Will sagen: hat David schon sein PC-Programm als mögliche Fehlerursache
>> ausgeschlossen?
>>
>> Viele Grüße
>>
>> Andreas
> Nein habe ich nicht, ich dachte, das hättest du mit dem Beweisbild.
> Bis Mittwoch (oder vlt. zwischendurch mobil)

Meinst Du mit "Beweisbild" das Bild aus diesem Posting:
Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)"  ?

Wenn ja, so beweist das leider nur, dass Dein PC-Programm teilweise 
funktioniert, denn es bricht ja immer nach X Zeilen ab.

Ich würde an Deiner Stelle das PC-Programm als Fehlerquelle erst einmal 
ausschließen, indem Du die Daten erst einmal mit Realterm in einer Datei 
auffängst. Mit meiner weiter oben erwähnten Website, kannst Du Dir diese 
Datei dann anzeigen lassen.

Wenn dabei Müll herauskommt => Bug im MC-Programm.

Außerdem würde ich den FiFo mehrfach auslesen und die per Realterm 
geschriebenen Dateien alle miteinander vergleichen.
Wenn nicht identisch => Bug im MC-Programm.

Sodann würde ich an vielen Stellen noch 20us delay einschieben, um das 
RCK-Signal etwas symmetrischer zu machen (nur so ein Bauchgefühl). Ich 
würde nicht in einem Befehl RCK=LOW und im nächsten Befehl direkt 
RCK=HIGH setzen (oder umgekehrt), sondern stets min. 20us Päuschen 
dazwischen spendieren.

Insgesamt würde ich sowieso eher den Timer-Ansatz bevorzugen und RCK 
gleichmäßig durchlaufen lassen. Ob das des Rätsels Lösung ist, kann ich 
Dir allerdings auch nicht versprechen.

> Die ist relativ "einfach" gehalten:
> es geht los in der main.c  case 0x0C:
>
> OV7670_captureNewImage();
> OV7670_ResetFifoReadPointer();
> sendFrameBufferToUART (width, height, BytesPerPixel);
>
> alle drei Funktionen aus der Datei: OV7670_withFifo.c
> Die Namen sind denke ich selbsterklärend.

Habe mir alle 3 Funktionen mittelgrob (d.h. nicht ganz oberflächlich, 
aber auch nicht ganz haarklitzeklein) angeschaut und keine direkten 
Fehler gefunden.

Viele Grüße

Igel1

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

Andreas S. schrieb:
> ??
> Willst Du sagen, dass das Bild aus Deinem letzten Posting von der
> OV7670-Camera stammt?

ja sicher....
Ich schmeiße die Arduino-UNO-Hardware bald aus dem Fenster...
Der Mega16U2 als USB-seriell-Wandler macht da definitiv Mist, der CH340 
auf dem nano hatte die Probleme nicht. Ich will aber meinen Adapter 
nicht umlöten!!!
Das mit /OE hatte ich aus seinen Sourcen, ich muß die Pinzuordnung 
soweiso durch meine ersetzen, ich habe die Pins etwas anders verteilt.
Ich weiß im Moment noch nicht, wie ich mit Davids Source weiter vorgehe.
Entweder ich mache seine UART-Routinen auf dem AVR neu und anders, mit 
seinem terminal kompatibel zu beliben sollte nicht das Problem zu sein, 
mir ist das irgendwie zu instabil und nicht immer reproduzierbar, was da 
passiert.
SCCB scheint ja soweit zu spielen. Mich stört im Moment, daß ich nicht 
einfach ein Bild anfordern kann, VGA geht soweiso nicht wegen der 
Fifogröße, QVGA mit RGB565 und QVGA mit YUV und nur Y senden wären 
brauchbare Voreinstellungen. Ich werde mal meine Registersettings in 
sein Terminal laden und schauen, ob es Bilder ergibt, das geht ja jetzt 
als Struktur einfach.

Dazu muß aber das Fifo übertragen zuverlässig sein. Ich lese ja bei mir 
immernoch mit TeraTerm ein, speichere binär und lasse es mir von 
Irfanview anzeigen. Registerdaten sind nur im AVR-Source, compilieren 
und neu flashen dauert ja nicht lange, egal ob AVR-Studio oder 
ArduinoIDE.

Mal im Laufe des Tages in Ruhe drüber nachdenken...

so, inzwischen ist etwas mehr Licht in der Ecke, also noch ein Bild der 
OV7670 mit meiner Software.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> Hallo,
>
> Andreas S. schrieb:
>> ??
>> Willst Du sagen, dass das Bild aus Deinem letzten Posting von der
>> OV7670-Camera stammt?
>
> ja sicher....
> Ich schmeiße die Arduino-UNO-Hardware bald aus dem Fenster...
> Der Mega16U2 als USB-seriell-Wandler macht da definitiv Mist, der CH340
> auf dem nano hatte die Probleme nicht. Ich will aber meinen Adapter
> nicht umlöten!!!

Hmmm - Mist, das ist wirklich ärgerlich.
Ich kann Dich da gut verstehen.

> Das mit /OE hatte ich aus seinen Sourcen, ich muß die Pinzuordnung
> soweiso durch meine ersetzen, ich habe die Pins etwas anders verteilt.

Okay.

> Ich weiß im Moment noch nicht, wie ich mit Davids Source weiter vorgehe.
> Entweder ich mache seine UART-Routinen auf dem AVR neu und anders, mit
> seinem terminal kompatibel zu beliben sollte nicht das Problem zu sein,
> mir ist das irgendwie zu instabil und nicht immer reproduzierbar, was da
> passiert.

... hier hat's Deinen Satz irgendwie zerwürfelt ...

> SCCB scheint ja soweit zu spielen. Mich stört im Moment, daß ich nicht
> einfach ein Bild anfordern kann, VGA geht soweiso nicht wegen der
> Fifogröße, QVGA mit RGB565 und QVGA mit YUV und nur Y senden wären
> brauchbare Voreinstellungen.

Yep - sollte aber kein Akt sein, dies in Davids Code umzustellen.
Das wäre sowieso mein Ansatz: erst einmal nur ein schnödes QVGA 
RGB565-Bild aus dem FiFo auslesen - mit fixen Register-Settings.
Erst wenn das zuverlässig funktioniert, würde ich weitermachen.

Kurzum: Reduktion auf das Minimum, um maximal viele Fehlerquellen zu 
eliminieren.

> Ich werde mal meine Registersettings in
> sein Terminal laden und schauen, ob es Bilder ergibt, das geht ja jetzt
> als Struktur einfach.
>
> Dazu muß aber das Fifo übertragen zuverlässig sein. Ich lese ja bei mir
> immernoch mit TeraTerm ein, speichere binär und lasse es mir von
> Irfanview anzeigen.

Bevor ich lange suche: wie läßt Du Dir mit Irfanview ein QVGA 
RGB565-Bild, welches in einer Datei ohne jeglichen Header liegt, 
anzeigen?

> Registerdaten sind nur im AVR-Source, compilieren
> und neu flashen dauert ja nicht lange, egal ob AVR-Studio oder
> ArduinoIDE.
>
> Mal im Laufe des Tages in Ruhe drüber nachdenken...

Darum beneide ich Dich wirklich. Aktuell kann ich mir noch nicht einmal 
vorstellen, meine Rente lebend zu erreichen ...

> so, inzwischen ist etwas mehr Licht in der Ecke, also noch ein Bild der
> OV7670 mit meiner Software.

Sehr schön, Michael!
Die Bilder sind so gut, dass man vermutlich tatsächlich mit einfacher 
Bildverarbeitung die Uhrzeit daraus ablesen könnte :-)
KI soll dafür ja superfesch sein ...

Nochmals zurück zu David's Problemen: wenn ich noch ein zusätzliches 
OV7670+AL422B-Modul hätte, wäre meine Hemmschwelle zum Ausprobieren 
seines Codes auf meinem Arduino Nano deutlich niedriger.

Aber ohne zweites Modul schrecke ich wirklich vor der stundenlangen 
Kabellitis zurück (denn der LogicAnalyzer will ja auch noch verkabelt 
sein). Und mit dem Dragon habe ich auch noch nichts gemacht (wenngleich 
er hier rumliegt) und mein AVR-Studio ist auch mehrere Jahre nicht mehr 
geupdated worden und Plattenplatz habe ich auch irgendwie nicht mehr ...
Soll ich mir das wirklich alles antun, wo ich doch so schöne ARM-Boards 
hier rumliegen habe? Hmmm, ich weiß nicht, ich weiß nicht ...

Ich glaube, ich setze einfach auf Dich, Michael, dass Du David's Fehler 
findest - ist deutlich bequemer für mich ;-)

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Bevor ich lange suche: wie läßt Du Dir mit Irfanview ein QVGA
> RGB565-Bild, welches in einer Datei ohne jeglichen Header liegt,
> anzeigen?

Datei->Öffnen als-> RAW-Datei
Im Requester dann eben Größe einstellen, Header auf 0 Bytes, Format 
16BPP, 5:6:5, Big Endian, Interleaved und ok.
Oder eben 8BPP für nur Y.
Wenn die Datei .raw heißt und man sie Irfanview als default zuweist, 
kann man auch einfach doppelklicken und der Requester kommt sofort und 
man muß nur OK klicken.

Andreas S. schrieb:
> Die Bilder sind so gut, dass man vermutlich tatsächlich mit einfacher
> Bildverarbeitung die Uhrzeit daraus ablesen könnte :-)
> KI soll dafür ja superfesch sein ...

kein Problem. Habe ja erst 1148 Byte des 32k Flash belegt........

Mein AVR-Studio ist die 4.18, der GCC der WinAVR-20100110, na und? ;-)
Plattenplatz? Soll ich Dir ein paar TB abgeben? Mein Bekannter baut 
öfter mal sein Datengrab um und dann landen bei mir meist die kleinen 
Platten, de er ausgebaut hat. Im Moment sind wohl seine letzten 
3TB-Platten bei mir gelandet... Er möge mir also noch lange erhalten 
bleiben. :-))

LA hänge ich meist erst ran, wenn ich mir einbilde, keinen Fehler in den 
Sachen drinzuhaben. Ein 8Bit-AVR ist gut überschaubar und auch der alte 
GCC optimiert die IO-Sachen da schon (fast) perfekt.

Ich habe jetzt einfach mal angefangen, den UART-Kram umzubauen, keine 
Ahnung, ob David dann noch mit mir redet... ;-)

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> Datei->Öffnen als-> RAW-Datei
> Im Requester dann eben Größe einstellen, Header auf 0 Bytes, Format
> 16BPP, 5:6:5, Big Endian, Interleaved und ok.

Danke für den Tipp!

Ich wusste gar nicht, dass beim Öffnen von *.raw ein Dialog erscheint. 
Passt alles - aber bei mir fehlt ein Auswahlfeld für "Big Endian" und 
entsprechend geht die Sache schief.

Hast Du tatsächlich dieses Auswahlfeld?
Welche Irfanview-Version hast Du?

Evtl. muss ich ja noch ein Plugin installieren.

Viele Grüße

Igel1

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

Andreas S. schrieb:
> Welche Irfanview-Version hast Du?
>
> Evtl. muss ich ja noch ein Plugin installieren.

bis eben die 4.44 64Bit, gerade auf die 4.52 64Bit update gemacht.
PlugIn-Paket muß installiert sein und zur version passen.
https://www.irfanview.com/

Der Haken ist noch da.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Hallo Michael,

in der Tat: es lag an der Irfanview-Version (obwohl die bestimmt noch 
gar nicht sooo alt war: 4.34**).

Seit meinem Upgrade auf die neueste Version (ich habe die 32-bit Version 
installiert, um die TWAIN-Schnittstelle meines Druckers weiterhin nutzen 
zu können), ist auch der Haken für Big-Endian-Auswahl da. Der fehlte 
vorher noch.

Ohne Deinen Hinweis hätte ich also stets gedacht, dass Irfanview mir 
nicht helfen kann. Danke also vielmals für den Tipp!

Viele Grüße

Igel1

PS:  ** Schock im Nachgang: Revision-History von Irfanview sagt, dass 
Version 4.34 im Jahr 2012 n.Chr. rauskam - as time goes by ...

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> PS:  ** Schock im Nachgang: Revision-History von Irfanview sagt, dass
> Version 4.34 im Jahr 2012 n.Chr. rauskam - as time goes by ...

:-))) Irfanview ist eins der sehr wenigen Programme, wo ich ab- und zu 
freiwillig nach aktuellen Versionen schaue. Immernoch recht klein und 
handlich, kann verdammt viel dafür und hat mich noch nie im Stich 
gelassen.

Gruß aus Berlin
michael

von Tom (Gast)


Lesenswert?

Michael U. schrieb:
> ist mir bisher nicht gelungen... FM6126A
Schau mal, ob das passend ist:
Beitrag "Chinesische IC und ihre Verwandschaft"

von Andreas S. (igel1)


Lesenswert?

... mir fehlt David - schnief - hoffentlich ist bald Mittwoch ...

Viele Grüße

Igel1

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

Also: bin gerade dabei, Davids Schaltung nachzubauen ...

Ja, ja - keine Ahnung, ist wohl ein Helfersyndrom gemäß:
"Watt tu'se nich alles, um de Jong zu helfen?!

Da ich AVR-mäßig allerdings ziemlich eingerostet bin, hier ein paar 
Fragen, bei denen Ihr bitte nicht zu hart mit dem Kopf auf der 
Tischkante aufschlagen möchtet:

- Wie lade ich Davids Programm am einfachsten in den Nano?
  Reicht dafür das USB-Kabel, oder muss ich den AVR-Dragon
 (den ich bislang noch nie benutzt habe) anschließen?

- Wenn ich den Dragon anschließen muss/soll, dann: wie?

- Mit welchem Programm sollte ich David's Projekt kompilieren
  und auf den Nano flashen (optimalerweise mit Null
  Code-Anpassungen)? Vermutlich mit dem neuesten
  AVR-Studiomonster, stimmt's?

Okay, ich gebe zu: ich bin etwas googlefaul, aber ich gebe zu: so 
richtig "heiß" bin ich auf diesen Retro-Ausflug in die 8-Bit-Welt nicht.
Ich befürchte daher, dass ich etwas "Anschubmotivation" in Form von ein 
paar Antworten auf die Fragen oben von Euch benötige  ...  (gerne auch 
in Form von ein paar guten Links).

Außerdem bedeutet es, dass ich 20 Kabel von meiner Kamera neu verdrahten 
muss (und später dann wieder Rolle rückwärts an den STM32 anstecken 
darf).

Macht schon mal das Bundesverdienstkreuz für mich klar ...

Viele Grüße

Igel1

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Also: bin gerade dabei, Davids Schaltung nachzubauen ...
>
> Ja, ja - keine Ahnung, ist wohl ein Helfersyndrom gemäß:
> "Watt tu'se nich alles, um de Jong zu helfen?!

warum denke ish sowas auch gerade?!?!?

Andreas S. schrieb:
> - Wie lade ich Davids Programm am einfachsten in den Nano?
>   Reicht dafür das USB-Kabel, oder muss ich den AVR-Dragon
>  (den ich bislang noch nie benutzt habe) anschließen?
USb-nutzt Dir nur as für die serielle, ansonsten den "Drachen".

> - Wenn ich den Dragon anschließen muss/soll, dann: wie?
6-pin Verbinder hinten quer auf dem Nano und auf dem Dragon auf ISP, 
Verbindung ist 1:1. Falls Du 6-Pin Quetschbuchsen hast und 
Flachbandkabel....

Andreas S. schrieb:
> - Mit welchem Programm sollte ich David's Projekt kompilieren
>   und auf den Nano flashen (optimalerweise mit Null
>   Code-Anpassungen)? Vermutlich mit dem neuesten
>   AVR-Studiomonster, stimmt's?
Wenn Du es relativ einfach haben willst, nimm das uralte AVR-Studio 4.18
https://www.microchip.com/mplab/avr-support/avr-and-sam-downloads-archive
Bis fast ans Ende der Welt runter scrollen, ich glaube, Du brauchst alle 
4 Files, das Studio und die SPs. Unter Win7 geht es völlig problemlos, 
unter 10 sollte es auch noch gehen.
Dazu den antiken WinAVR:
https://sourceforge.net/projects/winavr/files/WinAVR/20100110/
Den WinAVR bitte in seinen Wunschordner auf C:/ installieren...
Ich glaube, wenn man WinAVR zuerst installiert, erkennt ihn AVR-Studio 
beim Installieren allein, das können wir aber noch klären.

Geht eigentlich alles problemlos zu installieren mit den 
default-Angaben.
Wenn Du dann das AVR-Studio startest une New Project öffnset, sieht 
gleich, ob er Dir außer AVR-Assemblaer auch AVR-GCC anbietet.
Wenn Du bis dahin kommst sehen wir weiter.....

Andreas S. schrieb:
> Außerdem bedeutet es, dass ich 20 Kabel von meiner Kamera neu verdrahten
> muss (und später dann wieder Rolle rückwärts an den STM32 anstecken
> darf).

Was sind schon 20 Dupont-Strippen??? Mehr als 19 haben doch gleichzeitig 
sowieso nie Kontakt. ;-)

Das Studio sollte auch den Treiber für den Dragon mitinstallieren 
(Jungo-Treiber).

Andreas S. schrieb:
> Macht schon mal das Bundesverdienstkreuz für mich klar ...

Geht auch ein Aktivisten-Orden? Der müßte hier noch irgendwo 
rumliegen...

PS: AVR-Kram belegt kanpp 200MB, der WinAVR gut 150MB.

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

so, Kurzfassung meines Standes mit Davids Sourcen:
main.c, OV7670_with_Fifo.c und .h, SCCB_old.c und h sowie uart.c und h 
in ein AVR-Studio-Projekt geworfen.
Dragon ausgebuddelt, rangesteckt und einen Arduino UNO zum Mega328 
"degradiert", also Bootloader runter, Fuses angepasst.
In OV7670_with_Fifo.h die Pins an meine Verteilung angepasst und in 
uart.h die Baudrate auf 230400 gesetzt.
Meldet sich auch in seinem Terminal, zumindest manchmal/meistens.
Dann beschlossen, das alles erstmal wegzulassen, zu seinem Terminal 
müßte ich mir erst einen seriellen Sniffer installieren, um sein 
Protokoll rauszufinden, also welches Kommando sendet was und wieviele 
Bytes in welchem Format (offenbar alles binär) und welche Antwort wird 
erwartet usw.
Da ich seine UART-Routinen auch nicht auf Anhieb durchschaut habe, 
beschlossen, das alles vorerst zu ignorieren...
uart.c umgebaut, TX-Interrupt aus, Senden im Busy-Loop. Seinen 
Bildersende Aufruf in die main7while(1) rein, Kommandoauswertung 
auskommentiert und nur endlos mit 30s Abstand Bild geholt und 
rausgeschickt.
Andres S.: falls Du den alten AVR-Kram beutzt: _delay_ms() kann da noch 
keine langen Zeiten, also
1
  for (uint8_t i = 0; i < 20; i++)
2
  {
3
    _delay_ms(1000);
4
  }
benutzen für längere Wartezeiten. Ich hatte kurz überlegt, ob ich das 
aktuelle GCC-Paket installiere, aber keine Lust, da man da ein paar 
Sachen passend basteln muß...

Zumindest kamen jetzt alle 20s meine 153600 Bytes an. height = 320 habe 
ich erstmal wieder gesetzt. Bildinhalt der Daten war irgendwas, aber 
reproduzierbar.

Kurzerhand meine Init-Strukturen in seine main geworfen und die Kamera 
nach seinem OV7670_init(); mit meinen Registerwerten initialisiert.
Das Ergebnis hängt oben dran.

Darüber kann ich jetzt erstmal in Ruhe nachdenken, ich ahbe auch an ein 
paar Stellen in OV7670_with_Fifo.c noch was von ihm auskommentiert, das 
muß ich jetzt erstmal vergleichen bzw. rückgängig machen.
Seine SCCB-Sachen laufen auf jeden Fall erstmal ohne Änderungen und 
Probleme, die OV7670_with_Fifo.c wohl auch.
Mit seinen UART-Routinen bekomme ich irgendwie immer nur um die 15xxx 
Byte, warum auch immer.
Warum mit meinen Init-Daten kein vernünftiges Bild rauskommt weiß ich 
auch noch nicht.

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Hallo! Ich bin zurück! freut mich, dass ihr am Ball geblieben seid und 
mir weiterhin helfen wollt!
Heute Abend/Nachmittag habe ich wieder Zeit und werde mich in aller Ruhe 
mit euren Beiträgen auseinander setzten.

@Igel wenn dir der Speicherplatz auf dem Rechner erstmal nicht allzu 
wichtig ist, würde ich dir einfach empfehlen das neuste Atmel stuido zu 
ziehen. Dann brauchst du dich um den Kram wie GCC etc. garnicht erst 
kümmern. Dann läuft auch der Dragon Plug'n'Play.
Bis später!

Mir juckts schon in den Fingerspitzen

Gruß

David

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Hi Leute,

habe das neueste AVR-Studio installiert (mein schöner Plattenplatz - 
schnief ...).

Heute Abend werde ich mich dann wohl erst einmal mit dem AVR-Dragon 
beschäftigen dürfen: habe ihn hier im Forum gebraucht gekauft und er kam 
nur mit einem 10-adrigen Stecker.

Ich hoffe, ich kann diesen Stecker versetzt auf die Pfostenleisten an 
beiden Ende aufsetzen, ohne mir einen neues Kabel basteln zu müssen 
(denn dafür fehlt mir gerade das Zeugs).

Hauptsache Michael löst nicht alle Probleme, bevor ich überhaupt das 
erste Byte auf meinen Nano geschoben habe ;-)

Muss ich eigentlich vorab noch irgendetwas mit dem Nano veranstalten? 
(Bootloader platt machen? Fuses verbiegen? Beschwörungssprüche 
drüberhauchen?)

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

ich kann dir heute abend ein foto von meinem schicken.

nein, wenn du einfach vom studio aus flashest ist halt der Bootloader 
fürs erste Weg und du wirst die Arduino suit damit nicht mehr benutzten 
können, bis du wieder den Bootloader dafür falshest. An den Fuses musst 
du meines wissens nichts ändern. Nur in den Debug mode kannst du mim 
Nano nicht, weil du dich dann aussperrst. (Aber das wäre eben eine 
solche Fuse die man setzen müsste, also solange du da nichts machst kann 
eig. nichts passieren

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Hallo! Ich bin zurück! freut mich, dass ihr am Ball geblieben seid und
> mir weiterhin helfen wollt!
Schö wieder von Dir zu hören.

Andreas S. schrieb:
> habe das neueste AVR-Studio installiert (mein schöner Plattenplatz -
> schnief ...).
Du hast es so gewollt... ;-))

Andreas S. schrieb:
> Hauptsache Michael löst nicht alle Probleme, bevor ich überhaupt das
> erste Byte auf meinen Nano geschoben habe ;-)
Mit Sicherheit nicht, ich mache auch nur mal 'ne Stude oder so was, es 
sei denn, hier geht gerade die Post ab.

Ich muß meinen Salat jetzt erstmal aufräumen, irgendwo habe ich bei 
meinem Sketch jetzt erstmal was durcheinander gebracht...
Ich will jetzt erstmal Dvids Sourcen mit nur den nötigsten Änderungen, 
meinen Arduino-Sketch und die im AVR-Studio compilierte Version dazu 
überreden, mir alle 20s ein RGB565-Bild bzw. den Farbbalken zu schicken.

10-pol. sollte machbar sein wenn auf dem Dragon nicht alle Steckleisten 
bestückt sind, beim Nano ist ja nach beiden Seiten Platz. Zur Not sind 
es eben 6 Dupont-Strippen mehr.....

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Noch eine kleine Frage in die Runde:

Wie versorgt Ihr Kamera und Level-Shifter mit Strom?

Lese gerade, dass der Original-Nano nur 50mA Belastbarkeit an seinem 
3,3V-Ausgangspin hat.

Muss ich jenseits von USB noch eine Stromversorgung für das Steckbrett 
aufbauen?

Viele Grüße

Igel1

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

so, kurzer Nachtrag: Ordnung soweit gemacht.
Änderungen in Davids Source:
- uart.c - eigene Senderoutine ohne Interrupt, keine Empafamgsroutine
- main c - Kommandoauswertung auskommentiert, nur
1
while (1) 
2
{
3
  OV7670_captureNewImage();
4
  OV7670_ResetFifoReadPointer();
5
  sendFrameBufferToUART (width, height, BytesPerPixel);
6
7
  for (uint8_t i = 0; i < 20; i++)        //############## 20s warten
8
  {
9
    _delay_ms(1000);
10
  }
11
}
- main.c meine Register daten incl. Registersetzen eingefügt und nach 
seinem
OV7670_init(); aufgerufen.
So kommt alle 20s ein RGB565 Bild als RAW-Daten an.
Seltsamerweise kommen seine Daten Little Endian an????

Erstmal reicht es mir. ;-)
Bild ist auch "ok", ist aber zu dunkel in der Ecke für die 
Einstellungen.

Gruß aus Berlin
Michael

von David D. (saturi)


Angehängte Dateien:

Lesenswert?

Hi Michael,

vielen Dank für deine Mühen, das werde ich mir jetzt anschauen.
Ich habe soeben die Lötarbeiten fertig gestellt und siehe da! ich 
bekomme zuverlässig die gleiche Colorbar, auch nach mehrmaligem 
auslesen. Deaktiviere ich diese bekomme ich aber kein Bild sondern kann 
höchstens die Lampe sehen, wenn ich sie direkt davor halte. Ist aber 
auch logisch, weil ich noch keine Settings reingeladen habe.

Jetzt schaue ich mir mal an, was du Michael mit meinem Code 
veranstalltet hast und schaue auch mal, ob eure Registersettings von vor 
einigen Tagen/Wochen bei mir funktionieren ;-)

Dieser miese Wackelkontakt hat echt zu unglaublichen Sachen geführt 
:D...

@Igel ich habe so eine Spannungsversorgung fürs Steckbrett, die 3,3 und 
5V kann. Und jetzt mit Entwicklershield eben auf dem Uno, der ja 5V hat.

anbei ein Bild der Colorbar, meines neuen Testobjektes ;-) und dem 
Dragon für dich zur Veranschaung. Ich habe meinen in ein Gehäuse 
eingebaut und in meinem Unwissen alle Anschlüsse nach außen geführt, was 
im Nachhinein betrachtet nicht so clever war. Aber der ISP stecker ist 
blau markiert. Ist der 6er Stecker in der Mitte

von Tom (Gast)


Lesenswert?

David D. schrieb:
> Dieser miese Wackelkontakt hat echt zu unglaublichen Sachen geführt
Ich sage immer:
Für über 90% aller Fehler in der Elektronik ist eine defekte Verbindung 
die Ursache.

von Michael U. (amiga)


Lesenswert?

Hallo,

ok, das Problem mit der anderen byteorder hat sich für mich erstmal 
geklärt,
1
for(int ByteNumber =0; ByteNumber < BytesPerPixel; ByteNumber++)
2
{
3
  OV_RCK_PORT |= (1<<OV_RCK_PinNo);
4
5
  UART0_senden_Byte(Ov7670_readByte());
6
        
7
  OV_RCK_PORT &= ~(1<<OV_RCK_PinNo);
8
}

Du setzt RCK auf H und liest dann die Daten. TOH ist aber nur wenige ns, 
min. 4ns. Da der Fifo sehr schnell ist, liest Du sehr wahrscheinlich 
nicht das gewünschte, sondern schon das nächste Byte.
1
for(int ByteNumber =0; ByteNumber < BytesPerPixel; ByteNumber++)
2
{
3
  OV_RCK_PORT &= ~(1<<OV_RCK_PinNo);
4
5
  UART0_senden_Byte(Ov7670_readByte());
6
7
  OV_RCK_PORT |= (1<<OV_RCK_PinNo);      
8
}
macht es bei mir richtig rum. Da sind Timingprobleme zwischen Fifo und 
und dem "lahmen" AVR wohl schuld.
Ich habe jetzt keine Lust, den LA ranzuhängen und zu schauen, wann der 
Datenwechsel im Verhältnis zur RCK Flanke passiert, außerdem sind da die 
80MHz Samplerate meines LA sowieso zu langsam...

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Das ist jetzt interessant.
Wenn ich jetzt meine routine so änder wie von dir vorgeschlagen, erhalte 
ich die Colorbar, die du vorher hattest :D

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

David D. schrieb:
> Wenn ich jetzt meine routine so änder wie von dir vorgeschlagen, erhalte
> ich die Colorbar, die du vorher hattest :D

Und wenn Du mir jetzt noch sagst, welche ich vorher hatte... ;-)
Die aus dem Post von Datum: 20.02.2019 17:30 ist die richtige.
weiß-gelb-cyan-grün-magenta-rot-blau-schwarz ist richtig, der 
Standard-Farbbalken.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

Hi Leute,

ich hab's geahnt: Michael hat alle Probleme gefixed, bevor ich das erste 
Byte auf mein Arduino-Nano Board geschoben habe ...

Nach ein paar Anlaufschwierigkeiten mit dem ISP-Kabel, hat das Flashen 
gerade erstmals funktioniert - hurra.

Natürlich erst kurz nachdem Michael den Timing-Bug gefunden hat - so'n 
Mist, den hätte ich auch gern gefunden ...

Bevor ich jetzt die Kamera dranklemme, möchtet Ihr beide mir bitte 
nochmals genauer beschreiben, wie Ihr das Board mit Strom versorgt 
(sowohl Michael als auch David). Wie versorgt Ihr den Nano, die 
Level-Shifter (beide Seiten: 3,3V und 5V interessieren mich) und wie die 
Kamera?

Benutzt Ihr dafür etwa so eine Steckbrett-Versorgung wie unten rechts im 
Bild dargestellt?

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Hallo Igel!
Freut mich riesig, dass du diese Bürde auf dich genommen hast. Ich kann 
dich beruhigen. Es ist noch lange nicht alles gefixed.

Ich habe mir jetzt mal auf die beiläufige Erwähnung von Michael, dass es 
com swiffer gibt, so ein Tool geladen und sehe, dass es nicht ganz 
meinen Erwartungen entspricht, bzw. Der uC aus irgendwelchen Gründen 
nicht weiter macht.

Zur Stromversorgung. (Ich kopiere einfach nochmal von oben ;-) )

"@Igel ich habe so eine Spannungsversorgung fürs Steckbrett, die 3,3 und 
5V kann. Und jetzt mit Entwicklershield eben auf dem Uno, der ja 5V 
hat."

Also zuvor auf meinem steckbrett habe ich die steckbrettversorgung mit 
ext. Netzteil genutzt und jetzt betreibe ich den uno nur noch per USB 
und greife von dort die 3,3 und 5v ab

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:

> Hallo Igel!
> Freut mich riesig, dass du diese Bürde auf dich genommen hast. Ich kann
> dich beruhigen. Es ist noch lange nicht alles gefixed.

Nu freu Dich mal nicht zu früh: ich kann am kommenden Wochenende
nicht mitmachen und Michael schickt sich gerade an, keinen Bug mehr
für mich übrig zu lassen.

> Zur Stromversorgung. (Ich kopiere einfach nochmal von oben ;-) )

Das hatte ich durchaus gelesen, aber eben nicht richtig verstanden.

> "@Igel ich habe so eine Spannungsversorgung fürs Steckbrett, die 3,3 und
> 5V kann. Und jetzt mit Entwicklershield eben auf dem Uno, der ja 5V
> hat."

Nun habe ich es zum 2. Mal nicht richtig verstanden ...

> Also zuvor auf meinem steckbrett habe ich die steckbrettversorgung mit
> ext. Netzteil genutzt und jetzt betreibe ich den uno nur noch per USB
> und greife von dort die 3,3 und 5v ab

Vielleicht stehe ich etwas auf der Leitung daher nochmals konkret 
gefragt:

- Meinst Du mit "Steckbrettversorgung" so etwas wie rechts unten auf
  meinem Bild aus meinem letzten Posting?

- Wirft Dein Entwicklershield (welches hast Du?) 3,3V und 5,0V raus?

- Den 3,3V-Ausgang des Uno-Boards hast Du nicht genutzt, oder?
  (... denn der kann ja nur 50mA liefern)

Viele Grüße

Igel1

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> - Den 3,3V-Ausgang des Uno-Boards hast Du nicht genutzt, oder?
>   (... denn der kann ja nur 50mA liefern)

die 3,3V vom Nano reichen für die Kamera eigentlich aus, auch mit em 
FiFo.
Der AMS1117 auf dem Nano kann weit mehr, es wird ihm aber dann zu warm 
wegen der geringen Kühlfläche. Vusb geht über eine Schottkydiode an den 
Reglereingang, an üblichen USB-Ports sieht der also meist nur um 4,7V. 
Kannst Du ja am 5V Pin des Nano messen, was da bei USB wirklich anliegt.
Pegelwandler 5V vom 5V Nano-Pin, 3,3V und Kamera am 3,3V Pin.
Pegelwandler habe ich in den zur Kamera gehenden Leitungen, also SDA, 
SCK, RST, also was direkt zur OV7670 geht. Der Fifo hat sowieso 5V 
tolerante Eingänge.
Der UNo hat meist einen LP2985-33 drauf, der kann auch max. 150mA, kann 
aber eben auch thermische Probleme bekommen.
Bei gehen beise Varainten ohne erkennbare Probleme, Spannung eben normal 
vom USB-Port.

Ich habe mich gestern Abend irgendwie an "Processing" erinnert. Das ist 
eine Java-Geschichte im Arduino-Stile und habe es mal angeworfen.
Hmmmmm, wenn ich da durch die Funktionen usw. etwas durchgestiegen bin, 
habe ich da vermutlich in kruzer Zeit eine "Software", die die RAW-Daten 
vom Mega einliest und als Bild in ein Fenster pinselt.
Kann man einfach irgendwo hinwerfen und die .exe starten, 260MB tragen 
auch nicht so auf. :)

Ich werden an der OV7670 Software ohnehin jetzt nur was machen, wenn 
David "um Hilfe" schreit.
Ich kann bei Bedarf auch meine geänderte main.c und uart.c auch hier mal 
reinhängen.
Genauso auch meine Software, ist in einem kompletten .c File, läßt sich 
also auch problemlos in ein Studio-Projekt werfen.

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

@Michael:  Danke für die Mühen, die Du Dir da mit Deiner ausführlichen 
Email zum Thema Stromversorgung gemacht hast!

Dann also Augen zu und durch: ich werde den Nano per USB-Kabel direkt 
vom Rechner aus versorgen und schließe alles andere an die Pins 5V und 
3,3V des Nano an.

Sollte das schief gehen, so habe ich noch einen Ersatz-Nano hier in der 
Tüte gefunden. Ihr werdet mich also so schnell vermutlich nicht los ...

Viele Grüße

Igel1

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

Andreas S. schrieb:
> Sollte das schief gehen, so habe ich noch einen Ersatz-Nano hier in der
> Tüte gefunden. Ihr werdet mich also so schnell vermutlich nicht los ...

kannst ja einfach mal den Finger auf den Spannungsregler des Nano legen, 
wäre das einzige kritische Bauteil bei der Geschichte.

PS: meine ESP32-Espessif jungs waren auch fleißig. Endlich mal das 
aktuelle CamWebserver angepast und auf mein Cam-Modul geflasht.
Da muß ich mal mit rumspielen und schauen, was die da jetzt alles in die 
Lib für die Kameramodule gepackt haben.
Bild vom Webinterface mit Einzelbild in voller Auflösung in bekannter 
ziemlich schlechter Beleuchtung.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

Michael U. schrieb:
> PS: meine ESP32-Espessif jungs waren auch fleißig. Endlich mal das
> aktuelle CamWebserver angepast und auf mein Cam-Modul geflasht.

Meinst Du das "Cam-Modul": siehe Anhang ?

Das habe ich mir wegen Deiner positiven Bewertung in einem anderer 
Thread ebenfalls gekauft.

VG
Igel1

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

By the way: habe den ganzen Schmodder inzwischen verdrahtet: 2h 
Wurschteln. Ist ein fliegender, recht wackeliger Verhau geworden.
Bin dabei blind vertrauend nach David Schaltplan vorgegangen (nur OE 
habe ich fix auf GND gelegt).

@Michael: Ich würde nun zum Testen sehr gerne Deine Modifikationen von 
Davids Programm haben. Dann weiß ich zumindest, dass mein Drahtverhau 
passt, wenn ein Colorbar-Bild hinten rauskommt.

Bitte nur diejenigen Dateien hier einstellen, die sich von Davids 
Programm unterscheiden - dann würde ich diese Dateien schnell mal 
temporär tauschen und so die Schaltung testen.

Bleibt noch eine dumme Frage (bin zu müde, das nachzuprüfen - seht's mir 
nach):

Die Daten kommen seriell über die USB-Schnittstelle via virtuellem 
seriellem Port raus, stimmt's? Oder muss ich noch einen 
USB->RS232-Wandler irgendwo drankleben?

Viele Grüße

Igel1

: Bearbeitet durch User
von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

Andreas S. schrieb:
> Meinst Du das "Cam-Modul": siehe Anhang ?
ja, genau dieses. Da ist mir gestern noch was seltsames aufgefallen, was 
das Kamera-Modul selbst betrifft. Das muß ich mir aber erst genauer 
anschauen.

Andreas S. schrieb:
> Bitte nur diejenigen Dateien hier einstellen, die sich von Davids
> Programm unterscheiden - dann würde ich diese Dateien schnell mal
> temporär tauschen und so die Schaltung testen.
Wenn ich beim letzten Sortieren kenen Mist gebaut habe, passt es so.
Ich habe meine Eingriffe mit Kommentaren verziert, die  mit //######### 
beginnen.
UART steht auf 23400, alle 20s kommt ein RGB565 Bild.

Die Daten kommen seriell über die USB-Schnittstelle via virtuellem
seriellem Port raus, stimmt's? Oder muss ich noch einen
USB->RS232-Wandler irgendwo drankleben?
Kommen über USB, sollte beim Anstecken des Nano eine COM auftauchen wenn 
Du den Treiber drauf hast, meine Nano haben alle einen CH430 drauf.

Lassen wir uns mal überraschen.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

@Michael: Danke für die Starthilfe!

Damit konnte ich direkt den Funktionstest machen, der das Bild im Anhang 
ergab (allerdings Little Endian).

Fazit: kein Verkabelungsfehler (puhhh) - nicht zuletzt Dank David's 
sauberem Schaltplan.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Damit konnte ich direkt den Funktionstest machen, der das Bild im Anhang
> ergab (allerdings Little Endian).

schön. Wieder ein Spielzeug mehr. ;)

Byteorder: mein Post vom Datum: 20.02.2019 21:04

PS. heute die 64x64 LED-Matrix von der Post geholt, siehe oben der 
Uhr-Kram...

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

GUten Abend... endlich Feierabend, endlich Wochenende nach einer 
turbolenten Woche. Gleich nur noch der Tanzkurs zu dem ich genötigt 
werde und dann habe ich auch schon wieder die halbe Nacht und den 
Sonntag zeit, um mich meinem Lieblingsthema zu widmen. Juhu!


Dann mische ich wieder mit :)

Freut mich, dass wir alle wieder auf Hardware laufen und Michael ein 
Spielzeug für die Zwischenzeit gefunden hat :D
Bis später!

von Andreas S. (igel1)


Lesenswert?

Hier eine Kleinigkeit:

Ich schaue mir gerade Davids Routine "UART0_init (void)" an.
Dabei fällt mir auf, dass dort 2 Stoppbits konfiguriert werden.
Ist sicherlich kein Beinbruch, aber ich vermute eher, dass eigentlich 
8N1 konfiguriert werden sollte.

Etwas kritischer ist das hier:

Außerdem würde ich erst einmal "klein anfangen": also max. 115200 baud 
einstellen - da weiss man, dass die Abweichung von Soll-Baudrate und 
Ist-Baudrate mit 2,1% noch halbwegs "legal" ist (vgl. S.199 hier: 
http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf) 
und es zu keinen Fehlern kommen sollte.
Alles darüber ist Glückssache (so jedenfalls mein Verständnis).

Und ganz kritisch sehe ich das hier:

Dann sehe ich den UART-Empfänger-Interrupt aktiviert.
Ohne dass ich bisher weiteren Code gesichtet hätte (... gleich ist erst 
einmal Familie dran ...) halte ich das bei den dort eingestellten 2 
Mbaud für sehr gewagt:  bei 16MHz Takt hätte die ISR ganze 8 Takte Zeit, 
um das empfangene Bit zu verarbeiten (inklusive Ein- und Rücksprung!). 
Meiner Meinung nach kann das nicht funktionieren.

Soweit erst einmal meine 10 Cent zum Thema "UART0_init (void)".

Viele Grüße

Igel1


PS: ich weiss, dass Michael auch schon etwas dazu geschrieben hatte, bin 
aber zu bequem, das alles nochmals rauszusuchen - meine Anmerkungen 
können daher doppelt-gemoppelt sein.

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Ich schaue mir gerade Davids Routine "UART0_init (void)" an.
> Dabei fällt mir auf, dass dort 2 Stoppbits konfiguriert werden.
> Ist sicherlich kein Beinbruch, aber ich vermute eher, dass eigentlich
> 8N1 konfiguriert werden sollte.

ist in diesem Fall egal bzw. sogar von Vorteil. Mir ist kein real 
existierender RS232-RX bekannt, der wirklich noch auf 2 Stoppbits 
auswertet selbst wenn man 8N2 einstellt.das müßte dann auf 
Empfängerseite einen Frame-Error erzeugen, ist mir aber noch nicht 
untergekommen.
Wenn der Empfänger auf 8N1 steht und man 8N2 sendet schindet man eine 
Bitzeit Zeit raus, um sicher auf das nächste Startbit reagieren zu 
können. War aber nur ganz früher (tm) wichtig, weil da nur einmal mit 
dem Lesetakt der Zustand eingelesen wurde und es eben stimmen mußte.
Ich hatte es gesehen und deshalb ignoriert.

Ansonsten habe ich seinen UART-Kram bisher einen riesen Bogen gemacht. 
;-)

Gruß aus Berlin
Michael

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

OT: damit es nicht langweilig wird: ESP32 mit OV2640 vom neuen 
LED-Display 64x64 in 1600x1200.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

... David scheint einen Tanzunfall gehabt zu haben - man hört gar nichts 
mehr von ihm ...

von David D. (saturi)


Lesenswert?

Andreas S. schrieb:
> Dabei fällt mir auf, dass dort 2 Stoppbits konfiguriert werden.
> Ist sicherlich kein Beinbruch, aber ich vermute eher, dass eigentlich
> 8N1 konfiguriert werden sollte.
Öhm naja mit 8n1 oder 8N2 "Standards" muss ich gestehen, kenne ich mich 
nicht aus. diese UART Routine habe ich ganz am Anfang meiner uC-Karriere 
mal ans laufen gebracht und nehme sie immer wieder her. Also sollte man 
eher nur 1 Stopp-Bit verwenden?

> Etwas kritischer ist das hier:
>
> Außerdem würde ich erst einmal "klein anfangen": also max. 115200 baud
> einstellen - da weiss man, dass die Abweichung von Soll-Baudrate und
> Ist-Baudrate mit 2,1% noch halbwegs "legal" ist (vgl. S.199 hier:
> 
http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf)
Ja, können wir machen, hatte sie nur damals hochgedreht, da ich 
vermutete, dass das rauschen von einem unzureichend refreshtem FIFO kam. 
War ja nicht der Fall. Allerdings habe ich noch keine anderen 
Verhaltensweisen mit dem 2MBaud festgestellt, das Verhalten ist genauso 
wie vorher.

> Und ganz kritisch sehe ich das hier:
>
> Dann sehe ich den UART-Empfänger-Interrupt aktiviert.
> Ohne dass ich bisher weiteren Code gesichtet hätte (... gleich ist erst
> einmal Familie dran ...) halte ich das bei den dort eingestellten 2
> Mbaud für sehr gewagt:  bei 16MHz Takt hätte die ISR ganze 8 Takte Zeit,
> um das empfangene Bit zu verarbeiten (inklusive Ein- und Rücksprung!).
> Meiner Meinung nach kann das nicht funktionieren.
Jap, verstanden. Allerdings scheint es aktuell zu funktionieren. Kann 
aber auch daran liegen, dass ich mit dem Atmega nur relativ Wenige Bytes 
(ich glaube maximal 3) hintereinander empfange. Das scheint er 
offensichtlich noch hin zu bekommen.

> Soweit erst einmal meine 10 Cent zum Thema "UART0_init (void)".
Das finde ich gut, weil ich denke, dass das Problem irgendwo in der UART 
routine liegt. Und ich aktuell davon ausgehe, dass es an einem nicht 
beachtetem Empfangenen Kommando auf dem uC liegt.

Solange das Terminal nicht zuverlässig "Serien" schreiben oder Lesen 
kann, macht muss/müssen ich/wir zunächst das in den Griff bekommen.

Michael schrieb:
>Ansonsten habe ich seinen UART-Kram bisher einen riesen Bogen gemacht.
>;-)
Schade :D da liegt denke ich der Fehler, der Rest scheint "relativ" 
gut/schlecht zu funktionieren.

Ich würde auch gerne auf deinen Vorschlag von vor ein paar posts 
eingehen und die UART routinen umbauen, wenn das zum Erfolg führen kann.

Andreas schrieb:
>... David scheint einen Tanzunfall gehabt zu haben - man hört gar nichts
>mehr von ihm ...

Nicht ganz, ich bin nur gestern einfach tot ins Bett gefallen und war zu 
garnichts mehr in der Lage. Heute dann Skifahren aber jetzt wieder 
daheim und schon wieder mitten drin :)

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Ich würde auch gerne auf deinen Vorschlag von vor ein paar posts
> eingehen und die UART routinen umbauen, wenn das zum Erfolg führen kann.

mal schauen, wie meine Meinung morgen ist. Wenn das Display am 
Wemos-ESP32-Modul sich meldet, habe ich durchuas Lust. ;) Im Moment geht 
es mir wie Dir: ich habe die Verbindungen jetzt 3x kontrolliert, 
jedesmal einen Fehler entdeckt und behoben und stehe trotzdem noch "im 
Dunkeln". Also vorhin entnervt in die Ecke gelegt.....

Ich hatte irgendwo hier auch schon eine Empfangsroutine reingebaut, mit 
einfachem Buffer und RX-IRQ. Lief prinzipiell auch, da ich aber erst 
hätte schauen müssen, was Dein Terminal beim Druck auf welchen Button 
eigentlich sendet, habe ich am anderen Ende angefangen.
ok, habe gerade mal einen Seriellen Portmonitor installiert, ist zwar 
eine Demo und läuft nur 14 Tage, aber sie macht erstmal, was sie soll.
Also morgen mal schauen...

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Welche Software hast du da ausgewählt?
Ich nehme mir gerade die Warnings vor ;-)


Gruß
David

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Welche Software hast du da ausgewählt?
Die erstbeste, die mir in die Hände viel:
https://www.eltima.com/de/products/serial-port-monitor/

> Ich nehme mir gerade die Warnings vor ;-)
BNaja, die meisten sind ja nur warnings wegen den Zuweisungen in 
if-Anweisungen. Ein Klammerpaar drumrum und der Compiler erkennt die 
Absicht und vermutet keinen Tippfehler = <> ==

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Hi Leutis,

habe gerade einmal Davids Code genommen und statt main.c und uart.c 
komplett durch Michaels Code zu ersetzen, habe ich nur main.c durch 
Michaels Code ersetzt.

Damit wird alle 20s die Routine "sendFrameBufferToUART (width, height, 
BytesPerPixel);" aufgerufen. Außerdem ist sichergestellt, dass die 
Kamera-Parameter auch wirklich ein Colorbar-Testbild erzeugen.

Fazit: der Nano sendet anschließend keinen Pieps mehr über Seriell - 
schade aber auch, denn die Uart-Routinen mit dem Ringbuffer sehen auf 
den ersten Blick sehr elegant aus.

@David: bist Du von allein auf solche Konstrukte hier gekommen? :
1
volatile struct UART0_tx        //Transmit Buffer
2
{
3
volatile char data[UART0_tx_size];
4
char read;
5
char write;
6
}UART0_tx= {{}, 0, 0};
7
8
9
int UART0_tx_in (char input)
10
{
11
  char next= ((UART0_tx.write+1)&UART0_tx_mask);
12
  if (next==UART0_tx.read)
13
  {
14
    return 0;
15
  }
16
  UART0_tx.data[UART0_tx.write] = input;
17
  UART0_tx.write =next;
18
  return 1;
19
}

Für einen Programmieranfänger fände ich das mehr als bemerkenswert:
Ringbuffer mit sehr raffinierter, handcodierter Modulo-Berechnung.
Meine ersten Versuche sahen da deutlich schlichter aus.

Jetzt muss ich nur noch den Fehler finden, warum das Dingen so gar 
keinen Mucks von sich gibt. Nur leider ist Basteltime für heute schon 
wieder over.

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Hi,
Ich bin leider auch schon wieder im Land unterwegs, also bei dem 
Standard uart fürnktionen habe ich mich hier auf der Website  bei den 
avr "beispielen" bedient :D das hätte ich am Anfang niemals so 
hinbekommen. Das war ca. 2014 in meinem ersten uni Projekt.

Also bei mir läuft es mit meinem Terminal auch mehrmals hintereinander. 
Aber ich würde gefühlsmäßig nicht beim Bild anfangen sondern bei 
mehreren Registern lesen oder schreiben.
Also es liegt nicht an den Buffern habe breakpoints bei beiden fifo fiel 
Routinen gesetzt. Und die lösen nicht aus, wenn die Übertragung 
abbricht.
...
Hmm ich bin was ratlos
Grüße aus aktuell Regensburg

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Hi,
> Ich bin leider auch schon wieder im Land unterwegs,

Du meine Güte - bist Du Vertreter (neudeutsch: Vertriebler?)
Die machen echt "Landverschickung" mit Dir.

> also bei dem
> Standard uart fürnktionen habe ich mich hier auf der Website  bei den
> avr "beispielen" bedient :D das hätte ich am Anfang niemals so
> hinbekommen. Das war ca. 2014 in meinem ersten uni Projekt.

Ah - der Mann hat doch stuckadiert.

> Also bei mir läuft es mit meinem Terminal auch mehrmals hintereinander.

Was genau?

> Aber ich würde gefühlsmäßig nicht beim Bild anfangen sondern bei
> mehreren Registern lesen oder schreiben.

Passt schon - Bildausgabe ist schon okay.

> Also es liegt nicht an den Buffern habe breakpoints bei beiden fifo fiel
> Routinen gesetzt.

Was meinst Du mit "fifo fiel Routinen"?

> Und die lösen nicht aus, wenn die Übertragung
> abbricht.
> ...
> Hmm ich bin was ratlos

Das werden wir schon gemeinsam schaukeln.

Inzwischen fiel mir auch ein, warum Dein Code nix sagt, wenn ich Deine 
"main.c" durch Michaels "main.c" ersetze: vermutlich hatte Michael den 
Interrupt deaktiviert...
Und so war's denn auch - ich hätte einfach nur genauer hinschauen 
müssen.

Habe ab Do ein paar Tage frei, dann kann ich mich etwas mehr eindenken - 
braucht halt doch Ruhe und Muße, so eine Fehleranalyse. Hoffentlich läßt 
mir Michael den oder die Fehler übrig - jetzt wo ich alles mühevoll 
zusammengestöpselt habe.

By the way: warum nutzt Ihr Eure Logic-Analyser nicht zur Analyse des 
seriellen Protokolls und hantiert statt dessen mit Software herum?
Mein Intronix LogicPort kann UART im Schlaf decodieren.


> Grüße aus aktuell Regensburg

Grüße aus - Du weißt schon wo

Igel1

: Bearbeitet durch User
von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

Hi David,

schau mal das Bild im Anhang ...
Du wirst es nicht glauben: es stammt aus Deinem Programm - mit minimalen 
Anpassungen:

Ich habe - wie oben geschrieben - Deine "main.c" durch Michaels "main.c" 
ersetzt. Einziger Grund: ich wollte die Menüauswahl rauswerfen, um mich 
so auf die Routine "sendFrameBufferToUART (width, height, 
BytesPerPixel);" konzentrieren zu können.

Diese Routine habe ich dann wie folgt angepasst:
1
 void sendFrameBufferToUART (int ImageWidth, int ImageHeight, int BytesPerPixel)
2
 {
3
  OV7670_ResetFifoReadPointer();
4
5
  for(int height = 0; height < ImageHeight;height++)
6
  {
7
    for(int width =0; width < ImageWidth; width++)
8
    {
9
      for(int ByteNumber =0; ByteNumber < BytesPerPixel; ByteNumber++)
10
      {
11
        
12
        OV_RCK_PORT &= ~(1<<OV_RCK_PinNo);
13
        UART0_senden_Byte(Ov7670_readByte());
14
        _delay_us(300);
15
        OV_RCK_PORT |= (1<<OV_RCK_PinNo);
16
        
17
        
18
      }
19
    }
20
  }
21
 }

Begründung:

Flankenwechsel für RCK habe ich vertauscht, damit Du das erste Byte 
nicht verschlumpfst, denn wenn Du die Flanke von RCK von LOW nach HIGH 
gehen lässt und dann erst das Byte aus dem AL422B-FIFO liest, so landest 
Du schon beim zweiten Byte (Michael war das aufgefallen - diese Blumen 
gehen an ihn).

Sodann folgt das eigentliche Problem, das seinen Ursprung beim Aufruf 
von "UART0_senden_Byte(Ov7670_readByte())" hat.

Bei der Sichtung dieser Routine fiel mir auf: sie ruft die Unterroutine 
"UART0_tx_in(Byte)" auf und in dieser Unterroutine wiederum wird ein 
internen Puffer UART0_tx.data[] gefüllt. Das geht so:
1
int UART0_tx_in (char input)
2
{
3
  char next= ((UART0_tx.write+1)&UART0_tx_mask);
4
  if (next==UART0_tx.read)
5
  {
6
    return 0;
7
  }
8
  UART0_tx.data[UART0_tx.write] = input;
9
  UART0_tx.write =next;
10
  return 1;
11
}

Dieser Puffer wird dann anderweitig auch schön brav von der ISR-Routine 
gemäß Prinzip first-in-first-out ausgelesen und per UART auf die Leitung 
geschoben.

Der Knackpunkt: die Einleseroutine wartet nicht und schreibt immer 
weiter in den Puffer - solange, bis der Schreibzähler des Ringbuffers 
den Lesezähler quasi von hinten eingeholt hat. Spätestens dann sollte 
der Auslesevorgang aus dem AL422B eigentlich stoppen, denn der 
Ringbuffer ist ja voll.

Tut er aber nicht: statt dessen wird in obiger Routine ein "return 0" 
aufgerufen, was von der aufrufenden Routine "void UART0_senden_Byte(char 
Byte)" leider nicht als "Hilferuf" a la "ich bin voll, bitte nix mehr 
reinstopfen" beachtet wird.

Statt dessen kehrt diese zurück zur eingangs gelisteten 3-fachen 
for-Schleife, die ein weiteres Byte aus dem AL422B-FiFo ausliest und 
wiederum per Aufruf von "UART0_senden_Byte(char Byte) -> 
UART0_tx_in(Byte)" versucht in den Ringbuffer zu stopfen.

Genau hier nimmt das Unglück seinen Lauf, denn das Byte wird nicht mehr 
in den Ringbuffer geschrieben, weil die Routine "UART0_tx_in (char 
input)" per "return 0" verlassen wird. Die Folge: das Byte geht 
verloren.
Das ist übrigens auch der Grund dafür, warum dann später reproduzierbar 
zu wenig Bytes über die serielle Leitung rausgeschrieben werden - der 
fehlende Rest ist "per return 0" im Nirvana gelandet.

Verschafft man der ISR allerdings genügend Zeit, den Ringbuffer 
auszulesen und über die serielle Leitung zu schicken, so tritt kein 
Überlauf des Ringbuffers ein und alles ist gut. Das habe ich einfach 
durch Einfügen von "_delay_us(300);" im ganz oben zitierten Codeblock 
getan.

Alternativ kann man auch auch Warteschleifen innerhalb der Routine "void 
UART0_senden_Byte(char Byte)" fliegen - nämlich immer dann, wenn 
"UART0_tx_in(Byte);" ein "return 0" zurückgibt. Das sieht dann so aus:
1
void UART0_senden_Byte(char Byte)
2
{  
3
    while(!(UART0_tx_in(Byte))){}     
4
    UCSR0B |= 0b00100000;  // Data Register empty Interrupt anschalten
5
}

Das geht natürlich nur beim Betrieb mit AL422B FiFo. Ohne FiFo fliegen 
einem gnadenlos aus dem OV7670 die Bits weiter um die Ohren und man kann 
kein Warteschleifchen fliegen.

Ach ja: ich habe für meine Experimente die Baudrate auf 115200 Baud 
gedrosselt, indem ich in UART.c das Register UBRR0L auf den Wert 16 
gesetzt habe.
1
  UBRR0L = 0b00010000;  //115200

Viele Grüße

Igel1


PS: und Danke an Michael, dass er mir auch einen Fehler übriggelassen 
hat - er hatte obiges Problem sicherlich schon längst bemerkt und 
durchschaut und hat sich nur aus Edelmut zurückgehalten (ich meine 
sogar, er hatte in diesem Thread die Gefahr des Pufferüberlaufs schon 
einmal erwähnt).

: Bearbeitet durch User
von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

Hier noch schnell die veränderten Dateien.
1:40 Uhr - au weia - das wird ein harter Tag morgen ...

Gute Nacht

Igel1

von David D. (saturi)


Lesenswert?

Guten Morgen,

Define Lösung Mit der while schleife gefällt mir gut!
Leider -und ich traue es mich fast garnicht zu sagen- war oder ist mir 
das von dir erläuterte Problem bewusst und ich habe das auch immer 
berücksichtigt. Ich habe mit immer über die baudrate ausgerechnet, wie 
lange ich für die Übertragung brauche und dementsprechend ein delay 
reingesetzt. Bei 2MBaud vielen die delays dann ganz raus. Aber in eurer 
Version müssten noch die Kommentare drin sein.
Das erklärt jetzt auch warum bei euch die Bilder nicht "ganz" ankommen. 
Das konnte ich nicht nachvollziehen... da hätte ich vielleicht den von 
dir gefundenen Kniff erwähnen sollen (sorry).

Aber nur weiter so! :D
Jetzt weiß ich auch warum du beim Bild anfangen wolltest, wenn dass noch 
garnicht lief.

Was ich gestern schreiben wollte war, dass ich genau an diesen Stellen, 
wo die Funktionen um den Buffer zu füllen 0 zurückgeben, weil der Buffer 
voll ist, brake points gesetzt habe. Und bei mir löst der dort nicht 
aus.

Grüße,

David

von Michael U. (amiga)


Lesenswert?

Hallo,

kommt ja etwas Leben in die Bude. ;)

Andreas S. schrieb:
> Ich habe - wie oben geschrieben - Deine "main.c" durch Michaels "main.c"
> ersetzt. Einziger Grund: ich wollte die Menüauswahl rauswerfen, um mich
> so auf die Routine "sendFrameBufferToUART (width, height,
> BytesPerPixel);" konzentrieren zu können.

Genau das war mein Grund auch, ich wollte erstmal was sehen und halbwegs 
sicher sein, daß SCCB und die OV7670 Routinen von ihm laufen und das 
machen sie ja auch.

Andreas S. schrieb:
> Flankenwechsel für RCK habe ich vertauscht, damit Du das erste Byte
> nicht verschlumpfst, denn wenn Du die Flanke von RCK von LOW nach HIGH
> gehen lässt und dann erst das Byte aus dem AL422B-FIFO liest, so landest
> Du schon beim zweiten Byte (Michael war das aufgefallen - diese Blumen
> gehen an ihn).

Danke für die Blumen, ich wollte nur wegen dieser Änderung die 
OV7670_with_Fifo.c nicht auch noch mitschicken, hätte nur verwirrt.

Andreas S. schrieb:
> PS: und Danke an Michael, dass er mir auch einen Fehler übriggelassen
> hat - er hatte obiges Problem sicherlich schon längst bemerkt und
> durchschaut und hat sich nur aus Edelmut zurückgehalten (ich meine
> sogar, er hatte in diesem Thread die Gefahr des Pufferüberlaufs schon
> einmal erwähnt).

Vermutet ja, aber eben einfach komplett bei mir ausgeklammert. Edelmut 
ist das weniger, ich habe ja auch noch meine Spielereien hier rumliegen 
und manchmal hae ich selbst als Rentner noch ein paar andere Dinge 
vor...
Ich werden Deine UART-Änderungen mal reinhängen und schauen, was 
passiert. Irgendwann nachher, später oder so.

Andreas S. schrieb:
> By the way: warum nutzt Ihr Eure Logic-Analyser nicht zur Analyse des
> seriellen Protokolls und hantiert statt dessen mit Software herum?
> Mein Intronix LogicPort kann UART im Schlaf decodieren.

Mein Eigenbau LA hat die Routinen dafür nie bekommen.
Dazu kommt ein Umstand aus alter Zeit: meine ersten Diskussionen mit 
UART und USART sind lange her und da war LA noch Fremdwort. Also mußte 
ich mir meine Machwerke meist sehr lange und genau überlegen.Ich finde 
Softwarefehler auch heute noch meist durch schrittweises gedankliches 
Durchspielen, was der µC da macht oder/und durch Brüten über 
Datenblattpassagen und Timingdiagramme.
Auch ein Grund, weshalb ich z.B. bei den ESP, speziell dem ESP32, da 
ungern selbst tief einsteige. Das Zusammenspiel der Hardwarekomponenten, 
dem RTOS und der IO-Matrix ist eine andere Größenordnung als auf einem 
Mega328 rumzuspielen, wo man die Registerbits noch beim Vornamen kennen 
kann.

David D. schrieb:
> Leider -und ich traue es mich fast garnicht zu sagen- war oder ist mir
> das von dir erläuterte Problem bewusst und ich habe das auch immer
> berücksichtigt. Ich habe mit immer über die baudrate ausgerechnet, wie
> lange ich für die Übertragung brauche und dementsprechend ein delay
> reingesetzt. Bei 2MBaud vielen die delays dann ganz raus. Aber in eurer
> Version müssten noch die Kommentare drin sein.
Naja, wäre für mich zumindest generell eine unschöne Lösung, notfalls 
kämen da eben einige #ifdef für die Baudrate rein, um das zur 
Compilezeit anzupassen.
Ich bin der Geschichte, daß meine UNOs über 230400 Misz bauen, auch nur 
am Rande auf den Grund geganen: es sieht so aus, als ob der Mega16U2 als 
USB-Wandler Mist baut, wenn mehr Daten als sein UART-Buffer kommen und 
er zwischendurch das USB-Paket rausschickt. Mit kleinen Datenmegen gehen 
alle Baudraten stabil. Ein CH340 hat das Problem eben nicht. Ich müßte 
also beim Senden des Bildes noch Wartezeiten im passenden Blockabstand 
einfügen, macht aber letztlich keinen Sinn, dann kann ich auch bei 
230kBaud bleiben...

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Guten Morgen,
>
> Define Lösung Mit der while schleife gefällt mir gut!

Danke. Warten in while-Schleifen gehört zu meiner Spezialität:
1
while(I am working all day long and way to much)
2
{
3
   live passes by;
4
}

> Leider -und ich traue es mich fast garnicht zu sagen- war oder ist mir
> das von dir erläuterte Problem bewusst und ich habe das auch immer
> berücksichtigt.

Mist - dann habe ich mir die Nacht umsonst um die Ohren gehauen.
Na ja - bin vermutlich ein bisschen selber schuld - hätte halt genauer 
Deine Posts lesen sollen.

> Ich habe mit immer über die baudrate ausgerechnet, wie
> lange ich für die Übertragung brauche und dementsprechend ein delay
> reingesetzt. Bei 2MBaud vielen die delays dann ganz raus. Aber in eurer
> Version müssten noch die Kommentare drin sein.

Ich hatte mich nur auf "sendFrameBufferToUART (int ImageWidth, int 
ImageHeight, int BytesPerPixel)" konzentriert und da wa nischt drinne 
von wegen "delay" oder so.

> Das erklärt jetzt auch warum bei euch die Bilder nicht "ganz" ankommen.
> Das konnte ich nicht nachvollziehen... da hätte ich vielleicht den von
> dir gefundenen Kniff erwähnen sollen (sorry).

Immerhin: jetzt sind wir alle schlauer (bzw. genauso schlau, wie Du 
schon vorher warst :-))

> Aber nur weiter so! :D
> Jetzt weiß ich auch warum du beim Bild anfangen wolltest, wenn dass noch
> garnicht lief.

Okay - dann gehen wir bitte nochmals einen Schritt zurück und klärer 
erst einmal, was denn aktuell bei Dir nicht funktioniert?  (oder 
vermutlich genauer: wir repetieren noch einmal, was evtl. vor 100-200 
Posts schon einmal gesagt wurde).

Bitte beschreibe Deine Probleme netterweise noch einmal genauer (oder 
verlinke Deine Beschreibung, wenn Du die Probleme bereits vorher im 
Thread dokumentiert hast - ich habe nämlich etwas den Überblick 
verloren).

Dann könnten Michael und ich zielgenau versuchen, die Probleme zu 
reproduzieren, um sie anschließend einzugrenzen.

Ich selber möchte dabei Dein PC-Programm erst einmal außen vor lassen 
(also nicht nutzen) und mich nur auf das MC-Programm fokussieren. So 
können wir eine Fehlerquelle ausschließen.

> Was ich gestern schreiben wollte war, dass ich genau an diesen Stellen,
> wo die Funktionen um den Buffer zu füllen 0 zurückgeben, weil der Buffer
> voll ist, brake points gesetzt habe. Und bei mir löst der dort nicht
> aus.

Das war ein geschickter Schachzug von Dir, denn damit hast Du eindeutig 
bewiesen, dass der Puffer bei Dir nicht überläuft - gut.

> Grüße,
>
> David

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

Andreas S. schrieb:
>
> Okay - dann gehen wir bitte nochmals einen Schritt zurück und klärer
> erst einmal, was denn aktuell bei Dir nicht funktioniert?  (oder
> vermutlich genauer: wir repetieren noch einmal, was evtl. vor 100-200
> Posts schon einmal gesagt wurde).
>

Oh ha - klingt furchtbar arrogant, was ich da heute zwischen Tür und 
Angel   formuliert hatte - sollte es aber gar nicht sein:

Ich bräuchte nur einfach nur nochmals eine Beschreibung, wo genau bei 
Dir der Schuh / die Software drückt, damit ich weiß, wo genau ich 
anfangen soll.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Oh ha - klingt furchtbar arrogant, was ich da heute zwischen Tür und
> Angel   formuliert hatte - sollte es aber gar nicht sein:
mach es nicht schlimmer als es ist. :-)

> Ich bräuchte nur einfach nur nochmals eine Beschreibung, wo genau bei
> Dir der Schuh / die Software drückt, damit ich weiß, wo genau ich
> anfangen soll.
Du triffst damit den Nagel ziemlich genau auf den Kopf.
Was mich dabei betrifft: Deine UART-Änderung werde ist erstmal 
reinwerfen und schauen was passiert. Sein Terminalprogramm werde ich 
nutzen bzw. testen wenn es um irgendwas konkretes geht. Eigentlich ist 
mir dieses ziemlich egal, für mich interessant ist, was geht mit der 
OV7670, was kann man da Erreichen, weiche Bedeutung und Funktion haben 
Einstellungen da auf die Bildqualität usw. usw. Ob ich Registersettings 
da per spezieller Software mache oder die im Source ändere und flashe 
ist mir da relativ egal. Einfach, weil aus meiner Sicht da mehr 
Datenblattstudien, Funktionen verstehen im Vordergrund steht.

Gruß aus berlin
Michael

von David D. (saturi)


Lesenswert?

Andreas S. schrieb:
> Ich hatte mich nur auf "sendFrameBufferToUART (int ImageWidth, int
> ImageHeight, int BytesPerPixel)" konzentriert und da wa nischt drinne
> von wegen "delay" oder so.
Kann durchaus sein, weil ich ja immernur mit RbyR getestet hatte und das 
Empfangen des Gesamt bildes erst danach eingeführt habe.

> Okay - dann gehen wir bitte nochmals einen Schritt zurück und klärer
> erst einmal, was denn aktuell bei Dir nicht funktioniert?  (oder
> vermutlich genauer: wir repetieren noch einmal, was evtl. vor 100-200
> Posts schon einmal gesagt wurde).
Sehr gerne!

> Ich selber möchte dabei Dein PC-Programm erst einmal außen vor lassen
> (also nicht nutzen) und mich nur auf das MC-Programm fokussieren. So
> können wir eine Fehlerquelle ausschließen.
Das wird vermutlich nicht gehen, da das Problem folgendes ist:

Was funktioniert?
-einzelnes Register Lesen
-einzelnes Register Schreiben
-ein Bild requesten und Empfangen (solange es das komplette Bild und 
nicht Row by Row ist. (Colorbar und wenn ich auf Bild stelle ein sehr 
sehr matschiges Bild (siehe Anhang) (vermutlich wegen fehlender 
Registereinstellungen [habe nur die notwendigsten]) Die Einstellungen 
würde ich dann gerne mit dem Terminal machen können.

Was funktioniert nicht? (bzw. nicht zuverlässig?)
alle Register hintereinander lesen (obwohl hier rein befehlstechnisch 
nichts anderes passiert, als beim einzelnen Register lesen)
alle Register hintereinander schreiben
Besonders tragisch ist hier, dass das Problem sporadisch und nicht 
zuverlässig reproduzierbar auftaucht. Wenn ich so ein Tool zur 
überwachung wie Michael einsetze, so ist es laut meiner Anzeige der uC, 
der den einen Befehl des Terminals ignoriert und dieses dann aber auf 
Antwort wartet.
(Bin mir aber nicht sicher, ob ich das "Sniffer" Tool richtig eingesetzt 
habe.

Ist das ganze soweit verständlich?

Ein weiter Punkt, den wir - wie mir scheint - vööig außer acht gelassen 
haben ist, dass wir die Register einfach Blind schreiben, ohne Rücksicht 
auf evtl. reserved Bits richtig? Wie gehen wir damit um?

Gruß
David

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Ein weiter Punkt, den wir - wie mir scheint - vööig außer acht gelassen
> haben ist, dass wir die Register einfach Blind schreiben, ohne Rücksicht
> auf evtl. reserved Bits richtig? Wie gehen wir damit um?

Das Datenblatt der OV7670 ist da etwas... naja...
Im zweifel habe ich mich ausgehend von den dort angegeben Registerwerten 
an den Default-Werten orientiert. Genauso, wie bei reservierten 
Registern, orientiere ich mich im Zweifel an irgendwelchen 
Applikationsbeispielen usw.

Zum Terminal: ich werde mir zumindest die UART-Sachen auch nochmal 
genauer anschauen. Generell: mir erschließt sich der Zweck des 
Terminalprogramms irgendwie nicht.

Register lesen und schreiben: ok.
Alle Register lesen/schreiben und speichern/laden um einen bestimmten 
Zustand  schnell zu rekonstruieren ja, anschauen würde ich mir die Werte 
nur in einem Texteditor, wo ich scrollen, kommentieren, ändern könnte 
und eben bei Bedarf den Kram auch komplett in die AVR-Software 
übernehmen könnte.
Bild holen und evtl. gleich anzeigen ja, mit vordefinierten Formaten und 
im Stück. Die Formate würde ich dann bei bedarf erweitern, alle 
möglichen machen für mich sowieso keinen Sinn (Fifo-Größe/Verwendung).
Bei Register hätte ich vermitlich sogar noch eine änderbare 
Binärdarstellung eingebaut, um mit dem Datenblatt daneben geziehlt Bists 
setzen/löschen zu können.
Alles nur meine Gedanken...

PS: ich hätte die Daten außer den Bilddaten generell als ASCII/HEX 
geschickt/geholt. Dann würde jedes simple Terminalprogramm zum Debug 
reichen: a <enter> -> Kommando raus
35 2f 74 -> Antwort kontrolliert.
Der Aufwand HEX encode/decode ist auch auf dem AVR minimal und spielt 
auch keine Rolle, wenn der Mensch vor dem Bildschirm sowieso die Bremse 
ist.
Auch das ist Ansichtssache, aber sonst müßte ich mir für jedes 
Experiment mit irgendwelchen externen ICs erst ein Spezialprogramm 
basteln und dazu habe ich weder Lust noch nehme ich mir die Zeit.

Letztlich sind es aber Deine Pläne, Vorhaben und Absichten, die das 
alles entscheiden und ich gebe zu, daß ich da immernoch nicht so richtig 
durchschaue, wohin Dein Hase da eigentlich laufen soll.

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Michael U. schrieb:
> Zum Terminal: ich werde mir zumindest die UART-Sachen auch nochmal
> genauer anschauen. Generell: mir erschließt sich der Zweck des
> Terminalprogramms irgendwie nicht.
Der ursprüngliche Gedanke war, mit dem Terminal ein einfaches Werkzeug 
zu haben, um Registerwerte während der Laufzeit bequem ändern zu können, 
ohne für jede Änderung neu compilen+flashen zu müssen. Um hier 
Änderungen an den Register ausprobieren zu können. (Ich weiß du siehst 
im Ausprobieren keinen Sinn. Aber ich bin noch naiv genug ;-) )

> Register lesen und schreiben: ok.
> Alle Register lesen/schreiben und speichern/laden um einen bestimmten
> Zustand  schnell zu rekonstruieren ja, anschauen würde ich mir die Werte
> nur in einem Texteditor, wo ich scrollen, kommentieren, ändern könnte
Das steht noch auf meiner ToDo-Liste, sodass ich die Änderungen auch im 
Terminal vornehmen kann und nicht den Umweg gehen muss.

> Bild holen und evtl. gleich anzeigen ja, mit vordefinierten Formaten und
> im Stück. Die Formate würde ich dann bei bedarf erweitern, alle
> möglichen machen für mich sowieso keinen Sinn (Fifo-Größe/Verwendung).
Ja, hatten wir schon vereinbart ;-) Angefangen wurde jetzt erstmal mit 
RGB565.

> Bei Register hätte ich vermitlich sogar noch eine änderbare
> Binärdarstellung eingebaut, um mit dem Datenblatt daneben geziehlt Bists
> setzen/löschen zu können.
steht ebenfalls auf der ToDo, sodass da auch ein Umstellen wie bei den 
einzelnen Registern möglich wird.

> PS: ich hätte die Daten außer den Bilddaten generell als ASCII/HEX
> geschickt/geholt. Dann würde jedes simple Terminalprogramm zum Debug
> reichen: a <enter> -> Kommando raus
> 35 2f 74 -> Antwort kontrolliert.
> Der Aufwand HEX encode/decode ist auch auf dem AVR minimal und spielt
> auch keine Rolle, wenn der Mensch vor dem Bildschirm sowieso die Bremse
> ist.
Das verstehe ich nicht muss ich gestehen. Also die Kommandos und auch 
Bild Bytes werden ja als Bytes geschickt, wie du sie dir dann im 
Terminal anzeigen lässt ist doch deine Sache. Du kannst auch einfach mit 
Terra Term mit meinem uC Programm kommunizieren. Die Befehle sind in der 
Tabelle in diesem Beitrag zu sehen:
Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)"

> Auch das ist Ansichtssache, aber sonst müßte ich mir für jedes
> Experiment mit irgendwelchen externen ICs erst ein Spezialprogramm
> basteln und dazu habe ich weder Lust noch nehme ich mir die Zeit.
Das verstehe ich ebenfalls nicht, vermutlich weil ich vorherige Aussage 
nicht verstanden habe :D

> Letztlich sind es aber Deine Pläne, Vorhaben und Absichten, die das
> alles entscheiden und ich gebe zu, daß ich da immernoch nicht so richtig
> durchschaue, wohin Dein Hase da eigentlich laufen soll.
Wie oben beschriebe: "einfaches" handeln der Kamera ohne hunderte flash 
Vorgänge.

Außerdem kann ich für meine späteren Zwecke teile dieses Programms 
weiterbenutzten (maschinelle Bildverarbeitung) (kein Video nur 
Einzelbilder) ;-)

Gruß

David

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Das verstehe ich nicht muss ich gestehen. Also die Kommandos und auch
> Bild Bytes werden ja als Bytes geschickt, wie du sie dir dann im
> Terminal anzeigen lässt ist doch deine Sache. Du kannst auch einfach mit
> Terra Term mit meinem uC Programm kommunizieren. Die Befehle sind in der
> Tabelle in diesem Beitrag zu sehen:

Ganz einfach: normalerweise nutze ich /und die Terminalprogramm) 
irgendeine Emualtion, meist VT100. Da ist es dann mühsam Controlcodes 
(0x00...0x1f) zu senden bzw. eine Einstellung zu finden, die empfangenen 
Daten als hex ausgibt. HTerm kann sowas, ist aber eigentlich auch eher 
ein Debug-Tool als ein Terminalprogramm.

David D. schrieb:
> Wie oben beschriebe: "einfaches" handeln der Kamera ohne hunderte flash
> Vorgänge.
Wenn es ein guter alter TEA5757 wäre würde ich Dir vorbehaltlos 
zustimmen, beim MAS3507D wurde es damals für mich schon haariger.
Beim ENC28J60 mußte ich mir erst Grundlagen von TCp/IP usw. 
zusammensuchen, für einen rudimentären Stack mit dem Chip reichte es 
dann auch, ARP-Ping und IDCP-Ping ging und dann fehlöte damals zeit und 
auch Lust und ich habe auf was hlabwegs fertiges genommen, das 
angepasst. Die gewonnenen Vorkenntnisse haben zumindest gereicht, recht 
zielsicher in den fremden Sourcen dir richtigen Stellen zu finden.

Bei den 201 Registern der OV7670 incl. haarsträubender Bitkombination 
und Abhängigkeiten würde ich mir das freiwillig nicht antun wollen.
Ich will aus dem Teil ein Bild haben, ich muß rausfinden, welce Register 
ich dazu anfassen muß und welche Rolle genau diese spielen. Was die 
anderen 182 machen ist mir da ziemlich egal. ;) Es würde mir auch wenig 
für andere Projekte (Spielereien) bringen, bei einem anderen Kameramodul 
geht das Suchen sowieso von vorn los.
- gewünschte Auflösung
- gewünschtes Bildformat
dann die ersten Extras:
- Belichtungssteuerung
- Gammakorrektur
- Farbkorrektur
dann die Spezialitäten:
- Belichtungsautomatik
- Weißabgleichautomatik
- 50/60Hz Erkennung (Kunstlicht)
- Gain-Regelung, Nachtmodus
und was die Teile konkret jeweils können.
Das muß ich bei Bedarf auch in einem anderen Datenblatt schnell finden 
und testen können.
Die Kamera liefert prinzipiell ein Bild im gewünschten Format.
Jetzt könnte ich mich z.B. mit den Registern auseinandersetzen, die die 
Bildlage auf dem Sensor bestimmen, eigentlich müßten die 320x240 ohne 
Fehler an den Rändern rauskommen.

David D. schrieb:
> Außerdem kann ich für meine späteren Zwecke teile dieses Programms
> weiterbenutzten (maschinelle Bildverarbeitung) (kein Video nur
> Einzelbilder) ;-)
keine Einwände dagegen. Meine damalige LA-Software in VB6 kann auch nur 
rund 10 Kommandos ,it Einstellungen zum AVR schicken und dann 32k 
Sampleram zurückbekommen. Die Software selbst auf dem PC ist dann 
Anwendung: Einstellbutton, Darstellung der Samledaten usw. Das lief auch 
nicht auf Anhieb, war aber das erste. was ich stabil in Gang bekommen 
mußte.

Genug philosophiert. ;)

Gruß aus Berlin
Michel

von Andreas S. (igel1)


Lesenswert?

Hi David,

by the way:

Ich weiß nun, wann Dein Terminal-Programm (V0.6) am rechten Rand 
beschnitten wird:

Ich habe nämlich die Textgröße und weitere Elemente auf dem Bildschirm 
dauerhaft vergrößert, indem ich unter Win7 X64 in den Einstellungen 
Systemsteuerung\Darstellung und Anpassung\Anzeige im Fenster "Lesbarkeit 
auf dem Bildschirm erleichtern" die Vergrößerung auf "Mittel - 125%" 
eingestellt habe. Meine Auflösung ist dabei nach wie vor 1920x1200.

Sobald ich obige Einstellung auf 100% (Standard) zurücksetze, wird Dein 
Terminalfenster nicht mehr am rechten Rand beschnitten.

Es wäre super, wenn Du diesen Bug fixen könntest, denn dann könnte ich 
auch ein bisschen mit Deinem Terminalprogramm testen.

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Was funktioniert nicht? (bzw. nicht zuverlässig?)
> alle Register hintereinander lesen (obwohl hier rein befehlstechnisch
> nichts anderes passiert, als beim einzelnen Register lesen)
> alle Register hintereinander schreiben
> Besonders tragisch ist hier, dass das Problem sporadisch und nicht
> zuverlässig reproduzierbar auftaucht. Wenn ich so ein Tool zur
> überwachung wie Michael einsetze, so ist es laut meiner Anzeige der uC,
> der den einen Befehl des Terminals ignoriert und dieses dann aber auf
> Antwort wartet.
> (Bin mir aber nicht sicher, ob ich das "Sniffer" Tool richtig eingesetzt
> habe.
>
> Ist das ganze soweit verständlich?

Leider nein (sorry, wenn ich etwas langsam von Kapee bin):

Meinst Du mit "alle Register hintereinander lesen/schreiben", dass die 
Lese-/Schreibroutinen auf dem ATmega buggy sind, oder meinst Du dass der 
Lese-/Schreibvorgang (sporadisch) schief geht, wenn Du das 
Lesen-/Schreiben von Deinem Terminalprogamm aus anstößt?

Viele Grüße

Igel1

: Bearbeitet durch User
von David D. (saturi)


Lesenswert?

Andreas S. schrieb:
> Leider nein (sorry, wenn ich etwas langsam von Kapee bin):
kein Problem!

Es gibt in meinem uC-Programm keine Routinen für das auslesen oder 
schreiben von mehreren Registern.

Auf meinem Terminal Programm gibt es das aber zum Beispiel beim klick 
auf "Read Device Setting", "get Camera Status" (lesen) und "write Device 
Settings" (schreiben) die Möglichkeit mehrere Register hintereinander zu 
lesen respektive zu schreiben. Dabei läuft dann folgender 
Kommunikationspingpong ab:

am Beispiel lesen:

Terminal fordert Wert für Register 0x01 an
Terminal wartet auf Antwort
uC gibt Wert für Register 0x01 aus

Terminal forder Wert für Register 0x02 an
Terminal wartet auf Antwort
uC gibt Wert für Register 0x02 aus

...


(Das Programm bleibt nicht während des Wartens in einer While schleife 
hängen, da das ganze in C# Eventbasiert verarbeitet wird)


wenn ich mir jetzt anschaue, welche Kommunikation statt findet wenn 
bspw. nicht alle Register gelesen werden, so gerät die Kommunikation 
nach Terminal wartet auf Antwort ins stocken, weil einach die Antwort 
vom uC ausbleibt. Das ganze tritt sporadisch auf, sprich manchmal hängt 
es nach wenigen Registern manchmal nach mehreren manchmal garnicht. Und 
genau das kann ich mir nicht erklären.

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
(formatiert von Igel1)
1
> folgende Kommandos kann der uC empfangen:
2
> Command  Auswirkung     Byte1              Byte2             expected Return Value
3
> 0x01     Read Register  Register Address   -                 1 Byte register Value
4
> 0x02     Write Register Register Address   newRegisterValue  1 Byte Errorcode

Hmmm - mein Logic-Analyzer sagt da etwas anderes.
Du sendest in Wirklichkeit, z.B. beim Auslesen von Register 0x05:

0x01 0x05 0x0D 0x0A

Und erhältst in Wirklichkeit als Antwort:

0x05 0x80

... wobei 0x80 der Registerinhalt von Register 0x05 ist.

Und die Schreibfolge sieht so aus, wenn Du z.B. Register 0x05 mit Wert 
0x80 beschreibst:

0x02 0x05 0x80 0x0D 0x0A

Und als Antwort erhältst Du den Fehlercode:

0x00

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> wenn ich mir jetzt anschaue, welche Kommunikation statt findet wenn
> bspw. nicht alle Register gelesen werden, so gerät die Kommunikation
> nach Terminal wartet auf Antwort ins stocken, weil einach die Antwort
> vom uC ausbleibt. Das ganze tritt sporadisch auf, sprich manchmal hängt
> es nach wenigen Registern manchmal nach mehreren manchmal garnicht. Und
> genau das kann ich mir nicht erklären.

Ah ja: Du meinst, der grüne Ladebalken hängt (manchmal), wenn Du auf den 
Button "Read Device Settings" drückst?

Yep - dieses Problem kann ich zumindest reproduzieren.

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Ähm ja... :D

Das liegt daran, wie der uC erkennt ob ein Befehl vollständig gesendet 
wurde.

An jedes Kommando, dass das Terminal sendet wird am Ende ein CR+LF dran 
gehangen (13, 10 in dez. oder 0x0D 0x0A in Hex)


Anhand dieses Indikators wird der Rx Buffer in Sinnvolle empfangene 
Befehle gestückelt und sicher gestellt, dass ein Befehl erst verarbeitet 
wird, wenn alle notwendigen Informationen vorhanden sind.


Die Verarbeitung findet dann in UART.c unter der Funktion UART0_rx_work 
statt:
1
...
2
  if(UART0_rx_complete())
3
  {
4
5
  char Befehl[UART0_Befehl_FiFo] = {};      // Hier steht der Befehl
6
  volatile int j = 0;
7
  volatile int i = 0;
8
  do
9
  {
10
    char temp = UART0_rx_out();
11
      
12
    Befehl[i] = temp;
13
    i++;
14
15
    //Künstlicher Zähler, um das Abfragen der beiden Bits auch beim ersten zu ermöglichen
16
    if(i<2)
17
    j=1;
18
    else
19
    j=0;
20
  }while(((Befehl[i+j-2] != (char)0x0D) || (Befehl[i-1] != (char)0x0A))&&(i<UART0_Befehl_FiFo));        // solange kein CR+LF erkannt wird
21
...

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

die Bytefolgen hatte ich mir im Sniffer auch angeschaut und bin zu dem 
gleichen Schluß gekommen, was gesendet wird usw.
Zum Glück für Andreas habe ich im Moment etwas wenig Zeit für die 
GEschichte, so kann er mir in Ruhe die Arbeit abnehmen. ;-))

Ich habbe mal eine IRQ-RX-Routine in die uart.c gepackt, weil ich mir 
Davids Ablauf noch nicht im Detail angeschaut habe.

Ich hänge die hier einfach mal ran, in main() müssen vorn noch 3 Zeilen 
eingefügt werden.
In uart.h muß die Zeile
#define UART_MAXSTRLEN 63
eingefügt werden und in main()
1
extern volatile uint8_t uart_str_complete;     // 1 .. String komplett empfangen
2
extern volatile uint8_t uart_str_count;
3
extern volatile char * uart_string[];
Ich wollte da eigentlich nur schnell testen, ob sein switch für die 
Kommandoauswertung das, macht, was er soll, ist aber noch nicht 
passiert.
Ist alles nicht schön gemacht, sollte nur gehen...

Es fehlt z.B. ein error-flag wenn der Buffer voll ist, da geht es dann 
nie weiter. Müßte in main() abgefragt werden um den Buffer einfach neu 
zu initialisieren bei einem derartigen Fehler und ein overflow zum 
Terminal gemeldet werden..

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> Zum Glück für Andreas habe ich im Moment etwas wenig Zeit für die
> GEschichte, so kann er mir in Ruhe die Arbeit abnehmen. ;-))

Na wenn Du Dich da mal nicht täuscht: Andreas ist die nächsten 5 Tage 
computerlos, wird also erst mal nix mit Weiterdebuggen. Ich lasse Euch 
zwei Hübschen also erst einmal alleine im Code weiterrühren.

Aber so ist das mit dem Hobby: ständig ist alles andere wichtiger - es 
ist zum Mäusemelken.

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Na das klingt ja nach nem Karnevals Jecken... ich komm für den Samstag 
extra hoch ;-)

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Karnevals Jecken...

Was ist das??? ;-)

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Hi David,

habe gerade eine heiße Spur entdeckt, werde aber keine Zeit mehr haben, 
sie zu verfolgen:

Dein Ringpuffer-Mechanismus funktioniert offenbar nicht so, wie er 
eigentlich angedacht ist.

So definierst Du den Ringpuffer und die zugehörigen Zähler "read" und 
"write":
1
#define UART0_rx_size 512          // Nur Werte 2^n zulässig !
2
#define UART0_rx_mask (UART0_rx_size-1)
3
4
5
//------------------------------------------------------------------------------
6
7
int temp = 0;  
8
struct UART0_rx        //Receive Buffer
9
{
10
char data[UART0_rx_size];
11
char read;
12
char write;
13
}UART0_rx= {{}, 0, 0};

Und so verwendest Du sie:
1
int UART0_rx_in (char input)
2
{
3
  char temp= ((UART0_rx.write+1)&UART0_rx_mask);  //
4
  if (temp==UART0_rx.read)              //FiFo voll ?
5
  {  
6
    return 0;                    //return 0 -> Fifo voll
7
  }
8
  UART0_rx.data[UART0_rx.write]=(char)input;    //Daten ins Array legen
9
  UART0_rx.write = temp;                //write auf nächste Specicherzelle schieben
10
  return 1;                      //return 1 -> Fifo abspeichern erfolgreich 
11
}

Dabei fällt auf, dass die beiden Zähler nur 8 Bit breit sind, Dein 
Modulo-Mechanismus mit
1
((UART0_rx.write+1)&UART0_rx_mask)

... aber offenbar von einem Integer-Wert ausgeht.

Will sagen: der Mechanismus läuft ins Leere.

Jetzt müsste man nochmals genau durchdenken, ob es trotzdem per Zufall 
funktioniert - an allen Stellen und sogar auch bei Subtraktionen, die ja 
ebenfalls vorkommen.

Jedenfalls scheint es nicht so gedacht gewesen zu sein und von Deinem 
512 Byte breiten Ringpuffer werden dadurch auch nur 256 Bytes genutzt.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Jedenfalls scheint es nicht so gedacht gewesen zu sein und von Deinem
> 512 Byte breiten Ringpuffer werden dadurch auch nur 256 Bytes genutzt.

warum reserviert man auf einem kleinen AVR mit nur 2k Ram solche 
Riesenbuffer? So lang kann doch keine Kommandofolge sein und bevor er 
die nicht bearbeitet und beantwortet hat, macht es doch keinen Sinn was 
neues zum AVR zu schicken. Beim Senden ist es doch auch egal, ob man 
128Byte oder 512Byte Häppchen schickt?
Ist vielleicht auch Vorurteil, aber bei mir heißt AVR eben immernoch Ram 
sparen, wo es geht und geziehlt dort einsetzen, wo es wirklich nötig 
ist.
Bei den ESPs bin ich da weit weniger sparsam... ;)

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Hi Dirk,

schau mal hier:
https://ide.geeksforgeeks.org/E7p41NoTYk

Morgen mehr dazu.

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

Uppps - aus David wurde Dirk - sorry...

von Andreas S. (igel1)


Lesenswert?

... und noch mehr zum Thema:
https://ide.geeksforgeeks.org/nL9paB6EfN

Viele Grüße
Andreas

von Andreas S. (igel1)


Lesenswert?

Und noch eine schönere Version:

https://ide.geeksforgeeks.org/PwEDpstPrZ

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

ich bin mal auf meiner Spielwiese geblieben, also meine UART RX/TX 
Routine drin.
Schnelltest sagt: Register read/write geht, register komplett lesen 
geht, Kamera Init geht manchaml erst beim 2. Mal, Get Kamera Status 
geht.

Bilder holen passt von der Initalisierung nicht zusammen, er setzt VGA 
und holt dann 320 Zeilen und weiß nicht weiter. Es bleibt aber nichts 
hängen, ich kann im Terminalprogramm mit anderen Funktioneh weiter 
machen.
Es passieren bei Write Register seltsame Dinge: ich schreibe 0x40 in Reg 
0x80, bekomme ok zurück. Beim Lesen von Reg 0x80 meldet er meist 0x00 
zufürck obwohl definitiv geschrieben wurde.
Nochmal schreiben meldet 0x00 im seriellen Debug zurück, Terminal sagt 
Error 68. Muß ich mir mal genauer anschauen.
Andreas, ich lasse Dir weiter das Kramen in seinen UART-Sourcen und 
bleibe erstmal bei meiner Testversion...

Für David hänge ich mal meine modifizierte main.c und uart.c ran, falls 
er damit mal testen will, er kann ja sein Terminal sicher besser 
bedienen als ich...

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Hi David,

hier eine noch bessere Version:
https://ide.geeksforgeeks.org/kueWbVYXmL

Der Code lautet:
1
#include <stdio.h>
2
3
#define SIZE 512
4
#define MASK (SIZE - 1)
5
6
int main() {
7
  char c;
8
  char carray[] = {0,1,2,126,127,128,129,-1,-2};
9
  char cplus1;
10
  int  cintplus1;
11
  int data[SIZE]={};
12
  
13
  for(int p=0; p<SIZE; p++){
14
      data[p] = p;
15
  }
16
  
17
  for(int k=0; k<sizeof(carray); k++){
18
  
19
    c=carray[k];
20
      cplus1=(c+1) & MASK;
21
      cintplus1=(c+1) & MASK;
22
  
23
    printf("c=%d\n", c);
24
    printf("cplus1=%d\n", cplus1);
25
    printf("cintplus1=%d\n", cintplus1);
26
    printf("data[c]=%d\n", data[c]);
27
    printf("data[(c-1) & MASK]=%d\n", data[(c-1) & MASK]);
28
    printf("data[c & MASK] = %d\n",   data[c & MASK]);
29
    printf("data[(c+1) & MASK]=%d\n", data[(c+1) & MASK]);
30
    printf("........................\n\n");
31
  }
32
  return 0;
33
}

Und das Ergebnis lautet:
1
c=0
2
cplus1=1
3
cintplus1=1
4
data[c]=0
5
data[(c-1) & MASK]=511
6
data[c & MASK] = 0
7
data[(c+1) & MASK]=1
8
........................
9
10
c=1
11
cplus1=2
12
cintplus1=2
13
data[c]=1
14
data[(c-1) & MASK]=0
15
data[c & MASK] = 1
16
data[(c+1) & MASK]=2
17
........................
18
19
c=2
20
cplus1=3
21
cintplus1=3
22
data[c]=2
23
data[(c-1) & MASK]=1
24
data[c & MASK] = 2
25
data[(c+1) & MASK]=3
26
........................
27
28
c=126
29
cplus1=127
30
cintplus1=127
31
data[c]=126
32
data[(c-1) & MASK]=125
33
data[c & MASK] = 126
34
data[(c+1) & MASK]=127
35
........................
36
37
c=127
38
cplus1=-128
39
cintplus1=128
40
data[c]=127
41
data[(c-1) & MASK]=126
42
data[c & MASK] = 127
43
data[(c+1) & MASK]=128
44
........................
45
46
c=-128
47
cplus1=-127
48
cintplus1=385
49
data[c]=710832128
50
data[(c-1) & MASK]=383
51
data[c & MASK] = 384
52
data[(c+1) & MASK]=385
53
........................
54
55
c=-127
56
cplus1=-126
57
cintplus1=386
58
data[c]=32517
59
data[(c-1) & MASK]=384
60
data[c & MASK] = 385
61
data[(c+1) & MASK]=386
62
........................
63
64
c=-1
65
cplus1=0
66
cintplus1=0
67
data[c]=0
68
data[(c-1) & MASK]=510
69
data[c & MASK] = 511
70
data[(c+1) & MASK]=0
71
........................
72
73
c=-2
74
cplus1=-1
75
cintplus1=511
76
data[c]=8
77
data[(c-1) & MASK]=509
78
data[c & MASK] = 510
79
data[(c+1) & MASK]=511
80
........................


Schau Dir nun Deine Routinen an, die Deinen Ringbuffer verwenden.
Z.B. Diese hier:

[code]
int UART0_rx_complete(void)
{
  //Wenn CR+LF empfangen wird, ist der Befehl vollständig
  if(UART0_rx.data[(UART0_rx.write -2)&UART0_rx_mask] == 0x0D 
&&UART0_rx.data[(UART0_rx.write-1)&UART0_rx_mask]==0x0A)
  {
    return 1;
  }
  else
  {
    return 0;
  }
}
[/code)

... und leite aus obigen Programm ab, was passiert, wenn z. B.
UART0_rx.write = 0 ist.

Ja, richtig: Du liest Puffer 510 und 511 aus.
Scheint noch halbwegs richtig zu sein.

Aber wirst Du diese Pufferplätze jemals beschreiben?

Schau Dir dafür diese Routine an:

[code]
int UART0_rx_in (char input)
{
  char temp= ((UART0_rx.write+1)&UART0_rx_mask);  //
  if (temp==UART0_rx.read)              //FiFo voll ?
  {
    return 0;                    //return 0 -> Fifo voll
  }
  UART0_rx.data[UART0_rx.write]=(char)input;    //Daten ins Array legen
  UART0_rx.write = temp;                //write auf nächste 
Specicherzelle schieben
  return 1;                      //return 1 -> Fifo abspeichern 
erfolgreich
}
[/code)

Mit Blick auf mein Testprogramm oben meine ich, dass spätesten ab 
UART0_rx.write=128

... einiges Unvorhergesehene passieren wird.

Viele Grüße

Igel1

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Scharfes Nachdenken ergab: der Ringpuffer-Mechanismus sollte eigentlich 
funktionieren, wenn man für alle Variablen, die in Array-Indizes bzw. in 
Indexrechnungen verwendet werden, unsigned int Variablen verwendet.

Mangels Rechner kann ich das leider aktuell nicht testen.

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

Habe hier mal den Typ der Indexvariablen „c“ von char auf unsigned int 
umgestellt:

https://ide.geeksforgeeks.org/kueWbVYXmL

Scheint zu funktionieren - insbesondere an den Rändern des Puffers:
Am oberen Rand wird von 511 sauber auf 0 gesprungen.
Und am unteren Rand wird von 0 sauber nach 511 hochgesprungen.
Genau so soll ein Ringpuffer ja funktionieren.

Viele Grüße

Andreas

von David D. (saturi)


Lesenswert?

Hallo Andreas,
ich wollte ein kurzes Lebenszeichen von mir geben!

das sieht alles sehr sehr interessant aus. Leider bin ich noch nicht 
dazu gekommen dass in aller Ruhe zu überdenken, und nachzuvollziehen, 
sondern immernur zwischen Tür und Angel auf dem Handy, was dann auch 
nicht wirklich erfolgreich war.
Ich werde mir das jetzt die nächste halbe Stunde anschauen und 
spätestens Morgen gebe ich dir dann ein Statement ab!

@Michael, danke für Routinen. Das werde ich auch mal in meinen Code 
werfen und schauen wo/was da am Terminal klemmt.

Gruß

David

von David D. (saturi)


Lesenswert?

Edit: in diesem post stand nur wirres Zeug :D einfach ignorieren....

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Hallo Andreas,
> ich wollte ein kurzes Lebenszeichen von mir geben!

Wir hatten schon befürchtet, dass man Dich im Karneval totgebützt hat.

Was Deinen Code angeht, hier die Zusammenfassung:

- bei jeglichen Operationen mit char-Variablen, werden diese zunächst
  in int verwandelt - das ist einfach so in C.

- diese Verwandlung führt zusammen mit der Maskierung mit „& 0x1FF“
  zu nicht vorhergesehenen Ergebnissen - z.B. landest Du nach Arraywert
  127 als nächstes nicht bei 128, sondern bei 385, weil 128 bei signed
  char eben -128 entspricht (binär 0x1000 0001), was in int verwandelt 
zu
  binär 0x1111 1111 1000 0001 wird, was mit 0x1FF maskiert zu
  0x0000 0001 1000 0001 wird, was wiederum 385 entspricht.

- ein weiterer Bug ist die Verwendung von signed char statt einem
  unsigned Typen.

- und die Maskenlänge mit 9 Bit passt nicht so recht zum char-Wert.

Heilung aus der ganzen Misere könnte die Umstellung aller im
Zusammenhang mit Index-Zugriffen verwendeten Variablen auf
unsigned int bringen.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

wollte mich auch nur mal kurz melden, im Moment nicht weiter mit dem 
Kram gemacht. Ich werde nachher mal meinen Kram und den Sniffer mal 
anwerfen und schauen, wie sein Terminal mit dem AVR zusammenspielt. 
Bedienen kann ich das Terminal immernoch nicht ;-), es ist also "Button 
anlicken", schauen, was geschickt wird, schauen, was sein AVR-Code 
zurücksenden sollte und schauen, ob das auch kommt.
Andreas, schön daß Du seinen UART-Buffer so auseinandegenommen hast, ich 
werde den auch weiterhin erstmal ignorieren.

Mich interessiert im Moment da eher, was passiert bzw. passieren soll, 
wenn ich mein Registerinit auskommentiere, also nur Davids Vorgehen aus 
dem Terminal nachvollziehen kann, wie ich da zu einem Bild komme.

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Hallo,
Andreas S. schrieb:
> - diese Verwandlung führt zusammen mit der Maskierung mit „& 0x1FF“
>   zu nicht vorhergesehenen Ergebnissen - z.B. landest Du nach Arraywert
>   127 als nächstes nicht bei 128, sondern bei 385, weil 128 bei signed
>   char eben -128 entspricht (binär 0x1000 0001), was in int verwandelt
> zu
>   binär 0x1111 1111 1000 0001 wird, was mit 0x1FF maskiert zu
>   0x0000 0001 1000 0001 wird, was wiederum 385 entspricht.
...
> Heilung aus der ganzen Misere könnte die Umstellung aller im
> Zusammenhang mit Index-Zugriffen verwendeten Variablen auf
> unsigned int bringen.
>
Verstanden. Aktuell habe ich bei allen Bufferzugriffen unsigned char und 
die Buffergröße kleiner auf 128 (also kleiner als ein Byte). Diese 
Änderungen kamen aus der Beseitigungen der ganzen Warnings, womit der 
Compiler vermutlich auf genau auf das von dir beschriebene Problem
hinweisen wollte. Was ich jetzt noch nicht ganz nachvollziehen kann ist, 
warum ich auf unsigned int wechseln soll. Okay, wenn du davon ausgehst, 
dass die Maske 512 darstellt, komme ich mit einem Byte nicht mehr hin. 
Aber nach dem Rüffel von Michael einige Posts zuvor hatte ich die 
Buffergröße wieder zurückgenommen.
Dann sollte unsigned char doch genauso funktionieren oder tut es das 
nicht?
vielen Dank für die ausführliche Untersuchung.

Wenn es wirklich so ist, dass char zunächst in int umgewandelt wird, 
warum gibt es dann den Datentyp? wenn ich mir damit keinen Speicherplatz 
spare kann ich ihn ja komplett weglassen?

Gruß
David

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Aber nach dem Rüffel von Michael einige Posts zuvor hatte ich die
> Buffergröße wieder zurückgenommen.

naja, ein Rüffel sollte es ja nicht gleich sein...
Unser Herangehen ist da nur verschieden. Du hast versucht, ein mehr oder 
weniger universelles Konzept für verscheidene Sachen einzubauen, finde 
auch ich prinzipiell sinnvoll.
Mein Ansatz war/ist es: ich habe einen kleinen AVR und der soll mit 
einem Kameramodul was machen, wofür er eigentlich sowieso zu klein ist.
Das auch noch möglichst gut und schnell.
Da ordne ich für mich erstmal alles andere unter.

David D. schrieb:
> Wenn es wirklich so ist, dass char zunächst in int umgewandelt wird,
> warum gibt es dann den Datentyp? wenn ich mir damit keinen Speicherplatz
> spare kann ich ihn ja komplett weglassen?

Hier lehen ich mich jetzt mal aus dem Fenster, weil ich nur C 
Hobbyprogrammierer bin, Andreas möge also korrigieren/ergänzen.
C berechnet generell mit int-Werten. int auf dem AVR ist 16Bit, auf 
anderen CPUs meist 32Bit, ist Architekturabhängig.
char a = 5;
char b = 3;
char c = 0;
c = a+b:
In der Berechnung wird a und b generell auf int konvertiert, dann 
gerechnet und das Ergebnis nach char konvertiert und c zugewiesen. Platz 
spare ich also mit char schon, die Rechnerei in int ist c geschuldet, es 
war nie für eine 8Bit-Umgebung gedacht...
Die Fallen entstehen z.B. bei anderen Datentypen.
int a = 123;
float c = 0;
c = a/10;
Da enthält c nach der Berechnung nicht etwas 123/10 =12.3 sondern 12.0.
Da a ein int ist und 10 auch in einen int passt, wird als int gerechnet 
und das Ergebnis nach float gewandelt.
c = a/10.0; macht aus der Konstanten einen float und damit findet auch 
die Berechung als float statt und es kommt 12.3 raus.
Bei mir hat das zur Folge, daß ich im Zweifel gern Klammer bei 
komplexeren Sachen setze, wo dann die C-Könner aufheulen, weil das doch 
auch ohne Klammern eindeutig und logisch ist...

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Ernüchterung:
auch mit unsigned int ergibt sich selbiges Verhalten. Schade, das 
sporadische Auftreten wäre sogut mit dem Überlauf des Buffers zu 
erklären gewesen.

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

David D. schrieb:
> Was ich jetzt noch nicht ganz nachvollziehen kann ist,
> warum ich auf unsigned int wechseln soll. Okay, wenn du davon ausgehst,
> dass die Maske 512 darstellt, komme ich mit einem Byte nicht mehr hin.

Genau aus diesem Grunde ...
Außerdem willst Du ja evtl. später einmal die Kamera ohne FIFO auslesen 
und dann wirst Du vielleicht die 512 Bytes benötigen - zumindest wenn Du 
QVGA auslesen willst und evtl. darauf angewiesen bist, dass Du im 
horizontalen Austastzeitraum die restlichen Pixel seriell übertragen 
kannst, weil  während der 2x320 Pixel-Ausgabe nicht genügent Zeit zur 
seriellen Übertragung war.

> Aber nach dem Rüffel von Michael einige Posts zuvor hatte ich die
> Buffergröße wieder zurückgenommen.

Hat er nicht so gemeint ;-)   (siehe letztes Posting)

Ich habe gerade übrigens alle Variablen, die in Zs.hang mit Indizes 
verwendet werden, in UART.c auf uint16_t gesetzt und außerdem noch ein 
oder zwei weitere Typ-Ungenauigkeiten behoben.

Seitdem funktioniert das Auslesen der Registerwerte über Dein 
Terminal-Programm wunderbar (Notiz: ich habe 115200 Baud 8N1 in UART.c 
hineingecoded, um Bitübertragungsmäßig 100% auf der sicheren Seite zu 
sein)

Testszenario: ATmega frisch gestartet, dann Terminal-Programm frisch 
gestartet, dann Baudrate im Terminal-Programm eingestellt, dann auf 
Button "verbinden" geklickt, dann auf Button "Read Device Settings" 
gedrückt (bis zu 30x hintereinander - stets ohne Probleme).

Nun könnten wir die nächsten Probleme angehen: bitte beschreibe 
diejenigen Bugs, die Du als nächstes fixen willst, dann kann ich 
zunächst versuchen, sie zu reproduzieren.

Vermutlich benötige ich dafür dann allerdings ein komplettes 
Terminal-Fenster, welches nicht am rechten Rand beschnitten wird (vgl. 
meinen alten Post: 
Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)" )
Wäre nett, wenn Du, David, das fixen könntest ...

Ach ja: bitte erstelle noch eine kleine Hilfedatei, in der Du Deine 
Oberfläche etwas beschreibst. Felder, wie über dem Button "senden" oder 
über dem Button "empfangen" sind nicht selbsterklärend (jedenfalls nicht 
für mich). Ebenso weiß ich nicht, was sich hinter dem Button "read for 
change" verbirgt und die Buttons ganz rechts verstehe ich auch nicht 
genau - um nur wenige Beispiele zu nennen.

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Ernüchterung:
> auch mit unsigned int ergibt sich selbiges Verhalten. Schade, das
> sporadische Auftreten wäre sogut mit dem Überlauf des Buffers zu
> erklären gewesen.

Nein - es funktioniert bei mir reproduzierbar gut:

Ersetze einfach einmal Deine UART.c und die OV7670_with_Fifo.c durch 
meine Versionen aus dem letzten Posting und berichte ...

Viele Grüße

Igel1


PS: bitte genau das Testszenario aus dem letzten Posting einhalten, 
sonst spucken Dir evtl. andere Fehler dazwischen.

von Andreas S. (igel1)


Lesenswert?

Hi David,

ich hätte aktuell gerade etwas Zeit und könnte die nächsten Bugs 
untersuchen, benötige dazu aber etwas Feedback von Dir (siehe meine 
letzten Postings).

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Terminalprogramm: Kamara initialisieren -> ok
Auch mehrmals hintereinander -> kein Problem, ok
Macht nur wenig Sinn, weil da jedesmal u.a.
Ov7670_initPins(); und OV_SCCB_Init();
aufgerufen wird, was ja eigentlich wenig Sinn macht, eine Anzeige, daß 
Init erfolgt, ist gibt es ja nicht außer im Logfenster.

Dann get camera status -> ok, auch mehrmals.
Jetzt wieder Kamara initialisieren -> angeblich Error Code 4.
Angeblich, weil vom AVR definitv 0 zurückkommt und die 4 wohl von der 
Quittung bei get camera status stammt...

Wenn nach AVR-Reset und Terminalstart nicht Kamara initialisieren 
aufgerufen wird, sondern z.B. get camera status oder read Device 
Settings gibt es keine Fehler. Die gelesenen Werte sind natürlich Unfug, 
weil weder die Ca-Pins noch SCCB auf dem AVR initialisiert sind...

Wenn nach AVR Reset und Terminalstart direkt nach Verbinden get camera 
status aufgerufen wird (ohne Init!) sagt die Anzeige:
Version: 0x0 0x73
Resolution: QVGA
Color Format: RGB565

Wunsch? Wirklichkeit kann es da ja nicht sein...

Jetzt Kamara initialisieren (endet mit dem falschen Error 4).
Dann wieder get camera status und jetzt ist es VGA und YUV.
Wohl auch nicht besser?
Ich setze immernoch direkt nach OV7670_init(); meine beiden 
default-Rgisterwerte, eigentlich müßte die Cam also auf QVGA 565 stehen. 
Ich habe gerade mal ein paar Stichproben gemacht, die vom Terminal 
gelesenen Cam-Registerwerte passen auch zu meinen Settings.

Ich hör jetzt erstmal auf... ;-)
Richtige Lust, auf jeden Deiner Button zu klicken und im Sniffer zu 
schauen, was Du da jeweils sendest und was zurückkommt, habe ich auch 
nicht so richtig...

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> Ich hör jetzt erstmal auf... ;-)
> Richtige Lust, auf jeden Deiner Button zu klicken und im Sniffer zu
> schauen, was Du da jeweils sendest und was zurückkommt, habe ich auch
> nicht so richtig...

Hmmm - da kann ich Michael sogar ein bisschen verstehen.

@Dirk: ich glaube, Du musst Deine zwei Debugging-Knechte etwas bei Laune 
halten, indem Du den einen oder anderen Button gaaaanz genau 
beschreibst. Ich selber bin insbesondere an folgendem interessiert:

- was Du mit dem jeweiligen Button/Feld genau bezweckst.
- welche Zeichen Du versendest, wenn man den Button drückt.
- welche Antwort Du erwartest.

Natürlich könnten wir das alles auch aus Deinem Terminal-Programmcode 
per reverse-engineering heraustüfteln, aber, wie schon gesagt: auch ein 
Debugging-Knecht will ab und an verwöhnt werden :-)


Nächstes Thema:

Nachdem der Button "Read Device Settings" ja nun zuverlässig 
funktioniert, habe ich mich einmal dem Button "get camera status" 
zugewandt.

Mein LogicAnalyzer liest dabei folgende Bytefolge:
1
Sample  Nano    Nano
2
No  TX  RX
3
---------------------
4
0    
5
5234    01h
6
5320    0Ch
7
5407    0Dh
8
5493    0Ah
9
14492  0Ch  
10
39386  00h  
11
40611    01h
12
40698    12h
13
40784    0Dh
14
40870    0Ah
15
49475  12h  
16
74370  00h  
17
75367    01h
18
75453    1Ch
19
75540    0Dh
20
75626    0Ah
21
84459  1Ch  
22
109355  7Fh  
23
110693    01h
24
110779    1Dh
25
110865    0Dh
26
110952    0Ah
27
119444  1Dh  
28
144340  A2h  
29
145526    01h
30
145612    3Ah
31
145698    0Dh
32
145785    0Ah
33
154428  3Ah  
34
179324  0Dh  
35
180713    01h
36
180799    3Dh
37
180886    0Dh
38
180972    0Ah
39
189413  3Dh  
40
214309  88h  
41
215460    01h
42
215546    3Eh
43
215633    0Dh
44
215719    0Ah
45
224398  3Eh  
46
249293  00h  
47
250509    01h
48
250596    40h
49
250682    0Dh
50
250768    0Ah
51
259381  40h  
52
284276  C0h  
53
285334    01h
54
285420    42h
55
285507    0Dh
56
285593    0Ah
57
294365  42h  
58
319260  00h  
59
320262    01h
60
320349    70h
61
320435    0Dh
62
320521    0Ah
63
329349  70h  
64
354245  3Ah  
65
355467    01h
66
355553    71h
67
355639    0Dh
68
355726    0Ah
69
364334  71h  
70
389229  35h  
71
390369    01h
72
390456    0Ah
73
390542    0Dh
74
390628    0Ah
75
399318  0Ah  
76
424214  76h  
77
425358    01h
78
425444    0Bh
79
425531    0Dh
80
425617    0Ah
81
434303  0Bh  
82
459199  73h  
83
505116    04h
84
505203    80h
85
505289    02h
86
505375    0Dh
87
505462    0Ah
88
514918  04h  
89
524123

Das Ergebnis irritiert/überrascht mich in mehrfacher Hinsicht:

Punkt 1:

Die Button-Bezeichnung "get camera status" lässt ja eigentlich vermuten, 
dass hier nur Register ausgelesen werden.

Ab Sample No 505116 wird dann aber plötzlich ein Schreibbefehl 
abgesetzt:
0x04 0x80 0x02 0x0D 0x0A

Mit Blick auf Dein Posting vom 14.02.2019 20:20 
(Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)") ist 0x04 
der Control-Command für "set xResolution".


Punkt 2:

Wenn ich Deine Syntax-Beschreibung und meine 
LogicAnalyzer-Sniffing-Daten untereinander schreibe (Dein CR & LF blende 
ich einfach einmal aus), so sieht das wie folgt aus:
1
Command Auswirkung       Byte1             Byte2             expected Return Value
2
0x04    set xResolution  Resolution x MSB  Resolution x LSB  1 Byte xres. Value
3
0x04                     0x80              0x02              0x04


Punkt 2a:

Deine Doku aus dem Posting und die tatsächlich gesendeten Daten stimmen 
nicht überein, denn Du sendest zunächst das LSB und dann erst dass MSB - 
in dem Posting hast Du es aber genau umgekehrt dokumentiert.
Ist das so gewollt oder ist das ein Bug?

Punkt 2b:

Ich hatte nie so richtig verstanden, wie der "expected Return Value" in 
diesem Falle funktionieren soll:  Mit "1 Byte xresolution Value" 
könntest Du ja eine max. X-resolution von 256 darstellen.
Anyway - statt dessen kommt als Antwort 0x04 - das irritiert mich noch 
mehr.


Punkt 3:

Nachdem Du die X-resolution per Befehl setzt, hätte ich jetzt eigentlich 
erwartet, dass anschließend die Y-resolution gesetzt wird. Aber nach dem 
Empfang von 0x04 vom MC scheint die Kommunikation abzubrechen.

Erwartet das Terminal-Programm an dieser Stelle noch weitere Bytes vom 
MC oder erwartet der MC noch weitere Bytes vom Terminal-Programm?

Ich tippe auf ersteres.

Diese Annahme würde bedeuten: beim Befehl 0x04 geht irgendetwas auf 
MC-Seite schief. Der nächste Job wäre dann also, den MC-Code etwas zu 
durchwühlen ...
Schau'n wir mal ...


Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Die Button-Bezeichnung "get camera status" lässt ja eigentlich vermuten,
> dass hier nur Register ausgelesen werden.
>
> Ab Sample No 505116 wird dann aber plötzlich ein Schreibbefehl
> abgesetzt:
> 0x04 0x80 0x02 0x0D 0x0A

Richtig. Er setzt 640 als width (LSB/MSB). Das macht er im AVR auch 
richtig. Warum auch immer er das dort setzt...

Andreas S. schrieb:
> Nachdem Du die X-resolution per Befehl setzt, hätte ich jetzt eigentlich
> erwartet, dass anschließend die Y-resolution gesetzt wird. Aber nach dem
> Empfang von 0x04 vom MC scheint die Kommunikation abzubrechen.

Auch richtig, Kommando 0x04 wird hartcoded mit 0x04 beendet.

Andreas S. schrieb:
> Diese Annahme würde bedeuten: beim Befehl 0x04 geht irgendetwas auf
> MC-Seite schief. Der nächste Job wäre dann also, den MC-Code etwas zu
> durchwühlen ...

Nein, der AVR Code macht genau daß, was Du auch gesehen hast.

Mein Problem im Moment ist einfach, daß ich seine geplanten Abläufe 
nicht verstehe. Wie soll aus dem Terminal wann und womit in der Kamera 
gesetzt werden um zu einem Bild in gewünschter Auflösung und Format zu 
kommen?

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Hmmm - kaum will ich den MC-Code in Sachen "Command 0x04 - set 
xResolution" durchwühlen, da fällt mir auf, dass das Schreiben von 
Registern aus der Terminal-Oberfläche heraus Fehlermeldungen wirft.

Wenn das der Fall ist, so ist dieser Bug natürlich wichtiger und somit 
als erstes zu behandeln.

Szenario:

- Ich verwende den Code aus meinem letzten Posting mit Code-Anhängen 
(Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)").

- Ich starte den Nano frisch (= Versorgungsspannung wird angelegt).

- Ich startet das Terminalprogramm frisch.

- Ich setze die Baudrate auf 115200 und verbinde mich mit dem MC per
  Button "verbinden"

- Ich lese einmalig alle Register aus per Button "Reade Device Settings"

- Ich lese Register 0x00 (=GAIN) per Button "read for change" aus

- Ich Trage im Fensterbereich "Write Register" für Register 0x00
  als value 0x11 ein.

- Klick auf Button "write register" führt in der Fußleiste des
  Terminal-Fensters zur Fehlermeldung "Register Write Failed! ErrorCode 
105"

- Ein anschließender Klick auf Button "read register" ergibt als
  "Result" den Wert 0x6A, der nun angeblich in Register 0x00 stehen 
soll.

- Nachfolgende Operationen lesen/schreibe/lesen ergeben noch 
unlogischere
  Werte.

Fazit: da muss noch ein dicker Hund begraben sein. Ich fürchte, das 
sollten wir als allererstes fixen.

Viele Grüße

Igel1



PS:  weitere interessante Beobachtung: Habe in Register 0x01 einmal 
testweise den Wert 0x81 geschrieben. Ein Auslesen genau dieses Registers 
hat den Erfolg bestätigt. Ein Auslesen aller Register in einem Schwung 
zeigte dann allerdings den Wert 0x80? Bin mehr als irritiert darüber ...

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> - Ich startet das Terminalprogramm frisch.
>
> - Ich setze die Baudrate auf 115200 und verbinde mich mit dem MC per
>   Button "verbinden"
>
> - Ich lese einmalig alle Register aus per Button "Reade Device Settings"

wenn Du kein "kamera initialisieren" machst, sind weder die Cam-Pins 
noch SCCB initalisiert und Du hast Dir nur eine Würfelbude gebaut.
Siehe mein Post vom 06.03.2019 10:26 Uhr.

Gruß aus Berlin
michael

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> wenn Du kein "kamera initialisieren" machst, sind weder die Cam-Pins
> noch SCCB initalisiert und Du hast Dir nur eine Würfelbude gebaut.
> Siehe mein Post vom 06.03.2019 10:26 Uhr.

Sicher?

Ich dachte, der Aufruf von "OV7670_init();" relativ am Anfang von main() 
erledigt das?

Liege ich da falsch?

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Hallo, Wow ihr habt ein Tempo drauf!
Das freut mich!
Umsomehr freut es mich, dass igel es offensichtlich geschafft hat, durch 
konsequentes umsetzen des Bufferzugriffs alle Register auslesen zu 
können. Ich werde schauen und verstehen, wo die Unterschiede unserer 
Codes liegen und deine Änderungen übernehmen.


Ich hoffe, ich werde keine Fragen offen lassen:

erstmal: Kamera initialisieren muss am Terminal nicht zwangsläufig 
gedrückt werden. Beim start von meinem AVR wird die init routine 
aufgerufen. Mit dem Button wollte ich die Möglichkeit liefern, diese 
Initialisierungsfrequenz per Terminal erneut auszuführen, falls nach dem 
Register schreiben mal garnichts mehr geht. (Das wirft aber glaube ich 
noch Fehler)
Allerdings weiß ich nicht, was Michael alles in meinem Code gekürzt hat:

>>Version: 0x0 0x73
>>Resolution: QVGA
>>Color Format: RGB565
Sollte jedenfalls nicht rauskommen, wenn man frisch startet (und mit 
frisch meine ich auch die Kamera zu initialisieren und einen Register 
Reset auszuführen)
Wichtig: wenn die Kamera am strom hängen bleibt und kein Reset 
durchgeführt wird, behällt sie logischer Weise ihre Registerwerte)

jetzt zu den Punkten:

>@Dirk: ich glaube, Du musst Deine zwei Debugging-Knechte etwas bei Laune
>halten, indem Du den einen oder anderen Button gaaaanz genau
>beschreibst. Ich selber bin insbesondere an folgendem interessiert:
David ;-)

- was Du mit dem jeweiligen Button/Feld genau bezweckst.
- welche Zeichen Du versendest, wenn man den Button drückt.
- welche Antwort Du erwartest.

Das habe ich mit der von der gefundenen Excel Docu eigentlich versucht 
zu Dokumentieren. Nevertheless die Hilfe Datei wird kommen. Das mit dem 
vertauschten LSB und MSB überprüfe ich, sobald ich endlich nochmal an 
meinem Rechner sitze:

>Die Button-Bezeichnung "get camera status" lässt ja eigentlich vermuten,
>dass hier nur Register ausgelesen werden.
>
>Ab Sample No 505116 wird dann aber plötzlich ein Schreibbefehl
>abgesetzt:
>0x04 0x80 0x02 0x0D 0x0A
genau, es sollten xRes, yRes und BytesPerPixel nacheinander geschrieben 
werden
@Michael: Die brauche ich am AVR um die Enden der For-Schleifen beim 
Buffer ReadOut zu steuern, und später evtl. auch einmal für eigene 
Auflösungen flexibel zu sein.
Die expected return value ist, wie von michael schon erkannt hardgecoded 
in der Main vom uC: für xRes 0x04 yres 0x05 und BPP 0x06 (Doku stimmt 
also nicht)... wenn ihr jetzt immer einen Fehlercode 0x04 habt frage ich 
mich natürlich grade ob ich das richtig im Terminal verarbeite. Bei 
einem klick auf read register oder read all register wird allerdings der 
Buffer am PC gelöscht.

Meine Empfehlung wäre es die "write All Register" als erstes zu 
überpüfen, ob ich hier zuverlässig alle Register schreiben kann. (Bei 
dem get Camera status sind evtl. Fehler im Terminal programm momentan 
nicht auszuschließen.)

So, die eh verspätete Pause leider schon wieder vorbei. Ich danke euch 
für den moment und hoffe zumindet ein kleines Bisschen auf eure Fragen 
eingegangen zu sein.

Bis heute Abend

David (nicht Dirk ;-) )

PS: Read for Change hatte mal einer von euch beiden gefragt macht 
einfach nur ein ganz normales Register read out und trägt die Register 
Adresse und die gelesen Value in das Write feld ein um dann ggf. nur ein 
einzelnes Bit ändern zu können.

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Ich dachte, der Aufruf von "OV7670_init();" relativ am Anfang von main()
> erledigt das?
>
> Liege ich da falsch?

nö. Wo Du Recht hast, hast Du defnitiv Recht...
Gerade mal probiert: Reg 0x00 läßt sich nicht beschreiben, ab 0x01 geht 
es...
Keine Zeit jetzt, da nachzugraben. 105 als Errorcode bei Dir ist auch 
seltsam, eigentlich gibt er da nur kleine Codes zurück?

Gruß aus Berlin
Michael

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> genau, es sollten xRes, yRes und BytesPerPixel nacheinander geschrieben
> werden

das passiert laut Sniffer nicht, xres wird geschickt und mit 0x04 
quittiert, danach sendet das Terminal bei mir nichts mehr.

David D. schrieb:
> Meine Empfehlung wäre es die "write All Register" als erstes zu
> überpüfen, ob ich hier zuverlässig alle Register schreiben kann.

Gerade noch "Schnelltest" gemacht: Reguster 0 wird auch da nicht richtig 
beschrieben, da war anschlißend 0xFF drin. Der Rest schien stimmen, da 
muß ich aber noch in Ruhe anschauen.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Nachtrag zum "Read Device Settings":

Habe gerade festgestellt, dass nach Abfrage des letzten Registers 0xAF 
völlig überraschend vom Terminal-Programm noch ein "0x04 0x80 0x02 0x0D 
0x0A" hinterher geschickt wird.

Ich vermute, das ist nicht beabsichtigt, sondern eher ein Bug?

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

gerade mal schnell geschaut: da hast Du völlig Recht.
Halte ich auch für einen Bug.
Er schickt z.B. auch beim Start des Terminals 0x0D 0x0A raus, das hat so 
zwar keine Bedeutung, aber wenn sich sowas z.B. mit Fehlern in 
UART-Bufferverwaltung oder dem Kommando-Parser trifft, sucht man schnell 
an völlig falschen Stellen.

PS: gerade über Deinen LogicAnalyzer Thread gestolpert: Dein Problem 
dürfte eher sein, eine Software mit Protokolldarstellung für UART dazu 
zu finden.
100kB Sampletiefe bei 10 oder 20MHz Samplerate müßte auch ein ESP32 mit 
I2S-DMA gut machen, mit den STM habe ich ja noch nie was gemacht, keine 
Ahnung, wieviel Ram man da im Stück hat. Zum Rechner schaffen ist ja 
auch nicht unlösbar.
Trotzdem muß man es dann ja noch anzeigen und auswerten können.
Ich weiß im Moment ja auch noch nicht, wie weiter, die Demo des Sniffers 
von Eltima läuft ja auch in 2 Tagen bei mir ab, die Software selbst ist 
einfach genial.
Notalls geht eben die Einrichterei mit COM2COM o.ä. auf dem PC los, da 
reiße ich mich aber auch nicht drum...

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> Hallo,
>
> gerade mal schnell geschaut: da hast Du völlig Recht.
> Halte ich auch für einen Bug.

Okay, dann sind wir uns einig.

> Er schickt z.B. auch beim Start des Terminals 0x0D 0x0A raus,

Richtig, war mir auch schon aufgefallen.

> das hat so
> zwar keine Bedeutung, aber wenn sich sowas z.B. mit Fehlern in
> UART-Bufferverwaltung oder dem Kommando-Parser trifft, sucht man schnell
> an völlig falschen Stellen.

Korrekt. Im Falle von dem 0x0D 0x0A, was nach dem Verbindungsaufbau 
geschickt wird, meine ich sogar, dass dies im Code (Routine 
"UART0_rx_work") gar nicht abgefangen wird und tatsächlich 0x0D als 
Command betrachtet wird.

Und überhaupt - ich verstehe in dieser Routine "UART0_rx_work" so 
einiges nicht. Hier ein Ausschnitt mit meinen Fragen:
1
int UART0_rx_work(int* Programmstatus)
2
{
3
4
//igel1: Warum wird hier UART0_rx_complete() aufgerufen, wo es doch
5
//       schon vor dem Aufruf der Routine "UART0_rx_work" aufgerufen 
6
//       wurde?
7
8
  if(UART0_rx_complete())
9
  {
10
11
  char Befehl[UART0_Befehl_FiFo] = {};      // Hier steht der Befehl
12
  volatile int j = 0;
13
  volatile int i = 0;
14
15
//igel1: Was ist der Sinn und Zweck dieser while-Schleife ??
16
//       Warum so kompliziert?
17
//       Was hat sich David dabei gedacht, was wir möglicherweise
18
//       übersehen?
19
  do
20
  {
21
    char temp = UART0_rx_out();
22
      
23
    Befehl[i] = temp;
24
    i++;
25
26
    //Künstlicher Zähler, um das Abfragen der beiden Bits auch beim ersten zu ermöglichen
27
    if(i<2)
28
    j=1;
29
    else
30
    j=0;
31
//igel1:  Hier passt der Kommentar nicht zum Code: es wird nicht
32
//        auf "CR UND LF" geprüft, sondern auf "CR ODER LF".
33
//        Da ich den Sinn und Zweck des Codes aber nicht verstehe,
34
//        so kann ich nicht beurteilen, ob der Kommentar oder der
35
//        Code falsch sind.
36
  }while(((Befehl[i+j-2] != (char)0x0D) || (Befehl[i-1] != (char)0x0A))&&(i<10));        // solange kein CR+LF erkannt wird

Anderes Thema:

Mal 'ne ganz doofe Frage: könnte ich eigentlich mit dem Dragon das 
Programm von David auch Schritt für Schritt (quasi im Single-Step-Modus) 
debuggen?

Also z.B. im obigen Fall exakt nachprüfen, welche Wirrungen und Irrungen 
das Programm nach einem 0x0D 0x0A so nimmt?
Mein Dragon sagt mir "ISP on AVR Dragon does not support debugging".

Mit den ARM-Prozessoren und meinem J-Link geht so ein Debugging super 
genial.

> PS: gerade über Deinen LogicAnalyzer Thread gestolpert: Dein Problem
> dürfte eher sein, eine Software mit Protokolldarstellung für UART dazu
> zu finden.

Ja, es gibt 1000 Projekte, aber ich habe die richtige Lösung noch nicht 
gefunden. Ich glaube, ich muss mir doch so ein Saleae-Clone bestellen - 
obwohl mir das widerstrebt, weil ich das Gefühl habe, die echten 
Entwickler damit um ihren gerechten Lohn zu bringen.

Gleichzeitig ist mir das Geld für das Original für diesen einen Zweck 
aber auch zu viel ... hmmmm ...

Und bis das Dingen aus China angekommen ist, ist mein Urlaub auch schon 
3x vorbei - Mist.

> 100kB Sampletiefe bei 10 oder 20MHz Samplerate müßte auch ein ESP32 mit
> I2S-DMA gut machen, mit den STM habe ich ja noch nie was gemacht, keine
> Ahnung, wieviel Ram man da im Stück hat. Zum Rechner schaffen ist ja
> auch nicht unlösbar.
> Trotzdem muß man es dann ja noch anzeigen und auswerten können.

Korrekt - und dafür braucht's fertige, freie Software.
Ich fange hier nicht an, einen LA zu programmieren - Du selbst weißt ja, 
welch ein Aufwand das ist.

> Ich weiß im Moment ja auch noch nicht, wie weiter, die Demo des Sniffers
> von Eltima läuft ja auch in 2 Tagen bei mir ab, die Software selbst ist
> einfach genial.

Ja, schade.

> Notalls geht eben die Einrichterei mit COM2COM o.ä. auf dem PC los, da
> reiße ich mich aber auch nicht drum...

Ach ja COM2COM - das hatte ich auch mal probiert.
Habe halt immer in bißchen Respekt vor solchen Dingen, die mir zu tief 
in die Windows-Treiber eingreifen - da weiß man nie, welche 
Seiteneffekte dabei rumkommen.

Anyway - ich denke, früher oder später müssen wir da ran.

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

Habe mich gerade ein bisschen schlauer gemacht in Sachen Debugging.

Vermutlich erzähle ich Euch nichts Neues, aber debugWire scheint hier 
das Zauberwort zu sein.

Und damit debugWire funktioniert, muss man auf dem Nano sowohl den 
1k-Pullup-Widerstand als auch den Kondensator C4 vom Reset-Anschluss 
entfernen.
Korrekt?

Hmmm - und das, wo ich jetzt alles so schön verdrahtet habe - das muss 
ich mir aber 3x überlegen.

Wenn man nach der Nutzung von debugWire wieder nach ISP zurückschaltet, 
geht dann das Programmieren via ISP und AS7 noch problemlos? Ich las 
verschiedentlich, man müsse dann manuell resetten, was ich irgendwie 
nicht verstehe, denn der RESET-Pin vom ATmega328p ist doch nach wie vor 
mit der entsprechenden ISP-RESET-Leitung verbunden?!

Hmmm ...

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Korrekt. Im Falle von dem 0x0D 0x0A, was nach dem Verbindungsaufbau
> geschickt wird, meine ich sogar, dass dies im Code (Routine
> "UART0_rx_work") gar nicht abgefangen wird und tatsächlich 0x0D als
> Command betrachtet wird.

Du willst damit ausdrücken, daß ich mir das doch mal anschauen soll???
Ehrlich gesagt, ich wollte wegen David nur etwas mit OV7670 am AVR 
rumspielen..........

Andreas S. schrieb:
> Vermutlich erzähle ich Euch nichts Neues, aber debugWire scheint hier
> das Zauberwort zu sein.

Ich sage es mal so: man kamm mit dem Dragon am Mega328 debugWire nutzen, 
ja.
Der PullUp an Reset ist mit 1k zumindest grenzwertig, wenn er drin 
bleibt, könnte aber noch gehen. Der 100nF von Reset zum UART-chip muß 
auf jeden Fall raus, das spielt aber nur eine Rolle, wenn man direkt aus 
der ArduinoIDE mit dem Bootloader flasht.
Der AVR kann sich gern mal verheddern, wenn er im debugWire ist und 
irgendwie richtig abstürzt. SPI läßt sich aus debugWier NUR über 
debugWire wieder einschalten znbd man diskutiert dann gern mit dem 
Studio und dem Dragon, weil der meinst, daß der Mega328 nicht im 
debugWire-Mode wäre und ISP auch nicht geht. Läßt sich aber lösen, wenn 
es passiert.
Ich selbst habe es real nie wirklich benutzt.........

Andreas S. schrieb:
> Ach ja COM2COM - das hatte ich auch mal probiert.
Ich sage es mal so: wenn ich mir mit Win7 unsicher bin, wird die 
Free-Version von Macrium Reflect gestartet und nebenbei ein Image der 
Systempartition erstellt. Ganz früher (tm) habe ich da Acronis benutzt, 
das ist mir aber irgendwann zu kolossal und nervig geworden.

So, jetzt diskutiere ich aber erstmal mit meiner 64x64 LED-Matrix noch 
etwas, aber mehr zur Entspannung. ;)
Außerdem habe ich jetzt noch eine niedliche BT-Tastatur und eine Idee, 
aber dazu müßte ich mich mit ESP32 und BT näher auseinandersetzen, damit 
der mit der Tastatur redet.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Mist - David's Mittagspause scheint ihm heute gestrichen worden zu sein.
Dabei könnten wir gut ein bisschen Input gebrauchen ...

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Mist - David's Mittagspause scheint ihm heute gestrichen worden zu sein.
> Dabei könnten wir gut ein bisschen Input gebrauchen ...

Berliner ist er ja auch nicht, also morgen für ihn auch kein Feiertag...
Ich kann ja mal schauen, was da mit dem Rgister schreiben passiert, das 
macht ja mit meinem UART-Kram auch nicht, was es soll.

UART0_rx_work() habe ich bei mir ohnehin auskommetiert und habe das 
direkt in seinen switch in main eingebaut und erledige das gleich aus 
meinem rx_buffer ohne seine Hilfsvariablen.

ok. mein Display sieht immernoch etwas seltsam aus...

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Nabend Männers...
Ja, in der kurzen Mittagspause war heute leider kein Handy drin ;-)

@Igel & DebugWire: Mein lieb gemeinter Rat: Beim Nano finger weg, wenn 
kein Ersatz zu Hand ist. Ich habe hier einen liegen, wo ich dachte: "ich 
aktivier mal kurz die debugWireFuse" und seit dem bin ich ausgesperrt :D 
weil wenn das mit dem Widerstand und dem Kondensator nicht funktioniert 
(hatte ich damals nicht ausprobiert) kannst du, wie Michael schon 
erklärt hat, nicht mehr per ISP flashen/Fuses setzen, solange du das 
nicht vom debugwire aus machst.
oder ebenfalls per dragon aber einiges komplizierter das HV-Programming 
machst.

Ich nutze aber den Uno, hier hat man sogar ein extra lödpad "Reset En", 
dass man einfach mit dem schraubenzieher frei kratzen kann und ab dann 
ist das setzten der debug-wire nur noch formsache um schritt für schritt 
debuggen zu können.

Ihr habt ja schon einiges Entdeckt, was ich alles sooo gerne 
ausprobieren würde und hoffentlich auch bald werde

Meine Kommentare:
>Habe gerade festgestellt, dass nach Abfrage des letzten Registers 0xAF
>völlig überraschend vom Terminal-Programm noch ein "0x04 0x80 0x02 0x0D
>0x0A" hinterher geschickt wird.

Nennen wir es halber Bug :D nachdem alle Register gelesen wurden, habe 
ich es offensichtlich für Sinnvoll erachtet wieder den "Sync" zwischen 
Terminal und uC zu vollziehen und xRes, yRes und BpP zu senden. 
(Übrigens die Doku war falsch, zuerst LSB dann MSB) warum er dann 
abbricht und nicht yRes und Bpp schickt ist mir noch nicht klar, dem 
muss ich noch auf den Grund gehen, aber das Problem haben wir ja schon 
vorher identifiziert.
 Wenn an dieser Stelle keine Antwort vom uC kommt, ist dass übrigens der 
Grund

>Er schickt z.B. auch beim Start des Terminals 0x0D 0x0A raus,...

oh man... das sollte definitiv nicht sein, mal gucken, ob ich das auch 
noch finde xD

>//igel1: Warum wird hier UART0_rx_complete() aufgerufen, wo es doch
>//       schon vor dem Aufruf der Routine "UART0_rx_work" aufgerufen
>//       wurde?
berechtigte Frage, ist überflüssig, bzw. in der main überflüssig. Da 
habe ich offensichtlich meine Genialität beim Funktionen schreiben 
unterschätzt ;-) :D


>//igel1: Was ist der Sinn und Zweck dieser while-Schleife ??
>//       Warum so kompliziert?
>//       Was hat sich David dabei gedacht, was wir möglicherweise
>//       übersehen?
  Diese funktion liest den ersten Befehl aus dem Buffer. Es könnten ja 
auch mehrere im Buffer liegen, die ich dann trennen muss, das mache ich 
mit dieser Funktion... Wenn du da eine wesentlich einfachere Idee hast, 
lasse ich mich sehr gerne Belehren :D

>//igel1:  Hier passt der Kommentar nicht zum Code: es wird nicht
>//        auf "CR UND LF" geprüft, sondern auf "CR ODER LF".
Naja, nach meiner Auslegung ist beides richtig: Ich prüfe auf CR und LF:
CR&CL = !!(CR&&CL) = !(!CR||!CL)  -->Da wir aber solange in der While 
schleife bleiben wollen, wie diese Bedingung nicht erfüllt ist, eine 
weiter Verneinung: !!(!CR||!CL) = (!CR||!CL) --> siehe code
1
  }while(((Befehl[i+j-2] != (char)0x0D) || (Befehl[i-1] != (char)0x0A))&&(i<10));        // solange kein CR+LF erkannt wird

Die (i<10) ist nur eine "Notfallbremse" falls mal aus irgendeinem Grund 
kein CR+LF gefunden wird, was aber eigentlich nicht vorkommen dürfte. 
(Aber hatte offensichtlich mal Probleme damit, sonst hätte ich es nicht 
eingebaut :D )


PS: und nein... morgen ist kein Feiertag und am Wochenende kommen die 
Schwiegereltern --> wieder wenig Zeit... es bleiben eben immernur die 
Abenden -.-

: Bearbeitet durch User
von David D. (saturi)


Lesenswert?

Problem Solved: ab jetzt wird auch nach xRes yRes und BpP gesendet und 
die entsprechende Antwort überprüft.

warum sende ich am Terminal CR+LF auch das weiß ich wieder :D auch wenn 
der Punkt vlt. etwas beschämend ist:

beim Verbindes des Com anschlusses werden zeichen geschickt, die ich 
nicht beeinflussen kann. Scheint irgendein standard zu sein, jedenfalls 
wird das bei der COM-Port library von microsoft so gemacht... um diese 
Zeichen einfach zu verwerfen sende ich einfach ein CR+LF hinterher, 
womit das ganze als "Befehl" interpretiert wird, in der Switch anweisung 
im UART_Work aber nicht aufzufinden ist und somit einfach verworfen 
wird.

Edit: anbei noch der neue Release: incl. kurzfristigem Design umbau zur 
besseren Handhabung für Igel... habe es auf die Schnelle leider nicht 
besser hinbekommen
https://github.com/igittigitt/ov7670/tree/TWI-Interfac/OV7670-Terminal-Releases

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,

zu debugWire: Du nußt mit debugWire den Mode beneden, nur dann wechselt 
der AVR wieder auf ISP. Man bekommt den Chip wirklich nur per debugWire 
wieder in den Normalzustand. Problem ist dann gern, daß z.B. der Dragon 
nicht im debugWire conncted, weil er meint, der Chip wäre nicht im 
debugWire.
Da gibt es aber irgendwo einen Tipp, wie man den überreden kann.

David D. schrieb:
> Diese funktion liest den ersten Befehl aus dem Buffer. Es könnten ja
> auch mehrere im Buffer liegen, die ich dann trennen muss, das mache ich
> mit dieser Funktion... Wenn du da eine wesentlich einfachere Idee hast,
> lasse ich mich sehr gerne Belehren :D

Ich habe damit direkt kein Problem, aber das hängt eben von einer 
konkreten Anwendung ab. Wenn, wie hier ein Quittunhsverhalten zwischen 
Terminal und AVR benutzt wird, kann es keine mehreren Befehle geben, 
weil eben das Terminal nicht schicken darf, bevor es die Quittung des 
vorigen verarbeitet hat.
Es würde ja z.B. auch meist keinen Sinn machen, z.B. 3 Befehle 
hintereinander zu schicken und dann einen Errorcode beim 1. 
zurückzubekommen, der den Ablauf dann völlig aus dem Konzepte bringen 
kann.
Zumindest wäre das meine Vorstellung davon.

David D. schrieb:
> warum sende ich am Terminal CR+LF auch das weiß ich wieder :D auch wenn
> der Punkt vlt. etwas beschämend ist:

ok, ist dann klar, stört ja auch nicht. Ich muß mir das mal mit dem 
Sniffer ansehen, aufgefallen ist mir da eigentlich nichts überzähliges 
beim Start.

David D. schrieb:
> Wenn an dieser Stelle keine Antwort vom uC kommt, ist dass übrigens der
> Grund

Das 0x04 als Quittung von xRes kommt definitiv com AVR, vom Termial 
kommt aber nichts weiter danach.

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Doch jetzt schon

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

Hi Leute,

schön, dass Du, David, eine neue Terminal-Version online gestellt hast!

Und schon gibt's Gemecker, denn: wo ist die Status-Fußleiste hin?
Die war sehr hilfreich beim Debuggen.
Falls möglich, bitte dringend wieder einbauen!

Habe Deine Erläuterungen zu der von mir angefragten Codesektion beim 
ersten Lesen noch nicht ganz verstanden. Ich muss es nachher nochmals 
genauer lesen.

Als David sein Posting mit dem Hinweis a la "lass die Hände weg vom 
DebugWire-Umbau des Nanos" eingestellt hat, war ich gerade mit dem 
Lötkolben zugange und habe daher seine Warnung nicht gesehen.
Aber ich hatte offenbar mehr Glück als er, denn ich habe nun einen 
wunderbar funktionierenden Nano, der DebugWire spricht.

Alles frei nach dem Rheinisches Grundgesetz: Et hätt noch emmer joot 
jejange..

Die Rolle rückwärts von DebugWire zu ISP hat zwar beim ersten Mal nicht 
funktioniert, aber nach etwas wildem Rumprobieren, hat auch das 
geklappt.
... was wiederum die universale Gültigkeit des Rheinische Grundgesetzes 
unterstreicht ...

Jetzt muss ich mich erst einmal mit dem Debugger von Atmel Studio 7 
anfreunden (... noch sind wir keine echten Freunde ...).
Scheint alles Meilen hinter der ARM-Technik hinterher zu hinken.

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Das war keine Absicht... Achtung version 1.7.1 verwenden!
https://github.com/igittigitt/ov7670/tree/TWI-Interfac/OV7670-Terminal-Releases


da hab ich wohl beim scrollen ausversehen ne dropdown gedreht...
 Jetzt hast dus aber aufjedenfall wieder.


zum Debug-Wire mit Nano, dann hätte ich gerne von dir die Anleitung bzw. 
website wo beschrieben ist, was man zu löten hat.


Gib mir einfach Rückmeldung wenn das Verstehen beim zweiten Lesen besser 
funktioniert hat :D ansonsten muss ich wohl nochmal in etwas 
verständlicherem Deutsch schreiben.

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:

> zum Debug-Wire mit Nano, dann hätte ich gerne von dir die Anleitung bzw.
> website wo beschrieben ist, was man zu löten hat.

Danach habe ich zunächst auch 2h gesucht - erfolglos.
Dann bin ich einfach frei nach Schnauze vorgegangen.

Eine 1:1 Anleitung kann ich Dir nicht geben, weil ich festgestellt habe, 
dass es mindestens ein halbes Dutzend unterschiedliche Nano-Clone 
Layouts gibt (meines z.B. ist das hier: 
https://www.aliexpress.com/item/Mini-USB-Nano-V3-0-ATmega328P-CH340G-5V-16M-Micro-controller-board-for-arduino-NANO-328P/32951657212.html).

Wichtig ist nur: Damit DebugWire funktioniert, darf kein Kondensator am 
Reset-Pin des ATmega hängen und der Pullup am Reset-Pin muss mindestens 
10k haben (auch darin unterscheiden sich angeblich die Boards).

Dann schaust Du Dir das Schaltbild Deines Nano-Clones (meist mit CH340) 
genau an (ich habe hier geguckt: 
http://actrl.cz/blog/wp-content/uploads/nano_ch340_schematics-rev1.pdf).

Und dann versuchst Du die Leitungen zu verfolgen und misst zusätzlich 
mit dem Multimeter so lange herum, bis Du Dir absolut sicher bist, 
welcher Kondensator der Reset-Kondensator ist und welcher Widerstand der 
Reset-Widerstand ist. Das ging bei mir wesentlich schneller als die 2h 
erfolglose Internet-Recherche vorher.

Wenn der Reset-Widerstand 10k ist (wie in meinem Falle), so hast Du 
Glück und kannst ihn drin lassen. Der Kondensator muss in jedem Falle 
ausgelötet werden.

Wie Du von ISP auf DebugWire in AS7 umstellst, solltest Du aus Deinen 
Erfahrungen mit dem Uno-Board ja schon wissen.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Das war keine Absicht... Achtung version 1.7.1 verwenden!

tolle Wurst! ;-))
Jetzt habe ich rechts schönen großen Bereich im Fenster für Notizen und 
kann das Fenster nicht mehr kleiner schieben... :-))

Andreas S. schrieb:
> Danach habe ich zunächst auch 2h gesucht - erfolglos.
> Dann bin ich einfach frei nach Schnauze vorgegangen.

naja, Schaltungen zu den nanos gibt es im Netz, grundsätzlich ist da 
also immer ein PullUp und ein Kondensator für den Reset über DTR dran. 
Wo die auf den Versionen gelandet sind und welchen Wert die haben, ist 
dem Zufall überlassen. Suchen auf den Boards geht da immer schneller, 
als die Hoffnung, einen passenden "Bestückungsplan" zu finden. ;)

OT:
Falls es Dich tröstet: von meinen "Lieblings-"Display gibt es ungefähr 
genauso viele Varianten, die wohl nichtmal die Chinesen selbst 
auseinanderhalten können. Die von mir probierten Libraries können die 
vielleicht/manchmal/meist aus ansteuern. Irgendwie...

Inzwischen benimmt sich das 64x64 wie gewünscht, mein Bekannter war 
etwas schneller damit, die richtige Einstellung zu finden.
Falls es interessiert mal bei YouTube nach
led matrix 64x64 smartmatrix fastled
suchen und einen Blick auf die Demos dort werfen.
Nun muß mir nur noch eine Anwendung einfallen. :-)

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

@David:

Wunderbar: die Statusleiste im Fußbereich ist in Version 0.7.1 wieder 
drin.

Gleichzeitig stelle ich fest, dass ein "Read Device Settings" nun nicht 
mehr nur die Register 0x00 - 0xAF, sondern 0x00 - 0xC9 abfragt - voll 
korrekt.

Am ATmega-Code hast Du nichts verändert - dann verwende ich dort nach 
wie vor Deinen Originalcode, in dem ich allerdings drei Dateien durch 
diejenigen aus meinem Posting vom 05.03.2019 22:54 
(Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)") 
ersetze.

Weiter geht's ...

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> David D. schrieb:
>> Wenn an dieser Stelle keine Antwort vom uC kommt, ist dass übrigens der
>> Grund
>
> Das 0x04 als Quittung von xRes kommt definitiv com AVR, vom Termial
> kommt aber nichts weiter danach.
>

Daraufhin schrieb David D. im Beitrag #5762742:
> Doch jetzt schon

Wenn Ihr Euch auf das "Read Device Settings" bezieht, so hat Michael 
recht:
Nach dem Auslesen des letzten Registers 0xC9 kommt noch ein 0x04 0x80 
0x02 0x0D 0x0A vom Terminal und ein 0x04 vom ATmega und dann ist 
Funkstille.

Meiner Meinung nach ist das noch ein Bug.

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Andreas S. schrieb:
> @David:
> Weiter geht's ...

für mich leider nicht :/ ich kann euch nicht folgen... Also gedanklich 
schon, aber ich habe alle Änderungen, die du in den Datein vorgenommen 
hast, geprüft und übernommen. Bis auf die delays beim Bildsenden(was ja 
aktuell überhaupt keine Rolle spielt) ist alles gleich. Sowohl in der 
main, in der Uart.c als auch in der OV7670_withFifo.... und trotzdem 
bleibt meiner nachwievor bei read device settings sporadisch hängen...
Habe jetzt nochmal meinen Code gepusht:
https://github.com/igittigitt/ov7670/tree/TWI-Interfac/OV7670-AVR/OV7670-AVR
Ich scheine Blind zu sein?! Es geht einfach nicht und ich weiß nicht 
warum.

was mir auffällt: du sagst du hättest das Format 8N1 (also 1 Stopbit) 
setzt aber Register UCSR0C = 0b00001110; womit mit bit[3] 2 Stopbits 
configurierst. Aber scheint keinen Unterschied zu machen.

PS: ja :D ich versuche kleine Fehler (wie zum Beispiel das Übersehen der 
letzten RegisterSeite im PDF.... mit jedem Update auszumerzen ;-) Freut 
mich, dass es dir auffällt.

von David D. (saturi)


Lesenswert?

Andreas S. schrieb:
>
> Meiner Meinung nach ist das noch ein Bug.

und Michaels Meinung nach auch :D und ihr habt recht, jetzt hab ich ihn 
behoben. Aber bleibe nach wie vor hängen.

von Andreas S. (igel1)


Lesenswert?

Habe Deinen Code aus GitHub gezogen, compiliert, geflashed und dann die 
Register-Komplett-Auslesefunktion mit Terminal 0.7.1 getestet:

- ATmega resettet (im DebugWire-Modus)
- Terminal frisch gestartet
- 115200 8N1 Verbindung aufgenommen
- "Read Device Settings" gedrückt  (... und zu ende laufen lassen)
=> complete
- "Read Device Settings" gedrückt  (... und zu ende laufen lassen)
=> complete
- "Read Device Settings" gedrückt  (... und zu ende laufen lassen)
=> complete
  ... ca. 20x hintereinander erfolgreich laufen lassen ...

Läuft bombenstabil !

Viele Grüße & gute Nacht

Igel1

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

Andreas S. schrieb:
> Habe Deinen Code aus GitHub gezogen, compiliert, geflashed und dann die
> Register-Komplett-Auslesefunktion mit Terminal 0.7.1 getestet:
>
> - ATmega resettet (im DebugWire-Modus)
> - Terminal frisch gestartet
> - 115200 8N1 Verbindung aufgenommen
...
>   ... ca. 20x hintereinander erfolgreich laufen lassen ...
>
> Läuft bombenstabil !

bestätige ich so auch hier.
ich werde mir mal write register nachher anschauen, das ist immernoch 
eine Würfelbude. Die Fewhlernummern muß ich auch mal raussuchen, was da 
im Terminal angezeigt wird, passt irgendwie garnicht zum AVR-Source.
Mich stört auch immernoch etwas, daß die Cam auf VGA gesetzt wird. 
640x480 passt sowieso nicht in den Fifo und sinnlos 480 Zeilen einlesen 
ist mehr als langweilig. Die Statuszeile könnte man auch manchmal 
löschen,
"Empfange Bild  478 von 480Zeilen importiert, 0 RowRepeat requested"
sieht irgendwie irritierend aus.
Wenn nicht das obere Drittel des Fifo schon überschrieben würde, stimmt 
sogar das Bild...

Das läuft hier auch im wahllosen Wechsel mit Read Device Settings/Kamera 
initialisieren/get camera status/take Picture complett absolut stabil. 
Habe ich naber nur so 3-4x getestet, sonst wird mein Morgendkaffe kalt. 
;)

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> Hallo,
>
> Andreas S. schrieb:
>> Habe Deinen Code aus GitHub gezogen, compiliert, geflashed und dann die
>> Register-Komplett-Auslesefunktion mit Terminal 0.7.1 getestet:
>>
>> - ATmega resettet (im DebugWire-Modus)
>> - Terminal frisch gestartet
>> - 115200 8N1 Verbindung aufgenommen
> ...
>>   ... ca. 20x hintereinander erfolgreich laufen lassen ...
>>
>> Läuft bombenstabil !
>
> bestätige ich so auch hier.

Wunderbar!

> ich werde mir mal write register nachher anschauen, das ist immernoch
> eine Würfelbude.

Sehe ich auch so.

> Die Fewhlernummern muß ich auch mal raussuchen, was da
> im Terminal angezeigt wird, passt irgendwie garnicht zum AVR-Source.

Weil Du das Szenario nicht beschreibst, verstehe ich nicht, was Du genau 
meinst.

> Mich stört auch immernoch etwas, daß die Cam auf VGA gesetzt wird.
> 640x480 passt sowieso nicht in den Fifo und sinnlos 480 Zeilen einlesen
> ist mehr als langweilig.

3 x 100%ige Zustimmung.

> Die Statuszeile könnte man auch manchmal löschen,
> "Empfange Bild  478 von 480Zeilen importiert, 0 RowRepeat requested"
> sieht irgendwie irritierend aus.

100%ige Zustimmung.

> Wenn nicht das obere Drittel des Fifo schon überschrieben würde, stimmt
> sogar das Bild...

Hmmm - jetzt, wo Du's sagst: stimmt, sieht tatsächlich so aus.

> Das läuft hier auch im wahllosen Wechsel mit Read Device Settings/Kamera
> initialisieren/get camera status/take Picture complett absolut stabil.

Habe bislang nur "Read Device Settings" und "read register" genauer 
getestet und kann für diese beiden Buttons bestätigen: läuft absolut 
stabil.

> Habe ich naber nur so 3-4x getestet, sonst wird mein Morgendkaffe kalt.
> ;)

:-)

> Gruß aus Berlin
> Michael

Schön, wir kommen langsam weiter ...

Grüße aus Aachen

Igel1

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

So, das Debugging mit DebugWire macht folgende interessante Beobachtung 
möglich:

Szenario:

- ATmega resettet (im DebugWire-Modus)
- Terminal frisch gestartet
- 115200 8N1 Verbindung aufgenommen
- "Read Device Settings" gedrückt  (... und zu ende laufen lassen)
=> complete
- "read register" für Register 0x00 ausgeführt
=> successfull
- "read for change" für Register 0x00 ausgeführt
=> successfull
- "write register" für Register 0x00 mit value 0x10 ausgeführt
=> Statuszeile sagt: Register write complete
- "read register" für Register 0x00 ausgeführt
=> successfull, aber der Wert 0x10 ist nicht im Register 0x00 gelandet
===> das ist natürlich ein Fehler - der write-Befehl muss schiefgegangen 
sein.

Dabei habe ich die im Bild dargestellten Breakpoints gesetzt.

Ergebnis:  Die Routine wird korrekt angesprungen und hat nur beim ersten 
und beim letzten Breakpoint angehalten. Das ist scheinbar korrekt, aber 
trotzdem wird das Register nicht korrekt beschrieben.

Damit haben wir den Fehler schon einmal ziemlich eingegrenzt - es liegt 
nicht an der Kommunikation zwischen Terminal und ATmega, sondern am 
schnöden Beschreiben der Register (quasi das "Brot und Wasser - 
Geschäft")  über die Routine "OV7670_write  (char regID, char regData)".

Viele Grüße

Igel1

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

Andreas S. schrieb:
>> Die Fewhlernummern muß ich auch mal raussuchen, was da
>> im Terminal angezeigt wird, passt irgendwie garnicht zum AVR-Source.
>
> Weil Du das Szenario nicht beschreibst, verstehe ich nicht, was Du genau
> meinst.

Ich fange mal irgendwo an:
oben bis Zeile 1249 ist das Ende von Read Device Setting.
Er sendet immernoch xres 640, das wird sauber mit 0x04 quittiert und 
dann kommt vom Terminal nichts mehr.
In Zeile 1250 schicke ich write register (0x02) für Register 0x00 mit 
Wert 0x88. Wird in 1253 mit 0x00 quittiert, also als ok.
Terminal zeigt an: write failed ErrorCode: 4
Das ist aber die 4 von 1249...

Läßt sich auch bei anderen Kombinationen erreichen, er zeigt bei write 
register nicht den angekommenen ErrorCode an, Screen2.jpg:
Zeile 4946 read register 0x00 -> 0x00
Zeile 4952 write register 0x00 mit 0x00
Zeile 4955 0x00 kein Fehler
Terminal ErrorCode: 15
Die ist aus Zeile 4951...

Geschrieben wird nach 0x00 nichts, noch ungklärt.
Gerade noch getestet: save to struct, 0x00 im File auf 0x88 gesetzt.
load from struct, compare Lists 0x00 wird markiert, kann man kaum sehen 
weil fast außerhalb der Liste...
save to file ist auch komplett verschwunden, auch wenn ich es nicht 
wirklich vermisse.
0x00 wird definitiv nicht geschrieben.
Andere Abweichungen zwisch geschrieben und gelesen können auf Kosten von 
reservierten Registern/Bits kommen, das wird aja alles rigiros 
reingeschrieben, ob es geht/zulässig ist oder nicht.
Nach welchem System einege Button-Texte auf rot wechseln und warum/woszu 
ist mir auch unklar.

Es geht mir garnicht um Maulen um jeden Preis, aber wenn ich mir solch 
ein Tool zusammenbaue, dann teste ich jedes Detail im Zusammspiel, bis 
ich sicher bin, das es macht, was ich erwarte.
Statusmeldungen, die dann nicht den wirklichen Status anzeigen usw. oder 
Kommandos, die garnicht rausgehen (yres usw.) würden mir real genau 
garnichts nutzen.
Ich werde jetzt erstmal schauen, warum Register 0x00 nicht geschreiben 
wird, das zumindest passiert eindeutig auf dem AVR.

Gruß aus Berlin
Michael




Gruß aus Berlin
Michael

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Noch ein Bug im Terminal, der zunächst gefixed werden sollte:

Die folgende Abfolge gaukelt korrektes Funktionieren vor:

- "read register"  für Register X
=> successfull
- "read for change" für Register X
=> successfull
- "write register" für Register X auf den neuen value Y
=> Statuszeile sagt: Register write complete
- "read register" für Register X
=> successfull (und zeigt schön brav den neuen value Y für Register X an

ABER: ein anschließendes "read device settings" zeigt an, dass Register 
X noch immer den alten Wert enthält.

Wenn man danach nochmals "read register" aufruft, so besinnt sich die 
Routine eines Besseren und zeigt dann ebenfalls den alten value für 
Register X an.

Das beweist klar:
Die "read register" Routine im Terminal baut in diesem Falle Mist.
Und dies, obwohl sie korrekt den ATmega anfragt und auch das korrekte 
Ergebnis von diesem zurückgemeldet bekommt (nämlich, dass sich Register 
X nicht verändert hat und noch den alten Wert enthält).

Fazit: @David: bitte zunächst "read register" im Terminal bugfixen - es 
ist wichtig, dass diese Funktion zuverlässig tickt, bevor wir den 
Write-Bug angehen.

Ich mach' dann mal für eine Weilchen Schluss.

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

Hi,

Ich kann Michaels Kritik durchaus verstehen.

Zum Glück ist David ein netter, höflicher und bescheidener Mensch, dem 
man genau aus diesem Grunde so manchen programmatischen Lapsus gerne 
nachsieht.

Andernfalls wäre ich hier schon längst von der Fahne gegangen...

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Hallo, hatte grade ein halbe Stunde Zeit.
Mein Problem ist, nachwievor, dass es bei mir nicht läuft. Danke, dass 
du meinen Code getestet hast, also scheint es ja wiedermal an der 
Hardware zu liegen, wobei ja Lötfehler eigentlich ausgeschlossen sind, 
weil es ja die Uart Kommunikation ist...
@Michael, warst du auf dem uno board unterwegs? oder auch der Nano?

Seid ihr beiden über das USB Kabel mit dem Comport verbunden oder habt 
ihr an die TxRx Pins ein Com modul gehangen? (Ich weiß, dass es nicht 
der richtige Name ist, aber ich hoffe ihr wisst was ich meine)

Zu der Register write/read geschichte, dass kann ich gerade nicht 
nachstellen, weil ich nicht bis zum Ende durchlaufe... Auf den ersten 
Blick sieht es gut aus, hatte aber eben kurzzeitig die gleiche 
Beobachtung, aber erst als es einmal durchgelaufen war. Komme aber 
gerade nichtmal mehr ein einziges mal durch... Es ist wieder zum Mäuse 
Melken...

@Michael ich werde natürlich all deine Wünsche einarbeiten!. Und damit 
du nicht noch länger über den 0x04 bug meckerst anbei ein update ;-)
https://github.com/igittigitt/ov7670/tree/TWI-Interfac/OV7670-Terminal-Releases

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> @Michael, warst du auf dem uno board unterwegs? oder auch der Nano?
Auf dem UNO.
>
> Seid ihr beiden über das USB Kabel mit dem Comport verbunden oder habt
> ihr an die TxRx Pins ein Com modul gehangen? (Ich weiß, dass es nicht
> der richtige Name ist, aber ich hoffe ihr wisst was ich meine)

Ich weiß jetzt wirklich nicht, wie ich mich ausdrücken soll, damit es 
nicht zu sarkastisch rüberkommt.

Ob ich einen Mega328 auf ein Steckbrett nagle oder auf Lochraster löte 
und da einen TTL-USB-Wandler mit FTDI/CH34x/CP210x an GND, TX und RX 
randrahte, oder ob der Mega328 auf einem Nano oder UNO sitzt und schon 
mit einem USB-Wandler verbunden ist, ist einfach gesagt sch***egal.
Wenn da ein intaktes USB-Kabel zum PC geht (schon erkennbar, weil der 
den USB-Wandler sicher anmeldet, der weiß sowiao nicht vom AVR, der da 
dran hängt, wenn der installierte Treiber bis zum COM läuft, ist alles 
ok.
Natürlich kann jetzt in unserem kompletten Konstrukt z.B. ein 
Kontaktproblem zu SDA/SCL der Cam oder deren Betriebsspannung oder 
Resetanschluß alles blokieren. Das wäre aber nur ein Zeichen dafür, daß 
Deine SCCB-Routinen solche Fehlerzustände nicht sauber abfangen und 
melden.
Da bleibt dann meist nur systematische Fehlereingrenzung übrig.

Ich kann hier, wie auch Andreas, nur sagen: das Lesen der Register  (und 
auch die anderen Geschichten) laufen hier absolut stabil, auch mit dem 
jetzt aktuellen Terminal.

Andreas S. schrieb:
> Zum Glück ist David ein netter, höflicher und bescheidener Mensch, dem
> man genau aus diesem Grunde so manchen programmatischen Lapsus gerne
> nachsieht.
>
> Andernfalls wäre ich hier schon längst von der Fahne gegangen...

Ich sehe das ganz genauso wie Du. Sonst hätte ich das hier nicht in 
Griffnähe und passend vorbereitet, um es jederzeit anwerfen zu können.
Ich habe einfach das Problem, daß ich dem Konzept des Ganzen immer 
weniger folgen kann.

Aus einem älteren Post von Dir:
Andreas S. schrieb:
> Die Button-Bezeichnung "get camera status" lässt ja eigentlich vermuten,
> dass hier nur Register ausgelesen werden.
>
> Ab Sample No 505116 wird dann aber plötzlich ein Schreibbefehl
> abgesetzt:
> 0x04 0x80 0x02 0x0D 0x0A

Da beginnen dann auch meine Probleme. Eine Lesefunktion hat zu lesen und 
nichts zu verändern, zumindest, wenn es Debug-Zwecken dienen soll.
Nun werden zwar alle 3 Parameter richtig geschickt und quittiert, der 
Sinn dahinter hat sich mir aber nicht erschlossen.
Das der Fifo für 640x480 zu klein, ist zieht sich auch durch den halben 
Thread, trotzdem wird weiterhin in VGA initialisiert.

David D. schrieb:
> @Michael ich werde natürlich all deine Wünsche einarbeiten!. Und damit
> du nicht noch länger über den 0x04 bug meckerst anbei ein update ;-)

Meine Wünsche sind größtenteils Anmerkungen zu solchen und ähnlichen 
Sachen.
Für mich persöhnlich hat das Terminal keinerlei praktischen Nutzen.
Maximal könnte ich ein Datenset für einige Register als Struct reinladen 
und zur Kamera schicken und take Picture komplett anklicken.
Würde einige Sekunden flashen sparen und die Nutzung von TeraTerm + 
Irfanview. Das wäre aber nichtmal langsamer als die jetzige zeilenweise 
Übertragung, nur etwas umständlicher.

So, nun hoffe ich mal mit Andreas, daß Du den Fehler bei Dir findet und 
dann sehen wir weiter.

PS: meine Bekannten wissen, daß ich da ziemlich dickköpfig sein kann bei 
meinem Hareangehen. Nicht unbelehrbar, wenn aber viele Wege nach Rom 
führen können, bin ich oft sehr pragmatisch im Herangehen. Mein Projekt 
sieht dann manchmal weniger schön in Hard- und Software aus, würde in 
Serie so auch kaum durchgehen, läuft aber stabil unter meinen 
Bedingungen.
Gut möglich, daß das dann bgei -30 oder +60 Grad Umgebungstemperatur 
spinnt, stört nicht, wenn die in meinem Wohnzimmer sind habe ich ganz 
andere Probleme. Wenn das Handy neben dem UNO die Funktion stört, nehme 
ich das Handy zur Seite und baue nicht eine Abschirmung um den 
Versuchsaufbau.

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Wenn meine Vermutung richtig ist, dann habe ich den Fehler: (muss ich 
aber noch mit einem Sniffer nachweisen:


wenn hier was schief geht, flute ich den Buffer mit Bytes, die er nicht 
erwartet:
[code}void OV_SCCB_RegisterToUart(char RegisterAddress){
  char tempByte = 0x00;
  char ErrorByte;
  if(!(ErrorByte=OV7670_read(RegisterAddress,&tempByte)))
    UART0_senden_Byte(tempByte);
  else
  {
    UART0_senden("Error: ");
    UART0_senden_Byte(ErrorByte);
  }
}[/code]

Da muss ich mir jetzt mal gedanken machen, wie ich denn eine Sinnvolle 
Fehlerüberprüfung einbauen kann.

Edit: Nein... der Sniffer sagt: Befehl kommt vom Terminal, Antwort 
bleibt aus

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Okay, Leute: bitte lasst uns mal die Reihenfolge, in der wir die Dinge 
angehen wollen, festlegen.

Hier mein Vorschlag:


- Auflösung von VGA -> QVGA im Terminal umstellen

Ist vermutlich ein Klacks für David und erleichtert Michael und mir die 
weitere Fehlersuche. Ist natürlich dann in einem Abwasch auch in allen 
Initialisierungsroutinen umzustellen.

- Davids Hardwareproblem(?) fixen.

Davids und unsere Umgebungen sollten unbedingt gleich ticken, sonst 
kommen wir hier nie auf einen grünen Zweig.

- Routinen hinter "read register" im Terminal fixen

Der "read register" - Button sollte unbedingt zuverlässig funktionieren 
(Szenario & Fehlerbeschreibung, siehe hier: 
Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)"). 
Andernfalls können wir die "Write Register"-Bugs nicht sauber bearbeiten 
(oder nur sehr umständlich über den Button "Read Device Settings"

- Statusleiste im Terminal fixen

Bevor ein neuer Status/Error dort ausgegeben wird (ist übrigens sehr 
praktisch), sollte der alte Text unbedingt weggelöscht werden.

- Schreiboperationen aus Lesebefehlen entfernen

Genau wie Michael würde ich wärmstens anraten, sämtliche 
Schreiboperationen aus der Routine, die hinter dem Button "Read Device 
Settings" liegt, auszubauen (notfalls in einen separaten Button 
auslagern).

- Routinen hinter "write register" fixen

Wie in Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)" 
geschrieben, liegt in der Funktion "OV7670_write  (char regID, char 
regData)" bzw. deren Unterfunktionen der Bug. Hier ist ein wenig 
SCCB-Grundlagenforschung/arbeit erforderlich.

- Button "Save to File" wieder einbauen

Der war irgendwo zwischen Version 0.6 und 0.8 verloren gegangen.

- Doku schreiben

Welcher Button macht genau was?
Welche Fehlermeldung bedeutet genau was?



Das wäre meine aktuelle Liste.
Fehlt noch was?

Sollen wir die Liste hier im Forum pflegen oder als Issue-Liste auf 
GitHub?

Oder sollen wir gar nichts in Richtung "Priorisierung der 
Vorgehensweise" pflegen, weil's sonst schon bald in Richtung "Arbeit" 
ausartet und das Ganze ja nach wie vor Spaß machen soll? Oder weil's 
"Überorganisation" wäre?

Viele Grüße

Igel1

: Bearbeitet durch User
von David D. (saturi)


Lesenswert?

Die Github Variante würde ich ganz stark bevorzugen, weil sonst doch 
einiges hinten runter fällt, und man sich früher oder später im Kreis 
dreht. Allerdings fehlte mir da bisher etwas die Zustimmung.
Aber im Grunde ist es nach 5min Eingewöhnungszeit(wenn überhautp) 
wirklich gut strukturiert und gut zu bedienen

von Michael U. (amiga)


Lesenswert?

Hallo,

der Liste von Andreas stimme ich so erstmal völlig zu.

Zu github: mir die aktuellen Versionen von github zu holen ist für mich 
völlig ok, komplett werde ich mich mit github nicht befassen. Da sehe 
ich aber auch kein wirkliches Problem, die real anfallenden kurzen 
Codeausschnitte kann man, denke ich zumindest, gut hier diskutieren.

Ich habe inzwischen nochmal wegen der writeRegister-Geschichte geschaut. 
Habe in meinen modifizierten Code (nur uart.h und main.c verändert) mal 
etwas debug reingemacht. Effekte: Register 0x00 wird offenbar wirklich 
nicht geschrieben, fällt bei meinem init nicht auf, weil 0x00 da sowieso 
auf 0x00 bleibt. Andere Werte werden aber definitiv nicht übernommen. 
Noch ziemlich ungeprüft: schreiben von 0x00 auf Register 0x04 setzt 
0x01, andere Werte ergeben auch falsche Ergebnisse. Die reserved Bits 
liefern mir da keine Erklärung. Ich werde mir das mal so ändern, daß ich 
nur nicht identische Werte gemeldet bekomme, sonst ist das zu langweilig 
zu kontrollieren.
Außerdem werde ich mprgen mal schauen, ob ich OV7670_read() und 
OV7670_write() problemlos durch meine I2C-Routinen ersetzen kann zum 
Vergleich. Wenn die Differenzen bleiben jängt es mit der Kamera direkt 
zusammen, wenn nicht muß ich mir die SCCB-Routinen mal genauer anschauen 
bzw. den LA wieder ranhängen.

Schönen Abend noch.
Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> Hallo,
>
> der Liste von Andreas stimme ich so erstmal völlig zu.
>
> Zu github: mir die aktuellen Versionen von github zu holen ist für mich
> völlig ok, komplett werde ich mich mit github nicht befassen. Da sehe
> ich aber auch kein wirkliches Problem, die real anfallenden kurzen
> Codeausschnitte kann man, denke ich zumindest, gut hier diskutieren.

Ich vermute, Du hast hier etwas falsch verstanden.
Wir sprechen nicht über die Code-Versionierungsmöglichkeiten von GitHub, 
sondern über die Möglichkeiten, dort Bugs und Feature-Requests zu 
hinterlegen, zu dokumentieren, zu priorisieren und deren Fortschritt zu 
tracken. Siehe z.B. dieses Video dazu:
https://www.youtube.com/watch?v=WCH0j1Ywgrw

> Ich habe inzwischen nochmal wegen der writeRegister-Geschichte geschaut.
> Habe in meinen modifizierten Code (nur uart.h und main.c verändert) mal
> etwas debug reingemacht. Effekte: Register 0x00 wird offenbar wirklich
> nicht geschrieben, fällt bei meinem init nicht auf, weil 0x00 da sowieso
> auf 0x00 bleibt. Andere Werte werden aber definitiv nicht übernommen.

Aha - interessante Erkenntnis.

> Noch ziemlich ungeprüft: schreiben von 0x00 auf Register 0x04 setzt
> 0x01, andere Werte ergeben auch falsche Ergebnisse. Die reserved Bits
> liefern mir da keine Erklärung. Ich werde mir das mal so ändern, daß ich
> nur nicht identische Werte gemeldet bekomme, sonst ist das zu langweilig
> zu kontrollieren.

Das heißt, Du willst alle Register beschreiben und dann auslesen und 
vergleichen, um zu dokumentieren, welche Register nicht beschrieben 
werden können?

> Außerdem werde ich mprgen mal schauen, ob ich OV7670_read() und
> OV7670_write() problemlos durch meine I2C-Routinen ersetzen kann zum
> Vergleich. Wenn die Differenzen bleiben jängt es mit der Kamera direkt
> zusammen, wenn nicht muß ich mir die SCCB-Routinen mal genauer anschauen
> bzw. den LA wieder ranhängen.

Schöne Maikäferarbeit, aber so ähnlich würde ich ebenfalls vorgehen.

> Schönen Abend noch.
> Gruß aus Berlin
> Michael

Dito

Igel1

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Wenn meine Vermutung richtig ist, dann habe ich den Fehler: (muss ich
> aber noch mit einem Sniffer nachweisen:
>
>
> wenn hier was schief geht, flute ich den Buffer mit Bytes, die er nicht
> erwartet:
> [code}void OV_SCCB_RegisterToUart(char RegisterAddress){
>   char tempByte = 0x00;
>   char ErrorByte;
>   if(!(ErrorByte=OV7670_read(RegisterAddress,&tempByte)))
>     UART0_senden_Byte(tempByte);
>   else
>   {
>     UART0_senden("Error: ");
>     UART0_senden_Byte(ErrorByte);
>   }
> }[/code]
>
> Da muss ich mir jetzt mal gedanken machen, wie ich denn eine Sinnvolle
> Fehlerüberprüfung einbauen kann.
>
> Edit: Nein... der Sniffer sagt: Befehl kommt vom Terminal, Antwort
> bleibt aus

Verstehe nicht, was Du mit folgendem Satz meinst:

> wenn hier was schief geht, flute ich den Buffer mit Bytes, die er nicht
> erwartet:

Wenn Du bei "UART0_senden("Error: ");" landest, kann doch im AVR nichts 
Schlimmes passieren, oder?  Höchstens das Terminal-Programm kann 
Probleme bekommen, wenn es mit dieser Antwort nicht rechnet (im wahrsten 
Sinn des Wortes :-)  Meintest Du Letzteres?

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
>> Noch ziemlich ungeprüft: schreiben von 0x00 auf Register 0x04 setzt
>> 0x01, andere Werte ergeben auch falsche Ergebnisse. Die reserved Bits
>> liefern mir da keine Erklärung. Ich werde mir das mal so ändern, daß ich
>> nur nicht identische Werte gemeldet bekomme, sonst ist das zu langweilig
>> zu kontrollieren.
>
> Das heißt, Du willst alle Register beschreiben und dann auslesen und
> vergleichen, um zu dokumentieren, welche Register nicht beschrieben
> werden können?

Nicht direkt. Ich habe bei mir ja das Setzen der default Registerwerte 
mit seiner write Routine drin, die vergleiche ich erstmal nur mit read 
ob die übernommen wurden.

Andreas S. schrieb:
> Schöne Maikäferarbeit, aber so ähnlich würde ich ebenfalls vorgehen.

:-) Ich habe mir bei mir mal schnell ein UART_senden_Hex() eingebaut 
damit ich in TeraTerm gut zuschauen kann. Nun ist erstmal die Verwirrung 
komplett...
Es muß ein Timingproblem irgenbdwo bei OV7670_write/read geben. Wenn ich 
meine Ausgabe ausführlich genug mache, also zwischen den einzelnen 
OV7670_write/read Zeit vertrödle, werden alle Register fehlerfrei 
geschrieben, auch 0x00.

Schluß für heute.

Gruß aus Berlin
Michael

von Michael U. (amiga)


Lesenswert?

Hallo,

so, mal schnell meine Hardware-I2C-SCCB-Routinen in seine SCCB_old.c 
geworfen, ging tatsächlich schnell und problemlos.
Test mit meiner modifizierten Version ergab erstmal, daß das 
"Timingproblem" weg zu sein scheint. Das muß ich aber noch in Ruhe 
eingrenzen und mal genauer in Davids SCCB-Routinen schauen.
I2C-Routinen in seinem aktuellen AVR-Paket gingen auch problemlos mit 
dem Terminal, aber dort letztlich so chaotisch wie seine 
SCCB-Funktionen...
Ich mau da aber erstmal schauen, weil ich als Errorcode immer hardcoded 
0x00 zurückgebe, ob das passt.
Wenn die I2C-Routine einen Übertragungsfehler bemerkt, geht die in eine 
Endlosschleife und blnkt mit der onBoard-LED, das habe ich mit 
dringelassen weil es bei mir zuverlässig maulte wenn z.B. I2C keinen 
Kontakt zur OV7670 bekam.

Jetzt ist aber erstmal Einkaufen und einige andere Sachen dran, also mal 
schauen, wann es hier weitergeht.

Gruß aus Berlin
Michael

von Andreas S. (igel1)



Lesenswert?

Bei mir ist auch Einkaufen angesagt.

Damit Ihr währenddessen nicht Däumchen dreht, hier die 
Original-Mitschnitte von Davids SCCB-Busprotokoll (bei 100MHz 
Abtastrate):

- Auslesen von Register  0x00 (mit Wert 0x00)
- Schreiben von Register 0x00 mit Wert 0x88

In meinem LA habe ich dabei den I2C-Interpreter über die beiden Signale 
SIOC und SIOD laufen lassen - daher bitte die interpretierten Werte 
etwas mit Vorsicht genießen, denn SCCB ist ja nicht gleich I2C.

Einen direkten Fehler kann ich aus dem Stegreif nicht erkennen, müsste 
mich zur genauen Analyse aber nochmals wieder tief in das SCCB-Protokoll 
einarbeiten (au Mann, hab' ich vielleicht eine Lust darauf ...)

Viele Grüße

Igel1

von Andreas S. (igel1)



Lesenswert?

... und noch einmal mit Register 0x01 und anderen Werten:

- Auslesen von Register  0x01 (mit Wert 0x80)
- Schreiben von Register 0x01 mit Wert 0x59

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

Zwischen zwei Einkäufen schnell noch ein Test, der seltsames liefert:

Wenn ich vor der while(1){}-Schleife (die mit den vielen case-Abfragen) 
folgenden Code einbaue:
1
OV7670_write (0x00, 0x88);
2
OV_SCCB_RegisterToUart(0x00);
3
while(1){}

... so verschwindet das Programm beim dem 
OV_SCCB_RegisterToUart(0x00)-Aufruf auf nimmerwiedersehen.


Gleiches passiert bei folgendem Konstrukt:
1
char iregData;
2
OV7670_write (0x00, 0x88);
3
OV7670_read (0x00, &iregData);
4
while(1){}

Hier verschwindet das Programm beim dem OV7670_read (0x00, 
&iregData)-Aufruf auf nimmerwiedersehen.


Gleichzeitig funktioniert das - mehr oder minder - gleiche Konstrukt in 
der  Case-Abfrage wunderbar:
1
  case 1: //ReadRegister and sent it to Uart
2
    UART0_senden_Byte(receivedAddress);
3
    //_delay_ms(1);
4
    OV_SCCB_RegisterToUart(receivedAddress);
5
    Programstatus=-1;

Bin dem jetzt noch nicht klitzeklein nachgegangen, aber so richtig 
"normal" scheint mir dieses Verhalten nicht zu sein. (oder mag das ein 
Problem mit dem Debugger sein??)

Viele Grüße

Igel1

: Bearbeitet durch User
von David D. (saturi)


Lesenswert?

Hi Igel,

was genau meinst du mit "verschwinden"? hängen bleiben oder wie?
Ich werde mich heute nacht in eine Woche Urlaub verabschieden, nehme 
aber meinen Rechner mit. (vlt kann ich auch die Kamera mit schmuggeln 
;-))
aber meinen Dragon vermutlich nicht.

wo würdet ihr jetzt an meiner Stelle anfangen zu suchen, wenn die 
Software bei euch beiden Läuft und ich den COM-Port auch vernünftig 
verbinden kann?

Ich weiß einfach nicht, was ich jetzt machen soll? meine "Lötarbeiten" 
können ja nicht das Problem sein?!

Ich habe alle aufgeführten "Fehler" oder Aufgabenpakete in Github 
eingefügt, so wie du gestern schon begonnen hattest (@Igel) So stellen 
wir sicher, dass wir nichts vergessen.

Gruß
David

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Hi Igel,
>
> was genau meinst du mit "verschwinden"? hängen bleiben oder wie?

Das Programm ruft die besagte Funktion auf und taucht danach nicht mehr 
aus der Funktion auf. Aber wie gesagt: bitte diesen "Bug" mit Vorbehalt 
betrachten - es kann auch am Debugger liegen: dort kann ich nach der 
besagten Funktion keinen Breakpoint mehr setzen und ich weiß nicht 
warum. Ich werde das noch genauer untersuchen.

> Ich werde mich heute nacht in eine Woche Urlaub verabschieden,

Ich dachte, die Schwiegereltern kommen am Wochenende?
Oder hat Dich allein die Ankündigung der Schwiegereltern schon 
urlaubsreif gemacht?  ;-)

> nehme aber meinen Rechner mit.

Brav!

> (vlt kann ich auch die Kamera mit schmuggeln
> ;-)) aber meinen Dragon vermutlich nicht.

Na auf den Dragon kommt's dann doch auch nicht mehr an.

> wo würdet ihr jetzt an meiner Stelle anfangen zu suchen, wenn die
> Software bei euch beiden Läuft und ich den COM-Port auch vernünftig
> verbinden kann?

Lade mal ein Bild von Deinem Drahtverhau hier hoch.

Folgende Ideen hätte ich:

- Leitungen zum OV7670 Modul zu lang
- Masseleitungen ungünstig geführt
- Levelshifter falsch herum angeschlossen
- Feng Shui bei der Bestückung nicht beachtet

In der höchsten Not würde ich tatsächlich auf den Nano schwenken (wenn 
Du noch einen rumfliegen hast). Vorher unbedingt die 
DebugWire-Modifikation machen.

Was ich nicht geschrieben hatte: ich habe 2 Nanos. Die 
DebugWire-Modifikation habe ich nur am 2. Nano durchgeführt und dann 
anschließend in der Schaltung den ersten Nano durch den modifizierten 
ersetzt. Beide Nanos funktionieren in Deiner Schaltung - und dies, 
obwohl es ganz unterschiedliche Nanos sind (unterschiedliches Layout).


> Ich weiß einfach nicht, was ich jetzt machen soll?

Urlaub :-)

> meine "Lötarbeiten" können ja nicht das Problem sein?!

Läßt sich niemals ausschließen.
Notfalls mit dem Multimeter alles einmal durchpiepen.

> Ich habe alle aufgeführten "Fehler" oder Aufgabenpakete in Github
> eingefügt, so wie du gestern schon begonnen hattest (@Igel) So stellen
> wir sicher, dass wir nichts vergessen.

Oh, supi - das ist klasse, da kommt etwas Struktur in unsere Zs.arbeit.

Wenn wir das Dingen jemals zum Fliegen bekommen, müssen wir unbedingt 
mal ein Bier zusammen darauf trinken (oder uns wenigstens einmal 
zusammentelefonieren) - ich bin ja so neugierig, mit welchen Freaks ich 
mich hier seit Wochen herumbalge ...

> Gruß
> David

Gruß

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> - Leitungen zum OV7670 Modul zu lang
Bei mir ließ sie sich auch von 20cm Dupontkabeln noch nicht aus der Ruhe 
bringen, obwohl das natürlich nicht zu empfehlen ist.

> - Masseleitungen ungünstig geführt
Schafft man das in unserem Kontext wirklich? Auch Arduino Mini + 
getrenntem USB-Wandler mit besagten Strippen hat da real noch nie 
Probleme gemacht.

Generell liegen natürlich Kontaktunsicherheiten da gern auf der Lauer, 
ich sortiere vei den China-Strippen ziemlich schnell in Richtung 
Rundordner, wenn da was zu lose ist beim Stecken. Kosten ja nichts.....

> - Levelshifter falsch herum angeschlossen
Möglich, ich habe jetzt aber nicht geschaut, ob überhaupt etwas ginge.

> - Feng Shui bei der Bestückung nicht beachtet

Sehr gern auftretendes Problem, oder wie Herr Murphy sagte: Toleranzen 
summieren sich immer nach der ungünstigsten Seite.

Andreas S. schrieb:
>> meine "Lötarbeiten" können ja nicht das Problem sein?!
>
> Läßt sich niemals ausschließen.
> Notfalls mit dem Multimeter alles einmal durchpiepen.

Mache ich bei Fragwürdigkeiten immer und zwar möglichst direkt zwischen 
den Pins, wo es ankommen soll. Also auch z.B. AVR und Fifo-Pins als 
Beispiel.

Andreas S. schrieb:
> Wenn wir das Dingen jemals zum Fliegen bekommen, müssen wir unbedingt
> mal ein Bier zusammen darauf trinken (oder uns wenigstens einmal
> zusammentelefonieren) - ich bin ja so neugierig, mit welchen Freaks ich
> mich hier seit Wochen herumbalge ...

Der Idee schleiße ich mich unbedingt an, wenn statt Bier auch Kaffe 
zulässig ist. ;-).

Andreas S. schrieb:
> ... so verschwindet das Programm beim dem
> OV_SCCB_RegisterToUart(0x00)-Aufruf auf nimmerwiedersehen.
>
> Gleiches passiert bei folgendem Konstrukt:
> char iregData;
> OV7670_write (0x00, 0x88);
> OV7670_read (0x00, &iregData);
> while(1){}

teste ich mal bei mir, sehe ich aber auch eher als Debug-Problem, ich 
habe schon etliche Zusatzausgaben auch da vorn reingeklebt, da ist mir 
nicht Negatives aufgefallen.

Sorry für das chaotische Zitieren, aber ich denke, Ihr kommt damit 
klar...

PS: zur Entspannung versuche ich gerade, auf dem Odroid Go eine 
"Navi-"software in Gang zu bekommen, da hett im Netz jemad Langeweile...
https://forum.odroid.com/viewtopic.php?t=33629

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

ENTWARNUNG !

Kurzes Update zu folgendem Problem:


Andreas S. schrieb:
> David D. schrieb:
>> Hi Igel,
>>
>> was genau meinst du mit "verschwinden"? hängen bleiben oder wie?
>
> Das Programm ruft die besagte Funktion auf und taucht danach nicht mehr
> aus der Funktion auf. Aber wie gesagt: bitte diesen "Bug" mit Vorbehalt
> betrachten - es kann auch am Debugger liegen: dort kann ich nach der
> besagten Funktion keinen Breakpoint mehr setzen und ich weiß nicht
> warum. Ich werde das noch genauer untersuchen.


In der Tat: das Problem war der Debugger - oder genauer: der Typ, der 
vor dem Debugger saß.  Erst wenn man die Compiler-Optimierungen 
ausschaltet, funktioniert das "Durchsteppen" durch den Code so richtig.

Nur leider benötigt dann das Flashen des Programmes via DebugWire ca. 
10x so lang - echt nervig.

Immerhin - ich kann jetzt sauber durch den Code steppen und der 
verschollene Programcounter kehrt mit ausgeschalteter Optimierung auch 
irgendwann wieder aus der aufgerufenen Routine zurück.
Also: Entwarnung.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> In der Tat: das Problem war der Debugger - oder genauer: der Typ, der
> vor dem Debugger saß.  Erst wenn man die Compiler-Optimierungen
> ausschaltet, funktioniert das "Durchsteppen" durch den Code so richtig.

Ja, das ist das Problem: Debug geht nur zuverlässig ohne Optimierung 
weil der GCC sonst zuviel umsortiert.
Einer der Gründe, weshalb ich selten so auf dem AVR debugge, wenn ich 
Pech habe passt das Programm dann nicht in den Flash oder die Laufzeiten 
ändern sich drastisch.
Wenn sich nicht geändert hat, stimmt -delay_ms() ohne optimierung auch 
nicht.

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Lesenswert?

Liebe Mitstreiter,

uns allen ist klar, das "vorgefertigte, wundersame Einstellungen" 
richtig sind. O.K.

Ich habe nur mit "Realtime"-Abfragen gearbeitet und bin daher - 
zumindest in der Auflösung - starkt eingeschränkt.

Ihr arbeitet mit Puffer und habt "alle Zeit der Welt" ein Bild 
abzuholen. Meinetwegen auch mit z. B. 300 Baud.

Wo ist da das Problem? Wenn ein Bild im Puffer ist kann man es in aller 
Ruhe - Takt für Takt - auslesen und z. B. seriell an ein 
Terminal-Programm etc. übergeben.

Habt ihr ein Problem mit der seriellen Schnittstelle? Binärdaten 
übertragen ist immer etwas speziell, da es dann keine Steuerzeichen gibt 
/ geben kann.

VG
Dieter

von Andreas S. (igel1)


Lesenswert?

@Dieter F.:

Du willst helfen? Prima, das ist nett.

Bitte schau Dir einmal die Signalverläufe in diesem Posting an:
Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)"

... und sage uns, warum das Beschreiben des Registers nicht 
funktioniert.
Ich hoffe, Du hast gute SCCB-Protokoll-Erfahrung - mir fehlt hier 
irgendein Puzzlestück in meinem Halbwissen.

Viele Grüße

Igel1

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,

Dieter F. schrieb:
> Wo ist da das Problem? Wenn ein Bild im Puffer ist kann man es in aller
> Ruhe - Takt für Takt - auslesen und z. B. seriell an ein
> Terminal-Programm etc. übergeben.

Es gibt kein wirkliches Problem die Daten zu übertragen.
Mit CH34x oder FTDI kann ich die auch mit 500kBaud oder 1MBaud von einem 
AVR zuverlässig im Stück als RAW-Daten rüberschicken, ohne jeden Fehler, 
reproduzierbar.  Mit dem Mega16U2 als UBS-Wandler gehen nicht mehr als 
230400 und mit kleinen Pausen zwischen den Bytes, das ist aber ein 
problem der Firmware auf dem Mega16U2, seine Bufferverwaltung hat da 
offenbar Grenzen.
Das real die 500kBaud/1MBaud nicht erreicht werden, isz auch klar, weil 
das Abholen des Bytes aus dem Fifo eben auch ein paar Takte kostet und 
16NHz Takt des AVR nicht endlos schnell sind.
Dazu muß aber eben auf dem PC etwas die Daten entgegen nehmen, teraTerm 
macht das z.B. bei mir als Binär-Log auf die HD ohne Probleme.

Davids PC-Programm macht das prinzipiell sicher auch, da haben wir ihm 
aber noch ein paar Denkaufgaben gegeben. ;)

Die Farge von Andreas hat sich dabei auch ergeben, ich habe noch nicht 
genauer geschaut, das Problem besteht aber offenbar mit den 
SCBB-Routinen von David und isr noch sehr rätselhaft. Meit meinen 
Hardware-I2C-Routinen (ok, die sind nicht wirklich von mir...) passiert 
das aber nicht.
Ich hatte aber den LA noch nicht dran, um zu vergleichen.

Das nur als eine Art Zusammenfassung weil der Thread ja recht lang und 
damit teilweise unübersichtlich geworden ist.

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Lesenswert?

Andreas S. schrieb:
> ... und sage uns, warum das Beschreiben des Registers nicht
> funktioniert

Kannst Du bitte SCCB_E zusätzlich aufzeichnen?

von Andreas S. (igel1)


Lesenswert?

Dieter F. schrieb:
> Andreas S. schrieb:
>> ... und sage uns, warum das Beschreiben des Registers nicht
>> funktioniert
>
> Kannst Du bitte SCCB_E zusätzlich aufzeichnen?

Wird bei dem Modul nicht nach außen geführt => kann ich nicht 
aufzeichnen.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,
der OV7670 Chip hat nur SIO_C und SIO_D.
Ist auch in der SCCB-Doku als Anmerkung erwähnt, daß das möglich ist.
Bei mir in der v2.2 vom 25.06.2007 Table 2.2 Seite 6.

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Lesenswert?

Andreas S. schrieb:
> Wird bei dem Modul nicht nach außen geführt => kann ich nicht
> aufzeichnen.

Habe ich jetzt auch gesehen - danke :-)

Die Adresse ist (auf 7-Bit-Basis) grundsätzlich richtig - wird aber nach 
links geschoben damit das read-/write-Bit gesetzt werden kann - damit 
wird die Adresse zu 0x42 (write) oder 0x43 (read).

Mit 0x21 (lt. Deiner Aufzeichnung) "fühlt" sich die Kamera nicht 
angesprochen.

von Andreas S. (igel1)


Lesenswert?

Hi Leute,

in meinem STM32F429-Code bin ich mir relativ sicher, dass die 
Register-Lese- und Register-Schreibfunktionen funktionieren.

Also habe ich dort einmal über aller Register (0x00 - 0xC9) folgende 
Operation durchgeführt:

- Wert aus Register gelesen
- Wert 0x88 in Register geschrieben
- Wert nach der Schreiboperation erneut aus Register gelesen
- Wenn Wert==0x88 => SUCCESS, sonst FAILURE ausgegeben
- Danach nochmals alle Register in einer Schleife ausgelesen

Weiter unten findet Ihr meinen Code und noch weiter unten das Ergebnis.

Ich gebe zu: ich bin etwas ratlos, wie ich mit dem Ergebnis umgehen 
soll:

- zum einen scheinen nicht alle Register sauber mit dem Wert 0x88
  beschrieben werden zu können

- zum anderen scheint sich auch der Wert in den Registern bei einem
  späteren Auslesen nochmals verändert zu haben.

Hmmm .... grübel, grübel und kopfkratz ...

Viele Grüße

Igel1


-------------------------------------------------------------------

1
   I2C_Config(); // Initialize I2C
2
  printf("I2C_Config() done\n");
3
4
  OV7670_Reset();
5
6
 
7
  uint16_t regaddr = 0x00;
8
  uint8_t regdatabefore  = 0x00;
9
  uint8_t regdataafter   = 0x00;
10
  uint8_t regdatanew = 0x88;
11
  uint8_t retval   = 0x00;
12
  uint32_t delval  = 100;
13
14
  Delay(delval);
15
  printf("Writing 0x%x to registers\n\n", regdatanew);
16
  printf("regaddr       value before mod             value after mod\n");
17
  printf("-------------------------------------------------------------------------\n");
18
19
  // for register 0x00 .. 0x9C:  
20
  //   read register, write 0x88 into register, read register again ...
21
  for (regaddr = 0; regaddr <= 0xC9; regaddr++) {
22
    regdatabefore = OV7670_ReadReg(regaddr);
23
    Delay(delval);
24
    printf("regaddr=0x%X   regdata=0x%X  ", regaddr, regdatabefore);
25
    retval = OV7670_WriteReg(regaddr, regdatanew);
26
    Delay(delval);
27
    regdataafter = OV7670_ReadReg(regaddr);
28
    Delay(delval);
29
    printf("regdata=0x%X  ", regdataafter);
30
    if(regdataafter == 0x88){
31
      printf("SUCCESS\n");
32
    } else  {
33
      printf("FAILURE\n");
34
    }
35
  }
36
37
  printf("-------------------------------------------------------------------------\n");
38
   
39
  // ... and read out all registers again ...
40
  for (regaddr = 0; regaddr <= 0xC9; regaddr++) {
41
    regdataafter = OV7670_ReadReg(regaddr);
42
    printf("regaddr=0x%X   regdata=0x%X  \n", regaddr, regdataafter);
43
    Delay(delval);
44
  }


Ergebnis:
1
I2C_Config() done
2
Writing 0x88 to registers
3
4
regaddr       value before mod             value after mod
5
-------------------------------------------------------------------------
6
regaddr=0x0   regdata=0x3  regdata=0x3  FAILURE
7
regaddr=0x1   regdata=0x80  regdata=0x80  FAILURE
8
regaddr=0x2   regdata=0x82  regdata=0x82  FAILURE
9
regaddr=0x3   regdata=0x0  regdata=0x88  SUCCESS
10
regaddr=0x4   regdata=0x1  regdata=0x89  FAILURE
11
regaddr=0x5   regdata=0x7F  regdata=0x7F  FAILURE
12
regaddr=0x6   regdata=0x5F  regdata=0x6B  FAILURE
13
regaddr=0x7   regdata=0x40  regdata=0x40  FAILURE
14
regaddr=0x8   regdata=0x80  regdata=0x80  FAILURE
15
regaddr=0x9   regdata=0x1  regdata=0x88  SUCCESS
16
regaddr=0xA   regdata=0x76  regdata=0x76  FAILURE
17
regaddr=0xB   regdata=0x73  regdata=0x73  FAILURE
18
regaddr=0xC   regdata=0x0  regdata=0x88  SUCCESS
19
regaddr=0xD   regdata=0x0  regdata=0x88  SUCCESS
20
regaddr=0xE   regdata=0x1  regdata=0x88  SUCCESS
21
regaddr=0xF   regdata=0x43  regdata=0x88  SUCCESS
22
regaddr=0x10   regdata=0x7F  regdata=0x7F  FAILURE
23
regaddr=0x11   regdata=0x80  regdata=0x88  SUCCESS
24
regaddr=0x12   regdata=0x0  regdata=0x0  FAILURE
25
regaddr=0x13   regdata=0x8F  regdata=0x88  SUCCESS
26
regaddr=0x14   regdata=0x4A  regdata=0x88  SUCCESS
27
regaddr=0x15   regdata=0x0  regdata=0x88  SUCCESS
28
regaddr=0x16   regdata=0x0  regdata=0x88  SUCCESS
29
regaddr=0x17   regdata=0x11  regdata=0x88  SUCCESS
30
regaddr=0x18   regdata=0x61  regdata=0x88  SUCCESS
31
regaddr=0x19   regdata=0x3  regdata=0x88  SUCCESS
32
regaddr=0x1A   regdata=0x7B  regdata=0x88  SUCCESS
33
regaddr=0x1B   regdata=0x0  regdata=0x88  SUCCESS
34
regaddr=0x1C   regdata=0x7F  regdata=0x7F  FAILURE
35
regaddr=0x1D   regdata=0xA2  regdata=0xA2  FAILURE
36
regaddr=0x1E   regdata=0x1  regdata=0x88  SUCCESS
37
regaddr=0x1F   regdata=0x0  regdata=0x88  SUCCESS
38
regaddr=0x20   regdata=0x4  regdata=0x88  SUCCESS
39
regaddr=0x21   regdata=0x2  regdata=0x88  SUCCESS
40
regaddr=0x22   regdata=0x1  regdata=0x88  SUCCESS
41
regaddr=0x23   regdata=0x0  regdata=0x88  SUCCESS
42
regaddr=0x24   regdata=0x75  regdata=0x88  SUCCESS
43
regaddr=0x25   regdata=0x63  regdata=0x88  SUCCESS
44
regaddr=0x26   regdata=0xD4  regdata=0x88  SUCCESS
45
regaddr=0x27   regdata=0x80  regdata=0x88  SUCCESS
46
regaddr=0x28   regdata=0x80  regdata=0x88  SUCCESS
47
regaddr=0x29   regdata=0x7  regdata=0x88  SUCCESS
48
regaddr=0x2A   regdata=0x0  regdata=0x88  SUCCESS
49
regaddr=0x2B   regdata=0x0  regdata=0x88  SUCCESS
50
regaddr=0x2C   regdata=0x80  regdata=0x88  SUCCESS
51
regaddr=0x2D   regdata=0x0  regdata=0x88  SUCCESS
52
regaddr=0x2E   regdata=0x0  regdata=0x88  SUCCESS
53
regaddr=0x2F   regdata=0xE  regdata=0x88  SUCCESS
54
regaddr=0x30   regdata=0x8  regdata=0x88  SUCCESS
55
regaddr=0x31   regdata=0x30  regdata=0x88  SUCCESS
56
regaddr=0x32   regdata=0x80  regdata=0x88  SUCCESS
57
regaddr=0x33   regdata=0x8  regdata=0x88  SUCCESS
58
regaddr=0x34   regdata=0x11  regdata=0x88  SUCCESS
59
regaddr=0x35   regdata=0x1A  regdata=0x88  SUCCESS
60
regaddr=0x36   regdata=0x0  regdata=0x88  SUCCESS
61
regaddr=0x37   regdata=0x3F  regdata=0x88  SUCCESS
62
regaddr=0x38   regdata=0x1  regdata=0x88  SUCCESS
63
regaddr=0x39   regdata=0x0  regdata=0x88  SUCCESS
64
regaddr=0x3A   regdata=0xD  regdata=0x88  SUCCESS
65
regaddr=0x3B   regdata=0x0  regdata=0x88  SUCCESS
66
regaddr=0x3C   regdata=0x68  regdata=0x88  SUCCESS
67
regaddr=0x3D   regdata=0x88  regdata=0x88  SUCCESS
68
regaddr=0x3E   regdata=0x0  regdata=0x88  SUCCESS
69
regaddr=0x3F   regdata=0x0  regdata=0x88  SUCCESS
70
regaddr=0x40   regdata=0xC0  regdata=0x88  SUCCESS
71
regaddr=0x41   regdata=0x8  regdata=0x88  SUCCESS
72
regaddr=0x42   regdata=0x0  regdata=0x88  SUCCESS
73
regaddr=0x43   regdata=0x14  regdata=0x88  SUCCESS
74
regaddr=0x44   regdata=0xF0  regdata=0x88  SUCCESS
75
regaddr=0x45   regdata=0x45  regdata=0x88  SUCCESS
76
regaddr=0x46   regdata=0x61  regdata=0x88  SUCCESS
77
regaddr=0x47   regdata=0x51  regdata=0x88  SUCCESS
78
regaddr=0x48   regdata=0x79  regdata=0x88  SUCCESS
79
regaddr=0x49   regdata=0x0  regdata=0x88  SUCCESS
80
regaddr=0x4A   regdata=0x0  regdata=0x88  SUCCESS
81
regaddr=0x4B   regdata=0x0  regdata=0x88  SUCCESS
82
regaddr=0x4C   regdata=0x0  regdata=0x88  SUCCESS
83
regaddr=0x4D   regdata=0x4  regdata=0x88  SUCCESS
84
regaddr=0x4E   regdata=0x0  regdata=0x88  SUCCESS
85
regaddr=0x4F   regdata=0x40  regdata=0x88  SUCCESS
86
regaddr=0x50   regdata=0x34  regdata=0x88  SUCCESS
87
regaddr=0x51   regdata=0xC  regdata=0x88  SUCCESS
88
regaddr=0x52   regdata=0x17  regdata=0x88  SUCCESS
89
regaddr=0x53   regdata=0x29  regdata=0x88  SUCCESS
90
regaddr=0x54   regdata=0x40  regdata=0x88  SUCCESS
91
regaddr=0x55   regdata=0x0  regdata=0x88  SUCCESS
92
regaddr=0x56   regdata=0x40  regdata=0x88  SUCCESS
93
regaddr=0x57   regdata=0x80  regdata=0x88  SUCCESS
94
regaddr=0x58   regdata=0x1E  regdata=0x88  SUCCESS
95
regaddr=0x59   regdata=0x91  regdata=0x88  SUCCESS
96
regaddr=0x5A   regdata=0x94  regdata=0x88  SUCCESS
97
regaddr=0x5B   regdata=0xAA  regdata=0x88  SUCCESS
98
regaddr=0x5C   regdata=0x71  regdata=0x88  SUCCESS
99
regaddr=0x5D   regdata=0x8D  regdata=0x88  SUCCESS
100
regaddr=0x5E   regdata=0xF  regdata=0x88  SUCCESS
101
regaddr=0x5F   regdata=0xF0  regdata=0x88  SUCCESS
102
regaddr=0x60   regdata=0xF0  regdata=0x88  SUCCESS
103
regaddr=0x61   regdata=0xF0  regdata=0x88  SUCCESS
104
regaddr=0x62   regdata=0x0  regdata=0x88  SUCCESS
105
regaddr=0x63   regdata=0x0  regdata=0x88  SUCCESS
106
regaddr=0x64   regdata=0x50  regdata=0x88  SUCCESS
107
regaddr=0x65   regdata=0x30  regdata=0x88  SUCCESS
108
regaddr=0x66   regdata=0x0  regdata=0x88  SUCCESS
109
regaddr=0x67   regdata=0x80  regdata=0x88  SUCCESS
110
regaddr=0x68   regdata=0x80  regdata=0x88  SUCCESS
111
regaddr=0x69   regdata=0x0  regdata=0x88  SUCCESS
112
regaddr=0x6A   regdata=0x82  regdata=0x88  SUCCESS
113
regaddr=0x6B   regdata=0xA  regdata=0x88  SUCCESS
114
regaddr=0x6C   regdata=0x2  regdata=0x88  SUCCESS
115
regaddr=0x6D   regdata=0x55  regdata=0x88  SUCCESS
116
regaddr=0x6E   regdata=0xC0  regdata=0x88  SUCCESS
117
regaddr=0x6F   regdata=0x9A  regdata=0x88  SUCCESS
118
regaddr=0x70   regdata=0x3A  regdata=0x88  SUCCESS
119
regaddr=0x71   regdata=0x35  regdata=0x88  SUCCESS
120
regaddr=0x72   regdata=0x11  regdata=0x88  SUCCESS
121
regaddr=0x73   regdata=0x0  regdata=0x88  SUCCESS
122
regaddr=0x74   regdata=0x0  regdata=0x88  SUCCESS
123
regaddr=0x75   regdata=0xF  regdata=0x88  SUCCESS
124
regaddr=0x76   regdata=0x1  regdata=0x88  SUCCESS
125
regaddr=0x77   regdata=0x10  regdata=0x88  SUCCESS
126
regaddr=0x78   regdata=0x0  regdata=0x88  SUCCESS
127
regaddr=0x79   regdata=0x0  regdata=0x88  SUCCESS
128
regaddr=0x7A   regdata=0x24  regdata=0x88  SUCCESS
129
regaddr=0x7B   regdata=0x4  regdata=0x88  SUCCESS
130
regaddr=0x7C   regdata=0x7  regdata=0x88  SUCCESS
131
regaddr=0x7D   regdata=0x10  regdata=0x88  SUCCESS
132
regaddr=0x7E   regdata=0x28  regdata=0x88  SUCCESS
133
regaddr=0x7F   regdata=0x36  regdata=0x88  SUCCESS
134
regaddr=0x80   regdata=0x44  regdata=0x88  SUCCESS
135
regaddr=0x81   regdata=0x52  regdata=0x88  SUCCESS
136
regaddr=0x82   regdata=0x60  regdata=0x88  SUCCESS
137
regaddr=0x83   regdata=0x6C  regdata=0x88  SUCCESS
138
regaddr=0x84   regdata=0x78  regdata=0x88  SUCCESS
139
regaddr=0x85   regdata=0x8C  regdata=0x88  SUCCESS
140
regaddr=0x86   regdata=0x9E  regdata=0x88  SUCCESS
141
regaddr=0x87   regdata=0xBB  regdata=0x88  SUCCESS
142
regaddr=0x88   regdata=0xD2  regdata=0x88  SUCCESS
143
regaddr=0x89   regdata=0xE5  regdata=0x88  SUCCESS
144
regaddr=0x8A   regdata=0x0  regdata=0x88  SUCCESS
145
regaddr=0x8B   regdata=0x0  regdata=0x88  SUCCESS
146
regaddr=0x8C   regdata=0x0  regdata=0x88  SUCCESS
147
regaddr=0x8D   regdata=0xF  regdata=0x88  SUCCESS
148
regaddr=0x8E   regdata=0x0  regdata=0x88  SUCCESS
149
regaddr=0x8F   regdata=0x0  regdata=0x88  SUCCESS
150
regaddr=0x90   regdata=0x0  regdata=0x88  SUCCESS
151
regaddr=0x91   regdata=0x0  regdata=0x88  SUCCESS
152
regaddr=0x92   regdata=0x0  regdata=0x88  SUCCESS
153
regaddr=0x93   regdata=0x0  regdata=0x88  SUCCESS
154
regaddr=0x94   regdata=0x50  regdata=0x88  SUCCESS
155
regaddr=0x95   regdata=0x50  regdata=0x88  SUCCESS
156
regaddr=0x96   regdata=0x1  regdata=0x88  SUCCESS
157
regaddr=0x97   regdata=0x1  regdata=0x88  SUCCESS
158
regaddr=0x98   regdata=0x10  regdata=0x88  SUCCESS
159
regaddr=0x99   regdata=0x40  regdata=0x88  SUCCESS
160
regaddr=0x9A   regdata=0x40  regdata=0x88  SUCCESS
161
regaddr=0x9B   regdata=0x20  regdata=0x88  SUCCESS
162
regaddr=0x9C   regdata=0x0  regdata=0x88  SUCCESS
163
regaddr=0x9D   regdata=0x99  regdata=0x88  SUCCESS
164
regaddr=0x9E   regdata=0x7F  regdata=0x88  SUCCESS
165
regaddr=0x9F   regdata=0xC0  regdata=0x88  SUCCESS
166
regaddr=0xA0   regdata=0x90  regdata=0x88  SUCCESS
167
regaddr=0xA1   regdata=0x3  regdata=0x88  SUCCESS
168
regaddr=0xA2   regdata=0x2  regdata=0x88  SUCCESS
169
regaddr=0xA3   regdata=0x1E  regdata=0x88  SUCCESS
170
regaddr=0xA4   regdata=0x0  regdata=0x88  SUCCESS
171
regaddr=0xA5   regdata=0xF  regdata=0x88  SUCCESS
172
regaddr=0xA6   regdata=0xF0  regdata=0x88  SUCCESS
173
regaddr=0xA7   regdata=0xC1  regdata=0x88  SUCCESS
174
regaddr=0xA8   regdata=0xF0  regdata=0x88  SUCCESS
175
regaddr=0xA9   regdata=0xC1  regdata=0x88  SUCCESS
176
regaddr=0xAA   regdata=0x14  regdata=0x88  SUCCESS
177
regaddr=0xAB   regdata=0xF  regdata=0x88  SUCCESS
178
regaddr=0xAC   regdata=0x0  regdata=0x88  SUCCESS
179
regaddr=0xAD   regdata=0x80  regdata=0x88  SUCCESS
180
regaddr=0xAE   regdata=0x80  regdata=0x88  SUCCESS
181
regaddr=0xAF   regdata=0x80  regdata=0x88  SUCCESS
182
regaddr=0xB0   regdata=0x0  regdata=0x88  SUCCESS
183
regaddr=0xB1   regdata=0x0  regdata=0x88  SUCCESS
184
regaddr=0xB2   regdata=0x0  regdata=0x88  SUCCESS
185
regaddr=0xB3   regdata=0x80  regdata=0x88  SUCCESS
186
regaddr=0xB4   regdata=0x0  regdata=0x88  SUCCESS
187
regaddr=0xB5   regdata=0x4  regdata=0x88  SUCCESS
188
regaddr=0xB6   regdata=0x0  regdata=0x88  SUCCESS
189
regaddr=0xB7   regdata=0x66  regdata=0x88  SUCCESS
190
regaddr=0xB8   regdata=0x0  regdata=0x88  SUCCESS
191
regaddr=0xB9   regdata=0x6  regdata=0x88  SUCCESS
192
regaddr=0xBA   regdata=0x0  regdata=0x88  SUCCESS
193
regaddr=0xBB   regdata=0x0  regdata=0x88  SUCCESS
194
regaddr=0xBC   regdata=0x0  regdata=0x88  SUCCESS
195
regaddr=0xBD   regdata=0x0  regdata=0x88  SUCCESS
196
regaddr=0xBE   regdata=0x0  regdata=0x88  SUCCESS
197
regaddr=0xBF   regdata=0x0  regdata=0x88  SUCCESS
198
regaddr=0xC0   regdata=0x0  regdata=0x88  SUCCESS
199
regaddr=0xC1   regdata=0x0  regdata=0x88  SUCCESS
200
regaddr=0xC2   regdata=0x0  regdata=0x88  SUCCESS
201
regaddr=0xC3   regdata=0x0  regdata=0x88  SUCCESS
202
regaddr=0xC4   regdata=0x0  regdata=0x88  SUCCESS
203
regaddr=0xC5   regdata=0x0  regdata=0x88  SUCCESS
204
regaddr=0xC6   regdata=0x88  regdata=0x88  SUCCESS
205
regaddr=0xC7   regdata=0x88  regdata=0x88  SUCCESS
206
regaddr=0xC8   regdata=0x88  regdata=0x88  SUCCESS
207
regaddr=0xC9   regdata=0xC0  regdata=0x82  FAILURE
208
-------------------------------------------------------------------------
209
regaddr=0x0   regdata=0x0  
210
regaddr=0x1   regdata=0x80  
211
regaddr=0x2   regdata=0x82  
212
regaddr=0x3   regdata=0x0  
213
regaddr=0x4   regdata=0x1  
214
regaddr=0x5   regdata=0x24  
215
regaddr=0x6   regdata=0x24  
216
regaddr=0x7   regdata=0x40  
217
regaddr=0x8   regdata=0x24  
218
regaddr=0x9   regdata=0x1  
219
regaddr=0xA   regdata=0x76  
220
regaddr=0xB   regdata=0x73  
221
regaddr=0xC   regdata=0x0  
222
regaddr=0xD   regdata=0x0  
223
regaddr=0xE   regdata=0x1  
224
regaddr=0xF   regdata=0x43  
225
regaddr=0x10   regdata=0x7F  
226
regaddr=0x11   regdata=0x80  
227
regaddr=0x12   regdata=0x0  
228
regaddr=0x13   regdata=0x88  
229
regaddr=0x14   regdata=0x88  
230
regaddr=0x15   regdata=0x88  
231
regaddr=0x16   regdata=0x88  
232
regaddr=0x17   regdata=0x88  
233
regaddr=0x18   regdata=0x88  
234
regaddr=0x19   regdata=0x88  
235
regaddr=0x1A   regdata=0x88  
236
regaddr=0x1B   regdata=0x88  
237
regaddr=0x1C   regdata=0x7F  
238
regaddr=0x1D   regdata=0xA2  
239
regaddr=0x1E   regdata=0x88  
240
regaddr=0x1F   regdata=0x88  
241
regaddr=0x20   regdata=0x88  
242
regaddr=0x21   regdata=0x88  
243
regaddr=0x22   regdata=0x88  
244
regaddr=0x23   regdata=0x88  
245
regaddr=0x24   regdata=0x88  
246
regaddr=0x25   regdata=0x88  
247
regaddr=0x26   regdata=0x88  
248
regaddr=0x27   regdata=0x88  
249
regaddr=0x28   regdata=0x88  
250
regaddr=0x29   regdata=0x88  
251
regaddr=0x2A   regdata=0x88  
252
regaddr=0x2B   regdata=0x88  
253
regaddr=0x2C   regdata=0x88  
254
regaddr=0x2D   regdata=0x0  
255
regaddr=0x2E   regdata=0x0  
256
regaddr=0x2F   regdata=0x24  
257
regaddr=0x30   regdata=0x88  
258
regaddr=0x31   regdata=0x88  
259
regaddr=0x32   regdata=0x88  
260
regaddr=0x33   regdata=0x88  
261
regaddr=0x34   regdata=0x88  
262
regaddr=0x35   regdata=0x88  
263
regaddr=0x36   regdata=0x88  
264
regaddr=0x37   regdata=0x88  
265
regaddr=0x38   regdata=0x88  
266
regaddr=0x39   regdata=0x88  
267
regaddr=0x3A   regdata=0x88  
268
regaddr=0x3B   regdata=0x88  
269
regaddr=0x3C   regdata=0x88  
270
regaddr=0x3D   regdata=0x88  
271
regaddr=0x3E   regdata=0x88  
272
regaddr=0x3F   regdata=0x88  
273
regaddr=0x40   regdata=0x88  
274
regaddr=0x41   regdata=0x88  
275
regaddr=0x42   regdata=0x88  
276
regaddr=0x43   regdata=0x88  
277
regaddr=0x44   regdata=0x88  
278
regaddr=0x45   regdata=0x88  
279
regaddr=0x46   regdata=0x88  
280
regaddr=0x47   regdata=0x88  
281
regaddr=0x48   regdata=0x88  
282
regaddr=0x49   regdata=0x88  
283
regaddr=0x4A   regdata=0x88  
284
regaddr=0x4B   regdata=0x88  
285
regaddr=0x4C   regdata=0x88  
286
regaddr=0x4D   regdata=0x88  
287
regaddr=0x4E   regdata=0x88  
288
regaddr=0x4F   regdata=0x88  
289
regaddr=0x50   regdata=0x88  
290
regaddr=0x51   regdata=0x88  
291
regaddr=0x52   regdata=0x88  
292
regaddr=0x53   regdata=0x88  
293
regaddr=0x54   regdata=0x88  
294
regaddr=0x55   regdata=0x88  
295
regaddr=0x56   regdata=0x88  
296
regaddr=0x57   regdata=0x88  
297
regaddr=0x58   regdata=0x88  
298
regaddr=0x59   regdata=0x88  
299
regaddr=0x5A   regdata=0x88  
300
regaddr=0x5B   regdata=0x88  
301
regaddr=0x5C   regdata=0x88  
302
regaddr=0x5D   regdata=0x88  
303
regaddr=0x5E   regdata=0x88  
304
regaddr=0x5F   regdata=0x88  
305
regaddr=0x60   regdata=0x88  
306
regaddr=0x61   regdata=0x88  
307
regaddr=0x62   regdata=0x88  
308
regaddr=0x63   regdata=0x88  
309
regaddr=0x64   regdata=0x88  
310
regaddr=0x65   regdata=0x88  
311
regaddr=0x66   regdata=0x88  
312
regaddr=0x67   regdata=0x88  
313
regaddr=0x68   regdata=0x88  
314
regaddr=0x69   regdata=0x88  
315
regaddr=0x6A   regdata=0x88  
316
regaddr=0x6B   regdata=0x88  
317
regaddr=0x6C   regdata=0x88  
318
regaddr=0x6D   regdata=0x88  
319
regaddr=0x6E   regdata=0x88  
320
regaddr=0x6F   regdata=0x88  
321
regaddr=0x70   regdata=0x88  
322
regaddr=0x71   regdata=0x88  
323
regaddr=0x72   regdata=0x88  
324
regaddr=0x73   regdata=0x88  
325
regaddr=0x74   regdata=0x88  
326
regaddr=0x75   regdata=0x88  
327
regaddr=0x76   regdata=0x88  
328
regaddr=0x77   regdata=0x88  
329
regaddr=0x78   regdata=0x88  
330
regaddr=0x79   regdata=0x88  
331
regaddr=0x7A   regdata=0x88  
332
regaddr=0x7B   regdata=0x88  
333
regaddr=0x7C   regdata=0x88  
334
regaddr=0x7D   regdata=0x88  
335
regaddr=0x7E   regdata=0x88  
336
regaddr=0x7F   regdata=0x88  
337
regaddr=0x80   regdata=0x88  
338
regaddr=0x81   regdata=0x88  
339
regaddr=0x82   regdata=0x88  
340
regaddr=0x83   regdata=0x88  
341
regaddr=0x84   regdata=0x88  
342
regaddr=0x85   regdata=0x88  
343
regaddr=0x86   regdata=0x88  
344
regaddr=0x87   regdata=0x88  
345
regaddr=0x88   regdata=0x88  
346
regaddr=0x89   regdata=0x88  
347
regaddr=0x8A   regdata=0x88  
348
regaddr=0x8B   regdata=0x88  
349
regaddr=0x8C   regdata=0x88  
350
regaddr=0x8D   regdata=0x88  
351
regaddr=0x8E   regdata=0x88  
352
regaddr=0x8F   regdata=0x88  
353
regaddr=0x90   regdata=0x88  
354
regaddr=0x91   regdata=0x88  
355
regaddr=0x92   regdata=0x88  
356
regaddr=0x93   regdata=0x88  
357
regaddr=0x94   regdata=0x88  
358
regaddr=0x95   regdata=0x88  
359
regaddr=0x96   regdata=0x88  
360
regaddr=0x97   regdata=0x88  
361
regaddr=0x98   regdata=0x88  
362
regaddr=0x99   regdata=0x88  
363
regaddr=0x9A   regdata=0x88  
364
regaddr=0x9B   regdata=0x88  
365
regaddr=0x9C   regdata=0x88  
366
regaddr=0x9D   regdata=0x88  
367
regaddr=0x9E   regdata=0x88  
368
regaddr=0x9F   regdata=0x88  
369
regaddr=0xA0   regdata=0x88  
370
regaddr=0xA1   regdata=0x88  
371
regaddr=0xA2   regdata=0x88  
372
regaddr=0xA3   regdata=0x1E  
373
regaddr=0xA4   regdata=0x88  
374
regaddr=0xA5   regdata=0x88  
375
regaddr=0xA6   regdata=0x88  
376
regaddr=0xA7   regdata=0x88  
377
regaddr=0xA8   regdata=0x88  
378
regaddr=0xA9   regdata=0x88  
379
regaddr=0xAA   regdata=0x88  
380
regaddr=0xAB   regdata=0x88  
381
regaddr=0xAC   regdata=0x88  
382
regaddr=0xAD   regdata=0x88  
383
regaddr=0xAE   regdata=0x88  
384
regaddr=0xAF   regdata=0x88  
385
regaddr=0xB0   regdata=0x88  
386
regaddr=0xB1   regdata=0x88  
387
regaddr=0xB2   regdata=0x88  
388
regaddr=0xB3   regdata=0x88  
389
regaddr=0xB4   regdata=0x88  
390
regaddr=0xB5   regdata=0x88  
391
regaddr=0xB6   regdata=0x88  
392
regaddr=0xB7   regdata=0x88  
393
regaddr=0xB8   regdata=0x88  
394
regaddr=0xB9   regdata=0x88  
395
regaddr=0xBA   regdata=0x88  
396
regaddr=0xBB   regdata=0x88  
397
regaddr=0xBC   regdata=0x88  
398
regaddr=0xBD   regdata=0x88  
399
regaddr=0xBE   regdata=0x88  
400
regaddr=0xBF   regdata=0x88  
401
regaddr=0xC0   regdata=0x88  
402
regaddr=0xC1   regdata=0x88  
403
regaddr=0xC2   regdata=0x88  
404
regaddr=0xC3   regdata=0x88  
405
regaddr=0xC4   regdata=0x88  
406
regaddr=0xC5   regdata=0x88  
407
regaddr=0xC6   regdata=0x88  
408
regaddr=0xC7   regdata=0x88  
409
regaddr=0xC8   regdata=0x88  
410
regaddr=0xC9   regdata=0x82

Viele Grüße

Igel1

von Dieter F. (Gast)


Lesenswert?

Andreas S. schrieb:
> Weiter unten findet Ihr meinen Code

... leider ohne die ausführenden Routinen ....

von Dieter F. (Gast)


Lesenswert?

Dieter F. schrieb:
> Mit 0x21 (lt. Deiner Aufzeichnung) "fühlt" sich die Kamera nicht
> angesprochen.

Ah - ich habe mich auf die 0x21 aus dem Protokoll des Analysers 
verlassen - gesendet wird aber 0x42 zum Schreiben (also korrekt) - 
erkennbar am " W :21h" (und wenn man sich die Bits anschaut ...).
Der Schreib-Befehl bekommt ein ACK und sieht für mich deswegen gut aus.

Der Lese-Befehl bekommt aber ein NACK als Ergebnis - läuft also schief. 
Den muss man sich wohl etwas genauer anschauen.

Nach "I2C-Standard" sollte ein "Repeated-Start"-Kommando vor dem Read 
(nach dem vorangehenden Write-Kommando) kommen. Bei der SCCB-App-Note 
finde ich nichts anderslautendes (aber auch nichts direkt 
bestätigendes). In dem von mir missbrauchten Code wird ein Stopp- mit 
anschließendem neune Start-Kommando versendet - allerdings wird da auch 
nichts gelesen, ist also vermutlich auch nur irgendwo abgekupfert.

Ich würde also mal ein "Repeated-Start" oder auch nur ein Start-Kommando 
für das Read-Kommando (nach vorhergehendem Write-Kommando) - ohne 
eingeschobenes STOP - ausprobieren und schauen, ob ein ACK zurück kommt.

von Michael U. (amiga)


Lesenswert?

Hallo,

Dieter F. schrieb:
> Der Lese-Befehl bekommt aber ein NACK als Ergebnis - läuft also schief.
> Den muss man sich wohl etwas genauer anschauen.

SCCB ist kein I2C. Das 9.Bit ist nicht NACK/ACK nsch I2C Konvention.

Zitat aus SCCB-Doc:
The ninth Bit is a Don't-Care or an NA bit, depending on wether the data 
transmission is a write or read.

Ich komme im Moment nicht dazu, den Kram anzuwerfen, vielleicht später 
noch...

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Angehängte Dateien:

Lesenswert?

Michael U. schrieb:
> or an NA bit, depending on wether the data
> transmission is a write or read

Kommt also darauf an :-) und bei READ spielt es wohl auch eine Rolle.

Außerdem frage ich mich, was das (Bild) ist (Steckbrett ?).

So sieht ein erfolgreiches WRITE aus meiner Sicht aus (Bild 2)

von Andreas S. (igel1)


Lesenswert?

@Dieter F.: schön, dass Du hier so mitmischt!

Dieter F. schrieb:
> Michael U. schrieb:
>> or an NA bit, depending on wether the data
>> transmission is a write or read
>
> Kommt also darauf an :-) und bei READ spielt es wohl auch eine Rolle.

Hmmm - hört sich so an, als ob wir da nochmals ein näheres Auge drauf 
werfen sollten.

Ich werde nachher ebenfalls versuchen, eine Signalsequenz von meinem 
funktionierenden STM32F429<->OV7670_mit_FiFo - Aufbau per LA 
mitzuprotokollieren.

> Außerdem frage ich mich, was das (Bild) ist (Steckbrett ?).

Hatte ich auch schon gesehen, hab's aber unter EMV-"Einstreuung" 
verbucht.
Hatte solche Artefakte schön öfter mal bei meinem LA - war bislang noch 
niemals relevant.

> So sieht ein erfolgreiches WRITE aus meiner Sicht aus (Bild 2)

Mich würde nun brennend interessieren:
Wo genau hast Du die Sequenz aufgenommen?
Hast Du bereits einen funktionierenden Aufbau "MC <-> OV7670" am Start?

Wenn ja: könntest Du bitte einmal testen, ob Du ähnliche Probleme beim 
Schreiben der Register 0x00 - 0x10 hast, wie oben in meinem letzten 
Posting geschildert?

Wenn ja, so liegt der Schluss nahe, dass man eben nicht alle Register 
mit beliebigen Werten beschreiben kann - da waren Michael U. und ich uns 
bislang unsicher.

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

Hei Leutis,

manchmal soll ja pures Lesen helfen ...

So z.B. die Lektüre von OV7670-Datasheet (Version 1.4) - dort 
insbesondere  Tabelle 5. Dort werden die Register der Kamera beschrieben 
und dort ist z.B. dem Inhalt nach zu zu lesen:

Register 05:  "Automatically updated based on chip output format"
Register 06:  "Automatically updated based on chip output format"

Kurzum: wir haben wohl in einigen Fällen versucht, Register zu 
beschreiben, die von der Kamera selbst beschrieben werden.

Kein Wunder, dass das nicht funktioniert.

Ähnlich lautet meine Vermutung bei Registern, die zwar scheinbar korrekt 
auf den Wert 0x88 beschrieben wurden, beim zweiten, späteren Auslesen 
aber wieder einen ganz anderen Wert aufweisen (siehe z.B. Register 0x2D 
und 0x2E). Vermutlich ändern bestimmte Register auch Ihren Inhalt, wenn 
man andere Register beschreibt ...

Fazit: zum Austesten der SCCB-Lese- und Schreibroutinen eignen sich die 
untersten Register eher nicht.

Mein Vorschlag daher: bei unseren SCCB-Lese und Schreibversuchen 
beschränken wir uns auf die Register 0x4F - 0x54. Das sind sogenannten 
"Matrix-Koeffizienten", bei denen ich mal ganz stark davon ausgehe, dass 
sie explizit zum Setzen durch den Benutzer vorgesehen sind.

Hier die Register mit Ihren default-Werten (Spalte 2), die netterweise 
sogar mit dem Datasheet übereinstimmen:
1
regaddr=0x4F   regdata=0x40  regdata=0x88  SUCCESS
2
regaddr=0x50   regdata=0x34  regdata=0x88  SUCCESS
3
regaddr=0x51   regdata=0xC  regdata=0x88  SUCCESS
4
regaddr=0x52   regdata=0x17  regdata=0x88  SUCCESS
5
regaddr=0x53   regdata=0x29  regdata=0x88  SUCCESS
6
regaddr=0x54   regdata=0x40  regdata=0x88  SUCCESS

Viele Grüße

Igel1

von Dieter F. (Gast)


Lesenswert?

Andreas S. schrieb:
> Wo genau hast Du die Sequenz aufgenommen?
> Hast Du bereits einen funktionierenden Aufbau "MC <-> OV7670" am Start?

Ja - hatte ich ja geschrieben und auch verlinkt. Ich habe schlicht 
"abgekupfert" und es hat gut funktioniert.

Andreas S. schrieb:
> Wenn ja: könntest Du bitte einmal testen, ob Du ähnliche Probleme beim
> Schreiben der Register 0x00 - 0x10 hast, wie oben in meinem letzten
> Posting geschildert?

Gerne - aber erst in ca. 3 Wochen. Ab morgen sind wir 3 Wochen in Asien 
und da kümmere ich mich vorwiegend um den Reis-Abbau :-)

VG
Dieter

von Andreas S. (igel1)



Lesenswert?

Na tolles Projekt hier:

Zwei Urlauber und ein Rentner.
Was würde Deutschland nur ohne mich machen?!

Jetzt muss ich also für Euch 3 mitarbeiten ...

Um das Bruttosozialprodukt weiter hochzuhalten, findet Ihr im Anhang die 
Register-Read- bzw. Write-Sequenz von meiner Konstellation 
STM32F429<->OV7670.

Ganz analog zum Posting vom 09.03.2019 12:13 
(Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)") 
wieder:

- Auslesen von Register  0x00 (mit Wert 0x00)
- Schreiben von Register 0x00 mit Wert 0x88

Wobei die hier abgebildete Folge definitiv korrekt ist!
(auch wenn Register 0x00 scheinbar nicht beschreibbar ist - wie wir 
inzwischen mit hoher Wahrscheinlichkeit vermuten - siehe meine 
vorangegangenes Posting)

Viele Grüße

Igel1

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

Und noch ein "Nachthüpferle" (wie meine Oma zu sagen pflegte):

Habe in anliegender PDF-Datei die SCCB-Protokoll-Bilder von David's 
Schaltung mit meinen STM32F429*-SCCB-Protokollbildern zusammengeführt.

Read-Sequenz unter Read-Sequenz und Write-Sequenz unter Write-Sequenz.

Damit lassen sich die Protokolle optimal vergleichen und eventuelle 
Abweichungen finden.

Jetzt seid Ihr dran mit der Interpretation ...

Viele Grüße

Igel1


PS:  * was übrigens I2C-StdPeriphLib-Befehle nutzt

PPS:  vielleicht brauchen wir ja auch gar keine Fehler mehr suchen, wenn 
wir David's Schaltung einfach nochmals ausprobieren und diesmal nicht 
versuchen Register 0x00 zu beschreiben, sondern Register 0x50.

Vielleicht gab's ja gar keine Fehler in David's Programm ...

Ich kann den Test nur leider nicht so schnell durchführen, weil ich 
dafür erst einmal wieder die Kamera mit Ihren 22 Kabeln umstöpseln muss 
...

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Und noch ein "Nachthüpferle" (wie meine Oma zu sagen pflegte):

Hier: Betthupfer... :-)

Ich schau mir das morgen mal alles an, ich bin auch nicht sicher, ob es 
überhaupt einen Fehler gibt.
Bei Register 0x00 habe ich nur eine Unsicherheit: es ist AGC Gain, eine 
Abhängigkeit kann also zu 0x03 (VREF) bestehen, das veruche ich mal 
rauszufinden.
Daß man nicht alle Register unabhängig auf beliebige Werte setzen kann, 
ist ja klar, vielleicht habe ich mich da auch bei 0x00 verwirren lassen, 
es schien zumindest unabhängig zu sein.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:

> Hier: Betthupfer... :-)

Au Mist, ja natürlich: meine Oma sagte "Betthüpferle" und nicht 
"Nachthüpferle" - danke für die Korrektur! Ist schon erschreckend, wie 
man Dinge, von denen man gedacht hat, man würde sie niemals im Leben 
vergessen, dann doch vergisst.

> Ich schau mir das morgen mal alles an, ich bin auch nicht sicher, ob es
> überhaupt einen Fehler gibt.

Habe gerade mit den oben erwähnten Registern 0x49 - 0x54 getestet:
Diese Register sollten nun wirklich von außen beschreibbar sein und 
nicht vom System in irgendeiner weise beeinflusst werden.

Ergebnis:

Zunächst die wirklich gute Nachricht:

Schreib- und Leseoperationen haben korrekt die Register gesetzt bzw. 
ausgelesen.

Und nun der kleine Wermutstropfen:

Trotz der korrekten Funktionsweise und obwohl der ATmega jeweils per 
USART Fehlercode "0" (=alles korrekt) zurückmeldete, zeigte das 
OV7670-Terminal in der Statusleiste Fehler an. Will sagen: trotz 
korrekter Funktionsweise wird ein Fehler ausgewiesen => Das 
OV7670-Terminal hat hier ganz klar einen Bug, den ich soeben in unserem 
Issue-Tracker hinterlegt habe:
https://github.com/igittigitt/ov7670/issues

> Bei Register 0x00 habe ich nur eine Unsicherheit: es ist AGC Gain, eine
> Abhängigkeit kann also zu 0x03 (VREF) bestehen, das veruche ich mal
> rauszufinden.

Gerne - tu Du mal ...

> Daß man nicht alle Register unabhängig auf beliebige Werte setzen kann,
> ist ja klar, vielleicht habe ich mich da auch bei 0x00 verwirren lassen,
> es schien zumindest unabhängig zu sein.

Yep - ich bin auf dieselbe Falle reingefallen.

> Gruß aus Berlin
> Michael

Gruß aus Aachen ins ferne Berlin (Michael U.), Asien (Dieter F.) und 
nach ??? (David)

Igel1

von Andreas S. (igel1)


Lesenswert?

Mist, bevor David sich in den Urlaub abgesetzt hat, hätte er uns seinen 
Code für das OV7670-Terminal dalassen sollen ...

Jetzt hängen wir etwas fest ...

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Mist, bevor David sich in den Urlaub abgesetzt hat, hätte er uns seinen
> Code für das OV7670-Terminal dalassen sollen ...
>
> Jetzt hängen wir etwas fest ...

Prinzipiell hast Du ja recht, aber ich zumindest muß ausnahmsweise mal 
was für Geld machen, also ist etwas PHP, mySQL und Amazon-MWS 
Reportdaten angesagt...

Ansonsten habe ich ja noch die Odroid Go Standortanzeige (Navi will ich 
es nicht nennen), da mußte mir Maperitive erstmal gut 50000 nette kleine 
Kartenbildchen vom OpenStreetMap generieren und runterladen...
Außerdem weiß ich jetzt, daß die JDY-40 2.4GHz Modul vom netten Chinesen 
wirklich gut als serielle bridge zu gebrauchen sind.
Neo6M GPS an die Bridge, LiFePO4-Akkuzelle dazu und ich kann den 
GPS-Empfänger schön am Fenster plazieren, wo er genug Satelliten sieht.
2. Modul an den Odroid Go gesteckt, klappte auf Anhieb.

Hat keinen wirklichen Sinn, das Ganze, aber der Weg ist auch hier das 
Ziel. ;-)

OV7670 und Dragon liegen inzwischen auch parat, ich wollte ja eigentlich 
heute mal ein paar Register beschreiben...

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Hatte mir vor 1 Jahr auch mal so einen Neo6M GPS aus China kommen lassen 
- liegt bis heute noch im Dornröschenschlaf.

Aber Danke für den Tip mit den JDY-40 2.4GHz Modulen.

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

@David:

Habe mir inzwischen Visual Studio installiert - ein echtes Monster ...

Könntest Du evtl. die Sourcen Deiner letzten OV7670-Terminalversion in 
GitHub online stellen?

Viele Grüße

Igel1

: Bearbeitet durch User
von David D. (saturi)


Lesenswert?

Hallo!

Trotz, mitgenommenen PC und uC+Camera war Island einfach zu bezaubernd 
und hat mich ganz gefesselt ;-)
Jetzt sitze ich am Flughafen und warte auf den Rückflug. Dann bin ich 
wieder voll dabei! :)
Sourcecode kommt dann auch sobald möglich.
@Igel habe ich dich richtig verstanden? wenn du über den Sniffer 
schaust, stimmt die Kommunikation aber es wird ein Fehler ausgegeben? 
Bei einem einzelnen Register auselsen? Das sollte definitiv nicht so 
sein. Kannst du nochmal wie immer die genauen Schritte zur reproduktion 
mitteilen? Anschalten beschreiben lesen?

Gruß und bis Sonntag!

Andreas S. schrieb:
> @David:
>
> Habe mir inzwischen Visual Studio installiert - ein echtes Monster ...
>
> Könntest Du evtl. die Sourcen Deiner letzten OV7670-Terminalversion in
> GitHub online stellen?
>
> Viele Grüße
>
> Igel1

von Michael U. (amiga)


Lesenswert?

Hallo David,

schön, daß Dein Urlaub Dir so gefallen hat.

Michael U. schrieb:
> Dann get camera status -> ok, auch mehrmals.
> Jetzt wieder Kamara initialisieren -> angeblich Error Code 4.
> Angeblich, weil vom AVR definitv 0 zurückkommt und die 4 wohl von der
> Quittung bei get camera status stammt...

Momentaner Stand ist also:

Kopie von oben, das klappt immernoch so (nicht), allerdings kommt jetzt 
Error Code 6, weil Du ja inzwischen die damals fehlenden Kommandos beim 
Init schickst. Es wird also nicht der aktuelle Rückgabecode (der ist 
hier definitiv 0x00) angezeigt, sindern der von der letzten Operation 
davor.

Kamera Init, Camera get status, read Register 0x01:
es wird aus Reg. 0x01 0x80 gelesen (Sniffer) und damit 0x01 0x80 
zurückgeliefert.
Terminal zeigt als gelesen aber 0x01 an.
Schreiben Register 0x01 mit 0x33 ergibt Error Code 128 -> das ist die 
0x80 vom letzten Lesen des Register 0x01 davor.

Jetzt lesen von 0x01 (da wurde ja eben 0x33 reingeschrieben) ergibt 
jetzt scheinbar richtig 0x33, das stimmt aber nicht, die Camera meldet 
immernoch 0x80 als Registerinhalt.

Read Device Settings liefer jetzt aber richtig 0x80 als Inhalt von 0x01,
Im Registerfeld von 0x01 steht immernoch die 0x33, Lesen setzt da jetzt 
richtig die 0x80.

Die Frage, ob die Register in der Camera richtig beschreiben werden bzw. 
ob die sich jeweils mit dem gewünschten Wert überhaupt beschreiben 
lassen, habe ich jetzt mal völlig igniriert. Da müßte man jeweils im 
Datenblatt schauen, ob es da Abhängigkeiten geben könnte usw.
Macht aber im Moment wenig Sinn, wenn das Terminal nicht das anzeigt, 
was laut Sniffer eindeutig vom AVR kommt.

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Hallo!
>
> Trotz, mitgenommenen PC und uC+Camera war Island einfach zu bezaubernd
> und hat mich ganz gefesselt ;-)

Oh ja - das kann ich mir vorstellen.
Du scheinst ein harter Kerl zu sein, wenn Du um diese Jahrezeit dort 
Urlaub verbringst ...

> Jetzt sitze ich am Flughafen und warte auf den Rückflug. Dann bin ich
> wieder voll dabei! :)

Ha supi - dann kommt wieder Leben in die Bude!

> Sourcecode kommt dann auch sobald möglich.

Wunderbar.

Vielleicht könntest Du mir auch ein paar Tipps dazu geben, wie ich Dein 
Projekt in Visual Studio öffnen sollte - das Teil ist ein Molloch und 
ich möchte nicht unendlich viel Zeit dort reinstecken.

(Ich hab's zwar schon irgendwie geöffnet bekommen, bin mir aber nicht 
wirklich sicher, was ich da tue und wo und wie die Dateien 
sortiert/geordnet sind und welche Datei nun wofür zuständig ist.)

> @Igel habe ich dich richtig verstanden? wenn du über den Sniffer
> schaust, stimmt die Kommunikation aber es wird ein Fehler ausgegeben?

Yep.

> Bei einem einzelnen Register auselsen?

Nein.

Wenn ich ATmega und Terminal neu starte und mich dann ausschließlich auf 
das Einzel-Lesen und Einzel-Schreiben von Registern konzentriere (ich 
teste nur noch mir Register 0x49 - 0x54), so funktioniert das wunderbar.
Keine Fehlermeldung, alles läuft, wie's laufen sollte - supi.

Aber: wenn ich als erste Aktion ein "Read Device Settings" ausführe und 
dann anschließend ein "write register" (Ziel: Register 0x50, Value: 
0x88) ausführe, so erhalte ich die Fehlermeldung:
"Register write failed! ErrorCode: 6"

Und das, obwohl der ATmega per UART mit 0x00 quittiert hatte, dass der 
Schreibbefehl erfolgreich war.

Danach wird's noch wilder:
Wenn ich dann per Einzel-Read-Befehl das Register 0x50 auslese, so wird 
mir im Terminal der Wert 0x34 angezeigt (also der alte Wert, der vor der 
Schreibaktion im Register stand), obwohl der ATmega per UART bereits den 
neuen Wert 0x88 zurückmeldet.

Erst nach einem erneuten "Read Device Settings", besinnt sich der 
Einzel-Lesebefehl, dass doch 0x88 im Register 0x50 zu finden ist.

> Das sollte definitiv nicht so sein.

Nö.

> Kannst du nochmal wie immer die genauen Schritte zur reproduktion
> mitteilen?
> Anschalten beschreiben lesen?

... Wie zuvor beschrieben ...

> Gruß und bis Sonntag!

Gute Reise!

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

Schade - ich hätte ja mal gerne etwas in Davids Terminal-Code 
herumgeschnüffelt, aber ohne Code wird das nix und das Wochenende ist 
auch bald schon wieder vorbei ...

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Andreas S. schrieb:
> Schade - ich hätte ja mal gerne etwas in Davids Terminal-Code
> herumgeschnüffelt, aber ohne Code wird das nix und das Wochenende ist
> auch bald schon wieder vorbei ...
>
> Viele Grüße
>
> Igel1

entschuldige bitte... Mein Fazit vom Wochenende:Samstag spät aus dem 
Urlaub heim gekommen, quasi den ganzen Sonntag geschlafen und heute mit 
zu vielen Eskalationen in den Arbeitsaltag gestartet -.-

nichts desto trotz lade ich jetzt endlich mal das studio projekt hoch.

@Igel: Kurzanleitung: einfach das Projekt öffnen und dann im 
Projektexplorer die einzelnen Klassen öffnen. (Achtung das Programm ist 
sehr unübersichtlich. Das ganze aber in Textform zu erklären ist vlt. 
auch etwas viel :D...

unter bekanntem Link unter Solution zu finden:

https://github.com/igittigitt/ov7670/blob/TWI-Interfac/OV7670-Terminal-Releases/OV7670-Terminal-Solution_V0_9.zip

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Hi David,

Okay, ich will ja keinen Stress machen - soll ja alles noch Spaß machen 
und locker bleiben.

Hätte halt nur am WE so gut Zeit gehabt ... diese Woche muss ich leider 
Keulen bis zum Umfallen, wird also nix mit Weiter-Debuggen. Allerdings 
müsste ich sowieso erst einmal etwas C# und Visual Studio lernen, bevor 
ich den Terminal- Code sichten könnte.

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Whoop Whoop,
ich habe heute doch tatsächlich die nächste halbe Stunde Zeit mich 
endlich nochmal meinem elektro Hobby zu widmen.

In der zwischenzeit habe ich mir gedanken über das 
Kommunikationsprotokoll gemacht.

Was haltet ihr davon, nach JEDEM gesendeten Kommando an den uC einen 
Fehlercode zu erwarten? und dann kann ich abhängig von dem Fehlercode 
entscheiden was zu tun ist.

von Michael U. (amiga)


Lesenswert?

Hallo,

ich habe mich im Moment ja auch etwas rar gemacht hier.
Zumindest, was das Terminal angeht, wird sich das auch kaum ändern, mehr 
als Testen werde ich da nichts.
Mir fehlt da einfach eine reale Anwendung dafür. Vor allem, weil ich für 
die OV7670 keinerlei reale Anwendung für mich finde.

Ganz allgemein von meiner Seite: das Kommandoprotokoll würde ich immer 
so anlegen, wie ich es für die Anwendung brauche, um alles Nötige 
abzufangen.
Als Antwort vielleicht hier generell als Erstes den Fehlercode, 0x00 für 
alles ok usw.
Hat den Vorteil, daß man nichts nutzloses senden muß, wenn ein Fehler 
auftritt. Bei z.B. Register lesen brauche ich ja als Antwort nur den 
Inhalt, wenn es geklappt hat. Die Registeradresse kann man mitschicken 
(dann eben immer bei Erfolg) wenn man sich beim Auswerten nicht merken 
will/kann, was man angefordert hat. Macht z.B. Sinn, wenn ich eine 
Sammlung Register zum Ändern rüberschicke und die Differenzen erkennen 
will.
Andere Sachen, wie Dein zeilenweises Lesen des Bildes, machen für mich 
keinen wirklichen Sinn, normalerweise klappt die Übertragung ohne 
Probleme.
Bild anfordern -> 0x00 und dann die Bilddaten oder eben Errorcode und 
Schluß.
Bei ok würde ich noch die erwartete Byteanzahl am Ende prüfen (Timeout 
einplanen, wenn zuwenig Daten kommen, Fehlerzustand, wenn mehr als 
erwartet. usw. usw.
Aber das sind alles Planungen, nur mit Deinen konkreten Vorstellungen 
von der Anwendung Deines Terminal bestimmt werden.

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Hallo Michael,

deine Vorschläge werde ich auch auf die ToDo-Liste in Github einpflegen. 
Die gefallen mir sehr gut. Gerade bin ich dabei, die default 
Einstellungen nach der Initialisierung anzupassen, sodass wir QVGA und 
RGB565 haben.

Bei weiteren Code Verbesserungen ist mir nocheinmal Register 0x40 
(COM15) aufgefallen:

"[Bit5:4] RGB 555/565 option....
x0: Normal RGB output
01: RGB565
11: RGB555

Was bedeutet an dieser Stelle für uns Normal RGB? RGB888? Hatten wir 
nicht gesagt, dass die Kamera das nicht kann?

Ich weiß, dass du mal was zu gesagt hattest, aber ich kriege es gerade 
leider nicht mehr wirklich zusammen

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Was bedeutet an dieser Stelle für uns Normal RGB? RGB888? Hatten wir
> nicht gesagt, dass die Kamera das nicht kann?

hängt von 0x12 ab und wohl auch von 0x8C, müßte RGB444 sein.
Ich hatte mich da auf RGB565 festgelegt un nicht weiter geschaut.
Hinweise auf mehr als 2 Byte für die Bildinformation habe ich nirgends 
gefunden.

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Guten Abend,

neuer Release:
https://github.com/igittigitt/ov7670/blob/master/OV7670-Terminal-Releases/OV7670-Terminal_V0_10.zip

change log:
- kleiner Bugfix
- default Camera Einstellung bei Kamera initialisieren: QVGA RGB565
- read/write register Fehler sollte behoben sein
- Meldungen in der Statusleiste verbessert
- Write Register jetzt ebenfalls in der History
- ComSniffer (in absoluter Beta Version ;-) ) als Tab hinzugefügt.

Könnt ihr mal schauen, ob das mit den Fehlern bei euch behoben ist? Und 
falls weitere Fehler auftauchen und identifiziert sind wieder Bescheid 
geben :)

Bei mir funktioniert Read Device Settings immernoch sporadisch nicht.... 
:/

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Hi David,

zu dem neuen Terminal gehört aber noch der alte AVR-Code, stimmt's?
Oder wurde der AVR-Code auch angepasst?

Könntest Du netterweise den Code vom Terminal auch noch einstellen - ich 
lerne doch gerade C# dafür ...

Lesen und Schreiben von Registern scheint auf den ersten Blick nun gut 
zu funktionieren. Bild-Einlesen macht Mucken, muss ich morgen testen.

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

ist mir auch schon aufgefallen, liegt an dem "Sniffer"... Das Empfangen 
des Bildes überfordert ihn...

Daher in diesem Release wieder deaktiviert

uC Programm sollte noch das gleiche sein... entweder habe ich eben 
unbeabsichtigt was gelöscht, was beim Mousepad am Laptop leider schonmal 
schnell vorkommen kann, oder ich habe einen Riesen Bock im uC Programm 
gefunden... Das muss ich noch mit einer altern Version vergleichen.

https://github.com/igittigitt/ov7670

sowohl die gesamte Projekt Datei, als auch die .exe als release

von Andreas S. (igel1)



Lesenswert?

Hi David,

also:  Oberfläche sieht jetzt in Deiner Version 0.11 irgendwie schöner 
und aufgeräumter aus.

"Read register", "Write Register" und "Read Device Settings" scheinst Du 
inzwischen voll im Griff zu haben.

"take Picture" ging allerdings noch ziemlich daneben:

Szenario:

- AVR reset  (im DebugWire mode)
- COM-Port im Terminal-Programm verbunden
- Button "Kamera initialisieren"
- Button "get camera"
- Button "take picture"

Resultat siehst Du im 2. Bild im Anhang - da war die Terminal-Version 
0.7.0.1 schon einmal weiter (wenngleich auch nur s/w - vgl. 1. Bild im 
Anhang).

Aber: wenn ich die bekannten Colorbar-Initwerte manuell in die Register 
pumpe, so erhalte ich tatsächlich ein schönes Testbild (siehe Bild 3 im 
Anhang).

Erstaulich dabei: obwohl von Hand in die Register geschrieben, erkennt 
Dein Programm das Pattern und zeigt an: "Testpattern Colorbar".

Das führt mich zu der Vermutung, dass Dein "take Picture" eigentlich 
funktioniert, aber die Kombination der gesendeten "Kamera 
Initialisieren"-Registerwerte zu einem Bild führt, was auflösungs- oder 
formatmäßig nicht zu Deiner im Terminal gewählten X-/Y-Auflösung bzw. 
dem dort gewählten Format des Bildes passt.

Weitere "Bugs" und Verbesserungen hier (bin aktuell zu faul, sie alle 
ins GIT einzutragen):

- Button "read for change" schreibt keine Logmeldung
- Buttonbeschriftung solltest Du vereinheitlichen:
  Heute:  "read register",
          "Read Device Settings",
          "Kamera Initialisieren", ...
  Besser: "Read Register" oder "Init Camera"
          Also einheitliche Schreibweise in Englisch
- Die Idee mit dem "List not up to date" nach Schreiboperationen
  finde ich richtig gut! Du solltest das aber konsequent durchhalten -
  also auch bei "Kamera initialisieren" muss "List not up to date"
  gesetzt werden.
- Richtig wichtig fände ich unter dem Bild die Anzeige, mit welcher
  X- bzw. Y-Auflösung das Bild im Terminal dargestellt wird
- Umschalten zwischen den Tabs scheint nicht mehr zu funktionieren:
  Im Tab "manueller Modus" wird nach Umschalten noch weiterhin
  das rechte Fenster mit dem "take Picture" vom Tab "Settings" 
angezeigt.


Viele Grüße

Igel1

: Bearbeitet durch User
von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

Als Visual Studio - Newbie habe ich folgende Frage:

Welche "Workload" soll ich in Visual Studio installieren, um Dein 
Programm richtig bearbeiten zu können?

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Andreas S. schrieb:
> Hi David,
> "Read register", "Write Register" und "Read Device Settings" scheinst Du
> inzwischen voll im Griff zu haben.
sehr gut
> "take Picture" ging allerdings noch ziemlich daneben:
>
> Szenario:
>
> - AVR reset  (im DebugWire mode)
> - COM-Port im Terminal-Programm verbunden
> - Button "Kamera initialisieren"
> - Button "get camera"
> - Button "take picture"
Das ist korrekt, das liegt daran, dass wir mit der init routine die 
Register der Auflösung ändern. (Die init routine läuft übrigens im 
Terminal) Jetzt erkennt das Terminal anhand der Register Werte, welche 
Auflösung eingestellt ist. (Der uC weiß das aber nicht). Das bedeutet, 
dass ich jetzt noch die passende Auflösung und BytesPerPixel an de uC 
senden muss. Ihr wolltet aber sämtliche Schreibbefehle aus der get 
Status funktion raus haben. Daher sind die jetzt zu dem Butten sync 
Camera gewandert. Sprich:
nachdem ich die auflösung ändere (passiert bei init Kamera) muss danach 
zwingend der sync Camera knopf gedrückt werden.
Das versuche ich noch ersichtlicher zu machen

> Aber: wenn ich die bekannten Colorbar-Initwerte manuell in die Register
> pumpe, so erhalte ich tatsächlich ein schönes Testbild (siehe Bild 3 im
> Anhang).
Das widerrum ist merkwürdig... vlt. sollte ich mir das nochmal anschauen


> Erstaulich dabei: obwohl von Hand in die Register geschrieben, erkennt
> Dein Programm das Pattern und zeigt an: "Testpattern Colorbar".
Jap :)

> Das führt mich zu der Vermutung, dass Dein "take Picture" eigentlich
> funktioniert, aber die Kombination der gesendeten "Kamera
> Initialisieren"-Registerwerte zu einem Bild führt, was auflösungs- oder
> formatmäßig nicht zu Deiner im Terminal gewählten X-/Y-Auflösung bzw.
> dem dort gewählten Format des Bildes passt.
>
s.o.
> Weitere "Bugs" und Verbesserungen hier (bin aktuell zu faul, sie alle
> ins GIT einzutragen):
>
> - Button "read for change" schreibt keine Logmeldung
> - Buttonbeschriftung solltest Du vereinheitlichen:
>   Heute:  "read register",
>           "Read Device Settings",
>           "Kamera Initialisieren", ...
>   Besser: "Read Register" oder "Init Camera"
>           Also einheitliche Schreibweise in Englisch
> - Die Idee mit dem "List not up to date" nach Schreiboperationen
>   finde ich richtig gut! Du solltest das aber konsequent durchhalten -
>   also auch bei "Kamera initialisieren" muss "List not up to date"
>   gesetzt werden.
> - Richtig wichtig fände ich unter dem Bild die Anzeige, mit welcher
>   X- bzw. Y-Auflösung das Bild im Terminal dargestellt wird
> - Umschalten zwischen den Tabs scheint nicht mehr zu funktionieren:
>   Im Tab "manueller Modus" wird nach Umschalten noch weiterhin
>   das rechte Fenster mit dem "take Picture" vom Tab "Settings"
> angezeigt.
sehr gut :)


Zu dem Studio "Workload"... Ich habe da leider nicht den leisesten 
Schimmer was du damit meinst. Also dur brauchst c# windows forms (oder 
so ähnlich) und .net Framework

Edit: sorry Bild nicht gesehen: also im ersten Schritt brauchst du nur 
das oben rechts .net desktop development
Öffnen kannst du das Projekt einfach über die .sln datei.

viele Grüße
David

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Andreas S. schrieb:
>> [...]
>> "take Picture" ging allerdings noch ziemlich daneben:
>> [...]
> Das ist korrekt, das liegt daran, dass wir mit der init routine die
> Register der Auflösung ändern. (Die init routine läuft übrigens im
> Terminal)

Ja klar: sie sendet ein reset 0x12 0x80 und dann 2 
Register-write-Aktionen an den MC (so meine Erinnerung).

Die genaue Sendefolge solltest Du im Log ausgeben - der Benutzer sollte 
stets wissen, was exakt an den AVR gesendet wird.

> Jetzt erkennt das Terminal anhand der Register Werte, welche
> Auflösung eingestellt ist. (Der uC weiß das aber nicht).

Diese 2 Sätze verstehe ich nicht: das Setting von Registern kurz zuvor 
beeinflusst doch automatisch schon die Auflösung? Und der uC weiß doch 
davon?! Die Register-Write-Befehle werden ja an ihn geschickt?
Ich glaube, ich stehe aktuell wieder einmal ein wenig auf der Leitung?

> Das bedeutet,
> dass ich jetzt noch die passende Auflösung und BytesPerPixel an de uC
> senden muss.

> Ihr wolltet aber sämtliche Schreibbefehle aus der get
> Status funktion raus haben.

Ja, das ist unbedingt richtig!

> Daher sind die jetzt zu dem Butten sync Camera gewandert. Sprich:
> nachdem ich die auflösung ändere (passiert bei init Kamera) muss danach
> zwingend der sync Camera knopf gedrückt werden.
> Das versuche ich noch ersichtlicher zu machen

Au ja, das wäre gut, denn ich habe hier wieder Deine Erklärung noch das 
Zusammenspiel der beiden Buttons verstanden.

>> Aber: wenn ich die bekannten Colorbar-Initwerte manuell in die Register
>> pumpe, so erhalte ich tatsächlich ein schönes Testbild (siehe Bild 3 im
>> Anhang).
> Das widerrum ist merkwürdig... vlt. sollte ich mir das nochmal anschauen

Magic, magic ...

>> Erstaulich dabei: obwohl von Hand in die Register geschrieben, erkennt
>> Dein Programm das Pattern und zeigt an: "Testpattern Colorbar".
> Jap :)
>
>> Das führt mich zu der Vermutung, dass Dein "take Picture" eigentlich
>> funktioniert, aber die Kombination der gesendeten "Kamera
>> Initialisieren"-Registerwerte zu einem Bild führt, was auflösungs- oder
>> formatmäßig nicht zu Deiner im Terminal gewählten X-/Y-Auflösung bzw.
>> dem dort gewählten Format des Bildes passt.
>>
> s.o.

Wie gesagt: die Zs.hänge habe ich auch nach Deiner Erklärung noch nicht 
richtig verstanden.

>> Weitere "Bugs" und Verbesserungen hier (bin aktuell zu faul, sie alle
>> ins GIT einzutragen):
>>
>> - Button "read for change" schreibt keine Logmeldung
>> - Buttonbeschriftung solltest Du vereinheitlichen:
>>   Heute:  "read register",
>>           "Read Device Settings",
>>           "Kamera Initialisieren", ...
>>   Besser: "Read Register" oder "Init Camera"
>>           Also einheitliche Schreibweise in Englisch
>> - Die Idee mit dem "List not up to date" nach Schreiboperationen
>>   finde ich richtig gut! Du solltest das aber konsequent durchhalten -
>>   also auch bei "Kamera initialisieren" muss "List not up to date"
>>   gesetzt werden.
>> - Richtig wichtig fände ich unter dem Bild die Anzeige, mit welcher
>>   X- bzw. Y-Auflösung das Bild im Terminal dargestellt wird
>> - Umschalten zwischen den Tabs scheint nicht mehr zu funktionieren:
>>   Im Tab "manueller Modus" wird nach Umschalten noch weiterhin
>>   das rechte Fenster mit dem "take Picture" vom Tab "Settings"
>> angezeigt.
> sehr gut :)

Was meinst Du mit "sehr gut :)"?

Meinst Du:

- ich habe die Verbesserungsvorschläge/Bugbeschreibungen alle verstanden 
und werde sie umsetzen/fixen?
- Oder meinst Du: ich werde die Bugbeschreibungen alle in GIT 
nachtragen?
- Oder meinst Du: sehr gut, dass Dir, Igel1, die Dinge aufgefallen sind, 
aber ich arbeite aktuell an anderen Baustellen im Terminal?

> Zu dem Studio "Workload"... Ich habe da leider nicht den leisesten
> Schimmer was du damit meinst. Also dur brauchst c# windows forms (oder
> so ähnlich) und .net Framework

Immerhin sagt mir das, ich sollte mir neben C# auch etwas "windows 
forms" anlesen. Mann, oh Mann - ich werde hier in diesem Projekt noch 
richtig schlau ;-)

> Edit: sorry Bild nicht gesehen: also im ersten Schritt brauchst du nur
> das oben rechts .net desktop development
> Öffnen kannst du das Projekt einfach über die .sln datei.

Ah supi - das war die entscheidende Info, die ich benötigt habe.
Damit muss ich mir meinen schönen Compi nicht mit 16GB-Mikroschrott 
vollmüllen, sondern "nur" mit 4GB. Und öffnen via .sln-Datei habe ich 
mir inzwischen fast gedacht - danke trotzdem für die Bestätigung.

> viele Grüße
> David

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Hallo,
nach nun fast einer Woche funkstille möchte ich nochmal ein 
Lebenszeichen abfragen ;-) ich hoffe ihr verliert nicht die Lust. Bei 
mir war es die letzten zwei Wochen leider wieder sehr turbulent.
ich habe jetzt alles von dir genannte in die Issue liste übernommen und 
versuche mich mit dem Thema der Auflösung nochmal verständlicher 
auszudrücken:

1. die Auflösung die der Imager überträgt und in den Fifo ablegt hängt 
von den Registerwerten ab (Ich denke hier sind wir uns einig)

2. das Terminal liest die entsprechenden Register aus und entscheidet 
anhand einer Switch-Case-Anweisung welche Auflösung (und Farbformat) nun 
eingestellt wird.

3. Mit dem button Sync Camera werden die Auflösung und die BytesPerPixel 
and den uController gesendet, weil dieser bei der Übertragung von einem 
Bild ja die dreifach geschachtelte for-schleife durchläuft, deren 
Austrittskriterien ja die x-Res, y-Res und die BytesPerPixel sind:
1
 void sendFrameBufferToUART (int ImageWidth, int ImageHeight, int BytesPerPixel)
2
 {
3
  OV7670_ResetFifoReadPointer();
4
5
  for(int height = 0; height < ImageHeight;height++)
6
  {
7
    for(int width =0; width < ImageWidth; width++)
8
    {
9
      for(int ByteNumber =0; ByteNumber < BytesPerPixel; ByteNumber++)
10
      {
11
        OV_RCK_PORT &= ~(1<<OV_RCK_PinNo);
12
        _delay_us(85);
13
        UART0_senden_Byte(Ov7670_readByte());
14
        OV_RCK_PORT |= (1<<OV_RCK_PinNo);
15
        _delay_us(85);
16
      }
17
    }
18
  }
19
 }
die Variablen die in dieser Funktion übergeben werden, können vom 
Terminal aus angepasst werden (anhand des sync Camera buttons.

ein nicht Übermitteln der Auflösung/des Farbformates sollte aber 
höchstens eine falsche Anzahl der gesendeten Bytes verursachen. Das Bild 
sollte aber dennoch zumindest zum Teil richtig angezeigt werden. (Daher 
weiß ich gerade noch nicht, was jetzt wirklich im Terminal schief läuft.
Morgen habe ich aber wieder etwas Zeit und werde weiter arbeiten.

Bis dahin,

Gruß David

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> nach nun fast einer Woche funkstille möchte ich nochmal ein
> Lebenszeichen abfragen ;-)

Hatte ich gestern Abend auch schon überlegt. ;-)
Aus der Terminal-Programmierung selbst werde ich mit Sicherheit 
raushalten, ich werde aber sicher mittesten, wenn es das was zu testen 
gibt.
Der Kram liegt weiterhin parat, eine Terminalversion oder AVR-Source 
runterladen ist auch kein Problem und der serielle Sniffer lauert auch 
weiterhin auf Daten.
Ich werde in den aktuellen Stand also morgen mal reinschauen und mich 
überraschen lassen.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Bin auch noch mit von der Partie.

Wenn ich einen ganz kleinen Wunsch frei hätte, so würde ich mir manchmal 
etwas schnellere Reaktionen von David auf meine Fragen wünschen ...

Denn manchmal hätte ich Zeit und würde gerne weitermachen, hänge dann 
aber an fehlenden Antworten fest.

Andererseits akzeptiere ich es selbstverständlich, wenn David einfach 
keine Zeit hat - nur manchmal würden mir schon 5 Minuten Invest in eine 
schnelle Antwort sehr helfen.

Die letzten Erklärungen haben mir übrigens sehr geholfen - vorher war 
mir der Sinn des Sync-Camera-Buttons völlig schleierhaft.

Viele Grüße

Igel1



PS: ... ansonsten lese ich mir noch immer ein C# Tutorial durch - hatte 
die letzten 2 Wochen extrem viel zu tun.

von David D. (saturi)


Lesenswert?

17 min Reaktionszeit... Ich bin da :D

von Andreas S. (igel1)


Lesenswert?

Mist - und ich habe jetzt keine passende Frage ...

Oder vielleicht doch: wie ist das Wetter? ?

von Andreas S. (igel1)


Lesenswert?

Und noch eine Bonusfrage:

Du hast Dein Terminalprogramm mit Windows Forms geschrieben, korrekt?
Wenn ja: kannst Du mir eine gute Anleitung zur Einarbeitung (Windows 
Forms unter C#) empfehlen?

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Oder vielleicht doch: wie ist das Wetter? ?

hier laut meinem Balkon-Sensor: pffff.... Schau doch selber. ;)
http://www.roehres-home.de/fhem/fhem.png

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> hier laut meinem Balkon-Sensor: pffff.... Schau doch selber. ;)
> http://www.roehres-home.de/fhem/fhem.png

Ziemlich cool ...
Selbst gebaut oder selbst gekauft?

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Also ich habe damals meine ersten Schritte mit youtube gemacht. da gibt 
es tausende Videos wo es schritt für schritt erklärt wird. Einfach mal 
"Windows forms C# deutsch" oder so ähnlich eingeben. Noch mehr gibt es, 
wenn man keine probleme mit dem indischen englisch akzent hat ;-)

Beispielhaft: https://www.youtube.com/watch?v=x-qg5vQwu0s

Allerdings wäre es vermutlich gut, die absoluten Grundlagen zum 
Objektorientierten Programmierung zu kennen. (Klassen, Methoden, 
Objekte, Eigenschaften)

Aktuell "renoviere" ich gerade das Terminal programm. Weil es viele 
Sachen gab, die auf den ersten Blick zwar durch die Programmierung 
gelöst waren, aber Änderungen immer einen riesen Rattenschwanz nach sich 
gezogen haben.

Um das etwas elegenater und schlanker zu Lösen baue ich grade um und 
hoffe, dass ich nichts übersehe ;-)

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

Andreas S. schrieb:
> Selbst gebaut oder selbst gekauft?

Sensoren Tiny45/FOST02/RFM02, eigenes Protokoll, gebaut um 2009.
Datenerfassung inzwischen mit 433MHz Bridge RFM12/ESP8266 und Umsetzung 
nach MQTT und WLAN. MQTT-Broker und FHEM auf RasPi3. Das Bild erzeugt 
FHEM auf dem RasPi für ein altes 7" Tablett, das noch rumlag. Irgendwann 
dann dem RasPi gesagt, er soll das Bild alle paar Minuten auf meinen 
Webspace legen.
Hängen auch noch Funksteckdosen, PIRs und sonstiger Kram dran, gesteuert 
mit FHEM.
Nichts davon wirklich nötig, aber man will doch was zum Basteln haben...
Die Oberfläche von FEHM auf dem PC dazu...

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Also ich habe damals meine ersten Schritte mit youtube gemacht. da gibt
> es tausende Videos wo es schritt für schritt erklärt wird.

Ach ja - Du gehörst schon zu der Generation, die sich alles per Video 
beibringt. Ich gehöre noch zu der Generation, die lieber liest - ich 
persönlich kann mir den Stoff dann ca. 2-3x schneller "reinpfeifen", als 
wenn ich mir Videos anschaue.

Auch fehlt mir dann die Möglichkeit, das Gelernte nochmals schnell 
nachzuschlagen. Auf der anderen Seite ist die Bedienung von grafischen 
Oberflächen im Video zugegeben etwas besser zu verstehen.


Ist halt alles Geschmackssache.

> Einfach mal
> "Windows forms C# deutsch" oder so ähnlich eingeben. Noch mehr gibt es,
> wenn man keine probleme mit dem indischen englisch akzent hat ;-)

Englisch geht einigermaßen bei mir, aber zugegeben: je nach Inder 
verstehe ich wirklich manchmal nur Bahnhof.

>
> Beispielhaft: https://www.youtube.com/watch?v=x-qg5vQwu0s
>

Okay - die 20 Minuten werde ich mir einmal antun, wenn ich heute neben 
Gartenarbeit, Job-Nacharbeit und Kinder-Abi-klar-machen noch etwas Zeit 
finde.

> Allerdings wäre es vermutlich gut, die absoluten Grundlagen zum
> Objektorientierten Programmierung zu kennen. (Klassen, Methoden,
> Objekte, Eigenschaften)

Ich kann Java, C, C++, Perl, Python, verschiedene Assembler-Sprachen - 
das sollte für den Einstieg in C# reichen ;-)   C# scheint mir eh nur 
ein Microsoft-Abklatsch von C++ und etwas Java zu sein - aber trotzdem 
möchte ich es mir halbwegs anständig beibringen. Mein Hauptproblem ist 
eher, dass ich immer mehr die Programmiersprachen durcheinanderwerfe und 
mit Java-Konstrukten in C++ herummache und umgekehrt.

> Aktuell "renoviere" ich gerade das Terminal programm. Weil es viele
> Sachen gab, die auf den ersten Blick zwar durch die Programmierung
> gelöst waren, aber Änderungen immer einen riesen Rattenschwanz nach sich
> gezogen haben.

Ah - das hört sich interessant an.

> Um das etwas elegenater und schlanker zu Lösen baue ich grade um und
> hoffe, dass ich nichts übersehe ;-)

Bin dann mal gespannt auf Deinen überarbeiteten Code (evtl. möchtest Du 
ihn ja einfach in GitHub pflegen bzw. häufig einchecken?)

Bis dahin werde ich mich weiter in C# und Windows Forms 
einlesen/eingucken.

Hier übrigens das Tutorial, das ich nutze:
https://csharp.net-tutorials.com/
Ist für Anfänger sicherlich nicht optimal, für mich aber genau richtig.
Bin jetzt gerade beim Abschnitt "Operators".

Ach hätte ich doch nur mehr Zeit, ich würde es so gerne heute zu Ende 
durcharbeiten - aber that's life ...

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> Hallo,
>
> Andreas S. schrieb:
>> Selbst gebaut oder selbst gekauft?
>
> Sensoren Tiny45/FOST02/RFM02, eigenes Protokoll, gebaut um 2009.
> Datenerfassung inzwischen mit 433MHz Bridge RFM12/ESP8266 und Umsetzung
> nach MQTT und WLAN. MQTT-Broker und FHEM auf RasPi3. Das Bild erzeugt
> FHEM auf dem RasPi für ein altes 7" Tablett, das noch rumlag. Irgendwann
> dann dem RasPi gesagt, er soll das Bild alle paar Minuten auf meinen
> Webspace legen.
> Hängen auch noch Funksteckdosen, PIRs und sonstiger Kram dran, gesteuert
> mit FHEM.
> Nichts davon wirklich nötig, aber man will doch was zum Basteln haben...
> Die Oberfläche von FEHM auf dem PC dazu...
>
> Gruß aus Berlin
> Michael


Wow - nicht schlecht: Du hast das, wovon ich für unsere Wohnung schon 
immer geträumt habe, scheinbar bei Dir in vollem Umfang umgesetzt. Und 
das vor 10 Jahren, als die Technik noch ziemlich revolutionär war - 
nicht schlecht, Herr Specht!

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Wow - nicht schlecht: Du hast das, wovon ich für unsere Wohnung schon
> immer geträumt habe, scheinbar bei Dir in vollem Umfang umgesetzt. Und
> das vor 10 Jahren, als die Technik noch ziemlich revolutionär war -
> nicht schlecht, Herr Specht!

Schuld waren schon damals die Chinesen... HopeRF tauchte auf, 433MHz 
Funkmodule mit interessanten Funktionen, Temp./Feuchte/Luftdrucksensoren 
mit digitalen Schnittstellen und alles für Preise um 5€/Stück statt 
30-50€.
http://www.avr.roehres-home.de/sensoren/index.html
Dann lange nichts, erst als die ESP-Module kamen habe ich da 
weitergemacht, wieder wiel WLAN für kein Geld -> interessant...
FHEM auf dem RasPi kam erst 2016 dazu, der Rest ist nach und nach 
dazugewachsen. Ich wollte auch noch meine Wärme- und Wasserzähler 
reinnehmen, mit denen ich vor 2 Jahren beglückt wurde, mitlesen ist 
pronzipiell kein Problem, Teile für den CUL für die Anbindung sind auch 
da, mehr ist aber bisher nicht passiert.
Alexa hat auch Einzug gehalten, sie darf zumindest etwas Licht ein- und 
ausschalten, Bridge ist auch da ein ESP.
Die meisten Sachen sind nur aus Neugier mal angetestet, irgendwann kommt 
dann eine unsinnige Idee bei mir oder meinem Bekannten zustande, da wird 
dann was ausgekramt und zwischendurch eben realisiert, oft nur 
halbfertig. ;-)

Davids Kamerageschichte ist ja auch nur deshalb hier dabei. Die kleinen 
AVR sind immernoch meine Freunde, die Cam lag rum und meinen 
C-Kenntnissen schadet das auch nicht, sind ohnehin relativ bescheiden.
Müssen muß ich da ja nichts mehr... :-)

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> Ich wollte auch noch meine Wärme- und Wasserzähler
> reinnehmen, mit denen ich vor 2 Jahren beglückt wurde, mitlesen ist
> pronzipiell kein Problem, Teile für den CUL für die Anbindung sind auch
> da, mehr ist aber bisher nicht passiert.
> Problem, Teile für den CUL für die Anbindung sind auch da,
> mehr ist aber bisher nicht passiert

Was ist denn ein „CUL“?

Viele Grüße

Andreas

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Was ist denn ein „CUL“?

Ich zitiere mal aus dem FHEMWIKI:
"CUL (CC1101 USB Lite) ist ein RF-Gerät im Formfaktor eines USB-Dongles 
mit externer Antenne."

Hat sich bei dem Home-Automatisierungskram irgendwie eingebürgert für 
alle Sachen, die irgendwelche (kommerziellen) Funksensorren einsammeln, 
die Daten dekodieren/aufbereiten und per USB seriell zur Verfügung 
stellen.
Bei mir Arduino Nano mit passendem Funkmodul für 433 oder 868 MHz, meist 
CC1101, manchmal auch RFM12 oder RFM95 o.ä.
Die stecken dann am RasPi-USB und der darf sich mit den Daten rumärgern, 
FHEM und openHAB unterstützen die dann direkt.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

@Michael U.:

Danke für die Erklärungen - wieder was gelernt ...

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Ja, ich werde das Terminal Projekt so wie das AVR-Projekt in Github 
ablegen, sodass jede Code-Änderung nachvollziehbar wird.

Dann tust du dich vielleicht leichter. Allerdings würde ich für diesen 
Schritt gerne auf mein "eigenes" Github Projekt umswitchen. Weil das auf 
dem wir aktuell unterwegs sind von einem User hier im Forum ist, der 
ganz am Anfang mal dabei war, dann aber ausgestiegen ist.

Da ich nicht weiß in wiefern man bei so github Projekten von dem "Host" 
ist, würde ich es einfach kurz auf meinen Account ziehen und den Link 
dann hier teilen.

@Michael, ich glaube die Frage habe ich dir schonmal gestellt. Wärst du 
bereit auch auf der Github-Plattform zu kommentieren? (Keiner erwartet 
dass du am Terminal mit codest) Nur die auftretenden Fehler etc. lassen 
sich dann strukturierter bearbeiten.

Gruß

David

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> @Michael, ich glaube die Frage habe ich dir schonmal gestellt. Wärst du
> bereit auch auf der Github-Plattform zu kommentieren? (Keiner erwartet
> dass du am Terminal mit codest) Nur die auftretenden Fehler etc. lassen
> sich dann strukturierter bearbeiten.

ja, kann ich auf jeden Fall machen.
Nimm es mir nicht allzu übel, wenn ich hier manchmal etwas "spitz" 
kommentiere, mir geht nur manchmal durch den Kopf, ob Du Dir das zur 
Lebensaufgabe gemacht hast. Ich habe auch erst jetzt als Rentner mehr 
Zeit, fürher (tm) mit Berufsleben, Familie und Tocher waren auch meine 
Priorotäten andere. Trotzdem habe ich manches elektronische angefangen 
und etliches auch zu Ende gebracht. Wenn ich da so zurückdenke: das 
Westfernsehen führt Stereoton im Fernsehen ein, keine wirklichen Infos 
zum Verfahren hier im Osten verfügbar, nur wenige Randinformatinen und 
die damasl nog Mittgas gesendetet Testsendungen mit Testbild und eben 
dann auch Sereotest. das 2 Träger genutzt werden war schnell klar, ein 
Tonmodul von 5,5MHz auf 5,74MHz abgeglichen und es kam was raus. Bis wir 
rausgefunden haben, daß sie R+L und 2xR senden und das mit passiver 
Matrix zusammengenotet hatten, dauerte dann ein paar Tage. Letztlich 
habe aich aber mit einem Fragwürdigen Drahtverhau neben meinem Raduga 
Farb-TV die Eröffnungssendung von der Funkschau in Stereo gehört. Mit 
etwas Rauschen auf dem rechten Kanal garniert, aber Stereo.
Sorry, aber "alte" Leute reden eben gern "vom Krieg". ;)))

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Lesenswert?

Michael U. schrieb:
> Sorry, aber "alte" Leute reden eben gern "vom Krieg". ;)))

Schön - oder auch nicht - ich habe mal ein Modul mit Speicher bestellt, 
mal schauen, was dabei herauskommt.

von Dieter F. (Gast)


Lesenswert?

Michael U. schrieb:
> Sorry, aber "alte" Leute reden eben gern "vom Krieg". ;)))

Wenn ich von 1945 ausgehe - und wenigstens 15 Jahre annehme, dann musst 
Du knapp 90 Jahre alt sein. Gratuliere.

von Michael U. (amiga)


Lesenswert?

Hallo,

Dieter F. schrieb:
> Michael U. schrieb:
>> Sorry, aber "alte" Leute reden eben gern "vom Krieg". ;)))
>
> Wenn ich von 1945 ausgehe - und wenigstens 15 Jahre annehme, dann musst
> Du knapp 90 Jahre alt sein. Gratuliere.

Das ist eine Redensart... Und meist ist der erste dann gemeint. ;)
Ansonsten: da fehlen mir noch 22 Jahre. :-)

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Lesenswert?

Michael U. schrieb:
> Ansonsten: da fehlen mir noch 22 Jahre. :-)

Also - nix Krieg.

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
>> Wenn ich von 1945 ausgehe - und wenigstens 15 Jahre annehme, dann musst
>> Du knapp 90 Jahre alt sein. Gratuliere.
>
> Das ist eine Redensart... Und meist ist der erste dann gemeint. ;)
> Ansonsten: da fehlen mir noch 22 Jahre. :-)

Hui - gut gehalten, Michael (vor allem mit Blick auf Deine 
elektronischen a jour - Kenntnisse)!

@David: kannst den Speed hier aus dem Projekt rausnehmen  Michael wird 
uns noch ein paar Jahrzehnte erhalten bleiben  ;-)

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Dann tust du dich vielleicht leichter.

Och, ich finde gar nicht, dass ich mich schwer tue :-)
Ich habe halt einfach nur suuuper wenig Zeit, weil ich irgendein 
verrücktes internationales Chaos-Projekt mit dutzenden von Beteiligten 
schon seit vielen Monaten am Fliegen halten muss.

Und für den Flickenteppich an freien Zeitscheiben, der mir neben Arbeit 
und Familie zur Verfügung steht, halte ich mich hier ziemlich gut - 
finde ich wenigstens :-)

> Allerdings würde ich für diesen
> Schritt gerne auf mein "eigenes" Github Projekt umswitchen. Weil das auf
> dem wir aktuell unterwegs sind von einem User hier im Forum ist, der
> ganz am Anfang mal dabei war, dann aber ausgestiegen ist.

Yep - geht klar. Schade, dass uns Olli Z. seinerzeit von der Stange 
gegangen ist - der war auch schön engagiert und sehr gründlich. Hätte 
gut hier in den Club der toten AVR'ler reingepasst.

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

ja... hatte sogar versucht Olli per E-Mail zu reaktivieren. Eine nette 
antwort kam auch, aber leider keine Folgetaten ... naja kann man nix 
machen.
Ich finde das wir 3,5 uns auch gut schlagen! :)

@Michael deine spitzen Kommentare sind dir schon verziehen und deine 
Geschichten sind auch immer interssant. Immerhin kenne ich noch Stereo 
und Röhrenbildschirme ;-D

setzte mich jetzt dran und morgen hoffe ich euch den link incl. source 
code schicken zu können

heute war erstmal Geburtstag feiern dran ;-)

in diesem Sinne bis morgen!

Gruß
David

Edit:
dennoch muss ich anscheinend in meiner Hardware noch nach was suchen
camera anstecken mim terminal verbinden, read device settings klicken: 
läuft durch. nochmal klicken läuft durch, nochmal klicken läuft bis 
register 31. kamera abstecken, terminal neustarten, kamera anstecken, 
verbinden und read device settings klicken, läuft bis register 180
...

oder ich warte nochmal bis wir alle im gleichen projektstatus sind (mit 
dem neuen Github projekt)

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> ja... hatte sogar versucht Olli per E-Mail zu reaktivieren. Eine nette
> antwort kam auch, aber leider keine Folgetaten ... naja kann man nix
> machen.
> Ich finde das wir 3,5 uns auch gut schlagen! :)

Ja, finde ich auch.

> heute war erstmal Geburtstag feiern dran ;-)

Na dann herzlichen Glückwunsch, David!
Du holst also auch altersmäßig kräftig auf!

> Edit:
> dennoch muss ich anscheinend in meiner Hardware noch nach was suchen
> camera anstecken mim terminal verbinden, read device settings klicken:
> läuft durch. nochmal klicken läuft durch, nochmal klicken läuft bis
> register 31.

Yep - da ist bei Dir noch etwas faul.
Klemm vielleicht mal den LogicAnalyzer ab und teste dann nochmsls.
Oder bestelle Dir einen Haufen Nanos - die laufen bei mir schön rund.

> oder ich warte nochmal bis wir alle im gleichen projektstatus sind (mit
> dem neuen Github projekt)

Auch 'ne Möglichkeit ...

Viele Grüße

Igel1

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

da habe ich doch glatt die Geburtstagsmeldung überlesen, also:
nachträglich alles Gute, auch Du kannst also das älterwerden offenbar 
nicht verhindern. ;-)

Hier scheint ja die Sonne, also ist Ruhe im Thread.
OT:
Mich verwirren im Moment mal wieder die chinesichen Freunde:
auf dem aktuellen ESP32-OV2640 Modul ist ein Powerbank-IC IP5306 drauf, 
das war auch schon auf der kleinen M5Stack-Cam drauf.
Chinesischens Datenblatt ist verfügbar, die Übersetzung ...nja... 
ausreichend. Soweit, so gut.
Das IC hat 3 Ausgänge für LEDs zur Ladezustandanzeige, die sind bei der 
M5Stack-Cam unbeschaltet, ok.
Witzigerweise sind sie beim neuen Modul beschaltet, als I2C Bus, und 
werden auch wirklich in der Software angesprochen.
In einem Forum habe ich jetzt zumindest ein "Datenblatt" dazu gefunden. 
Es ist eine Custom-Version IP5306_I2C. An der Bezeichnung auf den beiden 
ICs durch nichts zu unterscheiden...
Man kann den Ladezustand auslesen, Abschaltspannung und Ladestrom 
einstellen, abfragen, ob viel oder wenig Last am Ausgang hängt, den 5V 
Boost-Converter abschalten und noch ein paar Sachen, die ich noch nicht 
ganz verstanden habe.
Völlig OT:
Zur Volksbelustigung hänge ich die deutsche "Übersetzung" einfach mal 
an, die Fachleute hier werden die Bit-Beschreibungen der Register sicher 
auf Anhieb verstehen. :-)

Gruß aus Berlin
Michael

von Nosnibor (Gast)


Lesenswert?

Michael U. schrieb:
> Es ist eine Custom-Version IP5306_I2C. An der Bezeichnung auf den beiden
> ICs durch nichts zu unterscheiden...

Je nachdem, wie die LEDs beschaltet und genutzt werden, könnte das ja 
rückwärtskompatibel sein. Mit den open-collector-Ausgängen am I2C kann 
man ja genausogut LEDs treiben. Wenn die LEDs nur auf Anforderung 
(Taster gedrückt) leuchten sollen, muß der Chip gar nicht wissen, wie er 
beschaltet ist (bis jemand den Taster drückt)...

von Michael U. (amiga)


Lesenswert?

Hallo,

Nosnibor schrieb:
> Je nachdem, wie die LEDs beschaltet und genutzt werden, könnte das ja
> rückwärtskompatibel sein.

da habe ich auch kurz drüber nachgedacht. Eigentlich ist das ja ein 
Powerbank-IC, wo eben mit dem Taster der 5V-Wandler gestartet wird und 
mit den LEDs der Ladezustand angezeigt wird.
Vielleicht teste ich das mal mit der anderen Cam-Version, wo der drauf 
ist. Sagt aber dann auch nur bedingt was aus, die Pins dort sind ja 
unbeschaltet und aus der IC-Bezeichnung ist nichts rauszulesen. Ist 
einfach nur interessant das Teil...

Gruß aus berlin
Michael

von David D. (saturi)


Lesenswert?

Sooo auf ins Wochenende.

Eigenes Github Projekt mit beiden Code-Strukturen ist jetzt online:
https://github.com/Saturi92/OV7670_AVR

Pflege heute Abend noch die ToDo-Liste ein und dann könnten wir da auch 
Lösungen erarbeiten ;-)

von David D. (saturi)


Lesenswert?

Andreas S. schrieb:
> Klemm vielleicht mal den LogicAnalyzer ab und teste dann nochmsls.
> Oder bestelle Dir einen Haufen Nanos - die laufen bei mir schön rund.

leider habe ich immernoch keinen zuverlässigen logic Analyzer -.- und 
mein "workaround" funktioniert leider auch nicht mehr?! warum auch 
immer, aber das javatool erkennt die HW nicht mehr :/ war eh immer nur 
ein Glücksgriff wenn es dann eins von zehn malen tat.


die nanos würde ich glatt machen... aber jetzt habe ich doch gerade das 
shield für den Uno gelötet :D da würde ich mir eher nochmal einen uno 
bestellen :D

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Eigenes Github Projekt mit beiden Code-Strukturen ist jetzt online:
> https://github.com/Saturi92/OV7670_AVR

den Link habe ich mir erstmal als aktuell hingelegt.

David D. schrieb:
> die nanos würde ich glatt machen... aber jetzt habe ich doch gerade das
> shield für den Uno gelötet :D da würde ich mir eher nochmal einen uno
> bestellen :D

richtig erklären kann ich mir eigentlich nicht, was da bei Dir passiert. 
Ich habe es ja aus mechanischen Gründen auch als Uno-Shield 
zusammengelötet. Hatte es vorher mit Dupount-Kabeln an einem Nano, das 
war mir aber wegen des Drahtverhaus zu wacklig um es zwischendurch 
einfach weglegen zu können.
Due kannst ja nochmal Bilder von Deinem Aufbau posten, vielleicht fällt 
mir irgendwas auf.
LA habe ich im Moment nicht dran, da muß ich bei meinem Eigenbau auch 
etwas aufpassen, weil die Eingangsschaltung 100k PullUp gegen die 
internen 5V hat.
Da passiert zwar nichts, das hat mir aber schon die Pegel versaut, wenn 
ich z.B. vergesse, den an USB zu stekchen und mit Spannung zu versorgen.
Es läuft das mit dem UNO genauso wie mit dem nano, aus AVR-Sicht sind 
die ja im Prinzip identisch.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Andreas S. schrieb:
>> Klemm vielleicht mal den LogicAnalyzer ab und teste dann nochmsls.
>> Oder bestelle Dir einen Haufen Nanos - die laufen bei mir schön rund.
>
> leider habe ich immernoch keinen zuverlässigen logic Analyzer -.- und
> mein "workaround" funktioniert leider auch nicht mehr?! warum auch
> immer, aber das javatool erkennt die HW nicht mehr :/ war eh immer nur
> ein Glücksgriff wenn es dann eins von zehn malen tat.
>
>
> die nanos würde ich glatt machen... aber jetzt habe ich doch gerade das
> shield für den Uno gelötet :D da würde ich mir eher nochmal einen uno
> bestellen :D

Gerade heute kamen 2 LA bei mir aus dem Reich der Mitte an - Stück 5 
EUR.
Ich denke, diesen Invesr solltest Du Dir auch einmal gönnen.

Und bevor Du jetzt noch lange nach dem Fehler suchst, würde ich die 
Schaltung mit einem für DebugWire präparierten Nano oder meinetwegen 
auch einem UNO nochmals aufbauen und Fertig.

Ich selber hätte gerne jetzt am Wochenende meine ersten C# Gehversuche 
gemacht, habe mir aber einen Infekt eingefangen und bin leider ziemlich 
platt. Wünsche Euch gute Fortschritte!

Igel1

von Andreas S. (igel1)


Lesenswert?

@David: Tschuldigung für den letzten Post - klingt sehr arrogant.
Bin halt aktuell ziemlich matsche in der Birne.

Da kommt mir in den Sinn: was mache ich mit 2 LA?
Darf ich Dir einen der beiden LA als Wiedergutmachung schenken?

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

@Andreas: erstmal gute Besserung.
Sind das die üblichen 8-Kanal/24MHz-Teile?
Als Software dann die von Sigrok?

Ich denke also wiedermal darüber nach, bei meiner AVR-Firmware das 
Protokoll anzupassen, weil ja meine Eigenbau 8-Kanal/80MHz Hardware 
stabil läuft.
Wollte ich schon immer mal, weil ich die Protokolldecoder (das Einzige, 
was fehlt) wohl sowieso nicht mehr in die alte VB6-Software einbaue.
Zumal ich den I2C-Decoder gerade für einen anderen "Hack" brauchen 
würde...

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> Hallo,
>
> @Andreas: erstmal gute Besserung.

Danke!

> Sind das die üblichen 8-Kanal/24MHz-Teile?

Yep.

> Als Software dann die von Sigrok?
>

Keine Ahnung, muss ich mich noch mit beschäftigen, wenn der Kopf wieder 
klar ist. Aber vermutlich hast Du recht.

> Ich denke also wiedermal darüber nach, bei meiner AVR-Firmware das
> Protokoll anzupassen, weil ja meine Eigenbau 8-Kanal/80MHz Hardware
> stabil läuft.
> Wollte ich schon immer mal, weil ich die Protokolldecoder (das Einzige,
> was fehlt) wohl sowieso nicht mehr in die alte VB6-Software einbaue.
> Zumal ich den I2C-Decoder gerade für einen anderen "Hack" brauchen
> würde...

Gut, bräuchte dann nur noch die Lieferadresse.
Sobald ich wieder fit bin, geht das Dingen auf die Reise.

>
> Gruß aus Berlin
> Michael

Gruß aus dem Bett

Igel1

von David D. (saturi)


Lesenswert?

Hallo, Bilder vom Aufbau folgen heute Nachmittag.

@Igel das wollte ich wirklich nicht mit meinem Gejammer erreichen... 
dein Angebot ist sehr sehr nett, aber das kann ich nicht annehmen. einen 
Investor von 5€ werde ich schon stemmen können. Habt ihr da gute 
Erfahrungen? Und evtl. Nen Link?

Hatten wir genau das Thema nicht schon vor zwei Monaten? Ich meine schon 
mal gefragt zu haben... wenn ja, tut es mir leid.

Ich habe jetzt mal den Level shifter getauscht (weil der das einzige 
Bauteil ist, dass ich mehrfach habe. Lief auf Anhieb besser, hat jetzt 
aber die gleichen Probleme nur seltener... ob es der Level shifter sein 
kann? Aber dann müsste der Arduino doch Fehler auswerfen?
Werde mir jetzt noch nen zweiten UNO bestellen und heute Abend ne 
Platine für den Nano löten. Sobald ich von dem Frühlingsmarkt zurück 
bin, wo meine Dame hinmöchte -.- :D

@Igel gute Besserung, mich hat es diese Woche auch halb erwischt.

Und den Invest für einen kleinen LA werde ich jetzt auch tätigen...

Und einen nano auf debug umbauen werde ich auch versuchen.

Da hab ich mir wieder viel vorgenommen für ein paar freie Stunden. 
Leider spinnt mein Visual Studio gerade.  Sonst könnte ich euch schon 
den neuen release zur Verfügung stellen.

Wünsche euch einen schönen Sonntag.

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Hallo, Bilder vom Aufbau folgen heute Nachmittag.
>
> @Igel das wollte ich wirklich nicht mit meinem Gejammer erreichen...
> dein Angebot ist sehr sehr nett, aber das kann ich nicht annehmen. einen
> Investor von 5€ werde ich schon stemmen können. Habt ihr da gute
> Erfahrungen? Und evtl. Nen Link?

https://www.aliexpress.com/item/USB-Logic-Analyzer-24M-8CH-Microcontroller-ARM-FPGA-Debug-Tool-24MHz-16MHz-12MHz-8MHz-4MHz-2MHz/32960102049.html

Kannst Du ruhig von mir annehmen: ist ja kein Allmosen, sondern einfach 
nur 'ne kleine Aufmerksamkeit von mir. Ich habe hier im Forum auch schon 
so viele tolle Sachen geschenkt bekommen - warum nicht auch einmal 
anderen eine Freude machen? Wenn Du den LA aus China bestellst, musst Du 
halt 3 Wochen warten - so lange hat's jedenfalls bei mir gedauert.

>
> Hatten wir genau das Thema nicht schon vor zwei Monaten? Ich meine schon
> mal gefragt zu haben... wenn ja, tut es mir leid.
>
> Ich habe jetzt mal den Level shifter getauscht (weil der das einzige
> Bauteil ist, dass ich mehrfach habe. Lief auf Anhieb besser, hat jetzt
> aber die gleichen Probleme nur seltener... ob es der Level shifter sein
> kann?

Ja schon, ich habe den hier:
https://www.ebay.de/itm/3x-I2C-5V-3-3V-4-Kanal-Level-Shifter-Konverter-Pegelwandler-Arduino-Raspberry/253048505379

Extra in DE bestellt, weil ich nicht lange warten wollte.
Und immer schön auf die "Polungsrichtung" achten.

> Aber dann müsste der Arduino doch Fehler auswerfen?
> Werde mir jetzt noch nen zweiten UNO bestellen und heute Abend ne
> Platine für den Nano löten. Sobald ich von dem Frühlingsmarkt zurück
> bin, wo meine Dame hinmöchte -.- :D
>
> @Igel gute Besserung, mich hat es diese Woche auch halb erwischt.
>
> Und den Invest für einen kleinen LA werde ich jetzt auch tätigen...
>
> Und einen nano auf debug umbauen werde ich auch versuchen.
>
> Da hab ich mir wieder viel vorgenommen für ein paar freie Stunden.
> Leider spinnt mein Visual Studio gerade.  Sonst könnte ich euch schon
> den neuen release zur Verfügung stellen.
>
> Wünsche euch einen schönen Sonntag.

Dito.

Igel1

von David D. (saturi)



Lesenswert?

Guten Abend,

anbei die Bilder vom derzeitigen Aufbau. Meine LvL-Shifter unterscheiden 
sich von deinen gezeigten jetzt eigentlich nur in der Anzahl der Ein- 
bzw. Ausgänge.

> 
https://www.aliexpress.com/item/USB-Logic-Analyzer-24M-8CH-Microcontroller-ARM-FPGA-Debug-Tool-24MHz-16MHz-12MHz-8MHz-4MHz-2MHz/32960102049.html

ist bestellt, allerdings bei E-Bay und sollte diese Woche noch kommen 
;-) dennoch vielen Dank für das Angebot, das weiß ich wirklich zu 
schätzen :-))


Der nano läuft auch im Debug-Modus... war ja einfach... musste nur einen 
Kondensator raus nehmen (fälschlicherweise hab ich zuerst einen falschen 
Entfernt, der dann verschwunden ist :D läuft trotzdem o.O :D

Gruß
David

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Guten Abend,
>
> anbei die Bilder vom derzeitigen Aufbau. Meine LvL-Shifter unterscheiden
> sich von deinen gezeigten jetzt eigentlich nur in der Anzahl der Ein-
> bzw. Ausgänge.
>
>>
> 
https://www.aliexpress.com/item/USB-Logic-Analyzer-24M-8CH-Microcontroller-ARM-FPGA-Debug-Tool-24MHz-16MHz-12MHz-8MHz-4MHz-2MHz/32960102049.html
>
> ist bestellt, allerdings bei E-Bay und sollte diese Woche noch kommen
> ;-) dennoch vielen Dank für das Angebot, das weiß ich wirklich zu
> schätzen :-))

Schade - ich hätte Dir auch gerne eine Freude gemacht.

> Der nano läuft auch im Debug-Modus... war ja einfach... musste nur einen
> Kondensator raus nehmen (fälschlicherweise hab ich zuerst einen falschen
> Entfernt, der dann verschwunden ist :D läuft trotzdem o.O :D

Na Du hast Nerven ...
Bevor es später zu unerklärlichen Seiteneffekten kommt, würde ich 
dringend nachforschen, welchen Kondensator Du da versehentlich entfernt 
hast.
Das würde ich an Deiner Stelle wirklich dringend(!) tun, denn auf den 
Boards ist kein einziges Bauteil zuviel drauf und jedes Bauteil hat 
Nebenwirkungen, wenn es fehlt.

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Andreas S. schrieb:
> Bevor es später zu unerklärlichen Seiteneffekten kommt, würde ich
> dringend nachforschen, welchen Kondensator Du da versehentlich entfernt
> hast.

Das hatte ich natürlich sowieso vor ;-)

Es handelt sich um den 0,1uF der direkt neben der Spannungsregler (5V 
sitzt), parallel geschaltet zum 4,7uF.

Kann mir einer von euch Elektronikspezialisten den schaltungstechnischen 
Sinn davon erklären? warum setzte ich einen kleinen Kondensator parallel 
zu einem um den Faktor 50 größeren?

Hat das was mit der Polungrichtung des größeren zu tun der nur Ladungen 
in eine Richtung aufnehmen kann?


@Igel um dich zu beruhigen: Er ist wieder an Ort und Stelle ;-)
 Und mein Visual studio läuft auch wieder... aber leider ist die 
Mittagspause schon wieder vorbei...


Bis heute Abend!

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Kann mir einer von euch Elektronikspezialisten den schaltungstechnischen
> Sinn davon erklären? warum setzte ich einen kleinen Kondensator parallel
> zu einem um den Faktor 50 größeren?

Weil die größeren Kapazitäten bei höheren Frequenzen schlechtere 
Eigenschaften haben (Stichwort Serieninduktivität und ESR).
Der größere liefert die Energie bei sehr schnellen Spannungsänderungen 
zu langsam, der kleinere alleine hätte zu wenig Kapazität und längere 
Einbrüche zu überbrücken.
Eigentlich spielen noch mehr Faktoren eine Rolle, für eigene 
Einschätzungen für die Notwendigkeit reicht das so aber durchaus aus.
Siehe auch die Dauerdiskussionen, warum an den µC oder an getaktete ICs 
allgemein nahe an die Spannungsanschlüsse Kondensatoren gehören.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Hallo David,

es ist, wie Michael gesagt hat. Je nach Deinem "Background" empfehle ich 
ggf. etwas Lektüre dazu. Ich selber hatte früher jedenfalls eine ganze 
Weile benötigt, um die Zs.hänge auch nur einigermaßen zu verstehen.

So richtig "klick" gemacht hat es bei mir erst, als ich mich im Studium 
mit komplexer Wechselstromrechnung beschäftigen durfte (@David: hast Du 
das ebenfalls in Deinem Studium/Ausbildung gehabt? Das mit 1/jwC bzw. 
jwL ... ). Erst danach habe ich wirklich verstanden, warum ein RC-Kreis 
dämpft, oder was Resonanz bedeutet oder welche Auswirkungen eine 
Induktivität in Zs.hang mit einem Kondensator hat.

Wenn Du es also ganz genau wissen willst, empfehle ich diese Seiten:
https://elektroniktutor.de/elektrophysik/zeiger.html
https://elektroniktutor.de/bauteilkunde/kondens.html

Wenn's Dir nicht so genau drauf ankommt, hier eine halbwegs 
"Laienkonforme" Erklärung:
https://rn-wissen.de/wiki/index.php/Abblockkondensator

Im ersten "Weiterführenden Weblink" gibt's die volle Theorie-Breitseite 
...
Im zweiten gibt's ein nettes YouTube-Video, was die Auswirkungen eines 
fehlenden 100nF Kondensators sehr eindrucksvoll zeigt.

Etwas anspruchsvoller sind dann schon diese Links hier:
http://www.g-qrp-dl.de/Projekte/bypass/bypass.pdf

Oder - wieder einmal supergenial - die Seite von Lothar Miller (er ist 
meiner Meinung nach einer der genialsten Elektroniker, die hier im Forum 
herumhüpfen - frage mich immer, wie man ein so universelles Wissen im 
Bereich FPGA und Elektronik allgemein auftürmen kann):
http://www.lothar-miller.de/s9y/categories/14-Entkopplung

Viele Grüße

Igel1

PS: hoffentlich habe ich mit meinem dröhnenden Schädel nicht zu viel 
Mist geschrieben.

von David D. (saturi)


Lesenswert?

Guten Abend,

vielen Dank für die Informationen, @Michael das war genau das was ich 
wissen wollte.

@Igel vielen Dank für die Zusammenstellung der Links. Diese Seite (ich 
spreche von den ersten Links) ist wirklich gut um das Wissen nochmal 
aufzufrischen.Ja ich hatte die komplexe Wechselstrom Lehre, allerdings 
im ersten bzw. zweiten Semester. Damals (vor 6 Jahren) hatte ich aber 
leider überhaupt keinen praktischen Bezug dazu. Beim durchlesen der 
Seiten kamen mir die Formeln aber noch sehr bekannt vor. Für morgen habe 
ich mir schon die nächsten Lese-Zeichen gesetzt. Jetzt Rückblickend 
macht alles so viel mehr Sinn :D...

Da noch keiner mit dem Morgenstern über meine Lötkünste hergefallen ist 
nehme ich entweder an, dass ihr noch keine Zeit hattet die Bilder zu 
betrachten oder mir keine groben Schnitzer unterlaufen sind (ist 
natürlich aus der Ferne nur schwer zu beurteilen).

Ich habe gerade eine neue Version vom Terminal hochgeladen. Mit vielen 
Bug-Fixes wodurch sich die Anzahl der Fehlermeldungen deutlich reduziert 
haben sollte. (Also nicht nur die Meldungen ^^)

Da ich die Probleme vom Read Device Settings ebenfalls beim Write Device 
Settings habe, würde es mich interessieren, ob die bei euch auch 
durchlaufen.

Wünsche euch einen schönen Abend.

Gruß David

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Prüfe nochmals Deine Levelshifterbeschaltung:
- 5V an HV ?
- 3,3V an LV ?
- Beide Seiten an GND angeschlossen ?
- Optimalerweise alle GND-Leitungen sternförmig am GND-Pol des 
Versorgungskondensators zusammenführen

Mehr fällt mir gerade auch nicht ein.
Aus den Fotos kann man die Verschaltung leider nicht genau 
zurückverfolgen - es wird zu vieles verdeckt und es wäre auch mit 
optimalen Fotos wahnsinnig aufwändig.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> - Beide Seiten an GND angeschlossen ?
Die üblichen Levelshifter mit MosFET und den 2 Widerständen brauche GND 
garnicht, es ist einfach nur durchverbunden, wenn überhaupt vorhanden.
Ich habe auch welche, wo es keinen GND gibt.

> - Optimalerweise alle GND-Leitungen sternförmig am GND-Pol des
> Versorgungskondensators zusammenführen
Wie Du schon schreibst optimalerweise. Allerdings sind mir bisher da bei 
dieser Art Schaltungen im AVR-Umfeld (nur digitale Komponenten, keine 
AD-Wandlung, kein Audio usw.), den relativ kurzen Leitungen (da zähle 
ich aich noch 10cm Dupontkabel dazu) und Frequenzen um 10MHz noch nie 
passiert.
Kontaktunsicherheiten speziell durch Dupontkabel, Litzen, wo Drähte 
abstanden und benachbarte Sachen berührten, Zinnbrücken, die man kaum 
sieht usw. dagegen öfter. Ich löten Lochrasterkram generell mit 0,4er 
Blankdraht und, wenn nötig ein Stück Gewebeschlauch, für die 
Spannungsversorgung.
Der Rest ist Warpdraht, eine Sorte zu finden, wo die Isolierung sich 
1-2mm sauber zurückzieht, wenn man die Lötspitze senkerecht an den 
abgeschnittenen Draht hält, ist mühsam, aber möglich. ;)
Die Sorte, wo Du mir das Bienchen aberkannt hast, ist leider eine, wo 
das nicht schön klappt...
Sein Problem wird sein, rauszufinden, wobei sich der Kram aufhängt.
Wenn man mit seinem Aufbau etwas "rumrandaliert" wenn der in Betrieb ist 
darf nichts aussetzen, sonst ist da Ursachenforschung angesagt...

Gruß aus Berlin
Michael

von David D. (saturi)


Angehängte Dateien:

Lesenswert?

Ein hoch auf den Händler und den fleißigen Paketboten!

Jetzt muss ich das Ding nur noch zum laufen bringen und dann schauen wir 
mal wo es klemmt

Aus Spaß ist auch ein stm32 dabei ;-) für die ganz ganz ganz weite 
Zukunft

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Ein hoch auf den Händler und den fleißigen Paketboten!
>
> Jetzt muss ich das Ding nur noch zum laufen bringen und dann schauen wir
> mal wo es klemmt

Bitte schreibe ein bisschen Doku dazu - wenn ich wieder gesund bin, 
möchte ich meine LA's ja auch ans Laufen bringen und könnte dann ggf. 
von Deinen Erfahrungen lernen.

> Aus Spaß ist auch ein stm32 dabei ;-) für die ganz ganz ganz weite
> Zukunft

Ah - der Mann kommt langsam zur Vernunft :-)

Konnte inzwischen Deinen Code aus GitHub in mein VS clonen und 
erfolgreich aus Laufen bringen - wegen Bettlage aber noch ohne 
angeschlossenen AVR. Der für Dich spannende Teil, fehlt also leider 
noch.

Habe gerade bemerkt, dass Dein Code mit Events vollgestopft ist und in 
meinem Tutorial das Thema "Events" nicht vorkam. So'n Pech - jetzt mit 
dem Düllekopp passt aktuell leider nicht viel in den Kopf außer das 
Event "schlafen".

Anyway - kommt Zeit, kommt Rat.

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

An Events habe ich mich sehr sehr lange auch nicht ran getraut (deshalb 
gibt es auch immernoch Altlasten in diesem Projekt, die mit einem Event 
wesentlich eleganter zu lösen wären. Folge Seiten haben mir sehr 
geholfen, die kann ich wirklich nur empfehlen:

https://www.youtube.com/watch?v=jQgwEsJISy0
(ja ein Video... Aber für den ersten Anlauf und den ersten "Kontakt" mit 
events wirklich sehr zu empfehelen)

http://www.hinzberg.net/csharp/csharp/csharp/threadevents.html
Hier die beiden Kapitel Threads u. Events und Threads u. Invoke
(Nach diesem Beispiel wirst du sie auch bei mir im Code finden)

und noch was über delegates:
https://www.tutorialspoint.com/csharp/csharp_delegates.htm

von David D. (saturi)


Lesenswert?

Soo noch kurz vor dem Schlafengehen den LA zum laufen gebracht... Da 
kann ich die Software Sigrok (bzw. PulseView) nur empfehlen. Das sieht 
auf den ersten Blick richtig gut aus und um Welten besser, als alles was 
ich bisher hatte:

hier die Anleitung:
https://sigrok.org/wiki/Windows

für den LA brauchen wir nur den PulseView. Im gesamten Sigrok paket ist 
aber die "zagdig.exe" drin, die man braucht um den LA mit dem Win-USB 
driver zu verknüpfen. Danach läuft es!


Dann kann ich mich morgen Abend endlich an die Fehlerursachenforschung 
machen. Auch wenn morgen erstmal ein langer Tag bevorsteht -.-


bis denne.

Gruß
David

von Andreas S. (igel1)


Lesenswert?

@David: Danke für die Links - so etwas hilft immer sehr.

Habe Delegates und Events inzwischen halbwegs kapiert (soweit mein Kopf 
das aktuell zulässt).

Habe nun erstmals in Deinen Code geguckt - fürchte, es wird ein Weilchen 
dauern, bis ich da durchblicke, denn es sind ja doch ein paar Zeilchen.

Immerhin habe ich C#-mäßig kaum Konstrukte entdeckt, die ich 
sprachenmäßig nicht verstanden habe. Die Tutorials scheinen besser 
angeschlagen zu haben, als die Medizin, die ich aktuell reinkomme - das 
macht schon mal Mut.

Jetzt kann ich mich der Programmlogik widmen, wobei mir ein paar 
grundsätzliche Worte von Dir, David, zur Funktionsweise sicherlich das 
Reverse-Engineering etwas vereinfachen könnten.

Beabsichtigst Du in den kommenden Tagen noch größere Änderungen am 
Terminal-Code? Sollte ich einen eigenen Branch in GitHub aufmachen, 
damit wir dann ggf. Codemerges machen können? Keine Ahnung, wie das in 
VS funktioniert ... Aber das ist auch erst einmal nur Prio2.

Viele Grüße

Igel1

PS: und Danke für die Erläuterungen zur LA-Inbetriebnahme!

von David D. (saturi)


Angehängte Dateien:

Lesenswert?

> Habe nun erstmals in Deinen Code geguckt - fürchte, es wird ein Weilchen
> dauern, bis ich da durchblicke, denn es sind ja doch ein paar Zeilchen.
Ja mittlerweile hat sich da was angehäuft.
Ich hoffe du hast schon das Form gefunden und kannst es im Ansicht 
designer sehen. dann kannst du einfach auf einen button doppelklicken 
und er führt dich zu dem Startpunkt und von da aus würde ich mich mit 
rechtsklick definition anzeigen am code entlanghangeln. Ich werde dir 
auch am Wochenende etwas mehr zusammenschreiben. erstmal würde ich sagen 
sind die beiden "Klassen" (im weitesten Sinne) OV7670_Device und 
Form_Terminal die wichtigsten in denen alles abläuft.

> Immerhin habe ich C#-mäßig kaum Konstrukte entdeckt, die ich
> sprachenmäßig nicht verstanden habe.

das ist gut, da ich ja auch kein "gelernter" Programmierer bin fehlt mir 
wahrscheinlich auch der ein oder andere Kniff mit dem es sich besser 
machen ließe. Aber wir sind ja zum Lernen hier ;-)

> Beabsichtigst Du in den kommenden Tagen noch größere Änderungen am
> Terminal-Code? Sollte ich einen eigenen Branch in GitHub aufmachen,
> damit wir dann ggf. Codemerges machen können? Keine Ahnung, wie das in
> VS funktioniert ... Aber das ist auch erst einmal nur Prio2.
Ja im Grunde halte ich das für eine Gute Idee, auch wenn ich das noch 
nie gemacht habe. Auch cool finde ich es, dass du Github anscheinend ins 
VS eingebunden hast, das werde ich mir mal anschauen. Da ich es ja 
ursprünglich nur für den uC code gedacht hatte, habe ich "Github 
Desktop" verwendet. Damit kann man dann einfach einen comit mit 
anschließendem Push ausführen. Aber das geht bestimmt auch aus dem VS.
Gute Besserung weiterhin.
-----------------------------------


Back to Topic:"Read Device Settings stoppt mitten drin"
habe jetz Tx,Rx,SIOC,SIOD (alles direkt am uC) am LA hängen. Folgende , 
angehängte Beobachtung:
rx kommt noch auf dem uC an (zumindest auf der rx Leitung) danach 
passiert nichts mehr, kein tx, kein SIOC, kein SIOD.
Damit gehe ich davon aus, dass das Problem keins ist, welches durch 
meine adapter Platine und die Lötkünste verbunden ist. Teilt ihr diese 
Ansicht?

Da ich das Problem auf beiden Uno-Boards habe, gehe ich weiterhin davon 
aus, dass es sich nicht um ein defektes Board handelt.

Bleiben zwei Möglichkeiten:
- Es liegt am Code... Warum um alles in der Welt funktioniert der dann 
bei euch?!

- Es scheint ein generelles Problem mit dem Uno zu geben.
Das wäre zu Überprüfen mit einem Adapter board für den Nano, dass ich 
mir am Wochenende basteln könnte.

Gruß
David


PS: dieser LA und die Software sind ein Traum!
ich kann mir sowohl die UART symbole als auch die I2C Symbole anzeigen 
lassen. (Für euch vlt. nichts neues) Aber ich schwebe auf Wolke 7 :D

: Bearbeitet durch User
von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

Habe gerade Terminal-Programm V0.12 mit meiner AVR-Codeversion (keine 
Ahnung, welche Version es war) zusammen kurz getestet:

- Read Device Settings funktioniert zuverlässig und stabil
- read register funktioniert zuverlässig und stabil
- write register funktioniert zuverlässig und stabil

Drücke dann nacheinander "Camera initialisieren", "get Camera", "sync 
Camera", "take Picture". Das Ergebnis siehst Du im Anhang.

Neue Terminal-Version sieht chic aus.
Folgende Probleme hatte ich:

- Die Tabelle "Device Settings" ist zu schmal - es geht Info verloren - 
siehe Bild im Anhang

- Gleiches gilt vermutlich für "Loaded Settings"

Viele Grüße

Igel1

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

David D. schrieb:

> Ich hoffe du hast schon das Form gefunden und kannst es im Ansicht
> designer sehen.

Yep - läuft.

> dann kannst du einfach auf einen button doppelklicken
> und er führt dich zu dem Startpunkt

Yep - klappt.

> und von da aus würde ich mich mit
> rechtsklick definition anzeigen am code entlanghangeln. Ich werde dir
> auch am Wochenende etwas mehr zusammenschreiben.

Au ja - das wäre klasse.

> erstmal würde ich sagen
> sind die beiden "Klassen" (im weitesten Sinne) OV7670_Device und
> Form_Terminal die wichtigsten in denen alles abläuft.

Das habe ich schon geblickt.

>
>> Immerhin habe ich C#-mäßig kaum Konstrukte entdeckt, die ich
>> sprachenmäßig nicht verstanden habe.
>
> das ist gut, da ich ja auch kein "gelernter" Programmierer bin fehlt mir
> wahrscheinlich auch der ein oder andere Kniff mit dem es sich besser
> machen ließe. Aber wir sind ja zum Lernen hier ;-)

Nur aus Neugierde: Hattest Du vorher schon C# programmiert?

>> Beabsichtigst Du in den kommenden Tagen noch größere Änderungen am
>> Terminal-Code? Sollte ich einen eigenen Branch in GitHub aufmachen,
>> damit wir dann ggf. Codemerges machen können? Keine Ahnung, wie das in
>> VS funktioniert ... Aber das ist auch erst einmal nur Prio2.
> Ja im Grunde halte ich das für eine Gute Idee, auch wenn ich das noch
> nie gemacht habe. Auch cool finde ich es, dass du Github anscheinend ins
> VS eingebunden hast, das werde ich mir mal anschauen.

Habe ich im "Team Explorer" gefunden:
Dort unter "Manage Connections" > Local Git Repo. > Clone

> Da ich es ja
> ursprünglich nur für den uC code gedacht hatte, habe ich "Github
> Desktop" verwendet.

Was ist "Github Desktop"?  Eine Einstellung bei Github oder eine 
Einstellung in VS?

> Damit kann man dann einfach einen comit mit
> anschließendem Push ausführen. Aber das geht bestimmt auch aus dem VS.
> Gute Besserung weiterhin.

Danke - heute Abend ist erstmals leichte Besserung zu spüren.
Klassische Männergrippe halt ...

> Back to Topic:"Read Device Settings stoppt mitten drin"
> habe jetz Tx,Rx,SIOC,SIOD (alles direkt am uC) am LA hängen. Folgende ,
> angehängte Beobachtung:
> rx kommt noch auf dem uC an (zumindest auf der rx Leitung) danach
> passiert nichts mehr, kein tx, kein SIOC, kein SIOD.

> Damit gehe ich davon aus, dass das Problem keins ist, welches durch
> meine adapter Platine und die Lötkünste verbunden ist. Teilt ihr diese
> Ansicht?

Aber Du hast doch geschrieben, "Read Device Settings stoppt mitten 
drin".
Dann muss doch rx beim AVR ankommen und tx einiges senden bevor die 
Sache stoppt, oder?

Bitte beschreibe die Dinge etwas genauer - ich kann das Problem mit 
Deiner Beschreibung leider nicht nachvollziehen.

> Da ich das Problem auf beiden Uno-Boards habe, gehe ich weiterhin davon
> aus, dass es sich nicht um ein defektes Board handelt.
>
> Bleiben zwei Möglichkeiten:
> - Es liegt am Code... Warum um alles in der Welt funktioniert der dann
> bei euch?!

Komisch.
Sollte Dein AVR-Code fritte sein?
Im Anhang findest Du denjenigen Code, der bei mir läuft.
Ein Verzweifelungsversuch ist's ja vielleicht wert:
Einfach mal einspielen und gucken, ob's läuft.

> - Es scheint ein generelles Problem mit dem Uno zu geben.
> Das wäre zu Überprüfen mit einem Adapter board für den Nano, dass ich
> mir am Wochenende basteln könnte.

Hmmm ...

Also: ich würde systematisch vorgehen und dabei DebugWire nutzen:

- Starte Dein AVR-Programm im Debug-Modus und setze Breakpoints
- Sende vom Terminal ein "read register" und schau dann per Debugging,
  was auf dem AVR passiert.
- Wenn Du dann parallel noch per LA mitschneidest, was auf rx, tx,
  SIOC, SIOD passiert, so musst Du das Problem mit 100%iger Wahr-
  scheinlichkeit herausbekommen können.

> PS: dieser LA und die Software sind ein Traum!
> ich kann mir sowohl die UART symbole als auch die I2C Symbole anzeigen
> lassen. (Für euch vlt. nichts neues) Aber ich schwebe auf Wolke 7 :D

Ah - das hört sich gut an und macht mich sehr neugierig.
Ich schwebe mit meinem Intronix-LA schon seit langem auf Wolke 140 (weil 
er halt die 20-fache Bandbreite des China-Clones hat: 500MHz ...).
Ich erhoffe mir einzig und allein vom China-LA, dass ich damit beliebig 
lange Serielle oder I2C-Übertragungen angucken kann - das fehlt bei 
meinem Intronix leider.

Viele Grüße

Igel1

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> PS: dieser LA und die Software sind ein Traum!
> ich kann mir sowohl die UART symbole als auch die I2C Symbole anzeigen
> lassen. (Für euch vlt. nichts neues) Aber ich schwebe auf Wolke 7 :D

Auch wenn ich im Moment nur mitlese:
Kann man mit der Software die decodierten I2C-Daten irgendwie sinnvoll 
speichern? Ich will die Daten, die an einen SI4735 geschickt werden, 
mitloggen. Normalerweise Adresse, Kommando und dann 3-8 Datenbytes. Das 
müßte praktisch bis zum I2C Stop jeweis in eine Zeile geschrieben 
werden.
Eben so, das ich es extern passen formatieren kann.

Ist völlig OT, aber ich komme da im Moment sowieso nur theoretisch dazu.
Ja, Rentner haben niemals Zeit... ;-)

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

@Michael die Antwort liefer ich dir heute Abend.

@Igel, meine Schilderung bezieht sich auf das letzte abgefragte Register 
(vgl. Bild) davor läuft es so wie ich es mir vorstelle

von David D. (saturi)


Lesenswert?

> Nur aus Neugierde: Hattest Du vorher schon C# programmiert?
Nein, nicht mal in Informatik behandelt. Alles learning by doing... mit 
vielen Fehlgriffen :D

> Was ist "Github Desktop"?  Eine Einstellung bei Github oder eine
> Einstellung in VS?
Weder noch, ein kostenloses Programm, mit dem man quasi ein Github 
projekt in einen Ordner clonen kann (ich denke so wie in VS) und dann 
eben von dort aus pull requests geben kann.

> Aber Du hast doch geschrieben, "Read Device Settings stoppt mitten
> drin".
> Dann muss doch rx beim AVR ankommen und tx einiges senden bevor die
> Sache stoppt, oder?
wie heute mittag schon gesagt, es wird einiges gesendet und empfangen 
und irgendwann reißt der informationsfluss ab. Und das ist dann immer 
nach einem (richtigen) Rx also es kommen die richtigen daten noch auf 
dem Rx Pin des uC an.

> Komisch.
> Sollte Dein AVR-Code fritte sein?
> Im Anhang findest Du denjenigen Code, der bei mir läuft.
> Ein Verzweifelungsversuch ist's ja vielleicht wert:
> Einfach mal einspielen und gucken, ob's läuft.

Danke, habe ich getan (allerdings meine Projektdatei und den Ordner mit 
den Source-Dateien durch deinen ersetzt. Ergebniss ist das gleiche wie 
vorher.... Jetzt bin ich wirklich ratlos...

> Also: ich würde systematisch vorgehen und dabei DebugWire nutzen:

Tolle Idee aber wie soll ich bei einem sporadischen Fehler Debug-Wire 
nutzen? Wenn es erst beim 138sten mal auftritt klick ich mir einen 
Wolf?! das halte ich für nicht machbar. Oder hast du da einen Trick auf 
Lager?

> Ah - das hört sich gut an und macht mich sehr neugierig.
> Ich schwebe mit meinem Intronix-LA schon seit langem auf Wolke 140 (weil
> er halt die 20-fache Bandbreite des China-Clones hat: 500MHz ...).
> Ich erhoffe mir einzig und allein vom China-LA, dass ich damit beliebig
> lange Serielle oder I2C-Übertragungen angucken kann - das fehlt bei
> meinem Intronix leider.
Naja nicht beliebig aber bis zu 1T Samples kann man aufzeichnen. Dann 
hängt es von deiner Sample Frequenz die du einstellst ab, wie lange 
aufgezeichnet wird. Aber es gibt sogar ne Trigger funktion ab der dann 
gestartet wird.

Ich hoffe ihr könnt mir helfen :( :/ und habt noch ne coole idee bevor 
ich mich ans löten mache...


@Michael, es gibt mehrere export möglichkeiten: rechtsklick auf die i2C 
Zeile eröffnet nochmal weitere Möglichkeiten, hier ein Beispiel zu einer 
der Möglichkeiten:

4007-4007 I²C: Address/Data: Start
6319-6620 I²C: Address/Data: Write
4209-6319 I²C: Address/Data: Address write: 21
6620-6921 I²C: Address/Data: ACK
7023-9434 I²C: Address/Data: Data write: 00
9434-9735 I²C: Address/Data: ACK
9935-9935 I²C: Address/Data: Stop


Gruß

David

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
>> Also: ich würde systematisch vorgehen und dabei DebugWire nutzen:
>
> Tolle Idee aber wie soll ich bei einem sporadischen Fehler Debug-Wire
> nutzen? Wenn es erst beim 138sten mal auftritt klick ich mir einen
> Wolf?! das halte ich für nicht machbar. Oder hast du da einen Trick auf
> Lager?

Der Fehler ist wirklich absolut sporadisch/beliebig?

Leider fehlt noch die exakte Beschreibung, wann der Fehler auftritt.
Ich mache mal ein Beispiel, was ich meine:

- AVR per USB bestromen
- OV7670-Terminal-Prog starten
- Button "verbinden" klicken
- Button "Read Device Settings" klicken ... läuft durch ...
- Denselben Button nochmals drücken ... bricht bei Register XYZ ab ???

Ist das der Ablauf?

Viele Grüße

Igel1


PS: sollte das wirklich Dein erstes C#-Programm sein, so hast Du schon 
ziemlich viele Stilmittel angewendet (soweit ich das überhaupt 
beurteilen kann) - Junge, Junge: Respekt, Respekt.

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

Andreas S. schrieb:
> - AVR per USB bestromen
> - OV7670-Terminal-Prog starten
> - Button "verbinden" klicken
> - Button "Read Device Settings" klicken ... läuft durch ...
> - Denselben Button nochmals drücken ... bricht bei Register XYZ ab ???
>
> Ist das der Ablauf?

... sollte das tatsächlich der Ablauf sein, so gibt es eine gute (und 
gleichzeitig auch schlechte) Nachricht:

Ich konnte Dein Problem soeben reproduzieren:

Auch bei mir bricht Deine OV7670-Terminal Version 0.12 beim Einlesen der 
Register per "Read Device Settings"-Button sporadisch (ja sogar häufig) 
ab.

Ich scheine also bei meinem letzten vor-vorigen Posting, als ich Dir 
"funktioniert zuverlässig und stabil" bescheinigt habe, entweder nicht 
vernünftig getestet zu haben (zu meiner Entschuldigung: da brummte mein 
Schädel auch noch deutlich mehr als aktuell) oder ich hatte einfach 
Glück.

Aktuell kann ich das Problem aber sicher reproduzieren.
Bei Version 0.10 tritt es übrigens viel, viel seltener auf - aber auch 
dort tritt es auf.

Auch bei mir scheint das Terminal noch korrekt einen letzten 
Registerwert anzufragen, aber der AVR antwortet nicht mehr - gleiches 
Fehlerbild wie bei Dir (siehe auch Bild im Anhang).


Was ich dabei nicht verstehe: warum passiert das bei Version 0.12 viel 
häufiger als bei Version 0.10, wenn's laut LA doch eigentlich am AVR 
liegt, der nicht mehr antwortet ??

Immerhin: Du weisst jetzt, dass Du mit Deinem Problem nicht allein bist 
und es scheinbar nicht an Deiner Verdrahtung liegt.

Viele Grüße

Igel1

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,

@David: Danke fürs Nachschauen, sieht ja ganz gut aus. Ich werden mal 
heute Abend meinen Bekannten fragen, ob er Sigrok bzw. PulseView 
benutzt.

Ansonsten: ich werde morgen mal Deinen aktuellen Kram aufspielen und 
schauen, ob ich den Erkenntnissen von Andreas was möglichst sinnvolles 
hinzufügen kann.

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

> Was ich dabei nicht verstehe: warum passiert das bei Version 0.12 viel
> häufiger als bei Version 0.10, wenn's laut LA doch eigentlich am AVR
> liegt, der nicht mehr antwortet ??
Das verstehe ich auch nicht. vielleicht Zufall?

Du hast aber seit dem letzten mal (also als es bei dir und bei Michael 
zuverlässig lief so an die 10-30 mal wie ihr mir versichert habt, nicht 
nochmal ein anderes AVR Programm geflashed?

> Immerhin: Du weisst jetzt, dass Du mit Deinem Problem nicht allein bist
> und es scheinbar nicht an Deiner Verdrahtung liegt.

ja... geteiltes Leid ist halbes Leid...

Aber ich weiß nicht wo ich ansetzen soll?
Ich bräuchte sowas wie einen reverse debugger :D mit dem ich schritte 
rückwärts gehen kann...

von Dieter F. (Gast)


Lesenswert?

Mahlzeit :-)

Du solltest Deine serielle Kommunikation mal auf den Prüfstand stellen.
1
while(((Befehl[i+j-2] != (char)0x0D) || (Befehl[i-1] != (char)0x0A))&&(i<10));        // solange kein CR+LF erkannt wird
2
    
3
...
4
5
if(Befehl[0]==0x0A)    //new Line from Buffer requested by the Terminal
6
    {
7
      *Programmstatus = 0x0A ;
8
    }

Es ist nicht besonders geschickt, "Befehle" mit Linefeed, CR etc. zu 
mischen. Reduziere Deine Main mal auf die reine Reaktion auf Befehle 
ohne die Kamera ins Spiel zu bringen. Also immer die erwarteten 
(O.K.)-Werte zurückgeben (bei Register lesen z.B. die Registernummer als 
Rückgabewert etc.) und je nach Bild-Lese-Befehl verschiedene Bit-Muster 
(0x11001100, 0x10101010, 0x00110011).

Das wird sicher interessant für Dich :-)

Ich werde am Wochenende mal wieder "mitspielen" - habe eine Kamera mit 
Fifo bekommen und werde die auch einsetzen.

VG
Dieter

von Dieter F. (Gast)


Lesenswert?

Hi,

wenn ich schon mal am schauen bin ...
1
   UCSR0C = 0b00001110;
2
             ^^|||||| USART Mode Select
3
               ^^|||| Parity Mode Bits
4
                 ^||| STOP Bit Select          -> damit setzt Du 2 Stop-Bits
5
                  ^^| Character Size 11 -> 8Bit
6
                    ^ Clock Polarity

... oder habe ich Tomaten auf den Augen?

VG

von Andreas S. (igel1)


Lesenswert?

Dieter F. schrieb:
> ... oder habe ich Tomaten auf den Augen?

Jein:
Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)"

... und bitte auch das darauf folgende Posting von Michael lesen.

von Dieter F. (Gast)


Angehängte Dateien:

Lesenswert?

Nochmal hi,

für heute die letzte Baustelle - siehe Hardcopy.

Was passiert bei den längeren Strings?

VG

von Dieter F. (Gast)


Lesenswert?

Andreas S. schrieb:
> ... und bitte auch das darauf folgende Posting von Michael lesen.

Und warum testet ihr dann damit weiter, statt es zu korrigieren?

Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)"


Ich bin kein U(S)ART-Spezialist, aber das wird schon seine Berechtigung 
haben:

https://electronics.stackexchange.com/questions/335695/why-the-start-bit-and-the-stop-bits-are-necessary

Keine Ahnung, wann und wie ein "Framing-Error" erkannt wird - aber ich 
versuche schon, gleiche Einstellungen auf beiden Seiten herzustellen.

Ob und wie sich da die akzeptierte Fehlerrate von 2,1 % bei der 
Einstellung der Baudrate (bei 16 MHz Takt) kumuliert ist mir auch nicht 
bekannt.

von David D. (saturi)


Lesenswert?

Dieter F. schrieb:
> Nochmal hi,
>
> für heute die letzte Baustelle - siehe Hardcopy.
>
> Was passiert bei den längeren Strings?
>
> VG

Guten Abend Dieter!

schön von dir zu hören, schön, dass du jetzt Auch eine Kamera mit Fifo 
zum "mitspielen" hast :)

Und noch schöner, dass du schon fleißig im Code gewühlt hast.

dein Einwandt zum Uart senden ist berechtigt!
Allerdings tritt dieser Fall nur auf, wenn es einen Fehler bei der 
Kommunikation mit dem SCCB gibt. Soweit kommen wir aber garnicht.

Das das Problem beim Bildempfang nicht auftritt stimmt. Also wird das 
Problem wie von dir erkannt vielleicht in meiner wahrscheinlich in der 
Befehlsdetektion liegen. Was genau meinst du mit:"Es ist nicht besonders 
geschickt, "Befehle" mit Linefeed, CR etc. zu
mischen." Wo liegt das Problem oder wie würdest du es geschickter lösen?

von David D. (saturi)


Lesenswert?

Ähmm ich stehe gerade mächtig auf dem Schlauch... Hier müsste mich mal 
jemand runter schubsen:
In unserer UART_init:
1
void UART0_init (void)
2
{
3
  TX_DDR |=(1<<TX_Pin);    //definiere TX Pin als Ausgang
4
  RX_DDR &=~(1<<RX_Pin);    //definiere RX Pin als Eingang
5
6
7
  UBRR0H = 0b00000000;      // Setzt Baudrate
8
  //UBRR0L = 0b00110011;      // dezimal : 103->9600; dez 68->14400;dez 51->19200; dez 8 ->115200 
9
  //UBRR0L = 0b00011001;  //38400
10
  //UBRR0L = 0b00000011;  //230400
11
  //UBRR0L = 0b11001111;  //9600
12
  UBRR0L = 0b00010000;  //115200
13
  UCSR0A = 0b00000010;
14
15
  UCSR0A |=0b00000000;
16
        //   ^---U2X  
17
...

Laut Datenblatt und Kommentar ist bei 16.0 MHz bei UBRR0n = 8 die 
Baudrate 115200.

Das läuft ja auch schon seit Tagen/Wochen auf dieser Baudrate. im Code 
ist aber UBRR0L auf 16 und nicht auf 8? Wie kann das sein? ebenso die 
anderen Baudraten... sind ebenfalls "verschoben" ich habe das gefühl 
gerade völlig verrückt zu sein? :O
Ddas gibts doch nicht. WO ist mein Denkfehler?


EDIT: hat sich erledigt.... das U2X bit ist ja gesetzt... warum zum 
Teufel wird dann nochmal mit dem gleichen Register verodert? :D... das 
nehm ich jetzt erstmal raus...

: Bearbeitet durch User
von Dieter F. (Gast)


Lesenswert?

David D. schrieb:
> WO ist mein Denkfehler?

Alles gut - ich hatte nicht gesehen, dass

  UCSR0A = 0b00000010;
  UCSR0A |=0b00000000;

doch auf 0b00000010 und damit U2X auf 1 steht. Daher habe ich den 
Kommentar wieder zurück genommen (nachdem Du zitiert hast :-) )

David D. schrieb:
> warum zum
> Teufel wird dann nochmal mit dem gleichen Register verodert? :D... das
> nehm ich jetzt erstmal raus...

Genau das hat mich auf den falschen Weg geführt ...



David D. schrieb:
> Was genau meinst du mit:"Es ist nicht besonders
> geschickt, "Befehle" mit Linefeed, CR etc. zu
> mischen." Wo liegt das Problem oder wie würdest du es geschickter lösen?

Wenn ein Befehl 0x0A lautet und LF ist auch 0x0A (so ist es nunmal), 
dann kneift sich das.

https://de.wikipedia.org/wiki/Zeilenumbruch

Ich würde generell alles unter 0x20 nicht als "Befehl" verwenden (bei 
einer seriellen Übertragung).

von David D. (saturi)


Lesenswert?

> Wenn ein Befehl 0x0A lautet und LF ist auch 0x0A (so ist es nunmal),
> dann kneift sich das.
Ja verstehe ich. Daher verwende ich zwei "Stop-Zeichen" CR+LF um genau 
diesen Fall ausschließen zu können.

(Wobei ausschließen natürlich auch nicht stimmt, wenn ich in Register 
0x0C 0x0A schreiben würde... hmm da sollten wir nochmal drüber 
nachdenken...


> Ich würde generell alles unter 0x20 nicht als "Befehl" verwenden (bei
> einer seriellen Übertragung).
ja verstanden... aber wie ist es mit Werten die zwischen 0 und 255 
liegen können? Wie würdest du die dann übertragen?

von Dieter F. (Gast)


Lesenswert?

David D. schrieb:
> aber wie ist es mit Werten die zwischen 0 und 255
> liegen können? Wie würdest du die dann übertragen?

Bei den Werten erwartest Du genau x Werte bis zum Ende der Übertragung. 
Die überträgst Du binär und zählst mit.

Bei den Befehlen erwartest Du (in Deinem Programm) nach jedem Befehl ein 
LF (0x0A) und CR (0x0C). Wenn ein Befehl 0x0A lautet und Du 0x0A als LF 
abfragst um das Ende eines Befehls zu erkennen, dann kneift sich das 
natürlich, weil dann 0x0A nicht mehr als Befehl erkannt werden kann.

Um das unterscheiden zu können musst Du ein Protokoll "vereinbaren" (was 
Du ja auch irgendwie gemacht hast - nur nicht ganz ausreichend). Das 
muss eindeutig sein. Dazu gibt es verschiedene Ansätze (da kennen sich 
andere besser aus ...) z.B.

https://cache.industry.siemens.com/dl/files/253/24178253/att_101236/v1/uss_24178253_spez_00.pdf

von David D. (saturi)


Lesenswert?

> Bei den Befehlen erwartest Du (in Deinem Programm) nach jedem Befehl ein
> LF (0x0A) und CR (0x0C). Wenn ein Befehl 0x0A lautet und Du 0x0A als LF
> abfragst um das Ende eines Befehls zu erkennen, dann kneift sich das
> natürlich, weil dann 0x0A nicht mehr als Befehl erkannt werden kann.


Hmmm... das werde ich mir jetzt einmal durchlesen.

Aber bist du sicher? also um diese "Feinheit" klar zu stellen ich warte 
zuerst auf 0x0D und dann auf 0x0Aund nur wenn beide aufeinander folgen 
wird die Zeichenfolge als solche erkannt. kommt nur ein 0x0D oder nur 
ein 0x0A passiert nichts, das Zeichen geht auch nicht verloren. 
Zumindest sollte das so ablaufen. Wenn ich hier einen Fehler habe, mach 
mich bitte darauf aufmerksam!

Danke :)

David

von Dieter F. (Gast)


Lesenswert?

David D. schrieb:
> ich warte
> zuerst auf 0x0D und dann auf 0x0A

Nö, auf beides (ODER) - wenn Du es so "vereinbart hast". Wobei auch das 
wieder unschön ist, weil eigentlich die "Folge" LF und CR vereinbart 
ist.
1
while(((Befehl[i+j-2] != (char)0x0D) || (Befehl[i-1] != (char)0x0A))&&(i<10));

Dein ODER sagt, dass Du bei einem 0x0A ein Zeilenende (und KEINEN 
Befehl) oder ein 0x0D (auch kein Befehl) erkannt hast und damit auch 
KEINEN gleichlautenden Befehl abarbeiten wirst. Dein "i+j-2" vs. "i-1" 
entwirrst Du bitte selbst :-)

von David D. (saturi)


Lesenswert?

Da fällst du glaube ich über den selben Fallstrick wie einst Igel:


David D. schrieb:
>>//igel1:  Hier passt der Kommentar nicht zum Code: es wird nicht
>>//        auf "CR UND LF" geprüft, sondern auf "CR ODER LF".
> Naja, nach meiner Auslegung ist beides richtig: Ich prüfe auf CR und LF:
> CR&CL = !!(CR&&CL) = !(!CR||!CL)  -->Da wir aber solange in der While
> schleife bleiben wollen, wie diese Bedingung nicht erfüllt ist, eine
> weiter Verneinung: !!(!CR||!CL) = (!CR||!CL) --> siehe code
> }while(((Befehl[i+j-2] != (char)0x0D) || (Befehl[i-1] !=
> (char)0x0A))&&(i<10));        // solange kein CR+LF erkannt wird

stimmst du mir da zu?

von Dieter F. (Gast)


Lesenswert?

David D. schrieb:
> stimmst du mir da zu?

Nein.

Befehl: 0x01 0x0D 0x0A

I     J     I+J-2     I-1     Befehl[i+j-2]  Befehl[i-1]

1     1      0        0       0x01           0x01
2     0      0        1       0x01           0x0D
3     0      1        2       0x0D           0x0A
4

Bei I = 3 greift die Bedingung "Befehl[i+j-2] != (char)0x0D" und es ist 
Schluss. "Befehl[i-1] != (char)0x0A" wird gar nicht mehr ausgewertet, 
weil der erste Teil der kombinierten ODER-Verknüpfung bereits wahr ist.

Das kannst Du auch schön im LSS-File im generierten Assembler-Code 
nachlesen.

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Andreas S. schrieb:
>> - AVR per USB bestromen
>> - OV7670-Terminal-Prog starten
>> - Button "verbinden" klicken
>> - Button "Read Device Settings" klicken ... läuft durch ...
>> - Denselben Button nochmals drücken ... bricht bei Register XYZ ab ???
>>
>> Ist das der Ablauf?
>
> ... sollte das tatsächlich der Ablauf sein, so gibt es eine gute (und
> gleichzeitig auch schlechte) Nachricht:
>
> Ich konnte Dein Problem soeben reproduzieren:
>
> Auch bei mir bricht Deine OV7670-Terminal Version 0.12 beim Einlesen der
> Register per "Read Device Settings"-Button sporadisch (ja sogar häufig)
> ab.

Ich nicht, wie oft muß ich da raufklicken? Bin jetzt vermutlich beom 20. 
Durchlauf, alles ok...
Aktueller Kram von github auf dem AVR und Terminal 0.12

Und nun?

Dieter F. schrieb:
> Befehl: 0x01 0x0D 0x0A

Nicht in den Source reingeschaut, nur getestet: 01 0a 0d 0a, also lesen 
Register 0d - ok.
02 0d 0a 0d 0a, also 0d mit 0a beschreiben - ok.
Auch alle anderen Kombinationen daraus werden ausgeführt und 
beantwortet.
Register 0a mit 0d beschreiben klappt natürlich nicht, ist die PID und 
read only.

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Dieter F. (Gast)


Lesenswert?

Michael U. schrieb:
> 02 0d 0a 0d 0a, also 0d mit 0a beschreiben - ok.
> Auch alle anderen Kombinationen daraus werden ausgeführt und
> beantwortet.

Dann probiere doch mal Register 0x0D mit 0x0D zu beschreiben

0x02 0x0D 0x0D 0x0D 0x0A :-)

von David D. (saturi)


Lesenswert?

Dieter F. schrieb:

> Bei I = 3 greift die Bedingung "Befehl[i+j-2] != (char)0x0D" und es ist
> Schluss. "Befehl[i-1] != (char)0x0A" wird gar nicht mehr ausgewertet,
> weil der erste Teil der kombinierten ODER-Verknüpfung bereits wahr ist.

hmm das verstehe ich nicht? Deine tabellarische Aufschlüsselung 
entspricht erstmal meinem Gedankengang und damit kann ich auch mitgehen.
ABER: Bei I=3 greift keine der beiden Bedingungen und deswegen wird aus 
der whileschleife ausgestiegen. Genau das ist ja der Clou an der 
Oder-Verknüpfung. Ich bleibe solange in der Schleifen, bis beide 
bedingungen nicht mehr erfüllt sind.

In diesem Beispiel steige ich trotzem bei I=3 aus, aber nur weil die 
zweite Bedingung "Befehl[i-1] != (char)0x0A" auch unwahr ist:

I     J     I+J-2     I-1     Befehl[i+j-2](!= 0x0D)  Befehl[i-1](!= 
0x0A)

1     1      0        0       0x01(WAHR)               0x01(WAHR)
2     0      0        1       0x01(WAHR)               0x0D(WAHR)
3     0      1        2       0x0D(FALSE)              0x0A(FALSE)

aus der While-Schleife wird nur ausgestiegen, wenn beide Bedingungen 
False sind. (Sie sind ja oder verknüpft) sonst erfüllt eines die 
Bedingung und die While Schleife läuft freudig weiter.

Stimmst du mir jetzt zu? :D Sonst habe ich wohl noch nicht verstanden wo 
du das Problem siehst.

Es ist allerdings richtig, was Michael auch schon getestet hat, dass 
wenn die Daten innerhalb des Befehls(oder der Datenbytes) 0x0D 0x0A 
nacheinander sind, wird fälschlicherweise ein BefehlsabschlussSignal 
erkannt. (Gilt es für die Zukunft zu umgehen)

> Das kannst Du auch schön im LSS-File im generierten Assembler-Code
> nachlesen.
Das weiß ich leider nicht wie funktioniert.

von David D. (saturi)


Lesenswert?

> Dann probiere doch mal Register 0x0D mit 0x0D zu beschreiben
>
> 0x02 0x0D 0x0D 0x0D 0x0A :-)

Habe ich und funktioniert. Obwohl es sich dabei um reserved Bits 
handelt, deren Reaktion nich immer absehbar ist.


Gruß
David

von Dieter F. (Gast)


Lesenswert?

David D. schrieb:
> aus der While-Schleife wird nur ausgestiegen, wenn beide Bedingungen
> False sind. (Sie sind ja oder verknüpft)

Sobald EINE der Nicht-Bedingungen zutrifft wird ausgestiegen - weil sie 
ODER-verknüpft sind.
1
    while(((Befehl[i+j-2] != (char)0x0D) || (Befehl[i-1] != (char)0x0A))&&(i<10));        // solange kein CR+LF erkannt wird
2
 51c:  eb 85         ldd  r30, Y+11  ; 0x0b
3
 51e:  fc 85         ldd  r31, Y+12  ; 0x0c
4
 520:  8d 85         ldd  r24, Y+13  ; 0x0d
5
 522:  9e 85         ldd  r25, Y+14  ; 0x0e
6
 524:  a1 e0         ldi  r26, 0x01  ; 1
7
 526:  b0 e0         ldi  r27, 0x00  ; 0
8
 528:  ac 0f         add  r26, r28
9
 52a:  bd 1f         adc  r27, r29
10
 52c:  ea 0f         add  r30, r26
11
 52e:  fb 1f         adc  r31, r27
12
 530:  e8 0f         add  r30, r24
13
 532:  f9 1f         adc  r31, r25
14
 534:  32 97         sbiw  r30, 0x02  ; 2
15
 536:  80 81         ld  r24, Z
16
 538:  8d 30         cpi  r24, 0x0D  ; Wenn 0x0D erkannt wird wird 0x0A nicht mehr verprobt
17
                                       Es geht dann direkt zum Check auf kleiner 10
18
 53a:  39 f4         brne  .+14       ; 0x54a <UART0_rx_work+0xa2>
19
 53c:  eb 85         ldd  r30, Y+11  ; 0x0b
20
 53e:  fc 85         ldd  r31, Y+12  ; 0x0c
21
 540:  ec 0f         add  r30, r28
22
 542:  fd 1f         adc  r31, r29
23
 544:  80 81         ld  r24, Z
24
 546:  8a 30         cpi  r24, 0x0A  ; 10
25
 548:  21 f0         breq  .+8        ; 0x552 <UART0_rx_work+0xaa>
26
 54a:  8b 85         ldd  r24, Y+11  ; 0x0b
27
 54c:  9c 85         ldd  r25, Y+12  ; 0x0c
28
 54e:  0a 97         sbiw  r24, 0x0a  ; 10
29
 550:  64 f2         brlt  .-104      ; 0x4ea <UART0_rx_work+0x42>


David D. schrieb:
> Habe ich und funktioniert.

Ja, weil Du (wie ich zu spät gesehen habe) damit ja zufällig die 
korrekte Folge schon im Speicher hast - obwohl Du den Terminator (0x0D 
und 0x0A) noch gar nicht gelesen hast und auch nie lesen wirst, weil ja 
0x0D schon erkannt worden ist.

von David D. (saturi)


Lesenswert?

Michael U. schrieb:
> Ich nicht, wie oft muß ich da raufklicken? Bin jetzt vermutlich beom 20.
> Durchlauf, alles ok...
> Aktueller Kram von github auf dem AVR und Terminal 0.12
>
> Und nun?

Das gibts doch nicht. ich steck die Kamera ein, verbinde die Kamera 
8Datenbits 1 stoppbit, parity none handshake none. und spätestens beim 
dritten durchlauf von Read Device Settings bleibts hängen. (meistens 
schon beim 1. oder 2.)

von Dieter F. (Gast)


Lesenswert?

David D. schrieb:
> spätestens beim
> dritten durchlauf von Read Device Settings bleibts hängen. (meistens
> schon beim 1. oder 2.)

Willkommen im Club :-(

von David D. (saturi)


Lesenswert?

Dieter F. schrieb:
>Sobald EINE der Nicht-Bedingungen zutrifft wird ausgestiegen - weil sie
>ODER-verknüpft sind.

Das sehe ich anders:
in einer while schleife wird solange verweilt, bis die Bedingung falsch 
ist:
1
while(true); //Endlosschleife. Da sind wir uns einig denke ich.
2
while(true || false) //Endlosschleife, weil die Bedingung (true||false) immer true ist.
3
4
I=0;
5
while((true||false)&&(i<10)){
6
i++
7
}//10 Schleifen Durchläufe, weil die erste Bedingung true ist. Wenn jetzt der Assambler (oder welcher Baustein auch immmer dafür verantwortlich ist) feststellt dass bei der ersten oder Bedingung der 1. parameter schon true ist, brauche ich die restlichen garnicht mehr prüfen (weil mit true verodert immer true ist) und springe direkt zum nächsten && verknüpften teil.



>>Wenn 0x0D erkannt wird wird 0x0A nicht mehr verprobt.Es geht dann direkt >>zum 
Check auf kleiner 10

Exakt, habe ich versucht oben zu beschreiben.
Ich hoffe ich konnte mich verständlich ausdrücken :)

Sind wir dann JETZT einer Meinung? :D Oder kannst du mich doch noch von 
einem Fehler überzeugen :)

Gruß und vielen Dank!

 David

von Michael U. (amiga)


Lesenswert?

Hallo,

ich habe da jetzt kurz über Deinen Ausschitt des ASM-Listings geschaut 
ohne mir alles zusammenzusuchen.
while(((Befehl[i+j-2] != (char)0x0D) || (Befehl[i-1] != 
(char)0x0A))&&(i<10));

Was ist hier j?
Wenn er auf die letzten Bytes im Buffer auf 0x0D 0x0A prüfen will, hätte 
ich mir jetzt ein simples
while(((Befehl[i-2] != (char)0x0D) && (Befehl[i-1] != (char)0x0A)) && 
(i<10));
vorgestellt.
Vielleicht komme ich nachher dazu, mir das mal selber genauer 
anzuschauen.

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Ich kann leider den Assambler Code nicht lesen. vielleicht würde ich 
sonst verstehen, auf was du mich aufmerksam machen möchtest.

von David D. (saturi)


Lesenswert?

Michael U. schrieb:

> Was ist hier j?
> Wenn er auf die letzten Bytes im Buffer auf 0x0D 0x0A prüfen will, hätte
> ich mir jetzt ein simples
> while(((Befehl[i-2] != (char)0x0D) && (Befehl[i-1] != (char)0x0A)) &&
> (i<10));
> vorgestellt.
genau das ist es auch, allerdings kommst du jetzt an ein Problem, wenn 
du gerade bei Befehl[0] bist, weil Befehl[0-2] zu einem Fehler führt. 
Daher gibt es j als "künstlichen" Zähler, der i für die ersten beiden 
Befehle beeinflusst.
Es mag sein, dass es da eine bessere Art gibt, das zu Umgehen aber so 
hatte ich es mir ganz am Anfang mal überlegt.

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> Es mag sein, dass es da eine bessere Art gibt, das zu Umgehen aber so
> hatte ich es mir ganz am Anfang mal überlegt.

Sieht an dieser Stelle kompliziert aus und was kompliziert aussieht, ist 
meist keine gute Lösung.
Ok, muß ich mir heute Nachmittag mal in Ruhe anschauen.
Wenn i Dein Zeiger auf den Buffer ist und die Auswertung erst nach 
mindestens 3 Zeichen beginnen soll weil es 1 Byte Kommandos ohne 
Parameter nicht gibt, warum dann nicht einfach einen Vergleich auf i > 2 
mit in die Abfrage?

Gruß aus Berlin
Michael

Beitrag #5807520 wurde von einem Moderator gelöscht.
von Dieter F. (Gast)


Lesenswert?

David D. schrieb:
> Sind wir dann JETZT einer Meinung?

Ja.

Ich werde mal die UART-Routinen ersetzen und schauen, ob es dann 
stabiler wird.

von David D. (saturi)


Lesenswert?

Dieter F. schrieb:
> David D. schrieb:
>> Sind wir dann JETZT einer Meinung?
>
> Ja.
>
> Ich werde mal die UART-Routinen ersetzen und schauen, ob es dann
> stabiler wird.

Sehr gut :) und vielen Dank für das Sparring :) das hilft immer bei der 
Verbesserung. Du hattest die Lösung ja schon mit dem gelöschten Wiki 
Beitrag geschickt ;-)

Jetzt müssen wir den Fehler aber wo anders suchen

von Dieter F. (Gast)


Lesenswert?

David D. schrieb:
> Jetzt müssen wir den Fehler aber wo anders suchen

So - die serielle Kommunikation funktioniert jetzt zuverlässig. Ich habe 
Peter Danneggers Routinen mit Ringpuffer eingebaut und bei 76.800 und 
250.000 Baud funktioniert alles tadellos (mit Dummy-Werten). Bei 115.200 
Baud habe ich jede Menge Fehler und nichts geht richtig (habe ein 
SSD1306 LCD drangehängt und mir die übertragenen Bytes mal angeschaut). 
Mit dem LA habe ich immer nur gesehen, dass es nicht weiter ging - 
vielleicht habe ich da noch Schwächen in der Bedienung :-/

Die Fehlerrate ist vermutlich schlicht zu hoch - das hat ggf. nicht mal 
etwas mit Davids Routinen zu tun (rückbauen werde ich aber jetzt nicht 
mehr). Warum das bei Michael ohne Probleme funktioniert verstehe ich 
nicht - macht aber nichts. Hauptsache das Problem ist erstmal weg.

Nachher werde ich die Kamera mal anstecken und weiter schauen :-)

von Dieter F. (Gast)


Angehängte Dateien:

Lesenswert?

Na ja - SCCB scheint auch noch zu haken.

Register schreiben funktioniert erst im 2. Ansatz, Register lesen bringt 
nich zuverlässig identische Werte.

Ich muss dazu schreiben, dass ich ohne Level-Shifter arbeite. Lt. 
Datenblatt V 1.01 für den AL422B Punkt 8.2 "In either case the AL422B is 
5V or 3.3V I/O tolerant." sollte das gehen.

An SIOC und SIOD habe ich jeweils einen pullup - das hat mit meiner 
Routine prima funktioniert. Vielleicht schreibe ich die auch noch um.

Morgen ist auch noch ein Tag :-)

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

Hi Leute,

ganz schön was los hier!
Super, das Dieter hier so kräftig mitmischt.

Ich habe derweil meine neue erworbenen C# Kenntnisse einmal ausprobiert, 
um eine kleine Testutility zu schreiben, mit der man auch Davids 
MC-Programm prima testen kann.

Ich habe das Tool "SendMaster" genannt, weil es beliebige Bytes über die 
serielle Schnittstelle senden (und auch empfangen) kann.

Nix Dolles, aber man kann damit einfachste Protokolle gut nachstellen:

Dazu werden die zu sendenden Bytes als Folge von Hex-Zahlen im 
Sende-Fenster eingegeben. Wenn das Tool auf Antwort-Bytes warten soll, 
trägt man an der jeweiligen Stelle einfach Punkte '.' ein. Jeder Punkt 
steht für ein zu empfängendes Byte.

Mit der folgenden Sequenz kann man z.B. via Davids MC-Programm das 
Kamera-Register 0x50 abfragen, es dann auf den Wert 0x88 setzen und es 
anschließend nochmals abfragen.

01 50 0D 0A . .
02 50 88 0D 0A .
01 50 0D 0A . .

Die Antwort seht Ihr im Screenshot im Anhang.
Das Programm habe ich ebenfalls angehängt.

Der Code ist allerdings aktuell noch so grottig, dass ich ihn niemandem 
zumuten möchte (und so richtig auf Herz und Nieren ist er auch noch 
nicht getestet - erwartet also das Schlimmste und freut Euch, wenn's 
trotzdem funktioniert)

Viele Grüße

Igel1

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,

Dieter F. schrieb:
> Ich muss dazu schreiben, dass ich ohne Level-Shifter arbeite. Lt.
> Datenblatt V 1.01 für den AL422B Punkt 8.2 "In either case the AL422B is
> 5V or 3.3V I/O tolerant." sollte das gehen.

Der Fifo ja, der OV7670 aber nicht, XCLK, RESET usw.
Möglich, daß sie mitspielt, aber nicht sicher.

Dieter F. schrieb:
> So - die serielle Kommunikation funktioniert jetzt zuverlässig. Ich habe
> Peter Danneggers Routinen mit Ringpuffer eingebaut und bei 76.800 und
> 250.000 Baud funktioniert alles tadellos (mit Dummy-Werten). Bei 115.200
> Baud habe ich jede Menge Fehler und nichts geht richtig (habe ein
> SSD1306 LCD drangehängt und mir die übertragenen Bytes mal angeschaut).

Ich hatte irgendwann früher auch schon mal einen Ersatz für die 
UART-Routinen gemacht und wohl auch hier reingestellt. War primitiv und 
nur auf die Verwendung mit der Kamera-Geschichte zugeschnitten.
David hat ja nunmal den Ehrgeiz, jedes Fahrrad neu erfinden zu wollen, 
kann man machen, trifft zugegebener Weise aber weniger meinen Nerv.
Das zieht sich hier jetzt schon über 1 Jahr so hin, ohne für mich 
erkennbares Ziel und eigentlich auch ohne wirklichen Fortschritt.

Andreas S. schrieb:
> Mit der folgenden Sequenz kann man z.B. via Davids MC-Programm das
> Kamera-Register 0x50 abfragen, es dann auf den Wert 0x88 setzen und es
> anschließend nochmals abfragen.

Wenn für Dich Kenntnisse in C# sinnvoll sind ist das natürlich sinnvoll, 
Dich damit auseinanderzusetzen. Mir reicht es schon, meine durchaus 
mangelhaften C/C++ Kenntnisse aufzubessern. ;)
Das, was Deine Programmierübung da macht, kann ich auch mit HTerm 
erledigen, wenn ich es will.
So, vermutlich habe ich den Sonntag Morgen falsch angefangen, aber 
egal...

ok. Der UART hat bei 16MHz Takt und 115200 Baud einen Fehler von +2,1% 
mit gesetztem U2X-Bit, eigentlich geht das noch gut. Auch die -3,5% bei 
U2X = 0 gehen eigentlich noch. Beim UNO kommt noch die Tolereanz des 
Ceramic-Resonators dazu, der Nano kommt mit seinem Quarz da wohl etwas 
besser weg.
Interessant ist ja, daß Probleme ja auch dem Board zwischen AVR und 
UART-Bridge passieren müssen, zum Rechner per USB ist das ja egal.
Bei mir laufen auch die 230400 noch völlig stabil, warum auch immer...
Da ist der Fehler dann ja schon -3,5%.
Der CH340 auf dem Nano ist friedlicher, die Firmware Mega16U2 auf dem 
UNO kann man überfahren, wenn man bei der Bildübertragung zuviele Bytes 
direkt hintereinander schickt. 500000 sind da bei mir nicht mehr stabil, 
da verliert er willkürlich Bytes, wenn ich ein komplettes Bild 
rüberschicke.
Ich habe ja noch meine ürsprüngliche Testsoftware, die einfach nur alle 
60s ein komplettes Bild schickt, da kann ich das gut reproduzieren.

Der Kram liegt weiterhin hier griffbereit, wenn ich was bestimmtes 
Testen soll, gern. Am Besten eine Bediensequenz für sein Terminal 
mitteilen und was passieren soll oder auch nicht. Ich schau da auch 
weiterhin gern in den AVR-Code, wo er da evtl. klemmt.

Sich mit der OV7670 zu befassen, mit ihren Möglichkeiten und Grenzen, 
ist ja irgendwie in weiter Ferne...

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> Das, was Deine Programmierübung da macht, kann ich auch mit HTerm
> erledigen, wenn ich es will.
> So, vermutlich habe ich den Sonntag Morgen falsch angefangen, aber
> egal...

Oh ja - heute bist Du wirklich nicht gut drauf und wir bekommen alle 
unser Fett weg. Vermutlich zu recht, denn HTerm scheint wirklich toll zu 
sein.
Aber mein SendMaster kann sich ja noch mausern und scheint mir für die 
Analyse von Davids Programm auch ganz gut geeignet.

Und was Davids Code angeht, so kann man die Fehler selbstverständlich 
mit vorhandenen Bibliotheken ausmerzen, aber David hat nun mal den 
Ehrgeiz, die Dinge mit eigenem Code ans Laufen zu bringen und das finde 
ich bewundernswert - zumal er in seinen jungen Jahren hier schon so 
einiges auf den Tisch legt. Sein C# Code ist jedenfalls auch nicht von 
schlechten Eltern ...

Ich war mit 26 (Schätzung korrekt? Oder hatte sich David hier dazu schon 
mal geoutet?) jedenfalls noch nicht so weit, dass ich C# programmieren 
konnte (hi, hi - Ältere wissen, warum ...).

Ausserdem ist David nicht nur clever sondern hat auch noch gute Manieren 
- und diese Kombination ist hier im Forum eher selten anzutreffen. Schon 
aus diesen 2 Gründen macht es Spaß, hier in diesem Thread mitzumischen.

Natürlich ist es ebenfalls toll, von alten Hasen wie Michael oder Dieter 
noch etwas dazu zu lernen.

Deine, Michaels, Anregungen haben übrigens dazu geführt, dass ich hier 
schon eine erquicklicher Sammlung weiterer interessanter Module liegen 
habe - habe nämlich so einiges von Deinen Ideen aufgegriffen - Danke 
dafür!

So - ich hoffe, der Sonntag fängt nun etwas versöhnlicher an ...

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Oh ja - heute bist Du wirklich nicht gut drauf und wir bekommen alle
> unser Fett weg. Vermutlich zu recht, denn HTerm scheint wirklich toll zu
> sein.

Naja, irgendwie war mir eben nach "ausheulen", man möge mir bitte 
verzeihen. ;-))

Andreas S. schrieb:
> Ich war mit 26 (Schätzung korrekt? Oder hatte sich David hier dazu schon
> mal geoutet?) jedenfalls noch nicht so weit, dass ich C# programmieren
> konnte (hi, hi - Ältere wissen, warum ...).

Ich auch nicht, ich kann es auch heute noch nicht... ;-)))

Andreas S. schrieb:
> Ausserdem ist David nicht nur clever sondern hat auch noch gute Manieren
> - und diese Kombination ist hier im Forum eher selten anzutreffen. Schon
> aus diesen 2 Gründen macht es Spaß, hier in diesem Thread mitzumischen.

Ich will ihm auf keinen Fall den Spaß an der Sache irgendwie verderben, 
eigentlich wollte ich nur sagen, warum ich in manche Tiefe da nicht 
einsteigen will.

Andreas S. schrieb:
> Natürlich ist es ebenfalls toll, von alten Hasen wie Michael oder Dieter
> noch etwas dazu zu lernen.

Danke für die Blumen, für mich war Elektronik immer nur Hobby, auch wenn 
ich im Laufe der Jahre über Wartung/Instandhaltung später auch zu ein 
paar beruflichen Programmierübungen gekommen bin, aber nur Richtung 
HTML/PHP/MySQL usw. Ansonsten war immer Hardware meine Lieblingsrichtung 
und Software dann Mittel zum Zweck.

Andreas S. schrieb:
> Deine, Michaels, Anregungen haben übrigens dazu geführt, dass ich hier
> schon eine erquicklicher Sammlung weiterer interessanter Module liegen
> habe - habe nämlich so einiges von Deinen Ideen aufgegriffen - Danke
> dafür!

Oh ja, im "dumme Ideen haben" sind mein Bekannter und ich Spitze...
Die 64x64 LED-Matrix von irgendwo oben hat inzwischen ein Lagerfeuer, 
zeigt die Uhr an und scrollt den Wetterbericht von Apixu_Weather an. Der 
Softwarestand stammt allerdings von meinem Bekannten. MQTT natürlich 
auch für lokale Meldungen und bei ihm noch das CD-Cover wenn der 
Audioplayer läuft. ok, ein Cover in 64x64 sieht etwas ...seltsam... aus.
Ich muß das mal sinnvoll in mein FHEM einbinden.
Aktueller Blödsinn: ich habe den SI4735 ausgegraben, der schon ewig 
rumlag und diskutiere mit dessen Datenblatt, durchaus erfolgreich. Da 
ich irgendwo im Netz den SSB-Patch ausgegraben habe und mein Bekannter 
Amateurfunker (um Gottes Willen... natürlich Funkamateure...) hat...

Ich hoffe durchaus, daß ich hier zwischendurch auch bei Davis Kamerakram 
was zu tun finde. :-)

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

@Michael:

Na das hört sich doch schon wieder alles viel versöhnlicher an ...
Ich denke, der Kaffee war gut und die Croissants waren frisch?  :-)

> Ich will ihm auf keinen Fall den Spaß an der Sache irgendwie verderben,
> eigentlich wollte ich nur sagen, warum ich in manche Tiefe da nicht
> einsteigen will.

Ist schon gut. Zum Glück ist das hier ja alles nur Hobby und niemand 
zwingt niemanden, bei der zweiten Erfindung des Rades mitzumachen. Ich 
gebe zu: hier ist wirklich nur der Weg das Ziel.

Mir selber macht's halt gerade Spaß und ich werde daher gerne auch in 
Davids Code weiterhin mit herumstochern. Wie schon der alte Fritz sagte: 
jeder soll nach seiner Facon glücklich werden.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Na das hört sich doch schon wieder alles viel versöhnlicher an ...
> Ich denke, der Kaffee war gut und die Croissants waren frisch?  :-)

Programmierer sind die einzige Spezie des Menschen, die Kaffee direkt in 
Programmcode umwandeln können.

Andreas S. schrieb:
> Wie schon der alte Fritz sagte:
> jeder soll nach seiner Facon glücklich werden.

Der alte Fritz... Von dem habe ich ja lange nichts mehr gehört...

Ich zitiere mich mal selbst:

Michael U. schrieb:
> Oh ja, im "dumme Ideen haben" sind mein Bekannter und ich Spitze...

Vorhin Mail von meinem Bekannten mit Betreff "nutzloses Zeug" und einem 
Link:
https://www.thingiverse.com/thing:3417955

Hmmm... wäre dann wohl die 9. Uhr, die hier irgendwo rumsteht. Naja, 
warum auch nicht, VFD in dieser Bauform ist noch nicht dabei...

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Guten Tag zusammen,
na da bin ich ja froh, dass sich die Wogen schon wieder geglättet haben 
:)
interessant fande ich Michaels Aussage über die unterschiedlichen UART 
komponenten zwischen Uno und Nano. VIelleicht löte ich mir doch einfach 
mal eine Aufnahme. Ansonsten werde ich die Beobachtung von Dieter vorher 
noch ausprobieren. Hat die anderen Baudraten schon jemand mit "meinen" 
Uart routinen ausprobiert? ich bin gerade leider nicht zuhause :/...

@Igel dein Programm werde ich mir auch anschauen und finde es stark, 
dass du das anscheinend schon auf die Beine gestellt hast. Ich würde dir 
aber anbieten wollen, dass doch einfach in unser gemeinsames Terminal 
Programm zu "implementieren". Vielleicht auf einer anderen Tab seite. 
Dann entwicklen wir nicht zwei "tools" parallel zueinander.

Einfach während der Testphase eine neue Branch erstellen und los gehts 
:)

@Michael die Aussage, dass es keinen erkennbaren Fortschritt gibt nehme 
ich dir Übel :D... vlt. nicht so schnell wie du es sonst gewohnt bist, 
aber wenn ich mir die Posts von vor einem Jahr aufrufen, waren wir da 
noch an einer ganz anderen Baustelle ;-)

viele Grüße

David

von Michael U. (amiga)


Lesenswert?

Hallo,

David D. schrieb:
> @Michael die Aussage, dass es keinen erkennbaren Fortschritt gibt nehme
> ich dir Übel :D... vlt. nicht so schnell wie du es sonst gewohnt bist,
> aber wenn ich mir die Posts von vor einem Jahr aufrufen, waren wir da
> noch an einer ganz anderen Baustelle ;-)

ok, ich entschuldige mich dafür in aller Form. Zumindest ein wenig. ;)
Mein "Tempo" ist hier garnicht nicht entscheidend. Ist mehr so eine 
Sache der Erwartungshaltung. Kleiner AVR und die OV7670 - reizvoll, weil 
an der Grenze des machbaren. Ausloten, welche Möglichkeiten diese 
Kombination und auch die OV7670 selbst bietet oder auch nicht. Das ging 
mir eben die letzten Tage so durch den Kopf und heute morgen eben auch 
etwas durch die Tastatur...

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> @Igel dein Programm werde ich mir auch anschauen und finde es stark,
> dass du das anscheinend schon auf die Beine gestellt hast. Ich würde dir
> aber anbieten wollen, dass doch einfach in unser gemeinsames Terminal
> Programm zu "implementieren". Vielleicht auf einer anderen Tab seite.
> Dann entwicklen wir nicht zwei "tools" parallel zueinander.

Ja, habe ich auch schon überlegt und fände ich gut.
Aktuell ist das ganze allerdings eher eine Lern-Fallstudie als etwas, 
was Du integrieren möchtest. Du würdest Dir vermutlich mehr Baustellen 
ins Haus holen, als Du jemals haben möchtest.

Außerdem müßten wir uns vorab sowieso abstimmen, damit sich unsere 
Programme nicht gleichzeitig um die serielle Schnittstelle prügeln.

Trotzdem: sobald mein C# - Kenntnisse halbwegs passabel sind, können wir 
die Integration gerne angehen.

> Einfach während der Testphase eine neue Branch erstellen und los gehts
> :)

Das sagst Du so "einfach".
Ich weiß leider aktuell nicht wie und bin zugegeben aktuell etwas zu 
faul, mich in die Branching-/Merging-Technologie unter VS einzulesen.
Wenn Du da schon weiter bist, so freue ich mich über ein paar 
Instruktionen von Dir ...

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

> Dieter F. schrieb:
>> Ich muss dazu schreiben, dass ich ohne Level-Shifter arbeite. Lt.
>> Datenblatt V 1.01 für den AL422B Punkt 8.2 "In either case the AL422B is
>> 5V or 3.3V I/O tolerant." sollte das gehen.
>

Woraufhin Michael U. schrieb:
> Der Fifo ja, der OV7670 aber nicht, XCLK, RESET usw.
> Möglich, daß sie mitspielt, aber nicht sicher.


@Dieter F.:
Ich glaube auch, Du sparst hier an der falschen Stelle: auf diese Weise 
kannst Du Dir Fehler ins Haus holen, die Du später an völlig anderen 
Ecken suchst - das würde ich mir wirklich nicht antun.

Um Dir das Leben zu erleichtern, hier zwei Quellen, über die ich 
Level-Shifter bezogen habe:

Wenn's schnell gehen muss, aus Deutschland
(3x Level-Shifter mit je 4 Ports für zusammen 2,65 € inkl. Versand):
https://www.ebay.de/itm/253048505379?ul_noapp=true

Wer Zeit hat, kann in China bestellen
(5x Level-Shifter mit je 4 Ports für zusammen 1 EUR inkl. Versand):
https://www.aliexpress.com/snapshot/0.html?spm=a2g0s.9042647.6.2.74c34c4dXKYa0u&orderId=508148612005408&productId=32697947079

Viele Grüße

Igel1

von Dieter F. (Gast)


Lesenswert?

Andreas S. schrieb:
> @Dieter F.:
> Ich glaube auch, Du sparst hier an der falschen Stelle: auf diese Weise
> kannst Du Dir Fehler ins Haus holen, die Du später an völlig anderen
> Ecken suchst - das würde ich mir wirklich nicht antun.

Danke für das Angebot - Level-Shifter habe ich (die aus Deinem ersten 
Link).

Ich hatte noch eine Unsicherheit - ein Breadboard. Das habe ich jetzt 
durch Dupont-Kabel abgelöst. Die sitzen fest und es gbt keine "Wackler".

Aus meiner Sicht bereiten jetzt noch die SCCB-Routinen Probleme. Die 
serielle Kommunikation ist korrekt. Ich stelle auf I2C /TWI um. 
"Bitbanging" ist mir zu aufwändig und I2C /TWI funktioniert 
nachweislich.

Heute wird das aber nichts mehr - das Wetter ist hier zu schön und heute 
Abend wird gefeiert :-)

Melde mich morgen wieder.

VG
Dieter

von Andreas S. (igel1)


Lesenswert?

@Dieter: ich sehe, Du bist sehr schnell - hier geht's sonst etwas 
gemütlicher zu ...

@All:  Habe gerade mein SendMaster-Progrämmchen erweitert:
Es kann jetzt auch nur ein Byte pro Tastendruck versenden - das 
erleichtert das Debugging noch mehr.

Viele Grüße
Igel1

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

... hier schnell noch die neue Version von SendMaster mit der 
Möglichkeit, nun auch Bytes im Einzelstep-Verfahren zu versenden.
Zu diesem Zweck gibt es den neuen Button "Send 1 Byte".

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

@Andreas: das gefällt mir, gleich mal eingelagert. Eine Verwendung bei 
einem anderen Modul ist mir auch schon eingefallen.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> Hallo,
>
> @Andreas: das gefällt mir, gleich mal eingelagert. Eine Verwendung bei
> einem anderen Modul ist mir auch schon eingefallen.
>
> Gruß aus Berlin
> Michael

Danke, Michael.
Solltest Du spezielle Wünsche an das Tool haben, Du kennst ja den 
Entwickler :-) ...

Ich selber habe aktuell noch einen Haufen Ideen, wie ich SendMaster 
erweitern/optimieren möchte. Ich mache einfach so lange weiter, bis ich 
keine Lust mehr habe. Dieses C#-Gedöhnse macht mehr Spaß als ich 
erwartet hatte - vor allem wegen der VisualStudio-IDE - bietet eine 
wirklich intelligente Unterstützung des Entwicklers.

Hier meine aktuelle Prio-Liste:

1.) Statt Punkten "." für zu empfangende Bytes,  möchte ich auch ein
    "p" als Zeichen für ein zu empfangendes Bild zulassen.
    Dazu möchte ich auf der rechten Seite einen konfigurierbaren
    Bildbereich einrichten. Konfigurierbar wären Xdim, Ydim,
    Bytes/Pixel, Bildformat (z.B. RGB565, ...).
    Wenn man dann auf ein "p" im "Send" Fenster stößt, werden
    genausoviele Bytes eingelesen, wie der konfigurierte Bildbereich
    erwartet. Ich möchte die Bild-Bytes dabei zunächst in einen
    Buffer einlesen, so dass man verschiedene Bildformate auf die
    bereits gespeicherten Bytes anwenden kann (um so
    z.B. per Try & Error die Bilddimensionen ermitteln zu können).
    Das Bild wird dann jeweils im geänderten Format mit den Daten aus
    dem Buffer neu dargestellt.

2.) Byte-/Befehls-Folgen im "Send"-Feld sollen aus aus Dateien
    eingelesen bzw. dorthin abgespeichert werden können.

3.) Ich möchte "X" als Breakpoint im "Send"-Feld zulassen, dann könnte
    man von Breakpoint zu Breakpoint rauschen und alle dazwischen-
    liegenden Bytes ausgeben lassen.

4.) Eher Fleißarbeit: den seriellen Port noch etwas konfigurierbaren
    machen - z.B Baudrate, Stopbits, ...

Soweit ein Teil meiner aktuellen Ideen ...

Viele Grüße

Igel1

: Bearbeitet durch User
von David D. (saturi)


Lesenswert?

Hallo Igel,
freut mich, dass dir C# so viel freude bereitet.

Trotzdem würde ich gerne nochmal darauf hinweisen, dass es doch mehr 
Sinn machen würde alles in einem zu vereinen.
Passende Klassen wären schon vorhanden und du hast alle freiheit sie 
nach deinen Wünschen zu Editieren ;-)

Das mit dem Comport sehe ich als nicht so kritisch an. (Sobald der 
Comport connected ist, kannst du über den senden und empfangen wie du 
lustig bist, da funkt das bestehende Programm dann eigentlich nicht 
rein.

ich werde dir heute abend eine branch erstellen und schauen wie das im 
vs einzubinden ist.

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Solltest Du spezielle Wünsche an das Tool haben, Du kennst ja den
> Entwickler :-) ...

:-))

Zu Deine Ideen: man kann alles machen, was man will. Ich habe nur gerade 
überlegt, welche Verwendung ich für Dein Tool hätte. Einige sind mir 
eingefallen, speziell Sachen, die wenig Datenverkehr brauchen und wo das 
Protokoll unklar/unhandlich/binär ist. Da kommen Terminalprogramme dann 
nicht gut klar und das von mir schon erwähnte HTerm kann eigentlich 
schon wieder zuviel. Für Deine Bildidee fehlt mir im Moment die reale 
Anwendung, es gibt nicht viel außer mal einem Kameramodul, was mir 
Bilddaten schicken könnte.
Beipisle bei mir: das Billig-China Funkbridge-Modul redet irgendwie 
nicht mit mir. Will es CR oder NL oder beides und wierum dann? Genau 
sowas sollte mit Deinem Tool gut rauszufinden sein. Auch bei Spielereien 
mit dem SI4735, den ich gerade in der Mache habe, könnte es praktisch 
sein: ich klebe einfach in die ESP32 Routinen zum Test eine 
seriell-I2C-bridge rein, da passt auch Dein Format sehr gut, Hex 
Adresse, Kommando, Datenbytes und die Anzahl Punkte für die Antworten. 
Hmmm... Punkte: Ziffer in Kalmmern für erwartete Anzahl Antwortbytes 
wahlweise statt der Punkte?

David D. schrieb:
> Trotzdem würde ich gerne nochmal darauf hinweisen, dass es doch mehr
> Sinn machen würde alles in einem zu vereinen.
> Passende Klassen wären schon vorhanden und du hast alle freiheit sie
> nach deinen Wünschen zu Editieren ;-)

Da halte ich mich mal komplett raus, für mich wäre es nur schade, wenn 
sein kleines Tool irgendwo in Deinem Terminal "versinkt".

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Lesenswert?

Hi,

ich hangle mich von Baustelle zu Baustelle :-)

SCCB läuft (mit I2C) ordentlich. Jetzt beschäftige ich mich mit der 
Kommunikation mit dem FiFo :-\

Es klemmt - und ich weiß noch nicht, wo. Das wird ein wenig dauern, da 
ich leider auch ab und an meiner Arbeit nachgehen muss. Ostern geht es 
weiter :-)

VG
Dieter

Beitrag #5810269 wurde vom Autor gelöscht.
von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

Michael U. schrieb:
> Hmmm... Punkte: Ziffer in Kalmmern für erwartete Anzahl Antwortbytes
> wahlweise statt der Punkte?

Geliefert wie bestellt (oder genauer: fast, wie bestellt - ich finde 
sogar noch etwas eleganter, als bestellt): anbei Version 0.03 vom 
SendMaster.

Neuigkeiten:

* Baudrate läßt sich nun auswählen

* Timeout läßt sich in ms einstellen:  Kommt > Timeout ms nichts am 
seriellen Port an, so wird dies [-] gekennzeichnet, wenn ein Byte 
erwartet wurde (also ein Dot '.' gesetzt war).

* Neben den Dots '.' gibt es jetzt auch Sternchen '*' - die stehen für 
beliebig viele zu empfangende Bytes. Erst wenn keine Bytes mehr am 
seriellen Port ankommen (will sagen: die konfigurierbare Timeout-Zeit 
überschritten wird), werden weitere Zeichen im Sende-Fenster geparst. 
Extra-Gimmick: die Anzahl der empfangenen Bytes wird zusätzlich 
ausgegeben (siehe Bild im Anhang).


Sieht hübsch aus und scheint auch auf den ersten Blick mit Davids 
MC-Programm zusammen zu ticken.

Allerdings ist mein SendMaster definitiv noch nicht auf Herz und Nieren 
getestet - bitte also keine Atomkraftwerke damit steuern :-)

Insbesondere fürchte ich, dass bei einem "*" und Anlieferung größerer 
Bytemengen, das Schreiben in das Result-Fenster irgendwann nicht mehr 
hinterher kommt und es ggf. zu Aufzeichnungsfehlern kommt.

Hier müsste ich etwas mehr Hirnschmalz reinstecken, als mir aktuell zur 
Verfügung steht.

Was die Bilddarstellungsklamotte angeht, so scheint mir das 
.NET-Framework diesbezüglich etwas sperrig zu sein. Will sagen: geht 
nicht so geschmeidig in den Kopp und es fehlt noch definitiv an 
Kenntnissen bei mir - aber was nicht ist, kann ja bald sein ...

Wäre schon cool, wenn ich durch schöde Eingabe von Bytes (also 
handgestricktes David-Protokoll) aus Davids AVR-Programm ein Bild 
herauslutschen könnte.

David möchte sich bitte trotzdem nicht ärgern, denn so ein SendMaster 
habe ich mir für unterschiedlichste Zwecke schon immer einmal gewünscht 
- wird also keine "Konkurrenzveranstaltung" zu Deinem Programm, David, 
und zielt eher in Richtung "schweizer Messer für serielle Protokolle"

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Geliefert wie bestellt (oder genauer: fast, wie bestellt - ich finde
> sogar noch etwas eleganter, als bestellt): anbei Version 0.03 vom
> SendMaster.

Das ist ein Service! Morgen komme ich nicht zum Testen, ich muß wirklich 
mal für meinen Rentner-Nebenverdienst auch noch arbeiten.... ;-)

OT: da Du ja seltsame Sachen magst, heute entdeckt und einfach mal 
bestellt (wofür auch immer...):
https://www.shotech.de/de/advanced_search_result.php?categories_id=0&keywords=air602&inc_subcat=1

Bei Seeedstudio sind die Unterlagen und das SDK verlinkt:
https://www.seeedstudio.io/Air602-WiFi-Module-p-3139.html
irgendwo ziemlich unten auf der Seite.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> OT: da Du ja seltsame Sachen magst, heute entdeckt und einfach mal
> bestellt (wofür auch immer...):

... ja, man kann nie wissen: der nächste Krieg kommt bestimmt :-)
Aber mal im Ernst: das Teil macht wirklich einen  interessanten Eindruck 
- immerhin ist ein ARM Cortex-M3 Prozessor mir 8MB Flash und 288k RAM 
drauf.

Beim Ali für ca. 1 EUR zu bekommen - Wahnsinn. Hab's mir direkt schon 
mal in den Warenkorb gelegt.

Bliebe nur zu recherchieren, wie gut die Doku dazu ist.
Ohne anständige Doku ist das Ding schlichtweg ein Lebenszeitfresser.

Viele Grüße

Igel1

von Dieter F. (Gast)


Lesenswert?

Andreas S. schrieb:
> David möchte sich bitte trotzdem nicht ärgern

Na ja, David hat ja schon mehrfach darum gebeten, die Entwicklung zu 
integrieren. Irgendwie ging (geht ?) es ja hier auch darum, seine Lösung 
funktionsfähig zu bekommen.

Wenn ich rein mit der seriellen Schnittstelle spielen/testen will nutze 
ich Hterm. (http://www.der-hammer.info/terminal/) das ist zwar alt - ber 
bietet alles, was ich mir so wünsche.

Habe beschlossen den verbleibenden Pin, den ich eigentlich für OE 
verwenden wollte, für ein Debug-Schalterchen einzusetzten. Dann kann ich 
gezielt Debug-Meldungen ausgeben, wenn ich nicht mit Davids Programm 
steuere. Dann brauche ich nicht jedesmal neu zu flashen.

VG
Dieter

von Andreas S. (igel1)


Lesenswert?

Dieter F. schrieb:
> Andreas S. schrieb:
>> David möchte sich bitte trotzdem nicht ärgern
>
> Na ja, David hat ja schon mehrfach darum gebeten, die Entwicklung zu
> integrieren. Irgendwie ging (geht ?) es ja hier auch darum, seine Lösung
> funktionsfähig zu bekommen.

Ja, Integration können wir auch gerne angehen, wenn SendMaster einen 
gewissen Reifegrad erreicht hat. Allerdings würde ich SendMaster halt 
gerne auch in anderen Projekten einsetzen und dafür ist es als 
Stand-Alone Tool dann doch irgendwie praktischer.

> Wenn ich rein mit der seriellen Schnittstelle spielen/testen will nutze
> ich Hterm. (http://www.der-hammer.info/terminal/) das ist zwar alt - ber
> bietet alles, was ich mir so wünsche.

Das hat Michael ebenfalls angepriesen. Muss ich mir nochmals näher 
angucken. Kann man damit auch serielle Protokolle "nachspielen": also 
z.B. 4 Bytes senden, dann 2 Bytes empfangen, dann 5 Bytes senden, dann 3 
Bytes empfangen, ...  - so, wie es mit meinem SendMaster und dem 
"."-Dot-Mechanismus funktioniert?

> Habe beschlossen den verbleibenden Pin, den ich eigentlich für OE
> verwenden wollte, für ein Debug-Schalterchen einzusetzten. Dann kann ich
> gezielt Debug-Meldungen ausgeben, wenn ich nicht mit Davids Programm
> steuere. Dann brauche ich nicht jedesmal neu zu flashen.

So ganz habe ich jetzt nicht verstanden, was Du vorhast, aber ich 
entnehme dem, dass Du vermutlich kein DebugWire zum Debugging nutzt?

Wenn nein: denke einmal über den Invest in einen AVR-Dragon nach - ist 
echt 'ne coole Sache. David, Michael und ich nutzen den ebenfalls: 
ermöglicht Breakpoints und Einzelschritt-Debugging auf der Hardware. 
Geht schon ein wenig in die Richtung, was ARM-Prozessoren so bieten.

> VG
> Dieter

VG
Andreas

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Aber mal im Ernst: das Teil macht wirklich einen  interessanten Eindruck
> - immerhin ist ein ARM Cortex-M3 Prozessor mir 8MB Flash und 288k RAM
> drauf.
...
> Bliebe nur zu recherchieren, wie gut die Doku dazu ist.
> Ohne anständige Doku ist das Ding schlichtweg ein Lebenszeitfresser.

Naja, bei dem Beschaffungspreis und der Baugröße landet es 
schlimmstenfalls in der Schachtel: irgendwann schaue ich mir das mal 
genauer an. ;-)

Dieter F. schrieb:
> Na ja, David hat ja schon mehrfach darum gebeten, die Entwicklung zu
> integrieren. Irgendwie ging (geht ?) es ja hier auch darum, seine Lösung
> funktionsfähig zu bekommen.

Du gehst ja im Moment wohl auch den Weg, bekannte Lösungen zu nutzen 
(peda's Serielle Lib, Hardware-I2C). Da habe ich hier ja auch eine 
Version, die macht, was ich erwarte. Aber eben ohne Davids Terminal (das 
kam ja erst später von ihm). Ich bin da im Moment in etwas abwartender 
Haltung, wohin der Hase läuft.

Dieter F. schrieb:
> Wenn ich rein mit der seriellen Schnittstelle spielen/testen will nutze
> ich Hterm. (http://www.der-hammer.info/terminal/) das ist zwar alt - ber
> bietet alles, was ich mir so wünsche.

Hatte ich auch schonmal erwähnt und nutze ich manchmal auch.

Dieter F. schrieb:
> Habe beschlossen den verbleibenden Pin, den ich eigentlich für OE
> verwenden wollte, für ein Debug-Schalterchen einzusetzten.

Auch eine gute Idee. Bei mir ist der freie Pin die interne LED des UNO, 
in meiner anderen Software hatte der Programmierer da schön I2C 
(SCCB)-Fehler abgefangen und dann im Endlos-Loop die LED blinken lassen. 
Hatte mir am Anfang gut geholfen als Schnelltest, ob die Drähte noch 
dran sind. ;)

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Andreas S. schrieb:
> Michael U. schrieb:
>> OT: da Du ja seltsame Sachen magst, heute entdeckt und einfach mal
>> bestellt (wofür auch immer...):
>
> ... ja, man kann nie wissen: der nächste Krieg kommt bestimmt :-)
[...]
>
> Bliebe nur zu recherchieren, wie gut die Doku dazu ist.
> Ohne anständige Doku ist das Ding schlichtweg ein Lebenszeitfresser.
>

Habe mal ein Weilchen recherchiert.

Ergebnis: Doku scheint grottig zu sein und Community ist bislang nicht 
vorhanden. Ergo => Finger weg vom W600 (auch wenn's wirklich schade 
ist).

Immer wieder erstaunlich, dass die Chinesen in der Lage sind, solche 
tollen Chips zu designen und dann wiederum nicht in der Lage sind, eine 
vernünftige Doku dazu zu schreiben. Zum Vergleich: die Referenz-Manuals 
von ST zu deren Cortex-M4-Prozessoren sind >1000 Seiten. Die 
Datenblätter mit den genauen Specs, nochmals ein paarhundert Seiten - 
und das braucht man auch.

Viele Grüße

Igel1

von Dieter F. (Gast)


Lesenswert?

Andreas S. schrieb:
> Kann man damit auch serielle Protokolle "nachspielen": also
> z.B. 4 Bytes senden, dann 2 Bytes empfangen, dann 5 Bytes senden, dann 3
> Bytes empfangen, ...  - so, wie es mit meinem SendMaster und dem
> "."-Dot-Mechanismus funktioniert?

Jein. Nicht analog Deines "."-Mechanismus - aber man kann natürlich 
entsprechende Eingaben (auch per Datei) machen und die Rückgabewerte 
anschauen.

Andreas S. schrieb:
> So ganz habe ich jetzt nicht verstanden, was Du vorhast, aber ich
> entnehme dem, dass Du vermutlich kein DebugWire zum Debugging nutzt?

Genau - hier reicht es mir aus, an bestimmten Stellen kleine Ausgaben zu 
erzeugen um zu schauen, ob alles O.K. ist. Ansonsten habe ich den Atmel 
ICE zur Verfügung.

VG (Viele Grüße)
Dieter

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Ergebnis: Doku scheint grottig zu sein und Community ist bislang nicht
> vorhanden. Ergo => Finger weg vom W600 (auch wenn's wirklich schade
> ist).

naja, ich habe vorerst nichts anderes erwartet. Man muß ja nicht alles 
gleich selber programmieren können/wollen.
Der AT-Kommandosatz sieht merklich sinnvoller aus als der der ersten 
ESP8266.
Grundfunktionen MQTT, HTTP GET/POST sind da schon drin.
Ein bißchen Spaß muß sein. ;)

Andreas S. schrieb:
> Immer wieder erstaunlich, dass die Chinesen in der Lage sind, solche
> tollen Chips zu designen und dann wiederum nicht in der Lage sind, eine
> vernünftige Doku dazu zu schreiben.

Auch hier naja. Sie können sowas offenbar entwickeln und herstellen und 
auch liefern. Sie stellen relativ schnell überhaupt was zur Verfügung, 
ohne NDA usw. Kenne ich von anderen namhaften Herstellern durchaus 
anders.

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Dieter F. schrieb:

> Jein. Nicht analog Deines "."-Mechanismus - aber man kann natürlich
> entsprechende Eingaben (auch per Datei) machen und die Rückgabewerte
> anschauen.

Ah, interessant.  Das mit dem Datei-Einlesen wollte ich bei mir auch 
noch einbauen - schau'n wir mal.

> Andreas S. schrieb:
>> So ganz habe ich jetzt nicht verstanden, was Du vorhast, aber ich
>> entnehme dem, dass Du vermutlich kein DebugWire zum Debugging nutzt?
>
> Genau - hier reicht es mir aus, an bestimmten Stellen kleine Ausgaben zu
> erzeugen um zu schauen, ob alles O.K. ist.

Claro - so geht's auch - ist halt etwas umständlicher als Breakpoints 
und DebugWire. Aber bekanntlich führen ja viele Wege nach Rom.

> Ansonsten habe ich den Atmel
> ICE zur Verfügung.

Dann scheinst Du auf der Sonnenseite des Lebens zu parken (mal rein 
investment-mäßig gesprochen) :-)

Die Anleitung hier scheint ganz gut zu beschreiben, wie Du Deinen ICE 
mit einem Nano zusammenschrauben und ans Fliegen bringen kannst:
http://www.crash-bang.com/debug-atmel-ice/

Falls das wirklich funktioniert, so würde ich dieses Feature an Deiner 
Stelle unbedingt nutzen - Debugging im Studio mit Breakpoints und 
Single-Step Modus erleichtert die Entwicklung und das Debuggen nach 
meiner Erfahrung massiv. 1-2h Einarbeitung, danach nie wieder 
Print-Statements in den Code einfügen und wieder rauslöschen - das lohnt 
sich.

> VG (Viele Grüße)
> Dieter

VGZ (Viele Grüße zurück)
Andreas

: Bearbeitet durch User
von Dieter F. (Gast)


Lesenswert?

Andreas S. schrieb:
> Dann scheinst Du auf der Sonnenseite des Lebens zu parken (mal rein
> investment-mäßig gesprochen) :-)

Nö - nur die Billig-Version (Platine) mit selbst gedrucktem Gehäuse und 
selbst gefertigtem Kabel. So in etwa - aber noch ein paar € güstiger (da 
gab es mal ein Angebot, dem ich nicht widerstehen konnte) 
http://shop.mymcu.de/index.php?sp=article.sp.php&artID=200142

Ich habe auch schon "früher" mit JTAG debugging betrieben. Für mich 
macht das bei diesem "Projekt" aber aktuell keinen Sinn (ist ja 
eigentlich nicht sooo komplex). Mir reicht es, wenn ich sehe, wo es 
klemmt (und was dann dort so ankommt). Das geht mit Ausgaben über die 
serielle Schnittstelle sehr gut.

VGZZ
Dieter

von Andreas S. (igel1)


Lesenswert?

Dieter F. schrieb:
> Ich habe auch schon "früher" mit JTAG debugging betrieben. Für mich
> macht das bei diesem "Projekt" aber aktuell keinen Sinn (ist ja
> eigentlich nicht sooo komplex). Mir reicht es, wenn ich sehe, wo es
> klemmt (und was dann dort so ankommt). Das geht mit Ausgaben über die
> serielle Schnittstelle sehr gut.

Alles klar - Du scheinst mehr Erfahrung auf diesem Gebiet zu besitzen 
als ich  - man kann das hier im Forum manchmal schlecht einschätzen.
Werde ich mein Klugschwätzen etwas zurückfahren :-)

Viele Grüße

Igel1

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

Hi Leute,

anbei die abendliche Lieferung: diesmal SendMaster V0.04

Zu dem Dot '.' und dem Asterisk '*' hat sich noch ein Dollar '$' als 
Steuerzeichen hinzugesellt. '$' steht für ein zu empfangendes Bild,
was dann auf dem Panel rechts dargestellt wird (wenn's gut läuft -
ist aktuell noch ziemlich buggy).

Die erwartete Bildgröße ist derzeit noch auf 313x240 fest codiert,
wird in Version 0.05 dann aber über die Oberfläche frei
konfigurierbar werden.

Anbei das Ergebnis (siehe Bild im Anhang), wenn ich diese Steuersequenz 
zu David's AVR-Programm sende:
1
08 0D 0A .
2
02 12 16 0D 0A .
3
02 40 14 0D 0A *
4
02 3A 05 0D 0A .
5
02 42 08 0D 0A .
6
04 72 02 0D 0A .
7
05 F0 00 0D 0A .
8
06 01 00 0D 0A .
9
0C 0D 0A $

Leider sind die Streifen des Testbildes noch schief - ich hoffe,
ich finde die Ursache noch. Aktuell fällt mir gerade nichts dazu ein.

Wie immer gilt: alles bislang nur sehr vage getestet - wer's
ausprobieren möchte braucht derzeit noch starke Nerven.


Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Andreas S. schrieb:
> Wie immer gilt: alles bislang nur sehr vage getestet - wer's
> ausprobieren möchte braucht derzeit noch starke Nerven.

warum? Explodiert der Arduino dabei? ;-)

OT: China-WLAN-Schnipsel lagen heute im Briefkasten. 5 bestellt, 6 
bekommen???
4 Drähte ran, an mein USB-Modul mit 3,3V Spannungsregler gesteckt, 3cm 
Draht als WLAN-Hochanrtenne ans Modul gelötet und TeraTerm gestartet.
Anmelden in meinem WLAN ok, anmelden am MQTT-Broker ok, Publish Message 
ok.
MQTT-Subscribe in der Beschreibung erstmal nicht verstanden.
Es gibt bereits eine Einbindung in die Arduino-IDE in Version 0.2.0, die 
sieht dafür nichtmal so schlecht aus...

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

kurzes Lebenszeichen...

Die Woche ist wieder besonders schlimm...

von Andreas S. (igel1)


Lesenswert?

Andreas S. schrieb:
> Leider sind die Streifen des Testbildes noch schief - ich hoffe,
> ich finde die Ursache noch. Aktuell fällt mir gerade nichts dazu ein.

Verdammt, das war schwierig und ich habe ca. 10h gebraucht, um meinen 
(nicht Davids!) Fehler zu finden:

Das Testbild kommt von David's AVR-Programm mit 313x240 im rgb565 Format 
- ohne Header, ohne alles - so weit, so gut.

C# arbeitet intern nun aber massiv mit Bitmap-Objekten.
Also musste ich Davids Roh-Bilddaten in C# in ein Bitmap-Objekt 
einlesen, wobei man sich allein dabei schon halb die Ohren bricht. In 
Summe ist es trotzdem nichts anderes, als dass man den Roh-Bilddaten 
noch einen Bitmap-Header davorspannt. Anschließend kann man diese 
erweiterten Daten in ein Bitmap-Objekt einlesen und dieses Objekt dann 
mit .NET-Bibliotheken auf dem Bildschirm zeichnen lassen. Das 
frustrierende Ergebnis seit 2 Tagen: die vertikalen Teststreifen waren 
und blieben im C#-Programm diagonal.

Nach unendlichem Suchen fand ich heraus:
Bitmap specification requires, to pad row size to a multiple of 4 Bytes.
https://upload.wikimedia.org/wikipedia/commons/c/c4/BMPfileFormat.png

Will sagen: die Zeilenbreite des OV7670-Colorbar-Testbildes von 313 
Pixeln entsprach wegen rgb565 genau 626 Bytes. 626 ist aber kein 
Vielfaches von 4 - daher müssen noch 2 Füllbytes an jede Zeile angehängt 
werden - "Padding" eben. Danach hat man ein Bitmap-Bild, wo jede Zeile 
eigentlich aus 628 Bytes besteht, wo im Header jedoch als Zeilenbreite 
313 vermerkt ist.
Kaum war das getan, schon wurden die Streifen schön senkrecht!

Da muss man erst einmal drauf kommen ...

Viele Grüße

Igel1

von Andreas S. (igel1)


Lesenswert?

Frohe Ostern, Ihr Lieben!
Wer als erstes den Osterhasen mit unserer OV7670 ablichtet, hat 
gewonnen!

Viele Grüße

Igel1

von Andreas S. (igel1)


Angehängte Dateien:

Lesenswert?

Hi Leute,

anbei eine Osteredition von SendMaster: SendMaster v0.05

* In einer "history.xml"-Datei kann man Sende-Sequenzen speichern,
  um sie später schnell per DropDown in das Send-Feld einfügen zu
  können - sehr praktisch.

* Erstmals generiert '$' ein korrektes Bild im rechten Bereich
  (aktuell nur mit Colorbar-Testbild getestet) - siehe Screenshot
  im Anhang.

* Die Anzeige der Bilddaten erfolgt in einem Bildframe, dessen X- und 
Y-Dimensionen sowie dessen Pixelformat frei konfigurierbar sind.

* Einmal eingelesene Bilddaten können mit dem "Apply"-Button
  in unterschiedlichsten X-/Y-Dimensionen und unterschiedlichsten
  Pixelformaten angezeigt werden

* Bilder können gespeichert und aus Dateien eingeladen werden.

Wie immer gilt: es gibt noch viel Optimierungsbedarf und alles ist
bislang nur sehr vage getestet - aber so langsam mausert sich das
Programm und man kann inzwischen ganz passabel damit testen.

@Michael: ... und nein, es explodiert nicht :-)

Trotzdem gibt es auch noch echte Baustellen:

* Aktuell blockiert das Einlesen serieller Daten das gesamte Programm -
  das ist insbesondere beim Bildempfang etwas nervig.
  Ich muss das früher oder später in Threads auslagern.

* Eingehende Daten, die nicht per "." oder "*" oder "$" erwartet
  wurden, werden bislang nicht angezeigt bzw. erst beim nächsten
  "." oder '*' oder '$' angezeigt - das verwirrt manchmal.

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

schöne Ostern erstmal noch, natürlich auch allen anderen.

Andreas S. schrieb:
> anbei eine Osteredition von SendMaster: SendMaster v0.05

:-( kein Osterhase...
Dein Farbbalken ist kaputt ;-)

Andreas S. schrieb:
> @Michael: ... und nein, es explodiert nicht :-)

Das kann ich so 100% bestätigen. :-)

Andreas S. schrieb:
> * Aktuell blockiert das Einlesen serieller Daten das gesamte Programm -
>   das ist insbesondere beim Bildempfang etwas nervig.
>   Ich muss das früher oder später in Threads auslagern.

Das macht z.B. mein altes VB-Programm vom LA auch.
Für mich gibt es da immer die Frage: stört das? Also kann ich 
währenddessen überhaupt was sinnvolles anderes mit dem Programm machen?
Bei mir war die Antwort nein, also wurde nur der Start-Button 
währenddessen in Stop umbenannt und ein Break eingebaut, um Abzubrechen.

Würde meiner Meinung nach auch hier reichen falls das Bild einlesen mal 
hängt oder man schon nach den ersten Zeilen sieht, das nur Müll kommt.

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Lesenswert?

Hi,

ich habe leider nicht so intensiv gearbeitet, wie ich wollte.

Ostern war einfach (vom Wetter her) zu schön.

USART und SCCB (TWI) funktionieren zuverlässig - nur mit der 
Fifo-Kommunikation hapert es noch. Verständlich, weil weder RE noch OE 
beschaltet sind. Eines von beiden benötigt man wohl für einen 
Read-Reset.

Es dauert noch etwas, bis ich die anderen "Parameter" durchschaut habe - 
aber es wird. Ich melde mich wieder - leider aktuell kein Osterhase :-(

von Michael U. (amiga)


Lesenswert?

Hallo,

Dieter F. schrieb:
> USART und SCCB (TWI) funktionieren zuverlässig - nur mit der
> Fifo-Kommunikation hapert es noch. Verständlich, weil weder RE noch OE
> beschaltet sind. Eines von beiden benötigt man wohl für einen
> Read-Reset.

Wenn Du mit OE den FIFO_OE (/OE vom Fifo) meinst: der kann fest auf Low, 
zumindest solange der AVR-Port schön auf Eingang bleibt.
/RE vom FiFo ist auf den üblichen OV7670-Fifo Boards doch sowieso fest 
auf GND und nicht rausgeführt?

Gruß aus Berlin
Michael

von Dieter F. (Gast)


Lesenswert?

Michael U. schrieb:
> Wenn Du mit OE den FIFO_OE (/OE vom Fifo) meinst: der kann fest auf Low,
> zumindest solange der AVR-Port schön auf Eingang bleibt.
> /RE vom FiFo ist auf den üblichen OV7670-Fifo Boards doch sowieso fest
> auf GND und nicht rausgeführt?

Ja - aber nicht beide.

Entweder oder - das sagt das Datenblatt.

von Michael U. (amiga)


Lesenswert?

Hallo,

Dieter F. schrieb:
> Entweder oder - das sagt das Datenblatt.

Das Thema gab es schon ganz am Anfang hier mal. Das Datenblatt verbietet 
es nicht direkt, beide Signale dürfen bleibig lange aktiv sein. /RE 
stoppt intern den Lesecounter, auch wenn RCK weiterläuft.
AL422-08 Read Cycle Timing (Read Enable)

/OE aktiviert unabhängig davon den Ausgangstreiber unabhängig davon, was 
intern passiert.
AL422-09 Read Cycle Timing (Output Enable)

Wir steuern aber über RCK, damit entscheidet derFlankenwechsel von RCK, 
wann gültige Daten ausgegeben werden, auch wenn beide städig auf Low 
liegen.
Ein paar ns nach der fallenden Flanke von RCK liegen gültige Daten an 
und können eingelesen werden.

Da gab es auch am Anfang ein Timingproblem bei David, weil er wohl nach 
der steigenden Flanke gelesen hat. Da sind die Daten aber nur noch für 
TOH (4ns) gülig und nach TAC (max. 15ns) liegt bereits das nächste Byte 
gülig an. So fehlte am Anfang das erste Byte bzw, die vermeintlich 
falsche Byteorder wurde angenommen.

Gerade gesehen: er warte da jetzt auch unnötig lange bis er einliest, da 
reichen ein paar ns bzw. keine Wartezeit, weil schon der Aufruf der 
Funktion UART0_senden_Byte() länger dauert.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Dieter F. schrieb:

> Ostern war einfach (vom Wetter her) zu schön.

Gut so!

> USART und SCCB (TWI) funktionieren zuverlässig - nur mit der
> Fifo-Kommunikation hapert es noch.

Evtl. möchtest Du Dir einmal diese beiden Posts von mir anschauen,
dort habe ich in Pseudocode die Vorgehensweise zum Beschreiben und
zum Auslesen des FiFo's aufgeschrieben (und später danach erfolgreich
auf einem ARM-Prozessor 1:1 implementiert):
Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)"

> Verständlich, weil weder RE noch OE
> beschaltet sind. Eines von beiden benötigt man wohl für einen
> Read-Reset.

In einigen Posts vor dem o.g. Link hatten wir herausgefunden,
dass mit der vorgegebenen inneren Beschaltung der Module die Spec
in bestimmten Punkten nicht eingehalten werden kann.
Genauso gut möglich ist es aber auch,  dass die Spec in einigen
Punkten nicht korrekt ist.

Wenn Du Dir also ab und an sagst "pfeif" drauf, und ein wenig nach
"Intuition" interpretierst und implementierstso ist das der
richtige Weg, das Dingen ans Fliegen zu bringen.

> Es dauert noch etwas, bis ich die anderen "Parameter" durchschaut habe -
> aber es wird. Ich melde mich wieder - leider aktuell kein Osterhase :-(

Wird schon noch ...

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

Guten Abend zusammen,
das lange Osterwochenende ist um und ich bin zu NICHTS gekommen... (also 
zumindest was das elektro Hobby angeht ;-) ich lese mich jetzt erstmal 
durch die posts durch und zu allzuviel mehr wird es heute wohl nicht 
reichen... Morgen dann :)

beste Grüße aus dem Süden

David

von Michael U. (amiga)


Lesenswert?

Hallo,

Ostern ist vorbei, da war auch bei mir reihum Durchfuttern gehen 
angesagt. ;-)
Das Älterwerden habe ich auch dieses Jahr erfolgreich überstanden und 
den Pollin-Gutschein in Empfang genommen. :-)

Noch die OT-Runde, wohl speziell an Andreas:
Meine ESP32-Cams haben zum Test eine Software bekommen, die das Bild per 
FTP-Client auf mein NAS legt. DeepSleep läuft auch wie gewünscht, Wecken 
entweder per Timer oder bei dem Modul mit dem PIR auch damit.

Der China-WLAN-Schnipsel (Air602) ist jetzt im Test auch stabil, schickt 
mir alle Minute per MQTT die Uhrzeit, NTP läuft also auch.

Alles (natürlich) aus der Arduino-IDE, ich bin ja bequem.
Wenn ich nur wüßte, wozu???

Ich habe auch mal spaßeshalber ein paar CH552 bestellt:
https://www.shotech.de/de/
Der Händler ist gut, lag jeweils nach 2 Tagen im Briefkasten.
Auch keine Ahnung, wozu, mit der ArduinoIDE ist da ja erstmal nichts zu 
machen...

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Michael U. schrieb:
> Hallo,
>
> Ostern ist vorbei, da war auch bei mir reihum Durchfuttern gehen
> angesagt. ;-)

Gut gemacht!  Ähnliches habe ich auch über Ostern getan.

Meine Waage meinte daraufhin, die Stelle vor dem Dezimalpunkt um 2 
Nummern hochdrehen zu müssen. Seitdem ist das Dingen nicht mehr mein 
Freund.

> Das Älterwerden habe ich auch dieses Jahr erfolgreich überstanden und
> den Pollin-Gutschein in Empfang genommen. :-)

Glückwunsch (zum neuen Lebensjahr - nicht zum Pollin-Gutschein)!

> Noch die OT-Runde, wohl speziell an Andreas:

Ah - kleine Ausflug - das ist immer interessant bei Michael ...

> Meine ESP32-Cams haben zum Test eine Software bekommen, die das Bild per
> FTP-Client auf mein NAS legt. DeepSleep läuft auch wie gewünscht, Wecken
> entweder per Timer oder bei dem Modul mit dem PIR auch damit.

Huch - war da auch ein PIR drauf?
Meine 2 Module sind inzwischen ja auch angekommen, liegen aber noch 
unberührt in der Schublade. Hast Du Deine Aktionen/Aktivitäten hier im 
Forum irgendwo dokumentiert? Würde ich später gerne einmal darauf 
zurückgreifen.

> Der China-WLAN-Schnipsel (Air602) ist jetzt im Test auch stabil, schickt
> mir alle Minute per MQTT die Uhrzeit, NTP läuft also auch.
> Alles (natürlich) aus der Arduino-IDE, ich bin ja bequem.

Hast Du das in einem Thread beschrieben?
Oder kannst du einen Thread dazu empfehlen?

> Wenn ich nur wüßte, wozu???

Um andere (wie mich) neugierig zu machen ;-)

> Ich habe auch mal spaßeshalber ein paar CH552 bestellt:
> https://www.shotech.de/de/

Du meine Güte - was sind die Dinger billig!

> Der Händler ist gut, lag jeweils nach 2 Tagen im Briefkasten.
> Auch keine Ahnung, wozu, mit der ArduinoIDE ist da ja erstmal nichts zu
> machen...

Macht nix - war allemal interessant und lesenswert.

> Gruß aus Berlin
> Michael

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Andreas S. schrieb:
> Meine Waage meinte daraufhin, die Stelle vor dem Dezimalpunkt um 2
> Nummern hochdrehen zu müssen. Seitdem ist das Dingen nicht mehr mein
> Freund.
Wieso? Kann man doch bestimmt die Firmware anpassen. ;)

> Glückwunsch (zum neuen Lebensjahr - nicht zum Pollin-Gutschein)!
Danke.

>> Meine ESP32-Cams haben zum Test eine Software bekommen, die das Bild per
>> FTP-Client auf mein NAS legt. DeepSleep läuft auch wie gewünscht, Wecken
>> entweder per Timer oder bei dem Modul mit dem PIR auch damit.
>
> Huch - war da auch ein PIR drauf?
Das war dieses Modul, hatte ich beim Erscheinen für 15€ bestellt, bei 
mir ist sogar der BME280 bestückt, obwohl der nur die Temperatur obwohl 
der nur die Temperatur des Regler-IC misst, der auf der Rückseite ist...

> Meine 2 Module sind inzwischen ja auch angekommen, liegen aber noch
> unberührt in der Schublade. Hast Du Deine Aktionen/Aktivitäten hier im
> Forum irgendwo dokumentiert? Würde ich später gerne einmal darauf
> zurückgreifen.
Jein, das Interesse ist da allgemein ziemlich bescheiden, spielt wohl 
kaum jemand damit rum...
Hier kurz erwähnt:
Beitrag "ov2640 Bild schießen und speichern"

>> Der China-WLAN-Schnipsel (Air602) ist jetzt im Test auch stabil, schickt
>> mir alle Minute per MQTT die Uhrzeit, NTP läuft also auch.
>> Alles (natürlich) aus der Arduino-IDE, ich bin ja bequem.
>
> Hast Du das in einem Thread beschrieben?
> Oder kannst du einen Thread dazu empfehlen?
Eigentlich nicht. Erwähnt und drüber gemault wurde mal, gekauft hat sie 
wohl keiner und gemacht auch nichts?

>> Ich habe auch mal spaßeshalber ein paar CH552 bestellt:
>> https://www.shotech.de/de/
> Du meine Güte - was sind die Dinger billig!
:-)
Beitrag "uC für 0,20€ CH552 / CH554 von WCH Billig Micro mit USB Funktion, Chip vorstellung"
Ein wenig habe ich zu den Teilen schon zusammengesucht, aber noch nichts 
gemacht.

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Hi Leute,

um einmal wieder etwas "OnTopic" zu schreiben:

Ich kämpfe aktuell damit, die serielle Schnittstelle in meinem 
SendMaster-C# Programm von synchron auf asynchron umzustellen.

Synchron hat den riesigen Nachteil: das Programm hängt so lange, bis die 
serielle Schnittstelle fertiggelesen bzw. in Timeout gelaufen ist.
Und "Hängen" bedeutet: es geht während dieser Zeit wirklich nichts.
Das ist unschön und gefällt mir nicht.

Außerdem hatte sich Michael einen Break-Button gewünscht und den soll er 
auch bekommen ...

Leider muss ich für die Umstellung deutlich tiefer in C# eintauchen, als 
ich mir eigentlich vorgenommen hatte: Die Themen Threads, Delegates, 
Events, Callbacks, Invoke und all so'n Gemüse kenne ich zwar von anderen 
Programmiersprachen (Ausnahme: Delegates), aber eben noch nicht in C#.

Trotzdem ist dieses C# irgendwie interessant: Teils elegant, teils 
verwirrend. Elegant finde ich die Einbindung von SQL direkt in die 
Sprache via LINQ und die Einbindung von Lambda-Expressions. Verwirrend 
finde ich nach wie vor, dass Groß-Kleinschreibkonventionen oftmals nicht 
beachtet werden - da sind die Java-Jünger deutlich pingeliger. Auch gibt 
es in C# viele Abkürzungen für Dinge, die sauber ausgeschrieben meiner 
Meinung nach verständlicher wären - auch wenn man dann mal 10 Tasten 
mehr drücken muss.

Nach wie vor fasziniert mich aber die Entwicklungsumgebung Visual Studio 
mit Ihren Tooltips, Syntax-Hinweisen, der Voranzeige von 
Funktions-Signaturen, der Auto-Completion-Funktion. Und das alles bei 
wirklich guter Performance. Da stecken bestimmt hunderte von Mannjahren 
drin - sehr beeindruckend.

Jetzt aber nochmals konkret zur Implementierung der Abfrage des 
seriellen Ports unter C#.  David möchte bitte einmal diesen Artikel 
lesen:
https://www.sparxeng.com/blog/software/must-use-net-system-io-ports-serialport

Darin (und in vielen anderen "Profi"-Artikeln im Internet) wird 
beschrieben, das die SerialPort-Implementierung unter .Net äußerst buggy 
ist. Zitat:
1
The worst offending System.IO.Ports.SerialPort members, ones that not only should not be used but are signs of a deep code smell and the need to rearchitect all IOPSP usage:
2
3
    The DataReceived event (100% redundant, also completely unreliable)
4
    The BytesToRead property (completely unreliable)
5
    The Read, ReadExisting, ReadLine methods (handle errors completely wrong, and are synchronous)
6
    The PinChanged event (delivered out of order with respect to every interesting thing you might want to know about it)
7
8
Members that are safe to use:
9
10
    The mode properties: BaudRate, DataBits, Parity, StopBits, but only before opening the port. And only for standard baud rates.
11
    Hardware handshaking control: the Handshake property
12
    Port selection: constructors, PortName property, Open method, IsOpen property, GetPortNames method
13
14
And the one member that no one uses because MSDN gives no example, but is absolutely essential to your sanity:
15
16
    The BaseStream property
17
18
The only serial port read approaches that work correctly are accessed via BaseStream.  Its implementation, the System.IO.Ports.SerialStream class (which has internal visibility; you can only use it via Stream virtual methods) is also home to the few lines of code which I wouldn’t choose to rewrite.


Nach meinem aktuellen Stand der Recherchen kommen all diese Artikel zu 
dem Schluss, dass nur der Zugriff via SerialPort.Basestream zuverlässig 
funktioniert.

Anfänger-Artikel (leider die große Masse der Artikel im Netz), bewerben 
die Event-Mechanismen via "DataReceived event" und die Nutzung von 
"BytesToRead".

Bei den Profi-Artikeln (also von Leuten, die wirklich die Schnittstelle 
dann auch richtig genutzt haben - nicht nur für "Hello World") steht 
jedes Mal: Finger weg von diesen (deutlich einfacher) zu nutzenden 
Funktionen/Properties.

Dies nur als Hinweis für Dich, David, da wir vermutlich beide bislang 
"auf das falsche Pferd" gesetzt haben.

Viele Grüße

Andreas

von David D. (saturi)


Lesenswert?

Andreas S. schrieb:

> Nach meinem aktuellen Stand der Recherchen kommen all diese Artikel zu
> dem Schluss, dass nur der Zugriff via SerialPort.Basestream zuverlässig
> funktioniert.

Auf dieses Basestream war ich auch schoneinmal gestoßen, allerdings 
nicht darauf, dass das andere unzuverlässig ist. Das einzige was ich 
einmal gelesen hab war, dass man sich nicht "sicher" sein kann, dass das 
serialPort.received() event auch wirklich für jedes empfangene Byte 
auslöst.

Das habe ich auch berücksichtigt, indem ich in meinen Verarbeitungen 
immernoch die Anzahl der empfangenen Bytes kontrolliert habe.

Wahrscheinlich haben die "Profis" recht und es wäre durchaus sinnvoll 
sich auch hier etwas tiefer in Mater einzuarbeiten. Allerdings frage ich 
mich ob das für unsere "unprofessionelle" Anwendung wirklich notwendig 
ist. Ich gehe davon aus, dass die uC mit ihrer Baudrate hier nicht 
wirklich an das "Limit" von C# und der SerialPort klasse kommen? Unsere 
beobachteten Fehler sind ja nachgewiesener maßen eher auf Seiten de uCs 
zu finden.


> Dies nur als Hinweis für Dich, David, da wir vermutlich beide bislang
> "auf das falsche Pferd" gesetzt haben.

vielen Dank, das werde ich in meine To-Do liste aufnehmen. Allerdings 
fehlt mir aktuell mal wieder die Zeit... Ich habe es nochnichtmal 
geschafft die "funktionierenden" Baudraten auszuprobieren.

Auch toll, dass dich C# so fesselt. Schade nur, dass das eigentlich 
Terminal (noch) nicht davon profitiert ;-) Du hättest auch dort absolute 
Gestalltungsfreiheit ;-) Aber vermutlich kann ich dich von deinem 
eigenen Projekt nichtmehr abbringen.

Gruß aus dem aktuell regnerischen Süden

David

von Andreas S. (igel1)


Lesenswert?

David D. schrieb:
> Auch toll, dass dich C# so fesselt. Schade nur, dass das eigentlich
> Terminal (noch) nicht davon profitiert ;-) Du hättest auch dort absolute
> Gestalltungsfreiheit ;-) Aber vermutlich kann ich dich von deinem
> eigenen Projekt nichtmehr abbringen.

Ein Anfang wäre, wenn Du den  versprochenen Branch anlegst und 
herausfindest, wie Code-Merging - also das Übernehmen meiner Änderungen 
in Deinen Branch - funktioniert.

Und keine Sorge: wenn ich mich genügend in C# ausgetobt habe, dann 
wollte ich als  nächstes in Deinem uC-Programm auf Bugjagd gehen. Ich 
warte aktuell noch auf den Motivationsschub, denn die Bugsuche riecht 
mächtig nach Arbeit ...

VG
Igel1

von David D. (saturi)


Lesenswert?

Hi Igel, den Branch hatte ich doch schon erstellt? einfach mal in Github 
auf das Branch: Master klicken, dann kannst du da ein anderes auswählen. 
(hoffe ich) und wenn du in VS dann auch dadrauf umstellst werden alle 
Änderungen in das/den Branch übernommen.

Das mergen sollte dann auch kein Problemm sein: hier erklärt für git. 
Das ganze Kommandozeilen getue brauchen wir an dieser Stelle nicht, weil 
Github uns das ganze als grafische Oberfläche zur Verfügung stellt.

https://git-scm.com/book/de/v1/Git-Branching-Einfaches-Branching-und-Merging

Gruß
David

: Bearbeitet durch User
von Andreas S. (igel1)


Lesenswert?

Hallo David, hi Leute,

wollte nur sagen: mich gibt's noch, habe aber gerade andere private 
Baustellen (Auto). Werde mich mit Deinen GIT-Tipps (danke dafür) die 
Tage einmal beschäftigen.

In der freien Zeit versuche ich immer noch, die serielle Schnittstelle 
unter C# über das Auslesen des Basestreams ans Laufen zu bekommen - 
bislang leider nur mit sehr mäßigem Erfolg:

Lesen geht schon irgendwie, aber ich möchte auch wissen, wann ein 
Timeout passiert und das geht aktuell noch nicht, weil der Timeout von 
Serialport.Basestream scheinbar keine Exceptions wirft.

Außerdem ist alles in diesem Bereich nur sehr mau von Microsoft 
dokumentiert. Macht nicht sonderlich viel Spaß, die Raterei.

Viele Grüße

Igel1

: Bearbeitet durch User
von nickdann27 (Gast)


Lesenswert?

Hallo Leute,

erstmal danke für die tolle Ideen, die hiergepostet wurden. Damit konnte 
ich schneller einstegen.

Jetzt zu meiner Frage:

Ich verwende wie die meisten hier ein OV7670+Al422B mit 12 MHz. Ich 
konnte schon das Kameramodul mit einem Arduino steuern und Bilder 
aufnehmen. Jetzt möchte ich dieses Modul mit einem FPGA zum Laufen 
bringen aber im Internet werden nur meistens ohne FIFO mit dem FPGA 
verwendet. Ich weiß auch, dass man mit einem FPGA kein Modul mit einem 
FIFO braucht, weil er schnell genug ist aber in meinem Fall benutze ich 
5 davon und die Bilderaufnahme müssen gleichzeitig laufen und in dem 
FIFO gespeichert werden, um später beliebig verarbeitet zu werden.

Bis jetzt Konnte ich schon Pixeldaten in dem FIFO einlesen und auslesen 
aber die Ausgangdaten sind noch falsch.

Hat schon jemand hier Erfahrung mit diesem Kamera Modul mit FPGA 
gemacht?

Ich freue mich schon über eure Antworten :)

Liebe Grüße

von Andreas S. (igel1)


Lesenswert?

nickdann27 schrieb:
> erstmal danke für die tolle Ideen, die hiergepostet wurden.
> Damit konnte ich schneller einstegen.

Um ehrlich zu sein: ich zweifle ein ganz kleines bisschen, ob Du
wirklich alles hier gelesen hast - sonst wären Deine Fragen nämlich
schon beantwortet :-)

> Bis jetzt Konnte ich schon Pixeldaten in dem FIFO einlesen und auslesen
> aber die Ausgangdaten sind noch falsch.

Womit hast Du das getestet?
Mit einem Atmega oder einem anderen MC oder schon mit Deinem FPGA?
(by the way: welchen verwendest Du?)
Und was genau ist an den Ausgangsdaten falsch?
Wie sehen sie aus und wie sieht das Bild mit diesen "falschen 
Ausgangsdaten" aus?


> Hat schon jemand hier Erfahrung mit diesem Kamera Modul mit FPGA
> gemacht?

Aus unserer kleinen, bescheidenen Runde hier in diesem Thead,
vermutlich nicht. Ist aber irgendwie auch nicht nötig, denn der
FPGA muss protokollmäßig einfach nur das machen, was wir hier mit
dem MC veranstaltet haben - und schon wird es auch mit dem FPGA
klappen.

Ich könnte das vermutlich auf meinem Xilinx-Board hinbekommen,
aber dann wären meine Weihnachtsferien vorbei und das wollen
wir ja nicht :-)

>
> Ich freue mich schon über eure Antworten :)

Zu früh gefreut ;-)

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

hier lebt ja noch jemand... :-)

Andreas S. schrieb:
> Aus unserer kleinen, bescheidenen Runde hier in diesem Thead,
> vermutlich nicht. Ist aber irgendwie auch nicht nötig, denn der
> FPGA muss protokollmäßig einfach nur das machen, was wir hier mit
> dem MC veranstaltet haben - und schon wird es auch mit dem FPGA
> klappen.

auch bei mir hat er Pech, nix mit FPGA am Hut bisher.

Um auf das alte Thema zu kommen: irgendwo liegt die OV7670 immernoch an 
anen AVR gesteckt und verstaubt. Beim ESP32 Modul mit der OV2640 habe 
ich mir eine Software fertig gemacht, die alle x Minuten ein Bild auf 
meinen internen FTP Server legt. Sollte auf den Balkon für 
Wolkenaufnahmen. Stromversorgung sollte eine LiFePO4 Zelle mit einem 
kleinen Solarmodule und Laderegler werden. Die liegt seit Monaten auf 
dem Balkon und hält den Akku auch artig voll. Den benutzt aber keiner, 
weil das Cam-Modul noch nicht im gedruckten Gehäuse und auch hier 
irgendwo rumliegt.
Ansonsten habe ich z.B. mit dem BME680 diskutiert und mir aus Blödsinn 
einen Geigerzählerbausatz geholt. War bei Banggood gerade im Angebot...
Fehlt mir nur noch ein Orchester dazu. ;-)

Gruß aus Berlin
Michael

von Andreas S. (igel1)


Lesenswert?

Hallo Michael,

schön, einmal wieder etwas von Dir zu hören!

Bei mir liegt die Kiste mit dem OV7670 inklusive verkabeltem 
LogicAnalyzer und allem drum herum auch in der Ecke und setzt Staub an. 
Sollte es etwa eines der vielen begonnenen und niemals fertiggestellten 
Projekte werden?
Nicht auszudenken .... ;-)

Immerhin habe ich durch David's Inspiration C# gelernt (und inzwischen 
leider auch schon wieder vergessen). Außerdem habe ich im Rahmen dieses 
Threads erstmals so richtig mit VisualStudio programmiert, was ein 
interessanter "Blick über den Tellerrand" für mich war.

Habe mir seit unserem OV7670-Projektchen die Zeit ein wenig mit 
Pferdeortung vertrieben: eine Beate suchte hier im Forum eine Methode, 
damit sich das Gatter zu Ihrem Stall nur für ihr Pferd öffnet:
Beitrag "Elektromagneten mit NFC/RFID Chipimplantat steuern *Auftrag*"

Über diesen Pferde-Thread bin ich zu Bluetooth Low Energie gekommen und 
habe mich dort ein wenig mit Beacons und deren Ortung beschäftigt. 
Allerdings nur sehr rudimentär - wie's die Zeit eines stressgeplagten 
Hobby-Elektronikers halt hergibt.

Aktuell rüste ich gerade optikmäßig etwas auf: die Augen werden 
schlechter und ich konnte ein Mantis Vision Mikroskop günstig samt 3 
Objektiven (2x, 4x, 8x Vergrößerung) in zwei Privatverkäufen gebraucht 
schießen. Ist gerade alles auf dem Postweg und ich bin ja schon sooooo 
gespannt! Das Dingen wird oft in Dental-Laboren verwendet und soll 
angeblich für Hobby-Elektronik ideal sein.

Nun aber zurück zu unserem Thread:

Irgendwie hätte ich schon Spaß, das OV7670-Projektchen hier wieder neu 
aufleben zu lassen, denn es war echt nett und angenehm hier mit Dir und 
David: hatte das Gefühl, dass hier jeder etwas vom anderen lernen 
konnte.

Allerdings stehen bei mir jetzt erst einmal andere Sachen an:  ich muss 
dringend mein Messy-Arbeitszimmer in den Griff bekommen, sonst gehe ich 
hier unter. Die Weihnachtsferien sind ideal dafür und wenn ich jetzt 
wieder hier im Thread einsteige, würde mein innerer Schweinehund 
abermals siegen, indem er das Angenehme vor dem Notwendigen priorisiert 
(das kann er suuuuper gut).

Was Deine Projektchen angeht, so ist es immer spannend davon zu hören. 
Ich kannte den BME280, aber der BMP680 scheint ja ein wahres 
Wundertierchen zu sein. Die Bosch-Leute sind da ganz weit vorn in Sachen 
Sensortechnik - schön zu sehen. Der Drucksensor ist so genau, dass ich 
damit doch glatt einen Höhentracker für unsere Familiendrohne bauen 
könnte - hmmm, schon wieder lauter interessante, verführerische Ideen 
...

Apropos Geigerzähler: könntest Du mir einen Link auf Dein 
Ali-Schnäppchen senden? Ich wollte mir auch immer mal wieder einen neuen 
Geigerzähler anschaffen - das nächste Atomkraftwerk geht bestimmt noch 
vor meinem Ableben in die Luft - da kann man dann wieder schöne Kurven 
aufzeichnen (auch wenn's vielleicht die Letzten sind).

Stammt die Ali-Schaltung von einem gängigen Schaltplan, der irgendwo im 
Internet, im MC-Forum oder in der Elektor entwickelt & diskutiert wurde? 
Das machen die Jungs aus Fernost ja ganz gerne und höchst erfolgreich: 
warum auch selbst entwickeln, wenn man doch gut abkupfern kann? (okay, 
okay - wir machen hier in diesem Thread zu 99% genau dasselbe, daher 
packe ich den moralischen Zeigefinger sofort wieder ein)

Und ah jaaa - jetzt erst, wo ich "GEIGER"zähler dreimal geschrieben 
habe, verstehe ich Deinen Wortwitz mit dem fehlenden "Orchester" ...

Viele Grüße

Igel1

von Michael U. (amiga)


Lesenswert?

Hallo,

Geiegerzähler:
https://www.banggood.com/Assembled-DIY-Geiger-Counter-Kit-Module-Miller-Tube-GM-Tube-Nuclear-Radiation-Detector-p-1136883.html?rmmds=myorder&cur_warehouse=CN

Ich gestelle öfter bei Banggood, bisher keine Probleme. Lieferzeit 
üblicherweise 2-3 Wochen, bisher nur ein Ausreißer mit 6 Wochen.

Der Bausatz geistert überall rum, allerdings zu ziemlich traumhafte 
Preisen.
Ich hätte auch selber gebaut, aber inzwischen haben die Händler wohl 
alle Zählrohre aus der Ukraine für ihre Bausätze aufgekauft, damit sind 
die Zählrohre nicht mehr um 25€ zu bekommen...
Etwas dumma war, daß inzwischen ein anderes Zählrohr geliefert wird, für 
das es etwas Sucherei im Netz war, um den passenden Korrekturfaktor 
dafür zu finden. Schaltung ist an sich dem Zweck entsprechend und 
funktioniert. Allerdings haben die Jungs den Impulsausgang mit einem 
470k in Reihe gemacht, ein ESP8266 war da nicht gewillt, irgendeine 
Flanke zu erkennen. Ich habe mich jetzt einfach hinter den Monoflog 
gehängt, direkt an die rote Kontrollled. Mit 1,6V als High triggert der 
IRQ des ESP8266 hier zuverlässig.

BME680 ist eigentlich mehr lustig. Luftdruckwerte stimmen gut mit meinen 
beiden BME280 überein, Feuchte ist erwartungsgemäß eben ungefähr. 
Temperatur hat natürlich das gleiche Problem wie beim BME280, es wird 
die Chiptemperatur gemessen. Nachteil ist aber: der BME680 muß 
durchlaufen, sonst geht des IAQ-Sensor nicht sinnvoll. Damit geht die 
Temperatur immer vor...
IAQ muß man die BSEC Lib von Bosch nehmen, nur die wissen, was sie da 
treiben und verraten das auch nicht wirklich.

Andreas S. schrieb:
> Und ah jaaa - jetzt erst, wo ich "GEIGER"zähler dreimal geschrieben
> habe, verstehe ich Deinen Wortwitz mit dem fehlenden "Orchester" ...

:-)) Naja, einen Pferdezähler hatten sie leider nicht im Angebot...

Gruß aus Berlin
Michael

von nickdann27 (Gast)


Angehängte Dateien:

Lesenswert?

Andreas S. schrieb:
> Womit hast Du das getestet?
> Mit einem Atmega oder einem anderen MC oder schon mit Deinem FPGA?
> (by the way: welchen verwendest Du?)
> Und was genau ist an den Ausgangsdaten falsch?
> Wie sehen sie aus und wie sieht das Bild mit diesen "falschen
> Ausgangsdaten" aus?

Hallo Igel1 und Frohe Weihnachten :),

Ich habe das mit dem LA getestet und damit konnte ich feststellen, dass 
Pixeldaten reinkommen.
Ich verwende einen Cora Z7-10 von Digilent.
Das Ausgangsbild habe ich angehängt.

Ich versuche jetzt nochmal alle Schritte durchzugehen ( Von der 
Initialisation bis zum Auslesen der Pixeldaten aus dem FIFO, um zu 
sehen, woran das Problem liegt)
Im Anhang habe ich eine PDF-Datei von meinem Blockdesign.

Ich würde auch gerne meine Pixeldaten über eine UART Schnittstelle 
beobachten können aber das ist etwa kompliziert mit dem Cora z7, da er 
nur ein UART Pin auf dem PS Logic hat und dort müsste alles über Xilinx 
SDK programmiert werden, damit bin ich noch nicht fit.

von Michael U. (amiga)


Lesenswert?

Hallo,

welche Datenbeispiele nimmst Du für Init usw.?
Leihe Dir unsere irgendwo oben aus der Gegend mit dem 
Farbbalken-Testbild aus, die gehen zumindest dann erstmal.

Gruß aus Berlin
Michael

von David D. (saturi)


Lesenswert?

Welch eine Überraschung!!!
Da verrät mein E-Mail Postfach mir, dass hier wieder etwas los ist :)
Das freut mich sehr! Außerdem möchte ich mich zu tiefst entschuldigen, 
dass die ganze Sache so abrupt eingeschlafen war. vielleicht schaffen 
wir es ja nochmal Zeitnah das unterfangen aufleben zu lassen :)
Ich melde mich die Tage wieder.

Gruß

David

von Andreas S. (igel1)


Lesenswert?

Och ja - das wäre irgendwie schön, denn hier war's doch ganz nett ...
Aber gräme Dich nicht - Du warst ja nicht der einzige, der ein Päuschen 
eingelegt hat.

Ich muss allerdings gestehen, dass ich aktuell hier noch ein paar 
größere Baustellen (also echte ...) habe.

Nevertheless läßt mich die Geschichte mit dem OV7670 auch irgendwie 
nicht los - wir haben es final nie so richtig gelöst und so etwas kann 
ich eigentlich nicht so gut leiden: es fehlt der "Deckel drauf".

Allerdings müßte ich jetzt vermutlich fast wieder bei Null anfangen. 
Seit unserer Zäsur bin ich leider zu so gar nichts Elektronischem 
gekommen - ein Jammer.

Viele Grüße

Igel1

von David D. (saturi)


Lesenswert?

richtig! Das stört mich auch etwas. Vor allem, dass die Kritiker zu 
Beginn des Projektes dadurch womöglich recht bekommen würden ;-)

ich habe zwischenzeitlich immernur zwischen Tür und Angel sachen 
ausprobiert. Aber nicht spezifisch auf dieses Projekt bezogen.

Allerdings habe ich dadurch das UART Protokoll weiter verbessert, 
nachdem Vorbild - (ich glaube es war Michael, wenn ich mich recht 
erinnere) -  des Siemens Protokoll, welches hier mal gepostet wurde.

von Michael U. (amiga)


Lesenswert?

Hallo,

ich lebe auch noch, der Kram liegt noch irgendwo zusammengesteckt rum 
usw.
Für mich ist es aber nach wie vor nur eine Art von Lernprojekt ohne 
irgendeinen praktisch nutzbaren Zweck.
Angefangene Projekte liegen auch bei mir ausreichend rum, es ist ohnehin 
nur Rentnerhobby, aber ein paar davon sollen durchuas mal fertig werden.
Das ESP32 Cam Modul mit der OV2640 soll eigentlich immernoch auf dem 
Balkon landen und Bilder vom Himmel zu meinen privaten Wetterdaten 
legen.
Sinn- und nutzlos, macht mir aber eben Spaß.
AVR mit OV7660 wäre von vielen Jahren interessant gewesen, wo es nicht 
anderes beschaff- und bezahlbares gab, da ist die Zeit aber eben 
weitergegangen.

Es war und ist aber hier eine nette Truppe zusammengekommen und der 
Thread bot immer wieder was Neues, insofern ist es schade, daß es so 
eingeschalfen ist.

Gruß aus Berlin
Michael

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.