String omzetten naar bruikbare waardes

Arduino specifieke Software
Berichten: 10
Geregistreerd: 02 Mrt 2014, 11:38
Woonplaats: Winschoten

String omzetten naar bruikbare waardes

Berichtdoor doddema74 » 11 Aug 2016, 00:26

Hallo,
Ben Mischa uit Winschoten met een vraag

ben met een Emoncms server bezig en waardes in deze cms zetten met Arduino ethernet of ESP8266 lukt eigenlijk probleemloos
maar ik wil ook graag via een arduino ethernet en lcd display enkele waardes uit mijn cms kunnen lezen en eventueel hier acties op ondernemen middels json
dit lukt tot op een zekere hoogte aardig maar ik kom er maar niet uit om mijn string Serial.println(pageValue); //print out the findings.
uit elkaar te halen in 3 bruikbare waardes.

Code: Alles selecteren
void loop() {
  String pageValue = connectAndRead(); //connect to the server and read the output

  Serial.println(pageValue); //print out the findings.



De string die wordt afgedrukt is

Code: Alles selecteren
"58.28","20.13","18.5"
"58.28","20.1","18.52"
enz..........


de eerste waarde is de hygro de tweede is de binnen temp en de derde is de buitentemp.

Hieronder de sketch waarmee ik nu aan het spelen ben

Code: Alles selecteren
#include <Ethernet.h>
#include <SPI.h>

byte server[] = { 192, 168, 2, 6 }; //ip Address of the server you will connect to
char apikey[] = "e6608a1d6ea38c49d707cc08412c0e6c";

// if need to change the MAC address (Very Rare)
byte mac[] = { 0xDE, 0xAD, 0x00, 0x00, 0xFE, 0xED };

EthernetClient client;

char inString[32]; // string for incoming serial data
int stringPos = 0; // string index counter
boolean startRead = false; // is reading?

void setup() {
  Ethernet.begin(mac);
  Serial.begin(9600);
}

void loop() {
  String pageValue = connectAndRead(); //connect to the server and read the output

  Serial.println(pageValue); //print out the findings.


  delay(5000); //wait 5 seconds before connecting again
}

String connectAndRead() {
  //connect to the server

//  Serial.println("connecting...");

  if (client.connect(server, 80)) {
//    Serial.println("connected");
    client.print("GET /emoncms/feed/fetch.json?apikey=");
    client.print(apikey);
    client.print("&ids=1,2,3");
    client.println(" HTTP/1.1");
    client.println("Host:emoncms");
    client.println("User-Agent: Arduino-ethernet");
    client.println("Connection: close");
    client.println();

    //Connected - Read the page
    return readPage(); //go and read the output

  } else {
    return "connection failed";
  }

}

String readPage() {
  //read the page, and capture & return everything between '[' and ']'

  stringPos = 0;
  memset( &inString, 0, 32 ); //clear inString memory

  while (true) {

    if (client.available()) {
      char c = client.read();

      if (c == '[' ) { //'<' is our begining character
        startRead = true; //Ready to start reading the part
      } else if (startRead) {

        if (c != ']') { //'>' is our ending character
          inString[stringPos] = c;
          stringPos ++;
        } else {
          //got what we need here! We can disconnect now
          startRead = false;
          client.stop();
          client.flush();
//          Serial.println("disconnecting.");
          return inString;

        }
      }
    }
  }
}


Wie o Wie kan mij een beste duw in de rug geven hoe ik dit kan oplossen ......

Advertisement

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

Re: String omzetten naar bruikbare waardes

Berichtdoor nicoverduin » 11 Aug 2016, 08:38

Waarom gebruik je geen JSON voor de server reply?
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

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

Re: String omzetten naar bruikbare waardes

Berichtdoor Koepel » 11 Aug 2016, 16:33

De sscanf zou het meest logisch zijn, maar die heeft geen floating point support in Arduino.
Misschien kan de parseFloat() en String.toFloat() gebruikt worden.
Hieronder staat een voorbeeld die de text langs gaat, en met atof werkt:
Code: Alles selecteren
// Decoding text with format: "58.28","20.13","18.5"

char myTest0[] = "\"58.28\",\"20.13\",\"18.5\"";
char myTest1[] = "\"-0.0012345\",\"1.05E+08\",\"2\"";

float a[3];

void setup()
{
  Serial.begin( 9600);

  char *p = myTest1;
 
  if( strlen( p) > 0)            // for safety, check if string is not empty.
  {
    for( int i = 0; i < 3; i++)      // we are trying to find three numbers
    {
      // Search for a double quote character, followed by a number or minus sign.
      while( p[1] != '\0')
      {
        if( p[0] == '"' && ( isdigit( p[1]) || p[1] == '-'))
        {
          p++;                   // skip the double quote
          a[i] = atof( p);
          Serial.println( a[i], 8);
          break;
        }
        else
        {
          p++;              // advance in the string of text
        }
      }
    }
  }
}

void loop()
{
}

Berichten: 10
Geregistreerd: 02 Mrt 2014, 11:38
Woonplaats: Winschoten

Re: String omzetten naar bruikbare waardes

Berichtdoor doddema74 » 12 Aug 2016, 18:09

Bedankt voor jullie reactie
ben zelf ook nog aan het stoeien geweest en kom op dit moment tot de volgende oplossing

stukje stoei code......

Code: Alles selecteren
void setup(){
  // Decoding text with format: "58.28","-20.13","18.5"
  char instring[] = "\"58.28\",\"-20.13\",\"18.5\"";
  char delimiters[] = "\"\",\"\",\"\"";
  char* Position;
 
  Position = strtok(instring, delimiters);
  double value[] = {0, 0, 0};
 
  Serial.begin(9600);
 
  for(int i = 0; i < 3; i++){
    value[i] = atof(Position);
    Serial.println(value[i]);
    Position = strtok(NULL, delimiters);
  }

}

void loop() {
  // put your main code here, to run repeatedly:

}



de uitkomst wordt nu

Code: Alles selecteren
58.28
-20.13
18.50

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

Re: String omzetten naar bruikbare waardes

Berichtdoor Koepel » 12 Aug 2016, 20:52

Dat ziet er eenvoudiger uit. Weer wat geleerd :D
Ik heb strtok() misschien nog nooit gebruikt. Dus ik heb de beschrijving eens goed doorgelezen ;)

