String mit wirren Symbolen

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
ossy
Beiträge: 18
Registriert: 07.11.2006 23:04
Computerausstattung: Schneider CPC6128, Amiga 500 1.3, PC mit XP SP3, PC mit WIN7
Wohnort: Burladingen

String mit wirren Symbolen

Beitrag von ossy »

Hallo zusammen,
ich habe mir vor circa 11 Jahren ein kleines Programm geschrieben.
Das Programm ist ein serieller Monitor. Das ich seiner Zeit zu einer
EXE-Datei kompiliert hatte. Mein damaliger Computer war ein mit Windows XP
Betriebssystem Laptop mit 32 Bit. Das Programm läuft bis heute einwandfrei.
Auch auf meinem neuen Rechner Windows 10 mit 64 Bit System.
Jetzt wollte ich mein Programm auf meine neuen Bedürfnisse anpassen.
Ich sende einen String vom Arduino an den Computer.
Mit dem alten Programm funktioniert alles einwandfrei.
Das selbige Programm, wenn ich es neu kompiliere, funktioniert nicht mehr
und empfängt nur noch chinesische Schriftzeichen. Auch mit dem unveränderten
Quellcode von damals die gleichen wirren Zeichen.
Also mit der Arduino IDE und dem seriellen Monitor funktioniert die
Übertragung einwandfrei, auch mit meinem älteren Programm.
Ich sende folgenden String: " Taster-gedrueckt " als Ergebnis kommt das
zurück " 慔瑳牥朠摥畲捥瑫਍ ".
Vieleicht kann mir jemand einen Tip geben.
Hier noch mein Code:

Code: Alles auswählen

;**************************
;*                        *
;*   Kleines Com-Port     *
;*     Version 1.4        *
;*    vom 05.10.2011      *
;*      Wolfgang D.       *
;**************************

Dim Messages.s(14)
    Messages(0) = "50"
    Messages(1) = "75"
    Messages(2) = "110"
    Messages(3) = "150"
    Messages(4) = "300"
    Messages(5) = "600"
    Messages(6) = "1200"
    Messages(7) = "1800"
    Messages(8) = "2400"
    Messages(9) = "4800"
    Messages(10) = "9600"
    Messages(11) = "19200"
    Messages(12) = "38400"
    Messages(13) = "57600"
    Messages(14) = "115200"
    Global Dim verfuegbar(30) ; kann bei bedarf noch erweitert werden
    Global Dim verfuegbaralt(30)
        
Declare startwerte()
Declare port()
Declare schreibe()
Declare prefs()
Declare cls()
Declare speichern()
Declare senden()
Declare GetAvailableComPorts()
Declare vergleichePorts()

Global NewList AvailableComs()


Structure kc    ;kleines comport
  
  baud.l    ;50, 75, 110, 150, 300, 600, 1200, 1800, 2400
            ;4800, 9600, 19200, 38400, 57600 oder 115200
  com.b
  comport.s

  datei.s
  file.s
  StandardFile.s
  windowbr.l
  windowh.l
  gadgetbr.l
  gadgeth.l
  ver.s
  text.s
  er.b
  open.b
  speicher.b
  set.l
  send.s
  datenstring.s[1000]
  zaehler.l
  x.b
  xneu.b
  xalt.b
  w.b
  aktiv.b
  gleich.b
  
EndStructure

Global wd.kc

LoadFont(0,"Arial black",10)
LoadFont(1,"Arial",20)
LoadFont(2,"Arial black",8)


startwerte()

