Forum: Platinen UV-Laserdrucker


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Dieter F. (Gast)


Angehängte Dateien:

Lesenswert?

Jens schrieb:
> Hoffentlich hast du den Spiegelmotor
> nicht mit gegrillt!

Hallo Jens,

nein, dann würde er auch mit dem Frequenzgenerator nicht mehr laufen.

Kerko 100 nF habe ich direkt auf den Adapter gelötet, die Kerkos für den 
Quarz sitzen auch gut. Spannungsversorgung ist stabilisiert mit Elko(s).

Habe 2 Bilder angehängt (mache ich in dem Stadium nicht gerne ... gibt 
zuviel Haue ...:-( ). Egal 1 mal der Aufbau auf Lochraster und dann noch 
ein Oszi-Bild des generierten Signals. Mir fällt nichts besonderes auf. 
Zur Sicherheit ziehe ich das Signal mit 100 kOhm auf GND ... . Habe den 
MC auf Sockel gesetzt und einen ISP-Anschluss zugefügt. Funktioniert 
alles ...

Die Schaltung mit den 2 Transistoren und dem P-FET stammt hier aus 
"Snippets" - schaltet den Polygonmotor an und aus. Funktioniert, hat 
auch vorher schon funktioniert.

Gruß
Dieter

von Dieter F. (Gast)


Lesenswert?

Oh nein! Es ist nicht zu glauben ...

Die low-Phase war zu kurz - jetzt mit dem ATTiny85, auf dem ATTiny2313 
war es ausreichend. Ich weiß, kann eigentlich gar nicht sein, da beide 
mit dem gleichen Quarz gleich schnell sind.ggf. ist die Flankensteilheit 
bei dem ATTiny2313 besser - oder meine Schaltung war "besser". Egal, 
jetzt geht es wieder :-)

Habe
1
OCR0B  = 0x00;                                // Ab 0 wird das Ausgabe-Bit gesetzt

durch
1
OCR0B  = 0x01;                                // Ab 1 wird das Ausgabe-Bit gesetzt

ersetzt und damit die low-Phase verlängert - und Bingo!

Hat mich, seit gestern, einen Tag gekostet :-(

von Jens (Gast)


Lesenswert?

Hallo Dieter,

schön dass es funktioniert.
Was mir bei deinen Bildern noch auffällt sind die starken Überschwinger. 
Die sind bei fast 2V. Das ist schon viel. Vielleicht kannst du da noch 
ein bisschen Filtern bei vielleicht 10MHz. Also ein RC-Glied an den 
Ausgang.
Ich würde als Serienwiderstand 100 Ohm nehmen und als Kondensator 150p.

Dann die Flanken nochmal messen und gegebenenfalls nochmal anpassen. 
Dann kommst du besser hin.
Und beim Messen immer den Tastkopf auf 1:10 stellen, dass die Bandbreite 
passt und man nicht das Klingeln des Tastkopfs misst.

Grüße, Jens

von Dieter F. (Gast)


Lesenswert?

Jens schrieb:
> Was mir bei deinen Bildern noch auffällt sind die starken Überschwinger.
> Die sind bei fast 2V. Das ist schon viel. Vielleicht kannst du da noch
> ein bisschen Filtern bei vielleicht 10MHz. Also ein RC-Glied an den
> Ausgang.

Hallo Jens,

ja -- habe den Tastkopf auf 1:10 umgestellt (erwischt :-) ) aber die 
Überschwinger sind - je nach "timebase" - immer noch da. Filtern tue ich 
erst, wenn der "Wirkbetrieb" gestört wird. Aktuell also nicht ...

Übrigens glaube ich nicht, dass die Überschwinger ein Problem darstellen 
- wichtig ist, dass PIN2 des Polygonmotors in definierten Abständen auf 
GND gezogen wird. Der Rest spielt - aus meiner Sicht - keine 
entscheidende Rolle.

Werde als nächstes den LD-Treiber anklinken und dann das Gesamtkonstrukt 
Testen. Ostern steht vor der Tür - und ich will dann wieder unter den 
Laser-Belichtern sein :-) (hoffentlich ...)

Gruß
Dieter

von Martin S. (pcterabyte)


Angehängte Dateien:

Lesenswert?

Mal ein kleines update...

Heute hab ich endlich die erste kleine Platine mal nebenbei belichten 
und fertigen können.

Ich hatte noch ein weiteren Drucker geschlachtet und könnte ein schönes 
Bedienfeld (2 Taster und 4 Leds) von einem HP Drucker ausschneiden. Da 
brauchte ich mal schnell ein Adapter fürs Steckbrett, gesagt getan und 
gleich damit die Probe aufs Exempel.

Bild 7: Nach dem Entwickeln
Bild 8: Nach dem Ätzen und entfernen restlicher Fotoschicht
Bild 9: Fertig :)

Gruß
Martin

: Bearbeitet durch User
von Dieter F. (Gast)


Lesenswert?

Hallo Martin,

das sieht ja prima aus - mein Glückwunsch.

Ich kann keine Verzerrungen etc. erkennen. Wäre froh, wenn ich auch 
schon den Stand erreicht hätte ...

Kannst Du Gelegentlich mal ein Bild Deines "Boliden" in Action 
einstellen?

Gruß
Dieter

von Dieter F. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

Ostern steht vor der Tür - und ich habe endlich wieder einen halbwegs 
vernünftigen Stand :-)

Ich bekomme das mil-Pattern wieder hin (Abstände noch nicht korrigiert) 
- den Umstieg auf ATXMega und den IC-HG mit ATTiny85 habe ich damit 
schon mal halbwegs geschafft.

Aktuell habe ich noch Probleme mit dem Synch.-Impuls. Der "flattert" 
noch ab und an weg - muss ich wohl noch etwas suchen ...

Die Datenübertragung vom und zum PC (921.600 Baud) funktioniert 
einwandfrei. Bei der Schrittmotorsteuerung muss ich wohl bei den 
Einzelschritten noch ein wenig mit dem delay spielen.

Gut, dass ich die neue LD-Treiber-Platine noch nicht wieder neu in 
Arbeit gegeben habe. Ich hatte nicht bedacht, dass die Eingänge des 
ATXMega nicht 5V-spannungsfest sind und hatte da noch ein "paar 
Kleinigkeiten" anzupassen.

Schön, dass ich die minimale Pulsbreite jetzt auf 20 Takte bei 32 MHz = 
1,6 MHz und damit ca. 2 mil (vorher 30 Takte bei 16 MHz = 533 kHz und 
damit ca. 6 mil) verringern konnte. Braucht man zwar nicht, gibt aber 
etwas Reserve.

Gruß und schöne Ostern
Dieter

von Guido B. (guido-b)


Lesenswert?

Sieht gut aus, weiter so! :-)

von Jens (Gast)


Lesenswert?

Hallo Dieter,

da kann ich mich nur anschließen! Sieht super aus.

Ich bin auch in den letzten Zügen. Ich habe nun alle Kommunikationen 
zwischen PC und den beiden Controllern fertig. Mit dem Debugger sieht 
auch alles gut aus. Heute Abend oder morgen werde ich das dann am 
"lebenden" Objekt testen können. Mal sehen ob es da auch so schön 
aussieht.
Ich bin schon ganz gespannt.

Aber ich muss hier noch was los werden:
Zwei Controller in einem Gerät zu verbauen ist KEINE gute Idee. Das 
werde ich nicht mehr machen. Ich habe das so geplant, da es die 
Controller als DIL Gehäuse gibt und ich die leicht auf Lochraster 
bekomme. Aber der Aufwand, den man sich beim Aufbau gespart hat, steckt 
man mindestens doppelt und dreifach wieder in die Software.
Ein Protokoll zwischen den Controllern zu implementieren macht sich 
nicht in ein paar Stunden. Das hat mich richtig viel Zeit gekostet. 
Funktioniert zwar prima, aber ich würde das nicht mehr so machen. Dann 
lieber einen XMEGA nehmen und der macht alles was die beiden zusammen 
auch können.

Grüße und frohe Ostern an alle, Jens

von chris (Gast)


Lesenswert?

Braucht jemand EV Platinen? Werde am 10 bestellen, es ware noch Platz 
vorhanden. 6mil rules mit Möglichkeit von innenfrasungen.

von Jens (Gast)


Lesenswert?

Hallo an alle,