De 'tokens' zijn de stukken tekst in 'instring'. De 'delimiters' is een enkele string van losse tekens, en dat zijn geen tokens. Daarom hoef je alleen maar een dubbele aanhalingsteken en een komma in de delimiters te zetten.
Code: Alles selecteren
char delimiters[] = "\",";

Berichten: 10
Geregistreerd: 02 Mrt 2014, 11:38
Woonplaats: Winschoten

Re: String omzetten naar bruikbare waardes

Berichtdoor doddema74 » 13 Aug 2016, 21:30

Ben nog weer aan het stoeien geweest en heb nu een werkende code die nu doet wat ik wil.
nu denk ik dat er vast wel veel betere en efficiëntere manieren zijn om dit voor elkaar te krijgen
maar als redelijke NOOB op Arduino gebied en als vriend Google en deze Forum natuurlijk
is het gelukt dit voor elkaar te krijgen.

Ik kan nu met onderstaande code, waardes uitlezen uit mijn Emoncms server...

Ik vraag uit mijn Emoncms deze 3 waardes die mijn Arduino verstuurt:
Code: Alles selecteren
http://192.168.2.6/emoncms/feed/fetch.json?ids=1,2,3


en krijg dit als response vanuit Emoncms:
Code: Alles selecteren
["68.92","22.31","18.28"]


in mijn terminal venster geeft de Arduino dan het volgende respons weer:
Code: Alles selecteren
__________________________
Lucht vochtigheid 68.9
Binnen Temp 22.3
Buiten Temp 18.3
__________________________


Dit alles wordt gedaan door deze code:
Code: Alles selecteren
#include <Ethernet.h>
#include <SPI.h>

byte server[] = { 192, 168, 2, 6 }; //ip Address of the server you will connect to
char apikey[] = "e6608a1d6ea38c49d707cc08412c0e6c";  // apikey of test opencms server

// if need to change the MAC address (Very Rare)
byte mac[] = { 0xDE, 0xAD, 0x00, 0x00, 0xFE, 0xED };

EthernetClient client;
char inString[32]; // string for incoming serial data
int stringPos = 0; // string index counter
boolean startRead = false; // is reading?

//char receivedChars[] = "\"58.28\",\"-20.13\",\"18.5\"";

double waarde1 = 0.0;
double waarde2 = 0.0;
double waarde3 = 0.0;


