Thread Lesen von serieller Schnittstelle: Events unter Win nutzen (1 answers)
Opened by Hellmaker at 2005-09-23 13:23

Hellmaker
 2005-09-23 13:23
#58378 #58378
User since
2005-08-05
16 Artikel
BenutzerIn
[default_avatar]
Hallo liebe Perl Gemeinde,

mein Problem ist eigentlich ganz schnell genannt: Ich kann auf die serielle Schnittstelle schreiben (Funkmodul, Daten kommen auch wunderbar auf der anderen Seite an), aber lesen klappt einfach mal garnicht! :(

Erklärt ist es leider nicht so einfach:
Das schreiben klappt mit verschiedenen Modulen (z.B. Win32API::CommPort, Win32::API) und verschiedenen Funktionen (z.B. $PortObj->write() oder WriteFile() der kernel32.dll).
Der Code für das Schreiben sieht dann z.B. so aus:
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
64
65
use strict;
require 5.003;
use Win32API::CommPort;
use Win32::SerialPort qw( :STAT 0.19);
use Win32;

my $quiet = 1; # Einschränkung bei Fehlermeldung
my $PortName = 'COM3';
my $configFile = 'ER400TRS.cfg';

my $PortObj = new Win32::SerialPort( $PortName, $quiet )
   or die "Can't open $PortName: $^E\n";

## initialize
$PortObj->user_msg( 'ON' );
$PortObj->baudrate( 19200 );
$PortObj->databits( 8 );
$PortObj->parity( "none" );
$PortObj->stopbits( 1 );

$PortObj->handshake( "none" );
my @ar=$PortObj->buffers( 128, 128 ); ## read buffer, write buffer

## write settings to com port
$PortObj->write_settings or undef $PortObj;
unless( $PortObj ){ print "can't change device control block: $^E\n"; }
## save settings in configuration file
$PortObj->save( $configFile ) or warn "can't save $configFile: $^E\n";

## close all stuff
$PortObj->close or die "failed to close";
undef $PortObj; ## frees memory back to perl

## open again with tie (needed for some functions)
$PortObj = tie( *COMFH, 'Win32::SerialPort', $configFile )
or die "can't tie using $configFile: ^E\n";

### ready to communicate
##get current status

my $BlockingFlags;
my ( $InBytes, $OutBytes, $LatchErrorFlags );
( $BlockingFlags, $InBytes, $OutBytes, $LatchErrorFlags ) = $PortObj->status
       || warn "could not get port status\n";

if ( $BlockingFlags ) { warn "Port is blocked"; }
if ( $BlockingFlags & BM_fCtsHold ) { warn "Waiting for CTS (clear to send)"; }
if ( $LatchErrorFlags & CE_FRAME ) { warn "Framing Error"; }


#######write to serial port###################
my ( $count_out, $output_string );
$output_string = "Hallo ";

my $i = 10;
while( $i > 0 ) {
  $count_out = $PortObj->write( $output_string );
  warn "write failed\n"         unless ( $count_out );
  warn "write incomplete\n"     if ( $count_out != length( $output_string ) );
  $i--;
}

## close all stuff
$PortObj->close or die "failed to close";
undef $PortObj; ## frees memory back to perl

bis zum eigentlich write-Abschnitt werden einige Werte gesetzt und überprüft (möglich, dass sich hier schon Fehler eingeschlichen haben). Diese Initialisierungssequenz gilt auch für die entsprechende read-Anweisung.

Für das Lesen von der seriellen Schnittstelle gibts in den einzelnen Modulen/dlls natürlich auch jede Menge Funktionen, wie read() oder ReadFile. Das entsprechende read()-Beispiel zum oberen write()-File sieht dann folgendermaßen aus (Init. und close() hier weggelassen):
Code: (dl )
1
2
3
4
5
6
## read
$InBytes = 1;
my ( $count_in, $string_in );
( $count_in, $string_in ) = $PortObj->read( $InBytes );
print "count: $count_in\nin: $string_in\n";
warn "read unsuccessful\n" unless ( $count_in == $InBytes );


Wie schon gesagt funktioniert das leider nicht. Auch die anderen Read-Funktionen, der unterschiedlichen Module bringen keine Ergebnisse. write und read Funktionen werden in einem Beispiel auch nur aus dem selben Modul verwendet, kein MischMasch!
Ich denke ich muss vor dem lesen bestimmte Event-Flags abwarten, wie z.B InputBuffer80%Full.
Leider habe ich da keine Beispiele gefunden, die das Auslesen der seriellen Schnittstelle oder das Nutzen der Events in diesem Zusammenhang behandlen oder gar gut dokumentieren.

Hat das schon mal jemand gemacht?! Wie nutz ich die Flags, wie kann ich die Schnittstelle auslesen, damit ich auch wirklichen das Zeichen reinkrieg, welches gerade an der Schnittstelle aufläuft?

View full thread Lesen von serieller Schnittstelle: Events unter Win nutzen