SetGadgetFont(#PB_Default, FontID(2))   ; geladenen Arial 20 Zeichensatz als neuen Standard festlegen

wd\text="Kleines Comport V"+ wd\ver

OpenWindow(0, 0, 0, wd\windowbr, wd\windowh, wd\text, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget)
  ComboBoxGadget(0, 2, 2, 70, 23)
      wd\w=0
;-------
    GetAvailableComPorts()

    vergleichePorts()
    
      For a = 1 To wd\x+1
        AddGadgetItem(0, -1,"Com " + Str(verfuegbar(a)))
       Next
             
        If wd\gleich = 1            
        SetGadgetState(0,0)
        Else
        SetGadgetState(0,wd\aktiv)
        EndIf
        
      ComboBoxGadget(1, 72, 2, 100, 23)
      For a=0 To 14
        AddGadgetItem(1, -1,Messages(a))
      Next
      SetGadgetState(1, wd\set)
      ButtonGadget(2, 175, 2, 78, 26, "Verbinden" , #PB_Button_Toggle)  
      ButtonGadget(3, 175,210,78,26, "Löschen")
      ButtonGadget(4, 175, 58, 78, 26, "Senden" ) 
      ButtonGadget(5, 175, 30, 78, 26, "Speichern" ) 
      EditorGadget(50, 10, 58, 150, 26 )
      ;TextGadget(100, 10, 100, wd\gadgetbr, wd\gadgeth )
      EditorGadget(100, 10, 100, wd\gadgetbr, wd\gadgeth,  #PB_Editor_ReadOnly )
      
          wd\text="Version "+ wd\ver
      
          SetGadgetText(100, wd\text)
          

      Repeat 
        
        With wd.kc
        
          EventID = WindowEvent()
          ;If EventID = #PB_Event_Gadget
          If eventid = #PB_Event_CloseWindow  
            prefs()
            Delay(20)
            End
            ElseIf EventID = #PB_Event_Gadget
            
            Select EventGadget()
                
                Case 2 :If GetGadgetState(2):\er=1:SetGadgetText(2,"Trennen"):
                        Else: SetGadgetText(2,"Verbinden"): \er=0: EndIf
                
                    Case 3 : cls()
                      
                    Case 4 : senden()
                      
                      Case 5 : speichern()
                  
            EndSelect    
            port()
          EndIf
          
          If \open=1
            schreibe()
            
            Delay(10)
          EndIf
          
        EndWith
        
      

;Until EventID = #PB_Event_CloseWindow 

ForEver




Procedure startwerte()
  
  With wd.kc
    
    \ver="1.4"
    \StandardFile="standart"
   \windowbr = 260 
   \windowh = 250 
   
   \gadgetbr = 240
   \gadgeth = 100
   
   \baud = 2400
   \com = 1
   \comport = "COM1"
   \datei="init.dat"
   \text="Version 1.0"
   \er=0
   \open=0
   \speicher=0
   \set=6
   \zaehler=1
   \x=0
   \xneu=0
   \xalt=0
   
   prefs()
  
  EndWith
  
EndProcedure

Procedure GetAvailableComPorts()
   Protected hKey, lpcbName, lpName.s, a$, lType, i

   If RegOpenKeyEx_(#HKEY_LOCAL_MACHINE, "HARDWARE\DEVICEMAP\SERIALCOMM", 0, #KEY_QUERY_VALUE, @hKey) = #ERROR_SUCCESS
      lpName   = Space(255)

      Repeat
         lpcbName = 255
         If RegEnumValue_(hKey, i, @lpName, @lpcbName, 0, 0, 0, 0) = #ERROR_SUCCESS
            a$ = Left(lpName, lpcbName)
            If a$ = ""
               Break
            EndIf
            lpcbName = 255
            lType    = 0
            If RegQueryValueEx_(hKey, a$, 0, @lType, @lpName, @lpcbName) = #ERROR_SUCCESS
               a$ = Left(lpName, lpcbName - 1)
               If LCase(Left(a$, 3)) = "com"
                  AddElement(AvailableComs())
                  AvailableComs() = Val(RemoveString(a$, "COM", 1))
                  verfuegbar(i+1) = Val(RemoveString(a$, "COM", 1))
                  wd\xneu=i

               EndIf
            EndIf
            i + 1

         Else
            Break
         EndIf
      ForEver
      RegCloseKey_(hKey)
   EndIf

 EndProcedure
 
 Procedure vergleichePorts()
   
   With wd.kc
     \gleich=0
     
     
     If \xalt=\xneu
       \x=\xalt    
     Else
       \x=\xneu
       \gleich=1
     EndIf
     
     For a=1 To \xalt+1
       
       If verfuegbaralt(a)=verfuegbar(a)
       Else
         \gleich=1
          
         Break 
       EndIf
     Next a
     
     If \gleich=1
       MessageRequester(" COMPORT veränderung!", "Comport neu auswählen", #PB_MessageRequester_Ok)
     EndIf
      
     
             
   EndWith
   
 EndProcedure
 
Procedure port()
  
  With wd.kc
    
    \comport=GetGadgetText(0)
    \comport=RemoveString(\comport, " ") ;Leerzeichen aus dem COM-String entfernen
    
    If GetGadgetState(1)=0
      \baud=50
    EndIf
    If GetGadgetState(1)=1
      \baud=75
    EndIf
      If GetGadgetState(1)=2
      \baud=110
    EndIf
    If GetGadgetState(1)=3
      \baud=150
    EndIf
    If GetGadgetState(1)=4
      \baud=300
    EndIf
    If GetGadgetState(1)=5
      \baud=600
    EndIf
    If GetGadgetState(1)=6
      \baud=1200
    EndIf
    If GetGadgetState(1)=7
      \baud=1800
    EndIf
    If GetGadgetState(1)=8
      \baud=2400
    EndIf
    If GetGadgetState(1)=9
      \baud=4800
    EndIf
    If GetGadgetState(1)=10
      \baud=9600
    EndIf
    If GetGadgetState(1)=11
      \baud=19200
    EndIf
    If GetGadgetState(1)=12
      \baud=38400
    EndIf
    If GetGadgetState(1)=13
      \baud=57600
    EndIf
    If GetGadgetState(1)=14
      \baud=115200
    EndIf
    
    If \er=1
      If \open=0
        
        
      If OpenSerialPort(0,\comport, \baud,#PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 256,256)
        \open=1
      Else
            \text="Nix open "+\comport
          MessageRequester("Hilfe", \text, #PB_MessageRequester_Ok)  ;Kann Com x nicht öffnen
          SetGadgetState(2, 0)                                            ;Gatget wieder zurücksetzten
        SetGadgetText(2,"Verbinden")
        \er=0
    EndIf
  EndIf
  EndIf
  If \er=0
    If \open=1
      
      
      
      
        CloseSerialPort(0)
        
    \open=0 
    EndIf
  EndIf
  If \open=1
    schreibe()
    EndIf
    
  EndWith
  
EndProcedure

Procedure schreibe()

  With wd.kc
    
   If IsSerialPort(0) 
      input=AvailableSerialPortInput(0) 
      If input 
        a$=Space(input) 
        
        ReadSerialPortData(0,@a$,input) 
        Delay(4)
        a$=Trim(a$)
        
        \text=GetGadgetText(100)+a$  + Chr(13)
        
        \datenstring[\zaehler]=a$
        
        SetGadgetText(100, \text)
       
        \zaehler+1
      EndIf 
      
    EndIf  
    
    
    
    
    
  EndWith
      


EndProcedure

Procedure prefs()
  
  With wd.kc
    
    If \speicher=0
    If ReadFile(0, \datei)
      
      \text= ReadString(0)        ;Kleines Comport
      \comport=ReadString(0)      ; COM9
      \text=ReadString(0)         ; 6
      \set=Val(\text)             ;set ist zuständig für BAUD
      \text=ReadString(0)         ;9 Anzahl der zuletzt verwendeten Aktiven Comports
      \xalt=Val(\text)
     
      \text=ReadString(0)
      \aktiv=Val(\text)       ;aktiv ist zuständig zuletzt verwendeten Comport
      
      For a=1 To \xalt + 1
        
        verfuegbaralt(a)=Val(ReadString(0))  ;Comports mit Nummern
        
      Next a
      
     CloseFile(0)
     
   Else
     
      \baud = 2400
      \set=8
      \com = 1
      \comport = "COM1"
      \datei="init.dat"
      \text="Version 1.0 keine Daten geladen."
      
    EndIf
    EndIf
    
    \com=Val(Mid(\comport,4,2))
    
   
  
     If \speicher=1
       DeleteFile(\datei)
      
    If CreateFile(0, \datei)
      
      WriteStringN(0, "Kleines Comport")
      
      WriteStringN(0, \comport)
      
      \text=Str(GetGadgetState(1))
      
      WriteString(0, \text)
      WriteStringN(0, "  ")
      WriteStringN(0, Str(\xneu))
      \aktiv=GetGadgetState(0)
      WriteStringN(0, Str(\aktiv))
      For a=1 To \x + 1
        WriteStringN(0, Str(verfuegbar(a)))
      Next a
      
      
      CloseFile(0)
    
    EndIf
    EndIf
    
    \speicher=1
    
    
  EndWith
  
EndProcedure


Procedure cls()   
  
  With wd.kc
    
    \text=""
    
    SetGadgetText(100, \text)
    
    \zaehler=0
    
  EndWith
  
EndProcedure

Procedure speichern()
  
  With wd.kc
    
    Pattern$ = "Text (*.txt)|*.txt;*.dat|Alle Dateien (*.*)|*.*"
  Pattern = 0    ; wir verwenden den ersten von drei möglichen Pattern als Standard
  \file = SaveFileRequester("Bitte Datei zum Laden auswählen", \StandardFile, Pattern$, Pattern)
    
    
    ;\file=\file + Pattern$
    
    OpenFile(0, \file) 
    
    WriteStringN(0, "")
    WriteStringN(0, "")
    
    For x=0 To \zaehler
      If \datenstring[x]=""
        Goto nichtschreib
        EndIf
        WriteStringN(0,\datenstring[x])
 nichtschreib:
      Next x

    CloseFile(0)
    
  EndWith
  
EndProcedure

Procedure senden()
  
  With wd.kc
    
    If \open=0
      
      \text= "Erst Comport öffnen!"
      
      MessageRequester("Hilfe", \text, #PB_MessageRequester_Ok)  
      
    EndIf
    
    If \open=1
    
    a$=GetGadgetText(50) 
    
     
            If Len(a$)=1
              WriteSerialPortData(0,@a$,1) 
              
            Else 
              a$=Chr(Val(a$)) 
              WriteSerialPortData(0,@a$,1) 
               
            EndIf 
            
            EndIf
    
  EndWith
  
EndProcedure


Gruß Wolfgang


Was tut ein Frosch, der in ein Glas Milch gefallen ist?

Der eine gibt auf und ertrinkt, ein anderer strapelt solange, bis aus der Milch Butter geworden ist und er hinausklettern kann.

Das Problem an der zweiten Strategie ist nur: " Die Arbeitgeber haben erkannt, wie man billig Butter machen kann ".
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: String mit wirren Symbolen

Beitrag von mk-soft »

PB v5.x ist Unicode.

du musst die string von zu ASCII wandeln.

Code: Alles auswählen

*buffer = Ascii("Hallo")

sVal.s = PeekS(*buffer, -1, #PB_Ascii)

Debug sVal

FreeMemory(*buffer)
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Andesdaf
Moderator
Beiträge: 2658
Registriert: 15.06.2008 18:22
Wohnort: Dresden

Re: String mit wirren Symbolen

Beitrag von Andesdaf »

Kodierungsproblem, PB verwendet inzwischen Unicode als Standardkodierung. Du musst also entsprechend nach Ascii umwandeln.

// Edit: mk-soft war schneller.
Win11 x64 | PB 6.00 (x64)
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: String mit wirren Symbolen

Beitrag von NicTheQuick »

Du musst jetzt `ReadSerialPortData()` verwenden um die Daten roh zu empfangen und dann mit `PeekS(*Buffer, -1, #PB_Ascii)` aus dem Buffer lesen.
Bild
Benutzeravatar
ossy
Beiträge: 18
Registriert: 07.11.2006 23:04
Computerausstattung: Schneider CPC6128, Amiga 500 1.3, PC mit XP SP3, PC mit WIN7
Wohnort: Burladingen

Re: String mit wirren Symbolen

Beitrag von ossy »

Hallo Zusammen,

ich habe mich sehr gefreut über die schnellen Antworten.

Das Programm funktioniert jetzt!

Danke an alle die mich unterstützt haben.

Abschließend möchte ich noch den Code veröffentlichen, damit jemand mit dem gleichen Problem etwas abschauen kann.

Code: Alles auswählen

Procedure schreibe()

  With wd.kc
    
   If IsSerialPort(0) 
      input=AvailableSerialPortInput(0) 
      If input 
        a$=Space(input) 
        
        ReadSerialPortData(0,@a$,input) 

        Delay(20)
        
        
        a$=Trim(a$)
        m=Len(a$)

        a$ = PeekS(@a$, -1, #PB_Ascii)
        
           \text=GetGadgetText(100)+a$
               
        \datenstring[\zaehler]=a$
        
        SetGadgetText(100, \text)
        
        \zaehler+1
      EndIf 
    
    EndIf  
 
  EndWith
      


EndProcedure
Gruß Wolfgang


Was tut ein Frosch, der in ein Glas Milch gefallen ist?

Der eine gibt auf und ertrinkt, ein anderer strapelt solange, bis aus der Milch Butter geworden ist und er hinausklettern kann.

Das Problem an der zweiten Strategie ist nur: " Die Arbeitgeber haben erkannt, wie man billig Butter machen kann ".
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: String mit wirren Symbolen

Beitrag von NicTheQuick »

Dein Code ist nicht korrekt.
Erstens werden dir Trim und Len keine vernünftigen Ergebnisse liefern, wenn du es vor dem PeekS ausführst, und zweitens solltest du die möglicherweise binären Daten nicht in einem String speichern, sondern in einem echten Speicherbereich. Außerdem passt -1 als Längen-Parameter bei PeekS nicht, wenn die Daten nicht nullterminiert sind. Das habe ich auch angepasst. Ich habe außerdem deine Variablen deklariert. Deswegen hier der korrigierte Code:

Code: Alles auswählen

Procedure schreibe()
	Protected *buffer, gelesen.i, input.i, a.s
	With wd
		
		If IsSerialPort(0)
			input = AvailableSerialPortInput(0)
			If input
				*buffer = AllocateMemory(input)
				
				gelesen = ReadSerialPortData(0, *buffer, input)
				
				Delay(20)
				
				a = Trim(PeekS(*buffer, gelesen, #PB_Ascii))
				
				FreeMemory(*buffer)
				
				\text = GetGadgetText(100) + a
				
				\datenstring[\zaehler] = a
				
				SetGadgetText(100, \text)
				
				\zaehler + 1
			EndIf
		EndIf 
	EndWith
EndProcedure
Noch eine Frage: Warum hast du da ein Delay(20) drin? Das erscheint mir falsch.
Bild
Benutzeravatar
ossy
Beiträge: 18
Registriert: 07.11.2006 23:04
Computerausstattung: Schneider CPC6128, Amiga 500 1.3, PC mit XP SP3, PC mit WIN7
Wohnort: Burladingen

Re: String mit wirren Symbolen

Beitrag von ossy »

Hallo NicTheQuick,

das Delay kann vermutlich raus. Das stammt aus Tagen, an denen ich vermutlich etwas ausprobiert habe. Ich experimentiere seit Jahren mit Microchip PIC und Neuerdings auch mit Arduino und Kompatiblen.

Nicht wundern ich bin kein Programmierer. :D

Das war vor Jahren so, ich hatte mit den Daten, die verarbeitet werden sollten, Probleme. Und das sollte so werden, daß der empfangene String zerlegt werden sollte. Text / Asci-Code / Hex / Bin. Deswegen sind die Code-Schnipsel noch drinnen.
Vielleicht kommt das noch.

Danke für deine Infos.
Gruß Wolfgang


Was tut ein Frosch, der in ein Glas Milch gefallen ist?

Der eine gibt auf und ertrinkt, ein anderer strapelt solange, bis aus der Milch Butter geworden ist und er hinausklettern kann.

Das Problem an der zweiten Strategie ist nur: " Die Arbeitgeber haben erkannt, wie man billig Butter machen kann ".
Antworten