void setup() {
  Ethernet.begin(mac);
  Serial.begin(9600);
  Serial.println("<Arduino is ready>");
}

void loop() {
  String pageValue = connectAndRead(); //connect to the server and read the output
  char receivedChars[50];
  pageValue.toCharArray(receivedChars, 50);
//  Serial.println(pageValue); //print out the findings.


  delay(5000); //wait 5 seconds before connecting again
  {
    // split the data into its parts
    char * strtokIndx; // this is used by strtok() as an index

    strtokIndx = strtok(receivedChars, "\",");  // get the first part - the string
    waarde1 = atof(strtokIndx);                 // convert this part to a float

    strtokIndx = strtok(NULL, "\",");           // this continues where the previous call left off
    waarde2 = atof(strtokIndx);                 // convert this part to a float

    strtokIndx = strtok(NULL, "\",");
    waarde3 = atof(strtokIndx);                 // convert this part to a float
    {
      Serial.println("___________________________");
      Serial.print("Lucht vochtigheid ");
      Serial.println(waarde1 ,1);
      Serial.print("Binnen Temp ");
      Serial.println(waarde2 ,1);
      Serial.print("Buiten Temp ");
      Serial.println(waarde3 ,1);
      Serial.println("___________________________");     
    }
  }
}

String connectAndRead() {
  //connect to the server

  //  Serial.println("connecting...");

  if (client.connect(server, 80)) {
    //    Serial.println("connected");
    client.print("GET /emoncms/feed/fetch.json?apikey=");
    client.print(apikey);
    client.print("&ids=5,7,4");
    client.println(" HTTP/1.1");
    client.println("Host:emoncms");
    client.println("User-Agent: Arduino-ethernet");
    client.println("Connection: close");
    client.println();

    //Connected - Read the page
    return readPage(); //go and read the output

  } else {
    return "connection failed";
  }

}

String readPage() {
  //read the page, and capture & return everything between '[' and ']'

  stringPos = 0;
  memset( &inString, 0, 32 ); //clear inString memory

  while (true) {

    if (client.available()) {
      char c = client.read();

      if (c == '[' ) { //'<' is our begining character
        startRead = true; //Ready to start reading the part
      } else if (startRead) {

        if (c != ']') { //'>' is our ending character
          inString[stringPos] = c;
          stringPos ++;
        } else {
          //got what we need here! We can disconnect now
          startRead = false;
          client.stop();
          client.flush();
          //          Serial.println("disconnecting.");
          return inString;

        }
      }
    }
  }
}

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

Re: String omzetten naar bruikbare waardes

Berichtdoor Koepel » 13 Aug 2016, 23:39

Het lijkt me in orde, ik zie geen dingen die er uit springen.

Soms wordt een socket niet goed vrijgegeven. Dus als het na een tijdje vast loopt, dan kun je daar tegenaan gelopen zijn. Dan zijn alle vier de sockets bezet, en kan er geen nieuwe internet-verbinding meer gemaakt worden.
Je kunt een timeout op de sockets zetten. Zoek naar de functie "checkSockStatus" op deze bladzijde : http://playground.arduino.cc/Code/WebServerST

Je gebruikt accoladen die niet nodig zijn. Bijvoorbeeld na delay(5000) en na waarde3 = atof in de loop().
Het is in c en c++ toegestaan om één of meerdere statements binnen accoladen te zetten, maar dat is daar niet nodig. Als je een onderdeel er uit wilt lichten, dan kun je er commentaar boven zetten.

Voor een ATmega chip gebruik ik geen String object. Vanwege "Kaboom" : https://learn.adafruit.com/memories-of-an-arduino/solving-memory-problems.
De functie readPage() gebruikt een character array 'inString', maar gebruikt dat als return waarde als String object. En dat wordt later weer terug omgezet naar een normaal character array 'receivedChars'. Daar lijkt me nog wel iets te verbeteren.

Even controleren of het wel klopt wat ik over de compiler zei:
Code: Alles selecteren
void setup(){{}{{}{{}{{}{{Serial.begin((9600));}{;}{}}{}}{}}{}}{}}
void loop(){{}{{}{Serial.println(((("Hello"))));{{;}{;}{;}}{delay(1000);{;}{}}{}}{}}{}}
Ja hoor, dat werkt gewoon.

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: Google [Bot], ixhogucuwikep en 100 gasten