mscomm macht Fehler

#1129084
Lesenswert?

(Oder ich mache die Fehler)

Hat jemand Erfahrung mit dem MSCOMM Control?

Ich sende vom Mikrocontroller Daten über die serielle Schnittstelle und 
fange diese im Excel ab.

InputLen = 1

Excel untersucht jedes Zeichen:
Zeichen = ;  ==> nächste Spalte
Zeichen = Z  ==> warte auf Zeilennr.
Zeichen = E  ==> Ende Port schließen

Das HTerminal zeichnet die Daten einwandfrei auf:
Z001;025;026;027;028;039:030;
Z002;025;026;027;028;039:030;
Z003;025;026;027;028;039:030;
Z004;025;026;027;028;039:030;E

Mein Problem ist, dass Excel in manchen Feldern nach dem Wert ein 
Symbol (kleines Quadrat) anhängt. Da der Wert im Excel 
weiterverwendet wird ist dieser dann unbrauchbar.

Hat jemand eine Idee oder kennt eine Verbesserung???
Gast #1132022
Lesenswert?

Der Fehler ist in Zeile 48 deines Programms...

Das Symbol (kleines Quadrat) bedeutet, dass ein Wert empfangen wurde, zu 
dem es kein Zeichen gibt (z.B. Steuerzeichen).

Erster Tip: Überprüfe mal deine Baudraten. Insbesondere die Fehlerquote 
vom µC (Taktfrequenz, Quarz ja/nein, ...)
#1132481
Lesenswert?

Der Fehler beträgt 0,2%. (8Mhz ---> 9600Baud)

Habe herausgefunden, wenn ich nach einem gesendten Zeichen ein 
delay_ms(5) mache, dann ignoriert Excel das Zeichen.

Benutze folgende Einstellung im MSCOMM:

AutoLoad       1
DTREnable      True
EOFEnable      True
Handshaking    0
InBufferSize   1024
InputLen       1
InputMode      0
NullDiscard    False
ParrityReplace ?
Placement      2
RThreshold     1
RTSEnable      False
Settings       9600,n,8,1

Ich vermute den Fehler in der MSComm-Einstellung, da es im Terminal nie 
Probleme gibt.
#1132545
Lesenswert?

1
Private Sub MSComm1_OnComm()
2
    Dim zeile As Integer
3
    Dim spalte As Integer
4
    
5
    
6
Select Case MSComm1.CommEvent
7
        Case comOverrun:   MsgBox "Datenverlust! Overrun"
8
        Case comRxOver:    MsgBox "Datenverlust! RxOver"
9
        Case comEvReceive           
10
        
11
            
12
Abfrage:    RxInput = MSComm1.Input
13
           
14
        If RxInput = ";" Then
15
            spalte = Worksheets("Programm").Range("B10").Value + 1
16
            Worksheets("Programm").Range("B10").Value = spalte
17
            Rx = ""
18
            RxInput = ""
19
                
20
        ElseIf RxInput = "Z" Then
21
            Worksheets("Programm").Range("B10").Value = 1
22
                
23
            Rx = ""
24
            RxInput = ""
25
            Rx = MSComm1.Input
26
            Worksheets("Programm").Range("B8").Value = Rx
27
               
28
            RxInput = MSComm1.Input
29
                If RxInput = ";" Then
30
                    Rx = ""
31
                    GoTo Abfrage
32
                End If
33
            Rx = Rx + RxInput
34
            Worksheets("Programm").Range("B8").Value = Rx
35
            RxInput = MSComm1.Input
36
                    If RxInput = ";" Then
37
                    Rx = ""
38
                    GoTo Abfrage
39
                End If
40
            Rx = Rx + RxInput
41
            Worksheets("Programm").Range("B8").Value = Rx
42
                
43
               
44
        ElseIf RxInput = "E" Then
45
            MSComm1.PortOpen = False
46
            MsgBox ("Übertragung erfolgreich beendet!")
47
        Else
48
            Rx = Rx + RxInput
49
              
50
            zeile = Worksheets("Programm").Range("B8").Value
51
            spalte = Worksheets("Programm").Range("B10").Value
52
            Worksheets("Messwerte").Cells(zeile + 3, spalte + 1).Value = Rx
53
        End If
54

55
                        
56

57
   End Select
58

59
End Sub

Freue mich über Verbesserungsvorschläge!!!!
Gast #1132679
Lesenswert?

Du hast RThreshold = 1, gesetzt d. h. es wird ein OnComm-Ereignis bei 
eintreffen eines Zeichens ausgelöst.

