Wie könnte man eine 0 in einem String verwenden

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    Aufgrund technischer Veränderungen ist der Mailverkehr innerhalb des Forums (Private Nachrichten) nur noch eingeschränkt möglich. Die Einschränkung ist notwendig, um zusätzliche Betriebskosten für das Forum zu vermeiden. Näheres zu den Hintergründen im Thread "Aktuelles zum Forum".Wir bitten um Verständnis.

    Hinweis kann nach Kenntnisnahme deaktiviert werden!

    • Wie könnte man eine 0 in einem String verwenden

      Hallo zusammen
      ich habe ein Problem und habe noch keine vernünftige Lösung gefunden. ?(
      Vielleicht hat jemand eine bessere Idee.
      Ich verwende das intelligente Display von Electronic Assembly eDIPTFT43. Ich steuere das Display über die Serieschnittstelle.
      Problem: Zur Steuerung wird eine Zeichenkette gesendet die in den Bytes (4-7) die Startposition beinhaltet.
      Da die Position mit 2 Bytes übertragen wird (Low und Highbyte) und der Bereich 1...480 sowie 1...272 Pixel abdeckt MUSS für die Werte 1...255 das Highbyte auf 0 gesetzt werden.
      Leider ist die 0 auch das Stringendezeichen; tritt es innerhalb des Strings auf wird es verworfen respektive wird als Stringende interpretiert. Somit wird die 0 nie gesendet und das Display reagiert nicht.
      Meine provisorische Abhilfe:
      Statt 0 wird die Zahl 255 verwendet. In der Sub Write_edit wird auf 255 geprüft und wenn ja durch 0 ersetzt.
      Die Zeichen werden dann mittels PRINTBIN gesendet da sonst die 0 wegen der automatischen ASCII-Konvertierung der PRINT-Routine ebenfalls nicht gesendet wird.
      Durch den Trick kann die Pixelposition 255 jedoch nicht angesteuert werden da sie dann durch 0 ersetzt wird.
      Weiss jemand eine andere Lösung? Ich möchte gerne die Stringfunktionen behalten.

      Beispielcode:

      Quellcode

      1. Buffer = Chr(27) + "ZL" + Chr(1) + Chr(255) + Chr(220) + Chr(255) + "Font7x12.1---------2---------3---------4---------5" + Chr(13)
      2. Gosub Write_edip
      3. Sub Write_edip
      4. Dat = 17 'Startbyte DC1
      5. M = Len(buffer)
      6. Bcc = 17 + M
      7. Print Chr(dat) ; 'DC1
      8. Print Chr(M) ; 'LEN
      9. For M = 1 To Len(buffer)
      10. C = Mid(buffer , M , 1) 'aktuelles Zeichen
      11. if C = Chr(255) then C = Chr(0)
      12. Printbin C ;
      13. Bcc = Bcc + Asc(c) 'Zeichen wird für die Checksumme benötigt
      14. Next M
      15. Print Chr(bcc) ; 'und noch Checksumme senden
      16. End Sub
      Alles anzeigen
      Gruss
      jepe
    • jepe schrieb:

      Ich möchte gerne die Stringfunktionen behalten.
      Warum?
      Erst baust du dir einen String zusammen, um dann in der Sub wieder umständlich die einzelnen Zeichen rauszuholen und die sendest du dann.
      Ich empfehle dir, dich mal mit Arrays zu beschäftigen. Das ist am Ende auch nichts anderes als ein String, aber ohne díe Einschränkungen. Buffer wäre dann ein solches Array.
    • Habe ich auch mal überlegt aber:
      Die Texte sind verschieden lang also Buchstabenzählen (kein Abschlusszeichen möglich).
      Das Array muss ich auch auseinanderbröseln um die Checksumme zu bekommen.
      Wie gebe ich die Texte ein, Buffer(1) = A; Buffer(2) = u; Buffer(3) = s ; Buffer(4) = &h0 etc ?
      Nicht sehr übersichtlich oder liege ich falsch?
    • Da du die Daten seriell ausgibst (ich nehme jetzt mal Hardware UART an),
      kannst du auch den SerialOut-Buffer verwenden.

      Dann schreibst du einfach Print "Aus"
      Printbin 0

      das würde deinen String "Aus" zunächst ohne CHR(0) in den Sendebuffer verfrachten.
      Danach einbach per PrintBin eine 0 nachschieben.

      Da du aber eine Checksumme brauchst, musst du vorher die Werte berechnen oder einen anderen Weg gehen.

      Dieser wäre z.B. eine Routine schreiben, die deinen String in ein Array kopiert samt der abschließenden 0.
      Weitere Schreibzugriffe würden dann immer anhängen. Dazu musst du einen Index als Zeiger verwenden.

      Auf diese weise kannst du alles, was zu senden ist erst mal in ein Array (Sendebuffer) kopieren.
      Vor dem Senden berechnest du deine Checksumme und dann gibst du die Zeichen byteweise aus
      etwas so:

      PrintBin BufferArray(0),20
    • in diesem Falle
      müsste ich die Headerbytes ins Array kopieren (bestehen aus Text und Zahlen inkl. NULL), die Länge notieren, dann den Textstring hinter die Headerbytes ins Array kopieren eventuell nochmals (falls nötig) eine NULL hinterherschieben und die neue Länge im Header nachführen; dann die Checksumme im Array berechnen. Danach PrintBIN Array(0),Länge und schlussendlich noch die Prüfsumme nachschieben.
      Etwas unübersichtlich wenn man viel Text und viele verschiedene Header hat aber wohl die einzige Möglichkeit. Oder man verzichtet auf die Pixelposition 255. ?(

      Dazu noch eine Zwischenfrage: Unterschied zwischen
      Print STRING resp.
      Pro Zeichen des STRING ein PrintBIN
      Gehen die Einzel-PrintBIN-Bytes in einen Puffer (anzunehmen) oder wird gewartet bis das Byte gesendet ist?

      P.S. konnte kein jpg.Bild einfügen oder es erscheint in der Vorschau nicht
    • jepe schrieb:

      leider ist die Anzahl Headerbytes verschieden
      Nicht immer 10? =17,länge, 27,"Z","L",Low,HighZeile,Low,HighSpalte und danach ein String mit dem Text (ohne Null)
      Wie wärs damit:
      Dim Buffer as Byte(40)
      Buffer(1)=27 : Buffer(2)=$5A ..... 'die ersten vier
      Dim Spalte as word at buffer+ 6 Overlay, Zeile as word at buffer+8 Overlay
      Dim Text as String*36 at buffer+10 Overlay
      Falls gebraucht noch dim Voltext as String*40 at Buffer was aber wenig Sinn macht
      Zur Ausgabe
      l=len(Text)
      For a= 1 to l+10
      ...
      PS Printbin dat ist erheblich schneller als print chr(dat)
    • jepe schrieb:

      Buffer = Chr(27) + "ZL" + Chr(1) + Chr(0) + Chr(220) + Chr(0) + "Font7x12.1---------2---------3---------4---------5" + Chr(13)
      Wenn du sowas schreibst (beachte die Chr(0)), dann müssten die die 0-Bytes auch in dem String vorliegen.
      Nur wenn du dann mit Len(Buffer) die Länge ermittelst, wird es nicht funktionieren.
      Grund ist, dass die Funktion die Bytes zählt, bis es auf das 0-Byte trifft.

      Wenn du aber am Ende des erzeugten Buffer-Strings noch z.B. ein Chr(255) als Stringende-Erkennung anhängst,
      könntest du eine eigene Len-Function schreiben, die eben die Anzahl Bytes zurück gibt, bis sie auf Chr(255) trifft.

      Zum seriell Ausgeben nimmst du dann PrintBin Array(startindex),Länge und übergibst das Array (Overlay auf String) mit der selbst ermittelten Länge.

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Mitch64 ()

    • Sorry, ist mir im Nachhinein auch aufgefallen.

      Aber ich habe vielleicht des Rätsels Lösung.

      Du sendest Befehle im Binärmodus, wenn du für Escape $1B verwendest. Siehe Datenblatt Seite 12.
      Wenn du anstelle 1B das Zeichen # verwendest, sendest du im Ascii-Mode.

      Bedeutet, dass du keine 0 mehr in den String bauen musst. Stattdessen schreibst du dezimale Zahlen mit Komma getrennt.

      Wenn das Display nicht so teuer wäre, würde ich mir glatt auch eins kaufen. Ist nicht schlecht!
    • @Mitch64
      Es geht um die Steuerzentrale. Die LP ist für 2 Displays vorgesehen, ein 4" 480*320 Display (mit IL9486) mit hipnick's Routinen (Ihm sei hier herzlich gedankt) sowie das eDIPTFT43.
      Das eDIPTFT43-Display läuft im Normalbetrieb mit 57600 Baud. Im ASCII-Betrieb werden die Kommandos z.T. doppelt so lange, mit Text relativ weniger.
      Wenn ich wieder zuhause bin werde ich das mal ausprobieren.

      @musterkonsument
      Leider ist die Leiterplatte fertig und für RS232 ausgelegt. Am Code wäre ich jedoch interessiert; ich sende Dir eine PM

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von jepe () aus folgendem Grund: ergänzt

    • Hallo @jepe

      Ich habe mal geschaut, wie das funktionieren könnte, wenn man im seriellen Binärmodus bleibt.
      Natürlich kommt man da um das Kopieren der Daten in den Buffer nicht herum.
      Grund ist die Datenbyte Daten-Länge im Frame, welches in die Checksumme einfließt.

      Bascom schränkt einen da auch ein, indem es z.B. die Checksummen-Berechnung nicht für ein Array unterstützt.
      Die Berechnung hört dann auf, wenn in dem Array ein 0-Bytes vorkommt.

      Also nicht so ganz easy. Auch die Werte in den Buffer bringen erfordert einen gewissen Overhead.

      Lange Rede kurzer Sinn.

      Ich habe eine kleine Demo geschrieben. Dieses Schnipsel zeigt, wie einfach man im Hauptprogramm (Zeile 39 bis 41) z.B. den Bildschirm löscht, einen Text ausgibt oder eine Linie zeichnet.

      BASCOM-Quellcode: Demo_EA_Lib.bas

      1. ' ============================================================================
      2. ' Demo EA_Lib.inc
      3. ' Generierung von Display-Datenpaketen für EA eDIPTFT43-A
      4. ' Schittstelle: serial Binärmode
      5. ' Autor: Mitch64 (Bascomforum.de)
      6. ' Version: 0.0.1
      7. ' Erstellt: 06.01.2020
      8. ' ============================================================================
      9. ' Die Lib ist noch vollständig und kann nach eigenen Bedürfnissen
      10. ' im vorgezeigtem Schema erweitert werden.
      11. ' ============================================================================
      12. $Regfile = "m1284def.dat"
      13. $HWStack = 64
      14. $SWStack = 64
      15. $FrameSize = 64
      16. $Crystal = 16000000
      17. $Baud = 19200
      18. Config Base = 0
      19. $Include "EA_Lib.inc" ' Einbindung der Display-Routinen
      20. ' ============================================================================
      21. ' Hauptschleife
      22. ' ============================================================================
      23. ' Die in der Hauptschleife angegebenen Befehle sind in der EA_Lib.inc definiert.
      24. ' Jeder Befehl (Zeile) erzeugt die Daten im Buffer, berechnet die Checksumme
      25. ' und sendet das komplette Frame (Paket) an das Display.
      26. ' EA_Cls() löscht den Bildschirm
      27. ' Dann wird mit EA_Text() ein String ausgegeben
      28. ' Zum Schluss wird noch eine Linie gezeichnet mit EA_Line()
      29. Do
      30. Call EA_CLS() ' Bildschirm löschen
      31. Call EA_TextL( "Hallo Welt" , 20 , 50) ' Text (Linksbündig) an Koordinate ausgeben
      32. Call EA_Line(0 , 0 , 479 , 271) ' Linie zeichnen
      33. Wait 3
      34. Loop
      35. ' Die Erweiterung der EA_Lib mit eigenen Befehlen ist recht simpel.
      36. ' In den 3 definierten High-Level Routinen wird gezeigt, wie es geht.
      37. ' Die wichtigsten LowLevel-Routinen sind bereits enthalten.
      Alles anzeigen

      Die Routinen die das einfache Handling ermöglichen habe ich ausgelagert in eine Include-Datei namens EA_Lib.inc. die im Demo in Zeile 24 eingebunden wird.

      Dort sind im wesentlichen die Kopier-Routinen, die unterschiedliche Variablen-Typen in den Buffer kopieren. und die High-Level Routinen, mit denen man dann im Hauptprogramm das Display steuert und die Daten ans Display sendet.

      Die Lib kann ich hier leider nicht aufzeigen, da ich die Zeichengrenze (10000) überschreite.
      Das komplette Demo mit EA_Lib.inc gibst aber auch unten zum Download.

      Die Lib ist natürlich nicht vollständig. Das ist in einem Tag auch nicht machbar. Abgesehen davon habe ich kein Display um es auszuprobieren.
      Fehler können also enthalten sein. Die Lib ist, so denke ich mal, ein guter Ansatz, um Routinen für das Display wiederverwendbar aufzubereiten.
      Was ich gar nicht berücksichtigt habe ist das Acknowledge vom Display.

      Ich habe das Demo und die Lib hoffentlich ausreichend kommentiert, damit man in der Lage ist, die Lib selber an die Anwendung anzupassen.
      Also entsprechend die Hinweise und Kommentare auch lesen.

      Würde mich freuen über ein Feedback, ob es funktioniert oder ob und wo es hakt.
      Dateien
      • Demo.zip

        (4,79 kB, 10 mal heruntergeladen, zuletzt: )