mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 06:39:11 +00:00
bd3d1ec7d3
00_RPII2C.pm: =item summary added 51_I2C_BMP180.pm: =item summary added 51_Netzer.pm: =item summary added 51_RPI_GPIO.pm: =item summary added 52_I2C_BME280.pm: =item summary added 52_I2C_EEPROM.pm: =item summary added 52_I2C_MCP23008.pm: =item summary added 52_I2C_MCP23017.pm: =item summary added 52_I2C_MCP342x.pm: =item summary added 52_I2C_PCA9532.pm: =item summary added 52_I2C_PCA9685.pm: =item summary added 52_I2C_PCF8574.pm: =item summary added 52_I2C_SHT21.pm: =item summary added 53_GHoma.pm: =item summary added, Notes for new firmware added git-svn-id: https://svn.fhem.de/fhem/trunk@12059 2b470e98-0d58-463d-a4d8-8e2adae1ed80
454 lines
18 KiB
Perl
454 lines
18 KiB
Perl
##############################################################################
|
|
# $Id$
|
|
# 51_Netzer.pm
|
|
#
|
|
##############################################################################
|
|
# Modul for Netzer access
|
|
#
|
|
#
|
|
#
|
|
##############################################################################
|
|
|
|
package main;
|
|
use strict;
|
|
use warnings;
|
|
use POSIX;
|
|
use Scalar::Util qw(looks_like_number);
|
|
use IO::File;
|
|
|
|
#vorhandene Ports
|
|
my @ports = ( "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m" );
|
|
|
|
sub Netzer_Initialize($) {
|
|
my ($hash) = @_;
|
|
$hash->{DefFn} = "Netzer_Define";
|
|
$hash->{ReadFn} = "Netzer_Read";
|
|
$hash->{GetFn} = "Netzer_Get";
|
|
$hash->{SetFn} = "Netzer_Set";
|
|
$hash->{AttrFn} = "Netzer_Attr";
|
|
$hash->{UndefFn} = "Netzer_Undef";
|
|
$hash->{ExceptFn} = "Netzer_Except";
|
|
$hash->{AttrList} = "poll_interval" .
|
|
" Port_a:in,out,cnt" . " Port_b:in,out,cnt" . " Port_c:in,out,cnt" .
|
|
" Port_d:in,out,PWM" .
|
|
" Port_e:in,out,ADC" . " Port_f:in,out,ADC" .
|
|
" Port_g:in,out" . " Port_h:in,out" . " Port_i:in,out" .
|
|
" Port_j:in,out,PWM" .
|
|
" Port_k:in,out" . " Port_l:in,out" . " Port_m:in,out";
|
|
}
|
|
#############################################
|
|
sub Netzer_Define($$) {
|
|
my ($hash, $def) = @_;
|
|
|
|
my @args = split("[ \t]+", $def);
|
|
my $menge = int(@args);
|
|
if (int(@args) < 2) {
|
|
return "Define: to less arguments. Usage:\n" .
|
|
"define <name> Netzer <Host>:<port>";
|
|
}
|
|
#Pruefen, ob GPIO bereits verwendet
|
|
foreach my $dev (devspec2array("TYPE=$hash->{TYPE}")) {
|
|
if ($args[2] eq InternalVal($dev,"DeviceName","")) {
|
|
return "IP-Address $args[2] already used by $dev";
|
|
}
|
|
}
|
|
my $name = $args[0];
|
|
$hash->{DeviceName} = $args[2];
|
|
Netzer_conn($hash);
|
|
# create default attributes
|
|
#my $msg = CommandAttr(undef, $name . ' direction input');
|
|
#return $msg if ($msg);
|
|
return undef;
|
|
}
|
|
#############################################
|
|
sub Netzer_Get($;$) {
|
|
my (@a) = @_;
|
|
my $hash = $a[0];
|
|
my $name = $hash->{NAME};
|
|
my ($port,$cnt) = split("_", $a[2]) if ( defined($a[2]) );
|
|
my $function = $attr{$name}{"Port_".$port} if defined($port) && defined($attr{$name}{"Port_".$port});
|
|
my $buf = "";
|
|
if ( !( defined($a[2]) ) ) {
|
|
foreach (@ports) {
|
|
if(defined($attr{$name}) && defined($attr{$name}{"Port_".$_})) {
|
|
my $function = $attr{$name}{"Port_".$_};
|
|
if ($function =~ m/^(PWM|ADC)$/i) {
|
|
$buf = $_."=?\r\n";
|
|
Netzer_send($hash, $buf);
|
|
} elsif ($function =~ m/^(cnt)$/i) {
|
|
$buf = "z".$_."=?\r\n";
|
|
Netzer_send($hash, $buf);
|
|
}
|
|
}
|
|
}
|
|
$buf = "x=?\r\n";
|
|
} elsif ( defined($port) && grep( /^$port$/, @ports ) && defined($cnt) && $cnt eq "counter" && defined($function) && $function eq "cnt" ) {
|
|
$buf = "z" . $port ."=?\r\n";
|
|
} elsif ( defined($port) && grep( /^$a[2]$/, @ports ) && $port ne "?" ) {
|
|
$buf = $a[2]."=?\r\n";
|
|
} else {
|
|
my $list = "";
|
|
foreach (@ports) {
|
|
#next if (wenn port nicht genutzt werden soll);
|
|
$list .= " " unless ($list eq "");
|
|
$list .= $_ . ':noArg';
|
|
$list .= " " . $_ . "_counter:noArg" if( defined($attr{$name}) && defined($attr{$name}{"Port_".$_}) && $attr{$name}{"Port_".$_} eq "cnt" );
|
|
}
|
|
return 'Unknown argument ' . $a[2] . ', choose one of ' . $list;
|
|
}
|
|
Netzer_send($hash, $buf);
|
|
return;
|
|
}
|
|
#############################################
|
|
sub Netzer_Set($@) {
|
|
my ($hash, @a) = @_;
|
|
my $name = $a[0];
|
|
my $port = $a[1] if (defined ($a[1]));
|
|
my $val = $a[2] if (defined ($a[2]));
|
|
($port, my $cnt) = split("_", $port) if defined($port) && $port =~ m/(_counter)$/;
|
|
my $function = $attr{$name}{"Port_".$port} if defined($port) && defined($attr{$name}{"Port_".$port});
|
|
if ( defined($function) && ( ( $function=~ m/^(PWM|out)$/i && !defined($cnt) ) || ( $function=~ m/^(cnt)$/i && defined($cnt) ) ) ) {
|
|
my $msg = "$name: wrong value ". (defined($val)?"$val ":"") . "for Port_$a[1], valid values: 0-";
|
|
my $buf = undef;
|
|
if ( $function eq "cnt" && defined($cnt) ) {
|
|
return $msg . "32767" if !defined($val) || $val > 32767 || $val < 0;
|
|
$buf = "z" . $port;
|
|
} else {
|
|
return $msg . "1023" if ($function eq "PWM" && (!defined($val) || $val > 1023 || $val < 0));
|
|
return $msg . "1" if ($function eq "out" && (!defined($val) || $val > 1 || $val < 0));
|
|
$buf = $port;
|
|
}
|
|
$val = sprintf("%x",$val);
|
|
$buf .= "=$val\r\n";
|
|
Netzer_send($hash, $buf);
|
|
} else {
|
|
my $list = "";
|
|
foreach (@ports) {
|
|
if(defined($attr{$name}) && defined($attr{$name}{"Port_".$_})) {
|
|
my $function = $attr{$name}{"Port_".$_};
|
|
if ($function eq "out") {
|
|
$list .= " " unless ($list eq "");
|
|
$list .= $_ . ':0,1';
|
|
} elsif ($function eq "PWM") {
|
|
$list .= " " unless ($list eq "");
|
|
$list .= $_ . ':slider,0,1,1023';
|
|
} elsif ($function eq "cnt") {
|
|
$list .= " " unless ($list eq "");
|
|
$list .= $_ . "_counter" ;
|
|
}
|
|
}
|
|
}
|
|
return 'Unknown argument ' . (defined($port)?$port:"") . (defined($cnt)?"_$cnt":"") . ', choose one of ' . $list;
|
|
}
|
|
return;
|
|
}
|
|
#############################################
|
|
sub Netzer_Attr(@) {
|
|
my (undef, $name, $attr, $val) = @_;
|
|
my $hash = $defs{$name};
|
|
my $msg = '';
|
|
#Log3 $name, 1, "Name: $name Attr: $attr Wert: $val";
|
|
|
|
if ($attr eq 'poll_interval') {
|
|
if ( defined($val) ) {
|
|
if ( looks_like_number($val) && $val > 0) {
|
|
RemoveInternalTimer($hash);
|
|
InternalTimer(1, 'Netzer_Poll', $hash, 0);
|
|
} else {
|
|
$msg = "$hash->{NAME}: Wrong poll intervall defined. poll_interval must be a number > 0";
|
|
}
|
|
} else { #wird auch aufgerufen wenn $val leer ist, aber der attribut wert wird auf 1 gesetzt
|
|
RemoveInternalTimer($hash);
|
|
}
|
|
}
|
|
|
|
if (!$val) {
|
|
delete ($hash->{READINGS}{$attr."_counter"}) if defined($hash->{READINGS}{$attr."_counter"});
|
|
} elsif ($val =~ m/^(in|out)$/) {
|
|
delete ($hash->{READINGS}{$attr."_counter"}) if defined($hash->{READINGS}{$attr."_counter"});
|
|
} elsif ($attr =~ m/^(Port_[a-c])$/) {
|
|
$msg = "$hash->{NAME}: $attr wrong function $val. Use in, out or cnt" if $val !~ m/^(cnt)$/;
|
|
delete ($hash->{READINGS}{$attr."_counter"}) if defined($hash->{READINGS}{$attr."_counter"}) && $val !~ m/^(cnt)$/;
|
|
} elsif ($attr =~ m/^(Port_[d|j])$/) {
|
|
$msg = "$hash->{NAME}: $attr wrong function $val. Use in, out or PWM" if $val !~ m/^(PWM)$/;
|
|
delete ($hash->{READINGS}{$attr."_counter"}) if defined($hash->{READINGS}{$attr."_counter"});
|
|
} elsif ($attr =~ m/^(Port_[e|f])$/) {
|
|
$msg = "$hash->{NAME}: $attr wrong function $val. Use in, out or ADC" if $val !~ m/^(ADC)$/;
|
|
delete ($hash->{READINGS}{$attr."_counter"}) if defined($hash->{READINGS}{$attr."_counter"});
|
|
}
|
|
return ($msg) ? $msg : undef;
|
|
}
|
|
#############################################
|
|
sub Netzer_Read($) {
|
|
my ($hash) = @_;
|
|
my $name = $hash->{NAME};
|
|
my $buf;
|
|
my $ret = sysread($hash->{CD}, $buf, 1024*1024);
|
|
if(!defined($ret) || $ret <= 0) {
|
|
Netzer_conn($hash);
|
|
return;
|
|
} else {
|
|
chomp ($buf);
|
|
my @msg = split(" ", $buf);
|
|
readingsBeginUpdate($hash);
|
|
foreach (@msg) {
|
|
#abfangen wenn mehrere botschafen
|
|
my ($port, $val) = split("=", $_);
|
|
$val =~ s/ //g;
|
|
$val = hex($val);
|
|
my $sval;
|
|
#my ($bufc) = $_ =~ /(\d+)/;
|
|
if ($port eq "x") {
|
|
for (my $i = 0; $i <= 12; $i++) {
|
|
next if defined($attr{$name}{"Port_".$ports[$i]}) && $attr{$name}{"Port_".$ports[$i]} =~ m/^(PWM|ADC)$/;
|
|
$sval = hex($val) & (1 << $i);
|
|
$sval = $sval == 0 ? "0" :"1";
|
|
readingsBulkUpdate($hash, 'Port_'.$ports[$i] , $sval) if (ReadingsVal($name,'Port_'.$ports[$i],0) ne $sval);
|
|
}
|
|
} elsif ( grep( /^$port$/, @ports ) ) {
|
|
readingsBulkUpdate($hash, 'Port_'.$port , $val);
|
|
} elsif ( grep( ($port =~ s/z// ), @ports ) ) {
|
|
readingsBulkUpdate($hash, 'Port_'.$port.'_counter' , ($val > 32767?"overflow":$val));
|
|
}
|
|
}
|
|
readingsBulkUpdate($hash, 'received', $buf);
|
|
#readingsBulkUpdate($hash, 'zeichenmenge', $ret);
|
|
readingsEndUpdate($hash, 1);
|
|
}
|
|
}
|
|
#############################################
|
|
sub Netzer_Poll($) {#Update of all Readings
|
|
my ($hash) = @_;
|
|
my $name = $hash->{NAME};
|
|
Netzer_Get($hash);
|
|
my $pollInterval = AttrVal($hash->{NAME}, 'poll_interval', 0);
|
|
if ($pollInterval > 0) {
|
|
InternalTimer(gettimeofday() + ($pollInterval * 60), 'Netzer_Poll', $hash, 0);
|
|
}
|
|
return;
|
|
}
|
|
#############################################
|
|
sub Netzer_Undef($$) {
|
|
my ($hash, $arg) = @_;
|
|
if ( defined (AttrVal($hash->{NAME}, "poll_interval", undef)) ) {
|
|
RemoveInternalTimer($hash);
|
|
}
|
|
Netzer_disconn($hash,0);
|
|
return undef;
|
|
}
|
|
#############################################
|
|
sub Netzer_send($$) {
|
|
my ($hash, $buf) = @_;
|
|
my $cnt= length ($buf);
|
|
if (not defined($hash->{CD})) {
|
|
Log3 $hash, 1, "$hash->{NAME}: Verbindung unterbrochen, versuche Verbindungsaufbau";
|
|
Netzer_conn($hash);
|
|
}
|
|
if ($hash->{CD}) {
|
|
syswrite($hash->{CD}, $buf, $cnt) ;
|
|
} else {
|
|
Log3 $hash, 1, "$hash->{NAME}: Daten konnten nicht gesendet werden";
|
|
}
|
|
}
|
|
#############################################
|
|
sub Netzer_conn($) {
|
|
my ($hash) = @_;
|
|
my $name = $hash->{NAME};
|
|
|
|
Netzer_disconn($hash,0);
|
|
my $timeout = $hash->{TIMEOUT} ? $hash->{TIMEOUT} : 3;
|
|
my $conn = IO::Socket::INET->new(PeerAddr=>"$hash->{DeviceName}", Timeout => $timeout);
|
|
if($conn) {
|
|
$hash->{STATE} = "Connected";
|
|
|
|
$hash->{FD} = $conn->fileno();
|
|
$hash->{CD} = $conn; # sysread / close won't work on fileno
|
|
$hash->{CONNECTS}++;
|
|
$selectlist{$name} = $hash;
|
|
Log(GetLogLevel($name,3), "$name: connected to $hash->{DeviceName}");
|
|
} else {
|
|
Netzer_disconn($hash, 1);
|
|
}
|
|
}
|
|
#############################################
|
|
sub Netzer_disconn($$) {
|
|
my ($hash, $connect) = @_;
|
|
my $name = $hash->{NAME};
|
|
return if( !$hash->{CD} );
|
|
close($hash->{CD}) if($hash->{CD});
|
|
delete($hash->{FD});
|
|
delete($hash->{CD});
|
|
delete($selectlist{$name});
|
|
$hash->{STATE} = "Disconnected";
|
|
if($connect) {
|
|
Log3 $name, 4, "$name: Connect failed.";
|
|
} else {
|
|
Log3 $name, 4, "$name: Disconnected";
|
|
}
|
|
}
|
|
|
|
1;
|
|
|
|
=pod
|
|
=item device
|
|
=item summary controls/reads GPIO pins on an Netzer
|
|
=item summary_DE steuern/lesen der GPIO Pins eines Netzer
|
|
=begin html
|
|
|
|
<a name="Netzer"></a>
|
|
<h3>Netzer</h3>
|
|
<ul>
|
|
The <a href="http://www.mobacon.de/wiki/doku.php/en/netzer/index">Netzer</a> realizes an Ethernet interface on a PIC-based platform. As a gateway module it enables communication between standard TCP/IP sockets and serial busses like I2C, SPI and UART.
|
|
Also up to 13 GPIO pins can be accessed. This Modul provides access to these GPIO pins on a Netzer running IO_base in Version 1.5.
|
|
There are two pins usable as ADC channel, two as PMW outputs, three as counter and three can generate an interrupt.
|
|
The GPIO pins are configured a input per default. Before a port can be used as output it must be <a href="http://www.mobacon.de/wiki/doku.php/en/netzer/io">configured</a> via the embedded webpage.
|
|
If one of the input ports is configured to send interrupt events on GPIO Server, on every event all port values will be updated.
|
|
All ports can be read and controlled individually by the function readingsProxy.
|
|
<br><br>
|
|
|
|
<a name="NetzerDefine"></a>
|
|
<b>Define</b>
|
|
<ul>
|
|
<code>define <name> Netzer <host:port></code>
|
|
<br><br>
|
|
</ul>
|
|
|
|
<a name="NetzerSet"></a>
|
|
<b>Set</b>
|
|
<ul>
|
|
<code>set <name> <port[_counter]> <value></code>
|
|
<br>
|
|
Where <value> is a character between <code>a</code> and <code>m</code> <br> according to the port. If Port attr is <code>cnt</code> an aditional value <port_counter> can be set.<br>
|
|
Only ports with corresponding attr Port_[a-m] set to <code>PWM</code> or <code>out</code> can be used.<br>
|
|
If Port attr is:<ul>
|
|
<li>PWM <value> can be a number between 0 and 1023</li>
|
|
<li>out <value> can be a number between 0 and 1</li>
|
|
<li>cnt <port_counter> <value> can be a number between 0 and 32767</li>
|
|
<br></ul>
|
|
</ul>
|
|
|
|
<b>Get</b>
|
|
<ul>
|
|
<code>get <name> [<port[_counter]>]</code>
|
|
<br>
|
|
If no <port> is set, all readings will be updated.<br>
|
|
<port> is a character between <code>a</code> and <code>m</code><br> according to the port. If Port attr is <code>cnt</code> an aditional reading <port_counter> can be read.
|
|
<br><br>
|
|
</ul>
|
|
|
|
<a name="NetzerAttr"></a>
|
|
<b>Attributes</b>
|
|
<ul>
|
|
<a name="poll_interval"></a>
|
|
<li>poll_interval<br>
|
|
Set the polling interval in minutes to query the sensor for new measured values.
|
|
Default: 5, valid values: decimal number</li><br>
|
|
|
|
<a name="Port_<port>"></a>
|
|
<li>Port_<port><br>
|
|
<ul>
|
|
Configuration for Netzer port.<br>
|
|
<port> is a character between <code>a</code> and <code>m</code>.<br>
|
|
<li><code>in</code>: Port is defined as input. Same behavior as no attribute. Set is not avaliable for this port.<br>
|
|
Can be used for all ports</li>
|
|
<li><code>out</code>: Port is defined as output. Set is avaliable for this port with <value> between 0 and 1.<br>
|
|
Can be used for all ports</li>
|
|
<li><code>cnt</code>: Port is defined as input. Set is not avaliable for this port.<br>
|
|
An second reading: Port_<port>_counter is avaiable.
|
|
It can be updated with <code>get</code> an changed with <code>set</code>.<br>
|
|
Port_<port>_counter <value> = 0-32767 or overflow if outside this range.<br>
|
|
Can be used for ports a,b,c</li>
|
|
<li><code>ADC</code>: Port is defined as analog input. <code>Get</code> <value> is 0-1023 according the voltage on port. Set is not avaliable for this port.<br>
|
|
Can be used for ports e,f</li>
|
|
<li><code>PWM</code>: Port is defined as PWM output. <code>Set</code> and <code>get</code> <value> is 0-1023 according the duty cycle on the port.<br>
|
|
Can be used for ports d,j</li>
|
|
</ul>
|
|
</li><br>
|
|
|
|
|
|
</ul>
|
|
<br>
|
|
</ul>
|
|
|
|
=end html
|
|
|
|
=begin html_DE
|
|
|
|
<a name="Netzer"></a>
|
|
<h3>Netzer</h3>
|
|
<ul>
|
|
The <a href="http://www.mobacon.de/wiki/doku.php/de/netzer/index">Netzer</a> realisiert ein Ethernetinterface auf PIC-Basis. Es agiert als Gateway zwischen TCP/IP und verschiedenen seriellen Busses wie I2C, SPI oder UART. Es können bis zu 13 GPIO Pins angesprochen (gelesen oder geschrieben) werden.
|
|
This Modul ermöglicht den Zugriff auf diese GPIO Pin's auf einem Netzer mit IO_base in Version 1.5.
|
|
Es gibt zwei als ADC nutzbare Pin's channel, 2 als PMW Ausgänge, drei als Zähler sowie drei die einen Interrupt auslösen können.
|
|
Die GPIO Pin's sind standardmäßig als Eingänge konfiguriert. Bevor ein Pin anderweitig genutzt werden kann, muss er über die eingebaute Website entsprechend <a href="http://www.mobacon.de/wiki/doku.php/de/netzer/io">eingestellt</a> werden.
|
|
Ist einer der Eingänge als Inerrupteingang eingestellt, werden bei jedem Interrupereignis die Weter sämtlicher Ports aktualisiert.
|
|
<br><br>
|
|
|
|
<a name="NetzerDefine"></a>
|
|
<b>Define</b>
|
|
<ul>
|
|
<code>define <name> Netzer <host:port></code>
|
|
<br><br>
|
|
</ul>
|
|
|
|
<a name="NetzerSet"></a>
|
|
<b>Set</b>
|
|
<ul>
|
|
<code>set <name> <port[_counter]> <value></code>
|
|
<br>
|
|
Dabei ist <value> ein dem Port entsprechender Buchstabe zwischen <code>a</code> und <code>m</code>. Besitzt der Port das Attribut <code>cnt</code> so kann ein weiterer Wert <port_counter> gesetzt werden.<br>
|
|
Ausschließlich Port's die über Attribut Port_[a-m] auf <code>PWM</code> oder <code>out</code> gesetzt sind können benutzt werden.<br>
|
|
Bei Port Attribut:<ul>
|
|
<li>PWM <value> kann ein Wert zwischen 0 und 1023 sein</li>
|
|
<li>out <value> kann ein Wert zwischen 0 und 1 sein</li>
|
|
<li>cnt <port_counter> <value> kann ein Wert zwischen 0 und 32767 sein</li>
|
|
<br></ul>
|
|
</ul>
|
|
|
|
<b>Get</b>
|
|
<ul>
|
|
<code>get <name> [<port[_counter]>]</code>
|
|
<br>
|
|
Ohne <port> werde alle Werte aktualisiert.<br>
|
|
Wenn <port> ein Buchstabe zwischen <code>a</code> und <code>m</code><br> ist, wird der Portwert aktualisiert und bei Port Attribut <code>cnt</code> kann ein weiterer Zählerwert <port_counter> gelesen werden.<br>
|
|
<br>
|
|
</ul>
|
|
|
|
<a name="NetzerAttr"></a>
|
|
<b>Attributes</b>
|
|
<ul>
|
|
<a name="poll_interval"></a>
|
|
<li>poll_interval<br>
|
|
Aktualisierungsintervall aller Werte in Minuten.<br>
|
|
Standard: 5, gültige Werte: Dezimalzahl
|
|
</li><br>
|
|
|
|
<a name="Port_<port>"></a>
|
|
<li>Port_<port><br>
|
|
<ul>
|
|
Konfiguration des jeweiligen GPIO.<br>
|
|
<port> ist ein Buchstabe zwischen <code>a</code> und <code>m</code>.<br>
|
|
<li><code>in</code>: Port ist Eingang. Kann auch weggelassen werden, da Standard. Set ist für diesen Port nicht verfügbar.<br>
|
|
Nutzbar für alle Port's</li>
|
|
<li><code>out</code>: Port ist Ausgang. Set kann <value> zwischen 0 und 1 haben.<br>
|
|
Nutzbar für alle Port's</li>
|
|
<li><code>cnt</code>: Port ist Eingang. Set ist für diesen Port nicht verfügbar.<br>
|
|
Ein weiteres Reading: Port_<port>_counter ist verfügbar.
|
|
Dieses kann auch mit <code>get</code> gelesen und mit <code>set</code> verändert werden.<br>
|
|
Port_<port>_counter <value> = 0-32767 oder overflow wenn es ausserhalb dieses Bereichs liegt.<br>
|
|
Nutzbar für Port's a,b,c</li>
|
|
<li><code>ADC</code>: Port ist Analogeingang. <code>get</code> <value> ist 0-1023 entsprechend der Spannung am Port. Set ist für diesen Port nicht verfügbar.<br>
|
|
Nutzbar für Port's e,f</li>
|
|
<li><code>PWM</code>: Port ist PWM-Ausgang. <code>set</code> und <code>get</code> <value> ist 0-1023 entsprechend des Dutycycle am Port.<br>
|
|
Nutzbar für Port's d,j</li>
|
|
</ul>
|
|
</li><br>
|
|
|
|
|
|
</ul>
|
|
<br>
|
|
</ul>
|
|
|
|
=end html_DE
|
|
|
|
=cut |