Hallo
Erst einmal danke fürs ändern der Formatierung.
Hier ist die Unit "uavrnetio":
Code: Alles auswählen
(******************************************************************************)
(* Writen by Corpsman 18.11.2010 *)
(* Support : http://www.Corpsman.de" onclick="window.open(this.href);return false; *)
(* Desription : The Class TAVR_NET_IO connects via Indy10 an the AVR-NET-IO *)
(* Board ( ver. 1.03) *)
(* License : This Unit is Freeware for non commercial use only. *)
(* Warranty : This unit is Freeware, there is no Warranty *)
(******************************************************************************)
Unit uavrnetio;
{$MODE objfpc}{$H+}
Interface
Uses
Classes, SysUtils,
dialogs, // Für diverse Statusmeldungen
IdTCPClient, IdGlobal, IdComponent // Indy Client
;
Const
crt = #13#10;
Type
TState = Array[0..7] Of Boolean;
(*
Die Basisklasse für das AVR-Board, Implementiert sind alle Befehle, die
Out off Box auf dem µ-Controller Integriert sind. Dazu noch "SetStatus".
*)
{ TAVR_NET_IO }
TAVR_NET_IO = Class
private
FIP: String; // IP des Boards
FPort: Integer; // Port der IP
FIdTCPClient: TIdTCPClient; // Die Indy Komponente für die Kommunikation
FKeep_Connection_Alive: Boolean; // Wenn True
FValidate_Results: Boolean; // Property Validate_SetPort
Fstate: TState; // Der Bakup status, der immer bei Connect aufgenommen wird, sollte Keep_Connection_Alive aktiviert sein (reduziert den Traffic)
Function FGetConnected: Boolean; // Gibt an ob der TCPclient verbunden ist
Function FGetIP: String; // Property IP
Procedure FSetIP(Const AValue: String); // Property IP
Function FGetKCA: Boolean; // Property Keep_Connection_Alive
Procedure FSetKCA(Const AValue: Boolean); // Property Keep_Connection_Alive
public
Property Connected: Boolean read FGetConnected; // True wenn auf das Board verbunden
Property IP: String read FGetIP write FSetIP; // Gibt die IP auf die Verbunden wurde
Property Keep_Connection_Alive: Boolean read FGetKCA write FSetKCA; // Wenn False erhöht sich der Traffic, True kann es "Unsicher" werden
Property Port: Integer read FPort; // Der Port auf dem das AVR-Net-IO Board reagiert
Property Validate_Results: Boolean read FValidate_Results write FValidate_Results; // Wenn diese Option gesetzt ist, wird geprüft ob die Ausgänge tatsächlich gesetzt wurden.
Constructor Create;
Destructor destroy; override;
// Verbindet zum Board
Procedure Connect;
// Trennt die Verbindung
Procedure Disconnect;
// Ermittelt die IP vom Board = Property IP, wenn Connected
Function GetIP: String;
// Setzt die IP vom Board, ACHTUNG danach ist ein Reconnect notwendig.
Procedure SetIP(Const IP_Address: String);
// Ermittelt die Subnetmaske
Function GetMask: String;
// Setzen der Subnetmaske
Procedure SetMask(Mask: String);
// Gibt die IP des Eingestellten Gateway an
Function GetGw: String;
// Gibt die Versoinsinformationen zurück
Function Version: String;
// Setzt die IP des Gateway
Procedure SetGw(Const Gw_Address: String);
// Gibt die Werte der 8 Digitalen Ausgänge zurück
(*
Die Ports werden von Rechts nach Links gelesen :
s87654321
dito bei TState und Byte !!
*)
Function GetStatus: String; // Nach Handbuch sXXXXXXXX
Function GetStatusAsString: String; // Nach Handbuch sXXXXXXXX
Function GetStatusAsState: TState;
Function GetStatusAsByte: Byte;
// Setzt alle 8 Ausgänge auf einmal Status nach Handbuch der Form sXXXXXXXX
Procedure SetStatus(Const Status: String); overload;
Procedure SetStatus(Const State: TState); overload;
Procedure SetStatus(Const State: Byte); overload;
// Setzt einen Ausgang auf den Wert Value
Procedure SetPort(Const Portnumber: Integer; Const Value: Boolean);
Procedure SetPort1(Const Value: Boolean);
Procedure SetPort2(Const Value: Boolean);
Procedure SetPort3(Const Value: Boolean);
Procedure SetPort4(Const Value: Boolean);
Procedure SetPort5(Const Value: Boolean);
Procedure SetPort6(Const Value: Boolean);
Procedure SetPort7(Const Value: Boolean);
Procedure SetPort8(Const Value: Boolean);
// Gibt den Wert eines digitalen Eingangs PortNumber in [1..4]
Function GetPort(Const PortNumber: Integer): Boolean;
Function GetPort1: Boolean;
Function GetPort2: Boolean;
Function GetPort3: Boolean;
Function GetPort4: Boolean;
// Gibt den Wert eines analogen Eingangs PortNumber in [1..4]
// Ergebniss in [0..1023], Fehler = -1)
Function GetADC(Const PortNumber: Integer): Integer;
Function GetADC1: Integer;
Function GetADC2: Integer;
Function GetADC3: Integer;
Function GetADC4: Integer;
// Initialisiert das LCD Display
Procedure InitLCD;
// Schreibt den Text in eine Zeile, Line in [1,2]
Procedure WriteLCD(Const Line: Integer; Text: String);
// Löscht eine Zeile Line in [0,1,2]
// Line = 0 = Komplettes Display Löschen
Procedure ClearLCD(Const Line: integer);
Procedure Writeln(Const AValue: String); // Zum Senden an die AVR-Karte !! ACHTUNG !! Writeln wird ohne weitere Checks ausgeführt
Function Readln: String; // Eine Zeile Lesen !! ACHTUNG !! Readln wird ohne weitere Checks ausgeführt
End;
Implementation
Function CheckIP(IP: String): Boolean;
Var
i, j: integer;
tmp: String;
bool: Boolean;
Begin
result := true;
tmp := ip + '.';
For i := 0 To 3 Do Begin
If pos('.', tmp) = 0 Then Begin
result := false;
Raise Exception.create('Error invalid IP : "' + IP + '"');
End
Else Begin
bool := true;
Try
j := strtoint(copy(tmp, 1, pos('.', tmp) - 1));
delete(tmp, 1, pos('.', tmp));
If (j < 0) Or (j > 255) Then bool := false;
Except
bool := false;
End;
If Not bool Then Begin
result := false;
Raise Exception.create('Error invalid IP : "' + IP + '"');
End;
End;
End;
End;
(*
Konvertiert sxxxxxxxx -> TState
*)
Function StatusToState(Const Value: String): TState;
Var
i: Integer;
Begin
If Length(Value) <> length('sxxxxxxxx') Then
Raise Exception.create('Error invalid State String : "' + Value + '"');
For i := 0 To 7 Do
result[i] := Value[i + 2] = '1';
End;
(*
Konvertiert TState -> nach xxxxxxxx
*)
Function StateToString(Const Value: TState): String;
Var
i: Integer;
Begin
setlength(result, 8);
For i := 1 To 8 Do
result[i] := inttostr(ord(value[i - 1]))[1];
End;
{ TAVR_NET_IO }
Constructor TAVR_NET_IO.Create;
Begin
Inherited Create;
// Init
Fport := 50290;
FIP := '192.168.1.92';
FKeep_Connection_Alive := true;
FValidate_Results := false;
// der TCP-Client
FIdTCPClient := TIdTCPClient.create(Nil);
FIdTCPClient.Port := Fport;
FIdTCPClient.Host := FIP;
End;
Destructor TAVR_NET_IO.destroy;
Begin
If Connected Then
FIdTCPClient.Disconnect;
FIdTCPClient.free;
FIdTCPClient := Nil;
End;
Procedure TAVR_NET_IO.Writeln(Const AValue: String);
Begin
FIdTCPClient.IOHandler.WriteLn(avalue + ' \r\n');
End;
Function TAVR_NET_IO.Readln: String;
Begin
result := FIdTCPClient.IOHandler.ReadLn;
End;
Function TAVR_NET_IO.FGetConnected: Boolean;
Begin
result := FIdTCPClient.Connected;
End;
Function TAVR_NET_IO.FGetIP: String;
Begin
// Egal ob Verbunden oder nicht, wir kennen nur diese IP
result := FIP;
End;
Procedure TAVR_NET_IO.FSetIP(Const AValue: String);
Var
s: String;
Begin
If CheckIP(AValue) Then Begin
If Connected And (FIP <> AValue) Then Begin
WriteLn(AValue);
s := ReadLn();
If lowercase(s) = 'ack' Then Begin
Disconnect;
Showmessage('IP sucessfully set to : "' + fip + '"'#13'You have to reconnect');
End
Else Begin
Raise Exception.create('Error could not Change IP-settings.');
End;
End;
FIP := AValue;
End;
End;
Function TAVR_NET_IO.FGetKCA: Boolean;
Begin
result := FKeep_Connection_Alive;
End;
Procedure TAVR_NET_IO.FSetKCA(Const AValue: Boolean);
Begin
FKeep_Connection_Alive := avalue;
If FIdTCPClient.Connected And AValue Then Begin
Fstate := StatusToState(GetStatus);
End;
End;
Procedure TAVR_NET_IO.Connect;
Var
b: Boolean;
Begin
// Nicht unötig verbinden
If Not Connected Then Begin
FIdTCPClient.Host := fip;
FIdTCPClient.Connect;
If FKeep_Connection_Alive Then Begin
b := Validate_Results;
Validate_Results := true; // Sonst lesen wir den Cache aus
Fstate := StatusToState(GetStatus);
Validate_Results := b;
End;
End;
End;
Procedure TAVR_NET_IO.Disconnect;
Begin
If FIdTCPClient.Connected Then Begin
FIdTCPClient.Disconnect
End;
End;
Function TAVR_NET_IO.GetIP: String;
Begin
// Wenn Wir verbunden sind hat FGetIP die Richtige IP, andernfalls ist es Eh egal
result := FGetIP;
End;
Procedure TAVR_NET_IO.SetIP(Const IP_Address: String);
Begin
FSetIP(IP_Address);
End;
Function TAVR_NET_IO.GetMask: String;
Begin
// Ob nun Keep Alive oder nicht, spielt keine Rolle verbunden werden mus immer
// oder ist eben schon.
Connect;
writeln('getmask');
result := readln;
If Not FKeep_Connection_Alive Then
Disconnect;
End;
Procedure TAVR_NET_IO.SetMask(Mask: String);
Var
s: String;
Begin
If CheckIP(Mask) Then Begin
// Ob nun Keep Alive oder nicht, spielt keine Rolle verbunden werden mus immer
// oder ist eben schon.
Connect;
writeln('setmask ' + mask);
If FValidate_Results Then Begin
s := readln;
If lowercase(s) <> 'ack' Then
Raise Exception.create('Error got "' + s + '" in SetMask');
End;
If FKeep_Connection_Alive Then Begin
// Wenn die Verbindung Aktive gehalten wird, muss Trotzdem weitergelesen werden.
If Not FValidate_Results Then
readln;
End
Else Begin
Disconnect;
End;
End;
End;
Function TAVR_NET_IO.GetGw: String;
Begin
// Ob nun Keep Alive oder nicht, spielt keine Rolle verbunden werden mus immer
// oder ist eben schon.
Connect;
writeln('getgw');
result := readln;
If Not FKeep_Connection_Alive Then
Disconnect;
End;
Function TAVR_NET_IO.Version: String;
Begin
// Ob nun Keep Alive oder nicht, spielt keine Rolle verbunden werden mus immer
// oder ist eben schon.
Connect;
writeln('version');
result := readln;
result := result + crt + readln;
result := result + crt + readln;
If Not FKeep_Connection_Alive Then
Disconnect;
End;
Procedure TAVR_NET_IO.SetGw(Const Gw_Address: String);
Var
s: String;
Begin
If CheckIP(Gw_Address) Then Begin
// Ob nun Keep Alive oder nicht, spielt keine Rolle verbunden werden mus immer
// oder ist eben schon.
Connect;
writeln('setgw ' + Gw_Address);
If FValidate_Results Then Begin
s := readln;
If lowercase(s) <> 'ack' Then
Raise Exception.create('Error got "' + s + '" in SetGw');
End;
If FKeep_Connection_Alive Then Begin
// Wenn die Verbindung Aktive gehalten wird, muss Trotzdem weitergelesen werden.
If Not FValidate_Results Then
readln;
End
Else Begin
Disconnect;
End;
End;
End;
Function TAVR_NET_IO.GetStatus: String;
Begin
If Keep_Connection_Alive Then Begin
If Validate_Results Then Begin
Connect;
writeln('getstatus');
result := readln;
End
Else
result := 's' + StateToString(Fstate);
End
Else Begin
Connect;
writeln('getstatus');
result := readln;
Disconnect;
End;
End;
Function TAVR_NET_IO.GetStatusAsString: String;
Begin
result := Getstatus;
End;
Function TAVR_NET_IO.GetStatusAsState: TState;
Begin
result := StatusToState(GetStatus);
End;
Function TAVR_NET_IO.GetStatusAsByte: Byte;
Var
tmpS: TState;
v, i: Integer;
Begin
tmpS := GetStatusAsState;
result := 0;
v := 128;
For i := 0 To 7 Do Begin
If tmps[i] Then Begin
result := result Or v;
End;
v := v div 2;
End;
End;
Procedure TAVR_NET_IO.SetStatus(Const Status: String);
Var
s: Tstate;
Begin
s := StatusToState(Status);
SetStatus(s);
End;
Procedure TAVR_NET_IO.SetStatus(Const State: TState);
Var
s: String;
i: integer;
Begin
// Um den Traffic Möglichst Gering zu halten schreiben wir nur die sich "Ändernden"
// Ports, mit dem Overhead des vorherigen Abfragens
connect;
s := GetStatusAsString;
For i := 1 To 8 Do Begin
If ((s[i + 1] = '1') And (Not State[i - 1])) Or ((s[i + 1] = '0') And (State[i - 1]))
Then Begin
SetPort(9 - i, State[i - 1]);
End;
End;
// evtl Auswählen
If Not Keep_Connection_Alive Then
Disconnect;
End;
Procedure TAVR_NET_IO.SetStatus(Const State: Byte);
Var
t: Tstate;
b, i: Integer;
Begin
// Konvertierung Byte nach TState
b := 1;
For i := 0 To 7 Do Begin
t[7 - i] := (b And State) = b;
b := b * 2;
End;
SetStatus(t);
End;
Procedure TAVR_NET_IO.SetPort(Const Portnumber: Integer; Const Value: Boolean);
Begin
Case Portnumber Of
1: SetPort1(Value);
2: SetPort2(Value);
3: SetPort3(Value);
4: SetPort4(Value);
5: SetPort5(Value);
6: SetPort6(Value);
7: SetPort7(Value);
8: SetPort8(Value);
Else
Raise Exception.create('Error invalid portnumber : ' + inttostr(Portnumber));
End;
End;
Procedure TAVR_NET_IO.SetPort1(Const Value: Boolean);
Var
s: String;
Begin
connect;
writeln('Setport 1.' + inttostr(ord(value)));
s := readln;
// Wenn Kontroliert werden soll
If Validate_Results Then Begin
If lowercase(s) <> 'ack' Then
Raise Exception.create('Error could not set port 1 to value : ' + inttostr(ord(Value)));
s := GetStatusAsString;
If s[9] <> inttostr(ord(value)) Then
Raise Exception.create('Error could not set port 1 to value : ' + inttostr(ord(Value)));
End;
If Keep_Connection_Alive Then Begin
Fstate[7] := value;
End
Else Begin
Disconnect;
End;
End;
Procedure TAVR_NET_IO.SetPort2(Const Value: Boolean);
Var
s: String;
Begin
connect;
writeln('Setport 2.' + inttostr(ord(value)));
s := readln;
// Wenn Kontroliert werden soll
If Validate_Results Then Begin
If lowercase(s) <> 'ack' Then
Raise Exception.create('Error could not set port 2 to value : ' + inttostr(ord(Value)));
s := GetStatusAsString;
If s[8] <> inttostr(ord(value)) Then
Raise Exception.create('Error could not set port 2 to value : ' + inttostr(ord(Value)));
End;
If Keep_Connection_Alive Then Begin
Fstate[6] := value;
End
Else Begin
Disconnect;
End;
End;
Procedure TAVR_NET_IO.SetPort3(Const Value: Boolean);
Var
s: String;
Begin
connect;
writeln('Setport 3.' + inttostr(ord(value)));
s := readln;
// Wenn Kontroliert werden soll
If Validate_Results Then Begin
If lowercase(s) <> 'ack' Then
Raise Exception.create('Error could not set port 3 to value : ' + inttostr(ord(Value)));
s := GetStatusAsString;
If s[7] <> inttostr(ord(value)) Then
Raise Exception.create('Error could not set port 3 to value : ' + inttostr(ord(Value)));
End;
If Keep_Connection_Alive Then Begin
Fstate[5] := value;
End
Else Begin
Disconnect;
End;
End;
Procedure TAVR_NET_IO.SetPort4(Const Value: Boolean);
Var
s: String;
Begin
connect;
writeln('Setport 4.' + inttostr(ord(value)));
s := readln;
// Wenn Kontroliert werden soll
If Validate_Results Then Begin
If lowercase(s) <> 'ack' Then
Raise Exception.create('Error could not set port 4 to value : ' + inttostr(ord(Value)));
s := GetStatusAsString;
If s[6] <> inttostr(ord(value)) Then
Raise Exception.create('Error could not set port 4 to value : ' + inttostr(ord(Value)));
End;
If Keep_Connection_Alive Then Begin
Fstate[4] := value;
End
Else Begin
Disconnect;
End;
End;
Procedure TAVR_NET_IO.SetPort5(Const Value: Boolean);
Var
s: String;
Begin
connect;
writeln('Setport 5.' + inttostr(ord(value)));
s := readln;
// Wenn Kontroliert werden soll
If Validate_Results Then Begin
If lowercase(s) <> 'ack' Then
Raise Exception.create('Error could not set port 5 to value : ' + inttostr(ord(Value)));
s := GetStatusAsString;
If s[5] <> inttostr(ord(value)) Then
Raise Exception.create('Error could not set port 5 to value : ' + inttostr(ord(Value)));
End;
If Keep_Connection_Alive Then Begin
Fstate[3] := value;
End
Else Begin
Disconnect;
End;
End;
Procedure TAVR_NET_IO.SetPort6(Const Value: Boolean);
Var
s: String;
Begin
connect;
writeln('Setport 6.' + inttostr(ord(value)));
s := readln;
// Wenn Kontroliert werden soll
If Validate_Results Then Begin
If lowercase(s) <> 'ack' Then
Raise Exception.create('Error could not set port 6 to value : ' + inttostr(ord(Value)));
s := GetStatusAsString;
If s[4] <> inttostr(ord(value)) Then
Raise Exception.create('Error could not set port 6 to value : ' + inttostr(ord(Value)));
End;
If Keep_Connection_Alive Then Begin
Fstate[2] := value;
End
Else Begin
Disconnect;
End;
End;
Procedure TAVR_NET_IO.SetPort7(Const Value: Boolean);
Var
s: String;
Begin
connect;
writeln('Setport 7.' + inttostr(ord(value)));
s := readln;
// Wenn Kontroliert werden soll
If Validate_Results Then Begin
If lowercase(s) <> 'ack' Then
Raise Exception.create('Error could not set port 7 to value : ' + inttostr(ord(Value)));
s := GetStatusAsString;
If s[3] <> inttostr(ord(value)) Then
Raise Exception.create('Error could not set port 7 to value : ' + inttostr(ord(Value)));
End;
If Keep_Connection_Alive Then Begin
Fstate[1] := value;
End
Else Begin
Disconnect;
End;
End;
Procedure TAVR_NET_IO.SetPort8(Const Value: Boolean);
Var
s: String;
Begin
connect;
writeln('Setport 8.' + inttostr(ord(value)));
s := readln;
// Wenn Kontroliert werden soll
If Validate_Results Then Begin
If lowercase(s) <> 'ack' Then
Raise Exception.create('Error could not set port 8 to value : ' + inttostr(ord(Value)));
s := GetStatusAsString;
If s[2] <> inttostr(ord(value)) Then
Raise Exception.create('Error could not set port 8 to value : ' + inttostr(ord(Value)));
End;
If Keep_Connection_Alive Then Begin
Fstate[0] := value;
End
Else Begin
Disconnect;
End;
End;
Function TAVR_NET_IO.GetPort(Const PortNumber: Integer): Boolean;
Begin
Case Portnumber Of
1: result := Getport1;
2: result := Getport2;
3: result := Getport3;
4: result := Getport4;
Else
Raise Exception.create('Error invalid portnumber ' + inttostr(portnumber));
End;
End;
Function TAVR_NET_IO.GetPort1: Boolean;
Var
s: String;
Begin
connect;
Writeln('getport 1');
s := readln;
result := s = '1';
If Validate_Results Then Begin
If Length(s) <> 1 Then
Raise exception.create('Error, AVL-Board send invalid data : "' + s + '"');
End;
If Not Keep_Connection_Alive Then Begin
Disconnect;
End;
End;
Function TAVR_NET_IO.GetPort2: Boolean;
Var
s: String;
Begin
connect;
Writeln('getport 2');
s := readln;
result := s = '1';
If Validate_Results Then Begin
If Length(s) <> 1 Then
Raise exception.create('Error, AVL-Board send invalid data : "' + s + '"');
End;
If Not Keep_Connection_Alive Then Begin
Disconnect;
End;
End;
Function TAVR_NET_IO.GetPort3: Boolean;
Var
s: String;
Begin
connect;
Writeln('getport 3');
s := readln;
result := s = '1';
If Validate_Results Then Begin
If Length(s) <> 1 Then
Raise exception.create('Error, AVL-Board send invalid data : "' + s + '"');
End;
If Not Keep_Connection_Alive Then Begin
Disconnect;
End;
End;
Function TAVR_NET_IO.GetPort4: Boolean;
Var
s: String;
Begin
connect;
Writeln('getport 4');
s := readln;
result := s = '1';
If Validate_Results Then Begin
If Length(s) <> 1 Then
Raise exception.create('Error, AVL-Board send invalid data : "' + s + '"');
End;
If Not Keep_Connection_Alive Then Begin
Disconnect;
End;
End;
Function TAVR_NET_IO.GetADC(Const PortNumber: Integer): Integer;
Begin
Case Portnumber Of
1: result := GetADC1;
2: result := GetADC2;
3: result := GetADC3;
4: result := GetADC4;
Else
Raise Exception.create('Error invalid portnumber ' + inttostr(portnumber));
End;
End;
Function TAVR_NET_IO.GetADC1: Integer;
Var
s: String;
b: Boolean;
Begin
result := 0;
connect;
Writeln('getadc 1');
s := readln;
Try
result := strtoint(s);
b := true;
Except
b := false;
End;
If Not b Then
Raise exception.create('Error, AVL-Board send invalid data : "' + s + '"');
If Not Keep_Connection_Alive Then Begin
Disconnect;
End;
End;
Function TAVR_NET_IO.GetADC2: Integer;
Var
s: String;
b: Boolean;
Begin
result := 0;
connect;
Writeln('getadc 2');
s := readln;
Try
result := strtoint(s);
b := true;
Except
b := false;
End;
If Not b Then
Raise exception.create('Error, AVL-Board send invalid data : "' + s + '"');
If Not Keep_Connection_Alive Then Begin
Disconnect;
End;
End;
Function TAVR_NET_IO.GetADC3: Integer;
Var
s: String;
b: Boolean;
Begin
result := 0;
connect;
Writeln('getadc 3');
s := readln;
Try
result := strtoint(s);
b := true;
Except
b := false;
End;
If Not b Then
Raise exception.create('Error, AVL-Board send invalid data : "' + s + '"');
If Not Keep_Connection_Alive Then Begin
Disconnect;
End;
End;
Function TAVR_NET_IO.GetADC4: Integer;
Var
s: String;
b: Boolean;
Begin
result := 0;
connect;
Writeln('getadc 4');
s := readln;
Try
result := strtoint(s);
b := true;
Except
b := false;
End;
If Not b Then
Raise exception.create('Error, AVL-Board send invalid data : "' + s + '"');
If Not Keep_Connection_Alive Then Begin
Disconnect;
End;
End;
Procedure TAVR_NET_IO.InitLCD;
Begin
Raise exception.create('Todo.');
End;
Procedure TAVR_NET_IO.WriteLCD(Const Line: Integer; Text: String);
Begin
Raise exception.create('Todo.');
End;
Procedure TAVR_NET_IO.ClearLCD(Const Line: integer);
Begin
Raise exception.create('Todo.');
End;
End.
Hier der Link zu Corpsmann's Thread:
http://www.lazarusforum.de/viewtopic.php?f=9&t=4300
Hier der Link seiner HP wo ich die Unit her habe:
http://corpsman.de/index.php?doc=avrnetio/basic
In der Unit ist nur die IP angepasst worden.
Gruß Klaus