Ethernet W5100 parser kód

Odpovědět
martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Ethernet W5100 parser kód

Příspěvek od martinius96 » 23 lis 2017, 15:37

Ahoj, dlhšie hľadám parser kód na Ethernet Shield W5100 - Webclient mód. Originál pre Webclient vráti premennú (z txt súboru) a okrem toho aj celú HTTP hlavičku. Potreboval by som to odstrániť a dostať iba výslednú hodnotu, ktorá sa nachádza v tom textovom súbore. Vďaka :)

afilip
Příspěvky: 116
Registrován: 26 črc 2017, 16:34
Reputation: 0
Kontaktovat uživatele:

Re: Ethernet W5100 parser kód

Příspěvek od afilip » 01 pro 2017, 13:15

Jestli na to přijdeš, tak mi dej vědět. Já jsem to vyřešil tak, že načtu do bufferu celou hlavičku, tu odříznu, a použiju jenom konec s datama. Bohužel má ta hlavička si 300 bajtů, takže to zabere docela dost paměti. Nepřišel jsem na to, jak to udělat jinak, a to si to načítám ze svého serveru. Takže jsem zkoušel laborovat s nastavením Apache, atd. Jedině to udělat v .php.

martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Re: Ethernet W5100 parser kód

Příspěvek od martinius96 » 27 pro 2017, 02:07

Mohol by som to od vás vyškúšať? Nepodarilo sa mi nič.

zbysek
Site Admin
Příspěvky: 125
Registrován: 22 úno 2017, 15:18
Reputation: 0

Re: Ethernet W5100 parser kód

Příspěvek od zbysek » 27 pro 2017, 11:22

Řekněme, že máme soubor data.txt obsahující hodnotu 100.
Když se připojíme na: http://.../data.txt, dostaneme odpověd ve tvaru:

Kód: Vybrat vše

HTTP hlavička 
Další řádek HTTP hlavičky
....
Poslední řádek HTTP hlavičky

100
Místo, kde končí HTTP hlavička a začíná obsah souboru poznáme tak, že je mezi nimi prázdný řádek.
Algoritmus načtení hodnoty by mohl být třeba takový:
  1. vytvoříme si dostatečně velké pole na uložení čísla v podobě znaků (říkejme mu a_cislo)
  2. toto pole vynulujeme
  3. stáhneme obsah souboru data.txt
  4. čteme výstup z ethernet modulu znak po znaku
  5. když narazíme na dva znaky zalomení řádku ('\n') za sebou, víme, že končí hlavička a začíná obsah souboru (jeden znak je za posledním řádkem hlavičky, druhý za prázdným řádkem)
  6. do připraveného pole ukládáme přicházející znaky, dokud jsou to čísla, pokud narazíme na jiný znak, popřípadě konec souboru, končíme načítání
  7. v poli teď máme uložené číslo v podobě znaků, to převedeme na číslo
Pozor jen na to, že znak (char) '0' nemá hodnotu 0. Více viz. ASCII.
Znaky jsou jen jiným způsobem zápisu číselné hodnoty. Z ASCII tabulky zjistíme tyto hodnoty:
  • '0' = 48
  • '1' = 49
  • '2' = 50
  • '3' = 51
  • '4' = 52
  • '5' = 53
  • '6' = 54
  • '7' = 55
  • '8' = 56
  • '9' = 57
Hodnotu znaku, který reprezentuje číslo je možné zjistit pomocí výrazu: znak - '0'
Například '5' - '0' = 5

Při načítání znaků do pole si můžeme ukládat, kolik jsme jich načetli. Díky tomu pak víme, kolik číslic výsledné číslo má.
Například:
načetli jsme 4 znaky - nejvyšší číslice tedy udává tisíce, další stovky, další desítky a poslední jednotky.
Výsledná hodnota je:
(a_cislo[0] - '0') * 1000 + (a_cislo[1] - '0') * 100 + (a_cislo[2] - '0') * 10 + (a_cislo[3] - '0')

Když si na to vytvoříme funkci, může vypadat třeba takto:

Kód: Vybrat vše

int parseNum(char *a, int len) {
  int out = 0;
  int p = pow(10, len - 1);
  
  for(int i = 0; i < len; i++) {
    out += (a[i] - '0') * p;
    p /= 10;
  }

  return out;
}
Celý kód, ve kterém si do pole uložíme znaky '2', '5', '5', '6' a ty pak převedeme na číslo může vypadat třeba takto:

Kód: Vybrat vše

#define A_SIZE 10

char a_cislo[A_SIZE];


void clearArray(char *a) {
  for(int i = 0; i < A_SIZE; i++) {
    a[i] = '\0';  
  }
}

