LCD Display performant steuern ?

Hallo, Im Rahmen meines Lasercutter Projekts habe ich ein Lcd Display eingebaut. Zeigt die G-Code Zeile an und die Leistung des Lasers.

Jedenfalls fällt mir auf, das nach jedem Wechsel der G-Code Zeile eine sehr kleine Wartezeit entsteht. Ist natürlich nicht gut, da der Laser in dieser Zeit (wenn diese sehr kurz ist) auf einem Punkt steht und dort reinbruzelt.

Ich verwende die LiquidCrystal Lib im 4Bit Mode, ein Blick in den Libcode zeigt das hier Zeit verbraucht wird (mit Delays) damit der Display Controller das richtige Timeing hat.

Ist ja auch richtig, nur ist dies in meinem Fall kontraproduktiv.

Stehe nun auf dem Schlauch, wie könnte man dies lösen ? Hat jemand eine Idee ?

Hallo rudirabbit,

eine Möglichkeit wäre es, die ganzen Libary umschreiben zB mit millis().

Die Brachialmethode wäre es dem Display einen eigenen Controller zu spendieren. Mehr Hardware-Aufwand, aber von der Software her einfacher als die Library zu ändern.

rudirabbit: Stehe nun auf dem Schlauch, wie könnte man dies lösen ? Hat jemand eine Idee ?

Machst Du einfach einen Umschalter für die Schaltstellungen "Debugmode" und "Normalmode".

Wenn der Umschalter auf "Normalmode" steht, einfach keine Ausgaben auf dem Display machen.

Serenifly: Die Brachialmethode wäre es dem Display einen eigenen Controller zu spendieren. Mehr Hardware-Aufwand, aber von der Software her einfacher als die Library zu ändern.

Theoretisch wäre das bei I2C Displays der Fall, wäre einen Test wert.

Wenn ich z.b die diverse Atmel Firmware für 3D Drucker ansehe, die geben z.b die aktuelle x,y,z beim Fahren auf dem Display aus :o Werde mal einen Blick in die Sourcen werfen.

Im Endeffekt ist es nur ein Gadget, schaut halt schick aus ;)

Mal so aus Neugier, was schnippelst du damit, wenn es funktioniert?

Zufälligerweise Arduinogehäuse mit LCD Ausschnitt?

Ein Portexpander wie bei den meisten I2C-Interfaces für die LCDs ist nicht die Lösung. Dadurch wird das ganze nicht schneller, sondern eher noch langsamer. Du berechnest auf deinem Arduino jedes Mal, welche Ausgänge gesetzt und welche gelöscht werden müssen. Das Ergebnis wird dann an den I2C (PCFxx) gesendet, der dass übernimmt. Da bist du besser beraten, wenn du dass direkt auf die Ports(µc) ausgibst.

Was du brauchst, wäre zB. ein 2 µC, der nur die LCD Lib macht. Du müsstest dann die Daten, am besten über SPI (aufgrund der deutlich höheren Perfomance) an den 2 Kontroller schicken. Hier wirst du dich aber selber ransetzen müssen, mir ist keine Libary bekannt, die das unterstützt.

Du Messages könntest du dann mit einem Byte zur Zeilensteuerung und einem String erreichen. Das erste Byte zur Zeilensteuerung enthält die Adresse der Startposition.

Hallo,

mal zurück auf Anfang. Du sagst, dass Dich es stört, dass der Laser zu lange stehen bleibt, wenn das Display eine Zeile schreibt. Im Normalfall passiert das so schnell, dass man optisch keine Verzögerung mitbekommt. Das sind wenige ms. Das heißt, wenn Du optisch schon siehst und fühlst, dass der Laser zu lange wartet, kann das aus meiner Sicht drei Gründe haben.

a) Du hast irgendwelche künstlichen delay's drin, die mit dem Display nichts zu tun haben b) Deine Display Library funktioniert zwar, ist aber "zu sicher" programmiert, zu lange Wartezeiten c) Du berechnest vorher irgendwas was dann zur Anzeige gebracht wird, was die Verzögerung verursacht

Mein Neffe hatte im Rahmen eines Schulprojekts sein 2x20 Display auf maximalen Speed getrimmt, da konnte man nichts mehr lesen, was aber so gewollt war. Es wurden Zufallszeichen ohne Ende ausgegeben und nochmal ein Zeichen wie drüber gelegt welches auf dem Display wanderte. Sah schon cool aus. Ich möchte damit sagen, dass ein Display für sich nicht der alleinige Grund sein kann für die Verzögerung.

Zeig am besten mal deinen Sketch. lcd.init(), lcd.clear(), lcd.home() sind eigentlich die einzigen Befehle, die wenige ms dauern. Die anderen Befehle sind in wenigen µs erledigt.

Ein Test ohne Lcdausgabe zeigte das dies nicht die Hauptursache ist.

