SQL Datensätze über PHP mit dem Arduino auslesen.

Guten Tag liebe Community,

wir würden gerne mit dem Arduino Daten aus unserer Datenbank auslesen und reinschreiben. Das reinschreiben der Daten klappt einwandfrei, allerdings bekommen wir es nicht hin, mit dem Arduino auszulesen. Kann mir jemand einen Link o.Ä. zukommen lassen zu einem Programm Code, an dem man sich lang hangeln kann? Also am besten mit dem PHP und Arduino Code.

Danke im Voraus, Fabian

Ist es eine bezüglich der abgefragten Felder konstante Abfrage oder sind die Art und Anzahl der Parameter variabel?

Ansonsten die Felder in php in eine lange Textzeile mit einem festen Trennzeichen (z.B. ;) und Zeilenvorschub hinten dran. Also so wie eine CSV-Datei.

Auf dem Arduino (welchen?) zeilenweise einlesen und per strtok aufteilen. Infos zu strtok und Zeichenketten gibt es hier.

Es gibt auch eine Lib für Direktzugriffe auf MySQL.

Zu den Bestandteilen gibt es genug Beispiele im Netz. Beim Einlesen der Zeilen kann man sich auch an Beispielen für die Serielle Übertragung orientieren.

Gruß Tommy

Auf dem Arduino (welchen?) zeilenweise einlesen und per strtok aufteilen. Infos zu strtok und Zeichenketten gibt es hier.

sehe ich auch so. Der konkrete Microcontroller fehlt uns für eine Hilfestellung.

Im Falle eines Uno/Nano/Mega soll das PHP ein CSV ausgeben und das zerteilst mit strtok.

Im Falle eines ESP8266 (oder stärker), lasst dir von PHP ein JSON ausgeben und parst das JSON mi der JSON Library.

Hallo zusammen, erstmal danke für die schnellen Antworten.

Wir arbeiten mit einem Arduino Mega. Anfangs haben wir es auch per Direktzugriff versucht, hat auch mit einzelnen Werten au der DB gut geklappt. Allerdings hatten wir Probleme als es um Verknüpfungen von Tabellen (joins) ging, sodass wir weiter recherchiert haben und auf php gekommen sind. Man muss dazu erwähnen, das wir absolute Neulinge im Bereich Datenbank/Server sind.

Der Arduino + DB soll quasi als Zugangsberechtigung dienen und aus verschiedenen Tabellen die nötigen Informationen rauslesen. Ich habe aktuell leider keinen Programmcode hier, werde diesen aber nachreichen, sobald ich zuhause am Laptop bin.

Gruß, Fabian

Anbei die INSERT Befehle:

Arduino

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xA8, 0x61, 0x0A, 0xAE, 0x65, 0xC1 };                // MAC-ADRESSE Ethernet-Shield
IPAddress server ( 192, 168, 00, 000 );                            // IP des MySQL Servers 

IPAddress ip( 192,168,000,00 );                                     // IP des Servers

EthernetClient client;

// Globale Variablen
 bool printWebData = true;
 long int ma_id;
 String vn; 
 String nn; 
 long int rfid; 

void setup()
{
 Serial.begin(9600);
 while (!Serial)
 {
   
 }
 Ethernet.begin(mac, ip);
}

void loop()
{
 delay(1000);
 Serial.println("Verbinden...");
 Serial.print("IP = ");
 Serial.print(ip);
 Serial.print("Server = ");
 Serial.print(server);

 if (client.connect(server, 80)) 
 {
 ma_id = 1234;
 vn = "Max";
 nn = "Mustermann";
 rfid = 56789;
 
 Serial.print("GET /cmp/data.php?Maschinen_ID=");
 Serial.print(ma_id);
 Serial.print("&Vorname=");
 Serial.print(vn);
 Serial.print("&Nachname=");
 Serial.print(nn);
 Serial.print("&RFID=");
 Serial.print(rfid);
 Serial.println(" HTTP/1.1");
 Serial.print("Host: ");
 Serial.println(server);
 Serial.println("Connection: close");
 Serial.println();

 client.print("GET /cmp/data.php?ma_id=");
 client.print(ma_id);
 client.print("&vn=");
 client.print(vn);
 client.print("&nn=");
 client.print(nn);
 client.print("&rfid=");
 client.print(rfid);
 client.println(" HTTP/1.1");
 client.print("Host: ");
 client.println(server);
 client.println("Connection: close");
 client.println();
 }
 else
 {
   Serial.println("connection failed");
 }
  while (client.connected()) {
   int len = client.available();
   if (len > 0) {
     byte buffer[80];
     if (len > 80) len = 80;
     client.read(buffer, len);
     if (printWebData) {
       Serial.write(buffer, len);
     }
   }
 }

 if (!client.connected()) {
   Serial.println("Disconnecting...");
   Serial.println();
   client.stop();
   delay(10000);
 }
}

