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
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.
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?
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.
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.
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.
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.
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?
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.
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.
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.
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.
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.
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.
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.
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?
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
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
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...
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
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...
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
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...?,
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
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
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.
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
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.
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.
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 :)
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
voidsetup(){
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(intadr=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
intb=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
voidloop(){
47
48
}
Und hier mein Ergebnis dazu. Auch ich stelle teils massive Abweichungen
zu den Defaultwerten laut Datenlbatt fest:
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.
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
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.
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
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
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!
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
charc=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?
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
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.
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.
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
*OV7670DirArduinoMeaning
2
*3v3<-3V3Vcc(+3,3V)
3
*GND<-GNDGND
4
*SIOC<-A5SCL(I2Cclock)!USELEVEL-SHIFTER!
5
*SIOD<-A4SDA(I2Cdata)!USELEVEL-SHIFTER!
6
*XCLK<-D2System-Clock!USELEVEL-SHIFTER!
7
*RESET<-3V3Resetfixedfortesting
8
*PWDN<-GNDPower-Downfixedfortesting
9
*HREF->A6StartofnewlineinVideoframe
10
*VSYNC->A7StartofnewVideoframe
11
*PCLK<-D3Pixelclock!USELEVEL-SHIFTER!
12
*D0->A0VideodataLSB
13
*D1->A1Videodata
14
*D2->A2Videodata
15
*D3->A3Videodata
16
*D4->D4Videodata
17
*D5->D5Videodata
18
*D6->D6Videodata
19
*D7->D7VideodataMSB
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.
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
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
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?
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
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
*OV7670DirArduinoMeaning
2
*3v3<-3V3Vcc(+3,3V)
3
*GND<-GNDGND
4
*SIOC<-A5SCL(I2Cclock)!USELEVEL-SHIFTER!
5
*SIOD<-A4SDA(I2Cdata)!USELEVEL-SHIFTER!
6
*XCLK<-D3System-Clock!USELEVEL-SHIFTER!
7
*RESET<-3V3Resetfixedfortesting
8
*PWDN<-GNDPower-Downfixedfortesting
9
*HREF->A0StartofnewlineinVideoframe
10
*VSYNC->A1StartofnewVideoframe
11
*PCLK->A2Pixelclock
12
*D0->D8VideodataLSB
13
*D1->D9Videodata
14
*D2->D10Videodata
15
*D3->D11Videodata
16
*D4->D4Videodata
17
*D5->D5Videodata
18
*D6->D6Videodata
19
*D7->D7VideodataMSB
> 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 ;-)
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
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
*OV7670DirArduinoMeaning
2
*3v3<-3V3Vcc(+3,3V)
3
*GND<-GNDGND
4
*SIOC<-A5SCL(I2Cclock)!USELEVEL-SHIFTER!
5
*SIOD<-A4SDA(I2Cdata)!USELEVEL-SHIFTER!
6
*XCLK<-D3System-Clock!USELEVEL-SHIFTER!
7
*RESET<-3V3Resetfixedfortesting
8
*PWDN<-GNDPower-Downfixedfortesting
9
*HREF->A0StartofnewlineinVideoframe
10
*VSYNC->A1StartofnewVideoframe
11
*PCLK->D3Pixelclock
12
*D0->D8VideodataLSB
13
*D1->D9Videodata
14
*D2->D10Videodata
15
*D3->D11Videodata
16
*D4->D4Videodata
17
*D5->D5Videodata
18
*D6->D6Videodata
19
*D7->D7VideodataMSB
>> 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.
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?
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 :-)
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?
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...
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
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
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ß!!! :-)
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?
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
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.
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.
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
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
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
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
@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
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 :-)
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
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ö
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
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
... 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
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
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
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
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
volatileunsignedinti=0;
22
//unsigned char myBytes[100];
23
boolinterruptFlag=false;
24
intmain(void)
25
{
26
sei();
27
28
UART0_init();
29
OV7670_init();
30
OV7670_checkConnection();
31
32
33
//Reduce frequency of PCLK
34
charReadData=0;
35
charMASK=~0x80;
36
charWriteData;
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
boolHREF_Flag=false;
82
83
volatileintj=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)
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
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?
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
@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:
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
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
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
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
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
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! :-)
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.
Viktor, ich stimme mit Dir überein, lesbarer Code ist die Basis für eine
sinnvolle Zusammenarbeit und erfolgreiches Debugging. Und lieber
Unterfunktionen anstelle Makros.
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“.
@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:
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
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
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:
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
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
> 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
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
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 :)
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
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
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
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
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
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
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
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
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
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)
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
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
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
:)
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
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
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
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...
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
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
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
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
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
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
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
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
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.
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
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
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
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
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
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
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
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
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
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
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ß.
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
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
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.
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
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 WS2812LED-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
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
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
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
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...
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
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
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
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
...)
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.
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?
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
> 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
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
:-)
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
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
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
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
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
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.
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
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.
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?
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.
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
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
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.
@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
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
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
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
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....
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...
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
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
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
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
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
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
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
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
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
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
@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
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
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
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
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
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
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
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
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
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
@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
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
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
@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
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.
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
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
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
@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.
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 :-)
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.
@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
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
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
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
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
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
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.
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
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.
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:
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
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.
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
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
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
>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?
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 ...
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
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.
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
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.
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
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...
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
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
> 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!
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
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
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."
@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
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
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" :-)
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
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 :-)
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
@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
> (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.
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
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
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"
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
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 :-)
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.
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
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).
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
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
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.
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
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.
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()".
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
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
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
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 :-)
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 )
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 :-)
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?
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
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
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
>>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
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
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
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
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:
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
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
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
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
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 :)
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
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 ;-)
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
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
>poweron
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
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
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
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
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)
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
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
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
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
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
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
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
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 -,-
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
... 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
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
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
@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
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
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
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
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
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.
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
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
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
> Zur Bilderzeugung kann ich gerne mein Python-Scriptchen (primitiv - aber> funktionierend und leicht anpassbar) zur Verfügung stellen (heute> Abend).
das wäre subba :)
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
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 :(
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
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:
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
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
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
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?
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
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.
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
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
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
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
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
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
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
@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
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
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
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.
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
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
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
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
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
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
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
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
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
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
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.
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]
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
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...
@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...
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.
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
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).
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
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 ...
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
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
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
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
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
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
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
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
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
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
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
@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
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
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
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.
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...
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.
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
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
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
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
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
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
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
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:
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
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
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
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
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
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
>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 ;-)
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
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
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
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
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
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...
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:
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
@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.
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
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
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 ...
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
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...
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
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
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 :)
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
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:
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
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
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
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 ...
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
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
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
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
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:
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
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
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
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
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
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
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
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
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
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
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
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
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 ...
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
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
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
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
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
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
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
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
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
Hallo,
so, kurzer Nachtrag: Ordnung soweit gemacht.
Änderungen in Davids Source:
- uart.c - eigene Senderoutine ohne Interrupt, keine Empafamgsroutine
- main c - Kommandoauswertung auskommentiert, nur
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
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
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.
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.
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
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
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
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
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
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
@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
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
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
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
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
@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
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
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!
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.
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
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 :)
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
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
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
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
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
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)
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).
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
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
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
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
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
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
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
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
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
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
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
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.
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
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
Ä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
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()
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
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
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 !
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
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
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
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
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
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
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
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
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
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
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
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.
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
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.
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
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
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
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
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 ...
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
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
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.
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
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
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
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
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
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
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
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
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 -.-
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
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
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
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.
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
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
@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 ...
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
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.
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.
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
... 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
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
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
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
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
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
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
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
@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
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
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
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
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.
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_tregaddr=0x00;
8
uint8_tregdatabefore=0x00;
9
uint8_tregdataafter=0x00;
10
uint8_tregdatanew=0x88;
11
uint8_tretval=0x00;
12
uint32_tdelval=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");
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.
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
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)
@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
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:
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
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
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
...
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
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
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
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
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
@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
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
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
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
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
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
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
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.
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
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
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
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....
:/
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
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
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
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
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
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
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)
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
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
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.
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
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 ;-)
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
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
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
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
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
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
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
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
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.
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.
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
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
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
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)
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
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
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)...
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
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 ;-)
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
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
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
@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
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
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
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.
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
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
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
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!
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
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.htmlhttps://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.
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
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
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
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
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
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
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
@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!
> 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
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
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
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
@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
> 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
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.
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
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
> 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...
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
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?
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...
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).
> 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?
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
> 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
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.
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 :-)
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?
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.
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
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 :-)
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.
> 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
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
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.
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.)
David D. schrieb:> spätestens beim> dritten durchlauf von Read Device Settings bleibts hängen. (meistens> schon beim 1. oder 2.)
Willkommen im Club :-(
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
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
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.
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
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
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 :-)
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 :-)
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
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
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
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
@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
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
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
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
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
> 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
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
@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
... 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
Hallo,
@Andreas: das gefällt mir, gleich mal eingelagert. Eine Verwendung bei
einem anderen Modul ist mir auch schon eingefallen.
Gruß aus Berlin
Michael
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
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.
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 :-(
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
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.
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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.
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
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
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
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.
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