also ich habe am Wochenende endlich meine ersten Tests fahren können. 
Allerdings ist das Ergebnis noch nicht so toll.
Ich habe noch vertikale Streifen auf meinem Layout. Man kann aber 
erkennen wie schön die Auflösung mal werden wird. Das ist schon mal gut.
Ich denke ich habe noch Probleme bei der Datenübertragung zwischen den 
Controllern. Da sieht es so aus, als ob das Layout verschoben wäre. Was 
natürlich für einen falschen RAM zugriff spricht.
Da muss ich mir jetzt erst nochmal überlegen wie ich das Debuggen will. 
Da bin ich grad noch ein wenig ratlos.
Ich bin auch am Überlegen ob ich nicht doch noch auf den XMEGA umsteige 
um die Probleme zu umgehen. Ich weiss halt nicht ob ich da noch viel 
Arbeit reinstecken muss bis ich das richtig zum Laufen bekommen habe 
oder ob es weniger Aufwand ist auf einen anderen Controller umzusteigen. 
Da werde ich nochmal in mich gehen müssen. Es widerstrebt mir ein 
bisschen kurz vor dem Ziel das Konzept wieder völlig über den Haufen 
schmeißen zu müssen.

Wie sind eure Ergebnisse?

Grüße, Jens

von Jens (Gast)


Lesenswert?

Hallo an alle,

also ich habe gestern noch weiter getestet.
Ergebnis ist nicht so toll. So wie es aussieht gibt es die Probleme, da 
sich die Controller gegenseitig blockieren. Ich habe so keine 
Möglichkeit die Interrupts der beiden Controller zu synchronisieren.
Und wenn der eine gerade beschäftigt ist und der andere aber Daten haben 
will gibt Fehler bei der Übertragung.
Mein Fazit:
Ich muss da noch einiges umbauen. Und da ich so auch keine Möglichkeit 
sehe die beiden Controller gleichzeitig zu debuggen werde ich nun auch 
auf den XMAGA umsteigen. Das wollte ich zwar erst später machen, aber 
ich denke ich kann mir dadurch sehr viel Zeit sparen.

Grüße, Jens

von Jens B. (fernostler)


Angehängte Dateien:

Lesenswert?

Zurück zu http://www.das-labor.org ...

Ist das PCB Layout doppelseitig? Da schimmert was durch.

http://www.das-labor.org/wiki/Datei:Exposer_layout.pdf

Oder hat jemand die Gerberdaten dazu? Wäre nett!

Und nochmal eine Frage zur Kissenverzerrung, könnte man statt Linse oder 
im µP ausrechnen nicht einfach den PDF so umrechnen das es passt?

von Dieter F. (Gast)


Lesenswert?

Jens schrieb:
> werde ich nun auch
> auf den XMAGA umsteigen. Das wollte ich zwar erst später machen, aber
> ich denke ich kann mir dadurch sehr viel Zeit sparen

Hallo Jens,

das sehe ich leicht anders :-)

Zeit sparen - wenn alles mal funktioniert - ja, da der Prozessor höher 
getaktet werden kann und kleine Schmankerl (double buffer für die timer 
und dma mit Einschränkungen) vorhanden / möglich sind.

Aber vorher: Man muss sich vieles mühsam aneignen, da es eine etwas 
andere Prozessor-Welt ist. Ich kämpfe immer noch damit, bin aber ganz 
froh, den Weg gegangen zu sein. Brauchte halt (bei mir) viel Zeit - und 
brauche die immer noch.

Ich mache das Ganze auch nur, um etwas zu Lernen. Das Ziel möchte ich 
natürlich gerne erreichen, aber der Weg dorthin ist (ein großer) Teil 
meines Ziels.

Aktuell kämpfe ich immer noch mit dem Timing und versuche die Ursache 
für meinen "flatternden" Synch.-Impuls zu finden. Das ist "schwere Kost" 
und ich  wäre ohne Logik-Analysator wahrscheinlich nicht dazu in der 
Lage. Aber auch dabei lerne ich :-)

Wenn ich nur auf die Zeit bis zum Belichten eine Platine aus wäre würde 
ich die "alte" Steuerung mit ATMega32 auf die neuen Komponenten 
(Schrittmotorsteuerung und LD-Treiber) umstellen und könnte sehr zeitnah 
(da bin ich mir sicher) Ergebnisse präsentieren. Da ich mir aber die 
Umstellung auf ATXMega (und später versuchsweise auch auf dma) in den 
Kopf gesetzt habe gehe ich halt den harten Weg.

@Jan: Nein, da schimmert nichts durch, das sieht nur merkwürdig aus. Ich 
habe einfach das board

http://www.kreatives-chaos.com/artikel/atmega1632-testboard-v2

genommen und die Anschlüsse entsprechend angepasst. Den 
Schrittmotor-Treiber habe ich mit L297/L298 selbst gebaut (never ever 
:-) ).

Klaus hatte (glaube ich) ein fertiges Layout (weiter oben im thread) 
eingestellt. Ich habe halt mit den bei mir vorhandenen Komponenten 
gearbeitet ...

Gruß
Dieter

von Jens (Gast)


Lesenswert?

Hallo Dieter,

ich habe ja auch schon eine Version Zeit im Kopf. Und die ist auch mit 
dem XMEGA geplant. Daher kann ich auch gleich damit anfangen.
Deine Bedenken kann ich nachvollziehen. Aber bei mir sieht das anders 
aus. Es gibt keinen Controller für den ich schon mehr geschrieben habe 
als für den XMEGA. Da habe ich alle Module schon am Laufen bis auf den 
DMA. Aber den will ich ja eh noch nicht verwenden.
Ich bin sicher, dass es nicht allzu viel Aufwand wird da umzusteigen.

Ich halte dich auf dem Laufenden!

Grüße, Jens

von Martin S. (pcterabyte)


Lesenswert?

@Dieter
Ja, werd demnächst mal Bilder in Aktion machen, sind aber warscheinlich 
recht unspektakulär.
Achso was mir noch einfällt - Triggerst du auf fallender Flanke? Deine 
Zeile fängt auch links an zu Rastern, korrekt?

@Jan
> Und nochmal eine Frage zur Kissenverzerrung, könnte man statt Linse oder
> im µP ausrechnen nicht einfach den PDF so umrechnen das es passt?
Gleich erstmal vorab, die Berechnung findet nicht im µP, sondern auf dem 
PC Programm statt. Das wäre also faktisch kein Unterschied zu deinem 
Vorschlag das im PDF so zu machen.

@All
Ich hab so ganz nebenbei einen defekten Samsung ML2010 ergattern können, 
die LSU ist die selbige wie oben von Jan!
Die eignet sich zwar kaum zum waagerechten Einbau, da keine 
Umlenkspiegel, dafür aber perfekt für meinen bereits erwähnten Test.
Ich muss dazu den Umlenkspiegel (für Trigger) und entsprechende 
Fotodiode anders platzieren, damit ich den Abstand der langen Linse zur 
Polygoneinheit vergrößern (nicht verkleinern) kann. Vielleicht kann man 
sich die Triangulation wegen anderen Brechungsindexes von UV sparen oder 
wenigsten nur die Fokusverteilung verbessern. Ideal also um seperat zu 
testen ohne meine jetzige LSU Umbauen zu müssen.

Kleines Update: Mein Laser hab ich jetzt fest verbauen können. Dazu hab 
ich den Aixiz-Kühlrippenhalter bekommen, den ich nochmal tiefergelegt 
und halbiert habe. Durch die andere LSU hab ich jetzt sogar eine 
Ersatzlinseneinheit, für den Fall das die Linse den baldigen stärkeren 
Laser nicht übersteht sollte!? Bin gespannt :)

Und ich hab schon angefangen mir ein vernünftiges Gehäuse zu planen. Für 
2 seitige Platinen hab ich mir bereits auch eine einfache Methode 
überlegt.

Noch eine allgemeine Frage: Wie stellt ihr euren Fokus ein? Kann es 
sein, dass hier das nicht zwangsläufig per Auge (mit Schutzbrille!) 
funktioniert, da es hier evtl zu optische Täuschung kommen kann? Erzählt 
einfach mal eure positiven Erfahrungen zur Herrangehensweise.

Gruß und schönes Wochende
Martin

: Bearbeitet durch User
von Dieter F. (Gast)


Lesenswert?

Martin S. schrieb:
> Achso was mir noch einfällt - Triggerst du auf fallender Flanke? Deine
> Zeile fängt auch links an zu Rastern, korrekt?

Hallo Martin,

korrekt, ich triggere auf die fallende Flanke (nur die bekomme ich 
sauber vom Polygon-Motor). Das war aber nicht mein Problem - mein 
synch-timeout war nicht o.k.

Das 100mil-Raster steht jetzt perfekt - aber bei der Belichtung habe ich 
heftige Probleme. Sieht nach Interrupt-Prioritäten aus ... Beisse mich 
gerade Stück für Stück durch. Dumm ist, dass ein JTAG dabei nicht hilft. 
Also toggele ich fleissig Port-Pins und schaue, was so passiert.