insert.php:

<form action="data.php" method="get">
Maschinen_ID: <input type="text" name="ma_id">

Vorname: <input type="text" name="vn">

Nachname: <input type="text" name="nn">

RFID: <input type="text" name="rfid">

<input type="submit">
</form>

data.php:

<?php
$dbname = 'cmpsz100';
$dbuser = 'sa';
$dbpass = 'cmpsz100';
$dbhost = 'localhost';

$connect = @mysqli_connect($dbhost,$dbuser,$dbpass,$dbname);

if(!$connect){
echo "Error: " . mysqli_connect_error();
exit();
}

echo "Connection Success!

";

$ma_id = $_GET["ma_id"];
$vn = $_GET["vn"];
$nn = $_GET["nn"];
$rfid = $_GET["rfid"];
$now = date("Y-m-d H:i:s");

$query = "INSERT INTO Mitarbeiter (Maschienen_ID, Vorname, Nachname, RFID, Datum) VALUES ('$ma_id','$vn','$nn','$rfid','$now')";
$result = mysqli_query($connect,$query);

echo "Insertion Success!
";

?>

code.txt (2.02 KB)

Setze Deinen Code bitte in Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
Dann ist er auch auf mobilen Geräten besser lesbar.
Das kannst Du auch noch nachträglich ändern.

Joins zur Abfrage mit Direktzugriff gehen übrigens problemlos. Ich glaufe die fehlenden SQL-Kenntnisse sind eher Euer Problem.

Gruß Tommy

Hab ich gemacht.

Tommy56: Joins zur Abfrage mit Direktzugriff gehen übrigens problemlos. Ich glaufe die fehlenden SQL-Kenntnisse sind eher Euer Problem.

Das kann natürlich sein :-D. Allerdings hat das ganze mit dem Befehl in MySQL funktioniert.

Kann mir jemand einen Link o.Ä. zukommen lassen zu einem Programm Code, an dem man sich lang hangeln kann? Also am besten mit dem PHP und Arduino Code.

Einen code kann ich dir leider nicht liefern.. Aber wir haben dunnemals den BeanCan Server verwendet, um Unmengen Messwerte aufzunehmen und zu verarbeiten. Auch wenn da viel von JS steht, dem ist es egal, ob das von Arduino, oder wo auch immer her kommt.

fav3_20: Allerdings hat das ganze mit dem Befehl in MySQL funktioniert.

Dann muss es auch mit dem Direktzugriff funktionieren, wenn ihr den Zugriff auf den DB-Server habt.

Euer PHP-DB-Zugriff ist übrigens in keiner Weise vor SQL-Injection geschützt. Schaut Euch mal prepared Statements an. Eine Prüfung, ob alle notwendigen Felder gefüllt sind, fehlt auch.

Gruß Tommy

fav3_20: Anbei die INSERT Befehle:

Das geht mit der mysql-lib sehr gut. Macht ca. 10 Codezeilen

SQL injection war bereits angesprochen. Mag im lokalen z.B. mittels VLAN abgekoppelten Netz nicht ganz so die Rolle spielen...

Aus sicherheitspolitischer Sicht schaffst Du Dir mit PHP und nem Webserver zusätzlichen Wartungsaufwand.

Du hast ursprünglich von joins gesprochen, die nicht mit der mysql-lib liefen.

wir würden gerne mit dem Arduino Daten aus unserer Datenbank auslesen und reinschreiben. Das reinschreiben der Daten klappt einwandfrei, allerdings bekommen wir es nicht hin, mit dem Arduino auszulesen.

Das wäre jetzt mein Ansatz. Dazu müsste man aber wissen, was das Problem ist und nicht die inserts aufdröseln.

Beschreib doch mal die Tabellen und das join - bitte nicht mit realen Daten

Also hier ist das Folgende Programm um direkt auf SQL zu zu greifen.

#include <Ethernet.h> // Einbindung Bibliothek des Ethernet shields
#include <MySQL_Connection.h> // Einbindung der MySQL Bibliothek
#include <MySQL_Cursor.h>
 
