connect mysql resolve problem und zuweisung der IP für ethernet

Hallo

ich versuche gerade ein paar Lösungsansätze für Lese/Schreib-Aktionen auf einer im lokalen Netz befindlichen MYSQL-DB zu finden und bin dabei auf die Bibliothek mysql.h von http://drcharlesbell.blogspot.de/2013/04/introducing-mysql-connectorarduino_6.html
gestoßen.

ich vermute das diese eigentlich das macht was ich suche, also direkt in eine mysql-db schreiben und werte aus dieser holen ohne dabei umständlich ein php-script mit URL-Übergaben benutzen zu müssen.

leider stoße ich gerade jetzt auf Probleme mit der Zuweisung einer festen IP-Adresse für den Arduino

ich benutze folgende Hardware

  • Arduino mega R3 (dieser sollte die IP 192.168.2.105 haben)
  • Raspberry pi (dieser hat die IP 192.168.2.104)
    auf dem raspberry läuft die mysql-db und der Webserver
    die User sind in der mysql-db angelegt und lassen Zugriffe von 192.168.2.105 und localhost zu.
    den mysqld habe ich mit bind-address an 127.0.0.1 und 192.168.2.104 gebunden.

Folgende Probleme tauchen auf.

obwohl in meinem sketch
byte ip = { 192, 168, 2, 105 };
angegeben wurde,
wird dem arduino die IP-Adresse
192.168.2.106 zugewiesen
wieso?
ich habe den arduino neu gestartet usw. nichts hilft

/**
* Example: Hello, MySQL!
*
* This code module demonstrates how to create a simple 
* database-enabled sketch.
*/
#include "SPI.h"
#include "Ethernet.h"
#include "sha1.h"
#include "mysql.h"

/* Setup for Ethernet Library */
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte server[] = { 192, 168, 2, 104};
byte ip[] = { 192, 168, 2, 105 };

/* Setup for the Connector/Arduino */
Connector my_conn; // The Connector/Arduino reference

char user[] = "meinuser";
char password[] = "meinpasswort";
char INSERT_SQL[] = "INSERT INTO test.test_db (`temp`) VALUES (13)";

void setup() {
  Ethernet.begin(mac, ip);
  Serial.begin(9600);
  delay(1000);
  Serial.println("Connecting...");
  if (my_conn.mysql_connect(server, 3306, user, password))
  {
    delay(500);
     /* Write Hello, World to MySQL table test_arduino.hello */
      Serial.println("connection ok Success!"); 
     my_conn.cmd_query(INSERT_SQL);
     Serial.println("Query Success!"); 
  } 
  else
    Serial.println("Connection failed.");
}

void loop() {
}

wenn dann doch mal ein connect zustande kommt dann meckert der mysqld und meint das er die ip 192.168.2.105 nicht auflösen kann
skip-host-cache
skip-name-resolve

haben auch nichts gebracht

weiss jemand was ich hier grundlegendes falsch mache?

Gruß Jürgen

Direkt das Binäre-MySQL Protokoll zu sprechen halte ich aus verschiedenen Gründen für eine sehr ungute Idee.

Zu einem MySQL Server gehört meist noch etwas auf dem ein Webserver läuft. Du hast nicht zufällig noch einen Webserver mit PHP auf der gleichen Maschine? Das würde die Sache extrem vereinfachen, wenn du einfach mit nem PHP Script arbeiten würdest.

Manawyrm:
Direkt das Binäre-MySQL Protokoll zu sprechen halte ich aus verschiedenen Gründen für eine sehr ungute Idee.

Zu einem MySQL Server gehört meist noch etwas auf dem ein Webserver läuft. Du hast nicht zufällig noch einen Webserver mit PHP auf der gleichen Maschine? Das würde die Sache extrem vereinfachen, wenn du einfach mit nem PHP Script arbeiten würdest.

ja, auf dem Raspberry läuft mysql und der Webserver also apache2 mit php Untzerstützung.