Übrigens kann ich 20 Minuten das 100mil-Raster auf mein Thermo-Papier 
belichten, ohne dass irgendetwas (sicher) zu sehen ist. Ist auch 
logisch, da der Energie-Eintrag pro Mikro-Punkt und Zyklus sehr gering 
ist.

Zur Fokus-Einstellung finde ich das Thermo-Papier aber gut geeignet - 
wenn man die Zeit nicht außer Acht lässt. Rein nach Sicht (mit 
Schutzbrille) ist ein reines Glücksspiel. Die Methode mit dem 
USB-Mikroskop scheint auch gut zu sein - kann ich aber nicht bestätigen. 
Ich hatte mal so ein Teil - baer das musste extrem nahe an das zu 
untersuchende Objekt gebracht werden - für den Laserpunkt zu nah ...

@Jens:

Jens schrieb:
> Es gibt keinen Controller für den ich schon mehr geschrieben habe
> als für den XMEGA. Da habe ich alle Module schon am Laufen bis auf den
> DMA. Aber den will ich ja eh noch nicht verwenden.
> Ich bin sicher, dass es nicht allzu viel Aufwand wird da umzusteigen.

Na, das hoffe ich mal für Dich. Ich kämpfe derzeit recht heftig - habe 
aber auch relativ viel umgestellt und damit "selbst verbockt". Was 
solls, ich will ja etwas Lernen.

Gruß
Dieter

von Fritz R. (f_richter)


Lesenswert?

Hallo,
auch vom mir wieder mal ein Update.
Nach einem eigentlich nicht geplantem Software Umbau habe ich nun die 
für mich optimale Methode gefunden.
Die Hardware ist gleich geblieben, ein STM32 Discovery enthält ein 
portiertes GRBL, ergänzt um die Belichterfunktionen und kümmert sich um 
die Kommunikation und das Ansteuern der Motoren.
Ein PIC32 (jetzt ein PIC32MZ) steuert den Spiegelmotor und den Laser.
Der Discovery hängt via Ethernet am PC und der PIC32 mittels RS232 
(1Mbit) am Disovery.
Soweit nochmal zum Aufbau.
Bisher habe die Pixel mittels SPI Hardware, die ich mittels DMA 
gefüttert habe ausgegeben. Das habe ich nun entfernt und durch folgenden 
Ablauf ersetzt.

-PIC erhält die Pixeldaten im Block über DMA in konstanter Länge 
(600bytes = 4800 Pixel) und einmalig dazu ein Feld mit Korrekturwerten 
für die Kissenentzerrung.
-Aus den Pixeldaten errechnet er beim Eintreffen der jeweligen 
Pixeldaten für die nächste Zeile ein korrigiertes Array aus 32bit 
Verzögerungswerten, welches nur noch den Zählerstand für die 
Zustandsänderungen des Laserpunktes (hell/dunkel) enthält.
-Beim Interrupt vom Syncronimpuls wird ein Zähler gestartet der die 
Lücke bis zum Start der Zeile festlegt.
-Im "Zeilen Start Interrupt" wird ein 32bit Zähler,welcher mit 100Mhz 
getaktet ist gestartet und dessen Output Capture mit dem ersten Wert des 
Verzögerungsarrays geladen. Außerdem wird ein DMA gestartet, der auf den 
Output Compare Interrupt triggert und dann jeweils automatisch den 
nächsten Verzögerungswert in die OC Einheit schreibt.
-Die DMA Methode hat den großen Vorteil die Interrupt Latenzen zu 
umgehen und somit die Gefahr, bei kurzen Verögerungen (1Pixel) den 
richtigen Zeitpunkt zu verpassen, zu umgehen.
-Der Laser hängt direkt am Output Compare Pin und wird völlig sychron 
bei Match getogglet.

Mit dieser Methode bin ich jetzt in der Lage, in jedem Bereich der Zeile 
minimalste Korrekturen vorzunehmen und trotzdem die Pixel absolut 
Syncron auszugeben.

Viele Grüße

von Dieter F. (Gast)


Lesenswert?

Fritz Richter schrieb:
> Die Hardware ist gleich geblieben, ein STM32 Discovery enthält ein
> portiertes GRBL, ergänzt um die Belichterfunktionen und kümmert sich um
> die Kommunikation und das Ansteuern der Motoren.

Hallo Fritz,

ja - da überlege ich auch gerade, da ich erhebliche Probleme habe ...

Fritz Richter schrieb:
> Ein PIC32 (jetzt ein PIC32MZ) steuert den Spiegelmotor und den Laser.
> Der Discovery hängt via Ethernet am PC und der PIC32 mittels RS232
> (1Mbit) am Disovery.

... ob ich die Last nicht besser auf 3 Prozessoren verteile ...

Fritz Richter schrieb:
> Mit dieser Methode bin ich jetzt in der Lage, in jedem Bereich der Zeile
> minimalste Korrekturen vorzunehmen und trotzdem die Pixel absolut
> Syncron auszugeben.

Da spätestens (nach Lektüre der Verfahrensweise) muss ich verstärkt 
nachdenken ... . Ich habs mir erst 3 mal durchgelesen - brauche also 
noch einige Zeit :-)

Die 32-Bit-Version für den Zähler habe ich auch schon angedacht - da 
muss ich aber auch 32-Bit-Werte liefern und verarbeiten können (in 
vertretbaren Intervallen). Mit einer 8-Bit-CPU AT... kann ich da wenig 
reißen ... Ich sehe mich schon in Richtung 32-Bit-CPU PIC... ) abdriften 
... - oder gibt es da Alternativen?

DMA scheint mir immer noch die optimale Verfahrensweise zu sein - die 
Korrekturwerte (wenn man die Original-Linsen einsetzt) sind meiner 
Erfahrung heraus nahe 0.

Ich denke, ich werde den Schrittmotor - ähnlich wie die 
Polygonmotor-Steuerung auslagern und damit Komplexität herausnehmen. Mal 
schauen, wie es dann aussieht.

Gruß
Dieter

von Jens (Gast)


Lesenswert?

Hallo an alle,

jetzt muss ich nochmal nachfragen. Warum braucht ihr die große 
Rechenleistung? Seid ihr sicher, dass ihr nicht das Problem auch anders 
lösen könnt?
Ich verstehe, dass bei kleinen Abständen die Zeiten der Timer recht 
klein werden. Und dass das schnell gehen muss, dass man keinen Jitter 
rein bekommt.
Aber wie bekommen die das vom Labor dann hin? Da ist doch auch nur ein 
normaler Atmega verwendet worden und die Ergebnisse waren durchaus 
brauchbar.
Was habt ihr jetzt geändert, dass das nicht mehr geht?

Noch mehr Controller einzusetzen, da kann ich nur abraten. Das scheint 
mir der falsche Weg zu sein. Das habe ich auch bei mir gemacht und das 
hat nicht gut funktioniert. Da hat man zwar insgesamt mehr 
Rechenleistung, aber die müssen auch alle sauber zusammen spielen. Das 
hat bei mir nicht funktioniert. Und ich habe nicht mal so kurze Zeiten. 
Bei mir ist die größte Frequenz, die ich habe bei etwa 10kHz. Das kann 
ein 8bitter locker verarbeiten.

Das muss bei euch auch einfacher gehen!

Grüße, Jens

von Fritz R. (f_richter)


Angehängte Dateien:

Lesenswert?

Dieter Frohnapfel schrieb:
> Die 32-Bit-Version für den Zähler habe ich auch schon angedacht - da
> muss ich aber auch 32-Bit-Werte liefern und verarbeiten können (in
> vertretbaren Intervallen). Mit einer 8-Bit-CPU AT... kann ich da wenig
> reißen ... Ich sehe mich schon in Richtung 32-Bit-CPU PIC... ) abdriften
> ... - oder gibt es da Alternativen?
>
> DMA scheint mir immer noch die optimale Verfahrensweise zu sein - die
> Korrekturwerte (wenn man die Original-Linsen einsetzt) sind meiner
> Erfahrung heraus nahe 0.

Hallo Dieter,
Du kannst gerne was von mir nachnutzen, wie schon oben geschrieben halte 
ich die derzeitige, für mich finale Soft und Hardware Lösung, für 
optimal.
Klar gibt es noch eine Menge anderer 32Bit Controller STM,Atmel, ich 
habe von Anfang an einen 32Bit PIC da. Ein 32Bit Timer zur Ausgabe der 
Zeile, hat den Vorteil, das der Timer für eine komplette Zeile reicht 
und nicht laufend neugestartet wird. Ich berechne die Zählerstände wo 
der Laser umgeschaltet werden soll schon komplett vor dem Beginn der 
Belichtung, im Zusammenspiel mit dem DMA ist der Jitter somit quasi 
Null. Der Grund warum ich jetzt nochmal von PIC32MX zu PIC32MZ 
gewechselt habe war nicht die Leistung, sondern die höhere Flexibilität 
bei den Timern. Ich wollte unbedingt einen 32Bit Timer mit möglichst 
hoher Frequenz im Zusammenhang mit einer 32Bit Capture Compare Einheit. 
Diese Kombination gibt es in den PIC32MX nur genau ein mal, ich brauche 
aber noch eine weitere Timer-OC Einheit für das PWM des Spiegelmotors 
sowie eine Timer-Inputcapture für die Regelung(Messung) der Drehzahl.
Achja nochwas zum Aufwand. der 32Bit PIC kostet nicht mehr als ein 20 
Jahre alter Atmega und 200Mhz und 512k Ram sind auch ganz nett, oben ist 
die aktuelle Platine.