Im OnComm-Ereignis holst du aber mehrfach Zeichen mit "RxInput = 
MSComm1.Input".

Beim ersten "RxInput = MSComm1.Input" in deiner OnComm-Ereignis-Prozedur 
wird natürlich das Zeichen gelesen, das das Ereignis ausgelöst hat.

Aber du kannst doch gar nicht sicher ein, dass zu den Zeitpunkten der 
weiteren "RxInput = MSComm1.Input" Zuweisungen auch schon weitere 
Zeichen im Eingangspuffer vorhanden sind. Du must vor dem Abholen der 
Zeichen prüfen, ob auch welche da sind und ggfls. warten, bis eines da 
ist. (Dabei ein timeout nicht vergessen, damit dein Programm nicht 
endloos wartet).
Gast #1132823
Lesenswert?

@Burns B.

Entweder du stellst vor jeder "Rx = MSComm1.Input" Zuweisung sicher, 
dass auch mindestens ein Zeichen da ist
1
    While Me.MSComm1.InBufferCount < 0
2
        DoEvents
3
    Wend
4
    Rx = MSComm1.Input

Oder (falls du vorher weisst, wieviele Zeichen kommen) du wartest
am Anfang deiner Ereignisprozedur, bis alle Zeichen da sind
1
    Dim iAnzahlErwarteterZeichen As Integer
2
    :
3
    iAnzahlErwarteterZeichen = 5
4
    While Me.MSComm1.InBufferCount < iAnzahlErwarteterZeichen
5
        DoEvents
6
    Wend
7
    :    
8
    Rx = MSComm1.Input
9
    :
10
    Rx = MSComm1.Input
11
    :
12
    Rx = MSComm1.Input
13
    :
14
    Rx = MSComm1.Input
15
    :
16
    Rx = MSComm1.Input
17
    :
Gast #1132828
Lesenswert?

@Paul P.

Du kannst das MSComm-Steuerelement irgendwo als Komponente hinzufügen. 
Such mal in der Hilfe nach Komponenten. (War jedenfalls unter VB6 noch 
so, mit .NET hab ich nix mehr/noch nichts am Hut).
#1132879
Lesenswert?

Hmm,
Hab jetzt die erste Variante probiert, aber jetzt geht die Variable 
ZEILE von 0 - 9 und fängt wieder bei 0 an.

Könnte es funktionieren, wenn ich RThreshold = 4 setzte und die 
kommenden Daten so ändere, dass immer 4 Zeichen zusammengehören?



Zeile Nr.     Werte Trennzeichen + 3 Ziffen      Ende der Übertragung
Z001           ;100 ;101 ;102 ;103 ;104 ;105        ;EEE

Die Lösung sollte so einfach wie möglich sein.
Gast #1132915
Lesenswert?

Vorschlag, wenn jede Zeile 29 Zeichen hat:
(VB ist schon Jahre her....)
1
Private Sub MSComm1_OnComm()
2
    Dim zeile As Integer
3
    Dim spalte As Integer
4
    
5
    
6
Select Case MSComm1.CommEvent
7
        Case comOverrun:   MsgBox "Datenverlust! Overrun"
8
        Case comRxOver:    MsgBox "Datenverlust! RxOver"
9
        Case comEvReceive           
10
        
11
            
12
Abfrage:    
13

14
        RxInputString = MSComm1.Input
15
          
16
        If RxInputString = "Z" Then
17
          While MSComm1.InBufferCount < 28
18
              DoEvents
19
          Wend
20
          RxInputString = RxInputString & MSComm1.Input 
21

22
          '''' Kompletten String empfangen -> Bitte bearbeiten...
23

24
        ElseIf RxInputString = "E"
25

26
            ' Ende-Kennung
27

28
        ElseIf
29

30
            ' Verwerfen, da mitten in der Übertragung
31

32
        End
33
                       
34

35
End Select
36

37
End Sub
#1133874
Lesenswert?

Funktioniert nur, wenn ich DoEvents in die While-Schleife weglasse.
Ansonsten bekomme ich einen BLUESCREEN (verwende RS232-Converter).

Nun hab ich folgendes Problem:
Wenn z.B. der Mikrocontroller die Zeile nicht vollständig ausgibt, oder 
während der Übertragung das Kabel ausgesteckt wird, wartet Excel (und 
hängt sich auf).
Da hilft mir das Timeout auch nicht weiter.
???


Da alle Werte sehr wichtig sind, werde ich ein Zeichen an dem MC 
zurücksenden, wenn eine Zeile erfolgreich Übertragen wurde. Danach 
können die Werte aus dem EEPROM gelöscht werden.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren