array geworstel

Software vragen voor ESP chip familie
Berichten: 126
Geregistreerd: 21 Feb 2013, 16:04

array geworstel

Berichtdoor René » 02 Apr 2017, 13:06

Ik probeer met een array de response van een website te lezen.
Als ik het volgende commando :
https://maps.googleapis.com/maps/api/ti ... M2rY_e92X4

via de browser naar de website geef, krijg ik het volgende terug op mijn scherm
Code: Alles selecteren
{
   "dstOffset" : 3600,
   "rawOffset" : 3600,
   "status" : "OK",
   "timeZoneId" : "Europe/Amsterdam",
   "timeZoneName" : "Central European Summer Time"
}


Ik probeer met de onderstaande functie het resultaat van de tweede regel "dstOffset" : 3600, te lezen.

Code: Alles selecteren
char * getStime()    // functie om zomertijd op te halen van website

  char charArray[800];                        // ff ruim genomen
  charArray[0] = '\0';   
  uint8_t charArrayIndex = 0;
 // Use WiFiClientSecure class to create TLS connection
  WiFiClientSecure client;
  Serial.print("connecting to ");
  Serial.println(host);
  if (!client.connect(host, httpsPort)) {
    Serial.println("connection failed");
   // return;
    }
   
  client.print("HEAD / HTTP/1.1\r\n\r\n");
    while(!!!client.available()) {
      yield();
    }
    while(client.available()) {
      charArray[charArrayIndex] = client.read();    // lees teken in de tabel
        if (charArray[charArrayIndex] == '\r' ){         // blijven lezen tot er een return komt
        charArray[charArrayIndex] = '\0';                // en sluit te tekst af met een '\0'. De return halen we gelijk weg
          //
          // kijk of dit de zomertijd regel is
          //
          char *startPositie;

     startPositie = strstr(charArray, "\n   \"dstOffset\" : ");
          //
          // is dit is onze regel?
          //
            if (startPositie != NULL){
              //
              // yep dus skip 3 posities en we hebben het startpunt
              //
              startPositie = startPositie + 3;
              client.stop();
              return startPositie;
            }
              else {
               Serial.println(" niet de gewenste regel dus zet hem maar weer op 0 in else");
                //
                charArray[0] = '\0';   
                charArrayIndex = 0;
              }
            }
              else {
                charArrayIndex++;
              }
       }
 Serial.println("als je hier terecht komt heb je niet hetgene ontvangen wat je wilde");
  client.stop();
  return (char *) NULL;
}





Het resultaat van de functie is:
Code: Alles selecteren
connecting to maps.googleapis.com
 niet de gewenste regel dus zet hem maar weer op 0 in else
 niet de gewenste regel dus zet hem maar weer op 0 in else
 niet de gewenste regel dus zet hem maar weer op 0 in else
 niet de gewenste regel dus zet hem maar weer op 0 in else
 niet de gewenste regel dus zet hem maar weer op 0 in else
 niet de gewenste regel dus zet hem maar weer op 0 in else
 niet de gewenste regel dus zet hem maar weer op 0 in else
 niet de gewenste regel dus zet hem maar weer op 0 in else
als je hier terecht komt heb je niet hetgene ontvangen wat je wilde


Het blijft heel lastig die array's!

Graag nog een lesje van een specialist

Advertisement

Gebruikers-avatar
Berichten: 4641
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: array geworstel

Berichtdoor nicoverduin » 02 Apr 2017, 15:51

Waarom zoek je eigenlijk niet direct op dstOffset?

Of kies voor een json parser. Wat je terugkrijgt is een JSON string en er is een library voor JSON voor de Arduino. Moet je wel weer ff wat bijleren....
Docent Software Engineering, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Gebruikers-avatar
Berichten: 1477
Geregistreerd: 06 Aug 2016, 01:03

Re: array geworstel

Berichtdoor Koepel » 02 Apr 2017, 15:55

Het is een beetje rommelig en dat boemerangt terug.