Zu den Korrekturwerten, von 0 ist da zumindest am Anfang der Zeile bei 
meiner Spiegeleinheit nichts zu sehen, hier ein Auszug:
Korr_1=2
Korr_2=3
Korr_3=5
Korr_4=5
Korr_5=5
Korr_6=3
Korr_7=10
Korr_8=5
Korr_9=5
Korr_10=4
Korr_11=2
Korr_12=2
Korr_13=7
Korr_14=4
Korr_15=14
Korr_16=14
Korr_17=12
Korr_18=9
Korr_19=10
Korr_20=6
Korr_21=6
Korr_22=5

Die Zeilenlänge ist 203 mm, der Timer läuft mit 100Mhz, von Pixel zu 
Pixel sind 48 Ticks, die Korrekturwerte sind 1/x, also 1 ist das Maximum 
da wird ein ganze Takt weggelassen.
Mit diesen Werten ist die Abweichung über die gesamte Länge unter 0.1mm.

Viele Grüße

: Bearbeitet durch User
von Dieter F. (Gast)


Lesenswert?

Jens schrieb:
> Warum braucht ihr die große
> Rechenleistung?

@ Jens:

Nicht große Rechenleistung ist gefragt - mehr schnelle und große Timer 
mit Compare-Möglichkeit.

Aktuell arbeite ich mit 3 mS pro Zeile = 48.000 Takte bei 16 MHz. Wenn 
ich z.B. die möglichen 32 MHz (oder mehr) nutzen will, dann muss der 
Timer schon 96.000 Takte oder mehr zählen können - mit 16 Bit geht das 
nur mit Verrenkungen, die Zeit kosten. Der ATXMega kann zwar auch 32-Bit 
Zähler bedienen - aber nicht (vernünftig) im Compare-Modus. Daher nutze 
ich aktuell einen Prescaler für den Belichtungs-Timer, obwohl ich das 
eigentlich nicht will.  Je schneller man den MC/Timer takten kann, desto 
besser die Auflösung.

Die Trennung der Aufgaben auf einzelne Prozessoren (die ja nicht viel 
kosten) reduziert das Interrupt-Dilemma ( :-) ) auf ein Minimum. 
Während der Belichtung dürfen keine Interrupts stören. Wenn die anderen 
Aufgaben (Steuerung Polygon-Motor bzw. Stepper) durch "Sklaven" 
eigenständig erledigt werden hat man das auch vom Hals. Bei mir arbeitet 
die Polygon-Motor-Steuerung vollkommen unabhängig vom Haupt-Prozessor.

@ Fritz:

Das nehme ich gerne zu gegebener Zeit an :-) Melde mich dann ...

Aktuell muss ich aber erstmal mein Problem lösen. Außerdem scheue ich, 
ehrlich gesagt, den Einarbeitungsaufwand noch etwas. Ich bin gerade 
dabei, mich in die ATXMega-Welt einzuarbeiten, was schon ein 
ordentlicher Schritt ist. Wobei mir die Erfahrungen aus der ATTiny- und 
ATMega-Welt natürlich helfen - aber irgendwie ist alles etwas anders ...

Der ATXMega hat für mich den Charme des "double-buffering" bei den 
Timer-Vergleichswerten - was heisst, ich kann den Vergleichswert für den 
nächsten "compare" schon in einen Puffer laden, während der aktuelle 
"compare" noch läuft. Das beschleunigt natürlich, da der Vergleichswert 
dann per Hardware aus dem Puffer aktualisiert wird. Beschränkend ist 
aktuell daher der 8-Bit-MC, da die Übertragung der Werte entsprechende 
Zyklen benötigt.

Aus beiden genannten Gründen (Zähler und Übertragung der Werte) die 
Überlegung in Richtung 32-Bit-MC.

Eine Korrektur ist bei mir - mit dem Original-Linsensystem - nicht 
erforderlich. Ich passe lediglich die Belichtungszeit pro Punkt 
entsprechend des Fokus / Objektabstandes generell an. Ehrlich gesagt 
habe ich aber auch nicht auf 0,1 mm genau die jeweiligen Abstände des 
mil-Rasters geprüft. Aber auf "sichtbarer Ebene" (Zoll-Lineal) passt das 
Haargenau.

Für den Jitter ist aus meiner Sicht mehr die Opto-Einheit 
verantwortlich. Wenn die nicht vernünftig eingestellt ist / arbeitet 
gibt es Probleme. Der Zähler selbst bzw. die Aktualisierung läuft bei 
mir problemlos, wenn ich die Mindest-Zyklen für die Aktualisierung der 
Werte einhalte.

Gruß
Dieter

von Fritz R. (f_richter)


Lesenswert?

Dieter Frohnapfel schrieb:
> Der ATXMega hat für mich den Charme des "double-buffering" bei den
> Timer-Vergleichswerten - was heisst, ich kann den Vergleichswert für den
> nächsten "compare" schon in einen Puffer laden, während der aktuelle
> "compare" noch läuft.

Hallo Dieter,
das "double buffering" brauchst Du aber gar nicht, wenn Du die 
Vergleichsregitser einfach per DMA befüllst. Bei mir gibt es während der 
gesamten Zeile keinen einzigen Interrupt mehr :-)

von Dieter F. (Gast)


Lesenswert?

Fritz Richter schrieb:
> wenn Du die
> Vergleichsregitser einfach per DMA befüllst

Hallo Fritz,

öhhh, jaaa, ich wüsste im Moment nicht wie :\

DMA kann ich per USART auf einen PIN geben - das war mein Fern-Ziel. 
Habe ich schon erfolgreich im kleinen Maßstab ausprobiert. Hat den 
Nachteil, dass man jedes Bit einzeln übergeben (vom PC) muss. Daher 
spiele ich nebenbei mit dem Gedanken, SRAM-Bausteine anzubinden.

Aber mit DMA direkt auf/in ein Vergleichsregister zu schreiben - wie 
soll das gehen? Ich kann mir erstmal da nur eine Interrupt-Lösung 
vorstellen, die wegen des Handlers auch wieder nicht sonderlich 
performant ist. O.K. - bin kein Profi ... .

Vielleicht könnte man einen Event-Handler auf den Compare-Event triggern 
und damit DMA anstoßen ... muss ich mal nachlesen ...

Gruß
Dieter

von Jens (Gast)


Lesenswert?

Hallo an alle,

ich habe nun meine Software portiert und war gerade dabei alles zu 
testen. Schaut auch gar nicht schlecht aus. Dann habe ich aus einer 
Unachtsamkeit eine Leitung(24V) fallen lassen und die ist direkt auf 
meinen PortB gefallen. Der hat sich somit verabschiedet. Die Motoren 
laufen alle noch, aber auf PortB ist auch der JTAG und somit kann ich 
nicht mehr programmieren. Ich muss also eine Zwangspause einlegen bis 
die Ersatzteile da sind. Ich hoffe nur, dass mein SDRAM nichts 
abbekommen hat. Da kann ich nicht so einfach Ersatz bestellen. Ich habe 
das noch nirgends gefunden wo ich das selber bestellen kann.

@Dieter
Das habe ich verstanden warum ihr da andere Timer einsetzen wollt.
Und das die Zeile durch einen Interrupt nicht mehr gestört werden soll.
Kannst du den Timer nicht anders laufen lassen? So wie ich dich verstehe 
läuft dein Timer einmal durch pro Zeile. Aber was ist mit dem Single 
Slope Betrieb. Der scheint mir auch geeignet zu sein. Du lässt den Timer 
immer nur von Pixel zu Pixel laufen und startest ihn dann neu. Oder wenn 
du vier Compare Einheiten hast, dann eben vier Pixel weit. Der Neustart 
des Timers geht von alleine und die Werte kannst du in die gebufferten 
Register vor laden. Wenn du dann die Werte einer Zeile im Ram speicherst 
(Array) dann kannst du beim Overflow des Timers(Neustart) die Werte per 
DMA in die Compare Register laden.
Wenn ich da nicht was falsch verstanden habe wie eure Drucker arbeiten, 
dann sollte das funktionieren.