int parseNum(char *a, int len) {
  int out = 0;
  int p = pow(10, len - 1);
  
  for(int i = 0; i < len; i++) {
    out += (a[i] - '0') * p;
    p /= 10;
  }

  return out;
} 

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

  clearArray(a_cislo);
  
  // uložíme si do pole znaky 2556
  a_cislo[0] = '2';
  a_cislo[1] = '5';
  a_cislo[2] = '5';
  a_cislo[3] = '6';

  int cislo = parseNum(a_cislo, 4);
  Serial.println(cislo);
}

void loop() {
  
}

martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Re: Ethernet W5100 parser kód

Příspěvek od martinius96 » 29 pro 2017, 14:12

Ahoj, tak sa mi podarilo na internete zohnať prototyp. Skúšal som to od zbyšeka ale nešlo mi to dobre.
V tom kóde sú 2 premenné: readString a readString1.
Keď si vypisujem readString do nového riadku tak je tam o jednu medzeru (riadok) viac ako má byť...
Obrázek
Podľa kódu tá poloha premennej nesedí, lebo by tam nemal byť prázdny riadok, kde by bol teda problém?
Obrázek
Druhá premenná orezáva pôvodnú readString a číta z nej počet znakov, ak tomu správne chápem.

Dal som tam 4, keď dám 3, tak sa mi vypíše VY a nie VYP. Kód sa pripája k môjmu projektu, kde sa spína relé. Momentálne to riadi NodeMCU, ktoré vie bez problému ten string spracovať :-) Ale radšej by som bol za Ethernet.
V prototypovom kóde som teda upravil to orezanie stringu z 8 na 4 znaky, i keď nechápem prečo má string VYP 4 znaky keď má 3. Asi ma na konci LF znak alebo sa mýlim?

Ďalej som upravil counter riadkov v podmienke, original bol 10, ja som použil 12, lebo dostávam tak dlhú hlavičku.
Mohol by to niekto ešte vytuniť, resp zjednodušiť na jednu premennú, aby sa z tej druhej ten string nemusel orezávať? :D



Kód je následovný:

Kód: Vybrat vše

#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
char serverName[] = "www.arduino.php5.sk"; // zoomkat's test web page server
IPAddress ip(192, 168, 2, 40);
EthernetClient client;

String readString, readString1;
int x=0; //for counting line feeds
char lf=10; //line feed character
//////////////////////

void setup(){

  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }
  Serial.begin(9600); 
  Serial.println("Better client test 5/13/13"); // so I can keep track of what is loaded
  Serial.println("Send an e in serial monitor to test"); // what to do to test
}

void loop(){
  // check for serial input
  if (Serial.available() > 0) //if something in serial buffer
  {
    byte inChar; // sets inChar as a byte
    inChar = Serial.read(); //gets byte from buffer
    if(inChar == 'e') // checks to see byte is an e
    {
      sendGET(); // call sendGET function below when byte is an e
    }
  }  
} 

//////////////////////////

void sendGET() //client function to send/receive GET request data.
{
  if (client.connect(serverName, 80)) {  //starts client connection, checks for connection
    Serial.println("connected");
    client.println("GET /rosko/system/values/voda.txt HTTP/1.1"); //download text
    client.println("Host: www.arduino.php5.sk");
    client.println("Connection: close");  //close 1.1 persistent connection  
    client.println(); //end of get request
  } 
  else {
    Serial.println("connection failed"); //error message if no client connect
    Serial.println();
  }

  while(client.connected() && !client.available()) delay(1); //waits for data
  while (client.connected() || client.available()) { //connected or data available
    char c = client.read(); //gets byte from ethernet buffer
    Serial.print(c); //prints raw feed for testing
    if (c==lf) x=(x+1); //counting line feeds
    if (x==12) readString += c; //building readString
   }
readString1 = (readString.substring(0,4)); //extracting "woohoo!"
  Serial.println();  
  Serial.println();
  Serial.print("Current data row:" );
  Serial.println(readString); //the 10th line captured
Serial.println("Premenna je: ");
Serial.println(readString); 
  Serial.print("How we feeling?: ");
 readString1 = (readString.substring(0,4)); //extracting "woohoo!"
  Serial.println(readString1);    
  Serial.println("done");
  Serial.println("disconnecting.");
  Serial.println("==================");
  Serial.println();
  readString = ("");
  readString1 = ("");  
  client.stop(); //stop client
}
Kód sa spúšťa cez zadanie e do serial monitoru

martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Re: Ethernet W5100 parser kód

Příspěvek od martinius96 » 30 pro 2017, 20:24

Podarilo sa mi to :-) Vďaka za rady, pomohli mi.

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 7 hostů