Hallo allerseits!
Ich hatte ja vor einiger Zeit mein Terrarium auf Arduino-Steuerung umgebaut. Hier nun das Ergebnis mit 2-Wege-Kommunikation
>>> Download des Sketch am Ende dieses Beitrags
Da man das sowieso nicht 1zu1 übernehmen kann, erkläre ich gar nicht viel dazu. Einfach mal den Code vom Arduino-Sketch anschauen, da sieht man schon was man so anstellen kann
Aber auf jeden Fall kann man vom IPS über Scripte Befehle an den Arduino senden und dieser schaltet dann z.B. einen Relaiskanal oder ändert Variablen oder liest die Temperatursensoren aus und schickt die Daten zurück ans IPS.
Wenn ihr den Sketch auf euch angepasst und auf euren Arduino geladen habt, dann braucht ihr auf der IPS Seite:
> I/O Instanz > ArduinoXY - ServerSocket - Port 6661
> Darunter eine „Register Variable“ mit diesem Script als Ziel:
<?
$GeraeteName = "Arduino01";
$Kategorie_Arduino01_Vars = 32993 /*[Hardware\Arduino\Arduino01 (Terrarium)]*/; // Hier eine Kategorie eintragen, in der das Script die entsprechenden Variablen anlegt
if ($_IPS['SENDER'] == "Execute") {
$Arduino01_ServerSocket = 41007 /*[Arduino01_Terrarium]*/;
if (IPS_GetParent($_IPS['SELF']) != $Arduino01_ServerSocket) {
IPS_SetParent(IPS_GetParent($_IPS['SELF']), $Arduino01_ServerSocket);
}
}
if ($_IPS['SENDER'] == "RegisterVariable") {
$data = RegVar_GetBuffer($_IPS['INSTANCE']);
$data .= $_IPS['VALUE'];
RegVar_SetBuffer($_IPS['INSTANCE'], $data);
if (strpos($data, '!')) {
$data = trim($data);
$data = str_replace("!", "", $data);
$datasets = explode(':', $data);
EmpfangeneDatenVerarbeiten($datasets);
RegVar_SetBuffer($_IPS['INSTANCE'], "");
}
}
function EmpfangeneDatenVerarbeiten($datasets) {
$Var = $datasets[0];
$Wert1 = $datasets[1];
$Wert2 = @$datasets[2];
$Wert3 = @$datasets[3];
//IPS_LogMessage("VAR", $Var);
//IPS_LogMessage("WERT1", $Wert1);
//IPS_LogMessage("WERT2", $Wert2);
//IPS_LogMessage("WERT3", $Wert3);
if ($Var == "Sternenhimmel") {
if ($Wert1 == "AUS") {
$Wert1 = false;
UpdateIPSvar($Var,$Wert1,0);
}
elseif ($Wert1 == "AN") {
$Wert1 = true;
UpdateIPSvar($Var,$Wert1,0);
}
}
elseif ($Var == "T5_Helligkeit") {
UpdateIPSvar($Var,$Wert1,1);
}
elseif ($Var == "VERBUNDEN") {
$Var = "Check";
UpdateIPSvar($Var,true,0);
}
elseif ($Var == "Sternenhimmel_Einstellungen") {
$Wert = "$Wert1,$Wert2,$Wert3";
UpdateIPSvar($Var,$Wert,3);
}
elseif ($Var == "Relaiskarte") {
$Var = "Relaiskarte$Wert1";
if ($Wert2 == "AUS") {
$Wert2 = false;
}
elseif ($Wert2 == "AN") {
$Wert2 = true;
}
UpdateIPSvar($Var,$Wert2,0);
}
elseif ($Var == "TemperaturSensoren_Anzahl") {
UpdateIPSvar($Var,$Wert1,1);
}
elseif ($Var == "TemperaturSensor") {
$Var = "$Var$Wert1";
UpdateIPSvar($Var,$Wert2,2);
}
}
function UpdateIPSvar($ident,$value,$type) {
Global $Kategorie_Arduino01_Vars;
$parent = $Kategorie_Arduino01_Vars;
if (is_int($type))
{
$ips_type=$type;
} else {
switch ($type)
{
case "i1":
case "i2":
case "i4":
case "ui1":
case "ui2":
case "ui4":
$ips_type=1;
break;
case "boolean":
$ips_type=0;
break;
case "uuid":
case "dateTime":
case "string":
$ips_type=3;
break;
default:
echo "Unbekannter Datentyp:".$type.PHP_EOL;
return;
break;
}
}
$var_id = @IPS_GetObjectIDByIdent($ident,$parent);
if ($var_id === false)
{
$var_id = IPS_CreateVariable($ips_type);
IPS_SetName($var_id,$ident);
IPS_SetIdent($var_id,$ident);
IPS_SetParent($var_id,$parent);
}
switch ($ips_type)
{
case 0:
if (GetValueBoolean($var_id) <> (bool)$value)
{
SetValueBoolean($var_id,(bool)$value);
}
elseif ($ident == "Check") {
SetValueBoolean($var_id,(bool)$value);
}
break;
case 1:
if (GetValueInteger($var_id) <> (int)$value)
{
SetValueInteger($var_id,(int)$value);
}
break;
case 2:
if (GetValueFloat($var_id) <> round((float)$value,2))
{
SetValueFloat($var_id,round((float)$value,2));
}
break;
case 3:
if (GetValueString($var_id) <> $value)
{
SetValueString($var_id,$value);
}
break;
}
}
?>
Dieses Script legt dann automatisch Variablen an und aktualisiert diese auch.
Zur Bedienung/Steuerung habe ich mir eine Funktion gebaut, diese sieht wie folgt aus:
<?
//Arduino_Befehl_Senden("Arduino01", "help!");
//Arduino_Befehl_Senden("Arduino01", "Sternenhimmel,AN!");
//Arduino_Befehl_Senden("Arduino01", "Sternenhimmel,AUS!");
//Arduino_Befehl_Senden("Arduino01", "TemperaturSensoren_Anzahl!");
//Arduino_Befehl_Senden("Arduino01", "TemperaturSensor_Abfragen,0!");
//Arduino_Befehl_Senden("Arduino01", "Relaiskarte,1,AN!");
//Arduino_Befehl_Senden("Arduino01", "Relaiskarte,1,AUS!");
//Arduino_Befehl_Senden("Arduino01", "Relaiskarte,2,AN!");
//Arduino_Befehl_Senden("Arduino01", "Relaiskarte,2,AUS!");
//Arduino_Befehl_Senden("Arduino01", "Relaiskarte,3,AN!");
//Arduino_Befehl_Senden("Arduino01", "Relaiskarte,3,AUS!");
//Arduino_Befehl_Senden("Arduino01", "Relaiskarte,4,AN!");
//Arduino_Befehl_Senden("Arduino01", "Relaiskarte,4,AUS!");
//Arduino_Befehl_Senden("Arduino01", "T5_Helligkeit,50!");
//Arduino_Befehl_Senden("Arduino01", "T5_Helligkeit,150!");
//Arduino_Befehl_Senden("Arduino01", "T5_Helligkeit,255!");
//Arduino_Befehl_Senden("Arduino01", "Sternenh_Einstellungen,2,1,10!");
function Arduino_Befehl_Senden($Device, $Befehl) {
if ($Device == "Arduino01") {
$InstanzID = 41007 /*[Arduino01_Terrarium]*/;
}
if (IPS_SemaphoreEnter($Device, 9000)) {
$result = @SSCK_SendText($InstanzID, $Befehl);
if (!$result) {
IPS_Sleep(3000);
@SSCK_SendText($InstanzID, $Befehl);
}
IPS_Sleep(250);
IPS_SemaphoreLeave($Device);
}
}
?>
Die Temperaturen kann ich dann z.B. mit diesem Script, per Timer gesteuert, auslesen:
<?
include 'Arduino.ips.php';
for ($ts = 0; $ts <= 8; $ts++) {
Arduino_Befehl_Senden("Arduino01", "TemperaturSensor_Abfragen,$ts!");
IPS_Sleep(800);
}
?>
Die Ausgabe erfolgt sowohl über LAN an den ServerSocket (IPS), als auch per Seriell (falls man USB angeschlossen hat, gut zum Testen).
Bevor einer was sagt, ja, man sollte das Senden auch über die RegVar machen, aber ich kam noch nicht dazu es umzubauen g Und da ich momentan kaum Zeit habe und alles läuft, bleibt es erstmal so
Sooo…hab ich was vergessen? Ich hoffe nicht Viel Spaß damit
Grüße,
Chris
!!! ACHTUNG !!! BENUTZUNG AUF EIGENE GEFAHR !!! ERST AUF EUCH ANPASSEN !!!
Arduino-Sketch_Terrarium_v1.5.zip (3.9 KB)