Grüße, Jens

von Dieter F. (Gast)


Lesenswert?

Jens schrieb:
> Du lässt den Timer
> immer nur von Pixel zu Pixel laufen und startest ihn dann neu. Oder wenn
> du vier Compare Einheiten hast, dann eben vier Pixel weit. Der Neustart
> des Timers geht von alleine und die Werte kannst du in die gebufferten
> Register vor laden.

Hallo Jens,

das wäre schön :-)

Bei 600 dpi habe ich 9144 Pixel/15,24 cm - d.h. ca. 9144 low/high- bzw. 
high/low-Wechsel pro ca. 2 mS. Bei 16 MHz habe ich da 3,5 Zähler-Takte 
pro Wechsel. Unmöglich, in dieser Zeit die 16-Bit-Register zu versorgen 
(aus meiner Sicht). Und mit den 4 Compare-Einheiten - wie willst Du das 
denn steuern / synchronisieren? Über Interrupts geht das sicher nicht - 
alleine wegen des ISR-Overheads...

Da reichen meine bescheidenen Fähigkeiten nicht aus ... :-(

Schade, dass Dein MC sich verabschiedet hat - aber solche Ausfälle hatte 
ich auch schon. Ich arbeite grundsätzlich nur noch gesockelt bzw. mit 
gesockeltem Adapter :-)

Gruß
Dieter

von Fritz R. (f_richter)


Lesenswert?

Dieter Frohnapfel schrieb:
> Vielleicht könnte man einen Event-Handler auf den Compare-Event triggern
> und damit DMA anstoßen ... muss ich mal nachlesen ...

Hallo Dieter,
stimmt schon fast.
Also Du erzeugst ein Array aus 32Bit Werten, welches inkrementell alle 
Vergleichswerte für die gesamte Zeile enthält.
Der DMA Einheit sagst Du: Source=pointer auf dieses 
Array,Destination=Compare Register, Start Trigger=Compare Interrupt, 
Mode=Repeat (für die Wiederholungen der Zeile). Am Syncronimpuls lädst 
Du den ersten Wert ins Vergleichsregister. Und dann zurücklehnen, der 
DMA macht von da an alles allein, so ganz ohne Interrupt und 
irgendwelche Latenzen.
1
DCH1SSA=VirtToPhys((void*)&pixel_delay[1]); // transfer source physical address
2
        DCH1DSA=VirtToPhys((void*)&OC4R); // transfer destination physical address
3
        DCH1SSIZ=event_count*4; // source size is 32bit
4
        DCH1DSIZ=4; // destination size
5
        DCH1CSIZ=4; // 32bit per transfer request

Viele Grüße

von Jens (Gast)


Lesenswert?

Genau so geht das auch mit dem XMEGA! Das habe ich gemeint!

von Dieter F. (Gast)


Lesenswert?

Fritz Richter schrieb:
> Der DMA Einheit sagst Du: Source=pointer auf dieses
> Array,Destination=Compare Register, Start Trigger=Compare Interrupt,
> Mode=Repeat (für die Wiederholungen der Zeile). Am Syncronimpuls lädst
> Du den ersten Wert ins Vergleichsregister. Und dann zurücklehnen, der
> DMA macht von da an alles allein, so ganz ohne Interrupt und
> irgendwelche Latenzen.

Hallo Fritz,

ja - bei Deinem PIC kann ich mir das vorstellen ...

Ich bin auf einem 8-Bit-MC und muss ein 16-Bit-Register versorgen. Ein 
"repeat 2 times" ist mir nicht bekannt ... :-(
Da müsste ich ggf. mit 2 DMA-Transfers - gekoppelt an den einen Trigger 
arbeiten - und die auch synchronisieren ... uiuiui

@Jens: Wie genau sollte denn so ein Code beispielhaft aussehen?

Gruß
Dieter

von Jens (Gast)


Lesenswert?

Wenn du Werte hast die größer als acht bit sind, dann kannst du bei 
deinem Transfer die Blockgröße angeben.
Ich habe den DMA noch nicht wirklich gebraucht, aber die Datenblätter 
habe ich schon studiert. Ich schau mal was ich finde.
Beim XMEGA gibst du beim DMA Init die Source Adresse an. Das ist die 
Baseadresse deines Arrays. Dann die Destination Adresse. Das ist die 
Registeradresse von den Compare Registern. Dann brauchst du die 
Blockgröße (eins bis vier) und die Widerholung deines Transfers. Das 
berechnest du aus der Länge deines Arrays.
Da gibt es von Atmel eine Application Note. Hast du die schon? Die habe 
ich auf jeden Fall auf Platte gespeichert. Da ist auch Software dabei.
Wenn du die nicht hast schicke ich dir die.

Grüße, Jens

von Dieter F. (Gast)


Lesenswert?

Jens schrieb:
> Ich habe den DMA noch nicht wirklich gebraucht, aber die Datenblätter
> habe ich schon studiert. Ich schau mal was ich finde.

Hallo Jens,

vielen Dank - habe zwischenzeitig auch noch mal geschaut - könnte gehen, 
Du hast Recht mit der Blockgröße :-)
Da muss ich aber erst nochmal ein(ig)e Nacht(Nächte) drüber schlafen.

@Fritz:

Dann brauche ich die 32 Bit ggf. gar nicht. Wenn ich mit DMA schnell 
genug bin (Ziel 1 dpi Auflösung - THEORETISCH - DEN FOKUS BEKOMME ICH 
SOWIESO NICHT HIN) dann reicht mir das vollkommen aus.

Da ich die Werte vom PC vorberechnet bekomme brauche ich die nur 
geschickt in das Vergleichsregister zu bekommen. Wenn ich per DMA 
schneller bin wie mit double buffer und die theoretischen 1 mil erreiche 
ist alles prima. Dazu muss ich nur unter 11 Takte/Transfer kommen ...

Werde ich ausprobieren, sobald ich die aktuellen Probleme überwunden 
habe :-(

Gruß
Dieter

von Dieter F. (Gast)


Lesenswert?

Hallo Fritz,

je mehr ich darüber nachdenke, desto besser gefällt mir die Idee! Vielen 
Dank, das nimmt mir einige Probleme - und schafft neue, da ich mich 
intensiver mit DMA beschäftigen muss ...

Sobald ich einen nachvollziehbaren Stand erreicht habe melde ich mich 
...

Gruß
Dieetr

von Fritz R. (f_richter)


Lesenswert?

Dieter Frohnapfel schrieb:
> und schafft neue, da ich mich
> intensiver mit DMA beschäftigen muss ...

Schön, das wolltest Du doch sowieso machen, dann ist jetzt der richtige 
Zeitpunkt dazu, und es lohnt sich auf jeden Fall.

Viele Grüße

von Dieter F. (Gast)


Lesenswert?

Fritz Richter schrieb:
> Schön, das wolltest Du doch sowieso machen, dann ist jetzt der richtige
> Zeitpunkt dazu, und es lohnt sich auf jeden Fall.

Ja :-)  -  das hoffe ich ...

Gruß
Dieter

von Jens (Gast)


Lesenswert?

Hallo Dieter,

die gebufferten Register brauchst du trotzdem. Der DMA ist zwar schnell, 
aber der kann auch nur ein Byte pro Takt. Wenn du in die buffered 
Register schreibst wird der Wert immer beim Überlauf aktualisiert. So 
kannst du sicher stellen, dass die Werte immer zur richtigen Zeit 
nachgeladen werden und du kannst quasi parallel alle anderen Werte 
schreiben.
Ich bin mal auf deine Ergebnisse gespannt!

Da habe ich mit meinem System natürlich wesentlich weniger Probleme.
Könnt ihr den Spiegel nicht langsamer drehen lassen? Wenn man die Zeit 
pro Zeile von 3ms auf 30ms erhöhen würde hätte man genug Zeit alles zu 
rechnen und die Register zu laden. Und man braucht eine Zeile dann nicht 
200mal zu wiederholen sondern nur 20mal. Das sollte sonst keine 
Unterschiede machen.