Ich sehe es nicht direkt daran das der Laser zu lange stehen bleibt. Wenn ich die Leistung runter regle weil ich nicht schneiden will sondern nur gravieren kann man am Ergebnis sehen das beim Wechsel der G-Code Zeile der Laser wohl eine kleine Pause einlegt. Da reichen schon ms aus, ohne Lcd ist es zwar besser aber nicht ganz behoben.

Da hier eben auch die Displayanzeige refreshed wird, dachte ich erst es liegt daran. Es ist aber schon so, das die Arduino Lcd Lib alles andere als optimal ist. Z.b wird der R/W Pin des Displays auf 0 gelegt, es wird wohl nicht ausgelesen wann der Display Controller fertig ist sondern einfach gewartet, (Also so wie schon erwähnt wird mit Sicherheitsdelays gearbeitet) Aber das ist eine Vermutung von mir, in das Datenblatt des Displaycontrollers habe ich nicht reingesehen. @Doc_Arduino: Denke dein Neffe hat mit Sicherheit nicht mit dieser Lib die Performanceerfolge erzielt ;)

Der Parser wird es auch nicht sein, denn ich arbeite mit Char Arrays und den entsprechenden Zeichenkettenfunktionen.

Die Übertragung des G-Code vom PC zum Arduino erfolgt mit 9600 Baud. Mein G-Code Sender Programm kann aber nur 9600 Baud, deshalb kann ich auf die Schnelle nicht testen ob eine schnellere Baudrate was bringt. Die anderen (grbl) Programme erwarten von der Maschine beim Starten Informationen sonst starten die nicht. Bevor ich rausfinde was die Programme so wollen baue ich besser ein simples Sender Programm mit Delphi und einstellbarer Baudrate.

PS: Wollte schon lange mal ein Video reinstellen wenn der Laser arbeitet. Bei den Videos mit dem Handy kann man nicht viel mehr als einen sehr hellen großen Punkt mit viel Rauch erkennen. Ich trage dabei eine OD4+ Schutzbrille, sehe damit genau was der Laser macht. Das Handy braucht wohl auch eine Brille. Der CCD des Handys geht dabei aber nicht kaputt. ;) Hätte nicht gedacht das eine 2.5 Watt 445 nm Diode doch so viel Wirkung hat. Bin neugierig was mit den Halbleiterlasern in der Zukunft möglich ist, vor allem wenn es in den 405 nm Bereich mit mehr Leistung geht

Das mit RW wird aber nichts schneller. Die delays kann man als Sicherheitsdelays ansehen, muss man aber nicht. In der Lib von Peter Fleury wird der RW Pin genutzt. (avr gcc). Aber dadurch ist das ganze nicht weniger blockierend. Hier wird anstelle der delays mit dem busyflag gearbeitet. Jedoch steht die Maschine auch, wenn nein keine Rückmeldung kam.

Ein optimierte LCD Libary zu erstellen, ist nicht zwingend ein Hexenwerk. Wichtig ist hier, dass mit direkten Portzugriffen gearbeitet wird. Wenn möglich auch noch die DB's auf einanderfolgenden Bits. Die vordefenierten Delays lassen sich noch weiter einschränken. Die sind idR nur so hoch, damit diese eine hohe Kompatibilität zu anderen LCD Controllern haben. HD44780 gibt es soviele ja nicht, viele sind inzwischen nur noch Nachbauten.

Wenn man das passende Datenblatt von seinem HD44780 kompatibilen Kontroller mal gefunden hat, dann sieht man schnell, dass die Zeiten doch meist sehr großzügig gewählt werden.

sschultewolter:
Was du brauchst, wäre zB. ein 2 µC, der nur die LCD Lib macht.

Du Messages könntest du dann mit einem Byte zur Zeilensteuerung und einem String erreichen. Das erste Byte zur Zeilensteuerung enthält die Adresse der Startposition.

Ich habe einen ATtiny 4313, der die LiquidCrystal.h ausführt, mit einem LC-Display verbunden. Glücklicherweise paßt auch noch TinyWireS.h drauf. Der Sketch ist erfreulich kurz. Fuses mit 8 Mhz!

Hallo,

wenn das mit dem Laser und der geringsten Wartezeit so kritisch ist, dann mußte den Laser sobald er stehl wohl ausschalten und sobald er weitermachen soll wieder einschalten. Oder geht das nicht?

Dein Code ist ansonsten frei von delay's?

Doc_Arduino: Hallo,

wenn das mit dem Laser und der geringsten Wartezeit so kritisch ist, dann mußte den Laser sobald er stehl wohl ausschalten und sobald er weitermachen soll wieder einschalten. Oder geht das nicht?

Dein Code ist ansonsten frei von delay's?

Über das M Kommando aus dem G.Code wird der Laser bei Bedarf aus/ein geschaltet.

