Zitat: |
Hallo Hr.
Horter,
Das Programm funktioniert so unter
Windows und Linux.
Die Haupt-Ursache warum es Anfangs nicht so recht
funktioniert hat war ein nicht eingestellter
Timeout-Parameter.
Unter Linux kommt das Write-Kommando quasi sofort zurück (write
background), das nachfolgende Read wird per default auch
sofort ausgeführt.
Im Prinzip wird so gelesen, obwohl der write noch nicht
fertig war. Nun, so schnell kann der PIC auch nicht
reagieren.
Deshalb hat es auch mit der 20ms-Pause funktioniert. Der
entscheidende "read_const_time"-Parameter muss (auf meinem
System) auf mind. 5ms eingestellt werden.
Eine weitere Verkürzung bringt wieder den gleichen Effekt.
Viele Grüße und schönes Wochenende!
Thomas D.
|
#!/usr/bin/perl #Testprogramm fuer Horter & Kalb I2C-Modem
#(C)2006 Thomas Dressler
use constant false=>0;
useconstant true=>1;
useTime::HiRes qw( usleep ualarm);
if ($#ARGV ==1) {
$PortName=$ARGV[0];
$Adresse=$ARGV[1];
$quiet=0;
$OS=$^O;
if ($OS eq 'MSWin32') {
eval ("use Win32::SerialPort qw { :PARAM :STAT };");
die "$@\n" if ($@);
$PortObj = new Win32::SerialPort ($PortName, $quiet)
|| die "Can't open $PortName: $^E\n";
# $quiet is optional
} else {
eval ("use Device::SerialPort qw { :PARAM :STAT };");
die "$@\n" if ($@);
$PortObj = new Device::SerialPort ($PortName, $quiet)
|| die "Can't open $PortName: $^E\n";
# $quiet is optional
}
$PortObj->databits(8);
$PortObj->baudrate(19200);
$PortObj->parity("none");
$PortObj->stopbits(1);
$PortObj->handshake("none");
$PortObj->datatype('raw'); # in case an application needs_to_know
$PortObj->binary(1);
$PortObj->debug(1);
# prints hardware messages like "Framing Error"
$PortObj->error_msg(1);
# prints function messages like "Waiting for CTS"
$PortObj->user_msg(1);
# wait 1ms for each character
$PortObj->read_char_time(1);
# 15 ms per unfulfilled "read" call (maybe more)
$PortObj->read_const_time(15);
if (! $PortObj->write_settings) {
undef $PortObj;
die "Write Settings failed!\n";
}
#Check Modem
$cmd=chr(16);
$PortObj->write($cmd);
#($BlockingFlags, $InBytes, $OutBytes,
#$LatchErrorFlags) = $PortObj->status;
#print "Status:in-> ".$InBytes . ":out->".$OutBytes.
#":Block->".$BlockingFlags. ":Error->".$LatchErrorFlags. "\n";
#usleep(20000);
$r=$PortObj->read(1);
if ((ord($r)==192)) {
print "I2C-Modem detected\n";
#Get Version
$cmd=chr(80);
$PortObj->write($cmd);
#usleep(20000);
$v1=ord($PortObj->read(1));
$v2=ord($PortObj->read(1));
$version=chr($v1+48).".".chr($v2+48);
print "Version $version\n";
#read LM75
$cmd=chr(128+1);
$PortObj->write($cmd);
$PortObj->write(chr($Adresse+1));
#usleep(20000);
$r=$PortObj->read(1);
if ((ord($r)==192)) {
$v1=ord($PortObj->read(1));
$v2=ord($PortObj->read(1));
if (($v1 & 128) == 0) {
$T = $v1;
}else{
$T = $v1 - 255;
}
if (($v2 & 128) == 128) {
$T = $T + 0.5;
}
print "Temperatur ".sprintf("%4.1f",$T)."°C\n^";
} else {
print "Error,Modem Code is:".ord($r)."\n";
}
}else {
print "I2C-Modem not detected:".ord($r)."\n";
}
$PortObj->close;
}else{
print "Usage: perl testmodem.pl \n";
print "Windows: perl testmodem.pl 'COM1' 144\n";
print "Unix: perl testmodem.pl '/dev/ttyS0' 144\n";
}
Perl-Quellcode für das I2C-RS232-Modem |
|
perl-i2c-modem-test.pl (3 kB)
Perl-Quellcode mit einem Beispiel, wie das I2C-Modem
angesprochen werden kann.
(Bitte mit der rechten Maustaste "speichern unter" wählen! ) |
|
perl_tests.zip (10 kB)
Hier ein
Beispiel für den LM75 in Perl. Die Bibliotheken sind so
gebaut, dass sich
beliebige andere Geräte damit programmieren lassen. Insofern
ist nur die LM75-Funktionalität ein Beispiel der Anwendung.
Die Perlscripte laufen unverändert auch unter Linux und
sollten genauso auf anderen Unix-Maschinen laufen, wo sich
das Device "Serialport" Modul von Perl installieren lässt.
Für Windows heißt das Modul Win32:.Serialport, welches
zusätzlich installiert werden muss." (Autor: Thomas D.) |
|