Forum: PC-Programmierung mscomm macht Fehler


von Burns B. (fox1707)


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???

von ahnungslos (Gast)


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, ...)

von Burns B. (fox1707)


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.

von kosti (Gast)


Lesenswert?

würdest du dein Macro hier reinstellen?

von Burns B. (fox1707)


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!!!!

von ahnungslos (Gast)


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).

von Burns B. (fox1707)


Lesenswert?

AHA!

Das heißt, ich kann in einem OnComm Ereignis keine weitere Zeichen 
lesen?!?

Wie kann ich nun prüfen ob weitere Zeichen vorhanden sind?

Oder bietet sich eine ganz andere Lösung an?

von Paul P. (dorpreuss)


Lesenswert?

Hallo,

das gehört zwar nur bedingt hier hin, aber ich habe auch ein kleines 
Problem zum Thema.

Ich habe Visiual Studio.net 2003 installiert und MS Excel 2003. Ich habe 
aber diese mscomm.dll nicht. Wo finde ich die, oder ist die da gar nicht 
dabei?

Vielen Dank

Paul

von ahnungslos (Gast)


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
    :

von ahnungslos (Gast)


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).

von Burns B. (fox1707)


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.

von ahnungslos (Gast)


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

von Burns B. (fox1707)


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.

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.