Meine Zwangspause regt mich grad echt auf! Heute hätte ich alles fertig 
machen können und hätte sogar vielleicht ein paar Drucke machen können. 
:-(
Aber wie es immer so ist. Einmal nicht aufgepasst und schon ist es 
passiert. Ich bin nur froh dass mein Programmer das überlebt hat. Sonst 
wäre es echt teuer geworden!

Grüße, Jens

von Dieter F. (Gast)


Lesenswert?

Jens schrieb:
> Wenn du in die buffered
> Register schreibst wird der Wert immer beim Überlauf aktualisiert. So
> kannst du sicher stellen, dass die Werte immer zur richtigen Zeit
> nachgeladen werden

Hallo Jens,

ja - aber dann muss ich wieder Abfragen auf das Zeilenende einbauen, die 
das Ganze verlangsamen ... Muss ich drüber nachdenken ...

Jens schrieb:
> Könnt ihr den Spiegel nicht langsamer drehen lassen?

Geht zumindest mit der Original-Polygon-Motor-Steuereinheit nicht - die 
ist dann nicht zuverlässig und Oszilliert ... . Damit habe ich schon 
rumgespielt (den Gedanken hatte ich auch schon) - werde das aber 
systematisch nochmal durchspielen (mit wenig Hoffnung).

Gruß
Dieter

von Dieter F. (Gast)


Lesenswert?

Jens schrieb:
> die gebufferten Register brauchst du trotzdem. Der DMA ist zwar schnell,
> aber der kann auch nur ein Byte pro Takt.

Hallo Jens,

ja, 1 Byte pro Takt - aber nein, das brauche ich, denke ich, nicht. Der 
DMA kann 1, 2, 4 oder 8 Byte in einem burst übertragen.

Mit dem Buffer brauche ich nicht arbeiten, da der DMA durch das 
Compare-Ereignis getriggert wird. Ein Verschieben vom Buffer in das 
Compare-Register ist auch nicht schneller.


@Fritz / alle:

Aktuell habe ich das Problem, dass der DMA beim erstem Compare-Ereignis 
wie gewünscht losläuft - aber nicht mehr aufhört zu Laufen, obwohl ich 
das entsprechende Interrupt-Flag (per DMA :-) ) lösche.

Ich fürchte, ich muss doch einen Minimal-Interrupt (nur mit "reti") 
einrichten, damit das Compare-Ereignis für den DMA "sichtbar" gelöscht 
wird. Oder gibt es da noch andere Möglichkeiten? Ich möchte halt gerne 
die Interrupt-Routine (wenn auch minimal) vermeiden, da doch einige 
Takte "verloren" gehen.


Nachtrag:

Das muss ich, glaube ich, noch erklären. Atmel schweigt sich (soweit ich 
Lesen konnte) darüber aus, was genau die Übertragung auslöst. Man kann 
Compare-Channel auswählen - weiß aber nicht (wie in meinem Fall), was 
genau die Übertragung auslöst.

Meine Vorgehensweise:
Zunächst habe ich die DMA-Kanäle 0 und 1 (0 für den Compare-Wert, 1 für 
das Löschen der Interrupt-Flags) initialisiert und aktiviert. Dann habe 
ich den Compare-Wert vorbelegt und den Timer gestartet.

Mit dem ersten Compare startete auch DMA-Kanal 0 - kurz darauf DMA-Kanal 
1, da ich diese Reihenfolge über die Priorität festgelegt habe. Prima, 
bis dahin.

Dann beginnt das Elend. Die DMA-Kanäle arbeiten weiter, bis keine Werte 
mehr zu übertragen sind - ohne auf den nächsten Compare zu Warten -  ... 
. Das Ergebnis ist nicht zufriedenstellend :-(


Gruß
Dieter

von Dieter F. (Gast)


Lesenswert?

Ich mache mal einen Post dazu auf - vielleicht können spess & co. helfen 
...

von Chris S. (schris)


Lesenswert?

Um welche Bitzeiten geht es hier eigentlich ?

von Dieter F. (Gast)


Lesenswert?

Ich mache mal einen Post dazu auf - vielleicht können spess & co. helfen 
...

Chris S. schrieb:
> Um welche Bitzeiten geht es hier eigentlich ?

Wie meinst Du das? Spielt das eine Rolle in Bezug auf meine Frage? Ich 
glaube, eher nicht ...

(Aber, wenn Du es genau wissen willst: CPU-Takt / 8  :-) )

von Fritz R. (f_richter)


Lesenswert?

Dieter Frohnapfel schrieb:
> Aktuell habe ich das Problem, dass der DMA beim erstem Compare-Ereignis
> wie gewünscht losläuft - aber nicht mehr aufhört zu Laufen, obwohl ich
> das entsprechende Interrupt-Flag (per DMA :-) ) lösche.

Der DMA stoppt erst wenn die Blockgröße (Anzahl der berechneten 
Hell/Dunkel Events in Bytes!) die Du eingestellt hast erreicht wurde.
Dann sollte er einen "Block done" Interrupt auslösen, dort kannst Du ihn 
dann abschalten. Du brauchst für das Compare Ereignis keine 
Interrupt-Routine, und darfst den Compare Match Interrupt auch nicht 
enablen. Der DMA schaut nur auf das Interrupt Flag und benutzt das als 
Trigger. Zumindest ist das bei allen MCU's die ich kenne so.
Und die Funktion des DMA Kanal 2 kann ich nicht nachvollziehen, Du 
brauchst da nichts zu löschen, das macht der DMA Controller schon 
alleine.

Viele Grüße

: Bearbeitet durch User
von Dieter F. (Gast)


Lesenswert?

Fritz Richter schrieb:
> Der DMA stoppt erst wenn die Blockgröße die Du eingestellt hast erreicht
> wurde.

Hallo Fritz,

ja - die habe ich vorgegeben.

Fritz Richter schrieb:
> Dann sollte er einen "Block done" Interrupt auslösen, dort kannst Du ihn
> dann abschalten.

Nö - dazu gebe ich ja vor, wie viele Bytes der Block enthält - und wenn 
der Block abgearbeitet ist ist Schluss.

Fritz Richter schrieb:
> Du brauchst für das Compare Ereignis keine
> Interrupt-Routine, und darfst den Compare Match Interrupt auch nicht
> enablen.

Habe ich nicht - ich schaue nur auf die Flags und lösche diese ....

Fritz Richter schrieb:
> Der DMA schaut nur auf das Interrupt Flag und benutzt das als
> Trigger.

Das hatte ich so angenommen - aber dem ist scheinbar nicht so ...

Fritz Richter schrieb:
> Zumindest ist das bei allen MCU's die ich kenne so.

Hmm - ja ...

Gruß
Dieter

von Mike (Gast)


Lesenswert?

Hallo,

ich verfolge diesen Thread schon seit einiger Zeit und plane ebenfalls 
einen Belichter zu bauen. Jedoch würde ich vermutlich einen etwas 
anderen Weg verfolgen, da mir die Polygon-Methode etwas zu 
fehleranfällig erscheint.

Zunächst jedoch habe ich in der Planung ein anderes Problem:

kennt einer von euch eine Möglichkeit eines der KiCad-ausgabeformate für 
PCBs in eine Bildmatrix zu überführen? Also z.B. Postscript --> 
n,m-Matrix?
Ich würde das Ganze entweder in C++ oder in Python versuchen wollen.

Bevor ich dieses grundlegende Problem nicht gelöst habe, brauche ich 
mich mit der Mechanik/Elektronik erst gar nicht beschäftigen :(

Ich hoffe auf Tipps von euch

Mit Gruß

Mike

von Chris S. (schris)


Lesenswert?

Dieter Frohnapfel schrieb:
> Chris S. schrieb:
>> Um welche Bitzeiten geht es hier eigentlich ?
>
> Wie meinst Du das? Spielt das eine Rolle in Bezug auf meine Frage? Ich
> glaube, eher nicht ...
>
Was ich meinte, welche Zeiten in Nanosekunden braucht man fuer ein Bit 
des Bitstreams bei der Belichtung, um den Laser mit ausreichend DPI 
betreiben zu koennen.

von Dieter F. (Gast)


Lesenswert?

Chris S. schrieb:
> Was ich meinte, welche Zeiten in Nanosekunden braucht man fuer ein Bit
> des Bitstreams bei der Belichtung, um den Laser mit ausreichend DPI
> betreiben zu koennen.

Ah, o.k. - das ist abhängig von der Drehzahl des Polygonspiegels und der 
gewünschten Auflösung.

Bei mir z.B. 3 mS / Belichtungs-Zeile und nach Möglichkeit 600 dpi auf 
18 cm Belichtungszeilenbreite (welche ca. 70 % der "Zeilenzeit" 
beansprucht) bei 16MHz Timer-Takt = (16.000.000 * 0,003 * 0,7) / 
((18/2,54) * 600) = rund 8 Timer-Zyklen. Das entspricht damit in etwa 
500 Nanosekunden. Ein ordentliches Ziel :-)

@Mike:
Da hast Du scheinbar nicht alles gelesen ... :-) Ich nutze "pdftoppm" - 
eine Komponente der sog. "Poppler-Tools" - um PDF's in BMP umzuwandeln, 
so wie Tixiv das auch gemacht hat. Es gibt aber noch einige andere 
Möglichkeiten - diese sind weiter oben im Thread genannt.

von Dieter F. (Gast)


Lesenswert?

