Werte aus einer php Seite einlesen

Hallo!
Ich möchte von einer PHP Seite Werte in Arduino einlsen und habe dazu folgendes versucht:

if (WiFi.status() == WL_CONNECTED) {
   
   if (!client.connect(host, 80)) {
    Serial.println("connection failed");
    return;
  }
  
 
   //Werte von DAtenbank holen - beginn

   
   url = "/settings.php?board="+String(id);
   Serial.println(url);

   
   client.print(String("GET ") + url + " HTTP/1.1\r\n" +
                 "Host: " + host + "\r\n" + 
                 "Connection: close\r\n\r\n");
    // start waiting for the response             
    unsigned long lasttime = millis();
    while (!client.available() && millis() - lasttime < 1000) {delay(1);}   // wait max 1s for data
    // Read all the lines of the reply from server and print them to Serial
    while(client.available()){
      //char readchar = client.read();
      //Serial.print(readchar);
      String line = client.readString(); //Until('\r');
      Serial.println(line);
      //Serial.print(line.substring(204));

       String text = line.substring(204);
        char copy[500];
        text.toCharArray(copy, 500);
        
        char *ptr;
        ptr = strtok(copy, ";");
       y=0;
      while(ptr != NULL) {
        y++;
        Serial.println(z);
        if (y==2) {
        //pfad
        pfad = String(ptr);
        }
        if (y==3) {
        //hoehe
        hoehe = atof(ptr);
        }
        if (y==4) {
        //faktor
        faktor = atof(ptr);
        }
        if (y==5) {
        //zeit in minuten
        sleepSeconds = 60 * atof(ptr);
        if (sleepSeconds == 0) { sleepSeconds = 60; }
        }
        if (y==6) {
        //host
         host = String(ptr);
        }
        if (y==7) {
        //standort
         standort = String(ptr);
        }
        if (y==8) {
        //hoehe_sensor
         hoehe_sensor = atof(ptr);
        }
        if (y==9) {
        //max. Liter
         maxliter = atof(ptr);
        }

         if (y==10) {
        //messgerät
         messgeraet = String(ptr);
        }
        
        printf("Abschnitt gefunden: %s\n", ptr);
        // naechsten Abschnitt erstellen
        ptr = strtok(NULL, ";");
      }
    }

    client.stop(); //stop client

Das Ergebnis der PHP Seite sieht wie folgt aus:

;/arduino/zisterne;89.0;42.553191489361700;30.00000;domain.at;Zisterne;109.00;3000;Ultrasensor;

Ich habe bemerkt, dass aber beim Aufrufen der Seite dies nicht immer gleich aussieht.
Wenn ich mir die Ergebnisse von Serial.println(line); ansehe bekomme ich einmal:

HTTP/1.1 200 OK
Date: Thu, 15 Oct 2020 15:13:11 GMT
Server: Apache
X-Powered-By: PHP/5.6.40
Vary: Accept-Encoding
Content-Length: 97
Connection: close
Content-Type: text/html; charset=UTF-8

;/arduino/zisterne;89.0;42.553191489361700;30.00000;domain.at;Zisterne;109.00;3000;Ultrasensor;

und es kann auch vorkommen dass ich folgendes Ergebnis bekomme

HTTP/1.1 200 OK
Date: Thu, 15 Oct 2020 15:12:49 GMT
Server: Apache
X-Powered-By: PHP/5.6.40
Vary: Accept-Encoding
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

61
;/arduino/zisterne;89.0;42.553191489361700;30.00000;domain.at;Zisterne;109.00;3000;Ultrasensor;

Somit passt der Startwert von 204 in der Zeile String text = line.substring(204); nicht immer.

Daher wollte ich fragen warum dieser Fehler auftritt und wie ich dieses Problem lösen könnte.
Vielen Dank für jede Antwort

Du willst doch nur den HTML body haben. Lies ab der leerzeile!

such nach ;/arduino und fang dann an.

Danke für die Antworten und Hinweise.
Dies ist o.k. nur wie kann es sein, dass der eingelesene Code unterschiedlich ist und wie könnte man dies verhindern.
Vielen Dank nochmals

Dazu müsste man Dein PHP-Programm kennen und wie Du es aufrufst.

Gruß Tommy

Hallo!
Danke für die Antwort.
Hier mein php Code:

<?php
include "db.php";
$pdo = new PDO('mysql:host='.$Server.';dbname='.$dbname,$user,$passwort);
$id = $_GET["board"];
$statement = $pdo->prepare("SELECT * FROM einstellungen where board = ?");
$statement->execute(array($id));
$row = $statement->fetch();
echo ";".$row['pfad'].";".$row['hoehe'].";".$row['faktor'].";".$row['zeit'].";".$row['host'].";".$row['standort'].";".$row['hoehe_sensor'].";".$row['max'].";".$row['messgeraet'].";";
?>

lg

und der include?
und wie kanst du uns darlegen, dass im $row['pfad'] nicht auch fallweise ein ;61LF;arduino drinnensteht???

Dein PHP gibt halt unter bestimmten Konstellationen diesen 61LF aus. Wie sollen wir das aus dem unvollständigen 5 Zeiler erkennen.

Mensch das ist doch nicht dein erster Post.

Da dürften die user/passwd des Datenbankzugriffs drin stehen.

Gruß Tommy

Danke für die Antwort.
Ja im include stehen die Zugangsdaten für den Datenbankzugriff.
Wie kann es zu den ;61LF;arduino kommen?
Der Pfad steht in einer mysql Datenbank in einem varchar(200) Feld.

Bitte um weitere Infos, wenn ich etwas vergessen habe.
Danke

Ist noch unbeantwortet:

und wie kanst du uns darlegen, dass im $row['pfad'] nicht auch fallweise ein ;61LF;arduino drinnensteht???

Und wenn du das PHP nicht debuggen kannst, dann must du halt so vorgehen wie ElEspanol vorgeschlagen hat.

haiflosse:

echo ";".$row['pfad'].";".$row['hoehe'].";".$row['faktor'].";".$row['zeit'].";".$row['host'].";".$row['standort'].";".$row['hoehe_sensor'].";".$row['max'].";".$row['messgeraet'].";";

lg

noiasca:
und der include?
und wie kanst du uns darlegen, dass im $row['pfad'] nicht auch fallweise ein ;61LF;arduino drinnensteht???

Hier will ich dem TO mal beispringen.
Das echo beginnt mit einem ; somit ist ein ;61 im Pfad ausgeschlossen, denn dann müsste ein ;; ankommen.
Als Alternative könnte in [pfad] ein 61\LF am Anfang drin stehen. Ohne jegliche Semikolon.
@haiflosse:

Serial.println(line);

Ich würde gerne wissen, was tatsächlich kommt.
Prüfe auf die Leerzeile zwischen Header und Body und gebe ab dann alles eingelesene als reinen bytewert auf dem Monitor aus.
Damit erkennst Du auch Steuerzeichen.
ascii dec(61) wäre das = Zeichen

Danke für die Antwort.
Leider habe ich das ganze nicht ganz verstanden.
Warum kann ein 61\LF am Anfang stehen. Es steht im Pfad immer /arduino/zisterne drinnen?

Wie kann ich das tatsächliche Ergebnis auf Leerzeichen prüfen?
Ich habe die Ausgabe der php Dateien im Posting 1 eingefügt, oder fehlen da noch Informationen.
Danke und lg

wodurch sollte die Zeile

Serial.println(line);

Fallweise Steuerzeichen in dec ausgeben? Das ist doch unlogisch. Was die Byteweise Ausgabe zigen würde, obs ein 61LF oder ein 61CRLF ist. Ja wäre interessant, aber obs weiterhilft?

Ich bleib dabei - das 61 kommt aus der PHP Ausgabe. Das $pfad Argument nehme ich. Ich sehe nicht den ganzen PHP Code, also kommts aus dem include. Und wenn das nicht lösbar ist, würde ich so vorgehen wie ElEspanol vorgeschlagen hat. Dass das Überlesen von 204 Zeichen so und so bedenklich ist, brauchen wir hoffentlich nicht diskutieren.

haiflosse:
Leider habe ich das ganze nicht ganz verstanden.
Warum kann ein 61\LF am Anfang stehen. Es steht im Pfad immer /arduino/zisterne drinnen?

Das ist die Frage.
Das = wird z.B. genutzt, wenn eine Zeile umgebrochen wird.

Wie kann ich das tatsächliche Ergebnis auf Leerzeichen prüfen?
oder fehlen da noch Informationen.

Ja.
Der Code, wie Du das einliest.

Danke für die Antwort.
die db.php sieht wie folgt aus:

<?php
$Server="mysql.domain.xx";
$dbname = "db_arduino";
$user = "benutzer";
$passwort = "pwd";
?>

Dachte ich habe den code zum Einleisen zu Beginn angegeben.

if (WiFi.status() == WL_CONNECTED) {
   
   if (!client.connect(host, 80)) {
    Serial.println("connection failed");
    return;
  }
  
 
   //Werte von DAtenbank holen - beginn

   
   url = "/arduino/zisterne/settings.php?board="+String(id);
   Serial.println(url);

   
   client.print(String("GET ") + url + " HTTP/1.1\r\n" +
                 "Host: " + host + "\r\n" + 
                 "Connection: close\r\n\r\n");
    // start waiting for the response             
    unsigned long lasttime = millis();
    while (!client.available() && millis() - lasttime < 1000) {delay(1);}   // wait max 1s for data
    // Read all the lines of the reply from server and print them to Serial
    while(client.available()){
      //char readchar = client.read();
      //Serial.print(readchar);
      String line = client.readString();

Oder habe ich das falsch verstanden und es ist etwas anderes gemeint?
Danke und lg

noiasca:
wodurch sollte die Zeile
Serial.println(line);
Fallweise Steuerzeichen in dec ausgeben? Das ist doch unlogisch.

.print gibt m.E. keine Steuerzeichen aus - Das könnte der Knackpunkt sein.
Das = ist ebenfalls eine Ankündigung, das es in der nächsten Zeile weitergeht.

Ich bleib dabei - das 61 kommt aus der PHP Ausgabe. Das $pfad Argument nehme ich. Ich sehe nicht den ganzen PHP Code, also kommts aus dem include.

Dem trau ich noch nicht so recht.
Alternativ wäre das mitschneiden am Server eine Option.

würde ich so vorgehen wie ElEspanol vorgeschlagen hat. Dass das Überlesen von 204 Zeichen so und so bedenklich ist, brauchen wir hoffentlich nicht diskutieren.

Ohne Frage!

Ansonsten mal mit Wireshark den Netzwerktransfer mitschneiden.

Gruß Tommy

haiflosse:

     //char readchar = client.read();

//Serial.print(readchar);
     String line = client.readString();




Oder habe ich das falsch verstanden und es ist etwas anderes gemeint?

Alles richtig!
Nicht alles was Du einliest wird "printable" sein.
Der auskommentierte Teil muss jetzt so geändert werden, das Du jedes byte als (hexa-)dezimalcode ausgibst.
z.B. bekommst Du ein \t - TAB - DEC 9 gar nicht zu sehen. Genauso ein ESC - DEC 27 u.s.w.
Alles das was nicht sichtbar ist, braucht man aber um Dir weiterhelfen zu können.

Danke für die Antwort.
Wie kann ich alles sichtbar machen.
Danke

Mit

Serial.print(readchar,HEX);

Gruß Tommy