Forum: Mikrocontroller und Digitale Elektronik Riesenproblem mit Datenübertragung, Betriebsblind?


von Jens P. (Gast)


Lesenswert?

Hallo Leute,

ich sitze seit einer halben Ewigkeit an einer Datenübertragung vom PC 
zum Controller.

Es geht um 127 Presets mit je 16 Zeichen Namensstring und 16 
Relaiszuständen.

Wenn ich vom Rechner an den Controller Sende und das danach auslese habe 
ich nur Schrott drinstehen.

Wenn ich Presets direkt am Gerät bearbeite und dass dann auf den rechner 
lade passt die Sache.

Ich wäre sehr froh, wenn jemand da mal drüberschauen könnte, nach 8 
Stunden an der selben sch'#@e bin ich wohl so langsam Betriebsblind.

Sendecode (vb.net):
1
 Private Sub BwSend_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BwSend.DoWork
2
        Com.Write("S") ' Sende!, Pipe als delimiter
3
        Do
4
        Loop Until Com.ReadTo("|") = "A"
5
        For z1 = 1 To 128
6
            ' Es gibt keine Fixlängen-Strings unter .NET, daher Eingabefelder begrenzen und nach rechts mit Leerzeichen auffüllen
7
            Do
8
            Loop Until Com.ReadTo("|") = "A"
9
            ConfigArr(z1, 0) = ConfigArr(z1, 0).PadRight(16, " ")
10
            'MsgBox("|" & ConfigArr(z1, 0).Substring(0, 16) & "|")
11
            For z3 = 0 To 15
12
                ' MsgBox(ConfigArr(z1, 0).Substring(z3, 1))
13
                Com.Write(ConfigArr(z1, 0).Substring(z3, 1))
14
            Next z3
15
            Do
16
            Loop Until Com.ReadTo("|") = "A"
17
            ' MsgBox(ConfigArr(z1, 1) & ConfigArr(z1, 2) & ConfigArr(z1, 3) & ConfigArr(z1, 4) & ConfigArr(z1, 5) & ConfigArr(z1, 6) & ConfigArr(z1, 7) & ConfigArr(z1, 8) & ConfigArr(z1, 9) & ConfigArr(z1, 10) & ConfigArr(z1, 11) & ConfigArr(z1, 12) & ConfigArr(z1, 13) & ConfigArr(z1, 14) & ConfigArr(z1, 15) & ConfigArr(z1, 16))
18
            For z2 = 1 To 16
19
                If ConfigArr(z1, z2).Trim = "1" Then
20
                    Com.Write("1")
21
                Else
22
                    Com.Write("0")
23
                End If
24
            Next z2
25
        Next z1

Code im Controller(relevante Teile):
1
.....
2
         if TempChar="S" then
3
            ReceiveFromComputer()
4
         end if
5
......
6
7
8
sub procedure ReceiveFromComputer
9
            TempChar=0
10
            LCD_OUT(1,1," Receiving Data ")
11
            LCD_OUT(2,1," from Computer  ")
12
            j=0
13
            ct=0
14
            UART_WRITE_TEXT("A|")
15
           ' Zuerst die Presets, erst Name, dann Outputs
16
           for ct= 0 to 127
17
               'Name empfangen
18
               Preset=ct
19
               calc7seg
20
               UART_WRITE_TEXT("A|")
21
               for j = 0 to 15
22
                   WaitForChar(false)
23
                   NewReceive=false
24
                   Presetname[j]=tempchar
25
               next j
26
               Write_PresetName()
27
               j=0
28
               UART_WRITE_TEXT("A|")
29
               for j= 0 to 15
30
                   WaitForChar(false)
31
                   NewReceive=false
32
                   if TempChar="1" then
33
                      Outputs.j=1
34
                   end if
35
                   if TempChar="0" then
36
                      Outputs.j=0
37
                   end if
38
               next j
39
               write_presetrelais()
40
           next ct
41
end sub
42
43
sub procedure WaitForChar(dim Acknowledge as boolean)
44
    do
45
    loop until NewReceive=true
46
    if acknowledge=TRUE then
47
       UART_WRITE_TEXT("A|")
48
    end if
49
end sub
50
51
.... ISR....
52
       if ReceiveMode = 0 then          ' RS232-Empfang
53
          TempChar=receivetemp
54
          NewReceive=true
55
       end if
56
....

Wäre echt Super wenn sich jemand dafür erwärmen könnte mal drüber zu 
schauen. Mir raucht so langsam der Kopf, ich komm und komm nicht weiter.