Fritz Richter schrieb:
> er DMA stoppt erst wenn die Blockgröße (Anzahl der berechneten
> Hell/Dunkel Events in Bytes!) die Du eingestellt hast erreicht wurde.

Hallo Fritz,

da bin ich halb drüber weggegangen. Ich nutze den sog. "burst mode" - 
daei wird pro Trigger genau ein burst (1, 2, 4 oder 8 Byte) des Blocks 
übertragen. Das passiert genau so lange, bis der Block komplett 
übertragen wurde (lt. Bytezähler-Vorgabe für den Block).

Am Blockende hört er auch auf - es wird halt permanent getriggert und 
damit bursts übertragen, obwohl kein Compare-Ereignis stattgefunden hat. 
Es muss also noch irgendetwas anderes - außer dem Compare-Interrupt-Flag 
- sein, was den Trigger auslöst.

Gruß
Dieter

von Jens (Gast)


Lesenswert?

Hallo Dieter,

du schreibst, dass du 4 Bytes in einem Burst schreiben kannst. Das 
bestreite ich nicht. Aber du schließt daraus, dass ein Burst auch nur 
ein Takt lang ist. Das ist aber nicht so. Das sind mindestens vier 
Takte.
Du darfst nicht vergessen auf welcher Maschine du arbeitest. Das ist ein 
8bitter. Dein Datenbus ist nicht breiter. Um 32bit in einem Takt zu 
schreiben brauchst du einen entsprechend breiten Datenbus. Das ist mit 
dem Atmel nicht möglich!

Aber das ist gar nicht dein Problem. Das habe ich nur angesprochen, da 
man da schon im Vorfeld abschätzen kann ob du mit der Zeit hin kommst 
oder nicht. Du hast ein Pixel ja mit 500ns abgeschätzt. Das sind bei dir 
maximal 16 Takte.

Hast du dir die Application Note von Atmel dazu schonmal vor genommen?
Ich denke, dass bei deinem Init noch ein Problem ist, dass der nicht 
mehr aufhört. Da könnte die Blockgröße falsch sein oder die 
Wiederholungen.

Gruß, Jens

von Dieter F. (Gast)


Lesenswert?

Jens schrieb:
> Aber du schließt daraus, dass ein Burst auch nur
> ein Takt lang ist. Das ist aber nicht so. Das sind mindestens vier
> Takte.

Hallo Jens,

nein - ich schließe nicht daraus, dass ein burst 1 nur einen Takt dauert 
- habe ich auch nicht so geschrieben. Aber ein burst im "single 
shot"-Modus wird nach Triggerung "in einem Rutsch" übetragen - pro Byte 
ein Takt.

Die App-Notes (es gibt 3 mit Bezug zu DMA soweit mir bekannt) habe ich 
alle durchgeschaut. Da sind die Datenblätter informativer. Meine 
Initialisierung ist nach meinem Kenntnisstand in Ordnung.

Ich habe im Netz einen Hinweis gefunden, dass bei Timern auf dem ATXMega 
IMMER der den DMA triggernden Interrupt AKTIVIERT sein muss. Was mich 
dann natürlich zur Interrupt-Behandlung (wenn auch minimal) zwingt. 
Alternativ - und beides werde ich heute Abend ausprobieren - kann man 
das Eventsystem nutzen um ohne aktivierten Interrupt z.B. das 
Compare-Ereignis nutzen zu können (bedeutet natürlich 1 Takt für den 
Event mehr ...).

Ich berichte ...

Gruß
Dieter

von Jens (Gast)


Lesenswert?

Ich bin gespannt!
Wenn man zur Abarbeitung mit dem DMA eine Interrupt Routine braucht, 
dann geht das eigentlich an der Sache vorbei.
Ich bin mal gespannt, ob Atmel da alles durchgängig entwickelt hat. Das 
kann natürlich auch ein Bug bei den XMEGAs sein.
Da könnte ein Blick in die Errata Sheets helfen ob da irgendwelche 
Fehler bekannt sind.
Aber vielleicht kommst du heute Abend auch zum Ziel!
Ich drück die Daumen!

Grüße, Jens

von Robin E. (why_me)


Lesenswert?

Wie bzw mit welchem interrupt startest du den DMA?

Ich würde bei einer Flanke des LDR starten und den Versatz/Verzögerung 
durch Füllbits erzeugen.
Der DMA schickt dann immer ein Byte an den SPI, wenn dieser ein Byte 
gesendet hat.

Ich wüsste nicht, warum man dafür den SPI Interrupt aktivieren müsste. 
Dafür hast man dich denn DMA, damit man ohne Last Daten schaufeln kann.

Kenne mich mit den xmegas nicht aus. Kann mir aber heute Abend gerne mal 
das datenblatt anschauen.

von Chris S. (schris)


Lesenswert?

2 Mhz, zumindest mit dem Pic ist es problemlos machbar.
Derzeit gibt es noch pic's mit 75Mips. Der normale Pic
ist 10Mips. Damit sollten 5Mhz machbar sein.

von Fritz R. (f_richter)


Lesenswert?

Dieter Frohnapfel schrieb:
> Am Blockende hört er auch auf - es wird halt permanent getriggert und
> damit bursts übertragen, obwohl kein Compare-Ereignis stattgefunden hat.
> Es muss also noch irgendetwas anderes - außer dem Compare-Interrupt-Flag
> - sein, was den Trigger auslöst.

Hallo Dieter,
wenn Du den Fehler nicht findest, probier den DMA im Zweifelsfall 
erstmal z.b. mit einem UART aus. Da lässt es sich leichter Debuggen. 
Wenn Du z.B. den RX-Int als Trigger nimmst, kannst Du wunderbar mit 
einem Terminal Programm einzelne Zeichen senden und die Funktion 
nachvollziehen.
Im übrigen kannst Du den RX-DMA wenn er einmal läuft dann auch gleich 
drinlassen, dann hast Du noch ein paar Ints weniger beim Empfang der 
Packete vom PC (hab ich bei mir auch so).
Wie Jens schon geschrieben hat, ist DMA mit einer Interrupt-Routine 
ziemlich sinnlos, weil er ja eigentlich den Prozessor entlasten soll, 
was er so aber nicht tut.
Entweder Du hast noch einen Bug (was wahrscheinlicher ist), oder Atmel 
das Ziel verfehlt.

Viele Grüße

von Dieter F. (Gast)


Lesenswert?

Hallo Fritz und Jens,

ja - da muss ich mir etwas überlegen. Im Moment bin ich ziemlich ratlos. 
Der aktivierte Interrupt hat rein gar nichts gebracht. Immerhin bin ich 
jetzt darauf gekommen, dass der DMA-Kanal zwar heftig Aktivität 
entwickelt und Adressen hochzählt etc. - sich aber auf der 
Empfänger-Seite - bezogen auf das Compare-"Register" - nichts tut.

Das habe ich gestern gar nicht so wahrgenommen, da ich nur auf die 
Zähler und Flags geachtet habe.

Ehrlich gesagt verstehe ich nicht, was da abgeht. Ich habe Sender- und 
Empfänger-Adressen korrekt eingestellt (habe ich im Debugger geprüft). 
Der DMA läuft vollkommen korrekt an und ändert auch erwartungsgemäß 
DMA-Status-Flags sowie DMA-Zähler und DMA-Adressen.

In das Compare-"Register" wird NICHTS übertragen. Ich dachte erst - o.k- 
das liegt an der low / high-Problematik des 16-Bit-"Registers". Falsch - 
auch per DMA beschreibe ich erst low, dann high. Interessant dabei ist, 
dass ich das INTFLAG-Register über den DMA-Kanal 1 jeweils korrekt 
überschrieben habe.

Für heute habe ich keine Lust mehr und morgen bin ich unterwegs. Also 
werde ich am Freitag weiter suchen. Muss noch etwas nachdenken ...

Gruß
Dieter

von Robin E. (why_me)


Lesenswert?

Kannst du mal deine DMA-Funktion beschreiben? ich verstehe nicht ganz, 
warum du etwas in ein compare Register schreibst.

Kannst du die Ausgabe nicht über ein SPI oder UART realisieren?

von Jens (Gast)


Lesenswert?

Hallo Dieter,

wie geht es voran?
Bei mir sind die Ersatzteile gestern geliefert worden. Jetzt kann ich 
weiter machen. Die Motoren drehen auch schon so wie es soll. Das RAM ist 
angeschlossen und in Betrieb. Das Einzige was noch fehlt ist die UART. 
Die mache ich am Wochenende fertig und dann hoffe ich, dass alles 
zusammen spielt. Dann kommen kommende Woche hoffentlich die neue 
Testdrucks dran.

Grüße, Jens

von Dieter F. (Gast)


Lesenswert?

Jens schrieb:
> wie geht es voran?

Hallo Jens,

gar nicht :-)

