Go Down

Topic: String/Array auflösen bei Webabfrage (Read 935 times) previous topic - next topic

plaubel

Moinsen!

Ich habe da ein "interessantes" Problem, bei dem mir nicht klar ist, warum das so ist und für mich ist es irgendwie unlogisch. Aber ich bin ja noch Greenhorn :smiley-mr-green:


Ich habe eine Webabfrage, der Ardu spricht in regelmäßigen Abständen einen Server an und holt den Inhalt einer Textdatei. Diese hat als Inhalt eine 6-stellige Zahlenkombination. An Hand der Kombination soll der Ardu nun reagieren.

Das tut er aber komischerweise nur mit der Funktion string.endsWith, alle anderen Abfragen werden ignoriert, bzw ergeben nur Grütze.

Kann mir einer verraten, warum das so ist?

Hier mal die wichtigen Code Ausschnitte:

// include usw... rausgekürzt

Code: [Select]

char website[ ] PROGMEM = "meineURL.de";

// called when the client request is complete
static void my_callback (byte status, word off, word len){

String  schalter = ((const char*) Ethernet::buffer + off);

  Serial.println (schalter); // liefert den kompletten 6-stelligen Textcode
 
  Serial.println (schalter.substring(0,3));  // liefert irgendwelche Grütze, aber keine Teile des o.g. Codes
 
//Abfragen funktionieren, wenn der Code in der Textdatei entsprechend endet

if (schalter.endsWith("000")) {
   digitalWrite(2, LOW);
}

 
  if (schalter.endsWith("999")) {
  digitalWrite(2, HIGH);
}
 

// Abfragen funktionieren nicht

  if (schalter.substring(3,7) = "000") {
    digitalWrite(3, LOW);
  }
 
  if (schalter.substring(3,7) = "999") {
    digitalWrite(3, HIGH);
  }


// Variante Abfragen funktionieren auch nicht

if (schalter.startsWith("000")) {
    digitalWrite(3, LOW);
  }
 
iif (schalter.startsWith("999")) {
    digitalWrite(3, HIGH);
  }



//um das void setup gekürzt


Code: [Select]


void loop () {

 
  ether.packetLoop(ether.packetReceive());
 
  if (millis() > timer) {
    timer = millis() + 5000;
    ether.browseUrl(PSTR("/verzeichnis/"), "datei.txt", website, my_callback);   

  }


}



 


Auch nur einzelne Stellen mit Substring abzufragen funktioniert nicht.

OK, ich kann mir jetzt erstmal behelfen, indem ich mit eine mathematische Formel überlege, um alle Möglichkeiten mit möglichst wenig Code in solche "endsWith" zu bekommen, aber spätestens wenn es nicht nur zwei relevante Zustände und Empfänger (Schalter) sind, wird es unübersichtlich...

Jemand eine Idee, wie man das Problem lösen kann und warum das so ist?

plaubel

Keiner einen Plan, warum "endsWith" als Einziges geht und wie man da sonst Teilvariablen auslesen kann?

jurs


Keiner einen Plan, warum "endsWith" als Einziges geht


Das ist nix:
String  schalter = ((const char*) Ethernet::buffer + off);

Zwischen Pointern auf String-Objekte und Pointern auf Char-Arrays gibt es keine Zuweisungskompatibilität.

Keine Ahnung, warum nach dieser Zeile mit "schalter" überhaupt irgendwas noch scheinbar funktioniert.

Selbst:
Serial.println (schalter); // liefert den kompletten 6-stelligen Textcode
würde ich mal anzweifeln. Lasse Dir mal die genaue Länge von Schalter an der Stelle ausgeben und ob das wirklich nur der beabsichtigte "6-stellige Textcode" ist. Wenn ich mal raten soll ist die Variable dort schon deutlich länger als mit Serial.Println angezeigt wird und vorneweg kommen noch mehrere Zeichen mit ASCII-Codes, die am seriellen Terminal nicht dargestellt werden bzw. nicht darstellbar sind.

mkl0815


Zwischen Pointern auf String-Objekte und Pointern auf Char-Arrays gibt es keine Zuweisungskompatibilität.


Doch, gibt es. Das zeigt ein Blick in die WString.h :
Code: [Select]

// The string class
class String
{
        // use a function pointer to allow for "if (s)" without the
        // complications of an operator bool(). for more information, see:
        // http://www.artima.com/cppsource/safebool.html
        typedef void (String::*StringIfHelperType)() const;
        void StringIfHelper() const {}

public:
        // constructors
        // creates a copy of the initial value.
        // if the initial value is null or invalid, or if memory allocation
        // fails, the string will be marked as invalid (i.e. "if (s)" will
        // be false).
        String(const char *cstr = "");
        ...

Hier die letzte Zeile. Das Problem ist aber, das dieser Konstruktor immer eine komplette Kopie des übergebenen Strings macht. Das frisst zusätzlich Speicher, da die ENC28J60 Lib schon 700 Bytes Buffer verwendet. Dazu kommt dann die Kopie von einem großen Teil des Buffers.

jurs


Doch, gibt es. Das zeigt ein Blick in die WString.h :
...
Hier die letzte Zeile.


Danke für die Info, das funktioniert tatsächlich (wußte ich auch noch nicht)!

Go Up