Bis jetzt schaffte ich es Daten vom Arduino an ein PHP-Script auf dem Raspberry zu senden der dann die Daten in die DB schreibt.
Da ich jedoch auch von der DB Daten für den Arduino benötige muss ich auch lesen und diese an den Arduino übergeben.
#Laut eines Threads in diesem Forum soll das auch mit einem php-script gehen.

Da ich dann aber auf die Bibliothek mysql_connector gestoßen bin erhoffte ich mir das auch das lesen vom arduino aus und dann die übergabe der Ergebnisse an den arduino aus der mysql-db einfacher funktioniert und ich den Umweg über ein PHP-Script mir erspare.

war das falsch gedacht?

Der Arduino hat für solche Späße zu wenig Dampf. Vorallem fehlt im RAM. Du müsstest hier ja gar Strings parsen.

Am besten fährst du, wenn du dem Arduino gleich in PHP mundgerechte Stückchen Daten zuschmeißt.
Du müsstest alle benötigten Daten als GET-Argumente übergeben können.

Im Zweifelsfall lieber 3x soviel Code in PHP als auf dem Arduino – 2k RAM sind WIRKLICH wenig :wink:

Schweif mal etwas weiter aus und erzähle uns, was du im Endeffekt erreichen möchtest, dafür gibt es sicherlich ne gute und elegante Lösung :slight_smile:

Hallo,

ok ich will mal versuchen es ein bisschen transparenter zu machen was ich erreichen möchte.

Es geht eigentlich um eine simple Aquariumsteuerung.
Dabei sollen vorgegebene Werte die in einer Datenbank stehen den Arduino steuern

Z.B.: Einschaltzeit Licht 14:00 Uhr und Ausschalten 22:00 Uhr.
Vorgabe_Temp der Becken: z.B. min 24 und max 26 Grad.
oder auch Wasserstand

Der Arduino soll also x-mal am Tag die Datenbank lesen und anhand der Daten dann enstprechende Funktionen ausführen.
Weiter sollen dann vom Arduino eingelesenen Daten der Sensoren, z.B, Wasserstand (soll über einen Ultraschall-HC-SR-04) oder PH-Werte (über atlas-PH-Shield und PH-Sensor), oder auch Temps in die Datenbank eingetragen werden.

Das schreiben in die Datenbank leuchtet mir noch ein (also wie ich Werte an eine URL übergebe und die dann vom PHP-Script ausgelesen und in die DB geschrieben werden).
Ich begreife aber das lesen nicht, also wenn ich vom Arduino eine Verbindung zum Webserver auf dem die DB läuft herstelle und diesem Daten übermittle (z.B. lese die Felder xyz in der DB abc) kapiere ich noch, wie dann jedoch diese daten durch die offene http-verbindung wieder an den Arduinio gehen sollen… phooo da steige ich völlig aus.

Die Rückgabedaten von PHP könntest du mit einem einfachen print zurückgeben. Vielleich sogar gleich binär sodass du sie wirklich nur noch auf nen int32 casten musst :)

Am besten ist es wahrs. wenn du dir mal einen Telnet Clienten organisierst (apt-get install telnet) auf dem Raspi, und dann mit telnet 127.0.0.1 80 mal versuchst "von Hand" mit dem Raspi HTTP zu sprechen.

Da dürftest du relativ schnell Ergebnisse und das Verständnis erzielen :)

Viele Grüße, TObias

Manawyrm:
Die Rückgabedaten von PHP könntest du mit einem einfachen print zurückgeben.
Vielleich sogar gleich binär sodass du sie wirklich nur noch auf nen int32 casten musst :slight_smile:

Am besten ist es wahrs. wenn du dir mal einen Telnet Clienten organisierst (apt-get install telnet) auf dem Raspi, und dann mit
telnet 127.0.0.1 80 mal versuchst “von Hand” mit dem Raspi HTTP zu sprechen.

Da dürftest du relativ schnell Ergebnisse und das Verständnis erzielen :slight_smile:

Viele Grüße,
TObias

hallo,