Delays habe ich in der Takterzeugung drin. Also wenn bespielsweise 300 Schritte zu fahren sind dann wird in einer Schleife die Takte für die pololu Treiber erzeugt. Um die geforderte Verfahrgeschwindig zu haben liegt ein berechneter Delay in der Schleife. Ich weiß schon, das dies nicht schön ist. Aber ich habe das Problem nicht beim Fahren sondern immer dann wenn eine neue G-Code Zeile zu verabrbeiten ist. Der Atmega sckickt wenn eine G-Code Zeile fertig gefahren ist ein "ok\r\n" an das Windows Sender Programm. Dieses schickt dann die nächste Zeile an dem Atmega. Das ganze läuft wie gesagt mit 9600 Baud, ich will es erstmal mit einer höheren Baudrate versuchen.

Wenn man das Fahren ohne Delays macht, also mit z.b millies() könnte man in dieser Zeit gleich die neue Zeile anfordern und parsen. Oder die Stepper Lib verwenden. Diese blockiert aber auch solange die Motoren laufen, CustomSteper ist hier anders ausgelegt.

Wäre ein Ansatz, wenn die höhere Baudrate nichts bringt.

@sschultewolter: Klar das wäre kein Hexenwerk eine Optimierte LCD Lib zu bauen, wie du aber erkennen kannst habe ich gerade eine andere Baustelle. Wenn man mit dem R/W Pin arbeitet, müsste man einen Timeout einbauen wenn das Flag nicht gestzt wird. Sonst blockiert das ganze. Evtl. versuche ich sowas später mal das LCD Display ist quasi hier nur ein Beiwerk.

Hallo,

ob mit oder ohne Display, es gibt eine störende Verzögerungen, sagst Du. Jetzt kommt ans Licht, dass Du delays in der Takterzeugung hast und es "eine kurze Weile" dauert wenn Daten zwischen PC und Arduino ausgetauscht werden.

Jetzt weist Du wo es hängt. Vermeintlich unwichtige delays stören an anderen Stellen.

Eine Takterzeugung ohne delay ist auch möglich, da paßt bestimmt meine blinkende LED gut dazu.

Wurde hier im Thread optimiert und zur Mehrfachnutzung umgebaut. http://forum.arduino.cc/index.php?topic=322029.0

@Doc_Arduino : Mir ist die Problematik schon bekannt ("blink without delays"), klar ist eine Takterzeugung ohne Delays besser.

War mir auch durchaus bewusst als ich den Code so geschrieben hatte, nur meine Überlegung war. Solange der Schrittmotor läuft, muss man sowieso warten bis der nächste Befehl abzuarbeiten ist.

Das hier ohne den blockierendem Thread doch was zu optimieren ist nun logisch. Mal sehen ..

Hallo,

ich weis wie umständlich es ist einen funktionierenden Code abzuändern. Mußte ich schon mehrfach machen, aber es hat immer neue Vorteile gebracht. Versuch es wenigstens ... ich drück die Daumen.

Doc_Arduino: Hallo, ich weis wie umständlich es ist einen funktionierenden Code abzuändern. Mußte ich schon mehrfach machen, aber es hat immer neue Vorteile gebracht. Versuch es wenigstens ... ich drück die Daumen.

Mache ich auf jeden Fall, das Projekt ist noch lange nicht so wie ich es gerne hätte. Im Moment baue ich mir erstmal ein Windows G-Code Sender Programm.

Läuft auch schon fast, Baudrate einstellbar. Startet schnell und die RX Daten (bei bedarf sendet der Arduino dort auch Debug Daten) in der Scrollbox werden in Echtzeit angezeigt.

Das ist bei den meisten G-Code Sender Programmen nicht so. Ist oft langsamer Java Dreck >:( Mit Delphi ist sowas schnell zusammengeköpelt.

Sehr OT: Warum man Programme in Java schreibt die im Prinzip nur auf einer Windows Maschine laufen sollen ist mir ein Rätsel. Bei mir in der Arbeit ist die Diagnosesoftware nun auch Java basierend. (Win7 OS) Startet langsam, läuft sehr träge und schmiert ab und zu einfach ab. Damit müssen wir Diagnoseprozesse erstellen, um beim Hersteller Garantieansprüche geltend zu machen können ist das natürlich nicht gut wenn der Tester abkackt. Wir haben nun die Anweisung bekommen, regelmässig innerhalb der Sitzung zu speichern. :)

Der Vollständigkeit halber meine Version eines einfachen G-Code Senders.

Läuft mit 115200 Baud.
Auf dem Atmel ist nur die Baudrate angepasst, die Performanceprobleme sind damit behoben.

Obwohl wie Doc_Arduino schon sagte der Atmel Code noch zu optimieren ist, sind so keine Unterbrechungen mehr festzustellen.

Gcodesender.zip (232 KB)