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.
Übrigens sind die Signale schon am Maximum der Absolute Maximum Werte.
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?
Nimm einen Atmega mit weniger F_CPU und probier alles zusammen bei 3,3V aus. Damit sollte sich das Problem einkreisen lassen.
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.
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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?
:
Bearbeitet durch User
Hallo David. Ich würde nicht mitten drin die Verhältnisse ändern. Du schaffst gerade neue Probleme. Lass uns doch erstmal mit der "alten" Kamera ohne FIFO weiterarbeiten. Das Bild interessiert uns doch aktuell noch nicht. Dabei ist es völlig egal ob das Teil nene Fifo hat oder nicht und wie und ob die Sync-Signale genutzt werden. Hier ein Test-Code
1 | #include "Wire.h" |
2 | |
3 | void setup() { |
4 | // put your setup code here, to run once:
|
5 | |
6 | pinMode(9, OUTPUT); |
7 | TCCR1A = ((1 << COM1A0)); //0x23; |
8 | TCCR1B = ((1 << WGM12) | (1 << CS10)); //0x09; |
9 | TIMSK1 = 0; |
10 | OCR1A = 0; |
11 | |
12 | Serial.begin(38400); |
13 | |
14 | Wire.begin(); |
15 | Wire.beginTransmission(0x21); |
16 | Wire.write(0x12); |
17 | Wire.write(0x80); |
18 | Wire.endTransmission(); |
19 | delay(500); |
20 | |
21 | Wire.beginTransmission(0x21); |
22 | Wire.write(0x0A); |
23 | Wire.endTransmission(); |
24 | Wire.requestFrom(0x21, 1); |
25 | while(Wire.available() == 0); |
26 | while(Wire.available()) |
27 | Serial.println(Wire.read(), HEX); |
28 | |
29 | Wire.beginTransmission(0x21); |
30 | Wire.write(0x0B); |
31 | Wire.endTransmission(); |
32 | Wire.requestFrom(0x21, 1); |
33 | while(Wire.available() == 0); |
34 | while(Wire.available()) |
35 | Serial.println(Wire.read(), HEX); |
36 | |
37 | }
|
38 | |
39 | void loop() { |
40 | // put your main code here, to run repeatedly:
|
41 | |
42 | }
|
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...
:
Bearbeitet durch User
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 :)
:
Bearbeitet durch User
Ich lese folgende Werte: Register 0x0A = 0x76 Register 0x0B = 0x73 Darin soll ja die Produkt-ID stecken. In 0A das MSB (PID) und in 0B das LSB (VER). Da wirken meine Werte jetzt plausibel, denn die Product-ID (PID) ist laut Datenblatt 0x76 und die Versions-ID (VER) unterscheidet sich nur leicht (0x73 anstelle im Datenblatt 0x70). Was ich noch nicht finde ist die tatsächliche Slave-ID. Im Datenblatt steht: auf Seite 10 "The device slave addresses are 42 for write and 43 for read.". Leider weder ob das Dezimal oder Hexadezimaladressen sind, es ist auch anders als in den Arduino Beispielcodes zu finden, da wird für Read und Write diesselbe Adresse verwendet, nämlich 0x21. Habe mal zum vergleichen den Sketch angepasst um einfach mal alle Register damit auslesen und anzeigen zu können. Laut Datenblatt gibt es nur die Register von 0x00 bis 0xC9.
1 | #include "Wire.h" |
2 | |
3 | void setup() { |
4 | Serial.begin(38400); |
5 | |
6 | // Generate 8 MHz clock output on Pin "9"
|
7 | pinMode(9, OUTPUT); |
8 | TCCR1A = ((1 << COM1A0)); //0x23; |
9 | TCCR1B = ((1 << WGM12) | (1 << CS10)); //0x09; |
10 | TIMSK1 = 0; |
11 | OCR1A = 0; |
12 | |
13 | // Reset chip to defaults
|
14 | // (write 0b10000000 into register 0x12)
|
15 | Wire.begin(); |
16 | Wire.beginTransmission(0x21); |
17 | Wire.write(0x12); |
18 | Wire.write(0x80); |
19 | Wire.endTransmission(); |
20 | delay(500); |
21 | |
22 | // Read out values of all registers
|
23 | for (int adr=0; adr<256; adr++) |
24 | {
|
25 | Serial.print("Value of 0x"); |
26 | if (adr < 0x10) |
27 | Serial.print("0"); |
28 | Serial.print(adr, HEX); |
29 | Serial.print(" = "); |
30 | Wire.beginTransmission(0x21); |
31 | Wire.write(adr); |
32 | Wire.endTransmission(); |
33 | Wire.requestFrom(0x21, 1); |
34 | while(Wire.available() == 0); |
35 | while(Wire.available()) { |
36 | int b = Wire.read(); |
37 | Serial.print("0x"); |
38 | if (b < 0x10) |
39 | Serial.print("0"); |
40 | Serial.print(b, HEX); |
41 | }
|
42 | Serial.println(""); |
43 | }
|
44 | }
|
45 | |
46 | void loop() { |
47 | |
48 | }
|
Und hier mein Ergebnis dazu. Auch ich stelle teils massive Abweichungen zu den Defaultwerten laut Datenlbatt fest:
1 | Value of 0x00 = 0x1A |
2 | Value of 0x01 = 0x80 |
3 | Value of 0x02 = 0x88 |
4 | Value of 0x03 = 0x00 |
5 | Value of 0x04 = 0x01 |
6 | Value of 0x05 = 0x7D |
7 | Value of 0x06 = 0x6E |
8 | Value of 0x07 = 0x40 |
9 | Value of 0x08 = 0x7D |
10 | Value of 0x09 = 0x01 |
11 | Value of 0x0A = 0x76 |
12 | Value of 0x0B = 0x73 |
13 | Value of 0x0C = 0x00 |
14 | Value of 0x0D = 0x00 |
15 | Value of 0x0E = 0x01 |
16 | Value of 0x0F = 0x43 |
17 | Value of 0x10 = 0x7F |
18 | Value of 0x11 = 0x80 |
19 | Value of 0x12 = 0x00 |
20 | Value of 0x13 = 0x8F |
21 | Value of 0x14 = 0x4A |
22 | Value of 0x15 = 0x00 |
23 | Value of 0x16 = 0x00 |
24 | Value of 0x17 = 0x11 |
25 | Value of 0x18 = 0x61 |
26 | Value of 0x19 = 0x03 |
27 | Value of 0x1A = 0x7B |
28 | Value of 0x1B = 0x00 |
29 | Value of 0x1C = 0x7F |
30 | Value of 0x1D = 0xA2 |
31 | Value of 0x1E = 0x01 |
32 | Value of 0x1F = 0x00 |
33 | Value of 0x20 = 0x04 |
34 | Value of 0x21 = 0x02 |
35 | Value of 0x22 = 0x01 |
36 | Value of 0x23 = 0x00 |
37 | Value of 0x24 = 0x75 |
38 | Value of 0x25 = 0x63 |
39 | Value of 0x26 = 0xD4 |
40 | Value of 0x27 = 0x80 |
41 | Value of 0x28 = 0x80 |
42 | Value of 0x29 = 0x07 |
43 | Value of 0x2A = 0x00 |
44 | Value of 0x2B = 0x00 |
45 | Value of 0x2C = 0x80 |
46 | Value of 0x2D = 0x00 |
47 | Value of 0x2E = 0x00 |
48 | Value of 0x2F = 0x72 |
49 | Value of 0x30 = 0x08 |
50 | Value of 0x31 = 0x30 |
51 | Value of 0x32 = 0x80 |
52 | Value of 0x33 = 0x08 |
53 | Value of 0x34 = 0x11 |
54 | Value of 0x35 = 0x1A |
55 | Value of 0x36 = 0x00 |
56 | Value of 0x37 = 0x3F |
57 | Value of 0x38 = 0x01 |
58 | Value of 0x39 = 0x00 |
59 | Value of 0x3A = 0x0D |
60 | Value of 0x3B = 0x00 |
61 | Value of 0x3C = 0x68 |
62 | Value of 0x3D = 0x88 |
63 | Value of 0x3E = 0x00 |
64 | Value of 0x3F = 0x00 |
65 | Value of 0x40 = 0xC0 |
66 | Value of 0x41 = 0x08 |
67 | Value of 0x42 = 0x00 |
68 | Value of 0x43 = 0x14 |
69 | Value of 0x44 = 0xF0 |
70 | Value of 0x45 = 0x45 |
71 | Value of 0x46 = 0x61 |
72 | Value of 0x47 = 0x51 |
73 | Value of 0x48 = 0x79 |
74 | Value of 0x49 = 0x00 |
75 | Value of 0x4A = 0x00 |
76 | Value of 0x4B = 0x00 |
77 | Value of 0x4C = 0x00 |
78 | Value of 0x4D = 0x04 |
79 | Value of 0x4E = 0x00 |
80 | Value of 0x4F = 0x40 |
81 | Value of 0x50 = 0x34 |
82 | Value of 0x51 = 0x0C |
83 | Value of 0x52 = 0x17 |
84 | Value of 0x53 = 0x29 |
85 | Value of 0x54 = 0x40 |
86 | Value of 0x55 = 0x00 |
87 | Value of 0x56 = 0x40 |
88 | Value of 0x57 = 0x80 |
89 | Value of 0x58 = 0x1E |
90 | Value of 0x59 = 0x91 |
91 | Value of 0x5A = 0x94 |
92 | Value of 0x5B = 0xAA |
93 | Value of 0x5C = 0x71 |
94 | Value of 0x5D = 0x8D |
95 | Value of 0x5E = 0x0F |
96 | Value of 0x5F = 0xF0 |
97 | Value of 0x60 = 0xF0 |
98 | Value of 0x61 = 0xF0 |
99 | Value of 0x62 = 0x00 |
100 | Value of 0x63 = 0x00 |
101 | Value of 0x64 = 0x50 |
102 | Value of 0x65 = 0x30 |
103 | Value of 0x66 = 0x00 |
104 | Value of 0x67 = 0x80 |
105 | Value of 0x68 = 0x80 |
106 | Value of 0x69 = 0x00 |
107 | Value of 0x6A = 0x88 |
108 | Value of 0x6B = 0x0A |
109 | Value of 0x6C = 0x02 |
110 | Value of 0x6D = 0x55 |
111 | Value of 0x6E = 0xC0 |
112 | Value of 0x6F = 0x9A |
113 | Value of 0x70 = 0x3A |
114 | Value of 0x71 = 0x35 |
115 | Value of 0x72 = 0x11 |
116 | Value of 0x73 = 0x00 |
117 | Value of 0x74 = 0x00 |
118 | Value of 0x75 = 0x0F |
119 | Value of 0x76 = 0x01 |
120 | Value of 0x77 = 0x10 |
121 | Value of 0x78 = 0x00 |
122 | Value of 0x79 = 0x00 |
123 | Value of 0x7A = 0x24 |
124 | Value of 0x7B = 0x04 |
125 | Value of 0x7C = 0x07 |
126 | Value of 0x7D = 0x10 |
127 | Value of 0x7E = 0x28 |
128 | Value of 0x7F = 0x36 |
129 | Value of 0x80 = 0x44 |
130 | Value of 0x81 = 0x52 |
131 | Value of 0x82 = 0x60 |
132 | Value of 0x83 = 0x6C |
133 | Value of 0x84 = 0x78 |
134 | Value of 0x85 = 0x8C |
135 | Value of 0x86 = 0x9E |
136 | Value of 0x87 = 0xBB |
137 | Value of 0x88 = 0xD2 |
138 | Value of 0x89 = 0xE5 |
139 | Value of 0x8A = 0x00 |
140 | Value of 0x8B = 0x00 |
141 | Value of 0x8C = 0x00 |
142 | Value of 0x8D = 0x0F |
143 | Value of 0x8E = 0x00 |
144 | Value of 0x8F = 0x00 |
145 | Value of 0x90 = 0x00 |
146 | Value of 0x91 = 0x00 |
147 | Value of 0x92 = 0x00 |
148 | Value of 0x93 = 0x00 |
149 | Value of 0x94 = 0x50 |
150 | Value of 0x95 = 0x50 |
151 | Value of 0x96 = 0x01 |
152 | Value of 0x97 = 0x01 |
153 | Value of 0x98 = 0x10 |
154 | Value of 0x99 = 0x40 |
155 | Value of 0x9A = 0x40 |
156 | Value of 0x9B = 0x20 |
157 | Value of 0x9C = 0x00 |
158 | Value of 0x9D = 0x99 |
159 | Value of 0x9E = 0x7F |
160 | Value of 0x9F = 0xC0 |
161 | Value of 0xA0 = 0x90 |
162 | Value of 0xA1 = 0x03 |
163 | Value of 0xA2 = 0x02 |
164 | Value of 0xA3 = 0x02 |
165 | Value of 0xA4 = 0x00 |
166 | Value of 0xA5 = 0x0F |
167 | Value of 0xA6 = 0xF0 |
168 | Value of 0xA7 = 0xC1 |
169 | Value of 0xA8 = 0xF0 |
170 | Value of 0xA9 = 0xC1 |
171 | Value of 0xAA = 0x14 |
172 | Value of 0xAB = 0x0F |
173 | Value of 0xAC = 0x00 |
174 | Value of 0xAD = 0x80 |
175 | Value of 0xAE = 0x80 |
176 | Value of 0xAF = 0x80 |
177 | Value of 0xB0 = 0x00 |
178 | Value of 0xB1 = 0x00 |
179 | Value of 0xB2 = 0x00 |
180 | Value of 0xB3 = 0x80 |
181 | Value of 0xB4 = 0x00 |
182 | Value of 0xB5 = 0x04 |
183 | Value of 0xB6 = 0x00 |
184 | Value of 0xB7 = 0x66 |
185 | Value of 0xB8 = 0x00 |
186 | Value of 0xB9 = 0x06 |
187 | Value of 0xBA = 0x00 |
188 | Value of 0xBB = 0x00 |
189 | Value of 0xBC = 0x00 |
190 | Value of 0xBD = 0x00 |
191 | Value of 0xBE = 0x00 |
192 | Value of 0xBF = 0x00 |
193 | Value of 0xC0 = 0x00 |
194 | Value of 0xC1 = 0x00 |
195 | Value of 0xC2 = 0x00 |
196 | Value of 0xC3 = 0x00 |
197 | Value of 0xC4 = 0x00 |
198 | Value of 0xC5 = 0x00 |
199 | Value of 0xC6 = 0x00 |
200 | Value of 0xC7 = 0x00 |
201 | Value of 0xC8 = 0x06 |
202 | Value of 0xC9 = 0xC0 |
203 | Value of 0xCA = 0xC0 |
204 | Value of 0xCB = 0xC0 |
205 | Value of 0xCC = 0xC0 |
206 | Value of 0xCD = 0xC0 |
207 | Value of 0xCE = 0xC0 |
208 | Value of 0xCF = 0xC0 |
209 | Value of 0xD0 = 0xC0 |
210 | Value of 0xD1 = 0xC0 |
211 | Value of 0xD2 = 0x88 |
212 | Value of 0xD3 = 0x88 |
213 | Value of 0xD4 = 0x88 |
214 | Value of 0xD5 = 0x88 |
215 | Value of 0xD6 = 0x88 |
216 | Value of 0xD7 = 0x88 |
217 | Value of 0xD8 = 0x88 |
218 | Value of 0xD9 = 0x88 |
219 | Value of 0xDA = 0x88 |
220 | Value of 0xDB = 0x88 |
221 | Value of 0xDC = 0x1A |
222 | Value of 0xDD = 0x1A |
223 | Value of 0xDE = 0x1A |
224 | Value of 0xDF = 0x1A |
225 | Value of 0xE0 = 0x1A |
226 | Value of 0xE1 = 0x1A |
227 | Value of 0xE2 = 0x1A |
228 | Value of 0xE3 = 0x1A |
229 | Value of 0xE4 = 0x1A |
230 | Value of 0xE5 = 0x88 |
231 | Value of 0xE6 = 0x88 |
232 | Value of 0xE7 = 0x88 |
233 | Value of 0xE8 = 0x88 |
234 | Value of 0xE9 = 0x88 |
235 | Value of 0xEA = 0x88 |
236 | Value of 0xEB = 0x88 |
237 | Value of 0xEC = 0x88 |
238 | Value of 0xED = 0x88 |
239 | Value of 0xEE = 0x1A |
240 | Value of 0xEF = 0x1A |
241 | Value of 0xF0 = 0x1A |
242 | Value of 0xF1 = 0x1A |
243 | Value of 0xF2 = 0x1A |
244 | Value of 0xF3 = 0x1A |
245 | Value of 0xF4 = 0x1A |
246 | Value of 0xF5 = 0x1A |
247 | Value of 0xF6 = 0x1A |
248 | Value of 0xF7 = 0x1A |
249 | Value of 0xF8 = 0x88 |
250 | Value of 0xF9 = 0x88 |
251 | Value of 0xFA = 0x88 |
252 | Value of 0xFB = 0x88 |
253 | Value of 0xFC = 0x88 |
254 | Value of 0xFD = 0x88 |
255 | Value of 0xFE = 0x88 |
256 | Value of 0xFF = 0x88 |
:
Bearbeitet durch User
Okay, dann hab ich bei mir offensichtlich noch ein Problem. Ich werde nochmal den Aufbau überprüfen und mich dann nochmal melden, entweder mit dem gefundenen Fehler oder ein paar Fotografien zur Fehleranalyse mit euch :D Edit: Habe den Fehler gefunden... aber es ist mir zu peinlich zuzugeben, dass ich bei meinem Terminal Programm vergessen habe die Baudrate anzupassen xD.... Damit bin ich mit dir auf einem Nenner, manche Register zeigen zu deinen zwar Abweichungen, aber ich habe auch die 76 und die 73 in 0A und 0B > Was ich noch nicht finde ist die tatsächliche Slave-ID. Im Datenblatt > steht: auf Seite 10 "The device slave addresses are 42 for write and 43 > for read.". Leider weder ob das Dezimal oder Hexadezimaladressen sind, > es ist auch anders als in den Arduino Beispielcodes zu finden, da wird > für Read und Write diesselbe Adresse verwendet, nämlich 0x21. Da kann ich Licht ins Dunkle bringen. Das ist nämlich bei beiden das gleiche ;-) nur das im Datenblatt offensichtlich das Lese bzw. Schreib Bit dazugezählt wird, also das R/W-Bit Sprich der Aufbau ist ja: Die ersten 7 Bit sind die Adresse und das 8. Bit ist schreiben/lesen. Wenn jetzt die Adresse 0x21 ist, man die aber einmal nach Links shiftet um das 8. Bit noch anhängen zu können erhält man: 0x42 (Multiplikation mit 2) jetzt ist das R/W bit beim schreiben 0 sprich wir bleiben bei 0x42 und beim lesen 1 womit wir bei der 0x43 wären. Ich hoffe das ist soweit verständlich ausgedrückt.
:
Bearbeitet durch User
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 | char c = Wire.read(); |
8 | ...
|
9 | }
|
Der erste Teil löst einen 2-Phase-Write aus und schreibt nur Slave-ID und Register-Adresse die man lesen möchte. Das nachfolgende "requestFrom()" löst einen 2-Phase-Read aus. Dieser übermittelt die Slave-ID (erster Parameter) und die Anzahl der zu lesenden Bytes (zweiter Parameter im Funktionsaufruf). Jetzt müssen wir warten bis die Daten vom Slave im Eingangspuffer des I2C-Controllers stehen. Hierfür ist die erste Dummy-While-Schleife mit "Wire.available() == 0". Ja, das ist unsauber, weil es die Programmausführung blockiert und sich der Atmega hier aufhängen würde, käme nie eine Antwort vom Slave. In der Realität würde man hier eher Events bevorzugen und mittels "Wire.onReceive(handler)" einbauen. Im Prinzip könnte man sich die nachfolgende While-Schleife um "Wire.read()" sparen und durch ein einzelnes read ersetzen, weil wir ja genau ein Byte angefragt haben. Das ist hier nur zur Sicherheit, falls der Client doch mal mehr oder weniger Bytes sendet als erwartet. Um anstelle von Bytewerten mit Register- und Wertenamen arbeiten zu können, sollten wir das benötigte per "#define" Deklaration bekannt geben. Z.B.:
1 | #define OV7670_I2C_ID 0x21
|
2 | #define OV7670_PID 0x76
|
3 | #define OV7670_COM7 0x12
|
4 | #define OV7670_RESET 0x80
|
So, das müsste im groben und ganzen alles sein was wir zur Kommunikation mit dem OV-Chip benötigen. Hab ich was vergessen?
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.
1 | /*
|
2 | * main.cpp
|
3 | *
|
4 | * Created: 23.07.2017 17:35:15
|
5 | * Author: David
|
6 | */
|
7 | |
8 | #ifndef F_CPU
|
9 | #define F_CPU 16000000
|
10 | #endif
|
11 | |
12 | #include <avr/io.h> |
13 | #include <avr/interrupt.h> |
14 | |
15 | #include "OV7670.h" |
16 | #include "OV7670.c" |
17 | |
18 | #include "UART.h" |
19 | |
20 | int main(void) |
21 | |
22 | {
|
23 | sei(); |
24 | UART0_init(); |
25 | OV7670_init(); |
26 | |
27 | int RowCount = 0; |
28 | bool VSync_Flag=false; |
29 | bool HREF_Flag=false; |
30 | while (1) |
31 | {
|
32 | if(((OV_VSYNC_PIN>>OV_VSYNC_PINNR)&(0x01))&&(VSync_Flag==false)) |
33 | {
|
34 | VSync_Flag=true; |
35 | UART0_senden_zahl(RowCount); |
36 | UART0_senden_Byte(13); |
37 | UART0_senden_Byte(10); |
38 | RowCount=0; |
39 | }
|
40 | if(!((OV_VSYNC_PIN>>OV_VSYNC_PINNR)&(0x01))&&(VSync_Flag==true)) |
41 | {
|
42 | VSync_Flag=false; |
43 | RowCount=0; |
44 | }
|
45 | |
46 | if(((OV_HREF_PIN>>OV_HREF_PINNR)&(0x01))&&(HREF_Flag==false)) |
47 | {
|
48 | HREF_Flag=true; |
49 | RowCount++; |
50 | }
|
51 | |
52 | if(!((OV_HREF_PIN>>OV_HREF_PINNR)&(0x01))&&(HREF_Flag==true)) |
53 | {
|
54 | HREF_Flag=false; |
55 | }
|
56 | }
|
57 | return 0; |
58 | }
|
Zur Vorgehensweise würde ich als erstes Versuchen die Frequenz runter zu nehmen, also PCLK zu verringern und zu schauen, ob es Wirkung zeigt. Verstehe ich es richtig, dass dann auch die V-Sync und HREF Frequenzen runter gehen? Die nötigen Register hierfür wären 0x11 und 0x6B, wobei ich letzteres nicht ganz verstehe.
Die HREF und VSYNC ändern sich bei der fallenden Flanke von PCLK, sind also synchron zum Takt.
Wir sollten kurz das Pinout klären, damit wir auch auf einem Nenner bleiben :-) Das Problem beim Nano ist, das nur relativ wenig IO-Pins zur Verfügung stehen. Leider haben wir nichtmal einen kompletten 8-Bit Port für die Videodaten zur Verfügung. Port D ist mit 2 Bit am UART und fällt damit flach, sonst haben wir keine Debug-Schnittstelle. Einzige Alternative wäre hier SoftSerial und zwei andere Pins nehmen. Dann müsste man den Nano aber wohl besser über ISP flashen. Habe das jetzt erstmal so vorgesehen:
1 | * OV7670 Dir Arduino Meaning |
2 | * 3v3 <- 3V3 Vcc (+3,3V) |
3 | * GND <- GND GND |
4 | * SIOC <- A5 SCL (I2C clock) !USE LEVEL-SHIFTER! |
5 | * SIOD <- A4 SDA (I2C data) !USE LEVEL-SHIFTER! |
6 | * XCLK <- D2 System-Clock !USE LEVEL-SHIFTER! |
7 | * RESET <- 3V3 Reset fixed for testing |
8 | * PWDN <- GND Power-Down fixed for testing |
9 | * HREF -> A6 Start of new line in Videoframe |
10 | * VSYNC -> A7 Start of new Videoframe |
11 | * PCLK <- D3 Pixel clock !USE LEVEL-SHIFTER! |
12 | * D0 -> A0 Videodata LSB |
13 | * D1 -> A1 Videodata |
14 | * D2 -> A2 Videodata |
15 | * D3 -> A3 Videodata |
16 | * D4 -> D4 Videodata |
17 | * D5 -> D5 Videodata |
18 | * D6 -> D6 Videodata |
19 | * D7 -> D7 Videodata MSB |
Ich hab das Datenwort in ein low- und high-nibble geteilt und damit es einfach einzulesen ist, das lower auf Bit 0-3 von Port C (A0-A3) und das higher auf Bit 4-7 von Port D (D4-D7). So müssen wir nur beide Ports lesen, maskieren und oder-verknüpfen.
:
Bearbeitet durch User
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 | * OV7670 Dir Arduino Meaning |
2 | * 3v3 <- 3V3 Vcc (+3,3V) |
3 | * GND <- GND GND |
4 | * SIOC <- A5 SCL (I2C clock) !USE LEVEL-SHIFTER! |
5 | * SIOD <- A4 SDA (I2C data) !USE LEVEL-SHIFTER! |
6 | * XCLK <- D3 System-Clock !USE LEVEL-SHIFTER! |
7 | * RESET <- 3V3 Reset fixed for testing |
8 | * PWDN <- GND Power-Down fixed for testing |
9 | * HREF -> A0 Start of new line in Videoframe |
10 | * VSYNC -> A1 Start of new Videoframe |
11 | * PCLK -> A2 Pixel clock |
12 | * D0 -> D8 Videodata LSB |
13 | * D1 -> D9 Videodata |
14 | * D2 -> D10 Videodata |
15 | * D3 -> D11 Videodata |
16 | * D4 -> D4 Videodata |
17 | * D5 -> D5 Videodata |
18 | * D6 -> D6 Videodata |
19 | * D7 -> D7 Videodata MSB |
> D8-D11 wäre dann der PORTB 0-3 > und D4-D7 wäre PORTD 4-7 Um ein Datenbyte zu lesen wär dann nur sowas nötig:
1 | c = (PORTD & 0b11110000) | (PORTB & 0b00001111); |
> Weiterhin habe ich HREF und VSYNC auf A0 und A1 geholt, weil es A6 und > A7 auf dem UNO nicht nach außen geführt gibt. Stimmt! Hab ich komplett übersehen, bzw. nicht quer geprüft. A6+A7 sind Analog-Only und fallen eh flach. > Bist du damit einverstanden oder übersehe ich was? Ich glaub wir habens fast ;-)
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 | * OV7670 Dir Arduino Meaning |
2 | * 3v3 <- 3V3 Vcc (+3,3V) |
3 | * GND <- GND GND |
4 | * SIOC <- A5 SCL (I2C clock) !USE LEVEL-SHIFTER! |
5 | * SIOD <- A4 SDA (I2C data) !USE LEVEL-SHIFTER! |
6 | * XCLK <- D3 System-Clock !USE LEVEL-SHIFTER! |
7 | * RESET <- 3V3 Reset fixed for testing |
8 | * PWDN <- GND Power-Down fixed for testing |
9 | * HREF -> A0 Start of new line in Videoframe |
10 | * VSYNC -> A1 Start of new Videoframe |
11 | * PCLK -> D3 Pixel clock |
12 | * D0 -> D8 Videodata LSB |
13 | * D1 -> D9 Videodata |
14 | * D2 -> D10 Videodata |
15 | * D3 -> D11 Videodata |
16 | * D4 -> D4 Videodata |
17 | * D5 -> D5 Videodata |
18 | * D6 -> D6 Videodata |
19 | * D7 -> D7 Videodata MSB |
>> D8-D11 wäre dann der PORTB 0-3 >> und D4-D7 wäre PORTD 4-7 > Um ein Datenbyte zu lesen wär dann nur sowas nötig:
1 | > c = (PORTD & 0b11110000) | (PORTB & 0b00001111); |
2 | >
|
richtig, das sollte mit dem Maskieren eigentlich recht einfach gehen. >> Weiterhin habe ich HREF und VSYNC auf A0 und A1 geholt, weil es A6 und >> A7 auf dem UNO nicht nach außen geführt gibt. > Stimmt! Hab ich komplett übersehen, bzw. nicht quer geprüft. A6+A7 sind > Analog-Only und fallen eh flach. Jetzt sind wir hoffentlich schon fast d'accord :-) @Michael Ich glaube, dass du da recht hast, aber es war bisher ja nur ein erster Gedanke und Entwurf von Olli. Aber ich habe es mal in der Liste der zu behandelnden Punkte geschrieben.
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?
Hi Leute, ich habe vor ein paar Monaten die OV7670 an meinem STM32 ARM ans Laufen gebracht: Beitrag "Camera OV7670: Register Settings für Farbbilder gesucht" Dasselbe auf dem ATmega stelle ich mir sehr herausfordernd vor,... Zuerst wollte ich mir ebenfalls alles selber erschließen, aber die Doku zu dem Teil ist so schlecht, dass man wirklich beliebig viel Zeit vergeuden kann, bis alles richtig läuft. Diese Zeit war mir dann irgendwann zu schade und ich habe bei anderen "abgespickt". Ich würde Euch nun natürlich gerne mit ein paar Tipps versorgen, habe dummerweise aktuell aber Null Zeit. Daher hier nur auf die Schnelle meine Quellen, die mir seinerzeit sehr geholfen hatten: Zum Allgemeinen Verständnis: http://embeddedprogrammer.blogspot.de/2012/07/hacking-ov7670-camera-module-sccb-cheat.html http://embeddedprogrammer.blogspot.de/2013/01/demo-stm32f4-ov7670-qserialterm.html SCCB: https://e2e.ti.com/support/embedded/linux/f/354/p/171390/862562#862562 https://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/99/t/120548 http://embeddedprogrammer.blogspot.de/2012/07/hacking-ov7670-camera-module-sccb-cheat.html https://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/99/p/6092/22820#22820 http://forum.arduino.cc/index.php?topic=195642.msg1446591#msg1446591 https://electronics.stackexchange.com/questions/259119/ov7670-omnivision-sccb-read-sequence-issue Die functional specification: http://www4.cs.umanitoba.ca/~jacky/Teaching/Courses/74.795-LocalVision/ReadingList/ov-sccb.pdf Der Implementation Guide: http://www.haoyuelectronics.com/Attachment/OV7670%20+%20AL422B%28FIFO%29%20Camera%20Module%28V2.0%29/OV7670%20Implementation%20Guide%20%28V1.0%29.pdf Wie ich lese, kämpft Ihr aktuell noch mit dem SCCB-Protokoll - da ist die Doku sogar noch halbwegs verständlich und vollständig. Spätestens wenn Ihr Euch mit den dutzenden Registern und ihren teils undokumentierten Werten und Bedeutungen herumschlagt, werdet Ihr evtl. auch zu meiner Erkenntnis kommen: die Doku ist Schrott und selber ausprobieren macht kaum Sinn, wenn's andere vor einem schon durch wochenlanges Herumprobieren herausbekommen haben. Selbst dann ist der Weg noch hinreichend steinig ... Good luck Euch! Viele Grüße Igel1
David D. schrieb: > Der Vorteil an D3 ist, dass der Pin Interrupt fähig ist. Wenn wir es Gutes Argument. Das wäre bei der Verarbeitung der PCLK sicher hilfreich. Sehe grad das ich D3 in meinem Pinout zweimal geschrieben hab. Aber wo wir grad bei Interrupts sind, viellecht setzen wir erstmal nochmal da an, bevor wir das Pinout festzurren. Wir müssen ja PCLK (24 MHz laut Datenblatt), HSYNC (ca. 32 kHz) und VSYNC (50-60 Hz) verarbeiten. Ich würde vorschlagen wir tasten VSYNC ab bis wir einen Bildstart erkennen und setzen ein Flag. Bei jedem HSYNC müssen wir eine Bildzeile einlesen. Dafür brauchen wir soviel Power vom kleinen Atmega das wir vermutlich zu nichts anderem kommen werden?! Das wäre doch was für den Interrupt. Den PCLK können wir für den Interrupt eh nutzen, da er viel zu schnell ist. Bitte Vorschläge hierzu :-) P.S. An alle die ab jetzt erst mitlesen die Info: Wir wollen keine fertigen Lösungen sondern unsere eigene erarbeiten. Warum? Um genau auf all die vielen kleinen Details zu kommen die es bei einem solchen Design zu beachten gilt :-)
:
Bearbeitet durch User
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?
:
Bearbeitet durch User
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ö
:
Bearbeitet durch User
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 | volatile unsigned int i=0; |
22 | //unsigned char myBytes[100];
|
23 | bool interruptFlag =false; |
24 | int main(void) |
25 | {
|
26 | sei(); |
27 | |
28 | UART0_init(); |
29 | OV7670_init(); |
30 | OV7670_checkConnection(); |
31 | |
32 | |
33 | //Reduce frequency of PCLK
|
34 | char ReadData =0; |
35 | char MASK = ~0x80; |
36 | char WriteData; |
37 | //Read the RCLK Register to get the internal Clock
|
38 | OV7670_read(OV_SCCB_CLKRC,&ReadData); |
39 | UART0_senden_Byte(ReadData); |
40 | UART0_newLine(); |
41 | |
42 | //Reduce PCLK by Prescaler
|
43 | OV7670_write(OV_SCCB_CLKRC,0x0F); |
44 | |
45 | //Check if change succed
|
46 | OV7670_read(OV_SCCB_CLKRC,&ReadData); |
47 | UART0_senden_Byte(ReadData); |
48 | UART0_newLine(); |
49 | |
50 | //Change Format to QCIF and YUV
|
51 | OV7670_read(OV_SCCB_COM7,&ReadData); |
52 | MASK = ReadData & 0b01000000; |
53 | MASK |= 0x08; |
54 | ReadData |= MASK; |
55 | OV7670_write(OV_SCCB_COM7,ReadData); |
56 | |
57 | //activate Skaling
|
58 | OV7670_read(OV_SCCB_COM3,&ReadData); |
59 | ReadData|=0x08; |
60 | OV7670_write(OV_SCCB_COM3,ReadData); |
61 | |
62 | //Activate DCW and scaling PCLK enable (neccessary for Divide PCLK) and Divide PCLK by 16
|
63 | OV7670_read(OV_SCCB_COM14,&ReadData); |
64 | ReadData|=0x1C; |
65 | OV7670_write(OV_SCCB_COM14,ReadData); |
66 | |
67 | //deactivate PCLK during HREF Blank
|
68 | OV7670_read(OV_SCCB_COM10,&ReadData); |
69 | ReadData|=0x20; |
70 | OV7670_write(OV_SCCB_COM10,ReadData); |
71 | |
72 | //Scaling PCLK
|
73 | OV7670_read(OV_SCCB_SCALING_PCLK,&ReadData); |
74 | ReadData &=~(0x0F); |
75 | ReadData |=0x04; |
76 | OV7670_write(OV_SCCB_SCALING_PCLK,ReadData); |
77 | |
78 | //set Variables and Flags
|
79 | i=0; |
80 | interruptFlag=false; |
81 | bool HREF_Flag=false; |
82 | |
83 | volatile int j=0; |
84 | //Setup interrupt pin
|
85 | EICRA |= (0b00000011); //Interrupt at Int0-Pin at positiv change |
86 | EIMSK &= ~(0b00000001); //Disable Int0-Pin |
87 | |
88 | while (1) |
89 | {
|
90 | //start conditions for external interrupt (Wait until HREF is LOW to make sure to get a complete Line)
|
91 | if((!((OV_HREF_PIN>>OV_HREF_PINNR)&(0x01)))&&(HREF_Flag==false)) |
92 | {
|
93 | i=0; |
94 | j=0; |
95 | EIMSK |= 0b00000001; //Enable Int0-Pin |
96 | }
|
97 | |
98 | //Count PCLK in Line
|
99 | if(((OV_HREF_PIN>>OV_HREF_PINNR)&(0x01))&&(interruptFlag==true)) |
100 | {
|
101 | j++; //Count the Interrupts in the Main-Loop (Test if j and i have the same value) |
102 | interruptFlag=false; |
103 | HREF_Flag=true; //indicate a period of HREF |
104 | }
|
105 | |
106 | //Disable Interrupt after One Line
|
107 | if((!((OV_HREF_PIN>>OV_HREF_PINNR)&(0x01)))&&(HREF_Flag==true)) |
108 | {
|
109 | EIMSK &= ~0b00000001; //Disable Int0-Pin |
110 | }
|
111 | |
112 | }
|
113 | return 0; |
114 | }
|
115 | |
116 | |
117 | ISR(INT0_vect){ |
118 | cli(); |
119 | PORTB |= 0x20; //Just for measuring at oscilloscope |
120 | interruptFlag=true; |
121 | i++; |
122 | PORTB&= ~(0x20); |
123 | sei(); |
124 | }
|
Derzeit stellt es sich wie folgt da: Führe ich den Code wie oben dargestellt aus (und setzte einen Breakpoint in der letzten If-Schleife, so zählt der Zähler nur bis eins, was für mich absolut unverständlich ist. Die interrupts kann ich nach wie vor durch Pin 13 nicht detektieren, was mir ebenso nicht einleuchten will. Kommentiere ich die letzte if-Schleife aus und pausiere willkürlich über den Debug-Mode, haben beide Zähler den gleichen Wert. (Ich habe aber das gefühl, dass sie zu langsam hochzählen) Trotzdem sehe ich die ISR-Routine nicht auf dem Oszi. von Michael kam folgender Beitrag: >Ich wollte auch mehr darauf hinaus, daß es für das konrete Projekt nicht >wirklich etwas zwischen dem Einlesen von 2 Pixeln zu tun gibt. >Wenn man also eine Zeile komplett in einer HSync-ISR einliest und >zwischenspeichert, erspart man sich mögliche Timingprobleme mit einer >PCLK-ISR erstmal ganz. Da stimme ich grob erstmal mit dir überein. Für mich stellt sich dann aber die Frage, wie ich die PCLK-Flanken dann detektiere, um dann jeweils das anliegende Byte zu übernehmen. Wie kann ich soetwas denn abbilden? Die ISR wird doch nur einmal durchlaufen. Lasse mich da gerne belehren :) Auf den Beitrag von Igel1 bezogen: >... >Und das Beste: so ein ARM-Prozessor kommt mit einem "Hardware- >Debugger" daher - man kann seine Programme also Schritt für >Schritt debuggen - nicht im (buggy Atmel-)Simulator, sondern >nativ auf der Hardware (inkl. Register-Auslesen und Pi-Pa-Po) über das Debug-Wire und dem Dragon kann ich doch auch die Hardware direkt debuggen und auch die Register lesen inkl. Eingänge. Oder liege ich da falsch? Im Prinzip hast du vermutlich recht, dass dein Vorgeschlagener Controller für diese Anwendung besser geeignet ist. Ich habe mich aber damals für die Arduino (Atmel) Reihe entschieden und auch bisher nur damit Erfahrungen gemacht. Jetzt auf einen anderen Umzusteigen würde mich (zumindest für den Anfang) wieder auf null zurückwerfen. Dafür fehlt mir leider noch etwas die Zeit und die Motivation. Mir ist bewusst, dass ich mit dem Atmega328 keine videos darstellen werden kann. Für mich geht es aber, wie Michael auch schon erkannt hat: >Wozu also das Ganze? Man lernt Datenblätter zu lesen, man lernt I2C >kennen, man lernt es, das Zeitverhalten eines System in Hardwarenähe zu >beachten. >Das hilft aber auch auf anderen Systemen bei anderen Aufgaben. Mir reicht es tatsächlich zunächst ersteinmal ein Foto zusammengesetzt zu bekommen. Das ich danach in Ruhe weiterverarbeiten kann. Ich habe in ferner Zukunft damit dann vor, eine Art von Sortierer zu bauen. Wie gesagt, ferne Zukunft :D ab dem Sommer habe ich auch privat etwas mehr Zeit und dann kann man sich den Schwenk auf einen ARM-Prozessor ja nochmal überlegen. :) Dann noch der interessante letzte Beitrag von Igel1: >Kurzum: Ein Polling-Mechanismus wäre vermutlich besser geeignet, um die >Pixel aus der Kamera in das RAM einzulesen. Polling sagte mir bis zur Erstellung von diesem Beitrag noch nichts. Sollte ich das eher mit einer While-Schleife oder If-Schleifen lösen? (Mein verständnis von Polling ist "aktives" Warten, bin ich da richtig?) Ich hoffe ihr könnt mir sagen, wo ich in obrigem Code einen Denkfehler habe? Es ist ja nun wirklich noch keine hochkomplizierte Angelegenheit und ich weiß einfach nicht wo das Problem liegt. vielen Dank für eure Hilfe! sonnige Grüße David
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:
1 | if((!((OV_HREF_PIN>>OV_HREF_PINNR)&(0x01)))&&(HREF_Flag==false)) |
Ich hätte so etwas erwartet:
1 | if( !(OV_HREF_PIN & (1 << OV_HREF_PINNR)) && (HREF_Flag==false)) |
Außerdem wäre es gut, wenn Du den gesamten Code hier einstellst/anhängst. So fehlt z.B. die Definition von OV_HREF_PIN in Deinem Code-Fragment. Viele Grüße Igel1
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
Andreas S. schrieb: > Ich hätte so etwas erwartet: > if( !(OV_HREF_PIN & (1 << OV_HREF_PINNR)) && (HREF_Flag==false)) Ich hätte eher sowas erwartet:
1 | if( bit_is_clear( OV_HREF_PIN, OV_HREF_PINNR) && (HREF_Flag==false)) |
Aus welchem Grund auch immer diese Makros nicht empfohlen werden: https://www.mikrocontroller.net/articles/Bitmanipulation#Hilfsfunktionen_als_C-Makro_.28nicht_empfohlen.29 Ich finde: Lesebarer Code hat oberste Priorität.
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! :-)
:
Bearbeitet durch User
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“.
David, könntest Du mir mal kurz erklären wie ich das mit dem Debug-Wire aufsetze? Welche AVR IDE benutzt Du?
@Victor: Yep, Dein Makro sieht tatsächlich etwas schöner aus. Gründe, die gegen so ein Makro sprechen, fallen mir ebenfalls nicht ein, was nicht heißt, dass es eventuell doch welche gibt. Ich selbst bevorzuge daher immer "mainstream coding style". Ist halt etwas Geschmackssache. @OV7670-Kämpfer: Olli schlug vor: > Sollen wir mal versuchen einen Programmablauf zu skizzieren und > Unterfunktionen zu nennen, die man dann mit Code füllen kann? Ich denke > mit diesem Gedankengerüst kommt man schneller zum Ziel, weil es uns > etwas „zusammenhält“. Mit Blick auf die arg beschränkten AVR-Ressourcen, würde ich ein Polling zum Einlesen einer beliebigen Zeile vorschlagen. Und da das RAM des ATmega bereits nach dem Einlesen von nur einer Zeile randvoll sein dürfte, würde ich nach dem Einlesen der Zeile (evtl. sogar schon während des Einlesens), die gelesenen Werte an den PC (oder an mein TFT-Display) versenden. Erst wenn das erledigt ist, kann ich die nächste Zeile einlesen. Dabei sollte mir bewußt sein, dass ich mich zu diesem Zeitpunkt vermutlich schon X-Zeilen weiter im Frame befinde und daher die nächste Zeile im folgenden Frame abpassen muß. Der Ablauf wäre also:
1 | N=0 |
2 | while (N < Zeilenzahl_eines_Frames) { |
3 | Framebeginn abpassen |
4 | Alle Pixel der N.-ten Zeile einlesen |
5 | Alle Pixel der N.-ten Zeile ausgeben |
6 | N = N+1 |
7 | } |
Das Einlesen aller Pixel der N.-ten Zeile würde ich wie folgt angehen: Zunächst einen scharfen Blick auf die Abbildungen "Horizontal Synchronization" und "VGA timing" aus meiner Lieblings-OV7670-Page werfen: http://embeddedprogrammer.blogspot.de/2012/07/hacking-ov7670-camera-module-sccb-cheat.html Oder Direktlinks: http://2.bp.blogspot.com/-K-OIuy-inUU/UA2gp3SYgYI/AAAAAAAAAPg/Gure3RWI8G4/s1600/href.png http://3.bp.blogspot.com/-cjOYTMj4C4M/UA2kV-db8GI/AAAAAAAAAPs/rtCGSIGjOHo/s1600/vga.png Daraus läßt sich entnehmen: - Die erste Zeile eines Frames beginnt, wenn VSYNC von Hi auf Low geht - Die Zeile N beginnt, wenn HREF genau zum N.ten mal von Low auf Hi geht - Die jeweiligen Pixel einer Zeile stehen bereit, wenn PCLK von Low auf Hi geht - Die Zeile ist beendet, wenn HREF auf Low geht Daraus ergibt sich folgender Pseudo-Code:
1 | // Zunächst warten wir auf den Beginn eines neuen Frames |
2 | // (sprich: VSYNC soll von Hi auf Low springen ...) |
3 | |
4 | while (VSYNC == LOW) {} // alten Frame auslaufen lassen ... |
5 | while (VSYNC == HI) {} // Hi-Schulter abwarten ... |
6 | |
7 | // Wenn Du hier ankommst, ist VSYNC von Hi auf Low |
8 | // gesprungen => Framestart |
9 | |
10 | // Nun pickst Du Dir die N-te Zeile raus (hier: nline) ... |
11 | // (Notiz: wir zählen ab 0, d.h. die erste Zeile ist nline=0) |
12 | |
13 | linecnt = 0 |
14 | |
15 | while (nline > linecnt) { |
16 | while (HREF == LOW) {} |
17 | linecnt ++ |
18 | while (HREF == HI) {} |
19 | } |
20 | |
21 | // Wenn Du hier ankommst, ist gerade die (N-1)-te Zeile vorbei |
22 | // und HREF ist von Hi auf Low gesprungen |
23 | |
24 | // Jetzt geht's ans Einlesen der N-ten Zeile ... |
25 | // Pixel-Zählung beginnt bei 0 |
26 | |
27 | pixelcnt = 0 |
28 | |
29 | wunschcode1 // Minimal Zeit, um Wunschcode auszuführen |
30 | while (HREF == LOW) {} // Erst die Low-Schulter zum Zeilen- |
31 | // beginn abwarten |
32 | |
33 | while (HREF == HIGH) { |
34 | wunschcode2 // Während der PCLK-Low-Schulter ist |
35 | // minimal Zeit, um Wunschcode auszuführen |
36 | while (PCLK == LOW) {} // Warten auf Pixeldaten |
37 | pixel[pixelcnt] = OV7670_data // Daten einlesen |
38 | // Nicht vergessen: Bei YCrCb422 besteht |
39 | // ein Pixel aus 2 Bytes. Das pixel-Array |
40 | // wird als 2-mal so lang wie die Anzahl |
41 | // der Pixel in einer Zeile (oder man |
42 | // wirft die Farbinfos weg und nimmt nur |
43 | // den Y-Wert. |
44 | pixelcnt++ |
45 | wunschcode3 // Minimal Zeit, um Wunschcode auszuführen |
46 | while (PCLK == HIGH) {} |
47 | wait(tphl) // Etwas warten, da HREF nach dem letzten |
48 | // Pixel erst um tphl verzögert auf Low |
49 | // geht |
50 | } |
51 | |
52 | pixelarray_ausgeben(pixel) |
Zu beachten:
1 | T(wunschcode1) < 144 * tp // tp: siehe Timing-Diagramme |
2 | T(wunschcode2) < (1/2 * tp - tphl) |
3 | T(wunschcode3) < (1/2 * tp) |
Soweit mein Vorschlag. Wie immer gilt: bitte nicht ohne genaues Nachprüfen übernehmen, denn alles ist ungetestet und der Code ist ausschließlich aus den TimingDiagrammen abgeleitet. Da ist bestimmt noch das eine oder andere Schnitzerchen drin ... Viele Grüße Igel1
:
Bearbeitet durch User
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:
1 | 1.) PCLK einstellen |
2 | Prescaler-Register OV_SCCB_CLKRC (0x11) auf "Disable Double clock (Bit7=0)", "Prescale external clock (Bit6=0)", "durch 16 teilen (Bit0-5=01111)" (=0b0000 1111, =0x0F) stellen |
3 | 2.) Bildformat QCIF und RGB. |
4 | Register COM7 (0x12) mit Wert 0b0001 0100 laden. |
5 | 3.) Skalierung einstellen |
6 | Register COM3 (0x0C) mit Wert 0b0000 1000 laden. |
>
1 | > N=0 |
2 | > while (N < Zeilenzahl_eines_Frames) { |
3 | > Framebeginn abpassen |
4 | > Alle Pixel der N.-ten Zeile einlesen |
5 | > Alle Pixel der N.-ten Zeile ausgeben |
6 | > N = N+1 |
7 | > } |
8 | > |
Du würdest also dadurch "Zeit schinden" indem Du einfach nur eine Zeile pro Frame liest und überträgst? Ok, für den Anfang eine durchaus brauchbare Methode. Da hat man vermutlich genug Zeit die Daten an den PC zu bekommen. > - Die erste Zeile eines Frames beginnt, > wenn VSYNC von Hi auf Low geht Verstanden und bestätigt. > - Die Zeile N beginnt, > wenn HREF genau zum N.ten mal von Low auf Hi geht Verstanden und bestätigt. Laut Timingtabelle ist das nach 17*PCLK, also 340us der Fall. Wir haben also von der Erkennung der fallenden VSYNC-Flanke bis zur ersten Prüfung auf eine steigende Flanke diese Zeit zur freien Verfügung. Ob das für einen Kurzlurlaub reicht? ;-) > - Die jeweiligen Pixel einer Zeile stehen bereit, > wenn PCLK von Low auf Hi geht Verstanden und bestätigt, mit einer kleinen Anmerkung: Ich würde hier nur nicht von Pixeln, sondern von Bytes sprechen. Denn wieviele Byte pro Pixel benötigt werden, hängt vom Bildausgabeformat ab. In der Regel sind es aber immer 2 Byte pro Pixel, da die Kamera keinen nativen Graufstufenmodus kennt. Theoretisch könnte man den erreichen indem man die Kamera auf YUV-Ausgabe stellt und immer nur das erste Byte (Y=Luminanz) hernimmt und das zweite einfach ignoriert. > - Die Zeile ist beendet, > wenn HREF auf Low geht Verstanden und bestätigt. Das ist dann nach PCLK * H-Pixel der Fall. Also 20us * 160 = 0,0032us = 3,2 ms. Anschließend folgt noch die Austastlücke von 144 PCLK, also nochmal 0,00288us oder 2,88 ms. Dies wäre für mich die Zeit die wir hätten um störungsfrei zum PC zu übertragen. >
1 | > |
> Soweit mein Vorschlag.
PERFEKT würde ich sagen, und von der Form her exakt das was wir
diskutieren sollten bevor auch nur eine einzige Zeile Code geschrieben
wird :-)
Ich bin begeistert! Gern würd ich das alles mal irgendwie im Wiki
ablegen, vielleicht auch mal mit Visio ein einfaches PAP dazu zeichnen.
Es sind ja die vielen kleinen Nebeninformationen zum Timing, etc. die
man später braucht, wenn man "mehr will".
Oli
Olli Z. schrieb: > Andreas S. schrieb: >> Mit Blick auf die arg beschränkten AVR-Ressourcen, würde ich ein >> Polling zum Einlesen einer beliebigen Zeile vorschlagen. > Das halte ich auch für eine gute Idee. Da wir im Moment nichts anderes > tun wollen als Daten von der Kamera zu lesen, gibt es eigentlich keinen > Grund sich der Komplexität einer ISR auszuliefern. Ehrlich gesagt wäre der ISR-Ansatz der einfachere. Aber damit kommt Ihr nicht weit, weil Aufruf und Rücksprung der ISR halt viel Resourcen verbrauchen. > Parallel zu dieser > würde unser Main-Code nämlich nur in einer Sinnlos-Schleife rotieren. > Ich glaub wir sollten erstmal versuchen das mit reinem Polling hin zu > bekommen. Okay. > Also die Main startet nach der Initialisierung mit einem Poll auf VSYNC > und dann gehts los. Yep. > Wir arbeiten doch mit QQVGA, also 160x120 Bildpunkten. Der XCLK wird mit > 8 MHz gefahren und der PCLK schwingt sich somit auf 50 kHz ein. Das > macht eine Periodenzeit von 20µs, unser Bezugslevel. Legt Euch nicht von vorne herein auf QQVGA fest, sondern macht den Code flexibel / konfigurierbar. > Nehmen wir weiter an das wir die Bilddaten im RGB565 oder RGB555 > Ausgabemodus übertragen. Ist etwas ineffektiver als YUV, aber erstmal > leichter zu verarbeiten. Davon würde ich klar abraten. Fangt erst einmal mit YUV an und verarbeitet zunächst nur das Y-Signal. Das ergibt zwar nur SW-Bilder, aber das ist ideal, um überhaupt erst einmal die Kamera einstellen zu können. Z.B. war ich lange Zeit der Meinung, dass mein Programm nicht funktioniert und dabei war einfach nur die Linse massiv unscharf eingestellt. > Jede Bildzeile hat also dann eine Länge von 320 > Byte. Das gesamte Bild eine Größe von 38.400 Byte. Der SRAM des > Atmega328p ist 2.048 Byte groß, wovon ein guter Teil auch für das > Programm benötigt wird. Ich denke aber ein Zwischenpuffern von 2-3 > Zeilen sollte schon drin sein. Claro, kann man gerne später dazuprogrammieren. > > Das Setup des OV7670 wäre dann doch so: > >
1 | > 1.) PCLK einstellen |
2 | > Prescaler-Register OV_SCCB_CLKRC (0x11) auf "Disable Double clock |
3 | > (Bit7=0)", "Prescale external clock (Bit6=0)", "durch 16 teilen |
4 | > (Bit0-5=01111)" (=0b0000 1111, =0x0F) stellen |
5 | > 2.) Bildformat QCIF und RGB. |
6 | > Register COM7 (0x12) mit Wert 0b0001 0100 laden. |
7 | > 3.) Skalierung einstellen |
8 | > Register COM3 (0x0C) mit Wert 0b0000 1000 laden. |
9 | > |
Auch wenn's super wichtig ist - ich bin jetzt einfach mal zu faul, das zu überprüfen ... Ich hoffe, ein anderer erbarmt sich. Da man hier eine ganze Menge falsch machen kann, würde ich mit einer Konfiguration beginnen, die nachweislich bei anderen Leuten im Internet funktioniert hat. > >>
1 | >> N=0 |
2 | >> while (N < Zeilenzahl_eines_Frames) { |
3 | >> Framebeginn abpassen |
4 | >> Alle Pixel der N.-ten Zeile einlesen |
5 | >> Alle Pixel der N.-ten Zeile ausgeben |
6 | >> N = N+1 |
7 | >> } |
8 | >> |
> Du würdest also dadurch "Zeit schinden" indem Du einfach nur eine Zeile > pro Frame liest und überträgst? Ok, für den Anfang eine durchaus > brauchbare Methode. Da hat man vermutlich genug Zeit die Daten an den PC > zu bekommen. Richtig - das war der Grundgedanke. Im nächsten Schritt läßt sich das natürlich deutlich verfeinern und ist in Teilen im Pseudocode schon "vorgedacht": Ihr könnt die max. Geschwindigkeit mit einer Art FiFo-Puffer erreichen: vorne schreibt Ihr in den Puffer rein (so lange bis der Puffer voll ist) und hinten nutzt holt Ihr die Bytes raus und übertragt sie an den PC oder ein TFT-Display. Jedes übertragene Byte leert den FiFo-Puffer dann wieder. Sobald genug Platz für eine weitere Zeile ist, kann diese wieder eingelesen und gespeichert werden, während hinten weiterhin die Bytes entnommen und rausgeschrieben werden. Das Entnehmen und rausschreiben kann in den oben markierten "Wunschcode"-Zeilen passieren. > >> - Die erste Zeile eines Frames beginnt, >> wenn VSYNC von Hi auf Low geht > Verstanden und bestätigt. > >> - Die Zeile N beginnt, >> wenn HREF genau zum N.ten mal von Low auf Hi geht > Verstanden und bestätigt. > Laut Timingtabelle ist das nach 17*PCLK, also 340us der Fall. Wir haben > also von der Erkennung der fallenden VSYNC-Flanke bis zur ersten Prüfung > auf eine steigende Flanke diese Zeit zur freien Verfügung. Ob das für > einen Kurzlurlaub reicht? ;-) Mindestens ;-) Alternativ kann man in ca. 80us bei 115,2 kbit/s ein Byte übertragen. > >> - Die jeweiligen Pixel einer Zeile stehen bereit, >> wenn PCLK von Low auf Hi geht > Verstanden und bestätigt, mit einer kleinen Anmerkung: Ich würde hier > nur nicht von Pixeln, sondern von Bytes sprechen. Denn wieviele Byte pro > Pixel benötigt werden, hängt vom Bildausgabeformat ab. In der Regel sind > es aber immer 2 Byte pro Pixel, da die Kamera keinen nativen > Graufstufenmodus kennt. Theoretisch könnte man den erreichen indem man > die Kamera auf YUV-Ausgabe stellt und immer nur das erste Byte > (Y=Luminanz) hernimmt und das zweite einfach ignoriert. Genau damit würde ich an Eurer Stelle anfangen. > >> - Die Zeile ist beendet, >> wenn HREF auf Low geht > Verstanden und bestätigt. Das ist dann nach PCLK * H-Pixel der Fall. > Also 20us * 160 = 0,0032us = 3,2 ms. Nicht ganz: wie Du oben selber schreibt, benötigt man immer 2 Bytes pro Pixel, also in Deinem Beispiel 6,2 ms für eine Zeile im YCrCb422- Format. > Anschließend folgt noch die > Austastlücke von 144 PCLK, also nochmal 0,00288us oder 2,88 ms. Dies > wäre für mich die Zeit die wir hätten um störungsfrei zum PC zu > übertragen. ... Könnte man meinen, aber leider bekommst Du bei 115,2kbit/s gerade mal max. 36 Bytes in dieser Zeit per USART über die Leitung geschoben. Die horizontale Austastlücke reicht also nicht zur Übertragung der Zeileninformation. Das wiederum bedeutet im obigen Pseudocode: es wird auf den nächsten Frame gewartet und dort die nächste Zeile entnommen. Will sagen: pro Zeile benötigt Ihr bei diesem Ansatz einen Frame. Mit der weiter oben von mir berechneten "Spaßgrenze" liegt Ihr bei einer PCLK von 50kHz bei einer Framerate von 1 Frame / 16 Sekunden ... (wenn die Kamera überhaupt so niedrige PCLK's erlaubt) Um also 120 Zeilen zu übertragen braucht's hier 120 * 16s = 32 Minuten. Das wird nicht spaßig werden. Hmmm - ich glaube, vor dem Coding ist hier doch noch etwas Konzept-Tuning nötig ... (wozu ich aber vermutlich heute und die nächsten Tage nicht mehr kommen werde => Ihr seid dran ...) > >>
1 | >> |
>> Soweit mein Vorschlag. > PERFEKT würde ich sagen, und von der Form her exakt das was wir > diskutieren sollten bevor auch nur eine einzige Zeile Code geschrieben > wird :-) > > Ich bin begeistert! Gern würd ich das alles mal irgendwie im Wiki > ablegen, vielleicht auch mal mit Visio ein einfaches PAP dazu zeichnen. > Es sind ja die vielen kleinen Nebeninformationen zum Timing, etc. die > man später braucht, wenn man "mehr will". > > Oli Nur zu ... Viele Grüße Igel1
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)
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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...
:
Bearbeitet durch User
Hallo, da sind sie wieder, meine 3 Probleme... ;) Ich kann es mal nach meiner Ansicht versuchen. "meine Ansicht" deshalb, weil: ich kann weder C noch C++ wirklich. Grundlagen habe ich mir projektabhängig über die letzten Jahre zusammengesucht, C++ bekanntschaft erst durch die Arduino-Geschichte. Es war und ist nur Hobby, vom Z80 über 6510 zu den ersten AVR usw. Alles in Assembler. C kam als Notwendigkeit weil mein Anfang einen TCP-Stack in ASM zu schreiben zwar durchaus gangbar war (IP ging, TCP ging, ARP ging ICMP-Ping ging grundsätzlich. Alles nur, weil der ENC28J60 Ethernet Chip bezahlbar beschaffbar war und LAN am AVR.. Super! Dann kam U.Radig mit seinem Webserver daher und ich stand vor der Entscheidung, meins weitermachen oder mich in C einzulesen und seine Software an meine Wünsche anzupassen. Ich habe mich für seine Software entschieden... Entscheidend dafür war, daß ich auf Grund meiner eigenen Basteile TCP/IP usw. ausreichend verstand, um recht zielsicher die C-Funktionen in seiner Software zuordnen zu können und auch (nach und nach) zu verstehen. Das schreibe ich an David D, ich finde es gut, den Dingen weit auf den Grund zu gehen. Von mir kenne ich aber auch, daß es oft besser ist, Teile zu nutzen, die andere Funktionsfähih schon gemacht haben und sich auf bestimmte Sachen zu konzentrieren, die eben noch nicht wunschgemäß verfügbar sind. Ds Risiko, das ein Projekt auf der Strecke bleibt, weil fehlende Erfolgserlebnisse und steigender Zeitaufwand eben keinen Spaß mehr machen, ist recht hoch. PS: Es ist zwar etwas riskant, solchen Source in ein Forum zu packen, weil der generelle Verriß da dicht daneben steht. Bisher hat man uns ja in diesem Thread in der Beziehung in Ruhe gelassen. Ich hoffe mal, das bleibt auch so. Ich habe mit dem Stand des Codes kein Problem, es ist eben schwer, im Internet die Vorkenntnisse usw. des Gegenüber einzuschätzen. Also: David D... Augen zu und durch und nicht die Lust verlieren, das wird schon. Gruß aus Berlin Michael
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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 WS2812 LED-Stripe. Bin gerade einfach mal so durchgegangen, in solchen Dingen sehe ich den Zweck der ESP8266 gerade durch den Preis. Einen MP3-Streamplayer mit einem VS1053 gibt es auch noch, prizipiell stabil, durch den etws knappen Ram aber hier im WLAN manchmal zu Aussetzern neigend, war auch eher ein proof-of-concept weil das Zeug rumlag. Da wird ein ESP32 einziehen, dank mehr Ram und stabil laufendem Software-MP3-Decoder und I2S-Ausgabe besser geeignet. Für (unangenehme) Überraschungen ist der ESP32 aber auch noch eine Weile gut... Olli Z. schrieb: > Ich bin aber echt froh einen Vollblut-Programmierer hier im Thread zu > haben. Meine Kenntnisse sind an vielen Stellen nur rudimentär. Ach, es > gibt ja so wahnsinnig viel interessantes Zeug und so wenig Zeit ;-) Hmmm... Vollblut-Programmierer... Ich sage es mal so: ein Projekt zu haben, das in seine sinnvollen Abschnitte zu zerlegen, Lösungsansätze für die Teilprobleme zu finden, Datenblätter lesen und verstehen zu können, kein Problem. Assembler kein Problem. C geht, oft schreibe ich da aber eher ASM-Abläufe, nutze also die C-Vorteile nicht immer aus (Struktur, Union, Bitfelder usw. usw.). C++ nur duch Arduino, keine wirkliche Erfahrung mit Klassen usw. Das SCCB nagele ich wahrscheinlich hier mit dem Datenblatt der OV76770 in 2 Stunden stabil in AVR-ASM zusammen, in C vermutlich auch, da kommen dann aber sicher 10 Leute, die sagen, daß man das doch in C viel eleganter mit nutzung aller Möglichkeiten von C machen kann... Olli Z. schrieb: > Wow, das ist wirklich wenig, hätte ich nicht mit gerechnet. Da könnte > man ja sogar noch das ASM "verstehen" ;-) vermutlich lese und verstehe ich das ASM schneller als den Inhalt einer C++-Klasse. ;) Olli Z. schrieb: > Ich hoffe das wir mit verschiedenen Versionen keine Probleme bekommen. > Ich würde halt immer das aktuelle nehmen, also jetzt 7. Für mich sehe ich da in diesem Zusammenhang keine wirklichen Probleme. Ich kopiere nur die .c und .h Dateien in mein angelegtes Projekt, egal ob Arduino oder Atmel-Studio und lasse den Compiler meckern. Ist normalerweis in diesem Umfang in 10 Minuten angepasst, Änderungen an den eigentlich Sourcen sollten nicht nötig sein und Sachen wie das mit dem #include <stdbool.h> sind über verscheiden versionen ohnehin üblich. Sollte auch das aktuelle Studio nicht stören, wenn das drinsthen würde. Vielleicht gäbe es eine Warnung über eine doppelte Deklaration... Gruß aus Berlin Michael
Olli Z. schrieb: > Beim Levelshifter benötigst Du keine zusätzlichen Pullups. Sicher? @David: könntest Du den genauen Schaltplan Deines Levelshifters hier einmal posten? Sieht der vielleicht so aus: https://learn.sparkfun.com/tutorials/bi-directional-logic-level-converter-hookup-guide ? Viele Grüße Igel1
:
Bearbeitet durch User
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
Hallo, liegt hier auch noch alles griffbereit, anderer Projekte habe ich ausreichend. ;) Ansonsten auch von mir: Viel Erfolg! Gruß aus Berlin Michael
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
:
Bearbeitet durch User
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
:
Bearbeitet durch User
Ich dachte das hatten wir doch ein paar hundert Antworten weiter oben schon geklärt?! :-) Wir wollten damit natürlich auch ein Biöd übertragen, aber eigentlich ging es ums Protokoll und die Ansteuerlokig sowie Videoformate.
:
Bearbeitet durch User
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
Also ich, für meinen Teil, habe und brauche keine konkrete Anwendung und sehe die Sache rein akademisch :-)
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.
:
Bearbeitet durch User
@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
Zur JPGE-Dekodierung hat elm-chan was: http://elm-chan.org/fsw/tjpgd/00index.html Außerdem gibt es picojpeg: https://github.com/richgel999/picojpeg Sollte beides vom Flashverbrauch her nicht zu dick auftragen...
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....
:
Bearbeitet durch User
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
@Michael U.: Das klingt wirklich sehr interessant. Bin auf Deine Bilder gespannt. Dient der USB-C-Anschluß zur Stromversorgung? Wie hast Du die Kamera mit Deinem Board verbunden? Und musstet Ihr viele Klimmzüge machen, bis das Teil lief? Gibt es Vorteile, die Dein Modul gegenüber den 8$-Varianten von Aliexpress hat? (vgl. https://www.aliexpress.com/item/OV2640-camera-module-Module-2-million-pixel-electronic-integrated-with-jpeg-compression-new-big-promotion/32886018967.html) Viele Grüße Igel1
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
@Michael: Danke für den kleine Bericht. Gutes Bild - macht wirklich neugierig ... Viele Grüße Igel1
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
:
Bearbeitet durch User
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
:
Bearbeitet durch User
Michael U. schrieb: > Es gibt ein Applikation-Dokument im Netz zur OV7670 bei www.play-zone.ch > Google hat ihn gefunden, ich selbst auf der Seite nicht, deshalb hänge > ich das pdf hier mal frech ran. Ganz so frech warst Du dann doch nicht - es hing nämlich nichts dran :-) Hier die mir bekannten Links (hatte damals auch teils lange recherchiert) - vermutlich wäre der 4. Link Dein Tipp gewesen: Datasheet V1.01 (08.07.2005): https://www.voti.nl/docs/OV7670.pdf SCCB functional Specification: http://www4.cs.umanitoba.ca/~jacky/Teaching/Courses/74.795-LocalVision/ReadingList/ov-sccb.pdf Implementation Guide V1.0 (Sept. 2005): http://www.haoyuelectronics.com/Attachment/OV7670%20+%20AL422B%28FIFO%29%20Camera%20Module%28V2.0%29/OV7670%20Implementation%20Guide%20%28V1.0%29.pdf Software Application Note: https://www.play-zone.ch/en/fileuploader/download/download/?d=1&file=custom%2Fupload%2FFile-1402681702.pdf Links zum OV7670 + AL422B(FIFO) Camera Module(V2.0): http://www.hotmcu.com/ov7670-al422bfifo-camera-modulev20-p-19.html Und meine absoluten Lieblingslinks: http://embeddedprogrammer.blogspot.com/2012/07/hacking-ov7670-camera-module-sccb-cheat.html http://embeddedprogrammer.blogspot.com/2013/01/demo-stm32f4-ov7670-qserialterm.html Was das Register-Herumprobieren angeht, so hast Du natürlich recht: blind herumstochern macht keinen Sinn. Aber manchmal sind die Beschreibungen so missverständlich, dass man einfach prüfen muss, was passiert, wenn man Register X verändert und ob dies dem erwarteten Verhalten entspricht. Ich für meinen Teil war mir damals jedenfalls oftmals unsicher, ob ich die Beschreibung korrekt verstanden hatte (und/oder ob diese nicht doch Buggy war). Außerdem haben die Arduino-Anhänger ja diese Wahnsinns-Compile&Flash-Zeiten (die ich beim STM32 mit J-Link ja nicht habe). Da macht so ein Register-Tweating-Tool schon irgendwo Sinn. Viele Grüße Igel1
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
@Michael U. : Meinst Du mit "Odroid" den hier: https://www.heise.de/make/meldung/Odroid-Go-Bastel-Game-Boy-mit-ESP32-zum-Odroid-Geburtstag-4088637.html ? Und hast Du die JPG-Decompression selbst programmiert? Wenn ja: mit welcher Library? Viele Grüße Igel1
Hallo, Andreas S. schrieb: > @Michael U. : > > Meinst Du mit "Odroid" den hier: > https://www.heise.de/make/meldung/Odroid-Go-Bastel-Game-Boy-mit-ESP32-zum-Odroid-Geburtstag-4088637.html > ? Ja, gekauft hier: https://www.pollin.de/p/odroid-go-mobile-spielekonsole-kit-810887 > Und hast Du die JPG-Decompression selbst programmiert? > Wenn ja: mit welcher Library? Nein, wäre wie auch MP3 in der Klasse, wo ich durchaus verstehe, was da passiert, mich der Arbeitsaufwand bei meinen C/C++ Kenntnissen aber doch etwas abschrecken würde. https://github.com/Bodmer/JPEGDecoder Gruß aus Berlin Michael
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
:
Bearbeitet durch User
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
Andreas S. schrieb: > Irgendwo hatte ich schon einmal so ein Programm gesehen ... wo war das > nur ... Ha - gefunden: qSerialTerm heißt das Dingen - ich habe es aber niemals probiert: http://embeddedprogrammer.blogspot.com/2012/07/hacking-ov7670-camera-module-sccb-cheat.html > nach qSerialTerm suchen
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
1 | void OV7670_captureNewImage (void) |
muss es heißen:
1 | ... |
2 | OV_WR_PORT &= ~(1<<OV_WR_PinNo); |
3 | while(!getValueOfPin(OV_VSync_PIN,OV_VSync_PinNo)); |
4 | OV_WR_PORT |= (1<<OV_WR_PinNo); |
hier hatte ich vorher OV_WR_PIN stehen. Das muss definitiv korrigiert werden. Dann habe ich gerade noch etwas mit den Low Active Signalen gespielt und das Timing etwas geändert. Das werde ich jetzt direkt noch ins Github Project Pushen. Anbei noch drei Bilder. Das eine aufgenommen im "normalen" Modus, das zweite, bunte mit dem test pattern 8bar color bar (Register 0x70 [7] und 0x71 [7] auf 10 gestellt) Immerhin wird es Bunt. Und das dritte mit dem Testpattern 11 "FadeToGrayColorBar" Aber etwas scheint entweder mit der Bildaufnahme, der Farb zusammenstellung oder der Auflösung nicht zu passen. Aber man sieht unterschiede. vielen Dank fürs Miteifern. Die nächste Woche bin ich leider auf Dienstreise. Vielleicht kann ich die Zeit nutzen, um die Kommunikation zwischen uC und PC zu beschreiben, oder zumindest meine Vorstellung davon. lg. David
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:
1 | char OV7670_getByte (void) |
dazu gibt es keinen Aufruf ...
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
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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
:
Bearbeitet durch User
> (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
:
Bearbeitet durch User
Das kann ich leider nur Bestätigen. Bei betrieb habe ich noch eine Spannung von 0.2 V an dem Pin anliegen. Und auch in der Schematic die ich gefunden habe: https://www.beyondlogic.org/pdf/OV7670_FIFO_SCH_V1.pdf wird ~RE auf GND gezogen... Wie gehen wir jetzt weiter vor? :D Edit: Altes Datenblatt Seite 18 könnte uns retten. Allerdings finde ich diese Beschreibung im neuen nicht mehr.... Das ist doch zum Mäuse melken :D "8.3.4 One Field Delay Line (The Old Data Read) As the design shown in diagram by applying the reset every 1-field cycle (with the common signal for /WRST and /RRST) and a constant read/write operation (with all /WE, /RE and /OE are tied to ground), “1 field delay line” timing is shown in timing chart below"
:
Bearbeitet durch User
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 :-)
:
Bearbeitet durch User
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
:
Bearbeitet durch User
Andreas S. schrieb: > Wie/womit programmierst Du? Um kompatibel zu sein mit C und Atmel Studio auf ATMega328P (Arduino Nano Hardware) - das ist zwar eine Krücke, aber auch eine Herausforderung :-). Normalerweise würde ich mit ausreichend Ports und DMA arbeiten (ATXMega) oder idealerweise einen STM mit entsprechender Anschlussmöglichkeit (es gibt welche mit "Kamera-Schnittstelle") nutzen - aber STM ist mir nicht geläufig und nur zum Spaß will ich mich da auch nicht einarbeiten. Es haben sich schon viele mit der Ansteuerung beschäftigt und fast alle nutzen Vorarbeiten von anderen (Register-Definitionen und -Werte) - da ist ein weites Feld. Noch bin ich nur am "rumspielen" und lesen - aber eine "normale" TWI-Anbindung funktioniert gut und mit 8MHz externem Takt läuft die Kamera auch ohne Probleme. Wie geschrieben suche ich nach Möglichkeiten, ohne Fifo mit dem 328P "vernünftige" Bilder zu bekommen und vielleicht wenigsten 1 FPS zu erreichen (ggf. interleaved, wie geschrieben).
Beitrag #5717113 wurde von einem Moderator gelöscht.
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
:
Bearbeitet durch User
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
Hallo, Andreas S. schrieb: > Könntest Du netterweise "den anderen Link" ebenfalls hier einstellen? Hatte Dieter oben gepostet: http://acoptex.com/project/254/basics-project-052a-ov7670-camera-sensor-module-without-fifo-ram-at-acoptexcom/#sthash.IDGNJNcx.P8aXeyqc.dpbs Mein Link: https://www.instructables.com/id/OV7670-Arduino-Camera-Sensor-Module-Framecapture-T/ ist vom code für den UNO prinzipiell identisch und läuft genauso, bei Dieter war nur netterweise die Windows-exe für den Anzeiger dabei, mußte ich den JAVA-Kram nicht erst hier in Gnag bringen. > Und schön: Dieter hat lauffähigen Code im Internet aufgetrieben - der > grundsätzliche Beweis, dass ein Atmega eine OV7670 Kamera auslesen kann, > scheint damit schon einmal erbracht. Jetzt müssen wir es nur selber > ebenfalls noch hinbekommen. Prinzipiell sollte sich das auch auf dem STM32 so in Gnag bringen lassen, wenn man die Hardwareabhängigkeiten bei XCLK Erzeugung, Seriell und TWI anpasst. Gruß aus Berlin Michael
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 )
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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
:
Bearbeitet durch User
Hallo, Andreas S. schrieb: > Unser Problem: das "Horizontal Timing" der OV7670 Kamera besagt, dass > nach einem Ansteigen von HREF bereits die erste Taktflanke von PCLK das > erste Pixel-Byte überträgt. ich habe jetzt nicht in das Datenblatt des AL422B geschaut und auch die Schaltung nicht genauer angeschaut. Wie wird die OV7670 für den FiFo-Betrieb initialisiert? Wenn z.B. Bit 5 in COM10 gesetzt ist wird kein PCLK während des HSYNC ausgegeben. Ich komme erst heute nachmittag dazu, da mal reinzuschauen. PS: doch kurz reingechaut: AL422 übernimmt mit der steigenden Flanke von WCK die Daten wenn /WE aktiv ist. Die Kamera hat das Byte mit der steigenden Flanke von PCLK gültig, die kommt nach Ende HREF. Sieht für mich im Moment glaubwürdig aus? Gruß aus Berlin Michael
:
Bearbeitet durch User
Michael U. schrieb: > Wie wird die OV7670 für den FiFo-Betrieb initialisiert? > Wenn z.B. Bit 5 in COM10 gesetzt ist wird kein PCLK während des HSYNC > ausgegeben. Das ist meiner Meinung nach unbedingt zu vermeiden: Die Clocks sollten auf beiden Seiten durchlaufen, vgl. Datenblatt Absatz 8.3.1. "It is recommended that the WCK and RCK are kept running at least 1MHz at all times." Und wenn wir schon den RCK-Takt brutal unter 1MHz runterdrücken, um das Bild in Ruhe auslesen zu können, dann sollte der WCK-Takt zumindest auf >1MHz durchlaufen, denn angeblich wird ja (lt. Datenblatt) der schnellere der beiden Takte zum DRAM-refresh verwendet (... glauben wir das mal ...), siehe Kapitel 8.3.1.: "The faster one of WCK and RCK is used as the DRAM refresh timing clock and has to be kept free running." > Ich komme erst heute nachmittag dazu, da mal reinzuschauen. Du bist entschuldigt :-) > PS: doch kurz reingechaut: AL422 übernimmt mit der steigenden Flanke von > WCK die Daten wenn /WE aktiv ist. Ja schon, aber laut dem Bild in meinem letzten Posting übernimmt der AL422B nach einem /WE=LOW (also nach einem Aktivieren der Schreibfähigkeit) erst mit der 2. steigenden Flanke wieder Daten vom Bus! Das ist genau der Knackpunkt. Schaut Euch mein Bild aus dem letzten Posting bitte einmal genau an. > Die Kamera hat das Byte mit der > steigenden Flanke von PCLK gültig, die kommt nach Ende HREF. Richtig - die Kamera wirft somit das 1. Byte raus, bevor der AL422B es aufschnappen kann, denn der liest seinerseits die Daten erst ab er 2. steigenden Flanke ein. > Sieht für > mich im Moment glaubwürdig aus? ... für mich nicht - aber ich lasse mich gerne von Euch vom Gegenteil überzeugen ... Ich kann nur hoffen, das das Datenblatt in diesem Punkt falsch ist, denn für diese Einlese-Verzögerung um einen WCK-Takt findet sich meiner Ansicht nach keine echte Begründung, die sich aus internen Aufbau des Chips ableiten ließe (vgl. "AL422-03 Block Diagram" auf S. 14 des Datenblatts). Viele Grüße Igel1
:
Bearbeitet durch User
Hi Leute, so, hier der erste Versuch ein komplettes Bild in den AL422B zu schieben. Wenn Ihr Lust habt, so wäre es super nett, wenn Ihr einmal meinen Pseudo-Code sichten und ggf. kommentieren könntet:
1 | Reading an image frame from OV7670 into AL422B fifo: |
2 | ----------------------------------------------------- |
3 | |
4 | FIFO_WCK = >=1MHz clock // make sure AL422B FiFo is clocked by camera's PCLK with at least 1MHz |
5 | |
6 | delay(1ms) // see AL422 datasheet: do wait 0.1ms after power up before applying reset |
7 | |
8 | FIFO_WR = HIGH // enable chips WE (and keep it enabled all time till end of frame-grabbing |
9 | FIFO_WRST = HIGH // disable write reset |
10 | // at this point, pixels already get shifted into AL422B, but we don't care for it |
11 | // because we will reset the FiFo's write address pointer later on. |
12 | |
13 | while(!VSYNC) {} // VSYNC=LOW: wait for end of current frame |
14 | while(VSYNC) {} // VSYNC=HIGH: vsync=high marks end of old frame |
15 | |
16 | // new frame starts here |
17 | FIFO_WRST = LOW // reset AL422B write addr pointer by driving /WRST to LOW for >= 2 cycles (1 cycle = 1 PCLK-cycle) |
18 | delay(1ms) // and < 17x Tline => driving /WRST to LOW for 1ms should be okay |
19 | FIFO_WRST = HIGH // reset write address pointer of AL422B |
20 | |
21 | while(!VSYNC){} // read data while VSYNC=LOW |
22 | |
23 | // new frame ends here |
24 | FIFO_WR = LOW // disable chips WE when end of frame is reached (VSYNC goes HIGH) |
25 | // and keep it disabled since we are done with reading one frame. |
Das Schöne am Ganzen: es ist wirklich keine echt zeitkritische Aktion enthalten - das ATmega sollte das also genauso locker bewerkstelligen können. Viele Grüße Igel1
:
Bearbeitet durch User
... und weil's so schön war, hier direkt der Pseudo-Code für das Auslesen des AL422B FiFo:
1 | Reading an image frame out of AL422B fifo: |
2 | ------------------------------------------- |
3 | |
4 | FIFO_RCK = 10kHz clock // feed FiFo with clock signal (using TIM1 on STM32F4) |
5 | // frequency can be adjusted according to UART-baudrate (e.g. 115200 baud) |
6 | // and UART-mode (e.g. 8N1 => 1 Start-Bit + 8 Data-Bits + 1 Stop-Bit = 10 Bits) |
7 | // If you use 115200 baud, you can transfer 115200baud/10bit/Byte = 11520 Bytes/s |
8 | // So FIFO_RCK can be at most 11.520 KHz in this example |
9 | // See: http://www.netzmafia.de/skripten/hardware/PC-Schnittstellen/seriell.html |
10 | |
11 | delay(1ms) // see AL422 datasheet: do wait 0.1ms after power up before applying reset |
12 | |
13 | FIFO_RRST = LOW // reset AL422B read addr pointer by driving /RRST to LOW |
14 | delay(1ms) |
15 | |
16 | // pull /RRST high right after a falling RCK shoulder |
17 | while(!FIFO_RCK){} // wait for a possible high shoulder to end |
18 | while(FIFO_RCK){} // wait for FIFO_RCK to become low |
19 | FIFO_RRST = HIGH // read addr pointer starts upcounting here (at very rising FIFO_RCK-edge) |
20 | |
21 | // read out image from AL422B FiFo |
22 | for(noOfPixels x bytes per pixel){ // repeat for "number of bytes in an image frame" times |
23 | while(!FIFO_RCK) // wait during low FIFO_RCK-shoulder |
24 | get FIFO_DATA // grab data right after rising edge of FIFO_RCK |
25 | UARTsend(FIFO_DATA) // send data |
26 | while(FIFO_RCK) // wait till end of high shoulder of FIFO_RCK |
27 | } |
Auch hier würde ich mich sehr freuen, wenn Ihr einen intensiven Blick darauf werfen könntet und mir Feedback gebt. Viele Grüße Igel1
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 ;-)
:
Bearbeitet durch User
Hallo, David D. schrieb: > @Michael, wie willst du es schaffen, dass beide Kameras mit dem Board > kompatibel sind? ich habe auch beide Versionen hier, aber die Pins > weichen eben schon voneinander ab in den beiden Modellen? Oder willst du > das aufwändig über jumper lösen? Ich habe 2 passende Buchsenleisten parallel verlötet, es wird natürlich nur jeweils eine Kamara gesteckt werden. Die "identischen" Pins verbinde ich direkt, SDA/SCl/XCLK über Levelshifter, D0...D7 kommen auch zusammen, ist ja egal, ob die Daten vom OV7670 oder dem AL422B kommen. PCLK und XCLK kommen parallel auf 2 Pins des AL422B, dann bleiben von dem noch 4 Signale, die ich auf freie Pins verteilen muß. Prinzipiell sind ja D9...D13 (PB1...PB5) noch verfügbar, außer der Kamera kommt an des "Spielbrett" nicht ran, bei OB7670 ohne FiFo und OV2640 wäre dann selbst SPI ja noch verfügbar. Der Rest ist ja dann Sache der Definitionen in der jeweiligen Software. Prinzipiell würde auch mein OV2640 Modul noch auch dem Platz der OV7670 passen, die PinOuts sind identisch. Dann kann ich zumindest die Hardware mal in die Ecke legen, wenn ich keine Zeit dafür habe, ohne das was auseinanderfällt... Gruß aus Berlin Michael
:
Bearbeitet durch User
David D. schrieb: > Sooo... meine bessere hälfte hatte doch noch was zu tun, wodurch ich > wenigstens die Möglichkeit hatte die Write Sequenz schon einmal > durchzuschauen: Dankeschön - sehr nett von Dir. >FIFO_WCK = >=1MHz clock // make sure AL422B FiFo is clocked by camera's >PCLK > with at least 1MHz > So far so good... Wenn ich bei mir messe, liegen ungefähr die 12 Mhz vom > verbauen Oszillator an. Dann passt ja alles. > >>delay(1ms) // see AL422 datasheet: do wait 0.1ms after power >up > before applying reset > jep... aber jetzt steht dort: "Apply /WRST and /RRST 0.1ms after power > on" Für mich hieß apply bei einem low-active signal auf Low ziehen. > Bin ich hier falsch? JA. Ich glaube, Du hast da einen Denkfehler gemacht: Schau Dir das Nand Gatter im Schaltplan genau an: Damit wird \WE nur dann auf LOW gezogen, wenn FiFo_WR = HIGH AND HREF = HIGH ist. > also ich habe an dieser Stelle dann >
1 | //Initialization From Datasheet: "Apply/WRST and //RRST 0.1ms after
|
2 | > power on |
3 | > OV_WRST_PORT &= ~(1<<OV_WRST_PinNo); |
4 | > OV_RRST_PORT &= ~(1<<OV_RRST_PinNo); |
> womit ich beide Pins auf Low Signal ziehe. Okay - da könnte etwas dran sein. Muss ich mir nochmals überlegen, ob ich das genauso machen werde. > > bei mir pulse ich danach nohc zweimal den RCK Pin um den Read Pointer > wirklich auf 0 zurückzuholen. Keine Ahnung ob das notwendig ist... Na > gut, weiter im Text: > > > >>FIFO_WR = HIGH // enable chips WE (and keep it enabled all time >till > end of frame-grabbing >>FIFO_WRST = HIGH // disable write reset >> // at this point, pixels already get shifted into >AL422B, > but we don't care for it >> // because we will reset the FiFo's write address >>pointer later on. > Ist WE nicht ebenfalls Low-active? also eigentlich /WE demnach würdest > du es deaktivieren und dann wird garnichts geschrieben. Siehe Anmerkungen von mir weiter oben. > > >>while(!VSYNC) {} // VSYNC=LOW: wait for end of current frame >>while(VSYNC) {} // VSYNC=HIGH: vsync=high marks end of old frame > while(VSYNC) {}... sehr gut... das hatte ich bis jetzt noch nicht, macht > aber durchaus Sinn > >>// new frame starts here >>FIFO_WRST = LOW // reset AL422B write addr pointer by >driving /WRST to > LOW for >= 2 cycles (1 cycle = 1 PCLK-cycle) >>delay(1ms) // and < 17x Tline => driving /WRST to LOW for >1ms > should be okay > was meinst du genau mit diesem Kommentar?: < 17x Tline => Der Write Reset muss unbedingt disabled werden, bevor HREF auf HIGH geht, also bevor die Zeilenübertragung beginnt. > Ich habe da nur ein delay von 6 us drin... frage mich grade wie ich > dadrauf gekommen bin > >>FIFO_WRST = HIGH // reset write address pointer of AL422B >> >>while(!VSYNC){} // read data while VSYNC=LOW >> >>// new frame ends here >>FIFO_WR = LOW // disable chips WE when end of frame is reached (VSYNC > goes HIGH) >> // and keep it disabled since we are done with >reading > one frame. > FIFO_WR = LOW --> siehe oben, ich meine Low-active > > Die Read Sequenz dann später :) > Danke! > > @Michael, wie willst du es schaffen, dass beide Kameras mit dem Board > kompatibel sind? ich habe auch beide Versionen hier, aber die Pins > weichen eben schon voneinander ab in den beiden Modellen? Oder willst du > das aufwändig über jumper lösen? > > Bis später, > David > > EDIT: irgendwie hats die Zitate verhauen und ich bekomme es auch nicht > korriegiert... Ich hoffe ihr könnt es dennnoch inhaltlich trennen ;-) Macht nix. Viele Grüße Igel1
:
Bearbeitet durch User
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)
|
6 | write_register_i2c(0x11, 0x02); |
7 | |
8 | //Home - Steuerung Belichtung
|
9 | write_register_i2c(0x13, 0xe5); //AWB off |
10 | write_register_i2c(0x01, 0x96); |
11 | write_register_i2c(0x02, 0x40); |
12 | |
13 | //Saturation 0
|
14 | write_register_i2c(0x4f, 0x80); |
15 | write_register_i2c(0x50, 0x80); |
16 | write_register_i2c(0x51, 0x00); |
17 | write_register_i2c(0x52, 0x22); |
18 | write_register_i2c(0x53, 0x5e); |
19 | write_register_i2c(0x54, 0x80); |
20 | write_register_i2c(0x58, 0x9e); |
21 | |
22 | //Brightness 0
|
23 | write_register_i2c(0x55, 0x00); |
24 | |
25 | //QQVGA
|
26 | // write_register_i2c(0x12, 0x04); //"normale" Funktion RGB
|
27 | write_register_i2c(0x12, 0x06); //"normale" Funktion RGB - + Color Bar |
28 | write_register_i2c(0x0C, 0x04); //DCW enable |
29 | write_register_i2c(0x3E, 0x1A); //DCW and scaling PCLK / 4 |
30 | write_register_i2c(0x70, 0x3A); //Horizontaler Skalierungs-Faktor |
31 | write_register_i2c(0x71, 0x35); //Vertikaler Skalierungs-Faktor |
32 | write_register_i2c(0x72, 0x22); //DCW control parameter |
33 | write_register_i2c(0x73, 0xF2); //Clock divider für DSP / 4 |
34 | write_register_i2c(0xA2, 0x02); //Histogramm ... |
35 | write_register_i2c(0x56, 0x40); //Kontrast 0 |
Das Timing auf Kamera-Seite sieht (aus meiner Sicht) hingegen gut aus: Gelb -> VSYNC Violett -> HREF Blau -> TX (Ich sende den String "Start" bei jedem neuen Bild - daher der "blaue Ausreisser") QQVGA hat den Vorteil, dass nur jeder 4. HREF-Slot (im Vergleich zu VGA) Daten enthält/übermittelt. Die "Totzeit" nutze ich für die serielle Übertragung. VG Dieter
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
:
Bearbeitet durch User
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
Michael U. schrieb: > Letztlich sind aber wohl die Leute > damals damit ja auch zurechtgekommen. Dann schau mal weiter nach - ich bin gespannt.
@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
:
Bearbeitet durch User
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
David D. schrieb: > das wäre subba :) Auf eigene Gefahr ... :-) Das Script schreibt halt jede Menge Bilder in den aufrufenden Pfad ...
Hallo, Dieter F. schrieb: > Auf eigene Gefahr ... :-) Danke, ich liebe die Gefahr. ;-) 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:
1 | static unsigned char OV7670_QVGA[][2]= |
2 | { |
3 | 0x12, 0x80, |
4 | |
5 | 0x11, 0x01, // see Implementation Guide "30 fps QVGA YUV mode" |
6 | 0x12, 0x10, // original: YUV422 = 0x00; |
7 | 0x40, 0xD0, // original: not set |
8 | 0x0C, 0x04, |
9 | 0x3E, 0x19, |
10 | 0x70, 0x3A, |
11 | 0x71, 0x35, |
12 | 0x72, 0x11, |
13 | 0x73, 0xF1, |
14 | 0xA2, 0x02, |
15 | |
16 | 0x13, 0x8B, |
17 | REG_COM9 , 0x6A, // 128x gain ceiling; 0x8 is reserved bit |
18 | |
19 | 0x4f , 0x80 , // "matrix coefficient 1" |
20 | 0x50 , 0x80 , // "matrix coefficient 2" |
21 | 0x51 , 0 , // vb |
22 | 0x52 , 0x22 , // "matrix coefficient 4" |
23 | 0x53 , 0x5e , // "matrix coefficient 5" |
24 | 0x54 , 0x80 // "matrix coefficient 6" |
25 | }; |
Achtung, grosse Erkenntnis: Eigentlich würde man bei diesen Werten ein 320x240 QVGA-Bild im RGB-Modus erwarten. Aber: April, April. Heraus kommt ein 315x240 Bild !! Wäre ich nicht vor 1,5 Jahren schon darauf gestoßen, hätte es mich sicherlich Tage gekostet, das zu bemerken. Mein Tipp des Tages lautet daher: Prüft mit dem Oszi oder mit dem LA genau die Länge der HREF- Pulse und rechnet zurück, ob die von Euch erwartete Zeilenbreite bei der von Euch gesetzten Taktrate auch tatsächlich zu der Länge des HREF-Pulses passt. In meinem Fall konnte ich so exakt auf die 315 Pixelbreite einer Zeile schließen. Schon bei geringen Abweichungen in der Darstellung - ich habe zunächst mit 320 Pixel/Zeile dargestellt - kann man kein Bild mehr erkennen/erahnen. Und zum Schluss zu Dieter: Saubere Leistung: Blitzeblanker Code - kein Kommentar trübt die Ästhetik - daran erkennt man den Hardcore-Programmierer :-) Aber einem geschenkten Gaul guckt man ja bekanntlich nicht ins Maul, also: Danke für den Code! Sobald ich mit meinem LCD-Display nicht mehr zufrieden bin, kommt Dein Code zum Einsatz. Viele Grüße Igel1
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?
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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
:
Bearbeitet durch User
@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
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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] |
8 | 0x3a, 0x05 , // TSLB - Window auto, YUYV [00] Ausgabe - TSLB [3], COM13[0] |
9 | 0x42, 0x08 , // COM17 - AEC Window [7:6] Bit 1 und 0 wie COM4 [5:4], DSP Color Bar on/off[3], on 0x08 off 0x00 |
10 | |
11 | 0x15, 0x00 , // COM10 - PCLK auch bei HREF |
12 | }; |
Das Ergebnis ist ein Testbild mit 313 Pixel/Zeile und 240 Zeilen. Jedes Pixel besteht aus 2 Bytes, die nach RGB565 kodiert sind, also: [RRRRRGGG][GGGBBBBB]. Dabei wird das hier links dargestellte Byte als erstes Übertragen. Wenn das funktioniert, so ändere die Werte von Register 0x12 auf 0x14 und Register 0x42 auf 0x00 und Du bekommst Dein erstes "echtes" Bild - ziemlich schwache Farben, aber immerhin - ein Bild. Danach kannst Du weiterforschen. Das wäre meine Rat an Dich bzgl. Vorgehensweise. Viele Grüße Igel1
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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
1 | UDR0 = (PIN_LOW & MASK_LOW) | (PIN_HIGH & MASK_HIGH); // Byte (Y) einlesen und rausschicken |
Dazu denn eben
1 | #define PIN_HREF PB0 // (D8) IN H-aktiv OV7670 Zeilenstart mit H-Impuls |
2 | #define PIN_VSYNC PD3 // (D3) IN H-aktiv OV7670 Bildstart mit H-Impuls |
3 | #define PIN_WRST PD2 // (D2) OUT L-aktiv AL422B Write-Counterreset mit L-Impuls |
4 | |
5 | #define PIN_STR PB1 // (D9) IN H-aktiv OV7670 Blitzlichtsteuerung |
6 | #define PIN_RCK PB2 // (D10) OUT H-aktiv AL422B default L |
7 | #define PIN_RRST PB3 // (D11) OUT L-aktiv AL422B Read-Counterreset mit L-Impuls |
8 | #define PIN_WR PB4 // (D12) OUT H-aktiv AL422B verknüpft mit HREF OV7670 zu /WR AL422B |
9 | #define PIN_OE PB5 // (D13) OUT L-aktiv AL422B Output tristate/aktiv, kann hier wohl auf L bleiben |
10 | |
11 | #define PIN_LOW PINC |
12 | #define MASK_LOW 0x0F // (A0...A3) PC0...PC3 IN |
13 | |
14 | #define PIN_HIGH PIND |
15 | #define MASK_HIGH 0xF0 // (D4...D7) PD4...PD7 IN |
Das komplette Init der Kamera-IO dann
1 | DDRB &= ~((1 << PIN_HREF) | (1 << PIN_STR)); // IN |
2 | |
3 | PORTB &= ~((1 << PIN_WR) | (1 << PIN_OE) | (1 << PIN_RCK)); // Low |
4 | PORTB |= (1 << PIN_RRST); // HIGH |
5 | DDRB |= (1 << PIN_RCK) | (1 << PIN_RRST) | (1 << PIN_WR) | (1 << PIN_OE); // OUT |
6 | |
7 | DDRD &= ~(1 << PIN_VSYNC); // IN |
8 | PORTD |= (1 << PIN_WRST); // HIGH |
9 | DDRD |= (1 << PIN_WRST); // OUT |
10 | |
11 | DDRC &= ~MASK_LOW; // D0-D3 camera IN |
12 | DDRD &= ~MASK_HIGH; // D7-D4 camera IN |
Ich weiß, daß das Herangehen da ewige Diskussionen auslösen kann, es stellt also nur meine Vorstellung und Meinung dar. Wenn die Pin-Zuordnungen (für mich) schnell auffindbar gewesen wären, hätte ich den Kram vermutlich noch schnell an mein PinOut des AVR angepasst und mal geflasht. So werde ich mich erstmal durchkramen müssen um mehr zu verstehen. So, genug gemault... ;-) @Andres S. schrieb: > Ich warte also explizit nicht auf das Zeilenende, bevor ich die > Daten in Richtung LCD versende. Ich warte auch auf nichts, die Geschwindigkeit wird nur von der UART-Rate bestimmt, sind hier RCLK im Moment 22,4kHz, eben 230400 Baud, passt ja auch ganz gut. Mit 115200 ist es aber genauso stabil, dann eben bei gut 11kHz RCLK. Gruß aus Berlin Michael
:
Bearbeitet durch User
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
Dieter F. schrieb: >
1 | > volatile int height = 480; |
2 | > volatile int width = 640; |
3 | > volatile int BytesPerPixel = 3; |
4 | > |
Die werden vom Terminal mit einem Klick auf get Camera Status auf die aktuellen Einstellungen angepasst. > Passt das zu dem, was Du einlesen willst? Würde bedeuten, dass Du RAW > Bayer (height / width) einlesen möchtest. Da kommt aber nur 1 Byte pro > Pixel und nicht 3 (ob die Register-Werte dazu passen habe ich nicht > geprüft). Im Processed BayerRaw kommt nur eins an? Da hätte ich drei gedacht. > 3 Byte pro Pixel kann die Kamera gar nicht - die passen auch nicht in > den Fifo bei der gewählten Auflösung, so weit mir bekannt. Damit wird > nichts vernünftiges herauskommen. Im QCiF auch nicht? > Das > >
1 | > //Reset the Write Pointer, (not sure, if that will work) |
2 | > OV7670_ResetFifoWritePointer(); |
3 | > |
> > gehört nicht ans Ende von "OV7670_captureNewImage" - keine Ahnung, ob es > stört. Richtig, ich hatte nur irgendwo gelesen, dass der write pointer immer x Positionen vor dem read Pointer sein muss und dass ein reset das umgehen würde... Kann mich aber auch irren. Werde ich nochmal prüfen
David D. schrieb: > Im QCiF auch nicht? Nein: Application Note Punkt 2 - Tabelle (achte auf die "or") Dann 2.1 erster Absatz: RAW Bayer nur bei VGA, Processed Bayer für VGA und QVGA. Alle anderen Ausgabe-Formate gelten für VGA und alle Auflösungen kleiner CIF. Kein Ausgabe-Format hat 3 Byte für die Farb-Information. Hier ist es schön dargestellt: http://joe-c.de/pages/optik/kamerasensor.php
Beitrag #5730463 wurde vom Autor gelöscht.
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
:
Bearbeitet durch User
@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
:
Bearbeitet durch User
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
:
Bearbeitet durch User
Guten Abend, >kein Problem. Ich grabe das ja ohnehin nur bei Bedarf aus, ist dank >meiner Adapterplatine jetzt auch kein Problem, das schnell >zusammenzustecken. Davon habe ich mich inspirieren lassen, weil ich eben auch nur sehr eingeschränkten Platz habe und schon immer rumgenörgelt wird, dass mein "Scheiß" den ganzen Schreibtisch blockiert :D... Das einzige was mir noch fehlt ist der 2x11 Pin header für die Kamera, dann fange ich auch das Löten an. @Igel: >- In welchem (Protokoll)format sendet David die Bilddaten an sein > PC-Programm? RGB565, Big-Endian? Oder läßt er gar unterschiedliche > Formate zu? Ja tut es, und zwar (sollte) es das automatisch tuen. Bisher implementiert sind das RGB565 format 1.Byte RRRRRGGG 2. Byte GGGBBBBB, und das YUV (wobei hier nur das Y interpretiert wird (hier sind dann auch noch abhängigkeit von der eingestellten Byte Order noch nicht implementiert, also würde ich raten auf RGB565 zu bleiben) Sowohl das Farbformat als auch die Auflösung werden über Register 0x12 erkannt und mit dem klick auf "get Camera Status" zuerst vom controller gelesen, ausgewertet und dann die Informationen xRes, yRes und BytesPerPixel an den Controller gesendet. Hier werden sie für die Ausleseroutine des FiFos benutzt. Bei einem klick auf take picture complete, wird der ganze Frame direkt gesendet (ohne abschluss zeichen) bei take picture RbyR, Zeilenweise mit jeweils einem CR+LF am ende. > In welchem (Protokoll)format sendet David Befehle von seinem > PC-Programm an seinen MC? Und insbesondere: welche Bytefolge sendet > David, um ein Register im OV7670 zu setzen? folgende Kommandos kann der uC empfangen: CommandAuswirkung Byte1 Byte2 expected Return Value 0x01 Read Register Register Address - 1 Byte register Value 0x02 Write Register Register Address newRegisterValue 1 Byte Errorcode 0x03 Take Picture 1 Row with CR+LF 0x04 set xResolution Resolution x MSB Resolution x LSB 1 Byte xresolution Value 0x05 set yResolution Resolution y MSB Resolution y LSB 1 Byte yresolution Value 0x06 set BytesPerPixel BytesPerPixel 1 Byte bytesperpixel Value 0x08 initialisiere Kamera Error Code 0x0A request new Line 1 Row with CR+LF 0x0B request Line repeat 1 Row with CR + LF 0x0C take complete Picture complete frame in px Ich hoffe, dass ist lesbar Edit: hmm wohl kaum. Ich schaue mal, dass ich vlt. noch ne Tabelle herbekommen, anbei aber schonmal ein Screenshot von der Excel Tabelle:
:
Bearbeitet durch User
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
... und weil's gerade so gut läuft, hier noch ein "richtiges Bild" - ebenfalls per USART übertragen. 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
:
Bearbeitet durch User
Hi David, Du hast geschrieben: > Sowohl das Farbformat als auch die Auflösung werden über Register 0x12 > erkannt und mit dem klick auf "get Camera Status" zuerst vom controller > gelesen, ausgewertet und dann die Informationen xRes, yRes und > BytesPerPixel an den Controller gesendet. Hier werden sie für die > Ausleseroutine des FiFos benutzt. Habe eine Nacht darüber geschlafen, verstehe die Zs.hänge aber leider nicht richtig: Frage 1: Warum liest Du Register 0x12 aus, um daraus die Dimensionen des Bildes abzuleiten und diese dann wiederum zurück an den MC zu senden? Frage 2: Wie wir festgestellt haben, haben die Bilder, trotz ausgewähltem QVGA, teilweise nur Zeilenlängen von 311 oder 313 Pixeln. Wie berechnest Du dann aus Register 0x12 die richtige Zeilenlänge? Frage 3: Und dann verstehe ich das CR+LF am Ende der Übertragung einer Zeile nicht. Was ist Sinn und Zweck der beiden Zeichen? Frage 4: Was genau macht der Befehl 0x03 ? Frage 5: Was ist der Unterschied zwischen Befehl 0x03 und 0x0B ? Ich gebe zu: ich könnte sicherlich auch alles mit Fleiß und Ausdauer aus Deinem Code ableiten, aber dazu bin ich ein bisschen zu bequem ... Viele Grüße Igel1
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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:
1 | Problemsignatur: |
2 | Problemereignisname: CLR20r3 |
3 | Problemsignatur 01: OV7670-Terminal.exe |
4 | Problemsignatur 02: 1.0.0.0 |
5 | Problemsignatur 03: 5c67f336 |
6 | Problemsignatur 04: OV7670-Terminal |
7 | Problemsignatur 05: 1.0.0.0 |
8 | Problemsignatur 06: 5c67f336 |
9 | Problemsignatur 07: 6c |
10 | Problemsignatur 08: 1c |
11 | Problemsignatur 09: System.NullReferenceException |
12 | Betriebsystemversion: 6.1.7601.2.1.0.256.4 |
13 | Gebietsschema-ID: 1031 |
14 | Zusatzinformation 1: 0a9e |
15 | Zusatzinformation 2: 0a9e372d3b4ad19135b953a78882e789 |
16 | Zusatzinformation 3: 0a9e |
17 | Zusatzinformation 4: 0a9e372d3b4ad19135b953a78882e789 |
18 | |
19 | Lesen Sie unsere Datenschutzbestimmungen online: |
20 | http://go.microsoft.com/fwlink/?linkid=104288&clcid=0x0407 |
21 | |
22 | Wenn die Onlinedatenschutzbestimmungen nicht verfügbar sind, lesen Sie unsere Datenschutzbestimmungen offline: |
23 | C:\Windows\system32\de-DE\erofflps.txt |
Das Clipping-Problem existiert leider ebenfalls noch: Der rechte Rand des Programm-Windows wird abgeschnitten und das gesamte Window läßt sich nicht über die existierende Breite hinaus aufziehen - wohl aber verkleinern. Meine Auflösung: 1920 x 1200 TrueColor (32bit), Windows 7 x64. Wenn ich das Programm starte, so nimmt es von Anfang an die gesamte Bildschirmbreite ein und wird am rechten Rand abgeschnitten - wie weiter oben in einem meiner vorigen Postings gezeigt. Viele Grüße Igel1
@Michael: Schickes Display - versuche doch mal mit der OV7670-Kamera die Uhrzeit abzulesen - das wäre vermutlich genau die richtige Herausforderung für einen Hobbyisten Deines Kalibers :-) Viele Grüße Igel1 PS: Juhu, gewonnen: erster Beitrag in der dritten MC-Threadseite.
:
Bearbeitet durch User
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:
1 | OV7670_captureNewImage(); |
2 | OV7670_ResetFifoReadPointer(); |
3 | sendFrameBufferToUART (width, height, BytesPerPixel); |
alle drei Funktionen aus der Datei: OV7670_withFifo.c Die Namen sind denke ich selbsterklärend.
Sonntag, 17.02.2019 .... irgendwann mitten in der Nacht, David D. gelingt nach 1,5 JAHREN Entwicklungszeit der vermeintliche Durchbruch. Das bisherige Problem? BANAL! Lediglich der pure Zufall brachte ihm die Erkenntnis. Er hatte sich entschlossen nur noch eine letzte Messung in dieser Nacht vorzunehmen, bevor er am nächsten Morgen mit der Betonwalze über diese Kamera fahren würde. Die Zielführende Messung war die Pulsdauer des WCK. Schon hundertmal durchgeführt, ohne Erfolg. Doch diesmal sollte es anders kommen, denn diesmal drehte er das Kamera Modul nicht einfach herum, um die Pins des Fifos zu erreichen. Dem Zufall geschuldet war, dass gerade seine 3. Hand Lupe in Reichweite stand, in die er die Kameraplatine einspannte und so die Verkabelung - eigentlich nicht hinnehmbar - unter Spannung setzte. Ein kurzer Klick auf take picture und den Blick zum Oszilloskop gewannt brachte die ernüchternde Erkenntnis nichts neues entdeckt zu haben. Ein Blick zurück zum Bildschirm, um erneut ein Bild aufzunehmen und.... WAS? eine Colorbar im Terminal Programm? Wo kommt die denn jetzt her? Nichts am uC verändert, nichts am Terminal Programm? Kurze Augenblicke der Ratlosigkeit und dann der Gedanke daran, dass es wohl an der EMV liegen könnte, schließlich standen bei ihm einige elektrische Geräte in kurzer Distanz rund um den Versuchsaufbau. Kurz ausgespannt, wieder eingespannt.... und nichts... Dann schoss ihm der Gedanke in den Kopf, evtl. mit der Oszilloskop Probe zwei Kontakte gleichzeitig berührt zu haben und so den FIFO in einen funktionierenden Zustand versetzt zu haben, doch nein, das erschien ihm dann doch zu unwahrscheinlich. Was konnte es also gewesen sein? Es traf ihn wie einen Blitz: die Kabel der einzelnen Breadboardverbindern sind durch das einspannen in die andere Richtung gebogen gewesen als sonst, kurz nachgestellt und ZACK! die Colorbar ist da. Offenbar handelt es sich um eine Kontaktschwierigkeit an den Steckern, die eigentlich allesamt bombenfest an der Kamera sitzen. Leichte Kontaktierungsprobleme die eine so fatale Wirkung haben, dass von dem eigentlichen Bild nichts mehr zu erkennen ist. Ich danke an dieser Stelle dem Schicksal :D Morgen wird also gelötet und dann bin ich wieder mit im Rennen! Anbei zwei Bilder, 1x Colorbar (klar hier stimmt noch einiges nicht, aber es sind schonmal Balken zu sehen! und 2x meine Handy Taschenlampe in völliger Dunkelheit :D Bis Morgen Gruß David
:
Bearbeitet durch User
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 ...
:
Bearbeitet durch User
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
:
Bearbeitet durch User
Michael U. schrieb: > PS: er hat inzwischen 479 Zeilen abgeholt, für die letzte hat er keine > Lust mehr ... weil er vermutlich bei Zeile 0 beginnt ...
Hallo, Andreas S. schrieb: > ... weil er vermutlich bei Zeile 0 beginnt ... da steht doch aber "hole Zeile 479 von 480"... ;-) 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:
1 | void OV7670_captureNewImage_David (void) |
2 | { |
3 | //OV_WR_PORT &= ~(1<<OV_WR_PinNo); //Write Disabled (defined start value) |
4 | Write_FIFO_WR(Bit_RESET); |
5 | |
6 | // while(!getValueOfPin(OV_VSync_PIN,OV_VSync_PinNo)); //Wait for VSync to indicate a new Frame |
7 | while (!Read_VSYNC()) {} |
8 | |
9 | //OV7670_ResetFifoWritePointer();//Enable Write Pointer |
10 | Write_FIFO_WRST(Bit_RESET); |
11 | Delay(1); |
12 | Write_FIFO_WRST(Bit_SET); |
13 | |
14 | |
15 | //while(getValueOfPin(OV_VSync_PIN,OV_VSync_PinNo)); |
16 | while (Read_VSYNC()) {} |
17 | |
18 | //OV_WR_PORT |= (1<<OV_WR_PinNo); //Write Enable so that the camera can write on the FrameBuffer |
19 | Write_FIFO_WR(Bit_SET); |
20 | |
21 | //while(!getValueOfPin(OV_VSync_PIN,OV_VSync_PinNo)); //Wait for the next VSync Pulse, so the frame is complete |
22 | while (!Read_VSYNC()) {} |
23 | |
24 | //OV_WR_PORT &= ~(1<<OV_WR_PinNo); //Write Disabled that the picture is safe in the Framebuffer |
25 | Write_FIFO_WR(Bit_RESET); |
26 | |
27 | // _delay_ms(20); |
28 | |
29 | //Reset the Write Pointer, (not sure, if that will work) |
30 | //OV7670_ResetFifoWritePointer(); |
31 | } |
Ergebnis: funktioniert auf meinem STM32F429 tadellos. Viele Grüße Igel1
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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
Michael U. schrieb: > ist mir bisher nicht gelungen... FM6126A Schau mal, ob das passend ist: Beitrag "Chinesische IC und ihre Verwandschaft"
... mir fehlt David - schnief - hoffentlich ist bald Mittwoch ... Viele Grüße Igel1
Also: bin gerade dabei, Davids Schaltung nachzubauen ... Ja, ja - keine Ahnung, ist wohl ein Helfersyndrom gemäß: "Watt tu'se nich alles, um de Jong zu helfen?! Da ich AVR-mäßig allerdings ziemlich eingerostet bin, hier ein paar Fragen, bei denen Ihr bitte nicht zu hart mit dem Kopf auf der Tischkante aufschlagen möchtet: - Wie lade ich Davids Programm am einfachsten in den Nano? Reicht dafür das USB-Kabel, oder muss ich den AVR-Dragon (den ich bislang noch nie benutzt habe) anschließen? - Wenn ich den Dragon anschließen muss/soll, dann: wie? - Mit welchem Programm sollte ich David's Projekt kompilieren und auf den Nano flashen (optimalerweise mit Null Code-Anpassungen)? Vermutlich mit dem neuesten AVR-Studiomonster, stimmt's? Okay, ich gebe zu: ich bin etwas googlefaul, aber ich gebe zu: so richtig "heiß" bin ich auf diesen Retro-Ausflug in die 8-Bit-Welt nicht. Ich befürchte daher, dass ich etwas "Anschubmotivation" in Form von ein paar Antworten auf die Fragen oben von Euch benötige ... (gerne auch in Form von ein paar guten Links). Außerdem bedeutet es, dass ich 20 Kabel von meiner Kamera neu verdrahten muss (und später dann wieder Rolle rückwärts an den STM32 anstecken darf). Macht schon mal das Bundesverdienstkreuz für mich klar ... Viele Grüße Igel1
:
Bearbeitet durch User
Hallo, Andreas S. schrieb: > Also: bin gerade dabei, Davids Schaltung nachzubauen ... > > Ja, ja - keine Ahnung, ist wohl ein Helfersyndrom gemäß: > "Watt tu'se nich alles, um de Jong zu helfen?! warum denke ish sowas auch gerade?!?!? Andreas S. schrieb: > - Wie lade ich Davids Programm am einfachsten in den Nano? > Reicht dafür das USB-Kabel, oder muss ich den AVR-Dragon > (den ich bislang noch nie benutzt habe) anschließen? USb-nutzt Dir nur as für die serielle, ansonsten den "Drachen". > - Wenn ich den Dragon anschließen muss/soll, dann: wie? 6-pin Verbinder hinten quer auf dem Nano und auf dem Dragon auf ISP, Verbindung ist 1:1. Falls Du 6-Pin Quetschbuchsen hast und Flachbandkabel.... Andreas S. schrieb: > - Mit welchem Programm sollte ich David's Projekt kompilieren > und auf den Nano flashen (optimalerweise mit Null > Code-Anpassungen)? Vermutlich mit dem neuesten > AVR-Studiomonster, stimmt's? Wenn Du es relativ einfach haben willst, nimm das uralte AVR-Studio 4.18 https://www.microchip.com/mplab/avr-support/avr-and-sam-downloads-archive Bis fast ans Ende der Welt runter scrollen, ich glaube, Du brauchst alle 4 Files, das Studio und die SPs. Unter Win7 geht es völlig problemlos, unter 10 sollte es auch noch gehen. Dazu den antiken WinAVR: https://sourceforge.net/projects/winavr/files/WinAVR/20100110/ Den WinAVR bitte in seinen Wunschordner auf C:/ installieren... Ich glaube, wenn man WinAVR zuerst installiert, erkennt ihn AVR-Studio beim Installieren allein, das können wir aber noch klären. Geht eigentlich alles problemlos zu installieren mit den default-Angaben. Wenn Du dann das AVR-Studio startest une New Project öffnset, sieht gleich, ob er Dir außer AVR-Assemblaer auch AVR-GCC anbietet. Wenn Du bis dahin kommst sehen wir weiter..... Andreas S. schrieb: > Außerdem bedeutet es, dass ich 20 Kabel von meiner Kamera neu verdrahten > muss (und später dann wieder Rolle rückwärts an den STM32 anstecken > darf). Was sind schon 20 Dupont-Strippen??? Mehr als 19 haben doch gleichzeitig sowieso nie Kontakt. ;-) Das Studio sollte auch den Treiber für den Dragon mitinstallieren (Jungo-Treiber). Andreas S. schrieb: > Macht schon mal das Bundesverdienstkreuz für mich klar ... Geht auch ein Aktivisten-Orden? Der müßte hier noch irgendwo rumliegen... PS: AVR-Kram belegt kanpp 200MB, der WinAVR gut 150MB. Gruß aus Berlin Michael
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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
1 | while (1) |
2 | { |
3 | OV7670_captureNewImage(); |
4 | OV7670_ResetFifoReadPointer(); |
5 | sendFrameBufferToUART (width, height, BytesPerPixel); |
6 | |
7 | for (uint8_t i = 0; i < 20; i++) //############## 20s warten |
8 | { |
9 | _delay_ms(1000); |
10 | } |
11 | } |
- main.c meine Register daten incl. Registersetzen eingefügt und nach seinem OV7670_init(); aufgerufen. So kommt alle 20s ein RGB565 Bild als RAW-Daten an. Seltsamerweise kommen seine Daten Little Endian an???? Erstmal reicht es mir. ;-) Bild ist auch "ok", ist aber zu dunkel in der Ecke für die Einstellungen. Gruß aus Berlin Michael
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.
Hallo, ok, das Problem mit der anderen byteorder hat sich für mich erstmal geklärt,
1 | for(int ByteNumber =0; ByteNumber < BytesPerPixel; ByteNumber++) |
2 | { |
3 | OV_RCK_PORT |= (1<<OV_RCK_PinNo); |
4 | |
5 | UART0_senden_Byte(Ov7670_readByte()); |
6 | |
7 | OV_RCK_PORT &= ~(1<<OV_RCK_PinNo); |
8 | } |
Du setzt RCK auf H und liest dann die Daten. TOH ist aber nur wenige ns, min. 4ns. Da der Fifo sehr schnell ist, liest Du sehr wahrscheinlich nicht das gewünschte, sondern schon das nächste Byte.
1 | for(int ByteNumber =0; ByteNumber < BytesPerPixel; ByteNumber++) |
2 | { |
3 | OV_RCK_PORT &= ~(1<<OV_RCK_PinNo); |
4 | |
5 | UART0_senden_Byte(Ov7670_readByte()); |
6 | |
7 | OV_RCK_PORT |= (1<<OV_RCK_PinNo); |
8 | } |
macht es bei mir richtig rum. Da sind Timingprobleme zwischen Fifo und und dem "lahmen" AVR wohl schuld. Ich habe jetzt keine Lust, den LA ranzuhängen und zu schauen, wann der Datenwechsel im Verhältnis zur RCK Flanke passiert, außerdem sind da die 80MHz Samplerate meines LA sowieso zu langsam... Gruß aus Berlin Michael
Das ist jetzt interessant. Wenn ich jetzt meine routine so änder wie von dir vorgeschlagen, erhalte ich die Colorbar, die du vorher hattest :D
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
:
Bearbeitet durch User
Hallo, Andreas S. schrieb: > - Den 3,3V-Ausgang des Uno-Boards hast Du nicht genutzt, oder? > (... denn der kann ja nur 50mA liefern) die 3,3V vom Nano reichen für die Kamera eigentlich aus, auch mit em FiFo. Der AMS1117 auf dem Nano kann weit mehr, es wird ihm aber dann zu warm wegen der geringen Kühlfläche. Vusb geht über eine Schottkydiode an den Reglereingang, an üblichen USB-Ports sieht der also meist nur um 4,7V. Kannst Du ja am 5V Pin des Nano messen, was da bei USB wirklich anliegt. Pegelwandler 5V vom 5V Nano-Pin, 3,3V und Kamera am 3,3V Pin. Pegelwandler habe ich in den zur Kamera gehenden Leitungen, also SDA, SCK, RST, also was direkt zur OV7670 geht. Der Fifo hat sowieso 5V tolerante Eingänge. Der UNo hat meist einen LP2985-33 drauf, der kann auch max. 150mA, kann aber eben auch thermische Probleme bekommen. Bei gehen beise Varainten ohne erkennbare Probleme, Spannung eben normal vom USB-Port. Ich habe mich gestern Abend irgendwie an "Processing" erinnert. Das ist eine Java-Geschichte im Arduino-Stile und habe es mal angeworfen. Hmmmmm, wenn ich da durch die Funktionen usw. etwas durchgestiegen bin, habe ich da vermutlich in kruzer Zeit eine "Software", die die RAW-Daten vom Mega einliest und als Bild in ein Fenster pinselt. Kann man einfach irgendwo hinwerfen und die .exe starten, 260MB tragen auch nicht so auf. :) Ich werden an der OV7670 Software ohnehin jetzt nur was machen, wenn David "um Hilfe" schreit. Ich kann bei Bedarf auch meine geänderte main.c und uart.c auch hier mal reinhängen. Genauso auch meine Software, ist in einem kompletten .c File, läßt sich also auch problemlos in ein Studio-Projekt werfen. Gruß aus Berlin Michael
:
Bearbeitet durch User
@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
:
Bearbeitet durch User
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
Hallo, OT: damit es nicht langweilig wird: ESP32 mit OV2640 vom neuen LED-Display 64x64 in 1600x1200. Gruß aus Berlin Michael
... David scheint einen Tanzunfall gehabt zu haben - man hört gar nichts mehr von ihm ...
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
Welche Software hast du da ausgewählt? Ich nehme mir gerade die Warnings vor ;-) Gruß David
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
:
Bearbeitet durch User
Hi David, schau mal das Bild im Anhang ... Du wirst es nicht glauben: es stammt aus Deinem Programm - mit minimalen Anpassungen: Ich habe - wie oben geschrieben - Deine "main.c" durch Michaels "main.c" ersetzt. Einziger Grund: ich wollte die Menüauswahl rauswerfen, um mich so auf die Routine "sendFrameBufferToUART (width, height, BytesPerPixel);" konzentrieren zu können. Diese Routine habe ich dann wie folgt angepasst:
1 | void sendFrameBufferToUART (int ImageWidth, int ImageHeight, int BytesPerPixel) |
2 | { |
3 | OV7670_ResetFifoReadPointer(); |
4 | |
5 | for(int height = 0; height < ImageHeight;height++) |
6 | { |
7 | for(int width =0; width < ImageWidth; width++) |
8 | { |
9 | for(int ByteNumber =0; ByteNumber < BytesPerPixel; ByteNumber++) |
10 | { |
11 | |
12 | OV_RCK_PORT &= ~(1<<OV_RCK_PinNo); |
13 | UART0_senden_Byte(Ov7670_readByte()); |
14 | _delay_us(300); |
15 | OV_RCK_PORT |= (1<<OV_RCK_PinNo); |
16 | |
17 | |
18 | } |
19 | } |
20 | } |
21 | } |
Begründung: Flankenwechsel für RCK habe ich vertauscht, damit Du das erste Byte nicht verschlumpfst, denn wenn Du die Flanke von RCK von LOW nach HIGH gehen lässt und dann erst das Byte aus dem AL422B-FIFO liest, so landest Du schon beim zweiten Byte (Michael war das aufgefallen - diese Blumen gehen an ihn). Sodann folgt das eigentliche Problem, das seinen Ursprung beim Aufruf von "UART0_senden_Byte(Ov7670_readByte())" hat. Bei der Sichtung dieser Routine fiel mir auf: sie ruft die Unterroutine "UART0_tx_in(Byte)" auf und in dieser Unterroutine wiederum wird ein internen Puffer UART0_tx.data[] gefüllt. Das geht so:
1 | int UART0_tx_in (char input) |
2 | { |
3 | char next= ((UART0_tx.write+1)&UART0_tx_mask); |
4 | if (next==UART0_tx.read) |
5 | { |
6 | return 0; |
7 | } |
8 | UART0_tx.data[UART0_tx.write] = input; |
9 | UART0_tx.write =next; |
10 | return 1; |
11 | } |
Dieser Puffer wird dann anderweitig auch schön brav von der ISR-Routine gemäß Prinzip first-in-first-out ausgelesen und per UART auf die Leitung geschoben. Der Knackpunkt: die Einleseroutine wartet nicht und schreibt immer weiter in den Puffer - solange, bis der Schreibzähler des Ringbuffers den Lesezähler quasi von hinten eingeholt hat. Spätestens dann sollte der Auslesevorgang aus dem AL422B eigentlich stoppen, denn der Ringbuffer ist ja voll. Tut er aber nicht: statt dessen wird in obiger Routine ein "return 0" aufgerufen, was von der aufrufenden Routine "void UART0_senden_Byte(char Byte)" leider nicht als "Hilferuf" a la "ich bin voll, bitte nix mehr reinstopfen" beachtet wird. Statt dessen kehrt diese zurück zur eingangs gelisteten 3-fachen for-Schleife, die ein weiteres Byte aus dem AL422B-FiFo ausliest und wiederum per Aufruf von "UART0_senden_Byte(char Byte) -> UART0_tx_in(Byte)" versucht in den Ringbuffer zu stopfen. Genau hier nimmt das Unglück seinen Lauf, denn das Byte wird nicht mehr in den Ringbuffer geschrieben, weil die Routine "UART0_tx_in (char input)" per "return 0" verlassen wird. Die Folge: das Byte geht verloren. Das ist übrigens auch der Grund dafür, warum dann später reproduzierbar zu wenig Bytes über die serielle Leitung rausgeschrieben werden - der fehlende Rest ist "per return 0" im Nirvana gelandet. Verschafft man der ISR allerdings genügend Zeit, den Ringbuffer auszulesen und über die serielle Leitung zu schicken, so tritt kein Überlauf des Ringbuffers ein und alles ist gut. Das habe ich einfach durch Einfügen von "_delay_us(300);" im ganz oben zitierten Codeblock getan. Alternativ kann man auch auch Warteschleifen innerhalb der Routine "void UART0_senden_Byte(char Byte)" fliegen - nämlich immer dann, wenn "UART0_tx_in(Byte);" ein "return 0" zurückgibt. Das sieht dann so aus:
1 | void UART0_senden_Byte(char Byte) |
2 | { |
3 | while(!(UART0_tx_in(Byte))){} |
4 | UCSR0B |= 0b00100000; // Data Register empty Interrupt anschalten |
5 | } |
Das geht natürlich nur beim Betrieb mit AL422B FiFo. Ohne FiFo fliegen einem gnadenlos aus dem OV7670 die Bits weiter um die Ohren und man kann kein Warteschleifchen fliegen. Ach ja: ich habe für meine Experimente die Baudrate auf 115200 Baud gedrosselt, indem ich in UART.c das Register UBRR0L auf den Wert 16 gesetzt habe.
1 | UBRR0L = 0b00010000; //115200 |
Viele Grüße Igel1 PS: und Danke an Michael, dass er mir auch einen Fehler übriggelassen hat - er hatte obiges Problem sicherlich schon längst bemerkt und durchschaut und hat sich nur aus Edelmut zurückgehalten (ich meine sogar, er hatte in diesem Thread die Gefahr des Pufferüberlaufs schon einmal erwähnt).
:
Bearbeitet durch User
Hier noch schnell die veränderten Dateien. 1:40 Uhr - au weia - das wird ein harter Tag morgen ... Gute Nacht Igel1
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
:
Bearbeitet durch User
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.
David D. schrieb:
(formatiert von Igel1)
1 | > folgende Kommandos kann der uC empfangen: |
2 | > Command Auswirkung Byte1 Byte2 expected Return Value |
3 | > 0x01 Read Register Register Address - 1 Byte register Value |
4 | > 0x02 Write Register Register Address newRegisterValue 1 Byte Errorcode |
Hmmm - mein Logic-Analyzer sagt da etwas anderes. Du sendest in Wirklichkeit, z.B. beim Auslesen von Register 0x05: 0x01 0x05 0x0D 0x0A Und erhältst in Wirklichkeit als Antwort: 0x05 0x80 ... wobei 0x80 der Registerinhalt von Register 0x05 ist. Und die Schreibfolge sieht so aus, wenn Du z.B. Register 0x05 mit Wert 0x80 beschreibst: 0x02 0x05 0x80 0x0D 0x0A Und als Antwort erhältst Du den Fehlercode: 0x00 Viele Grüße Igel1
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 |
21 | ... |
Hallo, die Bytefolgen hatte ich mir im Sniffer auch angeschaut und bin zu dem gleichen Schluß gekommen, was gesendet wird usw. Zum Glück für Andreas habe ich im Moment etwas wenig Zeit für die GEschichte, so kann er mir in Ruhe die Arbeit abnehmen. ;-)) Ich habbe mal eine IRQ-RX-Routine in die uart.c gepackt, weil ich mir Davids Ablauf noch nicht im Detail angeschaut habe. Ich hänge die hier einfach mal ran, in main() müssen vorn noch 3 Zeilen eingefügt werden. In uart.h muß die Zeile #define UART_MAXSTRLEN 63 eingefügt werden und in main()
1 | extern volatile uint8_t uart_str_complete; // 1 .. String komplett empfangen |
2 | extern volatile uint8_t uart_str_count; |
3 | extern volatile char * uart_string[]; |
Ich wollte da eigentlich nur schnell testen, ob sein switch für die Kommandoauswertung das, macht, was er soll, ist aber noch nicht passiert. Ist alles nicht schön gemacht, sollte nur gehen... Es fehlt z.B. ein error-flag wenn der Buffer voll ist, da geht es dann nie weiter. Müßte in main() abgefragt werden um den Buffer einfach neu zu initialisieren bei einem derartigen Fehler und ein overflow zum Terminal gemeldet werden.. Gruß aus Berlin Michael
:
Bearbeitet durch User
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
Na das klingt ja nach nem Karnevals Jecken... ich komm für den Samstag extra hoch ;-)
Hi David, habe gerade eine heiße Spur entdeckt, werde aber keine Zeit mehr haben, sie zu verfolgen: Dein Ringpuffer-Mechanismus funktioniert offenbar nicht so, wie er eigentlich angedacht ist. So definierst Du den Ringpuffer und die zugehörigen Zähler "read" und "write":
1 | #define UART0_rx_size 512 // Nur Werte 2^n zulässig ! |
2 | #define UART0_rx_mask (UART0_rx_size-1) |
3 | |
4 | |
5 | //------------------------------------------------------------------------------ |
6 | |
7 | int temp = 0; |
8 | struct UART0_rx //Receive Buffer |
9 | { |
10 | char data[UART0_rx_size]; |
11 | char read; |
12 | char write; |
13 | }UART0_rx= {{}, 0, 0}; |
Und so verwendest Du sie:
1 | int UART0_rx_in (char input) |
2 | { |
3 | char temp= ((UART0_rx.write+1)&UART0_rx_mask); // |
4 | if (temp==UART0_rx.read) //FiFo voll ? |
5 | { |
6 | return 0; //return 0 -> Fifo voll |
7 | } |
8 | UART0_rx.data[UART0_rx.write]=(char)input; //Daten ins Array legen |
9 | UART0_rx.write = temp; //write auf nächste Specicherzelle schieben |
10 | return 1; //return 1 -> Fifo abspeichern erfolgreich |
11 | } |
Dabei fällt auf, dass die beiden Zähler nur 8 Bit breit sind, Dein Modulo-Mechanismus mit
1 | ((UART0_rx.write+1)&UART0_rx_mask) |
... aber offenbar von einem Integer-Wert ausgeht. Will sagen: der Mechanismus läuft ins Leere. Jetzt müsste man nochmals genau durchdenken, ob es trotzdem per Zufall funktioniert - an allen Stellen und sogar auch bei Subtraktionen, die ja ebenfalls vorkommen. Jedenfalls scheint es nicht so gedacht gewesen zu sein und von Deinem 512 Byte breiten Ringpuffer werden dadurch auch nur 256 Bytes genutzt. Viele Grüße Igel1
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
Hi Dirk, schau mal hier: https://ide.geeksforgeeks.org/E7p41NoTYk Morgen mehr dazu. Viele Grüße Igel1
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
Hi David, hier eine noch bessere Version: https://ide.geeksforgeeks.org/kueWbVYXmL Der Code lautet:
1 | #include <stdio.h> |
2 | |
3 | #define SIZE 512 |
4 | #define MASK (SIZE - 1) |
5 | |
6 | int main() { |
7 | char c; |
8 | char carray[] = {0,1,2,126,127,128,129,-1,-2}; |
9 | char cplus1; |
10 | int cintplus1; |
11 | int data[SIZE]={}; |
12 | |
13 | for(int p=0; p<SIZE; p++){ |
14 | data[p] = p; |
15 | } |
16 | |
17 | for(int k=0; k<sizeof(carray); k++){ |
18 | |
19 | c=carray[k]; |
20 | cplus1=(c+1) & MASK; |
21 | cintplus1=(c+1) & MASK; |
22 | |
23 | printf("c=%d\n", c); |
24 | printf("cplus1=%d\n", cplus1); |
25 | printf("cintplus1=%d\n", cintplus1); |
26 | printf("data[c]=%d\n", data[c]); |
27 | printf("data[(c-1) & MASK]=%d\n", data[(c-1) & MASK]); |
28 | printf("data[c & MASK] = %d\n", data[c & MASK]); |
29 | printf("data[(c+1) & MASK]=%d\n", data[(c+1) & MASK]); |
30 | printf("........................\n\n"); |
31 | } |
32 | return 0; |
33 | } |
Und das Ergebnis lautet:
1 | c=0 |
2 | cplus1=1 |
3 | cintplus1=1 |
4 | data[c]=0 |
5 | data[(c-1) & MASK]=511 |
6 | data[c & MASK] = 0 |
7 | data[(c+1) & MASK]=1 |
8 | ........................ |
9 | |
10 | c=1 |
11 | cplus1=2 |
12 | cintplus1=2 |
13 | data[c]=1 |
14 | data[(c-1) & MASK]=0 |
15 | data[c & MASK] = 1 |
16 | data[(c+1) & MASK]=2 |
17 | ........................ |
18 | |
19 | c=2 |
20 | cplus1=3 |
21 | cintplus1=3 |
22 | data[c]=2 |
23 | data[(c-1) & MASK]=1 |
24 | data[c & MASK] = 2 |
25 | data[(c+1) & MASK]=3 |
26 | ........................ |
27 | |
28 | c=126 |
29 | cplus1=127 |
30 | cintplus1=127 |
31 | data[c]=126 |
32 | data[(c-1) & MASK]=125 |
33 | data[c & MASK] = 126 |
34 | data[(c+1) & MASK]=127 |
35 | ........................ |
36 | |
37 | c=127 |
38 | cplus1=-128 |
39 | cintplus1=128 |
40 | data[c]=127 |
41 | data[(c-1) & MASK]=126 |
42 | data[c & MASK] = 127 |
43 | data[(c+1) & MASK]=128 |
44 | ........................ |
45 | |
46 | c=-128 |
47 | cplus1=-127 |
48 | cintplus1=385 |
49 | data[c]=710832128 |
50 | data[(c-1) & MASK]=383 |
51 | data[c & MASK] = 384 |
52 | data[(c+1) & MASK]=385 |
53 | ........................ |
54 | |
55 | c=-127 |
56 | cplus1=-126 |
57 | cintplus1=386 |
58 | data[c]=32517 |
59 | data[(c-1) & MASK]=384 |
60 | data[c & MASK] = 385 |
61 | data[(c+1) & MASK]=386 |
62 | ........................ |
63 | |
64 | c=-1 |
65 | cplus1=0 |
66 | cintplus1=0 |
67 | data[c]=0 |
68 | data[(c-1) & MASK]=510 |
69 | data[c & MASK] = 511 |
70 | data[(c+1) & MASK]=0 |
71 | ........................ |
72 | |
73 | c=-2 |
74 | cplus1=-1 |
75 | cintplus1=511 |
76 | data[c]=8 |
77 | data[(c-1) & MASK]=509 |
78 | data[c & MASK] = 510 |
79 | data[(c+1) & MASK]=511 |
80 | ........................ |
Schau Dir nun Deine Routinen an, die Deinen Ringbuffer verwenden. Z.B. Diese hier: [code] int UART0_rx_complete(void) { //Wenn CR+LF empfangen wird, ist der Befehl vollständig if(UART0_rx.data[(UART0_rx.write -2)&UART0_rx_mask] == 0x0D &&UART0_rx.data[(UART0_rx.write-1)&UART0_rx_mask]==0x0A) { return 1; } else { return 0; } } [/code) ... und leite aus obigen Programm ab, was passiert, wenn z. B. UART0_rx.write = 0 ist. Ja, richtig: Du liest Puffer 510 und 511 aus. Scheint noch halbwegs richtig zu sein. Aber wirst Du diese Pufferplätze jemals beschreiben? Schau Dir dafür diese Routine an: [code] int UART0_rx_in (char input) { char temp= ((UART0_rx.write+1)&UART0_rx_mask); // if (temp==UART0_rx.read) //FiFo voll ? { return 0; //return 0 -> Fifo voll } UART0_rx.data[UART0_rx.write]=(char)input; //Daten ins Array legen UART0_rx.write = temp; //write auf nächste Specicherzelle schieben return 1; //return 1 -> Fifo abspeichern erfolgreich } [/code) Mit Blick auf mein Testprogramm oben meine ich, dass spätesten ab UART0_rx.write=128 ... einiges Unvorhergesehene passieren wird. Viele Grüße Igel1
:
Bearbeitet durch User
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
Edit: in diesem post stand nur wirres Zeug :D einfach ignorieren....
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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
Mist - David's Mittagspause scheint ihm heute gestrichen worden zu sein. Dabei könnten wir gut ein bisschen Input gebrauchen ...
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 -.-
:
Bearbeitet durch User
Problem Solved: ab jetzt wird auch nach xRes yRes und BpP gesendet und die entsprechende Antwort überprüft. warum sende ich am Terminal CR+LF auch das weiß ich wieder :D auch wenn der Punkt vlt. etwas beschämend ist: beim Verbindes des Com anschlusses werden zeichen geschickt, die ich nicht beeinflussen kann. Scheint irgendein standard zu sein, jedenfalls wird das bei der COM-Port library von microsoft so gemacht... um diese Zeichen einfach zu verwerfen sende ich einfach ein CR+LF hinterher, womit das ganze als "Befehl" interpretiert wird, in der Switch anweisung im UART_Work aber nicht aufzufinden ist und somit einfach verworfen wird. Edit: anbei noch der neue Release: incl. kurzfristigem Design umbau zur besseren Handhabung für Igel... habe es auf die Schnelle leider nicht besser hinbekommen https://github.com/igittigitt/ov7670/tree/TWI-Interfac/OV7670-Terminal-Releases
:
Bearbeitet durch User
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
:
Bearbeitet durch User
@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.
Habe Deinen Code aus GitHub gezogen, compiliert, geflashed und dann die Register-Komplett-Auslesefunktion mit Terminal 0.7.1 getestet: - ATmega resettet (im DebugWire-Modus) - Terminal frisch gestartet - 115200 8N1 Verbindung aufgenommen - "Read Device Settings" gedrückt (... und zu ende laufen lassen) => complete - "Read Device Settings" gedrückt (... und zu ende laufen lassen) => complete - "Read Device Settings" gedrückt (... und zu ende laufen lassen) => complete ... ca. 20x hintereinander erfolgreich laufen lassen ... Läuft bombenstabil ! Viele Grüße & gute Nacht Igel1
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
:
Bearbeitet durch User
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
:
Bearbeitet durch User
Okay, Leute: bitte lasst uns mal die Reihenfolge, in der wir die Dinge angehen wollen, festlegen. Hier mein Vorschlag: - Auflösung von VGA -> QVGA im Terminal umstellen Ist vermutlich ein Klacks für David und erleichtert Michael und mir die weitere Fehlersuche. Ist natürlich dann in einem Abwasch auch in allen Initialisierungsroutinen umzustellen. - Davids Hardwareproblem(?) fixen. Davids und unsere Umgebungen sollten unbedingt gleich ticken, sonst kommen wir hier nie auf einen grünen Zweig. - Routinen hinter "read register" im Terminal fixen Der "read register" - Button sollte unbedingt zuverlässig funktionieren (Szenario & Fehlerbeschreibung, siehe hier: Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)"). Andernfalls können wir die "Write Register"-Bugs nicht sauber bearbeiten (oder nur sehr umständlich über den Button "Read Device Settings" - Statusleiste im Terminal fixen Bevor ein neuer Status/Error dort ausgegeben wird (ist übrigens sehr praktisch), sollte der alte Text unbedingt weggelöscht werden. - Schreiboperationen aus Lesebefehlen entfernen Genau wie Michael würde ich wärmstens anraten, sämtliche Schreiboperationen aus der Routine, die hinter dem Button "Read Device Settings" liegt, auszubauen (notfalls in einen separaten Button auslagern). - Routinen hinter "write register" fixen Wie in Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)" geschrieben, liegt in der Funktion "OV7670_write (char regID, char regData)" bzw. deren Unterfunktionen der Bug. Hier ist ein wenig SCCB-Grundlagenforschung/arbeit erforderlich. - Button "Save to File" wieder einbauen Der war irgendwo zwischen Version 0.6 und 0.8 verloren gegangen. - Doku schreiben Welcher Button macht genau was? Welche Fehlermeldung bedeutet genau was? Das wäre meine aktuelle Liste. Fehlt noch was? Sollen wir die Liste hier im Forum pflegen oder als Issue-Liste auf GitHub? Oder sollen wir gar nichts in Richtung "Priorisierung der Vorgehensweise" pflegen, weil's sonst schon bald in Richtung "Arbeit" ausartet und das Ganze ja nach wie vor Spaß machen soll? Oder weil's "Überorganisation" wäre? Viele Grüße Igel1
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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
Andreas S. schrieb: > ... und sage uns, warum das Beschreiben des Registers nicht > funktioniert Kannst Du bitte SCCB_E zusätzlich aufzeichnen?
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_t regaddr = 0x00; |
8 | uint8_t regdatabefore = 0x00; |
9 | uint8_t regdataafter = 0x00; |
10 | uint8_t regdatanew = 0x88; |
11 | uint8_t retval = 0x00; |
12 | uint32_t delval = 100; |
13 | |
14 | Delay(delval); |
15 | printf("Writing 0x%x to registers\n\n", regdatanew); |
16 | printf("regaddr value before mod value after mod\n"); |
17 | printf("-------------------------------------------------------------------------\n"); |
18 | |
19 | // for register 0x00 .. 0x9C:
|
20 | // read register, write 0x88 into register, read register again ...
|
21 | for (regaddr = 0; regaddr <= 0xC9; regaddr++) { |
22 | regdatabefore = OV7670_ReadReg(regaddr); |
23 | Delay(delval); |
24 | printf("regaddr=0x%X regdata=0x%X ", regaddr, regdatabefore); |
25 | retval = OV7670_WriteReg(regaddr, regdatanew); |
26 | Delay(delval); |
27 | regdataafter = OV7670_ReadReg(regaddr); |
28 | Delay(delval); |
29 | printf("regdata=0x%X ", regdataafter); |
30 | if(regdataafter == 0x88){ |
31 | printf("SUCCESS\n"); |
32 | } else { |
33 | printf("FAILURE\n"); |
34 | }
|
35 | }
|
36 | |
37 | printf("-------------------------------------------------------------------------\n"); |
38 | |
39 | // ... and read out all registers again ...
|
40 | for (regaddr = 0; regaddr <= 0xC9; regaddr++) { |
41 | regdataafter = OV7670_ReadReg(regaddr); |
42 | printf("regaddr=0x%X regdata=0x%X \n", regaddr, regdataafter); |
43 | Delay(delval); |
44 | }
|
Ergebnis:
1 | I2C_Config() done |
2 | Writing 0x88 to registers |
3 | |
4 | regaddr value before mod value after mod |
5 | ------------------------------------------------------------------------- |
6 | regaddr=0x0 regdata=0x3 regdata=0x3 FAILURE |
7 | regaddr=0x1 regdata=0x80 regdata=0x80 FAILURE |
8 | regaddr=0x2 regdata=0x82 regdata=0x82 FAILURE |
9 | regaddr=0x3 regdata=0x0 regdata=0x88 SUCCESS |
10 | regaddr=0x4 regdata=0x1 regdata=0x89 FAILURE |
11 | regaddr=0x5 regdata=0x7F regdata=0x7F FAILURE |
12 | regaddr=0x6 regdata=0x5F regdata=0x6B FAILURE |
13 | regaddr=0x7 regdata=0x40 regdata=0x40 FAILURE |
14 | regaddr=0x8 regdata=0x80 regdata=0x80 FAILURE |
15 | regaddr=0x9 regdata=0x1 regdata=0x88 SUCCESS |
16 | regaddr=0xA regdata=0x76 regdata=0x76 FAILURE |
17 | regaddr=0xB regdata=0x73 regdata=0x73 FAILURE |
18 | regaddr=0xC regdata=0x0 regdata=0x88 SUCCESS |
19 | regaddr=0xD regdata=0x0 regdata=0x88 SUCCESS |
20 | regaddr=0xE regdata=0x1 regdata=0x88 SUCCESS |
21 | regaddr=0xF regdata=0x43 regdata=0x88 SUCCESS |
22 | regaddr=0x10 regdata=0x7F regdata=0x7F FAILURE |
23 | regaddr=0x11 regdata=0x80 regdata=0x88 SUCCESS |
24 | regaddr=0x12 regdata=0x0 regdata=0x0 FAILURE |
25 | regaddr=0x13 regdata=0x8F regdata=0x88 SUCCESS |
26 | regaddr=0x14 regdata=0x4A regdata=0x88 SUCCESS |
27 | regaddr=0x15 regdata=0x0 regdata=0x88 SUCCESS |
28 | regaddr=0x16 regdata=0x0 regdata=0x88 SUCCESS |
29 | regaddr=0x17 regdata=0x11 regdata=0x88 SUCCESS |
30 | regaddr=0x18 regdata=0x61 regdata=0x88 SUCCESS |
31 | regaddr=0x19 regdata=0x3 regdata=0x88 SUCCESS |
32 | regaddr=0x1A regdata=0x7B regdata=0x88 SUCCESS |
33 | regaddr=0x1B regdata=0x0 regdata=0x88 SUCCESS |
34 | regaddr=0x1C regdata=0x7F regdata=0x7F FAILURE |
35 | regaddr=0x1D regdata=0xA2 regdata=0xA2 FAILURE |
36 | regaddr=0x1E regdata=0x1 regdata=0x88 SUCCESS |
37 | regaddr=0x1F regdata=0x0 regdata=0x88 SUCCESS |
38 | regaddr=0x20 regdata=0x4 regdata=0x88 SUCCESS |
39 | regaddr=0x21 regdata=0x2 regdata=0x88 SUCCESS |
40 | regaddr=0x22 regdata=0x1 regdata=0x88 SUCCESS |
41 | regaddr=0x23 regdata=0x0 regdata=0x88 SUCCESS |
42 | regaddr=0x24 regdata=0x75 regdata=0x88 SUCCESS |
43 | regaddr=0x25 regdata=0x63 regdata=0x88 SUCCESS |
44 | regaddr=0x26 regdata=0xD4 regdata=0x88 SUCCESS |
45 | regaddr=0x27 regdata=0x80 regdata=0x88 SUCCESS |
46 | regaddr=0x28 regdata=0x80 regdata=0x88 SUCCESS |
47 | regaddr=0x29 regdata=0x7 regdata=0x88 SUCCESS |
48 | regaddr=0x2A regdata=0x0 regdata=0x88 SUCCESS |
49 | regaddr=0x2B regdata=0x0 regdata=0x88 SUCCESS |
50 | regaddr=0x2C regdata=0x80 regdata=0x88 SUCCESS |
51 | regaddr=0x2D regdata=0x0 regdata=0x88 SUCCESS |
52 | regaddr=0x2E regdata=0x0 regdata=0x88 SUCCESS |
53 | regaddr=0x2F regdata=0xE regdata=0x88 SUCCESS |
54 | regaddr=0x30 regdata=0x8 regdata=0x88 SUCCESS |
55 | regaddr=0x31 regdata=0x30 regdata=0x88 SUCCESS |
56 | regaddr=0x32 regdata=0x80 regdata=0x88 SUCCESS |
57 | regaddr=0x33 regdata=0x8 regdata=0x88 SUCCESS |
58 | regaddr=0x34 regdata=0x11 regdata=0x88 SUCCESS |
59 | regaddr=0x35 regdata=0x1A regdata=0x88 SUCCESS |
60 | regaddr=0x36 regdata=0x0 regdata=0x88 SUCCESS |
61 | regaddr=0x37 regdata=0x3F regdata=0x88 SUCCESS |
62 | regaddr=0x38 regdata=0x1 regdata=0x88 SUCCESS |
63 | regaddr=0x39 regdata=0x0 regdata=0x88 SUCCESS |
64 | regaddr=0x3A regdata=0xD regdata=0x88 SUCCESS |
65 | regaddr=0x3B regdata=0x0 regdata=0x88 SUCCESS |
66 | regaddr=0x3C regdata=0x68 regdata=0x88 SUCCESS |
67 | regaddr=0x3D regdata=0x88 regdata=0x88 SUCCESS |
68 | regaddr=0x3E regdata=0x0 regdata=0x88 SUCCESS |
69 | regaddr=0x3F regdata=0x0 regdata=0x88 SUCCESS |
70 | regaddr=0x40 regdata=0xC0 regdata=0x88 SUCCESS |
71 | regaddr=0x41 regdata=0x8 regdata=0x88 SUCCESS |
72 | regaddr=0x42 regdata=0x0 regdata=0x88 SUCCESS |
73 | regaddr=0x43 regdata=0x14 regdata=0x88 SUCCESS |
74 | regaddr=0x44 regdata=0xF0 regdata=0x88 SUCCESS |
75 | regaddr=0x45 regdata=0x45 regdata=0x88 SUCCESS |
76 | regaddr=0x46 regdata=0x61 regdata=0x88 SUCCESS |
77 | regaddr=0x47 regdata=0x51 regdata=0x88 SUCCESS |
78 | regaddr=0x48 regdata=0x79 regdata=0x88 SUCCESS |
79 | regaddr=0x49 regdata=0x0 regdata=0x88 SUCCESS |
80 | regaddr=0x4A regdata=0x0 regdata=0x88 SUCCESS |
81 | regaddr=0x4B regdata=0x0 regdata=0x88 SUCCESS |
82 | regaddr=0x4C regdata=0x0 regdata=0x88 SUCCESS |
83 | regaddr=0x4D regdata=0x4 regdata=0x88 SUCCESS |
84 | regaddr=0x4E regdata=0x0 regdata=0x88 SUCCESS |
85 | regaddr=0x4F regdata=0x40 regdata=0x88 SUCCESS |
86 | regaddr=0x50 regdata=0x34 regdata=0x88 SUCCESS |
87 | regaddr=0x51 regdata=0xC regdata=0x88 SUCCESS |
88 | regaddr=0x52 regdata=0x17 regdata=0x88 SUCCESS |
89 | regaddr=0x53 regdata=0x29 regdata=0x88 SUCCESS |
90 | regaddr=0x54 regdata=0x40 regdata=0x88 SUCCESS |
91 | regaddr=0x55 regdata=0x0 regdata=0x88 SUCCESS |
92 | regaddr=0x56 regdata=0x40 regdata=0x88 SUCCESS |
93 | regaddr=0x57 regdata=0x80 regdata=0x88 SUCCESS |
94 | regaddr=0x58 regdata=0x1E regdata=0x88 SUCCESS |
95 | regaddr=0x59 regdata=0x91 regdata=0x88 SUCCESS |
96 | regaddr=0x5A regdata=0x94 regdata=0x88 SUCCESS |
97 | regaddr=0x5B regdata=0xAA regdata=0x88 SUCCESS |
98 | regaddr=0x5C regdata=0x71 regdata=0x88 SUCCESS |
99 | regaddr=0x5D regdata=0x8D regdata=0x88 SUCCESS |
100 | regaddr=0x5E regdata=0xF regdata=0x88 SUCCESS |
101 | regaddr=0x5F regdata=0xF0 regdata=0x88 SUCCESS |
102 | regaddr=0x60 regdata=0xF0 regdata=0x88 SUCCESS |
103 | regaddr=0x61 regdata=0xF0 regdata=0x88 SUCCESS |
104 | regaddr=0x62 regdata=0x0 regdata=0x88 SUCCESS |
105 | regaddr=0x63 regdata=0x0 regdata=0x88 SUCCESS |
106 | regaddr=0x64 regdata=0x50 regdata=0x88 SUCCESS |
107 | regaddr=0x65 regdata=0x30 regdata=0x88 SUCCESS |
108 | regaddr=0x66 regdata=0x0 regdata=0x88 SUCCESS |
109 | regaddr=0x67 regdata=0x80 regdata=0x88 SUCCESS |
110 | regaddr=0x68 regdata=0x80 regdata=0x88 SUCCESS |
111 | regaddr=0x69 regdata=0x0 regdata=0x88 SUCCESS |
112 | regaddr=0x6A regdata=0x82 regdata=0x88 SUCCESS |
113 | regaddr=0x6B regdata=0xA regdata=0x88 SUCCESS |
114 | regaddr=0x6C regdata=0x2 regdata=0x88 SUCCESS |
115 | regaddr=0x6D regdata=0x55 regdata=0x88 SUCCESS |
116 | regaddr=0x6E regdata=0xC0 regdata=0x88 SUCCESS |
117 | regaddr=0x6F regdata=0x9A regdata=0x88 SUCCESS |
118 | regaddr=0x70 regdata=0x3A regdata=0x88 SUCCESS |
119 | regaddr=0x71 regdata=0x35 regdata=0x88 SUCCESS |
120 | regaddr=0x72 regdata=0x11 regdata=0x88 SUCCESS |
121 | regaddr=0x73 regdata=0x0 regdata=0x88 SUCCESS |
122 | regaddr=0x74 regdata=0x0 regdata=0x88 SUCCESS |
123 | regaddr=0x75 regdata=0xF regdata=0x88 SUCCESS |
124 | regaddr=0x76 regdata=0x1 regdata=0x88 SUCCESS |
125 | regaddr=0x77 regdata=0x10 regdata=0x88 SUCCESS |
126 | regaddr=0x78 regdata=0x0 regdata=0x88 SUCCESS |
127 | regaddr=0x79 regdata=0x0 regdata=0x88 SUCCESS |
128 | regaddr=0x7A regdata=0x24 regdata=0x88 SUCCESS |
129 | regaddr=0x7B regdata=0x4 regdata=0x88 SUCCESS |
130 | regaddr=0x7C regdata=0x7 regdata=0x88 SUCCESS |
131 | regaddr=0x7D regdata=0x10 regdata=0x88 SUCCESS |
132 | regaddr=0x7E regdata=0x28 regdata=0x88 SUCCESS |
133 | regaddr=0x7F regdata=0x36 regdata=0x88 SUCCESS |
134 | regaddr=0x80 regdata=0x44 regdata=0x88 SUCCESS |
135 | regaddr=0x81 regdata=0x52 regdata=0x88 SUCCESS |
136 | regaddr=0x82 regdata=0x60 regdata=0x88 SUCCESS |
137 | regaddr=0x83 regdata=0x6C regdata=0x88 SUCCESS |
138 | regaddr=0x84 regdata=0x78 regdata=0x88 SUCCESS |
139 | regaddr=0x85 regdata=0x8C regdata=0x88 SUCCESS |
140 | regaddr=0x86 regdata=0x9E regdata=0x88 SUCCESS |
141 | regaddr=0x87 regdata=0xBB regdata=0x88 SUCCESS |
142 | regaddr=0x88 regdata=0xD2 regdata=0x88 SUCCESS |
143 | regaddr=0x89 regdata=0xE5 regdata=0x88 SUCCESS |
144 | regaddr=0x8A regdata=0x0 regdata=0x88 SUCCESS |
145 | regaddr=0x8B regdata=0x0 regdata=0x88 SUCCESS |
146 | regaddr=0x8C regdata=0x0 regdata=0x88 SUCCESS |
147 | regaddr=0x8D regdata=0xF regdata=0x88 SUCCESS |
148 | regaddr=0x8E regdata=0x0 regdata=0x88 SUCCESS |
149 | regaddr=0x8F regdata=0x0 regdata=0x88 SUCCESS |
150 | regaddr=0x90 regdata=0x0 regdata=0x88 SUCCESS |
151 | regaddr=0x91 regdata=0x0 regdata=0x88 SUCCESS |
152 | regaddr=0x92 regdata=0x0 regdata=0x88 SUCCESS |
153 | regaddr=0x93 regdata=0x0 regdata=0x88 SUCCESS |
154 | regaddr=0x94 regdata=0x50 regdata=0x88 SUCCESS |
155 | regaddr=0x95 regdata=0x50 regdata=0x88 SUCCESS |
156 | regaddr=0x96 regdata=0x1 regdata=0x88 SUCCESS |
157 | regaddr=0x97 regdata=0x1 regdata=0x88 SUCCESS |
158 | regaddr=0x98 regdata=0x10 regdata=0x88 SUCCESS |
159 | regaddr=0x99 regdata=0x40 regdata=0x88 SUCCESS |
160 | regaddr=0x9A regdata=0x40 regdata=0x88 SUCCESS |
161 | regaddr=0x9B regdata=0x20 regdata=0x88 SUCCESS |
162 | regaddr=0x9C regdata=0x0 regdata=0x88 SUCCESS |
163 | regaddr=0x9D regdata=0x99 regdata=0x88 SUCCESS |
164 | regaddr=0x9E regdata=0x7F regdata=0x88 SUCCESS |
165 | regaddr=0x9F regdata=0xC0 regdata=0x88 SUCCESS |
166 | regaddr=0xA0 regdata=0x90 regdata=0x88 SUCCESS |
167 | regaddr=0xA1 regdata=0x3 regdata=0x88 SUCCESS |
168 | regaddr=0xA2 regdata=0x2 regdata=0x88 SUCCESS |
169 | regaddr=0xA3 regdata=0x1E regdata=0x88 SUCCESS |
170 | regaddr=0xA4 regdata=0x0 regdata=0x88 SUCCESS |
171 | regaddr=0xA5 regdata=0xF regdata=0x88 SUCCESS |
172 | regaddr=0xA6 regdata=0xF0 regdata=0x88 SUCCESS |
173 | regaddr=0xA7 regdata=0xC1 regdata=0x88 SUCCESS |
174 | regaddr=0xA8 regdata=0xF0 regdata=0x88 SUCCESS |
175 | regaddr=0xA9 regdata=0xC1 regdata=0x88 SUCCESS |
176 | regaddr=0xAA regdata=0x14 regdata=0x88 SUCCESS |
177 | regaddr=0xAB regdata=0xF regdata=0x88 SUCCESS |
178 | regaddr=0xAC regdata=0x0 regdata=0x88 SUCCESS |
179 | regaddr=0xAD regdata=0x80 regdata=0x88 SUCCESS |
180 | regaddr=0xAE regdata=0x80 regdata=0x88 SUCCESS |
181 | regaddr=0xAF regdata=0x80 regdata=0x88 SUCCESS |
182 | regaddr=0xB0 regdata=0x0 regdata=0x88 SUCCESS |
183 | regaddr=0xB1 regdata=0x0 regdata=0x88 SUCCESS |
184 | regaddr=0xB2 regdata=0x0 regdata=0x88 SUCCESS |
185 | regaddr=0xB3 regdata=0x80 regdata=0x88 SUCCESS |
186 | regaddr=0xB4 regdata=0x0 regdata=0x88 SUCCESS |
187 | regaddr=0xB5 regdata=0x4 regdata=0x88 SUCCESS |
188 | regaddr=0xB6 regdata=0x0 regdata=0x88 SUCCESS |
189 | regaddr=0xB7 regdata=0x66 regdata=0x88 SUCCESS |
190 | regaddr=0xB8 regdata=0x0 regdata=0x88 SUCCESS |
191 | regaddr=0xB9 regdata=0x6 regdata=0x88 SUCCESS |
192 | regaddr=0xBA regdata=0x0 regdata=0x88 SUCCESS |
193 | regaddr=0xBB regdata=0x0 regdata=0x88 SUCCESS |
194 | regaddr=0xBC regdata=0x0 regdata=0x88 SUCCESS |
195 | regaddr=0xBD regdata=0x0 regdata=0x88 SUCCESS |
196 | regaddr=0xBE regdata=0x0 regdata=0x88 SUCCESS |
197 | regaddr=0xBF regdata=0x0 regdata=0x88 SUCCESS |
198 | regaddr=0xC0 regdata=0x0 regdata=0x88 SUCCESS |
199 | regaddr=0xC1 regdata=0x0 regdata=0x88 SUCCESS |
200 | regaddr=0xC2 regdata=0x0 regdata=0x88 SUCCESS |
201 | regaddr=0xC3 regdata=0x0 regdata=0x88 SUCCESS |
202 | regaddr=0xC4 regdata=0x0 regdata=0x88 SUCCESS |
203 | regaddr=0xC5 regdata=0x0 regdata=0x88 SUCCESS |
204 | regaddr=0xC6 regdata=0x88 regdata=0x88 SUCCESS |
205 | regaddr=0xC7 regdata=0x88 regdata=0x88 SUCCESS |
206 | regaddr=0xC8 regdata=0x88 regdata=0x88 SUCCESS |
207 | regaddr=0xC9 regdata=0xC0 regdata=0x82 FAILURE |
208 | ------------------------------------------------------------------------- |
209 | regaddr=0x0 regdata=0x0 |
210 | regaddr=0x1 regdata=0x80 |
211 | regaddr=0x2 regdata=0x82 |
212 | regaddr=0x3 regdata=0x0 |
213 | regaddr=0x4 regdata=0x1 |
214 | regaddr=0x5 regdata=0x24 |
215 | regaddr=0x6 regdata=0x24 |
216 | regaddr=0x7 regdata=0x40 |
217 | regaddr=0x8 regdata=0x24 |
218 | regaddr=0x9 regdata=0x1 |
219 | regaddr=0xA regdata=0x76 |
220 | regaddr=0xB regdata=0x73 |
221 | regaddr=0xC regdata=0x0 |
222 | regaddr=0xD regdata=0x0 |
223 | regaddr=0xE regdata=0x1 |
224 | regaddr=0xF regdata=0x43 |
225 | regaddr=0x10 regdata=0x7F |
226 | regaddr=0x11 regdata=0x80 |
227 | regaddr=0x12 regdata=0x0 |
228 | regaddr=0x13 regdata=0x88 |
229 | regaddr=0x14 regdata=0x88 |
230 | regaddr=0x15 regdata=0x88 |
231 | regaddr=0x16 regdata=0x88 |
232 | regaddr=0x17 regdata=0x88 |
233 | regaddr=0x18 regdata=0x88 |
234 | regaddr=0x19 regdata=0x88 |
235 | regaddr=0x1A regdata=0x88 |
236 | regaddr=0x1B regdata=0x88 |
237 | regaddr=0x1C regdata=0x7F |
238 | regaddr=0x1D regdata=0xA2 |
239 | regaddr=0x1E regdata=0x88 |
240 | regaddr=0x1F regdata=0x88 |
241 | regaddr=0x20 regdata=0x88 |
242 | regaddr=0x21 regdata=0x88 |
243 | regaddr=0x22 regdata=0x88 |
244 | regaddr=0x23 regdata=0x88 |
245 | regaddr=0x24 regdata=0x88 |
246 | regaddr=0x25 regdata=0x88 |
247 | regaddr=0x26 regdata=0x88 |
248 | regaddr=0x27 regdata=0x88 |
249 | regaddr=0x28 regdata=0x88 |
250 | regaddr=0x29 regdata=0x88 |
251 | regaddr=0x2A regdata=0x88 |
252 | regaddr=0x2B regdata=0x88 |
253 | regaddr=0x2C regdata=0x88 |
254 | regaddr=0x2D regdata=0x0 |
255 | regaddr=0x2E regdata=0x0 |
256 | regaddr=0x2F regdata=0x24 |
257 | regaddr=0x30 regdata=0x88 |
258 | regaddr=0x31 regdata=0x88 |
259 | regaddr=0x32 regdata=0x88 |
260 | regaddr=0x33 regdata=0x88 |
261 | regaddr=0x34 regdata=0x88 |
262 | regaddr=0x35 regdata=0x88 |
263 | regaddr=0x36 regdata=0x88 |
264 | regaddr=0x37 regdata=0x88 |
265 | regaddr=0x38 regdata=0x88 |
266 | regaddr=0x39 regdata=0x88 |
267 | regaddr=0x3A regdata=0x88 |
268 | regaddr=0x3B regdata=0x88 |
269 | regaddr=0x3C regdata=0x88 |
270 | regaddr=0x3D regdata=0x88 |
271 | regaddr=0x3E regdata=0x88 |
272 | regaddr=0x3F regdata=0x88 |
273 | regaddr=0x40 regdata=0x88 |
274 | regaddr=0x41 regdata=0x88 |
275 | regaddr=0x42 regdata=0x88 |
276 | regaddr=0x43 regdata=0x88 |
277 | regaddr=0x44 regdata=0x88 |
278 | regaddr=0x45 regdata=0x88 |
279 | regaddr=0x46 regdata=0x88 |
280 | regaddr=0x47 regdata=0x88 |
281 | regaddr=0x48 regdata=0x88 |
282 | regaddr=0x49 regdata=0x88 |
283 | regaddr=0x4A regdata=0x88 |
284 | regaddr=0x4B regdata=0x88 |
285 | regaddr=0x4C regdata=0x88 |
286 | regaddr=0x4D regdata=0x88 |
287 | regaddr=0x4E regdata=0x88 |
288 | regaddr=0x4F regdata=0x88 |
289 | regaddr=0x50 regdata=0x88 |
290 | regaddr=0x51 regdata=0x88 |
291 | regaddr=0x52 regdata=0x88 |
292 | regaddr=0x53 regdata=0x88 |
293 | regaddr=0x54 regdata=0x88 |
294 | regaddr=0x55 regdata=0x88 |
295 | regaddr=0x56 regdata=0x88 |
296 | regaddr=0x57 regdata=0x88 |
297 | regaddr=0x58 regdata=0x88 |
298 | regaddr=0x59 regdata=0x88 |
299 | regaddr=0x5A regdata=0x88 |
300 | regaddr=0x5B regdata=0x88 |
301 | regaddr=0x5C regdata=0x88 |
302 | regaddr=0x5D regdata=0x88 |
303 | regaddr=0x5E regdata=0x88 |
304 | regaddr=0x5F regdata=0x88 |
305 | regaddr=0x60 regdata=0x88 |
306 | regaddr=0x61 regdata=0x88 |
307 | regaddr=0x62 regdata=0x88 |
308 | regaddr=0x63 regdata=0x88 |
309 | regaddr=0x64 regdata=0x88 |
310 | regaddr=0x65 regdata=0x88 |
311 | regaddr=0x66 regdata=0x88 |
312 | regaddr=0x67 regdata=0x88 |
313 | regaddr=0x68 regdata=0x88 |
314 | regaddr=0x69 regdata=0x88 |
315 | regaddr=0x6A regdata=0x88 |
316 | regaddr=0x6B regdata=0x88 |
317 | regaddr=0x6C regdata=0x88 |
318 | regaddr=0x6D regdata=0x88 |
319 | regaddr=0x6E regdata=0x88 |
320 | regaddr=0x6F regdata=0x88 |
321 | regaddr=0x70 regdata=0x88 |
322 | regaddr=0x71 regdata=0x88 |
323 | regaddr=0x72 regdata=0x88 |
324 | regaddr=0x73 regdata=0x88 |
325 | regaddr=0x74 regdata=0x88 |
326 | regaddr=0x75 regdata=0x88 |
327 | regaddr=0x76 regdata=0x88 |
328 | regaddr=0x77 regdata=0x88 |
329 | regaddr=0x78 regdata=0x88 |
330 | regaddr=0x79 regdata=0x88 |
331 | regaddr=0x7A regdata=0x88 |
332 | regaddr=0x7B regdata=0x88 |
333 | regaddr=0x7C regdata=0x88 |
334 | regaddr=0x7D regdata=0x88 |
335 | regaddr=0x7E regdata=0x88 |
336 | regaddr=0x7F regdata=0x88 |
337 | regaddr=0x80 regdata=0x88 |
338 | regaddr=0x81 regdata=0x88 |
339 | regaddr=0x82 regdata=0x88 |
340 | regaddr=0x83 regdata=0x88 |
341 | regaddr=0x84 regdata=0x88 |
342 | regaddr=0x85 regdata=0x88 |
343 | regaddr=0x86 regdata=0x88 |
344 | regaddr=0x87 regdata=0x88 |
345 | regaddr=0x88 regdata=0x88 |
346 | regaddr=0x89 regdata=0x88 |
347 | regaddr=0x8A regdata=0x88 |
348 | regaddr=0x8B regdata=0x88 |
349 | regaddr=0x8C regdata=0x88 |
350 | regaddr=0x8D regdata=0x88 |
351 | regaddr=0x8E regdata=0x88 |
352 | regaddr=0x8F regdata=0x88 |
353 | regaddr=0x90 regdata=0x88 |
354 | regaddr=0x91 regdata=0x88 |
355 | regaddr=0x92 regdata=0x88 |
356 | regaddr=0x93 regdata=0x88 |
357 | regaddr=0x94 regdata=0x88 |
358 | regaddr=0x95 regdata=0x88 |
359 | regaddr=0x96 regdata=0x88 |
360 | regaddr=0x97 regdata=0x88 |
361 | regaddr=0x98 regdata=0x88 |
362 | regaddr=0x99 regdata=0x88 |
363 | regaddr=0x9A regdata=0x88 |
364 | regaddr=0x9B regdata=0x88 |
365 | regaddr=0x9C regdata=0x88 |
366 | regaddr=0x9D regdata=0x88 |
367 | regaddr=0x9E regdata=0x88 |
368 | regaddr=0x9F regdata=0x88 |
369 | regaddr=0xA0 regdata=0x88 |
370 | regaddr=0xA1 regdata=0x88 |
371 | regaddr=0xA2 regdata=0x88 |
372 | regaddr=0xA3 regdata=0x1E |
373 | regaddr=0xA4 regdata=0x88 |
374 | regaddr=0xA5 regdata=0x88 |
375 | regaddr=0xA6 regdata=0x88 |
376 | regaddr=0xA7 regdata=0x88 |
377 | regaddr=0xA8 regdata=0x88 |
378 | regaddr=0xA9 regdata=0x88 |
379 | regaddr=0xAA regdata=0x88 |
380 | regaddr=0xAB regdata=0x88 |
381 | regaddr=0xAC regdata=0x88 |
382 | regaddr=0xAD regdata=0x88 |
383 | regaddr=0xAE regdata=0x88 |
384 | regaddr=0xAF regdata=0x88 |
385 | regaddr=0xB0 regdata=0x88 |
386 | regaddr=0xB1 regdata=0x88 |
387 | regaddr=0xB2 regdata=0x88 |
388 | regaddr=0xB3 regdata=0x88 |
389 | regaddr=0xB4 regdata=0x88 |
390 | regaddr=0xB5 regdata=0x88 |
391 | regaddr=0xB6 regdata=0x88 |
392 | regaddr=0xB7 regdata=0x88 |
393 | regaddr=0xB8 regdata=0x88 |
394 | regaddr=0xB9 regdata=0x88 |
395 | regaddr=0xBA regdata=0x88 |
396 | regaddr=0xBB regdata=0x88 |
397 | regaddr=0xBC regdata=0x88 |
398 | regaddr=0xBD regdata=0x88 |
399 | regaddr=0xBE regdata=0x88 |
400 | regaddr=0xBF regdata=0x88 |
401 | regaddr=0xC0 regdata=0x88 |
402 | regaddr=0xC1 regdata=0x88 |
403 | regaddr=0xC2 regdata=0x88 |
404 | regaddr=0xC3 regdata=0x88 |
405 | regaddr=0xC4 regdata=0x88 |
406 | regaddr=0xC5 regdata=0x88 |
407 | regaddr=0xC6 regdata=0x88 |
408 | regaddr=0xC7 regdata=0x88 |
409 | regaddr=0xC8 regdata=0x88 |
410 | regaddr=0xC9 regdata=0x82 |
Viele Grüße Igel1
Andreas S. schrieb: > Weiter unten findet Ihr meinen Code ... leider ohne die ausführenden Routinen ....
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:
1 | regaddr=0x4F regdata=0x40 regdata=0x88 SUCCESS |
2 | regaddr=0x50 regdata=0x34 regdata=0x88 SUCCESS |
3 | regaddr=0x51 regdata=0xC regdata=0x88 SUCCESS |
4 | regaddr=0x52 regdata=0x17 regdata=0x88 SUCCESS |
5 | regaddr=0x53 regdata=0x29 regdata=0x88 SUCCESS |
6 | regaddr=0x54 regdata=0x40 regdata=0x88 SUCCESS |
Viele Grüße Igel1
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
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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.... :/
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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) |
2 | { |
3 | OV7670_ResetFifoReadPointer(); |
4 | |
5 | for(int height = 0; height < ImageHeight;height++) |
6 | { |
7 | for(int width =0; width < ImageWidth; width++) |
8 | { |
9 | for(int ByteNumber =0; ByteNumber < BytesPerPixel; ByteNumber++) |
10 | { |
11 | OV_RCK_PORT &= ~(1<<OV_RCK_PinNo); |
12 | _delay_us(85); |
13 | UART0_senden_Byte(Ov7670_readByte()); |
14 | OV_RCK_PORT |= (1<<OV_RCK_PinNo); |
15 | _delay_us(85); |
16 | } |
17 | } |
18 | } |
19 | } |
die Variablen die in dieser Funktion übergeben werden, können vom Terminal aus angepasst werden (anhand des sync Camera buttons. ein nicht Übermitteln der Auflösung/des Farbformates sollte aber höchstens eine falsche Anzahl der gesendeten Bytes verursachen. Das Bild sollte aber dennoch zumindest zum Teil richtig angezeigt werden. (Daher weiß ich gerade noch nicht, was jetzt wirklich im Terminal schief läuft. Morgen habe ich aber wieder etwas Zeit und werde weiter arbeiten. Bis dahin, Gruß David
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.
Mist - und ich habe jetzt keine passende Frage ... Oder vielleicht doch: wie ist das Wetter? ?
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
Hallo, Andreas S. schrieb: > Oder vielleicht doch: wie ist das Wetter? ? hier laut meinem Balkon-Sensor: pffff.... Schau doch selber. ;) http://www.roehres-home.de/fhem/fhem.png Gruß aus Berlin Michael
:
Bearbeitet durch User
Michael U. schrieb: > hier laut meinem Balkon-Sensor: pffff.... Schau doch selber. ;) > http://www.roehres-home.de/fhem/fhem.png Ziemlich cool ... Selbst gebaut oder selbst gekauft? Viele Grüße Igel1
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
:
Bearbeitet durch User
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
@Michael U.: Danke für die Erklärungen - wieder was gelernt ... Viele Grüße Igel1
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)
:
Bearbeitet durch User
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.html https://elektroniktutor.de/bauteilkunde/kondens.html Wenn's Dir nicht so genau drauf ankommt, hier eine halbwegs "Laienkonforme" Erklärung: https://rn-wissen.de/wiki/index.php/Abblockkondensator Im ersten "Weiterführenden Weblink" gibt's die volle Theorie-Breitseite ... Im zweiten gibt's ein nettes YouTube-Video, was die Auswirkungen eines fehlenden 100nF Kondensators sehr eindrucksvoll zeigt. Etwas anspruchsvoller sind dann schon diese Links hier: http://www.g-qrp-dl.de/Projekte/bypass/bypass.pdf Oder - wieder einmal supergenial - die Seite von Lothar Miller (er ist meiner Meinung nach einer der genialsten Elektroniker, die hier im Forum herumhüpfen - frage mich immer, wie man ein so universelles Wissen im Bereich FPGA und Elektronik allgemein auftürmen kann): http://www.lothar-miller.de/s9y/categories/14-Entkopplung Viele Grüße Igel1 PS: hoffentlich habe ich mit meinem dröhnenden Schädel nicht zu viel Mist geschrieben.
Guten Abend, vielen Dank für die Informationen, @Michael das war genau das was ich wissen wollte. @Igel vielen Dank für die Zusammenstellung der Links. Diese Seite (ich spreche von den ersten Links) ist wirklich gut um das Wissen nochmal aufzufrischen.Ja ich hatte die komplexe Wechselstrom Lehre, allerdings im ersten bzw. zweiten Semester. Damals (vor 6 Jahren) hatte ich aber leider überhaupt keinen praktischen Bezug dazu. Beim durchlesen der Seiten kamen mir die Formeln aber noch sehr bekannt vor. Für morgen habe ich mir schon die nächsten Lese-Zeichen gesetzt. Jetzt Rückblickend macht alles so viel mehr Sinn :D... Da noch keiner mit dem Morgenstern über meine Lötkünste hergefallen ist nehme ich entweder an, dass ihr noch keine Zeit hattet die Bilder zu betrachten oder mir keine groben Schnitzer unterlaufen sind (ist natürlich aus der Ferne nur schwer zu beurteilen). Ich habe gerade eine neue Version vom Terminal hochgeladen. Mit vielen Bug-Fixes wodurch sich die Anzahl der Fehlermeldungen deutlich reduziert haben sollte. (Also nicht nur die Meldungen ^^) Da ich die Probleme vom Read Device Settings ebenfalls beim Write Device Settings habe, würde es mich interessieren, ob die bei euch auch durchlaufen. Wünsche euch einen schönen Abend. Gruß David
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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
Hi, wenn ich schon mal am schauen bin ...
1 | UCSR0C = 0b00001110; |
2 | ^^|||||| USART Mode Select |
3 | ^^|||| Parity Mode Bits |
4 | ^||| STOP Bit Select -> damit setzt Du 2 Stop-Bits |
5 | ^^| Character Size 11 -> 8Bit |
6 | ^ Clock Polarity |
... oder habe ich Tomaten auf den Augen? VG
Dieter F. schrieb: > ... oder habe ich Tomaten auf den Augen? Jein: Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)" ... und bitte auch das darauf folgende Posting von Michael lesen.
Nochmal hi, für heute die letzte Baustelle - siehe Hardcopy. Was passiert bei den längeren Strings? VG
Andreas S. schrieb: > ... und bitte auch das darauf folgende Posting von Michael lesen. Und warum testet ihr dann damit weiter, statt es zu korrigieren? Beitrag "Re: Brauche Unterstützung beim OV7670 (bzw. SCCB)" Ich bin kein U(S)ART-Spezialist, aber das wird schon seine Berechtigung haben: https://electronics.stackexchange.com/questions/335695/why-the-start-bit-and-the-stop-bits-are-necessary Keine Ahnung, wann und wie ein "Framing-Error" erkannt wird - aber ich versuche schon, gleiche Einstellungen auf beiden Seiten herzustellen. Ob und wie sich da die akzeptierte Fehlerrate von 2,1 % bei der Einstellung der Baudrate (bei 16 MHz Takt) kumuliert ist mir auch nicht bekannt.
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?
Ähmm ich stehe gerade mächtig auf dem Schlauch... Hier müsste mich mal jemand runter schubsen: In unserer UART_init:
1 | void UART0_init (void) |
2 | { |
3 | TX_DDR |=(1<<TX_Pin); //definiere TX Pin als Ausgang |
4 | RX_DDR &=~(1<<RX_Pin); //definiere RX Pin als Eingang |
5 | |
6 | |
7 | UBRR0H = 0b00000000; // Setzt Baudrate |
8 | //UBRR0L = 0b00110011; // dezimal : 103->9600; dez 68->14400;dez 51->19200; dez 8 ->115200 |
9 | //UBRR0L = 0b00011001; //38400 |
10 | //UBRR0L = 0b00000011; //230400 |
11 | //UBRR0L = 0b11001111; //9600 |
12 | UBRR0L = 0b00010000; //115200 |
13 | UCSR0A = 0b00000010; |
14 | |
15 | UCSR0A |=0b00000000; |
16 | // ^---U2X |
17 | ... |
Laut Datenblatt und Kommentar ist bei 16.0 MHz bei UBRR0n = 8 die Baudrate 115200. Das läuft ja auch schon seit Tagen/Wochen auf dieser Baudrate. im Code ist aber UBRR0L auf 16 und nicht auf 8? Wie kann das sein? ebenso die anderen Baudraten... sind ebenfalls "verschoben" ich habe das gefühl gerade völlig verrückt zu sein? :O Ddas gibts doch nicht. WO ist mein Denkfehler? EDIT: hat sich erledigt.... das U2X bit ist ja gesetzt... warum zum Teufel wird dann nochmal mit dem gleichen Register verodert? :D... das nehm ich jetzt erstmal raus...
:
Bearbeitet durch User
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.
1 | while(((Befehl[i+j-2] != (char)0x0D) || (Befehl[i-1] != (char)0x0A))&&(i<10)); |
Dein ODER sagt, dass Du bei einem 0x0A ein Zeilenende (und KEINEN Befehl) oder ein 0x0D (auch kein Befehl) erkannt hast und damit auch KEINEN gleichlautenden Befehl abarbeiten wirst. Dein "i+j-2" vs. "i-1" entwirrst Du bitte selbst :-)
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
:
Bearbeitet durch User
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 |
2 | 51c: eb 85 ldd r30, Y+11 ; 0x0b |
3 | 51e: fc 85 ldd r31, Y+12 ; 0x0c |
4 | 520: 8d 85 ldd r24, Y+13 ; 0x0d |
5 | 522: 9e 85 ldd r25, Y+14 ; 0x0e |
6 | 524: a1 e0 ldi r26, 0x01 ; 1 |
7 | 526: b0 e0 ldi r27, 0x00 ; 0 |
8 | 528: ac 0f add r26, r28 |
9 | 52a: bd 1f adc r27, r29 |
10 | 52c: ea 0f add r30, r26 |
11 | 52e: fb 1f adc r31, r27 |
12 | 530: e8 0f add r30, r24 |
13 | 532: f9 1f adc r31, r25 |
14 | 534: 32 97 sbiw r30, 0x02 ; 2 |
15 | 536: 80 81 ld r24, Z |
16 | 538: 8d 30 cpi r24, 0x0D ; Wenn 0x0D erkannt wird wird 0x0A nicht mehr verprobt |
17 | Es geht dann direkt zum Check auf kleiner 10 |
18 | 53a: 39 f4 brne .+14 ; 0x54a <UART0_rx_work+0xa2> |
19 | 53c: eb 85 ldd r30, Y+11 ; 0x0b |
20 | 53e: fc 85 ldd r31, Y+12 ; 0x0c |
21 | 540: ec 0f add r30, r28 |
22 | 542: fd 1f adc r31, r29 |
23 | 544: 80 81 ld r24, Z |
24 | 546: 8a 30 cpi r24, 0x0A ; 10 |
25 | 548: 21 f0 breq .+8 ; 0x552 <UART0_rx_work+0xaa> |
26 | 54a: 8b 85 ldd r24, Y+11 ; 0x0b |
27 | 54c: 9c 85 ldd r25, Y+12 ; 0x0c |
28 | 54e: 0a 97 sbiw r24, 0x0a ; 10 |
29 | 550: 64 f2 brlt .-104 ; 0x4ea <UART0_rx_work+0x42> |
David D. schrieb: > Habe ich und funktioniert. Ja, weil Du (wie ich zu spät gesehen habe) damit ja zufällig die korrekte Folge schon im Speicher hast - obwohl Du den Terminator (0x0D und 0x0A) noch gar nicht gelesen hast und auch nie lesen wirst, weil ja 0x0D schon erkannt worden ist.
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
Ich kann leider den Assambler Code nicht lesen. vielleicht würde ich sonst verstehen, auf was du mich aufmerksam machen möchtest.
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
Beitrag #5807520 wurde von einem Moderator gelöscht.
David D. schrieb: > Sind wir dann JETZT einer Meinung? Ja. Ich werde mal die UART-Routinen ersetzen und schauen, ob es dann stabiler wird.
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
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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
Beitrag #5810269 wurde vom Autor gelöscht.
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
Hallo, Andreas S. schrieb: > Geliefert wie bestellt (oder genauer: fast, wie bestellt - ich finde > sogar noch etwas eleganter, als bestellt): anbei Version 0.03 vom > SendMaster. Das ist ein Service! Morgen komme ich nicht zum Testen, ich muß wirklich mal für meinen Rentner-Nebenverdienst auch noch arbeiten.... ;-) OT: da Du ja seltsame Sachen magst, heute entdeckt und einfach mal bestellt (wofür auch immer...): https://www.shotech.de/de/advanced_search_result.php?categories_id=0&keywords=air602&inc_subcat=1 Bei Seeedstudio sind die Unterlagen und das SDK verlinkt: https://www.seeedstudio.io/Air602-WiFi-Module-p-3139.html irgendwo ziemlich unten auf der Seite. Gruß aus Berlin Michael
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
:
Bearbeitet durch User
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
:
Bearbeitet durch User
Dieter F. schrieb: > Jein. Nicht analog Deines "."-Mechanismus - aber man kann natürlich > entsprechende Eingaben (auch per Datei) machen und die Rückgabewerte > anschauen. Ah, interessant. Das mit dem Datei-Einlesen wollte ich bei mir auch noch einbauen - schau'n wir mal. > Andreas S. schrieb: >> So ganz habe ich jetzt nicht verstanden, was Du vorhast, aber ich >> entnehme dem, dass Du vermutlich kein DebugWire zum Debugging nutzt? > > Genau - hier reicht es mir aus, an bestimmten Stellen kleine Ausgaben zu > erzeugen um zu schauen, ob alles O.K. ist. Claro - so geht's auch - ist halt etwas umständlicher als Breakpoints und DebugWire. Aber bekanntlich führen ja viele Wege nach Rom. > Ansonsten habe ich den Atmel > ICE zur Verfügung. Dann scheinst Du auf der Sonnenseite des Lebens zu parken (mal rein investment-mäßig gesprochen) :-) Die Anleitung hier scheint ganz gut zu beschreiben, wie Du Deinen ICE mit einem Nano zusammenschrauben und ans Fliegen bringen kannst: http://www.crash-bang.com/debug-atmel-ice/ Falls das wirklich funktioniert, so würde ich dieses Feature an Deiner Stelle unbedingt nutzen - Debugging im Studio mit Breakpoints und Single-Step Modus erleichtert die Entwicklung und das Debuggen nach meiner Erfahrung massiv. 1-2h Einarbeitung, danach nie wieder Print-Statements in den Code einfügen und wieder rauslöschen - das lohnt sich. > VG (Viele Grüße) > Dieter VGZ (Viele Grüße zurück) Andreas
:
Bearbeitet durch User
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
kurzes Lebenszeichen... Die Woche ist wieder besonders schlimm...
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
Frohe Ostern, Ihr Lieben! Wer als erstes den Osterhasen mit unserer OV7670 ablichtet, hat gewonnen! 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
:
Bearbeitet durch User
Hallo David, hi Leute, wollte nur sagen: mich gibt's noch, habe aber gerade andere private Baustellen (Auto). Werde mich mit Deinen GIT-Tipps (danke dafür) die Tage einmal beschäftigen. In der freien Zeit versuche ich immer noch, die serielle Schnittstelle unter C# über das Auslesen des Basestreams ans Laufen zu bekommen - bislang leider nur mit sehr mäßigem Erfolg: Lesen geht schon irgendwie, aber ich möchte auch wissen, wann ein Timeout passiert und das geht aktuell noch nicht, weil der Timeout von Serialport.Basestream scheinbar keine Exceptions wirft. Außerdem ist alles in diesem Bereich nur sehr mau von Microsoft dokumentiert. Macht nicht sonderlich viel Spaß, die Raterei. Viele Grüße Igel1
:
Bearbeitet durch User
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
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.