Gruß,
Jens

von Jens P. (Gast)


Lesenswert?

Achso: Mit den ganzen auskommentierten Messageboxen konnte ich 
feststellen, dass meine Sendewerte soweit stimmen.

von Werner A. (homebrew)


Lesenswert?

Schau doch mit nem Terminalprogramm erstmal nach, obs nen Problem auf 
der Sender- oder Empfängerseite gibt. Dann kannst du an der 
entsprechenden Stelle weitersuchen...

von Purzel H. (hacky)


Lesenswert?

>UART_WRITE_TEXT("A|")
>..
>WaitForChar(false)

Scheint mir blockierender Betrieb zu sein. So wird das nichts. Mach ne 
Zustandsmaschine, die gleichzeitiges Senden und Empfangen zulaesst.

von Jens P. (Gast)


Lesenswert?

gleichzeitiges Senden und Empfangen ist hier (in diesem Modus des 
Programmes) nicht nötig bzw erwünscht.

Es geht immer: Anfordeurng->warten->Acknowledge

Ist zwar hier mit Polling gelöst, aber ist das prinzipiell falsch?

von Purzel H. (hacky)


Lesenswert?

Naja, wenn du gleichzeitig blockierend schreibst...

von MaWin (Gast)


Lesenswert?

> aber ist das prinzipiell falsch?

Ich finde ja.

Ein Programmpaket, welches nur funktioniert, wenn sich beide so gut 
verstehen wie es die eng verzahnten und aufeinander wartenden Prozesse 
für ihre fehlerfreie Abarbeitung verlangen, ist meiner Meinung nach 
komplett lebensuntauglich.

Eine serielle Kommunikation muß
1. damit zurecht kommen, daß nicht die erwarteten Zeichen kommen und 
sich dabei dann resynchronisieren
2. damit zurecht kommen, daß überhaupt kein Zeichen kommt, also einen 
TimeOut besitzen.

Deine Delimiter (immer das A) machen es natürlich besonders schwierig, 
eine fehlerhafte Kommunikation zu erkennen. Es sollten zumindest nicht 
die Buchstaben sein, die wohl auch im Namensfeld erlaubt sind.

Ein loop until NewReceive=true ist doch ein deadlock. Kabel ab Prozessor 
steht.

Die ISR sollte jedes Zeichen entgegennehmen und auf Grund des aktuellen 
Zustandes dorthin verteilen, wo es hingehört, und wenn das Zeichen dort 
nicht hingehört, dann sollte der Zustand auf das geändert werden, wo es 
hingehört, also eine Resynchronisation stattfinden.

von Jens P. (Gast)


Lesenswert?

Gut, vielleicht zur Erklärung warum ich hier den "bequemen" weg nehme:

Dieser Modus des Gerätes dient eigentlich NUR dem übertragen der 
PResets. Im Normalbetrieb wird der UART als MIDI-Schnittstelle benutzt, 
inklusive Statemachine und allem drum und dran.

Ich dachte mir nur "die paar Hundert Bytes sollten doch auch so gehen".

Wenn bei den 10 Sekunden übertragung dann halt mal das Kabel rausrutscht 
steht die Kiste halt, das würde ich in dem Fall als hinnehmbar 
akzeptieren.

von Jens P. (Gast)


Lesenswert?

Nur so als Info für die Nachwelt:

Schuld war natürlich jetzt die pure Dummheit.

Ein einzelnes Zeichen als Delimiter zu verweden mag ja gehen wenn man 
ausschliesslich mit Ascii-Zeichen arbeitet und auf Sonderzeichen 
verzichen kann. In meinem Fall | (Pipe)

Blöd nur wenn mitten im String auch mal beliebige Relais-Setups 
übertragen werden, bei denen sich durchaus auch mal eine Paarung mit dem 
Wert 124 ergeben kann.

Manchmal würde man sich dann gerne selber hauen....

von Hans (Gast)


Lesenswert?

Jens Plappert schrieb:
> Manchmal würde man sich dann gerne selber hauen....

Hallo Jens,

hier kann Dir geholfen werden : http://www.rotelinien.de/

von Jens P. (Gast)


Lesenswert?

Danke Hans, hab da auch was für dich:
http://www.rasputin.de/Humorlos/

von Hans (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Jens,

ich habe den Test auf der von Dir genannten Seite nicht bestanden :(

von Jens P. (Gast)


Lesenswert?

Schade ;-)

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.