anhören tut sich das gut.
habe grade telnet installiert
aber mit
telnet 127.0.0.1 80 bekomme ich keinen connect und auf 192.168.2.104 bekomme ich auch keinen
der webserver läuft aber zu 100% auf 192.168.2.104 und antwortet dort auch

kannst Du mir das mit dem Rückgabewert Binär etc. etwas genauer erklären?
wie das gehen soll…gibt es dazu Beispiele?

da ich nicht der Programmierprofi bin brauch ich meist etwas Anschaungsmaterial :frowning:

telnet 127.0.0.1 80 bekomme ich keinen connect und auf 192.168.2.104 bekomme ich auch keinen

Öhh. Wie definierst du, keinen Connect? Das muss gehen. Kommt wirklich ne Fehlermeldung? oder einfach nichts?
Du musst anfangen. Schick mal “GET / HTTP/1.1” dann Enter dann “Host: localhost” dann zwei mal Enter.

Viele Grüße,
Tobias

Manawyrm:
Öhh. Wie definierst du, keinen Connect? Das muss gehen. Kommt wirklich ne Fehlermeldung? oder einfach nichts?
Du musst anfangen. Schick mal “GET / HTTP/1.1” dann Enter dann “Host: localhost” dann zwei mal Enter.

Viele Grüße,
Tobias

das kommt

GET / HTTP/1.1

HTTP/1.1 400 Bad Request
Date: Mon, 21 Apr 2014 13:56:49 GMT
Server: Apache/2.2.22 (Debian)
Vary: Accept-Encoding
Content-Length: 301
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.

</p>
<hr>
<address>Apache/2.2.22 (Debian) Server at 127.0.1.1 Port 80</address>
</body></html>
Connection closed by foreign host.

ich bekomme also eine Antwort aber da muss ich schon fix sein sonst bricht die Verbindung ab

Ähh, das Host: localhost ist wichtig ;)

ja ok,
aber das ändert auch nicht viel oder?

siehe ergebnis

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET / HTTP/1.1
Host: localhost

HTTP/1.1 200 OK
Date: Mon, 21 Apr 2014 14:05:50 GMT
Server: Apache/2.2.22 (Debian)
Last-Modified: Wed, 09 Apr 2014 19:08:42 GMT
ETag: "5fd77-b1-4f6a0d4371aa8"
Accept-Ranges: bytes
Content-Length: 177
Vary: Accept-Encoding
Content-Type: text/html
X-Pad: avoid browser bug

<html><body><h1>It works!</h1>
<p>This is the default web page for this server.</p>
<p>The web server software is running but no content has been added, yet.</p>
</body></html>
Connection closed by foreign host.

dann habe ich es noch mit der php-seite probiert

Escape character is '^]'.
GET / HTTP/1.1
HOST: localhost/test_db/db_conect.php

HTTP/1.1 400 Bad Request
Date: Mon, 21 Apr 2014 14:08:58 GMT
Server: Apache/2.2.22 (Debian)
Vary: Accept-Encoding
Content-Length: 323
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.

</p>
<hr>
<address>Apache/2.2.22 (Debian) Server at localhost/test_db/db_conect.php Port 80</address>
</body></html>
Connection closed by foreign host.

Hallo noch jemand da?

bin hier fast am verzweifeln da ich eine Lösung suche mit der ich Daten aus der DB lese und im Arduino verarbeiten muss/sollte.

Die Lösung des mysql_connectors wurde ja schon nicht empfohlen wegen extremen Speicherbedarf ...

wie bekomme ich sonst noch die Daten?

gibt es dazu eine Anleitung? finde im Netz nur Anleitungen wie man Daten vom Arduino aus in die mysql schreibt (über PHP-Script) das funktioniert auch sehr gut bei mir.

ich brauche aber das Lesen auch noch? und begreife nicht wie man in php dann an die offene http-Vebindung Daten an den Arduino zurücksendet und der diese dann auch liest

wäre wirklich froh wenn mir hier jemand das näher erklären kann

