Forum: PC-Programmierung C++ RS232 Timeout-Problem ?


von michael (Gast)


Lesenswert?

Hallo,

ich habe ein kleines Problem mit dieser RS232-Lib: 
http://www.teuniz.net/RS-232/index.html

Ich sende mit einem RS232-USB-Dongle zum Arduino Uno und von dort geht 
es parallel in einen Homecomputer (Commodore Plus/4). Das funktioniert 
einwandfrei mit Linux "cat".
Das zu sendende Programm wird in ein Array geladen und dieses dann um 
einige Parameter für den Empfänger erweitert. Danach wird gesendet:

   filename ="sendarray.prg";
   datei = fopen(filename, "wb");
   fwrite(buffer2, sendsize+1, 1, datei);
   fclose(datei);
   system ("cat sendarray.prg >/dev/ttyUSB0");
   system ("rm sendarray.prg");

Das funktioniert soweit einwandfrei. Ich hätte aber gern die 
RS232-Funktionen im Programm integriert. Also hatte ich die oben 
genannte RS232-Lib verwendet und dieser Code macht Probleme:

/* Transfer */
        RS232_OpenComport(xport,baudrate,mode);
        RS232_SendBuf(xport,buffer2,sendsize+1);
        RS232_CloseComport(xport);

Da stirbt die Verbindung immer wieder nach genau 4608 Bytes ab. Davor 
wird immer alles einwandfrei übertragen.

Gibt es vielleicht irgendeine Kleinigkeit, die ich übersehen habe ?

Gruß
Michael

von Peter II (Gast)


Lesenswert?

michael schrieb:
> RS232_OpenComport(xport,baudrate,mode);
>         RS232_SendBuf(xport,buffer2,sendsize+1);
>         RS232_CloseComport(xport);
>
> Da stirbt die Verbindung immer wieder nach genau 4608 Bytes ab. Davor
> wird immer alles einwandfrei übertragen.
>
> Gibt es vielleicht irgendeine Kleinigkeit, die ich übersehen habe ?

ich kenne die Lib nicht, ich würde mal vor dem Close warten, denn 
RS232_SendBuf wird nicht so lange warten bis alles übertragen wurde.


Man braucht für RS232 eigentlich gar keine lib, ich würde es ohne machen 
dann kannst du die lib als Fehlerquelle ausschließen.

von michael (Gast)


Lesenswert?

Dank für den Hinweis, es brachte aber leider keine Besserung. Ich habe 
jetzt einen kleinen Workaround:

        RS232_OpenComport(xport,baudrate,mode);
         for(i=0; i<=sendsize+1; i++)
          {
            RS232_SendByte (xport,buffer2[i]);
            usleep(1);
          }
        RS232_CloseComport(xport);

Das Senden einzelner Bytes funktioniert so.

Ich vermute einen Rückstau im USB-RS232-Dongle, der dann beim 
Pufferüberlauf das Senden einstellt.

von Peter II (Gast)


Lesenswert?

michael schrieb:
> Ich vermute einen Rückstau im USB-RS232-Dongle, der dann beim
> Pufferüberlauf das Senden einstellt.

nein, das funktioniert eigentlich ordentlich. Sonst würde es mit dem cat 
auch nicht funktionieren.

Der fehler ist entweder ein der Lib oder bei der Verwendung der Lib.

von A. S. (Gast)


Lesenswert?

Warum eigentlich einmal sendsize plus eins und nun plus zwei?

Wieviel Bytes fehlen am Ende?

Zur Probe nur z.b. 3000bytes in Blöcken versenden und mit dem nächsten 
erstmal warten?

von michael (Gast)


Lesenswert?

Ist eigentlich immer sendsize+1. Das Programm im Array wird auf volle 
Blocks (256 Bytes bei Commodore) aufgefüllt, damit die Empfangsroutine 
kurz gehalten werden kann.

Auf der Seite des alten Homecomputers mit 6502-Assembler:

loadprg:           lda porta                ; get byte
                   sta (t_lo),y             ; save
                   lda #$40
                   sta portc                ; set ack (pc6)
                   asl
                   sta portc                ; and delete ack
-                  lda portc
                   cmp #$80                 ; wait for dav (pc7)
                   bne -
                   iny
                   bne loadprg              ; get 256 bytes
                   inx
                   cpx blocks               ; blocks reached
                   beq eot
                   inc t_hi                 ; inc hi-addr
                   bne loadprg

Wenn die vollen Blocks empfangen wurden, braucht es einen Schubs (1 
Byte), damit das Y-Register auf 1 springt und das Programm verlassen 
wird. Zwischen PC und Homecomputer ist dann ein Arduino-Klon, der RS232 
empfängt, um dann parallel mit zwei Steuerleitungen durchzureichen.
Kommt dann hier an: 
http://www.zimmers.net/anonftp/pub/cbm/schematics/drives/new/1551/paddle-251925.png 
. Ist das Interface der alten Floppy 1551, eigentlich nur eine 
Adresskodierung mit I/O-Chip.


Ich habe es jetzt so erst mal gelöst:

        RS232_OpenComport(xport,baudrate,mode);

         for(i=0; i<=sendsize+1; i++)
          {
            RS232_SendByte (xport,buffer2[i]);

             if (i <= sendsize+1) {

                                   printf("\r# Progress: %i", i); 
printf(" Bytes");
                                   fflush(stdout);
                                  }

             usleep(1);
          }


        RS232_CloseComport(xport);
        printf("\n");

Wenn man "usleep(1)" herausnimmt, springt die Progress-Anzeige sofort 
auf die zu erreichende Byte-Anzahl. Mit der Verzögerung werden dem 
USB-Dongle alle Bytes passend verbimmelt.

Hier ist auch der ganze Source: 
http://www.cbmhardware.de/show.php?r=10&id=16 Geht sicher eleganter, 
aber ich programmiere recht selten mit C(++).

Aber Dank für die Hilfe ! - Ich trage mal alles auf meiner Website 
zusammen. Da wird es in Zukunft sicher noch Änderungen geben, wenn die 
Retro-Computing Szene sich damit auch beschäftigt.

von michael (Gast)


Lesenswert?

Achim S. schrieb:
> Wieviel Bytes fehlen am Ende?
>

Gesamt waren es 6361 Byte von denen 4608 ankamen. Es fehlten also 1753. 
Bei anderen Werten kamen aber auch immer wieder 4608 Bytes an.


> Zur Probe nur z.b. 3000bytes in Blöcken versenden und mit dem nächsten
> erstmal warten?

Ich belasse es erst mal so wie vorher beschrieben. Das läuft stabil und 
flott. Auf feste Baudraten bin ich eigentlich nicht angewiesen.

von A. S. (Gast)


Lesenswert?

michael schrieb:
> Ist eigentlich immer sendsize+1.

nur zur Info, falls es irgendwann damit ein Problem gibt: hier sind es + 
2 Durchläufe.

michael schrieb:
> for(i=0; i<=sendsize+1; i++)

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.