byte mac_addr[] = { 0xA8, 0x61, 0x0A, 0xAE, 0x65, 0xC1 }; // Mac des Arduinos 
IPAddress ip(192,168,0,0);   // IP des Arduinos 

 
IPAddress server_addr(192, 168, 0, 0);  // IP des MySQL Servers  
char user[] = "sa";              // MySQL Benutzer login  
char password[] = "cmpsz100";        // MySQL Benutzer Passwort

String daten;
 
// Beispiel Befehl query 
const char QUERY_POP[] = "SELECT MA.Mitarbeiter_ID FROM cmpsz100.mitarbeiter AS MA WHERE MA.RFID_Nummer = '1235698'";
//"SELECT MA.Mitarbeiter_ID, MAU.Gueltigkeit, MASCHU.Maschinen_ID, MAU.Unterweisung_ID, MASCHU.Abteilungs_ID FROM [cmpsz100].[dbo].[Mitarbeiter] AS MA JOIN [cmpsz100].[dbo].[Mitarbeiter Unterweisung] AS MAU ON MA.Mitarbeiter_ID = MAU.Mitarbeiter_ID JOIN [cmpsz100].[dbo].[Maschinenunterweisung] AS MASCHU ON MAU.Unterweisung_ID = MASCHU.Unterweisungs_ID JOIN [cmpsz100].[dbo].[Maschinenunterweisung] as MASCHU ON MASCHU.Abteilungs_ID = MAU.Abteilungs_ID WHERE MA.RFID_Nummer='1235698' AND MASCHU.Maschinen_ID = '111106' "; 
char query[128];

EthernetClient client; 
MySQL_Connection conn((Client *)&client); 
// Create an instance of the cursor passing in the connection
MySQL_Cursor cur = MySQL_Cursor(&conn);
 
void setup() { 
   Serial.begin(9600); 
   while (!Serial); // warte auf einen Seriellen Port zur Verbindung 
   Ethernet.begin(mac_addr); 
   Serial.println("Connecting..."); 
   if (conn.connect(server_addr, 3306, user, password)) { 
     delay(1000); 
   } 
   else 
     Serial.println("Connection failed."); 
} 
 
 
void loop() {
  delay(1000);

  Serial.println("> Running SELECT with dynamically supplied parameter");

  // Initiate the query class instance
  MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
  // Supply the parameter for the query
  // Here we use the QUERY_POP as the format string and query as the
  // destination. This uses twice the memory so another option would be
  // to allocate one buffer for all formatted queries or allocate the
  // memory as needed (just make sure you allocate enough memory and
  // free it when you're done!).
  sprintf(query, QUERY_POP, 9000000);
  // Execute the query
  cur_mem->execute(query);
  // Fetch the columns and print them
  column_names *cols = cur_mem->get_columns();
  for (int f = 0; f < cols->num_fields; f++) {
    Serial.print(cols->fields[f]->name);
    if (f < cols->num_fields-1) {
      Serial.print(',');
    }
  }
  Serial.println();
  // Read the rows and print them
  row_values *row = NULL;
  do {
    row = cur_mem->get_next_row();
    if (row != NULL) {
      for (int f = 0; f < cols->num_fields; f++) {
        Serial.print(row->values[f]);
        //daten = row->values[f];
        //Serial.print(daten);
        if (f < cols->num_fields-1) {
          Serial.print(',');
        }
      }
      Serial.println();
    }
  } while (row != NULL);
  // Deleting the cursor also frees up memory used
  delete cur_mem;
}

Mit den einfachen Werten unktioniert das, sobald wir allerdings wollen, das der Arduino den auskommentierten Befehl ausführt, passiert nichts mehr.

Übrigens haben wir das ganze mit dem Arduino & PHP hinbekommen. Allerdings müssen wir jetzt noch gucken, wie wir den Char auseinander brechen.

Danke für die schnelle Hilfe.

Gruß,
Fabian

Habt Ihr tatsächlich eine Tabelle "Mitarbeiter Unterweisung" mit einem Leerzeichen im Tabellennamen?

Die Syntax von MS-Access ist nicht für MySQL direkt geeignet.

Gruß Tommy

fav3_20: Also hier ist das Folgende Programm um direkt auf SQL zu zu greifen.

Danke - schau ich mir an. Kann das derzeit nicht nachbauen. Bitte Geduld.

Ich sagte doch keine Echtdaten...

char user[] = "s";              // MySQL Benutzer login  
char password[] = "c";        // MySQL Benutzer Passwort

Das könnte Dir auf die Füsse fallen:

char query[128];

Das was tommy56 schon gesagt hat, kann ich nur bekräftigen. Keine Spaces im Tabellenname!

Vll. ist's ein 255er?