Viele Grüße Jürgen

GET / HTTP/1.1 HOST: localhost/test_db/db_conect.php

Neh,

GET /test_db/db_conect.php HTTP/1.1 Host: localhost

wäre richtig ;)

ah
ok
also wenn ich das eingebe

dann spuckt er das aus

Connected to localhost.
Escape character is '^]'.


GET /test_db/db_conect.php HTTP/1.1
Host: localhost

HTTP/1.1 200 OK
Date: Mon, 21 Apr 2014 15:07:35 GMT
Server: Apache/2.2.22 (Debian)
X-Powered-By: PHP/5.4.4-14+deb7u8
Vary: Accept-Encoding
Content-Length: 701
Content-Type: text/html



<b>Notice</b>:  Undefined index: func in <b>/var/www/test_db/db_conect.php</b> on line <b>14</b>



<b>Notice</b>:  Undefined index: TEMP in <b>/var/www/test_db/db_conect.php</b> on line <b>15</b>



<b>Notice</b>:  Undefined index: HUM in <b>/var/www/test_db/db_conect.php</b> on line <b>16</b>



<b>Notice</b>:  Undefined index: water_1 in <b>/var/www/test_db/db_conect.php</b> on line <b>17</b>



<b>Notice</b>:  Undefined index: TEST in <b>/var/www/test_db/db_conect.php</b> on line <b>19</b>

das ist func ===> func

<b>Fatal error</b>:  Call to undefined function func() in <b>/var/www/test_db/db_conect.php</b> on line <b>27</b>

Connection closed by foreign host.

komisch ist das er trotzdem in die db schreibt und liest

hier das php-script

<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
// Neues Datenbank-Objekt erzeugen
$db = @new mysqli( '192.168.2.104', 'pi', 'mainpass', 'test' );
// Pruefen ob die Datenbankverbindung hergestellt werden konnte
/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}


        $func                   =($_GET['func']);
        $TEMP                   =($_GET['TEMP']);
        $HUM                    =($_GET['HUM']);
        $water_1               =($_GET['water_1']);
        //$W_1_Dist             =($_GET['W_1_DIST']);
        $TEST                   =($_GET['TEST']);


    $DATUM = date("Y-m-d H:i:s");
    $funct = "func";
    //$water_1 = water_1;
    $funct = $funct.$func;
    echo "das ist func ===> ". $funct;
    echo $funct($TEMP, $HUM, $water_1, $DATUM, $db, $TEST);



function func1($TEMP, $HUM, $water_1, $DATUM, $db, $TEST)
{
        $sql = 'INSERT INTO test_db(temp,hum,water_1, datumzeit) VALUES (?,?,?,?)';
        //$mysqli->query($query1);

        $eintrag = $db->prepare( $sql );
        $eintrag->bind_param( 'ddds',$TEMP, $HUM, $water_1, $DATUM );
        $eintrag->execute();



        if ($TEST == 1 ) {
                echo "test ist gesetzt";
                                $sql = 'SELECT `temp`, `hum`,`water_1` , `datumzeit` FROM `test_db`';
                                $ergebnis = $db->query( $sql );
                                // Anzahl gefunde Datensaetze ausgeben
                                //echo "<p>Es wurden " .$ergebnis->num_rows. " Eintr&auml;ge gefunden.</p$
                                // Ergebnisse ausgeben


                                while ($zeile = $ergebnis->fetch_object())
                                {
                                        echo  $zeile->temp. "  Luftfeuchte ==> " .$zeile->hum. "wasserhoe$
                                        //echo  $zeile->temp "
";
                                        return $zeile->water_1;
                                }


                }else
                {
                        echo "test ist nicht gesetzt";
                }

}

$db->close();
?>

Zu allererst: Nimm dein Passwort aus dem Post raus ;)

Manawyrm: Zu allererst: Nimm dein Passwort aus dem Post raus ;)

shit, ja habe ich schon... vor lauter Verzweiflung habe ich zu schnell gepostet

und was meinst Du zu dem script?