Je hebt bijvoorbeeld twee keer "client.stop" en twee keer "return". Dus de structuur van die functie zou beter kunnen.
Welk Arduino board heb je, dat je zomaar 800 byte op de stack kunt declareren ? En welke multitasking library ? Sommige multitasking libraries maken een stack in de heap en hebben default maar een hele kleine stack.
Ja hoor, daar zijn ze weer, drie uitroeptekens "!!!" achter elkaar. Zou je dat niet willen doen ? Het is gebruiken maken van de mazen in de 'c' taal. De "client.available()" geeft een nummer terug, dus je kunt gewoon "while( client.available() == 0)" doen.
Het array op de stack is niet meer geldig zodra je die functie verlaat. Je geeft echter een pointer terug die ergens in dat array wijst. Dat kan dus niet op die manier.
Je neemt een groot risico door te zoeken naar zo iets precies. Misschien staat er per ongeluk een '\r' na de '\n'. Ik denk niet dat zo iets aan de hand is, maar probeer eerst eens naar "dstOffset" te zoeken.

De echte fout kan ik niet ontdekken :oops: Misschien dat iemand anders het ziet.
Bestaat er misschien al een bibliotheek om json te lezen ?
Is het terug sturen van "HEAD / HTTP/1.1" echt voldoende ? Kun je daarvan een werkend voorbeeld op internet vinden ?
Je kunt zelf naar het probleem zoeken, door voor de aanroep van strstr(), de hele regel in het array naar de seriele monitor te sturen. Zo kom je stapje-voor-stapje een beetje verder.

(terwijl ik dit type heeft nicoverduin al twee dingen genoemd, ik verstuur toch maar het hele bericht)

Gebruikers-avatar
Berichten: 4641
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: array geworstel

Berichtdoor nicoverduin » 02 Apr 2017, 16:04

Koepel schreef:(terwijl ik dit type heeft nicoverduin al twee dingen genoemd, ik verstuur toch maar het hele bericht)
Ik schrijf ook niet van die hele epistels :mrgreen: :mrgreen: :mrgreen: :mrgreen: ben je eerder klaar :mrgreen:
Docent Software Engineering, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Gebruikers-avatar
Berichten: 1477
Geregistreerd: 06 Aug 2016, 01:03

Re: array geworstel

Berichtdoor Koepel » 02 Apr 2017, 16:10

Ha ha, dat is waar ;)
Zou het zo'n Arduino 101 of iets dergelijks zijn ? Want een Arduino met Ethernet Shield kan geen HTTPS.

Berichten: 126
Geregistreerd: 21 Feb 2013, 16:04

Re: array geworstel

Berichtdoor René » 02 Apr 2017, 16:20

Dank voor je reactie Nico maar.....
Er zat nog een behoorlijke beginners fout in mijn code.
Ik was vergeten de url mee te nemen.
Ik had de functie eerst gebouwd met "String" dat werkte maar omdat "String gebruik" vloeken in de kerk is wil ik de functie ombouwen mbv array's en daar loopt het nu mis.
Ik heb de url inmiddels toegevoegd maar krijg gewoon niet een goede response. De array wordt wel gevuld want als ik zoek op "OK" dan krijg ik als response de tekst "HTTP/1.1 200 OK" Volgens mij betekent dat dat het verzoek goed is afgehandeld volgens de server. Maar ik verwacht een heel andere response!

Code: Alles selecteren
char * getStime()    // functie om zomertijd op te halen van website

  char charArray[800];                        // ff ruim genomen
  charArray[0] = '\0';   
  uint8_t charArrayIndex = 0;
 // Use WiFiClientSecure class to create TLS connection
  WiFiClientSecure client;
  Serial.print("connecting to ");
  Serial.println(host);
  if (!client.connect(host, httpsPort)) {
    Serial.println("connection failed");
   // return;
    }


String url = "/maps/api/timezone/json?location=51.643567,%205.946934&timestamp=1490531639&key=AIzaSyCtC0BKgufYKsLMvouXrtr66M2rY_e92X4";
 
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");

 
 
    while(!!!client.available()) {
         yield();
      }
     while(client.available()) {
      charArray[charArrayIndex] = client.read();    // lees teken in de tabel
        if (charArray[charArrayIndex] == '\r' ){         // blijven lezen tot er een return komt
        charArray[charArrayIndex] = '\0';                // en sluit te tekst af met een '\0'. De return halen we gelijk weg
          //
          // kijk of dit de zomertijd regel is
          //
          char *startPositie;

     startPositie = strstr(charArray, "OK");
          //
          // is dit is onze regel?
          //
            if (startPositie != NULL){
              //
              // yep dus skip 3 posities en we hebben het startpunt
              //
              startPositie = startPositie - 13;
              client.stop();
              return startPositie;
            }
              else {
               Serial.println(" niet de gewenste regel dus zet hem maar weer op 0 in else");
                //
                charArray[0] = '\0';   
                charArrayIndex = 0;
              }
            }
              else {
                charArrayIndex++;
              }
       }
 Serial.println("als je hier terecht komt heb je niet hetgene ontvangen wat je wilde");
  client.stop();
  return (char *) NULL;
}

