Schrift
[thread]6498[/thread]

Schwierigkeiten mit serieller Schnittstelle: Benutzen von Win32::SerialPort

Leser: 1


<< >> 4 Einträge, 1 Seite
Gast Gast
 2004-08-14 10:12
#49291 #49291
Ich habe in Perl ein kleines Script geschrieben, das (unter Windows) eine Serielle Schnittstelle öffnet, Einen Befehl in die Schnittstelle schreibt, und dann ein paar Zeichen wieder Ausliest.

Das komische daran ist jedoch, dass das manchmal klappt, manchmal auch nicht.

Ich glaube nicht, dass das an der Hardware oder an Windows liegt, da ich das schon auf zwei verschiedenen Rechnern ausprobiert habe (einmal win 2000, einmal XP).

Hier das Script:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!perl -w

use strict;
use Win32::SerialPort;

my ($count, $result);
$count = 0;
$result = "#";

my $pruefling = new Win32::SerialPort ("COM1") || die "Konnte den Port für den Prüfling nicht öffnen!";


print "Port ist nun geöffnet!\n";
$pruefling->user_msg("ON");
$pruefling->databits(8);
$pruefling->baudrate(1200);
$pruefling->parity("none");
$pruefling->stopbits(1);
$pruefling->handshake("none");
$pruefling->write_settings || undef $pruefling;


print "Einrichten fertig!\n";

$pruefling->read_interval(300); # Zeit Zwischen einzelnen Zeichen, bei Überschreitung Abbruch
$pruefling->read_const_time(1000); # Maximale Gesamtzeit zum Einlesen von Zeichen, dann Abbruch
$pruefling->write("#036\r");

($count, $result) = $pruefling->read(80); # Entweder 80 Zeichen einlesen, oder Zeitaus
print "count = $count, result = $result\n";


undef $pruefling;



Hat jemand eine Idee was man an diesem Script verbessern könnte?


Bearbeitet von Crian: CODE-Tags ergänzt\n\n

<!--EDIT|Crian|1092491775-->
Crian
 2004-08-14 17:58
#49292 #49292
User since
2003-08-04
5871 Artikel
ModeratorIn
[Homepage]
user image
Hallo Josef,

herzlich willkommen im Forum. leider kann ich zu Deinem Problem nichts sagen, da ich das Modul nicht kenne, aber da wird sich bestimmt noch jemand anders zu äußern können. Ich habe Deinem Posting mal CODE-Tags spendiert, dadurch steht Dein Quelltext jetzt in einem eigenen Kasten, in diesem ist er in einer anti-proportional-Schrift dargestellt und es werden nicht aus Versehen Smilies aus dem Code erzeugt.

so wie in

Code: (dl )
(1, 2, 3, 4, 5, 6, 7, 8)


versus

(1, 2, 3, 4, 5, 6, 7, 8)\n\n

<!--EDIT|Crian|1092492009-->
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
renee
 2004-08-14 18:24
#49293 #49293
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Hast Du mal versucht, genauere Fehlermeldungen zu bekommen??

Ein einfaches "Es klappt nicht!" ist nicht wirklich aussagekräftig. Geb mal $! aus (zusätzlich zu die "Konnte den Port für den Prüfling nicht öffnen!" ). Dann kommen wir dem Problem vielleicht auch schneller auf die Schliche...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
steffenw
 2004-08-15 00:38
#49294 #49294
User since
2003-08-15
692 Artikel
BenutzerIn
[Homepage] [default_avatar]
So läuft's bei mir. Ich muß aber auch nur senden. Es war eine schwere Geburt. Deswegen habe ich auch die Fehlermeldungen so detailliert gemacht, daß ich noch 'nen Durchblick habe, was da wirklich passiert.
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use Win32API::CommPort qw(:PARAM :STAT 0.19);
use Win32::SerialPort;

my $comm_port = 'COM1';