Nun, das sind die Fehler, die dein PHP Script rausgibt.

Die Undefines kommen natürlich, weil du die GET Parameter nicht mit übergibst, die du da ausließt. Müsstest also hinter der URL noch mit ?parameter=wert¶meter2=wert2 übergeben.

Der Undefined Funktion-Call kommt wegen deines Rechtschreibfehlers.

Manawyrm: Nun, das sind die Fehler, die dein PHP Script rausgibt.

Die Undefines kommen natürlich, weil du die GET Parameter nicht mit übergibst, die du da ausließt. Müsstest also hinter der URL noch mit ?parameter=wert¶meter2=wert2 übergeben.

Der Undefined Funktion-Call kommt wegen deines Rechtschreibfehlers.

anscheinend ist es im script jetzt ok

das gebe ich (siehe code) ein und das kommt dabei rauss

 telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET /test_db/db_conect_2.php?TEMP=22&HUM=56&water_1=6.05&func=1&TEST=1 HTTP/1.1
Host: localhost

HTTP/1.1 200 OK
Date: Mon, 21 Apr 2014 15:38:44 GMT
Server: Apache/2.2.22 (Debian)
X-Powered-By: PHP/5.4.4-14+deb7u8
Vary: Accept-Encoding
Content-Length: 173
Content-Type: text/html

das ist func ===> func1 das ist temp 22 
das ist hum 56 
das ist dfate 2014-04-21 17:38:53 
test ist gesetzt24.00  Luftfeuchte ==> 0.00wasserhoehe ==> 0.00
0.00Connection closed by foreign host.

Ich übergebe z.B "1" bei func in der URL um dann im PHP-script zu entscheiden welche funktion benötigt wird.

ich hoffte so alles in eine php-datei unterbringen zu können also sämtliche SQL-inserts, updates und lesen

da wie ich nun von dir erfuhr die variablen die in der URL übergeben werden wohl immer angegeben werden müssen lasse ich die halt dann leer oder benutze sie bei Gebrauch.

wollte zumindest das es auf der Webserver-seite nicht zu viele scripts gibt

oder ist das nicht gut?

und wie bekomme ich jetzt eine sql-abfrage und das Ergebnis zum arduino?

ps. dass das Ergebnis (noch) nicht stimmt was er aus der DB liest, ist klar, da dort nur der erste Datensatz gelesen wird und nicht der, der als letztes geschrieben wurde!

wollte zumindest das es auf der Webserver-seite nicht zu viele scripts gibt

Ist doch kein Problem. Mach ruhig viele.

und wie bekomme ich jetzt eine sql-abfrage und das Ergebnis zum arduino?

Du ließt die Daten aus und schickst sie einfach als echo raus. Musst dann auf dem Arduino mit C-Stringmanipulationen arbeiten #brechreiz

Manawyrm:

wollte zumindest das es auf der Webserver-seite nicht zu viele scripts gibt

Ist doch kein Problem. Mach ruhig viele.

und wie bekomme ich jetzt eine sql-abfrage und das Ergebnis zum arduino?

Du ließt die Daten aus und schickst sie einfach als echo raus. Musst dann auf dem Arduino mit C-Stringmanipulationen arbeiten #brechreiz

ach so, jetzt verstehe ich langsam. als ich in der Telnet-session mit return $wert; was zurück gegeben habe, sah ich dieser auch das Ergebnis.

wenn ich also meine db-Abfrage in einen String packe (geht das überhaupt?) dann kann ich diese durch die offene http-verbindung auf der anderen seite (also beim arduino) auslesen.

Da ich aber bestimmt 3 Datenfelder in der DB abfrage, brauch ich ja fast ein array oder ich übergebe mehrere einzelnen strings.

gibt es irgendwo ein Beispiel wie man solch eine Rückgabestring auf Adruino-Seite wieder sauber zerlegt? kann man ein array zurück geben? wie macht man das am besten? bräuchte mal ein Beispiel damit ich sehe wie das funktioniert und aufgebaut ist.