Guten Tag liebe Gemeinde,
bzgl. der Auslesung von Zählern:
brauch ich mal Hilfe mit meinem Code. Ein neuer Thread deshalb weil ich hier speziell Hilfe von Perl-Kennern suche die sich mit Device::Serial auskennen.
Der Code soll erstmal nur den Zähler Abfragen, ohne parsing. Es geht mir darum erstmal die Geschwindigkeit zu ändern, dann kann man da weiter aufsetzen.
Vielen Dank schonmal an alle die sich bemühen und helfen können.
Die Kernfrage: Wie wechsele ich in Perl die Geschwindigkeit eines seriellen Ports?
Der Zähler wechselt auf jeden Fall mit dem entsprechenden Telegramm die richtige Geschwindigkeit, nur mein Port gibt nur was aus wenn er auf 300 baud steht. Kommen die Daten schneller kommen dann eben nur noch kryptische Zeichen an.
bzgl. der Auslesung von Zählern:
brauch ich mal Hilfe mit meinem Code. Ein neuer Thread deshalb weil ich hier speziell Hilfe von Perl-Kennern suche die sich mit Device::Serial auskennen.
Der Code soll erstmal nur den Zähler Abfragen, ohne parsing. Es geht mir darum erstmal die Geschwindigkeit zu ändern, dann kann man da weiter aufsetzen.
Vielen Dank schonmal an alle die sich bemühen und helfen können.
Die Kernfrage: Wie wechsele ich in Perl die Geschwindigkeit eines seriellen Ports?
Code:
#!/usr/bin/perl # # (m)ein Stromz0hler mit IR-Schnittstelle blubbert nach einem "Anforderung- # telegramm" Daten raus. Das Telegramm ist mit 300 Baud, 7 Bit, 1 Stoppbit # und gerader Parit0t zu senden. Das ist der Initialmodus von Ger0ten, # die das Protokoll IEC 62056-21 implementieren. # # Autor: Andreas Schulze # Bugfix: Eric Schanze # Datum: 20120302 # use warnings; use strict; use Device::SerialPort; use RRDs; ### KONFIGURATION ### my $device="/dev/ttyUSB-2-4.1"; #Port my $conf4800="/var/tmp/conf4800"; #Konfigurationsdatei my $endsign="!"; #Letztes Zeichen im Protokoll vom Zähler my $data="2f3f210d0a"; #Anfrage als HEX "/?!<CR><LF>" my $request = pack('H*',$data); my $ga = "0/0/4"; my $data2="063034300d0a"; #ACK und neue Geschwindigkeit in HEX "<ACK>040<CR><LF>" my $baudwechsel = pack('H*',$data2); ### Seriellen Port initialisieren ####4800baud my $port = new Device::SerialPort($device) || die "can't open $device: $!"; $port->baudrate(4800) || die 'fail setting baudrate'; $port->databits(7) || die 'fail setting databits'; $port->stopbits(1) || die 'fail setting stopbits'; $port->parity("even") || die 'fail setting parity'; $port->rts_active(1); $port->dtr_active(1); $port->read_char_time(500); # 0.5 seconds for each character $port->read_const_time(1000); # 1 second per unfulfilled "read" call $port->write_settings || die 'fail write settings'; $port->save($conf4800) || warn "Can't save $conf4800: $!\n"; ####START 300baud $port->baudrate(300) || die 'fail setting baudrate'; $port->databits(7) || die 'fail setting databits'; $port->stopbits(1) || die 'fail setting stopbits'; $port->parity("even") || die 'fail setting parity'; $port->dtr_active(1); $port->rts_active(1); $port->read_char_time(500); # 0.5 seconds for each character $port->read_const_time(1000); # 1 second per unfulfilled "read" call $port->write_settings || die 'fail write settings'; ### Anforderungstelegramm senden my $num_out = $port->write($request); print $request; die "write failed\n" unless ($num_out); die "write inclomplete\n" unless ($num_out == length($request)); print "$num_out Bytes written\n"; ### Warte auf Zählerkennung sleep (2); ### Telegram mit ACK und neuer Geschwindigkeit senden my $num_out2 = $port->write($baudwechsel); print $baudwechsel; die "write failed\n" unless ($num_out2); die "write inclomplete\n" unless ($num_out2 == length($baudwechsel)); print "$num_out2 Bytes written\n"; ### Port mit neuer Geschwindigkeit intialisieren $port->restart($conf4800) || warn "Can't restart $conf4800: $!\n"; ; #$port->baudrate(300); #$port->write_settings; ### AUSLESEN my $STALL_DEFAULT=5; # how many seconds to wait for new input my $timeout=$STALL_DEFAULT; my $chars=0; my $buffer=""; while ($timeout>0) { my ($count,$saw)=$port->read(25); # Liest 25 Zeichen je Durchlauf aus if ($count > 0) { $chars+=$count; $buffer.=$saw; print ($buffer,"\n"); # Ausgabe der eingelesenen Daten ### FILTER FOR END if ($buffer =~ /\Q$endsign\E/) # \Q \E entwertet alle Sonderzeichen dazwischen { $port->close || die "can't close $device: $!"; # Port schlieflen last; # Schleife verlassen } ### ENDE FILTER FOR END } else { $timeout--; } } if ($timeout<=0) { $port->close || die "can't close $device: $!"; print "Waited $STALL_DEFAULT seconds and never saw what I wanted\n"; }
Kommentar