Ich habe div. DMA-Varianten erfolglos ausprobiert und gebe vorerst auf. 
So macht das keinen Spaß ... Entweder ich bin zu doof (möglich) oder es 
funktioniert schlicht nicht so, wie von Atmel beschrieben. Errata hab 
ich keine passende gefunden - sagt aber nichts, da ich vielleicht nicht 
überall gesucht habe ...

Habe beschlossen, wie geplant, erstmal wieder DMA außen vor zu lassen 
und im  "normalen" Timer-Modus das Teil zum Laufen zu bekommen.

@Robin:
Ich möchte die jeweils nächsten Hell- / Dunkel-Zeiten in das 
Compare-Register schreiben. Aktuell mache ich das per Programm - per DMA 
sollte es schneller gehen. Den Timer betreibe ich im "frequency-mode" - 
heißt
, bei jedem "compare-event" wird der Pin für den Laser (an/aus) 
getoggelt.

Gruß
Dieter

von Dieter F. (Gast)


Lesenswert?

Dieter Frohnapfel schrieb:
> gar nicht :-)

... stimmt nicht mehr ... :-)

Der Misserfolg mir keine Ruhe gelassen und ich habe jetzt einen kleinen, 
funktionierenden Prototypen. Allerdings glaube ich jetzt lange nicht 
mehr alles, was sich so in den Datenblättern und App.-Notes findet.

Übrigens scheinen 10 CPU-Takte damit für einen Compare-Wert-Wechsel 
auszureichen. Die benötige ich, da ich einen Compare-Interrupt 
aktivieren und behandeln muss. Da arbeite ich mit einer "naked ISR" die 
nur ein RETI() enthält - deswegen bewegt sich der "Takt-Verbrauch" noch 
im vertretbaren Rahmen.

Problem bei dem tollen ATXMega-DMA ist, dass parallel keinerlei Zugriffe 
auf I/O, SRAM, EEPROM oder bus interface etc. durch die CPU stattfinden 
dürfen, da diese Vorrang vor DMA haben. Ich überlege also gerade, die 
CPU bis zum Ende der Transfers (= Ende der Belichtungszyklen in der 
Zeile) schlafen zu legen. Dazu muss ich mich mal mit den sleep-Modi 
beschäftigen. Vielleicht finde ich ja auch noch einen anderen Weg, auf 
das Ende der Übertragung zu warten.

Gruß
Dieter

von Dieter F. (Gast)


Lesenswert?

Dieter Frohnapfel schrieb:
> Ich überlege also gerade, die
> CPU bis zum Ende der Transfers (= Ende der Belichtungszyklen in der
> Zeile) schlafen zu legen.

Ist hiermit gestrichen. Geht nicht, da ich ja die Interrupts für den 
compare match aktivieren muss und jeder Interrupt den idle-mode (und nur 
den könnte ich nutzen) beendet :-(

Immerhin habe ich jetzt die "naked ISR" durch einen 
"EMPTY_INTERRUPT(TCC0_CCA_vect);" ersetzt, was schonmal schöner aussieht 
:-)

Bei der Gelegenheit habe ich bemerkt, dass es gar nicht schlecht ist, 
sich mal mit dem AVR GCC-Compiler zu beschäftigen. Man wird nicht dümmer 
dadurch ...


Das (ATXMega A-Manual):
...
12.12.10 INTFLAGS - Interrupt Flag Register
...
The CCxIF can be used for requesting a DMA transfer. A DMA read or write 
access of the corresponding CCx or CCxBUF will then clear the CCxIF and 
releases the request.
...
ist vielleicht ein Wunschvorstellung für zukünftige Releases ...


Dies

Dieter Frohnapfel schrieb:
> Übrigens scheinen 10 CPU-Takte damit für einen Compare-Wert-Wechsel
> auszureichen.

muss ich relativieren. 8 Takte scheinen ausreichend zu sein. Im Debugger 
kann man das halt schlecht erkennen - und berechnen kann ich es nicht, 
da ich nicht weiß ob der buffer-transfer Takte "verbrät". Ich habe das 
Debugging mit einer aktiven, unendlichen WHILE-Schleife durchgeführt. 
Mit einer WHILE-Schleife werde ich wohl auch leben müssen, da ich die 
MCU nicht schlafen legen kann.


@Jens:

Bist Du erfolgreicher wie ich? Habe vor lauter Frust vergessen 
nachzuhaken. Ist wieder mal sehr ruhig geworden ...

Außerdem sollten wir einen neuen Thread aufmachen - aufgrund der Größe 
komme ich manchmal gar nicht mehr "rein" :-(

Gruß
Dieter

von Jens (Gast)


Lesenswert?

Hallo Dieter,

hört sich aber doch nicht so schlecht an. Die Sleep Modi brauchst du 
nicht. Ich dachte die sind eher dazu da um Strom zu sparen. Aber die 
paar mA sind ja nicht schlimm. Ich denke es ist nur wichtig, dass du den 
Bus nicht belegst. Der XMega hat einen getrennten Befehls- und Datenbus. 
Wenn du mir der CPU in ein Register schreibst brauchst du den Datenbus. 
Dann ist der für den DMA blockiert. Wenn du deinen Controller aber 
warten lässt wie while(1); dann brauchst du den Datenbus nicht und der 
DMA hat freie Bahn.
Dass mit dem Datenblättern noch nicht alles stimmt habe ich auch hier 
und da schon festgestellt. Aber meistens kann man sich doch irgendwie 
weiter helfen.

Bei mir geht es auch weiter. Die letzten zwei Wochen hatte ich nur noch 
andere Sachen zu tun und da kam der Drucker etwas zu kurz.
Ich muss meine Schaltungen für den neuen Controller nur etwas umbauen. 
Da ich die alte Version aber nicht einfach verwerfen wollte habe ich 
sämtliche Platinen neu aufgefädelt auf Lochraster. Das hat mich ein 
bisschen Zeit gekostet.
Ich denke ich komme ab morgen wieder dazu weiter mit der Software zu 
spielen. Wie gesagt, portiert ist alles schon aber ich will die 
einzelnen Module noch einzeln testen um sicher zu gehen, dass ich nicht 
noch Fehler drin habe und dass auch alles so funktioniert wie es soll. 
Sonst ist vielleicht die LD gleich kaputt und dann wird es wieder teuer. 
Unnötige Hast bringt meiner Meinung an der Stelle nichts.

Viele Grüße, Jens

von Dieter F. (Gast)


Lesenswert?

Hallo Jens,

ja, ich werde wohl mit einer While-Konstruktion arbeiten müssen. Bin 
noch am  Überlegen, wie.

Genau wie Du kann ich mich nicht immer um mein Hobby kümmern - manche 
Dinge ("Regierungsangelegenheiten") gehen halt immer vor.

Ich habe gestern noch den Thread "UV-Laserdrucker II" eröffnet und würde 
gerne dort weitermachen. Habe mal meinen kleinen Prototypen eingestellt 
- wer will kann gerne damit spielen und ggf. Verbesserungsvorschläge 
machen :-)

Grund ist, dass ich mit dem Smartphone nur mit Mühe im aktuellen Thread 
lesen kann und manchmal - wegen mangelnder Bandbreite - vom Rechner aus 
auch keine richtige Verbindung mehr bekomme. Es wäre schön, wenn sich 
alle anschliessen.

Gruß
Dieter

von Conny G. (conny_g)


Lesenswert?

Hier geht's weiter:
Beitrag "UV-Laserdrucker II"

von Barney G. (fuzzel)


Lesenswert?

Dieter Frohnapfel schrieb:
> Grund ist, dass ich mit dem Smartphone nur mit Mühe im aktuellen Thread
> lesen kann und manchmal - wegen mangelnder Bandbreite - vom Rechner aus
> auch keine richtige Verbindung mehr bekomme. Es wäre schön, wenn sich
> alle anschliessen.

Letzter Beitrag hier.

Hast Du die Seitenaufteilung eingeschaltet ? Bei mir hat das einiges 
gebracht. Wenn ich die aus habe nuetzt mir auch die 100000er Leitung 
nicht wirklich was. Mit dem Handy (LTE) das selbe Spiel. Warum das auch 
mit Seitenaufteilung sooo lahm ist habe ich noch nicht nachgesehen, aber 
mit geht es zumindest einigermassen. Ohne macht selbst eine schnelle 
Leitung mit allen typischen Browsern hier schlapp.
Kommt mir vor wie zu Modem-Zeiten. Teilweise kann man sich zwischendrin 
wirklich 'n Kaffee kochen.

Wollte ich nur mal anmerken, evtl. geht es ja mehreren so und vielleicht 
hat auch wer eine Loesung oder weiss woran es liegt. Denn sooo lang ist 
dieser Thread ja nun auch nicht.

Nu gut, rueber zu Teil II

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