# serielle Schnittstelle initialisieren
my $serial_port = new Win32::SerialPort($comm_port) or do
{ log_write error => qq~Kann "$comm_port" nicht öffnen.~;
 exit;
};
$serial_port->handshake('rts');
$serial_port->baudrate(9600);
$serial_port->databits(7);
$serial_port->parity('even');
$serial_port->parity_enable(1);   # Paritätsprüfung einschalten
$serial_port->stopbits(2);
$serial_port->buffers(4096, 4096);
$serial_port->error_char(0xff);   # zum Paritätsfehler erkennen
$serial_port->write_settings or do
{ log_write error => qq~Kann Settingdaten nicht zu "$comm_port" schreiben.~;
 exit;
};

# alle Puffer löschen
$serial_port->purge_all;
$serial_port->reset_error;
# Portstatus
for (@nc_prog)   # NC-Programme übertrage ich da
{ # Zeilenende formatieren
 s/\n/\x0D\x0A\x0D/g;
 my $start = time;
 while (length $_)
 { my ($blocking_flags, $in_bytes, $out_bytes, $latch_error_flags) = $serial_port->status
   or do
   { log_write error => qq~Portstatus "Status von $comm_port" konnte nicht gelesen werden.~;
     exit;
   };
   if (time > $start + TIMEOUT_COM_T)
   { # Timeout
     $blocking_flags & BM_fCtsHold and return qq~"$comm_port" blockiert: wartet wegen CTS.~;
     $blocking_flags & BM_fDsrHold and return qq~"$comm_port" blockiert: wartet wegen DSR.~;
     $blocking_flags & BM_fRlsdHold and return qq~"$comm_port" blockiert: wartet wegen Rlsd.~;
     $blocking_flags & BM_fXoffHold and return qq~"$comm_port" blockiert: wartet wegen Xoff.~;
     $blocking_flags & BM_fXoffSent and return qq~"$comm_port" blockiert: Xoff gesendet.~;
     $blocking_flags & BM_fEof and return qq~"$comm_port" blockiert: Eof.~;
     $blocking_flags & BM_fTxim and return qq~"$comm_port" blockiert: Txim.~;
     $blocking_flags and return qq~"$comm_port" blockiert.~;
     return "Konnte Daten nicht innerhalb von @{[TIMEOUT_COM_T]} s zur Maschine senden.";
   }
   $latch_error_flags & CE_RXOVER and return qq~RXOVER-Fehler: "$comm_port".~;
   $latch_error_flags & CE_OVERRUN and return qq~OVERRUN-Fehler: "$comm_port".~;
   $latch_error_flags & CE_TXFULL and return qq~TXFULL-Fehler: "$comm_port".~;
   $latch_error_flags & CE_MODE and return qq~MODE-Fehler: "$comm_port".~;
   $latch_error_flags & CE_RXPARITY and return qq~Paritäts-Fehler: "$comm_port".~;
   $latch_error_flags & CE_FRAME and return qq~Frame-Fehler: "$comm_port".~;
   $latch_error_flags & CE_BREAK and return qq~Break-Fehler: "$comm_port".~;
   $latch_error_flags and return qq~Übertragungsfehler: "$comm_port".~;
   # Timeoutzeit verstreichen lassen
   redo if $blocking_flags;
   # Daten senden und gesendete Anzahl abschneiden
   substr $_, 0, $serial_port->write($_), '';
 }
}

Ich denke mal, wenn es mal geht und mal nicht, liegt es vielleicht daran, daß irgendwelche Zeichen im Puffer liegen und Du so durcheinander kommst. Das passiert meist auch dann, wenn irgendwann ein BREAK erkannt wurde. Es könnte sein, daß Dir die Zeilen
Code: (dl )
1
2
3
# alle Puffer löschen
$serial_port->purge_all;
$serial_port->reset_error;
dann schon helfen.\n\n

<!--EDIT|steffenw|1092516678-->
$SIG{USER} = sub {love 'Perl' or die};
<< >> 4 Einträge, 1 Seite



View all threads created 2004-08-14 10:12.