Jörg B. misst mit dem I2C-Koppler und der I2C-Analogkarte die Temperatur seiner Solaranlage und schreibt diese grafisch mit. Als Messfühler verwendet er Platin-Heißleiter vom Heizungsbauer und berechnet aus der Kennlinie des NTC die Spannungen bzw. die Analogwerte.
#!/usr/bin/perl -w
###################################################
# I2C über I2C-RS232 Koppler von horter.de
# Jörg Brune joergbrune.de
###################################################
use constant false=>0;
use constant true=>1;
$PortName="COM1"; # verwendete serielle Schnittstelle
$t_bps=1000; # Bits pro Sekunde
$debug=false; # true/false true: Busverkehr anzeigen
print "Content-Type: text/html\n\n";
print "<htm><head><title>i2c test</title></head><body bgcolor=cornsilk>";
use Time::HiRes qw(usleep);
use Win32::SerialPort; # Linux Device::SerialPort
# SerialPort gibts hier: http://www.bribes.org/perl/ppm/
$t_bt=1000000/$t_bps/4;
$startdelay=20;
## port öffnen
$quiet=0;
$PortObj = new Win32::SerialPort ($PortName, $quiet)
|| die "kann $PortName: $^E nicht öffnen\n";
sub i2cout
{ $cl=shift;$dt=shift;
$PortObj->dtr_active($dt);$PortObj->rts_active($cl);
usleep $t_bt; }
sub i2cstart
{ if($debug){print "<br><font size=2><> 76543120 ack dez<br>";} ##
for($i = 1; $i <= $startdelay; $i++) { i2cout(1,1); }
i2cout(1,1);i2cout(1,0);i2cout(1,0);i2cout(0,0); }
sub i2cstop ##stopbit schreiben
{ i2cout(0,0);i2cout(1,0);i2cout(1,0);i2cout(1,1);
for($i = 1; $i <= $startdelay; $i++) { i2cout(1,1); } }
sub i2cwt ## bit schreiben
{ $bit=shift;
i2cout(0,$bit);i2cout(1,$bit);i2cout(1,$bit);i2cout(0,$bit); }
sub i2crb
{ i2cout(0,1);i2cout(1,1);
$r = $PortObj->modemlines & 32; ## ist 32 richtig? oder 16?
if($r>0){$r=1;}
i2cout(1,1);i2cout(0,1);
return($r);}
sub ic2_wb ## byte schreiben
{ $by=shift; $by0=$by;
if($debug){print "-> ";} ##
for($i=1;$i<=8;$i++)
{ $bt=0;if(($by & 128)>0){$bt=1;}
$by=($by << 1);
i2cwt($bt);
if($debug){print "$bt";} ##
}
$ack=i2crb();
if($debug){print " $ack $by0<br>"}; ##
return($ack); }
sub ic2_rb ## byte lesen
{ $by=0;
if($debug){print "<- ";} ##
for($i=1;$i<=8;$i++)
{ $bt=i2crb();
$by=($by << 1)+$bt;
if($debug){print "$bt";} ##
}
$ack=i2crb();
if($debug){print " $ack $by<br>";} ##
return($by); }
##############################
# Funktionen für I2C Bausteine
sub pcf8574wt
{ $adr=shift;$dat=shift;
i2cstart();
$err=-ic2_wb(64+$adr+$adr);
$err=-ic2_wb($dat)+2*$err;
i2cstop();
return($err);}
sub pcf8574rd
{ $adr=shift;
i2cstart();
ic2_wb(64+$adr+$adr);
ic2_wb(255);
i2cstop();
i2cstart();
ic2_wb(65+$adr+$adr);
$dat=ic2_rb();
i2cstop();
return($dat); }
sub pcf8591rd
{ $adr=shift;$ain=shift;
i2cstart();
ic2_wb(144+$adr+$adr);
ic2_wb($ain);
i2cstop();
i2cstart();
ic2_wb(144+$adr+$adr+1);
$dat=ic2_rb();
i2cstop();
i2cstart();
ic2_wb(144+$adr+$adr+1);
$dat=ic2_rb();
i2cstop();
return($dat); }
sub pcf8591wt
{ $adr=shift;$dat=shift;
i2cstart();
ic2_wb(144+$adr+$adr);
$err=-ic2_wb(64);
$err=-ic2_wb($dat)+2*$err;
i2cstop();
return($err); }
############################################
## beispiel für pcf8574
# schreiben
$res=pcf8574wt(0,254); # a:0-7, out:0-255
# lesen
$res=pcf8574rd(0); # a:0-7
print " ....$res<br><br>";
## beispiel für pcf8591
# lesen
$res=pcf8591rd(0,0); # a:0-7, in:0-3
print " ....$res<br><br>";
# schreiben
$res=pcf8591wt(0,20); # a:0-7, out:0-255
print " ....$res<br><br>";
print "</body></html>\n";