Berichten: 126
Geregistreerd: 21 Feb 2013, 16:04

Re: array geworstel

Berichtdoor René » 02 Apr 2017, 16:33

Beste Koepel bedankt voor je uitgebreide reactie.

Ik gebruik een ESP8266
Mijn wijsheid heb ik gevonden op internet
Ik vond daar een voorbeeld voor HTTPS en heb die omgebouwd.
Vervolgens probeerde ik naar Nico te luisteren om vooral geen "String" te gebruiken en er een functie van te maken die array toepast.
Onderstaand mijn "startcode" daar heb ik host en keys aangepast. Dit werkt.
De reden waarom ik dit probeer is dat ik de zomertijd in mijn programma voor mijn zonnepanelen automatisch wil corrigeren. Moeilijk dus voor mij:)


Code: Alles selecteren
/*
 *  HTTP over TLS (HTTPS) example sketch
 *
 *  This example demonstrates how to use
 *  WiFiClientSecure class to access HTTPS API.
 *  We fetch and display the status of
 *  esp8266/Arduino project continuous integration
 *  build.
 *
 *  Created by Ivan Grokhotkov, 2015.
 *  This example is in public domain.
 */

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>

const char* ssid = "XXX";
const char* password = "XXXXXXX";
const char* host = "maps.googleapis.com";
//const char* host = "api.github.com";
const int httpsPort = 443;

// Use web browser to view and copy
// SHA1 fingerprint of the certificate
const char* fingerprint = "CF 05 98 89 CA FF 8E D8 5E 5C E0 C2 E4 F7 E6 C3 C7 50 DD 5C";

void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.print("connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  // Use WiFiClientSecure class to create TLS connection
  WiFiClientSecure client;
  Serial.print("connecting to ");
  Serial.println(host);
  if (!client.connect(host, httpsPort)) {
    Serial.println("connection failed");
    return;
  }

  if (client.verify(fingerprint, host)) {
    Serial.println("certificate matches");
  } else {
    Serial.println("certificate doesn't match");
  }
  String url = "/maps/api/timezone/json?location=51.643567,%205.946934&timestamp=1490531639&key=AIzaSyCtC0BKgufYKsLMvouXrtr66M2rY_e92X4";

 // String url = "/repos/esp8266/Arduino/commits/master/status";
  Serial.print("requesting URL: ");
  Serial.println(url);

  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "User-Agent: BuildFailureDetectorESP8266\r\n" +
               "Connection: close\r\n\r\n");

  Serial.println("request sent");
  while (client.connected()) {
    String line = client.readStringUntil('\n');
    if (line == "\r") {
      Serial.println("headers received");
      break;
    }
  }
  String line = client.readStringUntil('\n');
  if (line.startsWith("{\"state\":\"success\"")) {
    Serial.println("esp8266/Arduino CI successfull!");
  } else {
    Serial.println("esp8266/Arduino CI has failed");
  }
  Serial.println("reply was:");
  Serial.println("==========");
  Serial.println(line);
  Serial.println("==========");
  Serial.println("closing connection");
}

void loop() {
}

Berichten: 126
Geregistreerd: 21 Feb 2013, 16:04

Re: array geworstel

Berichtdoor René » 02 Apr 2017, 19:30

testje
In de onderstaande code is de functie String getDST() die zijn werk naar behoren doet.
De functie char * getStime() werkt niet goed, Het lijkt erop of de url niet goed wordt verwerkt in mijn code
Code: Alles selecteren
void loop() {

Serial.println("response van String getDST()");
Serial.println(getDST());
Serial.println("response van char * getStime()");
Serial.println(getStime());
delay(1000);
}

