Bei diesem Projekt geht es darum, ein FBAS-Videosignal mit dem ADC eines
STM32F103C8T6 abzutasten, per USB zum PC zu übertragen und dort
auszuwerten.
Richtig, ein FBAS-Image-Grabber hat praktisch keinen Nutzwert, erst
recht nicht 2022.
#### Warum macht man sowas?
Angefangen hat es mit einer STM32-Fingerübung. Ziel war, das
Videotextsignal ohne CPU, also nur mit Hilfe der STM32-Peripherie, als
Byte-Stream einzulesen. Weil das zu schnell fertig war, habe ich noch
Tests mit dem Luminanzsignal gemacht. Die Zeilensynchronisation (+-14ns)
nur anhand von ADC-Werten (1000ns Intervall) war schwierig, klappte dann
aber auch. Voller Hochmut wollte ich alles mit dem Farbsignal
"vollenden". Eine Riesendummheit. PAL-Standard, Unterabtastung,
Starrsinn und ein planloses Vorgehen sind eine schlechte Kombination.
Die ersten 80% der Projektzeit waren eigentlich eine einzige
Fehlersuche. Dutzende Stunden Lebenszeit wurden vernichtet. - So ist man
halt.
#### Warum der Thread?
Einfach weil ein STM32 zum FBAS-Image-Grabben skurril ist und das
Ergebnis vielleicht überrascht - s. Anhang "01_Modus_1.jpg".
Anmerkung: Das Bild ist wegen der Dateigröße jpeg-komprimiert und zeigt
nicht die richtige Qualität (mal besser mal schlechter). Der Anhang
"02_Modus_0.png" ist hingegen ein verlustfrei komprimierter
Bildausschnitt, sofern die Forumssoftware das nicht geändert hat.
(Den weiteren Post-Text kann man sich sparen.)
#### Bildauflösung
Das schwächste Glied ist nicht der ADC sondern der USB. Mit dem
STM32F103 ("USB Full Speed") sind nur 1 MByte/s möglich, also 64 Byte
pro Bildzeile. Bei 1 Byte/Pixel sind das 59 Pixel/Zeile (Netto). Wenn
mehrere Frames (mit unterscheidlichem x-Offset) zu einem Bild
zusammengefasst werden, dann ist die Auflösung mit 1872 Pixel/Zeile
allerdings sehr gut und übertrifft die maximale Composite-Auflösung bei
weitem. Der Wert 1872 ergibt sich aus dem sichtbaren Zeilenbereich
(52µs) und der ADC-Taktfrequenz (36MHz=fCPU/2).
#### Standbilder
Für ein farbiges Bild mit 8 Bit/Komponente und 1888x576 Pixel müssen
Daten von 64 Vollbildern (=1888/59*2) überlagert werden. Für ein Bild
braucht man dann 2.56 Sekunden. Diese Zeit ist eine Art Belichtungszeit.
Bei bewegten Bildern kann man also nicht mehr viel erkennen.
Im Bild "02_Modus_0.png" sind die vertikalen Linien unsauber. Die
Hauptursache liegt darin, dass die ADC-Frequenz vom STM32-Takt
abgeleitet werden muss und daher nicht synchron zur Zeilenfrequenz
laufen kann. Die Pixel wackeln deshalb über +-0.5 Pixel. Der genaue
Zeitpunkt für ein Pixel einer Zeile kann aber mit Hilfe des
PAL-Burst-Signals auf 1ns genau (gemessene Streuung) ermittelt werden.
Wenn man extrem lange mißt, wäre eine Auflösung von 50000 Pixel/Zeile
möglich.
#### bewegte Bilder
Im Programm habe ich auch Versuche gemacht um die "Belichtungszeit" zu
verkleinern. Das geht über die Reduzierung von Farbtiefe und Auflösung.
Das Hauptproblem dabei ist, dass man für die Aufspaltung vom Signal in
Luminanz und Chrominanz auch gleichzeitig geeignete Samples (Zeitpunkt
und Ort) benötigt. Fehler (Ort, Zeit, Farbtiefe, Farbart, Sättigung,
Farbränder, Flimmern, Schatten, Unschärfen, ...) sind nicht zu
verhindern. Man kann sie nur untereinander umschichten.
Beim Programm sind 7 Modi wählbar:
1
// - Modi
2
// 0: 2.56 s / 1880 x 576
3
// 1: 1.28 s / 940 x 576
4
// 2: 0.64 s / 940 x 576 weniger Farbtiefe
5
// 3: 0.32 s / 940 x 576 halbe XY-Auflösung & weniger Farbtiefe,
6
// 4: 0.32 s / 480 x 576 halbe XY-Auflösung
7
// 5: 0.16 s / 480 x 576 halbe XY-Auflösung & weniger Farbtiefe
8
// 6: 0.04 s / 480 x 576 halbe XY-Auflösung & weniger Farbtiefe & xyz
Der Modus 6 ist ein Sonderfall. Die um den Faktor 4 bessere
Zeitauflösung gegenüber Modus 5 gibt es so nicht. Beim Modus 6 wird
versucht Bildänderungen zu erkennen und gegebenenfalls die Auflösung
einzelner Bildbereiche zu reduzieren. Im Prinzip geht es nur um ein
(vertikales) Deinterlacing. Es sind aber nicht nur eine einzige sondern
mehrere Spalten zu überbrücken und die liegen zeitlich weit auseinander.
Daraus entsteht das Problem, dass auch kleine Fehler beim Deinterlacing
auffällige Artefakte (da groß und andauernd) hinterlassen. Zu viel
fehlende Informationen kann man eben nicht einfach kaschieren. Das
Ergebnis lässt sich nicht mit Worten beschrieben und es ist sehr viel
schlechter als man nach dem Bild "03_Modus_6.jpg" meinen würde. Machbar
wäre mehr.
#### Software
Das Programm ist vermutlich nur auf einem realen System lauffähig. Mit
VirtualBox 4.2.18 war jedenfalls die USB-Geschwindigkeit zu niedrig
(950kB/s -> ca. 10% VBox-Verluste und damit 5% zu langsam).
Der Source-Code ist nur aus Prinzip angehängt. Es ist ein Bastelcode!
#### Fazit
- Die Bildqualität bei stehenden Bildern ist überraschend gut. Für
bewegte Bilder reicht es aber nicht. Das Fernsehbild in den 1950er
Jahren war vermutlich besser. Zwar Schwarz-weiß, dafür ohne
Bewegungsartefakte.
- Bei allen Bildeigenschaften (örtliche-, zeitliche-, farbliche
Auflösung, ...) scheint die Wahrnehmungsgrenze für Fehler sehr scharf zu
sein.
- Mit dem STM32F103 können periodische Signale mit über 100 MHz
Bandbreite erfasst werden. Sternchentext: ...
Danke fürs zeigen und Gratulation zum Durchhaltevermögen!
Eigentlich habe ich nur eine Frage, aber die ist wohl ziemlich
unangemessen. Ich stelle sie trotzdem: Gefällt Dir EmBitz 2.3 besser als
1.11 und warum?
Ich nutze nur die Kernfunktionen von EmBitz. Trotzdem hat die Version
2.3 auch für mich einige Vorteile gebracht:
Sehr wertvoll ist das gut funktionierende Wiederherstellen der
Debug-Einstellungen ("Watches") beim Programmstart. Auch die neue
Funktion "Target Hotplug" ist klasse, auch wenn ich sie nur selten
brauche. Außerdem ist man mit der 2.3 wieder UpToDate und man fühlt sich
nicht mehr wie auf einem Abstellgleis. Das neue EBlink finde ich sehr
gelungen: Mehrere Programmieradapter sind auf verschiedenen Rechnern
(auch Linux) Remote verwendbar und die Skriptfähigkeit ermöglicht
wichtige kleinere Tweaks.
Mehr Vorteile fallen mir im Moment nicht ein.
Besten Dank für das Teilen Deiner Erfahrung! "Mitten" im Projekt die IDE
wechseln werde ich wohl nicht, aber das nächste Kleinprojekt probiere
ich es aus.
Wie schätzt Du den Aufwand ein, ein reines 1-Bit-Monochromsignal zu
erfassen? Welche "samplerate" könnte damit erreicht werden?
Ich versuche, einen ollen Röhrenkübel eines alten Gerätes durch was
neueres zu ersetzen. Ein TFT-Display mit Composite-Eingang funktioniert
prinzipiell, aber leider macht das Ding Overscan, was man ihm nicht
abgewöhnen kann, und das schneidet relevante Inhalte an allen Rändern
ab.
Timing ist ausreichend genau am "Fernseh"-Standard, daß der
Composite-Eingang des Displays damit zurechtkommt, der ixeltakt liegt
bei 10 MHz und wie gesagt, es ist 1-Bit-Monochrom, also Pixel an oder
Pixel aus.
DerEinzigeBernd schrieb:> Wie schätzt Du den Aufwand ein, ein reines 1-Bit-Monochromsignal zu> erfassen? Welche "samplerate" könnte damit erreicht werden?
Das habe ich mit einem AVR8 vor fast 20 Jahren schon getan. Dafür
brauchst du keinen ADC, sondern nur einen AC. Und praktischerweise kann
man die ACs der ollen AVR mit dem Capture-Mechanismus eines Timers
direkt koppeln. Damit ist mögliche zeitliche (und damit
horizontal-räumliche) Auflösung nur dadurch bestimmt, wie schnell deine
Capture-ISR läuft.
Das hat praktisch nix mit der Komplexität von FBAS zu schaffen, das ist
um viele Größenordnungen einfacher.
Sprich: du bist in diesem Thread deutlich falsch.
Tim . schrieb:> Respekt, super Projekt! Wenn man bedenkt, das es früher als> Herausforderung angesehen wurde, ein B/W PAL Signal mit einer 8-Bit MCU> zu erzeugen...
Nö, erzeugen war niemals ein großes Problem, das habe die ganzen
Hobbycomputer der 70er und 80er Jahre des vorigen Jahrhunderts schon
gemeistert. Einlesen hingegen ist schon ganz erheblich schwieriger.
Aber, wie schon gesagt: selbst das paßt nicht in diesen Thread, in dem
es um das Einlesen von FBAS geht. DAS ist wirklich DEUTLICH
schwieriger. Das spielt sich in ganz anderen Frequenzbereichen ab und
ist offensichtlich selbst mit einem recht ordentlich motorisierten STM32
nur durch Supersampling machbar.
Cooles Projekt. Schön zu sehen, was man aus so einem kleinen
Mikrocontroller alles rausholen kann.
Verstehe ich das richtig: Du samplest in mehreren Durchgängen 1888 Werte
pro Zeile? Das entspricht bei einer Zeilenlänge von 64µs dann 29,5MSPS.
Damit der Trick mit der Unterabtastung funktioniert, muss halt die
Samplezeit klein genug sein. Laut Datenblatt sind das bei f_ADC=14MHz
0,107µs, was aber nur 9,345MSPS = 598 Samples/Zeile entspricht. Bringt
das dann überhaupt noch was?
Die größeren STM32, z.B. die H7 gibts auch mit schnelleren ADCs, viel
mehr RAM, schnellem USB und JPEG-Kompression. Aber da wäre vielleicht
die Herausforderung nicht so groß. :)
Markus K. schrieb:> Verstehe ich das richtig: Du samplest in mehreren Durchgängen 1888 Werte> pro Zeile? Das entspricht bei einer Zeilenlänge von 64µs dann 29,5MSPS.
Es sind 36,0 MSPS, da fADC=36 MHz ist.
Der AD-Wandler wird also extrem übertaktet. Ohne Übertaktung wäre das
Rauschen der Farbphase größer als 90°, wodurch die Trennung von Luminanz
und Chrominanz für sehr viele Pixel nicht möglich wäre.
Wie ich erst heute gemerkt habe (Danke!), bleiben wegen der Übertaktung
von den 12 Bits nur im "wesentlichen" 10 Bits übrig. Es gibt nämlich
grob acht Stellen über den ADC-Wertebereich, an denen nicht mal 8 Bits
bleiben. Im Bild dürfte das allerdings kaum auffallen, da nur einige
Pixel um etwa 3% verfälscht sind und selbst gute Bilder auch so schon
ziemlich verrauscht sind.
Für normale ADC-Projekte dürfte eine Übertaktung jedenfalls für mich ab
jetzt tabu sein.
> Damit der Trick mit der Unterabtastung funktioniert, muss halt die> Samplezeit klein genug sein. Laut Datenblatt sind das bei f_ADC=14MHz> 0,107µs, was aber nur 9,345MSPS = 598 Samples/Zeile entspricht. Bringt> das dann überhaupt noch was?
Für die Genauigkeit spielen einige Parameter eine Rolle:
- Samplezeit (Source-Code): 0.042 us (=1.5/36MHz)
- Pixelzeit (Source-Code): 0.028 us (=1.0/36MHz)
- Eingangswiderstand (Schaltplan): 520 Ohm (=50+470)
- Widerstand zum Sample&Hold-Kondensator (Datenblatt): 1000 Ohm
- Kapazität vom Sample&Hold-Kondensator (Datenblatt): 8 pF
- Umschaltzeit von Sample nach Hold (vermutlich): <0.005 ns
- Board-Kapazität für den ADC-Pin: ? pF
Theorie:
Die Zeitkonstante für das Sampeln beträgt 0.0122µs (=R*C=1520Ohm*8pF).
Demnach müsste man für ein Pixel 90% der Helligkeitsänderung
(=(1-exp(-0.028µs/0.0122µs) erreichen.
Wenn man den Eingangswiderstand von 470 Ohm auf 100 Ohm verkleinert,
dann sind es 95% (=(1-exp(-0.028µs/0.0092µs).
Praxis:
Zur Messung habe ich ein 1MHz-PWM-Signal mit 0.028µs Pulslänge von einem
zweiten Controller angelegt. Am Histogramm der ADC-Werte kann der
Endwert sehr deutlich ermittelt werden. Trotz der zusätzlichen
Board-Kapazität erreicht man 84% bei 470 Ohm und 99.6% bei 100 Ohm.
Die Praxis passt zwar nicht zur Theorie, aber die Genauigkeit reicht
eigentlich in beiden Fällen für 1872 Pixel. Da das FBAS-Signal vom
Receiver laut Doku eine Auflösung von 720 Pixel hat, sind die 1872 Pixel
letztendlich doch übertrieben.
> Die größeren STM32, z.B. die H7 gibts auch mit schnelleren ADCs, viel> mehr RAM, schnellem USB und JPEG-Kompression. Aber da wäre vielleicht> die Herausforderung nicht so groß. :)
Also 720x576 Pixel mit 25 fps YUV sollten damit tatsächlich gehen. Für
eine JPEG-Kompression dürfte es knapp werden. Wenn ich mich nicht irre
bräuchte nämlich ein Kern eines 2.1GHz Core2Duo 10% CPU dazu.
Auf die Schnelle habe ich nur einen kaufbaren H7 gefunden und das zum
Preis von über 20 Euro. Einen fertigen Grabber gibt es in China für die
Hälfte. :-)
Franz schrieb:> Markus K. schrieb:>> Verstehe ich das richtig: Du samplest in mehreren Durchgängen 1888 Werte>> pro Zeile? Das entspricht bei einer Zeilenlänge von 64µs dann 29,5MSPS.>> Es sind 36,0 MSPS, da fADC=36 MHz ist.
Aber da die Samplezeit 1,5 Takte beträgt sind es nur 36/1,5=24MSPS.
> Die Praxis passt zwar nicht zur Theorie, aber die Genauigkeit reicht> eigentlich in beiden Fällen für 1872 Pixel. Da das FBAS-Signal vom> Receiver laut Doku eine Auflösung von 720 Pixel hat, sind die 1872 Pixel> letztendlich doch übertrieben.
Früher, als die Pixel noch quadratisch waren, hatte PAL eine Auflösung
von 768x576 und NTSC 640x480. Das hat man dann irgendwann
vereinheitlicht und ist bei 720x576 und 720x480 gelandet. Letztendlich
ist es halt ein analoges Signal und hat einfach eine bestimmte
Bandbreite. Ein VHS-Videorekorder hat da deutlich weniger Auflösung als
ein DVD-Player.
>> Die größeren STM32, z.B. die H7 gibts auch mit schnelleren ADCs, viel>> mehr RAM, schnellem USB und JPEG-Kompression. Aber da wäre vielleicht>> die Herausforderung nicht so groß. :)>> Also 720x576 Pixel mit 25 fps YUV sollten damit tatsächlich gehen. Für> eine JPEG-Kompression dürfte es knapp werden. Wenn ich mich nicht irre> bräuchte nämlich ein Kern eines 2.1GHz Core2Duo 10% CPU dazu.
Es gibt Modelle mit JPEG-Kompression in Hardware.
https://www.st.com/resource/en/application_note/dm00356635-hardware-jpeg-codec-peripheral-in-stm32f7677xxx-and-stm32h743534555475750a3b3b0xx-microcontrollers-stmicroelectronics.pdf> Auf die Schnelle habe ich nur einen kaufbaren H7 gefunden und das zum> Preis von über 20 Euro. Einen fertigen Grabber gibt es in China für die> Hälfte. :-)
Ist halt ein schlechter Zeitpunkt um Elektronik zu kaufen.
Aus der Erfahrung heraus muss ich sagen, dass die China-Grabber nicht
unbedingt die problemlosesten Treiber haben. Das wäre hier wohl besser.
Markus K. schrieb:> Franz schrieb:>> Markus K. schrieb:>>> Verstehe ich das richtig: Du samplest in mehreren Durchgängen 1888 Werte>>> pro Zeile? Das entspricht bei einer Zeilenlänge von 64µs dann 29,5MSPS.>>>> Es sind 36,0 MSPS, da fADC=36 MHz ist.>> Aber da die Samplezeit 1,5 Takte beträgt sind es nur 36/1,5=24MSPS.
Eigentlich gibt es im Programm keine richtige Samplefrequenz, da die
sich mehrfach in jeder Zeile ändert. Für die Bildpixel könnte man aber
die Frequenz von 1.125 MSPS nennen.
Die 1.5 Takte ist die Taktanzahl, für die der Sample&Hold-Kondensator
zugänglich ist. Entscheidend für den AD-Wert ist aber nur die
Kondensatorspannung am Ende der 1.5 Takte. Und die hängt von den
Bauteilewerten (Eingangswiderstand, Sample&Hold-Kondensator, ...) ab.
Letztendlich landet man in diesem Fall trotzdem in der Größenordnung von
29,5MSPS. Das liegt an der großen Unsicherheit bei der Berechnung und
auch bei der Messung. Da wären 50% Abweichung eigentlich wenig.
> Es gibt Modelle mit JPEG-Kompression in Hardware.> https://www.st.com/resource/en/application_note/dm00356635-hardware-jpeg-codec-peripheral-in-stm32f7677xxx-and-stm32h743534555475750a3b3b0xx-microcontrollers-stmicroelectronics.pdf>
Danke, werde ich mir ansehen.
Ja klar, kein Problem.
Arduinofan schrieb:> Mal sehen ob ich es in Arduino verwenden kann.
Falls was daraus wird, dann zeig doch bitte das Ergebnis hier im Forum!
:-)