char * getStime()    // functie om zomertijd op te halen van website

  char charArray[800];                        // ff ruim genomen
  charArray[0] = '\0';   
  uint8_t charArrayIndex = 0;
  WiFiClientSecure client;
  if (!client.connect(host, httpsPort)) {
    Serial.println("connection failed");
  }
  String  url = "/maps/api/timezone/json?location=51.643567,%205.946934&timestamp=";
          url += t;
          url += "&key=AIzaSyCtC0BKgufYKsLMvouXrtr66M2rY_e92X4"; 
  //  Serial.print("requesting URL: ");
  //  Serial.println(url);
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
   while(client.available() == 0) {
         yield();
   }
   while(client.available()) {
    charArray[charArrayIndex] = client.read();           // lees teken in de tabel
    if (charArray[charArrayIndex] == '\r' ){            // blijven lezen tot er een return komt
        charArray[charArrayIndex] = '\0';               // en sluit te tekst af met een '\0'. De return halen we gelijk weg
        //
        // kijk of dit de zomertijd regel is
        //
        char *startPositie;
        startPositie = strstr(charArray, "OK");
        //
        // is dit is onze regel?
        //
        if (startPositie != NULL){
            //
            // yep dus skip 3 posities en we hebben het startpunt
            //
            startPositie = startPositie - 13;
            client.stop();
            return startPositie;
         }
         else {
             Serial.println(" niet de gewenste regel dus zet hem maar weer op 0 in else");
             //
             charArray[0] = '\0';   
             charArrayIndex = 0;
         }
    }
    else {
        charArrayIndex++;
    }
  }
  Serial.println("als je hier terecht komt heb je niet hetgene ontvangen wat je wilde");
  client.stop();
  return (char *) NULL;
}

String getDST()
{
  WiFiClientSecure client;
  if (!client.connect(host, httpsPort)) {
    Serial.println("connection failed");
    // return;
  }
  String url = "/maps/api/timezone/json?location=51.643567,%205.946934&timestamp=";
  url += t;
  url += "&key=AIzaSyCtC0BKgufYKsLMvouXrtr66M2rY_e92X4";
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");

  while (client.connected()) {
    String line = client.readStringUntil('\n');
    if (line == "{") {
    break;
    }
  }
  String line = client.readStringUntil(',');
   client.stop();
  return line;
}


dit is de response van de functies
Code: Alles selecteren
response van char * getStime()
HTTP/1.1 200 OK
response van String getDST()
   "dstOffset" : 3600


getDST gaat naar verwachting.
getStime geeft een onverwachte response. Ik verwacht op basis van de code "status" : "OK"

Gebruikers-avatar
Berichten: 1477
Geregistreerd: 06 Aug 2016, 01:03

Re: array geworstel

Berichtdoor Koepel » 04 Apr 2017, 02:25

Je bent waarschijnlijk wel connected, en er is waarschijnlijk data available, en waarschijnlijk lees je die data... dan komt er een zwart gat... en dan druk je een foutmelding af.
Het zou handig zijn als je dat zwarte gat kon opvullen. Daarom schreef ik: "Je kunt zelf naar het probleem zoeken, door voor de aanroep van strstr(), de hele regel in het array naar de seriele monitor te sturen. Zo kom je stapje-voor-stapje een beetje verder."
Dus op het moment dat je een hele regel hebt, die laten zien in de seriele monitor.

Berichten: 126
Geregistreerd: 21 Feb 2013, 16:04

Re: array geworstel

Berichtdoor René » 14 Apr 2017, 14:19

Dank voor je reactie Koepel,
Ik "moest" eerst even een weekje op vakantie maar heb nu gedaan wat je adviseerde.
Voor mij is het resultaat onbegrijpelijk.
De "string" functie geeft het verwachte resultaat.
De "array" functie doet dat niet.
Vanuit beide functies stuur ik exact hetzelfde GET commando naar de website en krijg vervolgens een ander resultaat.
Dit doe ik:
Code: Alles selecteren
void loop() {

Serial.println("response van String getDST()");
Serial.println(getDST());
Serial.println("response van char * getStime()");
Serial.println(getStime());
delay(1000);
}

char * getStime()    // functie om zomertijd op te halen van website

  char charArray[200];                        // ff ruim genomen
  charArray[0] = '\0';   
  uint8_t charArrayIndex = 0;
  WiFiClientSecure client;
  if (!client.connect(host, httpsPort)) {
    Serial.println("connection failed");
    // return;
  }
  String url = "/maps/api/timezone/json?location=51.643567,%205.946934&timestamp=";
  url += t;
  url += "&key=AIzaSyCtC0BKgufYKsLMvouXrtr66M2rY_e92X4";
Serial.print("requesting URLStime: ");
  Serial.println(url);
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
   while(client.available() == 0) {
         yield();
   }
   while(client.available()) {
    charArray[charArrayIndex] = client.read();           // lees teken in de tabel
    if (charArray[charArrayIndex] == '\r' ){            // blijven lezen tot er een return komt
        charArray[charArrayIndex] = '\0';               // en sluit te tekst af met een '\0'. De return halen we gelijk weg
        //
        // kijk of dit de zomertijd regel is
        //
        char *startPositie;

        Serial.println(charArray);
        startPositie = strstr(charArray, "Europe/Amsterdam");
        //
        // is dit is onze regel?
        //
        if (startPositie != NULL){
            //
            // yep dus skip 3 posities en we hebben het startpunt
            //
            startPositie = startPositie - 13;
            client.stop();
            return startPositie;
         }
         else {
             Serial.println(" niet de gewenste regel dus zet hem maar weer op 0 in else");
             //
             charArray[0] = '\0';   
             charArrayIndex = 0;
         }
    }
    else {
        charArrayIndex++;
    }
  }
  Serial.println("als je hier terecht komt heb je niet hetgene ontvangen wat je wilde");
  client.stop();
  return (char *) NULL;
}

String getDST()
{
  WiFiClientSecure client;
  if (!client.connect(host, httpsPort)) {
    Serial.println("connection failed");
    // return;
  }
  String url = "/maps/api/timezone/json?location=51.643567,%205.946934&timestamp=";
  url += t;
  url += "&key=AIzaSyCtC0BKgufYKsLMvouXrtr66M2rY_e92X4";
Serial.print("requesting URLDST: ");
  Serial.println(url);
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
   while(client.available() == 0) {
         yield();
   }
   while(client.available()) {

    String line = client.readStringUntil('\n');
    if (line == "{") {
    break;
    }
  }
  String line = client.readStringUntil(',');
   client.stop();
  return line;
}

En dit is het resultaat:

Code: Alles selecteren
response van String getDST()
requesting URLDST: /maps/api/timezone/json?location=51.643567,%205.946934&timestamp=1492175431&key=AIzaSyCtC0BKgufYKsLMvouXrtr66M2rY_e92X4
   "dstOffset" : 3600
response van char * getStime()
requesting URLStime: /maps/api/timezone/json?location=51.643567,%205.946934&timestamp=1492175431&key=AIzaSyCtC0BKgufYKsLMvouXrtr66M2rY_e92X4
HTTP/1.1 200 OK
 niet de gewenste regel dus zet hem maar weer op 0 in else

Content-Type: application/json; charset=UTF-8
 niet de gewenste regel dus zet hem maar weer op 0 in else

Date: Fri, 14 Apr 2017 12:10:35 GMT
 niet de gewenste regel dus zet hem maar weer op 0 in else

Expires: Sat, 15 Apr 2017 12:10:35 GMT
 niet de gewenste regel dus zet hem maar weer op 0 in else

Access-Control-Allow-Origin: *
 niet de gewenste regel dus zet hem maar weer op 0 in else

Server: mafe
 niet de gewenste regel dus zet hem maar weer op 0 in else

X-XSS-Protection: 1; mode=block
 niet de gewenste regel dus zet hem maar weer op 0 in else

X-Frame-Options: SAMEORIGIN
 niet de gewenste regel dus zet hem maar weer op 0 in else

Cache-Control: public, max-age=86400
 niet de gewenste regel dus zet hem maar weer op 0 in else

Age: 66
 niet de gewenste regel dus zet hem maar weer op 0 in else

Alt-Svc: quic=":443"; ma=2592000; v="37,36,35"
 niet de gewenste regel dus zet hem maar weer op 0 in else

Accept-Ranges: none
 niet de gewenste regel dus zet hem maar weer op 0 in else

Vary: Accept-Encoding
 niet de gewenste regel dus zet hem maar weer op 0 in else

Connection: close
 niet de gewenste regel dus zet hem maar weer op 0 in else


 niet de gewenste regel dus zet hem maar weer op 0 in else
als je hier terecht komt heb je niet hetgene ontvangen wat je wilde



Volgende

Terug naar ESP Software

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 16 gasten